domain is or becomes inactive
+ *guest-agent-available*
+
+ the guest agent inside the guest connects and becomes available for commands
+ (usually means that the guest has booted)
+
If *--timeout* is specified, the command gives up waiting for the condition to
satisfy after *seconds* have elapsed. If SIGINT is delivered to virsh
(usually via ``Ctrl-C``) the wait is given up immediately. In non-interactive
#include "virenum.h"
#include "virtime.h"
#include "virtypedparam.h"
+#include "virxml.h"
/*
* "event" command
}
+static void
+virshDomainEventAwaitAgentLifecycle(virConnectPtr conn G_GNUC_UNUSED,
+ virDomainPtr dom G_GNUC_UNUSED,
+ int state G_GNUC_UNUSED,
+ int reason G_GNUC_UNUSED,
+ void *opaque G_GNUC_UNUSED)
+{
+ struct virshDomEventAwaitConditionData *data = opaque;
+
+ if (data->cond->handler(data) < 1)
+ vshEventDone(data->ctl);
+}
+
+
struct virshDomainEventAwaitCallbackTuple {
int event;
virConnectDomainEventGenericCallback eventCB;
{ .event = VIR_DOMAIN_EVENT_ID_LIFECYCLE,
.eventCB = VIR_DOMAIN_EVENT_CALLBACK(virshDomainEventAwaitCallbackLifecycle),
},
+ { .event = VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE,
+ .eventCB = VIR_DOMAIN_EVENT_CALLBACK(virshDomainEventAwaitAgentLifecycle),
+ },
};
}
+static int
+virshDomainEventAwaitConditionGuestAgentAvailable(struct virshDomEventAwaitConditionData *data)
+{
+ g_autoptr(xmlDoc) xml = NULL;
+ g_autoptr(xmlXPathContext) ctxt = NULL;
+ g_autofree char *state = NULL;
+
+ if (virshDomainGetXMLFromDom(data->ctl, data->dom, 0, &xml, &ctxt) < 0)
+ return -1;
+
+ if ((state = virXPathString("string(//devices/channel/target[@name = 'org.qemu.guest_agent.0']/@state)",
+ ctxt))) {
+ if (STREQ(state, "connected"))
+ return 0;
+ }
+
+ return 1;
+}
+
+
static const struct virshDomainEventAwaitCondition conditions[] = {
{ .name = "domain-inactive",
.event = VIR_DOMAIN_EVENT_ID_LIFECYCLE,
.handler = virshDomainEventAwaitConditionDomainInactive,
},
+ { .name = "guest-agent-available",
+ .event = VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE,
+ .handler = virshDomainEventAwaitConditionGuestAgentAvailable,
+ },
};