X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ovsdb%2Fovsdb.c;h=2a54a7b908b8283fe96d3b323cdaf7b80b8b90b5;hb=822b56da1165488311e7a5460ed995cf0465b672;hp=45683766c1c937a4e24dcca013bdd2d61e443e1f;hpb=a0bc29a541fc7dc6e20137d5558e2094d614e6ab;p=openvswitch diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c index 45683766..2a54a7b9 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,12 +26,14 @@ #include "transaction.h" struct ovsdb_schema * -ovsdb_schema_create(const char *name) +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; @@ -43,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); + new = ovsdb_schema_create(old->name, old->version, old->cksum); SHASH_FOR_EACH (node, &old->tables) { const struct ovsdb_table_schema *ts = node->data; @@ -52,7 +54,6 @@ ovsdb_schema_clone(const struct ovsdb_schema *old) return new; } - void ovsdb_schema_destroy(struct ovsdb_schema *schema) { @@ -67,6 +68,8 @@ ovsdb_schema_destroy(struct ovsdb_schema *schema) } shash_destroy(&schema->tables); free(schema->name); + free(schema->version); + free(schema->cksum); free(schema); } @@ -116,26 +119,50 @@ ovsdb_schema_check_ref_table(const struct ovsdb_column *column, } } +static bool +is_valid_version(const char *s) +{ + int n = -1; + sscanf(s, "%*[0-9].%*[0-9].%*[0-9]%n", &n); + return n != -1 && s[n] == '\0'; +} + struct ovsdb_error * ovsdb_schema_from_json(struct json *json, struct ovsdb_schema **schemap) { struct ovsdb_schema *schema; - const struct json *name, *tables; + const struct json *name, *tables, *version_json, *cksum; struct ovsdb_error *error; struct shash_node *node; struct ovsdb_parser parser; + const char *version; *schemap = NULL; ovsdb_parser_init(&parser, json, "database schema"); name = ovsdb_parser_member(&parser, "name", OP_ID); + version_json = ovsdb_parser_member(&parser, "version", + 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) { return error; } - schema = ovsdb_schema_create(json_string(name)); + if (version_json) { + version = json_string(version_json); + if (!is_valid_version(version)) { + return ovsdb_syntax_error(json, NULL, "schema version \"%s\" not " + "in format x.y.z", version); + } + } else { + /* Backward compatibility with old databases. */ + 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; @@ -190,6 +217,12 @@ ovsdb_schema_to_json(const struct ovsdb_schema *schema) 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); + } tables = json_object_create(); @@ -202,6 +235,23 @@ ovsdb_schema_to_json(const struct ovsdb_schema *schema) 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,