X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fovsdb-idl.c;h=f72e18762f0857f6e89ed74dd4869c87c1252918;hb=6c1b89ed0e6b9934d63ae4d71ba885bfcb87891a;hp=e0c540641d95821875172f9fcfd3b1de9c30b4c7;hpb=586bb84a49efa62a56e9aed2a345e01679dcccca;p=openvswitch diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index e0c54064..f72e1876 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -23,6 +23,7 @@ #include #include "bitmap.h" +#include "dynamic-string.h" #include "json.h" #include "jsonrpc.h" #include "ovsdb-data.h" @@ -79,6 +80,8 @@ struct ovsdb_idl_txn { struct ovsdb_idl *idl; struct hmap txn_rows; enum ovsdb_idl_txn_status status; + bool dry_run; + struct ds comment; }; static struct vlog_rate_limit syntax_rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -791,13 +794,34 @@ ovsdb_idl_txn_create(struct ovsdb_idl *idl) txn->idl = idl; txn->status = TXN_INCOMPLETE; hmap_init(&txn->txn_rows); + txn->dry_run = false; + ds_init(&txn->comment); return txn; } +void +ovsdb_idl_txn_add_comment(struct ovsdb_idl_txn *txn, const char *s) +{ + if (txn->comment.length) { + ds_put_char(&txn->comment, '\n'); + } + ds_put_cstr(&txn->comment, s); +} + +void +ovsdb_idl_txn_set_dry_run(struct ovsdb_idl_txn *txn) +{ + txn->dry_run = true; +} + void ovsdb_idl_txn_destroy(struct ovsdb_idl_txn *txn) { + if (txn->status == TXN_INCOMPLETE) { + hmap_remove(&txn->idl->outstanding_txns, &txn->hmap_node); + } ovsdb_idl_txn_abort(txn); + ds_destroy(&txn->comment); free(txn); } @@ -977,9 +1001,6 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn) any_updates = false; HMAP_FOR_EACH (row, struct ovsdb_idl_row, txn_node, &txn->txn_rows) { const struct ovsdb_idl_table_class *class = row->table->class; - size_t n_columns = class->n_columns; - struct json *row_json; - size_t idx; if (row->old == row->new) { continue; @@ -989,43 +1010,61 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn) json_object_put_string(op, "table", class->name); json_object_put(op, "where", where_uuid_equals(&row->uuid)); json_array_add(operations, op); + any_updates = true; } else { - row_json = NULL; - BITMAP_FOR_EACH_1 (idx, n_columns, row->written) { + struct json *row_json; + struct json *op; + size_t idx; + + op = json_object_create(); + json_object_put_string(op, "op", row->old ? "update" : "insert"); + json_object_put_string(op, "table", class->name); + if (row->old) { + json_object_put(op, "where", where_uuid_equals(&row->uuid)); + } else { + json_object_put(op, "uuid-name", + json_string_create_nocopy( + uuid_name_from_uuid(&row->uuid))); + } + row_json = json_object_create(); + json_object_put(op, "row", row_json); + + BITMAP_FOR_EACH_1 (idx, class->n_columns, row->written) { const struct ovsdb_idl_column *column = &class->columns[idx]; - if (row->old - && ovsdb_datum_equals(&row->old[idx], &row->new[idx], - &column->type)) { - continue; + if (!row->old || !ovsdb_datum_equals(&row->old[idx], + &row->new[idx], + &column->type)) { + json_object_put(row_json, column->name, + substitute_uuids( + ovsdb_datum_to_json(&row->new[idx], + &column->type), + txn)); } - if (!row_json) { - struct json *op = json_object_create(); - json_array_add(operations, op); - json_object_put_string(op, "op", - row->old ? "update" : "insert"); - json_object_put_string(op, "table", class->name); - if (row->old) { - json_object_put(op, "where", - where_uuid_equals(&row->uuid)); - } else { - json_object_put(op, "uuid-name", - json_string_create_nocopy( - uuid_name_from_uuid(&row->uuid))); - } - row_json = json_object_create(); - json_object_put(op, "row", row_json); - any_updates = true; - } - json_object_put(row_json, column->name, - substitute_uuids( - ovsdb_datum_to_json(&row->new[idx], - &column->type), - txn)); + } + + if (!row->old || !shash_is_empty(json_object(row_json))) { + json_array_add(operations, op); + any_updates = true; + } else { + json_destroy(op); } } } + if (txn->comment.length) { + struct json *op = json_object_create(); + json_object_put_string(op, "op", "comment"); + json_object_put_string(op, "comment", ds_cstr(&txn->comment)); + json_array_add(operations, op); + } + + if (txn->dry_run) { + struct json *op = json_object_create(); + json_object_put_string(op, "op", "abort"); + json_array_add(operations, op); + } + if (!any_updates) { txn->status = TXN_SUCCESS; } else if (!jsonrpc_session_send( @@ -1125,11 +1164,8 @@ ovsdb_idl_txn_delete(struct ovsdb_idl_row *row) hmap_insert(&row->table->idl->txn->txn_rows, &row->txn_node, uuid_hash(&row->uuid)); } - if (row->new == row->old) { - row->new = NULL; - } else { - ovsdb_idl_row_clear_new(row); - } + ovsdb_idl_row_clear_new(row); + row->new = NULL; } struct ovsdb_idl_row * @@ -1207,7 +1243,7 @@ ovsdb_idl_txn_process_reply(struct ovsdb_idl *idl, if (error->type == JSON_STRING) { if (!strcmp(error->u.string, "timed out")) { soft_errors++; - } else { + } else if (strcmp(error->u.string, "aborted")) { hard_errors++; } } else {