[libvirt] [PATCH 0/11 v2] Add supports for three new QMP events

v1 ~ v2: * Two more patches, [5/11] to prohibit tray='open' for block type disk. And [9/11] to introduce a new domain state 'pmsuspended' * Definition (including name) for DEVICE_TRAY_MOVED event is changed into: typedef void (*virConnectDomainEventTrayChangeCallback)(virConnectPtr conn, virDomainPtr dom, const char *devAlias, int reason, void *opaque); * Definition for both SUSPEND and WAKEUP event are changed, one more parameter 'int reason' for future extension. * While SUSPEND event is emitted, the running domain will be transfered into the new domain state "pmsuspended", instead of "paused". And while WAKEUP is emitted, it will transfer the domain state to running only if the domain state is "pmsuspended". This patch series adds support for 3 new QMP events: WAKEUP, SUSPEND, and DEVICE_TRAY_MOVED, and related changes on domain's conf and status. [1/11] Add support for tray moved event [2/11] ~ [6/11]: New attribute "tray" is added to disk target, it indicates the tray status of removable disk, i.e. CDROM and Floppy disks, its value could be either of "open" or "closed", defaults to "closed", and a removable disk with tray == "open" won't have the source when domain is started. The value of "tray" will be updated while tray moved event is emitted from guest. tray status 'open' is prohibited for block type disk. Prior to these patches, if the user ejected the medium of removable disk from guest side, and then do migration or save/restoring, the guest will still starts the medium source ,and thus the medium will still exists in guest, which is strange. These patches fix it. [7/11] + [11/11]: Add support for wakeup event, and update the domain status to running if the domain is in pmsuspended state, while the wakeup event is emitted. [9/11] Introduce new domain state "pmsuspended", which indicates the domain has been suspended by guest power management, e.g, entered into s3 state. [8/11] + [10/11]: Add support for suspend event, and update the domain status to pmsuspended if the domain was running, while the suspend event is emitted. Osier Yang(11) Add support for event tray moved of removable disks docs: Add documentation for new attribute tray of disk target conf: Parse and for the tray attribute qemu: Do not start with source for removable disks if tray is open qemu: Prohibit setting tray status as open for block type disk qemu: Update tray status while tray moved event is emitted Add support for the wakeup event Add support for the suspend event New domain state pmsuspended qemu: Update domain state to pmsuspended while suspend event occurs qemu: Update domain status to running while wakeup event is emitted daemon/remote.c | 79 ++++++++++ docs/formatdomain.html.in | 13 ++- docs/schemas/domaincommon.rng | 8 + examples/domain-events/events-c/event-test.c | 66 +++++++++- examples/domain-events/events-python/event-test.py | 12 ++ include/libvirt/libvirt.h.in | 98 ++++++++++++- python/libvirt-override-virConnect.py | 27 ++++ python/libvirt-override.c | 150 ++++++++++++++++++++ src/conf/domain_conf.c | 71 ++++++++-- src/conf/domain_conf.h | 9 ++ src/conf/domain_event.c | 115 +++++++++++++++ src/conf/domain_event.h | 10 ++ src/libvirt_private.syms | 6 + src/qemu/qemu_command.c | 31 ++++- src/qemu/qemu_monitor.c | 33 +++++ src/qemu/qemu_monitor.h | 16 ++- src/qemu/qemu_monitor_json.c | 45 ++++++ src/qemu/qemu_process.c | 121 ++++++++++++++++ src/remote/remote_driver.c | 95 ++++++++++++ src/remote/remote_protocol.x | 19 +++- src/remote_protocol-structs | 14 ++ tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml | 2 +- .../qemuxml2argv-boot-complex-bootindex.xml | 6 +- .../qemuxml2argvdata/qemuxml2argv-boot-complex.xml | 6 +- .../qemuxml2argvdata/qemuxml2argv-boot-floppy.xml | 2 +- ...uxml2argv-boot-menu-disable-drive-bootindex.xml | 2 +- .../qemuxml2argv-boot-menu-disable-drive.xml | 2 +- .../qemuxml2argv-boot-menu-disable.xml | 2 +- .../qemuxml2argv-boot-menu-enable.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml | 4 +- tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml | 2 +- .../qemuxml2argv-disk-cdrom-empty.xml | 2 +- ...qemuxml2argv-disk-cdrom-tray-no-device-cap.args | 4 + .../qemuxml2argv-disk-cdrom-tray-no-device-cap.xml | 32 ++++ .../qemuxml2argv-disk-cdrom-tray.args | 10 ++ .../qemuxml2argv-disk-cdrom-tray.xml | 43 ++++++ tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml | 2 +- .../qemuxml2argv-disk-copy_on_read.xml | 2 +- .../qemuxml2argv-disk-drive-boot-cdrom.xml | 2 +- .../qemuxml2argv-disk-drive-boot-disk.xml | 2 +- .../qemuxml2argv-disk-drive-cache-directsync.xml | 2 +- .../qemuxml2argv-disk-drive-cache-unsafe.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-none.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wb.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wt.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-none.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wb.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wt.xml | 2 +- ...muxml2argv-disk-drive-error-policy-enospace.xml | 2 +- .../qemuxml2argv-disk-drive-error-policy-stop.xml | 2 +- ...rgv-disk-drive-error-policy-wreport-rignore.xml | 2 +- .../qemuxml2argv-disk-drive-fmt-qcow.xml | 2 +- .../qemuxml2argv-disk-drive-no-boot.xml | 4 +- .../qemuxml2argv-disk-drive-readonly-disk.xml | 2 +- .../qemuxml2argv-disk-drive-readonly-no-device.xml | 2 +- .../qemuxml2argv-disk-drive-shared.xml | 2 +- ...emuxml2argv-disk-floppy-tray-no-device-cap.args | 4 + ...qemuxml2argv-disk-floppy-tray-no-device-cap.xml | 37 +++++ .../qemuxml2argv-disk-floppy-tray.args | 10 ++ .../qemuxml2argv-disk-floppy-tray.xml | 37 +++++ .../qemuxml2argvdata/qemuxml2argv-disk-floppy.xml | 4 +- .../qemuxml2argv-disk-ioeventfd.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml | 2 +- .../qemuxml2argv-disk-snapshot.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-virtio.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml | 2 +- .../qemuxml2argv-floppy-drive-fat.xml | 2 +- .../qemuxml2argv-graphics-spice-timeout.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-lease.xml | 2 +- .../qemuxml2argv-net-bandwidth.xml | 2 +- tests/qemuxml2argvtest.c | 6 + .../qemuxml2xmlout-graphics-spice-timeout.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml | 8 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml | 4 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml | 2 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml | 2 +- tests/vmx2xmldata/vmx2xml-floppy-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-floppy-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml | 2 +- tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml | 2 +- tools/virsh.c | 12 ++ tools/virsh.pod | 7 +- 89 files changed, 1277 insertions(+), 99 deletions(-) Osier

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); --- daemon/remote.c | 33 +++++++++++ examples/domain-events/events-c/event-test.c | 26 +++++++++- examples/domain-events/events-python/event-test.py | 4 ++ include/libvirt/libvirt.h.in | 35 ++++++++++++ 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 | 10 +++- src/qemu/qemu_monitor_json.c | 27 +++++++++ src/qemu/qemu_process.c | 32 +++++++++++ src/remote/remote_driver.c | 34 ++++++++++++ src/remote/remote_protocol.x | 9 +++- src/remote_protocol-structs | 6 ++ 16 files changed, 350 insertions(+), 5 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 0dd4f2e..060f77b 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -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[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -517,6 +549,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventControlError), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTrayChange), }; 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..cca9a1a 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -313,6 +313,22 @@ static int myDomainEventDiskChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED, 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) { @@ -349,6 +365,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 +436,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_CHANGE, + VIR_DOMAIN_EVENT_CALLBACK(myDomainEventTrayChangeCallback), + strdup("tray change"), myFreeFunc); if ((callback1ret != -1) && (callback2ret != -1) && @@ -427,7 +449,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 +475,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..6e0409d 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 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): 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_CHANGE, myDomainEventTrayChangeCallback, None) vc.setKeepAlive(5, 3) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7d41642..7bf1004 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3668,6 +3668,40 @@ typedef void (*virConnectDomainEventDiskChangeCallback)(virConnectPtr conn, 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: * * Used to cast the event specific callback into the generic one @@ -3687,6 +3721,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_CHANGE = 10, /* virConnectDomainEventTrayChangeCallback */ #ifdef VIR_ENUM_SENTINELS /* diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index b908b32..82c2437 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 _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): """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..915ebd2 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_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 * 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_CHANGE: + cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventTrayChangeCallback); + break; } if (!cb) { diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 1d8b45d..9c2a052 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; + int reason; + } trayChange; } 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_CHANGE: + VIR_FREE(event->data.trayChange.devAlias); + break; } VIR_FREE(event->dom.name); @@ -1043,6 +1050,50 @@ virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom, 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: @@ -1167,6 +1218,13 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, cbopaque); break; + case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE: + ((virConnectDomainEventTrayChangeCallback)cb)(conn, dom, + event->data.trayChange.devAlias, + event->data.trayChange.reason, + 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..e5010a3 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 virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj, + const char *devAlias, + int reason); +virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom, + const char *devAlias, + int reason); void virDomainEventFree(virDomainEventPtr event); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1f55f5d..e247472 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -525,6 +525,8 @@ virDomainEventStateRegisterID; virDomainEventStateFree; virDomainEventStateNew; virDomainEventStateQueue; +virDomainEventTrayChangeNewFromDom; +virDomainEventTrayChangeNewFromObj; virDomainEventWatchdogNewFromDom; virDomainEventWatchdogNewFromObj; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 78eb492..90b8e12 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1040,6 +1040,19 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, 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, const char *diskAlias, int type, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 654d9bd..b5a0c30 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -124,9 +124,12 @@ struct _qemuMonitorCallbacks { const char *diskAlias, int type, int status); + int (*domainTrayChange)(qemuMonitorPtr mon, + virDomainObjPtr vm, + const char *devAlias, + int reason); }; - char *qemuMonitorEscapeArg(const char *in); char *qemuMonitorUnescapeArg(const char *in); @@ -191,13 +194,14 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, const char *authScheme, const char *x509dname, const char *saslUsername); +int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, + const char *devAlias, + int reason); int qemuMonitorEmitBlockJob(qemuMonitorPtr mon, const char *diskAlias, int type, int status); - - int qemuMonitorStartCPUs(qemuMonitorPtr mon, virConnectPtr conn); int qemuMonitorStopCPUs(qemuMonitorPtr mon); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 1a0ee94..0312ca7 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 qemuMonitorJSONHandleTrayChange(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", qemuMonitorJSONHandleTrayChange, }, }; @@ -725,6 +727,31 @@ out: 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 qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index ef311d1..b6e14ad 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 +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 = { .destroy = qemuProcessHandleMonitorDestroy, .eofNotify = qemuProcessHandleMonitorEOF, @@ -1034,6 +1065,7 @@ static qemuMonitorCallbacks monitorCallbacks = { .domainIOError = qemuProcessHandleIOError, .domainGraphics = qemuProcessHandleGraphics, .domainBlockJob = qemuProcessHandleBlockJob, + .domainTrayChange = qemuProcessHandleTrayChange, }; static int diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 031167a..ac95dcc 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 +remoteDomainBuildEventTrayChange(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_CHANGE, + remoteDomainBuildEventTrayChange, + sizeof(remote_domain_event_tray_change_msg), + (xdrproc_t)xdr_remote_domain_event_tray_change_msg }, }; enum virDrvOpenRemoteFlags { @@ -3645,6 +3654,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) remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags) diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 4d845e7..6c8c497 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_change_msg { + remote_nonnull_domain dom; + remote_nonnull_string devAlias; + int reason; +}; + 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_CHANGE = 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..0ce7c1c 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_change_msg { + remote_nonnull_domain dom; + remote_nonnull_string devAlias; + int reason; +} struct remote_domain_managed_save_args { remote_nonnull_domain dom; u_int flags; @@ -2178,4 +2183,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_METADATA = 265, REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266, REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, + REMOTE_PROC_DOMAIN_TRAY_CHANGE = 268, }; -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:45PM +0800, Osier Yang wrote:
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); --- daemon/remote.c | 33 +++++++++++ examples/domain-events/events-c/event-test.c | 26 +++++++++- examples/domain-events/events-python/event-test.py | 4 ++ include/libvirt/libvirt.h.in | 35 ++++++++++++ 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 | 10 +++- src/qemu/qemu_monitor_json.c | 27 +++++++++ src/qemu/qemu_process.c | 32 +++++++++++ src/remote/remote_driver.c | 34 ++++++++++++ src/remote/remote_protocol.x | 9 +++- src/remote_protocol-structs | 6 ++ 16 files changed, 350 insertions(+), 5 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c index 0dd4f2e..060f77b 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -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[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -517,6 +549,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventControlError), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTrayChange), };
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..cca9a1a 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -313,6 +313,22 @@ static int myDomainEventDiskChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED, 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) { @@ -349,6 +365,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 +436,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_CHANGE, + VIR_DOMAIN_EVENT_CALLBACK(myDomainEventTrayChangeCallback), + strdup("tray change"), myFreeFunc);
if ((callback1ret != -1) && (callback2ret != -1) && @@ -427,7 +449,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 +475,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..6e0409d 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 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): 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_CHANGE, myDomainEventTrayChangeCallback, None)
vc.setKeepAlive(5, 3)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7d41642..7bf1004 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3668,6 +3668,40 @@ typedef void (*virConnectDomainEventDiskChangeCallback)(virConnectPtr conn, 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: * * Used to cast the event specific callback into the generic one @@ -3687,6 +3721,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_CHANGE = 10, /* virConnectDomainEventTrayChangeCallback */
#ifdef VIR_ENUM_SENTINELS /* diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index b908b32..82c2437 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 _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): """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..915ebd2 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_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 * 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_CHANGE: + cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventTrayChangeCallback); + break; }
if (!cb) { diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 1d8b45d..9c2a052 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; + int reason; + } trayChange; } 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_CHANGE: + VIR_FREE(event->data.trayChange.devAlias); + break; }
VIR_FREE(event->dom.name); @@ -1043,6 +1050,50 @@ virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom, 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: @@ -1167,6 +1218,13 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, cbopaque); break;
+ case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE: + ((virConnectDomainEventTrayChangeCallback)cb)(conn, dom, + event->data.trayChange.devAlias, + event->data.trayChange.reason, + 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..e5010a3 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 virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj, + const char *devAlias, + int reason); +virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom, + const char *devAlias, + int reason);
void virDomainEventFree(virDomainEventPtr event);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1f55f5d..e247472 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -525,6 +525,8 @@ virDomainEventStateRegisterID; virDomainEventStateFree; virDomainEventStateNew; virDomainEventStateQueue; +virDomainEventTrayChangeNewFromDom; +virDomainEventTrayChangeNewFromObj; virDomainEventWatchdogNewFromDom; virDomainEventWatchdogNewFromObj;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 78eb492..90b8e12 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1040,6 +1040,19 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, 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, const char *diskAlias, int type, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 654d9bd..b5a0c30 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -124,9 +124,12 @@ struct _qemuMonitorCallbacks { const char *diskAlias, int type, int status); + int (*domainTrayChange)(qemuMonitorPtr mon, + virDomainObjPtr vm, + const char *devAlias, + int reason); };
- char *qemuMonitorEscapeArg(const char *in); char *qemuMonitorUnescapeArg(const char *in);
@@ -191,13 +194,14 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, const char *authScheme, const char *x509dname, const char *saslUsername); +int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, + const char *devAlias, + int reason); int qemuMonitorEmitBlockJob(qemuMonitorPtr mon, const char *diskAlias, int type, int status);
- - int qemuMonitorStartCPUs(qemuMonitorPtr mon, virConnectPtr conn); int qemuMonitorStopCPUs(qemuMonitorPtr mon); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 1a0ee94..0312ca7 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 qemuMonitorJSONHandleTrayChange(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", qemuMonitorJSONHandleTrayChange, }, };
@@ -725,6 +727,31 @@ out: 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 qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index ef311d1..b6e14ad 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 +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 = { .destroy = qemuProcessHandleMonitorDestroy, .eofNotify = qemuProcessHandleMonitorEOF, @@ -1034,6 +1065,7 @@ static qemuMonitorCallbacks monitorCallbacks = { .domainIOError = qemuProcessHandleIOError, .domainGraphics = qemuProcessHandleGraphics, .domainBlockJob = qemuProcessHandleBlockJob, + .domainTrayChange = qemuProcessHandleTrayChange, };
static int diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 031167a..ac95dcc 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 +remoteDomainBuildEventTrayChange(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_CHANGE, + remoteDomainBuildEventTrayChange, + sizeof(remote_domain_event_tray_change_msg), + (xdrproc_t)xdr_remote_domain_event_tray_change_msg }, };
enum virDrvOpenRemoteFlags { @@ -3645,6 +3654,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) remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags) diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 4d845e7..6c8c497 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_change_msg { + remote_nonnull_domain dom; + remote_nonnull_string devAlias; + int reason; +}; + 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_CHANGE = 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..0ce7c1c 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_change_msg { + remote_nonnull_domain dom; + remote_nonnull_string devAlias; + int reason; +} struct remote_domain_managed_save_args { remote_nonnull_domain dom; u_int flags; @@ -2178,4 +2183,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_METADATA = 265, REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266, REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, + REMOTE_PROC_DOMAIN_TRAY_CHANGE = 268, };
ACK, looks fine to me, but it needs a bit of rebase because the Spice events went in in the meantime. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Example XML: <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/tmp/cdrom.img'/> <target dev='hdd' bus='ide' tray='open'/> </disk> --- docs/formatdomain.html.in | 13 +++++++++---- docs/schemas/domaincommon.rng | 8 ++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index bf0675e..da335dd 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1116,7 +1116,7 @@ </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='open'/> <readonly/> </disk> <disk type='block' device='lun'> @@ -1227,10 +1227,15 @@ possible values are driver specific, with typical values being "ide", "scsi", "virtio", "xen", "usb" or "sata". If omitted, the bus type is inferred from the style of the device name. eg, a device named - 'sda' will typically be exported using a SCSI bus. + 'sda' will typically be exported using a SCSI bus. The optional + attribute <code>tray</code> indicates the tray status of the + removable disks (i.e. CDROM or Floppy disk), the value can be either + "open" or "closed", defaults to "closed". NB, the value of + <code>tray</code> could be updated while the domain is running. <span class="since">Since 0.0.3; <code>bus</code> attribute since 0.4.3; - "usb" attribute value since after 0.4.4; "sata" attribute value since - 0.9.7</span></dd> + <code>tray</code> attribute since 0.9.11; "usb" attribute value since + after 0.4.4; "sata" attribute value since 0.9.7</span> + </dd> <dt><code>iotune</code></dt> <dd>The optional <code>iotune</code> element provides the ability to provide additional per-device I/O tuning, with diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 646a51b..bb04273 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -959,6 +959,14 @@ </choice> </attribute> </optional> + <optional> + <attribute name="tray"> + <choice> + <value>open</value> + <value>closed</value> + </choice> + </attribute> + </optional> </element> </define> <!-- -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:46PM +0800, Osier Yang wrote:
Example XML:
<disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/tmp/cdrom.img'/> <target dev='hdd' bus='ide' tray='open'/> </disk> --- docs/formatdomain.html.in | 13 +++++++++---- docs/schemas/domaincommon.rng | 8 ++++++++ 2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index bf0675e..da335dd 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1116,7 +1116,7 @@ </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='open'/> <readonly/> </disk> <disk type='block' device='lun'> @@ -1227,10 +1227,15 @@ possible values are driver specific, with typical values being "ide", "scsi", "virtio", "xen", "usb" or "sata". If omitted, the bus type is inferred from the style of the device name. eg, a device named - 'sda' will typically be exported using a SCSI bus. + 'sda' will typically be exported using a SCSI bus. The optional + attribute <code>tray</code> indicates the tray status of the + removable disks (i.e. CDROM or Floppy disk), the value can be either + "open" or "closed", defaults to "closed". NB, the value of + <code>tray</code> could be updated while the domain is running. <span class="since">Since 0.0.3; <code>bus</code> attribute since 0.4.3; - "usb" attribute value since after 0.4.4; "sata" attribute value since - 0.9.7</span></dd> + <code>tray</code> attribute since 0.9.11; "usb" attribute value since + after 0.4.4; "sata" attribute value since 0.9.7</span> + </dd>
could have kept them in ascending order version but it's cosmetic
<dt><code>iotune</code></dt> <dd>The optional <code>iotune</code> element provides the ability to provide additional per-device I/O tuning, with diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 646a51b..bb04273 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -959,6 +959,14 @@ </choice> </attribute> </optional> + <optional> + <attribute name="tray"> + <choice> + <value>open</value> + <value>closed</value> + </choice> + </attribute> + </optional> </element> </define> <!-- -- 1.7.1
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The "tray" is only allowed for removable disks, i.e. CDROM and Floppy disks. As the value for "tray" defaults to "closed", lots of tests are updated to include "tray='closed'" in the disk target XML. --- src/conf/domain_conf.c | 33 +++++++++++++++++++- src/conf/domain_conf.h | 9 +++++ tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml | 2 +- .../qemuxml2argv-boot-complex-bootindex.xml | 6 ++-- .../qemuxml2argvdata/qemuxml2argv-boot-complex.xml | 6 ++-- .../qemuxml2argvdata/qemuxml2argv-boot-floppy.xml | 2 +- ...uxml2argv-boot-menu-disable-drive-bootindex.xml | 2 +- .../qemuxml2argv-boot-menu-disable-drive.xml | 2 +- .../qemuxml2argv-boot-menu-disable.xml | 2 +- .../qemuxml2argv-boot-menu-enable.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml | 4 +- tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml | 2 +- .../qemuxml2argv-disk-cdrom-empty.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml | 2 +- .../qemuxml2argv-disk-copy_on_read.xml | 2 +- .../qemuxml2argv-disk-drive-boot-cdrom.xml | 2 +- .../qemuxml2argv-disk-drive-boot-disk.xml | 2 +- .../qemuxml2argv-disk-drive-cache-directsync.xml | 2 +- .../qemuxml2argv-disk-drive-cache-unsafe.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-none.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wb.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wt.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-none.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wb.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wt.xml | 2 +- ...muxml2argv-disk-drive-error-policy-enospace.xml | 2 +- .../qemuxml2argv-disk-drive-error-policy-stop.xml | 2 +- ...rgv-disk-drive-error-policy-wreport-rignore.xml | 2 +- .../qemuxml2argv-disk-drive-fmt-qcow.xml | 2 +- .../qemuxml2argv-disk-drive-no-boot.xml | 4 +- .../qemuxml2argv-disk-drive-readonly-disk.xml | 2 +- .../qemuxml2argv-disk-drive-readonly-no-device.xml | 2 +- .../qemuxml2argv-disk-drive-shared.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-floppy.xml | 4 +- .../qemuxml2argv-disk-ioeventfd.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml | 2 +- .../qemuxml2argv-disk-snapshot.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-virtio.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml | 2 +- .../qemuxml2argv-floppy-drive-fat.xml | 2 +- .../qemuxml2argv-graphics-spice-timeout.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-lease.xml | 2 +- .../qemuxml2argv-net-bandwidth.xml | 2 +- .../qemuxml2xmlout-graphics-spice-timeout.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml | 8 ++-- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml | 4 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml | 2 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml | 2 +- tests/vmx2xmldata/vmx2xml-floppy-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-floppy-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml | 2 +- tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml | 2 +- 59 files changed, 109 insertions(+), 69 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e2ed115..10174ab 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -624,6 +624,10 @@ VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST, "requisite", "optional"); +VIR_ENUM_IMPL(virDomainDiskTray, VIR_DOMAIN_DISK_TRAY_LAST, + "closed", + "open"); + #define virDomainReportError(code, ...) \ virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) @@ -3307,6 +3311,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, char *authUsage = NULL; char *authUUID = NULL; char *usageType = NULL; + char *tray = NULL; if (VIR_ALLOC(def) < 0) { virReportOOMError(); @@ -3415,6 +3420,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, (xmlStrEqual(cur->name, BAD_CAST "target"))) { target = virXMLPropString(cur, "dev"); bus = virXMLPropString(cur, "bus"); + tray = virXMLPropString(cur, "tray"); /* HACK: Work around for compat with Xen * driver in previous libvirt releases */ @@ -3684,6 +3690,25 @@ virDomainDiskDefParseXML(virCapsPtr caps, } } + if (tray) { + if ((def->tray_status = virDomainDiskTrayTypeFromString(tray)) < 0) { + virDomainReportError(VIR_ERR_XML_ERROR, + _("unknown disk tray status '%s'"), tray); + goto error; + } + + if (def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY && + def->device != VIR_DOMAIN_DISK_DEVICE_CDROM) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("tray is only valid for cdrom and floppy")); + goto error; + } + } else { + if (def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || + def->device == VIR_DOMAIN_DISK_DEVICE_CDROM) + def->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED; + } + if (def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY && def->bus != VIR_DOMAIN_DISK_BUS_FDC) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, @@ -10666,8 +10691,14 @@ virDomainDiskDefFormat(virBufferPtr buf, } } - virBufferAsprintf(buf, " <target dev='%s' bus='%s'/>\n", + virBufferAsprintf(buf, " <target dev='%s' bus='%s'", def->dst, bus); + if (def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || + def->device == VIR_DOMAIN_DISK_DEVICE_CDROM) + virBufferAsprintf(buf, " tray='%s'/>\n", + virDomainDiskTrayTypeToString(def->tray_status)); + else + virBufferAddLit(buf, "/>\n"); /*disk I/O throttling*/ if (def->blkdeviotune.total_bytes_sec || diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6da22f4..3c19534 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -451,6 +451,13 @@ enum virDomainDiskProtocol { VIR_DOMAIN_DISK_PROTOCOL_LAST }; +enum virDomainDiskTray { + VIR_DOMAIN_DISK_TRAY_CLOSED, + VIR_DOMAIN_DISK_TRAY_OPEN, + + VIR_DOMAIN_DISK_TRAY_LAST +}; + typedef struct _virDomainDiskHostDef virDomainDiskHostDef; typedef virDomainDiskHostDef *virDomainDiskHostDefPtr; struct _virDomainDiskHostDef { @@ -541,6 +548,7 @@ struct _virDomainDiskDef { char *src; virSecurityDeviceLabelDefPtr seclabel; char *dst; + int tray_status; int protocol; int nhosts; virDomainDiskHostDefPtr hosts; @@ -2093,6 +2101,7 @@ VIR_ENUM_DECL(virDomainDiskProtocol) VIR_ENUM_DECL(virDomainDiskIo) VIR_ENUM_DECL(virDomainDiskSecretType) VIR_ENUM_DECL(virDomainDiskSnapshot) +VIR_ENUM_DECL(virDomainDiskTray) VIR_ENUM_DECL(virDomainIoEventFd) VIR_ENUM_DECL(virDomainVirtioEventIdx) VIR_ENUM_DECL(virDomainDiskCopyOnRead) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml index 77c73a1..d83773b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml @@ -16,7 +16,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-complex-bootindex.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-complex-bootindex.xml index 3aab45e..babb33f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-complex-bootindex.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-complex-bootindex.xml @@ -37,17 +37,17 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/hdc'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd1'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-complex.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-complex.xml index 3aab45e..babb33f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-complex.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-complex.xml @@ -37,17 +37,17 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/hdc'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd1'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml index 25490f1..f61890a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml @@ -21,7 +21,7 @@ </disk> <disk type='file' device='floppy'> <source file='/tmp/firmware.img'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.xml index f8eda91..3d085c9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.xml @@ -17,7 +17,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive.xml index f8eda91..3d085c9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive.xml @@ -17,7 +17,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml index f8eda91..3d085c9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml @@ -17,7 +17,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-enable.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-enable.xml index 89e1172..93d3bde 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-enable.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-enable.xml @@ -17,7 +17,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml index eca1307..cc98ee7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml @@ -20,7 +20,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml index cbbc958..d5c9dde 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml @@ -20,7 +20,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/root/boot.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <boot order='1'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> @@ -36,7 +36,7 @@ <disk type='file' device='floppy'> <driver name='qemu' type='raw'/> <source file='/dev/null'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <boot order='4'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml index d201252..7e9126f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml @@ -16,7 +16,7 @@ <emulator>/usr/bin/xenner</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml index e29b75e..82b5d20 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw' io='threads'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml index 88f650f..7849335 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml @@ -20,7 +20,7 @@ <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='cdrom'> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml index 6bdd46b..1772fed 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml @@ -21,7 +21,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/root/boot.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-copy_on_read.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-copy_on_read.xml index 48c742b..01b0ef3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-copy_on_read.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-copy_on_read.xml @@ -23,7 +23,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml index d137231..056a175 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml index 5e638cd..4969a5d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml index 2abae66..ee44c9c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml index e4d29c7..9e8ad59 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml index f3deecc..0321730 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml index dc0d595..31cb1e6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml index af39de0..4419c28 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml index 63e82f0..847a62f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml index 14f9a28..97c8c16 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml index 5da9d2c..7dc6dce 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-enospace.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-enospace.xml index d3b446b..65dd0cc 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-enospace.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-enospace.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml index 721a5f6..26b0a29 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-wreport-rignore.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-wreport-rignore.xml index 07a4cf7..066df48 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-wreport-rignore.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-wreport-rignore.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml index 0fa5897..54e4e3c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-no-boot.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-no-boot.xml index 5750ab2..b24242a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-no-boot.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-no-boot.xml @@ -23,12 +23,12 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml index ab75067..a5b528b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/sr0'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-no-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-no-device.xml index ab75067..a5b528b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-no-device.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-no-device.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/sr0'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml index 0760afa..235a0a9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml @@ -25,7 +25,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml index b9240cf..5ed9bb5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml @@ -21,12 +21,12 @@ </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='floppy'> <source file='/tmp/firmware.img'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-ioeventfd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-ioeventfd.xml index 82a6999..b5dd99d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-ioeventfd.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-ioeventfd.xml @@ -23,7 +23,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml index 10cdee7..47e5eef 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml @@ -16,7 +16,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> </disk> <disk type='file' device='disk'> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml index 019603d..26ea137 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom' snapshot='no'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml index 00111be..091c0e2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml index 2fa1e38..26b0af5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml b/tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml index 5c4664c..755dcdf 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml @@ -25,7 +25,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml index c31bb29..04a0910 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml @@ -17,7 +17,7 @@ <disk type='dir' device='floppy'> <driver name='qemu' type='fat'/> <source dir='/var/somefiles'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml index 8f751ff..6400292 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml @@ -48,7 +48,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-lease.xml b/tests/qemuxml2argvdata/qemuxml2argv-lease.xml index c915cd7..dbfacb6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-lease.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-lease.xml @@ -21,7 +21,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/root/boot.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-bandwidth.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-bandwidth.xml index e1cfdc6..a5e6517 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-bandwidth.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-bandwidth.xml @@ -30,7 +30,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/home/zippy/tmp/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml index 14df58a..0a89946 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml @@ -48,7 +48,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml b/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml index 726e4cf..ffe3e9b 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml @@ -13,7 +13,7 @@ <devices> <disk type='block' device='cdrom'> <source dev='/dev/scd0'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='ide' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml b/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml index 7fc6b3b..6c7f475 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml @@ -13,7 +13,7 @@ <devices> <disk type='file' device='cdrom'> <source file='[datastore] directory/cdrom.iso'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='ide' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml index 7e823e8..30378cd 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml @@ -13,7 +13,7 @@ <devices> <disk type='block' device='cdrom'> <source dev='/dev/scd0'/> - <target dev='sda' bus='scsi'/> + <target dev='sda' bus='scsi' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='scsi' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml index d4179af..f6db8d7 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml @@ -13,7 +13,7 @@ <devices> <disk type='file' device='cdrom'> <source file='[datastore] directory/cdrom.iso'/> - <target dev='sda' bus='scsi'/> + <target dev='sda' bus='scsi' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='scsi' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml index de678c1..90147e2 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml @@ -20,17 +20,17 @@ </disk> <disk type='file' device='cdrom'> <source file='[datastore] directory/Debian1-cdrom.iso'/> - <target dev='sdp' bus='scsi'/> + <target dev='sdp' bus='scsi' tray='closed'/> <address type='drive' controller='1' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='cdrom'> <source file='/vmimages/tools-isoimages/linux.iso'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <source dev='/dev/scd0'/> - <target dev='hdb' bus='ide'/> + <target dev='hdb' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <disk type='file' device='disk'> @@ -40,7 +40,7 @@ </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml index 4101634..d49c52f 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml @@ -19,12 +19,12 @@ </disk> <disk type='file' device='cdrom'> <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Isos/debian-testing-amd64-netinst.iso'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='floppy'> <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Debian2/dummy.flp'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml index e1b7040..654b645 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml @@ -26,7 +26,7 @@ </disk> <disk type='file' device='cdrom'> <source file='[4af0231d-1eff559a-6369-0024e84773b6] isos/CentOS-5.5-x86_64-bin-DVD-1of2.iso'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml index 5583cff..0f42ad7 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml @@ -19,7 +19,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/usr/lib/vmware/isoimages/linux.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='vmpvscsi'/> diff --git a/tests/vmx2xmldata/vmx2xml-floppy-device.xml b/tests/vmx2xmldata/vmx2xml-floppy-device.xml index 41cda93..f8eac2e 100644 --- a/tests/vmx2xmldata/vmx2xml-floppy-device.xml +++ b/tests/vmx2xmldata/vmx2xml-floppy-device.xml @@ -13,7 +13,7 @@ <devices> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='fdc' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-floppy-file.xml b/tests/vmx2xmldata/vmx2xml-floppy-file.xml index f436a3b..3e25249 100644 --- a/tests/vmx2xmldata/vmx2xml-floppy-file.xml +++ b/tests/vmx2xmldata/vmx2xml-floppy-file.xml @@ -13,7 +13,7 @@ <devices> <disk type='file' device='floppy'> <source file='[datastore] directory/floppy.flp'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='fdc' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml b/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml index 2cca409..9bc4a49 100644 --- a/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml +++ b/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml @@ -19,7 +19,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/usr/lib/vmware/isoimages/linux.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> diff --git a/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml b/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml index 391e45c..94efc0f 100644 --- a/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml +++ b/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml @@ -19,7 +19,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/usr/lib/vmware/isoimages/linux.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:47PM +0800, Osier Yang wrote:
The "tray" is only allowed for removable disks, i.e. CDROM and Floppy disks.
As the value for "tray" defaults to "closed", lots of tests are updated to include "tray='closed'" in the disk target XML.
I tend to think "tray='closed'" should be ommited since it's the default value, no need to serialize it out systematically
src/conf/domain_conf.c | 33 +++++++++++++++++++- src/conf/domain_conf.h | 9 +++++ tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml | 2 +- .../qemuxml2argv-boot-complex-bootindex.xml | 6 ++-- .../qemuxml2argvdata/qemuxml2argv-boot-complex.xml | 6 ++-- .../qemuxml2argvdata/qemuxml2argv-boot-floppy.xml | 2 +- ...uxml2argv-boot-menu-disable-drive-bootindex.xml | 2 +- .../qemuxml2argv-boot-menu-disable-drive.xml | 2 +- .../qemuxml2argv-boot-menu-disable.xml | 2 +- .../qemuxml2argv-boot-menu-enable.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml | 4 +- tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml | 2 +- .../qemuxml2argv-disk-cdrom-empty.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml | 2 +- .../qemuxml2argv-disk-copy_on_read.xml | 2 +- .../qemuxml2argv-disk-drive-boot-cdrom.xml | 2 +- .../qemuxml2argv-disk-drive-boot-disk.xml | 2 +- .../qemuxml2argv-disk-drive-cache-directsync.xml | 2 +- .../qemuxml2argv-disk-drive-cache-unsafe.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-none.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wb.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wt.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-none.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wb.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wt.xml | 2 +- ...muxml2argv-disk-drive-error-policy-enospace.xml | 2 +- .../qemuxml2argv-disk-drive-error-policy-stop.xml | 2 +- ...rgv-disk-drive-error-policy-wreport-rignore.xml | 2 +- .../qemuxml2argv-disk-drive-fmt-qcow.xml | 2 +- .../qemuxml2argv-disk-drive-no-boot.xml | 4 +- .../qemuxml2argv-disk-drive-readonly-disk.xml | 2 +- .../qemuxml2argv-disk-drive-readonly-no-device.xml | 2 +- .../qemuxml2argv-disk-drive-shared.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-floppy.xml | 4 +- .../qemuxml2argv-disk-ioeventfd.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml | 2 +- .../qemuxml2argv-disk-snapshot.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-virtio.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml | 2 +- .../qemuxml2argv-floppy-drive-fat.xml | 2 +- .../qemuxml2argv-graphics-spice-timeout.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-lease.xml | 2 +- .../qemuxml2argv-net-bandwidth.xml | 2 +- .../qemuxml2xmlout-graphics-spice-timeout.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml | 8 ++-- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml | 4 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml | 2 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml | 2 +- tests/vmx2xmldata/vmx2xml-floppy-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-floppy-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml | 2 +- tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml | 2 +- 59 files changed, 109 insertions(+), 69 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e2ed115..10174ab 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -624,6 +624,10 @@ VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST, "requisite", "optional");
+VIR_ENUM_IMPL(virDomainDiskTray, VIR_DOMAIN_DISK_TRAY_LAST, + "closed", + "open"); + #define virDomainReportError(code, ...) \ virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) @@ -3307,6 +3311,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, char *authUsage = NULL; char *authUUID = NULL; char *usageType = NULL; + char *tray = NULL;
if (VIR_ALLOC(def) < 0) { virReportOOMError(); @@ -3415,6 +3420,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, (xmlStrEqual(cur->name, BAD_CAST "target"))) { target = virXMLPropString(cur, "dev"); bus = virXMLPropString(cur, "bus"); + tray = virXMLPropString(cur, "tray");
/* HACK: Work around for compat with Xen * driver in previous libvirt releases */ @@ -3684,6 +3690,25 @@ virDomainDiskDefParseXML(virCapsPtr caps, } }
+ if (tray) { + if ((def->tray_status = virDomainDiskTrayTypeFromString(tray)) < 0) { + virDomainReportError(VIR_ERR_XML_ERROR, + _("unknown disk tray status '%s'"), tray); + goto error; + } + + if (def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY && + def->device != VIR_DOMAIN_DISK_DEVICE_CDROM) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("tray is only valid for cdrom and floppy")); + goto error; + } + } else { + if (def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || + def->device == VIR_DOMAIN_DISK_DEVICE_CDROM) + def->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED; + } + if (def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY && def->bus != VIR_DOMAIN_DISK_BUS_FDC) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, @@ -10666,8 +10691,14 @@ virDomainDiskDefFormat(virBufferPtr buf, } }
- virBufferAsprintf(buf, " <target dev='%s' bus='%s'/>\n", + virBufferAsprintf(buf, " <target dev='%s' bus='%s'", def->dst, bus); + if (def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || + def->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
I would add here && (def->tray_status != VIR_DOMAIN_DISK_TRAY_CLOSED)) and keep most of the test outputs identical !
+ virBufferAsprintf(buf, " tray='%s'/>\n", + virDomainDiskTrayTypeToString(def->tray_status)); + else + virBufferAddLit(buf, "/>\n");
/*disk I/O throttling*/ if (def->blkdeviotune.total_bytes_sec || diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6da22f4..3c19534 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -451,6 +451,13 @@ enum virDomainDiskProtocol { VIR_DOMAIN_DISK_PROTOCOL_LAST };
+enum virDomainDiskTray { + VIR_DOMAIN_DISK_TRAY_CLOSED, + VIR_DOMAIN_DISK_TRAY_OPEN, + + VIR_DOMAIN_DISK_TRAY_LAST +}; + typedef struct _virDomainDiskHostDef virDomainDiskHostDef; typedef virDomainDiskHostDef *virDomainDiskHostDefPtr; struct _virDomainDiskHostDef { @@ -541,6 +548,7 @@ struct _virDomainDiskDef { char *src; virSecurityDeviceLabelDefPtr seclabel; char *dst; + int tray_status; int protocol; int nhosts; virDomainDiskHostDefPtr hosts; @@ -2093,6 +2101,7 @@ VIR_ENUM_DECL(virDomainDiskProtocol) VIR_ENUM_DECL(virDomainDiskIo) VIR_ENUM_DECL(virDomainDiskSecretType) VIR_ENUM_DECL(virDomainDiskSnapshot) +VIR_ENUM_DECL(virDomainDiskTray) VIR_ENUM_DECL(virDomainIoEventFd) VIR_ENUM_DECL(virDomainVirtioEventIdx) VIR_ENUM_DECL(virDomainDiskCopyOnRead) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml index 77c73a1..d83773b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml @@ -16,7 +16,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-complex-bootindex.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-complex-bootindex.xml index 3aab45e..babb33f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-complex-bootindex.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-complex-bootindex.xml @@ -37,17 +37,17 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/hdc'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd1'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-complex.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-complex.xml index 3aab45e..babb33f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-complex.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-complex.xml @@ -37,17 +37,17 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/hdc'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd1'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml index 25490f1..f61890a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml @@ -21,7 +21,7 @@ </disk> <disk type='file' device='floppy'> <source file='/tmp/firmware.img'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.xml index f8eda91..3d085c9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive-bootindex.xml @@ -17,7 +17,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive.xml index f8eda91..3d085c9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable-drive.xml @@ -17,7 +17,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml index f8eda91..3d085c9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml @@ -17,7 +17,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-enable.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-enable.xml index 89e1172..93d3bde 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-enable.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-enable.xml @@ -17,7 +17,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml index eca1307..cc98ee7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml @@ -20,7 +20,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml index cbbc958..d5c9dde 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml @@ -20,7 +20,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/root/boot.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <boot order='1'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> @@ -36,7 +36,7 @@ <disk type='file' device='floppy'> <driver name='qemu' type='raw'/> <source file='/dev/null'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <boot order='4'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml index d201252..7e9126f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml @@ -16,7 +16,7 @@ <emulator>/usr/bin/xenner</emulator> <disk type='block' device='cdrom'> <source dev='/dev/cdrom'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml index e29b75e..82b5d20 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw' io='threads'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml index 88f650f..7849335 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml @@ -20,7 +20,7 @@ <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='cdrom'> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml index 6bdd46b..1772fed 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml @@ -21,7 +21,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/root/boot.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-copy_on_read.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-copy_on_read.xml index 48c742b..01b0ef3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-copy_on_read.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-copy_on_read.xml @@ -23,7 +23,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml index d137231..056a175 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml index 5e638cd..4969a5d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml index 2abae66..ee44c9c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml index e4d29c7..9e8ad59 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml index f3deecc..0321730 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml index dc0d595..31cb1e6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml index af39de0..4419c28 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml index 63e82f0..847a62f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml index 14f9a28..97c8c16 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml index 5da9d2c..7dc6dce 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-enospace.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-enospace.xml index d3b446b..65dd0cc 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-enospace.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-enospace.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml index 721a5f6..26b0a29 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-stop.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-wreport-rignore.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-wreport-rignore.xml index 07a4cf7..066df48 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-wreport-rignore.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-error-policy-wreport-rignore.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml index 0fa5897..54e4e3c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-no-boot.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-no-boot.xml index 5750ab2..b24242a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-no-boot.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-no-boot.xml @@ -23,12 +23,12 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml index ab75067..a5b528b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/sr0'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-no-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-no-device.xml index ab75067..a5b528b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-no-device.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-no-device.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/sr0'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml index 0760afa..235a0a9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml @@ -25,7 +25,7 @@ <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml index b9240cf..5ed9bb5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml @@ -21,12 +21,12 @@ </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='floppy'> <source file='/tmp/firmware.img'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <controller type='usb' index='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-ioeventfd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-ioeventfd.xml index 82a6999..b5dd99d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-ioeventfd.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-ioeventfd.xml @@ -23,7 +23,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml index 10cdee7..47e5eef 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml @@ -16,7 +16,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> </disk> <disk type='file' device='disk'> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml index 019603d..26ea137 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml @@ -23,7 +23,7 @@ <disk type='block' device='cdrom' snapshot='no'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml index 00111be..091c0e2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml index 2fa1e38..26b0af5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml @@ -21,7 +21,7 @@ </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml b/tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml index 5c4664c..755dcdf 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml @@ -25,7 +25,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml index c31bb29..04a0910 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml @@ -17,7 +17,7 @@ <disk type='dir' device='floppy'> <driver name='qemu' type='fat'/> <source dir='/var/somefiles'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml index 8f751ff..6400292 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml @@ -48,7 +48,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-lease.xml b/tests/qemuxml2argvdata/qemuxml2argv-lease.xml index c915cd7..dbfacb6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-lease.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-lease.xml @@ -21,7 +21,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/root/boot.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-bandwidth.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-bandwidth.xml index e1cfdc6..a5e6517 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-bandwidth.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-bandwidth.xml @@ -30,7 +30,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/home/zippy/tmp/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml index 14df58a..0a89946 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml @@ -48,7 +48,7 @@ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml b/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml index 726e4cf..ffe3e9b 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml @@ -13,7 +13,7 @@ <devices> <disk type='block' device='cdrom'> <source dev='/dev/scd0'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='ide' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml b/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml index 7fc6b3b..6c7f475 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml @@ -13,7 +13,7 @@ <devices> <disk type='file' device='cdrom'> <source file='[datastore] directory/cdrom.iso'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='ide' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml index 7e823e8..30378cd 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml @@ -13,7 +13,7 @@ <devices> <disk type='block' device='cdrom'> <source dev='/dev/scd0'/> - <target dev='sda' bus='scsi'/> + <target dev='sda' bus='scsi' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='scsi' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml index d4179af..f6db8d7 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml @@ -13,7 +13,7 @@ <devices> <disk type='file' device='cdrom'> <source file='[datastore] directory/cdrom.iso'/> - <target dev='sda' bus='scsi'/> + <target dev='sda' bus='scsi' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='scsi' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml index de678c1..90147e2 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml @@ -20,17 +20,17 @@ </disk> <disk type='file' device='cdrom'> <source file='[datastore] directory/Debian1-cdrom.iso'/> - <target dev='sdp' bus='scsi'/> + <target dev='sdp' bus='scsi' tray='closed'/> <address type='drive' controller='1' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='cdrom'> <source file='/vmimages/tools-isoimages/linux.iso'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <source dev='/dev/scd0'/> - <target dev='hdb' bus='ide'/> + <target dev='hdb' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <disk type='file' device='disk'> @@ -40,7 +40,7 @@ </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml index 4101634..d49c52f 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml @@ -19,12 +19,12 @@ </disk> <disk type='file' device='cdrom'> <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Isos/debian-testing-amd64-netinst.iso'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='floppy'> <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Debian2/dummy.flp'/> - <target dev='fdb' bus='fdc'/> + <target dev='fdb' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml index e1b7040..654b645 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml @@ -26,7 +26,7 @@ </disk> <disk type='file' device='cdrom'> <source file='[4af0231d-1eff559a-6369-0024e84773b6] isos/CentOS-5.5-x86_64-bin-DVD-1of2.iso'/> - <target dev='hda' bus='ide'/> + <target dev='hda' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml index 5583cff..0f42ad7 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml @@ -19,7 +19,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/usr/lib/vmware/isoimages/linux.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='vmpvscsi'/> diff --git a/tests/vmx2xmldata/vmx2xml-floppy-device.xml b/tests/vmx2xmldata/vmx2xml-floppy-device.xml index 41cda93..f8eac2e 100644 --- a/tests/vmx2xmldata/vmx2xml-floppy-device.xml +++ b/tests/vmx2xmldata/vmx2xml-floppy-device.xml @@ -13,7 +13,7 @@ <devices> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='fdc' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-floppy-file.xml b/tests/vmx2xmldata/vmx2xml-floppy-file.xml index f436a3b..3e25249 100644 --- a/tests/vmx2xmldata/vmx2xml-floppy-file.xml +++ b/tests/vmx2xmldata/vmx2xml-floppy-file.xml @@ -13,7 +13,7 @@ <devices> <disk type='file' device='floppy'> <source file='[datastore] directory/floppy.flp'/> - <target dev='fda' bus='fdc'/> + <target dev='fda' bus='fdc' tray='closed'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='fdc' index='0'/> diff --git a/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml b/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml index 2cca409..9bc4a49 100644 --- a/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml +++ b/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml @@ -19,7 +19,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/usr/lib/vmware/isoimages/linux.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> diff --git a/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml b/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml index 391e45c..94efc0f 100644 --- a/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml +++ b/tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml @@ -19,7 +19,7 @@ </disk> <disk type='file' device='cdrom'> <source file='/usr/lib/vmware/isoimages/linux.iso'/> - <target dev='hdc' bus='ide'/> + <target dev='hdc' bus='ide' tray='closed'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <controller type='scsi' index='0' model='lsilogic'/> -- 1.7.1
Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 03/23/2012 04:05 PM, Daniel Veillard wrote:
On Wed, Mar 14, 2012 at 11:26:47PM +0800, Osier Yang wrote:
The "tray" is only allowed for removable disks, i.e. CDROM and Floppy disks.
As the value for "tray" defaults to "closed", lots of tests are updated to include "tray='closed'" in the disk target XML. I tend to think "tray='closed'" should be ommited since it's the default value, no need to serialize it out systematically
Not sure which way is better, but from my point of view, it's more explicit for a user's eyes to see what the tray status is, and when updating the device, changing the value of "tray" between "open" and "closed" is more sensiable than "adding tray='open'" and "removing tray='open'" (supposing QEMU will support CD-ROM and Floppy device updating with tray status in future, e.g. a qemu monitor command "change-tray", and one uses "virsh edit" to change the XML). But I acknowledge all these reasons are weak somehow, :-) so I'm fine with either. By the way, it seems to me it's not consistent on whether to print the default value for tags or not, some tags do, some not. Such as rawio='no' for disk won't be printed, and managed='no' for hostdevs will be printed. Osier

On Fri, Mar 23, 2012 at 05:48:32PM +0800, Osier Yang wrote:
On 03/23/2012 04:05 PM, Daniel Veillard wrote:
On Wed, Mar 14, 2012 at 11:26:47PM +0800, Osier Yang wrote:
The "tray" is only allowed for removable disks, i.e. CDROM and Floppy disks.
As the value for "tray" defaults to "closed", lots of tests are updated to include "tray='closed'" in the disk target XML. I tend to think "tray='closed'" should be ommited since it's the default value, no need to serialize it out systematically
Not sure which way is better, but from my point of view, it's more explicit for a user's eyes to see what the tray status is, and when updating the device, changing the value of "tray" between "open" and "closed" is more sensiable than "adding tray='open'" and "removing tray='open'" (supposing QEMU will support CD-ROM and Floppy device updating with tray status in future, e.g. a qemu monitor command "change-tray", and one uses "virsh edit" to change the XML).
But I acknowledge all these reasons are weak somehow, :-) so I'm fine with either.
By the way, it seems to me it's not consistent on whether to print the default value for tags or not, some tags do, some not. Such as rawio='no' for disk won't be printed, and managed='no' for hostdevs will be printed.
Well in this case I would expect tray="closed" 99% of the time (if not more as on a physical machine !) so to me the only data worth noticing is tray="open", and actually not dumping tray="closed" makes the fact that the tray is open more ovious IMHO. So yeah I really think it's better even from an human POV (well I'm firmly convinced that users should never see XML dumps but that's a different story :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 03/23/2012 05:29 PM, Daniel Veillard wrote:
On Fri, Mar 23, 2012 at 05:48:32PM +0800, Osier Yang wrote:
On 03/23/2012 04:05 PM, Daniel Veillard wrote:
On Wed, Mar 14, 2012 at 11:26:47PM +0800, Osier Yang wrote:
The "tray" is only allowed for removable disks, i.e. CDROM and Floppy disks.
As the value for "tray" defaults to "closed", lots of tests are updated to include "tray='closed'" in the disk target XML. I tend to think "tray='closed'" should be ommited since it's the default value, no need to serialize it out systematically
Not sure which way is better, but from my point of view, it's more explicit for a user's eyes to see what the tray status is, and when updating the device, changing the value of "tray" between "open" and "closed" is more sensiable than "adding tray='open'" and "removing tray='open'" (supposing QEMU will support CD-ROM and Floppy device updating with tray status in future, e.g. a qemu monitor command "change-tray", and one uses "virsh edit" to change the XML).
But I acknowledge all these reasons are weak somehow, :-) so I'm fine with either.
By the way, it seems to me it's not consistent on whether to print the default value for tags or not, some tags do, some not. Such as rawio='no' for disk won't be printed, and managed='no' for hostdevs will be printed.
Well in this case I would expect tray="closed" 99% of the time (if not more as on a physical machine !) so to me the only data worth noticing is tray="open", and actually not dumping tray="closed" makes the fact that the tray is open more ovious IMHO.
So yeah I really think it's better even from an human POV (well I'm firmly convinced that users should never see XML dumps but that's a different story :-)
I pushed with no tray='closed' in domain XML, with indention nits fixed incidentally. Thanks for the revewing. Regards, Osier

This is similiar with physical world, one will be surprised if the box starts with medium exists while the tray is open. New tests are added, tests disk-{cdrom,floppy}-tray are for the qemu supports "-device" flag, and disk-{cdrom,floppy}-no-device-cap are for old qemu, i.e. which doesn't support "-device" flag. --- src/qemu/qemu_command.c | 16 ++++++- ...qemuxml2argv-disk-cdrom-tray-no-device-cap.args | 4 ++ .../qemuxml2argv-disk-cdrom-tray-no-device-cap.xml | 32 +++++++++++++++ .../qemuxml2argv-disk-cdrom-tray.args | 10 +++++ .../qemuxml2argv-disk-cdrom-tray.xml | 43 ++++++++++++++++++++ ...emuxml2argv-disk-floppy-tray-no-device-cap.args | 4 ++ ...qemuxml2argv-disk-floppy-tray-no-device-cap.xml | 37 +++++++++++++++++ .../qemuxml2argv-disk-floppy-tray.args | 10 +++++ .../qemuxml2argv-disk-floppy-tray.xml | 37 +++++++++++++++++ tests/qemuxml2argvtest.c | 6 +++ 10 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d5442e7..ba6edce 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1908,8 +1908,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, } /* disk->src is NULL when we use nbd disks */ - if (disk->src || (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK && - disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) { + if ((disk->src || + (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK && + disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) && + !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || + disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) && + disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) { if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) { /* QEMU only supports magic FAT format for now */ if (disk->driverType && @@ -4720,7 +4724,13 @@ qemuBuildCommandLine(virConnectPtr conn, } } - virCommandAddArgList(cmd, dev, file, NULL); + /* Don't start with source if the tray is open for + * CDROM and Floppy device. + */ + if (!((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || + disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) && + disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) + virCommandAddArgList(cmd, dev, file, NULL); VIR_FREE(file); } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.args new file mode 100644 index 0000000..5cd000e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none \ +-serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.xml new file mode 100644 index 0000000..9f891c7 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219100</memory> + <currentMemory>219100</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='cdrom'> + <source file='/root/boot.iso'/> + <target dev='hdc' bus='ide' tray='open'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.args new file mode 100644 index 0000000..dfa0006 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.args @@ -0,0 +1,10 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/bin/qemu -S -M pc-0.13 -m 1024 -smp 1 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot dc \ +-drive file=/var/lib/libvirt/images/f14.img,if=none,id=drive-virtio-disk0 \ +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0 \ +-drive file=/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso,if=none,media=cdrom,id=drive-ide0-1-0 \ +-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \ +-drive if=none,media=cdrom,id=drive-ide0-1-1 \ +-device ide-drive,bus=ide.1,unit=1,drive=drive-ide0-1-1,id=ide0-1-1 \ +-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.xml new file mode 100644 index 0000000..419f8f6 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>test</name> + <uuid>3fa02811-7832-34bd-004d-1ff56a9286ff</uuid> + <memory>1048576</memory> + <currentMemory>1048576</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='x86_64' machine='pc-0.13'>hvm</type> + <boot dev='cdrom'/> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/f14.img'/> + <target dev='vda' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> + <target dev='hdc' bus='ide' tray='closed'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw'/> + <source file='/tmp/cdrom.img'/> + <target dev='hdd' bus='ide' tray='open'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='1'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.args new file mode 100644 index 0000000..a0aed99 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -fda /dev/fd0 \ +-net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.xml new file mode 100644 index 0000000..1f4dd7f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219136</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='floppy'> + <source dev='/dev/fd0'/> + <target dev='fda' bus='fdc' tray='closed'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='floppy'> + <source file='/tmp/firmware.img'/> + <target dev='fdb' bus='fdc' tray='open'/> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </disk> + <controller type='usb' index='0'/> + <controller type='fdc' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.args new file mode 100644 index 0000000..1a61ea5 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.args @@ -0,0 +1,10 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-drive file=/dev/fd0,if=none,id=drive-fdc0-0-0 \ +-global isa-fdc.driveA=drive-fdc0-0-0 \ +-drive if=none,id=drive-fdc0-0-1 \ +-global isa-fdc.driveB=drive-fdc0-0-1 \ +-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.xml new file mode 100644 index 0000000..1f4dd7f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219136</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='floppy'> + <source dev='/dev/fd0'/> + <target dev='fda' bus='fdc' tray='closed'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='floppy'> + <source file='/tmp/firmware.img'/> + <target dev='fdb' bus='fdc' tray='open'/> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </disk> + <controller type='usb' index='0'/> + <controller type='fdc' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 9001834..4846971 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -392,7 +392,13 @@ mymain(void) DO_TEST("hugepages", false, QEMU_CAPS_MEM_PATH); DO_TEST("disk-cdrom", false, NONE); DO_TEST("disk-cdrom-empty", false, QEMU_CAPS_DRIVE); + DO_TEST("disk-cdrom-tray", false, + QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_TX_ALG); + DO_TEST("disk-cdrom-tray-no-device-cap", false, NONE); DO_TEST("disk-floppy", false, NONE); + DO_TEST("disk-floppy-tray-no-device-cap", false, NONE); + DO_TEST("disk-floppy-tray", false, + QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE); DO_TEST("disk-many", false, NONE); DO_TEST("disk-virtio", false, QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_BOOT); DO_TEST("disk-order", false, -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:48PM +0800, Osier Yang wrote:
This is similiar with physical world, one will be surprised if the box starts with medium exists while the tray is open.
New tests are added, tests disk-{cdrom,floppy}-tray are for the qemu supports "-device" flag, and disk-{cdrom,floppy}-no-device-cap are for old qemu, i.e. which doesn't support "-device" flag. --- src/qemu/qemu_command.c | 16 ++++++- ...qemuxml2argv-disk-cdrom-tray-no-device-cap.args | 4 ++ .../qemuxml2argv-disk-cdrom-tray-no-device-cap.xml | 32 +++++++++++++++ .../qemuxml2argv-disk-cdrom-tray.args | 10 +++++ .../qemuxml2argv-disk-cdrom-tray.xml | 43 ++++++++++++++++++++ ...emuxml2argv-disk-floppy-tray-no-device-cap.args | 4 ++ ...qemuxml2argv-disk-floppy-tray-no-device-cap.xml | 37 +++++++++++++++++ .../qemuxml2argv-disk-floppy-tray.args | 10 +++++ .../qemuxml2argv-disk-floppy-tray.xml | 37 +++++++++++++++++ tests/qemuxml2argvtest.c | 6 +++ 10 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d5442e7..ba6edce 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1908,8 +1908,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, }
/* disk->src is NULL when we use nbd disks */ - if (disk->src || (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK && - disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) { + if ((disk->src || + (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK && + disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) && + !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || + disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) && + disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) { if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) { /* QEMU only supports magic FAT format for now */ if (disk->driverType && @@ -4720,7 +4724,13 @@ qemuBuildCommandLine(virConnectPtr conn, } }
- virCommandAddArgList(cmd, dev, file, NULL); + /* Don't start with source if the tray is open for + * CDROM and Floppy device. + */ + if (!((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY || + disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) && + disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) + virCommandAddArgList(cmd, dev, file, NULL); VIR_FREE(file); } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.args new file mode 100644 index 0000000..5cd000e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none \ +-serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.xml new file mode 100644 index 0000000..9f891c7 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray-no-device-cap.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219100</memory> + <currentMemory>219100</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='cdrom'> + <source file='/root/boot.iso'/> + <target dev='hdc' bus='ide' tray='open'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.args new file mode 100644 index 0000000..dfa0006 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.args @@ -0,0 +1,10 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/bin/qemu -S -M pc-0.13 -m 1024 -smp 1 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot dc \ +-drive file=/var/lib/libvirt/images/f14.img,if=none,id=drive-virtio-disk0 \ +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0 \ +-drive file=/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso,if=none,media=cdrom,id=drive-ide0-1-0 \ +-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \ +-drive if=none,media=cdrom,id=drive-ide0-1-1 \ +-device ide-drive,bus=ide.1,unit=1,drive=drive-ide0-1-1,id=ide0-1-1 \ +-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.xml new file mode 100644 index 0000000..419f8f6 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-tray.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>test</name> + <uuid>3fa02811-7832-34bd-004d-1ff56a9286ff</uuid> + <memory>1048576</memory> + <currentMemory>1048576</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='x86_64' machine='pc-0.13'>hvm</type> + <boot dev='cdrom'/> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/f14.img'/> + <target dev='vda' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/> + <target dev='hdc' bus='ide' tray='closed'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw'/> + <source file='/tmp/cdrom.img'/> + <target dev='hdd' bus='ide' tray='open'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='1'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.args new file mode 100644 index 0000000..a0aed99 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -fda /dev/fd0 \ +-net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.xml new file mode 100644 index 0000000..1f4dd7f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray-no-device-cap.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219136</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='floppy'> + <source dev='/dev/fd0'/> + <target dev='fda' bus='fdc' tray='closed'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='floppy'> + <source file='/tmp/firmware.img'/> + <target dev='fdb' bus='fdc' tray='open'/> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </disk> + <controller type='usb' index='0'/> + <controller type='fdc' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.args new file mode 100644 index 0000000..1a61ea5 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.args @@ -0,0 +1,10 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-drive file=/dev/fd0,if=none,id=drive-fdc0-0-0 \ +-global isa-fdc.driveA=drive-fdc0-0-0 \ +-drive if=none,id=drive-fdc0-0-1 \ +-global isa-fdc.driveB=drive-fdc0-0-1 \ +-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.xml new file mode 100644 index 0000000..1f4dd7f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy-tray.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219136</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='floppy'> + <source dev='/dev/fd0'/> + <target dev='fda' bus='fdc' tray='closed'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='file' device='floppy'> + <source file='/tmp/firmware.img'/> + <target dev='fdb' bus='fdc' tray='open'/> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </disk> + <controller type='usb' index='0'/> + <controller type='fdc' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 9001834..4846971 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -392,7 +392,13 @@ mymain(void) DO_TEST("hugepages", false, QEMU_CAPS_MEM_PATH); DO_TEST("disk-cdrom", false, NONE); DO_TEST("disk-cdrom-empty", false, QEMU_CAPS_DRIVE); + DO_TEST("disk-cdrom-tray", false, + QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_TX_ALG); + DO_TEST("disk-cdrom-tray-no-device-cap", false, NONE); DO_TEST("disk-floppy", false, NONE); + DO_TEST("disk-floppy-tray-no-device-cap", false, NONE); + DO_TEST("disk-floppy-tray", false, + QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE); DO_TEST("disk-many", false, NONE); DO_TEST("disk-virtio", false, QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_BOOT); DO_TEST("disk-order", false,
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

-- Created this as a seperate patch, as I'm not quite sure if it's good to do this in libvirt, it's more like a protection for qemu problem, i.e. closing the physical drive tray won't close the guest tray. Paolo persist in doing this in libvirt, but IMHO QEMU is the better place to prevent that. Anyway, let's evaluate. --- src/qemu/qemu_command.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ba6edce..29cc4bd 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1963,6 +1963,13 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, break; } } else { + if ((disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) && + (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("tray status 'open' is invalid for " + "block type disk")); + goto error; + } virBufferEscape(&opt, ',', ",", "file=%s,", disk->src); } } @@ -4625,6 +4632,14 @@ qemuBuildCommandLine(virConnectPtr conn, const char *fmt; virDomainDiskDefPtr disk = def->disks[i]; + if ((disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) && + (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("tray status 'open' is invalid for " + "block type disk")); + goto error; + } + if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { virCommandAddArg(cmd, "-usbdevice"); -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:49PM +0800, Osier Yang wrote:
-- Created this as a seperate patch, as I'm not quite sure if it's good to do this in libvirt, it's more like a protection for qemu problem, i.e. closing the physical drive tray won't close the guest tray. Paolo persist in doing this in libvirt, but IMHO QEMU is the better place to prevent that. Anyway, let's evaluate. --- src/qemu/qemu_command.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ba6edce..29cc4bd 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1963,6 +1963,13 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, break; } } else { + if ((disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) && + (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("tray status 'open' is invalid for " + "block type disk")); + goto error; + } virBufferEscape(&opt, ',', ",", "file=%s,", disk->src); } } @@ -4625,6 +4632,14 @@ qemuBuildCommandLine(virConnectPtr conn, const char *fmt; virDomainDiskDefPtr disk = def->disks[i];
+ if ((disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) && + (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("tray status 'open' is invalid for " + "block type disk")); + goto error; + } + if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { virCommandAddArg(cmd, "-usbdevice");
I think it's fine to do this in libvirt, after all we decided that hard drives could have no tray, that's a libvirt decision from an API POV, so I think it fine to implement the check here IMHO, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

With this patch, libvirt won't start the guest with the medium source which already ejected by guest when doing migration, or saving/restoring. --- src/qemu/qemu_process.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b6e14ad..7511d4e 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1038,6 +1038,16 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, event = virDomainEventTrayChangeNewFromObj(vm, devAlias, reason); + /* Update disk tray status */ + if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN) + disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN; + else if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE) + disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED; + + if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { + VIR_WARN("Unable to save status on vm %s after tray moved event", + vm->def->name); + } } virDomainObjUnlock(vm); -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:50PM +0800, Osier Yang wrote:
With this patch, libvirt won't start the guest with the medium source which already ejected by guest when doing migration, or saving/restoring. --- src/qemu/qemu_process.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b6e14ad..7511d4e 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1038,6 +1038,16 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, event = virDomainEventTrayChangeNewFromObj(vm, devAlias, reason); + /* Update disk tray status */ + if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN) + disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN; + else if (reason == VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE) + disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED; + + if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { + VIR_WARN("Unable to save status on vm %s after tray moved event", + vm->def->name); + } }
virDomainObjUnlock(vm);
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

This patch introduces a new event type for the QMP event WAKEUP: VIR_DOMAIN_EVENT_ID_PMWAKEUP The event doesn't take any data, but considering there might be reason for wakeup in future, the callback definition is: typedef void (*virConnectDomainEventWakeupCallback)(virConnectPtr conn, virDomainPtr dom, int reason, void *opaque); "reason" is unused currently, always passes "0". --- daemon/remote.c | 24 +++++++++ examples/domain-events/events-c/event-test.c | 21 +++++++- examples/domain-events/events-python/event-test.py | 4 ++ include/libvirt/libvirt.h.in | 18 +++++++ python/libvirt-override-virConnect.py | 8 +++ python/libvirt-override.c | 50 ++++++++++++++++++++ src/conf/domain_event.c | 28 +++++++++++ src/conf/domain_event.h | 2 + src/libvirt_private.syms | 2 + src/qemu/qemu_monitor.c | 10 ++++ src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 9 ++++ src/qemu/qemu_process.c | 21 ++++++++ src/remote/remote_driver.c | 30 ++++++++++++ src/remote/remote_protocol.x | 7 ++- src/remote_protocol-structs | 4 ++ 16 files changed, 238 insertions(+), 3 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 060f77b..db3b6bc 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -538,6 +538,29 @@ static int remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; } + +static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + void *opaque) { + virNetServerClientPtr client = opaque; + remote_domain_event_pmwakeup_msg data; + + if (!client) + return -1; + + VIR_DEBUG("Relaying domain %s %d system pmwakeup", dom->name, dom->id); + + /* build return data */ + memset(&data, 0, sizeof data); + make_nonnull_domain(&data.dom, dom); + + remoteDispatchDomainEventSend(client, remoteProgram, + REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP, + (xdrproc_t)xdr_remote_domain_event_pmwakeup_msg, &data); + + return 0; +} + static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -550,6 +573,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTrayChange), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMWakeup), }; 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 cca9a1a..78cfa3b 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -330,6 +330,16 @@ static int myDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; } +static int myDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + int reason ATTRIBUTE_UNUSED, + void *opaque ATTRIBUTE_UNUSED) +{ + printf("%s EVENT: Domain %s(%d) system pmwakeup", + __func__, virDomainGetName(dom), virDomainGetID(dom)); + return 0; +} + static void myFreeFunc(void *opaque) { char *str = opaque; @@ -366,6 +376,7 @@ int main(int argc, char **argv) int callback8ret = -1; int callback9ret = -1; int callback10ret = -1; + int callback11ret = -1; struct sigaction action_stop; memset(&action_stop, 0, sizeof action_stop); @@ -441,7 +452,11 @@ int main(int argc, char **argv) VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, VIR_DOMAIN_EVENT_CALLBACK(myDomainEventTrayChangeCallback), strdup("tray change"), myFreeFunc); - + callback11ret = virConnectDomainEventRegisterAny(dconn, + NULL, + VIR_DOMAIN_EVENT_ID_PMWAKEUP, + VIR_DOMAIN_EVENT_CALLBACK(myDomainEventPMWakeupCallback), + strdup("pmwakeup"), myFreeFunc); if ((callback1ret != -1) && (callback2ret != -1) && (callback3ret != -1) && @@ -450,7 +465,8 @@ int main(int argc, char **argv) (callback6ret != -1) && (callback7ret != -1) && (callback9ret != -1) && - (callback10ret != -1)) { + (callback10ret != -1) && + (callback11ret != -1)) { if (virConnectSetKeepAlive(dconn, 5, 3) < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to start keepalive protocol: %s\n", @@ -476,6 +492,7 @@ int main(int argc, char **argv) virConnectDomainEventDeregisterAny(dconn, callback7ret); virConnectDomainEventDeregisterAny(dconn, callback9ret); virConnectDomainEventDeregisterAny(dconn, callback10ret); + virConnectDomainEventDeregisterAny(dconn, callback11ret); 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 6e0409d..249b590 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -477,6 +477,9 @@ def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, 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 myDomainEventPMWakeupCallback(conn, dom, reason, opaque): + print "myDomainEventPMWakeupCallback: Domain %s(%s) system pmwakeup" % ( + dom.name(), dom.ID()) def usage(out=sys.stderr): print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]" print >>out, " uri will default to qemu:///system" @@ -536,6 +539,7 @@ def main(): 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_CHANGE, myDomainEventTrayChangeCallback, None) + vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None) vc.setKeepAlive(5, 3) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7bf1004..a9a15e1 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3700,6 +3700,23 @@ typedef void (*virConnectDomainEventTrayChangeCallback)(virConnectPtr conn, int reason, void *opaque); +/** + * virConnectDomainEventPMWakeupCallback: + * @conn: connection object + * @dom: domain on which the event occurred + * @reason: reason why the callback was called, unused currently, + * always passes 0 + * @opaque: application specified data + * + * This callback occurs when the guest is waken up. + * + * The callback signature to use when registering for an event of type + * VIR_DOMAIN_EVENT_ID_PMWAKEUP with virConnectDomainEventRegisterAny() + */ +typedef void (*virConnectDomainEventPMWakeupCallback)(virConnectPtr conn, + virDomainPtr dom, + int reason, + void *opaque); /** * VIR_DOMAIN_EVENT_CALLBACK: @@ -3722,6 +3739,7 @@ typedef enum { VIR_DOMAIN_EVENT_ID_BLOCK_JOB = 8, /* virConnectDomainEventBlockJobCallback */ VIR_DOMAIN_EVENT_ID_DISK_CHANGE = 9, /* virConnectDomainEventDiskChangeCallback */ VIR_DOMAIN_EVENT_ID_TRAY_CHANGE = 10, /* virConnectDomainEventTrayChangeCallback */ + VIR_DOMAIN_EVENT_ID_PMWAKEUP = 11, /* virConnectDomainEventPMWakeupCallback */ #ifdef VIR_ENUM_SENTINELS /* diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index 82c2437..2d48828 100644 --- a/python/libvirt-override-virConnect.py +++ b/python/libvirt-override-virConnect.py @@ -143,6 +143,14 @@ cb(self, virDomain(self, _obj=dom), devAlias, reason, opaque) return 0; + def _dispatchDomainEventPMWakeupCallback(self, dom, reason, cbData): + """Dispatches event to python user domain pmwakeup event callbacks + """ + cb = cbData["cb"] + opaque = cbData["opaque"] + + cb(self, virDomain(self, _obj=dom), reason, opaque) + return 0; def domainEventDeregisterAny(self, callbackID): """Removes a Domain Event Callback. De-registering for a diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 915ebd2..f604a16 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -4974,6 +4974,53 @@ libvirt_virConnectDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNU return ret; } +static int +libvirt_virConnectDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + 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*)"_dispatchDomainEventPMWakeupCallback", + (char*)"OO", + pyobj_dom, + 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 * libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) @@ -5037,6 +5084,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventTrayChangeCallback); break; + case VIR_DOMAIN_EVENT_ID_PMWAKEUP: + cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMWakeupCallback); + break; } if (!cb) { diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 9c2a052..06a8e29 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -1094,6 +1094,30 @@ virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom, devAlias, reason); } +static virDomainEventPtr +virDomainEventPMWakeupNew(int id, const char *name, + unsigned char *uuid) +{ + virDomainEventPtr ev = + virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMWAKEUP, + id, name, uuid); + + return ev; +} + +virDomainEventPtr +virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj) +{ + return virDomainEventPMWakeupNew(obj->def->id, + obj->def->name, + obj->def->uuid); +} + +virDomainEventPtr +virDomainEventPMWakeupNewFromDom(virDomainPtr dom) +{ + return virDomainEventPMWakeupNew(dom->id, dom->name, dom->uuid); +} /** * virDomainEventQueuePush: @@ -1225,6 +1249,10 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, cbopaque); break; + case VIR_DOMAIN_EVENT_ID_PMWAKEUP: + ((virConnectDomainEventPMWakeupCallback)cb)(conn, dom, 0, 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 e5010a3..7d39201 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -120,6 +120,8 @@ virDomainEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj, virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom, const char *devAlias, int reason); +virDomainEventPtr virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj); +virDomainEventPtr virDomainEventPMWakeupNewFromDom(virDomainPtr dom); void virDomainEventFree(virDomainEventPtr event); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e247472..d591d04 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -511,6 +511,8 @@ virDomainEventNew; virDomainEventNewFromDef; virDomainEventNewFromDom; virDomainEventNewFromObj; +virDomainEventPMWakeupNewFromDom; +virDomainEventPMWakeupNewFromObj; virDomainEventRTCChangeNewFromDom; virDomainEventRTCChangeNewFromObj; virDomainEventRebootNew; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 90b8e12..adf3636 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1053,6 +1053,16 @@ int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, return ret; } +int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon) +{ + int ret = -1; + VIR_DEBUG("mon=%p", mon); + + QEMU_MONITOR_CALLBACK(mon, ret, domainPMWakeup, mon->vm); + + 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 b5a0c30..6919a66 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -128,6 +128,8 @@ struct _qemuMonitorCallbacks { virDomainObjPtr vm, const char *devAlias, int reason); + int (*domainPMWakeup)(qemuMonitorPtr mon, + virDomainObjPtr vm); }; char *qemuMonitorEscapeArg(const char *in); @@ -197,6 +199,7 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, const char *devAlias, int reason); +int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon); 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 0312ca7..7bb4410 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -60,6 +60,7 @@ static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValueP static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr data); +static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data); static struct { const char *type; @@ -77,6 +78,7 @@ static struct { { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, }, { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, }, { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, }, + { "WAKEUP", qemuMonitorJSONHandlePMWakeup, }, }; @@ -753,6 +755,13 @@ qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, qemuMonitorEmitTrayChange(mon, devAlias, reason); } +static void +qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_UNUSED) +{ + qemuMonitorEmitPMWakeup(mon); +} + int qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, const char *cmd_str, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7511d4e..7914a6a 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1061,6 +1061,26 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, return 0; } +static int +qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virDomainObjPtr vm) +{ + struct qemud_driver *driver = qemu_driver; + virDomainEventPtr event = NULL; + + virDomainObjLock(vm); + event = virDomainEventPMWakeupNewFromObj(vm); + + virDomainObjUnlock(vm); + + if (event) { + qemuDriverLock(driver); + qemuDomainEventQueue(driver, event); + qemuDriverUnlock(driver); + } + + return 0; +} static qemuMonitorCallbacks monitorCallbacks = { .destroy = qemuProcessHandleMonitorDestroy, @@ -1076,6 +1096,7 @@ static qemuMonitorCallbacks monitorCallbacks = { .domainGraphics = qemuProcessHandleGraphics, .domainBlockJob = qemuProcessHandleBlockJob, .domainTrayChange = qemuProcessHandleTrayChange, + .domainPMWakeup = qemuProcessHandlePMWakeup, }; static int diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index ac95dcc..27eafa1 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -243,6 +243,11 @@ remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog, virNetClientPtr client, void *evdata, void *opaque); +static void +remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog, + virNetClientPtr client, + void *evdata, void *opaque); + static virNetClientProgramEvent remoteDomainEvents[] = { { REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE, remoteDomainBuildEventRTCChange, @@ -288,6 +293,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = { remoteDomainBuildEventTrayChange, sizeof(remote_domain_event_tray_change_msg), (xdrproc_t)xdr_remote_domain_event_tray_change_msg }, + { REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP, + remoteDomainBuildEventPMWakeup, + sizeof(remote_domain_event_pmwakeup_msg), + (xdrproc_t)xdr_remote_domain_event_pmwakeup_msg }, }; enum virDrvOpenRemoteFlags { @@ -3678,6 +3687,27 @@ remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteDomainEventQueue(priv, event); } +static void +remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, + virNetClientPtr client ATTRIBUTE_UNUSED, + void *evdata, void *opaque) +{ + virConnectPtr conn = opaque; + struct private_data *priv = conn->privateData; + remote_domain_event_pmwakeup_msg *msg = evdata; + virDomainPtr dom; + virDomainEventPtr event = NULL; + + dom = get_nonnull_domain(conn, msg->dom); + if (!dom) + return; + + event = virDomainEventPMWakeupNewFromDom(dom); + + virDomainFree(dom); + + remoteDomainEventQueue(priv, event); +} static virDrvOpenStatus ATTRIBUTE_NONNULL (1) remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth, diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 6c8c497..f462b20 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2184,6 +2184,10 @@ struct remote_domain_event_tray_change_msg { int reason; }; +struct remote_domain_event_pmwakeup_msg { + remote_nonnull_domain dom; +}; + struct remote_domain_managed_save_args { remote_nonnull_domain dom; unsigned int flags; @@ -2772,7 +2776,8 @@ enum remote_procedure { 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_EVENT_TRAY_CHANGE = 268 /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE = 268, /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269 /* 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 0ce7c1c..5eb4df3 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1655,6 +1655,9 @@ struct remote_domain_event_tray_change_msg { remote_nonnull_string devAlias; int reason; } +struct remote_domain_event_pmwakeup_msg { + remote_nonnull_domain dom; +} struct remote_domain_managed_save_args { remote_nonnull_domain dom; u_int flags; @@ -2184,4 +2187,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266, REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, REMOTE_PROC_DOMAIN_TRAY_CHANGE = 268, + REMOTE_PROC_DOMAIN_PMWAKEUP = 269, }; -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:51PM +0800, Osier Yang wrote:
This patch introduces a new event type for the QMP event WAKEUP:
VIR_DOMAIN_EVENT_ID_PMWAKEUP
The event doesn't take any data, but considering there might be reason for wakeup in future, the callback definition is:
typedef void (*virConnectDomainEventWakeupCallback)(virConnectPtr conn, virDomainPtr dom, int reason, void *opaque);
"reason" is unused currently, always passes "0". --- daemon/remote.c | 24 +++++++++ examples/domain-events/events-c/event-test.c | 21 +++++++- examples/domain-events/events-python/event-test.py | 4 ++ include/libvirt/libvirt.h.in | 18 +++++++ python/libvirt-override-virConnect.py | 8 +++ python/libvirt-override.c | 50 ++++++++++++++++++++ src/conf/domain_event.c | 28 +++++++++++ src/conf/domain_event.h | 2 + src/libvirt_private.syms | 2 + src/qemu/qemu_monitor.c | 10 ++++ src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 9 ++++ src/qemu/qemu_process.c | 21 ++++++++ src/remote/remote_driver.c | 30 ++++++++++++ src/remote/remote_protocol.x | 7 ++- src/remote_protocol-structs | 4 ++ 16 files changed, 238 insertions(+), 3 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c index 060f77b..db3b6bc 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -538,6 +538,29 @@ static int remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; }
+ +static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + void *opaque) { + virNetServerClientPtr client = opaque; + remote_domain_event_pmwakeup_msg data; + + if (!client) + return -1; + + VIR_DEBUG("Relaying domain %s %d system pmwakeup", dom->name, dom->id); + + /* build return data */ + memset(&data, 0, sizeof data); + make_nonnull_domain(&data.dom, dom); + + remoteDispatchDomainEventSend(client, remoteProgram, + REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP, + (xdrproc_t)xdr_remote_domain_event_pmwakeup_msg, &data); + + return 0; +} + static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -550,6 +573,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTrayChange), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMWakeup), };
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 cca9a1a..78cfa3b 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -330,6 +330,16 @@ static int myDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; }
+static int myDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + int reason ATTRIBUTE_UNUSED, + void *opaque ATTRIBUTE_UNUSED) +{ + printf("%s EVENT: Domain %s(%d) system pmwakeup", + __func__, virDomainGetName(dom), virDomainGetID(dom)); + return 0; +} + static void myFreeFunc(void *opaque) { char *str = opaque; @@ -366,6 +376,7 @@ int main(int argc, char **argv) int callback8ret = -1; int callback9ret = -1; int callback10ret = -1; + int callback11ret = -1; struct sigaction action_stop;
memset(&action_stop, 0, sizeof action_stop); @@ -441,7 +452,11 @@ int main(int argc, char **argv) VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, VIR_DOMAIN_EVENT_CALLBACK(myDomainEventTrayChangeCallback), strdup("tray change"), myFreeFunc); - + callback11ret = virConnectDomainEventRegisterAny(dconn, + NULL, + VIR_DOMAIN_EVENT_ID_PMWAKEUP, + VIR_DOMAIN_EVENT_CALLBACK(myDomainEventPMWakeupCallback), + strdup("pmwakeup"), myFreeFunc); if ((callback1ret != -1) && (callback2ret != -1) && (callback3ret != -1) && @@ -450,7 +465,8 @@ int main(int argc, char **argv) (callback6ret != -1) && (callback7ret != -1) && (callback9ret != -1) && - (callback10ret != -1)) { + (callback10ret != -1) && + (callback11ret != -1)) { if (virConnectSetKeepAlive(dconn, 5, 3) < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to start keepalive protocol: %s\n", @@ -476,6 +492,7 @@ int main(int argc, char **argv) virConnectDomainEventDeregisterAny(dconn, callback7ret); virConnectDomainEventDeregisterAny(dconn, callback9ret); virConnectDomainEventDeregisterAny(dconn, callback10ret); + virConnectDomainEventDeregisterAny(dconn, callback11ret); 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 6e0409d..249b590 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -477,6 +477,9 @@ def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, 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 myDomainEventPMWakeupCallback(conn, dom, reason, opaque): + print "myDomainEventPMWakeupCallback: Domain %s(%s) system pmwakeup" % ( + dom.name(), dom.ID()) def usage(out=sys.stderr): print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]" print >>out, " uri will default to qemu:///system" @@ -536,6 +539,7 @@ def main(): 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_CHANGE, myDomainEventTrayChangeCallback, None) + vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None)
vc.setKeepAlive(5, 3)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7bf1004..a9a15e1 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3700,6 +3700,23 @@ typedef void (*virConnectDomainEventTrayChangeCallback)(virConnectPtr conn, int reason, void *opaque);
+/** + * virConnectDomainEventPMWakeupCallback: + * @conn: connection object + * @dom: domain on which the event occurred + * @reason: reason why the callback was called, unused currently, + * always passes 0 + * @opaque: application specified data + * + * This callback occurs when the guest is waken up. + * + * The callback signature to use when registering for an event of type + * VIR_DOMAIN_EVENT_ID_PMWAKEUP with virConnectDomainEventRegisterAny() + */ +typedef void (*virConnectDomainEventPMWakeupCallback)(virConnectPtr conn, + virDomainPtr dom, + int reason, + void *opaque);
/** * VIR_DOMAIN_EVENT_CALLBACK: @@ -3722,6 +3739,7 @@ typedef enum { VIR_DOMAIN_EVENT_ID_BLOCK_JOB = 8, /* virConnectDomainEventBlockJobCallback */ VIR_DOMAIN_EVENT_ID_DISK_CHANGE = 9, /* virConnectDomainEventDiskChangeCallback */ VIR_DOMAIN_EVENT_ID_TRAY_CHANGE = 10, /* virConnectDomainEventTrayChangeCallback */ + VIR_DOMAIN_EVENT_ID_PMWAKEUP = 11, /* virConnectDomainEventPMWakeupCallback */
#ifdef VIR_ENUM_SENTINELS /* diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index 82c2437..2d48828 100644 --- a/python/libvirt-override-virConnect.py +++ b/python/libvirt-override-virConnect.py @@ -143,6 +143,14 @@ cb(self, virDomain(self, _obj=dom), devAlias, reason, opaque) return 0;
+ def _dispatchDomainEventPMWakeupCallback(self, dom, reason, cbData): + """Dispatches event to python user domain pmwakeup event callbacks + """ + cb = cbData["cb"] + opaque = cbData["opaque"] + + cb(self, virDomain(self, _obj=dom), reason, opaque) + return 0;
def domainEventDeregisterAny(self, callbackID): """Removes a Domain Event Callback. De-registering for a diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 915ebd2..f604a16 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -4974,6 +4974,53 @@ libvirt_virConnectDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNU return ret; }
+static int +libvirt_virConnectDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + 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*)"_dispatchDomainEventPMWakeupCallback", + (char*)"OO", + pyobj_dom, + 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 * libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) @@ -5037,6 +5084,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventTrayChangeCallback); break; + case VIR_DOMAIN_EVENT_ID_PMWAKEUP: + cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMWakeupCallback); + break; }
if (!cb) { diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 9c2a052..06a8e29 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -1094,6 +1094,30 @@ virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom, devAlias, reason); }
+static virDomainEventPtr +virDomainEventPMWakeupNew(int id, const char *name, + unsigned char *uuid) +{ + virDomainEventPtr ev = + virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMWAKEUP, + id, name, uuid); + + return ev; +} + +virDomainEventPtr +virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj) +{ + return virDomainEventPMWakeupNew(obj->def->id, + obj->def->name, + obj->def->uuid); +} + +virDomainEventPtr +virDomainEventPMWakeupNewFromDom(virDomainPtr dom) +{ + return virDomainEventPMWakeupNew(dom->id, dom->name, dom->uuid); +}
/** * virDomainEventQueuePush: @@ -1225,6 +1249,10 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, cbopaque); break;
+ case VIR_DOMAIN_EVENT_ID_PMWAKEUP: + ((virConnectDomainEventPMWakeupCallback)cb)(conn, dom, 0, 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 e5010a3..7d39201 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -120,6 +120,8 @@ virDomainEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj, virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom, const char *devAlias, int reason); +virDomainEventPtr virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj); +virDomainEventPtr virDomainEventPMWakeupNewFromDom(virDomainPtr dom);
void virDomainEventFree(virDomainEventPtr event);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e247472..d591d04 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -511,6 +511,8 @@ virDomainEventNew; virDomainEventNewFromDef; virDomainEventNewFromDom; virDomainEventNewFromObj; +virDomainEventPMWakeupNewFromDom; +virDomainEventPMWakeupNewFromObj; virDomainEventRTCChangeNewFromDom; virDomainEventRTCChangeNewFromObj; virDomainEventRebootNew; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 90b8e12..adf3636 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1053,6 +1053,16 @@ int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, return ret; }
+int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon) +{ + int ret = -1; + VIR_DEBUG("mon=%p", mon); + + QEMU_MONITOR_CALLBACK(mon, ret, domainPMWakeup, mon->vm); + + 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 b5a0c30..6919a66 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -128,6 +128,8 @@ struct _qemuMonitorCallbacks { virDomainObjPtr vm, const char *devAlias, int reason); + int (*domainPMWakeup)(qemuMonitorPtr mon, + virDomainObjPtr vm); };
char *qemuMonitorEscapeArg(const char *in); @@ -197,6 +199,7 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, const char *devAlias, int reason); +int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon); 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 0312ca7..7bb4410 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -60,6 +60,7 @@ static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValueP static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr data); +static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data);
static struct { const char *type; @@ -77,6 +78,7 @@ static struct { { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, }, { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, }, { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, }, + { "WAKEUP", qemuMonitorJSONHandlePMWakeup, }, };
@@ -753,6 +755,13 @@ qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, qemuMonitorEmitTrayChange(mon, devAlias, reason); }
+static void +qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_UNUSED) +{ + qemuMonitorEmitPMWakeup(mon); +} + int qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, const char *cmd_str, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7511d4e..7914a6a 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1061,6 +1061,26 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, return 0; }
+static int +qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virDomainObjPtr vm) +{ + struct qemud_driver *driver = qemu_driver; + virDomainEventPtr event = NULL; + + virDomainObjLock(vm); + event = virDomainEventPMWakeupNewFromObj(vm); + + virDomainObjUnlock(vm); + + if (event) { + qemuDriverLock(driver); + qemuDomainEventQueue(driver, event); + qemuDriverUnlock(driver); + } + + return 0; +}
static qemuMonitorCallbacks monitorCallbacks = { .destroy = qemuProcessHandleMonitorDestroy, @@ -1076,6 +1096,7 @@ static qemuMonitorCallbacks monitorCallbacks = { .domainGraphics = qemuProcessHandleGraphics, .domainBlockJob = qemuProcessHandleBlockJob, .domainTrayChange = qemuProcessHandleTrayChange, + .domainPMWakeup = qemuProcessHandlePMWakeup, };
static int diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index ac95dcc..27eafa1 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -243,6 +243,11 @@ remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog, virNetClientPtr client, void *evdata, void *opaque);
+static void +remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog, + virNetClientPtr client, + void *evdata, void *opaque); + static virNetClientProgramEvent remoteDomainEvents[] = { { REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE, remoteDomainBuildEventRTCChange, @@ -288,6 +293,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = { remoteDomainBuildEventTrayChange, sizeof(remote_domain_event_tray_change_msg), (xdrproc_t)xdr_remote_domain_event_tray_change_msg }, + { REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP, + remoteDomainBuildEventPMWakeup, + sizeof(remote_domain_event_pmwakeup_msg), + (xdrproc_t)xdr_remote_domain_event_pmwakeup_msg }, };
enum virDrvOpenRemoteFlags { @@ -3678,6 +3687,27 @@ remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteDomainEventQueue(priv, event); }
+static void +remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, + virNetClientPtr client ATTRIBUTE_UNUSED, + void *evdata, void *opaque) +{ + virConnectPtr conn = opaque; + struct private_data *priv = conn->privateData; + remote_domain_event_pmwakeup_msg *msg = evdata; + virDomainPtr dom; + virDomainEventPtr event = NULL; + + dom = get_nonnull_domain(conn, msg->dom); + if (!dom) + return; + + event = virDomainEventPMWakeupNewFromDom(dom); + + virDomainFree(dom); + + remoteDomainEventQueue(priv, event); +}
static virDrvOpenStatus ATTRIBUTE_NONNULL (1) remoteSecretOpen(virConnectPtr conn, virConnectAuthPtr auth, diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 6c8c497..f462b20 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2184,6 +2184,10 @@ struct remote_domain_event_tray_change_msg { int reason; };
+struct remote_domain_event_pmwakeup_msg { + remote_nonnull_domain dom; +}; + struct remote_domain_managed_save_args { remote_nonnull_domain dom; unsigned int flags; @@ -2772,7 +2776,8 @@ enum remote_procedure { 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_EVENT_TRAY_CHANGE = 268 /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE = 268, /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269 /* 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 0ce7c1c..5eb4df3 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1655,6 +1655,9 @@ struct remote_domain_event_tray_change_msg { remote_nonnull_string devAlias; int reason; } +struct remote_domain_event_pmwakeup_msg { + remote_nonnull_domain dom; +} struct remote_domain_managed_save_args { remote_nonnull_domain dom; u_int flags; @@ -2184,4 +2187,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266, REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, REMOTE_PROC_DOMAIN_TRAY_CHANGE = 268, + REMOTE_PROC_DOMAIN_PMWAKEUP = 269, };
ACK, looks fine, hopefully we can give it some testing before the release ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

This patch introduces a new event type for the QMP event SUSPEND: VIR_DOMAIN_EVENT_ID_PMSUSPEND The event doesn't take any data, but considering there might be reason for wakeup in future, the callback definition is: typedef void (*virConnectDomainEventSuspendCallback)(virConnectPtr conn, virDomainPtr dom, int reason, void *opaque); "reason" is unused currently, always passes "0". --- daemon/remote.c | 24 +++++++++- examples/domain-events/events-c/event-test.c | 20 +++++++- examples/domain-events/events-python/event-test.py | 4 ++ include/libvirt/libvirt.h.in | 19 +++++++ python/libvirt-override-virConnect.py | 9 ++++ python/libvirt-override.c | 50 ++++++++++++++++++++ src/conf/domain_event.c | 29 +++++++++++ src/conf/domain_event.h | 2 + src/libvirt_private.syms | 2 + src/qemu/qemu_monitor.c | 10 ++++ src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 11 ++++- src/qemu/qemu_process.c | 22 +++++++++ src/remote/remote_driver.c | 31 ++++++++++++ src/remote/remote_protocol.x | 7 ++- src/remote_protocol-structs | 4 ++ 16 files changed, 243 insertions(+), 4 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index db3b6bc..4fd676d 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -538,7 +538,6 @@ static int remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; } - static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, void *opaque) { @@ -561,6 +560,28 @@ static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; } +static int remoteRelayDomainEventPMSuspend(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + void *opaque) { + virNetServerClientPtr client = opaque; + remote_domain_event_pmsuspend_msg data; + + if (!client) + return -1; + + VIR_DEBUG("Relaying domain %s %d system pmsuspend", dom->name, dom->id); + + /* build return data */ + memset(&data, 0, sizeof data); + make_nonnull_domain(&data.dom, dom); + + remoteDispatchDomainEventSend(client, remoteProgram, + REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND, + (xdrproc_t)xdr_remote_domain_event_pmsuspend_msg, &data); + + return 0; +} + static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -574,6 +595,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTrayChange), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMWakeup), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMSuspend), }; 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 78cfa3b..9ffabd6 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -340,6 +340,16 @@ static int myDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; } +static int myDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + int reason ATTRIBUTE_UNUSED, + void *opaque ATTRIBUTE_UNUSED) +{ + printf("%s EVENT: Domain %s(%d) system pmsuspend", + __func__, virDomainGetName(dom), virDomainGetID(dom)); + return 0; +} + static void myFreeFunc(void *opaque) { char *str = opaque; @@ -377,6 +387,7 @@ int main(int argc, char **argv) int callback9ret = -1; int callback10ret = -1; int callback11ret = -1; + int callback12ret = -1; struct sigaction action_stop; memset(&action_stop, 0, sizeof action_stop); @@ -457,6 +468,11 @@ int main(int argc, char **argv) VIR_DOMAIN_EVENT_ID_PMWAKEUP, VIR_DOMAIN_EVENT_CALLBACK(myDomainEventPMWakeupCallback), strdup("pmwakeup"), myFreeFunc); + callback12ret = virConnectDomainEventRegisterAny(dconn, + NULL, + VIR_DOMAIN_EVENT_ID_PMSUSPEND, + VIR_DOMAIN_EVENT_CALLBACK(myDomainEventPMSuspendCallback), + strdup("pmsuspend"), myFreeFunc); if ((callback1ret != -1) && (callback2ret != -1) && (callback3ret != -1) && @@ -466,7 +482,8 @@ int main(int argc, char **argv) (callback7ret != -1) && (callback9ret != -1) && (callback10ret != -1) && - (callback11ret != -1)) { + (callback11ret != -1) && + (callback12ret != -1)) { if (virConnectSetKeepAlive(dconn, 5, 3) < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to start keepalive protocol: %s\n", @@ -493,6 +510,7 @@ int main(int argc, char **argv) virConnectDomainEventDeregisterAny(dconn, callback9ret); virConnectDomainEventDeregisterAny(dconn, callback10ret); virConnectDomainEventDeregisterAny(dconn, callback11ret); + virConnectDomainEventDeregisterAny(dconn, callback12ret); 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 249b590..78d36a3 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -480,6 +480,9 @@ def myDomainEventTrayChangeCallback(conn, dom, devAlias, reason, opaque): def myDomainEventWakeupCallback(conn, dom, reason, opaque): print "myDomainEventWakeupCallback: Domain %s(%s) system pmwakeup" % ( dom.name(), dom.ID()) +def myDomainEventPMSuspendCallback(conn, dom, reason, opaque): + print "myDomainEventPMSuspendCallback: Domain %s(%s) system pmsuspend" % ( + dom.name(), dom.ID()) def usage(out=sys.stderr): print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]" print >>out, " uri will default to qemu:///system" @@ -540,6 +543,7 @@ def main(): 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.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None) + vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback, None) vc.setKeepAlive(5, 3) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a9a15e1..caf5085 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3719,6 +3719,24 @@ typedef void (*virConnectDomainEventPMWakeupCallback)(virConnectPtr conn, void *opaque); /** + * virConnectDomainEventPMSuspendCallback: + * @conn: connection object + * @dom: domain on which the event occurred + * @reason: reason why the callback was called, unused currently, + * always passes 0 + * @opaque: application specified data + * + * This callback occurs when the guest is waken up. + * + * The callback signature to use when registering for an event of type + * VIR_DOMAIN_EVENT_ID_PMSuspend with virConnectDomainEventRegisterAny() + */ +typedef void (*virConnectDomainEventPMSuspendCallback)(virConnectPtr conn, + virDomainPtr dom, + int reason, + void *opaque); + +/** * VIR_DOMAIN_EVENT_CALLBACK: * * Used to cast the event specific callback into the generic one @@ -3740,6 +3758,7 @@ typedef enum { VIR_DOMAIN_EVENT_ID_DISK_CHANGE = 9, /* virConnectDomainEventDiskChangeCallback */ VIR_DOMAIN_EVENT_ID_TRAY_CHANGE = 10, /* virConnectDomainEventTrayChangeCallback */ VIR_DOMAIN_EVENT_ID_PMWAKEUP = 11, /* virConnectDomainEventPMWakeupCallback */ + VIR_DOMAIN_EVENT_ID_PMSUSPEND = 12, /* virConnectDomainEventPMSuspendCallback */ #ifdef VIR_ENUM_SENTINELS /* diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index 2d48828..811e16b 100644 --- a/python/libvirt-override-virConnect.py +++ b/python/libvirt-override-virConnect.py @@ -152,6 +152,15 @@ cb(self, virDomain(self, _obj=dom), reason, opaque) return 0; + def _dispatchDomainEventPMSuspendCallback(self, dom, reason, cbData): + """Dispatches event to python user domain pmsuspend event callbacks + """ + cb = cbData["cb"] + opaque = cbData["opaque"] + + cb(self, virDomain(self, _obj=dom), reason, 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 f604a16..e6127c1 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -5021,6 +5021,53 @@ libvirt_virConnectDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSE return ret; } +static int +libvirt_virConnectDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + 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*)"_dispatchDomainEventPMSuspendCallback", + (char*)"OO", + pyobj_dom, + 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 * libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) @@ -5087,6 +5134,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, case VIR_DOMAIN_EVENT_ID_PMWAKEUP: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMWakeupCallback); break; + case VIR_DOMAIN_EVENT_ID_PMSUSPEND: + cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMSuspendCallback); + break; } if (!cb) { diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 06a8e29..923c58d 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -1119,6 +1119,31 @@ virDomainEventPMWakeupNewFromDom(virDomainPtr dom) return virDomainEventPMWakeupNew(dom->id, dom->name, dom->uuid); } +static virDomainEventPtr +virDomainEventPMSuspendNew(int id, const char *name, + unsigned char *uuid) +{ + virDomainEventPtr ev = + virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND, + id, name, uuid); + + return ev; +} + +virDomainEventPtr +virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj) +{ + return virDomainEventPMSuspendNew(obj->def->id, + obj->def->name, + obj->def->uuid); +} + +virDomainEventPtr +virDomainEventPMSuspendNewFromDom(virDomainPtr dom) +{ + return virDomainEventPMSuspendNew(dom->id, dom->name, dom->uuid); +} + /** * virDomainEventQueuePush: * @evtQueue: the dom event queue @@ -1253,6 +1278,10 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, ((virConnectDomainEventPMWakeupCallback)cb)(conn, dom, 0, cbopaque); break; + case VIR_DOMAIN_EVENT_ID_PMSUSPEND: + ((virConnectDomainEventPMSuspendCallback)cb)(conn, dom, 0, 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 7d39201..f7776c7 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -122,6 +122,8 @@ virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom, int reason); virDomainEventPtr virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj); virDomainEventPtr virDomainEventPMWakeupNewFromDom(virDomainPtr dom); +virDomainEventPtr virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj); +virDomainEventPtr virDomainEventPMSuspendNewFromDom(virDomainPtr dom); void virDomainEventFree(virDomainEventPtr event); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d591d04..678e89e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -511,6 +511,8 @@ virDomainEventNew; virDomainEventNewFromDef; virDomainEventNewFromDom; virDomainEventNewFromObj; +virDomainEventPMSuspendNewFromDom; +virDomainEventPMSuspendNewFromObj; virDomainEventPMWakeupNewFromDom; virDomainEventPMWakeupNewFromObj; virDomainEventRTCChangeNewFromDom; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index adf3636..9372db6 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1063,6 +1063,16 @@ int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon) return ret; } +int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon) +{ + int ret = -1; + VIR_DEBUG("mon=%p", mon); + + QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspend, mon->vm); + + 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 6919a66..117e86c 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -130,6 +130,8 @@ struct _qemuMonitorCallbacks { int reason); int (*domainPMWakeup)(qemuMonitorPtr mon, virDomainObjPtr vm); + int (*domainPMSuspend)(qemuMonitorPtr mon, + virDomainObjPtr vm); }; char *qemuMonitorEscapeArg(const char *in); @@ -200,6 +202,7 @@ int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, const char *devAlias, int reason); int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon); +int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon); 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 7bb4410..c5cc59e 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -61,6 +61,7 @@ static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValueP static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data); +static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr data); static struct { const char *type; @@ -79,6 +80,7 @@ static struct { { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, }, { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, }, { "WAKEUP", qemuMonitorJSONHandlePMWakeup, }, + { "SUSPEND", qemuMonitorJSONHandlePMSuspend, }, }; @@ -757,11 +759,18 @@ qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, - virJSONValuePtr data ATTRIBUTE_UNUSED) + virJSONValuePtr data ATTRIBUTE_UNUSED) { qemuMonitorEmitPMWakeup(mon); } +static void +qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_UNUSED) +{ + qemuMonitorEmitPMSuspend(mon); +} + int qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, const char *cmd_str, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7914a6a..d55c269 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1082,6 +1082,27 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, return 0; } +static int +qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virDomainObjPtr vm) +{ + struct qemud_driver *driver = qemu_driver; + virDomainEventPtr event = NULL; + + virDomainObjLock(vm); + event = virDomainEventPMSuspendNewFromObj(vm); + + virDomainObjUnlock(vm); + + if (event) { + qemuDriverLock(driver); + qemuDomainEventQueue(driver, event); + qemuDriverUnlock(driver); + } + + return 0; +} + static qemuMonitorCallbacks monitorCallbacks = { .destroy = qemuProcessHandleMonitorDestroy, .eofNotify = qemuProcessHandleMonitorEOF, @@ -1097,6 +1118,7 @@ static qemuMonitorCallbacks monitorCallbacks = { .domainBlockJob = qemuProcessHandleBlockJob, .domainTrayChange = qemuProcessHandleTrayChange, .domainPMWakeup = qemuProcessHandlePMWakeup, + .domainPMSuspend = qemuProcessHandlePMSuspend, }; static int diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 27eafa1..d0c71da 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -248,6 +248,11 @@ remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog, virNetClientPtr client, void *evdata, void *opaque); +static void +remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog, + virNetClientPtr client, + void *evdata, void *opaque); + static virNetClientProgramEvent remoteDomainEvents[] = { { REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE, remoteDomainBuildEventRTCChange, @@ -297,6 +302,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = { remoteDomainBuildEventPMWakeup, sizeof(remote_domain_event_pmwakeup_msg), (xdrproc_t)xdr_remote_domain_event_pmwakeup_msg }, + { REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND, + remoteDomainBuildEventPMSuspend, + sizeof(remote_domain_event_pmsuspend_msg), + (xdrproc_t)xdr_remote_domain_event_pmsuspend_msg }, }; enum virDrvOpenRemoteFlags { @@ -3709,6 +3718,28 @@ remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteDomainEventQueue(priv, event); } +static void +remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, + virNetClientPtr client ATTRIBUTE_UNUSED, + void *evdata, void *opaque) +{ + virConnectPtr conn = opaque; + struct private_data *priv = conn->privateData; + remote_domain_event_pmsuspend_msg *msg = evdata; + virDomainPtr dom; + virDomainEventPtr event = NULL; + + dom = get_nonnull_domain(conn, msg->dom); + if (!dom) + return; + + event = virDomainEventPMSuspendNewFromDom(dom); + + 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 f462b20..2d57247 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2188,6 +2188,10 @@ struct remote_domain_event_pmwakeup_msg { remote_nonnull_domain dom; }; +struct remote_domain_event_pmsuspend_msg { + remote_nonnull_domain dom; +}; + struct remote_domain_managed_save_args { remote_nonnull_domain dom; unsigned int flags; @@ -2777,7 +2781,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266, /* autogen autogen */ REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, /* autogen autogen */ REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE = 268, /* autogen autogen */ - REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269 /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269, /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND = 270 /* 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 5eb4df3..474e574 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1658,6 +1658,9 @@ struct remote_domain_event_tray_change_msg { struct remote_domain_event_pmwakeup_msg { remote_nonnull_domain dom; } +struct remote_domain_event_pmsuspend_msg { + remote_nonnull_domain dom; +} struct remote_domain_managed_save_args { remote_nonnull_domain dom; u_int flags; @@ -2188,4 +2191,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, REMOTE_PROC_DOMAIN_TRAY_CHANGE = 268, REMOTE_PROC_DOMAIN_PMWAKEUP = 269, + REMOTE_PROC_DOMAIN_PMSUSPEND = 270, }; -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:52PM +0800, Osier Yang wrote:
This patch introduces a new event type for the QMP event SUSPEND:
VIR_DOMAIN_EVENT_ID_PMSUSPEND
The event doesn't take any data, but considering there might be reason for wakeup in future, the callback definition is:
typedef void (*virConnectDomainEventSuspendCallback)(virConnectPtr conn, virDomainPtr dom, int reason, void *opaque);
"reason" is unused currently, always passes "0". --- daemon/remote.c | 24 +++++++++- examples/domain-events/events-c/event-test.c | 20 +++++++- examples/domain-events/events-python/event-test.py | 4 ++ include/libvirt/libvirt.h.in | 19 +++++++ python/libvirt-override-virConnect.py | 9 ++++ python/libvirt-override.c | 50 ++++++++++++++++++++ src/conf/domain_event.c | 29 +++++++++++ src/conf/domain_event.h | 2 + src/libvirt_private.syms | 2 + src/qemu/qemu_monitor.c | 10 ++++ src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 11 ++++- src/qemu/qemu_process.c | 22 +++++++++ src/remote/remote_driver.c | 31 ++++++++++++ src/remote/remote_protocol.x | 7 ++- src/remote_protocol-structs | 4 ++ 16 files changed, 243 insertions(+), 4 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c index db3b6bc..4fd676d 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -538,7 +538,6 @@ static int remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; }
- static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, void *opaque) { @@ -561,6 +560,28 @@ static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; }
+static int remoteRelayDomainEventPMSuspend(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + void *opaque) { + virNetServerClientPtr client = opaque; + remote_domain_event_pmsuspend_msg data; + + if (!client) + return -1; + + VIR_DEBUG("Relaying domain %s %d system pmsuspend", dom->name, dom->id); + + /* build return data */ + memset(&data, 0, sizeof data); + make_nonnull_domain(&data.dom, dom); + + remoteDispatchDomainEventSend(client, remoteProgram, + REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND, + (xdrproc_t)xdr_remote_domain_event_pmsuspend_msg, &data); + + return 0; +} + static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -574,6 +595,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDiskChange), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTrayChange), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMWakeup), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventPMSuspend), };
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 78cfa3b..9ffabd6 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -340,6 +340,16 @@ static int myDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; }
+static int myDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + int reason ATTRIBUTE_UNUSED, + void *opaque ATTRIBUTE_UNUSED) +{ + printf("%s EVENT: Domain %s(%d) system pmsuspend", + __func__, virDomainGetName(dom), virDomainGetID(dom)); + return 0; +} + static void myFreeFunc(void *opaque) { char *str = opaque; @@ -377,6 +387,7 @@ int main(int argc, char **argv) int callback9ret = -1; int callback10ret = -1; int callback11ret = -1; + int callback12ret = -1; struct sigaction action_stop;
memset(&action_stop, 0, sizeof action_stop); @@ -457,6 +468,11 @@ int main(int argc, char **argv) VIR_DOMAIN_EVENT_ID_PMWAKEUP, VIR_DOMAIN_EVENT_CALLBACK(myDomainEventPMWakeupCallback), strdup("pmwakeup"), myFreeFunc); + callback12ret = virConnectDomainEventRegisterAny(dconn, + NULL, + VIR_DOMAIN_EVENT_ID_PMSUSPEND, + VIR_DOMAIN_EVENT_CALLBACK(myDomainEventPMSuspendCallback), + strdup("pmsuspend"), myFreeFunc); if ((callback1ret != -1) && (callback2ret != -1) && (callback3ret != -1) && @@ -466,7 +482,8 @@ int main(int argc, char **argv) (callback7ret != -1) && (callback9ret != -1) && (callback10ret != -1) && - (callback11ret != -1)) { + (callback11ret != -1) && + (callback12ret != -1)) { if (virConnectSetKeepAlive(dconn, 5, 3) < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Failed to start keepalive protocol: %s\n", @@ -493,6 +510,7 @@ int main(int argc, char **argv) virConnectDomainEventDeregisterAny(dconn, callback9ret); virConnectDomainEventDeregisterAny(dconn, callback10ret); virConnectDomainEventDeregisterAny(dconn, callback11ret); + virConnectDomainEventDeregisterAny(dconn, callback12ret); 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 249b590..78d36a3 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -480,6 +480,9 @@ def myDomainEventTrayChangeCallback(conn, dom, devAlias, reason, opaque): def myDomainEventWakeupCallback(conn, dom, reason, opaque): print "myDomainEventWakeupCallback: Domain %s(%s) system pmwakeup" % ( dom.name(), dom.ID()) +def myDomainEventPMSuspendCallback(conn, dom, reason, opaque): + print "myDomainEventPMSuspendCallback: Domain %s(%s) system pmsuspend" % ( + dom.name(), dom.ID()) def usage(out=sys.stderr): print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]" print >>out, " uri will default to qemu:///system" @@ -540,6 +543,7 @@ def main(): 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.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None) + vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback, None)
vc.setKeepAlive(5, 3)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a9a15e1..caf5085 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3719,6 +3719,24 @@ typedef void (*virConnectDomainEventPMWakeupCallback)(virConnectPtr conn, void *opaque);
/** + * virConnectDomainEventPMSuspendCallback: + * @conn: connection object + * @dom: domain on which the event occurred + * @reason: reason why the callback was called, unused currently, + * always passes 0 + * @opaque: application specified data + * + * This callback occurs when the guest is waken up. + * + * The callback signature to use when registering for an event of type + * VIR_DOMAIN_EVENT_ID_PMSuspend with virConnectDomainEventRegisterAny() + */ +typedef void (*virConnectDomainEventPMSuspendCallback)(virConnectPtr conn, + virDomainPtr dom, + int reason, + void *opaque); + +/** * VIR_DOMAIN_EVENT_CALLBACK: * * Used to cast the event specific callback into the generic one @@ -3740,6 +3758,7 @@ typedef enum { VIR_DOMAIN_EVENT_ID_DISK_CHANGE = 9, /* virConnectDomainEventDiskChangeCallback */ VIR_DOMAIN_EVENT_ID_TRAY_CHANGE = 10, /* virConnectDomainEventTrayChangeCallback */ VIR_DOMAIN_EVENT_ID_PMWAKEUP = 11, /* virConnectDomainEventPMWakeupCallback */ + VIR_DOMAIN_EVENT_ID_PMSUSPEND = 12, /* virConnectDomainEventPMSuspendCallback */
#ifdef VIR_ENUM_SENTINELS /* diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index 2d48828..811e16b 100644 --- a/python/libvirt-override-virConnect.py +++ b/python/libvirt-override-virConnect.py @@ -152,6 +152,15 @@ cb(self, virDomain(self, _obj=dom), reason, opaque) return 0;
+ def _dispatchDomainEventPMSuspendCallback(self, dom, reason, cbData): + """Dispatches event to python user domain pmsuspend event callbacks + """ + cb = cbData["cb"] + opaque = cbData["opaque"] + + cb(self, virDomain(self, _obj=dom), reason, 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 f604a16..e6127c1 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -5021,6 +5021,53 @@ libvirt_virConnectDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSE return ret; }
+static int +libvirt_virConnectDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + 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*)"_dispatchDomainEventPMSuspendCallback", + (char*)"OO", + pyobj_dom, + 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 * libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) @@ -5087,6 +5134,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, case VIR_DOMAIN_EVENT_ID_PMWAKEUP: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMWakeupCallback); break; + case VIR_DOMAIN_EVENT_ID_PMSUSPEND: + cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMSuspendCallback); + break; }
if (!cb) { diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 06a8e29..923c58d 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -1119,6 +1119,31 @@ virDomainEventPMWakeupNewFromDom(virDomainPtr dom) return virDomainEventPMWakeupNew(dom->id, dom->name, dom->uuid); }
+static virDomainEventPtr +virDomainEventPMSuspendNew(int id, const char *name, + unsigned char *uuid) +{ + virDomainEventPtr ev = + virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND, + id, name, uuid); + + return ev; +} + +virDomainEventPtr +virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj) +{ + return virDomainEventPMSuspendNew(obj->def->id, + obj->def->name, + obj->def->uuid); +} + +virDomainEventPtr +virDomainEventPMSuspendNewFromDom(virDomainPtr dom) +{ + return virDomainEventPMSuspendNew(dom->id, dom->name, dom->uuid); +} + /** * virDomainEventQueuePush: * @evtQueue: the dom event queue @@ -1253,6 +1278,10 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, ((virConnectDomainEventPMWakeupCallback)cb)(conn, dom, 0, cbopaque); break;
+ case VIR_DOMAIN_EVENT_ID_PMSUSPEND: + ((virConnectDomainEventPMSuspendCallback)cb)(conn, dom, 0, 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 7d39201..f7776c7 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -122,6 +122,8 @@ virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom, int reason); virDomainEventPtr virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj); virDomainEventPtr virDomainEventPMWakeupNewFromDom(virDomainPtr dom); +virDomainEventPtr virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj); +virDomainEventPtr virDomainEventPMSuspendNewFromDom(virDomainPtr dom);
void virDomainEventFree(virDomainEventPtr event);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d591d04..678e89e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -511,6 +511,8 @@ virDomainEventNew; virDomainEventNewFromDef; virDomainEventNewFromDom; virDomainEventNewFromObj; +virDomainEventPMSuspendNewFromDom; +virDomainEventPMSuspendNewFromObj; virDomainEventPMWakeupNewFromDom; virDomainEventPMWakeupNewFromObj; virDomainEventRTCChangeNewFromDom; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index adf3636..9372db6 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1063,6 +1063,16 @@ int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon) return ret; }
+int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon) +{ + int ret = -1; + VIR_DEBUG("mon=%p", mon); + + QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspend, mon->vm); + + 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 6919a66..117e86c 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -130,6 +130,8 @@ struct _qemuMonitorCallbacks { int reason); int (*domainPMWakeup)(qemuMonitorPtr mon, virDomainObjPtr vm); + int (*domainPMSuspend)(qemuMonitorPtr mon, + virDomainObjPtr vm); };
char *qemuMonitorEscapeArg(const char *in); @@ -200,6 +202,7 @@ int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, const char *devAlias, int reason); int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon); +int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon); 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 7bb4410..c5cc59e 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -61,6 +61,7 @@ static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValueP static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data); +static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr data);
static struct { const char *type; @@ -79,6 +80,7 @@ static struct { { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, }, { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, }, { "WAKEUP", qemuMonitorJSONHandlePMWakeup, }, + { "SUSPEND", qemuMonitorJSONHandlePMSuspend, }, };
@@ -757,11 +759,18 @@ qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon,
static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, - virJSONValuePtr data ATTRIBUTE_UNUSED) + virJSONValuePtr data ATTRIBUTE_UNUSED)
This indentation fix should really be carried in previous patch, but it's really a minor issue
{ qemuMonitorEmitPMWakeup(mon); }
+static void +qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_UNUSED) +{ + qemuMonitorEmitPMSuspend(mon); +} + int qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, const char *cmd_str, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7914a6a..d55c269 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1082,6 +1082,27 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, return 0; }
+static int +qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virDomainObjPtr vm) +{ + struct qemud_driver *driver = qemu_driver; + virDomainEventPtr event = NULL; + + virDomainObjLock(vm); + event = virDomainEventPMSuspendNewFromObj(vm); + + virDomainObjUnlock(vm); + + if (event) { + qemuDriverLock(driver); + qemuDomainEventQueue(driver, event); + qemuDriverUnlock(driver); + } + + return 0; +} + static qemuMonitorCallbacks monitorCallbacks = { .destroy = qemuProcessHandleMonitorDestroy, .eofNotify = qemuProcessHandleMonitorEOF, @@ -1097,6 +1118,7 @@ static qemuMonitorCallbacks monitorCallbacks = { .domainBlockJob = qemuProcessHandleBlockJob, .domainTrayChange = qemuProcessHandleTrayChange, .domainPMWakeup = qemuProcessHandlePMWakeup, + .domainPMSuspend = qemuProcessHandlePMSuspend, };
static int diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 27eafa1..d0c71da 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -248,6 +248,11 @@ remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog, virNetClientPtr client, void *evdata, void *opaque);
+static void +remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog, + virNetClientPtr client, + void *evdata, void *opaque); + static virNetClientProgramEvent remoteDomainEvents[] = { { REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE, remoteDomainBuildEventRTCChange, @@ -297,6 +302,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = { remoteDomainBuildEventPMWakeup, sizeof(remote_domain_event_pmwakeup_msg), (xdrproc_t)xdr_remote_domain_event_pmwakeup_msg }, + { REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND, + remoteDomainBuildEventPMSuspend, + sizeof(remote_domain_event_pmsuspend_msg), + (xdrproc_t)xdr_remote_domain_event_pmsuspend_msg }, };
enum virDrvOpenRemoteFlags { @@ -3709,6 +3718,28 @@ remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteDomainEventQueue(priv, event); }
+static void +remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, + virNetClientPtr client ATTRIBUTE_UNUSED, + void *evdata, void *opaque) +{ + virConnectPtr conn = opaque; + struct private_data *priv = conn->privateData; + remote_domain_event_pmsuspend_msg *msg = evdata; + virDomainPtr dom; + virDomainEventPtr event = NULL; + + dom = get_nonnull_domain(conn, msg->dom); + if (!dom) + return; + + event = virDomainEventPMSuspendNewFromDom(dom); + + 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 f462b20..2d57247 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2188,6 +2188,10 @@ struct remote_domain_event_pmwakeup_msg { remote_nonnull_domain dom; };
+struct remote_domain_event_pmsuspend_msg { + remote_nonnull_domain dom; +}; + struct remote_domain_managed_save_args { remote_nonnull_domain dom; unsigned int flags; @@ -2777,7 +2781,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_BLOCK_REBASE = 266, /* autogen autogen */ REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, /* autogen autogen */ REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE = 268, /* autogen autogen */ - REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269 /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269, /* autogen autogen */ + REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND = 270 /* 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 5eb4df3..474e574 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1658,6 +1658,9 @@ struct remote_domain_event_tray_change_msg { struct remote_domain_event_pmwakeup_msg { remote_nonnull_domain dom; } +struct remote_domain_event_pmsuspend_msg { + remote_nonnull_domain dom; +} struct remote_domain_managed_save_args { remote_nonnull_domain dom; u_int flags; @@ -2188,4 +2191,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, REMOTE_PROC_DOMAIN_TRAY_CHANGE = 268, REMOTE_PROC_DOMAIN_PMWAKEUP = 269, + REMOTE_PROC_DOMAIN_PMSUSPEND = 270, };
ACK, if you could get that nit fixed before pushing it would be nice, but it's really a minor issue :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

This introduces a new domain state pmsuspended to represent the domain which has been suspended by guest power management, e.g. (entered itno s3 state). Because a "running" state could be confused in this case, one will see the guest is paused actually while playing. And state "paused" is for the domain which was paused by virDomainSuspend. --- include/libvirt/libvirt.h.in | 23 ++++++++++++++++------- src/conf/domain_conf.c | 38 +++++++++++++++++++++++++++++--------- tools/virsh.c | 10 ++++++++++ tools/virsh.pod | 7 ++++++- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index caf5085..12ba63f 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -86,13 +86,15 @@ typedef virDomain *virDomainPtr; * A domain may be in different states at a given point in time */ typedef enum { - VIR_DOMAIN_NOSTATE = 0, /* no state */ - VIR_DOMAIN_RUNNING = 1, /* the domain is running */ - VIR_DOMAIN_BLOCKED = 2, /* the domain is blocked on resource */ - VIR_DOMAIN_PAUSED = 3, /* the domain is paused by user */ - VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */ - VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */ - VIR_DOMAIN_CRASHED = 6, /* the domain is crashed */ + VIR_DOMAIN_NOSTATE = 0, /* no state */ + VIR_DOMAIN_RUNNING = 1, /* the domain is running */ + VIR_DOMAIN_BLOCKED = 2, /* the domain is blocked on resource */ + VIR_DOMAIN_PAUSED = 3, /* the domain is paused by user */ + VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */ + VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */ + VIR_DOMAIN_CRASHED = 6, /* the domain is crashed */ + VIR_DOMAIN_PMSUSPENDED = 7, /* the domain is suspended by guest + power management */ #ifdef VIR_ENUM_SENTINELS /* @@ -183,6 +185,13 @@ typedef enum { #endif } virDomainCrashedReason; +typedef enum { + VIR_DOMAIN_PMSUSPENDED_UNKNOWN = 0, + +#ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_PMSUSPENDED_LAST +#endif +} virDomainPMSuspendedReason; /** * virDomainControlState: diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 10174ab..29ff556 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -511,7 +511,8 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_LAST, "paused", "shutdown", "shutoff", - "crashed") + "crashed", + "pmsuspended") /* virDomainSnapshotState is really virDomainState plus one extra state */ VIR_ENUM_IMPL(virDomainSnapshotState, VIR_DOMAIN_SNAPSHOT_STATE_LAST, @@ -522,6 +523,7 @@ VIR_ENUM_IMPL(virDomainSnapshotState, VIR_DOMAIN_SNAPSHOT_STATE_LAST, "shutdown", "shutoff", "crashed", + "pmsuspended", "disk-snapshot") #define VIR_DOMAIN_NOSTATE_LAST (VIR_DOMAIN_NOSTATE_UNKNOWN + 1) @@ -14308,14 +14310,32 @@ virDomainObjSetState(virDomainObjPtr dom, virDomainState state, int reason) int last = -1; switch (state) { - case VIR_DOMAIN_NOSTATE: last = VIR_DOMAIN_NOSTATE_LAST; break; - case VIR_DOMAIN_RUNNING: last = VIR_DOMAIN_RUNNING_LAST; break; - case VIR_DOMAIN_BLOCKED: last = VIR_DOMAIN_BLOCKED_LAST; break; - case VIR_DOMAIN_PAUSED: last = VIR_DOMAIN_PAUSED_LAST; break; - case VIR_DOMAIN_SHUTDOWN: last = VIR_DOMAIN_SHUTDOWN_LAST; break; - case VIR_DOMAIN_SHUTOFF: last = VIR_DOMAIN_SHUTOFF_LAST; break; - case VIR_DOMAIN_CRASHED: last = VIR_DOMAIN_CRASHED_LAST; break; - default: last = -1; + case VIR_DOMAIN_NOSTATE: + last = VIR_DOMAIN_NOSTATE_LAST; + break; + case VIR_DOMAIN_RUNNING: + last = VIR_DOMAIN_RUNNING_LAST; + break; + case VIR_DOMAIN_BLOCKED: + last = VIR_DOMAIN_BLOCKED_LAST; + break; + case VIR_DOMAIN_PAUSED: + last = VIR_DOMAIN_PAUSED_LAST; + break; + case VIR_DOMAIN_SHUTDOWN: + last = VIR_DOMAIN_SHUTDOWN_LAST; + break; + case VIR_DOMAIN_SHUTOFF: + last = VIR_DOMAIN_SHUTOFF_LAST; + break; + case VIR_DOMAIN_CRASHED: + last = VIR_DOMAIN_CRASHED_LAST; + break; + case VIR_DOMAIN_PMSUSPENDED: + last = VIR_DOMAIN_PMSUSPENDED_LAST; + break; + default: + last = -1; } if (last < 0) { diff --git a/tools/virsh.c b/tools/virsh.c index 630b77f..7ef9807 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -18817,6 +18817,8 @@ vshDomainStateToString(int state) return N_("shut off"); case VIR_DOMAIN_CRASHED: return N_("crashed"); + case VIR_DOMAIN_PMSUSPENDED: + return N_("pmsuspended"); case VIR_DOMAIN_NOSTATE: default: ;/*FALLTHROUGH*/ @@ -18930,6 +18932,14 @@ vshDomainStateReasonToString(int state, int reason) } break; + case VIR_DOMAIN_PMSUSPENDED: + switch ((virDomainPMSuspendedReason) reason) { + case VIR_DOMAIN_PMSUSPENDED_UNKNOWN: + case VIR_DOMAIN_PMSUSPENDED_LAST: + ; + } + break; + case VIR_DOMAIN_LAST: ; } diff --git a/tools/virsh.pod b/tools/virsh.pod index 64b00ee..88d04a5 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -327,7 +327,7 @@ State is the run state (see below). B<STATES> -The State field lists 7 states for a domain, and which ones the +The State field lists 8 states for a domain, and which ones the current domain is in. =over 4 @@ -371,6 +371,11 @@ restart on crash. The domain is in process of dying, but hasn't completely shutdown or crashed. +=item B<pmsuspended> + +The domain has been suspended by guest power management, e.g. entered +into s3 state. + =back If I<--managed-save> is specified, then domains that have managed save -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:53PM +0800, Osier Yang wrote:
This introduces a new domain state pmsuspended to represent the domain which has been suspended by guest power management, e.g. (entered itno s3 state). Because a "running" state could
typo: into !
be confused in this case, one will see the guest is paused actually while playing. And state "paused" is for the domain which was paused by virDomainSuspend. --- include/libvirt/libvirt.h.in | 23 ++++++++++++++++------- src/conf/domain_conf.c | 38 +++++++++++++++++++++++++++++--------- tools/virsh.c | 10 ++++++++++ tools/virsh.pod | 7 ++++++- 4 files changed, 61 insertions(+), 17 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index caf5085..12ba63f 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -86,13 +86,15 @@ typedef virDomain *virDomainPtr; * A domain may be in different states at a given point in time */ typedef enum { - VIR_DOMAIN_NOSTATE = 0, /* no state */ - VIR_DOMAIN_RUNNING = 1, /* the domain is running */ - VIR_DOMAIN_BLOCKED = 2, /* the domain is blocked on resource */ - VIR_DOMAIN_PAUSED = 3, /* the domain is paused by user */ - VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */ - VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */ - VIR_DOMAIN_CRASHED = 6, /* the domain is crashed */ + VIR_DOMAIN_NOSTATE = 0, /* no state */ + VIR_DOMAIN_RUNNING = 1, /* the domain is running */ + VIR_DOMAIN_BLOCKED = 2, /* the domain is blocked on resource */ + VIR_DOMAIN_PAUSED = 3, /* the domain is paused by user */ + VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */ + VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */ + VIR_DOMAIN_CRASHED = 6, /* the domain is crashed */ + VIR_DOMAIN_PMSUSPENDED = 7, /* the domain is suspended by guest + power management */
#ifdef VIR_ENUM_SENTINELS /* @@ -183,6 +185,13 @@ typedef enum { #endif } virDomainCrashedReason;
+typedef enum { + VIR_DOMAIN_PMSUSPENDED_UNKNOWN = 0, + +#ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_PMSUSPENDED_LAST +#endif +} virDomainPMSuspendedReason;
/** * virDomainControlState: diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 10174ab..29ff556 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -511,7 +511,8 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_LAST, "paused", "shutdown", "shutoff", - "crashed") + "crashed", + "pmsuspended")
/* virDomainSnapshotState is really virDomainState plus one extra state */ VIR_ENUM_IMPL(virDomainSnapshotState, VIR_DOMAIN_SNAPSHOT_STATE_LAST, @@ -522,6 +523,7 @@ VIR_ENUM_IMPL(virDomainSnapshotState, VIR_DOMAIN_SNAPSHOT_STATE_LAST, "shutdown", "shutoff", "crashed", + "pmsuspended", "disk-snapshot")
I was wondering why we didn't add at the end but that's normal based on virDomainSnapshotState comment.
#define VIR_DOMAIN_NOSTATE_LAST (VIR_DOMAIN_NOSTATE_UNKNOWN + 1) @@ -14308,14 +14310,32 @@ virDomainObjSetState(virDomainObjPtr dom, virDomainState state, int reason) int last = -1;
switch (state) { - case VIR_DOMAIN_NOSTATE: last = VIR_DOMAIN_NOSTATE_LAST; break; - case VIR_DOMAIN_RUNNING: last = VIR_DOMAIN_RUNNING_LAST; break; - case VIR_DOMAIN_BLOCKED: last = VIR_DOMAIN_BLOCKED_LAST; break; - case VIR_DOMAIN_PAUSED: last = VIR_DOMAIN_PAUSED_LAST; break; - case VIR_DOMAIN_SHUTDOWN: last = VIR_DOMAIN_SHUTDOWN_LAST; break; - case VIR_DOMAIN_SHUTOFF: last = VIR_DOMAIN_SHUTOFF_LAST; break; - case VIR_DOMAIN_CRASHED: last = VIR_DOMAIN_CRASHED_LAST; break; - default: last = -1; + case VIR_DOMAIN_NOSTATE: + last = VIR_DOMAIN_NOSTATE_LAST; + break; + case VIR_DOMAIN_RUNNING: + last = VIR_DOMAIN_RUNNING_LAST; + break; + case VIR_DOMAIN_BLOCKED: + last = VIR_DOMAIN_BLOCKED_LAST; + break; + case VIR_DOMAIN_PAUSED: + last = VIR_DOMAIN_PAUSED_LAST; + break; + case VIR_DOMAIN_SHUTDOWN: + last = VIR_DOMAIN_SHUTDOWN_LAST; + break; + case VIR_DOMAIN_SHUTOFF: + last = VIR_DOMAIN_SHUTOFF_LAST; + break; + case VIR_DOMAIN_CRASHED: + last = VIR_DOMAIN_CRASHED_LAST; + break; + case VIR_DOMAIN_PMSUSPENDED: + last = VIR_DOMAIN_PMSUSPENDED_LAST; + break; + default: + last = -1; }
if (last < 0) { diff --git a/tools/virsh.c b/tools/virsh.c index 630b77f..7ef9807 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -18817,6 +18817,8 @@ vshDomainStateToString(int state) return N_("shut off"); case VIR_DOMAIN_CRASHED: return N_("crashed"); + case VIR_DOMAIN_PMSUSPENDED: + return N_("pmsuspended"); case VIR_DOMAIN_NOSTATE: default: ;/*FALLTHROUGH*/ @@ -18930,6 +18932,14 @@ vshDomainStateReasonToString(int state, int reason) } break;
+ case VIR_DOMAIN_PMSUSPENDED: + switch ((virDomainPMSuspendedReason) reason) { + case VIR_DOMAIN_PMSUSPENDED_UNKNOWN: + case VIR_DOMAIN_PMSUSPENDED_LAST: + ; + } + break; + case VIR_DOMAIN_LAST: ; } diff --git a/tools/virsh.pod b/tools/virsh.pod index 64b00ee..88d04a5 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -327,7 +327,7 @@ State is the run state (see below).
B<STATES>
-The State field lists 7 states for a domain, and which ones the +The State field lists 8 states for a domain, and which ones the current domain is in.
=over 4 @@ -371,6 +371,11 @@ restart on crash. The domain is in process of dying, but hasn't completely shutdown or crashed.
+=item B<pmsuspended> + +The domain has been suspended by guest power management, e.g. entered +into s3 state. + =back
If I<--managed-save> is specified, then domains that have managed save
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

--- src/qemu/qemu_process.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d55c269..e041f8d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1092,6 +1092,19 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjLock(vm); event = virDomainEventPMSuspendNewFromObj(vm); + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { + VIR_DEBUG("Transitioned guest %s to pmsuspended state due to " + "QMP suspend event", vm->def->name); + + virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED, + VIR_DOMAIN_PMSUSPENDED_UNKNOWN); + + if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { + VIR_WARN("Unable to save status on vm %s after suspend event", + vm->def->name); + } + } + virDomainObjUnlock(vm); if (event) { -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:54PM +0800, Osier Yang wrote:
--- src/qemu/qemu_process.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d55c269..e041f8d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1092,6 +1092,19 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjLock(vm); event = virDomainEventPMSuspendNewFromObj(vm);
+ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { + VIR_DEBUG("Transitioned guest %s to pmsuspended state due to " + "QMP suspend event", vm->def->name); + + virDomainObjSetState(vm, VIR_DOMAIN_PMSUSPENDED, + VIR_DOMAIN_PMSUSPENDED_UNKNOWN); + + if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { + VIR_WARN("Unable to save status on vm %s after suspend event", + vm->def->name); + } + } + virDomainObjUnlock(vm);
if (event) {
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

This introduces a new running reason VIR_DOMAIN_RUNNING_WAKEUP, and new suspend event type VIR_DOMAIN_EVENT_STARTED_WAKEUP. While a wakeup event is emitted, the domain which entered into VIR_DOMAIN_PMSUSPENDED will be transferred to "running" with reason VIR_DOMAIN_RUNNING_WAKEUP, and a new domain lifecycle event emitted with type VIR_DOMAIN_EVENT_STARTED_WAKEUP. --- examples/domain-events/events-c/event-test.c | 3 ++ include/libvirt/libvirt.h.in | 3 ++ src/qemu/qemu_process.c | 27 ++++++++++++++++++++++++- tools/virsh.c | 2 + 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 9ffabd6..5a6ef1d 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -93,6 +93,9 @@ static const char *eventDetailToString(int event, int detail) { case VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT: ret = "Snapshot"; break; + case VIR_DOMAIN_EVENT_STARTED_WAKEUP: + ret = "Event wakeup"; + break; } break; case VIR_DOMAIN_EVENT_SUSPENDED: diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 12ba63f..c702e66 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -123,6 +123,8 @@ typedef enum { VIR_DOMAIN_RUNNING_UNPAUSED = 5, /* returned from paused state */ VIR_DOMAIN_RUNNING_MIGRATION_CANCELED = 6, /* returned from migration */ VIR_DOMAIN_RUNNING_SAVE_CANCELED = 7, /* returned from failed save process */ + VIR_DOMAIN_RUNNING_WAKEUP = 8, /* returned from pmsuspended due to + wakeup event */ #ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_RUNNING_LAST @@ -2695,6 +2697,7 @@ typedef enum { VIR_DOMAIN_EVENT_STARTED_MIGRATED = 1, /* Incoming migration from another host */ VIR_DOMAIN_EVENT_STARTED_RESTORED = 2, /* Restored from a state file */ VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT = 3, /* Restored from snapshot */ + VIR_DOMAIN_EVENT_STARTED_WAKEUP = 4, /* Started due to wakeup event */ #ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_STARTED_LAST diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index e041f8d..8b46186 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1067,15 +1067,38 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, { struct qemud_driver *driver = qemu_driver; virDomainEventPtr event = NULL; + virDomainEventPtr lifecycleEvent = NULL; virDomainObjLock(vm); event = virDomainEventPMWakeupNewFromObj(vm); + /* Don't set domain status back to running if it wasn't paused + * from guest side, otherwise it can just cause confusion. + */ + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PMSUSPENDED) { + VIR_DEBUG("Transitioned guest %s from pmsuspended to running " + "state due to QMP wakeup event", vm->def->name); + + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_WAKEUP); + lifecycleEvent = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_WAKEUP); + + if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { + VIR_WARN("Unable to save status on vm %s after wakeup event", + vm->def->name); + } + } + virDomainObjUnlock(vm); - if (event) { + if (event || lifecycleEvent) { qemuDriverLock(driver); - qemuDomainEventQueue(driver, event); + if (event) + qemuDomainEventQueue(driver, event); + if (lifecycleEvent) + qemuDomainEventQueue(driver, lifecycleEvent); qemuDriverUnlock(driver); } diff --git a/tools/virsh.c b/tools/virsh.c index 7ef9807..d36b545 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -18854,6 +18854,8 @@ vshDomainStateReasonToString(int state, int reason) return N_("migration canceled"); case VIR_DOMAIN_RUNNING_SAVE_CANCELED: return N_("save canceled"); + case VIR_DOMAIN_RUNNING_WAKEUP: + return N_("event wakeup"); case VIR_DOMAIN_RUNNING_UNKNOWN: case VIR_DOMAIN_RUNNING_LAST: ; -- 1.7.1

On Wed, Mar 14, 2012 at 11:26:55PM +0800, Osier Yang wrote:
This introduces a new running reason VIR_DOMAIN_RUNNING_WAKEUP, and new suspend event type VIR_DOMAIN_EVENT_STARTED_WAKEUP.
While a wakeup event is emitted, the domain which entered into VIR_DOMAIN_PMSUSPENDED will be transferred to "running" with reason VIR_DOMAIN_RUNNING_WAKEUP, and a new domain lifecycle event emitted with type VIR_DOMAIN_EVENT_STARTED_WAKEUP. --- examples/domain-events/events-c/event-test.c | 3 ++ include/libvirt/libvirt.h.in | 3 ++ src/qemu/qemu_process.c | 27 ++++++++++++++++++++++++- tools/virsh.c | 2 + 4 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 9ffabd6..5a6ef1d 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -93,6 +93,9 @@ static const char *eventDetailToString(int event, int detail) { case VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT: ret = "Snapshot"; break; + case VIR_DOMAIN_EVENT_STARTED_WAKEUP: + ret = "Event wakeup"; + break; } break; case VIR_DOMAIN_EVENT_SUSPENDED: diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 12ba63f..c702e66 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -123,6 +123,8 @@ typedef enum { VIR_DOMAIN_RUNNING_UNPAUSED = 5, /* returned from paused state */ VIR_DOMAIN_RUNNING_MIGRATION_CANCELED = 6, /* returned from migration */ VIR_DOMAIN_RUNNING_SAVE_CANCELED = 7, /* returned from failed save process */ + VIR_DOMAIN_RUNNING_WAKEUP = 8, /* returned from pmsuspended due to + wakeup event */
#ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_RUNNING_LAST @@ -2695,6 +2697,7 @@ typedef enum { VIR_DOMAIN_EVENT_STARTED_MIGRATED = 1, /* Incoming migration from another host */ VIR_DOMAIN_EVENT_STARTED_RESTORED = 2, /* Restored from a state file */ VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT = 3, /* Restored from snapshot */ + VIR_DOMAIN_EVENT_STARTED_WAKEUP = 4, /* Started due to wakeup event */
#ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_STARTED_LAST diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index e041f8d..8b46186 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1067,15 +1067,38 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, { struct qemud_driver *driver = qemu_driver; virDomainEventPtr event = NULL; + virDomainEventPtr lifecycleEvent = NULL;
virDomainObjLock(vm); event = virDomainEventPMWakeupNewFromObj(vm);
+ /* Don't set domain status back to running if it wasn't paused + * from guest side, otherwise it can just cause confusion. + */ + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PMSUSPENDED) { + VIR_DEBUG("Transitioned guest %s from pmsuspended to running " + "state due to QMP wakeup event", vm->def->name); + + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_WAKEUP); + lifecycleEvent = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_WAKEUP); + + if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) { + VIR_WARN("Unable to save status on vm %s after wakeup event", + vm->def->name); + } + } + virDomainObjUnlock(vm);
- if (event) { + if (event || lifecycleEvent) { qemuDriverLock(driver); - qemuDomainEventQueue(driver, event); + if (event) + qemuDomainEventQueue(driver, event); + if (lifecycleEvent) + qemuDomainEventQueue(driver, lifecycleEvent); qemuDriverUnlock(driver); }
diff --git a/tools/virsh.c b/tools/virsh.c index 7ef9807..d36b545 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -18854,6 +18854,8 @@ vshDomainStateReasonToString(int state, int reason) return N_("migration canceled"); case VIR_DOMAIN_RUNNING_SAVE_CANCELED: return N_("save canceled"); + case VIR_DOMAIN_RUNNING_WAKEUP: + return N_("event wakeup"); case VIR_DOMAIN_RUNNING_UNKNOWN: case VIR_DOMAIN_RUNNING_LAST: ;
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

ping. On 03/14/2012 11:26 PM, Osier Yang wrote:
v1 ~ v2: * Two more patches, [5/11] to prohibit tray='open' for block type disk. And [9/11] to introduce a new domain state 'pmsuspended'
* Definition (including name) for DEVICE_TRAY_MOVED event is changed into:
typedef void (*virConnectDomainEventTrayChangeCallback)(virConnectPtr conn, virDomainPtr dom, const char *devAlias, int reason, void *opaque);
* Definition for both SUSPEND and WAKEUP event are changed, one more parameter 'int reason' for future extension.
* While SUSPEND event is emitted, the running domain will be transfered into the new domain state "pmsuspended", instead of "paused". And while WAKEUP is emitted, it will transfer the domain state to running only if the domain state is "pmsuspended".
This patch series adds support for 3 new QMP events: WAKEUP, SUSPEND, and DEVICE_TRAY_MOVED, and related changes on domain's conf and status.
[1/11] Add support for tray moved event
[2/11] ~ [6/11]: New attribute "tray" is added to disk target, it indicates the tray status of removable disk, i.e. CDROM and Floppy disks, its value could be either of "open" or "closed", defaults to "closed", and a removable disk with tray == "open" won't have the source when domain is started. The value of "tray" will be updated while tray moved event is emitted from guest. tray status 'open' is prohibited for block type disk. Prior to these patches, if the user ejected the medium of removable disk from guest side, and then do migration or save/restoring, the guest will still starts the medium source ,and thus the medium will still exists in guest, which is strange. These patches fix it.
[7/11] + [11/11]: Add support for wakeup event, and update the domain status to running if the domain is in pmsuspended state, while the wakeup event is emitted.
[9/11] Introduce new domain state "pmsuspended", which indicates the domain has been suspended by guest power management, e.g, entered into s3 state.
[8/11] + [10/11]: Add support for suspend event, and update the domain status to pmsuspended if the domain was running, while the suspend event is emitted.
Osier Yang(11) Add support for event tray moved of removable disks docs: Add documentation for new attribute tray of disk target conf: Parse and for the tray attribute qemu: Do not start with source for removable disks if tray is open qemu: Prohibit setting tray status as open for block type disk qemu: Update tray status while tray moved event is emitted Add support for the wakeup event Add support for the suspend event New domain state pmsuspended qemu: Update domain state to pmsuspended while suspend event occurs qemu: Update domain status to running while wakeup event is emitted
daemon/remote.c | 79 ++++++++++ docs/formatdomain.html.in | 13 ++- docs/schemas/domaincommon.rng | 8 + examples/domain-events/events-c/event-test.c | 66 +++++++++- examples/domain-events/events-python/event-test.py | 12 ++ include/libvirt/libvirt.h.in | 98 ++++++++++++- python/libvirt-override-virConnect.py | 27 ++++ python/libvirt-override.c | 150 ++++++++++++++++++++ src/conf/domain_conf.c | 71 ++++++++-- src/conf/domain_conf.h | 9 ++ src/conf/domain_event.c | 115 +++++++++++++++ src/conf/domain_event.h | 10 ++ src/libvirt_private.syms | 6 + src/qemu/qemu_command.c | 31 ++++- src/qemu/qemu_monitor.c | 33 +++++ src/qemu/qemu_monitor.h | 16 ++- src/qemu/qemu_monitor_json.c | 45 ++++++ src/qemu/qemu_process.c | 121 ++++++++++++++++ src/remote/remote_driver.c | 95 ++++++++++++ src/remote/remote_protocol.x | 19 +++- src/remote_protocol-structs | 14 ++ tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml | 2 +- .../qemuxml2argv-boot-complex-bootindex.xml | 6 +- .../qemuxml2argvdata/qemuxml2argv-boot-complex.xml | 6 +- .../qemuxml2argvdata/qemuxml2argv-boot-floppy.xml | 2 +- ...uxml2argv-boot-menu-disable-drive-bootindex.xml | 2 +- .../qemuxml2argv-boot-menu-disable-drive.xml | 2 +- .../qemuxml2argv-boot-menu-disable.xml | 2 +- .../qemuxml2argv-boot-menu-enable.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml | 4 +- tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-aio.xml | 2 +- .../qemuxml2argv-disk-cdrom-empty.xml | 2 +- ...qemuxml2argv-disk-cdrom-tray-no-device-cap.args | 4 + .../qemuxml2argv-disk-cdrom-tray-no-device-cap.xml | 32 ++++ .../qemuxml2argv-disk-cdrom-tray.args | 10 ++ .../qemuxml2argv-disk-cdrom-tray.xml | 43 ++++++ tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml | 2 +- .../qemuxml2argv-disk-copy_on_read.xml | 2 +- .../qemuxml2argv-disk-drive-boot-cdrom.xml | 2 +- .../qemuxml2argv-disk-drive-boot-disk.xml | 2 +- .../qemuxml2argv-disk-drive-cache-directsync.xml | 2 +- .../qemuxml2argv-disk-drive-cache-unsafe.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-none.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wb.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wt.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-none.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wb.xml | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wt.xml | 2 +- ...muxml2argv-disk-drive-error-policy-enospace.xml | 2 +- .../qemuxml2argv-disk-drive-error-policy-stop.xml | 2 +- ...rgv-disk-drive-error-policy-wreport-rignore.xml | 2 +- .../qemuxml2argv-disk-drive-fmt-qcow.xml | 2 +- .../qemuxml2argv-disk-drive-no-boot.xml | 4 +- .../qemuxml2argv-disk-drive-readonly-disk.xml | 2 +- .../qemuxml2argv-disk-drive-readonly-no-device.xml | 2 +- .../qemuxml2argv-disk-drive-shared.xml | 2 +- ...emuxml2argv-disk-floppy-tray-no-device-cap.args | 4 + ...qemuxml2argv-disk-floppy-tray-no-device-cap.xml | 37 +++++ .../qemuxml2argv-disk-floppy-tray.args | 10 ++ .../qemuxml2argv-disk-floppy-tray.xml | 37 +++++ .../qemuxml2argvdata/qemuxml2argv-disk-floppy.xml | 4 +- .../qemuxml2argv-disk-ioeventfd.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-order.xml | 2 +- .../qemuxml2argv-disk-snapshot.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-virtio.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml | 2 +- .../qemuxml2argv-floppy-drive-fat.xml | 2 +- .../qemuxml2argv-graphics-spice-timeout.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-lease.xml | 2 +- .../qemuxml2argv-net-bandwidth.xml | 2 +- tests/qemuxml2argvtest.c | 6 + .../qemuxml2xmlout-graphics-spice-timeout.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml | 8 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml | 4 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-5.xml | 2 +- tests/vmx2xmldata/vmx2xml-esx-in-the-wild-6.xml | 2 +- tests/vmx2xmldata/vmx2xml-floppy-device.xml | 2 +- tests/vmx2xmldata/vmx2xml-floppy-file.xml | 2 +- tests/vmx2xmldata/vmx2xml-ws-in-the-wild-1.xml | 2 +- tests/vmx2xmldata/vmx2xml-ws-in-the-wild-2.xml | 2 +- tools/virsh.c | 12 ++ tools/virsh.pod | 7 +- 89 files changed, 1277 insertions(+), 99 deletions(-)
Osier
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (2)
-
Daniel Veillard
-
Osier Yang