X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ovsdb%2Fovsdb-tool.c;h=1c9e9206a154afb130e976c0fa6e10c71b7d4d60;hb=79c9f2ee7883b52860c76c3730725f5731402874;hp=d506aae334dc56a11f5ca66cb22c78b83b318ebc;hpb=c6782bb0f7c6cf7b09efe1b94d6bf40f89fe7ed6;p=openvswitch diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c index d506aae3..1c9e9206 100644 --- a/ovsdb/ovsdb-tool.c +++ b/ovsdb/ovsdb-tool.c @@ -25,10 +25,12 @@ #include "command-line.h" #include "compiler.h" #include "file.h" +#include "lockfile.h" #include "log.h" #include "json.h" #include "ovsdb.h" #include "ovsdb-error.h" +#include "socket-util.h" #include "table.h" #include "timeval.h" #include "util.h" @@ -109,6 +111,7 @@ usage(void) "usage: %s [OPTIONS] COMMAND [ARG...]\n" " create DB SCHEMA create DB with the given SCHEMA\n" " compact DB [DST] compact DB in-place (or to DST)\n" + " convert DB SCHEMA [DST] convert DB to SCHEMA (to DST)\n" " extract-schema DB print DB's schema on stdout\n" " query DB TRNS execute read-only transaction on DB\n" " transact DB TRNS execute read/write transaction on DB\n" @@ -150,7 +153,7 @@ check_ovsdb_error(struct ovsdb_error *error) } static void -do_create(int argc UNUSED, char *argv[]) +do_create(int argc OVS_UNUSED, char *argv[]) { const char *db_file_name = argv[1]; const char *schema_file_name = argv[2]; @@ -161,10 +164,11 @@ do_create(int argc UNUSED, char *argv[]) /* Read schema from file and convert to JSON. */ check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema)); json = ovsdb_schema_to_json(schema); + ovsdb_schema_destroy(schema); /* Create database file. */ - check_ovsdb_error(ovsdb_log_open(db_file_name, O_RDWR | O_CREAT | O_EXCL, - &log)); + check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_LOG_CREATE, + -1, &log)); check_ovsdb_error(ovsdb_log_write(log, json)); check_ovsdb_error(ovsdb_log_commit(log)); ovsdb_log_close(log); @@ -172,13 +176,79 @@ do_create(int argc UNUSED, char *argv[]) json_destroy(json); } +static void +compact_or_convert(const char *src_name, const char *dst_name, + const struct ovsdb_schema *new_schema, + const char *comment) +{ + struct lockfile *src_lock; + struct lockfile *dst_lock; + bool in_place = dst_name == NULL; + struct ovsdb *db; + int retval; + + /* Lock the source, if we will be replacing it. */ + if (in_place) { + retval = lockfile_lock(src_name, INT_MAX, &src_lock); + if (retval) { + ovs_fatal(retval, "%s: failed to lock lockfile", src_name); + } + } + + /* Get (temporary) destination and lock it. */ + if (in_place) { + dst_name = xasprintf("%s.tmp", src_name); + } + retval = lockfile_lock(dst_name, INT_MAX, &dst_lock); + if (retval) { + ovs_fatal(retval, "%s: failed to lock lockfile", dst_name); + } + + /* Save a copy. */ + check_ovsdb_error(new_schema + ? ovsdb_file_open_as_schema(src_name, new_schema, &db) + : ovsdb_file_open(src_name, true, &db, NULL)); + check_ovsdb_error(ovsdb_file_save_copy(dst_name, false, comment, db)); + ovsdb_destroy(db); + + /* Replace source. */ + if (in_place) { + if (rename(dst_name, src_name)) { + ovs_fatal(errno, "failed to rename \"%s\" to \"%s\"", + dst_name, src_name); + } + fsync_parent_dir(dst_name); + lockfile_unlock(src_lock); + } + + lockfile_unlock(dst_lock); +} + +static void +do_compact(int argc OVS_UNUSED, char *argv[]) +{ + compact_or_convert(argv[1], argv[2], NULL, "compacted by ovsdb-tool"); +} + +static void +do_convert(int argc OVS_UNUSED, char *argv[]) +{ + const char *schema_file_name = argv[2]; + struct ovsdb_schema *new_schema; + + check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &new_schema)); + compact_or_convert(argv[1], argv[3], new_schema, + "converted by ovsdb-tool"); + ovsdb_schema_destroy(new_schema); +} + static void transact(bool read_only, const char *db_file_name, const char *transaction) { struct json *request, *result; struct ovsdb *db; - check_ovsdb_error(ovsdb_file_open(db_file_name, read_only, &db)); + check_ovsdb_error(ovsdb_file_open(db_file_name, read_only, &db, NULL)); request = parse_json(transaction); result = ovsdb_execute(db, request, 0, NULL); @@ -189,13 +259,13 @@ transact(bool read_only, const char *db_file_name, const char *transaction) } static void -do_query(int argc UNUSED, char *argv[]) +do_query(int argc OVS_UNUSED, char *argv[]) { transact(true, argv[1], argv[2]); } static void -do_transact(int argc UNUSED, char *argv[]) +do_transact(int argc OVS_UNUSED, char *argv[]) { transact(false, argv[1], argv[2]); } @@ -267,8 +337,13 @@ print_db_changes(struct shash *tables, struct shash *names) : xmemdup0(row_uuid, 8))); } } else if (columns->type == JSON_NULL) { + struct shash_node *node; + printf("\t\tdelete row\n"); - shash_delete(names, shash_find(names, row_uuid)); + node = shash_find(names, row_uuid); + if (node) { + shash_delete(names, node); + } free(old_name); } @@ -280,14 +355,15 @@ print_db_changes(struct shash *tables, struct shash *names) } static void -do_show_log(int argc UNUSED, char *argv[]) +do_show_log(int argc OVS_UNUSED, char *argv[]) { const char *db_file_name = argv[1]; struct shash names; struct ovsdb_log *log; unsigned int i; - check_ovsdb_error(ovsdb_log_open(db_file_name, O_RDONLY, &log)); + check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_LOG_READ_ONLY, + -1, &log)); shash_init(&names); for (i = 0; ; i++) { struct json *json; @@ -328,13 +404,15 @@ do_show_log(int argc UNUSED, char *argv[]) } static void -do_help(int argc UNUSED, char *argv[] UNUSED) +do_help(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { usage(); } static const struct command all_commands[] = { { "create", 2, 2, do_create }, + { "compact", 1, 2, do_compact }, + { "convert", 2, 3, do_convert }, { "query", 2, 2, do_query }, { "transact", 2, 2, do_transact }, { "show-log", 1, 1, do_show_log },