mirror of
https://github.com/openvswitch/ovs
synced 2025-10-17 14:28:02 +00:00
ovsdb: Implement new "declare" operation.
This commit is contained in:
@@ -219,13 +219,13 @@ ovsdb_atom_parse_uuid(struct uuid *uuid, const struct json *json,
|
||||
error1 = unwrap_json(json, "named-uuid", JSON_STRING, &value);
|
||||
if (!error1) {
|
||||
const char *name = json_string(value);
|
||||
const struct uuid *named_uuid;
|
||||
const struct ovsdb_symbol *symbol;
|
||||
|
||||
ovsdb_error_destroy(error0);
|
||||
|
||||
named_uuid = ovsdb_symbol_table_get(symtab, name);
|
||||
if (named_uuid) {
|
||||
*uuid = *named_uuid;
|
||||
symbol = ovsdb_symbol_table_get(symtab, name);
|
||||
if (symbol) {
|
||||
*uuid = symbol->uuid;
|
||||
return NULL;
|
||||
} else {
|
||||
return ovsdb_syntax_error(json, NULL,
|
||||
@@ -728,7 +728,8 @@ ovsdb_symbol_table_destroy(struct ovsdb_symbol_table *symtab)
|
||||
struct shash_node *node, *next;
|
||||
|
||||
SHASH_FOR_EACH_SAFE (node, next, &symtab->sh) {
|
||||
free(node->data);
|
||||
struct ovsdb_symbol *symbol = node->data;
|
||||
free(symbol);
|
||||
shash_delete(&symtab->sh, node);
|
||||
}
|
||||
shash_destroy(&symtab->sh);
|
||||
@@ -736,7 +737,7 @@ ovsdb_symbol_table_destroy(struct ovsdb_symbol_table *symtab)
|
||||
}
|
||||
}
|
||||
|
||||
const struct uuid *
|
||||
struct ovsdb_symbol *
|
||||
ovsdb_symbol_table_get(const struct ovsdb_symbol_table *symtab,
|
||||
const char *name)
|
||||
{
|
||||
@@ -745,12 +746,13 @@ ovsdb_symbol_table_get(const struct ovsdb_symbol_table *symtab,
|
||||
|
||||
void
|
||||
ovsdb_symbol_table_put(struct ovsdb_symbol_table *symtab, const char *name,
|
||||
const struct uuid *uuid)
|
||||
const struct uuid *uuid, bool used)
|
||||
{
|
||||
struct uuid *entry = shash_find_data(&symtab->sh, name);
|
||||
if (!entry) {
|
||||
shash_add(&symtab->sh, name, xmemdup(uuid, sizeof *uuid));
|
||||
} else {
|
||||
*entry = *uuid;
|
||||
}
|
||||
struct ovsdb_symbol *symbol;
|
||||
|
||||
assert(!ovsdb_symbol_table_get(symtab, name));
|
||||
symbol = xmalloc(sizeof *symbol);
|
||||
symbol->uuid = *uuid;
|
||||
symbol->used = used;
|
||||
shash_add(&symtab->sh, name, symbol);
|
||||
}
|
||||
|
@@ -118,11 +118,16 @@ ovsdb_datum_conforms_to_type(const struct ovsdb_datum *datum,
|
||||
/* A table mapping from names to data items. Currently the data items are
|
||||
* always UUIDs; perhaps this will be expanded in the future. */
|
||||
|
||||
struct ovsdb_symbol {
|
||||
struct uuid uuid; /* The UUID that the symbol represents. */
|
||||
bool used; /* Already used as row UUID? */
|
||||
};
|
||||
|
||||
struct ovsdb_symbol_table *ovsdb_symbol_table_create(void);
|
||||
void ovsdb_symbol_table_destroy(struct ovsdb_symbol_table *);
|
||||
const struct uuid *ovsdb_symbol_table_get(const struct ovsdb_symbol_table *,
|
||||
const char *name);
|
||||
struct ovsdb_symbol *ovsdb_symbol_table_get(const struct ovsdb_symbol_table *,
|
||||
const char *name);
|
||||
void ovsdb_symbol_table_put(struct ovsdb_symbol_table *, const char *name,
|
||||
const struct uuid *);
|
||||
const struct uuid *, bool used);
|
||||
|
||||
#endif /* ovsdb-data.h */
|
||||
|
65
ovsdb/SPECS
65
ovsdb/SPECS
@@ -599,7 +599,7 @@ Request object members:
|
||||
"op": "insert" required
|
||||
"table": <table> required
|
||||
"row": <row> required
|
||||
"uuid-name": <string> optional
|
||||
"uuid-name": <id> optional
|
||||
|
||||
Result object members:
|
||||
|
||||
@@ -611,10 +611,31 @@ Semantics:
|
||||
for all the columns in "table", those columns receive default
|
||||
values.
|
||||
|
||||
The new row receives a new, randomly generated UUID, which is
|
||||
returned as the "uuid" member of the result. If "uuid-name" is
|
||||
supplied, then the UUID is made available under that name to this
|
||||
operation and later operations within the same transaction.
|
||||
If "uuid-name" is not supplied, the new row receives a new,
|
||||
randomly generated UUID.
|
||||
|
||||
If "uuid-name" is supplied, then it is an error if <id> has
|
||||
previously appeared as the "uuid-name" in an "insert" operation.
|
||||
|
||||
If "uuid-name" is supplied and its <id> previously appeared as the
|
||||
"uuid-name" in a "declare" operation, then the new row receives
|
||||
the UUID associated with that "uuid-name".
|
||||
|
||||
If "uuid-name" is supplied and its <id> has not previously
|
||||
appeared as the "uuid-name" in a "declare" operation, then the new
|
||||
row also receives a new, randomly generated UUID. This UUID is
|
||||
also made available under that name to this operation and later
|
||||
operations within the same transaction.
|
||||
|
||||
The UUID for the new row is returned as the "uuid" member of the
|
||||
result.
|
||||
|
||||
Errors:
|
||||
|
||||
"error": "duplicate uuid-name"
|
||||
|
||||
The same "uuid-name" appeared on an earlier "insert" operation
|
||||
within this transaction.
|
||||
|
||||
select
|
||||
......
|
||||
@@ -797,3 +818,37 @@ Errors:
|
||||
"error": "aborted"
|
||||
|
||||
This operation always fails with this error.
|
||||
|
||||
declare
|
||||
.......
|
||||
|
||||
Request object members:
|
||||
|
||||
"op": "declare" required
|
||||
"uuid-name": <id> required
|
||||
|
||||
Result object members:
|
||||
|
||||
none
|
||||
|
||||
Semantics:
|
||||
|
||||
Predeclares a UUID named <id> that may be referenced in later
|
||||
operations as ["named-uuid", <id>] or (at most once) in an
|
||||
"insert" operation as "uuid-name".
|
||||
|
||||
It is an error if <id> has appeared as the "uuid-name" in a prior
|
||||
"insert" or "declare" operation within this transaction.
|
||||
|
||||
The generated UUID is returned as the "uuid" member of the result.
|
||||
|
||||
Result object members:
|
||||
|
||||
"uuid": <uuid>
|
||||
|
||||
Errors:
|
||||
|
||||
"error": "duplicate uuid-name"
|
||||
|
||||
The same "uuid-name" appeared on an earlier "insert" or
|
||||
"declare" operation within this transaction.
|
||||
|
@@ -54,6 +54,7 @@ static ovsdb_operation_executor ovsdb_execute_delete;
|
||||
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_declare;
|
||||
|
||||
static ovsdb_operation_executor *
|
||||
lookup_executor(const char *name)
|
||||
@@ -71,6 +72,7 @@ lookup_executor(const char *name)
|
||||
{ "wait", ovsdb_execute_wait },
|
||||
{ "commit", ovsdb_execute_commit },
|
||||
{ "abort", ovsdb_execute_abort },
|
||||
{ "declare", ovsdb_execute_declare },
|
||||
};
|
||||
|
||||
size_t i;
|
||||
@@ -272,9 +274,25 @@ ovsdb_execute_insert(struct ovsdb_execution *x, struct ovsdb_parser *parser,
|
||||
uuid_name = ovsdb_parser_member(parser, "uuid-name", OP_ID | OP_OPTIONAL);
|
||||
error = ovsdb_parser_get_error(parser);
|
||||
|
||||
uuid_generate(&row_uuid);
|
||||
if (uuid_name) {
|
||||
ovsdb_symbol_table_put(x->symtab, json_string(uuid_name), &row_uuid);
|
||||
struct ovsdb_symbol *symbol;
|
||||
|
||||
symbol = ovsdb_symbol_table_get(x->symtab, json_string(uuid_name));
|
||||
if (symbol) {
|
||||
if (symbol->used) {
|
||||
return ovsdb_syntax_error(uuid_name, "duplicate uuid-name",
|
||||
"This \"uuid-name\" appeared on an "
|
||||
"earlier \"insert\" operation.");
|
||||
}
|
||||
row_uuid = symbol->uuid;
|
||||
symbol->used = true;
|
||||
} else {
|
||||
uuid_generate(&row_uuid);
|
||||
ovsdb_symbol_table_put(x->symtab, json_string(uuid_name),
|
||||
&row_uuid, true);
|
||||
}
|
||||
} else {
|
||||
uuid_generate(&row_uuid);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
@@ -580,3 +598,29 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser,
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct ovsdb_error *
|
||||
ovsdb_execute_declare(struct ovsdb_execution *x, struct ovsdb_parser *parser,
|
||||
struct json *result)
|
||||
{
|
||||
const struct json *uuid_name;
|
||||
struct uuid uuid;
|
||||
|
||||
uuid_name = ovsdb_parser_member(parser, "uuid-name", OP_ID);
|
||||
if (!uuid_name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ovsdb_symbol_table_get(x->symtab, json_string(uuid_name))) {
|
||||
return ovsdb_syntax_error(uuid_name, "duplicate uuid-name",
|
||||
"This \"uuid-name\" appeared on an "
|
||||
"earlier \"declare\" or \"insert\" "
|
||||
"operation.");
|
||||
}
|
||||
|
||||
uuid_generate(&uuid);
|
||||
ovsdb_symbol_table_put(x->symtab, json_string(uuid_name), &uuid, false);
|
||||
json_object_put(result, "uuid", json_string_create_nocopy(
|
||||
xasprintf(UUID_FMT, UUID_ARGS(&uuid))));
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -143,18 +143,18 @@ OVSDB_CHECK_IDL([self-linking idl, consistent ops],
|
||||
"table": "link1",
|
||||
"row": {"i": 0, "k": ["named-uuid", "self"]},
|
||||
"uuid-name": "self"}]' \
|
||||
'[{"op": "insert",
|
||||
'[{"op": "declare",
|
||||
"uuid-name": "row1"},
|
||||
{"op": "declare",
|
||||
"uuid-name": "row2"},
|
||||
{"op": "insert",
|
||||
"table": "link1",
|
||||
"row": {"i": 1},
|
||||
"row": {"i": 1, "k": ["named-uuid", "row2"]},
|
||||
"uuid-name": "row1"},
|
||||
{"op": "insert",
|
||||
"table": "link1",
|
||||
"row": {"i": 2, "k": ["named-uuid", "row1"]},
|
||||
"uuid-name": "row2"},
|
||||
{"op": "update",
|
||||
"table": "link1",
|
||||
"where": [["i", "==", 1]],
|
||||
"row": {"k": ["named-uuid", "row2"]}}]' \
|
||||
"uuid-name": "row2"}]' \
|
||||
'[{"op": "update",
|
||||
"table": "link1",
|
||||
"where": [["i", "==", 1]],
|
||||
@@ -166,7 +166,7 @@ OVSDB_CHECK_IDL([self-linking idl, consistent ops],
|
||||
[[000: empty
|
||||
001: {"error":null,"result":[{"uuid":["uuid","<0>"]}]}
|
||||
002: i=0 k=0 ka=[] l2= uuid=<0>
|
||||
003: {"error":null,"result":[{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"count":1}]}
|
||||
003: {"error":null,"result":[{"uuid":"<1>"},{"uuid":"<2>"},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]}]}
|
||||
004: i=0 k=0 ka=[] l2= uuid=<0>
|
||||
004: i=1 k=2 ka=[] l2= uuid=<1>
|
||||
004: i=2 k=1 ka=[] l2= uuid=<2>
|
||||
|
@@ -1346,7 +1346,8 @@ parse_uuids(const struct json *json, struct ovsdb_symbol_table *symtab,
|
||||
|
||||
if (json->type == JSON_STRING && uuid_from_string(&uuid, json->u.string)) {
|
||||
char *name = xasprintf("#%d#", *n);
|
||||
ovsdb_symbol_table_put(symtab, name, &uuid);
|
||||
fprintf(stderr, "%s = "UUID_FMT"\n", name, UUID_ARGS(&uuid));
|
||||
ovsdb_symbol_table_put(symtab, name, &uuid, false);
|
||||
free(name);
|
||||
*n += 1;
|
||||
} else if (json->type == JSON_ARRAY) {
|
||||
@@ -1368,12 +1369,12 @@ static void
|
||||
substitute_uuids(struct json *json, const struct ovsdb_symbol_table *symtab)
|
||||
{
|
||||
if (json->type == JSON_STRING) {
|
||||
const struct uuid *uuid;
|
||||
const struct ovsdb_symbol *symbol;
|
||||
|
||||
uuid = ovsdb_symbol_table_get(symtab, json->u.string);
|
||||
if (uuid) {
|
||||
symbol = ovsdb_symbol_table_get(symtab, json->u.string);
|
||||
if (symbol) {
|
||||
free(json->u.string);
|
||||
json->u.string = xasprintf(UUID_FMT, UUID_ARGS(uuid));
|
||||
json->u.string = xasprintf(UUID_FMT, UUID_ARGS(&symbol->uuid));
|
||||
}
|
||||
} else if (json->type == JSON_ARRAY) {
|
||||
size_t i;
|
||||
|
Reference in New Issue
Block a user