From 1b807595c4e6b4348444852bda8814e92412ad41 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 31 May 2011 12:50:57 -0700 Subject: [PATCH] ovsdb: Check ovsdb_mutation_set_execute() return value in transactions. Errors from this function were being ignored, which meant that transactions could use "mutate" to bypass number-of-elements constraints on sets and maps. This fixes the problem and adds a test to prevent the problem from recurring. Bug #5781. --- ovsdb/execution.c | 9 +++++---- ovsdb/mutation.h | 4 ++-- tests/ovsdb-execution.at | 10 +++++++++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/ovsdb/execution.c b/ovsdb/execution.c index 708cc60dd..ae1760731 100644 --- a/ovsdb/execution.c +++ b/ovsdb/execution.c @@ -451,6 +451,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 +460,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; } struct ovsdb_error * @@ -494,6 +494,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)); } diff --git a/ovsdb/mutation.h b/ovsdb/mutation.h index 57fd965af..86de6f246 100644 --- a/ovsdb/mutation.h +++ b/ovsdb/mutation.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010 Nicira Networks +/* Copyright (c) 2009, 2010, 2011 Nicira Networks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,6 +67,6 @@ struct ovsdb_error *ovsdb_mutation_set_from_json( struct json *ovsdb_mutation_set_to_json(const struct ovsdb_mutation_set *); void ovsdb_mutation_set_destroy(struct ovsdb_mutation_set *); struct ovsdb_error *ovsdb_mutation_set_execute( - struct ovsdb_row *, const struct ovsdb_mutation_set *); + struct ovsdb_row *, const struct ovsdb_mutation_set *) WARN_UNUSED_RESULT; #endif /* ovsdb/mutation.h */ diff --git a/tests/ovsdb-execution.at b/tests/ovsdb-execution.at index ebf118672..54ff0aeb2 100644 --- a/tests/ovsdb-execution.at +++ b/tests/ovsdb-execution.at @@ -26,7 +26,8 @@ m4_define([CONSTRAINT_SCHEMA], "b2a": {"type": {"key": {"type": "uuid", "refTable": "a"}, "min": 0, "max": "unlimited"}}, "b2b": {"type": {"key": {"type": "uuid", "refTable": "b"}, - "min": 0, "max": "unlimited"}}}}, + "min": 0, "max": "unlimited"}}, + "x": {"type": {"key": "integer", "min": 1, "max": 2}}}}, "constrained": { "columns": { "positive": {"type": {"key": {"type": "integer", @@ -575,6 +576,12 @@ OVSDB_CHECK_EXECUTION([referential integrity -- simple], {"op": "delete", "table": "b", "where": []}]]], +dnl Check that "mutate" honors number-of-elements constraints on sets and maps. + [[["constraints", + {"op": "mutate", + "table": "b", + "where": [], + "mutations": [["x", "delete", 0]]}]]], [[["constraints", {"op": "delete", "table": "a", @@ -601,6 +608,7 @@ OVSDB_CHECK_EXECUTION([referential integrity -- simple], "where": []}]]]], [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}] [{"count":1},{"details":"cannot delete b row <0> because of 3 remaining reference(s)","error":"referential integrity violation"}] +[{"details":"Attempted to store 0 elements in set of 1 to 2 integers.","error":"constraint violation"}] [{"count":1}] [{"count":1},{"details":"cannot delete b row <0> because of 2 remaining reference(s)","error":"referential integrity violation"}] [{"count":1}] -- 2.43.0