X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ovsdb%2Ftransaction.c;h=bfa2fcbad65c20dc1cc59640be6596596fd4a6f1;hb=d785193ad9989b429ea4c6931af9da7f4edf60ec;hp=2e4c73a82b867a922233997b506aad3573fdae29;hpb=7360012bdf64effd898242a58634267e203a2795;p=openvswitch diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index 2e4c73a8..bfa2fcba 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -152,7 +152,8 @@ find_txn_row(const struct ovsdb_table *table, const struct uuid *uuid) } static struct ovsdb_error * WARN_UNUSED_RESULT -ovsdb_txn_adjust_atom_refs(struct ovsdb_txn *txn, +ovsdb_txn_adjust_atom_refs(struct ovsdb_txn *txn, const struct ovsdb_row *r, + const struct ovsdb_column *c, const struct ovsdb_base_type *base, const union ovsdb_atom *atoms, unsigned int n, int delta) @@ -174,8 +175,12 @@ ovsdb_txn_adjust_atom_refs(struct ovsdb_txn *txn, txn_row = ovsdb_txn_row_modify(txn, row)->txn_row; } else { return ovsdb_error("referential integrity violation", - "reference to nonexistent row " - UUID_FMT, UUID_ARGS(uuid)); + "Table %s column %s row "UUID_FMT" " + "references nonexistent row "UUID_FMT" in " + "table %s.", + r->table->schema->name, c->name, + UUID_ARGS(ovsdb_row_get_uuid(r)), + UUID_ARGS(uuid), table->schema->name); } } txn_row->n_refs += delta; @@ -191,10 +196,10 @@ ovsdb_txn_adjust_row_refs(struct ovsdb_txn *txn, const struct ovsdb_row *r, const struct ovsdb_datum *field = &r->fields[column->index]; struct ovsdb_error *error; - error = ovsdb_txn_adjust_atom_refs(txn, &column->type.key, + error = ovsdb_txn_adjust_atom_refs(txn, r, column, &column->type.key, field->keys, field->n, delta); if (!error) { - error = ovsdb_txn_adjust_atom_refs(txn, &column->type.value, + error = ovsdb_txn_adjust_atom_refs(txn, r, column, &column->type.value, field->values, field->n, delta); } return error; @@ -441,6 +446,27 @@ determine_changes(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row) return NULL; } +static struct ovsdb_error * WARN_UNUSED_RESULT +check_max_rows(struct ovsdb_txn *txn) +{ + struct ovsdb_txn_table *t; + + LIST_FOR_EACH (t, struct ovsdb_txn_table, node, &txn->txn_tables) { + size_t n_rows = hmap_count(&t->table->rows); + unsigned int max_rows = t->table->schema->max_rows; + + if (n_rows > max_rows) { + return ovsdb_error("constraint violation", + "transaction causes \"%s\" table to contain " + "%zu rows, greater than the schema-defined " + "limit of %u row(s)", + t->table->schema->name, n_rows, max_rows); + } + } + + return NULL; +} + struct ovsdb_error * ovsdb_txn_commit(struct ovsdb_txn *txn, bool durable) { @@ -459,6 +485,13 @@ ovsdb_txn_commit(struct ovsdb_txn *txn, bool durable) return NULL; } + /* Check maximum rows table constraints. */ + error = check_max_rows(txn); + if (error) { + ovsdb_txn_abort(txn); + return error; + } + /* Update reference counts and check referential integrity. */ error = update_ref_counts(txn); if (error) {