aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2011-12-20 15:31:34 -0800
committerEthan Jackson <ethan@nicira.com>2012-01-10 14:30:14 -0800
commit1eb85ef5407e27b35dcec8a34eda23d3e39ddaa6 (patch)
treebf8653425ce7682ef472642db3b3f1f0956f5e4e
parente50abca5be5f0682012f6c0ef9b010708e56be07 (diff)
ovs-ofctl: Support daemonization for monitor and snoop.
This will ease implementation of future unit tests. Signed-off-by: Ethan Jackson <ethan@nicira.com>
-rw-r--r--NEWS2
-rw-r--r--manpages.mk2
-rw-r--r--utilities/ovs-ofctl.8.in11
-rw-r--r--utilities/ovs-ofctl.c62
4 files changed, 74 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 675e4c4f..332d7403 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 48f2db5f..14bb41f0 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 45574b4d..6c78c68f 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 7b20ba09..044f74cc 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();
}
}