ovsdb-server: Open --listen sockets before detaching.
authorBen Pfaff <blp@nicira.com>
Thu, 3 Dec 2009 22:20:33 +0000 (14:20 -0800)
committerBen Pfaff <blp@nicira.com>
Thu, 3 Dec 2009 22:47:00 +0000 (14:47 -0800)
This prevents a race condition in a command sequence that starts
ovsdb-server and then immediately connects to it with ovsdb-client.

ovsdb/jsonrpc-server.c
ovsdb/jsonrpc-server.h
ovsdb/ovsdb-server.c

index 897f9ae54f02eb92d534ed1dba82d50874734fe1..1c08a10f398f13135fe4fc5ebe63eb0ce154db6e 100644 (file)
@@ -89,23 +89,15 @@ ovsdb_jsonrpc_server_create(struct ovsdb *db)
     return server;
 }
 
-int
-ovsdb_jsonrpc_server_listen(struct ovsdb_jsonrpc_server *svr, const char *name)
+void
+ovsdb_jsonrpc_server_listen(struct ovsdb_jsonrpc_server *svr,
+                            struct pstream *pstream)
 {
-    struct pstream *pstream;
-    int error;
-
-    error = pstream_open(name, &pstream);
-    if (error) {
-        return error;
-    }
-
     if (svr->n_listeners >= svr->allocated_listeners) {
         svr->listeners = x2nrealloc(svr->listeners, &svr->allocated_listeners,
                                     sizeof *svr->listeners);
     }
     svr->listeners[svr->n_listeners++] = pstream;
-    return 0;
 }
 
 void
index 0a80ac61be5fa4203d8a44a0e8ac222929b2e008..6ff6fe0cb4456b7d3f218167a43ac33096249ddc 100644 (file)
 #define OVSDB_JSONRPC_SERVER_H 1
 
 struct ovsdb;
+struct pstream;
 
 struct ovsdb_jsonrpc_server *ovsdb_jsonrpc_server_create(struct ovsdb *);
 
-int ovsdb_jsonrpc_server_listen(struct ovsdb_jsonrpc_server *,
-                                const char *name);
+void ovsdb_jsonrpc_server_listen(struct ovsdb_jsonrpc_server *,
+                                 struct pstream *);
 void ovsdb_jsonrpc_server_connect(struct ovsdb_jsonrpc_server *,
                                   const char *name);
 
index f63081369183245a169e93bd27837249e6a1a43d..d80161b2dfb70730a27e81775de6258464e07223 100644 (file)
@@ -60,6 +60,7 @@ main(int argc, char *argv[])
     struct unixctl_server *unixctl;
     struct ovsdb_jsonrpc_server *jsonrpc;
     struct svec active, passive;
+    struct pstream **listeners;
     struct ovsdb_error *error;
     struct ovsdb *db;
     const char *name;
@@ -78,6 +79,18 @@ main(int argc, char *argv[])
 
     parse_options(argc, argv, &file_name, &active, &passive, &unixctl_path);
 
+    /* Open all the passive sockets before detaching, to avoid race with
+     * processes that start up later. */
+    listeners = xmalloc(passive.n * sizeof *listeners);
+    for (i = 0; i < passive.n; i++) {
+        int error;
+
+        error = pstream_open(passive.names[i], &listeners[i]);
+        if (error) {
+            ovs_fatal(error, "failed to listen on \"%s\"", passive.names[i]);
+        }
+    }
+
     if (get_detach() && is_chdir_enabled()) {
         /* We need to skip chdir("/") in daemonize() and do it later, because
          * we need to open the database and possible set up up Unix domain
@@ -101,11 +114,8 @@ main(int argc, char *argv[])
     SVEC_FOR_EACH (i, name, &active) {
         ovsdb_jsonrpc_server_connect(jsonrpc, name);
     }
-    SVEC_FOR_EACH (i, name, &passive) {
-        retval = ovsdb_jsonrpc_server_listen(jsonrpc, name);
-        if (retval) {
-            ovs_fatal(retval, "failed to listen on %s", name);
-        }
+    for (i = 0; i < passive.n; i++) {
+        ovsdb_jsonrpc_server_listen(jsonrpc, listeners[i]);
     }
     svec_destroy(&active);
     svec_destroy(&passive);