[ovs-dev] [packet_in v2 09/18] ovs-ofctl: Support daemonization for monitor and snoop.

Ethan Jackson ethan at nicira.com
Sat Jan 7 19:11:50 UTC 2012


This will ease implementation of future unit tests.

Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
 NEWS                     |    2 +
 manpages.mk              |    2 +
 utilities/ovs-ofctl.8.in |   11 ++++++++
 utilities/ovs-ofctl.c    |   62 +++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 675e4c4..332d740 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ port-v1.4.0
     - OpenFlow:
         - Added support for querying, modifying, and deleting flows
           based on flow cookie when using NXM.
+    - ovs-ofctl:
+        - Added daemonization support to the monitor and snoop commands.
 
 
 v1.4.0 - xx xxx xxxx
diff --git a/manpages.mk b/manpages.mk
index 48f2db5..14bb41f 100644
--- a/manpages.mk
+++ b/manpages.mk
@@ -121,11 +121,13 @@ lib/vlog.man:
 utilities/ovs-ofctl.8: \
 	utilities/ovs-ofctl.8.in \
 	lib/common.man \
+	lib/daemon.man \
 	lib/ssl.man \
 	lib/vconn-active.man \
 	lib/vlog.man
 utilities/ovs-ofctl.8.in:
 lib/common.man:
+lib/daemon.man:
 lib/ssl.man:
 lib/vconn-active.man:
 lib/vlog.man:
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 45574b4..6c78c68 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -1054,11 +1054,22 @@ flow format, \fBovs\-ofctl\fR will report a fatal error.
 Increases the verbosity of OpenFlow messages printed and logged by
 \fBovs\-ofctl\fR commands.  Specify this option more than once to
 increase verbosity further.
+.
+.ds DD \
+\fBovs\-ofctl\fR detaches only when executing the \fBmonitor\fR or \
+\fBsnoop\fR commands.
+.so lib/daemon.man
 .SS "Public Key Infrastructure Options"
 .so lib/ssl.man
 .so lib/vlog.man
 .so lib/common.man
 .
+.SH "RUNTIME MANAGEMENT COMMANDS"
+\fBovs\-appctl\fR(8) can send commands to a running \fBovs\-ofctl\fR process.
+The currently supported commands only apply when executing the \fBmonitor\fR or
+\fBsnoop\fR commands and are described below.
+.IP "\fBexit\fR"
+Causes \fBovs\-ofctl\fR to gracefully terminate.
 .SH EXAMPLES
 .
 The following examples assume that \fBovs\-vswitchd\fR has a bridge
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 7b20ba0..044f74c 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -30,6 +30,7 @@
 #include "byte-order.h"
 #include "classifier.h"
 #include "command-line.h"
+#include "daemon.h"
 #include "compiler.h"
 #include "dirs.h"
 #include "dynamic-string.h"
@@ -43,9 +44,11 @@
 #include "ofproto/ofproto.h"
 #include "openflow/nicira-ext.h"
 #include "openflow/openflow.h"
+#include "poll-loop.h"
 #include "random.h"
 #include "stream-ssl.h"
 #include "timeval.h"
+#include "unixctl.h"
 #include "util.h"
 #include "vconn.h"
 #include "vlog.h"
@@ -87,6 +90,7 @@ parse_options(int argc, char *argv[])
     enum {
         OPT_STRICT = UCHAR_MAX + 1,
         OPT_READD,
+        DAEMON_OPTION_ENUMS,
         VLOG_OPTION_ENUMS
     };
     static struct option long_options[] = {
@@ -97,6 +101,7 @@ parse_options(int argc, char *argv[])
         {"more", no_argument, NULL, 'm'},
         {"help", no_argument, NULL, 'h'},
         {"version", no_argument, NULL, 'V'},
+        DAEMON_LONG_OPTIONS,
         VLOG_LONG_OPTIONS,
         STREAM_SSL_LONG_OPTIONS,
         {NULL, 0, NULL, 0},
@@ -149,6 +154,7 @@ parse_options(int argc, char *argv[])
             readd = true;
             break;
 
+        DAEMON_OPTION_HANDLERS
         VLOG_OPTION_HANDLERS
         STREAM_SSL_OPTION_HANDLERS
 
@@ -193,6 +199,7 @@ usage(void)
            "where SWITCH or TARGET is an active OpenFlow connection method.\n",
            program_name, program_name);
     vconn_usage(true, false, false);
+    daemon_usage();
     vlog_usage();
     printf("\nOther options:\n"
            "  --strict                    use strict match for flow commands\n"
@@ -205,6 +212,15 @@ usage(void)
     exit(EXIT_SUCCESS);
 }
 
+static void
+ofctl_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
+           const char *argv[] OVS_UNUSED, void *exiting_)
+{
+    bool *exiting = exiting_;
+    *exiting = true;
+    unixctl_command_reply(conn, 200, "");
+}
+
 static void run(int retval, const char *message, ...)
     PRINTF_FORMAT(2, 3);
 
@@ -752,11 +768,51 @@ do_del_flows(int argc, char *argv[])
 static void
 monitor_vconn(struct vconn *vconn)
 {
+    struct unixctl_server *server;
+    bool exiting = false;
+    int error, fd;
+
+    /* Daemonization will close stderr but we really want to keep it, so make a
+     * copy. */
+    fd = dup(STDERR_FILENO);
+
+    daemonize_start();
+    error = unixctl_server_create(NULL, &server);
+    if (error) {
+        ovs_fatal(error, "failed to create unixctl server");
+    }
+    unixctl_command_register("exit", "", 0, 0, ofctl_exit, &exiting);
+    daemonize_complete();
+
+    /* Now get stderr back. */
+    dup2(fd, STDERR_FILENO);
+
     for (;;) {
         struct ofpbuf *b;
-        run(vconn_recv_block(vconn, &b), "vconn_recv");
-        ofp_print(stderr, b->data, b->size, verbosity + 2);
-        ofpbuf_delete(b);
+        int retval;
+
+        unixctl_server_run(server);
+
+        for (;;) {
+            retval = vconn_recv(vconn, &b);
+            if (retval == EAGAIN) {
+                break;
+            }
+
+            run(retval, "vconn_recv");
+            ofp_print(stderr, b->data, b->size, verbosity + 2);
+            ofpbuf_delete(b);
+        }
+
+        if (exiting) {
+            break;
+        }
+
+        vconn_run(vconn);
+        vconn_run_wait(vconn);
+        vconn_recv_wait(vconn);
+        unixctl_server_wait(server);
+        poll_block();
     }
 }
 
-- 
1.7.7.1




More information about the dev mailing list