On 04/04/2015 01:16 PM, Ján Tomko wrote:
The counterpart to VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED.
https://bugzilla.redhat.com/show_bug.cgi?id=1206114
---
daemon/remote.c | 37 +++++++++++++++++++
include/libvirt/libvirt-domain.h | 18 ++++++++++
src/conf/domain_event.c | 77 ++++++++++++++++++++++++++++++++++++++++
src/conf/domain_event.h | 6 ++++
src/libvirt_private.syms | 2 ++
src/remote/remote_driver.c | 29 +++++++++++++++
src/remote/remote_protocol.x | 14 +++++++-
src/remote_protocol-structs | 6 ++++
tools/virsh-domain.c | 20 +++++++++++
9 files changed, 208 insertions(+), 1 deletion(-)
I searched on VIR_DOMAIN_EVENT_ID_DEVICE - what about
examples/object-events/event-test.c ?
Also should 'src/libvirt-domain.c' have a description for the _ADDED
flag in 'virDomainAttachDeviceFlags' like there is for _REMOVED in
'virDomainDetachDeviceFlags'? (although even that text is a bit shy of
an 'a' - as in "or add a handler for" rather than "or add handler
for"
<sigh>
ACK in general for what's here and with the new test and change to
AttachDevice description...
John
diff --git a/daemon/remote.c b/daemon/remote.c
index 2e1f973..3a3f168 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1045,6 +1045,42 @@ remoteRelayDomainEventAgentLifecycle(virConnectPtr conn,
}
+static int
+remoteRelayDomainEventDeviceAdded(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *devAlias,
+ void *opaque)
+{
+ daemonClientEventCallbackPtr callback = opaque;
+ remote_domain_event_callback_device_added_msg data;
+
+ if (callback->callbackID < 0 ||
+ !remoteRelayDomainEventCheckACL(callback->client, conn, dom))
+ return -1;
+
+ VIR_DEBUG("Relaying domain device added event %s %d %s, callback %d",
+ dom->name, dom->id, devAlias, callback->callbackID);
+
+ /* build return data */
+ memset(&data, 0, sizeof(data));
+
+ if (VIR_STRDUP(data.devAlias, devAlias) < 0)
+ return -1;
+
+ make_nonnull_domain(&data.dom, dom);
+ data.callbackID = callback->callbackID,
+
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
+ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED,
+
(xdrproc_t)xdr_remote_domain_event_callback_device_added_msg,
+ &data);
+
+ return 0;
+}
+
+
+
+
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@@ -1065,6 +1101,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[]
= {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob2),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTunable),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventAgentLifecycle),
+ VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceAdded),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 7be4219..8a4fe53 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3202,6 +3202,23 @@ typedef void
(*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn,
void *opaque);
/**
+ * virConnectDomainEventDeviceAddedCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @devAlias: device alias
+ * @opaque: application specified data
+ *
+ * This callback occurs when a device is added to the domain.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_DOMAIN_EVENT_ID_DEVICE_ADDED with virConnectDomainEventRegisterAny()
+ */
+typedef void (*virConnectDomainEventDeviceAddedCallback)(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *devAlias,
+ void *opaque);
+
+/**
* VIR_DOMAIN_TUNABLE_CPU_VCPUPIN:
*
* Macro represents formatted pinning for one vcpu specified by id which is
@@ -3483,6 +3500,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2 = 16, /* virConnectDomainEventBlockJobCallback
*/
VIR_DOMAIN_EVENT_ID_TUNABLE = 17, /* virConnectDomainEventTunableCallback */
VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE = 18,/*
virConnectDomainEventAgentLifecycleCallback */
+ VIR_DOMAIN_EVENT_ID_DEVICE_ADDED = 19, /* virConnectDomainEventDeviceAddedCallback
*/
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_ID_LAST
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 2786c1e..20d66e1 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -55,6 +55,7 @@ static virClassPtr virDomainEventPMClass;
static virClassPtr virDomainQemuMonitorEventClass;
static virClassPtr virDomainEventTunableClass;
static virClassPtr virDomainEventAgentLifecycleClass;
+static virClassPtr virDomainEventDeviceAddedClass;
static void virDomainEventDispose(void *obj);
@@ -72,6 +73,7 @@ static void virDomainEventPMDispose(void *obj);
static void virDomainQemuMonitorEventDispose(void *obj);
static void virDomainEventTunableDispose(void *obj);
static void virDomainEventAgentLifecycleDispose(void *obj);
+static void virDomainEventDeviceAddedDispose(void *obj);
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
@@ -189,6 +191,14 @@ struct _virDomainEventDeviceRemoved {
typedef struct _virDomainEventDeviceRemoved virDomainEventDeviceRemoved;
typedef virDomainEventDeviceRemoved *virDomainEventDeviceRemovedPtr;
+struct _virDomainEventDeviceAdded {
+ virDomainEvent parent;
+
+ char *devAlias;
+};
+typedef struct _virDomainEventDeviceAdded virDomainEventDeviceAdded;
+typedef virDomainEventDeviceAdded *virDomainEventDeviceAddedPtr;
+
struct _virDomainEventPM {
virDomainEvent parent;
@@ -296,6 +306,12 @@ virDomainEventsOnceInit(void)
sizeof(virDomainEventDeviceRemoved),
virDomainEventDeviceRemovedDispose)))
return -1;
+ if (!(virDomainEventDeviceAddedClass =
+ virClassNew(virDomainEventClass,
+ "virDomainEventDeviceAdded",
+ sizeof(virDomainEventDeviceAdded),
+ virDomainEventDeviceAddedDispose)))
+ return -1;
if (!(virDomainEventPMClass =
virClassNew(virDomainEventClass,
"virDomainEventPM",
@@ -439,6 +455,15 @@ virDomainEventDeviceRemovedDispose(void *obj)
}
static void
+virDomainEventDeviceAddedDispose(void *obj)
+{
+ virDomainEventDeviceAddedPtr event = obj;
+ VIR_DEBUG("obj=%p", event);
+
+ VIR_FREE(event->devAlias);
+}
+
+static void
virDomainEventPMDispose(void *obj)
{
virDomainEventPMPtr event = obj;
@@ -1226,6 +1251,47 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
devAlias);
}
+static virObjectEventPtr
+virDomainEventDeviceAddedNew(int id,
+ const char *name,
+ unsigned char *uuid,
+ const char *devAlias)
+{
+ virDomainEventDeviceAddedPtr ev;
+
+ if (virDomainEventsInitialize() < 0)
+ return NULL;
+
+ if (!(ev = virDomainEventNew(virDomainEventDeviceAddedClass,
+ VIR_DOMAIN_EVENT_ID_DEVICE_ADDED,
+ id, name, uuid)))
+ return NULL;
+
+ if (VIR_STRDUP(ev->devAlias, devAlias) < 0)
+ goto error;
+
+ return (virObjectEventPtr)ev;
+
+ error:
+ virObjectUnref(ev);
+ return NULL;
+}
+
+virObjectEventPtr
+virDomainEventDeviceAddedNewFromObj(virDomainObjPtr obj,
+ const char *devAlias)
+{
+ return virDomainEventDeviceAddedNew(obj->def->id, obj->def->name,
+ obj->def->uuid, devAlias);
+}
+
+virObjectEventPtr
+virDomainEventDeviceAddedNewFromDom(virDomainPtr dom,
+ const char *devAlias)
+{
+ return virDomainEventDeviceAddedNew(dom->id, dom->name, dom->uuid,
+ devAlias);
+}
static virObjectEventPtr
virDomainEventAgentLifecycleNew(int id,
@@ -1537,6 +1603,17 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
goto cleanup;
}
+ case VIR_DOMAIN_EVENT_ID_DEVICE_ADDED:
+ {
+ virDomainEventDeviceAddedPtr deviceAddedEvent;
+
+ deviceAddedEvent = (virDomainEventDeviceAddedPtr)event;
+ ((virConnectDomainEventDeviceAddedCallback)cb)(conn, dom,
+
deviceAddedEvent->devAlias,
+ cbopaque);
+ goto cleanup;
+ }
+
case VIR_DOMAIN_EVENT_ID_LAST:
break;
}
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index 534ff9e..afbed89 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -185,6 +185,12 @@ virObjectEventPtr
virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
const char *devAlias);
virObjectEventPtr
+virDomainEventDeviceAddedNewFromObj(virDomainObjPtr obj,
+ const char *devAlias);
+virObjectEventPtr
+virDomainEventDeviceAddedNewFromDom(virDomainPtr dom,
+ const char *devAlias);
+virObjectEventPtr
virDomainEventTunableNewFromObj(virDomainObjPtr obj,
virTypedParameterPtr params,
int nparams);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9f82926..cbd8089 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -486,6 +486,8 @@ virDomainEventBlockJobNewFromDom;
virDomainEventBlockJobNewFromObj;
virDomainEventControlErrorNewFromDom;
virDomainEventControlErrorNewFromObj;
+virDomainEventDeviceAddedNewFromDom;
+virDomainEventDeviceAddedNewFromObj;
virDomainEventDeviceRemovedNewFromDom;
virDomainEventDeviceRemovedNewFromObj;
virDomainEventDiskChangeNewFromDom;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index b275d86..9c3b53f 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -321,6 +321,10 @@ static void
remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
+static void
+remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgramPtr prog,
+ virNetClientPtr client,
+ void *evdata, void *opaque);
static void
remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog,
@@ -496,6 +500,10 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteDomainBuildEventCallbackAgentLifecycle,
sizeof(remote_domain_event_callback_agent_lifecycle_msg),
(xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg },
+ { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED,
+ remoteDomainBuildEventCallbackDeviceAdded,
+ sizeof(remote_domain_event_callback_device_added_msg),
+ (xdrproc_t)xdr_remote_domain_event_callback_device_added_msg },
};
@@ -5431,6 +5439,27 @@ remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr
prog ATTRIBUT
remoteDomainBuildEventDeviceRemovedHelper(conn, &msg->msg,
msg->callbackID);
}
+static void
+remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
+ virNetClientPtr client ATTRIBUTE_UNUSED,
+ void *evdata, void *opaque)
+{
+ virConnectPtr conn = opaque;
+ remote_domain_event_callback_device_added_msg *msg = evdata;
+ struct private_data *priv = conn->privateData;
+ virDomainPtr dom;
+ virObjectEventPtr event = NULL;
+
+ dom = get_nonnull_domain(conn, msg->dom);
+ if (!dom)
+ return;
+
+ event = virDomainEventDeviceAddedNewFromDom(dom, msg->devAlias);
+
+ virObjectUnref(dom);
+
+ remoteEventQueue(priv, event, msg->callbackID);
+}
static void
remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index d90e6b5..b02e58c 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3045,6 +3045,12 @@ struct remote_domain_event_callback_tunable_msg {
remote_typed_param params<REMOTE_DOMAIN_EVENT_TUNABLE_MAX>;
};
+struct remote_domain_event_callback_device_added_msg {
+ int callbackID;
+ remote_nonnull_domain dom;
+ remote_nonnull_string devAlias;
+};
+
struct remote_connect_get_cpu_model_names_args {
remote_nonnull_string arch;
int need_results;
@@ -5643,5 +5649,11 @@ enum remote_procedure {
* @generate: none
* @acl: domain:read
*/
- REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353
+ REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353,
+
+ /**
+ * @generate: both
+ * @acl: none
+ */
+ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED = 354
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index e614f77..2b6b47a 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2487,6 +2487,11 @@ struct remote_domain_event_callback_tunable_msg {
remote_typed_param * params_val;
} params;
};
+struct remote_domain_event_callback_device_added_msg {
+ int callbackID;
+ remote_nonnull_domain dom;
+ remote_nonnull_string devAlias;
+};
struct remote_connect_get_cpu_model_names_args {
remote_nonnull_string arch;
int need_results;
@@ -3017,4 +3022,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_GET_IOTHREAD_INFO = 351,
REMOTE_PROC_DOMAIN_PIN_IOTHREAD = 352,
REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353,
+ REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED = 354,
};
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 020a308..aeacf59 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -11959,6 +11959,24 @@ vshEventDeviceRemovedPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
}
static void
+vshEventDeviceAddedPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *alias,
+ void *opaque)
+{
+ vshDomEventData *data = opaque;
+
+ if (!data->loop && *data->count)
+ return;
+ vshPrint(data->ctl,
+ _("event 'device-added' for domain %s: %s\n"),
+ virDomainGetName(dom), alias);
+ (*data->count)++;
+ if (!data->loop)
+ vshEventDone(data->ctl);
+}
+
+static void
vshEventTunablePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
virTypedParameterPtr params,
@@ -12063,6 +12081,8 @@ static vshEventCallback vshEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(vshEventTunablePrint), },
{ "agent-lifecycle",
VIR_DOMAIN_EVENT_CALLBACK(vshEventAgentLifecyclePrint), },
+ { "device-added",
+ VIR_DOMAIN_EVENT_CALLBACK(vshEventDeviceAddedPrint), },
};
verify(VIR_DOMAIN_EVENT_ID_LAST == ARRAY_CARDINALITY(vshEventCallbacks));