unixctl: Log commands received and their replies (at debug level).
[cascardo/ovs.git] / lib / unixctl.c
index 20acc3c..c1a5048 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@
 #include "stream.h"
 #include "stream-provider.h"
 #include "svec.h"
-#include "vlog.h"
+#include "openvswitch/vlog.h"
 
 VLOG_DEFINE_THIS_MODULE(unixctl);
 
@@ -44,7 +44,7 @@ struct unixctl_command {
 };
 
 struct unixctl_conn {
-    struct list node;
+    struct ovs_list node;
     struct jsonrpc *rpc;
 
     /* Only one request can be in progress at a time.  While the request is
@@ -55,7 +55,7 @@ struct unixctl_conn {
 /* Server for control connection. */
 struct unixctl_server {
     struct pstream *listener;
-    struct list conns;
+    struct ovs_list conns;
 };
 
 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
@@ -63,8 +63,8 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
 static struct shash commands = SHASH_INITIALIZER(&commands);
 
 static void
-unixctl_help(struct unixctl_conn *conn, int argc OVS_UNUSED,
-             const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
+unixctl_list_commands(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                      const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
 {
     struct ds ds = DS_EMPTY_INITIALIZER;
     const struct shash_node **nodes = shash_sort(&commands);
@@ -88,12 +88,12 @@ static void
 unixctl_version(struct unixctl_conn *conn, int argc OVS_UNUSED,
                 const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
 {
-    unixctl_command_reply(conn, get_program_version());
+    unixctl_command_reply(conn, ovs_get_program_version());
 }
 
 /* Registers a unixctl command with the given 'name'.  'usage' describes the
  * arguments to the command; it is used only for presentation to the user in
- * "help" output.
+ * "list-commands" output.
  *
  * 'cb' is called when the command is received.  It is passed an array
  * containing the command name and arguments, plus a copy of 'aux'.  Normally
@@ -151,6 +151,13 @@ unixctl_command_reply__(struct unixctl_conn *conn,
         reply = jsonrpc_create_error(body_json, conn->request_id);
     }
 
+    if (VLOG_IS_DBG_ENABLED()) {
+        char *id = json_to_string(conn->request_id, 0);
+        VLOG_DBG("replying with %s, id=%s: \"%s\"",
+                 success ? "success" : "error", id, body);
+        free(id);
+    }
+
     /* If jsonrpc_send() returns an error, the run loop will take care of the
      * problem eventually. */
     jsonrpc_send(conn->rpc, reply);
@@ -211,28 +218,31 @@ unixctl_server_create(const char *path, struct unixctl_server **serverp)
 {
     struct unixctl_server *server;
     struct pstream *listener;
-    char *punix_path, *abs_path = NULL;
+    char *punix_path;
     int error;
-#ifdef _WIN32
-    FILE *file;
-#endif
 
     *serverp = NULL;
     if (path && !strcmp(path, "none")) {
         return 0;
     }
 
-#ifndef _WIN32
     if (path) {
+        char *abs_path;
+#ifndef _WIN32
         abs_path = abs_file_name(ovs_rundir(), path);
+#else
+        abs_path = xstrdup(path);
+#endif
         punix_path = xasprintf("punix:%s", abs_path);
+        free(abs_path);
     } else {
+#ifndef _WIN32
         punix_path = xasprintf("punix:%s/%s.%ld.ctl", ovs_rundir(),
                                program_name, (long int) getpid());
-    }
 #else
-    punix_path = xstrdup("ptcp:0:127.0.0.1");
+        punix_path = xasprintf("punix:%s/%s.ctl", ovs_rundir(), program_name);
 #endif
+    }
 
     error = pstream_open(punix_path, &listener, 0);
     if (error) {
@@ -240,31 +250,8 @@ unixctl_server_create(const char *path, struct unixctl_server **serverp)
         goto exit;
     }
 
-#ifdef _WIN32
-    if (path) {
-        abs_path = xstrdup(path);
-    } else {
-        abs_path = xasprintf("%s/%s.ctl", ovs_rundir(), program_name);
-    }
-
-    file = fopen(abs_path, "w");
-    if (!file) {
-        error = errno;
-        ovs_error(error, "could not open %s", abs_path);
-        goto exit;
-    }
-
-    fprintf(file, "%d\n", ntohs(listener->bound_port));
-    if (fflush(file) == EOF) {
-        error = EIO;
-        ovs_error(error, "write failed for %s", abs_path);
-        fclose(file);
-        goto exit;
-    }
-    fclose(file);
-#endif
-
-    unixctl_command_register("help", "", 0, 0, unixctl_help, NULL);
+    unixctl_command_register("list-commands", "", 0, 0, unixctl_list_commands,
+                             NULL);
     unixctl_command_register("version", "", 0, 0, unixctl_version, NULL);
 
     server = xmalloc(sizeof *server);
@@ -273,9 +260,6 @@ unixctl_server_create(const char *path, struct unixctl_server **serverp)
     *serverp = server;
 
 exit:
-    if (abs_path) {
-        free(abs_path);
-    }
     free(punix_path);
     return error;
 }
@@ -291,6 +275,15 @@ process_command(struct unixctl_conn *conn, struct jsonrpc_msg *request)
     COVERAGE_INC(unixctl_received);
     conn->request_id = json_clone(request->id);
 
+    if (VLOG_IS_DBG_ENABLED()) {
+        char *params_s = json_to_string(request->params, 0);
+        char *id_s = json_to_string(request->id, 0);
+        VLOG_DBG("received request %s%s, id=%s",
+                 request->method, params_s, id_s);
+        free(params_s);
+        free(id_s);
+    }
+
     params = json_array(request->params);
     command = shash_find_data(&commands, request->method);
     if (!command) {
@@ -460,32 +453,13 @@ unixctl_client_create(const char *path, struct jsonrpc **client)
     char *abs_path, *unix_path;
     struct stream *stream;
     int error;
-#ifdef _WIN32
-    FILE *file;
-    int port;
-
-    abs_path = strdup(path);
-    file = fopen(abs_path, "r");
-    if (!file) {
-        int error = errno;
-        ovs_error(error, "could not open %s", abs_path);
-        free(abs_path);
-        return error;
-    }
-
-    error = fscanf(file, "%d", &port);
-    if (error != 1) {
-        ovs_error(errno, "failed to read port from %s", abs_path);
-        free(abs_path);
-        return EINVAL;
-    }
-    fclose(file);
 
-    unix_path = xasprintf("tcp:127.0.0.1:%d", port);
+#ifdef _WIN32
+    abs_path = xstrdup(path);
 #else
     abs_path = abs_file_name(ovs_rundir(), path);
-    unix_path = xasprintf("unix:%s", abs_path);
 #endif
+    unix_path = xasprintf("unix:%s", abs_path);
 
     *client = NULL;