diff --git a/detach-disk.patch b/detach-disk.patch deleted file mode 100644 index 5ae9775..0000000 --- a/detach-disk.patch +++ /dev/null @@ -1,64 +0,0 @@ -Index: libvirt-0.7.5/src/xen/xend_internal.c -=================================================================== ---- libvirt-0.7.5.orig/src/xen/xend_internal.c -+++ libvirt-0.7.5/src/xen/xend_internal.c -@@ -4123,13 +4123,12 @@ xenDaemonAttachDevice(virDomainPtr domai - - priv = (xenUnifiedPrivatePtr) domain->conn->privateData; - -- /* -- * on older Xen without the inactive guests management -- * avoid doing this on inactive guests -- */ -- if ((domain->id < 0) && (priv->xendConfigVersion < 3)) -+ if (domain->id < 0) { -+ virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, -+ "%s", _("cannot attach device on inactive domain")); - return -1; -- -+ } -+ - if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, -@@ -4229,12 +4228,11 @@ xenDaemonDetachDevice(virDomainPtr domai - - priv = (xenUnifiedPrivatePtr) domain->conn->privateData; - -- /* -- * on older Xen without the inactive guests management -- * avoid doing this on inactive guests -- */ -- if ((domain->id < 0) && (priv->xendConfigVersion < 3)) -+ if (domain->id < 0) { -+ virXendError(domain->conn, VIR_ERR_OPERATION_INVALID, -+ "%s", _("cannot detach device on inactive domain")); - return -1; -+ } - - if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, -Index: libvirt-0.7.5/src/libvirt.c -=================================================================== ---- libvirt-0.7.5.orig/src/libvirt.c -+++ libvirt-0.7.5/src/libvirt.c -@@ -5066,7 +5066,8 @@ error: - * @domain: pointer to domain object - * @xml: pointer to XML description of one device - * -- * Create a virtual device attachment to backend. -+ * Create a virtual device attachment to backend. This function, having -+ * hotplug semantics, is only allowed on an active domain. - * - * Returns 0 in case of success, -1 in case of failure. - */ -@@ -5109,7 +5110,8 @@ error: - * @domain: pointer to domain object - * @xml: pointer to XML description of one device - * -- * Destroy a virtual device attachment to backend. -+ * Destroy a virtual device attachment to backend. This function, having -+ * hot-unplug semantics, is only allowed on an active domain. - * - * Returns 0 in case of success, -1 in case of failure. - */ diff --git a/devflag-01.patch b/devflag-01.patch new file mode 100644 index 0000000..50a084a --- /dev/null +++ b/devflag-01.patch @@ -0,0 +1,37 @@ +commit d8ec244c6513b7c44956a547e56c228a4c38fbbe +Author: Jim Fehlig +Date: Wed Jan 13 18:24:51 2010 -0700 + + doc: restrict virDomain{Attach,Detach}Device to active domains + + virDomain{Attach,Detach}Device is now only permitted on active + domains. Explicitly state this restriction in the API + documentation. + + V2: Only change doc, dropping the hunk that forced the restriction + in libvirt frontend. + +Index: libvirt-0.7.5/src/libvirt.c +=================================================================== +--- libvirt-0.7.5.orig/src/libvirt.c ++++ libvirt-0.7.5/src/libvirt.c +@@ -5066,7 +5066,8 @@ error: + * @domain: pointer to domain object + * @xml: pointer to XML description of one device + * +- * Create a virtual device attachment to backend. ++ * Create a virtual device attachment to backend. This function, ++ * having hotplug semantics, is only allowed on an active domain. + * + * Returns 0 in case of success, -1 in case of failure. + */ +@@ -5109,7 +5110,8 @@ error: + * @domain: pointer to domain object + * @xml: pointer to XML description of one device + * +- * Destroy a virtual device attachment to backend. ++ * Destroy a virtual device attachment to backend. This function, ++ * having hot-unplug semantics, is only allowed on an active domain. + * + * Returns 0 in case of success, -1 in case of failure. + */ diff --git a/devflag-02.patch b/devflag-02.patch new file mode 100644 index 0000000..e2a72b9 --- /dev/null +++ b/devflag-02.patch @@ -0,0 +1,50 @@ +commit 7269ec07ba4f298adab64ea66ac528ef66cf9ba0 +Author: Jim Fehlig +Date: Wed Jan 13 18:29:16 2010 -0700 + + Public API + + Definition of public API for virDomain{Attach,Detach}DeviceFlags. + +diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in +index f192fb1..99a5c45 100644 +--- a/include/libvirt/libvirt.h.in ++++ b/include/libvirt/libvirt.h.in +@@ -845,9 +845,22 @@ int virDomainGetVcpus (virDomainPtr domain, + */ + #define VIR_GET_CPUMAP(cpumaps,maplen,vcpu) &(cpumaps[(vcpu)*(maplen)]) + ++ ++typedef enum { ++ ++ VIR_DOMAIN_DEVICE_MODIFY_CURRENT = 0, /* Modify device allocation based on current domain state */ ++ VIR_DOMAIN_DEVICE_MODIFY_LIVE = (1 << 0), /* Modify live device allocation */ ++ VIR_DOMAIN_DEVICE_MODIFY_CONFIG = (1 << 1), /* Modify persisted device allocation */ ++} virDomainDeviceModifyFlags; ++ + int virDomainAttachDevice(virDomainPtr domain, const char *xml); + int virDomainDetachDevice(virDomainPtr domain, const char *xml); + ++int virDomainAttachDeviceFlags(virDomainPtr domain, ++ const char *xml, unsigned int flags); ++int virDomainDetachDeviceFlags(virDomainPtr domain, ++ const char *xml, unsigned int flags); ++ + /* + * NUMA support + */ +diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms +index 0521158..e190d83 100644 +--- a/src/libvirt_public.syms ++++ b/src/libvirt_public.syms +@@ -349,4 +349,10 @@ LIBVIRT_0.7.5 { + virDomainMemoryStats; + } LIBVIRT_0.7.3; + ++LIBVIRT_0.7.6 { ++ global: ++ virDomainAttachDeviceFlags; ++ virDomainDetachDeviceFlags; ++} LIBVIRT_0.7.5; ++ + # .... define new API here using predicted next version number .... diff --git a/devflag-03.patch b/devflag-03.patch new file mode 100644 index 0000000..62df1a2 --- /dev/null +++ b/devflag-03.patch @@ -0,0 +1,40 @@ +commit 5ebd48c5f4e424e0db663bf5930935b1c04d4998 +Author: Jim Fehlig +Date: Wed Jan 13 18:31:14 2010 -0700 + + Internal API + + Definition of internal API for virDomain{Attach,Detach}DeviceFlags. + +diff --git a/src/driver.h b/src/driver.h +index c7e4fbf..08fe816 100644 +--- a/src/driver.h ++++ b/src/driver.h +@@ -192,9 +192,17 @@ typedef int + (*virDrvDomainAttachDevice) (virDomainPtr domain, + const char *xml); + typedef int ++ (*virDrvDomainAttachDeviceFlags) (virDomainPtr domain, ++ const char *xml, ++ unsigned int flags); ++typedef int + (*virDrvDomainDetachDevice) (virDomainPtr domain, + const char *xml); + typedef int ++ (*virDrvDomainDetachDeviceFlags) (virDomainPtr domain, ++ const char *xml, ++ unsigned int flags); ++typedef int + (*virDrvDomainGetAutostart) (virDomainPtr domain, + int *autostart); + typedef int +@@ -419,7 +427,9 @@ struct _virDriver { + virDrvDomainDefineXML domainDefineXML; + virDrvDomainUndefine domainUndefine; + virDrvDomainAttachDevice domainAttachDevice; ++ virDrvDomainAttachDeviceFlags domainAttachDeviceFlags; + virDrvDomainDetachDevice domainDetachDevice; ++ virDrvDomainDetachDeviceFlags domainDetachDeviceFlags; + virDrvDomainGetAutostart domainGetAutostart; + virDrvDomainSetAutostart domainSetAutostart; + virDrvDomainGetSchedulerType domainGetSchedulerType; diff --git a/devflag-04.patch b/devflag-04.patch new file mode 100644 index 0000000..4c01784 --- /dev/null +++ b/devflag-04.patch @@ -0,0 +1,153 @@ +commit 487b2434403d520027957ed623354b398984af31 +Author: Jim Fehlig +Date: Wed Jan 13 18:34:23 2010 -0700 + + Public API Implementation + + Implementation of public API for virDomain{Attach,Detach}DeviceFlags. + + V2: Don't break remote compatibility with older libvirtd + +Index: libvirt-0.7.5/src/libvirt.c +=================================================================== +--- libvirt-0.7.5.orig/src/libvirt.c ++++ libvirt-0.7.5/src/libvirt.c +@@ -5090,14 +5090,68 @@ virDomainAttachDevice(virDomainPtr domai + conn = domain->conn; + + if (conn->driver->domainAttachDevice) { ++ int ret; ++ ret = conn->driver->domainAttachDevice (domain, xml); ++ if (ret < 0) ++ goto error; ++ return ret; ++ } ++ ++ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); ++ ++error: ++ virDispatchError(domain->conn); ++ return -1; ++} ++ ++/** ++ * virDomainAttachDeviceFlags: ++ * @domain: pointer to domain object ++ * @xml: pointer to XML description of one device ++ * @flags: an OR'ed set of virDomainDeviceModifyFlags ++ * ++ * Attach a virtual device to a domain, using the flags parameter ++ * to control how the device is attached. VIR_DOMAIN_DEVICE_MODIFY_CURRENT ++ * specifies that the device allocation is made based on current domain ++ * state. VIR_DOMAIN_DEVICE_MODIFY_LIVE specifies that the device shall be ++ * allocated to 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 allocated to 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. ++ * ++ * Returns 0 in case of success, -1 in case of failure. ++ */ ++int ++virDomainAttachDeviceFlags(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->domainAttachDeviceFlags) { + int ret; +- ret = conn->driver->domainAttachDevice (domain, xml); ++ ret = conn->driver->domainAttachDeviceFlags(domain, xml, flags); + if (ret < 0) + goto error; + return ret; + } + +- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); ++ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + + error: + /* Copy to connection error object for back compatability */ +@@ -5136,12 +5190,66 @@ virDomainDetachDevice(virDomainPtr domai + if (conn->driver->domainDetachDevice) { + int ret; + ret = conn->driver->domainDetachDevice (domain, xml); ++ if (ret < 0) ++ goto error; ++ return ret; ++ } ++ ++ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); ++ ++error: ++ virDispatchError(domain->conn); ++ return -1; ++} ++ ++/** ++ * virDomainDetachDeviceFlags: ++ * @domain: pointer to domain object ++ * @xml: pointer to XML description of one device ++ * @flags: an OR'ed set of virDomainDeviceModifyFlags ++ * ++ * Detach a virtual device from a domain, using the flags parameter ++ * to control how the device is detached. VIR_DOMAIN_DEVICE_MODIFY_CURRENT ++ * specifies that the device allocation is removed based on current domain ++ * state. VIR_DOMAIN_DEVICE_MODIFY_LIVE specifies that the device shall be ++ * deallocated from the active domain instance only and is not from the ++ * persisted domain configuration. VIR_DOMAIN_DEVICE_MODIFY_CONFIG ++ * specifies that the device shall be deallocated from 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 removing the ++ * persisted device allocation. ++ * ++ * Returns 0 in case of success, -1 in case of failure. ++ */ ++int ++virDomainDetachDeviceFlags(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->domainDetachDeviceFlags) { ++ int ret; ++ ret = conn->driver->domainDetachDeviceFlags(domain, xml, flags); + if (ret < 0) + goto error; + return ret; + } + +- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); ++ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + + error: + /* Copy to connection error object for back compatability */ diff --git a/devflag-05.patch b/devflag-05.patch new file mode 100644 index 0000000..0080715 --- /dev/null +++ b/devflag-05.patch @@ -0,0 +1,49 @@ +commit 5ef6d92292f5c9dd27c7db2bf56f8f24b13c681b +Author: Jim Fehlig +Date: Wed Jan 13 18:39:35 2010 -0700 + + Wire protocol format + + Definition of wire protocol format for + virDomain{Attach,Detach}DeviceFlags. + +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index bed3940..98953a9 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -708,11 +708,23 @@ struct remote_domain_attach_device_args { + remote_nonnull_string xml; + }; + ++struct remote_domain_attach_device_flags_args { ++ remote_nonnull_domain dom; ++ remote_nonnull_string xml; ++ unsigned int flags; ++}; ++ + struct remote_domain_detach_device_args { + remote_nonnull_domain dom; + remote_nonnull_string xml; + }; + ++struct remote_domain_detach_device_flags_args { ++ remote_nonnull_domain dom; ++ remote_nonnull_string xml; ++ unsigned int flags; ++}; ++ + struct remote_domain_get_autostart_args { + remote_nonnull_domain dom; + }; +@@ -1641,7 +1653,10 @@ enum remote_procedure { + REMOTE_PROC_INTERFACE_IS_ACTIVE = 156, + REMOTE_PROC_GET_LIB_VERSION = 157, + REMOTE_PROC_CPU_COMPARE = 158, +- REMOTE_PROC_DOMAIN_MEMORY_STATS = 159 ++ REMOTE_PROC_DOMAIN_MEMORY_STATS = 159, ++ REMOTE_PROC_DOMAIN_ATTACH_DEVICE_FLAGS = 160, ++ ++ REMOTE_PROC_DOMAIN_DETACH_DEVICE_FLAGS = 161 + + /* + * Notice how the entries are grouped in sets of 10 ? diff --git a/devflag-06.patch b/devflag-06.patch new file mode 100644 index 0000000..6183641 --- /dev/null +++ b/devflag-06.patch @@ -0,0 +1,88 @@ +commit 80bfb087ae4d92b271eadaee6e08b5ea2d1b68a6 +Author: Jim Fehlig +Date: Wed Jan 13 18:41:13 2010 -0700 + + Remote driver + + Implementation of Domain{Attach,Detach}DeviceFlags in remote driver. + +diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c +index d6f5fce..eb16f62 100644 +--- a/src/remote/remote_driver.c ++++ b/src/remote/remote_driver.c +@@ -3057,6 +3057,32 @@ done: + } + + static int ++remoteDomainAttachDeviceFlags (virDomainPtr domain, const char *xml, ++ unsigned int flags) ++{ ++ int rv = -1; ++ remote_domain_attach_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_ATTACH_DEVICE_FLAGS, ++ (xdrproc_t) xdr_remote_domain_attach_device_flags_args, (char *) &args, ++ (xdrproc_t) xdr_void, (char *) NULL) == -1) ++ goto done; ++ ++ rv = 0; ++ ++done: ++ remoteDriverUnlock(priv); ++ return rv; ++} ++ ++static int + remoteDomainDetachDevice (virDomainPtr domain, const char *xml) + { + int rv = -1; +@@ -3081,6 +3107,32 @@ done: + } + + static int ++remoteDomainDetachDeviceFlags (virDomainPtr domain, const char *xml, ++ unsigned int flags) ++{ ++ int rv = -1; ++ remote_domain_detach_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_DETACH_DEVICE_FLAGS, ++ (xdrproc_t) xdr_remote_domain_detach_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; +@@ -8894,7 +8946,9 @@ static virDriver remote_driver = { + remoteDomainDefineXML, /* domainDefineXML */ + remoteDomainUndefine, /* domainUndefine */ + remoteDomainAttachDevice, /* domainAttachDevice */ ++ remoteDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ + remoteDomainDetachDevice, /* domainDetachDevice */ ++ remoteDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + remoteDomainGetAutostart, /* domainGetAutostart */ + remoteDomainSetAutostart, /* domainSetAutostart */ + remoteDomainGetSchedulerType, /* domainGetSchedulerType */ diff --git a/devflag-07.patch b/devflag-07.patch new file mode 100644 index 0000000..f934e9c --- /dev/null +++ b/devflag-07.patch @@ -0,0 +1,79 @@ +commit 5b724a365e67d1cc2649ded76dea03836a067921 +Author: Jim Fehlig +Date: Wed Jan 13 18:42:28 2010 -0700 + + Server side dispatcher + + Server side dispatcher for Domain{Attach,Detach}DeviceFlags. + +diff --git a/daemon/remote.c b/daemon/remote.c +index 299f971..bf156e4 100644 +--- a/daemon/remote.c ++++ b/daemon/remote.c +@@ -890,6 +890,32 @@ remoteDispatchDomainAttachDevice (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + static int ++remoteDispatchDomainAttachDeviceFlags (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_attach_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 (virDomainAttachDeviceFlags (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, +@@ -1015,6 +1041,33 @@ remoteDispatchDomainDetachDevice (struct qemud_server *server ATTRIBUTE_UNUSED, + } + + static int ++remoteDispatchDomainDetachDeviceFlags (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_detach_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 (virDomainDetachDeviceFlags (dom, args->xml, args->flags) == -1) { ++ virDomainFree(dom); ++ remoteDispatchConnError(rerr, conn); ++ return -1; ++ } ++ ++ virDomainFree(dom); ++ return 0; ++} ++ ++static int + remoteDispatchDomainDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, diff --git a/devflag-08.patch b/devflag-08.patch new file mode 100644 index 0000000..dac106e --- /dev/null +++ b/devflag-08.patch @@ -0,0 +1,609 @@ +commit ff9fce67120771b0ec1e21a98afc96360a7bbb36 +Author: Jim Fehlig +Date: Wed Jan 13 18:44:26 2010 -0700 + + domain{Attach,Detach}DeviceFlags handler for drivers + + Implementation of domain{Attach,Detach}DeviceFlags handlers + in the drivers. + +Index: libvirt-0.7.5/src/esx/esx_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/esx/esx_driver.c ++++ libvirt-0.7.5/src/esx/esx_driver.c +@@ -3426,7 +3426,9 @@ static virDriver esxDriver = { + esxDomainDefineXML, /* domainDefineXML */ + esxDomainUndefine, /* domainUndefine */ + NULL, /* domainAttachDevice */ ++ NULL, /* domainAttachDeviceFlags */ + NULL, /* domainDetachDevice */ ++ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + esxDomainGetSchedulerType, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/lxc/lxc_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/lxc/lxc_driver.c ++++ libvirt-0.7.5/src/lxc/lxc_driver.c +@@ -2427,7 +2427,9 @@ static virDriver lxcDriver = { + lxcDomainDefine, /* domainDefineXML */ + lxcDomainUndefine, /* domainUndefine */ + NULL, /* domainAttachDevice */ ++ NULL, /* domainAttachDeviceFlags */ + NULL, /* domainDetachDevice */ ++ NULL, /* domainDetachDeviceFlags */ + lxcDomainGetAutostart, /* domainGetAutostart */ + lxcDomainSetAutostart, /* domainSetAutostart */ + lxcGetSchedulerType, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/opennebula/one_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/opennebula/one_driver.c ++++ libvirt-0.7.5/src/opennebula/one_driver.c +@@ -754,7 +754,9 @@ static virDriver oneDriver = { + oneDomainDefine, /* domainDefineXML */ + oneDomainUndefine, /* domainUndefine */ + NULL, /* domainAttachDevice */ ++ NULL, /* domainAttachDeviceFlags */ + NULL, /* domainDetachDevice */ ++ NULL, /* domainDetachDeviceFlags */ + oneGetAutostart, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/openvz/openvz_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/openvz/openvz_driver.c ++++ libvirt-0.7.5/src/openvz/openvz_driver.c +@@ -1506,7 +1506,9 @@ static virDriver openvzDriver = { + openvzDomainDefineXML, /* domainDefineXML */ + openvzDomainUndefine, /* domainUndefine */ + NULL, /* domainAttachDevice */ ++ NULL, /* domainAttachDeviceFlags */ + NULL, /* domainDetachDevice */ ++ NULL, /* domainDetachDeviceFlags */ + openvzDomainGetAutostart, /* domainGetAutostart */ + openvzDomainSetAutostart, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/phyp/phyp_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/phyp/phyp_driver.c ++++ libvirt-0.7.5/src/phyp/phyp_driver.c +@@ -1622,7 +1622,9 @@ virDriver phypDriver = { + NULL, /* domainDefineXML */ + NULL, /* domainUndefine */ + NULL, /* domainAttachDevice */ ++ NULL, /* domainAttachDeviceFlags */ + NULL, /* domainDetachDevice */ ++ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/qemu/qemu_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/qemu/qemu_driver.c ++++ libvirt-0.7.5/src/qemu/qemu_driver.c +@@ -5528,6 +5528,18 @@ cleanup: + return ret; + } + ++static int qemudDomainAttachDeviceFlags(virDomainPtr dom, ++ const char *xml, ++ unsigned int flags) { ++ if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { ++ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_INVALID, ++ "%s", _("cannot modify the persistent configuration of a domain")); ++ return -1; ++ } ++ ++ return qemudDomainAttachDevice(dom, xml); ++} ++ + static int qemudDomainDetachPciDiskDevice(virConnectPtr conn, + struct qemud_driver *driver, + virDomainObjPtr vm, +@@ -5856,6 +5868,18 @@ cleanup: + return ret; + } + ++static int qemudDomainDetachDeviceFlags(virDomainPtr dom, ++ const char *xml, ++ unsigned int flags) { ++ if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { ++ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_INVALID, ++ "%s", _("cannot modify the persistent configuration of a domain")); ++ return -1; ++ } ++ ++ return qemudDomainDetachDevice(dom, xml); ++} ++ + static int qemudDomainGetAutostart(virDomainPtr dom, + int *autostart) { + struct qemud_driver *driver = dom->conn->privateData; +@@ -7961,7 +7985,9 @@ static virDriver qemuDriver = { + qemudDomainDefine, /* domainDefineXML */ + qemudDomainUndefine, /* domainUndefine */ + qemudDomainAttachDevice, /* domainAttachDevice */ ++ qemudDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ + qemudDomainDetachDevice, /* domainDetachDevice */ ++ qemudDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + qemudDomainGetAutostart, /* domainGetAutostart */ + qemudDomainSetAutostart, /* domainSetAutostart */ + qemuGetSchedulerType, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/test/test_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/test/test_driver.c ++++ libvirt-0.7.5/src/test/test_driver.c +@@ -5209,7 +5209,9 @@ static virDriver testDriver = { + testDomainDefineXML, /* domainDefineXML */ + testDomainUndefine, /* domainUndefine */ + NULL, /* domainAttachDevice */ ++ NULL, /* domainAttachDeviceFlags */ + NULL, /* domainDetachDevice */ ++ NULL, /* domainDetachDeviceFlags */ + testDomainGetAutostart, /* domainGetAutostart */ + testDomainSetAutostart, /* domainSetAutostart */ + testDomainGetSchedulerType, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/uml/uml_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/uml/uml_driver.c ++++ libvirt-0.7.5/src/uml/uml_driver.c +@@ -1895,7 +1895,9 @@ static virDriver umlDriver = { + umlDomainDefine, /* domainDefineXML */ + umlDomainUndefine, /* domainUndefine */ + NULL, /* domainAttachDevice */ ++ NULL, /* domainAttachDeviceFlags */ + NULL, /* domainDetachDevice */ ++ NULL, /* domainDetachDeviceFlags */ + umlDomainGetAutostart, /* domainGetAutostart */ + umlDomainSetAutostart, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/vbox/vbox_tmpl.c +=================================================================== +--- libvirt-0.7.5.orig/src/vbox/vbox_tmpl.c ++++ libvirt-0.7.5/src/vbox/vbox_tmpl.c +@@ -4841,6 +4841,17 @@ cleanup: + return ret; + } + ++static int vboxDomainAttachDeviceFlags(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 vboxDomainAttachDevice(dom, xml); ++} ++ + static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) { + VBOX_OBJECT_CHECK(dom->conn, int, -1); + IMachine *machine = NULL; +@@ -4971,6 +4982,17 @@ cleanup: + return ret; + } + ++static int vboxDomainDetachDeviceFlags(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 vboxDomainDetachDevice(dom, xml); ++} ++ + #if VBOX_API_VERSION == 2002 + /* No Callback support for VirtualBox 2.2.* series */ + #else /* !(VBOX_API_VERSION == 2002) */ +@@ -7017,7 +7039,9 @@ virDriver NAME(Driver) = { + vboxDomainDefineXML, /* domainDefineXML */ + vboxDomainUndefine, /* domainUndefine */ + vboxDomainAttachDevice, /* domainAttachDevice */ ++ vboxDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ + vboxDomainDetachDevice, /* domainDetachDevice */ ++ vboxDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/xen/proxy_internal.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/proxy_internal.c ++++ libvirt-0.7.5/src/xen/proxy_internal.c +@@ -76,8 +76,8 @@ struct xenUnifiedDriver xenProxyDriver = + NULL, /* domainCreate */ + NULL, /* domainDefineXML */ + NULL, /* domainUndefine */ +- NULL, /* domainAttachDevice */ +- NULL, /* domainDetachDevice */ ++ NULL, /* domainAttachDeviceFlags */ ++ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/xen/xen_driver.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xen_driver.c ++++ libvirt-0.7.5/src/xen/xen_driver.c +@@ -1426,10 +1426,29 @@ xenUnifiedDomainAttachDevice (virDomainP + { + GET_PRIVATE(dom->conn); + int i; ++ unsigned int flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; ++ ++ if (dom->id >= 0) ++ flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; ++ ++ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) ++ if (priv->opened[i] && drivers[i]->domainAttachDeviceFlags && ++ drivers[i]->domainAttachDeviceFlags(dom, xml, flags) == 0) ++ return 0; ++ ++ return -1; ++} ++ ++static int ++xenUnifiedDomainAttachDeviceFlags (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]->domainAttachDevice && +- drivers[i]->domainAttachDevice (dom, xml) == 0) ++ if (priv->opened[i] && drivers[i]->domainAttachDeviceFlags && ++ drivers[i]->domainAttachDeviceFlags(dom, xml, flags) == 0) + return 0; + + return -1; +@@ -1440,10 +1459,29 @@ xenUnifiedDomainDetachDevice (virDomainP + { + GET_PRIVATE(dom->conn); + int i; ++ unsigned int flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; ++ ++ if (dom->id >= 0) ++ flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; ++ ++ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) ++ if (priv->opened[i] && drivers[i]->domainDetachDeviceFlags && ++ drivers[i]->domainDetachDeviceFlags(dom, xml, flags) == 0) ++ return 0; ++ ++ return -1; ++} ++ ++static int ++xenUnifiedDomainDetachDeviceFlags (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]->domainDetachDevice && +- drivers[i]->domainDetachDevice (dom, xml) == 0) ++ if (priv->opened[i] && drivers[i]->domainDetachDeviceFlags && ++ drivers[i]->domainDetachDeviceFlags(dom, xml, flags) == 0) + return 0; + + return -1; +@@ -1833,7 +1871,9 @@ static virDriver xenUnifiedDriver = { + xenUnifiedDomainDefineXML, /* domainDefineXML */ + xenUnifiedDomainUndefine, /* domainUndefine */ + xenUnifiedDomainAttachDevice, /* domainAttachDevice */ ++ xenUnifiedDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ + xenUnifiedDomainDetachDevice, /* domainDetachDevice */ ++ xenUnifiedDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + xenUnifiedDomainGetAutostart, /* domainGetAutostart */ + xenUnifiedDomainSetAutostart, /* domainSetAutostart */ + xenUnifiedDomainGetSchedulerType, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/xen/xen_driver.h +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xen_driver.h ++++ libvirt-0.7.5/src/xen/xen_driver.h +@@ -93,8 +93,8 @@ struct xenUnifiedDriver { + virDrvDomainCreate domainCreate; + virDrvDomainDefineXML domainDefineXML; + virDrvDomainUndefine domainUndefine; +- virDrvDomainAttachDevice domainAttachDevice; +- virDrvDomainDetachDevice domainDetachDevice; ++ virDrvDomainAttachDeviceFlags domainAttachDeviceFlags; ++ virDrvDomainDetachDeviceFlags domainDetachDeviceFlags; + virDrvDomainGetAutostart domainGetAutostart; + virDrvDomainSetAutostart domainSetAutostart; + virDrvDomainGetSchedulerType domainGetSchedulerType; +Index: libvirt-0.7.5/src/xen/xen_hypervisor.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xen_hypervisor.c ++++ libvirt-0.7.5/src/xen/xen_hypervisor.c +@@ -793,8 +793,8 @@ struct xenUnifiedDriver xenHypervisorDri + NULL, /* domainCreate */ + NULL, /* domainDefineXML */ + NULL, /* domainUndefine */ +- NULL, /* domainAttachDevice */ +- NULL, /* domainDetachDevice */ ++ NULL, /* domainAttachDeviceFlags */ ++ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + xenHypervisorGetSchedulerType, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/xen/xen_inotify.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xen_inotify.c ++++ libvirt-0.7.5/src/xen/xen_inotify.c +@@ -79,8 +79,8 @@ struct xenUnifiedDriver xenInotifyDriver + NULL, /* domainCreate */ + NULL, /* domainDefineXML */ + NULL, /* domainUndefine */ +- NULL, /* domainAttachDevice */ +- NULL, /* domainDetachDevice */ ++ NULL, /* domainAttachDeviceFlags */ ++ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/xen/xend_internal.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xend_internal.c ++++ libvirt-0.7.5/src/xen/xend_internal.c +@@ -4095,9 +4095,10 @@ xenDaemonCreateXML(virConnectPtr conn, c + } + + /** +- * xenDaemonAttachDevice: ++ * xenDaemonAttachDeviceFlags: + * @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. +@@ -4105,7 +4106,8 @@ xenDaemonCreateXML(virConnectPtr conn, c + * Returns 0 in case of success, -1 in case of failure. + */ + static int +-xenDaemonAttachDevice(virDomainPtr domain, const char *xml) ++xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml, ++ unsigned int flags) + { + xenUnifiedPrivatePtr priv; + char *sexpr = NULL; +@@ -4123,12 +4125,41 @@ xenDaemonAttachDevice(virDomainPtr domai + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; + +- /* +- * on older Xen without the inactive guests management +- * avoid doing this on inactive guests +- */ +- if ((domain->id < 0) && (priv->xendConfigVersion < 3)) +- return -1; ++ 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 " ++ "persisted 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 " ++ "persisted config")); ++ return -1; ++ } ++ /* Xen only supports modifying both live and persisted 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")); ++ return -1; ++ } ++ } + + if (!(def = xenDaemonDomainFetch(domain->conn, + domain->id, +@@ -4202,16 +4233,18 @@ cleanup: + } + + /** +- * xenDaemonDetachDevice: ++ * xenDaemonDetachDeviceFlags: + * @domain: pointer to domain object + * @xml: pointer to XML description of device ++ * @flags: an OR'ed set of virDomainDeviceModifyFlags + * + * Destroy a virtual device attachment to backend. + * + * Returns 0 in case of success, -1 in case of failure. + */ + static int +-xenDaemonDetachDevice(virDomainPtr domain, const char *xml) ++xenDaemonDetachDeviceFlags(virDomainPtr domain, const char *xml, ++ unsigned int flags) + { + xenUnifiedPrivatePtr priv; + char class[8], ref[80]; +@@ -4229,12 +4262,41 @@ xenDaemonDetachDevice(virDomainPtr domai + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; + +- /* +- * on older Xen without the inactive guests management +- * avoid doing this on inactive guests +- */ +- if ((domain->id < 0) && (priv->xendConfigVersion < 3)) +- return -1; ++ 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 " ++ "persisted 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 " ++ "persisted config")); ++ return -1; ++ } ++ /* Xen only supports modifying both live and persisted 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")); ++ return -1; ++ } ++ } + + if (!(def = xenDaemonDomainFetch(domain->conn, + domain->id, +@@ -5164,8 +5226,8 @@ struct xenUnifiedDriver xenDaemonDriver + xenDaemonDomainCreate, /* domainCreate */ + xenDaemonDomainDefineXML, /* domainDefineXML */ + xenDaemonDomainUndefine, /* domainUndefine */ +- xenDaemonAttachDevice, /* domainAttachDevice */ +- xenDaemonDetachDevice, /* domainDetachDevice */ ++ xenDaemonAttachDeviceFlags, /* domainAttachDeviceFlags */ ++ xenDaemonDetachDeviceFlags, /* domainDetachDeviceFlags */ + xenDaemonDomainGetAutostart, /* domainGetAutostart */ + xenDaemonDomainSetAutostart, /* domainSetAutostart */ + xenDaemonGetSchedulerType, /* domainGetSchedulerType */ +Index: libvirt-0.7.5/src/xen/xm_internal.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xm_internal.c ++++ libvirt-0.7.5/src/xen/xm_internal.c +@@ -65,8 +65,10 @@ + static int xenXMConfigSetString(virConfPtr conf, const char *setting, + const char *str); + char * xenXMAutoAssignMac(void); +-static int xenXMDomainAttachDevice(virDomainPtr domain, const char *xml); +-static int xenXMDomainDetachDevice(virDomainPtr domain, const char *xml); ++static int xenXMDomainAttachDeviceFlags(virDomainPtr domain, const char *xml, ++ unsigned int flags); ++static int xenXMDomainDetachDeviceFlags(virDomainPtr domain, const char *xml, ++ unsigned int flags); + + #define XM_REFRESH_INTERVAL 10 + +@@ -109,8 +111,8 @@ struct xenUnifiedDriver xenXMDriver = { + xenXMDomainCreate, /* domainCreate */ + xenXMDomainDefineXML, /* domainDefineXML */ + xenXMDomainUndefine, /* domainUndefine */ +- xenXMDomainAttachDevice, /* domainAttachDevice */ +- xenXMDomainDetachDevice, /* domainDetachDevice */ ++ xenXMDomainAttachDeviceFlags, /* domainAttachDeviceFlags */ ++ xenXMDomainDetachDeviceFlags, /* domainDetachDeviceFlags */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ +@@ -2914,17 +2916,21 @@ cleanup: + + + /** +- * xenXMDomainAttachDevice: ++ * xenXMDomainAttachDeviceFlags: + * @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 config file. ++ * This driver only supports device allocation to ++ * persisted config. + * + * Returns 0 in case of success, -1 in case of failure. + */ + static int +-xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) { ++xenXMDomainAttachDeviceFlags(virDomainPtr domain, const char *xml, ++ unsigned int flags) { + const char *filename = NULL; + xenXMConfCachePtr entry = NULL; + int ret = -1; +@@ -2940,7 +2946,7 @@ xenXMDomainAttachDevice(virDomainPtr dom + + if (domain->conn->flags & VIR_CONNECT_RO) + return -1; +- if (domain->id != -1) ++ if (domain->id != -1 && !(flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG)) + return -1; + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; +@@ -3002,16 +3008,20 @@ xenXMDomainAttachDevice(virDomainPtr dom + + + /** +- * xenXMDomainDetachDevice: ++ * xenXMDomainDetachDeviceFlags: + * @domain: pointer to domain object + * @xml: pointer to XML description of device ++ * @flags: an OR'ed set of virDomainDeviceModifyFlags + * + * Destroy a virtual device attachment to backend. ++ * This driver only supports device deallocation from ++ * persisted config. + * + * Returns 0 in case of success, -1 in case of failure. + */ + static int +-xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) { ++xenXMDomainDetachDeviceFlags(virDomainPtr domain, const char *xml, ++ unsigned int flags) { + const char *filename = NULL; + xenXMConfCachePtr entry = NULL; + virDomainDeviceDefPtr dev = NULL; +@@ -3029,7 +3039,7 @@ xenXMDomainDetachDevice(virDomainPtr dom + + if (domain->conn->flags & VIR_CONNECT_RO) + return -1; +- if (domain->id != -1) ++ if (domain->id != -1 && !(flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG)) + return -1; + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; +Index: libvirt-0.7.5/src/xen/xs_internal.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xs_internal.c ++++ libvirt-0.7.5/src/xen/xs_internal.c +@@ -76,8 +76,8 @@ struct xenUnifiedDriver xenStoreDriver = + NULL, /* domainCreate */ + NULL, /* domainDefineXML */ + NULL, /* domainUndefine */ +- NULL, /* domainAttachDevice */ +- NULL, /* domainDetachDevice */ ++ NULL, /* domainAttachDeviceFlags */ ++ NULL, /* domainDetachDeviceFlags */ + NULL, /* domainGetAutostart */ + NULL, /* domainSetAutostart */ + NULL, /* domainGetSchedulerType */ diff --git a/devflag-09.patch b/devflag-09.patch new file mode 100644 index 0000000..de0dd91 --- /dev/null +++ b/devflag-09.patch @@ -0,0 +1,253 @@ +commit 3a9b2b900c5dac18c9c48c40ec2dbeaa7c306a0e +Author: Jim Fehlig +Date: Wed Jan 13 18:54:58 2010 -0700 + + Modify virsh commands + + Change all virsh commands that invoke virDomain{Attach,Detach}Device() + to use virDomain{Attach,Detach}DeviceFlags() instead. + + Add a "--persistent" flag to these virsh commands, allowing user to + specify that the domain persisted config be modified as well. + + V2: Only invoke virDomain{Attach,Detach}DeviceFlags() if + "--persistent" flag is specified. Otherwise invoke + virDomain{Attach,Detach}Device() to retain current behavior. + +Index: libvirt-0.7.5/tools/virsh.c +=================================================================== +--- libvirt-0.7.5.orig/tools/virsh.c ++++ libvirt-0.7.5/tools/virsh.c +@@ -6281,6 +6281,7 @@ static const vshCmdInfo info_attach_devi + static const vshCmdOptDef opts_attach_device[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("XML file")}, ++ {"persistent", VSH_OT_BOOL, 0, gettext_noop("persist device attachment")}, + {NULL, 0, 0, NULL} + }; + +@@ -6292,6 +6293,7 @@ cmdAttachDevice(vshControl *ctl, const v + char *buffer; + int ret = TRUE; + int found; ++ unsigned int flags; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; +@@ -6311,7 +6313,14 @@ cmdAttachDevice(vshControl *ctl, const v + return FALSE; + } + +- ret = virDomainAttachDevice(dom, buffer); ++ if (vshCommandOptBool(cmd, "persistent")) { ++ flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; ++ if (virDomainIsActive(dom) == 1) ++ flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; ++ ret = virDomainAttachDeviceFlags(dom, buffer, flags); ++ } else { ++ ret = virDomainAttachDevice(dom, buffer); ++ } + free (buffer); + + if (ret < 0) { +@@ -6339,6 +6348,7 @@ static const vshCmdInfo info_detach_devi + static const vshCmdOptDef opts_detach_device[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("XML file")}, ++ {"persistent", VSH_OT_BOOL, 0, gettext_noop("persist device detachment")}, + {NULL, 0, 0, NULL} + }; + +@@ -6350,6 +6360,7 @@ cmdDetachDevice(vshControl *ctl, const v + char *buffer; + int ret = TRUE; + int found; ++ unsigned int flags; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; +@@ -6369,7 +6380,14 @@ cmdDetachDevice(vshControl *ctl, const v + return FALSE; + } + +- ret = virDomainDetachDevice(dom, buffer); ++ if (vshCommandOptBool(cmd, "persistent")) { ++ flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; ++ if (virDomainIsActive(dom) == 1) ++ flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; ++ ret = virDomainDetachDeviceFlags(dom, buffer, flags); ++ } else { ++ ret = virDomainDetachDevice(dom, buffer); ++ } + free (buffer); + + if (ret < 0) { +@@ -6401,6 +6419,7 @@ static const vshCmdOptDef opts_attach_in + {"target", VSH_OT_DATA, 0, gettext_noop("target network name")}, + {"mac", VSH_OT_DATA, 0, gettext_noop("MAC address")}, + {"script", VSH_OT_DATA, 0, gettext_noop("script used to bridge network interface")}, ++ {"persistent", VSH_OT_BOOL, 0, gettext_noop("persist interface attachment")}, + {NULL, 0, 0, NULL} + }; + +@@ -6411,6 +6430,7 @@ cmdAttachInterface(vshControl *ctl, cons + char *mac, *target, *script, *type, *source; + int typ, ret = FALSE; + char *buf = NULL, *tmp = NULL; ++ unsigned int flags; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + goto cleanup; +@@ -6485,13 +6505,22 @@ cmdAttachInterface(vshControl *ctl, cons + if (!buf) goto cleanup; + strcat(buf, " \n"); + +- if (virDomainAttachDevice(dom, buf)) { +- goto cleanup; ++ if (vshCommandOptBool(cmd, "persistent")) { ++ flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; ++ if (virDomainIsActive(dom) == 1) ++ flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; ++ ret = virDomainAttachDeviceFlags(dom, buf, flags); + } else { +- vshPrint(ctl, "%s", _("Interface attached successfully\n")); ++ ret = virDomainAttachDevice(dom, buf); + } + +- ret = TRUE; ++ if (ret != 0) { ++ vshError(ctl, _("Failed to attach interface")); ++ ret = FALSE; ++ } else { ++ vshPrint(ctl, "%s", _("Interface attached successfully\n")); ++ ret = TRUE; ++ } + + cleanup: + if (dom) +@@ -6514,6 +6543,7 @@ static const vshCmdOptDef opts_detach_in + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, + {"type", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("network interface type")}, + {"mac", VSH_OT_STRING, 0, gettext_noop("MAC address")}, ++ {"persistent", VSH_OT_BOOL, 0, gettext_noop("persist interface detachment")}, + {NULL, 0, 0, NULL} + }; + +@@ -6530,6 +6560,7 @@ cmdDetachInterface(vshControl *ctl, cons + char *doc, *mac =NULL, *type; + char buf[64]; + int i = 0, diff_mac, ret = FALSE; ++ unsigned int flags; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + goto cleanup; +@@ -6601,10 +6632,21 @@ cmdDetachInterface(vshControl *ctl, cons + goto cleanup; + } + +- ret = virDomainDetachDevice(dom, (char *)xmlBufferContent(xml_buf)); +- if (ret != 0) ++ if (vshCommandOptBool(cmd, "persistent")) { ++ flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; ++ if (virDomainIsActive(dom) == 1) ++ flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; ++ ret = virDomainDetachDeviceFlags(dom, ++ (char *)xmlBufferContent(xml_buf), ++ flags); ++ } else { ++ ret = virDomainDetachDevice(dom, (char *)xmlBufferContent(xml_buf)); ++ } ++ ++ if (ret != 0) { ++ vshError(ctl, _("Failed to detach interface")); + ret = FALSE; +- else { ++ } else { + vshPrint(ctl, "%s", _("Interface detached successfully\n")); + ret = TRUE; + } +@@ -6638,6 +6680,7 @@ static const vshCmdOptDef opts_attach_di + {"subdriver", VSH_OT_STRING, 0, gettext_noop("subdriver of disk device")}, + {"type", VSH_OT_STRING, 0, gettext_noop("target device type")}, + {"mode", VSH_OT_STRING, 0, gettext_noop("mode of device reading and writing")}, ++ {"persistent", VSH_OT_BOOL, 0, gettext_noop("persist disk attachment")}, + {NULL, 0, 0, NULL} + }; + +@@ -6648,6 +6691,7 @@ cmdAttachDisk(vshControl *ctl, const vsh + char *source, *target, *driver, *subdriver, *type, *mode; + int isFile = 0, ret = FALSE; + char *buf = NULL, *tmp = NULL; ++ unsigned int flags; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + goto cleanup; +@@ -6763,12 +6807,22 @@ cmdAttachDisk(vshControl *ctl, const vsh + if (!buf) goto cleanup; + strcat(buf, " \n"); + +- if (virDomainAttachDevice(dom, buf)) +- goto cleanup; +- else +- vshPrint(ctl, "%s", _("Disk attached successfully\n")); ++ if (vshCommandOptBool(cmd, "persistent")) { ++ flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; ++ if (virDomainIsActive(dom) == 1) ++ flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; ++ ret = virDomainAttachDeviceFlags(dom, buf, flags); ++ } else { ++ ret = virDomainAttachDevice(dom, buf); ++ } + +- ret = TRUE; ++ if (ret != 0) { ++ vshError(ctl, _("Failed to attach disk")); ++ ret = FALSE; ++ } else { ++ vshPrint(ctl, "%s", _("Disk attached successfully\n")); ++ ret = TRUE; ++ } + + cleanup: + if (dom) +@@ -6790,6 +6844,7 @@ static const vshCmdInfo info_detach_disk + static const vshCmdOptDef opts_detach_disk[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, + {"target", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("target of disk device")}, ++ {"persistent", VSH_OT_BOOL, 0, gettext_noop("persist disk detachment")}, + {NULL, 0, 0, NULL} + }; + +@@ -6805,6 +6860,7 @@ cmdDetachDisk(vshControl *ctl, const vsh + virDomainPtr dom = NULL; + char *doc, *target; + int i = 0, diff_tgt, ret = FALSE; ++ unsigned int flags; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + goto cleanup; +@@ -6870,10 +6926,21 @@ cmdDetachDisk(vshControl *ctl, const vsh + goto cleanup; + } + +- ret = virDomainDetachDevice(dom, (char *)xmlBufferContent(xml_buf)); +- if (ret != 0) ++ if (vshCommandOptBool(cmd, "persistent")) { ++ flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; ++ if (virDomainIsActive(dom) == 1) ++ flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; ++ ret = virDomainDetachDeviceFlags(dom, ++ (char *)xmlBufferContent(xml_buf), ++ flags); ++ } else { ++ ret = virDomainDetachDevice(dom, (char *)xmlBufferContent(xml_buf)); ++ } ++ ++ if (ret != 0) { ++ vshError(ctl, _("Failed to detach disk")); + ret = FALSE; +- else { ++ } else { + vshPrint(ctl, "%s", _("Disk detached successfully\n")); + ret = TRUE; + } diff --git a/libvirt.changes b/libvirt.changes index 8303ac2..d4ac313 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,23 @@ +------------------------------------------------------------------- +Wed Jan 27 17:48:18 MST 2010 - jfehlig@novell.com + +- Support new XEN_SYSCTL_INTERFACE_VERSION 7 in libvirt + bnc#574124 + xen-sysctl-v7.patch +- Add upstream patches as prelude to fixing various device + attach/detach issues + devflag-0[1-9].patch +- Fix attaching/detaching disk device from inactive Xen guest + bnc#500586 and bnc#573748 + +------------------------------------------------------------------- +Tue Jan 12 12:36:15 MST 2010 - jfehlig@novell.com + +- Fix migration with Xen4.0 + bnc#569598 + Add xen-migration-params.patch + Remove migrate-params.patch + ------------------------------------------------------------------- Wed Jan 6 18:02:00 MST 2010 - jfehlig@novell.com diff --git a/libvirt.spec b/libvirt.spec index eca333d..7a06f79 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -137,14 +137,24 @@ Requires: PolicyKit >= 0.6 Source0: %{name}-%{version}.tar.bz2 Source1: libvirtd.init # Upstream patches -Patch0: detach-disk.patch -Patch1: xen-shr-pages.patch -Patch2: node-dev-free.patch +Patch0: xen-shr-pages.patch +Patch1: node-dev-free.patch +Patch2: xen-migration-params.patch +Patch3: xen-sysctl-v7.patch +Patch4: devflag-01.patch +Patch5: devflag-02.patch +Patch6: devflag-03.patch +Patch7: devflag-04.patch +Patch8: devflag-05.patch +Patch9: devflag-06.patch +Patch10: devflag-07.patch +Patch11: devflag-08.patch +Patch12: devflag-09.patch +Patch13: xen-name-for-devid.patch # Need to go upstream Patch100: socat.patch Patch101: clone.patch -Patch102: migrate-params.patch -Patch103: xen-pv-cdrom.patch +Patch102: xen-pv-cdrom.patch # Our patches Patch200: libvirtd-defaults.patch Patch201: suse-network.patch @@ -255,10 +265,20 @@ Authors: %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 %patch100 -p1 %patch101 %patch102 -p1 -%patch103 -p1 %patch200 -p1 %patch201 -p1 %patch202 -p1 diff --git a/migrate-params.patch b/migrate-params.patch deleted file mode 100644 index 70585c9..0000000 --- a/migrate-params.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: libvirt-0.7.5/src/xen/xend_internal.c -=================================================================== ---- libvirt-0.7.5.orig/src/xen/xend_internal.c -+++ libvirt-0.7.5/src/xen/xend_internal.c -@@ -4559,6 +4559,8 @@ xenDaemonDomainMigratePerform (virDomain - "node", "-1", - "ssl", "0", - "resource", "0", /* required, xend ignores it */ -+ "node", "-1", /* numa node, xen c/s 17753 */ -+ "ssl", "0", /* ssl migration, xen c/s 17709 */ - NULL); - VIR_FREE (hostname); - diff --git a/snapshots.patch b/snapshots.patch index b6ba9da..a484d07 100644 --- a/snapshots.patch +++ b/snapshots.patch @@ -221,7 +221,7 @@ Index: libvirt-0.7.5/src/driver.h (*virDrvDomainCoreDump) (virDomainPtr domain, const char *to, int flags); -@@ -448,6 +463,11 @@ struct _virDriver { +@@ -458,6 +473,11 @@ struct _virDriver { virDrvDomainIsActive domainIsActive; virDrvDomainIsPersistent domainIsPersistent; virDrvCPUCompare cpuCompare; @@ -319,7 +319,7 @@ Index: libvirt-0.7.5/src/xen/xen_driver.c xenUnifiedDomainCoreDump (virDomainPtr dom, const char *to, int flags) { GET_PRIVATE(dom->conn); -@@ -1862,6 +1937,11 @@ static virDriver xenUnifiedDriver = { +@@ -1902,6 +1977,11 @@ static virDriver xenUnifiedDriver = { xenUnifiedDomainIsActive, xenUnifiedDomainisPersistent, NULL, /* cpuCompare */ @@ -364,7 +364,7 @@ Index: libvirt-0.7.5/src/xen/xend_internal.c /* * The number of Xen scheduler parameters */ -@@ -3282,6 +3288,87 @@ xenDaemonDomainRestore(virConnectPtr con +@@ -3283,6 +3289,87 @@ xenDaemonDomainRestore(virConnectPtr con } return xend_op(conn, "", "op", "restore", "file", filename, NULL); } @@ -452,7 +452,7 @@ Index: libvirt-0.7.5/src/xen/xend_internal.c #endif /* !PROXY */ /** -@@ -5165,6 +5252,11 @@ struct xenUnifiedDriver xenDaemonDriver +@@ -5234,6 +5321,11 @@ struct xenUnifiedDriver xenDaemonDriver xenDaemonGetSchedulerType, /* domainGetSchedulerType */ xenDaemonGetSchedulerParameters, /* domainGetSchedulerParameters */ xenDaemonSetSchedulerParameters, /* domainSetSchedulerParameters */ @@ -500,7 +500,7 @@ Index: libvirt-0.7.5/src/xen/xm_internal.c =================================================================== --- libvirt-0.7.5.orig/src/xen/xm_internal.c +++ libvirt-0.7.5/src/xen/xm_internal.c -@@ -116,6 +116,11 @@ struct xenUnifiedDriver xenXMDriver = { +@@ -118,6 +118,11 @@ struct xenUnifiedDriver xenXMDriver = { NULL, /* domainGetSchedulerType */ NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ @@ -721,7 +721,7 @@ Index: libvirt-0.7.5/tools/virsh.c * "schedinfo" command */ static const vshCmdInfo info_schedinfo[] = { -@@ -7431,6 +7613,12 @@ static const vshCmdDef commands[] = { +@@ -7498,6 +7680,12 @@ static const vshCmdDef commands[] = { {"undefine", cmdUndefine, opts_undefine, info_undefine}, {"uri", cmdURI, NULL, info_uri}, @@ -738,7 +738,7 @@ Index: libvirt-0.7.5/src/lxc/lxc_driver.c =================================================================== --- libvirt-0.7.5.orig/src/lxc/lxc_driver.c +++ libvirt-0.7.5/src/lxc/lxc_driver.c -@@ -2456,6 +2456,11 @@ static virDriver lxcDriver = { +@@ -2458,6 +2458,11 @@ static virDriver lxcDriver = { lxcDomainIsActive, lxcDomainIsPersistent, NULL, /* cpuCompare */ @@ -754,7 +754,7 @@ Index: libvirt-0.7.5/src/openvz/openvz_driver.c =================================================================== --- libvirt-0.7.5.orig/src/openvz/openvz_driver.c +++ libvirt-0.7.5/src/openvz/openvz_driver.c -@@ -1535,6 +1535,11 @@ static virDriver openvzDriver = { +@@ -1537,6 +1537,11 @@ static virDriver openvzDriver = { openvzDomainIsActive, openvzDomainIsPersistent, NULL, /* cpuCompare */ @@ -770,7 +770,7 @@ Index: libvirt-0.7.5/src/qemu/qemu_driver.c =================================================================== --- libvirt-0.7.5.orig/src/qemu/qemu_driver.c +++ libvirt-0.7.5/src/qemu/qemu_driver.c -@@ -7990,6 +7990,11 @@ static virDriver qemuDriver = { +@@ -8016,6 +8016,11 @@ static virDriver qemuDriver = { qemuDomainIsActive, qemuDomainIsPersistent, qemuCPUCompare, /* cpuCompare */ @@ -786,7 +786,7 @@ Index: libvirt-0.7.5/src/esx/esx_driver.c =================================================================== --- libvirt-0.7.5.orig/src/esx/esx_driver.c +++ libvirt-0.7.5/src/esx/esx_driver.c -@@ -3455,6 +3455,11 @@ static virDriver esxDriver = { +@@ -3457,6 +3457,11 @@ static virDriver esxDriver = { esxDomainIsActive, /* domainIsActive */ esxDomainIsPersistent, /* domainIsPersistent */ NULL, /* cpuCompare */ @@ -802,7 +802,7 @@ Index: libvirt-0.7.5/src/test/test_driver.c =================================================================== --- libvirt-0.7.5.orig/src/test/test_driver.c +++ libvirt-0.7.5/src/test/test_driver.c -@@ -5238,6 +5238,11 @@ static virDriver testDriver = { +@@ -5240,6 +5240,11 @@ static virDriver testDriver = { testDomainIsActive, /* domainIsActive */ testDomainIsPersistent, /* domainIsPersistent */ NULL, /* cpuCompare */ @@ -818,7 +818,7 @@ Index: libvirt-0.7.5/src/uml/uml_driver.c =================================================================== --- libvirt-0.7.5.orig/src/uml/uml_driver.c +++ libvirt-0.7.5/src/uml/uml_driver.c -@@ -1924,6 +1924,11 @@ static virDriver umlDriver = { +@@ -1926,6 +1926,11 @@ static virDriver umlDriver = { umlDomainIsActive, umlDomainIsPersistent, NULL, /* cpuCompare */ @@ -834,7 +834,7 @@ Index: libvirt-0.7.5/src/vbox/vbox_tmpl.c =================================================================== --- libvirt-0.7.5.orig/src/vbox/vbox_tmpl.c +++ libvirt-0.7.5/src/vbox/vbox_tmpl.c -@@ -7051,6 +7051,11 @@ virDriver NAME(Driver) = { +@@ -7075,6 +7075,11 @@ virDriver NAME(Driver) = { vboxDomainIsActive, vboxDomainIsPersistent, NULL, /* cpuCompare */ @@ -850,7 +850,7 @@ Index: libvirt-0.7.5/src/opennebula/one_driver.c =================================================================== --- libvirt-0.7.5.orig/src/opennebula/one_driver.c +++ libvirt-0.7.5/src/opennebula/one_driver.c -@@ -783,6 +783,11 @@ static virDriver oneDriver = { +@@ -785,6 +785,11 @@ static virDriver oneDriver = { NULL, /* domainIsActive */ NULL, /* domainIsPersistent */ NULL, /* cpuCompare */ @@ -866,7 +866,7 @@ Index: libvirt-0.7.5/src/phyp/phyp_driver.c =================================================================== --- libvirt-0.7.5.orig/src/phyp/phyp_driver.c +++ libvirt-0.7.5/src/phyp/phyp_driver.c -@@ -1651,6 +1651,11 @@ virDriver phypDriver = { +@@ -1653,6 +1653,11 @@ virDriver phypDriver = { NULL, /* domainIsActive */ NULL, /* domainIsPersistent */ NULL, /* cpuCompare */ @@ -882,7 +882,7 @@ Index: libvirt-0.7.5/src/remote/remote_driver.c =================================================================== --- libvirt-0.7.5.orig/src/remote/remote_driver.c +++ libvirt-0.7.5/src/remote/remote_driver.c -@@ -8940,6 +8940,11 @@ static virDriver remote_driver = { +@@ -8994,6 +8994,11 @@ static virDriver remote_driver = { remoteDomainIsActive, /* domainIsActive */ remoteDomainIsPersistent, /* domainIsPersistent */ remoteCPUCompare, /* cpuCompare */ diff --git a/xen-migration-params.patch b/xen-migration-params.patch new file mode 100644 index 0000000..10eab1d --- /dev/null +++ b/xen-migration-params.patch @@ -0,0 +1,49 @@ +From 8e53215d5a73d88cceab0040b27529e4f547e74d Mon Sep 17 00:00:00 2001 +From: Jim Fehlig +Date: Tue, 12 Jan 2010 11:18:34 -0700 +Subject: [PATCH] Fix migration in xend driver + +Upstream xen has changed parameters to the migration operation +several times over the past 18 months. Changeset 17553 removed +the resouce parameter, Changesets 17709, 17753, and 20326 added +ssl, node, and change_home_server parameters respectively. + +Fortunately, testing has revealed that xend will fail the +operation if a parameter is missing but happily honor it if +unknown parameters are provided. Thus all currently supported +parameters can be provided, satisfying current xend but not +regressing older versions. +--- + src/xen/xend_internal.c | 14 ++++++++++---- + 1 files changed, 10 insertions(+), 4 deletions(-) + +Index: libvirt-0.7.5/src/xen/xend_internal.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xend_internal.c ++++ libvirt-0.7.5/src/xen/xend_internal.c +@@ -4552,15 +4552,21 @@ xenDaemonDomainMigratePerform (virDomain + + DEBUG("hostname = %s, port = %s", hostname, port); + +- /* Make the call. */ ++ /* Make the call. ++ * NB: xend will fail the operation if any parameters are ++ * missing but happily accept unknown parameters. This works ++ * to our advantage since all parameters supported and required ++ * by current xend can be included without breaking older xend. ++ */ + ret = xend_op (domain->conn, domain->name, + "op", "migrate", + "destination", hostname, + "live", live, + "port", port, +- "node", "-1", +- "ssl", "0", +- "resource", "0", /* required, xend ignores it */ ++ "node", "-1", /* xen-unstable c/s 17753 */ ++ "ssl", "0", /* xen-unstable c/s 17709 */ ++ "change_home_server", "0", /* xen-unstable c/s 20326 */ ++ "resource", "0", /* removed by xen-unstable c/s 17553 */ + NULL); + VIR_FREE (hostname); + diff --git a/xen-name-for-devid.patch b/xen-name-for-devid.patch new file mode 100644 index 0000000..c62b7f4 --- /dev/null +++ b/xen-name-for-devid.patch @@ -0,0 +1,100 @@ +commit 7906a668fa8d5c21cc729db8a13b08e3dd1d241f +Author: Jim Fehlig +Date: Wed Jan 27 16:11:41 2010 -0700 + + Do not search xenstore for disk device IDs + + Disk devices can be referenced by name in Xen, e.g. when modifying + their configuration or remvoving them. As such, don't search + xenstore for a device ID corresponding to the disk device. Instead, + search the disks contained in the domain definition and use the + disk's target name if found. + + This approach allows removing a disk when domain is inactive. We + obviously can't search xenstore when the domain is inactive. + +Index: libvirt-0.7.5/src/xen/xend_internal.c +=================================================================== +--- libvirt-0.7.5.orig/src/xen/xend_internal.c ++++ libvirt-0.7.5/src/xen/xend_internal.c +@@ -93,6 +93,7 @@ xenDaemonFormatSxprOnePCI(virConnectPtr + + static int + virDomainXMLDevID(virDomainPtr domain, ++ virDomainDefPtr domDef, + virDomainDeviceDefPtr dev, + char *class, + char *ref, +@@ -4214,7 +4215,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr + + sexpr = virBufferContentAndReset(&buf); + +- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) { ++ if (virDomainXMLDevID(domain, def, dev, class, ref, sizeof(ref))) { + /* device doesn't exist, define it */ + ret = xend_op(domain->conn, domain->name, "op", "device_create", + "config", sexpr, NULL); +@@ -4309,7 +4310,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr + def, xml, VIR_DOMAIN_XML_INACTIVE))) + goto cleanup; + +- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) ++ if (virDomainXMLDevID(domain, def, dev, class, ref, sizeof(ref))) + goto cleanup; + + if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { +@@ -6051,6 +6052,7 @@ error: + */ + static int + virDomainXMLDevID(virDomainPtr domain, ++ virDomainDefPtr domDef, + virDomainDeviceDefPtr dev, + char *class, + char *ref, +@@ -6059,27 +6061,33 @@ virDomainXMLDevID(virDomainPtr domain, + xenUnifiedPrivatePtr priv = domain->conn->privateData; + char *xref; + char *tmp; ++ unsigned int i; ++ virDomainDiskDefPtr disk; + + if (dev->type == VIR_DOMAIN_DEVICE_DISK) { ++ if (dev->data.disk->dst == NULL) ++ return -1; + if (dev->data.disk->driverName && + STREQ(dev->data.disk->driverName, "tap")) + strcpy(class, "tap"); + else + strcpy(class, "vbd"); + +- if (dev->data.disk->dst == NULL) +- return -1; +- xenUnifiedLock(priv); +- xref = xenStoreDomainGetDiskID(domain->conn, domain->id, +- dev->data.disk->dst); +- xenUnifiedUnlock(priv); +- if (xref == NULL) +- return -1; +- +- tmp = virStrcpy(ref, xref, ref_len); +- VIR_FREE(xref); +- if (tmp == NULL) +- return -1; ++ /* For disks, the device name can be used directly. ++ * If disk device exists in domain definintion, ++ * copy it to ref and return success. ++ */ ++ for (i = 0; i < domDef->ndisks; i++) { ++ disk = domDef->disks[i]; ++ if (STREQ(dev->data.disk->dst, disk->dst)) { ++ tmp = virStrcpy(ref, disk->dst, ref_len); ++ if (tmp == NULL) ++ return -1; ++ else ++ return 0; ++ } ++ } ++ return -1; + } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { + char mac[30]; + virDomainNetDefPtr def = dev->data.net; diff --git a/xen-pv-cdrom.patch b/xen-pv-cdrom.patch index b174db7..a7a5a92 100644 --- a/xen-pv-cdrom.patch +++ b/xen-pv-cdrom.patch @@ -2,7 +2,7 @@ Index: libvirt-0.7.5/src/xen/xend_internal.c =================================================================== --- libvirt-0.7.5.orig/src/xen/xend_internal.c +++ libvirt-0.7.5/src/xen/xend_internal.c -@@ -5409,7 +5409,10 @@ xenDaemonFormatSxprDisk(virConnectPtr co +@@ -5478,7 +5478,10 @@ xenDaemonFormatSxprDisk(virConnectPtr co } else if (def->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { virBufferVSprintf(buf, "(dev '%s:cdrom')", def->dst); } else { diff --git a/xen-sysctl-v7.patch b/xen-sysctl-v7.patch new file mode 100644 index 0000000..04ee7c5 --- /dev/null +++ b/xen-sysctl-v7.patch @@ -0,0 +1,38 @@ +commit 3bd3d6b0bf9b8f054a8b31c716f03e2d0dd8751f +Author: Jim Fehlig +Date: Wed Jan 27 10:56:18 2010 -0700 + + Support Xen 4.0 sysctl version 7 + + xen-unstable c/s 20762 bumped XEN_SYSCTL_INTERFACE_VERSION to 7. The + interface change does not affect libvirt, other than xenHypervisorInit() + failing since version 7 is not tried. + + The attached patch accommodates the upcoming Xen 4.0 release by checking + for XEN_SYSCTL_INTERFACE_VERSION 7. If found, it sets + XEN_DOMCTL_INTERFACE_VERSION to 6, which is also new to Xen 4.0. + +diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c +index 6d8accc..7f39095 100644 +--- a/src/xen/xen_hypervisor.c ++++ b/src/xen/xen_hypervisor.c +@@ -2100,12 +2100,14 @@ xenHypervisorInit(void) + DEBUG0("Using hypervisor call v2, sys ver6 dom ver5\n"); + goto done; + } +- /* Xen 4.0 */ ++ } ++ ++ /* Xen 4.0 */ ++ sys_interface_version = 7; /* XEN_SYSCTL_INTERFACE_VERSION */ ++ if (virXen_getdomaininfo(fd, 0, &info) == 1) { + dom_interface_version = 6; /* XEN_DOMCTL_INTERFACE_VERSION */ +- if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){ +- DEBUG0("Using hypervisor call v2, sys ver6 dom ver6\n"); +- goto done; +- } ++ DEBUG0("Using hypervisor call v2, sys ver7 dom ver6\n"); ++ goto done; + } + + hypervisor_version = 1;