[libvirt] [PATCH 0/6] Support VNC password changes on running guests v2

This patch introduces a new virDomainUpdateDeviceFlags() API to allow the configuration of a device to be changed on the fly. It ports the existing CDROM media change code in all drivers to use this new API (keeps old support too). It then adds VNC password change support in the QEMU driver using this new API v2: Fix feedback from first posting

The current virDomainAttachDevice API can be (ab)used to change the media of an existing CDROM/Floppy device. Going forward there will be more devices that can be configured on the fly and overloading virDomainAttachDevice for this is not too pleasant. This patch adds a new virDomainUpdateDeviceFlags() explicitly just for modifying existing devices. * include/libvirt/libvirt.h.in: Add virDomainUpdateDeviceFlags * src/driver.h: Internal API for virDomainUpdateDeviceFlags * src/libvirt.c, src/libvirt_public.syms: Glue public API to driver API * src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c, src/openvz/openvz_driver.c, src/phyp/phyp_driver.c, src/qemu/qemu_driver.c, src/remote/remote_driver.c, src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c, src/xen/xen_driver.c, src/xenapi/xenapi_driver.c: Add stubs for new driver entry point --- include/libvirt/libvirt.h.in | 2 + src/driver.h | 5 +++ src/esx/esx_driver.c | 1 + src/libvirt.c | 68 +++++++++++++++++++++++++++++++++++++++++- src/libvirt_public.syms | 1 + src/lxc/lxc_driver.c | 1 + src/opennebula/one_driver.c | 1 + src/openvz/openvz_driver.c | 1 + src/phyp/phyp_driver.c | 1 + src/qemu/qemu_driver.c | 1 + src/remote/remote_driver.c | 1 + src/test/test_driver.c | 1 + src/uml/uml_driver.c | 1 + src/vbox/vbox_tmpl.c | 1 + src/xen/xen_driver.c | 1 + src/xenapi/xenapi_driver.c | 1 + 16 files changed, 87 insertions(+), 1 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index aaefa09..e71a30c 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -878,6 +878,8 @@ int virDomainAttachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int flags); int virDomainDetachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int flags); +int virDomainUpdateDeviceFlags(virDomainPtr domain, + const char *xml, unsigned int flags); /* * NUMA support diff --git a/src/driver.h b/src/driver.h index 362533f..bec5545 100644 --- a/src/driver.h +++ b/src/driver.h @@ -204,6 +204,10 @@ typedef int const char *xml, unsigned int flags); typedef int + (*virDrvDomainUpdateDeviceFlags) (virDomainPtr domain, + const char *xml, + unsigned int flags); +typedef int (*virDrvDomainGetAutostart) (virDomainPtr domain, int *autostart); typedef int @@ -448,6 +452,7 @@ struct _virDriver { virDrvDomainAttachDeviceFlags domainAttachDeviceFlags; virDrvDomainDetachDevice domainDetachDevice; virDrvDomainDetachDeviceFlags domainDetachDeviceFlags; + virDrvDomainUpdateDeviceFlags domainUpdateDeviceFlags; virDrvDomainGetAutostart domainGetAutostart; virDrvDomainSetAutostart domainSetAutostart; virDrvDomainGetSchedulerType domainGetSchedulerType; diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 30a1adb..b566d77 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -3367,6 +3367,7 @@ static virDriver esxDriver = { NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ esxDomainGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/libvirt.c b/src/libvirt.c index 7b74fd9..66a4d6c 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -1868,7 +1868,7 @@ error: * * Deprecated after 0.4.6. * Renamed to virDomainCreateXML() providing identical functionality. - * This existing name will left indefinitely for API compatability. + * This existing name will left indefinitely for API compatibility. * * Returns a new domain object or NULL in case of failure */ @@ -5147,6 +5147,10 @@ error: * Create a virtual device attachment to backend. This function, * having hotplug semantics, is only allowed on an active domain. * + * For compatibility, this method can also be used to change the media + * in an existing CDROM/Floppy device, however, applications are + * recommended to use the virDomainUpdateDeviceFlag method instead. + * * Returns 0 in case of success, -1 in case of failure. */ int @@ -5201,6 +5205,10 @@ error: * return failure if LIVE is specified but it only supports modifying the * persisted device allocation. * + * For compatibility, this method can also be used to change the media + * in an existing CDROM/Floppy device, however, applications are + * recommended to use the virDomainUpdateDeviceFlag method instead. + * * Returns 0 in case of success, -1 in case of failure. */ int @@ -5336,6 +5344,64 @@ error: } /** + * virDomainUpdateDeviceFlags: + * @domain: pointer to domain object + * @xml: pointer to XML description of one device + * @flags: an OR'ed set of virDomainDeviceModifyFlags + * + * Change a virtual device on a domain, using the flags parameter + * to control how the device is changed. VIR_DOMAIN_DEVICE_MODIFY_CURRENT + * specifies that the device change is made based on current domain + * state. VIR_DOMAIN_DEVICE_MODIFY_LIVE specifies that the device shall be + * changed on the active domain instance only and is not added to the + * persisted domain configuration. VIR_DOMAIN_DEVICE_MODIFY_CONFIG + * specifies that the device shall be changed on the persisted domain + * configuration only. Note that the target hypervisor must return an + * error if unable to satisfy flags. E.g. the hypervisor driver will + * return failure if LIVE is specified but it only supports modifying the + * persisted device allocation. + * + * This method is used for actions such changing CDROM/Floppy device + * media, altering the graphics configuration such as password, + * reconfiguring the NIC device backend connectivity, etc. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainUpdateDeviceFlags(virDomainPtr domain, + const char *xml, unsigned int flags) +{ + virConnectPtr conn; + DEBUG("domain=%p, xml=%s, flags=%d", domain, xml, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + return (-1); + } + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainUpdateDeviceFlags) { + int ret; + ret = conn->driver->domainUpdateDeviceFlags(domain, xml, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** * virNodeGetCellsFreeMemory: * @conn: pointer to the hypervisor connection * @freeMems: pointer to the array of unsigned long long diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 623e53c..7247125 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -362,6 +362,7 @@ LIBVIRT_0.7.8 { global: virStorageVolWipe; virDomainMigrateSetMaxDowntime; + virDomainUpdateDeviceFlags; } LIBVIRT_0.7.7; # .... define new API here using predicted next version number .... diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index ba13065..88c3c55 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2428,6 +2428,7 @@ static virDriver lxcDriver = { NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ lxcDomainGetAutostart, /* domainGetAutostart */ lxcDomainSetAutostart, /* domainSetAutostart */ lxcGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c index e1d1efc..23f4c09 100644 --- a/src/opennebula/one_driver.c +++ b/src/opennebula/one_driver.c @@ -757,6 +757,7 @@ static virDriver oneDriver = { NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ oneGetAutostart, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 50aadfc..ea71d3b 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1509,6 +1509,7 @@ static virDriver openvzDriver = { NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ openvzDomainGetAutostart, /* domainGetAutostart */ openvzDomainSetAutostart, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index e4d67dc..909de77 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -1616,6 +1616,7 @@ virDriver phypDriver = { NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 257f914..caa6442 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9644,6 +9644,7 @@ static virDriver qemuDriver = { qemudDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ qemudDomainDetachDevice, /* domainDetachDevice */ qemudDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ qemudDomainGetAutostart, /* domainGetAutostart */ qemudDomainSetAutostart, /* domainSetAutostart */ qemuGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 1476f19..2088bed 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -9157,6 +9157,7 @@ static virDriver remote_driver = { remoteDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ remoteDomainDetachDevice, /* domainDetachDevice */ remoteDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ remoteDomainGetAutostart, /* domainGetAutostart */ remoteDomainSetAutostart, /* domainSetAutostart */ remoteDomainGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/test/test_driver.c b/src/test/test_driver.c index f54ebae..5254851 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5214,6 +5214,7 @@ static virDriver testDriver = { NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ testDomainGetAutostart, /* domainGetAutostart */ testDomainSetAutostart, /* domainSetAutostart */ testDomainGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index bf06787..5031d39 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1901,6 +1901,7 @@ static virDriver umlDriver = { NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ umlDomainGetAutostart, /* domainGetAutostart */ umlDomainSetAutostart, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 1765d63..f398041 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -7030,6 +7030,7 @@ virDriver NAME(Driver) = { vboxDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ vboxDomainDetachDevice, /* domainDetachDevice */ vboxDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 204ed91..1ff3e44 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1875,6 +1875,7 @@ static virDriver xenUnifiedDriver = { xenUnifiedDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ xenUnifiedDomainDetachDevice, /* domainDetachDevice */ xenUnifiedDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ xenUnifiedDomainGetAutostart, /* domainGetAutostart */ xenUnifiedDomainSetAutostart, /* domainSetAutostart */ xenUnifiedDomainGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index ac00424..a06781a 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -1716,6 +1716,7 @@ static virDriver xenapiDriver = { NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ xenapiDomainGetAutostart, /* domainGetAutostart */ xenapiDomainSetAutostart, /* domainSetAutostart */ xenapiDomainGetSchedulerType, /* domainGetSchedulerType */ -- 1.6.6.1

On 03/24/2010 05:46 AM, Daniel P. Berrange wrote:
+++ b/src/libvirt.c @@ -1868,7 +1868,7 @@ error: * * Deprecated after 0.4.6. * Renamed to virDomainCreateXML() providing identical functionality. - * This existing name will left indefinitely for API compatability. + * This existing name will left indefinitely for API compatibility.
s/will left/will be left/
/** + * virDomainUpdateDeviceFlags: + * @domain: pointer to domain object + * @xml: pointer to XML description of one device + * @flags: an OR'ed set of virDomainDeviceModifyFlags + * + * Change a virtual device on a domain, using the flags parameter + * to control how the device is changed. VIR_DOMAIN_DEVICE_MODIFY_CURRENT + * specifies that the device change is made based on current domain + * state. VIR_DOMAIN_DEVICE_MODIFY_LIVE specifies that the device shall be + * changed on the active domain instance only and is not added to the + * persisted domain configuration. VIR_DOMAIN_DEVICE_MODIFY_CONFIG + * specifies that the device shall be changed on the persisted domain + * configuration only. Note that the target hypervisor must return an + * error if unable to satisfy flags. E.g. the hypervisor driver will + * return failure if LIVE is specified but it only supports modifying the + * persisted device allocation.
s/persisted/persistent/ (you fixed new instances of this in 3/6, but my review of your first round missed that you had also introduced multiple instances in 1/6)
+ if (conn->driver->domainUpdateDeviceFlags) { + int ret; + ret = conn->driver->domainUpdateDeviceFlags(domain, xml, flags);
These two lines could be merged into one. ACK. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On Wed, Mar 24, 2010 at 11:46:22AM +0000, Daniel P. Berrange wrote:
The current virDomainAttachDevice API can be (ab)used to change the media of an existing CDROM/Floppy device. Going forward there will be more devices that can be configured on the fly and overloading virDomainAttachDevice for this is not too pleasant. This patch adds a new virDomainUpdateDeviceFlags() explicitly just for modifying existing devices.
* include/libvirt/libvirt.h.in: Add virDomainUpdateDeviceFlags * src/driver.h: Internal API for virDomainUpdateDeviceFlags * src/libvirt.c, src/libvirt_public.syms: Glue public API to driver API * src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c, src/openvz/openvz_driver.c, src/phyp/phyp_driver.c, src/qemu/qemu_driver.c, src/remote/remote_driver.c, src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c, src/xen/xen_driver.c, src/xenapi/xenapi_driver.c: Add stubs for new driver entry point [...] diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index aaefa09..e71a30c 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -878,6 +878,8 @@ int virDomainAttachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int flags); int virDomainDetachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int flags); +int virDomainUpdateDeviceFlags(virDomainPtr domain, + const char *xml, unsigned int flags);
/* * NUMA support [...] /** + * virDomainUpdateDeviceFlags: + * @domain: pointer to domain object + * @xml: pointer to XML description of one device + * @flags: an OR'ed set of virDomainDeviceModifyFlags + * + * Change a virtual device on a domain, using the flags parameter + * to control how the device is changed. VIR_DOMAIN_DEVICE_MODIFY_CURRENT + * specifies that the device change is made based on current domain + * state. VIR_DOMAIN_DEVICE_MODIFY_LIVE specifies that the device shall be + * changed on the active domain instance only and is not added to the + * persisted domain configuration. VIR_DOMAIN_DEVICE_MODIFY_CONFIG + * specifies that the device shall be changed on the persisted domain + * configuration only. Note that the target hypervisor must return an + * error if unable to satisfy flags. E.g. the hypervisor driver will + * return failure if LIVE is specified but it only supports modifying the + * persisted device allocation. + * + * This method is used for actions such changing CDROM/Floppy device + * media, altering the graphics configuration such as password, + * reconfiguring the NIC device backend connectivity, etc. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainUpdateDeviceFlags(virDomainPtr domain, + const char *xml, unsigned int flags)
ACK, API looks fine, 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 defines the wire format for the new virDomainUpdateDeviceFlags() API, and implements the server & client side of the marshalling code. * daemon/remote.c: Server side dispatch for virDomainUpdateDeviceFlags * src/remote/remote_driver.c: Client side serialization for virDomainUpdateDeviceFlags * src/remote/remote_protocol.x: Define wire format for virDomainUpdateDeviceFlags * daemon/remote_dispatch_args.h, daemon/remote_dispatch_prototypes.h, daemon/remote_dispatch_table.h, src/remote/remote_protocol.c, src/remote/remote_protocol.h: Re-generate code --- daemon/remote.c | 26 ++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 1 + daemon/remote_dispatch_prototypes.h | 8 ++++++++ daemon/remote_dispatch_table.h | 5 +++++ src/remote/remote_driver.c | 28 +++++++++++++++++++++++++++- src/remote/remote_protocol.c | 13 +++++++++++++ src/remote/remote_protocol.h | 10 ++++++++++ src/remote/remote_protocol.x | 9 ++++++++- 8 files changed, 98 insertions(+), 2 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 1b02143..0673351 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -916,6 +916,32 @@ remoteDispatchDomainAttachDeviceFlags (struct qemud_server *server ATTRIBUTE_UNU } static int +remoteDispatchDomainUpdateDeviceFlags (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header *hdr ATTRIBUTE_UNUSED, + remote_error *rerr, + remote_domain_update_device_flags_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom; + + dom = get_nonnull_domain (conn, args->dom); + if (dom == NULL) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + if (virDomainUpdateDeviceFlags (dom, args->xml, args->flags) == -1) { + virDomainFree(dom); + remoteDispatchConnError(rerr, conn); + return -1; + } + virDomainFree(dom); + return 0; +} + +static int remoteDispatchDomainCreate (struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, virConnectPtr conn, diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h index 68016aa..21217f3 100644 --- a/daemon/remote_dispatch_args.h +++ b/daemon/remote_dispatch_args.h @@ -142,3 +142,4 @@ remote_domain_abort_job_args val_remote_domain_abort_job_args; remote_storage_vol_wipe_args val_remote_storage_vol_wipe_args; remote_domain_migrate_set_max_downtime_args val_remote_domain_migrate_set_max_downtime_args; + remote_domain_update_device_flags_args val_remote_domain_update_device_flags_args; diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h index 13e78ce..2c9cc83 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -490,6 +490,14 @@ static int remoteDispatchDomainUndefine( remote_error *err, remote_domain_undefine_args *args, void *ret); +static int remoteDispatchDomainUpdateDeviceFlags( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_update_device_flags_args *args, + void *ret); static int remoteDispatchDomainXmlFromNative( struct qemud_server *server, struct qemud_client *client, diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h index b0d0d1e..ebd9b8b 100644 --- a/daemon/remote_dispatch_table.h +++ b/daemon/remote_dispatch_table.h @@ -837,3 +837,8 @@ .args_filter = (xdrproc_t) xdr_remote_domain_migrate_set_max_downtime_args, .ret_filter = (xdrproc_t) xdr_void, }, +{ /* DomainUpdateDeviceFlags => 167 */ + .fn = (dispatch_fn) remoteDispatchDomainUpdateDeviceFlags, + .args_filter = (xdrproc_t) xdr_remote_domain_update_device_flags_args, + .ret_filter = (xdrproc_t) xdr_void, +}, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 2088bed..024a24d 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -3158,6 +3158,32 @@ done: } static int +remoteDomainUpdateDeviceFlags (virDomainPtr domain, const char *xml, + unsigned int flags) +{ + int rv = -1; + remote_domain_update_device_flags_args args; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + args.xml = (char *) xml; + args.flags = flags; + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_UPDATE_DEVICE_FLAGS, + (xdrproc_t) xdr_remote_domain_update_device_flags_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int remoteDomainGetAutostart (virDomainPtr domain, int *autostart) { int rv = -1; @@ -9157,7 +9183,7 @@ static virDriver remote_driver = { remoteDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ remoteDomainDetachDevice, /* domainDetachDevice */ remoteDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ - NULL, /* domainUpdateDeviceFlags */ + remoteDomainUpdateDeviceFlags, /* domainUpdateDeviceFlags */ remoteDomainGetAutostart, /* domainGetAutostart */ remoteDomainSetAutostart, /* domainSetAutostart */ remoteDomainGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c index 3e5c1c7..3950049 100644 --- a/src/remote/remote_protocol.c +++ b/src/remote/remote_protocol.c @@ -1319,6 +1319,19 @@ xdr_remote_domain_detach_device_flags_args (XDR *xdrs, remote_domain_detach_devi } bool_t +xdr_remote_domain_update_device_flags_args (XDR *xdrs, remote_domain_update_device_flags_args *objp) +{ + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_remote_nonnull_string (xdrs, &objp->xml)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t xdr_remote_domain_get_autostart_args (XDR *xdrs, remote_domain_get_autostart_args *objp) { diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h index 43a3dc3..cd58c47 100644 --- a/src/remote/remote_protocol.h +++ b/src/remote/remote_protocol.h @@ -739,6 +739,13 @@ struct remote_domain_detach_device_flags_args { }; typedef struct remote_domain_detach_device_flags_args remote_domain_detach_device_flags_args; +struct remote_domain_update_device_flags_args { + remote_nonnull_domain dom; + remote_nonnull_string xml; + u_int flags; +}; +typedef struct remote_domain_update_device_flags_args remote_domain_update_device_flags_args; + struct remote_domain_get_autostart_args { remote_nonnull_domain dom; }; @@ -1887,6 +1894,7 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_ABORT_JOB = 164, REMOTE_PROC_STORAGE_VOL_WIPE = 165, REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_DOWNTIME = 166, + REMOTE_PROC_DOMAIN_UPDATE_DEVICE_FLAGS = 167, }; typedef enum remote_procedure remote_procedure; @@ -2028,6 +2036,7 @@ extern bool_t xdr_remote_domain_attach_device_args (XDR *, remote_domain_attach extern bool_t xdr_remote_domain_attach_device_flags_args (XDR *, remote_domain_attach_device_flags_args*); extern bool_t xdr_remote_domain_detach_device_args (XDR *, remote_domain_detach_device_args*); extern bool_t xdr_remote_domain_detach_device_flags_args (XDR *, remote_domain_detach_device_flags_args*); +extern bool_t xdr_remote_domain_update_device_flags_args (XDR *, remote_domain_update_device_flags_args*); extern bool_t xdr_remote_domain_get_autostart_args (XDR *, remote_domain_get_autostart_args*); extern bool_t xdr_remote_domain_get_autostart_ret (XDR *, remote_domain_get_autostart_ret*); extern bool_t xdr_remote_domain_set_autostart_args (XDR *, remote_domain_set_autostart_args*); @@ -2313,6 +2322,7 @@ extern bool_t xdr_remote_domain_attach_device_args (); extern bool_t xdr_remote_domain_attach_device_flags_args (); extern bool_t xdr_remote_domain_detach_device_args (); extern bool_t xdr_remote_domain_detach_device_flags_args (); +extern bool_t xdr_remote_domain_update_device_flags_args (); extern bool_t xdr_remote_domain_get_autostart_args (); extern bool_t xdr_remote_domain_get_autostart_ret (); extern bool_t xdr_remote_domain_set_autostart_args (); diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 1633908..def6c9e 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -730,6 +730,12 @@ struct remote_domain_detach_device_flags_args { unsigned int flags; }; +struct remote_domain_update_device_flags_args { + remote_nonnull_domain dom; + remote_nonnull_string xml; + unsigned int flags; +}; + struct remote_domain_get_autostart_args { remote_nonnull_domain dom; }; @@ -1717,7 +1723,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_JOB_INFO = 163, REMOTE_PROC_DOMAIN_ABORT_JOB = 164, REMOTE_PROC_STORAGE_VOL_WIPE = 165, - REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_DOWNTIME = 166 + REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_DOWNTIME = 166, + REMOTE_PROC_DOMAIN_UPDATE_DEVICE_FLAGS = 167 /* * Notice how the entries are grouped in sets of 10 ? -- 1.6.6.1

On Wed, Mar 24, 2010 at 11:46:23AM +0000, Daniel P. Berrange wrote:
This defines the wire format for the new virDomainUpdateDeviceFlags() API, and implements the server & client side of the marshalling code.
* daemon/remote.c: Server side dispatch for virDomainUpdateDeviceFlags * src/remote/remote_driver.c: Client side serialization for virDomainUpdateDeviceFlags * src/remote/remote_protocol.x: Define wire format for virDomainUpdateDeviceFlags * daemon/remote_dispatch_args.h, daemon/remote_dispatch_prototypes.h, daemon/remote_dispatch_table.h, src/remote/remote_protocol.c, src/remote/remote_protocol.h: Re-generate code
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/

To allow the new virDomainUpdateDeviceFlags() API to be universally used with all drivers, this patch adds an impl to all the current drivers which support CDROM or Floppy disk media change via the current virDomainAttachDeviceFlags API * src/qemu/qemu_driver.c, src/vbox/vbox_tmpl.c, src/xen/proxy_internal.c, src/xen/xen_driver.c, src/xen/xend_internal.c: Implement media change via the virDomainUpdateDeviceFlags API * src/xen/xen_driver.h, src/xen/xen_hypervisor.c, src/xen/xen_inotify.c, src/xen/xm_internal.c, src/xen/xs_internal.c: Stubs for Xen driver entry points --- src/qemu/qemu_driver.c | 117 +++++++++++++++++++++++++++++++++++++++++- src/vbox/vbox_tmpl.c | 23 +++++++- src/xen/proxy_internal.c | 1 + src/xen/xen_driver.c | 17 ++++++- src/xen/xen_driver.h | 1 + src/xen/xen_hypervisor.c | 1 + src/xen/xen_inotify.c | 1 + src/xen/xend_internal.c | 130 +++++++++++++++++++++++++++++++++++++++++++--- src/xen/xm_internal.c | 1 + src/xen/xs_internal.c | 1 + 10 files changed, 280 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index caa6442..b9cfae0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6819,6 +6819,121 @@ static int qemudDomainAttachDeviceFlags(virDomainPtr dom, return qemudDomainAttachDevice(dom, xml); } + +static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, + const char *xml, + unsigned int flags) +{ + struct qemud_driver *driver = dom->conn->privateData; + virDomainObjPtr vm; + virDomainDeviceDefPtr dev = NULL; + unsigned long long qemuCmdFlags; + virCgroupPtr cgroup = NULL; + int ret = -1; + + if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { + qemuReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("cannot modify the persistent configuration of a domain")); + return -1; + } + + qemuDriverLock(driver); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + if (!vm) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(dom->uuid, uuidstr); + qemuReportError(VIR_ERR_NO_DOMAIN, + _("no domain with matching uuid '%s'"), uuidstr); + goto cleanup; + } + + if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) + goto cleanup; + + if (!virDomainObjIsActive(vm)) { + qemuReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("cannot attach device on inactive domain")); + goto endjob; + } + + dev = virDomainDeviceDefParse(driver->caps, vm->def, xml, + VIR_DOMAIN_XML_INACTIVE); + if (dev == NULL) + goto endjob; + + if (qemudExtractVersionInfo(vm->def->emulator, + NULL, + &qemuCmdFlags) < 0) + goto endjob; + + switch (dev->type) { + case VIR_DOMAIN_DEVICE_DISK: + if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { + if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) !=0 ) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to find cgroup for %s\n"), + vm->def->name); + goto endjob; + } + if (dev->data.disk->src != NULL && + dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK && + virCgroupAllowDevicePath(cgroup, + dev->data.disk->src) < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("unable to allow device %s"), + dev->data.disk->src); + goto endjob; + } + } + + switch (dev->data.disk->device) { + case VIR_DOMAIN_DISK_DEVICE_CDROM: + case VIR_DOMAIN_DISK_DEVICE_FLOPPY: + ret = qemudDomainChangeEjectableMedia(driver, vm, dev->data.disk); + if (ret == 0) + dev->data.disk = NULL; + break; + + + default: + qemuReportError(VIR_ERR_NO_SUPPORT, + _("disk bus '%s' cannot be updated."), + virDomainDiskBusTypeToString(dev->data.disk->bus)); + break; + } + + if (ret != 0 && cgroup) { + virCgroupDenyDevicePath(cgroup, + dev->data.disk->src); + } + break; + + default: + qemuReportError(VIR_ERR_NO_SUPPORT, + _("disk device type '%s' cannot be updated"), + virDomainDiskDeviceTypeToString(dev->data.disk->device)); + break; + } + + if (!ret && virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) + ret = -1; + +endjob: + if (qemuDomainObjEndJob(vm) == 0) + vm = NULL; + +cleanup: + if (cgroup) + virCgroupFree(&cgroup); + + virDomainDeviceDefFree(dev); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} + + static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev, @@ -9644,7 +9759,7 @@ static virDriver qemuDriver = { qemudDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ qemudDomainDetachDevice, /* domainDetachDevice */ qemudDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ - NULL, /* domainUpdateDeviceFlags */ + qemuDomainUpdateDeviceFlags, /* domainUpdateDeviceFlags */ qemudDomainGetAutostart, /* domainGetAutostart */ qemudDomainSetAutostart, /* domainSetAutostart */ qemuGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index f398041..9bd1f49 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -4638,7 +4638,9 @@ cleanup: return ret; } -static int vboxDomainAttachDevice(virDomainPtr dom, const char *xml) { +static int vboxDomainAttachDeviceImpl(virDomainPtr dom, + const char *xml, + int mediaChangeOnly ATTRIBUTE_UNUSED) { VBOX_OBJECT_CHECK(dom->conn, int, -1); IMachine *machine = NULL; vboxIID *iid = NULL; @@ -4836,6 +4838,10 @@ cleanup: return ret; } +static int vboxDomainAttachDevice(virDomainPtr dom, const char *xml) { + return vboxDomainAttachDeviceImpl(dom, xml, 0); +} + static int vboxDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) { if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { @@ -4844,7 +4850,18 @@ static int vboxDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, return -1; } - return vboxDomainAttachDevice(dom, xml); + return vboxDomainAttachDeviceImpl(dom, xml, 0); +} + +static int vboxDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml, + unsigned int flags) { + if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { + vboxError(dom->conn, VIR_ERR_OPERATION_INVALID, "%s", + _("cannot modify the persistent configuration of a domain")); + return -1; + } + + return vboxDomainAttachDeviceImpl(dom, xml, 1); } static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) { @@ -7030,7 +7047,7 @@ virDriver NAME(Driver) = { vboxDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ vboxDomainDetachDevice, /* domainDetachDevice */ vboxDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ - NULL, /* domainUpdateDeviceFlags */ + vboxDomainUpdateDeviceFlags, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/xen/proxy_internal.c b/src/xen/proxy_internal.c index 0c00abc..26eec13 100644 --- a/src/xen/proxy_internal.c +++ b/src/xen/proxy_internal.c @@ -78,6 +78,7 @@ struct xenUnifiedDriver xenProxyDriver = { NULL, /* domainUndefine */ NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 1ff3e44..4386693 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1489,6 +1489,21 @@ xenUnifiedDomainDetachDeviceFlags (virDomainPtr dom, const char *xml, } static int +xenUnifiedDomainUpdateDeviceFlags (virDomainPtr dom, const char *xml, + unsigned int flags) +{ + GET_PRIVATE(dom->conn); + int i; + + for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) + if (priv->opened[i] && drivers[i]->domainUpdateDeviceFlags && + drivers[i]->domainUpdateDeviceFlags(dom, xml, flags) == 0) + return 0; + + return -1; +} + +static int xenUnifiedDomainGetAutostart (virDomainPtr dom, int *autostart) { GET_PRIVATE(dom->conn); @@ -1875,7 +1890,7 @@ static virDriver xenUnifiedDriver = { xenUnifiedDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ xenUnifiedDomainDetachDevice, /* domainDetachDevice */ xenUnifiedDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ - NULL, /* domainUpdateDeviceFlags */ + xenUnifiedDomainUpdateDeviceFlags, /* domainUpdateDeviceFlags */ xenUnifiedDomainGetAutostart, /* domainGetAutostart */ xenUnifiedDomainSetAutostart, /* domainSetAutostart */ xenUnifiedDomainGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h index 590777c..3e7c1d0 100644 --- a/src/xen/xen_driver.h +++ b/src/xen/xen_driver.h @@ -95,6 +95,7 @@ struct xenUnifiedDriver { virDrvDomainUndefine domainUndefine; virDrvDomainAttachDeviceFlags domainAttachDeviceFlags; virDrvDomainDetachDeviceFlags domainDetachDeviceFlags; + virDrvDomainUpdateDeviceFlags domainUpdateDeviceFlags; virDrvDomainGetAutostart domainGetAutostart; virDrvDomainSetAutostart domainSetAutostart; virDrvDomainGetSchedulerType domainGetSchedulerType; diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 4af3dba..552fbf5 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -795,6 +795,7 @@ struct xenUnifiedDriver xenHypervisorDriver = { NULL, /* domainUndefine */ NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ xenHypervisorGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c index ee24bc4..8ff3256 100644 --- a/src/xen/xen_inotify.c +++ b/src/xen/xen_inotify.c @@ -82,6 +82,7 @@ struct xenUnifiedDriver xenInotifyDriver = { NULL, /* domainUndefine */ NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 85ae2a1..87c26e5 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -4128,7 +4128,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml, if (priv->xendConfigVersion < 3) { virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", _("Xend version does not support modifying " - "persisted config")); + "persistent config")); return -1; } /* Cannot modify live config if domain is inactive */ @@ -4144,17 +4144,17 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml, flags != VIR_DOMAIN_DEVICE_MODIFY_LIVE)) { virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", _("Xend version does not support modifying " - "persisted config")); + "persistent config")); return -1; } - /* Xen only supports modifying both live and persisted config if + /* Xen only supports modifying both live and persistent config if * xendConfigVersion >= 3 */ if (flags != (VIR_DOMAIN_DEVICE_MODIFY_LIVE | VIR_DOMAIN_DEVICE_MODIFY_CONFIG)) { virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", _("Xend only supports modifying both live and " - "persisted config")); + "persistent config")); return -1; } } @@ -4230,6 +4230,119 @@ cleanup: } /** + * xenDaemonUpdateDeviceFlags: + * @domain: pointer to domain object + * @xml: pointer to XML description of device + * @flags: an OR'ed set of virDomainDeviceModifyFlags + * + * Create a virtual device attachment to backend. + * XML description is translated into S-expression. + * + * Returns 0 in case of success, -1 in case of failure. + */ +static int +xenDaemonUpdateDeviceFlags(virDomainPtr domain, const char *xml, + unsigned int flags) +{ + xenUnifiedPrivatePtr priv; + char *sexpr = NULL; + int ret = -1; + virDomainDeviceDefPtr dev = NULL; + virDomainDefPtr def = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + char class[8], ref[80]; + + if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { + virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, + __FUNCTION__); + return -1; + } + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; + + if (domain->id < 0) { + /* If xendConfigVersion < 3 only live config can be changed */ + if (priv->xendConfigVersion < 3) { + virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", + _("Xend version does not support modifying " + "persistent config")); + return -1; + } + /* Cannot modify live config if domain is inactive */ + if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { + virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", + _("Cannot modify live config if domain is inactive")); + return -1; + } + } else { + /* Only live config can be changed if xendConfigVersion < 3 */ + if (priv->xendConfigVersion < 3 && + (flags != VIR_DOMAIN_DEVICE_MODIFY_CURRENT || + flags != VIR_DOMAIN_DEVICE_MODIFY_LIVE)) { + virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", + _("Xend version does not support modifying " + "persistent config")); + return -1; + } + /* Xen only supports modifying both live and persistent config if + * xendConfigVersion >= 3 + */ + if (flags != (VIR_DOMAIN_DEVICE_MODIFY_LIVE | + VIR_DOMAIN_DEVICE_MODIFY_CONFIG)) { + virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", + _("Xend only supports modifying both live and " + "persistent config")); + return -1; + } + } + + if (!(def = xenDaemonDomainFetch(domain->conn, + domain->id, + domain->name, + NULL))) + goto cleanup; + + if (!(dev = virDomainDeviceDefParse(priv->caps, + def, xml, VIR_DOMAIN_XML_INACTIVE))) + goto cleanup; + + + switch (dev->type) { + case VIR_DOMAIN_DEVICE_DISK: + if (xenDaemonFormatSxprDisk(domain->conn, + dev->data.disk, + &buf, + STREQ(def->os.type, "hvm") ? 1 : 0, + priv->xendConfigVersion, 1) < 0) + goto cleanup; + break; + + default: + virXendError(domain->conn, VIR_ERR_NO_SUPPORT, "%s", + _("unsupported device type")); + goto cleanup; + } + + sexpr = virBufferContentAndReset(&buf); + + if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) { + virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", + _("requested device does not exist")); + goto cleanup; + } else { + /* device exists, attempt to modify it */ + ret = xend_op(domain->conn, domain->name, "op", "device_configure", + "config", sexpr, "dev", ref, NULL); + } + +cleanup: + VIR_FREE(sexpr); + virDomainDefFree(def); + virDomainDeviceDefFree(dev); + return ret; +} + +/** * xenDaemonDetachDeviceFlags: * @domain: pointer to domain object * @xml: pointer to XML description of device @@ -4264,7 +4377,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, const char *xml, if (priv->xendConfigVersion < 3) { virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", _("Xend version does not support modifying " - "persisted config")); + "persistent config")); return -1; } /* Cannot modify live config if domain is inactive */ @@ -4280,17 +4393,17 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, const char *xml, flags != VIR_DOMAIN_DEVICE_MODIFY_LIVE)) { virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", _("Xend version does not support modifying " - "persisted config")); + "persistent config")); return -1; } - /* Xen only supports modifying both live and persisted config if + /* Xen only supports modifying both live and persistent config if * xendConfigVersion >= 3 */ if (flags != (VIR_DOMAIN_DEVICE_MODIFY_LIVE | VIR_DOMAIN_DEVICE_MODIFY_CONFIG)) { virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, "%s", _("Xend only supports modifying both live and " - "persisted config")); + "persistent config")); return -1; } } @@ -5224,6 +5337,7 @@ struct xenUnifiedDriver xenDaemonDriver = { xenDaemonDomainUndefine, /* domainUndefine */ xenDaemonAttachDeviceFlags, /* domainAttachDeviceFlags */ xenDaemonDetachDeviceFlags, /* domainDetachDeviceFlags */ + xenDaemonUpdateDeviceFlags, /* domainUpdateDeviceFlags */ xenDaemonDomainGetAutostart, /* domainGetAutostart */ xenDaemonDomainSetAutostart, /* domainSetAutostart */ xenDaemonGetSchedulerType, /* domainGetSchedulerType */ diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 74bf0b6..ddbd2fe 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -113,6 +113,7 @@ struct xenUnifiedDriver xenXMDriver = { xenXMDomainUndefine, /* domainUndefine */ xenXMDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ xenXMDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c index 3b241c7..613f97a 100644 --- a/src/xen/xs_internal.c +++ b/src/xen/xs_internal.c @@ -78,6 +78,7 @@ struct xenUnifiedDriver xenStoreDriver = { NULL, /* domainUndefine */ NULL, /* domainAttachDeviceFlags */ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainUpdateDeviceFlags */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ -- 1.6.6.1

On Wed, Mar 24, 2010 at 11:46:24AM +0000, Daniel P. Berrange wrote:
To allow the new virDomainUpdateDeviceFlags() API to be universally used with all drivers, this patch adds an impl to all the current drivers which support CDROM or Floppy disk media change via the current virDomainAttachDeviceFlags API
* src/qemu/qemu_driver.c, src/vbox/vbox_tmpl.c, src/xen/proxy_internal.c, src/xen/xen_driver.c, src/xen/xend_internal.c: Implement media change via the virDomainUpdateDeviceFlags API * src/xen/xen_driver.h, src/xen/xen_hypervisor.c, src/xen/xen_inotify.c, src/xen/xm_internal.c, src/xen/xs_internal.c: Stubs for Xen driver entry points [...] +static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, + const char *xml, + unsigned int flags) +{ [...] + switch (dev->data.disk->device) { + case VIR_DOMAIN_DISK_DEVICE_CDROM: + case VIR_DOMAIN_DISK_DEVICE_FLOPPY: + ret = qemudDomainChangeEjectableMedia(driver, vm, dev->data.disk); + if (ret == 0) + dev->data.disk = NULL; + break; + + + default: + qemuReportError(VIR_ERR_NO_SUPPORT, + _("disk bus '%s' cannot be updated."), + virDomainDiskBusTypeToString(dev->data.disk->bus)); + break; + } + + if (ret != 0 && cgroup) { + virCgroupDenyDevicePath(cgroup, + dev->data.disk->src); + }
Hum ... I got a bit lost there, qemudDomainChangeEjectableMedia only returns -1 on error or 0 on success. But failure to change may mean that the previous data is still being used, shouldn't we check that the old and new data.disk->src are different before denying access ? But it's a minor question, 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/

On Thu, Mar 25, 2010 at 11:47:33AM +0100, Daniel Veillard wrote:
On Wed, Mar 24, 2010 at 11:46:24AM +0000, Daniel P. Berrange wrote:
To allow the new virDomainUpdateDeviceFlags() API to be universally used with all drivers, this patch adds an impl to all the current drivers which support CDROM or Floppy disk media change via the current virDomainAttachDeviceFlags API
* src/qemu/qemu_driver.c, src/vbox/vbox_tmpl.c, src/xen/proxy_internal.c, src/xen/xen_driver.c, src/xen/xend_internal.c: Implement media change via the virDomainUpdateDeviceFlags API * src/xen/xen_driver.h, src/xen/xen_hypervisor.c, src/xen/xen_inotify.c, src/xen/xm_internal.c, src/xen/xs_internal.c: Stubs for Xen driver entry points [...] +static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, + const char *xml, + unsigned int flags) +{ [...] + switch (dev->data.disk->device) { + case VIR_DOMAIN_DISK_DEVICE_CDROM: + case VIR_DOMAIN_DISK_DEVICE_FLOPPY: + ret = qemudDomainChangeEjectableMedia(driver, vm, dev->data.disk); + if (ret == 0) + dev->data.disk = NULL; + break; + + + default: + qemuReportError(VIR_ERR_NO_SUPPORT, + _("disk bus '%s' cannot be updated."), + virDomainDiskBusTypeToString(dev->data.disk->bus)); + break; + } + + if (ret != 0 && cgroup) { + virCgroupDenyDevicePath(cgroup, + dev->data.disk->src); + }
Hum ... I got a bit lost there, qemudDomainChangeEjectableMedia only returns -1 on error or 0 on success. But failure to change may mean that the previous data is still being used, shouldn't we check that the old and new data.disk->src are different before denying access ?
Oh, interesting - this code was only ever about reverting the ACL on the new media, upon failure. There is n code anywhere that rverts the ACL on the old media - this is broken in the existing change media method too. So I should fix both of them with another patch. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Support the new virDomainUpdateDeviceFlags API in virsh by adding a new 'update-device' command. In the future this should be augmented with an explicit 'change-disk' command for media change to make it end user discoverable, as attach-disk is. * tools/virsh.c: Add 'update-device' command --- tools/virsh.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 68 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 32895b2..35bdbf1 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -6677,6 +6677,73 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd) /* + * "update-device" command + */ +static const vshCmdInfo info_update_device[] = { + {"help", N_("update device from an XML file")}, + {"desc", N_("Update device from an XML <file>.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_update_device[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("XML file")}, + {"persistent", VSH_OT_BOOL, 0, N_("persist device update")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdUpdateDevice(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + char *from; + char *buffer; + int ret = TRUE; + int found; + unsigned int flags; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return FALSE; + + from = vshCommandOptString(cmd, "file", &found); + if (!found) { + vshError(ctl, "%s", _("update-device: Missing <file> option")); + virDomainFree(dom); + return FALSE; + } + + if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) { + virDomainFree(dom); + return FALSE; + } + + if (vshCommandOptBool(cmd, "persistent")) { + flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; + if (virDomainIsActive(dom) == 1) + flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; + } else { + flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE; + } + ret = virDomainUpdateDeviceFlags(dom, buffer, flags); + VIR_FREE(buffer); + + if (ret < 0) { + vshError(ctl, _("Failed to update device from %s"), from); + virDomainFree(dom); + return FALSE; + } else { + vshPrint(ctl, "%s", _("Device updated successfully\n")); + } + + virDomainFree(dom); + return TRUE; +} + + +/* * "attach-interface" command */ static const vshCmdInfo info_attach_interface[] = { @@ -7891,6 +7958,7 @@ static const vshCmdDef commands[] = { {"suspend", cmdSuspend, opts_suspend, info_suspend}, {"ttyconsole", cmdTTYConsole, opts_ttyconsole, info_ttyconsole}, {"undefine", cmdUndefine, opts_undefine, info_undefine}, + {"update-device", cmdUpdateDevice, opts_update_device, info_update_device}, {"uri", cmdURI, NULL, info_uri}, {"vol-create", cmdVolCreate, opts_vol_create, info_vol_create}, -- 1.6.6.1

On Wed, Mar 24, 2010 at 11:46:25AM +0000, Daniel P. Berrange wrote:
Support the new virDomainUpdateDeviceFlags API in virsh by adding a new 'update-device' command. In the future this should be augmented with an explicit 'change-disk' command for media change to make it end user discoverable, as attach-disk is.
Yeah 'change-disk' would be more convenient, but that's sufficient for using the new code path, 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/

Expand the parser for the standalone <device> XML format to allow inclusion of the <graphics> device type * src/conf/domain_conf.h: Add virDomainGraphicsDef to the virDomainDeviceDef struct * src/conf/domain_conf.c: Wire up parser for virDomainGraphicsDef to virDomainDeviceDefParse method --- src/conf/domain_conf.c | 10 +++++++++- src/conf/domain_conf.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 22e1679..a350b41 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -88,7 +88,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, "video", "hostdev", "watchdog", - "controller") + "controller", + "graphics") VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "none", @@ -575,6 +576,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def) case VIR_DOMAIN_DEVICE_CONTROLLER: virDomainControllerDefFree(def->data.controller); break; + case VIR_DOMAIN_DEVICE_GRAPHICS: + virDomainGraphicsDefFree(def->data.graphics); + break; } VIR_FREE(def); @@ -3300,6 +3304,10 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps, dev->type = VIR_DOMAIN_DEVICE_CONTROLLER; if (!(dev->data.controller = virDomainControllerDefParseXML(node, flags))) goto error; + } else if (xmlStrEqual(node->name, BAD_CAST "graphics")) { + dev->type = VIR_DOMAIN_DEVICE_GRAPHICS; + if (!(dev->data.graphics = virDomainGraphicsDefParseXML(node, flags))) + goto error; } else { virDomainReportError(VIR_ERR_XML_ERROR, "%s", _("unknown device type")); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 44fff0c..efd5db6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -544,6 +544,7 @@ enum virDomainDeviceType { VIR_DOMAIN_DEVICE_HOSTDEV, VIR_DOMAIN_DEVICE_WATCHDOG, VIR_DOMAIN_DEVICE_CONTROLLER, + VIR_DOMAIN_DEVICE_GRAPHICS, VIR_DOMAIN_DEVICE_LAST, }; @@ -562,6 +563,7 @@ struct _virDomainDeviceDef { virDomainVideoDefPtr video; virDomainHostdevDefPtr hostdev; virDomainWatchdogDefPtr watchdog; + virDomainGraphicsDefPtr graphics; } data; }; -- 1.6.6.1

On Wed, Mar 24, 2010 at 11:46:26AM +0000, Daniel P. Berrange wrote:
Expand the parser for the standalone <device> XML format to allow inclusion of the <graphics> device type
* src/conf/domain_conf.h: Add virDomainGraphicsDef to the virDomainDeviceDef struct * src/conf/domain_conf.c: Wire up parser for virDomainGraphicsDef to virDomainDeviceDefParse method
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/

Use the new virDomainUpdateDeviceFlags API to allow the VNC password to be changed on the fly * src/internal.h: Define STREQ_NULLABLE() which is like STREQ() but does not crash if either argument is NULL, and treats two NULLs as equal. * src/libvirt_private.syms: Export virDomainGraphicsTypeToString * src/qemu/qemu_driver.c: Support VNC password change on a live machine * src/qemu/qemu_monitor.c: Disable crazy debugging info. Treat a NULL password as "" (empty string), allowing passwords to be disabled in the monitor --- src/internal.h | 6 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 17 ++++++++- 4 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/internal.h b/src/internal.h index 4ec6edc..f82fbd2 100644 --- a/src/internal.h +++ b/src/internal.h @@ -58,6 +58,12 @@ # define STRCASENEQLEN(a,b,n) (strncasecmp(a,b,n) != 0) # define STRPREFIX(a,b) (strncmp(a,b,strlen(b)) == 0) +# define STREQ_NULLABLE(a, b) \ + ((!(a) && !(b)) || ((a) && (b) && STREQ((a), (b)))) +# define STRNEQ_NULLABLE(a, b) \ + ((!(a) ^ !(b)) || ((a) && (b) && STRNEQ((a), (b)))) + + # define NUL_TERMINATE(buf) do { (buf)[sizeof(buf)-1] = '\0'; } while (0) # define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f1ad6db..fe78743 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -139,6 +139,7 @@ virDomainFindByName; virDomainFindByUUID; virDomainGetRootFilesystem; virDomainGraphicsTypeFromString; +virDomainGraphicsTypeToString; virDomainGraphicsDefFree; virDomainHostdevDefFree; virDomainHostdevModeTypeToString; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b9cfae0..57fb941 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6820,6 +6820,83 @@ static int qemudDomainAttachDeviceFlags(virDomainPtr dom, } +static virDomainGraphicsDefPtr qemuDomainFindGraphics(virDomainObjPtr vm, + virDomainGraphicsDefPtr dev) +{ + int i; + + for (i = 0 ; i < vm->def->ngraphics ; i++) { + if (vm->def->graphics[i]->type == dev->type) + return vm->def->graphics[i]; + } + + return NULL; +} + + +static int +qemuDomainChangeGraphics(struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainGraphicsDefPtr dev) +{ + virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev); + qemuDomainObjPrivatePtr priv = vm->privateData; + int ret = -1; + + if (!olddev) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot find existing graphics device to modify")); + return -1; + } + + switch (dev->type) { + case VIR_DOMAIN_GRAPHICS_TYPE_VNC: + if ((olddev->data.vnc.autoport != dev->data.vnc.autoport) || + (!dev->data.vnc.autoport && (olddev->data.vnc.port != dev->data.vnc.port))) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot change port settings on vnc graphics")); + return -1; + } + if (STRNEQ_NULLABLE(olddev->data.vnc.listenAddr, dev->data.vnc.listenAddr)) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot change listen address setting on vnc graphics")); + return -1; + } + if (STRNEQ_NULLABLE(olddev->data.vnc.keymap, dev->data.vnc.keymap)) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot change keymap setting on vnc graphics")); + return -1; + } + + if (STRNEQ_NULLABLE(olddev->data.vnc.passwd, dev->data.vnc.passwd)) { + VIR_DEBUG("Updating password on VNC server %p %p", dev->data.vnc.passwd, driver->vncPassword); + qemuDomainObjEnterMonitorWithDriver(driver, vm); + ret = qemuMonitorSetVNCPassword(priv->mon, + dev->data.vnc.passwd ? + dev->data.vnc.passwd : + driver->vncPassword); + qemuDomainObjExitMonitorWithDriver(driver, vm); + + /* Steal the new dev's char * reference */ + VIR_FREE(olddev->data.vnc.passwd); + olddev->data.vnc.passwd = dev->data.vnc.passwd; + dev->data.vnc.passwd = NULL; + } else { + ret = 0; + } + break; + + default: + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("unable to change config on '%s' graphics type"), + virDomainGraphicsTypeToString(dev->type)); + break; + } + + return ret; +} + + static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) @@ -6908,6 +6985,10 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, } break; + case VIR_DOMAIN_DEVICE_GRAPHICS: + ret = qemuDomainChangeGraphics(driver, vm, dev->data.graphics); + break; + default: qemuReportError(VIR_ERR_NO_SUPPORT, _("disk device type '%s' cannot be updated"), diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 6b68db8..fe95afd 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -39,7 +39,8 @@ #define VIR_FROM_THIS VIR_FROM_QEMU -#define QEMU_DEBUG_RAW_IO 0 +#define DEBUG_IO 0 +#define DEBUG_RAW_IO 0 struct _qemuMonitor { virMutex lock; @@ -302,7 +303,8 @@ qemuMonitorIOProcess(qemuMonitorPtr mon) if (mon->msg && mon->msg->txOffset == mon->msg->txLength) msg = mon->msg; -#if QEMU_DEBUG_RAW_IO +#if DEBUG_IO +#if DEBUG_RAW_IO char *str1 = qemuMonitorEscapeNonPrintable(msg ? msg->txBuffer : ""); char *str2 = qemuMonitorEscapeNonPrintable(mon->buffer); VIR_ERROR("Process %d %p %p [[[[%s]]][[[%s]]]", (int)mon->bufferOffset, mon->msg, msg, str1, str2); @@ -311,6 +313,8 @@ qemuMonitorIOProcess(qemuMonitorPtr mon) #else VIR_DEBUG("Process %d", (int)mon->bufferOffset); #endif +#endif + if (mon->json) len = qemuMonitorJSONIOProcess(mon, mon->buffer, mon->bufferOffset, @@ -332,7 +336,9 @@ qemuMonitorIOProcess(qemuMonitorPtr mon) VIR_FREE(mon->buffer); mon->bufferOffset = mon->bufferLength = 0; } +#if DEBUG_IO VIR_DEBUG("Process done %d used %d", (int)mon->bufferOffset, len); +#endif if (msg && msg->finished) virCondBroadcast(&mon->notify); return len; @@ -455,7 +461,9 @@ qemuMonitorIORead(qemuMonitorPtr mon) mon->buffer[mon->bufferOffset] = '\0'; } +#if DEBUG_IO VIR_DEBUG("Now read %d bytes of data", (int)mon->bufferOffset); +#endif return ret; } @@ -485,7 +493,9 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { qemuMonitorLock(mon); qemuMonitorRef(mon); +#if DEBUG_IO VIR_DEBUG("Monitor %p I/O on watch %d fd %d events %d", mon, watch, fd, events); +#endif if (mon->fd != fd || mon->watch != watch) { VIR_ERROR("event from unexpected fd %d!=%d / watch %d!=%d", mon->fd, fd, mon->watch, watch); @@ -904,6 +914,9 @@ int qemuMonitorSetVNCPassword(qemuMonitorPtr mon, int ret; DEBUG("mon=%p, fd=%d", mon, mon->fd); + if (!password) + password = ""; + if (mon->json) ret = qemuMonitorJSONSetVNCPassword(mon, password); else -- 1.6.6.1

On Wed, Mar 24, 2010 at 11:46:27AM +0000, Daniel P. Berrange wrote:
Use the new virDomainUpdateDeviceFlags API to allow the VNC password to be changed on the fly
* src/internal.h: Define STREQ_NULLABLE() which is like STREQ() but does not crash if either argument is NULL, and treats two NULLs as equal. * src/libvirt_private.syms: Export virDomainGraphicsTypeToString * src/qemu/qemu_driver.c: Support VNC password change on a live machine * src/qemu/qemu_monitor.c: Disable crazy debugging info. Treat a NULL password as "" (empty string), allowing passwords to be disabled in the monitor --- src/internal.h | 6 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 17 ++++++++- 4 files changed, 103 insertions(+), 2 deletions(-)
diff --git a/src/internal.h b/src/internal.h index 4ec6edc..f82fbd2 100644 --- a/src/internal.h +++ b/src/internal.h @@ -58,6 +58,12 @@ # define STRCASENEQLEN(a,b,n) (strncasecmp(a,b,n) != 0) # define STRPREFIX(a,b) (strncmp(a,b,strlen(b)) == 0)
+# define STREQ_NULLABLE(a, b) \ + ((!(a) && !(b)) || ((a) && (b) && STREQ((a), (b)))) +# define STRNEQ_NULLABLE(a, b) \ + ((!(a) ^ !(b)) || ((a) && (b) && STRNEQ((a), (b)))) +
Not sure I can parse that, I would assume it's equivalent to: (!(STREQ_NULLABLE((a), (b)))) which would be simpler IMHO [...]
+static virDomainGraphicsDefPtr qemuDomainFindGraphics(virDomainObjPtr vm, + virDomainGraphicsDefPtr dev) +{ + int i; + + for (i = 0 ; i < vm->def->ngraphics ; i++) { + if (vm->def->graphics[i]->type == dev->type) + return vm->def->graphics[i]; + } + + return NULL; +}
it's a bit surprizing to match just on the type, what if we somehow add dual graphic support for a given type ?
+ [...]
-#if QEMU_DEBUG_RAW_IO +#if DEBUG_IO +#if DEBUG_RAW_IO char *str1 = qemuMonitorEscapeNonPrintable(msg ? msg->txBuffer : ""); char *str2 = qemuMonitorEscapeNonPrintable(mon->buffer); VIR_ERROR("Process %d %p %p [[[[%s]]][[[%s]]]", (int)mon->bufferOffset, mon->msg, msg, str1, str2); @@ -311,6 +313,8 @@ qemuMonitorIOProcess(qemuMonitorPtr mon) #else VIR_DEBUG("Process %d", (int)mon->bufferOffset); #endif +#endif +
hum, somehow I feel it's gonna break cppi indenting isn't it ? but it's minor, 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/
participants (3)
-
Daniel P. Berrange
-
Daniel Veillard
-
Eric Blake