X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ovsdb%2Fovsdb.c;h=d4a27d40ea3491c87305aa4e1892f29527895951;hb=933369b1194bce82bffa8cc1ccfdf82782cc5cde;hp=b767d386793fba5c9779170bcf0c01b0f5be6b7c;hpb=8159b984dced44851670bd48e204b4e854941a24;p=openvswitch diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c index b767d386..d4a27d40 100644 --- a/ovsdb/ovsdb.c +++ b/ovsdb/ovsdb.c @@ -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. @@ -26,13 +26,14 @@ #include "transaction.h" struct ovsdb_schema * -ovsdb_schema_create(const char *name, const char *version) +ovsdb_schema_create(const char *name, const char *version, const char *cksum) { struct ovsdb_schema *schema; schema = xzalloc(sizeof *schema); schema->name = xstrdup(name); schema->version = xstrdup(version); + schema->cksum = xstrdup(cksum); shash_init(&schema->tables); return schema; @@ -44,7 +45,7 @@ ovsdb_schema_clone(const struct ovsdb_schema *old) struct ovsdb_schema *new; struct shash_node *node; - new = ovsdb_schema_create(old->name, old->version); + new = ovsdb_schema_create(old->name, old->version, old->cksum); SHASH_FOR_EACH (node, &old->tables) { const struct ovsdb_table_schema *ts = node->data; @@ -68,6 +69,7 @@ ovsdb_schema_destroy(struct ovsdb_schema *schema) shash_destroy(&schema->tables); free(schema->name); free(schema->version); + free(schema->cksum); free(schema); } @@ -121,15 +123,30 @@ static bool is_valid_version(const char *s) { int n = -1; - sscanf(s, "%*[0-9].%*[0-9].%*[0-9]%n", &n); + ignore(sscanf(s, "%*[0-9].%*[0-9].%*[0-9]%n", &n)); return n != -1 && s[n] == '\0'; } +/* Returns the number of tables in 'schema''s root set. */ +static size_t +root_set_size(const struct ovsdb_schema *schema) +{ + struct shash_node *node; + size_t n_root = 0; + + SHASH_FOR_EACH (node, &schema->tables) { + struct ovsdb_table_schema *table = node->data; + + n_root += table->is_root; + } + return n_root; +} + struct ovsdb_error * ovsdb_schema_from_json(struct json *json, struct ovsdb_schema **schemap) { struct ovsdb_schema *schema; - const struct json *name, *tables, *version_json; + const struct json *name, *tables, *version_json, *cksum; struct ovsdb_error *error; struct shash_node *node; struct ovsdb_parser parser; @@ -141,7 +158,7 @@ ovsdb_schema_from_json(struct json *json, struct ovsdb_schema **schemap) name = ovsdb_parser_member(&parser, "name", OP_ID); version_json = ovsdb_parser_member(&parser, "version", OP_STRING | OP_OPTIONAL); - ovsdb_parser_member(&parser, "cksum", OP_STRING | OP_OPTIONAL); + cksum = ovsdb_parser_member(&parser, "cksum", OP_STRING | OP_OPTIONAL); tables = ovsdb_parser_member(&parser, "tables", OP_OBJECT); error = ovsdb_parser_finish(&parser); if (error) { @@ -159,7 +176,8 @@ ovsdb_schema_from_json(struct json *json, struct ovsdb_schema **schemap) version = ""; } - schema = ovsdb_schema_create(json_string(name), version); + schema = ovsdb_schema_create(json_string(name), version, + cksum ? json_string(cksum) : ""); SHASH_FOR_EACH (node, json_object(tables)) { struct ovsdb_table_schema *table; @@ -202,6 +220,18 @@ ovsdb_schema_from_json(struct json *json, struct ovsdb_schema **schemap) } } + /* "isRoot" was not part of the original schema definition. Before it was + * added, there was no support for garbage collection. So, for backward + * compatibility, if the root set is empty then assume that every table is + * in the root set. */ + if (root_set_size(schema) == 0) { + SHASH_FOR_EACH (node, &schema->tables) { + struct ovsdb_table_schema *table = node->data; + + table->is_root = true; + } + } + *schemap = schema; return 0; } @@ -211,24 +241,51 @@ ovsdb_schema_to_json(const struct ovsdb_schema *schema) { struct json *json, *tables; struct shash_node *node; + bool default_is_root; json = json_object_create(); json_object_put_string(json, "name", schema->name); if (schema->version[0]) { json_object_put_string(json, "version", schema->version); } + if (schema->cksum[0]) { + json_object_put_string(json, "cksum", schema->cksum); + } + + /* "isRoot" was not part of the original schema definition. Before it was + * added, there was no support for garbage collection. So, for backward + * compatibility, if every table is in the root set then do not output + * "isRoot" in table schemas. */ + default_is_root = root_set_size(schema) == shash_count(&schema->tables); tables = json_object_create(); SHASH_FOR_EACH (node, &schema->tables) { struct ovsdb_table_schema *table = node->data; json_object_put(tables, table->name, - ovsdb_table_schema_to_json(table)); + ovsdb_table_schema_to_json(table, default_is_root)); } json_object_put(json, "tables", tables); return json; } + +/* Returns true if 'a' and 'b' specify equivalent schemas, false if they + * differ. */ +bool +ovsdb_schema_equal(const struct ovsdb_schema *a, + const struct ovsdb_schema *b) +{ + /* This implementation is simple, stupid, and slow, but I doubt that it + * will ever require much maintenance. */ + struct json *ja = ovsdb_schema_to_json(a); + struct json *jb = ovsdb_schema_to_json(b); + bool equals = json_equal(ja, jb); + json_destroy(ja); + json_destroy(jb); + + return equals; +} static void ovsdb_set_ref_table(const struct shash *tables,