This patch introduces a new event type for the QMP event
DEVICE_TRAY_MOVED, which occurs when the tray of a removable
disk is moved (i.e opened or closed):
VIR_DOMAIN_EVENT_ID_TRAY_MOVED
The event's data includes the device alias and the tray's
status, which indicates whether the tray has been opened
or closed. Thus the callback definition for the event is:
typedef void
(*virConnectDomainEventTrayMovedCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *devAlias,
unsigned int trayOpened,
void *opaque);
---
daemon/remote.c | 33 +++++++++++
examples/domain-events/events-c/event-test.c | 21 +++++++-
examples/domain-events/events-python/event-test.py | 4 ++
include/libvirt/libvirt.h.in | 20 +++++++
python/libvirt-override-virConnect.py | 10 ++++
python/libvirt-override.c | 50 +++++++++++++++++
src/conf/domain_event.c | 58 ++++++++++++++++++++
src/conf/domain_event.h | 6 ++
src/libvirt_private.syms | 2 +
src/qemu/qemu_monitor.c | 13 +++++
src/qemu/qemu_monitor.h | 7 +++
src/qemu/qemu_monitor_json.c | 18 ++++++
src/qemu/qemu_process.c | 32 +++++++++++
src/remote/remote_driver.c | 34 ++++++++++++
src/remote/remote_protocol.x | 9 +++-
src/remote_protocol-structs | 5 ++
16 files changed, 320 insertions(+), 2 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 74a5f16..cc464fd 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -505,6 +505,38 @@ mem_error:
}
+static int remoteRelayDomainEventTrayMoved(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *devAlias,
+ unsigned int trayOpened,
+ void *opaque) {
+ virNetServerClientPtr client = opaque;
+ remote_domain_event_tray_moved_msg data;
+
+ if (!client)
+ return -1;
+
+ VIR_DEBUG("Relaying domain %s %d tray moved devAlias: %s trayOpened: %s",
+ dom->name, dom->id, devAlias, trayOpened ? "yes":
"no");
+
+ /* build return data */
+ memset(&data, 0, sizeof data);
+
+ if (!(data.devAlias = strdup(devAlias))) {
+ virReportOOMError();
+ return -1;
+ }
+ data.trayOpened = trayOpened;
+
+ make_nonnull_domain(&data.dom, dom);
+
+ remoteDispatchDomainEventSend(client, remoteProgram,
+ REMOTE_PROC_DOMAIN_EVENT_TRAY_MOVED,
+ (xdrproc_t)xdr_remote_domain_event_tray_moved_msg,
&data);
+
+ return 0;
+}
+
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
@@ -516,6 +548,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] =
{
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventControlError),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange),
+ VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTrayMoved),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/examples/domain-events/events-c/event-test.c
b/examples/domain-events/events-c/event-test.c
index f4938c4..c7bcaeb 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -313,6 +313,17 @@ static int myDomainEventDiskChangeCallback(virConnectPtr conn
ATTRIBUTE_UNUSED,
return 0;
}
+static int myDomainEventTrayMovedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *devAlias,
+ unsigned int trayOpened,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) removable disk's tray moved devAlias: %s
trayOpened: %s\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom),
+ devAlias, trayOpened ? "yes" : "no");
+ return 0;
+}
static void myFreeFunc(void *opaque)
{
@@ -349,6 +360,7 @@ int main(int argc, char **argv)
int callback7ret = -1;
int callback8ret = -1;
int callback9ret = -1;
+ int callback10ret = -1;
struct sigaction action_stop;
memset(&action_stop, 0, sizeof action_stop);
@@ -419,6 +431,11 @@ int main(int argc, char **argv)
VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventDiskChangeCallback),
strdup("disk change"),
myFreeFunc);
+ callback10ret = virConnectDomainEventRegisterAny(dconn,
+ NULL,
+ VIR_DOMAIN_EVENT_ID_TRAY_MOVED,
+
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventTrayMovedCallback),
+ strdup("tray moved"),
myFreeFunc);
if ((callback1ret != -1) &&
(callback2ret != -1) &&
@@ -427,7 +444,8 @@ int main(int argc, char **argv)
(callback5ret != -1) &&
(callback6ret != -1) &&
(callback7ret != -1) &&
- (callback9ret != -1)) {
+ (callback9ret != -1) &&
+ (callback10ret != -1)) {
if (virConnectSetKeepAlive(dconn, 5, 3) < 0) {
virErrorPtr err = virGetLastError();
fprintf(stderr, "Failed to start keepalive protocol: %s\n",
@@ -452,6 +470,7 @@ int main(int argc, char **argv)
virConnectDomainEventDeregisterAny(dconn, callback6ret);
virConnectDomainEventDeregisterAny(dconn, callback7ret);
virConnectDomainEventDeregisterAny(dconn, callback9ret);
+ virConnectDomainEventDeregisterAny(dconn, callback10ret);
if (callback8ret != -1)
virConnectDomainEventDeregisterAny(dconn, callback8ret);
}
diff --git a/examples/domain-events/events-python/event-test.py
b/examples/domain-events/events-python/event-test.py
index 0c75091..f2f5597 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -474,6 +474,9 @@ def myDomainEventGraphicsCallback(conn, dom, phase, localAddr,
remoteAddr, authS
def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, reason,
opaque):
print "myDomainEventDiskChangeCallback: Domain %s(%s) disk change oldSrcPath: %s
newSrcPath: %s devAlias: %s reason: %s" % (
dom.name(), dom.ID(), oldSrcPath, newSrcPath, devAlias, reason)
+def myDomainEventTrayMovedCallback(conn, dom, devAlias, trayOpened, opaque):
+ print "myDomainEventTrayMovedCallback: Domain %s(%s) tray moved devAlias: %s
trayOpened: %d" % (
+ dom.name(), dom.ID(), devAlias, trayOpened)
def usage(out=sys.stderr):
print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl]
[uri]"
print >>out, " uri will default to qemu:///system"
@@ -532,6 +535,7 @@ def main():
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG,
myDomainEventWatchdogCallback, None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS,
myDomainEventGraphicsCallback, None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
myDomainEventDiskChangeCallback, None)
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_TRAY_MOVED,
myDomainEventTrayMovedCallback, None)
vc.setKeepAlive(5, 3)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 58c4366..730f2a3 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -3643,6 +3643,25 @@ typedef void
(*virConnectDomainEventDiskChangeCallback)(virConnectPtr conn,
const char *devAlias,
int reason,
void *opaque);
+/**
+ * virConnectDomainEventTrayMovedCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @devAlias: device alias
+ * @trayOpened: the tray has been opened?
+ * @opaque: application specified data
+ *
+ * This callback occurs when the tray of a removable device is moved.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_DOMAIN_EVENT_ID_TRAY_MOVED with virConnectDomainEventRegisterAny()
+ */
+typedef void (*virConnectDomainEventTrayMovedCallback)(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *devAlias,
+ unsigned int trayOpened,
+ void *opaque);
+
/**
* VIR_DOMAIN_EVENT_CALLBACK:
@@ -3664,6 +3683,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_CONTROL_ERROR = 7, /* virConnectDomainEventGenericCallback */
VIR_DOMAIN_EVENT_ID_BLOCK_JOB = 8, /* virConnectDomainEventBlockJobCallback */
VIR_DOMAIN_EVENT_ID_DISK_CHANGE = 9, /* virConnectDomainEventDiskChangeCallback
*/
+ VIR_DOMAIN_EVENT_ID_TRAY_MOVED = 10, /* virConnectDomainEventTrayMovedCallback
*/
#ifdef VIR_ENUM_SENTINELS
/*
diff --git a/python/libvirt-override-virConnect.py
b/python/libvirt-override-virConnect.py
index b908b32..e93efa7 100644
--- a/python/libvirt-override-virConnect.py
+++ b/python/libvirt-override-virConnect.py
@@ -134,6 +134,16 @@
cb(self, virDomain(self, _obj=dom), oldSrcPath, newSrcPath, devAlias, reason,
opaque)
return 0;
+ def _dispatchDomainEventTrayMovedCallback(self, dom, devAlias, trayOpened, cbData):
+ """Dispatches event to python user domain trayMoved event
callbacks
+ """
+ cb = cbData["cb"]
+ opaque = cbData["opaque"]
+
+ cb(self, virDomain(self, _obj=dom), devAlias, trayOpened, opaque)
+ return 0;
+
+
def domainEventDeregisterAny(self, callbackID):
"""Removes a Domain Event Callback. De-registering for a
domain callback will disable delivery of this event type """
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 792cfa3..976c5d8 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -4927,6 +4927,53 @@ libvirt_virConnectDomainEventDiskChangeCallback(virConnectPtr conn
ATTRIBUTE_UNU
return ret;
}
+static int
+libvirt_virConnectDomainEventTrayMovedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *devAlias,
+ unsigned int trayOpened,
+ void *opaque)
+{
+ PyObject *pyobj_cbData = (PyObject*)opaque;
+ PyObject *pyobj_dom;
+ PyObject *pyobj_ret;
+ PyObject *pyobj_conn;
+ PyObject *dictKey;
+ int ret = -1;
+
+ LIBVIRT_ENSURE_THREAD_STATE;
+ /* Create a python instance of this virDomainPtr */
+ virDomainRef(dom);
+
+ pyobj_dom = libvirt_virDomainPtrWrap(dom);
+ Py_INCREF(pyobj_cbData);
+
+ dictKey = libvirt_constcharPtrWrap("conn");
+ pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
+ Py_DECREF(dictKey);
+
+ /* Call the Callback Dispatcher */
+ pyobj_ret = PyObject_CallMethod(pyobj_conn,
+
(char*)"_dispatchDomainEventTrayMovedCallback",
+ (char*)"OsiO",
+ pyobj_dom,
+ devAlias, trayOpened, pyobj_cbData);
+
+ Py_DECREF(pyobj_cbData);
+ Py_DECREF(pyobj_dom);
+
+ if(!pyobj_ret) {
+ DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
+ PyErr_Print();
+ } else {
+ Py_DECREF(pyobj_ret);
+ ret = 0;
+ }
+
+ LIBVIRT_RELEASE_THREAD_STATE;
+ return ret;
+}
+
static PyObject *
libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
PyObject * args)
@@ -4987,6 +5034,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject *
self,
case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventDiskChangeCallback);
break;
+ case VIR_DOMAIN_EVENT_ID_TRAY_MOVED:
+ cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventTrayMovedCallback);
+ break;
}
if (!cb) {
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 1d8b45d..dbd1bf1 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -117,6 +117,10 @@ struct _virDomainEvent {
char *devAlias;
int reason;
} diskChange;
+ struct {
+ char *devAlias;
+ unsigned int trayOpened :1;
+ } trayMoved;
} data;
};
@@ -546,6 +550,9 @@ void virDomainEventFree(virDomainEventPtr event)
VIR_FREE(event->data.diskChange.newSrcPath);
VIR_FREE(event->data.diskChange.devAlias);
break;
+ case VIR_DOMAIN_EVENT_ID_TRAY_MOVED:
+ VIR_FREE(event->data.trayMoved.devAlias);
+ break;
}
VIR_FREE(event->dom.name);
@@ -1043,6 +1050,50 @@ virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr
dom,
devAlias, reason);
}
+static virDomainEventPtr
+virDomainEventTrayMovedNew(int id, const char *name,
+ unsigned char *uuid,
+ const char *devAlias,
+ unsigned int trayOpened)
+{
+ virDomainEventPtr ev =
+ virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_TRAY_MOVED,
+ id, name, uuid);
+
+ if (ev) {
+ if (!(ev->data.trayMoved.devAlias = strdup(devAlias)))
+ goto error;
+
+ ev->data.trayMoved.trayOpened = trayOpened;
+ }
+
+ return ev;
+
+error:
+ virReportOOMError();
+ virDomainEventFree(ev);
+ return NULL;
+}
+
+virDomainEventPtr virDomainEventTrayMovedNewFromObj(virDomainObjPtr obj,
+ const char *devAlias,
+ unsigned int trayOpened)
+{
+ return virDomainEventTrayMovedNew(obj->def->id,
+ obj->def->name,
+ obj->def->uuid,
+ devAlias,
+ trayOpened);
+}
+
+virDomainEventPtr virDomainEventTrayMovedNewFromDom(virDomainPtr dom,
+ const char *devAlias,
+ unsigned int trayOpened)
+{
+ return virDomainEventTrayMovedNew(dom->id, dom->name, dom->uuid,
+ devAlias, trayOpened);
+}
+
/**
* virDomainEventQueuePush:
@@ -1167,6 +1218,13 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
cbopaque);
break;
+ case VIR_DOMAIN_EVENT_ID_TRAY_MOVED:
+ ((virConnectDomainEventTrayMovedCallback)cb)(conn, dom,
+ event->data.trayMoved.devAlias,
+
event->data.trayMoved.trayOpened,
+ cbopaque);
+ break;
+
default:
VIR_WARN("Unexpected event ID %d", event->eventID);
break;
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index 0e7cd75..3351be0 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -114,6 +114,12 @@ virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr
dom,
const char *newSrcPath,
const char *devAlias,
int reason);
+virDomainEventPtr virDomainEventTrayMovedNewFromObj(virDomainObjPtr obj,
+ const char *devAlias,
+ unsigned int trayOpened);
+virDomainEventPtr virDomainEventTrayMovedNewFromDom(virDomainPtr dom,
+ const char *devAlias,
+ unsigned int trayOpened);
void virDomainEventFree(virDomainEventPtr event);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a104e70..27d4ad3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -512,6 +512,8 @@ virDomainEventStateRegisterID;
virDomainEventStateFree;
virDomainEventStateNew;
virDomainEventStateQueue;
+virDomainEventTrayMovedNewFromDom;
+virDomainEventTrayMovedNewFromObj;
virDomainEventWatchdogNewFromDom;
virDomainEventWatchdogNewFromObj;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 1da73f6..dfa2960 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1040,6 +1040,19 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
return ret;
}
+int qemuMonitorEmitTrayMoved(qemuMonitorPtr mon,
+ const char *devAlias,
+ unsigned int trayOpened)
+{
+ int ret = -1;
+ VIR_DEBUG("mon=%p", mon);
+
+ QEMU_MONITOR_CALLBACK(mon, ret, domainTrayMoved, mon->vm,
+ devAlias, trayOpened);
+
+ return ret;
+}
+
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index b1c956c..18e6801 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -124,6 +124,10 @@ struct _qemuMonitorCallbacks {
const char *diskAlias,
int type,
int status);
+ int (*domainTrayMoved)(qemuMonitorPtr mon,
+ virDomainObjPtr vm,
+ const char *devAlias,
+ unsigned int trayOpened);
};
@@ -191,6 +195,9 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
const char *authScheme,
const char *x509dname,
const char *saslUsername);
+int qemuMonitorEmitTrayMoved(qemuMonitorPtr mon,
+ const char *devAlias,
+ unsigned int trayOpened);
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index c0f148b..ac6b02c 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -59,6 +59,7 @@ static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon,
virJSONValuePtr
static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr
data);
static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr
data);
static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandleTrayMoved(qemuMonitorPtr mon, virJSONValuePtr data);
static struct {
const char *type;
@@ -75,6 +76,7 @@ static struct {
{ "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
{ "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
{ "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, },
+ { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayMoved, },
};
@@ -725,6 +727,22 @@ out:
qemuMonitorEmitBlockJob(mon, device, type, status);
}
+static void qemuMonitorJSONHandleTrayMoved(qemuMonitorPtr mon, virJSONValuePtr data)
+{
+ const char *devAlias = NULL;
+ bool trayOpened;
+
+ if ((devAlias = virJSONValueObjectGetString(data, "device")) == NULL) {
+ VIR_WARN("missing device in tray moved event");
+ return;
+ }
+
+ if (virJSONValueObjectGetBoolean(data, "tray-open", &trayOpened) <
0) {
+ VIR_WARN("missing tray-open in tray moved event");
+ return;
+ }
+ qemuMonitorEmitTrayMoved(mon, devAlias, (unsigned int)trayOpened);
+}
int
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7b99814..387811a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1021,6 +1021,37 @@ static void qemuProcessHandleMonitorDestroy(qemuMonitorPtr mon,
virDomainObjUnlock(vm);
}
+static int
+qemuProcessHandleTrayMoved(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm,
+ const char *devAlias,
+ unsigned int trayOpened)
+{
+ struct qemud_driver *driver = qemu_driver;
+ virDomainEventPtr event = NULL;
+ virDomainDiskDefPtr disk;
+
+ virDomainObjLock(vm);
+ disk = qemuProcessFindDomainDiskByAlias(vm, devAlias);
+
+ if (disk) {
+ event = virDomainEventTrayMovedNewFromObj(vm,
+ devAlias,
+ trayOpened);
+ }
+
+ virDomainObjUnlock(vm);
+
+ if (event) {
+ qemuDriverLock(driver);
+ qemuDomainEventQueue(driver, event);
+ qemuDriverUnlock(driver);
+ }
+
+ return 0;
+}
+
+
static qemuMonitorCallbacks monitorCallbacks = {
.destroy = qemuProcessHandleMonitorDestroy,
.eofNotify = qemuProcessHandleMonitorEOF,
@@ -1034,6 +1065,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainIOError = qemuProcessHandleIOError,
.domainGraphics = qemuProcessHandleGraphics,
.domainBlockJob = qemuProcessHandleBlockJob,
+ .domainTrayMoved = qemuProcessHandleTrayMoved,
};
static int
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 9e74cea..31d09a9 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -238,6 +238,11 @@ remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
+static void
+remoteDomainBuildEventTrayMoved(virNetClientProgramPtr prog,
+ virNetClientPtr client,
+ void *evdata, void *opaque);
+
static virNetClientProgramEvent remoteDomainEvents[] = {
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
remoteDomainBuildEventRTCChange,
@@ -279,6 +284,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = {
remoteDomainBuildEventDiskChange,
sizeof(remote_domain_event_disk_change_msg),
(xdrproc_t)xdr_remote_domain_event_disk_change_msg },
+ { REMOTE_PROC_DOMAIN_EVENT_TRAY_MOVED,
+ remoteDomainBuildEventTrayMoved,
+ sizeof(remote_domain_event_tray_moved_msg),
+ (xdrproc_t)xdr_remote_domain_event_tray_moved_msg },
};
enum virDrvOpenRemoteFlags {
@@ -3643,6 +3652,31 @@ remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog
ATTRIBUTE_UNUSED,
}
+static void
+remoteDomainBuildEventTrayMoved(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
+ virNetClientPtr client ATTRIBUTE_UNUSED,
+ void *evdata, void *opaque)
+{
+ virConnectPtr conn = opaque;
+ struct private_data *priv = conn->privateData;
+ remote_domain_event_tray_moved_msg *msg = evdata;
+ virDomainPtr dom;
+ virDomainEventPtr event = NULL;
+
+ dom = get_nonnull_domain(conn, msg->dom);
+ if (!dom)
+ return;
+
+ event = virDomainEventTrayMovedNewFromDom(dom,
+ msg->devAlias,
+ msg->trayOpened);
+
+ virDomainFree(dom);
+
+ remoteDomainEventQueue(priv, event);
+}
+
+
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth,
unsigned int flags)
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 4d845e7..73e554c 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2178,6 +2178,12 @@ struct remote_domain_event_disk_change_msg {
int reason;
};
+struct remote_domain_event_tray_moved_msg {
+ remote_nonnull_domain dom;
+ remote_nonnull_string devAlias;
+ unsigned int trayOpened;
+};
+
struct remote_domain_managed_save_args {
remote_nonnull_domain dom;
unsigned int flags;
@@ -2765,7 +2771,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SET_METADATA = 264, /* autogen autogen */
REMOTE_PROC_DOMAIN_GET_METADATA = 265, /* autogen autogen */
REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266, /* autogen autogen */
- REMOTE_PROC_DOMAIN_PM_WAKEUP = 267 /* autogen autogen */
+ REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, /* autogen autogen */
+ REMOTE_PROC_DOMAIN_EVENT_TRAY_MOVED = 268 /* autogen autogen */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 8f882b7..aad8654 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1650,6 +1650,11 @@ struct remote_domain_event_disk_change_msg {
remote_nonnull_string devAlias;
int reason;
};
+struct remote_domain_event_tray_moved_msg {
+ remote_nonnull_domain dom;
+ remote_nonnull_string devAlias;
+ U_int trayOpened;
+}
struct remote_domain_managed_save_args {
remote_nonnull_domain dom;
u_int flags;
--
1.7.1