<div dir="ltr"><div><div><div>Hi,<br><br>There is a typo in the commit message. <br></div>This patch is for introducing virsh pool-event command.<br><br><br></div>Thanks,<br></div>Jovanka<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 16, 2016 at 7:27 PM, Jovanka Gulicoska <span dir="ltr"><<a href="mailto:jovanka.gulicoska@gmail.com" target="_blank">jovanka.gulicoska@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">---<br>
 tools/virsh-pool.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++<br>
 tools/virsh.pod    |  18 ++++++<br>
 2 files changed, 202 insertions(+)<br>
<br>
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c<br>
index f9299e2..18e218c 100644<br>
--- a/tools/virsh-pool.c<br>
+++ b/tools/virsh-pool.c<br>
@@ -32,6 +32,7 @@<br>
 #include "virfile.h"<br>
 #include "conf/storage_conf.h"<br>
 #include "virstring.h"<br>
+#include "virtime.h"<br>
<br>
 #define VIRSH_COMMON_OPT_POOL_FULL                            \<br>
     VIRSH_COMMON_OPT_POOL(N_("pool name or uuid"))            \<br>
@@ -1889,6 +1890,183 @@ cmdPoolEdit(vshControl *ctl, const vshCmd *cmd)<br>
     return ret;<br>
 }<br>
<br>
+/*<br>
+ * "pool-event" command<br>
+ */<br>
+VIR_ENUM_DECL(virshPoolEvent)<br>
+VIR_ENUM_IMPL(virshPoolEvent,<br>
+              VIR_STORAGE_POOL_EVENT_LAST,<br>
+              N_("Defined"),<br>
+              N_("Undefined"),<br>
+              N_("Started"),<br>
+              N_("Stopped"),<br>
+              N_("Refreshed"))<br>
+<br>
+static const char *<br>
+virshPoolEventToString(int event)<br>
+{<br>
+    const char *str = virshPoolEventTypeToString(event);<br>
+    return str ? _(str) : _("unknown");<br>
+}<br>
+<br>
+struct virshPoolEventData {<br>
+    vshControl *ctl;<br>
+    bool loop;<br>
+    bool timestamp;<br>
+    int count;<br>
+};<br>
+typedef struct virshPoolEventData virshPoolEventData;<br>
+<br>
+VIR_ENUM_DECL(virshPoolEventId)<br>
+VIR_ENUM_IMPL(virshPoolEventId,<br>
+              VIR_STORAGE_POOL_EVENT_ID_LAST,<br>
+              "lifecycle")<br>
+<br>
+static void<br>
+vshEventLifecyclePrint(virConnectPtr conn ATTRIBUTE_UNUSED,<br>
+                       virStoragePoolPtr pool,<br>
+                       int event,<br>
+                       int detail ATTRIBUTE_UNUSED,<br>
+                       void *opaque)<br>
+{<br>
+    virshPoolEventData *data = opaque;<br>
+<br>
+    if (!data->loop && data->count)<br>
+        return;<br>
+<br>
+    if (data->timestamp) {<br>
+        char timestamp[VIR_TIME_STRING_BUFLEN];<br>
+<br>
+        if (virTimeStringNowRaw(timestamp) < 0)<br>
+            timestamp[0] = '\0';<br>
+<br>
+        vshPrint(data->ctl, _("%s: event 'lifecycle' for storage pool %s: %s\n"),<br>
+                 timestamp,<br>
+                 virStoragePoolGetName(pool),<br>
+                 virshPoolEventToString(event));<br>
+    } else {<br>
+        vshPrint(data->ctl, _("event 'lifecycle' for storage pool %s: %s\n"),<br>
+                 virStoragePoolGetName(pool),<br>
+                 virshPoolEventToString(event));<br>
+    }<br>
+<br>
+    data->count++;<br>
+    if (!data->loop)<br>
+        vshEventDone(data->ctl);<br>
+}<br>
+<br>
+static const vshCmdInfo info_pool_event[] = {<br>
+    {.name = "help",<br>
+     .data = N_("Storage Pool Events")<br>
+    },<br>
+    {.name = "desc",<br>
+     .data = N_("List event types, or wait for storage pool events to occur")<br>
+    },<br>
+    {.name = NULL}<br>
+};<br>
+<br>
+static const vshCmdOptDef opts_pool_event[] = {<br>
+    {.name = "pool",<br>
+     .type = VSH_OT_STRING,<br>
+     .help = N_("filter by storage pool name or uuid")<br>
+    },<br>
+    {.name = "event",<br>
+     .type = VSH_OT_STRING,<br>
+     .help = N_("which event type to wait for")<br>
+    },<br>
+    {.name = "loop",<br>
+     .type = VSH_OT_BOOL,<br>
+     .help = N_("loop until timeout or interrupt, rather than one-shot")<br>
+    },<br>
+    {.name = "timeout",<br>
+     .type = VSH_OT_INT,<br>
+     .help = N_("timeout seconds")<br>
+    },<br>
+    {.name = "list",<br>
+     .type = VSH_OT_BOOL,<br>
+     .help = N_("list valid event types")<br>
+    },<br>
+    {.name = "timestamp",<br>
+     .type = VSH_OT_BOOL,<br>
+     .help = N_("show timestamp for each printed event")<br>
+    },<br>
+    {.name = NULL}<br>
+};<br>
+<br>
+static bool<br>
+cmdPoolEvent(vshControl *ctl, const vshCmd *cmd)<br>
+{<br>
+    virStoragePoolPtr pool = NULL;<br>
+    bool ret = false;<br>
+    int eventId = -1;<br>
+    int timeout = 0;<br>
+    virshPoolEventData data;<br>
+    const char *eventName = NULL;<br>
+    int event;<br>
+    virshControlPtr priv = ctl->privData;<br>
+<br>
+    if (vshCommandOptBool(cmd, "list")) {<br>
+        size_t i;<br>
+<br>
+        for (i = 0; i < VIR_STORAGE_POOL_EVENT_ID_LAST; i++)<br>
+            vshPrint(ctl, "%s\n", virshPoolEventIdTypeToString(i));<br>
+        return true;<br>
+    }<br>
+<br>
+    if (vshCommandOptStringReq(ctl, cmd, "event", &eventName) < 0)<br>
+        return false;<br>
+    if (!eventName) {<br>
+        vshError(ctl, "%s", _("either --list or event type is required"));<br>
+        return false;<br>
+    }<br>
+    if ((event = virshPoolEventIdTypeFromString(eventName)) < 0) {<br>
+        vshError(ctl, _("unknown event type %s"), eventName);<br>
+        return false;<br>
+    }<br>
+<br>
+    data.ctl = ctl;<br>
+    data.loop = vshCommandOptBool(cmd, "loop");<br>
+    data.timestamp = vshCommandOptBool(cmd, "timestamp");<br>
+    data.count = 0;<br>
+    if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0)<br>
+        return false;<br>
+<br>
+    if (vshCommandOptBool(cmd, "pool"))<br>
+        pool = virshCommandOptPool(ctl, cmd, "pool", NULL);<br>
+    if (vshEventStart(ctl, timeout) < 0)<br>
+        goto cleanup;<br>
+<br>
+    if ((eventId = virConnectStoragePoolEventRegisterAny(priv->conn, pool, event,<br>
+                                                         VIR_STORAGE_POOL_EVENT_CALLBACK(vshEventLifecyclePrint),<br>
+                                                         &data, NULL)) < 0)<br>
+        goto cleanup;<br>
+    switch (vshEventWait(ctl)) {<br>
+    case VSH_EVENT_INTERRUPT:<br>
+        vshPrint(ctl, "%s", _("event loop interrupted\n"));<br>
+        break;<br>
+    case VSH_EVENT_TIMEOUT:<br>
+        vshPrint(ctl, "%s", _("event loop timed out\n"));<br>
+        break;<br>
+    case VSH_EVENT_DONE:<br>
+        break;<br>
+    default:<br>
+        goto cleanup;<br>
+    }<br>
+    vshPrint(ctl, _("events received: %d\n"), data.count);<br>
+    if (data.count)<br>
+        ret = true;<br>
+<br>
+ cleanup:<br>
+    vshEventCleanup(ctl);<br>
+    if (eventId >= 0 &&<br>
+        virConnectStoragePoolEventDeregisterAny(priv->conn, eventId) < 0)<br>
+        ret = false;<br>
+    if (pool)<br>
+        virStoragePoolFree(pool);<br>
+    return ret;<br>
+}<br>
+<br>
+<br>
 const vshCmdDef storagePoolCmds[] = {<br>
     {.name = "find-storage-pool-sources-as",<br>
      .handler = cmdPoolDiscoverSourcesAs,<br>
@@ -2004,5 +2182,11 @@ const vshCmdDef storagePoolCmds[] = {<br>
      .info = info_pool_uuid,<br>
      .flags = 0<br>
     },<br>
+    {.name = "pool-event",<br>
+     .handler = cmdPoolEvent,<br>
+     .opts = opts_pool_event,<br>
+     .info = info_pool_event,<br>
+     .flags = 0<br>
+    },<br>
     {.name = NULL}<br>
 };<br>
diff --git a/tools/virsh.pod b/tools/virsh.pod<br>
index 1e56660..e530160 100644<br>
--- a/tools/virsh.pod<br>
+++ b/tools/virsh.pod<br>
@@ -3457,6 +3457,24 @@ Undefine the configuration for an inactive I<pool>.<br>
<br>
 Returns the UUID of the named I<pool>.<br>
<br>
+=item B<pool-event> {[I<pool>] I<event> [I<--loop>] [I<--timeout><br>
+I<seconds>] [I<--timestamp>] | I<--list>}<br>
+<br>
+Wait for a class of storage pool events to occur, and print appropriate<br>
+details of events as they happen.  The events can optionally be filtered<br>
+by I<pool>.  Using I<--list> as the only argument will provide a list<br>
+of possible I<event> values known by this client, although the connection<br>
+might not allow registering for all these events.<br>
+<br>
+By default, this command is one-shot, and returns success once an event<br>
+occurs; you can send SIGINT (usually via C<Ctrl-C>) to quit immediately.<br>
+If I<--timeout> is specified, the command gives up waiting for events<br>
+after I<seconds> have elapsed.   With I<--loop>, the command prints all<br>
+events until a timeout or interrupt key.<br>
+<br>
+When I<--timestamp> is used, a human-readable timestamp will be printed<br>
+before the event.<br>
+<br>
 =back<br>
<br>
 =head1 VOLUME COMMANDS<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.5<br>
<br>
</font></span></blockquote></div><br></div>