mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
Add support for event tray moved of removable disks
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_CHANGE The event's data includes the device alias and the reason for tray status' changing, which indicates why the tray status was changed. Thus the callback definition for the event is: enum { VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN = 0, VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE, \#ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_TRAY_CHANGE_LAST \#endif } virDomainEventTrayChangeReason; typedef void (*virConnectDomainEventTrayChangeCallback)(virConnectPtr conn, virDomainPtr dom, const char *devAlias, int reason, void *opaque);
This commit is contained in:
parent
25d3a2e01f
commit
a26a1969c3
@ -506,6 +506,38 @@ mem_error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
|
virDomainPtr dom,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason,
|
||||||
|
void *opaque) {
|
||||||
|
virNetServerClientPtr client = opaque;
|
||||||
|
remote_domain_event_tray_change_msg data;
|
||||||
|
|
||||||
|
if (!client)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
VIR_DEBUG("Relaying domain %s %d tray change devAlias: %s reason: %d",
|
||||||
|
dom->name, dom->id, devAlias, reason);
|
||||||
|
|
||||||
|
/* build return data */
|
||||||
|
memset(&data, 0, sizeof data);
|
||||||
|
|
||||||
|
if (!(data.devAlias = strdup(devAlias))) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data.reason = reason;
|
||||||
|
|
||||||
|
make_nonnull_domain(&data.dom, dom);
|
||||||
|
|
||||||
|
remoteDispatchDomainEventSend(client, remoteProgram,
|
||||||
|
REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE,
|
||||||
|
(xdrproc_t)xdr_remote_domain_event_tray_change_msg, &data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
|
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
|
||||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
|
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
|
||||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
|
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
|
||||||
@ -517,6 +549,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
|
|||||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventControlError),
|
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventControlError),
|
||||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob),
|
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob),
|
||||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange),
|
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange),
|
||||||
|
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTrayChange),
|
||||||
};
|
};
|
||||||
|
|
||||||
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
|
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
|
||||||
|
@ -313,6 +313,22 @@ static int myDomainEventDiskChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *trayChangeReasonStrings[] = {
|
||||||
|
"open",
|
||||||
|
"close",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int myDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
|
virDomainPtr dom,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
printf("%s EVENT: Domain %s(%d) removable disk's tray change devAlias: %s reason: %s\n",
|
||||||
|
__func__, virDomainGetName(dom), virDomainGetID(dom),
|
||||||
|
devAlias, trayChangeReasonStrings[reason]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void myFreeFunc(void *opaque)
|
static void myFreeFunc(void *opaque)
|
||||||
{
|
{
|
||||||
@ -349,6 +365,7 @@ int main(int argc, char **argv)
|
|||||||
int callback7ret = -1;
|
int callback7ret = -1;
|
||||||
int callback8ret = -1;
|
int callback8ret = -1;
|
||||||
int callback9ret = -1;
|
int callback9ret = -1;
|
||||||
|
int callback10ret = -1;
|
||||||
struct sigaction action_stop;
|
struct sigaction action_stop;
|
||||||
|
|
||||||
memset(&action_stop, 0, sizeof action_stop);
|
memset(&action_stop, 0, sizeof action_stop);
|
||||||
@ -419,6 +436,11 @@ int main(int argc, char **argv)
|
|||||||
VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
|
VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
|
||||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventDiskChangeCallback),
|
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventDiskChangeCallback),
|
||||||
strdup("disk change"), myFreeFunc);
|
strdup("disk change"), myFreeFunc);
|
||||||
|
callback10ret = virConnectDomainEventRegisterAny(dconn,
|
||||||
|
NULL,
|
||||||
|
VIR_DOMAIN_EVENT_ID_TRAY_CHANGE,
|
||||||
|
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventTrayChangeCallback),
|
||||||
|
strdup("tray change"), myFreeFunc);
|
||||||
|
|
||||||
if ((callback1ret != -1) &&
|
if ((callback1ret != -1) &&
|
||||||
(callback2ret != -1) &&
|
(callback2ret != -1) &&
|
||||||
@ -427,7 +449,8 @@ int main(int argc, char **argv)
|
|||||||
(callback5ret != -1) &&
|
(callback5ret != -1) &&
|
||||||
(callback6ret != -1) &&
|
(callback6ret != -1) &&
|
||||||
(callback7ret != -1) &&
|
(callback7ret != -1) &&
|
||||||
(callback9ret != -1)) {
|
(callback9ret != -1) &&
|
||||||
|
(callback10ret != -1)) {
|
||||||
if (virConnectSetKeepAlive(dconn, 5, 3) < 0) {
|
if (virConnectSetKeepAlive(dconn, 5, 3) < 0) {
|
||||||
virErrorPtr err = virGetLastError();
|
virErrorPtr err = virGetLastError();
|
||||||
fprintf(stderr, "Failed to start keepalive protocol: %s\n",
|
fprintf(stderr, "Failed to start keepalive protocol: %s\n",
|
||||||
@ -452,6 +475,7 @@ int main(int argc, char **argv)
|
|||||||
virConnectDomainEventDeregisterAny(dconn, callback6ret);
|
virConnectDomainEventDeregisterAny(dconn, callback6ret);
|
||||||
virConnectDomainEventDeregisterAny(dconn, callback7ret);
|
virConnectDomainEventDeregisterAny(dconn, callback7ret);
|
||||||
virConnectDomainEventDeregisterAny(dconn, callback9ret);
|
virConnectDomainEventDeregisterAny(dconn, callback9ret);
|
||||||
|
virConnectDomainEventDeregisterAny(dconn, callback10ret);
|
||||||
if (callback8ret != -1)
|
if (callback8ret != -1)
|
||||||
virConnectDomainEventDeregisterAny(dconn, callback8ret);
|
virConnectDomainEventDeregisterAny(dconn, callback8ret);
|
||||||
}
|
}
|
||||||
|
@ -474,6 +474,9 @@ def myDomainEventGraphicsCallback(conn, dom, phase, localAddr, remoteAddr, authS
|
|||||||
def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, reason, opaque):
|
def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, reason, opaque):
|
||||||
print "myDomainEventDiskChangeCallback: Domain %s(%s) disk change oldSrcPath: %s newSrcPath: %s devAlias: %s reason: %s" % (
|
print "myDomainEventDiskChangeCallback: Domain %s(%s) disk change oldSrcPath: %s newSrcPath: %s devAlias: %s reason: %s" % (
|
||||||
dom.name(), dom.ID(), oldSrcPath, newSrcPath, devAlias, reason)
|
dom.name(), dom.ID(), oldSrcPath, newSrcPath, devAlias, reason)
|
||||||
|
def myDomainEventTrayChangeCallback(conn, dom, devAlias, reason, opaque):
|
||||||
|
print "myDomainEventTrayChangeCallback: Domain %s(%s) tray change devAlias: %s reason: %s" % (
|
||||||
|
dom.name(), dom.ID(), devAlias, reason)
|
||||||
def usage(out=sys.stderr):
|
def usage(out=sys.stderr):
|
||||||
print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]"
|
print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]"
|
||||||
print >>out, " uri will default to qemu:///system"
|
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_WATCHDOG, myDomainEventWatchdogCallback, None)
|
||||||
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS, myDomainEventGraphicsCallback, 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_DISK_CHANGE, myDomainEventDiskChangeCallback, None)
|
||||||
|
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, myDomainEventTrayChangeCallback, None)
|
||||||
|
|
||||||
vc.setKeepAlive(5, 3)
|
vc.setKeepAlive(5, 3)
|
||||||
|
|
||||||
|
@ -3667,6 +3667,40 @@ typedef void (*virConnectDomainEventDiskChangeCallback)(virConnectPtr conn,
|
|||||||
int reason,
|
int reason,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectDomainEventTrayChangeReason:
|
||||||
|
*
|
||||||
|
* The reason describing why the callback was called
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN = 0,
|
||||||
|
VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE,
|
||||||
|
|
||||||
|
#ifdef VIR_ENUM_SENTINELS
|
||||||
|
VIR_DOMAIN_EVENT_TRAY_CHANGE_LAST
|
||||||
|
#endif
|
||||||
|
} virDomainEventTrayChangeReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectDomainEventTrayChangeCallback:
|
||||||
|
* @conn: connection object
|
||||||
|
* @dom: domain on which the event occurred
|
||||||
|
* @devAlias: device alias
|
||||||
|
* @reason: why the tray status was changed?
|
||||||
|
* @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_CHANGE with virConnectDomainEventRegisterAny()
|
||||||
|
*/
|
||||||
|
typedef void (*virConnectDomainEventTrayChangeCallback)(virConnectPtr conn,
|
||||||
|
virDomainPtr dom,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VIR_DOMAIN_EVENT_CALLBACK:
|
* VIR_DOMAIN_EVENT_CALLBACK:
|
||||||
*
|
*
|
||||||
@ -3687,6 +3721,7 @@ typedef enum {
|
|||||||
VIR_DOMAIN_EVENT_ID_CONTROL_ERROR = 7, /* virConnectDomainEventGenericCallback */
|
VIR_DOMAIN_EVENT_ID_CONTROL_ERROR = 7, /* virConnectDomainEventGenericCallback */
|
||||||
VIR_DOMAIN_EVENT_ID_BLOCK_JOB = 8, /* virConnectDomainEventBlockJobCallback */
|
VIR_DOMAIN_EVENT_ID_BLOCK_JOB = 8, /* virConnectDomainEventBlockJobCallback */
|
||||||
VIR_DOMAIN_EVENT_ID_DISK_CHANGE = 9, /* virConnectDomainEventDiskChangeCallback */
|
VIR_DOMAIN_EVENT_ID_DISK_CHANGE = 9, /* virConnectDomainEventDiskChangeCallback */
|
||||||
|
VIR_DOMAIN_EVENT_ID_TRAY_CHANGE = 10, /* virConnectDomainEventTrayChangeCallback */
|
||||||
|
|
||||||
#ifdef VIR_ENUM_SENTINELS
|
#ifdef VIR_ENUM_SENTINELS
|
||||||
/*
|
/*
|
||||||
|
@ -134,6 +134,16 @@
|
|||||||
cb(self, virDomain(self, _obj=dom), oldSrcPath, newSrcPath, devAlias, reason, opaque)
|
cb(self, virDomain(self, _obj=dom), oldSrcPath, newSrcPath, devAlias, reason, opaque)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
def _dispatchDomainEventTrayChangeCallback(self, dom, devAlias, reason, cbData):
|
||||||
|
"""Dispatches event to python user domain trayChange event callbacks
|
||||||
|
"""
|
||||||
|
cb = cbData["cb"]
|
||||||
|
opaque = cbData["opaque"]
|
||||||
|
|
||||||
|
cb(self, virDomain(self, _obj=dom), devAlias, reason, opaque)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
def domainEventDeregisterAny(self, callbackID):
|
def domainEventDeregisterAny(self, callbackID):
|
||||||
"""Removes a Domain Event Callback. De-registering for a
|
"""Removes a Domain Event Callback. De-registering for a
|
||||||
domain callback will disable delivery of this event type """
|
domain callback will disable delivery of this event type """
|
||||||
|
@ -5105,6 +5105,53 @@ libvirt_virConnectDomainEventDiskChangeCallback(virConnectPtr conn ATTRIBUTE_UNU
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
libvirt_virConnectDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
|
virDomainPtr dom,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason,
|
||||||
|
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*)"_dispatchDomainEventTrayChangeCallback",
|
||||||
|
(char*)"OsiO",
|
||||||
|
pyobj_dom,
|
||||||
|
devAlias, reason, 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 *
|
static PyObject *
|
||||||
libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
|
libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
|
||||||
PyObject * args)
|
PyObject * args)
|
||||||
@ -5165,6 +5212,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
|
|||||||
case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
|
case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
|
||||||
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventDiskChangeCallback);
|
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventDiskChangeCallback);
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
|
||||||
|
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventTrayChangeCallback);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cb) {
|
if (!cb) {
|
||||||
|
@ -117,6 +117,10 @@ struct _virDomainEvent {
|
|||||||
char *devAlias;
|
char *devAlias;
|
||||||
int reason;
|
int reason;
|
||||||
} diskChange;
|
} diskChange;
|
||||||
|
struct {
|
||||||
|
char *devAlias;
|
||||||
|
int reason;
|
||||||
|
} trayChange;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -546,6 +550,9 @@ void virDomainEventFree(virDomainEventPtr event)
|
|||||||
VIR_FREE(event->data.diskChange.newSrcPath);
|
VIR_FREE(event->data.diskChange.newSrcPath);
|
||||||
VIR_FREE(event->data.diskChange.devAlias);
|
VIR_FREE(event->data.diskChange.devAlias);
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
|
||||||
|
VIR_FREE(event->data.trayChange.devAlias);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_FREE(event->dom.name);
|
VIR_FREE(event->dom.name);
|
||||||
@ -1043,6 +1050,50 @@ virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
|
|||||||
devAlias, reason);
|
devAlias, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static virDomainEventPtr
|
||||||
|
virDomainEventTrayChangeNew(int id, const char *name,
|
||||||
|
unsigned char *uuid,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason)
|
||||||
|
{
|
||||||
|
virDomainEventPtr ev =
|
||||||
|
virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_TRAY_CHANGE,
|
||||||
|
id, name, uuid);
|
||||||
|
|
||||||
|
if (ev) {
|
||||||
|
if (!(ev->data.trayChange.devAlias = strdup(devAlias)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
ev->data.trayChange.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ev;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virReportOOMError();
|
||||||
|
virDomainEventFree(ev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason)
|
||||||
|
{
|
||||||
|
return virDomainEventTrayChangeNew(obj->def->id,
|
||||||
|
obj->def->name,
|
||||||
|
obj->def->uuid,
|
||||||
|
devAlias,
|
||||||
|
reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason)
|
||||||
|
{
|
||||||
|
return virDomainEventTrayChangeNew(dom->id, dom->name, dom->uuid,
|
||||||
|
devAlias, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virDomainEventQueuePush:
|
* virDomainEventQueuePush:
|
||||||
@ -1167,6 +1218,13 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
|
|||||||
cbopaque);
|
cbopaque);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
|
||||||
|
((virConnectDomainEventTrayChangeCallback)cb)(conn, dom,
|
||||||
|
event->data.trayChange.devAlias,
|
||||||
|
event->data.trayChange.reason,
|
||||||
|
cbopaque);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
VIR_WARN("Unexpected event ID %d", event->eventID);
|
VIR_WARN("Unexpected event ID %d", event->eventID);
|
||||||
break;
|
break;
|
||||||
|
@ -114,6 +114,12 @@ virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
|
|||||||
const char *newSrcPath,
|
const char *newSrcPath,
|
||||||
const char *devAlias,
|
const char *devAlias,
|
||||||
int reason);
|
int reason);
|
||||||
|
virDomainEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason);
|
||||||
|
virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason);
|
||||||
|
|
||||||
void virDomainEventFree(virDomainEventPtr event);
|
void virDomainEventFree(virDomainEventPtr event);
|
||||||
|
|
||||||
|
@ -522,6 +522,8 @@ virDomainEventStateRegisterID;
|
|||||||
virDomainEventStateFree;
|
virDomainEventStateFree;
|
||||||
virDomainEventStateNew;
|
virDomainEventStateNew;
|
||||||
virDomainEventStateQueue;
|
virDomainEventStateQueue;
|
||||||
|
virDomainEventTrayChangeNewFromDom;
|
||||||
|
virDomainEventTrayChangeNewFromObj;
|
||||||
virDomainEventWatchdogNewFromDom;
|
virDomainEventWatchdogNewFromDom;
|
||||||
virDomainEventWatchdogNewFromObj;
|
virDomainEventWatchdogNewFromObj;
|
||||||
|
|
||||||
|
@ -1040,6 +1040,19 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qemuMonitorEmitTrayChange(qemuMonitorPtr mon,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
VIR_DEBUG("mon=%p", mon);
|
||||||
|
|
||||||
|
QEMU_MONITOR_CALLBACK(mon, ret, domainTrayChange, mon->vm,
|
||||||
|
devAlias, reason);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
|
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
|
||||||
const char *diskAlias,
|
const char *diskAlias,
|
||||||
int type,
|
int type,
|
||||||
|
@ -124,9 +124,12 @@ struct _qemuMonitorCallbacks {
|
|||||||
const char *diskAlias,
|
const char *diskAlias,
|
||||||
int type,
|
int type,
|
||||||
int status);
|
int status);
|
||||||
|
int (*domainTrayChange)(qemuMonitorPtr mon,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
char *qemuMonitorEscapeArg(const char *in);
|
char *qemuMonitorEscapeArg(const char *in);
|
||||||
char *qemuMonitorUnescapeArg(const char *in);
|
char *qemuMonitorUnescapeArg(const char *in);
|
||||||
|
|
||||||
@ -191,13 +194,14 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
|
|||||||
const char *authScheme,
|
const char *authScheme,
|
||||||
const char *x509dname,
|
const char *x509dname,
|
||||||
const char *saslUsername);
|
const char *saslUsername);
|
||||||
|
int qemuMonitorEmitTrayChange(qemuMonitorPtr mon,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason);
|
||||||
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
|
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
|
||||||
const char *diskAlias,
|
const char *diskAlias,
|
||||||
int type,
|
int type,
|
||||||
int status);
|
int status);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
|
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
|
||||||
virConnectPtr conn);
|
virConnectPtr conn);
|
||||||
int qemuMonitorStopCPUs(qemuMonitorPtr mon);
|
int qemuMonitorStopCPUs(qemuMonitorPtr mon);
|
||||||
|
@ -62,6 +62,7 @@ static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr da
|
|||||||
static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONValuePtr data);
|
static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||||
static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJSONValuePtr data);
|
static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||||
static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJSONValuePtr data);
|
static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||||
|
static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr data);
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
const char *type;
|
const char *type;
|
||||||
@ -81,6 +82,7 @@ static struct {
|
|||||||
{ "SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect, },
|
{ "SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect, },
|
||||||
{ "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
|
{ "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
|
||||||
{ "SPICE_DISCONNECTED", qemuMonitorJSONHandleSPICEDisconnect, },
|
{ "SPICE_DISCONNECTED", qemuMonitorJSONHandleSPICEDisconnect, },
|
||||||
|
{ "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -773,6 +775,31 @@ out:
|
|||||||
qemuMonitorEmitBlockJob(mon, device, type, status);
|
qemuMonitorEmitBlockJob(mon, device, type, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon,
|
||||||
|
virJSONValuePtr data)
|
||||||
|
{
|
||||||
|
const char *devAlias = NULL;
|
||||||
|
bool trayOpened;
|
||||||
|
int reason;
|
||||||
|
|
||||||
|
if ((devAlias = virJSONValueObjectGetString(data, "device")) == NULL) {
|
||||||
|
VIR_WARN("missing device in tray change event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetBoolean(data, "tray-open", &trayOpened) < 0) {
|
||||||
|
VIR_WARN("missing tray-open in tray change event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trayOpened)
|
||||||
|
reason = VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN;
|
||||||
|
else
|
||||||
|
reason = VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE;
|
||||||
|
|
||||||
|
qemuMonitorEmitTrayChange(mon, devAlias, reason);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
|
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
|
||||||
|
@ -1021,6 +1021,37 @@ static void qemuProcessHandleMonitorDestroy(qemuMonitorPtr mon,
|
|||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *devAlias,
|
||||||
|
int reason)
|
||||||
|
{
|
||||||
|
struct qemud_driver *driver = qemu_driver;
|
||||||
|
virDomainEventPtr event = NULL;
|
||||||
|
virDomainDiskDefPtr disk;
|
||||||
|
|
||||||
|
virDomainObjLock(vm);
|
||||||
|
disk = qemuProcessFindDomainDiskByAlias(vm, devAlias);
|
||||||
|
|
||||||
|
if (disk) {
|
||||||
|
event = virDomainEventTrayChangeNewFromObj(vm,
|
||||||
|
devAlias,
|
||||||
|
reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
qemuDriverLock(driver);
|
||||||
|
qemuDomainEventQueue(driver, event);
|
||||||
|
qemuDriverUnlock(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static qemuMonitorCallbacks monitorCallbacks = {
|
static qemuMonitorCallbacks monitorCallbacks = {
|
||||||
.destroy = qemuProcessHandleMonitorDestroy,
|
.destroy = qemuProcessHandleMonitorDestroy,
|
||||||
.eofNotify = qemuProcessHandleMonitorEOF,
|
.eofNotify = qemuProcessHandleMonitorEOF,
|
||||||
@ -1034,6 +1065,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
|
|||||||
.domainIOError = qemuProcessHandleIOError,
|
.domainIOError = qemuProcessHandleIOError,
|
||||||
.domainGraphics = qemuProcessHandleGraphics,
|
.domainGraphics = qemuProcessHandleGraphics,
|
||||||
.domainBlockJob = qemuProcessHandleBlockJob,
|
.domainBlockJob = qemuProcessHandleBlockJob,
|
||||||
|
.domainTrayChange = qemuProcessHandleTrayChange,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -239,6 +239,11 @@ remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog,
|
|||||||
virNetClientPtr client,
|
virNetClientPtr client,
|
||||||
void *evdata, void *opaque);
|
void *evdata, void *opaque);
|
||||||
|
|
||||||
|
static void
|
||||||
|
remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog,
|
||||||
|
virNetClientPtr client,
|
||||||
|
void *evdata, void *opaque);
|
||||||
|
|
||||||
static virNetClientProgramEvent remoteDomainEvents[] = {
|
static virNetClientProgramEvent remoteDomainEvents[] = {
|
||||||
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
|
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
|
||||||
remoteDomainBuildEventRTCChange,
|
remoteDomainBuildEventRTCChange,
|
||||||
@ -280,6 +285,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = {
|
|||||||
remoteDomainBuildEventDiskChange,
|
remoteDomainBuildEventDiskChange,
|
||||||
sizeof(remote_domain_event_disk_change_msg),
|
sizeof(remote_domain_event_disk_change_msg),
|
||||||
(xdrproc_t)xdr_remote_domain_event_disk_change_msg },
|
(xdrproc_t)xdr_remote_domain_event_disk_change_msg },
|
||||||
|
{ REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE,
|
||||||
|
remoteDomainBuildEventTrayChange,
|
||||||
|
sizeof(remote_domain_event_tray_change_msg),
|
||||||
|
(xdrproc_t)xdr_remote_domain_event_tray_change_msg },
|
||||||
};
|
};
|
||||||
|
|
||||||
enum virDrvOpenRemoteFlags {
|
enum virDrvOpenRemoteFlags {
|
||||||
@ -3731,6 +3740,31 @@ remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
remoteDomainBuildEventTrayChange(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_change_msg *msg = evdata;
|
||||||
|
virDomainPtr dom;
|
||||||
|
virDomainEventPtr event = NULL;
|
||||||
|
|
||||||
|
dom = get_nonnull_domain(conn, msg->dom);
|
||||||
|
if (!dom)
|
||||||
|
return;
|
||||||
|
|
||||||
|
event = virDomainEventTrayChangeNewFromDom(dom,
|
||||||
|
msg->devAlias,
|
||||||
|
msg->reason);
|
||||||
|
|
||||||
|
virDomainFree(dom);
|
||||||
|
|
||||||
|
remoteDomainEventQueue(priv, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
|
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
|
||||||
remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth,
|
remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
|
@ -2178,6 +2178,12 @@ struct remote_domain_event_disk_change_msg {
|
|||||||
int reason;
|
int reason;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct remote_domain_event_tray_change_msg {
|
||||||
|
remote_nonnull_domain dom;
|
||||||
|
remote_nonnull_string devAlias;
|
||||||
|
int reason;
|
||||||
|
};
|
||||||
|
|
||||||
struct remote_domain_managed_save_args {
|
struct remote_domain_managed_save_args {
|
||||||
remote_nonnull_domain dom;
|
remote_nonnull_domain dom;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
@ -2765,7 +2771,8 @@ enum remote_procedure {
|
|||||||
REMOTE_PROC_DOMAIN_SET_METADATA = 264, /* autogen autogen */
|
REMOTE_PROC_DOMAIN_SET_METADATA = 264, /* autogen autogen */
|
||||||
REMOTE_PROC_DOMAIN_GET_METADATA = 265, /* autogen autogen */
|
REMOTE_PROC_DOMAIN_GET_METADATA = 265, /* autogen autogen */
|
||||||
REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266, /* 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_CHANGE = 268 /* autogen autogen */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notice how the entries are grouped in sets of 10 ?
|
* Notice how the entries are grouped in sets of 10 ?
|
||||||
|
@ -1650,6 +1650,11 @@ struct remote_domain_event_disk_change_msg {
|
|||||||
remote_nonnull_string devAlias;
|
remote_nonnull_string devAlias;
|
||||||
int reason;
|
int reason;
|
||||||
};
|
};
|
||||||
|
struct remote_domain_event_tray_change_msg {
|
||||||
|
remote_nonnull_domain dom;
|
||||||
|
remote_nonnull_string devAlias;
|
||||||
|
int reason;
|
||||||
|
}
|
||||||
struct remote_domain_managed_save_args {
|
struct remote_domain_managed_save_args {
|
||||||
remote_nonnull_domain dom;
|
remote_nonnull_domain dom;
|
||||||
u_int flags;
|
u_int flags;
|
||||||
@ -2178,4 +2183,5 @@ enum remote_procedure {
|
|||||||
REMOTE_PROC_DOMAIN_GET_METADATA = 265,
|
REMOTE_PROC_DOMAIN_GET_METADATA = 265,
|
||||||
REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266,
|
REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266,
|
||||||
REMOTE_PROC_DOMAIN_PM_WAKEUP = 267,
|
REMOTE_PROC_DOMAIN_PM_WAKEUP = 267,
|
||||||
|
REMOTE_PROC_DOMAIN_TRAY_CHANGE = 268,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user