X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ovsdb%2Ftransaction.c;h=d5e3601678b3bf3ccd4599e32999ba8e734eabea;hb=f0f54cb4dd1c4d890b6b4b9cd459c11fe880e88f;hp=21a46ec7c5fae5bd1b5038256333145afebb8704;hpb=f85f8ebbfac946c19b3c6eb0f4170f579d0a4d25;p=openvswitch diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index 21a46ec7..d5e36016 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -59,13 +59,6 @@ struct ovsdb_txn_row { struct ovsdb_row *new; /* The new row. */ }; -static const struct uuid * -ovsdb_txn_row_get_uuid(const struct ovsdb_txn_row *txn_row) -{ - const struct ovsdb_row *row = txn_row->old ? txn_row->old : txn_row->new; - return ovsdb_row_get_uuid(row); -} - struct ovsdb_txn * ovsdb_txn_create(struct ovsdb *db) { @@ -131,197 +124,43 @@ ovsdb_txn_row_commit(struct ovsdb_txn_row *txn_row) ovsdb_row_destroy(txn_row->old); } -void -ovsdb_txn_commit(struct ovsdb_txn *txn) -{ - txn->db->run_triggers = true; - ovsdb_txn_destroy(txn, ovsdb_txn_row_commit); -} - -static void -put_json_column(struct json *object, const struct ovsdb_row *row, - const struct ovsdb_column *column) -{ - json_object_put(object, column->name, - ovsdb_datum_to_json(&row->fields[column->index], - &column->type)); -} - -static struct json * -ovsdb_txn_row_to_json(const struct ovsdb_txn_row *txn_row) -{ - const struct ovsdb_row *old = txn_row->old; - const struct ovsdb_row *new = txn_row->new; - struct shash_node *node; - struct json *json; - - if (!new) { - return json_null_create(); - } - - json = NULL; - SHASH_FOR_EACH (node, &new->table->schema->columns) { - struct ovsdb_column *column = node->data; - unsigned int index = column->index; - - if (index != OVSDB_COL_UUID && column->persistent - && (!old || !ovsdb_datum_equals(&old->fields[index], - &new->fields[index], - &column->type))) - { - if (!json) { - json = json_object_create(); - } - put_json_column(json, new, column); - } - } - return json; -} - -static struct json * -ovsdb_txn_table_to_json(const struct ovsdb_txn_table *txn_table) -{ - struct ovsdb_txn_row *txn_row; - struct json *txn_table_json; - - txn_table_json = NULL; - HMAP_FOR_EACH (txn_row, struct ovsdb_txn_row, hmap_node, - &txn_table->txn_rows) { - struct json *txn_row_json = ovsdb_txn_row_to_json(txn_row); - if (txn_row_json) { - char uuid[UUID_LEN + 1]; - - if (!txn_table_json) { - txn_table_json = json_object_create(); - } - - snprintf(uuid, sizeof uuid, - UUID_FMT, UUID_ARGS(ovsdb_txn_row_get_uuid(txn_row))); - json_object_put(txn_table_json, uuid, txn_row_json); - } - } - return txn_table_json; -} - -struct json * -ovsdb_txn_to_json(const struct ovsdb_txn *txn) -{ - struct ovsdb_txn_table *txn_table; - struct json *txn_json; - - txn_json = NULL; - HMAP_FOR_EACH (txn_table, struct ovsdb_txn_table, hmap_node, - &txn->txn_tables) { - struct json *txn_table_json = ovsdb_txn_table_to_json(txn_table); - if (!txn_json) { - txn_json = json_object_create(); - } - json_object_put(txn_json, txn_table->table->schema->name, - txn_table_json); - } - return txn_json; -} - -static struct ovsdb_error * -ovsdb_txn_row_from_json(struct ovsdb_txn *txn, struct ovsdb_table *table, - const struct uuid *row_uuid, struct json *json) +struct ovsdb_error * +ovsdb_txn_commit(struct ovsdb_txn *txn, bool durable) { - const struct ovsdb_row *row = ovsdb_table_get_row(table, row_uuid); - if (json->type == JSON_NULL) { - if (!row) { - return ovsdb_syntax_error(NULL, NULL, "transaction deletes " - "row "UUID_FMT" that does not exist", - UUID_ARGS(row_uuid)); - } - ovsdb_txn_row_delete(txn, row); - return NULL; - } else if (row) { - return ovsdb_row_from_json(ovsdb_txn_row_modify(txn, row), - json, NULL, NULL); - } else { - struct ovsdb_error *error; - struct ovsdb_row *new; + struct ovsdb_replica *replica; + struct ovsdb_error *error; - new = ovsdb_row_create(table); - *ovsdb_row_get_uuid_rw(new) = *row_uuid; - error = ovsdb_row_from_json(new, json, NULL, NULL); + LIST_FOR_EACH (replica, struct ovsdb_replica, node, &txn->db->replicas) { + error = (replica->class->commit)(replica, txn, durable); if (error) { - ovsdb_row_destroy(new); - } - - ovsdb_txn_row_insert(txn, new); - - return error; - } -} - -static struct ovsdb_error * -ovsdb_txn_table_from_json(struct ovsdb_txn *txn, struct ovsdb_table *table, - struct json *json) -{ - struct shash_node *node; - - if (json->type != JSON_OBJECT) { - return ovsdb_syntax_error(json, NULL, "object expected"); - } - - SHASH_FOR_EACH (node, json->u.object) { - const char *uuid_string = node->name; - struct json *txn_row_json = node->data; - struct ovsdb_error *error; - struct uuid row_uuid; + /* We don't support two-phase commit so only the first replica is + * allowed to report an error. */ + assert(&replica->node == txn->db->replicas.next); - if (!uuid_from_string(&row_uuid, uuid_string)) { - return ovsdb_syntax_error(json, NULL, "\"%s\" is not a valid UUID", - uuid_string); - } - - error = ovsdb_txn_row_from_json(txn, table, &row_uuid, txn_row_json); - if (error) { + ovsdb_txn_abort(txn); return error; } } + txn->db->run_triggers = true; + ovsdb_txn_destroy(txn, ovsdb_txn_row_commit); return NULL; } -struct ovsdb_error * -ovsdb_txn_from_json(struct ovsdb *db, const struct json *json, - struct ovsdb_txn **txnp) +void +ovsdb_txn_for_each_change(const struct ovsdb_txn *txn, + ovsdb_txn_row_cb_func *cb, void *aux) { - struct ovsdb_error *error; - struct shash_node *node; - struct ovsdb_txn *txn; + struct ovsdb_txn_table *t; + struct ovsdb_txn_row *r; - *txnp = NULL; - if (json->type != JSON_OBJECT) { - return ovsdb_syntax_error(json, NULL, "object expected"); - } - - txn = ovsdb_txn_create(db); - SHASH_FOR_EACH (node, json->u.object) { - const char *table_name = node->name; - struct json *txn_table_json = node->data; - struct ovsdb_table *table; - - table = shash_find_data(&db->tables, table_name); - if (!table) { - error = ovsdb_syntax_error(json, "unknown table", - "No table named %s.", table_name); - goto error; - } - - error = ovsdb_txn_table_from_json(txn, table, txn_table_json); - if (error) { - goto error; + HMAP_FOR_EACH (t, struct ovsdb_txn_table, hmap_node, &txn->txn_tables) { + HMAP_FOR_EACH (r, struct ovsdb_txn_row, hmap_node, &t->txn_rows) { + if (!cb(r->old, r->new, aux)) { + break; + } } - } - *txnp = txn; - return NULL; - -error: - ovsdb_txn_abort(txn); - return error; + } } static struct ovsdb_txn_table *