9119d9
From a83a22de1508bd32385128421cb89991942df42e Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <a83a22de1508bd32385128421cb89991942df42e@dist-git>
9119d9
From: Peter Krempa <pkrempa@redhat.com>
9119d9
Date: Mon, 24 Nov 2014 17:51:18 +0100
9119d9
Subject: [PATCH] event: Add guest agent lifecycle event
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1146944
9119d9
9119d9
As qemu is now able to notify us about change of the channel state used
9119d9
for communication with the guest agent we now can more precisely track
9119d9
the state of the guest agent.
9119d9
9119d9
To allow notifying management apps this patch implements a new event
9119d9
that will be triggered on changes of the guest agent state.
9119d9
9119d9
(cherry picked from commit 1a4609101b63cacc648d7935f3e18898904d2697)
9119d9
9119d9
Conflicts:
9119d9
	include/libvirt/libvirt-domain.h - doesn't exist downstream yet
9119d9
	src/remote/remote_protocol.x - new api missing
9119d9
	src/remote_protocol-structs - new api missing
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 daemon/remote.c              | 36 ++++++++++++++++++++
9119d9
 include/libvirt/libvirt.h.in | 40 +++++++++++++++++++++++
9119d9
 src/conf/domain_event.c      | 78 ++++++++++++++++++++++++++++++++++++++++++++
9119d9
 src/conf/domain_event.h      |  9 +++++
9119d9
 src/libvirt_private.syms     |  2 ++
9119d9
 src/remote/remote_driver.c   | 31 ++++++++++++++++++
9119d9
 src/remote/remote_protocol.x | 16 ++++++++-
9119d9
 src/remote_protocol-structs  |  7 ++++
9119d9
 tools/virsh-domain.c         | 39 ++++++++++++++++++++++
9119d9
 9 files changed, 257 insertions(+), 1 deletion(-)
9119d9
9119d9
diff --git a/daemon/remote.c b/daemon/remote.c
9119d9
index 0112a32..253a4c3 100644
9119d9
--- a/daemon/remote.c
9119d9
+++ b/daemon/remote.c
9119d9
@@ -1013,6 +1013,41 @@ remoteRelayDomainEventTunable(virConnectPtr conn,
9119d9
 }
9119d9
 
9119d9
 
9119d9
+static int
9119d9
+remoteRelayDomainEventAgentLifecycle(virConnectPtr conn,
9119d9
+                                     virDomainPtr dom,
9119d9
+                                     int state,
9119d9
+                                     int reason,
9119d9
+                                     void *opaque)
9119d9
+{
9119d9
+    daemonClientEventCallbackPtr callback = opaque;
9119d9
+    remote_domain_event_callback_agent_lifecycle_msg data;
9119d9
+
9119d9
+    if (callback->callbackID < 0 ||
9119d9
+        !remoteRelayDomainEventCheckACL(callback->client, conn, dom))
9119d9
+        return -1;
9119d9
+
9119d9
+    VIR_DEBUG("Relaying domain agent lifecycle event %s %d, callback %d, "
9119d9
+              " state %d, reason %d",
9119d9
+              dom->name, dom->id, callback->callbackID, state, reason);
9119d9
+
9119d9
+    /* build return data */
9119d9
+    memset(&data, 0, sizeof(data));
9119d9
+    data.callbackID = callback->callbackID;
9119d9
+    make_nonnull_domain(&data.dom, dom);
9119d9
+
9119d9
+    data.state = state;
9119d9
+    data.reason = reason;
9119d9
+
9119d9
+    remoteDispatchObjectEventSend(callback->client, remoteProgram,
9119d9
+                                  REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE,
9119d9
+                                  (xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg,
9119d9
+                                  &data);
9119d9
+
9119d9
+    return 0;
9119d9
+}
9119d9
+
9119d9
+
9119d9
 static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
9119d9
     VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
9119d9
     VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
9119d9
@@ -1032,6 +1067,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
9119d9
     VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceRemoved),
9119d9
     VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob2),
9119d9
     VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTunable),
9119d9
+    VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventAgentLifecycle),
9119d9
 };
9119d9
 
9119d9
 verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
9119d9
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
9119d9
index 3ca935e..9099cc4 100644
9119d9
--- a/include/libvirt/libvirt.h.in
9119d9
+++ b/include/libvirt/libvirt.h.in
9119d9
@@ -5318,6 +5318,45 @@ typedef void (*virConnectDomainEventTunableCallback)(virConnectPtr conn,
9119d9
                                                      int nparams,
9119d9
                                                      void *opaque);
9119d9
 
9119d9
+typedef enum {
9119d9
+    VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED = 1, /* agent connected */
9119d9
+    VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_DISCONNECTED = 2, /* agent disconnected */
9119d9
+
9119d9
+# ifdef VIR_ENUM_SENTINELS
9119d9
+    VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_LAST
9119d9
+# endif
9119d9
+} virConnectDomainEventAgentLifecycleState;
9119d9
+
9119d9
+typedef enum {
9119d9
+    VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_UNKNOWN = 0, /* unknown state change reason */
9119d9
+    VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED = 1, /* state changed due to domain start */
9119d9
+    VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL = 2, /* channel state changed */
9119d9
+
9119d9
+# ifdef VIR_ENUM_SENTINELS
9119d9
+    VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_LAST
9119d9
+# endif
9119d9
+} virConnectDomainEventAgentLifecycleReason;
9119d9
+
9119d9
+/**
9119d9
+ * virConnectDomainEventAgentLifecycleCallback:
9119d9
+ * @conn: connection object
9119d9
+ * @dom: domain on which the event occurred
9119d9
+ * @state: new state of the guest agent, one of virConnectDomainEventAgentLifecycleState
9119d9
+ * @reason: reason for state change; one of virConnectDomainEventAgentLifecycleReason
9119d9
+ * @opaque: application specified data
9119d9
+ *
9119d9
+ * This callback occurs when libvirt detects a change in the state of a guest
9119d9
+ * agent.
9119d9
+ *
9119d9
+ * The callback signature to use when registering for an event of type
9119d9
+ * VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE with virConnectDomainEventRegisterAny()
9119d9
+ */
9119d9
+typedef void (*virConnectDomainEventAgentLifecycleCallback)(virConnectPtr conn,
9119d9
+                                                            virDomainPtr dom,
9119d9
+                                                            int state,
9119d9
+                                                            int reason,
9119d9
+                                                            void *opaque);
9119d9
+
9119d9
 
9119d9
 /**
9119d9
  * VIR_DOMAIN_EVENT_CALLBACK:
9119d9
@@ -5354,6 +5393,7 @@ typedef enum {
9119d9
     VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED = 15, /* virConnectDomainEventDeviceRemovedCallback */
9119d9
     VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2 = 16,    /* virConnectDomainEventBlockJobCallback */
9119d9
     VIR_DOMAIN_EVENT_ID_TUNABLE = 17,        /* virConnectDomainEventTunableCallback */
9119d9
+    VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE = 18,/* virConnectDomainEventAgentLifecycleCallback */
9119d9
 
9119d9
 #ifdef VIR_ENUM_SENTINELS
9119d9
     VIR_DOMAIN_EVENT_ID_LAST
9119d9
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
9119d9
index 3504b34..d1042bf 100644
9119d9
--- a/src/conf/domain_event.c
9119d9
+++ b/src/conf/domain_event.c
9119d9
@@ -54,6 +54,7 @@ static virClassPtr virDomainEventDeviceRemovedClass;
9119d9
 static virClassPtr virDomainEventPMClass;
9119d9
 static virClassPtr virDomainQemuMonitorEventClass;
9119d9
 static virClassPtr virDomainEventTunableClass;
9119d9
+static virClassPtr virDomainEventAgentLifecycleClass;
9119d9
 
9119d9
 
9119d9
 static void virDomainEventDispose(void *obj);
9119d9
@@ -70,6 +71,7 @@ static void virDomainEventDeviceRemovedDispose(void *obj);
9119d9
 static void virDomainEventPMDispose(void *obj);
9119d9
 static void virDomainQemuMonitorEventDispose(void *obj);
9119d9
 static void virDomainEventTunableDispose(void *obj);
9119d9
+static void virDomainEventAgentLifecycleDispose(void *obj);
9119d9
 
9119d9
 static void
9119d9
 virDomainEventDispatchDefaultFunc(virConnectPtr conn,
9119d9
@@ -215,6 +217,15 @@ struct _virDomainEventTunable {
9119d9
 typedef struct _virDomainEventTunable virDomainEventTunable;
9119d9
 typedef virDomainEventTunable *virDomainEventTunablePtr;
9119d9
 
9119d9
+struct _virDomainEventAgentLifecycle {
9119d9
+    virDomainEvent parent;
9119d9
+
9119d9
+    int state;
9119d9
+    int reason;
9119d9
+};
9119d9
+typedef struct _virDomainEventAgentLifecycle virDomainEventAgentLifecycle;
9119d9
+typedef virDomainEventAgentLifecycle *virDomainEventAgentLifecyclePtr;
9119d9
+
9119d9
 
9119d9
 static int
9119d9
 virDomainEventsOnceInit(void)
9119d9
@@ -303,6 +314,12 @@ virDomainEventsOnceInit(void)
9119d9
                       sizeof(virDomainEventTunable),
9119d9
                       virDomainEventTunableDispose)))
9119d9
         return -1;
9119d9
+    if (!(virDomainEventAgentLifecycleClass =
9119d9
+          virClassNew(virDomainEventClass,
9119d9
+                      "virDomainEventAgentLifecycle",
9119d9
+                      sizeof(virDomainEventAgentLifecycle),
9119d9
+                      virDomainEventAgentLifecycleDispose)))
9119d9
+        return -1;
9119d9
     return 0;
9119d9
 }
9119d9
 
9119d9
@@ -447,6 +464,13 @@ virDomainEventTunableDispose(void *obj)
9119d9
     virTypedParamsFree(event->params, event->nparams);
9119d9
 }
9119d9
 
9119d9
+static void
9119d9
+virDomainEventAgentLifecycleDispose(void *obj)
9119d9
+{
9119d9
+    virDomainEventAgentLifecyclePtr event = obj;
9119d9
+    VIR_DEBUG("obj=%p", event);
9119d9
+};
9119d9
+
9119d9
 
9119d9
 static void *
9119d9
 virDomainEventNew(virClassPtr klass,
9119d9
@@ -1202,6 +1226,49 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
9119d9
                                           devAlias);
9119d9
 }
9119d9
 
9119d9
+
9119d9
+static virObjectEventPtr
9119d9
+virDomainEventAgentLifecycleNew(int id,
9119d9
+                                const char *name,
9119d9
+                                const unsigned char *uuid,
9119d9
+                                int state,
9119d9
+                                int reason)
9119d9
+{
9119d9
+    virDomainEventAgentLifecyclePtr ev;
9119d9
+
9119d9
+    if (virDomainEventsInitialize() < 0)
9119d9
+        return NULL;
9119d9
+
9119d9
+    if (!(ev = virDomainEventNew(virDomainEventAgentLifecycleClass,
9119d9
+                                 VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE,
9119d9
+                                 id, name, uuid)))
9119d9
+        return NULL;
9119d9
+
9119d9
+    ev->state = state;
9119d9
+    ev->reason = reason;
9119d9
+
9119d9
+    return (virObjectEventPtr)ev;
9119d9
+}
9119d9
+
9119d9
+virObjectEventPtr
9119d9
+virDomainEventAgentLifecycleNewFromObj(virDomainObjPtr obj,
9119d9
+                                       int state,
9119d9
+                                       int reason)
9119d9
+{
9119d9
+    return virDomainEventAgentLifecycleNew(obj->def->id, obj->def->name,
9119d9
+                                           obj->def->uuid, state, reason);
9119d9
+}
9119d9
+
9119d9
+virObjectEventPtr
9119d9
+virDomainEventAgentLifecycleNewFromDom(virDomainPtr dom,
9119d9
+                                       int state,
9119d9
+                                       int reason)
9119d9
+{
9119d9
+    return virDomainEventAgentLifecycleNew(dom->id, dom->name, dom->uuid,
9119d9
+                                           state, reason);
9119d9
+}
9119d9
+
9119d9
+
9119d9
 /* This function consumes the params so caller don't have to care about
9119d9
  * freeing it even if error occurs. The reason is to not have to do deep
9119d9
  * copy of params.
9119d9
@@ -1459,6 +1526,17 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
9119d9
             goto cleanup;
9119d9
         }
9119d9
 
9119d9
+    case VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE:
9119d9
+        {
9119d9
+            virDomainEventAgentLifecyclePtr agentLifecycleEvent;
9119d9
+            agentLifecycleEvent = (virDomainEventAgentLifecyclePtr)event;
9119d9
+            ((virConnectDomainEventAgentLifecycleCallback)cb)(conn, dom,
9119d9
+                                                              agentLifecycleEvent->state,
9119d9
+                                                              agentLifecycleEvent->reason,
9119d9
+                                                              cbopaque);
9119d9
+            goto cleanup;
9119d9
+        }
9119d9
+
9119d9
     case VIR_DOMAIN_EVENT_ID_LAST:
9119d9
         break;
9119d9
     }
9119d9
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
9119d9
index dc0109c..534ff9e 100644
9119d9
--- a/src/conf/domain_event.h
9119d9
+++ b/src/conf/domain_event.h
9119d9
@@ -193,6 +193,15 @@ virDomainEventTunableNewFromDom(virDomainPtr dom,
9119d9
                                 virTypedParameterPtr params,
9119d9
                                 int nparams);
9119d9
 
9119d9
+virObjectEventPtr
9119d9
+virDomainEventAgentLifecycleNewFromObj(virDomainObjPtr obj,
9119d9
+                                       int state,
9119d9
+                                       int reason);
9119d9
+
9119d9
+virObjectEventPtr
9119d9
+virDomainEventAgentLifecycleNewFromDom(virDomainPtr dom,
9119d9
+                                       int state,
9119d9
+                                       int reason);
9119d9
 
9119d9
 int
9119d9
 virDomainEventStateRegister(virConnectPtr conn,
9119d9
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
9119d9
index 15843f8..6353d9c 100644
9119d9
--- a/src/libvirt_private.syms
9119d9
+++ b/src/libvirt_private.syms
9119d9
@@ -435,6 +435,8 @@ virDomainXMLOptionNew;
9119d9
 
9119d9
 
9119d9
 # conf/domain_event.h
9119d9
+virDomainEventAgentLifecycleNewFromDom;
9119d9
+virDomainEventAgentLifecycleNewFromObj;
9119d9
 virDomainEventBalloonChangeNewFromDom;
9119d9
 virDomainEventBalloonChangeNewFromObj;
9119d9
 virDomainEventBlockJob2NewFromDom;
9119d9
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
9119d9
index 6f7c894..59d4def 100644
9119d9
--- a/src/remote/remote_driver.c
9119d9
+++ b/src/remote/remote_driver.c
9119d9
@@ -331,6 +331,11 @@ remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog,
9119d9
                                       void *evdata, void *opaque);
9119d9
 
9119d9
 static void
9119d9
+remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog,
9119d9
+                                             virNetClientPtr client,
9119d9
+                                             void *evdata, void *opaque);
9119d9
+
9119d9
+static void
9119d9
 remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
9119d9
                                  virNetClientPtr client ATTRIBUTE_UNUSED,
9119d9
                                  void *evdata, void *opaque);
9119d9
@@ -485,6 +490,10 @@ static virNetClientProgramEvent remoteEvents[] = {
9119d9
       remoteDomainBuildEventCallbackTunable,
9119d9
       sizeof(remote_domain_event_callback_tunable_msg),
9119d9
       (xdrproc_t)xdr_remote_domain_event_callback_tunable_msg },
9119d9
+    { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE,
9119d9
+      remoteDomainBuildEventCallbackAgentLifecycle,
9119d9
+      sizeof(remote_domain_event_callback_agent_lifecycle_msg),
9119d9
+      (xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg },
9119d9
 };
9119d9
 
9119d9
 
9119d9
@@ -5542,6 +5551,28 @@ remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog ATTRIBUTE_UNUS
9119d9
 
9119d9
 
9119d9
 static void
9119d9
+remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
9119d9
+                                             virNetClientPtr client ATTRIBUTE_UNUSED,
9119d9
+                                             void *evdata, void *opaque)
9119d9
+{
9119d9
+    virConnectPtr conn = opaque;
9119d9
+    remote_domain_event_callback_agent_lifecycle_msg *msg = evdata;
9119d9
+    struct private_data *priv = conn->privateData;
9119d9
+    virDomainPtr dom;
9119d9
+    virObjectEventPtr event = NULL;
9119d9
+
9119d9
+    if (!(dom = get_nonnull_domain(conn, msg->dom)))
9119d9
+        return;
9119d9
+
9119d9
+    event = virDomainEventAgentLifecycleNewFromDom(dom, msg->state,
9119d9
+                                                   msg->reason);
9119d9
+
9119d9
+    virDomainFree(dom);
9119d9
+
9119d9
+    remoteEventQueue(priv, event, msg->callbackID);
9119d9
+}
9119d9
+
9119d9
+static void
9119d9
 remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
9119d9
                                  virNetClientPtr client ATTRIBUTE_UNUSED,
9119d9
                                  void *evdata, void *opaque)
9119d9
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
9119d9
index ee195c4..82f3902 100644
9119d9
--- a/src/remote/remote_protocol.x
9119d9
+++ b/src/remote/remote_protocol.x
9119d9
@@ -3086,6 +3086,14 @@ struct remote_connect_get_all_domain_stats_args {
9119d9
     unsigned int flags;
9119d9
 };
9119d9
 
9119d9
+struct remote_domain_event_callback_agent_lifecycle_msg {
9119d9
+    int callbackID;
9119d9
+    remote_nonnull_domain dom;
9119d9
+
9119d9
+    int state;
9119d9
+    int reason;
9119d9
+};
9119d9
+
9119d9
 struct remote_connect_get_all_domain_stats_ret {
9119d9
     remote_domain_stats_record retStats<REMOTE_DOMAIN_LIST_MAX>;
9119d9
 };
9119d9
@@ -5472,5 +5480,11 @@ enum remote_procedure {
9119d9
      * @generate: both
9119d9
      * @acl: none
9119d9
      */
9119d9
-    REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE = 346
9119d9
+    REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE = 346,
9119d9
+
9119d9
+    /**
9119d9
+     * @generate: both
9119d9
+     * @acl: none
9119d9
+     */
9119d9
+    REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE = 348
9119d9
 };
9119d9
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
9119d9
index 9d6d104..22097c4 100644
9119d9
--- a/src/remote_protocol-structs
9119d9
+++ b/src/remote_protocol-structs
9119d9
@@ -2547,6 +2547,12 @@ struct remote_connect_get_all_domain_stats_args {
9119d9
         u_int                      stats;
9119d9
         u_int                      flags;
9119d9
 };
9119d9
+struct remote_domain_event_callback_agent_lifecycle_msg {
9119d9
+        int                        callbackID;
9119d9
+        remote_nonnull_domain      dom;
9119d9
+        int                        state;
9119d9
+        int                        reason;
9119d9
+};
9119d9
 struct remote_connect_get_all_domain_stats_ret {
9119d9
         struct {
9119d9
                 u_int              retStats_len;
9119d9
@@ -2899,4 +2905,5 @@ enum remote_procedure {
9119d9
         REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD = 343,
9119d9
         REMOTE_PROC_CONNECT_GET_ALL_DOMAIN_STATS = 344,
9119d9
         REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE = 346,
9119d9
+        REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE = 348,
9119d9
 };
9119d9
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
9119d9
index 68c28fa..28f5319 100644
9119d9
--- a/tools/virsh-domain.c
9119d9
+++ b/tools/virsh-domain.c
9119d9
@@ -11276,6 +11276,43 @@ vshEventTunablePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
9119d9
         vshEventDone(data->ctl);
9119d9
 }
9119d9
 
9119d9
+VIR_ENUM_DECL(vshEventAgentLifecycleState)
9119d9
+VIR_ENUM_IMPL(vshEventAgentLifecycleState,
9119d9
+              VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_LAST,
9119d9
+              N_("unknown"),
9119d9
+              N_("connected"),
9119d9
+              N_("disconnected"))
9119d9
+
9119d9
+VIR_ENUM_DECL(vshEventAgentLifecycleReason)
9119d9
+VIR_ENUM_IMPL(vshEventAgentLifecycleReason,
9119d9
+              VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_LAST,
9119d9
+              N_("unknown"),
9119d9
+              N_("domain started"),
9119d9
+              N_("channel event"))
9119d9
+
9119d9
+#define UNKNOWNSTR(str) (str ? str : N_("unsupported value"))
9119d9
+static void
9119d9
+vshEventAgentLifecyclePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
9119d9
+                            virDomainPtr dom,
9119d9
+                            int state,
9119d9
+                            int reason,
9119d9
+                            void *opaque)
9119d9
+{
9119d9
+    vshDomEventData *data = opaque;
9119d9
+
9119d9
+    if (!data->loop && *data->count)
9119d9
+        return;
9119d9
+    vshPrint(data->ctl,
9119d9
+             _("event 'agent-lifecycle' for domain %s: state: '%s' reason: '%s'\n"),
9119d9
+             virDomainGetName(dom),
9119d9
+             UNKNOWNSTR(vshEventAgentLifecycleStateTypeToString(state)),
9119d9
+             UNKNOWNSTR(vshEventAgentLifecycleReasonTypeToString(reason)));
9119d9
+
9119d9
+    (*data->count)++;
9119d9
+    if (!data->loop)
9119d9
+        vshEventDone(data->ctl);
9119d9
+}
9119d9
+
9119d9
 static vshEventCallback vshEventCallbacks[] = {
9119d9
     { "lifecycle",
9119d9
       VIR_DOMAIN_EVENT_CALLBACK(vshEventLifecyclePrint), },
9119d9
@@ -11311,6 +11348,8 @@ static vshEventCallback vshEventCallbacks[] = {
9119d9
       VIR_DOMAIN_EVENT_CALLBACK(vshEventBlockJobPrint), },
9119d9
     { "tunable",
9119d9
       VIR_DOMAIN_EVENT_CALLBACK(vshEventTunablePrint), },
9119d9
+    { "agent-lifecycle",
9119d9
+      VIR_DOMAIN_EVENT_CALLBACK(vshEventAgentLifecyclePrint), },
9119d9
 };
9119d9
 verify(VIR_DOMAIN_EVENT_ID_LAST == ARRAY_CARDINALITY(vshEventCallbacks));
9119d9
 
9119d9
-- 
9119d9
2.1.3
9119d9