Setting tag sliver-openvswitch-2.2.90-1
[sliver-openvswitch.git] / ovsdb / ovsdb-server.c
index 912f599..a85a672 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
 #include <getopt.h>
 #include <inttypes.h>
 #include <signal.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include "column.h"
@@ -27,6 +28,7 @@
 #include "dirs.h"
 #include "dummy.h"
 #include "dynamic-string.h"
+#include "fatal-signal.h"
 #include "file.h"
 #include "hash.h"
 #include "json.h"
@@ -45,7 +47,6 @@
 #include "shash.h"
 #include "stream-ssl.h"
 #include "stream.h"
-#include "stress.h"
 #include "sset.h"
 #include "table.h"
 #include "timeval.h"
@@ -137,8 +138,8 @@ main(int argc, char *argv[])
 
     proctitle_init(argc, argv);
     set_program_name(argv[0]);
-    stress_init_command();
-    signal(SIGPIPE, SIG_IGN);
+    service_start(&argc, &argv);
+    fatal_ignore_sigpipe();
     process_init();
 
     parse_options(&argc, &argv, &remotes, &unixctl_path, &run_command);
@@ -304,6 +305,9 @@ main(int argc, char *argv[])
         }
         poll_timer_wait_until(status_timer);
         poll_block();
+        if (should_service_stop()) {
+            exiting = true;
+        }
     }
     ovsdb_jsonrpc_server_destroy(jsonrpc);
     SHASH_FOR_EACH(node, &all_dbs) {
@@ -321,9 +325,40 @@ main(int argc, char *argv[])
         }
     }
 
+    service_stop();
     return 0;
 }
 
+/* Returns true if 'filename' is known to be already open as a database,
+ * false if not.
+ *
+ * "False negatives" are possible. */
+static bool
+is_already_open(struct server_config *config OVS_UNUSED,
+                const char *filename OVS_UNUSED)
+{
+#ifndef _WIN32
+    struct stat s;
+
+    if (!stat(filename, &s)) {
+        struct shash_node *node;
+
+        SHASH_FOR_EACH (node, config->all_dbs) {
+            struct db *db = node->data;
+            struct stat s2;
+
+            if (!stat(db->filename, &s2)
+                && s.st_dev == s2.st_dev
+                && s.st_ino == s2.st_ino) {
+                return true;
+            }
+        }
+    }
+#endif  /* !_WIN32 */
+
+    return false;
+}
+
 static char *
 open_db(struct server_config *config, const char *filename)
 {
@@ -331,6 +366,13 @@ open_db(struct server_config *config, const char *filename)
     struct db *db;
     char *error;
 
+    /* If we know that the file is already open, return a good error message.
+     * Otherwise, if the file is open, we'll fail later on with a harder to
+     * interpret file locking error. */
+    if (is_already_open(config, filename)) {
+        return xasprintf("%s: already open", filename);
+    }
+
     db = xzalloc(sizeof *db);
     db->filename = xstrdup(filename);
 
@@ -532,7 +574,7 @@ get_datum(struct ovsdb_row *row, const char *column_name,
         if (!VLOG_DROP_DBG(&rl)) {
             char *type_name = ovsdb_type_to_english(&column->type);
             VLOG_DBG("Table `%s' column `%s' has type %s, not expected "
-                     "key type %s, value type %s, max elements %zd.",
+                     "key type %s, value type %s, max elements %"PRIuSIZE".",
                      schema->name, column_name, type_name,
                      ovsdb_atomic_type_to_string(key_type),
                      ovsdb_atomic_type_to_string(value_type),
@@ -985,6 +1027,7 @@ ovsdb_server_compact(struct unixctl_conn *conn, int argc,
                 char *s = ovsdb_error_to_string(error);
                 ds_put_format(&reply, "%s\n", s);
                 free(s);
+                ovsdb_error_destroy(error);
             }
 
             n++;
@@ -1168,7 +1211,9 @@ parse_options(int *argcp, char **argvp[],
     static const struct option long_options[] = {
         {"remote",      required_argument, NULL, OPT_REMOTE},
         {"unixctl",     required_argument, NULL, OPT_UNIXCTL},
+#ifndef _WIN32
         {"run",         required_argument, NULL, OPT_RUN},
+#endif
         {"help",        no_argument, NULL, 'h'},
         {"version",     no_argument, NULL, 'V'},
         DAEMON_LONG_OPTIONS,