X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ovsdb%2Fexecution.c;h=de25a8797770f2ddf4cf54cfa63cb52b44b287bb;hb=968eec593cc61690c9e0ed97450c4889258381af;hp=176858240c87f1f294d03a3226155ceaf9d6bd9e;hpb=b2fda3effc787f265b5ad5dfa967ac00627bd075;p=cascardo%2Fovs.git diff --git a/ovsdb/execution.c b/ovsdb/execution.c index 176858240..de25a8797 100644 --- a/ovsdb/execution.c +++ b/ovsdb/execution.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, 2011 Nicira Networks +/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ #include -#include #include #include "column.h" @@ -29,12 +28,14 @@ #include "ovsdb.h" #include "query.h" #include "row.h" +#include "server.h" #include "table.h" #include "timeval.h" #include "transaction.h" struct ovsdb_execution { struct ovsdb *db; + const struct ovsdb_session *session; struct ovsdb_txn *txn; struct ovsdb_symbol_table *symtab; bool durable; @@ -57,6 +58,7 @@ static ovsdb_operation_executor ovsdb_execute_wait; static ovsdb_operation_executor ovsdb_execute_commit; static ovsdb_operation_executor ovsdb_execute_abort; static ovsdb_operation_executor ovsdb_execute_comment; +static ovsdb_operation_executor ovsdb_execute_assert; static ovsdb_operation_executor * lookup_executor(const char *name) @@ -76,6 +78,7 @@ lookup_executor(const char *name) { "commit", ovsdb_execute_commit }, { "abort", ovsdb_execute_abort }, { "comment", ovsdb_execute_comment }, + { "assert", ovsdb_execute_assert }, }; size_t i; @@ -90,7 +93,8 @@ lookup_executor(const char *name) } struct json * -ovsdb_execute(struct ovsdb *db, const struct json *params, +ovsdb_execute(struct ovsdb *db, const struct ovsdb_session *session, + const struct json *params, long long int elapsed_msec, long long int *timeout_msec) { struct ovsdb_execution x; @@ -116,6 +120,7 @@ ovsdb_execute(struct ovsdb *db, const struct json *params, } x.db = db; + x.session = session; x.txn = ovsdb_txn_create(db); x.symtab = ovsdb_symbol_table_create(); x.durable = false; @@ -135,7 +140,7 @@ ovsdb_execute(struct ovsdb *db, const struct json *params, /* Parse and execute operation. */ ovsdb_parser_init(&parser, operation, - "ovsdb operation %zu of %zu", i, n_operations); + "ovsdb operation %"PRIuSIZE" of %"PRIuSIZE, i, n_operations); op = ovsdb_parser_member(&parser, "op", OP_ID); result = json_object_create(); if (op) { @@ -148,7 +153,7 @@ ovsdb_execute(struct ovsdb *db, const struct json *params, op_name); } } else { - assert(ovsdb_parser_has_error(&parser)); + ovs_assert(ovsdb_parser_has_error(&parser)); } /* A parse error overrides any other error. @@ -242,7 +247,7 @@ parse_table(struct ovsdb_execution *x, return table; } -static WARN_UNUSED_RESULT struct ovsdb_error * +static OVS_WARN_UNUSED_RESULT struct ovsdb_error * parse_row(const struct json *json, const struct ovsdb_table *table, struct ovsdb_symbol_table *symtab, struct ovsdb_row **rowp, struct ovsdb_column_set *columns) @@ -364,10 +369,11 @@ ovsdb_execute_select(struct ovsdb_execution *x, struct ovsdb_parser *parser, &condition); } if (!error) { - error = ovsdb_column_set_from_json(columns_json, table, &columns); + error = ovsdb_column_set_from_json(columns_json, table->schema, + &columns); } if (!error) { - error = ovsdb_column_set_from_json(sort_json, table, &sort); + error = ovsdb_column_set_from_json(sort_json, table->schema, &sort); } if (!error) { struct ovsdb_row_set rows = OVSDB_ROW_SET_INITIALIZER; @@ -427,6 +433,22 @@ ovsdb_execute_update(struct ovsdb_execution *x, struct ovsdb_parser *parser, if (!error) { error = parse_row(row_json, table, x->symtab, &row, &columns); } + if (!error) { + size_t i; + + for (i = 0; i < columns.n_columns; i++) { + const struct ovsdb_column *column = columns.columns[i]; + + if (!column->mutable) { + error = ovsdb_syntax_error(parser->json, + "constraint violation", + "Cannot update immutable column %s " + "in table %s.", + column->name, table->schema->name); + break; + } + } + } if (!error) { error = ovsdb_condition_from_json(table->schema, where, x->symtab, &condition); @@ -451,6 +473,7 @@ struct mutate_row_cbdata { size_t n_matches; struct ovsdb_txn *txn; const struct ovsdb_mutation_set *mutations; + struct ovsdb_error **error; }; static bool @@ -459,10 +482,9 @@ mutate_row_cb(const struct ovsdb_row *row, void *mr_) struct mutate_row_cbdata *mr = mr_; mr->n_matches++; - ovsdb_mutation_set_execute(ovsdb_txn_row_modify(mr->txn, row), - mr->mutations); - - return true; + *mr->error = ovsdb_mutation_set_execute(ovsdb_txn_row_modify(mr->txn, row), + mr->mutations); + return *mr->error == NULL; } static struct ovsdb_error * @@ -494,6 +516,7 @@ ovsdb_execute_mutate(struct ovsdb_execution *x, struct ovsdb_parser *parser, mr.n_matches = 0; mr.txn = x->txn; mr.mutations = &mutations; + mr.error = &error; ovsdb_query(table, &condition, mutate_row_cb, &mr); json_object_put(result, "count", json_integer_create(mr.n_matches)); } @@ -605,7 +628,8 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser, &condition); } if (!error) { - error = ovsdb_column_set_from_json(columns_json, table, &columns); + error = ovsdb_column_set_from_json(columns_json, table->schema, + &columns); } if (!error) { if (timeout) { @@ -619,6 +643,8 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser, } else { timeout_msec = LLONG_MAX; } + } + if (!error) { if (strcmp(json_string(until), "==") && strcmp(json_string(until), "!=")) { error = ovsdb_syntax_error(until, NULL, @@ -635,6 +661,7 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser, error = ovsdb_row_from_json(row, rows->u.array.elems[i], x->symtab, NULL); if (error) { + ovsdb_row_destroy(row); break; } @@ -703,3 +730,28 @@ ovsdb_execute_comment(struct ovsdb_execution *x, struct ovsdb_parser *parser, return NULL; } + +static struct ovsdb_error * +ovsdb_execute_assert(struct ovsdb_execution *x, struct ovsdb_parser *parser, + struct json *result OVS_UNUSED) +{ + const struct json *lock_name; + + lock_name = ovsdb_parser_member(parser, "lock", OP_ID); + if (!lock_name) { + return NULL; + } + + if (x->session) { + const struct ovsdb_lock_waiter *waiter; + + waiter = ovsdb_session_get_lock_waiter(x->session, + json_string(lock_name)); + if (waiter && ovsdb_lock_waiter_is_owner(waiter)) { + return NULL; + } + } + + return ovsdb_error("not owner", "Asserted lock %s not held.", + json_string(lock_name)); +}