aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2011-05-31 12:50:57 -0700
committerBen Pfaff <blp@nicira.com>2011-05-31 13:46:00 -0700
commitb7585d1dffe140a0271ba52acb72493fe6f518a1 (patch)
tree89fffb6c39db7d62bf3f5ab9444720368b413794
parentdd089894cacbf11f0e9359f52ecd2923b627ba90 (diff)
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.
-rw-r--r--ovsdb/execution.c9
-rw-r--r--ovsdb/mutation.h4
-rw-r--r--tests/ovsdb-execution.at10
3 files changed, 16 insertions, 7 deletions
diff --git a/ovsdb/execution.c b/ovsdb/execution.c
index 176858240..cb1bec3ee 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;
}
static 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}]