Re: [libvirt] [PATCH 00/20] flags cleanup
2011/7/7 Eric Blake ebl...@redhat.com: On 07/06/2011 05:23 PM, Eric Blake wrote: Inspired in part by Laine's recent cleanup of qemuDomainGetXMLDesc, in part by my desire to add a new flag to virDomainCoreDump and test that older clients reject that flag, and in part by an OCD desire for uniformity :), I'm proposing this giant patch series. And yes, I'm working on a patch 21/20 to cfg.mk to enforce this style in the future, but ran out of time today. I'm afraid that you're going to break stuff with this series. For example the patch for the ESX driver breaks opening a read-only connection as you made esxOpen reject VIR_CONNECT_RO. Yes, the ESX driver has no means to support a truly read-only connection as you always need to provide credentials, so one can consider this a bugfix or a regression depending on the point-of-view. -- Matthias Bolte http://photron.blogspot.com -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/4] support the listenNetwork attribute in graphics
This patch series resolves the following bug: https://bugzilla.redhat.com/show_bug.cgi?id=703851 In short, it implements support for a new listenNetwork attribute in the domain's graphics element. When listenNetwork is specified, libvirt will look for a network of that name (from the networks that can be created within libvirt), and derive a listen address from the physical interface used to connect that network to the outside world. (More details are given in each commit message). This patch series is meant to be applied on top of the series I sent on Tuesday: network: physical device abstraction aka 'virtual switch' https://www.redhat.com/archives/libvir-list/2011-July/msg00149.html Don't attempt to apply it by itself! Note that I'm not particularly fond of the attribute name (it's too long and has the ugly capital letter in the middle). If anyone has a suggestion for something better, please give your opinion now, before it's pushed and becomes permanent! -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/4] util: add an ifaceGetIPAddress to the interface utilies
This function uses ioctl(SIOCGIFADDR), which limits it to returning the first IPv4 address of an interface, but that's what we want right now (the place we're going to use the address only accepts one). --- src/libvirt_private.syms |1 + src/util/interface.c | 60 ++ src/util/interface.h |3 ++ 3 files changed, 64 insertions(+), 0 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4ef20bc..f89d92e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -506,6 +506,7 @@ ifaceCtrl; ifaceGetFlags; ifaceGetIndex; ifaceGetMacAddress; +ifaceGetIPAddress; ifaceGetNthParent; ifaceGetVlanID; ifaceIsUp; diff --git a/src/util/interface.c b/src/util/interface.c index 837ecce..a714bad 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -29,6 +29,7 @@ #include sys/socket.h #include sys/ioctl.h #include fcntl.h +#include netinet/in.h #ifdef __linux__ # include linux/if.h @@ -511,6 +512,65 @@ ifaceSetMacAddress(const char *ifname ATTRIBUTE_UNUSED, /** + * ifaceGetIPAddress: + * @ifname: name of the interface whose IP address we want + * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * + * This function gets the @macaddr for a given interface @ifname. + * + * Returns 0 in case of success or an errno code in case of failure. + */ +#ifdef __linux__ +int +ifaceGetIPAddress(const char *ifname, + virSocketAddrPtr addr) +{ +struct ifreq ifr; +int fd; +int rc = 0; + +if (!ifname || !addr) +return EINVAL; + +memset (addr, 0, sizeof(*addr)); +addr-data.stor.ss_family = AF_UNSPEC; + +fd = socket(AF_INET, SOCK_STREAM, 0); +if (fd 0) +return errno; + +memset(ifr, 0, sizeof(struct ifreq)); +if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { +rc = EINVAL; +goto err_exit; +} + +if (ioctl(fd, SIOCGIFADDR, (char *)ifr) != 0) { +rc = errno; +goto err_exit; +} + +addr-data.stor.ss_family = AF_INET; +addr-len = sizeof(addr-data.inet4); +memcpy(addr-data.inet4, ifr.ifr_addr, addr-len); + +err_exit: +VIR_FORCE_CLOSE(fd); +return rc; +} + +#else + +int +ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, + virSocketAddrPtr addr ATTRIBUTE_UNUSED) +{ +return ENOSYS; +} + +#endif /* __linux__ */ + +/** * ifaceLinkAdd * * @type: The type of device, i.e., macvtap diff --git a/src/util/interface.h b/src/util/interface.h index 5cbf5c1..9647653 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -24,6 +24,7 @@ struct nlattr; # endif # include datatypes.h +# include network.h int ifaceGetFlags(const char *name, short *flags); int ifaceIsUp(const char *name, bool *up); @@ -49,6 +50,8 @@ int ifaceSetMacAddress(const char *ifname, const unsigned char *macaddr); int ifaceGetMacAddress(const char *ifname, unsigned char *macaddr); +int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); + int ifaceMacvtapLinkAdd(const char *type, const unsigned char *macaddress, int macaddrsize, const char *ifname, -- 1.7.3.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] network: provide internal API to return IP of a network
The new listenNetwork atribute needs to learn an IP address based on a named network. This patch provides a function networkGetNetworkAddress which provides that. Some networks have an IP address explicitly in their configuration (ie, those with a forward type of none, route, or nat). For those, we can just return the IP address from the config. The rest will have a physical device associated with them (either via bridge name='...'/, forward ... dev='...'/, or possibly via a pool of interfaces inside the network's forward element) and we will need to ask the kernel for the current IP address of that device (via the newly added ifaceGetIPAddress --- src/libvirt_network.syms|1 + src/network/bridge_driver.c | 98 +++ src/network/bridge_driver.h |2 + 3 files changed, 101 insertions(+), 0 deletions(-) diff --git a/src/libvirt_network.syms b/src/libvirt_network.syms index e402b5f..1fe8902 100644 --- a/src/libvirt_network.syms +++ b/src/libvirt_network.syms @@ -5,5 +5,6 @@ # bridge_driver.h networkAllocateActualDevice; networkBuildDhcpDaemonCommandLine; +networkGetNetworkAddress; networkNotifyActualDevice; networkReleaseActualDevice; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 56c77f2..a7453ea 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -55,6 +55,7 @@ #include uuid.h #include iptables.h #include bridge.h +#include interface.h #include logging.h #include dnsmasq.h #include util/network.h @@ -3102,3 +3103,100 @@ cleanup: iface-data.network.actual = NULL; return ret; } + +/* + * networkGetNetworkAddress: + * @netname: the name of a network + * + * Attempt to return the IP (v4) address associated with the named + * network. If a libvirt virtual network, that will be provided in the + * configuration. For host bridge and direct (macvtap) networks, we + * must do an ioctl to learn the address. + * + * Note: This function returns the 1st IPv4 address it finds. It might + * be useful if it was more flexible, but the current use (getting a + * listen address for qemu's vnc/spice graphics server) can only use a + * single address anyway. + * + * Returns a string (which must be free'd by the caller) on success, + * or NULL on failure. + */ +char * +networkGetNetworkAddress(const char *netname) +{ +struct network_driver *driver = driverState; +virNetworkObjPtr network = NULL; +virNetworkDefPtr netdef; +virNetworkIpDefPtr ipdef; +virSocketAddr addr; +virSocketAddrPtr addrptr = NULL; +char *devname = NULL; +char *addrstr = NULL; + +networkDriverLock(driver); +network = virNetworkFindByName(driver-networks, netname); +networkDriverUnlock(driver); +if (!network) { +networkReportError(VIR_ERR_NO_NETWORK, + _(no network with matching name '%s'), + netname); +goto cleanup; +} +netdef = network-def; + +switch (netdef-forwardType) { +case VIR_NETWORK_FORWARD_NONE: +case VIR_NETWORK_FORWARD_NAT: +case VIR_NETWORK_FORWARD_ROUTE: +/* if there's an ipv4def, get it's address */ +ipdef = virNetworkDefGetIpByIndex(netdef, AF_INET, 0); +if (!ipdef) { +networkReportError(VIR_ERR_INTERNAL_ERROR, + _(network '%s' doesn't have an IP address), + netdef-name); +break; +} +addrptr = ipdef-address; +break; + +case VIR_NETWORK_FORWARD_BRIDGE: +if ((devname = netdef-bridge)) +break; +/* + * If netdef-bridge wasn't set, this is a direct-mode + * interface, so purposefully drop through to the next case + */ +case VIR_NETWORK_FORWARD_PRIVATE: +case VIR_NETWORK_FORWARD_VEPA: +case VIR_NETWORK_FORWARD_PASSTHROUGH: +if (netdef-nForwardIfs == 0) +devname = netdef-forwardDev; +else if (netdef-forwardIfs) +devname = netdef-forwardIfs[0].dev; + +if (!devname) { +networkReportError(VIR_ERR_INTERNAL_ERROR, + _(network '%s' has no associated interface or bridge), + netdef-name); +} +break; +} + +if (devname) { +if (ifaceGetIPAddress(devname, addr)) { +virReportSystemError(errno, + _(Failed to get IP address for '%s' (network '%s')), + devname, netdef-name); +} else { +addrptr = addr; +} +} + +if (addrptr) +addrstr = virSocketFormatAddr(addrptr); + +cleanup: +if (network) +virNetworkObjUnlock(network); +return addrstr; +} diff --git a/src/network/bridge_driver.h b/src/network/bridge_driver.h index 4f6a54d..3c76af2 100644 --- a/src/network/bridge_driver.h +++ b/src/network/bridge_driver.h @@ -39,6
[libvirt] [PATCH 3/4] conf: add listenNetwork attribute to domain graphics element
Once it's plugged in, listenNetwork will be an optional replacement for the listen attribute. While listen can be a host name or IP address, listenNetwork names one of the networks managed by libvirt (with virNetwork*()/visrh net-*). --- docs/schemas/domain.rng | 33 +-- src/conf/domain_conf.c | 67 +++--- src/conf/domain_conf.h |3 ++ 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 65572df..deefe4f 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1235,9 +1235,14 @@ /attribute /optional optional -attribute name=listen - ref name=addrIPorName/ -/attribute +choice + attribute name=listen +ref name=addrIPorName/ + /attribute + attribute name=listenNetwork +text/ + /attribute +/choice /optional /group group @@ -1287,9 +1292,14 @@ /attribute /optional optional -attribute name=listen - ref name=addrIPorName/ -/attribute +choice + attribute name=listen +ref name=addrIPorName/ + /attribute + attribute name=listenNetwork +text/ + /attribute +/choice /optional optional attribute name=passwd @@ -1439,9 +1449,14 @@ /attribute /optional optional -attribute name=listen - ref name=addrIPorName/ -/attribute +choice + attribute name=listen +ref name=addrIPorName/ + /attribute + attribute name=listenNetwork +text/ + /attribute +/choice /optional /group group diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f7a2689..eb9224d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -617,6 +617,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) switch (def-type) { case VIR_DOMAIN_GRAPHICS_TYPE_VNC: VIR_FREE(def-data.vnc.listenAddr); +VIR_FREE(def-data.vnc.listenNetwork); VIR_FREE(def-data.vnc.socket); VIR_FREE(def-data.vnc.keymap); virDomainGraphicsAuthDefClear(def-data.vnc.auth); @@ -629,6 +630,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) case VIR_DOMAIN_GRAPHICS_TYPE_RDP: VIR_FREE(def-data.rdp.listenAddr); +VIR_FREE(def-data.rdp.listenNetwork); break; case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: @@ -637,6 +639,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: VIR_FREE(def-data.spice.listenAddr); +VIR_FREE(def-data.spice.listenNetwork); VIR_FREE(def-data.spice.keymap); virDomainGraphicsAuthDefClear(def-data.spice.auth); break; @@ -4031,13 +4034,22 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { } def-data.vnc.listenAddr = virXMLPropString(node, listen); -def-data.vnc.socket = virXMLPropString(node, socket); -def-data.vnc.keymap = virXMLPropString(node, keymap); +if (def-data.vnc.listenAddr !def-data.vnc.listenAddr[0]) +VIR_FREE(def-data.vnc.listenAddr); -if (def-data.vnc.listenAddr -!def-data.vnc.listenAddr[0]) +def-data.vnc.listenNetwork = virXMLPropString(node, listenNetwork); +if (def-data.vnc.listenNetwork !def-data.vnc.listenNetwork[0]) VIR_FREE(def-data.vnc.listenAddr); +if (def-data.vnc.listenAddr def-data.vnc.listenNetwork) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + %s, _(Both listen and listenNetwork given in graphics element)); +goto error; +} + +def-data.vnc.socket = virXMLPropString(node, socket); +def-data.vnc.keymap = virXMLPropString(node, keymap); + if (virDomainGraphicsAuthDefParseXML(node, def-data.vnc.auth) 0) goto error; } else if (def-type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { @@ -4102,10 +4114,19 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { } def-data.rdp.listenAddr = virXMLPropString(node, listen); - -if (def-data.rdp.listenAddr -!def-data.rdp.listenAddr[0]) +if (def-data.rdp.listenAddr !def-data.rdp.listenAddr[0]) VIR_FREE(def-data.rdp.listenAddr); + +def-data.rdp.listenNetwork = virXMLPropString(node, listenNetwork); +if (def-data.rdp.listenNetwork
[libvirt] [PATCH 4/4] qemu: support the listenNetwork attribute in graphics
The domain XML now understands an attribute named listenNetwork in the graphics element, and the network driver has an internal API that will turn a network name into an IP address, so the final logical step is to put the glue into the qemu driver such that when it is starting up a domain, if it finds listenNetwork in the XML, it will call the network driver to get an associated IP address, and tell qemu to listen for vnc (or spice) on that address rather than the default (localhost). The motivation for this is that a large installation may want the guests' VNC servers listening on physical interfaces rather than localhost, so that users can connect directly from the outside; this requires sending qemu the appropriate IP address to listen on. But this address will of course be different for each host, and if a guest might be migrated around from one host to another, it's important that the guest's config not have any information embedded in it that is specific to one particular host. listenNetwork can solve this problem in the following manner: 1) on each host, define a libvirt network of the same name, associated with some interface on that host (for example, a simple macvtap network: forward mode='bridge' dev='eth0'/, or host bridge network: forward mode='bridge'/ bridge name='br0'/ 2) in the graphics element of each guest's domain xml, tell vnc to listen on the network name used in step 1: graphics type='vnc' autoport='yes' listenNetwork='example-net'/ (all the above also applies for graphics type='spice'). Since this is the commit that turns on the new functionality, I've included the doc changes here. --- docs/formatdomain.html.in | 22 ++--- src/qemu/qemu_command.c | 56 - src/qemu/qemu_hotplug.c | 12 + 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 10d87a9..626d163 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1890,8 +1890,15 @@ qemu-kvm -net nic,model=? /dev/null auto-allocated). The codeautoport/code attribute is the new preferred syntax for indicating autoallocation of the TCP port to use. The codelisten/code attribute is -an IP address for the server to listen -on. The codepasswd/code attribute provides a VNC +an IP address for the server to listen on. +Alternately, a codelistenNetwork/code attribute can be +specified insteadspan class=sinceSince 0.9.4/span; +the named network will be looked up in the list of +networks managed by libvirt and, if found, the VNC server +will listen on the IP address associated with the physical +device used by that network (e.g. the bridge device or the +direct mode forward codedev/code). +The codepasswd/code attribute provides a VNC password in clear text. The codekeymap/code attribute specifies the keymap to use. It is possible to set a limit on the validity of the password be giving an @@ -1912,8 +1919,15 @@ qemu-kvm -net nic,model=? /dev/null port number. The codeautoport/code attribute is the new preferred syntax for indicating autoallocation of both port numbers. The codelisten/code attribute is - an IP address for the server to listen - on. The codepasswd/code attribute provides a SPICE + an IP address for the server to listen on. + Alternately, a codelistenNetwork/code attribute can be + specified insteadspan class=sinceSince 0.9.4/span; + the named network will be looked up in the list of + networks managed by libvirt and, if found, the VNC server + will listen on the IP address associated with the physical + device used by that network (e.g. the bridge device or the + direct mode forward codedev/code). + The codepasswd/code attribute provides a SPICE password in clear text. The codekeymap/code attribute specifies the keymap to use. It is possible to set a limit on the validity of the password be giving an diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0b957cb..89b0da0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4097,16 +4097,40 @@ qemuBuildCommandLine(virConnectPtr conn, def-graphics[0]-data.vnc.socket); } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) { -const char *addr = def-graphics[0]-data.vnc.listenAddr ? -def-graphics[0]-data.vnc.listenAddr : -driver-vncListen; -bool escapeAddr = strchr(addr, ':') != NULL; +const char *addr; +
[libvirt] [PATCH] python: Fix bogus label placement
--- python/libvirt-override.c |8 +++- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 8be9af7..2b88796 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -1489,13 +1489,12 @@ libvirt_virNodeGetCellsFreeMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *arg return(NULL); if ((startCell 0) || (maxCells = 0) || (startCell + maxCells 1)) -goto error; +return VIR_PY_NONE; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); -freeMems = -malloc(maxCells * sizeof(*freeMems)); +freeMems = malloc(maxCells * sizeof(*freeMems)); if (freeMems == NULL) -goto error; +return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeGetCellsFreeMemory(conn, freeMems, startCell, maxCells); @@ -1503,7 +1502,6 @@ libvirt_virNodeGetCellsFreeMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *arg if (c_retval 0) { free(freeMems); -error: return VIR_PY_NONE; } py_retval = PyList_New(c_retval); -- 1.7.4.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] vbox: Fix logic in storage driver open function
If the main driver is the vbox driver, then the open function has to return an error if the private data is invalid. --- src/vbox/vbox_tmpl.c |7 ++- 1 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 37fe248..dfa676e 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -7753,19 +7753,16 @@ static virDrvOpenStatus vboxStorageOpen (virConnectPtr conn, vboxGlobalData *data = conn-privateData; if (STRNEQ(conn-driver-name, VBOX)) -goto cleanup; +return VIR_DRV_OPEN_DECLINED; if ((data-pFuncs == NULL) || (data-vboxObj == NULL) || (data-vboxSession == NULL)) -goto cleanup; +return VIR_DRV_OPEN_ERROR; VIR_DEBUG(vbox storage initialized); /* conn-storagePrivateData = some storage specific data */ return VIR_DRV_OPEN_SUCCESS; - -cleanup: -return VIR_DRV_OPEN_DECLINED; } static int vboxStorageClose (virConnectPtr conn) { -- 1.7.4.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Remove duplicate empty lines and correct indentation and style
No functional change included. --- python/libvirt-override.c |1 - src/conf/domain_conf.c|1 - src/conf/interface_conf.c |1 - src/conf/network_conf.c |1 - src/conf/node_device_conf.c |4 - src/conf/storage_conf.c |1 - src/interface/netcf_driver.c | 16 ++ src/libxl/libxl_driver.c |2 +- src/lxc/lxc_driver.c |2 +- src/node_device/node_device_driver.c |2 - src/node_device/node_device_linux_sysfs.c |2 - src/nwfilter/nwfilter_ebiptables_driver.c |2 - src/openvz/openvz_driver.c| 87 ++--- src/qemu/qemu_capabilities.c |2 +- src/qemu/qemu_command.c |2 +- src/qemu/qemu_driver.c| 10 +-- src/qemu/qemu_process.c |1 - src/rpc/virnetclient.c|2 - src/rpc/virnetserverservice.c |2 - src/uml/uml_driver.c |2 - src/xen/xen_driver.c |1 - src/xen/xs_internal.c | 12 ++-- src/xenxs/xen_xm.c|1 - tests/virnetsockettest.c |3 - 24 files changed, 60 insertions(+), 100 deletions(-) diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 2b88796..64d793d 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -2572,7 +2572,6 @@ libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED, ret = 0; } - cleanup: LIBVIRT_RELEASE_THREAD_STATE; return ret; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7bcdcaf..83930c1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -9806,7 +9806,6 @@ char *virDomainDefFormat(virDomainDefPtr def, if (virDomainFSDefFormat(buf, def-fss[n], flags) 0) goto cleanup; - for (n = 0 ; n def-nnets ; n++) if (virDomainNetDefFormat(buf, def-nets[n], flags) 0) goto cleanup; diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c index 10377e7..99c3052 100644 --- a/src/conf/interface_conf.c +++ b/src/conf/interface_conf.c @@ -1300,7 +1300,6 @@ virInterfaceObjPtr virInterfaceAssignDef(virInterfaceObjListPtr interfaces, interfaces-count++; return iface; - } void virInterfaceRemove(virInterfaceObjListPtr interfaces, diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index ae479bf..3aeec7e 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1155,7 +1155,6 @@ int virNetworkSaveXML(const char *configDir, cleanup: VIR_FORCE_CLOSE(fd); - VIR_FREE(configFile); return ret; diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index dde2921..1ea122e 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -746,11 +746,8 @@ virNodeDevCapScsiHostParseXML(xmlXPathContextPtr ctxt, } if (STREQ(type, vport_ops)) { - data-scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS; - } else if (STREQ(type, fc_host)) { - xmlNodePtr orignode2; data-scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST; @@ -775,7 +772,6 @@ virNodeDevCapScsiHostParseXML(xmlXPathContextPtr ctxt, } ctxt-node = orignode2; - } else { virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR, _(unknown SCSI host capability type '%s' for '%s'), diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index f6f8be1..21d39a8 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -1203,7 +1203,6 @@ virStorageVolTargetDefFormat(virStorageVolOptionsPtr options, virBufferAsprintf(buf, group%d/group\n, def-perms.gid); - if (def-perms.label) virBufferAsprintf(buf, label%s/label\n, def-perms.label); diff --git a/src/interface/netcf_driver.c b/src/interface/netcf_driver.c index dd15c9d..5a549db 100644 --- a/src/interface/netcf_driver.c +++ b/src/interface/netcf_driver.c @@ -125,22 +125,19 @@ static virDrvOpenStatus interfaceOpenInterface(virConnectPtr conn, { struct interface_driver *driverState; -if (VIR_ALLOC(driverState) 0) -{ +if (VIR_ALLOC(driverState) 0) { virReportOOMError(); goto alloc_error; } /* initialize non-0 stuff in driverState */ -if (virMutexInit(driverState-lock) 0) -{ +if (virMutexInit(driverState-lock) 0) { /* what error to report? */ goto mutex_error; } /* open netcf */ -if (ncf_init(driverState-netcf, NULL) != 0) -{ +if (ncf_init(driverState-netcf, NULL) != 0) { /* what error to report? */ goto
Re: [libvirt] [PATCH] python: Fix bogus label placement
On 07/07/2011 03:23 AM, Matthias Bolte wrote: --- python/libvirt-override.c |8 +++- 1 files changed, 3 insertions(+), 5 deletions(-) ACK. (couldn't resist, could you? :-P) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Virsh Command Reference is out of date
Hi, Virsh Command Reference on libvirt.org seems out of date, it's at libvirt 0.8.7 http://libvirt.org/sources/virshcmdref/html-single/ Any one can help to update it to latest stable libvirt? Thanks, Gui -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Remove duplicate empty lines and correct indentation and style
On 07/07/2011 03:24 AM, Matthias Bolte wrote: No functional change included. --- python/libvirt-override.c |1 - src/conf/domain_conf.c|1 - src/conf/interface_conf.c |1 - src/conf/network_conf.c |1 - src/conf/node_device_conf.c |4 - src/conf/storage_conf.c |1 - src/interface/netcf_driver.c | 16 ++ src/libxl/libxl_driver.c |2 +- src/lxc/lxc_driver.c |2 +- src/node_device/node_device_driver.c |2 - src/node_device/node_device_linux_sysfs.c |2 - src/nwfilter/nwfilter_ebiptables_driver.c |2 - src/openvz/openvz_driver.c| 87 ++--- src/qemu/qemu_capabilities.c |2 +- src/qemu/qemu_command.c |2 +- src/qemu/qemu_driver.c| 10 +-- src/qemu/qemu_process.c |1 - src/rpc/virnetclient.c|2 - src/rpc/virnetserverservice.c |2 - src/uml/uml_driver.c |2 - src/xen/xen_driver.c |1 - src/xen/xs_internal.c | 12 ++-- src/xenxs/xen_xm.c|1 - tests/virnetsockettest.c |3 - 24 files changed, 60 insertions(+), 100 deletions(-) diff --git a/python/libvirt-override.c b/python/libvirt-override.c True, there don't appear to be any functional changes, and it's nice to have a consistent style to the code. My only problem with this type of commit is that it increases the chances of merge conflicts now and in the future (when someone tries to backport a bugfix to some stable downstream release.) (I periodically have a desire to make similar changes, but then discourage myself for that reason; maybe I'm just too conservative) I assume these were found by an automated tool - do just these changes make all of the source in libvirt consistent to the style? Especially if that's the case, I lean more towards pushing them than not; hopefully any merge conflicts that come up will be easy to solve (definitely easier than the ones caused by actual functional changes in the code!), and we can start enforcing the style. So, 1/2 ACK, but wait for someone else to give their 1/2 ACK. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4] graphics: add support for action_if_connected in qemu
On 06.07.2011 00:34, Eric Blake wrote: On 07/04/2011 02:48 AM, Michal Privoznik wrote: This option accepts 3 values: -keep, to keep current client connected (Spice+VNC) -disconnect, to disconnect client (Spice) -fail, to fail setting password if there is a client connected (Spice) --- diff to v3: -rebase to current HEAD resend diff to v2: -fixed typo -added test. However, functionality provided by this patch will show up only when talking to qemu monitor (set_password command). diff to v1: -Eric's review suggestions included -update 'Since' docs/formatdomain.html.in | 13 +- docs/schemas/domain.rng| 16 +++ src/conf/domain_conf.c | 44 ++- src/conf/domain_conf.h | 11 + src/libvirt_private.syms |2 + src/qemu/qemu_hotplug.c| 15 +- .../qemuxml2argv-graphics-spice-timeout.xml|2 +- 7 files changed, 94 insertions(+), 9 deletions(-) This patch changes the .xml, but not the corresponding .args file, which to me says it is probably incomplete. We covered the case of changing the attribute affecting qemu_hotplug: +++ b/src/qemu/qemu_hotplug.c @@ -1065,10 +1065,12 @@ qemuDomainChangeGraphics(struct qemud_driver *driver, return -1; } -/* If a password lifetime was, or is set, then we must always run, - * even if new password matches old password */ +/* If a password lifetime was, or is set, or action if connected has + * changed, then we must always run, even if new password matches + * old password */ if (olddev-data.vnc.auth.expires || dev-data.vnc.auth.expires || +olddev-data.vnc.auth.connected != dev-data.vnc.auth.connected || But shouldn't we also handle the case of setting the property up front in the initial qemu -spice command line argument, meaning a change is also needed to qemu_command.c? No. This is purely QMP thing. qemu -spice does not have any option for setting this (the current git version at least). That .xml vs .args change: I've changed .xml so we can test RNG scheme. There is nothing to add to .args. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] php-virt-control
On 07/03/2011 05:28 PM, Andreas Cymbal wrote: Hello i have some problem with php-virt-control */Message:/**/ /*/Cannot connect to hypervisor. Please change connection information. /(Local)// Virt-manager run without Problems Virsh run only with sudo virsh My System is Ubuntu 10.04 LTS 64 With Xen 4.1.1 and 2.6.32.40 Libvirt 0.9.2 How does xen+ssh work without any password or ssh keys? Yours AndrewCat Hi Andrew, it can't. The xen+ssh or anything+ssh is requiring the keys since libvirt is using ssh command directly and not libssh2 so it doesn't work even with the password specified. The only thing you have to do it to provide the SSH keys to the apache. You can run the 'tools/apache-key-copy' tool from the repository which will automatically generate the keys for user apache if it doesn't exist and copy it to the remote host which is required. If you see the message about libvirt-php cannot connect to the hypervisor then you should try setting up the connection information in the form at the bottom of the page. Is the system having the PolicyKit or something similar to this? You need to enable the authentication for virsh not to require password for the connection to 'xen:///' (which should be the local Xen connection URI). For more information about authentication please see the libvirt authentication page at http://libvirt.org/auth.html . Thanks, Michal -- Michal Novotny minov...@redhat.com, RHCE, Red Hat Virtualization | libvirt-php bindings | php-virt-control.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC: API additions for enhanced snapshot support
On Wed, Jul 6, 2011 at 3:03 PM, Eric Blake ebl...@redhat.com wrote: In other words, it looks like we are stuck with updating XML to track new file names any time we take a snapshot. Yes, but QEMU's snapshot_blkdev command takes a filename argument so at least you get to specify that new filename. Stefan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Remove duplicate empty lines and correct indentation and style
On Thu, Jul 07, 2011 at 03:55:01AM -0400, Laine Stump wrote: On 07/07/2011 03:24 AM, Matthias Bolte wrote: No functional change included. --- python/libvirt-override.c |1 - src/conf/domain_conf.c|1 - src/conf/interface_conf.c |1 - src/conf/network_conf.c |1 - src/conf/node_device_conf.c |4 - src/conf/storage_conf.c |1 - src/interface/netcf_driver.c | 16 ++ src/libxl/libxl_driver.c |2 +- src/lxc/lxc_driver.c |2 +- src/node_device/node_device_driver.c |2 - src/node_device/node_device_linux_sysfs.c |2 - src/nwfilter/nwfilter_ebiptables_driver.c |2 - src/openvz/openvz_driver.c| 87 ++--- src/qemu/qemu_capabilities.c |2 +- src/qemu/qemu_command.c |2 +- src/qemu/qemu_driver.c| 10 +-- src/qemu/qemu_process.c |1 - src/rpc/virnetclient.c|2 - src/rpc/virnetserverservice.c |2 - src/uml/uml_driver.c |2 - src/xen/xen_driver.c |1 - src/xen/xs_internal.c | 12 ++-- src/xenxs/xen_xm.c|1 - tests/virnetsockettest.c |3 - 24 files changed, 60 insertions(+), 100 deletions(-) diff --git a/python/libvirt-override.c b/python/libvirt-override.c True, there don't appear to be any functional changes, and it's nice to have a consistent style to the code. My only problem with this type of commit is that it increases the chances of merge conflicts now and in the future (when someone tries to backport a bugfix to some stable downstream release.) (I periodically have a desire to make similar changes, but then discourage myself for that reason; maybe I'm just too conservative) I assume these were found by an automated tool - do just these changes make all of the source in libvirt consistent to the style? Especially if that's the case, I lean more towards pushing them than not; hopefully any merge conflicts that come up will be easy to solve (definitely easier than the ones caused by actual functional changes in the code!), and we can start enforcing the style. So, 1/2 ACK, but wait for someone else to give their 1/2 ACK. ACK. Yes it causes merge pain, but we're usually better off over the long term with this sort of thing. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Virsh Command Reference is out of date
On Thu, Jul 07, 2011 at 03:39:24PM +0800, Gui Jianfeng wrote: Hi, Virsh Command Reference on libvirt.org seems out of date, it's at libvirt 0.8.7 http://libvirt.org/sources/virshcmdref/html-single/ Any one can help to update it to latest stable libvirt? The virsh command reference is maintained in GIT, and written in docbook XML. Anyone who wishes to contribute patches to improve it can just follow normal patch submission procedure on this mailing list http://libvirt.org/git/?p=libvirt-virshcmdref.git;a=summary On the subject of documentation, we also have a developer guide which could do with more content too http://libvirt.org/git/?p=libvirt-appdev-guide.git;a=summary Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] docs: minor whitespace cleanups
On Wed, Jul 06, 2011 at 01:51:13PM -0600, Eric Blake wrote: No change in wording. One spacing change in a pre, noticed because of odd XML formatting online; the rest is in free-flowing text to make it easier to see nesting levels in the document. * docs/formatdomain.html.in: Adjust spacing. Break long lines. --- I'll probably push this under the trivial rule. The pre change is in the hunk at line 296, for numatune. docs/formatdomain.html.in | 195 ++--- 1 files changed, 112 insertions(+), 83 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] build: use gnulib pthread_sigmask
On Wed, Jul 06, 2011 at 11:24:12AM -0600, Eric Blake wrote: Gnulib finally learned how to do pthread_sigmask on mingw. We still have to worry about optional signals, like SIGWINCH, but overall, this makes for less conditional code. * .gnulib: Update to latest, for pthread_sigmask. * bootstrap.conf (gnulib_modules): Add pthread_sigmask. * configure.ac (AC_CHECK_FUNCS): Drop redundant check. * src/rpc/virnetclient.c (virNetClientSetTLSSession) (virNetClientIOEventLoop): Make code unconditional. * src/util/command.c (virFork): Likewise. * tools/virsh.c (doMigrate, cmdMigrate): Likewise. --- .gnulib|2 +- bootstrap.conf |1 + configure.ac |2 +- src/rpc/virnetclient.c | 24 src/util/command.c | 10 -- tools/virsh.c | 10 -- 6 files changed, 11 insertions(+), 38 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virsh: make destroy sound less scary
On Wed, Jul 06, 2011 at 03:44:13PM -0600, Eric Blake wrote: Destroy has a rather negative English connotation. Try to reduce the impact, so newbies aren't as scared to use it. * tools/virsh.c: Tweak all destroy documentation. * tools/virsh.pod: Likewise. --- tools/virsh.c | 20 +++- tools/virsh.pod | 16 +--- 2 files changed, 20 insertions(+), 16 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 01/20] maint: print flags in hex during debug
On Wed, Jul 06, 2011 at 05:23:44PM -0600, Eric Blake wrote: Debugging decimal flags is a pain. * src/libvirt.c: Always print flags in hex. --- src/libvirt.c | 216 ++--- 1 files changed, 114 insertions(+), 102 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 05/20] util: drop unused safezero argument
On Thu, Jul 07, 2011 at 11:10:31AM +0800, Daniel Veillard wrote: On Wed, Jul 06, 2011 at 05:23:48PM -0600, Eric Blake wrote: No caller was using the flags argument, and this function is internal only, so we might as well skip it. * src/util/util.h (safezero): Update signature. * src/util/util.c (safezero): Update function. * src/locking/lock_driver_sanlock.c (virLockManagerSanlockSetupLockspace) (virLockManagerSanlockCreateLease): Update all callers. * src/storage/storage_backend.c (createRawFile): Likewise. --- src/locking/lock_driver_sanlock.c |4 ++-- src/storage/storage_backend.c |4 ++-- src/util/util.c |6 +++--- src/util/util.h |2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c index 567221c..cd2bbb5 100644 --- a/src/locking/lock_driver_sanlock.c +++ b/src/locking/lock_driver_sanlock.c @@ -196,7 +196,7 @@ static int virLockManagerSanlockSetupLockspace(void) /* * Pre allocate enough data for 1 block of leases at preferred alignment */ -if (safezero(fd, 0, 0, rv) 0) { +if (safezero(fd, 0, rv) 0) { virReportSystemError(errno, _(Unable to allocate lockspace %s), path); @@ -567,7 +567,7 @@ static int virLockManagerSanlockCreateLease(struct sanlk_resource *res) /* * Pre allocate enough data for 1 block of leases at preferred alignment */ -if (safezero(fd, 0, 0, rv) 0) { +if (safezero(fd, 0, rv) 0) { virReportSystemError(errno, _(Unable to allocate lease %s), res-disks[0].path); diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 708d7b2..671b88e 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -331,7 +331,7 @@ createRawFile(int fd, virStorageVolDefPtr vol, if (bytes remain) bytes = remain; -if (safezero(fd, 0, vol-allocation - remain, bytes) 0) { +if (safezero(fd, vol-allocation - remain, bytes) 0) { ret = -errno; virReportSystemError(errno, _(cannot fill file '%s'), vol-target.path); @@ -340,7 +340,7 @@ createRawFile(int fd, virStorageVolDefPtr vol, remain -= bytes; } } else { /* No progress bars to be shown */ -if (safezero(fd, 0, 0, remain) 0) { +if (safezero(fd, 0, remain) 0) { ret = -errno; virReportSystemError(errno, _(cannot fill file '%s'), vol-target.path); diff --git a/src/util/util.c b/src/util/util.c index 5542557..3d0ceea 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -133,7 +133,7 @@ safewrite(int fd, const void *buf, size_t count) } #ifdef HAVE_POSIX_FALLOCATE -int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len) +int safezero(int fd, off_t offset, off_t len) { int ret = posix_fallocate(fd, offset, len); if (ret == 0) @@ -144,7 +144,7 @@ int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len) #else # ifdef HAVE_MMAP -int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len) +int safezero(int fd, off_t offset, off_t len) { int r; char *buf; @@ -168,7 +168,7 @@ int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len) # else /* HAVE_MMAP */ -int safezero(int fd, int flags ATTRIBUTE_UNUSED, off_t offset, off_t len) +int safezero(int fd, off_t offset, off_t len) { int r; char *buf; diff --git a/src/util/util.h b/src/util/util.h index 7a1eb11..6f07f8c 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -39,7 +39,7 @@ ssize_t saferead(int fd, void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; ssize_t safewrite(int fd, const void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; -int safezero(int fd, int flags, off_t offset, off_t len) +int safezero(int fd, off_t offset, off_t len) ATTRIBUTE_RETURN_CHECK; int virSetBlocking(int fd, bool blocking) ATTRIBUTE_RETURN_CHECK; ACK from me but Dan should probably check that it doesn't affect some coming patches before pushing this, ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |:
Re: [libvirt] [PATCH 10/20] libxl: reject unknown flags
On Wed, Jul 06, 2011 at 05:23:53PM -0600, Eric Blake wrote: * src/libxl/libxl_driver.c (libxlOpen, libxlDomainReboot) (libxlDomainXMLFromNative, libxlDomainXMLToNative) (libxlDomainCreateWithFlags): Reject unknown flags. --- src/libxl/libxl_driver.c | 18 +- 1 files changed, 13 insertions(+), 5 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 12/20] openvz: reject unknown flags
On Wed, Jul 06, 2011 at 05:23:55PM -0600, Eric Blake wrote: * src/openvz/openvz_driver.c (openvzDomainReboot, openvzOpen): Reject unknown flags. --- src/openvz/openvz_driver.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 2c6c870..2b4bf9e 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -613,12 +613,15 @@ cleanup: } static int openvzDomainReboot(virDomainPtr dom, - unsigned int flags ATTRIBUTE_UNUSED) { + unsigned int flags) +{ struct openvz_driver *driver = dom-conn-privateData; virDomainObjPtr vm; const char *prog[] = {VZCTL, --quiet, restart, PROGRAM_SENTINAL, NULL}; int ret = -1; +virCheckFlags(0, -1); + openvzDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); openvzDriverUnlock(driver); @@ -1281,10 +1284,12 @@ openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) static virDrvOpenStatus openvzOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { struct openvz_driver *driver; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (conn-uri == NULL) { if (!virFileExists(/proc/vz)) return VIR_DRV_OPEN_DECLINED; ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 11/20] lxc: reject unknown flags
On Wed, Jul 06, 2011 at 05:23:54PM -0600, Eric Blake wrote: * src/lxc/lxc_driver.c (lxcOpen, lxcDomainSetMemoryParameters) (lxcDomainGetMemoryParameters): Reject unknown flags. --- src/lxc/lxc_driver.c | 12 +--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 799a5e7..8684ec6 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -110,8 +110,10 @@ static void lxcDomainEventQueue(lxc_driver_t *driver, static virDrvOpenStatus lxcOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + /* Verify uri was specified */ if (conn-uri == NULL) { if (lxc_driver == NULL) @@ -746,7 +748,7 @@ cleanup: static int lxcDomainSetMemoryParameters(virDomainPtr dom, virTypedParameterPtr params, int nparams, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { lxc_driver_t *driver = dom-conn-privateData; int i; @@ -754,6 +756,8 @@ static int lxcDomainSetMemoryParameters(virDomainPtr dom, virDomainObjPtr vm = NULL; int ret = -1; +virCheckFlags(0, -1); + lxcDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); @@ -843,7 +847,7 @@ cleanup: static int lxcDomainGetMemoryParameters(virDomainPtr dom, virTypedParameterPtr params, int *nparams, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { lxc_driver_t *driver = dom-conn-privateData; int i; @@ -853,6 +857,8 @@ static int lxcDomainGetMemoryParameters(virDomainPtr dom, int ret = -1; int rc; +virCheckFlags(0, -1); + lxcDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 13/20] phyp: reject unknown flags
On Wed, Jul 06, 2011 at 05:23:56PM -0600, Eric Blake wrote: * src/phyp/phyp_driver.c (phypOpen, phypDomainReboot) (phypVIOSDriverOpen): Reject unknown flags. --- src/phyp/phyp_driver.c | 12 +--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index d1ab5b4..93f22eb 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -1128,7 +1128,7 @@ exit: static virDrvOpenStatus phypOpen(virConnectPtr conn, - virConnectAuthPtr auth, unsigned int flags ATTRIBUTE_UNUSED) + virConnectAuthPtr auth, unsigned int flags) { LIBSSH2_SESSION *session = NULL; ConnectionData *connection_data = NULL; @@ -1138,6 +1138,8 @@ phypOpen(virConnectPtr conn, char *char_ptr; char *managed_system = NULL; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (!conn || !conn-uri) return VIR_DRV_OPEN_DECLINED; @@ -3389,7 +3391,7 @@ cleanup: } static int -phypDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) +phypDomainReboot(virDomainPtr dom, unsigned int flags) { int result = -1; ConnectionData *connection_data = dom-conn-networkPrivateData; @@ -3402,6 +3404,8 @@ phypDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) char *ret = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; +virCheckFlags(0, -1); + virBufferAddLit(buf, chsysstate); if (system_type == HMC) virBufferAsprintf(buf, -m %s, managed_system); @@ -3725,8 +3729,10 @@ phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus) static virDrvOpenStatus phypVIOSDriverOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (conn-driver-no != VIR_DRV_PHYP) return VIR_DRV_OPEN_DECLINED; ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 14/20] qemu: reject unknown flags
On Wed, Jul 06, 2011 at 05:23:57PM -0600, Eric Blake wrote: * src/qemu/qemu_driver.c (qemudOpen, qemuDomainScreenshot) (qemuDomainXMLFromNative, qemuDomainXMLToNative) (qemudDomainBlockPeek, qemuCPUCompare, qemuCPUBaseline): Reject unknown flags. * src/qemu/qemu_migration.c (qemuMigrationConfirm): Likewise. (_qemuMigrationCookie, qemuMigrationCookieXMLParse) (qemuMigrationCookieXMLParseStr, qemuMigrationBakeCookie) (qemuMigrationEatCookie): Make flags unsigned. --- src/qemu/qemu_driver.c| 30 +++--- src/qemu/qemu_migration.c | 16 +--- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 4f12beb..a2fe4b8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -800,8 +800,10 @@ static int qemuDomainSnapshotSetCurrentInactive(virDomainObjPtr vm, static virDrvOpenStatus qemudOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (conn-uri == NULL) { if (qemu_driver == NULL) return VIR_DRV_OPEN_DECLINED; @@ -2686,7 +2688,7 @@ static char * qemuDomainScreenshot(virDomainPtr dom, virStreamPtr st, unsigned int screen, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { struct qemud_driver *driver = dom-conn-privateData; virDomainObjPtr vm; @@ -2695,6 +2697,8 @@ qemuDomainScreenshot(virDomainPtr dom, int tmp_fd = -1; char *ret = NULL; +virCheckFlags(0, NULL); + qemuDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); qemuDriverUnlock(driver); @@ -3881,11 +3885,14 @@ cleanup: static char *qemuDomainXMLFromNative(virConnectPtr conn, const char *format, const char *config, - unsigned int flags ATTRIBUTE_UNUSED) { + unsigned int flags) +{ struct qemud_driver *driver = conn-privateData; virDomainDefPtr def = NULL; char *xml = NULL; +virCheckFlags(0, NULL); + if (STRNEQ(format, QEMU_CONFIG_FORMAT_ARGV)) { qemuReportError(VIR_ERR_INVALID_ARG, _(unsupported config type %s), format); @@ -3908,7 +3915,8 @@ cleanup: static char *qemuDomainXMLToNative(virConnectPtr conn, const char *format, const char *xmlData, - unsigned int flags ATTRIBUTE_UNUSED) { + unsigned int flags) +{ struct qemud_driver *driver = conn-privateData; virDomainDefPtr def = NULL; virDomainChrSourceDef monConfig; @@ -3917,6 +3925,8 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, char *ret = NULL; int i; +virCheckFlags(0, NULL); + qemuDriverLock(driver); if (STRNEQ(format, QEMU_CONFIG_FORMAT_ARGV)) { @@ -6164,12 +6174,14 @@ qemudDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long offset, size_t size, void *buffer, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { struct qemud_driver *driver = dom-conn-privateData; virDomainObjPtr vm; int fd = -1, ret = -1, i; +virCheckFlags(0, -1); + qemuDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); qemuDriverUnlock(driver); @@ -7240,11 +7252,13 @@ out: static int qemuCPUCompare(virConnectPtr conn, const char *xmlDesc, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { struct qemud_driver *driver = conn-privateData; int ret = VIR_CPU_COMPARE_ERROR; +virCheckFlags(0, VIR_CPU_COMPARE_ERROR); + qemuDriverLock(driver); if (!driver-caps || !driver-caps-host.cpu) { @@ -7264,10 +7278,12 @@ static char * qemuCPUBaseline(virConnectPtr conn ATTRIBUTE_UNUSED, const char **xmlCPUs, unsigned int ncpus, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { char *cpu; +virCheckFlags(0, NULL); + cpu = cpuBaselineXML(xmlCPUs, ncpus, NULL, 0); return cpu; diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d7b27a0..a01cbd1 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -76,8 +76,8 @@ struct _qemuMigrationCookieGraphics { typedef struct _qemuMigrationCookie
Re: [libvirt] [PATCH 18/20] vmware: reject unknown flags
On Wed, Jul 06, 2011 at 05:24:01PM -0600, Eric Blake wrote: * src/vmware/vmware_driver.c (vmwareOpen, vmwareDomainReboot) (vmwareDomainCreateXML, vmwareDomainCreateWithFlags): Reject unknown flags. --- src/vmware/vmware_driver.c | 17 - 1 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 3f0cfae..11dc504 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -74,11 +74,13 @@ vmwareDataFreeFunc(void *data) static virDrvOpenStatus vmwareOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { struct vmware_driver *driver; char * vmrun = NULL; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (conn-uri == NULL) { /* @TODO accept */ return VIR_DRV_OPEN_DECLINED; @@ -446,11 +448,10 @@ vmwareDomainResume(virDomainPtr dom) } static int -vmwareDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) +vmwareDomainReboot(virDomainPtr dom, unsigned int flags) { struct vmware_driver *driver = dom-conn-privateData; const char * vmxPath = NULL; - virDomainObjPtr vm; const char *cmd[] = { VMRUN, -T, PROGRAM_SENTINAL, @@ -458,6 +459,8 @@ vmwareDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) }; int ret = -1; +virCheckFlags(0, -1); + vmwareDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); vmwareDriverUnlock(driver); @@ -492,7 +495,7 @@ vmwareDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) static virDomainPtr vmwareDomainCreateXML(virConnectPtr conn, const char *xml, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { struct vmware_driver *driver = conn-privateData; virDomainDefPtr vmdef = NULL; @@ -503,6 +506,8 @@ vmwareDomainCreateXML(virConnectPtr conn, const char *xml, vmwareDomainPtr pDomain = NULL; virVMXContext ctx; +virCheckFlags(0, NULL); + ctx.formatFileName = vmwareCopyVMXFileName; vmwareDriverLock(driver); @@ -562,12 +567,14 @@ cleanup: static int vmwareDomainCreateWithFlags(virDomainPtr dom, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { struct vmware_driver *driver = dom-conn-privateData; virDomainObjPtr vm; int ret = -1; +virCheckFlags(0, -1); + vmwareDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); if (!vm) { ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 16/20] uml: reject unknown flags
On Wed, Jul 06, 2011 at 05:23:59PM -0600, Eric Blake wrote: * src/uml/uml_driver.c (umlOpen, umlDomainGetXMLDesc) (umlDomainBlockPeek): Reject unknown flags. --- src/uml/uml_driver.c | 14 +++--- 1 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 6a396e4..22af8fb 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -946,7 +946,10 @@ static void umlShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, static virDrvOpenStatus umlOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, -unsigned int flags ATTRIBUTE_UNUSED) { +unsigned int flags) +{ +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (conn-uri == NULL) { if (uml_driver == NULL) return VIR_DRV_OPEN_DECLINED; @@ -1559,11 +1562,14 @@ cleanup: static char *umlDomainGetXMLDesc(virDomainPtr dom, - unsigned int flags ATTRIBUTE_UNUSED) { + unsigned int flags) +{ struct uml_driver *driver = dom-conn-privateData; virDomainObjPtr vm; char *ret = NULL; +virCheckFlags(0, NULL); + umlDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); umlDriverUnlock(driver); @@ -2045,12 +2051,14 @@ umlDomainBlockPeek(virDomainPtr dom, const char *path, unsigned long long offset, size_t size, void *buffer, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { struct uml_driver *driver = dom-conn-privateData; virDomainObjPtr vm; int fd = -1, ret = -1, i; +virCheckFlags(0, -1); + umlDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); umlDriverUnlock(driver); ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 15/20] test: reject unknown flags
On Wed, Jul 06, 2011 at 05:23:58PM -0600, Eric Blake wrote: * src/test/test_driver.c (testOpen, testDomainCoreDump) (testOpenNetwork, testNetworkGetXMLDesc, testOpenInterface) (testInterfaceChangeBegin, testInterfaceChangeCommit) (testInterfaceChangeRollback, testInterfaceGetXMLDesc) (testInterfaceDefineXML, testInterfaceCreate) (testInterfaceDestroy, testStorageOpen, testStoragePoolStart) (testStorageFindPoolSources, testStoragePoolCreate) (testStoragePoolDefine, testStoragePoolBuild) (testStoragePoolDelete, testStoragePoolRefresh) (testStoragePoolGetXMLDesc, testStorageVolumeCreateXML) (testStorageVolumeCreateXMLFrom, testStorageVolumeDelete) (testStorageVolumeGetXMLDesc, testDevMonOpen) (testNodeNumOfDevices, testNodeListDevices) (testNodeDeviceGetXMLDesc, testNodeDeviceCreateXML) (testSecretOpen, testNWFilterOpen): Reject unknown flags. --- src/test/test_driver.c | 144 +--- 1 files changed, 112 insertions(+), 32 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 98daca8..8dac713 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1099,11 +1099,13 @@ static int testOpenFromFile(virConnectPtr conn, static virDrvOpenStatus testOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { int ret; testConnPtr privconn; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (!conn-uri) return VIR_DRV_OPEN_DECLINED; @@ -1904,7 +1906,7 @@ cleanup: static int testDomainCoreDump(virDomainPtr domain, const char *to, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { testConnPtr privconn = domain-conn-privateData; int fd = -1; @@ -1912,6 +1914,8 @@ static int testDomainCoreDump(virDomainPtr domain, virDomainEventPtr event = NULL; int ret = -1; +virCheckFlags(0, -1); + testDriverLock(privconn); privdom = virDomainFindByName(privconn-domains, domain-name); @@ -2843,7 +2847,10 @@ error: static virDrvOpenStatus testOpenNetwork(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, -unsigned int flags ATTRIBUTE_UNUSED) { +unsigned int flags) +{ +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (STRNEQ(conn-driver-name, Test)) return VIR_DRV_OPEN_DECLINED; @@ -3178,12 +3185,14 @@ cleanup: } static char *testNetworkGetXMLDesc(virNetworkPtr network, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { testConnPtr privconn = network-conn-privateData; virNetworkObjPtr privnet; char *ret = NULL; +virCheckFlags(0, NULL); + testDriverLock(privconn); privnet = virNetworkFindByName(privconn-networks, network-name); @@ -3292,8 +3301,10 @@ cleanup: static virDrvOpenStatus testOpenInterface(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (STRNEQ(conn-driver-name, Test)) return VIR_DRV_OPEN_DECLINED; @@ -3476,11 +3487,13 @@ cleanup: } static int testInterfaceChangeBegin(virConnectPtr conn, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { testConnPtr privconn = conn-privateData; int ret = -1; +virCheckFlags(0, -1); + testDriverLock(privconn); if (privconn-transaction_running) { testError(VIR_ERR_OPERATION_INVALID, @@ -3501,11 +3514,13 @@ cleanup: } static int testInterfaceChangeCommit(virConnectPtr conn, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { testConnPtr privconn = conn-privateData; int ret = -1; +virCheckFlags(0, -1); + testDriverLock(privconn); if (!privconn-transaction_running) { @@ -3526,11 +3541,13 @@ cleanup: } static int testInterfaceChangeRollback(virConnectPtr conn, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { testConnPtr privconn = conn-privateData; int ret = -1; +virCheckFlags(0, -1); + testDriverLock(privconn); if
Re: [libvirt] [PATCH 17/20] vbox: reject unknown flags
On Wed, Jul 06, 2011 at 05:24:00PM -0600, Eric Blake wrote: * src/vbox/vbox_driver.c (vboxOpenDummy): Reject unknown flags. * src/vbox/vbox_tmpl.c (vboxOpen, vboxDomainReboot) (vboxNetworkOpen, vboxNetworkGetXMLDesc, vboxStorageOpen) (vboxStorageVolCreateXML, vboxStorageVolDelete) (vboxStorageVolGetXMLDesc, vboxDomainScreenshot): Likewise. --- src/vbox/vbox_driver.c |5 - src/vbox/vbox_tmpl.c | 44 +++- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/vbox/vbox_driver.c b/src/vbox/vbox_driver.c index b20998a..3b2e95a 100644 --- a/src/vbox/vbox_driver.c +++ b/src/vbox/vbox_driver.c @@ -142,9 +142,12 @@ int vboxRegister(void) { static virDrvOpenStatus vboxOpenDummy(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) { + unsigned int flags) +{ uid_t uid = getuid(); +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (conn-uri == NULL || conn-uri-scheme == NULL || STRNEQ (conn-uri-scheme, vbox) || diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 4a0858f..d6afa31 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -961,10 +961,13 @@ static void vboxUninitialize(vboxGlobalData *data) { static virDrvOpenStatus vboxOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) { + unsigned int flags) +{ vboxGlobalData *data = NULL; uid_t uid = getuid(); +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (conn-uri == NULL) { conn-uri = xmlParseURI(uid ? vbox:///session : vbox:///system); if (conn-uri == NULL) { @@ -1637,7 +1640,8 @@ cleanup: return ret; } -static int vboxDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) { +static int vboxDomainReboot(virDomainPtr dom, unsigned int flags) +{ VBOX_OBJECT_CHECK(dom-conn, int, -1); IMachine *machine= NULL; vboxIID iid = VBOX_IID_INITIALIZER; @@ -1646,6 +1650,8 @@ static int vboxDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSE PRBool isAccessible = PR_FALSE; nsresult rc; +virCheckFlags(0, -1); + vboxIIDFromUUID(iid, dom-uuid); rc = VBOX_OBJECT_GET_MACHINE(iid.value, machine); if (NS_FAILED(rc)) { @@ -6938,9 +6944,12 @@ static int vboxDomainEventDeregisterAny(virConnectPtr conn, */ static virDrvOpenStatus vboxNetworkOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, -unsigned int flags ATTRIBUTE_UNUSED) { +unsigned int flags) +{ vboxGlobalData *data = conn-privateData; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (STRNEQ(conn-driver-name, VBOX)) goto cleanup; @@ -7575,7 +7584,8 @@ static int vboxNetworkDestroy(virNetworkPtr network) { } static char *vboxNetworkGetXMLDesc(virNetworkPtr network, - unsigned int flags ATTRIBUTE_UNUSED) { + unsigned int flags) +{ VBOX_OBJECT_HOST_CHECK(network-conn, char *, NULL); virNetworkDefPtr def = NULL; virNetworkIpDefPtr ipdef = NULL; @@ -7583,6 +7593,8 @@ static char *vboxNetworkGetXMLDesc(virNetworkPtr network, PRUnichar *networkInterfaceNameUtf16= NULL; IHostNetworkInterface *networkInterface = NULL; +virCheckFlags(0, NULL); + if (VIR_ALLOC(def) 0) { virReportOOMError(); goto cleanup; @@ -7750,9 +7762,12 @@ cleanup: static virDrvOpenStatus vboxStorageOpen (virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) { + unsigned int flags) +{ vboxGlobalData *data = conn-privateData; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (STRNEQ(conn-driver-name, VBOX)) goto cleanup; @@ -8098,7 +8113,8 @@ static virStorageVolPtr vboxStorageVolLookupByPath(virConnectPtr conn, const cha static virStorageVolPtr vboxStorageVolCreateXML(virStoragePoolPtr pool, const char *xml, -unsigned int flags ATTRIBUTE_UNUSED) { +unsigned int flags) +{ VBOX_OBJECT_CHECK(pool-conn, virStorageVolPtr, NULL); virStorageVolDefPtr def = NULL; PRUnichar *hddFormatUtf16 = NULL; @@ -8106,6 +8122,8 @@ static virStorageVolPtr
Re: [libvirt] [PATCH 20/20] xenapi: reject unknown flags
On Wed, Jul 06, 2011 at 05:24:03PM -0600, Eric Blake wrote: * src/xenapi/xenapi_driver.c (xenapiOpen, xenapiDomainReboot) (xenapiDomainGetXMLDesc): Reject unknown flags. --- src/xenapi/xenapi_driver.c | 13 ++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 1c06f75..16f9f78 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -92,12 +92,14 @@ getCapsObject (void) */ static virDrvOpenStatus xenapiOpen (virConnectPtr conn, virConnectAuthPtr auth, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { char *username = NULL; char *password = NULL; struct _xenapiPrivate *privP = NULL; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (conn-uri == NULL || conn-uri-scheme == NULL || STRCASENEQ(conn-uri-scheme, XenAPI)) { return VIR_DRV_OPEN_DECLINED; @@ -802,12 +804,15 @@ xenapiDomainShutdown (virDomainPtr dom) * Returns 0 on success or -1 in case of error */ static int -xenapiDomainReboot (virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) +xenapiDomainReboot (virDomainPtr dom, unsigned int flags) { /* vm.clean_reboot */ xen_vm vm; struct xen_vm_set *vms; xen_session *session = ((struct _xenapiPrivate *)(dom-conn-privateData))-session; + +virCheckFlags(0, -1); + if (xen_vm_get_by_name_label(session, vms, dom-name) vms-size 0) { if (vms-size != 1) { xenapiSessionErrorHandler(dom-conn, VIR_ERR_INTERNAL_ERROR, @@ -1295,7 +1300,7 @@ xenapiDomainGetMaxVcpus (virDomainPtr dom) * Returns XML string of the domain configuration on success or -1 in case of error */ static char * -xenapiDomainGetXMLDesc(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) +xenapiDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) { xen_vm vm=NULL; xen_vm_set *vms; @@ -1309,6 +1314,8 @@ xenapiDomainGetXMLDesc(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) struct xen_vif_set *vif_set = NULL; char *xml; +virCheckFlags(0, NULL); + if (!xen_vm_get_by_name_label(session, vms, dom-name)) return NULL; if (vms-size != 1) { xenapiSessionErrorHandler(dom-conn, VIR_ERR_INTERNAL_ERROR, ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 19/20] xen: reject unknown flags
On Wed, Jul 06, 2011 at 05:24:02PM -0600, Eric Blake wrote: * src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative) (xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject unknown flags. * src/xen/xen_hypervisor.c (xenHypervisorOpen) (xenHypervisorGetDomainState): Likewise. * src/xen/xen_inotify.c (xenInotifyOpen): Likewise. * src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot) (xenDaemonDomainCoreDump, xenDaemonDomainGetState) (xenDaemonDomainMigratePrepare): Likewise. * src/xen/xm_internal.c (xenXMOpen, xenXMDomainGetState): Likewise. * src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState) (xenStoreDomainReboot): Likewise. --- src/xen/xen_driver.c | 12 +--- src/xen/xen_hypervisor.c |8 ++-- src/xen/xen_inotify.c|4 +++- src/xen/xend_internal.c | 20 +++- src/xen/xm_internal.c|8 ++-- src/xen/xs_internal.c| 12 +--- 6 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 0f66395..2cdb6c4 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1261,7 +1261,7 @@ static char * xenUnifiedDomainXMLFromNative(virConnectPtr conn, const char *format, const char *config, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { virDomainDefPtr def = NULL; char *ret = NULL; @@ -1271,6 +1271,8 @@ xenUnifiedDomainXMLFromNative(virConnectPtr conn, int vncport; GET_PRIVATE(conn); +virCheckFlags(0, NULL); + if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) { xenUnifiedError(VIR_ERR_INVALID_ARG, @@ -1311,13 +1313,15 @@ static char * xenUnifiedDomainXMLToNative(virConnectPtr conn, const char *format, const char *xmlData, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { virDomainDefPtr def = NULL; char *ret = NULL; virConfPtr conf = NULL; GET_PRIVATE(conn); +virCheckFlags(0, NULL); + if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) { xenUnifiedError(VIR_ERR_INVALID_ARG, @@ -1766,11 +1770,13 @@ xenUnifiedDomainInterfaceStats (virDomainPtr dom, const char *path, static int xenUnifiedDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long offset, size_t size, - void *buffer, unsigned int flags ATTRIBUTE_UNUSED) + void *buffer, unsigned int flags) { int r; GET_PRIVATE (dom-conn); +virCheckFlags(0, -1); + if (priv-opened[XEN_UNIFIED_XEND_OFFSET]) { r = xenDaemonDomainBlockPeek (dom, path, offset, size, buffer); if (r != -2) return r; diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index a92b743..7636bea 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -2201,11 +2201,13 @@ xenHypervisorInit(void) virDrvOpenStatus xenHypervisorOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { int ret; xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn-privateData; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (initialized == 0) if (xenHypervisorInit() == -1) return -1; @@ -3272,11 +3274,13 @@ int xenHypervisorGetDomainState(virDomainPtr domain, int *state, int *reason, -unsigned int flags ATTRIBUTE_UNUSED) +unsigned int flags) { xenUnifiedPrivatePtr priv = domain-conn-privateData; virDomainInfo info; +virCheckFlags(0, -1); + if (domain-conn == NULL) return -1; diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c index 2d7207c..0b6883f 100644 --- a/src/xen/xen_inotify.c +++ b/src/xen/xen_inotify.c @@ -383,13 +383,15 @@ cleanup: virDrvOpenStatus xenInotifyOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { DIR *dh; struct dirent *ent; char *path; xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn-privateData; +virCheckFlags(0, VIR_DRV_OPEN_ERROR); + if (priv-configDir) { priv-useXenConfigCache = 1; } else { diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 6c2f051..8a4c6a9 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@
[libvirt] [PATCH 1/1] microblaze: Add architecture support
Add libvirt support for MicroBlaze architecture as a QEMU target. Based on mips/mipsel pattern. Signed-off-by: John Williams john.willi...@petalogix.com --- docs/drvqemu.html.in |2 ++ docs/schemas/capability.rng |2 ++ examples/apparmor/libvirt-qemu |4 src/qemu/qemu_capabilities.c |2 ++ tests/capabilityschemadata/caps-qemu-kvm.xml | 24 5 files changed, 34 insertions(+), 0 deletions(-) diff --git a/docs/drvqemu.html.in b/docs/drvqemu.html.in index 7230cae..e0e44eb 100644 --- a/docs/drvqemu.html.in +++ b/docs/drvqemu.html.in @@ -16,6 +16,8 @@ li strongQEMU emulators/strong: The driver will probe code/usr/bin/code for the presence of codeqemu/code, codeqemu-system-x86_64/code, +codeqemu-system-microblaze/code, +codeqemu-system-microblazeel/code, codeqemu-system-mips/code,codeqemu-system-mipsel/code, codeqemu-system-sparc/code,codeqemu-system-ppc/code. The results of this can be seen from the capabilities XML output. diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index f894b09..99b4a9a 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -325,6 +325,8 @@ valuearm/value valuei686/value valueia64/value + valuemicroblaze/value + valuemicroblazeel/value valuemips/value valuemipsel/value valueppc64/value diff --git a/examples/apparmor/libvirt-qemu b/examples/apparmor/libvirt-qemu index faf8636..3251536 100644 --- a/examples/apparmor/libvirt-qemu +++ b/examples/apparmor/libvirt-qemu @@ -69,6 +69,8 @@ /usr/bin/qemu-system-cris rmix, /usr/bin/qemu-system-i386 rmix, /usr/bin/qemu-system-m68k rmix, + /usr/bin/qemu-system-microblaze rmix, + /usr/bin/qemu-system-microblazeel rmix, /usr/bin/qemu-system-mips rmix, /usr/bin/qemu-system-mips64 rmix, /usr/bin/qemu-system-mips64el rmix, @@ -87,6 +89,8 @@ /usr/bin/qemu-cris rmix, /usr/bin/qemu-i386 rmix, /usr/bin/qemu-m68k rmix, + /usr/bin/qemu-microblaze rmix, + /usr/bin/qemu-microblazeel rmix, /usr/bin/qemu-mips rmix, /usr/bin/qemu-mipsel rmix, /usr/bin/qemu-ppc rmix, diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index ad62a07..2c037ce 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -160,6 +160,8 @@ static const struct qemu_arch_info const arch_info_hvm[] = { { x86_64, 64, NULL, qemu-system-x86_64, NULL, arch_info_x86_64_flags, 2 }, { arm,32, NULL, qemu-system-arm,NULL, NULL, 0 }, +{ microblaze, 32, NULL, qemu-system-microblaze, NULL, NULL, 0 }, +{ microblazeel, 32, NULL, qemu-system-microblazeel, NULL, NULL, 0 }, { mips, 32, NULL, qemu-system-mips, NULL, NULL, 0 }, { mipsel, 32, NULL, qemu-system-mipsel, NULL, NULL, 0 }, { sparc, 32, NULL, qemu-system-sparc, NULL, NULL, 0 }, diff --git a/tests/capabilityschemadata/caps-qemu-kvm.xml b/tests/capabilityschemadata/caps-qemu-kvm.xml index 47accde..dc6fb76 100644 --- a/tests/capabilityschemadata/caps-qemu-kvm.xml +++ b/tests/capabilityschemadata/caps-qemu-kvm.xml @@ -113,6 +113,30 @@ guest os_typehvm/os_type +arch name='microblaze' + wordsize32/wordsize + emulator/usr/bin/qemu-system-microblaze/emulator + machinepetalogix-s3adsp1800/machine + machinemicroblaze-fdt/machine + domain type='qemu' + /domain +/arch + /guest + + guest +os_typehvm/os_type +arch name='microblazeel' + wordsize32/wordsize + emulator/usr/bin/qemu-system-microblazeel/emulator + machinepetalogix-s3adsp1800/machine + machinemicroblaze-fdt/machine + domain type='qemu' + /domain +/arch + /guest + + guest +os_typehvm/os_type arch name='mips' wordsize32/wordsize emulator/usr/bin/qemu-system-mips/emulator -- 1.7.0.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] 腾讯 could you give me any suggestions when running libvirtd in the container
Hi all: we manage the contaienr vms using libvirt, and we want to mornitor the vms by running the libvirtd in the container. but there is something wrong with it, a lock in the kernel is crashed. if you run the sudo or ping .etc, the system call can NOT be returned, the status of the command is D. would you like to give me the hand. Thank you BR. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 03/14] Add API for duplicating a socket/client file descriptor
From: Daniel P. Berrange berra...@redhat.com * src/rpc/virnetsocket.c, src/rpc/virnetsocket.h: Add virNetSocketDupFD() * src/rpc/virnetclient.c, src/rpc/virnetclient.h: Add virNetClientDupFD() and virNetClientGetFD() --- src/rpc/virnetclient.c | 20 src/rpc/virnetclient.h |3 +++ src/rpc/virnetsocket.c | 12 src/rpc/virnetsocket.h |2 ++ 4 files changed, 37 insertions(+), 0 deletions(-) diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 615de6c..ecc5c37 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -217,6 +217,26 @@ void virNetClientRef(virNetClientPtr client) } +int virNetClientGetFD(virNetClientPtr client) +{ +int fd; +virNetClientLock(client); +fd = virNetSocketGetFD(client-sock); +virNetClientUnlock(client); +return fd; +} + + +int virNetClientDupFD(virNetClientPtr client) +{ +int fd; +virNetClientLock(client); +fd = virNetSocketDupFD(client-sock); +virNetClientUnlock(client); +return fd; +} + + void virNetClientFree(virNetClientPtr client) { int i; diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h index de0782c..381d647 100644 --- a/src/rpc/virnetclient.h +++ b/src/rpc/virnetclient.h @@ -51,6 +51,9 @@ virNetClientPtr virNetClientNewExternal(const char **cmdargv); void virNetClientRef(virNetClientPtr client); +int virNetClientGetFD(virNetClientPtr client); +int virNetClientDupFD(virNetClientPtr client); + int virNetClientAddProgram(virNetClientPtr client, virNetClientProgramPtr prog); diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 4b0c2ee..aff68bc 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -675,6 +675,18 @@ int virNetSocketGetFD(virNetSocketPtr sock) } +int virNetSocketDupFD(virNetSocketPtr sock) +{ +int fd; +if ((fd = dup(sock-fd)) 0) { +virReportSystemError(errno, %s, + _(Unable to copy socket file handle)); +return -1; +} +return fd; +} + + bool virNetSocketIsLocal(virNetSocketPtr sock) { if (sock-localAddr.data.sa.sa_family == AF_UNIX) diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index 356d6c6..8053213 100644 --- a/src/rpc/virnetsocket.h +++ b/src/rpc/virnetsocket.h @@ -75,6 +75,8 @@ int virNetSocketNewConnectExternal(const char **cmdargv, virNetSocketPtr *addr); int virNetSocketGetFD(virNetSocketPtr sock); +int virNetSocketDupFD(virNetSocketPtr sock); + bool virNetSocketIsLocal(virNetSocketPtr sock); int virNetSocketGetPort(virNetSocketPtr sock); -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 08/14] Define a wire protocol for talking to the virtlockd daemon
From: Daniel P. Berrange berra...@redhat.com The virtlockd daemon will be responsible for managing locks on virtual machines. Communication will be via the standard RPC infrastructure. This provides the XDR protocol definition * src/locking/lock_protocol.x: Wire protocol for virtlockd --- .gitignore |1 + src/locking/lock_protocol.x | 98 +++ 2 files changed, 99 insertions(+), 0 deletions(-) create mode 100644 src/locking/lock_protocol.x diff --git a/.gitignore b/.gitignore index 1bfb7b9..e6ab70b 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ /po/* /proxy/ /src/libvirt_iohelper +/src/locking/lock_protocol.[ch] /src/remote/*_client_bodies.h /src/remote/*_protocol.[ch] /src/rpc/virnetprotocol.[ch] diff --git a/src/locking/lock_protocol.x b/src/locking/lock_protocol.x new file mode 100644 index 000..ece1652 --- /dev/null +++ b/src/locking/lock_protocol.x @@ -0,0 +1,98 @@ +/* -*- c -*- + */ + +%#include locking/lock_driver.h + +typedef opaque lock_uuid[VIR_UUID_BUFLEN]; + +/* Length of long, but not unbounded, strings. + * This is an arbitrary limit designed to stop the decoder from trying + * to allocate unbounded amounts of memory when fed with a bad message. + */ +const LOCK_STRING_MAX = 65536; + +const LOCK_PARAMETERS_MAX = 20; + +/* A long string, which may NOT be NULL. */ +typedef string lock_nonnull_stringLOCK_STRING_MAX; + +/* A long string, which may be NULL. */ +typedef lock_nonnull_string *lock_string; + +union lock_param_value switch (int type) { +case VIR_LOCK_MANAGER_PARAM_TYPE_STRING: +lock_nonnull_string s; +case VIR_LOCK_MANAGER_PARAM_TYPE_INT: +int i; +case VIR_LOCK_MANAGER_PARAM_TYPE_LONG: +hyper l; +case VIR_LOCK_MANAGER_PARAM_TYPE_UINT: +unsigned int ui; +case VIR_LOCK_MANAGER_PARAM_TYPE_ULONG: +unsigned hyper ul; +case VIR_LOCK_MANAGER_PARAM_TYPE_DOUBLE: +double d; +case VIR_LOCK_MANAGER_PARAM_TYPE_UUID: +lock_uuid u; +}; + +struct lock_param { +lock_nonnull_string key; +lock_param_value value; +}; + +struct lock_register_args { +unsigned int type; +lock_param paramsLOCK_PARAMETERS_MAX; +unsigned int flags; +bool restrictAccess; +}; + + +struct lock_add_resource_args { +unsigned int type; +lock_nonnull_string name; +lock_param paramsLOCK_PARAMETERS_MAX; +unsigned int flags; +}; + +struct lock_acquire_args { +unsigned int flags; +lock_string state; +}; + + +struct lock_release_args { +unsigned int flags; +}; + +struct lock_release_ret { +lock_string state; +}; + + +struct lock_inquire_args { +unsigned int flags; +}; + +struct lock_inquire_ret { +lock_string state; +}; + + +/* Define the program number, protocol version and procedure numbers here. */ +const LOCK_PROGRAM = 0xEA7BEEF; +const LOCK_PROTOCOL_VERSION = 1; + +enum lock_procedure { +/* Each function must have a two-word comment. The first word is + * whether remote_generator.pl handles daemon, the second whether + * it handles src/remote. Additional flags can be specified after a + * pipe. + */ +LOCK_PROC_REGISTER = 1, /* skipgen skipgen */ +LOCK_PROC_ADD_RESOURCE = 2, /* skipgen skipgen */ +LOCK_PROC_ACQUIRE = 3, /* skipgen skipgen */ +LOCK_PROC_RELEASE = 4, /* skipgen skipgen */ +LOCK_PROC_INQUIRE = 5 /* skipgen skipgen */ +}; -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 00/14] Add a virtlockd lock manager daemon
The lock manager infrastructure we recently added to QEMU only has two possible drivers at this time, 'nop' and 'sanlock'. The former does absolutely nothing, while the latter requires a 3rd party package installed and is a little heavy on disk I/O and storage requirements. This series adds a new daemon 'virtlockd' which is intended to be enabled by default on all hosts running 'libvirtd'. This daemon provides a service for disk locking based on the traditional fcntl() lock primitives. There is a new libvirt manager plugin which talks to this daemon over RPC. The reason for doing the locks in a separate process is that we want the locks to remain active, even if libvirtd crashes, or is restarted. The virtlockd daemon has this one single job so should be pretty reliable and selfcontained. This patch series really benefits from the new RPC APIs, requiring minimal code for the new daemon / client At this time, virtlockd does not lock the actual disk files, but instead creates a lockspace leases under /var/lib/libvirt/lockd. The lockspace we use for disks is named org.libvirt.lockd.files, and lease names are based on a SHA256 checksum of the fully qualified disk name. eg /var/lib/libvirt/lockd/org.libvirt.lockd.files/adf94fc33a24da1abff7dd7374a9919bb51efee646da8c3ac464c10cd59750bd These leases are all zero-bytes long and no I/O is ever performed on them, only fcntl() is used. So there is material overhead. Whenever creating or deleting leases, we first acquire a lock on /var/lib/libvirt/lockd/org.libvirt.lockd.files/org.libvirt.lockd.index A non-root virtlockd will instead use $HOME/.libvirt/lockd By default we gain protection out of the box against - Starting two guests on the same host with the same disk image not marked with shareable/ - libvirtd getting confused and forgetting a guest, allowing it to be started for a 2nd time If the admin mounts a shared filesytem (eg NFS) on /var/lib/libvirt/lockd then this protection is extended across all hosts sharing that mount volume. As part of this series, I also introduce support for systemd services for libvirtd and libvir-guests. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 01/14] Remove unused virNetServerProgramErrorHander typedef
From: Daniel P. Berrange berra...@redhat.com * src/rpc/virnetserverprogram.h: Remove unused typedef for virNetServerProgramErrorHander function callback * daemon/remote.h: Remove decl for non-existant variables --- daemon/remote.h |2 -- src/rpc/virnetserverprogram.h |3 --- 2 files changed, 0 insertions(+), 5 deletions(-) diff --git a/daemon/remote.h b/daemon/remote.h index c9bf5d7..5444e47 100644 --- a/daemon/remote.h +++ b/daemon/remote.h @@ -31,11 +31,9 @@ extern virNetServerProgramProc remoteProcs[]; extern size_t remoteNProcs; -extern virNetServerProgramErrorHander remoteErr; extern virNetServerProgramProc qemuProcs[]; extern size_t qemuNProcs; -extern virNetServerProgramErrorHander qemuErr; int remoteClientInitHook(virNetServerPtr srv, virNetServerClientPtr client); diff --git a/src/rpc/virnetserverprogram.h b/src/rpc/virnetserverprogram.h index 98071a2..ca31b7e 100644 --- a/src/rpc/virnetserverprogram.h +++ b/src/rpc/virnetserverprogram.h @@ -39,9 +39,6 @@ typedef virNetServerProgram *virNetServerProgramPtr; typedef struct _virNetServerProgramProc virNetServerProgramProc; typedef virNetServerProgramProc *virNetServerProgramProcPtr; -typedef struct _virNetServerProgramErrorHandler virNetServerProgramErrorHander; -typedef virNetServerProgramErrorHander *virNetServerProgramErrorHanderPtr; - typedef int (*virNetServerProgramDispatchFunc)(virNetServerPtr server, virNetServerClientPtr client, virNetMessageHeaderPtr hdr, -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 04/14] Ensure signal handler propagates fatal signals to default handler
From: Daniel P. Berrange berra...@redhat.com When replacing the default SEGV/ABORT/BUS signal handlers you can't rely on the process being terminated after your custom handler runs. It is neccessary to manually restore the default handler and then re-raise the signal * src/rpc/virnetserver.c: Restore default handler and raise signal --- src/rpc/virnetserver.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 5e1719b..d5e9d0a 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -257,8 +257,9 @@ static void virNetServerFatalSignal(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED #ifdef SIGUSR2 if (sig != SIGUSR2) { #endif -sig_action.sa_handler = SIG_IGN; +sig_action.sa_handler = SIG_DFL; sigaction(sig, sig_action, NULL); +raise(sig); #ifdef SIGUSR2 } #endif -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 02/14] Add virFileLock and virFileUnlock APIs
From: Daniel P. Berrange berra...@redhat.com Add some simple wrappers around the fcntl() discretionary file locking capability. * src/util/util.c, src/util/util.h, src/libvirt_private.syms: Add virFileLock and virFileUnlock APIs --- src/libvirt_private.syms |2 ++ src/util/util.c | 33 + src/util/util.h |3 +++ 3 files changed, 38 insertions(+), 0 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ae0d199..0746dee 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -993,6 +993,7 @@ virFileFindMountPoint; virFileHasSuffix; virFileIsExecutable; virFileLinkPointsTo; +virFileLock; virFileMakePath; virFileMatchesNameSuffix; virFileOpenAs; @@ -1004,6 +1005,7 @@ virFileReadPid; virFileResolveLink; virFileSanitizePath; virFileStripSuffix; +virFileUnlock; virFileWaitForDevices; virFileWriteStr; virFindFileInPath; diff --git a/src/util/util.c b/src/util/util.c index 4710fc5..1d8083f 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1175,6 +1175,39 @@ int virFileOpenTtyAt(const char *ptmx ATTRIBUTE_UNUSED, } #endif + +int virFileLock(int fd, bool shared, off_t start, off_t len) +{ +struct flock fl = { +.l_type = shared ? F_RDLCK : F_WRLCK, +.l_whence = SEEK_SET, +.l_start = start, +.l_len = len, +}; + +if (fcntl(fd, F_SETLK, fl) 0) +return -errno; + +return 0; +} + + +int virFileUnlock(int fd, off_t start, off_t len) +{ +struct flock fl = { +.l_type = F_UNLCK, +.l_whence = SEEK_SET, +.l_start = start, +.l_len = len, +}; + +if (fcntl(fd, F_SETLK, fl) 0) +return -errno; + +return 0; +} + + char* virFilePid(const char *dir, const char* name) { char *pidfile; diff --git a/src/util/util.h b/src/util/util.h index 1555653..820c9ff 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -117,6 +117,9 @@ int virFileOpenTtyAt(const char *ptmx, char **ttyName, int rawmode); +int virFileLock(int fd, bool shared, off_t start, off_t len); +int virFileUnlock(int fd, off_t start, off_t len); + char* virFilePid(const char *dir, const char *name); -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 07/14] Change function signature for creating new lock manager instances
From: Daniel P. Berrange berra...@redhat.com To allow a virLockManagerPtr to be created directly from a driver table struct, replace the virLockManagerPluginPtr parameter with a virLockDriverPtr parameter. * src/locking/domain_lock.c, src/locking/lock_manager.c, src/locking/lock_manager.h: Replace plugin param with a driver in virLockManagerNew --- src/locking/domain_lock.c |2 +- src/locking/lock_manager.c | 25 - src/locking/lock_manager.h |3 ++- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/locking/domain_lock.c b/src/locking/domain_lock.c index de1937c..0ce74ff 100644 --- a/src/locking/domain_lock.c +++ b/src/locking/domain_lock.c @@ -124,7 +124,7 @@ static virLockManagerPtr virDomainLockManagerNew(virLockManagerPluginPtr plugin, memcpy(params[0].value.uuid, dom-def-uuid, VIR_UUID_BUFLEN); -if (!(lock = virLockManagerNew(plugin, +if (!(lock = virLockManagerNew(virLockManagerPluginGetDriver(plugin), VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN, ARRAY_CARDINALITY(params), params, diff --git a/src/locking/lock_manager.c b/src/locking/lock_manager.c index 4ee7f44..f257707 100644 --- a/src/locking/lock_manager.c +++ b/src/locking/lock_manager.c @@ -43,8 +43,8 @@ virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) -#define CHECK_PLUGIN(field, errret) \ -if (!plugin-driver-field) {\ +#define CHECK_DRIVER(field, errret) \ +if (!driver-field) {\ virLockError(VIR_ERR_INTERNAL_ERROR, \ _(Missing '%s' field in lock manager driver), \ #field);\ @@ -268,9 +268,16 @@ bool virLockManagerPluginUsesState(virLockManagerPluginPtr plugin) } +virLockDriverPtr virLockManagerPluginGetDriver(virLockManagerPluginPtr plugin) +{ +VIR_DEBUG(plugin=%p, plugin); + +return plugin-driver; +} + /** * virLockManagerNew: - * @plugin: the plugin implementation to use + * @driver: the lock manager implementation to use * @type: the type of process to be supervised * @flags: optional flags, currently unused * @@ -279,27 +286,27 @@ bool virLockManagerPluginUsesState(virLockManagerPluginPtr plugin) * * Returns a new lock manager context */ -virLockManagerPtr virLockManagerNew(virLockManagerPluginPtr plugin, +virLockManagerPtr virLockManagerNew(virLockDriverPtr driver, unsigned int type, size_t nparams, virLockManagerParamPtr params, unsigned int flags) { virLockManagerPtr lock; -VIR_DEBUG(plugin=%p type=%u nparams=%zu params=%p flags=%u, - plugin, type, nparams, params, flags); +VIR_DEBUG(driver=%p type=%u nparams=%zu params=%p flags=%u, + driver, type, nparams, params, flags); virLockManagerLogParams(nparams, params); -CHECK_PLUGIN(drvNew, NULL); +CHECK_DRIVER(drvNew, NULL); if (VIR_ALLOC(lock) 0) { virReportOOMError(); return NULL; } -lock-driver = plugin-driver; +lock-driver = driver; -if (plugin-driver-drvNew(lock, type, nparams, params, flags) 0) { +if (driver-drvNew(lock, type, nparams, params, flags) 0) { VIR_FREE(lock); return NULL; } diff --git a/src/locking/lock_manager.h b/src/locking/lock_manager.h index 0fb3bb7..5afb0d0 100644 --- a/src/locking/lock_manager.h +++ b/src/locking/lock_manager.h @@ -37,8 +37,9 @@ void virLockManagerPluginUnref(virLockManagerPluginPtr plugin); const char *virLockManagerPluginGetName(virLockManagerPluginPtr plugin); bool virLockManagerPluginUsesState(virLockManagerPluginPtr plugin); +virLockDriverPtr virLockManagerPluginGetDriver(virLockManagerPluginPtr plugin); -virLockManagerPtr virLockManagerNew(virLockManagerPluginPtr plugin, +virLockManagerPtr virLockManagerNew(virLockDriverPtr driver, unsigned int type, size_t nparams, virLockManagerParamPtr params, -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 13/14] Change the default QEMU lock manager to 'lockd'
From: Daniel P. Berrange berra...@redhat.com The current default QEMU lock manager is the 'nop' lock manager, which obviously does not perform any locking. The new virtlockd daemon is able to work out of the box with zero configuration in single-host only mode. Enable this as the default lock manager for all QEMU guests * src/qemu/qemu.conf: Update docs for lock_driver parameter * src/qemu/qemu_conf.c: Change default lock manager to 'lockd' --- src/qemu/qemu.conf | 16 +++- src/qemu/qemu_conf.c |2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 2c50d9d..a8c1c87 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -281,9 +281,15 @@ # # max_processes = 0 -# To enable strict 'fcntl' based locking of the file -# content (to prevent two VMs writing to the same -# disk), start the 'virtlockd' service, and uncomment -# this # -# lock_manager = fcntl +# By default the QEMU driver talks to the 'virtlockd' +# daemon to acquire exclusive locks for all guest disk +# images associated with a running VM. +# +# To revert to behaviour of previous releases which did +# not acquire any locks, set this to 'nop'. +# +# To enable use of the external 'sanlock' locking +# daemon, change this to 'sanlock'. +# +# lock_manager = lockd diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 3d8aba4..1baa37e 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -116,7 +116,7 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, #endif if (!(driver-lockManager = - virLockManagerPluginNew(nop, NULL, 0))) + virLockManagerPluginNew(lockd, NULL, 0))) return -1; /* Just check the file is readable before opening it, otherwise -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 12/14] Add a 'lockd' lock driver implementation
From: Daniel P. Berrange berra...@redhat.com This adds a 'lockd' lock driver which is just a client which talks to the lockd daemon to perform all locking. This will be the default lock driver for any hypervisor which needs one. * src/Makefile.am: Add lockd.so plugin * src/locking/lock_driver_lockd.c: Lockd driver impl --- src/Makefile.am | 16 +- src/locking/lock_driver_lockd.c | 600 +++ 2 files changed, 613 insertions(+), 3 deletions(-) create mode 100644 src/locking/lock_driver_lockd.c diff --git a/src/Makefile.am b/src/Makefile.am index 3e2c376..9a9deab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -111,6 +111,10 @@ LOCKD_GENERATED = \ BUILT_SOURCES += $(LOCKD_GENERATED) +LOCK_DRIVER_LOCKD_SOURCES = \ + locking/lock_driver_lockd.c \ + $(LOCK_PROTOCOL_GENERATED) + LOCK_DAEMON_SOURCES = \ locking/lock_daemon.c \ locking/lock_daemon_dispatch.h \ @@ -1211,6 +1215,14 @@ libvirt_qemu_la_LIBADD = libvirt.la $(CYGWIN_EXTRA_LIBADD) EXTRA_DIST += $(LIBVIRT_QEMU_SYMBOL_FILE) if WITH_LIBVIRTD +lockdriverdir = $(libdir)/libvirt/lock-driver +lockdriver_LTLIBRARIES = lockd.la + +lockd_la_SOURCES = $(LOCK_DRIVER_LOCKD_SOURCES) +lockd_la_CFLAGS = $(AM_CFLAGS) +lockd_la_LDFLAGS = -module -avoid-version +lockd_la_LIBADD = ../gnulib/lib/libgnu.la libvirt-net-rpc.la libvirt-net-rpc-client.la + sbin_PROGRAMS = virtlockd virtlockd_SOURCES = $(LOCK_DAEMON_SOURCES) @@ -1272,9 +1284,7 @@ virtlockd.init: locking/virtlockd.init.in $(top_builddir)/config.status if HAVE_SANLOCK -lockdriverdir = $(libdir)/libvirt/lock-driver -lockdriver_LTLIBRARIES = sanlock.la - +lockdriver_LTLIBRARIES += sanlock.la sanlock_la_SOURCES = $(LOCK_DRIVER_SANLOCK_SOURCES) sanlock_la_CFLAGS = $(AM_CFLAGS) sanlock_la_LDFLAGS = -module -avoid-version diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c new file mode 100644 index 000..b7ac0f7 --- /dev/null +++ b/src/locking/lock_driver_lockd.c @@ -0,0 +1,600 @@ +/* + * lock_driver_lockd.c: A lock driver which locks nothing + * + * Copyright (C) 2010-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include config.h + +#include lock_driver.h +#include memory.h +#include logging.h +#include uuid.h +#include util.h +#include files.h +#include virterror_internal.h +#include rpc/virnetclient.h +#include lock_protocol.h +#include configmake.h + +#define VIR_FROM_THIS VIR_FROM_LOCKING + +#define virLockError(code, ...) \ +virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + +typedef struct _virLockManagerLockDPrivate virLockManagerLockDPrivate; +typedef virLockManagerLockDPrivate *virLockManagerLockDPrivatePtr; + +typedef struct _virLockManagerLockDResource virLockManagerLockDResource; +typedef virLockManagerLockDResource *virLockManagerLockDResourcePtr; + +struct _virLockManagerLockDResource { +int type; +char *name; +unsigned int flags; +size_t nparams; +virLockManagerParamPtr params; +}; + +struct _virLockManagerLockDPrivate { +int type; +unsigned int flags; +size_t nparams; +virLockManagerParamPtr params; +size_t nresources; +virLockManagerLockDResourcePtr resources; +}; + + +static virLockManagerParamPtr +virLockManagerLockDCopyParams(size_t nParams, + virLockManagerParamPtr params) +{ +virLockManagerParamPtr newParams; +size_t i, j; + +if (VIR_ALLOC_N(newParams, nParams) 0) { +virReportOOMError(); +return NULL; +} + +memcpy(newParams, params, sizeof(*params)*nParams); + +for (i = 0 ; i nParams ; i++) { +if (params[i].type == VIR_LOCK_MANAGER_PARAM_TYPE_STRING) { +if (!(newParams[i].value.str = strdup(params[i].value.str))) { +virReportOOMError(); +goto error; +} +} +} + +return newParams; + +error: +for (j = 0 ; j i ; j++) { +VIR_FREE(newParams[i].value.str); +} +VIR_FREE(newParams); +return NULL; +} + +static int virLockManagerLockDInit(unsigned int version, +
[libvirt] [PATCH 06/14] Add support for systemd init service
From: Daniel P. Berrange berra...@redhat.com This patch adds support for a systemd init service for libvirtd and libvirt-guests. The libvirtd.service is *not* written to use socket activation, since we want libvirtd to start on boot so it can do guest auto-start. The libvirt-guests.service is pretty lame, just exec'ing the original init script for now. Ideally we would factor out the functionality, into some shared tool. Instead of ./configure --with-init-script=redhat You can now do ./configure --with-init-script=systemd Or better still: ./configure --with-init-script=systemd+redhat * configure.ac: Add systemd, and systemd+redhat options to --with-init-script option * daemon/Makefile.am: Install systemd services * daemon/libvirtd.sysconf: Add note about unused env variable with systemd * daemon/libvirtd.service.in: libvirtd systemd service unit * libvirt.spec.in: Add scripts to installing systemd services and migrating from legacy init scripts * tools/Makefile.am: Install systemd services * tools/libvirt-guests.init.sh: Rename to tools/libvirt-guests.init.in * tools/libvirt-guests.service.in: systemd service unit --- configure.ac | 32 +-- daemon/.gitignore |1 + daemon/Makefile.am | 62 ++ daemon/libvirtd.service.in | 20 daemon/libvirtd.sysconf|3 + libvirt.spec.in| 92 +++- tools/Makefile.am | 63 +++--- ...bvirt-guests.init.sh = libvirt-guests.init.in} |0 tools/libvirt-guests.service.in| 13 +++ 9 files changed, 245 insertions(+), 41 deletions(-) create mode 100644 daemon/libvirtd.service.in rename tools/{libvirt-guests.init.sh = libvirt-guests.init.in} (100%) create mode 100644 tools/libvirt-guests.service.in diff --git a/configure.ac b/configure.ac index 13b4afb..d70e574 100644 --- a/configure.ac +++ b/configure.ac @@ -305,16 +305,30 @@ dnl init script flavor dnl AC_MSG_CHECKING([for init script flavor]) AC_ARG_WITH([init-script], -[AC_HELP_STRING([--with-init-script=@:@redhat|auto|none@:@], + [AC_HELP_STRING([--with-init-script=@:@redhat|systemd|systemd+redhat|upstart|auto|none@:@], [Style of init script to install @:@default=auto@:@])]) -if test x$with_init_script = x || test x$with_init_script = xauto; then -if test $cross_compiling = yes || test ! -f /etc/redhat-release; then -with_init_script=none -else -with_init_script=redhat -fi -fi -AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_RED_HAT], test x$with_init_script = xredhat) +init_redhat=no +init_systemd=no +case $with_init_script in +systemd+redhat) + init_redhat=yes + init_systemd=yes + ;; +systemd) + init_systemd=yes + ;; +redhat) + init_redhat=yes + ;; +*) + if test $cross_compiling != yes test -f /etc/redhat-release; then + init_redhat=yes + with_init_script=redhat + fi + ;; +esac +AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_RED_HAT], test $init_redhat = yes) +AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_SYSTEMD], test $init_systemd = yes) AC_MSG_RESULT($with_init_script) dnl RHEL-5 has a peculiar version of Xen, which requires some special casing diff --git a/daemon/.gitignore b/daemon/.gitignore index ab3d093..2873143 100644 --- a/daemon/.gitignore +++ b/daemon/.gitignore @@ -7,6 +7,7 @@ Makefile.in libvirt_qemud libvirtd libvirtd.init +libvirtd.service libvirtd*.logrotate libvirtd.8 libvirtd.8.in diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 8ed29b8..abb5e1f 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -180,13 +180,13 @@ probes.o: probes.d CLEANFILES += probes.h probes.o endif -install-data-local: install-init install-data-sasl install-data-polkit \ +install-data-local: install-init install-systemd install-data-sasl install-data-polkit \ install-logrotate mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt mkdir -p $(DESTDIR)$(localstatedir)/run/libvirt mkdir -p $(DESTDIR)$(localstatedir)/lib/libvirt -uninstall-local:: uninstall-init uninstall-data-sasl uninstall-data-polkit +uninstall-local:: uninstall-init uninstall-systemd uninstall-data-sasl uninstall-data-polkit rmdir $(DESTDIR)$(localstatedir)/log/libvirt || : rmdir $(DESTDIR)$(localstatedir)/run/libvirt || : rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || : @@ -244,20 +244,47 @@ install-logrotate: $(LOGROTATE_CONFS) $(INSTALL_DATA) libvirtd.lxc.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc $(INSTALL_DATA) libvirtd.uml.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml +install-sysconfig: + mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig +
[libvirt] [PATCH 09/14] Add a simple internal API for managing lockspaces
From: Daniel P. Berrange berra...@redhat.com This adds a simple module for managing lockspaces. A lockspace has a path to a directory, which will usually be kep on shared storage like NFS/GFS, etc Inside the lockspace leases are created as plain files. Locks on leases are taken using the virFileLock APIs (fcntl based). Leases can be created ahead of time, or auto-created/deleted at time of lock acquisition/release. Before creating/deleting a lock, a lock must be held on the index file for the lockspace * src/locking/lock_database.c, src/locking/lock_database.h: Simple internal API for lockspaces * include/libvirt/virterror.h, src/util/virterror.c: Add VIR_ERR_RESOURCE_BUSY --- include/libvirt/virterror.h |1 + src/locking/lock_database.c | 915 +++ src/locking/lock_database.h | 43 ++ src/util/virterror.c|6 + 4 files changed, 965 insertions(+), 0 deletions(-) create mode 100644 src/locking/lock_database.c create mode 100644 src/locking/lock_database.h diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index efa4796..84226ac 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -232,6 +232,7 @@ typedef enum { VIR_ERR_INVALID_DOMAIN_SNAPSHOT = 71,/* invalid domain snapshot */ VIR_ERR_NO_DOMAIN_SNAPSHOT = 72, /* domain snapshot not found */ VIR_ERR_INVALID_STREAM = 73,/* stream pointer not valid */ +VIR_ERR_RESOURCE_BUSY = 74, /* resource is already in use */ } virErrorNumber; /** diff --git a/src/locking/lock_database.c b/src/locking/lock_database.c new file mode 100644 index 000..4e51548 --- /dev/null +++ b/src/locking/lock_database.c @@ -0,0 +1,915 @@ + +#include config.h + +#include unistd.h +#include fcntl.h +#include sys/stat.h + +#include uuid.h +#include lock_database.h +#include virterror_internal.h +#include logging.h +#include memory.h +#include files.h +#include hash.h +#include util.h + +#define VIR_FROM_THIS VIR_FROM_LOCKING + +#define virLockError(code, ...) \ +virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + +/* + * Approach to handling locking: + * + * - Lock storage area, identified by a path to a directory + * + * eg /var/lib/libvirt/lock + * + *The storage area should generally be on shared storage (NFS, + *GFS, etc), unless protection is only desired within the + *scope of the local machine + * + * - Lockspaces within a storage area, identified by an + *arbitrary name, which must not contain '/'. Recommended + *to use domain name style lockspace names, eg org.libvirt.lockd.files + * + * /var/lib/libvirt/lockd/org.libvirt.lockd.files + * + * - Lockspaces contain a single 'index' file which contains + *the original unhashed lockspace name. + * + * - Lease key within a lockspace. Identified by a arbitrary + *string, which must not contain '/', or be the word + *'org.livirt.lockd.index'. + * + * /var/lib/libvirt/lockd/org.libvirt.lockd.files/wibble + * + * - When creating or deleting a lease must be held on the + *'org.libvirt.lockd.index' lease of the lockspace + * + */ + +typedef struct _virLockDatabaseLease virLockDatabaseLease; +typedef virLockDatabaseLease *virLockDatabaseLeasePtr; + +typedef struct _virLockDatabaseLockspace virLockDatabaseLockspace; +typedef virLockDatabaseLockspace *virLockDatabaseLockspacePtr; + +typedef struct _virLockDatabaseFile virLockDatabaseFile; +typedef virLockDatabaseFile *virLockDatabaseFilePtr; + +struct _virLockDatabaseFile { +bool shared; +char *path; +unsigned int refs; /* # of attached users for shared locks */ +int fd; +}; + +struct _virLockDatabaseLease { +char *key; + +virLockDatabaseFile file; +}; + +struct _virLockDatabaseLockspace { +char *path; +char *name; + +bool autoLease; + +virLockDatabaseLeasePtr idx; + +size_t nleases; +virLockDatabaseLeasePtr *leases; +}; + +struct _virLockDatabase { +unsigned char hostuuid[VIR_UUID_BUFLEN]; +char *hostname; + +size_t nlockspaces; +virLockDatabaseLockspacePtr *lockspaces; + +virHashTablePtr files; +}; + + +static void virLockDatabaseFileClear(virLockDatabaseFilePtr file) +{ +if (!file) +return; + +VIR_FORCE_CLOSE(file-fd); +VIR_FREE(file-path); +} + + +static void virLockDatabaseLeaseFree(virLockDatabaseLeasePtr lease) +{ +if (!lease) +return; + +virLockDatabaseFileClear(lease-file); + +VIR_FREE(lease-key); +VIR_FREE(lease); +} + + +static void virLockDatabaseLockspaceFree(virLockDatabaseLockspacePtr lkspc) +{ +size_t i; + +if (!lkspc) +return; + +for (i = 0 ; i lkspc-nleases ; i++) +virLockDatabaseLeaseFree(lkspc-leases[i]); +VIR_FREE(lkspc-leases); + +virLockDatabaseLeaseFree(lkspc-idx); + +VIR_FREE(lkspc-path); +
[libvirt] [PATCH 11/14] Add the virtlockd daemon for managing virtual guest locks
From: Daniel P. Berrange berra...@redhat.com This adds a new daemon 'virtlockd' which will manage the locks for all running virtual machines. Communication is via a new RPC lock program. The intent is that virtlockd runs forever and if it ever crashes, the entire host should be restarted (ideally via a hardware fencing agent) to ensure maximum safety of guest disks. * cfg.mk: Ignore the lockd files * src/locking/lock_daemon.c, src/locking/lock_daemon.h: Main daemon startup code * src/locking/lock_daemon_dispatch.c, src/locking/lock_daemon_dispatch.h: RPC dispatcher for lock program * src/locking/virtlockd.init.in: Init script * src/locking/virtlockd.sysconf: Init script configuration * libvirt.spec.in: Add initscript --- cfg.mk |4 +- libvirt.spec.in|8 + po/POTFILES.in |5 + src/.gitignore |4 + src/Makefile.am| 106 +- src/libvirt_private.syms |2 + src/locking/lock_daemon.c | 776 src/locking/lock_daemon_dispatch.c | 334 src/locking/lock_daemon_dispatch.h | 46 +++ src/locking/virtlockd.init.in | 93 + src/locking/virtlockd.sysconf |3 + 11 files changed, 1374 insertions(+), 7 deletions(-) create mode 100644 src/locking/lock_daemon.c create mode 100644 src/locking/lock_daemon.h create mode 100644 src/locking/lock_daemon_dispatch.c create mode 100644 src/locking/lock_daemon_dispatch.h create mode 100644 src/locking/virtlockd.init.in create mode 100644 src/locking/virtlockd.sysconf diff --git a/cfg.mk b/cfg.mk index b00cda3..8074b59 100644 --- a/cfg.mk +++ b/cfg.mk @@ -616,7 +616,7 @@ $(srcdir)/src/remote/remote_client_bodies.h: # List all syntax-check exemptions: exclude_file_name_regexp--sc_avoid_strcase = ^tools/virsh\.c$$ -_src1=libvirt|fdstream|qemu/qemu_monitor|util/(command|util)|xen/xend_internal|rpc/virnetsocket +_src1=libvirt|fdstream|qemu/qemu_monitor|util/(command|util)|xen/xend_internal|rpc/virnetsocket|locking/lock_daemon exclude_file_name_regexp--sc_avoid_write = \ ^(src/($(_src1))|daemon/libvirtd|tools/console)\.c$$ @@ -646,7 +646,7 @@ exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \ _src2=src/(util/command|libvirt|lxc/lxc_controller) exclude_file_name_regexp--sc_prohibit_fork_wrappers = \ - (^docs|^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$) + (^docs|^($(_src2)|tests/testutils|daemon/libvirtd|src/locking/lock_daemon)\.c$$) exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/util\.c$$ diff --git a/libvirt.spec.in b/libvirt.spec.in index 650f0bc..7f6fd13 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1007,11 +1007,13 @@ fi %{_sysconfdir}/libvirt/nwfilter/*.xml %{_sysconfdir}/rc.d/init.d/libvirtd +%{_sysconfdir}/rc.d/init.d/virtlockd %if %{with_systemd} %{_unitdir}/libvirtd.service %endif %doc daemon/libvirtd.upstart %config(noreplace) %{_sysconfdir}/sysconfig/libvirtd +%config(noreplace) %{_sysconfdir}/sysconfig/virtlockd %config(noreplace) %{_sysconfdir}/libvirt/libvirtd.conf %if %{with_dtrace} %{_datadir}/systemtap/tapset/libvirtd.stp @@ -1072,6 +1074,11 @@ fi %dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/dnsmasq/ %endif +%if %{with_libvirtd} +%dir %attr(0755, root, root) %{_libdir}/libvirt/lock-driver +%attr(0755, root, root) %{_libdir}/libvirt/lock-driver/lockd.so +%endif + %if %{with_qemu} %{_datadir}/augeas/lenses/libvirtd_qemu.aug %{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug @@ -1105,6 +1112,7 @@ fi %attr(0755, root, root) %{_libexecdir}/libvirt_iohelper %attr(0755, root, root) %{_sbindir}/libvirtd +%attr(0755, root, root) %{_sbindir}/virtlockd %{_mandir}/man8/libvirtd.8* diff --git a/po/POTFILES.in b/po/POTFILES.in index 32eaa2d..bb94d51 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -30,8 +30,13 @@ src/fdstream.c src/interface/netcf_driver.c src/internal.h src/libvirt.c +src/locking/lock_database.c +src/locking/lock_driver_fcntl.c +src/locking/lock_driver_lockd.c src/locking/lock_driver_sanlock.c src/locking/lock_manager.c +src/locking/lock_daemon.c +src/locking/lock_daemon_dispatch.c src/lxc/lxc_container.c src/lxc/lxc_conf.c src/lxc/lxc_controller.c diff --git a/src/.gitignore b/src/.gitignore index a619643..c499b47 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -16,3 +16,7 @@ libvirt_qemu.def *.s remote_protocol-structs-t virt-aa-helper +virtlockd +virtlockd.socket +locking/lock_daemon_dispatch_stubs.h +locking/qemu-sanlock.conf diff --git a/src/Makefile.am b/src/Makefile.am index cd8a7e9..3e2c376 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -96,8 +96,34 @@ DRIVER_SOURCES = \ libvirt.c libvirt_internal.h\ locking/lock_manager.c locking/lock_manager.h \ locking/lock_driver.h
[libvirt] [PATCH 14/14] Enable systemd socket activation with virtlockd
From: Daniel P. Berrange berra...@redhat.com This enhancement virtlockd so that it can receive a pre-opened UNIX domain socket from systemd at launch time, and adds the systemd service/socket unit files * daemon/libvirtd.service.in: Require virtlockd to be running * libvirt.spec.in: Add virtlockd systemd files * src/Makefile.am: Install systemd files * src/locking/lock_daemon.c: Support socket activation * src/locking/virtlockd.service.in, src/locking/virtlockd.socket.in: systemd unit files * src/rpc/virnetserverservice.c, src/rpc/virnetserverservice.h: Add virNetServerServiceNewFD() method * src/rpc/virnetsocket.c, src/rpc/virnetsocket.h: Add virNetSocketNewListenFD method --- daemon/libvirtd.service.in |2 + libvirt.spec.in |6 +++ src/.gitignore |2 + src/Makefile.am | 51 +- src/locking/lock_daemon.c| 73 - src/locking/virtlockd.service.in | 16 src/locking/virtlockd.socket.in |5 +++ src/rpc/virnetserverservice.c| 48 + src/rpc/virnetserverservice.h|5 +++ src/rpc/virnetsocket.c | 20 ++ src/rpc/virnetsocket.h |3 ++ 11 files changed, 227 insertions(+), 4 deletions(-) create mode 100644 src/locking/virtlockd.service.in create mode 100644 src/locking/virtlockd.socket.in diff --git a/daemon/libvirtd.service.in b/daemon/libvirtd.service.in index 9661428..1cc0ae8 100644 --- a/daemon/libvirtd.service.in +++ b/daemon/libvirtd.service.in @@ -9,7 +9,9 @@ After=syslog.target After=udev.target After=avahi.target After=dbus.target +After=virtlockd.service Before=libvirt-guests.service +Requires=virtlockd.service [Service] EnvironmentFile=-/etc/sysconfig/libvirtd diff --git a/libvirt.spec.in b/libvirt.spec.in index 7f6fd13..ccc3db3 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -892,6 +892,7 @@ done %if %{with_systemd} if [ $1 -eq 1 ] ; then # Initial installation +/bin/systemctl enable virtlockd.service /dev/null 21 || : /bin/systemctl enable libvirtd.service /dev/null 21 || : /bin/systemctl enable cgconfig.service /dev/null 21 || : fi @@ -914,8 +915,10 @@ fi %if %{with_systemd} if [ $1 -eq 0 ] ; then # Package removal, not upgrade +/bin/systemctl --no-reload disable virtlockd.service /dev/null 21 || : /bin/systemctl --no-reload disable libvirtd.service /dev/null 21 || : /bin/systemctl stop libvirtd.service /dev/null 21 || : +/bin/systemctl stop virtlockd.service /dev/null 21 || : fi %else if [ $1 = 0 ]; then @@ -931,6 +934,7 @@ fi /bin/systemctl daemon-reload /dev/null 21 || : if [ $1 -ge 1 ] ; then # Package upgrade, not uninstall +/bin/systemctl try-restart virtlockd.service /dev/null 21 || : /bin/systemctl try-restart libvirtd.service /dev/null 21 || : fi %endif @@ -1010,6 +1014,8 @@ fi %{_sysconfdir}/rc.d/init.d/virtlockd %if %{with_systemd} %{_unitdir}/libvirtd.service +%{_unitdir}/virtlockd.service +%{_unitdir}/virtlockd.socket %endif %doc daemon/libvirtd.upstart %config(noreplace) %{_sysconfdir}/sysconfig/libvirtd diff --git a/src/.gitignore b/src/.gitignore index c499b47..58729ca 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -17,6 +17,8 @@ libvirt_qemu.def remote_protocol-structs-t virt-aa-helper virtlockd +virtlockd.service +virtlockd.init virtlockd.socket locking/lock_daemon_dispatch_stubs.h locking/qemu-sanlock.conf diff --git a/src/Makefile.am b/src/Makefile.am index 9a9deab..b14381b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1283,6 +1283,53 @@ virtlockd.init: locking/virtlockd.init.in $(top_builddir)/config.status +EXTRA_DIST += locking/virtlockd.service.in locking/virtlockd.socket.in + +if WITH_LIBVIRTD +if LIBVIRT_INIT_SCRIPT_SYSTEMD + +SYSTEMD_UNIT_DIR = /lib/systemd/system + +BUILT_SOURCES += virtlockd.service virtlockd.socket + +install-systemd: virtlockd.init install-sysconfig + mkdir -p $(DESTDIR)$(SYSTEMD_UNIT_DIR) + $(INSTALL_SCRIPT) virtlockd.service \ + $(DESTDIR)$(SYSTEMD_UNIT_DIR)/ + $(INSTALL_SCRIPT) virtlockd.socket \ + $(DESTDIR)$(SYSTEMD_UNIT_DIR)/ + +uninstall-systemd: uninstall-sysconfig + rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/virtlockd.service + rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/virtlockd.socket +else +install-systemd: +uninstall-systemd: +endif +else +install-systemd: +uninstall-systemd: +endif + +virtlockd.service: locking/virtlockd.service.in $(top_builddir)/config.status + $(AM_V_GEN)sed \ + -e s!\@localstatedir\@!@localstatedir@!g\ + -e s!\@sbindir\@!@sbindir@!g\ + -e s!\@sysconfdir\@!@sysconfdir@!g \ +$ $@-t \ + chmod a+x $@-t\ + mv $@-t $@ + +virtlockd.socket:
[libvirt] [PATCH] Skip bugs which are CLOSED in todo list
From: Daniel P. Berrange berra...@redhat.com * docs/todo.pl: Skip closed bugs --- docs/todo.pl |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/docs/todo.pl b/docs/todo.pl index e6da418..1183ff5 100755 --- a/docs/todo.pl +++ b/docs/todo.pl @@ -47,6 +47,8 @@ my $trackers = BZ::Client::Bug-search($client, {'product' = $product, my @trackers; foreach my $tracker (@{$trackers}) { +next if $tracker-{'bug_status'} eq CLOSED; + my $summary = $tracker-{'short_desc'}; $summary =~ s/^\s*RFE\s*:\s*//; $summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//; @@ -64,6 +66,8 @@ foreach my $tracker (@trackers) { 'blocked' = $tracker-{id}}); foreach my $feature (@{$features}) { + next if $feature-{'bug_status'} eq CLOSED; + my $summary = $feature-{'short_desc'}; $summary =~ s/^\s*RFE\s*:\s*//; $summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//; -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Skip bugs which are CLOSED in todo list
On 07/07/2011 09:04 AM, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com * docs/todo.pl: Skip closed bugs --- docs/todo.pl |4 1 files changed, 4 insertions(+), 0 deletions(-) ACK. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Do not drop kernel cmdline for xen pv domains
On 07/07/2011 11:31 AM, Daniel P. Berrange wrote: On Wed, Jul 06, 2011 at 07:36:26PM -0600, Jim Fehlig wrote: Kernel cmdline args can be passed to xen pv domains even when a bootloader is specified. The current config-to-sxpr mapping ignores cmdline when bootloader is present. Since the xend sub-driver is used with many xen toolstack versions, this patch takes conservative approach of adding an else block to existing !def-os.bootloader, and only appends sxpr if def-os.cmdline is non-NULL. --- src/xenxs/xen_sxpr.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c index 13ca015..bd770bc 100644 --- a/src/xenxs/xen_sxpr.c +++ b/src/xenxs/xen_sxpr.c @@ -2261,6 +2261,12 @@ xenFormatSxpr(virConnectPtr conn, } virBufferAddLit(buf, ))); +} else { +/* PV domains accept kernel cmdline args */ +if (def-os.cmdline) { +virBufferEscapeSexpr(buf, (image (linux (args '%s'))), + def-os.cmdline); +} } ACK, assuming the test cases still pass - I'm surprised this doesn't require any testcase fixes It should require a new testcases too. :) Paolo -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: Don't chown files on NFS share if dynamic_ownership is off
When dynamic ownership is disabled we don't want to chown any files, not just local. --- src/qemu/qemu_driver.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 52b7dfd..968865f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2163,11 +2163,10 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, is_reg = true; } else { is_reg = !!S_ISREG(sb.st_mode); -/* If the path is regular local file which exists +/* If the path is regular file which exists * already and dynamic_ownership is off, we don't * want to change it's ownership, just open it as-is */ -if (is_reg !driver-dynamicOwnership -virStorageFileIsSharedFS(path) == 0) { +if (is_reg !driver-dynamicOwnership) { uid=sb.st_uid; gid=sb.st_gid; } -- 1.7.5.rc3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 14/14] Enable systemd socket activation with virtlockd
On 07/07/2011 04:17 PM, Daniel P. Berrange wrote: if [ $1 -eq 1 ] ; then # Initial installation +/bin/systemctl enable virtlockd.service/dev/null 21 || : /bin/systemctl enable libvirtd.service/dev/null 21 || : /bin/systemctl enable cgconfig.service/dev/null 21 || : fi @@ -914,8 +915,10 @@ fi %if %{with_systemd} if [ $1 -eq 0 ] ; then # Package removal, not upgrade +/bin/systemctl --no-reload disable virtlockd.service /dev/null 21 || : /bin/systemctl --no-reload disable libvirtd.service /dev/null 21 || : /bin/systemctl stop libvirtd.service /dev/null 21 || : +/bin/systemctl stop virtlockd.service /dev/null 21 || : fi Do you really want to enable the .service by default rather than the .socket? IIUC, in the common case of no autostart guests enabling the .socket will cut on boot-time operations. systemd is new to me though, so I may well have misunderstood something... Paolo -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Don't chown files on NFS share if dynamic_ownership is off
On 07/07/2011 09:33 AM, Michal Privoznik wrote: When dynamic ownership is disabled we don't want to chown any files, not just local. Is there more details on a scenario where this was causing an issue? Either a BZ number or a set of steps to reproduce the problem. --- src/qemu/qemu_driver.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 52b7dfd..968865f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2163,11 +2163,10 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, is_reg = true; } else { is_reg = !!S_ISREG(sb.st_mode); -/* If the path is regular local file which exists +/* If the path is regular file which exists * already and dynamic_ownership is off, we don't * want to change it's ownership, just open it as-is */ -if (is_reg !driver-dynamicOwnership -virStorageFileIsSharedFS(path) == 0) { +if (is_reg !driver-dynamicOwnership) { The code change looks fine, but without a pointer to a reproducer case proving that it is a bug fix, I'm not sure if this would have unintended consequences. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Do not drop kernel cmdline for xen pv domains
Paolo Bonzini wrote: On 07/07/2011 11:31 AM, Daniel P. Berrange wrote: On Wed, Jul 06, 2011 at 07:36:26PM -0600, Jim Fehlig wrote: Kernel cmdline args can be passed to xen pv domains even when a bootloader is specified. The current config-to-sxpr mapping ignores cmdline when bootloader is present. Since the xend sub-driver is used with many xen toolstack versions, this patch takes conservative approach of adding an else block to existing !def-os.bootloader, and only appends sxpr if def-os.cmdline is non-NULL. --- src/xenxs/xen_sxpr.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c index 13ca015..bd770bc 100644 --- a/src/xenxs/xen_sxpr.c +++ b/src/xenxs/xen_sxpr.c @@ -2261,6 +2261,12 @@ xenFormatSxpr(virConnectPtr conn, } virBufferAddLit(buf, ))); +} else { +/* PV domains accept kernel cmdline args */ +if (def-os.cmdline) { +virBufferEscapeSexpr(buf, (image (linux (args '%s'))), + def-os.cmdline); +} } ACK, assuming the test cases still pass - I'm surprised this doesn't require any testcase fixes It should require a new testcases too. :) Yes, good point. I'll add testcases. First though, I need to get to the bottom of build failures on older distro with polkit0. I quickly built using --without-polkit, only to have compilation failures during make check. Regards, Jim -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Don't chown files on NFS share if dynamic_ownership is off
On 07.07.2011 17:52, Eric Blake wrote: On 07/07/2011 09:33 AM, Michal Privoznik wrote: When dynamic ownership is disabled we don't want to chown any files, not just local. Is there more details on a scenario where this was causing an issue? Either a BZ number or a set of steps to reproduce the problem. --- src/qemu/qemu_driver.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 52b7dfd..968865f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2163,11 +2163,10 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, is_reg = true; } else { is_reg = !!S_ISREG(sb.st_mode); -/* If the path is regular local file which exists +/* If the path is regular file which exists * already and dynamic_ownership is off, we don't * want to change it's ownership, just open it as-is */ -if (is_reg !driver-dynamicOwnership -virStorageFileIsSharedFS(path) == 0) { +if (is_reg !driver-dynamicOwnership) { The code change looks fine, but without a pointer to a reproducer case proving that it is a bug fix, I'm not sure if this would have unintended consequences. Sure, https://bugzilla.redhat.com/show_bug.cgi?id=716478 Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Fix compilation of statstest.c during make check
--- tests/statstest.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/tests/statstest.c b/tests/statstest.c index d18bb0c..c989992 100644 --- a/tests/statstest.c +++ b/tests/statstest.c @@ -17,7 +17,7 @@ static void testQuietError(void *userData ATTRIBUTE_UNUSED, static int testDevice(const char *path, int expect) { -int actual = xenLinuxDomainDeviceID(NULL, 1, path); +int actual = xenLinuxDomainDeviceID(1, path); if (actual == expect) { return 0; -- 1.7.5.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Do not drop kernel cmdline for xen pv domains
Daniel P. Berrange wrote: On Wed, Jul 06, 2011 at 07:36:26PM -0600, Jim Fehlig wrote: Kernel cmdline args can be passed to xen pv domains even when a bootloader is specified. The current config-to-sxpr mapping ignores cmdline when bootloader is present. Since the xend sub-driver is used with many xen toolstack versions, this patch takes conservative approach of adding an else block to existing !def-os.bootloader, and only appends sxpr if def-os.cmdline is non-NULL. --- src/xenxs/xen_sxpr.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c index 13ca015..bd770bc 100644 --- a/src/xenxs/xen_sxpr.c +++ b/src/xenxs/xen_sxpr.c @@ -2261,6 +2261,12 @@ xenFormatSxpr(virConnectPtr conn, } virBufferAddLit(buf, ))); +} else { +/* PV domains accept kernel cmdline args */ +if (def-os.cmdline) { +virBufferEscapeSexpr(buf, (image (linux (args '%s'))), + def-os.cmdline); +} } ACK, assuming the test cases still pass - I'm surprised this doesn't require any testcase fixes Shame on me for not running make check. As you suspected, xml2sexpr disk-block-shareable test failed. I'll fix it up, and new testcases for this patch, and post a v2. Regards, Jim -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Fix compilation of statstest.c during make check
On 07/07/2011 10:16 AM, Jim Fehlig wrote: --- tests/statstest.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/tests/statstest.c b/tests/statstest.c index d18bb0c..c989992 100644 --- a/tests/statstest.c +++ b/tests/statstest.c @@ -17,7 +17,7 @@ static void testQuietError(void *userData ATTRIBUTE_UNUSED, static int testDevice(const char *path, int expect) { -int actual = xenLinuxDomainDeviceID(NULL, 1, path); +int actual = xenLinuxDomainDeviceID(1, path); ACK. This was a regression introduced in commit 60d769a1, back in April. So why did we not detect it until now? What is different about your test environment that triggered compilation of this code while others (myself included) have been happily unaware of its existence? -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Fix compilation of statstest.c during make check
Eric Blake wrote: On 07/07/2011 10:16 AM, Jim Fehlig wrote: --- tests/statstest.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/tests/statstest.c b/tests/statstest.c index d18bb0c..c989992 100644 --- a/tests/statstest.c +++ b/tests/statstest.c @@ -17,7 +17,7 @@ static void testQuietError(void *userData ATTRIBUTE_UNUSED, static int testDevice(const char *path, int expect) { -int actual = xenLinuxDomainDeviceID(NULL, 1, path); +int actual = xenLinuxDomainDeviceID(1, path); ACK. Pushed. This was a regression introduced in commit 60d769a1, back in April. So why did we not detect it until now? What is different about your test environment that triggered compilation of this code while others (myself included) have been happily unaware of its existence? In configure.ac, I see that xen kernel and xend must both be running to for ENABLE_XEN_TESTS to be true, which then enables building statstest.c and reconnect.c. I guess we're just not using xen much these days... Regards, Jim -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Fix compilation of statstest.c during make check
On 07/07/2011 10:28 AM, Eric Blake wrote: +++ b/tests/statstest.c @@ -17,7 +17,7 @@ static void testQuietError(void *userData ATTRIBUTE_UNUSED, static int testDevice(const char *path, int expect) { -int actual = xenLinuxDomainDeviceID(NULL, 1, path); +int actual = xenLinuxDomainDeviceID(1, path); ACK. This was a regression introduced in commit 60d769a1, back in April. So why did we not detect it until now? What is different about your test environment that triggered compilation of this code while others (myself included) have been happily unaware of its existence? Found it - statstest is guarded by the automake conditional ENABLE_XEN_TESTS, set at configure time according to whether xen sockets were usable. But to avoid this type of failure in the future, I'd rather have the test unconditionally compiled if xen headers are present, and merely have the test have an early opt-opt return 77 (for skip) if the xen socket cannot be connected to at runtime. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Don't chown files on NFS share if dynamic_ownership is off
On 07/07/2011 12:00 PM, Michal Privoznik wrote: On 07.07.2011 17:52, Eric Blake wrote: On 07/07/2011 09:33 AM, Michal Privoznik wrote: When dynamic ownership is disabled we don't want to chown any files, not just local. Is there more details on a scenario where this was causing an issue? Either a BZ number or a set of steps to reproduce the problem. --- src/qemu/qemu_driver.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 52b7dfd..968865f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2163,11 +2163,10 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, is_reg = true; } else { is_reg = !!S_ISREG(sb.st_mode); -/* If the path is regular local file which exists +/* If the path is regular file which exists * already and dynamic_ownership is off, we don't * want to change it's ownership, just open it as-is */ -if (is_reg !driver-dynamicOwnership -virStorageFileIsSharedFS(path) == 0) { +if (is_reg !driver-dynamicOwnership) { The code change looks fine, but without a pointer to a reproducer case proving that it is a bug fix, I'm not sure if this would have unintended consequences. Sure, https://bugzilla.redhat.com/show_bug.cgi?id=716478 And I can't think of any reason why it *should* check for local (if anything, we should do *less* changing of ownership on remote filesystems, not more). Oh, and this is fairly recent code, so there won't be anybody relying on the old behavior. So ACK. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4] graphics: add support for action_if_connected in qemu
On 07/07/2011 02:59 AM, Michal Privoznik wrote: On 06.07.2011 00:34, Eric Blake wrote: This patch changes the .xml, but not the corresponding .args file, which to me says it is probably incomplete. We covered the case of changing the attribute affecting qemu_hotplug: No. This is purely QMP thing. qemu -spice does not have any option for setting this (the current git version at least). That .xml vs .args change: I've changed .xml so we can test RNG scheme. There is nothing to add to .args. Ah, that makes sense now. This is not a qemu attribute associated with the spice device, rather it is a feature of the hotplug command (when hotplugging, what action to take in this condition). As such, I think you are right that there is no change to any .args file, so ACK to this patch as-is. That said, Jirka's proposed patch for introducing a monitor-proxy[1] sounds like it would be an awesome way to enhance our testsuite coverage. It would be nice to write up a test-stub proxy that pretends to be an active qemu monitor, but which functions even without running a real qemu process. In that way, we could get further exposure that the monitor commands that we are generating match our expectations. [1] https://www.redhat.com/archives/libvir-list/2011-July/msg00028.html -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 00/20] flags cleanup
On 07/07/2011 12:09 AM, Matthias Bolte wrote: 2011/7/7 Eric Blake ebl...@redhat.com: On 07/06/2011 05:23 PM, Eric Blake wrote: Inspired in part by Laine's recent cleanup of qemuDomainGetXMLDesc, in part by my desire to add a new flag to virDomainCoreDump and test that older clients reject that flag, and in part by an OCD desire for uniformity :), I'm proposing this giant patch series. And yes, I'm working on a patch 21/20 to cfg.mk to enforce this style in the future, but ran out of time today. I'm afraid that you're going to break stuff with this series. For example the patch for the ESX driver breaks opening a read-only connection as you made esxOpen reject VIR_CONNECT_RO. Hmm, are we really passing VIR_CONNECT_RO as a flags argument to all the driver instantiations? If so, then I have quite a few patches to amend, since it would not be just ESX rejecting a read-only driver instantiation. I'll hold off on pushing anything that added a virCheckFlags(0, VIR_DRV_OPEN_ERROR) until after I've done some more debugging (which is the bulk of my series)... Yes, the ESX driver has no means to support a truly read-only connection as you always need to provide credentials, so one can consider this a bugfix or a regression depending on the point-of-view. I'm 50-50 on whether this really is a bug-fix, whether it means we should allow (and otherwise ignore) the flag, as in: virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); Anyone else with an opinion? -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv3] build: fix virBufferVasprintf on mingw
2011/7/6 Eric Blake ebl...@redhat.com: Gnulib documents that mingw vsnprintf is broken (it returns -1 on out-of-space, instead of the count of what would have been printed); but while we were using the snprintf wrapper, we had not yet been using the vsnprintf wrapper. Meanwhile, mingw (but not mingw64) has a replacement snprintf that fixes return values, but still lacks %1$s support; so in that case, gnulib didn't replace snprintf, but libintl then went ahead and installed a version that supported %1$s but not return values.  Gnulib has since been fixed to guarantee that the snprintf module will always guarantee the constraints needed by libintl. Also, we want to guarantee that strdup sets errno on failure. * .gnulib: Update to latest, for vsnprintf fix. * bootstrap.conf (gnulib_modules): Add vsnprintf, strdup-posix. Reported by Matthias Bolte. --- v3: more gnulib updates, also fix strdup v2: see https://www.redhat.com/archives/libvir-list/2011-July/msg00042.html * .gnulib 7269b35...8db4963 (23):  sys_select: define sigset_t more portably  * m4/sys_select_h.m4 (gl_HEADER_SYS_SELECT): Poison pselect.  pselect: Use pthread_sigmask, not sigprocmask.  modules/pselect: Add Bruno and Jim to maintainers.  * modules/pselect: Add select, LIBSOCKET.  * lib/pselect.c (pselect): Use plain name, without rpl_.  pselect: document better  pthread_sigmask: new module  test-pselect: new module  * tests/test-sys_select.c (sigset_t): Test for it, too.  snprintf: guarantee %1$d, for libintl  maint: exempt stdio-read.c and stdio-write.c from the cppi check  maint: indent with spaces, not TABs, and add a rule to check this  maint.mk: correct omissions in prohibit_argmatch_without_use check  Comments about EINTR.  autoupdate  xnanosleep: Rewrite to use new dtotimespec module.  timespec-add, timespec-sub: new modules  dtotimespec: new module  * lib/timespec.h (timespectod): New inline function.  * lib/timespec.h (timespec_sign): New inline function.  pselect: new module  sys_select: don't depend on sys_socket I'm also investigating how easy it would be to use gnulib's new pthread_sigmask.  .gnulib     |   2 +-  bootstrap.conf |   2 ++  2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/.gnulib b/.gnulib index 7269b35..8db4963 16 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 7269b35c8d9be1a6f97906b9e29b8c422b92fc31 +Subproject commit 8db49630deab35ffbce5c113aed093359a75091d diff --git a/bootstrap.conf b/bootstrap.conf index 581d60b..d3ff150 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -80,6 +80,7 @@ socket  stdarg  stpcpy  strchrnul +strdup-posix  strndup  strerror  strerror_r-posix @@ -97,6 +98,7 @@ usleep  vasprintf  verify  vc-list-files +vsnprintf  waitpid  warnings  ' Okay, I finally tested this patch and it works, ACK. -- Matthias Bolte http://photron.blogspot.com -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] build: use gnulib pthread_sigmask
On 07/07/2011 03:22 AM, Daniel P. Berrange wrote: On Wed, Jul 06, 2011 at 11:24:12AM -0600, Eric Blake wrote: Gnulib finally learned how to do pthread_sigmask on mingw. We still have to worry about optional signals, like SIGWINCH, but overall, this makes for less conditional code. * .gnulib: Update to latest, for pthread_sigmask. * bootstrap.conf (gnulib_modules): Add pthread_sigmask. * configure.ac (AC_CHECK_FUNCS): Drop redundant check. * src/rpc/virnetclient.c (virNetClientSetTLSSession) (virNetClientIOEventLoop): Make code unconditional. * src/util/command.c (virFork): Likewise. * tools/virsh.c (doMigrate, cmdMigrate): Likewise. --- .gnulib|2 +- bootstrap.conf |1 + configure.ac |2 +- src/rpc/virnetclient.c | 24 src/util/command.c | 10 -- tools/virsh.c | 10 -- 6 files changed, 11 insertions(+), 38 deletions(-) ACK Pushed, along with the pre-requisite patch for fixing vsnprintf that also touched .gnulib and bootstrap.conf: https://www.redhat.com/archives/libvir-list/2011-July/msg00253.html -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC: API additions for enhanced snapshot support
On 07/07/2011 03:13 AM, Stefan Hajnoczi wrote: On Wed, Jul 6, 2011 at 3:03 PM, Eric Blake ebl...@redhat.com wrote: In other words, it looks like we are stuck with updating XML to track new file names any time we take a snapshot. Yes, but QEMU's snapshot_blkdev command takes a filename argument so at least you get to specify that new filename. Well, the best thing (from libvirt's point of view) would be if snapshot_blkdev took a single string argument, which is either a /path/to/filename (and qemu does open()) or fd:name notation (to refer to a previously-named fd passed via the getfd monitor command, so that libvirt does open()). This would make SELinux integration easier, as one of the sVirt goals is to get to the point where we can use SELinux to forbid qemu from open()ing files on NFS shares, while still permitting all other operations on already-open fds passed in from libvirt. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virsh: make destroy sound less scary
On 07/07/2011 03:23 AM, Daniel P. Berrange wrote: On Wed, Jul 06, 2011 at 03:44:13PM -0600, Eric Blake wrote: Destroy has a rather negative English connotation. Try to reduce the impact, so newbies aren't as scared to use it. * tools/virsh.c: Tweak all destroy documentation. * tools/virsh.pod: Likewise. --- tools/virsh.c | 20 +++- tools/virsh.pod | 16 +--- 2 files changed, 20 insertions(+), 16 deletions(-) ACK Thanks; pushed. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 03/20] drivers: prefer unsigned int for flags
On 07/06/2011 09:07 PM, Daniel Veillard wrote: On Wed, Jul 06, 2011 at 05:23:46PM -0600, Eric Blake wrote: Now that the public APIs always use unsigned flags, the internal driver callbacks might as well do likewise. struct remote_nwfilter_get_xml_desc_args { remote_nonnull_nwfilternwfilter; -intflags; +u_int flags; }; struct remote_nwfilter_get_xml_desc_ret { remote_nonnull_string xml; Can we triple check that the remote stuff really allocate the same space for int and u_int, that's my only doubt in that change, We've done that exact type of change before - see commit 1ff2b6f. ACK, I've pushed 1-5, and am slowly working on rebasing the remaining patches to deal with Matthias' observation about read-only connections (my debugging session proved that we _do_ pass a flag to all the driver open functions). -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 03/20] drivers: prefer unsigned int for flags
2011/7/7 Eric Blake ebl...@redhat.com: On 07/06/2011 09:07 PM, Daniel Veillard wrote: On Wed, Jul 06, 2011 at 05:23:46PM -0600, Eric Blake wrote: Now that the public APIs always use unsigned flags, the internal driver callbacks might as well do likewise.  struct remote_nwfilter_get_xml_desc_args {      remote_nonnull_nwfilter   nwfilter; -     int             flags; +     u_int            flags;  };  struct remote_nwfilter_get_xml_desc_ret {      remote_nonnull_string    xml;  Can we triple check that the remote stuff really allocate the same space for int and u_int, that's my only doubt in that change, We've done that exact type of change before - see commit 1ff2b6f.  ACK, I've pushed 1-5, and am slowly working on rebasing the remaining patches to deal with Matthias' observation about read-only connections (my debugging session proved that we _do_ pass a flag to all the driver open functions). There might be problems like that with other functions you touched too. I only picked that one as an example. For example, I know that the flags handling is quite broken in the ESX driver due to the undefined semantics of several functions at the time I wrote the driver. -- Matthias Bolte http://photron.blogspot.com -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 00/20] flags cleanup
On 07/07/2011 12:30 PM, Eric Blake wrote: Yes, the ESX driver has no means to support a truly read-only connection as you always need to provide credentials, so one can consider this a bugfix or a regression depending on the point-of-view. I'm 50-50 on whether this really is a bug-fix, whether it means we should allow (and otherwise ignore) the flag, as in: virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); Anyone else with an opinion? At this point, I'm making the change to allow (but otherwise ignore) VIR_CONNECT_RO for the flags cleanup patch. That way, there are no semantic changes. Beyond that, if we decide that a particular driver needs to pay attention to a flag, then we can later make a followup patch that restricts the flag for just that driver. Remember, read-only connections have already filtered out API calls from ever reaching driver callbacks in the first place. So, while it is conceivable that some drivers may need to do something different to connect to their hypervisor on a read-only connection, it appears that most (all?) drivers are just fine ignoring that piece of information from the connection (they behave the same whether read-only or read-write, for the callbacks that can actually be triggered on a read-only connection). -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Fix build when using polkit0
Here's a hacked attempt at fixing the build on older distros using polkit0. It works and user is authorized or denied depending on settings in PolicyKit.conf. I'm not too happy with it but haven't yet digested all the changes in rpc and daemon code. In the meantime, hopefully someone can suggest improvements. Regards, Jim From 3341912b3d34b363c6ecd922dd2489247a568f2e Mon Sep 17 00:00:00 2001 From: Jim Fehlig jfeh...@novell.com Date: Thu, 7 Jul 2011 15:12:26 -0600 Subject: [PATCH] Fix build when using polkit0 --- daemon/libvirtd.c | 24 daemon/libvirtd.h | 26 -- daemon/remote.c| 21 ++--- src/Makefile.am|4 +++- src/rpc/virnetserver.c | 40 src/rpc/virnetserver.h |8 6 files changed, 65 insertions(+), 58 deletions(-) diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index 06d2077..ddfcb79 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -576,26 +576,6 @@ static int daemonSetupNetworking(virNetServerPtr srv, } #endif -#if HAVE_POLKIT0 -if (auth_unix_rw == REMOTE_AUTH_POLKIT || -auth_unix_ro == REMOTE_AUTH_POLKIT) { -DBusError derr; - -dbus_connection_set_change_sigpipe(FALSE); -dbus_threads_init_default(); - -dbus_error_init(derr); -server-sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, derr); -if (!(server-sysbus)) { -VIR_ERROR(_(Failed to connect to system bus for PolicyKit auth: %s), - derr.message); -dbus_error_free(derr); -goto error; -} -dbus_connection_set_exit_on_disconnect(server-sysbus, FALSE); -} -#endif - return 0; error: @@ -1278,6 +1258,7 @@ int main(int argc, char **argv) { int ipsock = 0; struct daemonConfig *config; bool privileged = geteuid() == 0 ? true : false; +bool use_polkit; struct option opts[] = { { verbose, no_argument, verbose, 1}, @@ -1436,10 +1417,13 @@ int main(int argc, char **argv) { umask(old_umask); } +use_polkit = config-auth_unix_rw == REMOTE_AUTH_POLKIT || +config-auth_unix_ro == REMOTE_AUTH_POLKIT; if (!(srv = virNetServerNew(config-min_workers, config-max_workers, config-max_clients, config-mdns_adv ? config-mdns_name : NULL, +use_polkit, remoteClientInitHook))) { ret = VIR_DAEMON_ERR_INIT; goto cleanup; diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h index 8e1843c..18a10ef 100644 --- a/daemon/libvirtd.h +++ b/daemon/libvirtd.h @@ -91,30 +91,4 @@ extern virNetSASLContextPtr saslCtxt; extern virNetServerProgramPtr remoteProgram; extern virNetServerProgramPtr qemuProgram; -/* Main server state */ -struct qemud_server { -int privileged; - -int sigread; -int sigwrite; -char *logDir; -pthread_t eventThread; -unsigned int hasEventThread :1; -unsigned int quitEventThread :1; -# ifdef HAVE_AVAHI -struct libvirtd_mdns *mdns; -# endif -# if HAVE_SASL -char **saslUsernameWhitelist; -# endif -# if HAVE_POLKIT0 -DBusConnection *sysbus; -# endif -}; - - -# if HAVE_POLKIT -int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid); -# endif - #endif diff --git a/daemon/remote.c b/daemon/remote.c index 2889908..0fc26c6 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -43,6 +43,7 @@ #include command.h #include intprops.h #include virnetserverservice.h +#include virnetserver.h #include remote_protocol.h #include qemu_protocol.h @@ -2115,7 +2116,7 @@ authdeny: } #elif HAVE_POLKIT0 static int -remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED, +remoteDispatchAuthPolkit(virNetServerPtr server, virNetServerClientPtr client, virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED, virNetMessageErrorPtr rerr, @@ -2137,21 +2138,19 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED, memset(ident, 0, sizeof ident); -virMutexLock(server-lock); -virMutexLock(client-lock); -virMutexUnlock(server-lock); +virMutexLock(priv-lock); -action = client-readonly ? +action = virNetServerClientGetReadonly(client) ? org.libvirt.unix.monitor : org.libvirt.unix.manage; VIR_DEBUG(Start PolicyKit auth %d, virNetServerClientGetFD(client)); -if (client-auth != REMOTE_AUTH_POLKIT) { +if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) { VIR_ERROR(_(client tried invalid PolicyKit init request)); goto authfail; } -if (qemudGetSocketIdentity(virNetServerClientGetFD(client), callerUid, callerPid) 0) { +if (virNetServerClientGetLocalIdentity(client, callerUid, callerPid) 0)
[libvirt] [PATCH] Skip some xen tests if xend is not running
Currently, the xen statstest and reconnect tests are only compiled if xend is running. Compile them unconditionally if xen headers are present, but skip the tests at runtime if xend is not running. This is in response to Eric's suggestion here https://www.redhat.com/archives/libvir-list/2011-July/msg00367.html --- configure.ac | 24 tests/Makefile.am | 12 tests/reconnect.c | 11 +++ tests/statstest.c | 12 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/configure.ac b/configure.ac index aa589d6..ae747fb 100644 --- a/configure.ac +++ b/configure.ac @@ -1982,30 +1982,6 @@ AM_CONDITIONAL([WITH_PYTHON], [test $with_python = yes]) AC_SUBST([PYTHON_VERSION]) AC_SUBST([PYTHON_INCLUDES]) - - -AC_MSG_CHECKING([whether this host is running a Xen kernel]) -RUNNING_XEN= -if test -d /proc/sys/xen -then -RUNNING_XEN=yes -else -RUNNING_XEN=no -fi -AC_MSG_RESULT($RUNNING_XEN) - -AC_MSG_CHECKING([If XenD UNIX socket /var/run/xend/xmlrpc.sock is accessible]) -RUNNING_XEND= -if test -S /var/run/xend/xmlrpc.sock -then -RUNNING_XEND=yes -else -RUNNING_XEND=no -fi -AC_MSG_RESULT($RUNNING_XEND) - -AM_CONDITIONAL([ENABLE_XEN_TESTS], [test $RUNNING_XEN != no test $RUNNING_XEND != no]) - AC_ARG_ENABLE([test-coverage], AC_HELP_STRING([--enable-test-coverage], [turn on code coverage instrumentation @:@default=no@:@]), [case ${enableval} in diff --git a/tests/Makefile.am b/tests/Makefile.am index 48f9faa..528b88e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -93,10 +93,7 @@ ssh_LDADD = $(COVERAGE_LDFLAGS) if WITH_XEN check_PROGRAMS += xml2sexprtest sexpr2xmltest \ - xmconfigtest xencapstest -if ENABLE_XEN_TESTS -check_PROGRAMS += statstest reconnect -endif + xmconfigtest xencapstest statstest reconnect endif if WITH_QEMU check_PROGRAMS += qemuxml2argvtest qemuxml2xmltest qemuargv2xmltest qemuhelptest @@ -216,10 +213,9 @@ if WITH_XEN TESTS += xml2sexprtest \ sexpr2xmltest \ xmconfigtest \ - xencapstest -if ENABLE_XEN_TESTS -TESTS += reconnect statstest -endif + xencapstest \ + reconnect \ + statstest endif if WITH_QEMU diff --git a/tests/reconnect.c b/tests/reconnect.c index 63877fc..4bc092f 100644 --- a/tests/reconnect.c +++ b/tests/reconnect.c @@ -4,6 +4,7 @@ #include stdlib.h #include internal.h +#include command.h static void errorHandler(void *userData ATTRIBUTE_UNUSED, virErrorPtr error ATTRIBUTE_UNUSED) { @@ -14,6 +15,16 @@ int main(void) { int ro = 0; virConnectPtr conn; virDomainPtr dom; +int status; +virCommandPtr cmd; + +/* skip test if xend is not running */ +cmd = virCommandNewArgList(/usr/sbin/xend, status, NULL); +if (virCommandRun(cmd, status) == 0 status != 0) { +virCommandFree(cmd); +return 77; +} +virCommandFree(cmd); virSetErrorFunc(NULL, errorHandler); diff --git a/tests/statstest.c b/tests/statstest.c index c989992..7074914 100644 --- a/tests/statstest.c +++ b/tests/statstest.c @@ -8,6 +8,7 @@ #include internal.h #include xen/block_stats.h #include testutils.h +#include command.h static void testQuietError(void *userData ATTRIBUTE_UNUSED, virErrorPtr error ATTRIBUTE_UNUSED) @@ -44,6 +45,17 @@ static int mymain(void) { int ret = 0; +int status; +virCommandPtr cmd; + +/* skip test if xend is not running */ +cmd = virCommandNewArgList(/usr/sbin/xend, status, NULL); +if (virCommandRun(cmd, status) == 0 status != 0) { +virCommandFree(cmd); +return 77; +} +virCommandFree(cmd); + /* Some of our tests delibrately test failure cases, so * register a handler to stop error messages cluttering * up display -- 1.7.5.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 05/10] conf: put virtPortProfile struct / functions in a common location
On 07/05/2011 01:45 AM, Laine Stump wrote: virtPortProfiles are currently only used in the domain XML, but will soon also be used in the network XML. To prepare for that change, this patch moves the structure definition into util/network.h and the parse and format functions into util/network.c (I decided that this was a better choice than macvtap.h/c for something that needed to always be available on all platforms). Additionally, the virtPortProfile in the domain interface struct is now a separately allocated object rather *pointed to by* (rather than grammar nit - you can delete the first rather contained in) the main virDomainNetDef object. This is done to make is s/is/it/ easier to figure out when a virtualPortProfile has/hasn't been specified in a particular config. --- src/conf/domain_conf.c| 208 +++-- src/conf/domain_conf.h|2 +- src/libvirt_private.syms |2 + src/qemu/qemu_command.c |4 +- src/qemu/qemu_hotplug.c |2 +- src/qemu/qemu_migration.c |4 +- src/qemu/qemu_process.c |2 +- src/util/macvtap.c|6 +- src/util/macvtap.h| 36 + src/util/network.c| 196 ++ src/util/network.h| 47 ++ 11 files changed, 271 insertions(+), 238 deletions(-) ACK. Looks like pretty clean code motion, plus fallout due to a slight parameter change and alteration of who is responsible for actually reporting error messages. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 02/19] qemu: Consolidate BeginJob{, WithDriver} into a single method
This avoids code duplication and also avoids relying on good luck that ignore_value(virDomainObjUnref(obj)) doesn't set errno. --- src/qemu/qemu_domain.c | 93 ++-- 1 files changed, 43 insertions(+), 50 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index bbdfdc4..8f3eaa7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -517,20 +517,17 @@ qemuDomainObjDiscardJob(virDomainObjPtr obj) qemuDomainObjSetJob(obj, QEMU_JOB_NONE); } -/* - * obj must be locked before calling, qemud_driver must NOT be locked - * - * This must be called by anything that will change the VM state - * in any way, or anything that will use the QEMU monitor. - * - * Upon successful return, the object will have its ref count increased, - * successful calls must be followed by EndJob eventually - */ - /* Give up waiting for mutex after 30 seconds */ #define QEMU_JOB_WAIT_TIME (1000ull * 30) -int qemuDomainObjBeginJob(virDomainObjPtr obj) +/* + * obj must be locked before calling; driver_locked says if qemu_driver is + * locked or not. + */ +static int +qemuDomainObjBeginJobInternal(struct qemud_driver *driver, + bool driver_locked, + virDomainObjPtr obj) { qemuDomainObjPrivatePtr priv = obj-privateData; unsigned long long now; @@ -541,17 +538,24 @@ int qemuDomainObjBeginJob(virDomainObjPtr obj) then = now + QEMU_JOB_WAIT_TIME; virDomainObjRef(obj); +if (driver_locked) +qemuDriverUnlock(driver); while (priv-job.active) { if (virCondWaitUntil(priv-job.cond, obj-lock, then) 0) { -/* Safe to ignore value since ref count was incremented above */ -ignore_value(virDomainObjUnref(obj)); if (errno == ETIMEDOUT) qemuReportError(VIR_ERR_OPERATION_TIMEOUT, %s, _(cannot acquire state change lock)); else virReportSystemError(errno, %s, _(cannot acquire job mutex)); +if (driver_locked) { +virDomainObjUnlock(obj); +qemuDriverLock(driver); +virDomainObjLock(obj); +} +/* Safe to ignore value since ref count was incremented above */ +ignore_value(virDomainObjUnref(obj)); return -1; } } @@ -559,54 +563,43 @@ int qemuDomainObjBeginJob(virDomainObjPtr obj) qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED); priv-job.start = now; +if (driver_locked) { +virDomainObjUnlock(obj); +qemuDriverLock(driver); +virDomainObjLock(obj); +} + return 0; } /* - * obj must be locked before calling, qemud_driver must be locked + * obj must be locked before calling, qemud_driver must NOT be locked * * This must be called by anything that will change the VM state * in any way, or anything that will use the QEMU monitor. + * + * Upon successful return, the object will have its ref count increased, + * successful calls must be followed by EndJob eventually + */ +int qemuDomainObjBeginJob(virDomainObjPtr obj) +{ +return qemuDomainObjBeginJobInternal(NULL, false, obj); +} + +/* + * obj must be locked before calling. If qemud_driver is passed, it MUST be + * locked; otherwise it MUST NOT be locked. + * + * This must be called by anything that will change the VM state + * in any way, or anything that will use the QEMU monitor. + * + * Upon successful return, the object will have its ref count increased, + * successful calls must be followed by EndJob eventually */ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, virDomainObjPtr obj) { -qemuDomainObjPrivatePtr priv = obj-privateData; -unsigned long long now; -unsigned long long then; - -if (virTimeMs(now) 0) -return -1; -then = now + QEMU_JOB_WAIT_TIME; - -virDomainObjRef(obj); -qemuDriverUnlock(driver); - -while (priv-job.active) { -if (virCondWaitUntil(priv-job.cond, obj-lock, then) 0) { -if (errno == ETIMEDOUT) -qemuReportError(VIR_ERR_OPERATION_TIMEOUT, -%s, _(cannot acquire state change lock)); -else -virReportSystemError(errno, - %s, _(cannot acquire job mutex)); -virDomainObjUnlock(obj); -qemuDriverLock(driver); -virDomainObjLock(obj); -/* Safe to ignore value since ref count was incremented above */ -ignore_value(virDomainObjUnref(obj)); -return -1; -} -} -qemuDomainObjResetJob(priv); -qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED); -priv-job.start = now; - -virDomainObjUnlock(obj); -qemuDriverLock(driver); -virDomainObjLock(obj); - -return 0; +
[libvirt] [PATCH 10/19] qemu: Migration job on destination daemon
Make MIGRATION_IN use the new helper methods. --- src/qemu/qemu_domain.c|2 +- src/qemu/qemu_domain.h|1 - src/qemu/qemu_migration.c | 80 +++- 3 files changed, 36 insertions(+), 47 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 39cbf0e..2e4228a 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -645,7 +645,7 @@ void qemuDomainSetNamespaceHooks(virCapsPtr caps) caps-ns.href = qemuDomainDefNamespaceHref; } -void +static void qemuDomainObjSaveJob(struct qemud_driver *driver, virDomainObjPtr obj) { if (!virDomainObjIsActive(obj)) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 7245e67..387c64c 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -180,7 +180,6 @@ int qemuDomainObjEndAsyncJob(struct qemud_driver *driver, void qemuDomainObjEndNestedJob(struct qemud_driver *driver, virDomainObjPtr obj); -void qemuDomainObjSaveJob(struct qemud_driver *driver, virDomainObjPtr obj); void qemuDomainObjSetJobPhase(struct qemud_driver *driver, virDomainObjPtr obj, int phase); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 33aa89b..5e31b7d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1128,9 +1128,9 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, QEMU_MIGRATION_COOKIE_LOCKSTATE))) goto cleanup; -if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm, - QEMU_ASYNC_JOB_MIGRATION_IN) 0) +if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) 0) goto cleanup; +qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PREPARE); /* Domain starts inactive, even if the domain XML had an id field. */ vm-def-id = -1; @@ -1188,28 +1188,19 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_MIGRATED); -ret = 0; -endjob: -if (qemuDomainObjEndAsyncJob(driver, vm) == 0) { -vm = NULL; -} else if (!vm-persistent !virDomainObjIsActive(vm)) { -virDomainRemoveInactive(driver-domains, vm); +/* We keep the job active across API calls until the finish() call. + * This prevents any other APIs being invoked while incoming + * migration is taking place. + */ +if (qemuMigrationJobContinue(vm) == 0) { vm = NULL; +qemuReportError(VIR_ERR_OPERATION_FAILED, +%s, _(domain disappeared)); +goto cleanup; } -/* We set a fake job active which is held across - * API calls until the finish() call. This prevents - * any other APIs being invoked while incoming - * migration is taking place - */ -if (vm -virDomainObjIsActive(vm)) { -priv-job.asyncJob = QEMU_ASYNC_JOB_MIGRATION_IN; -qemuDomainObjSaveJob(driver, vm); -priv-job.info.type = VIR_DOMAIN_JOB_UNBOUNDED; -priv-job.start = now; -} +ret = 0; cleanup: virDomainDefFree(def); @@ -1221,6 +1212,15 @@ cleanup: qemuDomainEventQueue(driver, event); qemuMigrationCookieFree(mig); return ret; + +endjob: +if (qemuMigrationJobFinish(driver, vm) == 0) { +vm = NULL; +} else if (!vm-persistent) { +virDomainRemoveInactive(driver-domains, vm); +vm = NULL; +} +goto cleanup; } @@ -2395,26 +2395,22 @@ qemuMigrationFinish(struct qemud_driver *driver, virDomainPtr dom = NULL; virDomainEventPtr event = NULL; int newVM = 1; -qemuDomainObjPrivatePtr priv = NULL; qemuMigrationCookiePtr mig = NULL; +virErrorPtr orig_err = NULL; + VIR_DEBUG(driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, cookieout=%p, cookieoutlen=%p, flags=%lu, retcode=%d, driver, dconn, vm, NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen, flags, retcode); -virErrorPtr orig_err = NULL; -priv = vm-privateData; -if (priv-job.asyncJob != QEMU_ASYNC_JOB_MIGRATION_IN) { -qemuReportError(VIR_ERR_NO_DOMAIN, -_(domain '%s' is not processing incoming migration), vm-def-name); +if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN)) goto cleanup; -} -qemuDomainObjDiscardAsyncJob(driver, vm); -if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, 0))) -goto cleanup; +qemuMigrationJobStartPhase(driver, vm, + v3proto ? QEMU_MIGRATION_PHASE_FINISH3 + : QEMU_MIGRATION_PHASE_FINISH2); -if (qemuDomainObjBeginJobWithDriver(driver, vm,
[libvirt] [PATCH 03/19] qemu: Consolidate {Enter, Exit}Monitor{, WithDriver}
EnterMonitor and ExitMonitor methods are very similar to their *WithDriver variants; consolidate them into EnterMonitorInternal and ExitMonitorInternal to avoid (mainly future) code duplication. --- src/qemu/qemu_domain.c | 74 ++- 1 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 8f3eaa7..a2e77b6 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -622,16 +622,10 @@ int qemuDomainObjEndJob(virDomainObjPtr obj) return virDomainObjUnref(obj); } -/* - * obj must be locked before calling, qemud_driver must be unlocked - * - * To be called immediately before any QEMU monitor API call - * Must have already called qemuDomainObjBeginJob(), and checked - * that the VM is still active. - * - * To be followed with qemuDomainObjExitMonitor() once complete - */ -void qemuDomainObjEnterMonitor(virDomainObjPtr obj) + +static void +qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver, + virDomainObjPtr obj) { qemuDomainObjPrivatePtr priv = obj-privateData; @@ -639,14 +633,13 @@ void qemuDomainObjEnterMonitor(virDomainObjPtr obj) qemuMonitorRef(priv-mon); ignore_value(virTimeMs(priv-monStart)); virDomainObjUnlock(obj); +if (driver) +qemuDriverUnlock(driver); } - -/* obj must NOT be locked before calling, qemud_driver must be unlocked - * - * Should be paired with an earlier qemuDomainObjEnterMonitor() call - */ -void qemuDomainObjExitMonitor(virDomainObjPtr obj) +static void +qemuDomainObjExitMonitorInternal(struct qemud_driver *driver, + virDomainObjPtr obj) { qemuDomainObjPrivatePtr priv = obj-privateData; int refs; @@ -656,6 +649,8 @@ void qemuDomainObjExitMonitor(virDomainObjPtr obj) if (refs 0) qemuMonitorUnlock(priv-mon); +if (driver) +qemuDriverLock(driver); virDomainObjLock(obj); priv-monStart = 0; @@ -664,6 +659,28 @@ void qemuDomainObjExitMonitor(virDomainObjPtr obj) } } +/* + * obj must be locked before calling, qemud_driver must be unlocked + * + * To be called immediately before any QEMU monitor API call + * Must have already called qemuDomainObjBeginJob(), and checked + * that the VM is still active. + * + * To be followed with qemuDomainObjExitMonitor() once complete + */ +void qemuDomainObjEnterMonitor(virDomainObjPtr obj) +{ +qemuDomainObjEnterMonitorInternal(NULL, obj); +} + +/* obj must NOT be locked before calling, qemud_driver must be unlocked + * + * Should be paired with an earlier qemuDomainObjEnterMonitor() call + */ +void qemuDomainObjExitMonitor(virDomainObjPtr obj) +{ +qemuDomainObjExitMonitorInternal(NULL, obj); +} /* * obj must be locked before calling, qemud_driver must be locked @@ -676,16 +693,9 @@ void qemuDomainObjExitMonitor(virDomainObjPtr obj) void qemuDomainObjEnterMonitorWithDriver(struct qemud_driver *driver, virDomainObjPtr obj) { -qemuDomainObjPrivatePtr priv = obj-privateData; - -qemuMonitorLock(priv-mon); -qemuMonitorRef(priv-mon); -ignore_value(virTimeMs(priv-monStart)); -virDomainObjUnlock(obj); -qemuDriverUnlock(driver); +qemuDomainObjEnterMonitorInternal(driver, obj); } - /* obj must NOT be locked before calling, qemud_driver must be unlocked, * and will be locked after returning * @@ -694,21 +704,7 @@ void qemuDomainObjEnterMonitorWithDriver(struct qemud_driver *driver, void qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver, virDomainObjPtr obj) { -qemuDomainObjPrivatePtr priv = obj-privateData; -int refs; - -refs = qemuMonitorUnref(priv-mon); - -if (refs 0) -qemuMonitorUnlock(priv-mon); - -qemuDriverLock(driver); -virDomainObjLock(obj); - -priv-monStart = 0; -if (refs == 0) { -priv-mon = NULL; -} +qemuDomainObjExitMonitorInternal(driver, obj); } void qemuDomainObjEnterRemoteWithDriver(struct qemud_driver *driver, -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 01/19] qemu: Separate job related data into a new object
--- src/qemu/qemu_domain.c| 104 + src/qemu/qemu_domain.h| 25 +++--- src/qemu/qemu_driver.c| 82 +++--- src/qemu/qemu_migration.c | 123 ++--- src/qemu/qemu_process.c |5 +- 5 files changed, 192 insertions(+), 147 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4b65d87..bbdfdc4 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -79,6 +79,42 @@ void qemuDomainEventQueue(struct qemud_driver *driver, } +static int +qemuDomainObjInitJob(qemuDomainObjPrivatePtr priv) +{ +memset(priv-job, 0, sizeof(priv-job)); + +if (virCondInit(priv-job.cond) 0) +return -1; + +if (virCondInit(priv-job.signalCond) 0) { +ignore_value(virCondDestroy(priv-job.cond)); +return -1; +} + +return 0; +} + +static void +qemuDomainObjResetJob(qemuDomainObjPrivatePtr priv) +{ +struct qemuDomainJobObj *job = priv-job; + +job-active = QEMU_JOB_NONE; +job-start = 0; +memset(job-info, 0, sizeof(job-info)); +job-signals = 0; +memset(job-signalsData, 0, sizeof(job-signalsData)); +} + +static void +qemuDomainObjFreeJob(qemuDomainObjPrivatePtr priv) +{ +ignore_value(virCondDestroy(priv-job.cond)); +ignore_value(virCondDestroy(priv-job.signalCond)); +} + + static void *qemuDomainObjPrivateAlloc(void) { qemuDomainObjPrivatePtr priv; @@ -86,19 +122,10 @@ static void *qemuDomainObjPrivateAlloc(void) if (VIR_ALLOC(priv) 0) return NULL; -if (virCondInit(priv-jobCond) 0) -goto initfail; - -if (virCondInit(priv-signalCond) 0) { -ignore_value(virCondDestroy(priv-jobCond)); -goto initfail; -} +if (qemuDomainObjInitJob(priv) 0) +VIR_FREE(priv); return priv; - -initfail: -VIR_FREE(priv); -return NULL; } static void qemuDomainObjPrivateFree(void *data) @@ -109,9 +136,8 @@ static void qemuDomainObjPrivateFree(void *data) qemuDomainPCIAddressSetFree(priv-pciaddrs); virDomainChrSourceDefFree(priv-monConfig); +qemuDomainObjFreeJob(priv); VIR_FREE(priv-vcpupids); -ignore_value(virCondDestroy(priv-jobCond)); -ignore_value(virCondDestroy(priv-signalCond)); VIR_FREE(priv-lockState); /* This should never be non-NULL if we get here, but just in case... */ @@ -473,6 +499,24 @@ void qemuDomainSetNamespaceHooks(virCapsPtr caps) caps-ns.href = qemuDomainDefNamespaceHref; } +void +qemuDomainObjSetJob(virDomainObjPtr obj, +enum qemuDomainJob job) +{ +qemuDomainObjPrivatePtr priv = obj-privateData; + +priv-job.active = job; +} + +void +qemuDomainObjDiscardJob(virDomainObjPtr obj) +{ +qemuDomainObjPrivatePtr priv = obj-privateData; + +qemuDomainObjResetJob(priv); +qemuDomainObjSetJob(obj, QEMU_JOB_NONE); +} + /* * obj must be locked before calling, qemud_driver must NOT be locked * @@ -498,8 +542,8 @@ int qemuDomainObjBeginJob(virDomainObjPtr obj) virDomainObjRef(obj); -while (priv-jobActive) { -if (virCondWaitUntil(priv-jobCond, obj-lock, then) 0) { +while (priv-job.active) { +if (virCondWaitUntil(priv-job.cond, obj-lock, then) 0) { /* Safe to ignore value since ref count was incremented above */ ignore_value(virDomainObjUnref(obj)); if (errno == ETIMEDOUT) @@ -511,11 +555,9 @@ int qemuDomainObjBeginJob(virDomainObjPtr obj) return -1; } } -priv-jobActive = QEMU_JOB_UNSPECIFIED; -priv-jobSignals = 0; -memset(priv-jobSignalsData, 0, sizeof(priv-jobSignalsData)); -priv-jobStart = now; -memset(priv-jobInfo, 0, sizeof(priv-jobInfo)); +qemuDomainObjResetJob(priv); +qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED); +priv-job.start = now; return 0; } @@ -540,8 +582,8 @@ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, virDomainObjRef(obj); qemuDriverUnlock(driver); -while (priv-jobActive) { -if (virCondWaitUntil(priv-jobCond, obj-lock, then) 0) { +while (priv-job.active) { +if (virCondWaitUntil(priv-job.cond, obj-lock, then) 0) { if (errno == ETIMEDOUT) qemuReportError(VIR_ERR_OPERATION_TIMEOUT, %s, _(cannot acquire state change lock)); @@ -556,11 +598,9 @@ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, return -1; } } -priv-jobActive = QEMU_JOB_UNSPECIFIED; -priv-jobSignals = 0; -memset(priv-jobSignalsData, 0, sizeof(priv-jobSignalsData)); -priv-jobStart = now; -memset(priv-jobInfo, 0, sizeof(priv-jobInfo)); +qemuDomainObjResetJob(priv); +qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED); +priv-job.start = now; virDomainObjUnlock(obj); qemuDriverLock(driver); @@ -582,17 +622,13 @@ int
[libvirt] [PATCH 13/19] qemu: Fix monitor unlocking in some error paths
When monitor is entered with qemuDomainObjEnterMonitorWithDriver, the correct method for leaving and unlocking the monitor is qemuDomainObjExitMonitorWithDriver. --- src/qemu/qemu_hotplug.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 06e2c84..c86f128 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1240,14 +1240,14 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, ignore_value(qemuDomainObjEnterMonitorWithDriver(driver, vm)); if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv-mon, detach-info.alias) 0) { -qemuDomainObjExitMonitor(driver, vm); +qemuDomainObjExitMonitorWithDriver(driver, vm); qemuAuditDisk(vm, detach, NULL, detach, false); goto cleanup; } } else { if (qemuMonitorRemovePCIDevice(priv-mon, detach-info.addr.pci) 0) { -qemuDomainObjExitMonitor(driver, vm); +qemuDomainObjExitMonitorWithDriver(driver, vm); qemuAuditDisk(vm, detach, NULL, detach, false); goto cleanup; } @@ -1335,7 +1335,7 @@ int qemuDomainDetachDiskDevice(struct qemud_driver *driver, ignore_value(qemuDomainObjEnterMonitorWithDriver(driver, vm)); if (qemuMonitorDelDevice(priv-mon, detach-info.alias) 0) { -qemuDomainObjExitMonitor(driver, vm); +qemuDomainObjExitMonitorWithDriver(driver, vm); qemuAuditDisk(vm, detach, NULL, detach, false); goto cleanup; } @@ -1474,13 +1474,13 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, ignore_value(qemuDomainObjEnterMonitorWithDriver(driver, vm)); if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv-mon, detach-info.alias)) { -qemuDomainObjExitMonitor(driver, vm); +qemuDomainObjExitMonitorWithDriver(driver, vm); goto cleanup; } } else { if (qemuMonitorRemovePCIDevice(priv-mon, detach-info.addr.pci) 0) { -qemuDomainObjExitMonitor(driver, vm); +qemuDomainObjExitMonitorWithDriver(driver, vm); goto cleanup; } } @@ -1569,7 +1569,7 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, ignore_value(qemuDomainObjEnterMonitorWithDriver(driver, vm)); if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv-mon, detach-info.alias) 0) { -qemuDomainObjExitMonitor(driver, vm); +qemuDomainObjExitMonitorWithDriver(driver, vm); qemuAuditNet(vm, detach, NULL, detach, false); goto cleanup; } -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 05/19] qemu: Save job type in domain status XML
If libvirtd is restarted when a job is running, the new libvirtd process needs to know about that to be able to recover and rollback the operation. --- src/qemu/qemu_domain.c| 124 +++- src/qemu/qemu_domain.h| 35 src/qemu/qemu_driver.c| 138 +++-- src/qemu/qemu_hotplug.c | 12 ++-- src/qemu/qemu_migration.c | 20 --- src/qemu/qemu_process.c |8 +- 6 files changed, 212 insertions(+), 125 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 1ed5efd..062ecc7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -44,6 +44,26 @@ #define QEMU_NAMESPACE_HREF http://libvirt.org/schemas/domain/qemu/1.0; +VIR_ENUM_DECL(qemuDomainJob) +VIR_ENUM_IMPL(qemuDomainJob, QEMU_JOB_LAST, + none, + query, + destroy, + suspend, + modify, + none, /* async job is never stored in job.active */ + async nested, +); + +VIR_ENUM_DECL(qemuDomainAsyncJob) +VIR_ENUM_IMPL(qemuDomainAsyncJob, QEMU_ASYNC_JOB_LAST, + none, + migration out, + migration in, + save, + dump, +); + static void qemuDomainEventDispatchFunc(virConnectPtr conn, virDomainEventPtr event, @@ -214,6 +234,12 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data) if (priv-lockState) virBufferAsprintf(buf, lockstate%s/lockstate\n, priv-lockState); +if (priv-job.active || priv-job.asyncJob) { +virBufferAsprintf(buf, job type='%s' async='%s'/\n, + qemuDomainJobTypeToString(priv-job.active), + qemuDomainAsyncJobTypeToString(priv-job.asyncJob)); +} + return 0; } @@ -320,6 +346,32 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) priv-lockState = virXPathString(string(./lockstate), ctxt); +if ((tmp = virXPathString(string(./job[1]/@type), ctxt))) { +int type; + +if ((type = qemuDomainJobTypeFromString(tmp)) 0) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(Unknown job type %s), tmp); +VIR_FREE(tmp); +goto error; +} +VIR_FREE(tmp); +priv-job.active = type; +} + +if ((tmp = virXPathString(string(./job[1]/@async), ctxt))) { +int async; + +if ((async = qemuDomainAsyncJobTypeFromString(tmp)) 0) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(Unknown async job type %s), tmp); +VIR_FREE(tmp); +goto error; +} +VIR_FREE(tmp); +priv-job.asyncJob = async; +} + return 0; error: @@ -516,12 +568,16 @@ void qemuDomainSetNamespaceHooks(virCapsPtr caps) } void -qemuDomainObjSetJob(virDomainObjPtr obj, -enum qemuDomainJob job) +qemuDomainObjSaveJob(struct qemud_driver *driver, virDomainObjPtr obj) { -qemuDomainObjPrivatePtr priv = obj-privateData; +if (!virDomainObjIsActive(obj)) { +/* don't write the state file yet, it will be written once the domain + * gets activated */ +return; +} -priv-job.active = job; +if (virDomainSaveStatus(driver-caps, driver-stateDir, obj) 0) +VIR_WARN(Failed to save status on vm %s, obj-def-name); } void @@ -537,13 +593,14 @@ qemuDomainObjSetAsyncJobMask(virDomainObjPtr obj, } void -qemuDomainObjDiscardAsyncJob(virDomainObjPtr obj) +qemuDomainObjDiscardAsyncJob(struct qemud_driver *driver, virDomainObjPtr obj) { qemuDomainObjPrivatePtr priv = obj-privateData; if (priv-job.active == QEMU_JOB_ASYNC_NESTED) qemuDomainObjResetJob(priv); qemuDomainObjResetAsyncJob(priv); +qemuDomainObjSaveJob(driver, obj); } static bool @@ -559,7 +616,7 @@ qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv, enum qemuDomainJob job) * obj must be locked before calling; driver_locked says if qemu_driver is * locked or not. */ -static int +static int ATTRIBUTE_NONNULL(1) qemuDomainObjBeginJobInternal(struct qemud_driver *driver, bool driver_locked, virDomainObjPtr obj, @@ -611,6 +668,8 @@ retry: virDomainObjLock(obj); } +qemuDomainObjSaveJob(driver, obj); + return 0; error: @@ -639,16 +698,19 @@ error: * Upon successful return, the object will have its ref count increased, * successful calls must be followed by EndJob eventually */ -int qemuDomainObjBeginJob(virDomainObjPtr obj, enum qemuDomainJob job) +int qemuDomainObjBeginJob(struct qemud_driver *driver, + virDomainObjPtr obj, + enum qemuDomainJob job) { -return qemuDomainObjBeginJobInternal(NULL, false, obj, job, +
[libvirt] [PATCH 07/19] qemu: Add support for job phase
Asynchronous jobs may take long time to finish and may consist of several phases which we need to now about to help with recovery/rollback after libvirtd restarts. --- src/qemu/qemu_domain.c | 75 +++- src/qemu/qemu_domain.h |9 ++ 2 files changed, 83 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b26308e..d0dd764 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -65,6 +65,46 @@ VIR_ENUM_IMPL(qemuDomainAsyncJob, QEMU_ASYNC_JOB_LAST, ); +const char * +qemuDomainAsyncJobPhaseToString(enum qemuDomainAsyncJob job, +int phase ATTRIBUTE_UNUSED) +{ +switch (job) { +case QEMU_ASYNC_JOB_MIGRATION_OUT: +case QEMU_ASYNC_JOB_MIGRATION_IN: +case QEMU_ASYNC_JOB_SAVE: +case QEMU_ASYNC_JOB_DUMP: +case QEMU_ASYNC_JOB_NONE: +case QEMU_ASYNC_JOB_LAST: +; /* fall through */ +} + +return none; +} + +int +qemuDomainAsyncJobPhaseFromString(enum qemuDomainAsyncJob job, + const char *phase) +{ +if (!phase) +return 0; + +switch (job) { +case QEMU_ASYNC_JOB_MIGRATION_OUT: +case QEMU_ASYNC_JOB_MIGRATION_IN: +case QEMU_ASYNC_JOB_SAVE: +case QEMU_ASYNC_JOB_DUMP: +case QEMU_ASYNC_JOB_NONE: +case QEMU_ASYNC_JOB_LAST: +; /* fall through */ +} + +if (STREQ(phase, none)) +return 0; +else +return -1; +} + static void qemuDomainEventDispatchFunc(virConnectPtr conn, virDomainEventPtr event, virConnectDomainEventGenericCallback cb, @@ -135,6 +175,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) struct qemuDomainJobObj *job = priv-job; job-asyncJob = QEMU_ASYNC_JOB_NONE; +job-phase = 0; job-mask = DEFAULT_JOB_MASK; job-start = 0; memset(job-info, 0, sizeof(job-info)); @@ -151,6 +192,7 @@ qemuDomainObjRestoreJob(virDomainObjPtr obj, memset(job, 0, sizeof(*job)); job-active = priv-job.active; job-asyncJob = priv-job.asyncJob; +job-phase = priv-job.phase; qemuDomainObjResetJob(priv); qemuDomainObjResetAsyncJob(priv); @@ -249,9 +291,15 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data) virBufferAsprintf(buf, lockstate%s/lockstate\n, priv-lockState); if (priv-job.active || priv-job.asyncJob) { -virBufferAsprintf(buf, job type='%s' async='%s'/\n, +virBufferAsprintf(buf, job type='%s' async='%s', qemuDomainJobTypeToString(priv-job.active), qemuDomainAsyncJobTypeToString(priv-job.asyncJob)); +if (priv-job.phase) { +virBufferAsprintf(buf, phase='%s', + qemuDomainAsyncJobPhaseToString( +priv-job.asyncJob, priv-job.phase)); +} +virBufferAddLit(buf, /\n); } return 0; @@ -384,6 +432,17 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) } VIR_FREE(tmp); priv-job.asyncJob = async; + +if ((tmp = virXPathString(string(./job[1]/@phase), ctxt))) { +priv-job.phase = qemuDomainAsyncJobPhaseFromString(async, tmp); +if (priv-job.phase 0) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(Unknown job phase %s), tmp); +VIR_FREE(tmp); +goto error; +} +VIR_FREE(tmp); +} } return 0; @@ -595,6 +654,20 @@ qemuDomainObjSaveJob(struct qemud_driver *driver, virDomainObjPtr obj) } void +qemuDomainObjSetJobPhase(struct qemud_driver *driver, + virDomainObjPtr obj, + int phase) +{ +qemuDomainObjPrivatePtr priv = obj-privateData; + +if (!priv-job.asyncJob) +return; + +priv-job.phase = phase; +qemuDomainObjSaveJob(driver, obj); +} + +void qemuDomainObjSetAsyncJobMask(virDomainObjPtr obj, unsigned long long allowedJobs) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 49be3d2..7245e67 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -91,6 +91,7 @@ struct qemuDomainJobObj { virCond asyncCond; /* Use to coordinate with async jobs */ enum qemuDomainAsyncJob asyncJob; /* Currently active async job */ +int phase; /* Job phase (mainly for migrations) */ unsigned long long mask;/* Jobs allowed during async job */ unsigned long long start; /* When the async job started */ virDomainJobInfo info; /* Async job progress data */ @@ -133,6 +134,11 @@ struct qemuDomainWatchdogEvent int action; }; +const char
[libvirt] [PATCH 17/19] qemu: Remove special case for virDomainMigrateSetMaxDowntime
Call qemu monitor command directly within a special job that is only allowed during outgoing migration. --- src/qemu/qemu_domain.c|1 - src/qemu/qemu_domain.h|6 -- src/qemu/qemu_driver.c| 23 +++ src/qemu/qemu_migration.c | 13 - 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index c47ab60..deaf9fd 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -186,7 +186,6 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) job-start = 0; memset(job-info, 0, sizeof(job-info)); job-signals = 0; -memset(job-signalsData, 0, sizeof(job-signalsData)); } void diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 7e6b522..71cefd9 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -69,11 +69,6 @@ enum qemuDomainAsyncJob { enum qemuDomainJobSignals { QEMU_JOB_SIGNAL_CANCEL = 1 0, /* Request job cancellation */ QEMU_JOB_SIGNAL_SUSPEND = 1 1, /* Request VM suspend to finish live migration offline */ -QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME = 1 2, /* Request migration downtime change */ -}; - -struct qemuDomainJobSignalsData { -unsigned long long migrateDowntime; /* Data for QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME */ }; struct qemuDomainJobObj { @@ -89,7 +84,6 @@ struct qemuDomainJobObj { virCond signalCond; /* Use to coordinate the safe queries during migration */ unsigned int signals; /* Signals for running job */ -struct qemuDomainJobSignalsData signalsData;/* Signal specific data */ }; typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1235787..d62e99d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7383,19 +7383,23 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom, qemuDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); +qemuDriverUnlock(driver); 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; +return -1; } +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) 0) +goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, %s, _(domain is not running)); -goto cleanup; +goto endjob; } priv = vm-privateData; @@ -7403,18 +7407,21 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom, if (priv-job.asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT) { qemuReportError(VIR_ERR_OPERATION_INVALID, %s, _(domain is not being migrated)); -goto cleanup; +goto endjob; } -VIR_DEBUG(Requesting migration downtime change to %llums, downtime); -priv-job.signalsData.migrateDowntime = downtime; -priv-job.signals |= QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME; -ret = 0; +VIR_DEBUG(Setting migration downtime to %llums, downtime); +ignore_value(qemuDomainObjEnterMonitor(driver, vm)); +ret = qemuMonitorSetMigrationDowntime(priv-mon, downtime); +qemuDomainObjExitMonitor(driver, vm); + +endjob: +if (qemuDomainObjEndJob(driver, vm) == 0) +vm = NULL; cleanup: if (vm) virDomainObjUnlock(vm); -qemuDriverUnlock(driver); return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d7ad97f..ee2c5a0 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -775,19 +775,6 @@ qemuMigrationProcessJobSignals(struct qemud_driver *driver, VIR_DEBUG(Pausing domain for non-live migration); if (qemuMigrationSetOffline(driver, vm) 0) VIR_WARN(Unable to pause domain); -} else if (priv-job.signals QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME) { -unsigned long long ms = priv-job.signalsData.migrateDowntime; - -priv-job.signals ^= QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME; -priv-job.signalsData.migrateDowntime = 0; -VIR_DEBUG(Setting migration downtime to %llums, ms); -ret = qemuDomainObjEnterMonitorWithDriver(driver, vm); -if (ret == 0) { -ret = qemuMonitorSetMigrationDowntime(priv-mon, ms); -qemuDomainObjExitMonitorWithDriver(driver, vm); -} -if (ret 0) -VIR_WARN(Unable to set migration downtime); } else { ret = 0; } -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 06/19] qemu: Recover from interrupted jobs
Detect and react on situations when libvirtd was restarted or killed when a job was active. --- src/qemu/qemu_domain.c | 14 src/qemu/qemu_domain.h |2 + src/qemu/qemu_process.c | 80 +++ 3 files changed, 96 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 062ecc7..b26308e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -142,6 +142,20 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) memset(job-signalsData, 0, sizeof(job-signalsData)); } +void +qemuDomainObjRestoreJob(virDomainObjPtr obj, +struct qemuDomainJobObj *job) +{ +qemuDomainObjPrivatePtr priv = obj-privateData; + +memset(job, 0, sizeof(*job)); +job-active = priv-job.active; +job-asyncJob = priv-job.asyncJob; + +qemuDomainObjResetJob(priv); +qemuDomainObjResetAsyncJob(priv); +} + static void qemuDomainObjFreeJob(qemuDomainObjPrivatePtr priv) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 17d1356..49be3d2 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -177,6 +177,8 @@ void qemuDomainObjEndNestedJob(struct qemud_driver *driver, void qemuDomainObjSaveJob(struct qemud_driver *driver, virDomainObjPtr obj); void qemuDomainObjSetAsyncJobMask(virDomainObjPtr obj, unsigned long long allowedJobs); +void qemuDomainObjRestoreJob(virDomainObjPtr obj, + struct qemuDomainJobObj *job); void qemuDomainObjDiscardAsyncJob(struct qemud_driver *driver, virDomainObjPtr obj); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 3ffde51..49625b5 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2223,6 +2223,80 @@ qemuProcessUpdateState(struct qemud_driver *driver, virDomainObjPtr vm) return 0; } +static int +qemuProcessRecoverJob(struct qemud_driver *driver, + virDomainObjPtr vm, + virConnectPtr conn, + const struct qemuDomainJobObj *job) +{ +virDomainState state; +int reason; + +state = virDomainObjGetState(vm, reason); + +switch (job-asyncJob) { +case QEMU_ASYNC_JOB_MIGRATION_OUT: +case QEMU_ASYNC_JOB_MIGRATION_IN: +/* we don't know what to do yet */ +break; + +case QEMU_ASYNC_JOB_SAVE: +case QEMU_ASYNC_JOB_DUMP: +/* TODO cancel possibly running migrate operation */ +/* resume the domain but only if it was paused as a result of + * running save/dump operation */ +if (state == VIR_DOMAIN_PAUSED +((job-asyncJob == QEMU_ASYNC_JOB_DUMP + reason == VIR_DOMAIN_PAUSED_DUMP) || + (job-asyncJob == QEMU_ASYNC_JOB_SAVE + reason == VIR_DOMAIN_PAUSED_SAVE) || + reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { +if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_UNPAUSED) 0) { +VIR_WARN(Could not resume domain %s after, vm-def-name); +} +} +break; + +case QEMU_ASYNC_JOB_NONE: +case QEMU_ASYNC_JOB_LAST: +break; +} + +if (!virDomainObjIsActive(vm)) +return -1; + +switch (job-active) { +case QEMU_JOB_QUERY: +/* harmless */ +break; + +case QEMU_JOB_DESTROY: +VIR_DEBUG(Domain %s should have already been destroyed, + vm-def-name); +return -1; + +case QEMU_JOB_SUSPEND: +/* mostly harmless */ +break; + +case QEMU_JOB_MODIFY: +/* XXX depending on the command we may be in an inconsistent state and + * we should probably fall back to monitor error state and refuse to + */ +break; + +case QEMU_JOB_ASYNC: +case QEMU_JOB_ASYNC_NESTED: +/* async job was already handled above */ +case QEMU_JOB_NONE: +case QEMU_JOB_LAST: +break; +} + +return 0; +} + struct qemuProcessReconnectData { virConnectPtr conn; struct qemud_driver *driver; @@ -2239,9 +2313,12 @@ qemuProcessReconnect(void *payload, const void *name ATTRIBUTE_UNUSED, void *opa struct qemud_driver *driver = data-driver; qemuDomainObjPrivatePtr priv; virConnectPtr conn = data-conn; +struct qemuDomainJobObj oldjob; virDomainObjLock(obj); +qemuDomainObjRestoreJob(obj, oldjob); + VIR_DEBUG(Reconnect monitor to %p '%s', obj, obj-def-name); priv = obj-privateData; @@ -2287,6 +2364,9 @@ qemuProcessReconnect(void *payload, const void *name ATTRIBUTE_UNUSED, void *opa if (qemuProcessFiltersInstantiate(conn, obj-def)) goto error; +if (qemuProcessRecoverJob(driver, obj, conn, oldjob) 0) +goto error; + priv-job.active = QEMU_JOB_NONE; /* update domain state XML with possibly updated state
[libvirt] [PATCH 09/19] qemu: Implement migration job phases
This patch introduces several helper methods to deal with jobs and phases during migration in a simpler manner. --- src/qemu/MIGRATION.txt| 55 +++ src/qemu/qemu_domain.c|5 ++ src/qemu/qemu_migration.c | 91 + src/qemu/qemu_migration.h | 36 ++ 4 files changed, 187 insertions(+), 0 deletions(-) create mode 100644 src/qemu/MIGRATION.txt diff --git a/src/qemu/MIGRATION.txt b/src/qemu/MIGRATION.txt new file mode 100644 index 000..6c32998 --- /dev/null +++ b/src/qemu/MIGRATION.txt @@ -0,0 +1,55 @@ +QEMU Migration Locking Rules + + +Migration is a complicated beast which may span across several APIs on both +source and destination side and we need to keep the domain we are migrating in +a consistent state during the whole process. + +To avoid anyone from changing the domain in the middle of migration we need to +keep MIGRATION_OUT job active during migration from Begin to Confirm on the +source side and MIGRATION_IN job has to be active from Prepare to Finish on +the destination side. + +For this purpose we introduce several helper methods to deal with locking +primitives (described in THREADS.txt) in the right way: + +* qemuMigrationJobStart + +* qemuMigrationJobContinue + +* qemuMigrationJobStartPhase + +* qemuMigrationJobSetPhase + +* qemuMigrationJobFinish + +The sequence of calling qemuMigrationJob* helper methods is as follows: + +- The first API of a migration protocol (Prepare or Perform/Begin depending on + migration type and version) has to start migration job and keep it active: + + qemuMigrationJobStart(driver, vm, QEMU_JOB_MIGRATION_{IN,OUT}); + qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_*); + ...do work... + qemuMigrationJobContinue(vm); + +- All consequent phases except for the last one have to keep the job active: + + if (!qemuMigrationJobIsActive(vm, QEMU_JOB_MIGRATION_{IN,OUT})) + return; + qemuMigrationJobStartPhase(driver, vm, QEMU_MIGRATION_PHASE_*); + ...do work... + qemuMigrationJobContinue(vm); + +- The last migration phase finally finishes the migration job: + + if (!qemuMigrationJobIsActive(vm, QEMU_JOB_MIGRATION_{IN,OUT})) + return; + qemuMigrationJobStartPhase(driver, vm, QEMU_MIGRATION_PHASE_*); + ...do work... + qemuMigrationJobFinish(driver, vm); + +While migration job is running (i.e., after qemuMigrationJobStart* but before +qemuMigrationJob{Continue,Finish}), migration phase can be advanced using + + qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_*); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d0dd764..39cbf0e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -26,6 +26,7 @@ #include qemu_domain.h #include qemu_command.h #include qemu_capabilities.h +#include qemu_migration.h #include memory.h #include logging.h #include virterror_internal.h @@ -72,6 +73,8 @@ qemuDomainAsyncJobPhaseToString(enum qemuDomainAsyncJob job, switch (job) { case QEMU_ASYNC_JOB_MIGRATION_OUT: case QEMU_ASYNC_JOB_MIGRATION_IN: +return qemuMigrationJobPhaseTypeToString(phase); + case QEMU_ASYNC_JOB_SAVE: case QEMU_ASYNC_JOB_DUMP: case QEMU_ASYNC_JOB_NONE: @@ -92,6 +95,8 @@ qemuDomainAsyncJobPhaseFromString(enum qemuDomainAsyncJob job, switch (job) { case QEMU_ASYNC_JOB_MIGRATION_OUT: case QEMU_ASYNC_JOB_MIGRATION_IN: +return qemuMigrationJobPhaseTypeFromString(phase); + case QEMU_ASYNC_JOB_SAVE: case QEMU_ASYNC_JOB_DUMP: case QEMU_ASYNC_JOB_NONE: diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index e595596..33aa89b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -46,6 +46,19 @@ #define VIR_FROM_THIS VIR_FROM_QEMU +VIR_ENUM_IMPL(qemuMigrationJobPhase, QEMU_MIGRATION_PHASE_LAST, + none, + preform2, + begin3, + perform3, + perform3_done, + confirm3_cancelled, + confirm3, + prepare, + finish2, + finish3, +); + enum qemuMigrationCookieFlags { QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS, QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE, @@ -2749,3 +2762,81 @@ cleanup: } return ret; } + +int +qemuMigrationJobStart(struct qemud_driver *driver, + virDomainObjPtr vm, + enum qemuDomainAsyncJob job) +{ +qemuDomainObjPrivatePtr priv = vm-privateData; + +if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm, job) 0) +return -1; + +if (job == QEMU_ASYNC_JOB_MIGRATION_IN) +qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE); +else +qemuDomainObjSetAsyncJobMask(vm, DEFAULT_JOB_MASK); + +priv-job.info.type = VIR_DOMAIN_JOB_UNBOUNDED; + +return 0; +} + +void
[libvirt] [PATCH 08/19] qemu: Consolidate qemuMigrationPrepare{Direct, Tunnel}
Most of the code in these two functions is supposed to be identical but currently it isn't (which is natural since the code is duplicated). Let's move common parts of these functions into qemuMigrationPrepareAny. --- src/qemu/qemu_migration.c | 255 +++- 1 files changed, 87 insertions(+), 168 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 4c516b0..e595596 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1057,40 +1057,33 @@ cleanup: /* Prepare is the first step, and it runs on the destination host. - * - * This version starts an empty VM listening on a localhost TCP port, and - * sets up the corresponding virStream to handle the incoming data. */ -int -qemuMigrationPrepareTunnel(struct qemud_driver *driver, - virConnectPtr dconn, - const char *cookiein, - int cookieinlen, - char **cookieout, - int *cookieoutlen, - virStreamPtr st, - const char *dname, - const char *dom_xml) + +static int +qemuMigrationPrepareAny(struct qemud_driver *driver, +virConnectPtr dconn, +const char *cookiein, +int cookieinlen, +char **cookieout, +int *cookieoutlen, +const char *dname, +const char *dom_xml, +const char *migrateFrom, +virStreamPtr st) { virDomainDefPtr def = NULL; virDomainObjPtr vm = NULL; virDomainEventPtr event = NULL; int ret = -1; -int internalret; int dataFD[2] = { -1, -1 }; qemuDomainObjPrivatePtr priv = NULL; unsigned long long now; qemuMigrationCookiePtr mig = NULL; - -VIR_DEBUG(driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, - cookieout=%p, cookieoutlen=%p, st=%p, dname=%s, dom_xml=%s, - driver, dconn, NULLSTR(cookiein), cookieinlen, - cookieout, cookieoutlen, st, NULLSTR(dname), dom_xml); +bool tunnel = !!st; if (virTimeMs(now) 0) return -1; -/* Parse the domain XML. */ if (!(def = virDomainDefParseString(driver-caps, dom_xml, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; @@ -1129,50 +1122,45 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver, /* Domain starts inactive, even if the domain XML had an id field. */ vm-def-id = -1; -if (pipe(dataFD) 0 || -virSetCloseExec(dataFD[1]) 0) { +if (tunnel +(pipe(dataFD) 0 || virSetCloseExec(dataFD[1]) 0)) { virReportSystemError(errno, %s, _(cannot create pipe for tunnelled migration)); goto endjob; } /* Start the QEMU daemon, with the same command-line arguments plus - * -incoming stdio (which qemu_command might convert to exec:cat or fd:n) + * -incoming $migrateFrom */ -internalret = qemuProcessStart(dconn, driver, vm, stdio, true, - true, dataFD[0], NULL, - VIR_VM_OP_MIGRATE_IN_START); -if (internalret 0) { +if (qemuProcessStart(dconn, driver, vm, migrateFrom, true, + true, dataFD[0], NULL, + VIR_VM_OP_MIGRATE_IN_START) 0) { qemuAuditDomainStart(vm, migrated, false); /* Note that we don't set an error here because qemuProcessStart * should have already done that. */ -if (!vm-persistent) { -virDomainRemoveInactive(driver-domains, vm); -vm = NULL; -} goto endjob; } -if (virFDStreamOpen(st, dataFD[1]) 0) { -qemuAuditDomainStart(vm, migrated, false); -qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FAILED); -if (!vm-persistent) { -if (qemuDomainObjEndAsyncJob(driver, vm) 0) -virDomainRemoveInactive(driver-domains, vm); -vm = NULL; +if (tunnel) { +if (virFDStreamOpen(st, dataFD[1]) 0) { +virReportSystemError(errno, %s, + _(cannot pass pipe for tunnelled migration)); +qemuAuditDomainStart(vm, migrated, false); +qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FAILED); +goto endjob; } -virReportSystemError(errno, %s, - _(cannot pass pipe for tunnelled migration)); -goto endjob; +dataFD[1] = -1; /* 'st' owns the FD now will close it */ } -dataFD[1] = -1; /* 'st' owns the FD now will close it */ - -qemuAuditDomainStart(vm, migrated, true); -event = virDomainEventNewFromObj(vm, -
[libvirt] [PATCH 11/19] qemu: Migration job on source daemon
Make MIGRATION_OUT use the new helper methods. This also introduces new protection to migration v3 process: the migration job is held from Begin to Confirm to avoid changes to a domain during migration (esp. between Begin and Perform phases). This change, however brings a small issue when Prepare step fails during normal (not p2p or tunneled) migration when old client talks to new libvirtd. The old client doesn't call Confirm (with cancelled == 1) to end the migration job. I'm open to suggestions how to solve this in the best way. My idea is to use flags for Begin3 and Perform3 that would enable this extra protection by moving migration job start from Perform to Begin phase while maintaining the old behavior if the flags are not set. Note that virDomainAbortJob will be able to cancel migration in any phase (i.e., not only in Perform phase). --- src/libvirt.c | 11 ++- src/qemu/qemu_driver.c| 47 - src/qemu/qemu_migration.c | 232 +++-- 3 files changed, 211 insertions(+), 79 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index e00c64f..fa32d83 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -3761,7 +3761,7 @@ virDomainMigrateVersion3(virDomainPtr domain, int ret; virDomainInfo info; virErrorPtr orig_err = NULL; -int cancelled; +int cancelled = 1; VIR_DOMAIN_DEBUG(domain, dconn=%p xmlin=%s, flags=%lu, dname=%s, uri=%s, bandwidth=%lu, dconn, NULLSTR(xmlin), flags, @@ -3798,14 +3798,16 @@ virDomainMigrateVersion3(virDomainPtr domain, (dconn, cookiein, cookieinlen, cookieout, cookieoutlen, uri, uri_out, flags, dname, bandwidth, dom_xml); VIR_FREE (dom_xml); -if (ret == -1) -goto done; +if (ret == -1) { +/* Make sure Confirm doesn't overwrite the error */ +orig_err = virSaveLastError(); +goto confirm; +} if (uri == NULL uri_out == NULL) { virLibConnError(VIR_ERR_INTERNAL_ERROR, _(domainMigratePrepare3 did not set uri)); virDispatchError(domain-conn); -cancelled = 1; goto finish; } if (uri_out) @@ -3871,6 +3873,7 @@ finish: if (!orig_err) orig_err = virSaveLastError(); +confirm: /* * If cancelled, then src VM will be restarted, else * it will be killed diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9dcb248..e317c5b 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6850,12 +6850,42 @@ qemuDomainMigrateBegin3(virDomainPtr domain, goto cleanup; } -xml = qemuMigrationBegin(driver, vm, xmlin, - cookieout, cookieoutlen); +if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) 0) +goto cleanup; + +if (!virDomainObjIsActive(vm)) { +qemuReportError(VIR_ERR_OPERATION_INVALID, +%s, _(domain is not running)); +goto endjob; +} + +if (!(xml = qemuMigrationBegin(driver, vm, xmlin, + cookieout, cookieoutlen))) +goto endjob; + +/* We keep the job active across API calls until the confirm() call. + * This prevents any other APIs being invoked while migration is taking + * place. + */ +if (qemuMigrationJobContinue(vm) == 0) { +vm = NULL; +qemuReportError(VIR_ERR_OPERATION_FAILED, +%s, _(domain disappeared)); +VIR_FREE(xml); +if (cookieout) +VIR_FREE(*cookieout); +} cleanup: +if (vm) +virDomainObjUnlock(vm); qemuDriverUnlock(driver); return xml; + +endjob: +if (qemuMigrationJobFinish(driver, vm) == 0) +vm = NULL; +goto cleanup; } static int @@ -7005,7 +7035,6 @@ qemuDomainMigratePerform3(virDomainPtr dom, dconnuri, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, true); - cleanup: qemuDriverUnlock(driver); return ret; @@ -7065,6 +7094,7 @@ qemuDomainMigrateConfirm3(virDomainPtr domain, struct qemud_driver *driver = domain-conn-privateData; virDomainObjPtr vm; int ret = -1; +enum qemuMigrationJobPhase phase; virCheckFlags(VIR_MIGRATE_LIVE | VIR_MIGRATE_PEER2PEER | @@ -7085,14 +7115,21 @@ qemuDomainMigrateConfirm3(virDomainPtr domain, goto cleanup; } -if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) 0) +if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT)) goto cleanup; +if (cancelled) +phase = QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED; +else +phase = QEMU_MIGRATION_PHASE_CONFIRM3; + +qemuMigrationJobStartPhase(driver, vm, phase); + ret = qemuMigrationConfirm(driver, domain-conn, vm,
[libvirt] [PATCH 12/19] qemu: Recover from interrupted migration
--- src/qemu/qemu_process.c | 110 ++- 1 files changed, 109 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 49625b5..ddb29c1 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -38,6 +38,7 @@ #include qemu_hostdev.h #include qemu_hotplug.h #include qemu_bridge_filter.h +#include qemu_migration.h #if HAVE_NUMACTL # define NUMA_VERSION1_COMPATIBILITY 1 @@ -2224,6 +2225,111 @@ qemuProcessUpdateState(struct qemud_driver *driver, virDomainObjPtr vm) } static int +qemuProcessRecoverMigration(struct qemud_driver *driver, +virDomainObjPtr vm, +virConnectPtr conn, +enum qemuDomainAsyncJob job, +enum qemuMigrationJobPhase phase, +virDomainState state, +int reason) +{ +if (job == QEMU_ASYNC_JOB_MIGRATION_IN) { +switch (phase) { +case QEMU_MIGRATION_PHASE_NONE: +case QEMU_MIGRATION_PHASE_PERFORM2: +case QEMU_MIGRATION_PHASE_BEGIN3: +case QEMU_MIGRATION_PHASE_PERFORM3: +case QEMU_MIGRATION_PHASE_PERFORM3_DONE: +case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED: +case QEMU_MIGRATION_PHASE_CONFIRM3: +case QEMU_MIGRATION_PHASE_LAST: +break; + +case QEMU_MIGRATION_PHASE_PREPARE: +VIR_DEBUG(Killing unfinished incoming migration for domain %s, + vm-def-name); +return -1; + +case QEMU_MIGRATION_PHASE_FINISH2: +/* source domain is already killed so let's just resume the domain + * and hope we are all set */ +VIR_DEBUG(Incoming migration finished, resuming domain %s, + vm-def-name); +if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_UNPAUSED) 0) { +VIR_WARN(Could not resume domain %s, vm-def-name); +} +break; + +case QEMU_MIGRATION_PHASE_FINISH3: +/* migration finished, we started resuming the domain but didn't + * confirm success or failure yet; killing it seems safest */ +VIR_DEBUG(Killing migrated domain %s, vm-def-name); +return -1; +} +} else if (job == QEMU_ASYNC_JOB_MIGRATION_OUT) { +switch (phase) { +case QEMU_MIGRATION_PHASE_NONE: +case QEMU_MIGRATION_PHASE_PREPARE: +case QEMU_MIGRATION_PHASE_FINISH2: +case QEMU_MIGRATION_PHASE_FINISH3: +case QEMU_MIGRATION_PHASE_LAST: +break; + +case QEMU_MIGRATION_PHASE_BEGIN3: +/* nothing happen so far, just forget we were about to migrate the + * domain */ +break; + +case QEMU_MIGRATION_PHASE_PERFORM2: +case QEMU_MIGRATION_PHASE_PERFORM3: +/* migration is still in progress, let's cancel it and resume the + * domain */ +VIR_DEBUG(Canceling unfinished outgoing migration of domain %s, + vm-def-name); +/* TODO cancel possibly running migrate operation */ +/* resume the domain but only if it was paused as a result of + * migration */ +if (state == VIR_DOMAIN_PAUSED +(reason == VIR_DOMAIN_PAUSED_MIGRATION || + reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { +if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_UNPAUSED) 0) { +VIR_WARN(Could not resume domain %s, vm-def-name); +} +} +break; + +case QEMU_MIGRATION_PHASE_PERFORM3_DONE: +/* migration finished but we didn't have a chance to get the result + * of Finish3 step; third party needs to check what to do next + */ +break; + +case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED: +/* Finish3 failed, we need to resume the domain */ +VIR_DEBUG(Resuming domain %s after failed migration, + vm-def-name); +if (state == VIR_DOMAIN_PAUSED +(reason == VIR_DOMAIN_PAUSED_MIGRATION || + reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { +if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_UNPAUSED) 0) { +VIR_WARN(Could not resume domain %s, vm-def-name); +} +} +break; + +case QEMU_MIGRATION_PHASE_CONFIRM3: +/* migration completed, we need to kill the domain here */ +return -1; +} +} + +return 0; +} + +static int qemuProcessRecoverJob(struct qemud_driver *driver, virDomainObjPtr vm,
[libvirt] [PATCH 16/19] qemu: Remove special case for virDomainMigrateSetMaxSpeed
Call qemu monitor command directly within a special job that is only allowed during outgoing migration. --- src/qemu/qemu_domain.c|1 + src/qemu/qemu_domain.h|3 +-- src/qemu/qemu_driver.c| 23 +++ src/qemu/qemu_migration.c | 21 + src/qemu/qemu_process.c |1 + 5 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 2e4228a..c47ab60 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -52,6 +52,7 @@ VIR_ENUM_IMPL(qemuDomainJob, QEMU_JOB_LAST, destroy, suspend, modify, + migration operation, none, /* async job is never stored in job.active */ async nested, ); diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index c2ad456..7e6b522 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -43,6 +43,7 @@ enum qemuDomainJob { QEMU_JOB_DESTROY, /* Destroys the domain (cannot be masked out) */ QEMU_JOB_SUSPEND, /* Suspends (stops vCPUs) the domain */ QEMU_JOB_MODIFY,/* May change state */ +QEMU_JOB_MIGRATION_OP, /* Operation influencing outgoing migration */ /* The following two items must always be the last items before JOB_LAST */ QEMU_JOB_ASYNC, /* Asynchronous job */ @@ -69,12 +70,10 @@ enum qemuDomainJobSignals { QEMU_JOB_SIGNAL_CANCEL = 1 0, /* Request job cancellation */ QEMU_JOB_SIGNAL_SUSPEND = 1 1, /* Request VM suspend to finish live migration offline */ QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME = 1 2, /* Request migration downtime change */ -QEMU_JOB_SIGNAL_MIGRATE_SPEED = 1 3, /* Request migration speed change */ }; struct qemuDomainJobSignalsData { unsigned long long migrateDowntime; /* Data for QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME */ -unsigned long migrateBandwidth; /* Data for QEMU_JOB_SIGNAL_MIGRATE_SPEED */ }; struct qemuDomainJobObj { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cd64f85..1235787 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7432,19 +7432,23 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, qemuDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); +qemuDriverUnlock(driver); 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; +return -1; } +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) 0) +goto cleanup; + if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, %s, _(domain is not running)); -goto cleanup; +goto endjob; } priv = vm-privateData; @@ -7452,18 +7456,21 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, if (priv-job.asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT) { qemuReportError(VIR_ERR_OPERATION_INVALID, %s, _(domain is not being migrated)); -goto cleanup; +goto endjob; } -VIR_DEBUG(Requesting migration speed change to %luMbs, bandwidth); -priv-job.signalsData.migrateBandwidth = bandwidth; -priv-job.signals |= QEMU_JOB_SIGNAL_MIGRATE_SPEED; -ret = 0; +VIR_DEBUG(Setting migration bandwidth to %luMbs, bandwidth); +ignore_value(qemuDomainObjEnterMonitor(driver, vm)); +ret = qemuMonitorSetMigrationSpeed(priv-mon, bandwidth); +qemuDomainObjExitMonitor(driver, vm); + +endjob: +if (qemuDomainObjEndJob(driver, vm) == 0) +vm = NULL; cleanup: if (vm) virDomainObjUnlock(vm); -qemuDriverUnlock(driver); return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index a7566f4..d7ad97f 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -788,19 +788,6 @@ qemuMigrationProcessJobSignals(struct qemud_driver *driver, } if (ret 0) VIR_WARN(Unable to set migration downtime); -} else if (priv-job.signals QEMU_JOB_SIGNAL_MIGRATE_SPEED) { -unsigned long bandwidth = priv-job.signalsData.migrateBandwidth; - -priv-job.signals ^= QEMU_JOB_SIGNAL_MIGRATE_SPEED; -priv-job.signalsData.migrateBandwidth = 0; -VIR_DEBUG(Setting migration bandwidth to %luMbs, bandwidth); -ret = qemuDomainObjEnterMonitorWithDriver(driver, vm); -if (ret == 0) { -ret = qemuMonitorSetMigrationSpeed(priv-mon, bandwidth); -qemuDomainObjExitMonitorWithDriver(driver, vm); -} -if (ret 0) -VIR_WARN(Unable to set migration speed); } else { ret = 0; } @@ -2823,10 +2810,12 @@ qemuMigrationJobStart(struct qemud_driver *driver, if
[libvirt] [PATCH 14/19] qemu: Remove special case for virDomainGetBlockInfo
Like other query commands, this can now be called directly during migration. --- src/qemu/qemu_domain.h|4 src/qemu/qemu_driver.c| 42 -- src/qemu/qemu_migration.c | 14 -- 3 files changed, 12 insertions(+), 48 deletions(-) diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 387c64c..0958bf2 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -71,7 +71,6 @@ enum qemuDomainJobSignals { QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME = 1 2, /* Request migration downtime change */ QEMU_JOB_SIGNAL_MIGRATE_SPEED = 1 3, /* Request migration speed change */ QEMU_JOB_SIGNAL_BLKSTAT = 1 4, /* Request blkstat during migration */ -QEMU_JOB_SIGNAL_BLKINFO = 1 5, /* Request blkinfo during migration */ }; struct qemuDomainJobSignalsData { @@ -80,9 +79,6 @@ struct qemuDomainJobSignalsData { char *statDevName; /* Device name used by blkstat calls */ virDomainBlockStatsPtr blockStat; /* Block statistics for QEMU_JOB_SIGNAL_BLKSTAT */ int *statRetCode; /* Return code for the blkstat calls */ -char *infoDevName; /* Device name used by blkinfo calls */ -virDomainBlockInfoPtr blockInfo; /* Block information for QEMU_JOB_SIGNAL_BLKINFO */ -int *infoRetCode; /* Return code for the blkinfo calls */ }; struct qemuDomainJobObj { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e317c5b..76dfbd8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6455,39 +6455,21 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom, virDomainObjIsActive(vm)) { qemuDomainObjPrivatePtr priv = vm-privateData; -if ((priv-job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) -|| (priv-job.asyncJob == QEMU_ASYNC_JOB_SAVE)) { -virDomainObjRef(vm); -while (priv-job.signals QEMU_JOB_SIGNAL_BLKINFO) -ignore_value(virCondWait(priv-job.signalCond, vm-lock)); - -priv-job.signalsData.infoDevName = disk-info.alias; -priv-job.signalsData.blockInfo = info; -priv-job.signalsData.infoRetCode = ret; -priv-job.signals |= QEMU_JOB_SIGNAL_BLKINFO; - -while (priv-job.signals QEMU_JOB_SIGNAL_BLKINFO) -ignore_value(virCondWait(priv-job.signalCond, vm-lock)); +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) 0) +goto cleanup; -if (virDomainObjUnref(vm) == 0) -vm = NULL; +if (virDomainObjIsActive(vm)) { +ignore_value(qemuDomainObjEnterMonitor(driver, vm)); +ret = qemuMonitorGetBlockExtent(priv-mon, +disk-info.alias, +info-allocation); +qemuDomainObjExitMonitor(driver, vm); } else { -if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) 0) -goto cleanup; - -if (virDomainObjIsActive(vm)) { -ignore_value(qemuDomainObjEnterMonitor(driver, vm)); -ret = qemuMonitorGetBlockExtent(priv-mon, -disk-info.alias, -info-allocation); -qemuDomainObjExitMonitor(driver, vm); -} else { -ret = 0; -} - -if (qemuDomainObjEndJob(driver, vm) == 0) -vm = NULL; +ret = 0; } + +if (qemuDomainObjEndJob(driver, vm) == 0) +vm = NULL; } else { ret = 0; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index bcca454..8a14d2e 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -819,20 +819,6 @@ qemuMigrationProcessJobSignals(struct qemud_driver *driver, if (ret 0) VIR_WARN(Unable to get block statistics); -} else if (priv-job.signals QEMU_JOB_SIGNAL_BLKINFO) { -ret = qemuDomainObjEnterMonitorWithDriver(driver, vm); -if (ret == 0) { -ret = qemuMonitorGetBlockExtent(priv-mon, - priv-job.signalsData.infoDevName, - priv-job.signalsData.blockInfo-allocation); -qemuDomainObjExitMonitorWithDriver(driver, vm); -} - -*priv-job.signalsData.infoRetCode = ret; -priv-job.signals ^= QEMU_JOB_SIGNAL_BLKINFO; - -if (ret 0) -VIR_WARN(Unable to get block information); } else { ret = 0; } -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 15/19] qemu: Remove special case for virDomainBlockStats
Like other query commands, this can now be called directly during migration. --- src/qemu/qemu_domain.h|4 --- src/qemu/qemu_driver.c| 54 +++-- src/qemu/qemu_migration.c | 18 --- 3 files changed, 18 insertions(+), 58 deletions(-) diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 0958bf2..c2ad456 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -70,15 +70,11 @@ enum qemuDomainJobSignals { QEMU_JOB_SIGNAL_SUSPEND = 1 1, /* Request VM suspend to finish live migration offline */ QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME = 1 2, /* Request migration downtime change */ QEMU_JOB_SIGNAL_MIGRATE_SPEED = 1 3, /* Request migration speed change */ -QEMU_JOB_SIGNAL_BLKSTAT = 1 4, /* Request blkstat during migration */ }; struct qemuDomainJobSignalsData { unsigned long long migrateDowntime; /* Data for QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME */ unsigned long migrateBandwidth; /* Data for QEMU_JOB_SIGNAL_MIGRATE_SPEED */ -char *statDevName; /* Device name used by blkstat calls */ -virDomainBlockStatsPtr blockStat; /* Block statistics for QEMU_JOB_SIGNAL_BLKSTAT */ -int *statRetCode; /* Return code for the blkstat calls */ }; struct qemuDomainJobObj { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 76dfbd8..cd64f85 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6008,46 +6008,28 @@ qemudDomainBlockStats (virDomainPtr dom, } priv = vm-privateData; -if ((priv-job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) -|| (priv-job.asyncJob == QEMU_ASYNC_JOB_SAVE)) { -virDomainObjRef(vm); -while (priv-job.signals QEMU_JOB_SIGNAL_BLKSTAT) -ignore_value(virCondWait(priv-job.signalCond, vm-lock)); - -priv-job.signalsData.statDevName = disk-info.alias; -priv-job.signalsData.blockStat = stats; -priv-job.signalsData.statRetCode = ret; -priv-job.signals |= QEMU_JOB_SIGNAL_BLKSTAT; - -while (priv-job.signals QEMU_JOB_SIGNAL_BLKSTAT) -ignore_value(virCondWait(priv-job.signalCond, vm-lock)); - -if (virDomainObjUnref(vm) == 0) -vm = NULL; -} else { -if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) 0) -goto cleanup; +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) 0) +goto cleanup; -if (!virDomainObjIsActive(vm)) { -qemuReportError(VIR_ERR_OPERATION_INVALID, -%s, _(domain is not running)); -goto endjob; -} +if (!virDomainObjIsActive(vm)) { +qemuReportError(VIR_ERR_OPERATION_INVALID, +%s, _(domain is not running)); +goto endjob; +} -ignore_value(qemuDomainObjEnterMonitor(driver, vm)); -ret = qemuMonitorGetBlockStatsInfo(priv-mon, - disk-info.alias, - stats-rd_req, - stats-rd_bytes, - stats-wr_req, - stats-wr_bytes, - stats-errs); -qemuDomainObjExitMonitor(driver, vm); +ignore_value(qemuDomainObjEnterMonitor(driver, vm)); +ret = qemuMonitorGetBlockStatsInfo(priv-mon, + disk-info.alias, + stats-rd_req, + stats-rd_bytes, + stats-wr_req, + stats-wr_bytes, + stats-errs); +qemuDomainObjExitMonitor(driver, vm); endjob: -if (qemuDomainObjEndJob(driver, vm) == 0) -vm = NULL; -} +if (qemuDomainObjEndJob(driver, vm) == 0) +vm = NULL; cleanup: if (vm) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 8a14d2e..a7566f4 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -801,24 +801,6 @@ qemuMigrationProcessJobSignals(struct qemud_driver *driver, } if (ret 0) VIR_WARN(Unable to set migration speed); -} else if (priv-job.signals QEMU_JOB_SIGNAL_BLKSTAT) { -ret = qemuDomainObjEnterMonitorWithDriver(driver, vm); -if (ret == 0) { -ret = qemuMonitorGetBlockStatsInfo(priv-mon, - priv-job.signalsData.statDevName, - priv-job.signalsData.blockStat-rd_req, - priv-job.signalsData.blockStat-rd_bytes, - priv-job.signalsData.blockStat-wr_req, - priv-job.signalsData.blockStat-wr_bytes, - priv-job.signalsData.blockStat-errs); -
[libvirt] [PATCH 18/19] qemu: Remove special case for virDomainSuspend
--- src/qemu/qemu_domain.h|1 - src/qemu/qemu_driver.c| 46 ++-- src/qemu/qemu_migration.c |6 + 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 71cefd9..3da7931 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -68,7 +68,6 @@ enum qemuDomainAsyncJob { enum qemuDomainJobSignals { QEMU_JOB_SIGNAL_CANCEL = 1 0, /* Request job cancellation */ -QEMU_JOB_SIGNAL_SUSPEND = 1 1, /* Request VM suspend to finish live migration offline */ }; struct qemuDomainJobObj { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d62e99d..8b186f7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1319,6 +1319,8 @@ static int qemudDomainSuspend(virDomainPtr dom) { int ret = -1; virDomainEventPtr event = NULL; qemuDomainObjPrivatePtr priv; +virDomainPausedReason reason; +int eventDetail; qemuDriverLock(driver); vm = virDomainFindByUUID(driver-domains, dom-uuid); @@ -1345,34 +1347,32 @@ static int qemudDomainSuspend(virDomainPtr dom) { priv = vm-privateData; if (priv-job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) { -if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { -VIR_DEBUG(Requesting domain pause on %s, - vm-def-name); -priv-job.signals |= QEMU_JOB_SIGNAL_SUSPEND; -} -ret = 0; -goto cleanup; +reason = VIR_DOMAIN_PAUSED_MIGRATION; +eventDetail = VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED; } else { -if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_SUSPEND) 0) -goto cleanup; +reason = VIR_DOMAIN_PAUSED_USER; +eventDetail = VIR_DOMAIN_EVENT_SUSPENDED_PAUSED; +} -if (!virDomainObjIsActive(vm)) { -qemuReportError(VIR_ERR_OPERATION_INVALID, -%s, _(domain is not running)); +if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_SUSPEND) 0) +goto cleanup; + +if (!virDomainObjIsActive(vm)) { +qemuReportError(VIR_ERR_OPERATION_INVALID, +%s, _(domain is not running)); +goto endjob; +} +if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { +if (qemuProcessStopCPUs(driver, vm, reason) 0) { goto endjob; } -if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { -if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_USER) 0) { -goto endjob; -} -event = virDomainEventNewFromObj(vm, - VIR_DOMAIN_EVENT_SUSPENDED, - VIR_DOMAIN_EVENT_SUSPENDED_PAUSED); -} -if (virDomainSaveStatus(driver-caps, driver-stateDir, vm) 0) -goto endjob; -ret = 0; +event = virDomainEventNewFromObj(vm, + VIR_DOMAIN_EVENT_SUSPENDED, + eventDetail); } +if (virDomainSaveStatus(driver-caps, driver-stateDir, vm) 0) +goto endjob; +ret = 0; endjob: if (qemuDomainObjEndJob(driver, vm) == 0) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index ee2c5a0..de00811 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -770,11 +770,6 @@ qemuMigrationProcessJobSignals(struct qemud_driver *driver, if (ret 0) { VIR_WARN(Unable to cancel job); } -} else if (priv-job.signals QEMU_JOB_SIGNAL_SUSPEND) { -priv-job.signals ^= QEMU_JOB_SIGNAL_SUSPEND; -VIR_DEBUG(Pausing domain for non-live migration); -if (qemuMigrationSetOffline(driver, vm) 0) -VIR_WARN(Unable to pause domain); } else { ret = 0; } @@ -2801,6 +2796,7 @@ qemuMigrationJobStart(struct qemud_driver *driver, qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE); } else { qemuDomainObjSetAsyncJobMask(vm, DEFAULT_JOB_MASK | + JOB_MASK(QEMU_JOB_SUSPEND) | JOB_MASK(QEMU_JOB_MIGRATION_OP)); } -- 1.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Skip some xen tests if xend is not running
Eric Blake wrote: On 07/07/2011 04:00 PM, Jim Fehlig wrote: Currently, the xen statstest and reconnect tests are only compiled if xend is running. Compile them unconditionally if xen headers are present, but skip the tests at runtime if xend is not running. This is in response to Eric's suggestion here https://www.redhat.com/archives/libvir-list/2011-July/msg00367.html --- configure.ac | 24 tests/Makefile.am | 12 tests/reconnect.c | 11 +++ tests/statstest.c | 12 4 files changed, 27 insertions(+), 32 deletions(-) Nice - it removes more lines than it adds, while still improving compilation coverage! + +/* skip test if xend is not running */ +cmd = virCommandNewArgList(/usr/sbin/xend, status, NULL); +if (virCommandRun(cmd, status) == 0 status != 0) { If we fail to run the command for external reasons (such as no /usr/sbin/xend binary, or the status command was killed by a signal instead of a normal exit), we probably still want to skip this test. How about this (in both tests): if (virCommandRun(cmd, status) != 0 || status != 0) { +virCommandFree(cmd); +return 77; I forget we had a macro to avoid the magic number: s/77/EXIT_AM_SKIP/ +} +virCommandFree(cmd); + /* Some of our tests delibrately test failure cases, so Hmm, while you're touching this, how about s/delibrately/deliberately/ ACK with those changes. I've pushed this with your suggestions. Oh, and our testsuite has a cosmetic bug. After applying your patch, I see this during 'make check': TEST: xencapstest .. 10 OK PASS: xencapstest SKIP: reconnect TEST: statstest 0 FAIL SKIP: statstest Bonus points for fixing up that output to say SKIP instead of FAIL and to align it correctly (but that can be a separate patch). I'll look into it. Thanks, Jim -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 19/19] qemu: Remove special case for virDomainAbortJob
This doesn't abort migration job in any phase, yet. --- src/qemu/qemu_domain.c|9 +--- src/qemu/qemu_domain.h| 14 src/qemu/qemu_driver.c| 36 ++--- src/qemu/qemu_migration.c | 48 - src/qemu/qemu_process.c | 12 +- 5 files changed, 40 insertions(+), 79 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index deaf9fd..7e43238 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -52,6 +52,7 @@ VIR_ENUM_IMPL(qemuDomainJob, QEMU_JOB_LAST, destroy, suspend, modify, + abort, migration operation, none, /* async job is never stored in job.active */ async nested, @@ -158,12 +159,6 @@ qemuDomainObjInitJob(qemuDomainObjPrivatePtr priv) return -1; } -if (virCondInit(priv-job.signalCond) 0) { -ignore_value(virCondDestroy(priv-job.cond)); -ignore_value(virCondDestroy(priv-job.asyncCond)); -return -1; -} - return 0; } @@ -185,7 +180,6 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) job-mask = DEFAULT_JOB_MASK; job-start = 0; memset(job-info, 0, sizeof(job-info)); -job-signals = 0; } void @@ -208,7 +202,6 @@ qemuDomainObjFreeJob(qemuDomainObjPrivatePtr priv) { ignore_value(virCondDestroy(priv-job.cond)); ignore_value(virCondDestroy(priv-job.asyncCond)); -ignore_value(virCondDestroy(priv-job.signalCond)); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 3da7931..234acab 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -31,8 +31,10 @@ # include bitmap.h #define JOB_MASK(job) (1 (job - 1)) -#define DEFAULT_JOB_MASK\ -(JOB_MASK(QEMU_JOB_QUERY) | JOB_MASK(QEMU_JOB_DESTROY)) +#define DEFAULT_JOB_MASK\ +(JOB_MASK(QEMU_JOB_QUERY) | \ + JOB_MASK(QEMU_JOB_DESTROY) | \ + JOB_MASK(QEMU_JOB_ABORT)) /* Only 1 job is allowed at any time * A job includes *all* monitor commands, even those just querying @@ -43,6 +45,7 @@ enum qemuDomainJob { QEMU_JOB_DESTROY, /* Destroys the domain (cannot be masked out) */ QEMU_JOB_SUSPEND, /* Suspends (stops vCPUs) the domain */ QEMU_JOB_MODIFY,/* May change state */ +QEMU_JOB_ABORT, /* Abort current async job */ QEMU_JOB_MIGRATION_OP, /* Operation influencing outgoing migration */ /* The following two items must always be the last items before JOB_LAST */ @@ -66,10 +69,6 @@ enum qemuDomainAsyncJob { QEMU_ASYNC_JOB_LAST }; -enum qemuDomainJobSignals { -QEMU_JOB_SIGNAL_CANCEL = 1 0, /* Request job cancellation */ -}; - struct qemuDomainJobObj { virCond cond; /* Use to coordinate jobs */ enum qemuDomainJob active; /* Currently running job */ @@ -80,9 +79,6 @@ struct qemuDomainJobObj { unsigned long long mask;/* Jobs allowed during async job */ unsigned long long start; /* When the async job started */ virDomainJobInfo info; /* Async job progress data */ - -virCond signalCond; /* Use to coordinate the safe queries during migration */ -unsigned int signals; /* Signals for running job */ }; typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8b186f7..6fd6019 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7343,24 +7343,36 @@ static int qemuDomainAbortJob(virDomainPtr dom) { goto cleanup; } -priv = vm-privateData; +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_ABORT) 0) +goto cleanup; if (virDomainObjIsActive(vm)) { -if (priv-job.asyncJob) { -VIR_DEBUG(Requesting cancellation of job on vm %s, vm-def-name); -priv-job.signals |= QEMU_JOB_SIGNAL_CANCEL; -} else { -qemuReportError(VIR_ERR_OPERATION_INVALID, -%s, _(no job is active on the domain)); -goto cleanup; -} -} else { qemuReportError(VIR_ERR_OPERATION_INVALID, %s, _(domain is not running)); -goto cleanup; +goto endjob; } -ret = 0; +priv = vm-privateData; + +if (!priv-job.asyncJob) { +qemuReportError(VIR_ERR_OPERATION_INVALID, +%s, _(no job is active on the domain)); +goto endjob; +} else if (priv-job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) { +qemuReportError(VIR_ERR_OPERATION_INVALID, %s, +_(cannot abort incoming migration; + use virDomainDestroy instead)); +goto endjob; +} + +VIR_DEBUG(Cancelling job at client request); +
Re: [libvirt] [PATCH V2] Do not drop kernel cmdline for xen pv domains
Jim Fehlig wrote: Kernel cmdline args can be passed to xen pv domains even when a bootloader is specified. The current config-to-sxpr mapping ignores cmdline when bootloader is present. Since the xend sub-driver is used with many xen toolstack versions, this patch takes conservative approach of adding an else block to existing !def-os.bootloader, and only appends sxpr if def-os.cmdline is non-NULL. V2: Fix existing testcase broken by this patch and add new testcases Hmm, now domainschematest is failing --- src/xenxs/xen_sxpr.c |6 .../sexpr2xml-pv-bootloader-cmdline.sexpr |5 +++ .../sexpr2xml-pv-bootloader-cmdline.xml| 27 tests/sexpr2xmltest.c |1 + .../xml2sexpr-disk-block-shareable.sexpr |1 + .../xml2sexpr-pv-bootloader-cmdline.sexpr |5 +++ .../xml2sexpr-pv-bootloader-cmdline.xml| 22 tests/xml2sexprtest.c |1 + 8 files changed, 68 insertions(+), 0 deletions(-) create mode 100644 tests/sexpr2xmldata/sexpr2xml-pv-bootloader-cmdline.sexpr create mode 100644 tests/sexpr2xmldata/sexpr2xml-pv-bootloader-cmdline.xml create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-bootloader-cmdline.sexpr create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-bootloader-cmdline.xml on these two xml files. If I'm reading domain.rng correctly, kernel must be specified?? Can it be optional like initrd and cmdline? Regards, Jim diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c index 13ca015..bd770bc 100644 --- a/src/xenxs/xen_sxpr.c +++ b/src/xenxs/xen_sxpr.c @@ -2261,6 +2261,12 @@ xenFormatSxpr(virConnectPtr conn, } virBufferAddLit(buf, ))); +} else { +/* PV domains accept kernel cmdline args */ +if (def-os.cmdline) { +virBufferEscapeSexpr(buf, (image (linux (args '%s'))), + def-os.cmdline); +} } for (i = 0 ; i def-ndisks ; i++) diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-bootloader-cmdline.sexpr b/tests/sexpr2xmldata/sexpr2xml-pv-bootloader-cmdline.sexpr new file mode 100644 index 000..dde37fc --- /dev/null +++ b/tests/sexpr2xmldata/sexpr2xml-pv-bootloader-cmdline.sexpr @@ -0,0 +1,5 @@ +(domain (domid 6)(name 'pvtest')(memory 420)(maxmem 420)(vcpus 2)\ +(uuid '596a5d2171f48fb2e068e2386a5c413e')(bootloader '/usr/bin/pygrub')\ +(bootloader_args '-q')(image (linux (args ' xenfb.video=8,1280,1024 ')))\ +(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')\ +(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w' diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-bootloader-cmdline.xml b/tests/sexpr2xmldata/sexpr2xml-pv-bootloader-cmdline.xml new file mode 100644 index 000..7bc99d8 --- /dev/null +++ b/tests/sexpr2xmldata/sexpr2xml-pv-bootloader-cmdline.xml @@ -0,0 +1,27 @@ +domain type='xen' id='6' + namepvtest/name + uuid596a5d21-71f4-8fb2-e068-e2386a5c413e/uuid + memory430080/memory + currentMemory430080/currentMemory + vcpu2/vcpu + bootloader/usr/bin/pygrub/bootloader + bootloader_args-q/bootloader_args + os +typelinux/type +cmdline xenfb.video=8,1280,1024 /cmdline + /os + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootdestroy/on_reboot + on_crashdestroy/on_crash + devices +disk type='file' device='disk' + driver name='file'/ + source file='/root/some.img'/ + target dev='xvda' bus='xen'/ +/disk +console type='pty' + target type='xen' port='0'/ +/console + /devices +/domain diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c index f393935..26a987d 100644 --- a/tests/sexpr2xmltest.c +++ b/tests/sexpr2xmltest.c @@ -134,6 +134,7 @@ mymain(void) DO_TEST(pv-vfb-type-crash, pv-vfb-type-crash, 3); DO_TEST(fv-autoport, fv-autoport, 3); DO_TEST(pv-bootloader, pv-bootloader, 1); +DO_TEST(pv-bootloader-cmdline, pv-bootloader-cmdline, 1); DO_TEST(pv-vcpus, pv-vcpus, 1); DO_TEST(disk-file, disk-file, 2); diff --git a/tests/xml2sexprdata/xml2sexpr-disk-block-shareable.sexpr b/tests/xml2sexprdata/xml2sexpr-disk-block-shareable.sexpr index 8c0b1cd..b8387e5 100644 --- a/tests/xml2sexprdata/xml2sexpr-disk-block-shareable.sexpr +++ b/tests/xml2sexprdata/xml2sexpr-disk-block-shareable.sexpr @@ -1,6 +1,7 @@ (vm (name 'pvtest')(memory 384)(maxmem 512)(vcpus 1)\ (uuid '49a0c6ff-c066-5392-6498-3632d093c2e7')(bootloader '/usr/bin/pygrub')\ (on_poweroff 'destroy')(on_reboot 'restart')(on_crash 'restart')\ +(image (linux (args 'ro root=/dev/VolGroup00/LogVol00')))\ (device (tap (dev 'xvda')(uname 'tap:aio:/var/lib/xen/images/rhel5pv.img')\ (mode 'w!')))(device (vif (mac '00:16:3e:23:9e:eb')(bridge 'xenbr0')\ (script 'vif-bridge'\ diff --git
Re: [libvirt] [PATCH 1/1] microblaze: Add architecture support
On 07/06/2011 08:45 PM, John Williams wrote: Add libvirt support for MicroBlaze architecture as a QEMU target. Based on mips/mipsel pattern. Signed-off-by: John Williams john.willi...@petalogix.com --- docs/drvqemu.html.in |2 ++ docs/schemas/capability.rng |2 ++ examples/apparmor/libvirt-qemu |4 src/qemu/qemu_capabilities.c |2 ++ tests/capabilityschemadata/caps-qemu-kvm.xml | 24 5 files changed, 34 insertions(+), 0 deletions(-) ACK and pushed. I added you to AUTHORS; let me know if I need to adjust anything for preferred spelling. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/1] microblaze: Add architecture support
On Fri, Jul 8, 2011 at 9:50 AM, Eric Blake ebl...@redhat.com wrote: On 07/06/2011 08:45 PM, John Williams wrote: Add libvirt support for MicroBlaze architecture as a QEMU target. Based on mips/mipsel pattern. ACK and pushed. I added you to AUTHORS; let me know if I need to adjust anything for preferred spelling. All good, thanks for the quick response. John -- John Williams, PhD, B. Eng, B. IT PetaLogix - Linux Solutions for a Reconfigurable World w: www.petalogix.com p: +61-7-30090663 f: +61-7-30090663 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list