[libvirt] [PATCH v2 9/9] virt-admin: Introduce srv-clients-list command

Erik Skultety eskultet at redhat.com
Fri Apr 29 12:39:59 UTC 2016


Wire-up the public client listing API. Along with this change, a private time
simple conversion method to interpret client's timestamp obtained from server
has been added as well. Format used to for time output is as follows:
YYYY-mm-DD HH:MM:SS+ZZZZ.

Although libvirt exposes methods time-related methods through virtime.h
internally, it utilizes millisecond precision which we don't need in this case,
especially when connection timestamps use precision to seconds only.
This is just a convenience int to string conversion method.

To reflect the new API, man page has been adjusted accordingly.

Signed-off-by: Erik Skultety <eskultet at redhat.com>
---
 tools/virt-admin.c   | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/virt-admin.pod |   7 +++
 2 files changed, 148 insertions(+)

diff --git a/tools/virt-admin.c b/tools/virt-admin.c
index 22160ad..f0fecdd 100644
--- a/tools/virt-admin.c
+++ b/tools/virt-admin.c
@@ -38,6 +38,7 @@
 #include "virstring.h"
 #include "virthread.h"
 #include "virgettext.h"
+#include "virtime.h"
 
 /* Gnulib doesn't guarantee SA_SIGINFO support.  */
 #ifndef SA_SIGINFO
@@ -46,11 +47,64 @@
 
 #define VIRT_ADMIN_PROMPT "virt-admin # "
 
+/* we don't need precision to milliseconds in this module */
+#define VIRT_ADMIN_TIME_BUFLEN VIR_TIME_STRING_BUFLEN - 3
+
 static char *progname;
 
 static const vshCmdGrp cmdGroups[];
 static const vshClientHooks hooks;
 
+VIR_ENUM_DECL(virClientTransport)
+VIR_ENUM_IMPL(virClientTransport,
+              VIR_CLIENT_TRANS_LAST,
+              N_("unix"),
+              N_("tcp"),
+              N_("tls"))
+
+static const char *
+vshAdmClientTransportToString(int transport)
+{
+    const char *str = virClientTransportTypeToString(transport);
+    return str ? _(str) : _("unknown");
+}
+
+/*
+ * vshAdmGetTimeStr:
+ *
+ * Produces string representation (local time) of @then
+ * (seconds since epoch UTC) using format 'YYYY-MM-DD HH:MM:SS+ZZZZ'.
+ *
+ * Returns 0 if conversion finished successfully, -1 in case of an error.
+ * Caller is responsible for freeing the string returned.
+ */
+static int
+vshAdmGetTimeStr(vshControl *ctl, time_t then, char **result)
+{
+
+    char *tmp = NULL;
+    struct tm timeinfo;
+
+    if (!localtime_r(&then, &timeinfo))
+        goto error;
+
+    if (VIR_ALLOC_N(tmp, VIR_TIME_STRING_BUFLEN) < 0)
+        goto error;
+
+    if (strftime(tmp, VIR_TIME_STRING_BUFLEN, "%Y-%m-%d %H:%M:%S%z",
+                 &timeinfo) == 0) {
+        VIR_FREE(tmp);
+        goto error;
+    }
+
+    *result = tmp;
+    return 0;
+
+ error:
+    vshError(ctl, "%s", _("Timestamp string conversion failed"));
+    return -1;
+}
+
 /*
  * vshAdmCatchDisconnect:
  *
@@ -520,6 +574,87 @@ cmdSrvThreadpoolSet(vshControl *ctl, const vshCmd *cmd)
     goto cleanup;
 }
 
+/* ------------------------
+ * Command srv-clients-list
+ * ------------------------
+ */
+
+static const vshCmdInfo info_srv_clients_list[] = {
+    {.name = "help",
+     .data = N_("list clients connected to <server>")
+    },
+    {.name = "desc",
+     .data = N_("List all manageable clients connected to <server>.")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_srv_clients_list[] = {
+    {.name = "server",
+     .type = VSH_OT_DATA,
+     .flags = VSH_OFLAG_REQ,
+     .help = N_("server which to list connected clients from"),
+    },
+    {.name = NULL}
+};
+
+static bool
+cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
+{
+    int nclts = 0;
+    size_t i;
+    bool ret = false;
+    const char *srvname = NULL;
+    unsigned long long id;
+    virClientTransport transport;
+    char *timestr = NULL;
+    virAdmServerPtr srv = NULL;
+    virAdmClientPtr *clts = NULL;
+    vshAdmControlPtr priv = ctl->privData;
+
+    if (vshCommandOptStringReq(ctl, cmd, "server", &srvname) < 0)
+        return false;
+
+    if (!(srv = virAdmConnectLookupServer(priv->conn, srvname, 0)))
+        goto cleanup;
+
+    /* Obtain a list of clients connected to server @srv */
+    if ((nclts = virAdmServerListClients(srv, &clts, 0)) < 0) {
+        vshError(ctl, _("failed to obtain list of connected clients "
+                        "from server '%s'"), virAdmServerGetName(srv));
+        goto cleanup;
+    }
+
+    vshPrintExtra(ctl, " %-5s %-15s %-15s\n%s\n", _("Id"), _("Transport"),
+                  _("Connected since"),
+                  "-------------------------"
+                  "-------------------------");
+
+    for (i = 0; i < nclts; i++) {
+        virAdmClientPtr client = clts[i];
+        id = virAdmClientGetID(client);
+        transport = virAdmClientGetTransport(client);
+        if (vshAdmGetTimeStr(ctl, virAdmClientGetTimestamp(client),
+                             &timestr) < 0)
+            goto cleanup;
+
+        vshPrint(ctl, " %-5llu %-15s %-15s\n",
+                 id, vshAdmClientTransportToString(transport), timestr);
+    }
+
+    ret = true;
+
+ cleanup:
+    if (clts) {
+        for (i = 0; i < nclts; i++)
+            virAdmClientFree(clts[i]);
+        VIR_FREE(clts);
+    }
+    virAdmServerFree(srv);
+    VIR_FREE(timestr);
+    return ret;
+}
+
 static void *
 vshAdmConnectionHandler(vshControl *ctl)
 {
@@ -825,6 +960,12 @@ static const vshCmdDef monitoringCmds[] = {
      .info = info_srv_threadpool_info,
      .flags = 0
     },
+    {.name = "srv-clients-list",
+     .handler = cmdSrvClientsList,
+     .opts = opts_srv_clients_list,
+     .info = info_srv_clients_list,
+     .flags = 0
+    },
     {.name = NULL}
 };
 
diff --git a/tools/virt-admin.pod b/tools/virt-admin.pod
index 83a8cea..6f9dd63 100644
--- a/tools/virt-admin.pod
+++ b/tools/virt-admin.pod
@@ -220,6 +220,13 @@ The current number of active priority workers in a threadpool.
 
 =back
 
+=item B<srv-clients-list> I<server>
+
+Print a table showing the list of clients connected to <server>, also providing
+information about transport type used on client's connection (supported
+transports include B<unix>, B<tcp>, and B<tls>), as well as providing
+information about client's connection time (system local time is used).
+
 =back
 
 =head1 ENVIRONMENT
-- 
2.4.11




More information about the libvir-list mailing list