Break passive vconns out into separate pvconn routines and data structures.
[sliver-openvswitch.git] / controller / controller.c
index 2176fa7..48420c8 100644 (file)
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <getopt.h>
 #include <limits.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -83,7 +84,7 @@ int
 main(int argc, char *argv[])
 {
     struct switch_ switches[MAX_SWITCHES];
-    struct vconn *listeners[MAX_LISTENERS];
+    struct pvconn *listeners[MAX_LISTENERS];
     int n_switches, n_listeners;
     int retval;
     int i;
@@ -93,6 +94,7 @@ main(int argc, char *argv[])
     time_init();
     vlog_init();
     parse_options(argc, argv);
+    signal(SIGPIPE, SIG_IGN);
 
     if (argc - optind < 1) {
         fatal(0, "at least one vconn argument required; use --help for usage");
@@ -110,27 +112,29 @@ main(int argc, char *argv[])
         int retval;
 
         retval = vconn_open(name, &vconn);
-        if (retval) {
-            VLOG_ERR("%s: connect: %s", name, strerror(retval));
-            continue;
-        }
-
-        if (vconn_is_passive(vconn)) {
-            if (n_listeners >= MAX_LISTENERS) {
-                fatal(0, "max %d passive connections", n_listeners);
-            }
-            listeners[n_listeners++] = vconn;
-        } else {
+        if (!retval) {
             if (n_switches >= MAX_SWITCHES) {
                 fatal(0, "max %d switch connections", n_switches);
             }
             new_switch(&switches[n_switches++], vconn, name);
+            continue;
+        } else if (retval == EAFNOSUPPORT) {
+            struct pvconn *pvconn;
+            retval = pvconn_open(name, &pvconn);
+            if (!retval) {
+                if (n_listeners >= MAX_LISTENERS) {
+                    fatal(0, "max %d passive connections", n_listeners);
+                }
+                listeners[n_listeners++] = pvconn;
+            }
         }
+        VLOG_ERR("%s: connect: %s", name, strerror(retval));
     }
     if (n_switches == 0 && n_listeners == 0) {
         fatal(0, "no active or passive switch connections");
     }
 
+    die_if_already_running();
     daemonize();
 
     while (n_switches > 0 || n_listeners > 0) {
@@ -142,14 +146,14 @@ main(int argc, char *argv[])
             struct vconn *new_vconn;
             int retval;
 
-            retval = vconn_accept(listeners[i], &new_vconn);
+            retval = pvconn_accept(listeners[i], &new_vconn);
             if (!retval || retval == EAGAIN) {
                 if (!retval) {
                     new_switch(&switches[n_switches++], new_vconn, "tcp");
                 }
                 i++;
             } else {
-                vconn_close(listeners[i]);
+                pvconn_close(listeners[i]);
                 listeners[i] = listeners[--n_listeners];
             }
         }
@@ -180,7 +184,7 @@ main(int argc, char *argv[])
         /* Wait for something to happen. */
         if (n_switches < MAX_SWITCHES) {
             for (i = 0; i < n_listeners; i++) {
-                vconn_accept_wait(listeners[i]);
+                pvconn_wait(listeners[i]);
             }
         }
         for (i = 0; i < n_switches; i++) {
@@ -197,7 +201,7 @@ main(int argc, char *argv[])
 static void
 new_switch(struct switch_ *sw, struct vconn *vconn, const char *name)
 {
-    sw->rconn = rconn_new_from_vconn(name, 128, vconn);
+    sw->rconn = rconn_new_from_vconn(name, vconn);
     sw->lswitch = lswitch_create(sw->rconn, learn_macs,
                                  setup_flows ? max_idle : -1);
 }
@@ -229,6 +233,7 @@ parse_options(int argc, char *argv[])
     static struct option long_options[] = {
         {"detach",      no_argument, 0, 'D'},
         {"pidfile",     optional_argument, 0, 'P'},
+        {"force",       no_argument, 0, 'f'},
         {"hub",         no_argument, 0, 'H'},
         {"noflow",      no_argument, 0, 'n'},
         {"max-idle",    required_argument, 0, OPT_MAX_IDLE},
@@ -258,6 +263,10 @@ parse_options(int argc, char *argv[])
             set_pidfile(optarg);
             break;
 
+        case 'f':
+            ignore_existing_pidfile();
+            break;
+
         case 'H':
             learn_macs = false;
             break;
@@ -312,6 +321,7 @@ usage(void)
     printf("\nOther options:\n"
            "  -D, --detach            run in background as daemon\n"
            "  -P, --pidfile[=FILE]    create pidfile (default: %s/controller.pid)\n"
+           "  -f, --force             with -P, start even if already running\n"
            "  -H, --hub               act as hub instead of learning switch\n"
            "  -n, --noflow            pass traffic, but don't add flows\n"
            "  --max-idle=SECS         max idle time for new flows\n"