Re: [libvirt] Does libvirt support spice agent-mouse?
On 2012年02月28日 16:30, Zhou Peng wrote: Hi all, How to set the qemu-kvm argv agent-mouse=on/off option in libvirt xml file pls? It's not yet supported, as an alternative way, you can use qemu:commandline instead temporarily. There is example here: http://libvirt.org/drvqemu.html [Pass-through of arbitrary qemu commands] We're looking forward to add the support soon though. Regards, Osier -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-TCK][PATCH] use 'raw' format as the format of backing file of qcow2 image
If we don't explicitly specify the format of backing file, it should use raw by default, if so, libvirt's security drivers should *not* grant access to the last.img file the guest should not see the last.img data. That is the purpose of testing. --- scripts/qemu/205-qcow2-double-backing-file.t |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/scripts/qemu/205-qcow2-double-backing-file.t b/scripts/qemu/205-qcow2-double-backing-file.t index d3a5e33..ad54c7c 100644 --- a/scripts/qemu/205-qcow2-double-backing-file.t +++ b/scripts/qemu/205-qcow2-double-backing-file.t @@ -114,7 +114,6 @@ SKIP: { my $volmainxml = $tck-generic_volume(tck-main, qcow2, 1024*1024*50) -backing_file($pathback) - -backing_format(qcow2) -allocation(0)-as_xml; -- 1.7.7.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv4 0/3] Xen: Fix clock handling
Hello, On Tuesday 14 February 2012 19:07:21 Philipp Hahn wrote: Before version 3.1 xen only implemented clock/@offset='utc' and 'localtime'. With the introduction of managed domains in 3.1 xend keeps track of the rtc_timeoffset, even over reboots. This translates to libvirts clock/@offset='variable' variant. Be advised that only HV domains have a RTC. In addition xen also supports a variant where the offset is tracked to 'localtime', which is currently not supported by libvirt. To make matters worse, this was somehow broken in some versions of xen and was finally fixed with version xen-3.4. The following patch set ... * adds support for handling variable offsets relative to localtime, * fixes libvirt to use clock/@offset='variable' for newer xen versions, * adapts the test suit accordingly I've tested this on CenOS5 (xend-3.0.3 + 3.1.2 hypervisor?), UCS-2.3 (xen-3.2.1), UCS-2.4 (xen-3.4.3) and UCS-3.0 (xen-4.1.2). Ping? Since v1: + fix handling of direct-PV-domains + added handling of localtime=1 + rtc_timeoffset + fixed test suite Since v2: (on feedback by Eric) + add the adjustment='reset' attribute to force the old behaviour + handle adjustment='$timeDelta' as a short-cut for the conversion to variable. + simplify error path handling + update version numbers to 0.9.11 Since v3: + Add missing offset=VARIALE for adjustment='$timeDelta' conversion. Philipp Hahn (3): Support clock=variable relative to localtime Xen: Fix clock handling Xen: Adapt clock tests @Eric: If I understood your proposal right, v4 should implement your transition path for xen. In our local tests it worked okay. Sincerely Philipp -- Philipp Hahn Open Source Software Engineer h...@univention.de Univention GmbHLinux for Your Businessfon: +49 421 22 232- 0 Mary-Somerville-Str.1 D-28359 Bremen fax: +49 421 22 232-99 http://www.univention.de/ signature.asc Description: This is a digitally signed message part. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: fix cleanup of bridge during failure of qemuDomainAttachNetDevice
On 02/27/2012 01:15 PM, Eric Blake wrote: On 02/25/2012 04:40 PM, Laine Stump wrote: From: Laine Stump la...@redhat.com In qemuDomainAttachNetDevice, the guest's tap interface has only been attached to the bridge if iface_connected is true. It's possible for an error to occur prior to that happening, and previously we would attempt to remove the tap interface from the bridge even if it hadn't been attached. --- src/qemu/qemu_hotplug.c | 11 ++- 1 files changed, 6 insertions(+), 5 deletions(-) ACK - looks like the patch was just the addition of {} followed by reindentation. Correct - just moved the next stanza into the if. Pushed, thanks! -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] libxl: eliminate memory leak in libxmlDomainModifyDeviceFlags
On 02/27/2012 01:11 PM, Eric Blake wrote: On 02/27/2012 04:01 AM, Laine Stump wrote: I found this randomly by examination when a tag search led me to this file. I don't have a setup to test it, but it appears fairly obvious that this call to virDomainDeviceDefParse is both unnecessary (since it will again be called at the top of the immediately following if(), and if not there, then at the top of the if following that), but it also creates a leak of one virDomainDeviceDef and one [whatever type of device the DeviceDef is pointing to; probably a virDomainDiskDef] in the case that the function has been called with VIR_DOMAIN_DEVICE_MODIFY_CONFIG (the second parse will overwrite the devicedef that was just created). --- src/libxl/libxl_driver.c |4 1 files changed, 0 insertions(+), 4 deletions(-) ACK. Pushed. Thanks! -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] libvirt TCK wrapper for autotest review
On 02/24/2012 07:50 PM, Lucas Meneghel Rodrigues wrote: On 02/23/2012 12:27 PM, Guannan Ren wrote: Hi Lucas, Thanks for your these good modifications. There is one place I noticed where you output each testcase of *.t into a separate file with .tap extension. hence, it has a corresponding log file with little content for each testcase. it seem a little harder to check compared to just one log file. The rest of them is perfect for me. Guannan Ren Thanks! Now, feel free to pick this up and modify as you wish, then send me as a pull request/patch to the mailing list. I'll close the example pull request and will be waiting on you, ok? Cheers, Lucas That's ok, after I make some modification, I send the patch, thanks. Guannan Ren -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: Don't emit tls-port spice option if port is -1
Bug introduced by commit eda0fc7a. --- src/qemu/qemu_command.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 01adf0d..5e0ca95 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5345,13 +5345,16 @@ qemuBuildCommandLine(virConnectPtr conn, virBufferAsprintf(opt, port=%u, def-graphics[0]-data.spice.port); -if (def-graphics[0]-data.spice.tlsPort != -1) +if (def-graphics[0]-data.spice.tlsPort != -1) { if (!driver-spiceTLS) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, -_(spice TLS port set in XML configuration, but TLS is disabled in qemu.conf)); +_(spice TLS port set in XML configuration, + but TLS is disabled in qemu.conf)); goto error; } -virBufferAsprintf(opt, ,tls-port=%u, def-graphics[0]-data.spice.tlsPort); +virBufferAsprintf(opt, ,tls-port=%u, + def-graphics[0]-data.spice.tlsPort); +} switch (virDomainGraphicsListenGetType(def-graphics[0], 0)) { case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: -- 1.7.8.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Don't emit tls-port spice option if port is -1
On Tue, Feb 28, 2012 at 02:16:56PM +0100, Jiri Denemark wrote: Bug introduced by commit eda0fc7a. --- src/qemu/qemu_command.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 01adf0d..5e0ca95 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5345,13 +5345,16 @@ qemuBuildCommandLine(virConnectPtr conn, virBufferAsprintf(opt, port=%u, def-graphics[0]-data.spice.port); -if (def-graphics[0]-data.spice.tlsPort != -1) +if (def-graphics[0]-data.spice.tlsPort != -1) { if (!driver-spiceTLS) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, -_(spice TLS port set in XML configuration, but TLS is disabled in qemu.conf)); +_(spice TLS port set in XML configuration, + but TLS is disabled in qemu.conf)); goto error; } -virBufferAsprintf(opt, ,tls-port=%u, def-graphics[0]-data.spice.tlsPort); +virBufferAsprintf(opt, ,tls-port=%u, + def-graphics[0]-data.spice.tlsPort); +} switch (virDomainGraphicsListenGetType(def-graphics[0], 0)) { case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: Is it possible to get this checked by the test cases, so we don't risk messing it up again ? 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
[libvirt] [PATCH RFC]: Support numad
numad is an user-level daemon that monitors NUMA topology and processes resource consumption to facilitate good NUMA resource alignment of applications/virtual machines to improve performance and minimize cost of remote memory latencies. It provides a pre-placement advisory interface, so significant processes can be pre-bound to nodes with sufficient available resources. More details: http://fedoraproject.org/wiki/Features/numad numad -w ncpus:memory_amount is the advisory interface numad provides currently. This patch add the support by introducing new XML like: numatune cpu required_cpus=4 required_memory=524288/ /numatune And the corresponding numad command line will be: numad -w 4:500 The advisory nodeset returned from numad will be used to set domain process CPU affinity then. (e.g. qemuProcessInitCpuAffinity). If the user specifies both CPU affinity policy (e.g. (vcpu cpuset=1-10,^7,^84/vcpu) and XML indicating to use numad for the advisory nodeset, the specified CPU affinity will be overridden by the nodeset returned from numad. If no XML to specify the CPU affinity policy, and XML indicating to use numad is specified, the returned nodeset will be printed in cpu cpuset=$nodeset_from_numad/4/vcpu. Only QEMU/KVM and LXC drivers support it now. --- configure.ac |8 +++ docs/formatdomain.html.in | 18 ++- docs/schemas/domaincommon.rng | 12 src/conf/domain_conf.c| 125 +++-- src/conf/domain_conf.h|5 ++ src/lxc/lxc_controller.c | 98 src/qemu/qemu_process.c | 99 + 7 files changed, 311 insertions(+), 54 deletions(-) diff --git a/configure.ac b/configure.ac index c9cdd7b..31f0835 100644 --- a/configure.ac +++ b/configure.ac @@ -1445,6 +1445,14 @@ AM_CONDITIONAL([HAVE_NUMACTL], [test $with_numactl != no]) AC_SUBST([NUMACTL_CFLAGS]) AC_SUBST([NUMACTL_LIBS]) +dnl Do we have numad? +if test $with_qemu = yes; then +AC_PATH_PROG([NUMAD], [numad], [], [/bin:/usr/bin:/usr/local/bin:$PATH]) + +if test -n $NUMAD; then +AC_DEFINE_UNQUOTED([NUMAD],[$NUMAD], [Location or name of the numad program]) +fi +fi dnl pcap lib LIBPCAP_CONFIG=pcap-config diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 6fcca94..d8e70a6 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -505,6 +505,7 @@ ... lt;numatunegt; lt;memory mode=strict nodeset=1-4,^3/gt; +lt;cpu required_cpus=3 required_memory=524288/gt; lt;/numatunegt; ... lt;/domaingt; @@ -519,7 +520,7 @@ span class='since'Since 0.9.3/span dtcodememory/code/dt dd -The optional codememory/code element specify how to allocate memory +The optional codememory/code element specifies how to allocate memory for the domain process on a NUMA host. It contains two attributes, attribute codemode/code is either 'interleave', 'strict', or 'preferred', @@ -527,6 +528,21 @@ syntax with attribute codecpuset/code of element codevcpu/code. span class='since'Since 0.9.3/span /dd + dd +The optional codecpu/code element indicates pinning the virtual CPUs +to the nodeset returned by querying numad (a system daemon that monitors +NUMA topology and usage). It has two attributes, attribute +coderequired_cpus/code specifies the number of physical CPUs the guest +process want to use. And the optional attribute coderequired_memory/code +specifies the amount of free memory the guest process want to see on a node, +numad will pick the physical CPUs on the node which has enough free +memory of amount specified by coderequired_memory/code. + +NB, with using this element, the physical CPUs specified by attribute +codecpuset/code (of element codevcpu/code) will be overridden by the +nodeset returned from numad. +span class='since'Since 0.9.11 (QEMU/KVM and LXC only)/span + /dd /dl diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 3908733..d0f443d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -549,6 +549,18 @@ /attribute /element /optional + optional +element name=cpu + attribute name=required_cpu +ref name=countCPU/ + /attribute + optional +attribute name=required_memory + ref name=memoryKB/ +/attribute + /optional +/element + /optional /element /optional /interleave diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f9654f1..aa03c05 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7125,7 +7125,6 @@
Re: [libvirt] [PATCH] qemu: Don't emit tls-port spice option if port is -1
On Tue, Feb 28, 2012 at 13:21:21 +, Daniel P. Berrange wrote: On Tue, Feb 28, 2012 at 02:16:56PM +0100, Jiri Denemark wrote: Bug introduced by commit eda0fc7a. --- src/qemu/qemu_command.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 01adf0d..5e0ca95 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5345,13 +5345,16 @@ qemuBuildCommandLine(virConnectPtr conn, virBufferAsprintf(opt, port=%u, def-graphics[0]-data.spice.port); -if (def-graphics[0]-data.spice.tlsPort != -1) +if (def-graphics[0]-data.spice.tlsPort != -1) { if (!driver-spiceTLS) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, -_(spice TLS port set in XML configuration, but TLS is disabled in qemu.conf)); +_(spice TLS port set in XML configuration, + but TLS is disabled in qemu.conf)); goto error; } -virBufferAsprintf(opt, ,tls-port=%u, def-graphics[0]-data.spice.tlsPort); +virBufferAsprintf(opt, ,tls-port=%u, + def-graphics[0]-data.spice.tlsPort); +} switch (virDomainGraphicsListenGetType(def-graphics[0], 0)) { case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: Is it possible to get this checked by the test cases, so we don't risk messing it up again ? Possibly, although it won't save us from forgetting to add {} if we expand the body of such statements anywhere else in the code. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/1] complete netlink event integration
From: D. Herrendoerfer d.herrendoer...@herrendoerfer.name this patch adds the changes proposed by Laine Stump to netlink event code. Signed-off-by: D. Herrendoerfer d.herrendoer...@herrendoerfer.name --- src/util/virnetdevmacvlan.c | 47 +- src/util/virnetlink.c | 13 ++- src/util/virnetlink.h |7 - 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index 4256349..155ce79 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -448,7 +448,7 @@ static const uint32_t modeMap[VIR_NETDEV_MACVLAN_MODE_LAST] = { /* Struct to hold the state and configuration of a 802.1qbg port */ struct virNetlinkCallbackData { -char cr_ifname[64]; +char *cr_ifname; virNetDevVPortProfilePtr virtPortProfile; const unsigned char *macaddress; const char *linkdev; @@ -606,15 +606,13 @@ virNetDevMacVLanVPortProfileCallback(unsigned char *msg, if (memcmp(calld-macaddress, m, VIR_MAC_BUFLEN)) { /* Repeat the same check for a broadcast mac */ -unsigned char broadcastmac[VIR_MAC_BUFLEN]; int i; -for (i = 0;i VIR_MAC_BUFLEN; i++) -broadcastmac[i] = 0xFF; - -if (memcmp(calld-macaddress, broadcastmac, VIR_MAC_BUFLEN)) { -VIR_DEBUG(MAC address match failed.); -return; +for (i = 0;i VIR_MAC_BUFLEN; i++) { +if (calld-macaddress[i] != 0xff) { +VIR_DEBUG(MAC address match failed (wasn't broadcast)); +return; +} } } } @@ -728,6 +726,30 @@ virNetDevMacVLanVPortProfileCallback(unsigned char *msg, } /** + * virNetDevMacVLanVPortProfileDestroyCallback: + * + * @watch: watch whose handle to remove + * @macaddr: macaddr whose handle to remove + * @opaque: Contains vital information regarding the associated vm + * + * This function is called when a netlink message handler is terminated. + * The function frees locally allocated data referenced in the opaque + * data. + */ +static void +virNetDevMacVLanVPortProfileDestroyCallback(int watch ATTRIBUTE_UNUSED, +const unsigned char *macaddr ATTRIBUTE_UNUSED, +void *opaque) +{ +virNetlinkCallbackDataPtr calld = opaque; + +if (calld) { +VIR_FREE(calld-cr_ifname); +} +} + + +/** * virNetDevMacVLanCreateWithVPortProfile: * Create an instance of a macvtap device and open its tap character * device. @@ -879,7 +901,12 @@ create_name: goto disassociate_exit; } -strncpy(calld-cr_ifname, cr_ifname, 64); +calld-cr_ifname=strdup(cr_ifname); +if (calld-cr_ifname == NULL) { +virReportOOMError(); +goto disassociate_exit; +} + calld-virtPortProfile = virtPortProfile; calld-macaddress = macaddress; calld-linkdev = linkdev; @@ -938,7 +965,7 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, ret = -1; } -virNetlinkEventRemoveClient(0, macaddr); +virNetlinkEventRemoveClient(0, macaddr, virNetDevMacVLanVPortProfileDestroyCallback); return ret; } diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c index 751aa67..de6a135 100644 --- a/src/util/virnetlink.c +++ b/src/util/virnetlink.c @@ -446,6 +446,7 @@ error: * * @watch: watch whose handle to remove * @macaddr: macaddr whose handle to remove + * cb: callback for the destruction of local data * * Unregister a callback from a netlink monitor. * The handler function referenced will no longer receive netlink messages. @@ -454,7 +455,8 @@ error: * returns -1 if the file handle was not registered, 0 upon success */ int -virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr) { +virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr, +virNetlinkEventRemoveCallback cb) { int i; int ret = -1; virNetlinkEventSrvPrivatePtr srv = server; @@ -474,6 +476,9 @@ virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr) { continue; if (watch srv-handles[i].watch == watch) { +void *cpopaque = srv-handles[i].opaque; +(cb)( watch, macaddr, cpopaque); + VIR_FREE(srv-handles[i].opaque); srv-handles[i].deleted = VIR_NETLINK_HANDLE_DELETED; VIR_DEBUG(removed client: %d by index., @@ -482,6 +487,9 @@ virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr) { goto error; } if (!watch memcmp(macaddr, srv-handles[i].macaddr, VIR_MAC_BUFLEN) == 0) { +void *cpopaque = srv-handles[i].opaque; +
Re: [libvirt] [PATCH 1/1] Clarify what documentation is being referenced
On Mon, Feb 27, 2012 at 04:02:44PM -0700, Eric Blake wrote: On 02/27/2012 03:51 PM, Dave Allan wrote: virsh.pod had several instances in which it referred to the documentation which was a little puzzling to me since it is documentation. Reading the document from end to end makes it clear that it means a specific URI which was noted previously in the text, but I had never noticed those URI in several years of referring to the man page. This patch adds those URIs to several additional places in the text. --- tools/virsh.pod | 38 ++ 1 files changed, 22 insertions(+), 16 deletions(-) Much nicer. ACK with one nit. =item Battach-device Idomain-id IFILE -Attach a device to the domain, using a device definition in an XML file. -See the documentation to learn about libvirt XML format for a device. -For cdrom and floppy devices, this command only replaces the media within -the single existing device; consider using Bupdate-device for this usage. -For passthrough host devices, see also Bnodedev-dettach, needed if -the device does not use managed mode. +Attach a device to the domain, using a device definition in an XML +file. See the documentation at +Lhttp://libvirt.org/formatdomain.html to learn about libvirt XML Here, I'd link to formatdomain.html#elementsDevices, as well as specifically mention an example or two of the valid top-level elements we are looking for. Maybe: ...using a device definition (such as disk or interface) as the top-level element in an XML file. See the documentation... Good point; I'll send a v2 shortly. Dave -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv2] Error out when using SPICE TLS with spice_tls=0
On 24.02.2012 11:34, Christophe Fergeau wrote: It's possible to disable SPICE TLS in qemu.conf. When this happens, libvirt ignores any SPICE TLS port or x509 directory that may have been set when it builds the qemu command line to use. However, it's not ignoring the secure channels that may have been set and adds tls-channel arguments to qemu command line. Current qemu versions don't report an error when this happens, and try to use TLS for the specified channels. Before this patch domain type='kvm' nameauto-tls-port/name memory65536/memory os type arch='x86_64' machine='pc'hvm/type /os devices graphics type='spice' port='5900' tlsPort='-1' autoport='yes' listen='0' ke listen type='address' address='0'/ channel name='main' mode='secure'/ channel name='inputs' mode='secure'/ /graphics /devices /domain generates -spice port=5900,addr=0,disable-ticketing,tls-channel=main,tls-channel=inputs and starts QEMU. After this patch, an error is reported if a TLS port is set in the XML or if secure channels are specified but TLS is disabled in qemu.conf. This is the behaviour the oVirt people (where I spotted this issue) said they would expect. This fixes bug #790436 --- src/qemu/qemu_command.c | 12 +++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5a34504..4f3e61e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5231,7 +5231,12 @@ qemuBuildCommandLine(virConnectPtr conn, virBufferAsprintf(opt, port=%u, def-graphics[0]-data.spice.port); -if (driver-spiceTLS def-graphics[0]-data.spice.tlsPort != -1) +if (def-graphics[0]-data.spice.tlsPort != -1) +if (!driver-spiceTLS) { +qemuReportError(VIR_ERR_XML_ERROR, +_(spice TLS port set in XML configuration, but TLS is disabled in qemu.conf)); +goto error; +} virBufferAsprintf(opt, ,tls-port=%u, def-graphics[0]-data.spice.tlsPort); In fact, this needs to be wrapped with curly braces as the check for tlsPort != -1 is meant to protect virBufferAsprintf() in the first place. Sorry for not catching this earlier. As an act of repentance I'll send patch. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Don't emit tls-port spice option if port is -1
On 28.02.2012 14:16, Jiri Denemark wrote: Bug introduced by commit eda0fc7a. --- src/qemu/qemu_command.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] docs: Fix libvirt name in qemu commandline namespace URL
s/libirt/libvirt/g --- Pushed under trivial rule. docs/drvqemu.html.in |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/drvqemu.html.in b/docs/drvqemu.html.in index fc76829..9afae13 100644 --- a/docs/drvqemu.html.in +++ b/docs/drvqemu.html.in @@ -551,7 +551,7 @@ $ virsh domxml-to-native qemu-argv demo.xml (span class=sinceSince 0.8.3/span). In order to use the XML additions, it is necessary to issue an XML namespace request (the special codexmlns:iname/i/code attribute) that - pulls in codehttp://libirt.org/schemas/domain/qemu/1.0/code; + pulls in codehttp://libvirt.org/schemas/domain/qemu/1.0/code; typically, the namespace is given the name of codeqemu/code. With the namespace in place, it is then possible to add an element codelt;qemu:commandlinegt;/code @@ -571,7 +571,7 @@ $ virsh domxml-to-native qemu-argv demo.xml /dl pExample:/ppre -lt;domain type='qemu' xmlns:qemu='http://libirt.org/schemas/domain/qemu/1.0'gt; +lt;domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'gt; lt;namegt;QEmu-fedora-i686lt;/namegt; lt;memorygt;219200lt;/memorygt; lt;osgt; -- 1.7.3.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH RFC]: Support numad
On Tue, Feb 28, 2012 at 10:10:50PM +0800, Osier Yang wrote: numad is an user-level daemon that monitors NUMA topology and processes resource consumption to facilitate good NUMA resource alignment of applications/virtual machines to improve performance and minimize cost of remote memory latencies. It provides a pre-placement advisory interface, so significant processes can be pre-bound to nodes with sufficient available resources. More details: http://fedoraproject.org/wiki/Features/numad numad -w ncpus:memory_amount is the advisory interface numad provides currently. This patch add the support by introducing new XML like: numatune cpu required_cpus=4 required_memory=524288/ /numatune Isn't the usual case going to be the vcpus and memory in the guest? IMO we should default to passing those numbers to numad if required_cpus and required_memory are not provided explicitly. Dave And the corresponding numad command line will be: numad -w 4:500 The advisory nodeset returned from numad will be used to set domain process CPU affinity then. (e.g. qemuProcessInitCpuAffinity). If the user specifies both CPU affinity policy (e.g. (vcpu cpuset=1-10,^7,^84/vcpu) and XML indicating to use numad for the advisory nodeset, the specified CPU affinity will be overridden by the nodeset returned from numad. If no XML to specify the CPU affinity policy, and XML indicating to use numad is specified, the returned nodeset will be printed in cpu cpuset=$nodeset_from_numad/4/vcpu. Only QEMU/KVM and LXC drivers support it now. --- configure.ac |8 +++ docs/formatdomain.html.in | 18 ++- docs/schemas/domaincommon.rng | 12 src/conf/domain_conf.c| 125 +++-- src/conf/domain_conf.h|5 ++ src/lxc/lxc_controller.c | 98 src/qemu/qemu_process.c | 99 + 7 files changed, 311 insertions(+), 54 deletions(-) diff --git a/configure.ac b/configure.ac index c9cdd7b..31f0835 100644 --- a/configure.ac +++ b/configure.ac @@ -1445,6 +1445,14 @@ AM_CONDITIONAL([HAVE_NUMACTL], [test $with_numactl != no]) AC_SUBST([NUMACTL_CFLAGS]) AC_SUBST([NUMACTL_LIBS]) +dnl Do we have numad? +if test $with_qemu = yes; then +AC_PATH_PROG([NUMAD], [numad], [], [/bin:/usr/bin:/usr/local/bin:$PATH]) + +if test -n $NUMAD; then +AC_DEFINE_UNQUOTED([NUMAD],[$NUMAD], [Location or name of the numad program]) +fi +fi dnl pcap lib LIBPCAP_CONFIG=pcap-config diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 6fcca94..d8e70a6 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -505,6 +505,7 @@ ... lt;numatunegt; lt;memory mode=strict nodeset=1-4,^3/gt; +lt;cpu required_cpus=3 required_memory=524288/gt; lt;/numatunegt; ... lt;/domaingt; @@ -519,7 +520,7 @@ span class='since'Since 0.9.3/span dtcodememory/code/dt dd -The optional codememory/code element specify how to allocate memory +The optional codememory/code element specifies how to allocate memory for the domain process on a NUMA host. It contains two attributes, attribute codemode/code is either 'interleave', 'strict', or 'preferred', @@ -527,6 +528,21 @@ syntax with attribute codecpuset/code of element codevcpu/code. span class='since'Since 0.9.3/span /dd + dd +The optional codecpu/code element indicates pinning the virtual CPUs +to the nodeset returned by querying numad (a system daemon that monitors +NUMA topology and usage). It has two attributes, attribute +coderequired_cpus/code specifies the number of physical CPUs the guest +process want to use. And the optional attribute coderequired_memory/code +specifies the amount of free memory the guest process want to see on a node, +numad will pick the physical CPUs on the node which has enough free +memory of amount specified by coderequired_memory/code. + +NB, with using this element, the physical CPUs specified by attribute +codecpuset/code (of element codevcpu/code) will be overridden by the +nodeset returned from numad. +span class='since'Since 0.9.11 (QEMU/KVM and LXC only)/span + /dd /dl diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 3908733..d0f443d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -549,6 +549,18 @@ /attribute /element /optional + optional +element name=cpu + attribute name=required_cpu +ref name=countCPU/ + /attribute + optional +
Re: [libvirt] [PATCH RFC]: Support numad
On Tue, Feb 28, 2012 at 11:33:03AM -0500, Dave Allan wrote: On Tue, Feb 28, 2012 at 10:10:50PM +0800, Osier Yang wrote: numad is an user-level daemon that monitors NUMA topology and processes resource consumption to facilitate good NUMA resource alignment of applications/virtual machines to improve performance and minimize cost of remote memory latencies. It provides a pre-placement advisory interface, so significant processes can be pre-bound to nodes with sufficient available resources. More details: http://fedoraproject.org/wiki/Features/numad numad -w ncpus:memory_amount is the advisory interface numad provides currently. This patch add the support by introducing new XML like: numatune cpu required_cpus=4 required_memory=524288/ /numatune Isn't the usual case going to be the vcpus and memory in the guest? IMO we should default to passing those numbers to numad if required_cpus and required_memory are not provided explicitly. Indeed, why you would want to specify anything different ? At first glance my reaction was just skip the XML and call numad internally automatically with the guest configured allocation 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 RFC]: Support numad
On Tue, Feb 28, 2012 at 04:40:06PM +, Daniel P. Berrange wrote: On Tue, Feb 28, 2012 at 11:33:03AM -0500, Dave Allan wrote: On Tue, Feb 28, 2012 at 10:10:50PM +0800, Osier Yang wrote: numad is an user-level daemon that monitors NUMA topology and processes resource consumption to facilitate good NUMA resource alignment of applications/virtual machines to improve performance and minimize cost of remote memory latencies. It provides a pre-placement advisory interface, so significant processes can be pre-bound to nodes with sufficient available resources. More details: http://fedoraproject.org/wiki/Features/numad numad -w ncpus:memory_amount is the advisory interface numad provides currently. This patch add the support by introducing new XML like: numatune cpu required_cpus=4 required_memory=524288/ /numatune Isn't the usual case going to be the vcpus and memory in the guest? IMO we should default to passing those numbers to numad if required_cpus and required_memory are not provided explicitly. Indeed, why you would want to specify anything different ? At first glance my reaction was just skip the XML and call numad internally automatically with the guest configured allocation That seems reasonable to me. Dave 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
[libvirt] Fwd: for help
-- 已转发邮件 -- 发件人: 李成双 lichengshu...@gmail.com 日期: 2012年2月28日 下午8:15 主题: for help 收件人: net...@crc.id.au hi Some of the problems encountered in the installation process your document to you for help. PASS: vmx2xmltest TEST: xml2vmxtest 40 .41 OK PASS: xml2vmxtest TEST: eventtest ... 15 OK PASS: eventtest TEST: networkxml2xmltest 12 OK PASS: networkxml2xmltest TEST: networkxml2argvtest ... 7 OK PASS: networkxml2argvtest TEST: storagevolxml2xmltest .. 6 OK PASS: storagevolxml2xmltest TEST: storagepoolxml2xmltest 12 OK PASS: storagepoolxml2xmltest TEST: nodedevxml2xmltest .13 OK PASS: nodedevxml2xmltest TEST: interfacexml2xmltest ... 19 OK PASS: interfacexml2xmltest TEST: cputest 40 .57 OK PASS: cputest === 1 of 59 tests failed (2 tests were not run) Please report to libvir-list@redhat.com === make[1]: *** [check-TESTS] Error 1 make[1]: Leaving directory `/root/rpmbuild/BUILD/libvirt-0.9.4/tests' make: *** [check-am] Error 2 error: Bad exit status from /var/tmp/rpm-tmp.r4iOXk (%check) RPM build errors: Bad exit status from /var/tmp/rpm-tmp.r4iOXk (%check) -- 李成双 -- 李成双 rpm-tmp.r4iOXk Description: Binary data -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] libvirt-guests: Don't try to do a managed-save of transient guests
The libvirt-guests script tried to do a managed save of transient guest that failed. This patch notifies which guests are transient (and not being saved) and saves only the persistent ones. --- tools/libvirt-guests.init.sh | 37 +++-- 1 files changed, 35 insertions(+), 2 deletions(-) diff --git a/tools/libvirt-guests.init.sh b/tools/libvirt-guests.init.sh index 0d2fc24..21a7d31 100644 --- a/tools/libvirt-guests.init.sh +++ b/tools/libvirt-guests.init.sh @@ -293,13 +293,46 @@ stop() { printf %s $(guest_name $uri $uuid) empty=false done + if $empty; then -gettext no running guests.; echo +gettext no running guests. +fi +echo +fi + +if $suspending; then +transient=$(list_guests $uri --transient) +if [ $? -eq 0 ]; then +empty=true +for uuid in $transient; do +if $empty; then +eval_gettext Not suspending transient guests on URI: \$uri: +empty=false +else +printf , +fi +printf %s $(guest_name $uri $uuid) +done +echo +# reload domain list to contain only persistent guests +list=$(list_guests $uri --persistent) +if [ $? -ne 0 ]; then +eval_gettext Failed to list persistent guests on \$uri +echo +RETVAL=1 +return +fi else +gettext Failed to list transient guests echo -echo $uri $list $LISTFILE +RETVAL=1 +return fi fi + +if [ -n $list ]; then +echo $uri $list $LISTFILE +fi done set +f -- 1.7.3.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/4] libvirt-guests: Check if URI is reachable before launching commands
This patch adds a check to the libvirt-guests script to check for the URI to be alive before attempting any calls. This avoids nasty error messages and allows us to fail gracefuly and continue on other URIs configured in the script. --- tools/libvirt-guests.init.sh | 24 +++- 1 files changed, 19 insertions(+), 5 deletions(-) diff --git a/tools/libvirt-guests.init.sh b/tools/libvirt-guests.init.sh index 21a7d31..47914e3 100644 --- a/tools/libvirt-guests.init.sh +++ b/tools/libvirt-guests.init.sh @@ -88,6 +88,20 @@ run_virsh_c() { ( export LC_ALL=C; run_virsh $@ ) } +# test_connect URI +# check if URI is reachable +test_connect() +{ +uri=$1 + +run_virsh $uri connect 2/dev/null +if [ $? -ne 0 ]; then +eval_gettext Can't connect to \$uri. Skipping. +echo +return 1 +fi +} + # list_guests URI PERSISTENT # List running guests on URI. # PERSISTENT argument options: @@ -172,6 +186,8 @@ start() { continue fi +test_connect $uri || continue + eval_gettext Resuming guests on \$uri URI...; echo for guest in $list; do name=$(guest_name $uri $guest) @@ -278,12 +294,10 @@ stop() { set -f for uri in $URIS; do set +f -eval_gettext Running guests on \$uri URI: -if [ x$uri = xdefault ] [ ! -x $libvirtd ]; then -gettext libvirtd not installed; skipping this URI.; echo -continue -fi +test_connect $uri || continue + +eval_gettext Running guests on \$uri URI: list=$(list_guests $uri) if [ $? -eq 0 ]; then -- 1.7.3.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/4] libvirt-guests: Add documentation and clean up to use virsh's improved list
This patch adds documentation to functions defined in the libvirt-guests init script and changes use of virsh's new commands to make the script easier. --- tools/libvirt-guests.init.sh | 60 -- 1 files changed, 40 insertions(+), 20 deletions(-) diff --git a/tools/libvirt-guests.init.sh b/tools/libvirt-guests.init.sh index 367177e..0d2fc24 100644 --- a/tools/libvirt-guests.init.sh +++ b/tools/libvirt-guests.init.sh @@ -53,6 +53,9 @@ VAR_SUBSYS_LIBVIRT_GUESTS=$localstatedir/lock/subsys/libvirt-guests RETVAL=0 +# retval COMMAND ARGUMENTS... +# run command with arguments and convert non-zero return value to 1 and set +# the global return variable retval() { $@ if [ $? -ne 0 ]; then @@ -63,6 +66,10 @@ retval() { fi } +# run_virsh URI ARGUMENTS... +# start virsh and let it execute ARGUMENTS on URI +# If URI is default virsh is called without the -c argument +# (using libvirt's default connection) run_virsh() { uri=$1 shift @@ -74,64 +81,67 @@ run_virsh() { fi } +# run_virsh_c URI ARGUMENTS +# Same as run_virsh but the C locale is used instead of +# the system's locale. run_virsh_c() { ( export LC_ALL=C; run_virsh $@ ) } +# list_guests URI PERSISTENT +# List running guests on URI. +# PERSISTENT argument options: +# --persistent: list only persistent guests +# --transient: list only transient guests +# [none]: list both persistent and transient guests list_guests() { uri=$1 +persistent=$2 -list=$(run_virsh_c $uri list) +list=$(run_virsh_c $uri list --uuid $persistent) if [ $? -ne 0 ]; then RETVAL=1 return 1 fi -uuids= -for id in $(echo $list | awk 'NR 2 {print $1}'); do -uuid=$(run_virsh_c $uri dominfo $id | awk '/^UUID:/{print $2}') -if [ -z $uuid ]; then -RETVAL=1 -return 1 -fi -uuids=$uuids $uuid -done - -echo $uuids +echo $list } +# guest_name URI UUID +# return name of guest UUID on URI guest_name() { uri=$1 uuid=$2 -name=$(run_virsh_c $uri dominfo $uuid 2/dev/null | \ - sed -ne 's/^Name: *//p') -[ -n $name ] || name=$uuid - -echo $name +run_virsh $uri domname $uuid 2/dev/null } +# guest_is_on URI UUID +# check if guest UUID on URI is runnig +# Result is returned by variable guest_running guest_is_on() { uri=$1 uuid=$2 guest_running=false -info=$(run_virsh_c $uri dominfo $uuid) +id=$(run_virsh $uri domid $uuid) if [ $? -ne 0 ]; then RETVAL=1 return 1 fi -id=$(echo $info | awk '/^Id:/{print $2}') - [ -n $id ] [ x$id != x- ] guest_running=true return 0 } +# started +# Create the startup lock file started() { touch $VAR_SUBSYS_LIBVIRT_GUESTS } +# start +# Start or resume the guests start() { [ -f $LISTFILE ] || { started; return 0; } @@ -187,6 +197,9 @@ start() { started } +# suspend_guest URI GUEST +# Do a managed save on a GUEST on URI. This function returns after the guest +# was saved. suspend_guest() { uri=$1 @@ -213,6 +226,9 @@ suspend_guest() retval wait $virsh_pid printf '\r%s%-12s\n' $label $(gettext done) } +# shutdown_guest URI GUEST +# Start a ACPI shutdown of GUEST on URI. This function return after the quest +# was successfuly shutdown or the timeout defined by $SHUTDOWN_TIMEOUT expires. shutdown_guest() { uri=$1 @@ -241,6 +257,8 @@ shutdown_guest() fi } +# stop +# Shutdown or save guests on the configured uris stop() { # last stop was not followed by start [ -f $LISTFILE ] return 0 @@ -304,6 +322,8 @@ stop() { rm -f $VAR_SUBSYS_LIBVIRT_GUESTS } +# gueststatus +# List status of guests gueststatus() { set -f for uri in $URIS; do -- 1.7.3.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/4] libvirt-guests: improve behavior of the guests script
This patchset tweaks the libvirt guest script to enable parallel shutdown of guests and fix some bugs that appeared through time. Peter Krempa (4): libvirt-guests: Add documentation and clean up to use virsh's improved list libvirt-guests: Don't try to do a managed-save of transient guests libvirt-guests: Check if URI is reachable before launching commands libvirt-guests: Add parallel startup and shutdown of guests tools/libvirt-guests.init.sh | 261 -- tools/libvirt-guests.sysconf | 10 ++- 2 files changed, 235 insertions(+), 36 deletions(-) -- 1.7.3.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/4] libvirt-guests: Add parallel startup and shutdown of guests
With this patch, it's possible to shut down guests in parallel. Parallel startup was possible before, but this functionality was not documented properly. To enable parallel startup set the START_DELAY to 0. Parallel shutdown has a configurable parameter PARALLEL_SHUTDOWN that defines the number of machines being shut down in parallel. Enabling this feature changes the semantics of SHUTDOWN_TIMEOUT parameter that is applied as a cumulative timeout to shutdown all guests on a URI. --- tools/libvirt-guests.init.sh | 140 +++-- tools/libvirt-guests.sysconf | 10 +++- 2 files changed, 141 insertions(+), 9 deletions(-) diff --git a/tools/libvirt-guests.init.sh b/tools/libvirt-guests.init.sh index 47914e3..dd933c7 100644 --- a/tools/libvirt-guests.init.sh +++ b/tools/libvirt-guests.init.sh @@ -273,6 +273,127 @@ shutdown_guest() fi } +# shutdown_guest_async URI GUEST +# Start a ACPI shutdown of GUEST on URI. This function returns after the command +# was issued to libvirt to allow parallel shutdown. +shutdown_guest_async() +{ +uri=$1 +guest=$2 + +name=$(guest_name $uri $guest) +eval_gettext Starting shutdown on guest: \$name +echo +retval run_virsh $uri shutdown $guest /dev/null +} + +# guest_count GUEST_LIST +# Returns number of guests in GUEST_LIST +guest_count() +{ +set -- $1 +echo $# +} + +# guest_first GUEST GUEST GUEST... +# Returns the first guest in GUEST... +guest_first() +{ +echo $1 +} + +# guest_remove GUEST GUEST_LIST +# Remove GUEST from GUEST_LIST +guest_remove() +{ +guest=$1 +guests=$2 + +newguests= +for dom in $guests; do +if [ $dom != $guest ]; then +newguests=$newguests $dom +fi +done + +echo $newguests +} + +# check_domains_shutdown URI GUESTS +# check if shutdown is complete on guests in GUESTS and returns only +# guests that are still shutting down +check_domains_shutdown() +{ +uri=$1 +guests=$2 + +guests_up= +for guest in $guests; do +guest_is_on $uri $dom 21 /dev/null || continue +if $guest_running; then +guests_up=$guests_up $guest +fi +done +echo $guests_up +} + +# print_domains_shutdown URI BEFORE AFTER +# Checks for differences in the lists BEFORE and AFTER and prints +# a shutdown complete notice for guests that have finished +print_domains_shutdown() +{ +uri=$1 +before=$2 +after=$3 + +for guest in $before; do +found=false +for running in $after; do + if [ $guest = $running ]; then + found=true + break + fi +done + +if ! $found; then +name=$(guest_name $uri $guest) +eval_gettext Shutdown of guest \$name complete. +echo +fi +done +} + +# shutdown_guests_parallel URI GUESTS +# Shutdown guests GUESTS on machine URI in parallel +shutdown_guests_parallel() +{ +uri=$1 +guests=$2 + +on_shutdown= +timeout=$SHUTDOWN_TIMEOUT +while [ -n $on_shutdown ] || [ -n $guests ]; do +while [ -n $guests ] + [ $(guest_count $on_shutdown) -lt $PARALLEL_SHUTDOWN ]; do +guest=$(guest_first $guests) +guests=$(guest_remove $guest $guests) +shutdown_guest_async $uri $guest +on_shutdown=$on_shutdown $guest +done +sleep 1 +timeout=$(($timeout - 1)) +if [ $timeout -le 0 ]; then +eval_gettext Timeout expired while shutting down domains; echo +RETVAL=1 +return +fi +on_shutdown_prev=$on_shutdown +on_shutdown=$(check_domains_shutdown $uri $on_shutdown) +print_domains_shutdown $uri $on_shutdown_prev $on_shutdown +done + +} + # stop # Shutdown or save guests on the configured uris stop() { @@ -357,13 +478,18 @@ stop() { eval_gettext Shutting down guests on \$uri URI...; echo fi -for guest in $list; do -if $suspending; then -suspend_guest $uri $guest -else -shutdown_guest $uri $guest -fi -done +if [ $PARALLEL_SHUTDOWN -gt 1 ] + ! $suspending; then +shutdown_guests_parallel $uri $list +else +for guest in $list; do +if $suspending; then +suspend_guest $uri $guest +else +shutdown_guest $uri $guest +fi +done +fi done $LISTFILE rm -f $VAR_SUBSYS_LIBVIRT_GUESTS diff --git a/tools/libvirt-guests.sysconf b/tools/libvirt-guests.sysconf index 9b8b64f..e16af4f 100644 --- a/tools/libvirt-guests.sysconf +++ b/tools/libvirt-guests.sysconf @@ -10,7 +10,8 @@ # libvirtd #ON_BOOT=start -# number of seconds to wait between each guest start +# number of seconds to wait between each guest start. Set to 0 to allow parallel +#
Re: [libvirt] Fwd: for help
On 02/28/2012 05:17 AM, 李成双 wrote: -- 已转发邮件 -- 发件人: 李成双 lichengshu...@gmail.com 日期: 2012年2月28日 下午8:15 主题: for help 收件人: net...@crc.id.au hi Some of the problems encountered in the installation process your document to you for help. Thanks for the report; however... PASS: cputest === 1 of 59 tests failed You didn't paste which test actually failed, or how it failed. Please scroll back further to see the name of the failing test, and run: make -C tests check TESTS=$name VIR_TEST_DEBUG=1 with the appropriate test name stored in $name, then paste that output, so we can further diagnose why the test failed for you. (2 tests were not run) Please report to libvir-list@redhat.com === make[1]: *** [check-TESTS] Error 1 make[1]: Leaving directory `/root/rpmbuild/BUILD/libvirt-0.9.4/tests' 0.9.4 is old; upstream, we've just released 0.9.10. It may be that the bug you hit has been fixed in the meantime, and that it is just a matter of backporting the fix when re-building the rpm that you were testing. -- Eric Blake ebl...@redhat.com+1-919-301-3266 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] [libvirt-glib 1/6] Getters for GVirConfigDomainInterface attributes
From: Zeeshan Ali (Khattak) zeesha...@gnome.org --- libvirt-gconfig/libvirt-gconfig-domain-interface.c | 35 libvirt-gconfig/libvirt-gconfig-domain-interface.h |4 ++ libvirt-gconfig/libvirt-gconfig.sym|4 ++ 3 files changed, 43 insertions(+), 0 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-domain-interface.c b/libvirt-gconfig/libvirt-gconfig-domain-interface.c index 85cc194..61d35bd 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain-interface.c +++ b/libvirt-gconfig/libvirt-gconfig-domain-interface.c @@ -96,6 +96,41 @@ void gvir_config_domain_interface_set_model(GVirConfigDomainInterface *interface model, type, model); } +const char *gvir_config_domain_interface_get_ifname(GVirConfigDomainInterface *interface) +{ +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_INTERFACE(interface), NULL); + +return gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(interface), +target, device); +} + +GVirConfigDomainInterfaceLinkState gvir_config_domain_interface_get_link_state(GVirConfigDomainInterface *interface) +{ +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_INTERFACE(interface), + GVIR_CONFIG_DOMAIN_INTERFACE_LINK_STATE_DEFAULT); + +return gvir_config_object_get_attribute_genum(GVIR_CONFIG_OBJECT(interface), + link, state, + GVIR_CONFIG_TYPE_DOMAIN_INTERFACE_LINK_STATE, + GVIR_CONFIG_DOMAIN_INTERFACE_LINK_STATE_DEFAULT); +} + +const char *gvir_config_domain_interface_get_mac(GVirConfigDomainInterface *interface) +{ +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_INTERFACE(interface), NULL); + +return gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(interface), +mac, address); +} + +const char *gvir_config_domain_interface_get_model(GVirConfigDomainInterface *interface) +{ +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_INTERFACE(interface), NULL); + +return gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(interface), +model, type); +} + G_GNUC_INTERNAL GVirConfigDomainDevice * gvir_config_domain_interface_new_from_tree(GVirConfigXmlDoc *doc, xmlNodePtr tree) diff --git a/libvirt-gconfig/libvirt-gconfig-domain-interface.h b/libvirt-gconfig/libvirt-gconfig-domain-interface.h index 6e802fb..c8c4fb3 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain-interface.h +++ b/libvirt-gconfig/libvirt-gconfig-domain-interface.h @@ -72,6 +72,10 @@ void gvir_config_domain_interface_set_mac(GVirConfigDomainInterface *interface, const char *mac_address); void gvir_config_domain_interface_set_model(GVirConfigDomainInterface *interface, const char *model); +const char *gvir_config_domain_interface_get_ifname(GVirConfigDomainInterface *interface); +GVirConfigDomainInterfaceLinkState gvir_config_domain_interface_get_link_state(GVirConfigDomainInterface *interface); +const char *gvir_config_domain_interface_get_mac(GVirConfigDomainInterface *interface); +const char *gvir_config_domain_interface_get_model(GVirConfigDomainInterface *interface); G_END_DECLS diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym index 96ce58f..f91b8b0 100644 --- a/libvirt-gconfig/libvirt-gconfig.sym +++ b/libvirt-gconfig/libvirt-gconfig.sym @@ -145,6 +145,10 @@ LIBVIRT_GCONFIG_0.0.4 { gvir_config_domain_interface_set_link_state; gvir_config_domain_interface_set_mac; gvir_config_domain_interface_set_model; + gvir_config_domain_interface_get_ifname; + gvir_config_domain_interface_get_link_state; + gvir_config_domain_interface_get_mac; + gvir_config_domain_interface_get_model; gvir_config_domain_interface_bridge_get_type; gvir_config_domain_interface_bridge_new; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib 3/6] Add gvir_domain_device_get_domain()
From: Zeeshan Ali (Khattak) zeesha...@gnome.org Getter for the associated domain of a domain device. --- libvirt-gobject/libvirt-gobject-domain-device.c | 10 ++ libvirt-gobject/libvirt-gobject-domain-device.h |3 +++ libvirt-gobject/libvirt-gobject.sym |1 + 3 files changed, 14 insertions(+), 0 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain-device.c b/libvirt-gobject/libvirt-gobject-domain-device.c index 528b513..6282d8b 100644 --- a/libvirt-gobject/libvirt-gobject-domain-device.c +++ b/libvirt-gobject/libvirt-gobject-domain-device.c @@ -134,3 +134,13 @@ virDomainPtr gvir_domain_device_get_domain_handle(GVirDomainDevice *self) return handle; } + +/** + * gvir_domain_device_get_domain: + * @device: the domain device + * + * Returns: (transfer full): the associate domain + */ +GVirDomain *gvir_domain_device_get_domain(GVirDomainDevice *device) { +return g_object_ref (device-priv-domain); +} diff --git a/libvirt-gobject/libvirt-gobject-domain-device.h b/libvirt-gobject/libvirt-gobject-domain-device.h index 96c0433..98acc2d 100644 --- a/libvirt-gobject/libvirt-gobject-domain-device.h +++ b/libvirt-gobject/libvirt-gobject-domain-device.h @@ -27,6 +27,8 @@ #ifndef __LIBVIRT_GOBJECT_DOMAIN_DEVICE_H__ #define __LIBVIRT_GOBJECT_DOMAIN_DEVICE_H__ +#include libvirt-gobject/libvirt-gobject-domain.h + G_BEGIN_DECLS #define GVIR_TYPE_DOMAIN_DEVICE(gvir_domain_device_get_type ()) @@ -58,6 +60,7 @@ struct _GVirDomainDeviceClass GType gvir_domain_device_get_type(void); +GVirDomain *gvir_domain_device_get_domain(GVirDomainDevice *device); G_END_DECLS diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index 5081f41..0097692 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -33,6 +33,7 @@ LIBVIRT_GOBJECT_0.0.4 { gvir_connection_get_node_info; gvir_domain_device_get_type; + gvir_domain_device_get_domain; gvir_domain_disk_get_type; gvir_domain_disk_stats_get_type; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib 4/6] Add 'config' property to GVirDomainDevice
From: Zeeshan Ali (Khattak) zeesha...@gnome.org GVirDomainDevice should have an associated GVirConfigDomainDevice. --- libvirt-gobject/libvirt-gobject-domain-device.c | 32 +++ libvirt-gobject/libvirt-gobject-domain-device.h |1 + libvirt-gobject/libvirt-gobject.sym |1 + 3 files changed, 34 insertions(+), 0 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain-device.c b/libvirt-gobject/libvirt-gobject-domain-device.c index 6282d8b..85879d2 100644 --- a/libvirt-gobject/libvirt-gobject-domain-device.c +++ b/libvirt-gobject/libvirt-gobject-domain-device.c @@ -37,6 +37,7 @@ struct _GVirDomainDevicePrivate { GVirDomain *domain; +GVirConfigDomainDevice *config; }; G_DEFINE_ABSTRACT_TYPE(GVirDomainDevice, gvir_domain_device, G_TYPE_OBJECT); @@ -44,6 +45,7 @@ G_DEFINE_ABSTRACT_TYPE(GVirDomainDevice, gvir_domain_device, G_TYPE_OBJECT); enum { PROP_0, PROP_DOMAIN, +PROP_CONFIG, }; static void gvir_domain_device_get_property(GObject *object, @@ -59,6 +61,10 @@ static void gvir_domain_device_get_property(GObject *object, g_value_set_object(value, priv-domain); break; +case PROP_CONFIG: +g_value_set_object(value, priv-config); +break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } @@ -79,6 +85,11 @@ static void gvir_domain_device_set_property(GObject *object, priv-domain = g_value_dup_object(value); break; +case PROP_CONFIG: +g_clear_object(priv-config); +priv-config = g_value_dup_object(value); +break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } @@ -93,6 +104,7 @@ static void gvir_domain_device_finalize(GObject *object) g_debug(Finalize GVirDomainDevice=%p, self); g_clear_object(priv-domain); +g_clear_object(priv-config); G_OBJECT_CLASS(gvir_domain_device_parent_class)-finalize(object); } @@ -115,6 +127,16 @@ static void gvir_domain_device_class_init(GVirDomainDeviceClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); +g_object_class_install_property(object_class, +PROP_CONFIG, +g_param_spec_object(config, +Config, +The configuration, + GVIR_CONFIG_TYPE_DOMAIN_DEVICE, +G_PARAM_READWRITE | +G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_type_class_add_private(klass, sizeof(GVirDomainDevicePrivate)); } @@ -144,3 +166,13 @@ virDomainPtr gvir_domain_device_get_domain_handle(GVirDomainDevice *self) GVirDomain *gvir_domain_device_get_domain(GVirDomainDevice *device) { return g_object_ref (device-priv-domain); } + +/** + * gvir_domain_device_get_config: + * @device: the domain device + * + * Returns: (transfer full): the config + */ +GVirConfigDomainDevice *gvir_domain_device_get_config(GVirDomainDevice *device) { +return g_object_ref (device-priv-config); +} diff --git a/libvirt-gobject/libvirt-gobject-domain-device.h b/libvirt-gobject/libvirt-gobject-domain-device.h index 98acc2d..b308477 100644 --- a/libvirt-gobject/libvirt-gobject-domain-device.h +++ b/libvirt-gobject/libvirt-gobject-domain-device.h @@ -61,6 +61,7 @@ struct _GVirDomainDeviceClass GType gvir_domain_device_get_type(void); GVirDomain *gvir_domain_device_get_domain(GVirDomainDevice *device); +GVirConfigDomainDevice *gvir_domain_device_get_config(GVirDomainDevice *device); G_END_DECLS diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index 0097692..d6999dc 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -34,6 +34,7 @@ LIBVIRT_GOBJECT_0.0.4 { gvir_domain_device_get_type; gvir_domain_device_get_domain; + gvir_domain_device_get_config; gvir_domain_disk_get_type; gvir_domain_disk_stats_get_type; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib 2/6] Add gvir_domain_disk_resize()
From: Zeeshan Ali (Khattak) zeesha...@gnome.org Binding for virDomainBlockResize(). --- libvirt-gobject/libvirt-gobject-domain-disk.c | 38 + libvirt-gobject/libvirt-gobject-domain-disk.h |4 ++ libvirt-gobject/libvirt-gobject.sym |1 + 3 files changed, 43 insertions(+), 0 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain-disk.c b/libvirt-gobject/libvirt-gobject-domain-disk.c index f98d816..fb7672e 100644 --- a/libvirt-gobject/libvirt-gobject-domain-disk.c +++ b/libvirt-gobject/libvirt-gobject-domain-disk.c @@ -192,3 +192,41 @@ end: virDomainFree(handle); return ret; } + +/** + * gvir_domain_disk_resize: + * @self: the domain disk + * @size: new size of the block image in kilobytes + * @flags: flags, currently unused. Pass '0'. + * @err: placeholder for an error, or NULL + * + * This function resize the disk of a running domain. + * + * Returns: TRUE if size was successfully changed, FALSE otherwise. + **/ +gboolean gvir_domain_disk_resize(GVirDomainDisk *self, + guint64 size, + guint flags, + GError **err) +{ +gboolean ret = FALSE; +virDomainPtr handle; + +g_return_val_if_fail(GVIR_IS_DOMAIN_DISK(self), FALSE); +g_return_val_if_fail(err == NULL || *err != NULL, FALSE); + +handle = gvir_domain_device_get_domain_handle(GVIR_DOMAIN_DEVICE(self)); + +if (virDomainBlockResize(handle, self-priv-path, size, flags) 0) { +gvir_set_error_literal(err, GVIR_DOMAIN_DISK_ERROR, + 0, + Failed to resize domain disk); +goto end; +} + +ret = TRUE; + +end: +virDomainFree(handle); +return ret; +} diff --git a/libvirt-gobject/libvirt-gobject-domain-disk.h b/libvirt-gobject/libvirt-gobject-domain-disk.h index 21f2357..1788d63 100644 --- a/libvirt-gobject/libvirt-gobject-domain-disk.h +++ b/libvirt-gobject/libvirt-gobject-domain-disk.h @@ -72,6 +72,10 @@ GType gvir_domain_disk_get_type(void); GType gvir_domain_disk_stats_get_type(void); GVirDomainDiskStats *gvir_domain_disk_get_stats(GVirDomainDisk *self, GError **err); +gboolean gvir_domain_disk_resize(GVirDomainDisk *self, + guint64 size, + guint flags, + GError **err); G_END_DECLS diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index 1ad6b53..5081f41 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -37,6 +37,7 @@ LIBVIRT_GOBJECT_0.0.4 { gvir_domain_disk_get_type; gvir_domain_disk_stats_get_type; gvir_domain_disk_get_stats; + gvir_domain_disk_resize; gvir_domain_interface_get_type; gvir_domain_interface_stats_get_type; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib 5/6] Remove now redundant 'path' property
From: Zeeshan Ali (Khattak) zeesha...@gnome.org Remove now redundant 'path' property from GVirDomainDevice subclasses. --- libvirt-gobject/libvirt-gobject-domain-disk.c | 88 libvirt-gobject/libvirt-gobject-domain-disk.h |3 +- libvirt-gobject/libvirt-gobject-domain-interface.c | 89 +++- libvirt-gobject/libvirt-gobject-domain-interface.h |3 +- 4 files changed, 31 insertions(+), 152 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain-disk.c b/libvirt-gobject/libvirt-gobject-domain-disk.c index fb7672e..42e0e6c 100644 --- a/libvirt-gobject/libvirt-gobject-domain-disk.c +++ b/libvirt-gobject/libvirt-gobject-domain-disk.c @@ -34,75 +34,22 @@ #define GVIR_DOMAIN_DISK_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN_DISK, GVirDomainDiskPrivate)) -struct _GVirDomainDiskPrivate -{ -gchar *path; -}; - G_DEFINE_TYPE(GVirDomainDisk, gvir_domain_disk, GVIR_TYPE_DOMAIN_DEVICE); -enum { -PROP_0, -PROP_PATH, -}; - #define GVIR_DOMAIN_DISK_ERROR gvir_domain_disk_error_quark() - static GQuark gvir_domain_disk_error_quark(void) { return g_quark_from_static_string(gvir-domain-disk); } -static void gvir_domain_disk_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ -GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); -GVirDomainDiskPrivate *priv = self-priv; - -switch (prop_id) { -case PROP_PATH: -g_value_set_string(value, priv-path); -break; - -default: -G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); -} -} - - -static void gvir_domain_disk_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ -GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); -GVirDomainDiskPrivate *priv = self-priv; - -switch (prop_id) { -case PROP_PATH: -g_free(priv-path); -priv-path = g_value_dup_string(value); -break; - -default: -G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); -} -} - - static void gvir_domain_disk_finalize(GObject *object) { GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); -GVirDomainDiskPrivate *priv = self-priv; g_debug(Finalize GVirDomainDisk=%p, self); -g_free(priv-path); - G_OBJECT_CLASS(gvir_domain_disk_parent_class)-finalize(object); } @@ -111,27 +58,11 @@ static void gvir_domain_disk_class_init(GVirDomainDiskClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class-finalize = gvir_domain_disk_finalize; -object_class-get_property = gvir_domain_disk_get_property; -object_class-set_property = gvir_domain_disk_set_property; - -g_object_class_install_property(object_class, -PROP_PATH, -g_param_spec_string(path, -Path, -The disk path, -NULL, -G_PARAM_READWRITE | -G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - -g_type_class_add_private(klass, sizeof(GVirDomainDiskPrivate)); } static void gvir_domain_disk_init(GVirDomainDisk *self) { g_debug(Init GVirDomainDisk=%p, self); - -self-priv = GVIR_DOMAIN_DISK_GET_PRIVATE(self); } static GVirDomainDiskStats * @@ -151,6 +82,15 @@ gvir_domain_disk_stats_free(GVirDomainDiskStats *stats) G_DEFINE_BOXED_TYPE(GVirDomainDiskStats, gvir_domain_disk_stats, gvir_domain_disk_stats_copy, gvir_domain_disk_stats_free) +static const gchar *gvir_domain_disk_get_path(GVirDomainDisk *self) +{ +GVirConfigDomainDevice *config; + +config = gvir_domain_device_get_config(GVIR_DOMAIN_DEVICE(self)); + +return gvir_config_domain_disk_get_target_dev (GVIR_CONFIG_DOMAIN_DISK (config)); +} + /** * gvir_domain_disk_get_stats: * @self: the domain disk @@ -166,15 +106,15 @@ GVirDomainDiskStats *gvir_domain_disk_get_stats(GVirDomainDisk *self, GError **e { GVirDomainDiskStats *ret = NULL; virDomainBlockStatsStruct stats; -GVirDomainDiskPrivate *priv; virDomainPtr handle; +const gchar *path; g_return_val_if_fail(GVIR_IS_DOMAIN_DISK(self), NULL); -priv = self-priv; handle = gvir_domain_device_get_domain_handle(GVIR_DOMAIN_DEVICE(self)); +path = gvir_domain_disk_get_path (self); -if (virDomainBlockStats(handle, priv-path,
[libvirt] [libvirt-glib 6/6] Add gvir_domain_get_devices()
From: Zeeshan Ali (Khattak) zeesha...@gnome.org Currently we only support existing DomainDevice implementations: DomainDisk and DomainInterface. --- .../libvirt-gobject-domain-device-private.h|2 + libvirt-gobject/libvirt-gobject-domain-device.c| 21 ++ libvirt-gobject/libvirt-gobject-domain.c | 42 libvirt-gobject/libvirt-gobject-domain.h |3 + libvirt-gobject/libvirt-gobject.sym|1 + 5 files changed, 69 insertions(+), 0 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain-device-private.h b/libvirt-gobject/libvirt-gobject-domain-device-private.h index 72c660e..292a2ac 100644 --- a/libvirt-gobject/libvirt-gobject-domain-device-private.h +++ b/libvirt-gobject/libvirt-gobject-domain-device-private.h @@ -24,6 +24,8 @@ G_BEGIN_DECLS +G_GNUC_INTERNAL GVirDomainDevice *gvir_domain_device_new(GVirConfigDomainDevice *config, + GVirDomain *domain); virDomainPtr gvir_domain_device_get_domain_handle(GVirDomainDevice *self); G_END_DECLS diff --git a/libvirt-gobject/libvirt-gobject-domain-device.c b/libvirt-gobject/libvirt-gobject-domain-device.c index 85879d2..0ec5dad 100644 --- a/libvirt-gobject/libvirt-gobject-domain-device.c +++ b/libvirt-gobject/libvirt-gobject-domain-device.c @@ -176,3 +176,24 @@ GVirDomain *gvir_domain_device_get_domain(GVirDomainDevice *device) { GVirConfigDomainDevice *gvir_domain_device_get_config(GVirDomainDevice *device) { return g_object_ref (device-priv-config); } + +G_GNUC_INTERNAL GVirDomainDevice *gvir_domain_device_new(GVirConfigDomainDevice *config, + GVirDomain *domain) +{ +GType type; + +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DEVICE(config), NULL); + +if (GVIR_CONFIG_IS_DOMAIN_DISK(config)) +type = GVIR_TYPE_DOMAIN_DISK; +else if (GVIR_CONFIG_IS_DOMAIN_INTERFACE(config)) +type = GVIR_TYPE_DOMAIN_INTERFACE; +else { +g_debug(Unknown device type: %s, G_OBJECT_TYPE_NAME(config)); +return NULL; +} + +return GVIR_DOMAIN_DEVICE(g_object_new(type, + config, config, + domain, domain, NULL)); +} diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c index 23ad882..3c66c9c 100644 --- a/libvirt-gobject/libvirt-gobject-domain.c +++ b/libvirt-gobject/libvirt-gobject-domain.c @@ -29,6 +29,7 @@ #include libvirt-glib/libvirt-glib.h #include libvirt-gobject/libvirt-gobject.h #include libvirt-gobject-compat.h +#include libvirt-gobject/libvirt-gobject-domain-device-private.h #define GVIR_DOMAIN_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN, GVirDomainPrivate)) @@ -868,3 +869,44 @@ gboolean gvir_domain_get_saved(GVirDomain *dom) return virDomainHasManagedSaveImage(dom-priv-handle, 0) == 1; } + +/** + * gvir_domain_get_devices: + * @domain: the domain + * @err: place-holder for possible errors, or NULL + * + * Gets the list of devices attached to @domain + * + * Returns: (element-type LibvirtGObject.DomainDevice) (transfer full): a newly + * allocated #GList of #GVirDomainDevice. + */ +GList *gvir_domain_get_devices(GVirDomain *domain, + GError **err) +{ +GVirConfigDomain *config; +GList *config_devices; +GList *node; +GList *ret = NULL; + +g_return_val_if_fail(GVIR_IS_DOMAIN(domain), NULL); + +config = gvir_domain_get_config(domain, 0, err); +if (config == NULL) +return ret; + +config_devices = gvir_config_domain_get_devices(config); +for (node = config_devices; node != NULL; node = node-next) { +GVirConfigDomainDevice *device_config; +GVirDomainDevice *device; + +device_config = GVIR_CONFIG_DOMAIN_DEVICE(node-data); +device = gvir_domain_device_new(device_config, domain); +if (device != NULL) + ret = g_list_append(ret, device); + +g_object_unref (device_config); +} +g_list_free (config_devices); + +return ret; +} diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h index 56500a8..8a4836e 100644 --- a/libvirt-gobject/libvirt-gobject-domain.h +++ b/libvirt-gobject/libvirt-gobject-domain.h @@ -183,6 +183,9 @@ gboolean gvir_domain_save_finish (GVirDomain *dom, gboolean gvir_domain_get_persistent(GVirDomain *dom); gboolean gvir_domain_get_saved(GVirDomain *dom); +GList *gvir_domain_get_devices(GVirDomain *domain, + GError **err); + G_END_DECLS #endif /* __LIBVIRT_GOBJECT_DOMAIN_H__ */ diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index d6999dc..b7b95cb 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym
Re: [libvirt] [Resending] [PATCH 2/2] Allow x86 to fetch sysinfo from /proc/cpuinfo when dmidecode is absent.
On Fri, Feb 17, 2012 at 01:00:22PM +0530, Prerna wrote: The last patch was mangled by my mailer, resending. From: Prerna Saxena pre...@linux.vnet.ibm.com Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system. Until now, libvirt on x86 flags an error message if dmidecode is not found. With this patch, the following is a sample output on x86 when dmidecode is absent: virsh # sysinfo sysinfo type='smbios' processor entry name='socket_destination'0/entry entry name='type'Intel(R) Xeon(R) CPU X5570 @ 2.93GHz/entry entry name='family'6/entry entry name='manufacturer'GenuineIntel/entry /processor processor entry name='socket_destination'1/entry entry name='type'Intel(R) Xeon(R) CPU X5570 @ 2.93GHz/entry entry name='family'6/entry entry name='manufacturer'GenuineIntel/entry /processor ... (listing for all online CPUs) /sysinfo --- src/util/sysinfo.c | 95 +-- 1 files changed, 91 insertions(+), 4 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 1/2] Implement sysinfo on PowerPC.
On Thu, Feb 16, 2012 at 05:56:22PM +0530, Prerna wrote: From: Prerna Saxena pre...@linux.vnet.ibm.com Date: Tue, 17 Feb 2012 16:55:26 +0530 Subject: [PATCH 1/2] Implement sysinfo on PowerPC. Libvirt on x86 parses 'dmidecode' to gather characteristics of host system, which are then reflected to libvirt users by virSysinfoRead(), invoked by 'virsh sysinfo'. This patch implements it on PowerPC by reading /proc/cpuinfo. The presently available fields in 'sysinfo' are strongly tied to dmidecode output fields. This patch attempts to retrofit the information available in PowerPC to appropriate sysinfo fields. I will be happy to change the organization of this information to if there are expected outputs for individual fields. (I couldnt find any documentation which explained what each sysinfo field was expected to convey.) TODOS: 1. Adding Memory DIMM information 2) Firmware (bios) details. 3) Expand processor tag to have more fields available. Example output on PowerPC : virsh # sysinfo sysinfo type='smbios' system entry name='version'PowerNV 8246-L2C/entry entry name='serial'8246-L2C/entry entry name='family'PowerNV/entry /system processor entry name='socket_destination'0/entry entry name='type'POWER7 (raw), altivec supported/entry entry name='version'2.3 (pvr 003f 0203)/entry /processor processor entry name='socket_destination'4/entry entry name='type'POWER7 (raw), altivec supported/entry entry name='version'2.3 (pvr 003f 0203)/entry /processor .. 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
[libvirt] [PATCHv2 00/17] Support for interface type='hostdev'
This series of patches enhances the interface device to support a sort of intelligent hostdev, i.e. PCI passthrough where device-type specific initialization is done prior to assigning the device to the guest, in particular to allow setting the MAC address and do 802.1QbX setup for network devices. The first posting of this patch only supported parsing and formatting of these devices. This version also supports them in persistent config, as well as hotplug (both persistent and live-only). The only piece that isn't in this patchset (because it is coming from another author) is the code that actually Rather than adding all of the device-type specific config to hostdev, this is accomplished through adding a new type of interface element, type='hostdev'. When an interface is type='hostdev' the following is changed: * in the toplevel device, the managed attribute can be specified (with identical results as when it's specified in a hostdev * The source element can specify a pci address or usb address, just as can be done in hostdev. One notable difference is that the type of the address is specified directly in the source address element, rather than as an attribute of the toplevel device (that's how it's done for hostdev, but for interface, the toplevel element's type attribute is already used). NB: a type=hostdev interface will reside in both the interface list (for configuration and memory management) and hostdev list (for PCI attach/detach, and tracking of which devices are assigned)). This entire series is available on gitorious: git://gitorious.org/~laine/libvirt/laine-staging.git in the passthrough8 branch. Patches 1-7, 9-12, and 15-16 are just setup for the new functionality - they reorder and refactor existing code to allow greater re-use of existing code and easier plugin of the new code. Those marked with X are unchanged from V1 (as far as my git logs tell me). Those marked + are new patches that weren't in V1. + [PATCH 01/17] conf: add missing device types to [PATCH 02/17] conf: relocate virDomainDeviceDef and X [PATCH 03/17] conf: reorder static functions in domain_conf.c + [PATCH 04/17] qemu: rename virDomainDeviceInfoPtr variables to avoid + [PATCH 05/17] conf: add device pointer to args of [PATCH 06/17] conf: make hostdev info a separate object X [PATCH 07/17] conf: HostdevDef parse/format helper functions + [PATCH 09/17] conf: put subsys part of virDomainHostdevDef into its + [PATCH 10/17] conf: hostdev utility functions + [PATCH 11/17] qemu: re-order functions in qemu_hotplug.c + [PATCH 12/17] qemu: refactor hotplug detach of hostdevs + [PATCH 15/17] conf: change virDomainNetRemove from static to global + [PATCH 16/17] qemu: use virDomainNetRemove instead of inline code Patch 8 is just a couple lines: [PATCH 08/17] conf: give each hostdevdef a parent pointer [PATCH 13/17] conf: parse/format type='hostdev' network interfaces + [PATCH 14/17] qemu: support type='hostdev' network devices at domain start + [PATCH 17/17] qemu: support type=hostdev network device live hotplug -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 01/17] conf: add missing device types to virDomainDevice(Type|Def)
Not all device types were represented in virDomainDeviceType, so some types of devices couldn't be represented in a virDomainDeviceDef (which requires a different type of pointer in the union for each different kind of device). Since serial, parallel, channel, and console devices are all virDomainChrDef, and the virDomainDeviceType is never used to produce a string from the type (and only used in the other direction internally to code, never to produce XML), I only added one CHR type, which is associated with virDomainChrDefPtr chr in the union. --- New patch in V2. src/conf/domain_conf.c |6 +- src/conf/domain_conf.h | 11 +-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f9654f1..26190f1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -123,6 +123,7 @@ VIR_ENUM_IMPL(virDomainLifecycleCrash, VIR_DOMAIN_LIFECYCLE_CRASH_LAST, coredump-restart) VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, + none, disk, lease, filesystem, @@ -135,7 +136,10 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, controller, graphics, hub, - redirdev) + redirdev, + smartcard, + chr, + memballoon) VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, none, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 596be4d..9acf1e1 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1179,7 +1179,8 @@ enum virDomainSmbiosMode { }; /* Flags for the 'type' field in next struct */ -enum virDomainDeviceType { +typedef enum { +VIR_DOMAIN_DEVICE_NONE = 0, VIR_DOMAIN_DEVICE_DISK, VIR_DOMAIN_DEVICE_LEASE, VIR_DOMAIN_DEVICE_FS, @@ -1193,9 +1194,12 @@ enum virDomainDeviceType { VIR_DOMAIN_DEVICE_GRAPHICS, VIR_DOMAIN_DEVICE_HUB, VIR_DOMAIN_DEVICE_REDIRDEV, +VIR_DOMAIN_DEVICE_SMARTCARD, +VIR_DOMAIN_DEVICE_CHR, +VIR_DOMAIN_DEVICE_MEMBALLOON, VIR_DOMAIN_DEVICE_LAST, -}; +} virDomainDeviceType; typedef struct _virDomainDeviceDef virDomainDeviceDef; typedef virDomainDeviceDef *virDomainDeviceDefPtr; @@ -1215,6 +1219,9 @@ struct _virDomainDeviceDef { virDomainGraphicsDefPtr graphics; virDomainHubDefPtr hub; virDomainRedirdevDefPtr redirdev; +virDomainSmartcardDefPtr smartcard; +virDomainChrDefPtr chr; +virDomainMemballoonDefPtr memballoon; } data; }; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 02/17] conf: relocate virDomainDeviceDef and virDomainHostdevDef
This patch is only code movement + adding some forward definitions of typedefs. virDomainHostdevDef (not just a pointer to it, but an actual object) will be needed in virDomainNetDef and virDomainActualNetDef, so it must be relocated earlier in the file. Likewise, virDomainDeviceDef will be needed in virDomainHostdevDef, so it must be moved up even earlier. This, in turn, creates a forward reference problem, but fortunately only with pointers to other device types, so their typedefs can be moved up in the file, eliminating the problem. --- V2: aside from the fact that there are now more types of device to have their definitions/enums relocated, I learned that older versions of gcc will not allow a duplicate typedef, even if it is identical to the original, so rather than just copying the device typedefs from their original locations just above each struct definition, I had to move them, removing the original. src/conf/domain_conf.h | 262 ++-- 1 files changed, 141 insertions(+), 121 deletions(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9acf1e1..68b7cfd 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -44,6 +44,104 @@ # include virnetdevopenvswitch.h # include virnetdevbandwidth.h +/* forward declarations of all device types, required by + * virDomainDeviceDef + */ +typedef struct _virDomainDiskDef virDomainDiskDef; +typedef virDomainDiskDef *virDomainDiskDefPtr; + +typedef struct _virDomainControllerDef virDomainControllerDef; +typedef virDomainControllerDef *virDomainControllerDefPtr; + +typedef struct _virDomainLeaseDef virDomainLeaseDef; +typedef virDomainLeaseDef *virDomainLeaseDefPtr; + +typedef struct _virDomainFSDef virDomainFSDef; +typedef virDomainFSDef *virDomainFSDefPtr; + +typedef struct _virDomainNetDef virDomainNetDef; +typedef virDomainNetDef *virDomainNetDefPtr; + +typedef struct _virDomainInputDef virDomainInputDef; +typedef virDomainInputDef *virDomainInputDefPtr; + +typedef struct _virDomainSoundDef virDomainSoundDef; +typedef virDomainSoundDef *virDomainSoundDefPtr; + +typedef struct _virDomainVideoDef virDomainVideoDef; +typedef virDomainVideoDef *virDomainVideoDefPtr; + +typedef struct _virDomainHostdevDef virDomainHostdevDef; +typedef virDomainHostdevDef *virDomainHostdevDefPtr; + +typedef struct _virDomainWatchdogDef virDomainWatchdogDef; +typedef virDomainWatchdogDef *virDomainWatchdogDefPtr; + +typedef struct _virDomainGraphicsDef virDomainGraphicsDef; +typedef virDomainGraphicsDef *virDomainGraphicsDefPtr; + +typedef struct _virDomainHubDef virDomainHubDef; +typedef virDomainHubDef *virDomainHubDefPtr; + +typedef struct _virDomainRedirdevDef virDomainRedirdevDef; +typedef virDomainRedirdevDef *virDomainRedirdevDefPtr; + +typedef struct _virDomainSmartcardDef virDomainSmartcardDef; +typedef virDomainSmartcardDef *virDomainSmartcardDefPtr; + +typedef struct _virDomainChrDef virDomainChrDef; +typedef virDomainChrDef *virDomainChrDefPtr; + +typedef struct _virDomainMemballoonDef virDomainMemballoonDef; +typedef virDomainMemballoonDef *virDomainMemballoonDefPtr; + +/* Flags for the 'type' field in virDomainDeviceDef */ +typedef enum { +VIR_DOMAIN_DEVICE_NONE = 0, +VIR_DOMAIN_DEVICE_DISK, +VIR_DOMAIN_DEVICE_LEASE, +VIR_DOMAIN_DEVICE_FS, +VIR_DOMAIN_DEVICE_NET, +VIR_DOMAIN_DEVICE_INPUT, +VIR_DOMAIN_DEVICE_SOUND, +VIR_DOMAIN_DEVICE_VIDEO, +VIR_DOMAIN_DEVICE_HOSTDEV, +VIR_DOMAIN_DEVICE_WATCHDOG, +VIR_DOMAIN_DEVICE_CONTROLLER, +VIR_DOMAIN_DEVICE_GRAPHICS, +VIR_DOMAIN_DEVICE_HUB, +VIR_DOMAIN_DEVICE_REDIRDEV, +VIR_DOMAIN_DEVICE_SMARTCARD, +VIR_DOMAIN_DEVICE_CHR, +VIR_DOMAIN_DEVICE_MEMBALLOON, + +VIR_DOMAIN_DEVICE_LAST, +} virDomainDeviceType; + +typedef struct _virDomainDeviceDef virDomainDeviceDef; +typedef virDomainDeviceDef *virDomainDeviceDefPtr; +struct _virDomainDeviceDef { +int type; /* enum virDomainDeviceType */ +union { +virDomainDiskDefPtr disk; +virDomainControllerDefPtr controller; +virDomainLeaseDefPtr lease; +virDomainFSDefPtr fs; +virDomainNetDefPtr net; +virDomainInputDefPtr input; +virDomainSoundDefPtr sound; +virDomainVideoDefPtr video; +virDomainHostdevDefPtr hostdev; +virDomainWatchdogDefPtr watchdog; +virDomainGraphicsDefPtr graphics; +virDomainHubDefPtr hub; +virDomainRedirdevDefPtr redirdev; +virDomainSmartcardDefPtr smartcard; +virDomainChrDefPtr chr; +virDomainMemballoonDefPtr memballoon; +} data; +}; + /* Different types of hypervisor */ /* NB: Keep in sync with virDomainVirtTypeToString impl */ enum virDomainVirtType { @@ -234,8 +332,6 @@ struct _virDomainHostdevOrigStates { } states; }; -typedef struct _virDomainLeaseDef virDomainLeaseDef; -typedef virDomainLeaseDef *virDomainLeaseDefPtr; struct _virDomainLeaseDef { char *lockspace;
[libvirt] [PATCH 09/17] conf: put subsys part of virDomainHostdevDef into its own struct
To shorten some new code that accesses the many fields within the subsys struct of a hostdev, create a separate toplevel, typedefed virDomainHostdevSubsys struct so that we can define temporary pointers to the subsys part. --- New patch for V2. src/conf/domain_conf.h | 31 ++- 1 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index efb86bc..1a29fdb 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -354,25 +354,30 @@ enum virDomainHostdevSubsysType { VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST }; + +typedef struct _virDomainHostdevSubsys virDomainHostdevSubsys; +typedef virDomainHostdevSubsys *virDomainHostdevSubsysPtr; +struct _virDomainHostdevSubsys { +int type; /* enum virDomainHostdevBusType */ +union { +struct { +unsigned bus; +unsigned device; + +unsigned vendor; +unsigned product; +} usb; +virDomainDevicePCIAddress pci; /* host address */ +} u; +}; + /* basic device for direct passthrough */ struct _virDomainHostdevDef { virDomainDeviceDef parent; /* higher level Def containing this */ int mode; /* enum virDomainHostdevMode */ unsigned int managed : 1; union { -struct { -int type; /* enum virDomainHostdevBusType */ -union { -struct { -unsigned bus; -unsigned device; - -unsigned vendor; -unsigned product; -} usb; -virDomainDevicePCIAddress pci; /* host address */ -} u; -} subsys; +virDomainHostdevSubsys subsys; struct { /* TBD: struct capabilities see: * https://www.redhat.com/archives/libvir-list/2008-July/msg00429.html -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 03/17] conf: reorder static functions in domain_conf.c
No code change, movement only. This is necessary to eliminate forward references. --- V2: No change src/conf/domain_conf.c | 417 1 files changed, 208 insertions(+), 209 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 26190f1..a2536de 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2515,6 +2515,214 @@ virDomainParseLegacyDeviceAddress(char *devaddr, return 0; } +static int +virDomainHostdevSubsysUsbDefParseXML(const xmlNodePtr node, + virDomainHostdevDefPtr def) +{ + +int ret = -1; +int got_product, got_vendor; +xmlNodePtr cur; + +/* Product can validly be 0, so we need some extra help to determine + * if it is uninitialized*/ +got_product = 0; +got_vendor = 0; + +cur = node-children; +while (cur != NULL) { +if (cur-type == XML_ELEMENT_NODE) { +if (xmlStrEqual(cur-name, BAD_CAST vendor)) { +char *vendor = virXMLPropString(cur, id); + +if (vendor) { +got_vendor = 1; +if (virStrToLong_ui(vendor, NULL, 0, +def-source.subsys.u.usb.vendor) 0) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(cannot parse vendor id %s), vendor); +VIR_FREE(vendor); +goto out; +} +VIR_FREE(vendor); +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + %s, _(usb vendor needs id)); +goto out; +} +} else if (xmlStrEqual(cur-name, BAD_CAST product)) { +char* product = virXMLPropString(cur, id); + +if (product) { +got_product = 1; +if (virStrToLong_ui(product, NULL, 0, +def-source.subsys.u.usb.product) 0) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(cannot parse product %s), + product); +VIR_FREE(product); +goto out; +} +VIR_FREE(product); +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + %s, _(usb product needs id)); +goto out; +} +} else if (xmlStrEqual(cur-name, BAD_CAST address)) { +char *bus, *device; + +bus = virXMLPropString(cur, bus); +if (bus) { +if (virStrToLong_ui(bus, NULL, 0, +def-source.subsys.u.usb.bus) 0) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(cannot parse bus %s), bus); +VIR_FREE(bus); +goto out; +} +VIR_FREE(bus); +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + %s, _(usb address needs bus id)); +goto out; +} + +device = virXMLPropString(cur, device); +if (device) { +if (virStrToLong_ui(device, NULL, 0, +def-source.subsys.u.usb.device) 0) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(cannot parse device %s), + device); +VIR_FREE(device); +goto out; +} +VIR_FREE(device); +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, %s, + _(usb address needs device id)); +goto out; +} +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(unknown usb source type '%s'), + cur-name); +goto out; +} +} +cur = cur-next; +} + +if (got_vendor def-source.subsys.u.usb.vendor == 0) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, +%s, _(vendor cannot be 0.)); +goto out; +} + +if (!got_vendor got_product) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, +%s, _(missing vendor)); +goto out; +} +if (got_vendor !got_product) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, +
[libvirt] [PATCH 05/17] conf: add device pointer to args of virDomainDeviceInfoIterate callback
There will be cases where the iterator callback will need to know the type of the device whose info is being operated on, and possibly even need to use some of the device's config. This patch adds a virDomainDeviceDefPtr to the args of every callback, and fills it in appropriately as the devices are iterated through. --- New patch in V2. src/conf/domain_conf.c | 112 +- src/conf/domain_conf.h |3 +- src/qemu/qemu_command.c |2 + src/qemu/qemu_hotplug.c |1 + 4 files changed, 85 insertions(+), 33 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a2536de..03f8564 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1829,6 +1829,7 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) static int virDomainDeviceInfoClearAlias(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr device ATTRIBUTE_UNUSED, virDomainDeviceInfoPtr info, void *opaque ATTRIBUTE_UNUSED) { @@ -1837,6 +1838,7 @@ static int virDomainDeviceInfoClearAlias(virDomainDefPtr def ATTRIBUTE_UNUSED, } static int virDomainDeviceInfoClearPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr device ATTRIBUTE_UNUSED, virDomainDeviceInfoPtr info, void *opaque ATTRIBUTE_UNUSED) { @@ -1852,55 +1854,101 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def, void *opaque) { int i; +virDomainDeviceDef device; -for (i = 0; i def-ndisks ; i++) -if (cb(def, def-disks[i]-info, opaque) 0) +device.type = VIR_DOMAIN_DEVICE_DISK; +for (i = 0; i def-ndisks ; i++) { +device.data.disk = def-disks[i]; +if (cb(def, device, def-disks[i]-info, opaque) 0) return -1; -for (i = 0; i def-nnets ; i++) -if (cb(def, def-nets[i]-info, opaque) 0) +} +device.type = VIR_DOMAIN_DEVICE_NET; +for (i = 0; i def-nnets ; i++) { +device.data.net = def-nets[i]; +if (cb(def, device, def-nets[i]-info, opaque) 0) return -1; -for (i = 0; i def-nsounds ; i++) -if (cb(def, def-sounds[i]-info, opaque) 0) +} +device.type = VIR_DOMAIN_DEVICE_SOUND; +for (i = 0; i def-nsounds ; i++) { +device.data.sound = def-sounds[i]; +if (cb(def, device, def-sounds[i]-info, opaque) 0) return -1; -for (i = 0; i def-nhostdevs ; i++) -if (cb(def, def-hostdevs[i]-info, opaque) 0) +} +device.type = VIR_DOMAIN_DEVICE_HOSTDEV; +for (i = 0; i def-nhostdevs ; i++) { +device.data.hostdev = def-hostdevs[i]; +if (cb(def, device, def-hostdevs[i]-info, opaque) 0) return -1; -for (i = 0; i def-nvideos ; i++) -if (cb(def, def-videos[i]-info, opaque) 0) +} +device.type = VIR_DOMAIN_DEVICE_VIDEO; +for (i = 0; i def-nvideos ; i++) { +device.data.video = def-videos[i]; +if (cb(def, device, def-videos[i]-info, opaque) 0) return -1; -for (i = 0; i def-ncontrollers ; i++) -if (cb(def, def-controllers[i]-info, opaque) 0) +} +device.type = VIR_DOMAIN_DEVICE_CONTROLLER; +for (i = 0; i def-ncontrollers ; i++) { +device.data.controller = def-controllers[i]; +if (cb(def, device, def-controllers[i]-info, opaque) 0) return -1; -for (i = 0; i def-nsmartcards ; i++) -if (cb(def, def-smartcards[i]-info, opaque) 0) +} +device.type = VIR_DOMAIN_DEVICE_SMARTCARD; +for (i = 0; i def-nsmartcards ; i++) { +device.data.smartcard = def-smartcards[i]; +if (cb(def, device, def-smartcards[i]-info, opaque) 0) return -1; -for (i = 0; i def-nserials ; i++) -if (cb(def, def-serials[i]-info, opaque) 0) +} +device.type = VIR_DOMAIN_DEVICE_CHR; +for (i = 0; i def-nserials ; i++) { +device.data.chr = def-serials[i]; +if (cb(def, device, def-serials[i]-info, opaque) 0) return -1; -for (i = 0; i def-nparallels ; i++) -if (cb(def, def-parallels[i]-info, opaque) 0) +} +for (i = 0; i def-nparallels ; i++) { +device.data.chr = def-parallels[i]; +if (cb(def, device, def-parallels[i]-info, opaque) 0) return -1; -for (i = 0; i def-nchannels ; i++) -if (cb(def, def-channels[i]-info, opaque) 0) +} +for (i = 0; i def-nchannels ; i++) { +device.data.chr = def-channels[i]; +if (cb(def, device, def-channels[i]-info, opaque) 0) return -1; -for (i = 0; i def-nconsoles ; i++) -if (cb(def, def-consoles[i]-info, opaque) 0) +} +for (i = 0; i def-nconsoles ;
[libvirt] [PATCH 04/17] qemu: rename virDomainDeviceInfoPtr variables to avoid confusion
The virDomainDeviceInfoPtrs in qemuCollectPCIAddress and qemuComparePCIDevice are named dev and dev1, but those functions will be changed (in order to match a change in the args sent to virDomainDeviceInfoIterate() callback args) to contain a virDomainDeviceDefPtr device. This patch renames dev to info (and dev[n] to info[n]) to avoid later confusion. --- new Patch in V2. src/qemu/qemu_command.c | 18 +- src/qemu/qemu_hotplug.c | 12 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 01adf0d..04e580f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -835,22 +835,22 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev) static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, - virDomainDeviceInfoPtr dev, + virDomainDeviceInfoPtr info, void *opaque) { int ret = -1; char *addr = NULL; qemuDomainPCIAddressSetPtr addrs = opaque; -if (dev-type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) +if (info-type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) return 0; -addr = qemuPCIAddressAsString(dev); +addr = qemuPCIAddressAsString(info); if (!addr) goto cleanup; if (virHashLookup(addrs-used, addr)) { -if (dev-addr.pci.function != 0) { +if (info-addr.pci.function != 0) { qemuReportError(VIR_ERR_XML_ERROR, _(Attempted double use of PCI Address '%s' (may need \multifunction='on'\ for device on function 0), @@ -867,15 +867,15 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, goto cleanup; addr = NULL; -if ((dev-addr.pci.function == 0) -(dev-addr.pci.multi != VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON)) { +if ((info-addr.pci.function == 0) +(info-addr.pci.multi != VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON)) { /* a function 0 w/o multifunction=on must reserve the entire slot */ int function; -virDomainDeviceInfo temp_dev = *dev; +virDomainDeviceInfo temp_info = *info; for (function = 1; function QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) { -temp_dev.addr.pci.function = function; -addr = qemuPCIAddressAsString(temp_dev); +temp_info.addr.pci.function = function; +addr = qemuPCIAddressAsString(temp_info); if (!addr) goto cleanup; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5c64dbe..0ca3186 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1481,17 +1481,17 @@ static inline int qemuFindDisk(virDomainDefPtr def, const char *dst) } static int qemuComparePCIDevice(virDomainDefPtr def ATTRIBUTE_UNUSED, -virDomainDeviceInfoPtr dev1, +virDomainDeviceInfoPtr info1, void *opaque) { -virDomainDeviceInfoPtr dev2 = opaque; +virDomainDeviceInfoPtr info2 = opaque; -if (dev1-type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI || -dev2-type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) +if (info1-type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI || +info2-type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) return 0; -if (dev1-addr.pci.slot == dev2-addr.pci.slot -dev1-addr.pci.function != dev2-addr.pci.function) +if (info1-addr.pci.slot == info2-addr.pci.slot +info1-addr.pci.function != info2-addr.pci.function) return -1; return 0; } -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 06/17] conf: make hostdev info a separate object
In order to allow for a virDomainHostdevDef that uses the virDomainDeviceInfo of a higher level device (such as a virDomainNetDef), this patch changes the virDomainDeviceInfo in the HostdevDef into a virDomainDeviceInfoPtr. Rather than adding checks all over the code to check for a null info, we just guarantee that it is always valid. The new function virDomainHostdevDefAlloc() allocates a virDomainDeviceInfo and plugs it in, and virDomainHostdevDefFree() makes sure it is freed. There were 4 places allocating virDomainHostdevDefs, all of them parsers of one sort or another, and those have all had their VIR_ALLOC(hostdev) changed to virDomainHostdevDefAlloc(). Other than that, and the new functions, all the rest of the changes are just mechanical removals of or changing . to -. --- V2: also add a virDomainDeviceInfoClear() function. src/conf/domain_conf.c | 63 +++--- src/conf/domain_conf.h |4 ++- src/libvirt_private.syms |2 + src/qemu/qemu_command.c | 83 - src/qemu/qemu_hotplug.c | 28 src/xenxs/xen_sxpr.c |5 ++- src/xenxs/xen_xm.c |8 +++-- 7 files changed, 114 insertions(+), 79 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 03f8564..eb66223 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -786,6 +786,15 @@ bool virDomainObjTaint(virDomainObjPtr obj, return true; } +static void +virDomainDeviceInfoFree(virDomainDeviceInfoPtr info) +{ +if (info) { +virDomainDeviceInfoClear(info); +VIR_FREE(info); +} +} + static void virDomainGraphicsAuthDefClear(virDomainGraphicsAuthDefPtr def) @@ -1294,12 +1303,42 @@ void virDomainVideoDefFree(virDomainVideoDefPtr def) VIR_FREE(def); } +virDomainHostdevDefPtr virDomainHostdevDefAlloc(void) +{ +virDomainHostdevDefPtr def = NULL; + +if (VIR_ALLOC(def) 0) { +virReportOOMError(); +return NULL; +} +if (VIR_ALLOC(def-info) 0) { +virReportOOMError(); +VIR_FREE(def); +return NULL; +} +return def; +} + +void virDomainHostdevDefClear(virDomainHostdevDefPtr def) +{ +if (!def) +return; + +/* Free all resources in the hostdevdef. Currently the only + * such resource is the virDomainDeviceInfo. + */ + +virDomainDeviceInfoFree(def-info); +} + void virDomainHostdevDefFree(virDomainHostdevDefPtr def) { if (!def) return; -virDomainDeviceInfoClear(def-info); +/* free all subordinate objects */ +virDomainHostdevDefClear(def); + VIR_FREE(def); } @@ -1877,7 +1916,7 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def, device.type = VIR_DOMAIN_DEVICE_HOSTDEV; for (i = 0; i def-nhostdevs ; i++) { device.data.hostdev = def-hostdevs[i]; -if (cb(def, device, def-hostdevs[i]-info, opaque) 0) +if (cb(def, device, def-hostdevs[i]-info, opaque) 0) return -1; } device.type = VIR_DOMAIN_DEVICE_VIDEO; @@ -2743,14 +2782,14 @@ virDomainHostdevSubsysPciDefParseXML(const xmlNodePtr node, char *devaddr = virXMLPropString(cur, devaddr); if (devaddr virDomainParseLegacyDeviceAddress(devaddr, - def-info.addr.pci) 0) { + def-info-addr.pci) 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _(Unable to parse devaddr parameter '%s'), devaddr); VIR_FREE(devaddr); goto out; } -def-info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; +def-info-type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else if ((flags VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES) xmlStrEqual(cur-name, BAD_CAST origstates)) { virDomainHostdevOrigStatesPtr states = def-origstates; @@ -6379,10 +6418,8 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, virDomainHostdevDefPtr def; char *mode, *type = NULL, *managed = NULL; -if (VIR_ALLOC(def) 0) { -virReportOOMError(); +if (!(def = virDomainHostdevDefAlloc())) return NULL; -} mode = virXMLPropString(node, mode); if (mode) { @@ -6445,8 +6482,8 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, cur = cur-next; } -if (def-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { -if (virDomainDeviceInfoParseXML(node, bootMap, def-info, +if (def-info-type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { +if (virDomainDeviceInfoParseXML(node, bootMap, def-info, flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT |
[libvirt] [PATCH 07/17] conf: HostdevDef parse/format helper functions
In an upcoming patch, virDomainNetDef will acquire a virDomainHostdevDef, and the interface XML will take on some of the elements of a hostdev. To avoid duplicating the code for parsing and formatting the source element (which will be nearly identical in these two cases), this patch factors those parts out of the HostdevDef's parse and format functions, and puts them into separate helper functions that are now called by the HostdevDef parser/formatter, and will soon be called by the NetDef parser/formatter. One change in behavior - previously virDomainHostdevDefParseXML() had diverged from current common coding practice by logging an error and failing if it found any subelements of hostdev other than those it understood (standard libvirt practice is to ignore/discard unknown elements and attributes during parse). The new helper function ignores unknown elements, and thus so does the new virDomainHostdevDefParseXML. --- V2: Unchanged from V1. src/conf/domain_conf.c | 263 +--- 1 files changed, 160 insertions(+), 103 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index eb66223..6d7c148 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2810,6 +2810,90 @@ out: return ret; } +static int +virDomainHostdevPartsParse(xmlNodePtr node, + xmlXPathContextPtr ctxt, + const char *mode, + const char *type, + virDomainHostdevDefPtr def, + unsigned int flags) +{ +xmlNodePtr sourcenode; +char *managed = NULL; +int ret = -1; + +/* @mode is passed in separately from the caller, since an + * 'intelligent hostdev' has no place for 'mode' in the XML (it is + * always 'subsys'). + */ +if (mode) { +if ((def-mode=virDomainHostdevModeTypeFromString(mode)) 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(unknown hostdev mode '%s'), mode); +goto error; +} +} else { +def-mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; +} + +/* @managed can be read from the xml document - it is always an + * attribute of the toplevel element, no matter what type of + * element that might be (pure hostdev, or higher level device + * (e.g. interface) with type='hostdev') + */ +if ((managed = virXMLPropString(node, managed))!= NULL) { +if (STREQ(managed, yes)) +def-managed = 1; +} + +/* @type is passed in from the caller rather than read from the + * xml document, because it is specified in different places for + * different kinds of defs - it is an attribute of + * source/address for an intelligent hostdev (interface), + * but an attribute of the toplevel element for a standard + * hostdev. (the functions we're going to call expect address + * type to already be known). + */ +if (type) { +if ((def-source.subsys.type + = virDomainHostdevSubsysTypeFromString(type)) 0) { +virDomainReportError(VIR_ERR_XML_ERROR, + _(unknown host device source address type '%s'), + type); +goto error; +} +} else { +virDomainReportError(VIR_ERR_XML_ERROR, + %s, _(missing source address type)); +goto error; +} + +if (!(sourcenode = virXPathNode(./source, ctxt))) { +virDomainReportError(VIR_ERR_XML_ERROR, %s, + _(Missing source element in hostdev device)); +goto error; +} +switch (def-source.subsys.type) { +case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: +if (virDomainHostdevSubsysPciDefParseXML(sourcenode, def, flags) 0) +goto error; +break; +case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: +if (virDomainHostdevSubsysUsbDefParseXML(sourcenode, def) 0) +goto error; +break; +default: +virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(address type='%s' not supported in hostdev interfaces), + virDomainHostdevSubsysTypeToString(def-source.subsys.type)); +goto error; +} +ret = 0; +error: +VIR_FREE(managed); +return ret; +} + int virDomainDiskFindControllerModel(virDomainDefPtr def, virDomainDiskDefPtr disk, @@ -6411,76 +6495,23 @@ error: static virDomainHostdevDefPtr virDomainHostdevDefParseXML(const xmlNodePtr node, +xmlXPathContextPtr ctxt, virBitmapPtr bootMap, unsigned int flags) { -xmlNodePtr cur; virDomainHostdevDefPtr def; -char *mode, *type = NULL, *managed = NULL; - -if (!(def = virDomainHostdevDefAlloc())) -return NULL; +
[libvirt] [PATCH 10/17] conf: hostdev utility functions
Three new functions useful in other files: virDomainHostdevInsert: Add a new hostdev at the end of the array. This would more sensibly be called virDomainHostdevAppend, but the existing functions for other types of devices are called Insert. virDomainHostdevRemove: Eliminates one entry from the hostdevs array, but doesn't free it; patterned after the code at the end of the two qemuDomainDetachHostXXXDevice functions (and also other pre-existing virDomainXXXRemove functions for other device types). virDomainHostdevFind: This function is patterned from the search loops at the top of qemuDomainDetachHostPciDevice and qemuDomainDetachHostUsbDevice, and will be used to re-factor those (and other detach-related) functions. --- New patch for V2. src/conf/domain_conf.c | 94 ++ src/conf/domain_conf.h |5 ++ src/libvirt_private.syms |3 + 3 files changed, 102 insertions(+), 0 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 93fd8d7..94ee634 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6769,6 +6769,100 @@ virDomainChrTargetTypeToString(int deviceType, } int +virDomainHostdevInsert(virDomainDefPtr def, virDomainHostdevDefPtr hostdev) +{ +if (VIR_REALLOC_N(def-hostdevs, def-nhostdevs + 1) 0) +return -1; +def-hostdevs[def-nhostdevs++] = hostdev; +return 0; +} + +void +virDomainHostdevRemove(virDomainDefPtr def, size_t i) +{ +if (def-nhostdevs 1) { +memmove(def-hostdevs + i, +def-hostdevs + i + 1, +sizeof(*def-hostdevs) * +(def-nhostdevs - (i + 1))); +def-nhostdevs--; +if (VIR_REALLOC_N(def-hostdevs, def-nhostdevs) 0) { +/* ignore, harmless */ +} +} else { +VIR_FREE(def-hostdevs); +def-nhostdevs = 0; +} +} + +/* Find an entry in hostdevs that matches the source spec in + * @match. return pointer to the entry in @found (if found is + * non-NULL). Returns index (within hostdevs) of matched entry, or -1 + * if no match was found. + */ +int +virDomainHostdevFind(virDomainDefPtr def, + virDomainHostdevDefPtr match, + virDomainHostdevDefPtr *found) +{ +virDomainHostdevDefPtr local_found; +virDomainHostdevSubsysPtr m_subsys = match-source.subsys; +int i; + +if (!found) +found = local_found; +*found = NULL; + +/* There is no code that uses _MODE_CAPABILITIES, and nothing to + * compare if it did, so don't allow it. + */ +if (match-mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) +return -1; + +for (i = 0 ; i def-nhostdevs ; i++) { +virDomainHostdevDefPtr compare = def-hostdevs[i]; +virDomainHostdevSubsysPtr c_subsys = compare-source.subsys; + +if ((compare-mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) || +(c_subsys-type != m_subsys-type)) { +continue; +} + +switch (m_subsys-type) +{ +case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: +if ((c_subsys-u.pci.domain == m_subsys-u.pci.domain) +(c_subsys-u.pci.bus == m_subsys-u.pci.bus) +(c_subsys-u.pci.slot == m_subsys-u.pci.slot) +(c_subsys-u.pci.function == m_subsys-u.pci.function)) { +*found = compare; +} +break; +case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: +if (m_subsys-u.usb.bus m_subsys-u.usb.device) { +/* specified by bus location on host */ +if ((c_subsys-u.usb.bus== m_subsys-u.usb.bus) +(c_subsys-u.usb.device == m_subsys-u.usb.device)) { +*found = compare; +} +} else { +/* specified by product vendor id */ +if ((c_subsys-u.usb.product == m_subsys-u.usb.product) +(c_subsys-u.usb.vendor == m_subsys-u.usb.vendor)) { +*found = compare; +} +} +break; +default: +break; +} +if (*found) +break; +} +return *found ? i : -1; +} + +int virDomainDiskIndexByName(virDomainDefPtr def, const char *name, bool allow_ambiguous) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1a29fdb..343e48d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1895,6 +1895,11 @@ int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac); int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net); int virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac); +int virDomainHostdevInsert(virDomainDefPtr def, virDomainHostdevDefPtr hostdev); +void virDomainHostdevRemove(virDomainDefPtr def, size_t i); +int virDomainHostdevFind(virDomainDefPtr def, virDomainHostdevDefPtr match, +
[libvirt] [PATCH 16/17] qemu: use virDomainNetRemove instead of inline code
The code being replaced is exactly identical to the newly global function, right down to the comment. --- New patch in V2 src/qemu/qemu_hotplug.c | 14 +- 1 files changed, 1 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index cb41388..6119108 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2158,19 +2158,7 @@ qemuDomainDetachNetDevice(struct qemud_driver *driver, detach-ifname)); networkReleaseActualDevice(detach); -if (vm-def-nnets 1) { -memmove(vm-def-nets + i, -vm-def-nets + i + 1, -sizeof(*vm-def-nets) * -(vm-def-nnets - (i + 1))); -vm-def-nnets--; -if (VIR_REALLOC_N(vm-def-nets, vm-def-nnets) 0) { -/* ignore, harmless */ -} -} else { -VIR_FREE(vm-def-nets); -vm-def-nnets = 0; -} +virDomainNetRemove(vm-def, i); virDomainNetDefFree(detach); ret = 0; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 11/17] qemu: re-order functions in qemu_hotplug.c
Code movement only, no functional change. This is necessary to prevent a forward reference in an upcoming patch. --- New patch for V2. src/qemu/qemu_hotplug.c | 289 --- 1 files changed, 145 insertions(+), 144 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index e727cfe..e9df537 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1833,150 +1833,6 @@ cleanup: return ret; } -int qemuDomainDetachNetDevice(struct qemud_driver *driver, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev) -{ -int i, ret = -1; -virDomainNetDefPtr detach = NULL; -qemuDomainObjPrivatePtr priv = vm-privateData; -int vlan; -char *hostnet_name = NULL; -virNetDevVPortProfilePtr vport = NULL; - -for (i = 0 ; i vm-def-nnets ; i++) { -virDomainNetDefPtr net = vm-def-nets[i]; - -if (!memcmp(net-mac, dev-data.net-mac, sizeof(net-mac))) { -detach = net; -break; -} -} - -if (!detach) { -qemuReportError(VIR_ERR_OPERATION_FAILED, -_(network device %02x:%02x:%02x:%02x:%02x:%02x not found), -dev-data.net-mac[0], dev-data.net-mac[1], -dev-data.net-mac[2], dev-data.net-mac[3], -dev-data.net-mac[4], dev-data.net-mac[5]); -goto cleanup; -} - -if (!virDomainDeviceAddressIsValid(detach-info, - VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { -qemuReportError(VIR_ERR_OPERATION_FAILED, -%s, _(device cannot be detached without a PCI address)); -goto cleanup; -} - -if (qemuIsMultiFunctionDevice(vm-def, detach-info)) { -qemuReportError(VIR_ERR_OPERATION_FAILED, -_(cannot hot unplug multifunction PCI device :%s), -dev-data.disk-dst); -goto cleanup; -} - -if ((vlan = qemuDomainNetVLAN(detach)) 0) { -qemuReportError(VIR_ERR_OPERATION_FAILED, -%s, _(unable to determine original VLAN)); -goto cleanup; -} - -if (virAsprintf(hostnet_name, host%s, detach-info.alias) 0) { -virReportOOMError(); -goto cleanup; -} - -qemuDomainObjEnterMonitorWithDriver(driver, vm); -if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE)) { -if (qemuMonitorDelDevice(priv-mon, detach-info.alias) 0) { -qemuDomainObjExitMonitorWithDriver(driver, vm); -virDomainAuditNet(vm, detach, NULL, detach, false); -goto cleanup; -} -} else { -if (qemuMonitorRemovePCIDevice(priv-mon, - detach-info.addr.pci) 0) { -qemuDomainObjExitMonitorWithDriver(driver, vm); -virDomainAuditNet(vm, detach, NULL, detach, false); -goto cleanup; -} -} - -if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_NETDEV) -qemuCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE)) { -if (qemuMonitorRemoveNetdev(priv-mon, hostnet_name) 0) { -qemuDomainObjExitMonitorWithDriver(driver, vm); -virDomainAuditNet(vm, detach, NULL, detach, false); -goto cleanup; -} -} else { -if (qemuMonitorRemoveHostNetwork(priv-mon, vlan, hostnet_name) 0) { -qemuDomainObjExitMonitorWithDriver(driver, vm); -virDomainAuditNet(vm, detach, NULL, detach, false); -goto cleanup; -} -} -qemuDomainObjExitMonitorWithDriver(driver, vm); - -virDomainAuditNet(vm, detach, NULL, detach, true); - -if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE) -qemuDomainPCIAddressReleaseSlot(priv-pciaddrs, -detach-info.addr.pci.slot) 0) -VIR_WARN(Unable to release PCI address on NIC); - -virDomainConfNWFilterTeardown(detach); - -if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_DIRECT) { -ignore_value(virNetDevMacVLanDeleteWithVPortProfile( - detach-ifname, detach-mac, - virDomainNetGetActualDirectDev(detach), - virDomainNetGetActualDirectMode(detach), - virDomainNetGetActualVirtPortProfile(detach), - driver-stateDir)); -VIR_FREE(detach-ifname); -} - -if ((driver-macFilter) (detach-ifname != NULL)) { -if ((errno = networkDisallowMacOnPort(driver, - detach-ifname, - detach-mac))) { -virReportSystemError(errno, - _(failed to remove ebtables rule on '%s'), - detach-ifname); -} -} - -vport = virDomainNetGetActualVirtPortProfile(detach); -if (vport
[libvirt] [PATCH 12/17] qemu: refactor hotplug detach of hostdevs
This refactoring is necessary to support hotplug detach of type=hostdev network devices, but needs to be in a separate patch to make potential debugging of regressions more practical. Rather than the lowest level functions searching for a matching device, the search is now done in the toplevel function, and an intermediate-level function (qemuDomainDetachThisHostDevice()), which expects that the device's entry is already found, is called (this intermediate function will be called by qemuDomainDetachNetDevice() in order to support detach of type=hostdev net devices) This patch should result in 0 differences in functionality. --- New patch for V2. src/qemu/qemu_hotplug.c | 228 +++ 1 files changed, 93 insertions(+), 135 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index e9df537..cb41388 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1,7 +1,7 @@ /* * qemu_hotplug.h: QEMU device hotplug management * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -1836,48 +1836,20 @@ cleanup: static int qemuDomainDetachHostPciDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virDomainHostdevDefPtr *detach_ret) + virDomainHostdevDefPtr detach, + int idx) { -virDomainHostdevDefPtr detach = NULL; qemuDomainObjPrivatePtr priv = vm-privateData; -int i, ret; +virDomainHostdevSubsysPtr subsys = detach-source.subsys; +int ret; pciDevice *pci; pciDevice *activePci; -for (i = 0 ; i vm-def-nhostdevs ; i++) { -if (vm-def-hostdevs[i]-mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || -vm-def-hostdevs[i]-source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) -continue; - -unsigned domain = vm-def-hostdevs[i]-source.subsys.u.pci.domain; -unsigned bus = vm-def-hostdevs[i]-source.subsys.u.pci.bus; -unsigned slot = vm-def-hostdevs[i]-source.subsys.u.pci.slot; -unsigned function = vm-def-hostdevs[i]-source.subsys.u.pci.function; - -if (dev-data.hostdev-source.subsys.u.pci.domain == domain -dev-data.hostdev-source.subsys.u.pci.bus == bus -dev-data.hostdev-source.subsys.u.pci.slot == slot -dev-data.hostdev-source.subsys.u.pci.function == function) { -detach = vm-def-hostdevs[i]; -break; -} -} - -if (!detach) { -qemuReportError(VIR_ERR_OPERATION_FAILED, -_(host pci device %.4x:%.2x:%.2x.%.1x not found), -dev-data.hostdev-source.subsys.u.pci.domain, -dev-data.hostdev-source.subsys.u.pci.bus, -dev-data.hostdev-source.subsys.u.pci.slot, -dev-data.hostdev-source.subsys.u.pci.function); -return -1; -} - if (qemuIsMultiFunctionDevice(vm-def, detach-info)) { qemuReportError(VIR_ERR_OPERATION_FAILED, -_(cannot hot unplug multifunction PCI device: %s), -dev-data.disk-dst); +_(cannot hot unplug multifunction PCI device: %.4x:%.2x:%.2x.%.1x), +subsys-u.pci.domain, subsys-u.pci.bus, +subsys-u.pci.slot, subsys-u.pci.function); return -1; } @@ -1899,10 +1871,8 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, if (ret 0) return -1; -pci = pciGetDevice(detach-source.subsys.u.pci.domain, - detach-source.subsys.u.pci.bus, - detach-source.subsys.u.pci.slot, - detach-source.subsys.u.pci.function); +pci = pciGetDevice(subsys-u.pci.domain, subsys-u.pci.bus, + subsys-u.pci.slot, subsys-u.pci.function); if (pci) { activePci = pciDeviceListSteal(driver-activePciHostdevs, pci); if (pciResetDevice(activePci, driver-activePciHostdevs, @@ -1921,71 +1891,20 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, detach-info-addr.pci.slot) 0) VIR_WARN(Unable to release PCI address on host device); -if (vm-def-nhostdevs 1) { -memmove(vm-def-hostdevs + i, -vm-def-hostdevs + i + 1, -sizeof(*vm-def-hostdevs) * -(vm-def-nhostdevs - (i + 1))); -vm-def-nhostdevs--; -if (VIR_REALLOC_N(vm-def-hostdevs, vm-def-nhostdevs) 0) { -/* ignore, harmless */ -} -} else { -VIR_FREE(vm-def-hostdevs); -vm-def-nhostdevs = 0; -} -if
[libvirt] [PATCH 08/17] conf: give each hostdevdef a parent pointer
The parent can be any type of device. It defaults to type=none, and a NULL pointer. The intent is that if a hostdevdef is contained in the def for a higher level device (e.g. virDomainNetDef), hostdev-parent will point to the higher level device, and type will be set to that type of device. This way, during attach and detach of the device, parent can be checked, and appropriate callouts made to do higher level device initialization (e.g. setting MAC address). Also, although these hostdevs with parents will be added to a domain's hostdevs list, they will be treated slightly differently when traversing the list, e.g. virDomainHostdefDefFree for a hostdev that has a parent doesn't need to be called (and will be a NOP); it will simply be removed from the list (since the parent device object is in its own type-specific list, and will be freed from there). --- V2: unchanged from V1 src/conf/domain_conf.c | 12 ++-- src/conf/domain_conf.h |1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6d7c148..93fd8d7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1328,7 +1328,11 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def) * such resource is the virDomainDeviceInfo. */ -virDomainDeviceInfoFree(def-info); +/* If there is a parent device object, it will handle freeing + * def-info. + */ +if (def-parent.type == VIR_DOMAIN_DEVICE_NONE) +virDomainDeviceInfoFree(def-info); } void virDomainHostdevDefFree(virDomainHostdevDefPtr def) @@ -1339,7 +1343,11 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def) /* free all subordinate objects */ virDomainHostdevDefClear(def); -VIR_FREE(def); +/* If there is a parent device object, it will handle freeing + * the memory. + */ +if (def-parent.type == VIR_DOMAIN_DEVICE_NONE) +VIR_FREE(def); } void virDomainHubDefFree(virDomainHubDefPtr def) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7815ee7..efb86bc 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -356,6 +356,7 @@ enum virDomainHostdevSubsysType { /* basic device for direct passthrough */ struct _virDomainHostdevDef { +virDomainDeviceDef parent; /* higher level Def containing this */ int mode; /* enum virDomainHostdevMode */ unsigned int managed : 1; union { -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 13/17] conf: parse/format type='hostdev' network interfaces
This is the new interface type that sets up a PCI/USB network device to be assigned to the guest with PCI/USB passthrough after initializing some network device-specific things from the config (e.g. MAC address, virtualport profile parameters). Here is an example of the syntax: interface type='hostdev' managed='yes' source address type='pci' domain='0' bus='0' slot='4' function='0'/ /source mac address='00:11:22:33:44:55'/ address type='pci' domain='0' bus='0' slot='7' function='0'/ /interface This would assign the PCI card from bus 0 slot 4 function 0 on the host, to bus 0 slot 7 function 0 on the guest, but would first set the MAC address of the card to 00:11:22:33:44:55. Although it's not expected to be used very much, usb network hostdevs are also supported for completeness. source syntax is identical to that for plain hostdev devices, except that the address element should have type='usb' added if it's specified: interface type='hostdev' source address type='usb' bus='0' device='4'/ /source mac address='00:11:22:33:44:55'/ /interface If the vendor/product form of usb specification is used, type='usb' is implied: interface type='hostdev' source vendor id='0x0012'/ product id='0x24dd'/ /source mac address='00:11:22:33:44:55'/ /interface --- V2: address Eric's concerns from V1 - check for OOM after strdup - put in a NOP virDomainHostdevDefClear() rather than just commenting there is nothing in the HostdevDef that needs to be freed - eliminate inconsistent {} usage. docs/formatdomain.html.in | 41 + docs/schemas/domaincommon.rng | 50 +++ src/conf/domain_conf.c | 154 ++-- src/conf/domain_conf.h | 10 ++ src/libvirt_private.syms |1 + src/qemu/qemu_command.c|1 + src/uml/uml_conf.c |5 + src/xenxs/xen_sxpr.c |1 + .../qemuxml2argvdata/qemuxml2argv-net-hostdev.xml | 48 ++ tests/qemuxml2xmltest.c|1 + 10 files changed, 297 insertions(+), 15 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 6fcca94..06de0ca 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2303,6 +2303,47 @@ ... /pre + +h5a name=elementsNICSHostdevPCI/USB Passthrough/a/h5 + +p + A PCI or USB network device (specified by the lt;sourcegt; + element) is directly assigned to the guest using generic device + passthrough, after first optionally setting the device's MAC + address to the configured value, and associating the device with + a VEPA or 802.1Qgh capable switch using an optionally specified + %lt;virtualport%gt; element (see the examples of virtualport + given above for type='direct' network devices). + span class=sinceSince 0.9.11/span +/p + +p + Note that this intelligent passthrough of network devices is + very similar to the functionality of a standard lt;hostdevgt; + device, the difference being that this method allows specifying + a MAC address and lt;virtualportgt; for the passed-through + device. If these capabilities are not required, of if you are + using a version of libvirt older than 0.9.11, you should use + standard lt;hostdevgt; to assign the device to the guest + instead of lt;interface type='hostdev'/gt;. +/p + +pre + ... + lt;devicesgt; +lt;interface type='hostdev'gt; + lt;sourcegt; +lt;address type='pci' domain='0x' bus='0x00' slot='0x07' function='0x0'/gt; + lt;/sourcegt; + lt;mac address='52:54:00:6d:90:02'gt; + lt;virtualport type='802.1Qbh'gt; +lt;parameters profileid='finance'/gt; + lt;/virtualportgt; +lt;/interfacegt; + lt;/devicesgt; + .../pre + + h5a name=elementsNICSMulticastMulticast tunnel/a/h5 p diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 3908733..a905457 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1416,6 +1416,56 @@ /optional /interleave /group +group + attribute name=type +valuehostdev/value + /attribute + optional +attribute name=managed + choice +valueyes/value +valueno/value + /choice +/attribute + /optional + interleave +element name=source + choice +group + ref name=usbproduct/ + optional +ref name=usbaddress/ + /optional +/group
[libvirt] [PATCH 14/17] qemu: support type='hostdev' network devices at domain start
This patch makes sure that each network device (interface) of type='hostdev' appears on both the hostdevs list and the nets list of the virDomainDef, and it modifies the qemu driver startup code so that these devices will be presented to qemu on the commandline as hostdevs rather than as network devices. It does not add support for hotplug of these type of devices, or code to honor the mac address or virtualport given in the config (both of those will be done in separate patches). Once each device is placed on both lists, much of what this patch does is modify places in the code that traverse all the device lists so that these hybrid devices are only acted on once - either along with the other hostdevs, or along with the other interfaces. (In many cases, only one of the lists is traversed / a specific operation is performed on only one type of device. In those instances, the code can remain unchanged.) There is one special case - when building the commandline, interfaces are allowed to proceed all the way through networkAllocateActualDevice() before deciding to skip - this is so that (once we have support for networks with pools of hostdev devices) we can get the actual device allocated, then rely on the loop processing all hostdevs to generate the correct commandline. --- New patch in V2. src/conf/domain_conf.c | 54 +--- src/qemu/qemu_command.c| 36 -- .../qemuxml2argvdata/qemuxml2argv-net-hostdev.args |7 +++ .../qemuxml2argvdata/qemuxml2argv-net-hostdev.xml |7 --- tests/qemuxml2argvtest.c |2 + 5 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.args diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 70e9224..7135024 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1463,6 +1463,16 @@ void virDomainDefFree(virDomainDefPtr def) if (!def) return; +/* hostdevs must be freed before nets (or any future intelligent + * hostdevs) because the pointer to the hostdev is really + * pointing into the middle of the higher level device's object, + * so the original object must still be available during the call + * to virDomainHostdevDefFree(). + */ +for (i = 0 ; i def-nhostdevs ; i++) +virDomainHostdevDefFree(def-hostdevs[i]); +VIR_FREE(def-hostdevs); + for (i = 0 ; i def-nleases ; i++) virDomainLeaseDefFree(def-leases[i]); VIR_FREE(def-leases); @@ -1519,10 +1529,6 @@ void virDomainDefFree(virDomainDefPtr def) virDomainVideoDefFree(def-videos[i]); VIR_FREE(def-videos); -for (i = 0 ; i def-nhostdevs ; i++) -virDomainHostdevDefFree(def-hostdevs[i]); -VIR_FREE(def-hostdevs); - for (i = 0 ; i def-nhubs ; i++) virDomainHubDefFree(def-hubs[i]); VIR_FREE(def-hubs); @@ -7061,6 +7067,10 @@ int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net) return -1; def-nets[def-nnets] = net; def-nnets++; +if (net-type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { +/* hostdev net devices must also exist in the hostdevs array */ +return virDomainHostdevInsert(def, net-data.hostdev.def); +} return 0; } @@ -7076,6 +7086,23 @@ int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac) static void virDomainNetRemove(virDomainDefPtr def, size_t i) { +virDomainNetDefPtr net = def-nets[i]; + +if (net-type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { +/* hostdev net devices are normally also be in the hostdevs + * array, but might have already been removed by the time we + * get here. + */ +virDomainHostdevDefPtr hostdev = net-data.hostdev.def; +size_t h; + +for (h = 0; h def-nhostdevs; h++) { +if (def-hostdevs[h] == hostdev) { +virDomainHostdevRemove(def, h); +break; +} +} +} if (def-nnets 1) { memmove(def-nets + i, def-nets + i + 1, @@ -8086,6 +8113,12 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, goto error; def-nets[def-nnets++] = net; + +/* interface type='hostdev' must also be in the hostdevs array */ +if ((net-type == VIR_DOMAIN_NET_TYPE_HOSTDEV) +(virDomainHostdevInsert(def, net-data.hostdev.def) 0)) { +goto no_memory; +} } VIR_FREE(nodes); @@ -8412,7 +8445,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, if ((n = virXPathNodeSet(./devices/hostdev, ctxt, nodes)) 0) { goto error; } -if (n VIR_ALLOC_N(def-hostdevs, n) 0) +if (n VIR_REALLOC_N(def-hostdevs, def-nhostdevs + n) 0) goto no_memory; for (i = 0 ; i n ; i++) { virDomainHostdevDefPtr hostdev; @@ -12374,9 +12407,16 @@
[libvirt] [PATCH 15/17] conf: change virDomainNetRemove from static to global
This exact code is duplicated in qemuDomainDetachNetDevice(). --- New patch in V2. (yeah, I just noticed the movement of the virDomainHostdevXX() declarations in this patch; I guess I was rearranging for consistent ordering. If this concerns anyone, I can squash it out before I push.) src/conf/domain_conf.c |2 +- src/conf/domain_conf.h |5 +++-- src/libvirt_private.syms |1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7135024..b994718 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7084,7 +7084,7 @@ int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac) return -1; } -static void virDomainNetRemove(virDomainDefPtr def, size_t i) +void virDomainNetRemove(virDomainDefPtr def, size_t i) { virDomainNetDefPtr net = def-nets[i]; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6ab5f32..a9426b3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1902,12 +1902,13 @@ int virDomainDiskRemoveByName(virDomainDefPtr def, const char *name); int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac); int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net); +void virDomainNetRemove(virDomainDefPtr def, size_t i); int virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac); -int virDomainHostdevInsert(virDomainDefPtr def, virDomainHostdevDefPtr hostdev); -void virDomainHostdevRemove(virDomainDefPtr def, size_t i); int virDomainHostdevFind(virDomainDefPtr def, virDomainHostdevDefPtr match, virDomainHostdevDefPtr *found); +int virDomainHostdevInsert(virDomainDefPtr def, virDomainHostdevDefPtr hostdev); +void virDomainHostdevRemove(virDomainDefPtr def, size_t i); int virDomainGraphicsListenGetType(virDomainGraphicsDefPtr def, size_t ii) ATTRIBUTE_NONNULL(1); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index de02634..d50d191 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -389,6 +389,7 @@ virDomainNetGetActualType; virDomainNetGetActualVirtPortProfile; virDomainNetIndexByMac; virDomainNetInsert; +virDomainNetRemove; virDomainNetRemoveByMac; virDomainNetTypeToString; virDomainNostateReasonTypeFromString; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 17/17] qemu: support type=hostdev network device hotplug attach/detach
qemuDomainAttachNetDevice - re-ordered some things at start of function because networkAllocateActualDevice should always be run and a slot in def-nets always allocated, but host_net_add isn't needed if the actual type is hostdev. - if actual type is hostdev, defer to qemuDomainAttachHostDevice (which will reach up to the NetDef for things like MAC address when necessary). After return from qemuDomainAttachHostDevice, slip directly to cleanup, since the rest of the function is specific to emulated net devices. - put assignment of new NetDef into expanded def-nets down below cleanup: (but only on success) since it is also needed for emulated and hostdev net devices. qemuDomainDetachHostDevice - after locating the exact device to detach, check if it's a network device and, if so, use toplevel qemuDomainDetachNetDevice instead so that the def-nets list is properly updated, and 'actual device' properly returned to network pool if appropriate. Otherwise, for normal hostdevs, call the lower level qemuDomainDetachThisDevice. qemuDomainDetachNetDevice - This is where it gets a bit tricky. After locating the device on the def-nets list, if the network device type == hostdev, call the *lower level* qemuDomainDetachThisDevice (which will reach back up to the parent net device for MAC address / virtualport when appropriate, then clear the device out of def-hostdevs) before skipping past all the emulated net-device-specific code to cleanup:, where the network device is removed from def-nets, and the network device object is freed. In short, any time a hostdev-type network device is detached, we must go through the toplevel virDomaineDetachNetDevice function first and last, to make sure 1) the def-nnets list is properly managed, and 2) any device allocated with networkAllocateActualDevice is properly freed. At the same time, in the middle we need to go through the lower-level virDomainDetach*This*HostDevice to be sure that 1) the def-hostdevs list is properly managed, 2) the PCI device is properly detached from the guest and reattached to the host (if appropriate), and 3) any higher level setup/teardown is called at the appropriate time, by reaching back up to the NetDef config (part (3) will be covered in a separate patch). --- src/qemu/qemu_hotplug.c | 61 +- 1 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 6119108..50563c5 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -661,9 +661,9 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, bool iface_connected = false; int actualType; -if (!qemuCapsGet(priv-qemuCaps, QEMU_CAPS_HOST_NET_ADD)) { -qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, -_(installed qemu version does not support host_net_add)); +/* preallocate new slot for device */ +if (VIR_REALLOC_N(vm-def-nets, vm-def-nnets+1) 0) { +virReportOOMError(); return -1; } @@ -672,9 +672,27 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, * to the one defined in the network definition. */ if (networkAllocateActualDevice(net) 0) -goto cleanup; +return -1; actualType = virDomainNetGetActualType(net); + +if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) { +/* This is really a smart hostdev, so it should be attached + * as a hostdev (the hostdev code will reach over into the + * netdev-specific code as appropriate), then also added to + * the nets list (see cleanup:) if successful. + */ +ret = qemuDomainAttachHostDevice(driver, vm, + virDomainNetGetActualHostdev(net)); +goto cleanup; +} + +if (!qemuCapsGet(priv-qemuCaps, QEMU_CAPS_HOST_NET_ADD)) { +qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, +_(installed qemu version does not support host_net_add)); +goto cleanup; +} + if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || actualType == VIR_DOMAIN_NET_TYPE_NETWORK) { if ((tapfd = qemuNetworkIfaceConnect(vm-def, conn, driver, net, @@ -693,9 +711,6 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto cleanup; } -if (VIR_REALLOC_N(vm-def-nets, vm-def-nnets+1) 0) -goto no_memory; - if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_NET_NAME) || qemuCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceNetAlias(vm-def, net, -1) 0) @@ -826,10 +841,10 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, ret = 0; -vm-def-nets[vm-def-nnets++] = net; - cleanup: -if (ret 0) { +if (!ret) { +vm-def-nets[vm-def-nnets++] = net; +} else { if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE)
Re: [libvirt] [PATCHv2 00/17] Support for interface type='hostdev'
On 02/28/2012 03:14 PM, Laine Stump wrote: This series of patches enhances the interface device to support a sort of intelligent hostdev, i.e. PCI passthrough where device-type specific initialization is done prior to assigning the device to the guest, in particular to allow setting the MAC address and do 802.1QbX setup for network devices. The first posting of this patch only supported parsing and formatting of these devices. This version also supports them in persistent config, as well as hotplug (both persistent and live-only). The only piece that isn't in this patchset (because it is coming from another author) is the code that actually to finish this sentence: ...is the code that actually does the network device-specific setup/teardown, i.e. setting and restoring the MAC address, and doing virtualport associate/de-associate. That code is being tested now, so should be along soon. Rather than adding all of the device-type specific config to hostdev, this is accomplished through adding a new type of interface element, type='hostdev'. When an interface is type='hostdev' the following is changed: * in the toplevel device, the managed attribute can be specified (with identical results as when it's specified in a hostdev * The source element can specify a pci address or usb address, just as can be done in hostdev. One notable difference is that the type of the address is specified directly in the source address element, rather than as an attribute of the toplevel device (that's how it's done for hostdev, but for interface, the toplevel element's type attribute is already used). NB: a type=hostdev interface will reside in both the interface list (for configuration and memory management) and hostdev list (for PCI attach/detach, and tracking of which devices are assigned)). This entire series is available on gitorious: git://gitorious.org/~laine/libvirt/laine-staging.git in the passthrough8 branch. Patches 1-7, 9-12, and 15-16 are just setup for the new functionality - they reorder and refactor existing code to allow greater re-use of existing code and easier plugin of the new code. Those marked with X are unchanged from V1 (as far as my git logs tell me). Those marked + are new patches that weren't in V1. + [PATCH 01/17] conf: add missing device types to [PATCH 02/17] conf: relocate virDomainDeviceDef and X [PATCH 03/17] conf: reorder static functions in domain_conf.c + [PATCH 04/17] qemu: rename virDomainDeviceInfoPtr variables to avoid + [PATCH 05/17] conf: add device pointer to args of [PATCH 06/17] conf: make hostdev info a separate object X [PATCH 07/17] conf: HostdevDef parse/format helper functions + [PATCH 09/17] conf: put subsys part of virDomainHostdevDef into its + [PATCH 10/17] conf: hostdev utility functions + [PATCH 11/17] qemu: re-order functions in qemu_hotplug.c + [PATCH 12/17] qemu: refactor hotplug detach of hostdevs + [PATCH 15/17] conf: change virDomainNetRemove from static to global + [PATCH 16/17] qemu: use virDomainNetRemove instead of inline code Patch 8 is just a couple lines: [PATCH 08/17] conf: give each hostdevdef a parent pointer [PATCH 13/17] conf: parse/format type='hostdev' network interfaces + [PATCH 14/17] qemu: support type='hostdev' network devices at domain start + [PATCH 17/17] qemu: support type=hostdev network device live hotplug -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Integration with XtreemFS
Hello is somebody here interested in integrating http://xtreemfs.org/ into libvirt? We're willing to pay for it and contribute it we need to take advantage of libxtreemfs; as described in this thread: https://groups.google.com/d/topic/xtreemfs/mkfPKk1YVeU/discussion Please, contact me if so. Have a great day. -- Renich Bon Ciric CloudSigma -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/2] hooks: Add support for capturing hook output
Hooks may now be used as filters. --- daemon/libvirtd.c |6 +++--- src/lxc/lxc_driver.c|6 -- src/qemu/qemu_process.c | 12 src/util/hooks.c| 22 ++ src/util/hooks.h|2 +- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index b1b542b..52e80fa 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -1148,7 +1148,7 @@ static void daemonReloadHandler(virNetServerPtr srv ATTRIBUTE_UNUSED, { VIR_INFO(Reloading configuration on SIGHUP); virHookCall(VIR_HOOK_DRIVER_DAEMON, -, -VIR_HOOK_DAEMON_OP_RELOAD, SIGHUP, SIGHUP, NULL); +VIR_HOOK_DAEMON_OP_RELOAD, SIGHUP, SIGHUP, NULL, NULL); if (virStateReload() 0) VIR_WARN(Error while reloading drivers); } @@ -1571,7 +1571,7 @@ int main(int argc, char **argv) { * an error ? */ virHookCall(VIR_HOOK_DRIVER_DAEMON, -, VIR_HOOK_DAEMON_OP_START, -0, start, NULL); +0, start, NULL, NULL); if (daemonSetupNetworking(srv, config, sock_file, sock_file_ro, @@ -1604,7 +1604,7 @@ int main(int argc, char **argv) { ret = 0; virHookCall(VIR_HOOK_DRIVER_DAEMON, -, VIR_HOOK_DAEMON_OP_SHUTDOWN, -0, shutdown, NULL); +0, shutdown, NULL, NULL); cleanup: virNetServerProgramFree(remoteProgram); diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d77afcc..d9cbd9e 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1115,7 +1115,8 @@ static void lxcVmCleanup(lxc_driver_t *driver, /* we can't stop the operation even if the script raised an error */ virHookCall(VIR_HOOK_DRIVER_LXC, vm-def-name, -VIR_HOOK_LXC_OP_STOPPED, VIR_HOOK_SUBOP_END, NULL, xml); +VIR_HOOK_LXC_OP_STOPPED, VIR_HOOK_SUBOP_END, +NULL, xml, NULL); VIR_FREE(xml); } @@ -1632,7 +1633,8 @@ lxcBuildControllerCmd(lxc_driver_t *driver, int hookret; hookret = virHookCall(VIR_HOOK_DRIVER_LXC, vm-def-name, -VIR_HOOK_LXC_OP_START, VIR_HOOK_SUBOP_BEGIN, NULL, xml); + VIR_HOOK_LXC_OP_START, VIR_HOOK_SUBOP_BEGIN, + NULL, xml, NULL); VIR_FREE(xml); /* diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 41218de..36e5ce6 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3120,7 +3120,8 @@ int qemuProcessStart(virConnectPtr conn, int hookret; hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, vm-def-name, -VIR_HOOK_QEMU_OP_PREPARE, VIR_HOOK_SUBOP_BEGIN, NULL, xml); + VIR_HOOK_QEMU_OP_PREPARE, VIR_HOOK_SUBOP_BEGIN, + NULL, xml, NULL); VIR_FREE(xml); /* @@ -3305,7 +3306,8 @@ int qemuProcessStart(virConnectPtr conn, int hookret; hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, vm-def-name, -VIR_HOOK_QEMU_OP_START, VIR_HOOK_SUBOP_BEGIN, NULL, xml); + VIR_HOOK_QEMU_OP_START, VIR_HOOK_SUBOP_BEGIN, + NULL, xml, NULL); VIR_FREE(xml); /* @@ -3726,7 +3728,8 @@ void qemuProcessStop(struct qemud_driver *driver, /* we can't stop the operation even if the script raised an error */ virHookCall(VIR_HOOK_DRIVER_QEMU, vm-def-name, -VIR_HOOK_QEMU_OP_STOPPED, VIR_HOOK_SUBOP_END, NULL, xml); +VIR_HOOK_QEMU_OP_STOPPED, VIR_HOOK_SUBOP_END, +NULL, xml, NULL); VIR_FREE(xml); } @@ -3819,7 +3822,8 @@ retry: /* we can't stop the operation even if the script raised an error */ virHookCall(VIR_HOOK_DRIVER_QEMU, vm-def-name, -VIR_HOOK_QEMU_OP_RELEASE, VIR_HOOK_SUBOP_END, NULL, xml); +VIR_HOOK_QEMU_OP_RELEASE, VIR_HOOK_SUBOP_END, +NULL, xml, NULL); VIR_FREE(xml); } diff --git a/src/util/hooks.c b/src/util/hooks.c index 110a94b..8c16a3a 100644 --- a/src/util/hooks.c +++ b/src/util/hooks.c @@ -173,7 +173,7 @@ virHookPresent(int driver) { return(1); } -/* +/** * virHookCall: * @driver: the driver number (from virHookDriver enum) * @id: an id for the object '-' if non available for example on daemon hooks @@ -181,17 +181,26 @@ virHookPresent(int driver) { * @sub_op: a sub_operation, currently unused * @extra: optional string information * @input: extra input given to the script on stdin + * @output: optional address of variable to store malloced result buffer * * Implement a hook call, where the external script for the driver is * called with the given information. This is a synchronous call, we wait for - * execution
[libvirt] [PATCH 2/2] qemu: Add pre-migration hook
This hook is called during the Prepare phase on destination host and may be used for changing domain XML. --- docs/hooks.html.in| 35 +++ src/qemu/qemu_migration.c | 40 src/util/hooks.c |3 ++- src/util/hooks.h |1 + 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/docs/hooks.html.in b/docs/hooks.html.in index 890359e..6c82c6d 100644 --- a/docs/hooks.html.in +++ b/docs/hooks.html.in @@ -120,6 +120,16 @@ called again, span class=sincesince 0.9.0/span, to allow any additional resource cleanup:br/ pre/etc/libvirt/hooks/qemu guest_name release end -/pre/li + lispan class=sinceSince 0.9.11/span, the qemu hook script +is also called at the beginning of incoming migration. It is called +as: pre/etc/libvirt/hooks/qemu guest_name migrate begin -/pre +with domain XML sent to standard input of the script. In this case, +the script acts as a filter and is supposed to modify the domain +XML and print it out on its standard output. Empty output is +identical to copying the input XML without changing it. In case the +script returns failure or the output XML is not valid, incoming +migration will be canceled. This hook may be used to, e.g., change +location of disk images for incoming domains./li /ul h5a name=lxc/etc/libvirt/hooks/lxc/a/h5 @@ -161,19 +171,20 @@ source and destination hosts:/p ol liAt the beginning of the migration, the iqemu/i hook script on - the bdestination/b host is executed with the start - operation.br/br//li - liIf this hook script returns indicating success (error code 0), the - migration continues. Any other return code indicates failure, and - the migration is aborted.br/br//li - liThe QEMU guest is then migrated to the destination host.br/ - br//li + the bdestination/b host is executed with the migrate + operation./li + liBefore QEMU process is spawned, the two operations (prepare and + start) called for domain start are executed on + bdestination/b host./li + liIf any of these hook script executions returns indicating success + (error code 0), the migration continues. Any other return code + indicates failure, and the migration is aborted./li + liThe QEMU guest is then migrated to the destination host./li liUnless an error occurs during the migration process, the iqemu/i - hook script on the bsource/b host is then executed with the stopped - operation, to indicate it is no longer running on this - host.br/br/ - Regardless of the return code from this hook script, the migration - is not aborted as it has already been performed./li + hook script on the bsource/b host is then executed with the + stopped and release operations to indicate it is no longer + running on this host. Regardless of the return codes, the + migration is not aborted as it has already been performed./li /ol br/ diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 7df2d4f..d00bd61 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -47,6 +47,7 @@ #include rpc/virnetsocket.h #include storage_file.h #include viruri.h +#include hooks.h #define VIR_FROM_THIS VIR_FROM_QEMU @@ -1130,6 +1131,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, qemuMigrationCookiePtr mig = NULL; bool tunnel = !!st; char *origname = NULL; +char *xmlout = NULL; if (virTimeMillisNow(now) 0) return -1; @@ -1150,6 +1152,43 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, goto cleanup; } +/* Let migration hook filter domain XML */ +if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) { +char *xml = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE); +int hookret; + +hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def-name, + VIR_HOOK_QEMU_OP_MIGRATE, VIR_HOOK_SUBOP_BEGIN, + NULL, xml, xmlout); +VIR_FREE(xml); + +if (hookret 0) { +goto cleanup; +} else if (hookret == 0) { +if (!*xmlout) { +VIR_DEBUG(Migrate hook filter returned nothing; using the + original XML); +} else { +virDomainDefPtr newdef; + +VIR_DEBUG(Using hook-filtered domain XML: %s, xmlout); +newdef = virDomainDefParseString(driver-caps, xmlout, + QEMU_EXPECTED_VIRT_TYPES, + VIR_DOMAIN_XML_INACTIVE); +if (!newdef) +goto cleanup; + +
[libvirt] [PATCH 0/2] qemu: Add pre-migration hook
Current dxml parameter of virDomainMigrate{,ToURI}2 requires the caller to have deep knowlege of the environment on the target machine. In some cases, this may be impractical or even impossible to achieve. By adding per-migration hook which may filter incoming domain XML and change it appropriately called during the Prepare phase the destination host may filter incoming domain XMLs and change them to fit local environment. For example, such hook may relocate disk images. The hook is not allowed to make guest-visible changes to a domain XML. Jiri Denemark (2): hooks: Add support for capturing hook output qemu: Add pre-migration hook daemon/libvirtd.c |6 +++--- docs/hooks.html.in| 35 +++ src/lxc/lxc_driver.c |6 -- src/qemu/qemu_migration.c | 40 src/qemu/qemu_process.c | 12 src/util/hooks.c | 25 - src/util/hooks.h |3 ++- 7 files changed, 100 insertions(+), 27 deletions(-) -- 1.7.8.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [Resending] [PATCH 2/2] Allow x86 to fetch sysinfo from /proc/cpuinfo when dmidecode is absent.
On 02/28/2012 12:58 PM, Daniel P. Berrange wrote: On Fri, Feb 17, 2012 at 01:00:22PM +0530, Prerna wrote: The last patch was mangled by my mailer, resending. From: Prerna Saxena pre...@linux.vnet.ibm.com Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system. Until now, libvirt on x86 flags an error message if dmidecode is not found. With this patch, the following is a sample output on x86 when dmidecode is absent: --- src/util/sysinfo.c | 95 +-- 1 files changed, 91 insertions(+), 4 deletions(-) ACK NACK; we need a v2 for both patches. You had TABs (run 'make syntax-check'), and this compiler warning is evidence of a real bug: util/sysinfo.c: In function 'virSysinfoParseCPUInfoProcessor': util/sysinfo.c:622:9: error: passing argument 1 of 'virSkipSpaces' from incompatible pointer type [-Werror] util/util.h:162:6: note: expected 'const char **' but argument is of type 'char **' Looking at that code: if ((eol) ((processor-processor_socket_destination = strndup(cur, eol - cur)) == NULL)) goto no_memory; virSkipSpaces((processor-processor_socket_destination)); but virSkipSpaces is _designed_ to advance the pointer. Which means that when you later call VIR_FREE on the altered pointer, you aren't freeing the pointer returned by the malloc inside strndup, but are instead freeing some random address occurring later in the allocated chunk of memory - a surefire way to corrupt your heap. I didn't compile-test the PowerPC code, but see the same bug there by inspection. If you want to skip spaces, you need to skip them in 'cur', prior to calling strndup; something like: diff --git i/src/util/sysinfo.c w/src/util/sysinfo.c index de78d23..f8095e5 100644 --- i/src/util/sysinfo.c +++ w/src/util/sysinfo.c @@ -602,13 +602,15 @@ no_memory: static int virSysinfoParseCPUInfoProcessor(const char *base, virSysinfoDefPtr ret) { -char *cur, *eol, *tmp_base; +const char *cur; +char *eol, *tmp_base; virSysinfoProcessorDefPtr processor; while((tmp_base = strstr(base, processor)) != NULL) { base = tmp_base; eol = strchr(base, '\n'); cur = strchr(base, ':') + 1; +virSkipSpaces(cur); if (VIR_EXPAND_N(ret-processor, ret-nprocessor, 1) 0) { goto no_memory; @@ -619,7 +621,6 @@ virSysinfoParseCPUInfoProcessor(const char *base, virSysinfoDefPtr ret) ((processor-processor_socket_destination = strndup(cur, eol - cur)) == NULL)) goto no_memory; -virSkipSpaces((processor-processor_socket_destination)); if ((cur = strstr(base, vendor_id)) != NULL) { cur = strchr(cur, ':') + 1; -- Eric Blake ebl...@redhat.com+1-919-301-3266 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] [Resending] [PATCH 2/2] Allow x86 to fetch sysinfo from /proc/cpuinfo when dmidecode is absent.
On 02/17/2012 12:30 AM, Prerna wrote: The last patch was mangled by my mailer, resending. From: Prerna Saxena pre...@linux.vnet.ibm.com Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system. +processor = ret-processor[ret-nprocessor - 1]; +if ((eol) +((processor-processor_socket_destination = + strndup(cur, eol - cur)) == NULL)) This is over-parenthesized; I would write it: if (eol (processor-processor_socket_destination = strndup(cur, eol - cur)) == NULL) -- Eric Blake ebl...@redhat.com+1-919-301-3266 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/2] hooks: Add support for capturing hook output
On 02/28/2012 02:49 PM, Jiri Denemark wrote: Hooks may now be used as filters. --- daemon/libvirtd.c |6 +++--- src/lxc/lxc_driver.c|6 -- src/qemu/qemu_process.c | 12 src/util/hooks.c| 22 ++ src/util/hooks.h|2 +- 5 files changed, 34 insertions(+), 14 deletions(-) ACK. -- Eric Blake ebl...@redhat.com+1-919-301-3266 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 2/2] qemu: Add pre-migration hook
On 02/28/2012 02:49 PM, Jiri Denemark wrote: This hook is called during the Prepare phase on destination host and may be used for changing domain XML. --- docs/hooks.html.in| 35 +++ src/qemu/qemu_migration.c | 40 src/util/hooks.c |3 ++- src/util/hooks.h |1 + 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/docs/hooks.html.in b/docs/hooks.html.in index 890359e..6c82c6d 100644 --- a/docs/hooks.html.in +++ b/docs/hooks.html.in @@ -120,6 +120,16 @@ called again, span class=sincesince 0.9.0/span, to allow any additional resource cleanup:br/ pre/etc/libvirt/hooks/qemu guest_name release end -/pre/li + lispan class=sinceSince 0.9.11/span, the qemu hook script +is also called at the beginning of incoming migration. It is called +as: pre/etc/libvirt/hooks/qemu guest_name migrate begin -/pre +with domain XML sent to standard input of the script. In this case, +the script acts as a filter and is supposed to modify the domain +XML and print it out on its standard output. Empty output is +identical to copying the input XML without changing it. In case the +script returns failure or the output XML is not valid, incoming +migration will be canceled. This hook may be used to, e.g., change I think this reads better as: s/used to, e.g., change/used, e.g., to change/ +location of disk images for incoming domains./li /ul h5a name=lxc/etc/libvirt/hooks/lxc/a/h5 @@ -161,19 +171,20 @@ source and destination hosts:/p ol liAt the beginning of the migration, the iqemu/i hook script on - the bdestination/b host is executed with the start - operation.br/br//li - liIf this hook script returns indicating success (error code 0), the - migration continues. Any other return code indicates failure, and - the migration is aborted.br/br//li - liThe QEMU guest is then migrated to the destination host.br/ - br//li + the bdestination/b host is executed with the migrate + operation./li + liBefore QEMU process is spawned, the two operations (prepare and + start) called for domain start are executed on + bdestination/b host./li + liIf any of these hook script executions returns indicating success + (error code 0), the migration continues. Any other return code + indicates failure, and the migration is aborted./li This reads awkwardly - it makes it sound like 'prepare' exiting with 0 makes the overall operation succeed even if 'start' exits with non-zero. I'd change it to: If both of these hook script executions exit successfully (exit status 0), the migration continues. Any other exit code indicates failure, and the migration is aborted. @@ -1150,6 +1152,43 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, goto cleanup; } +/* Let migration hook filter domain XML */ +if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) { +char *xml = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE); +int hookret; + +hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def-name, + VIR_HOOK_QEMU_OP_MIGRATE, VIR_HOOK_SUBOP_BEGIN, + NULL, xml, xmlout); Needs to check for xml being NULL on OOM before virHookCall. ACK with those issues fixed. -- Eric Blake ebl...@redhat.com+1-919-301-3266 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/4] libvirt-guests: Add documentation and clean up to use virsh's improved list
On 02/28/2012 11:00 AM, Peter Krempa wrote: This patch adds documentation to functions defined in the libvirt-guests init script and changes use of virsh's new commands to make the script easier. --- tools/libvirt-guests.init.sh | 60 -- 1 files changed, 40 insertions(+), 20 deletions(-) +# guest_is_on URI UUID +# check if guest UUID on URI is runnig s/runnig/running/ +# shutdown_guest URI GUEST +# Start a ACPI shutdown of GUEST on URI. This function return after the quest +# was successfuly shutdown or the timeout defined by $SHUTDOWN_TIMEOUT expires. s/successfuly/successfully/ ACK with typos fixed. -- Eric Blake ebl...@redhat.com+1-919-301-3266 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 2/4] libvirt-guests: Don't try to do a managed-save of transient guests
On 02/28/2012 11:00 AM, Peter Krempa wrote: The libvirt-guests script tried to do a managed save of transient guest that failed. This patch notifies which guests are transient (and not being saved) and saves only the persistent ones. --- tools/libvirt-guests.init.sh | 37 +++-- 1 files changed, 35 insertions(+), 2 deletions(-) ACK with one fix: +# reload domain list to contain only persistent guests +list=$(list_guests $uri --persistent) +if [ $? -ne 0 ]; then +eval_gettext Failed to list persistent guests on \$uri +echo +RETVAL=1 +return +fi else +gettext Failed to list transient guests echo -echo $uri $list $LISTFILE +RETVAL=1 +return Before these two return statements, you need to add a 'set +f' statement; fi fi + +if [ -n $list ]; then +echo $uri $list $LISTFILE +fi done set +f since both of those early exits need to leave the function in the same state as if you exited normally. -- Eric Blake ebl...@redhat.com+1-919-301-3266 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] [libvirt-glib] Remove now redundant 'path' property
From: Zeeshan Ali (Khattak) zeesha...@gnome.org Remove now redundant 'path' property from GVirDomainDevice subclasses. These classes now have access to their configurations, from which they can easily get the path (among other properties) internally. --- libvirt-gobject/libvirt-gobject-domain-disk.c | 88 libvirt-gobject/libvirt-gobject-domain-disk.h |3 +- libvirt-gobject/libvirt-gobject-domain-interface.c | 89 +++- libvirt-gobject/libvirt-gobject-domain-interface.h |3 +- 4 files changed, 31 insertions(+), 152 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain-disk.c b/libvirt-gobject/libvirt-gobject-domain-disk.c index fb7672e..42e0e6c 100644 --- a/libvirt-gobject/libvirt-gobject-domain-disk.c +++ b/libvirt-gobject/libvirt-gobject-domain-disk.c @@ -34,75 +34,22 @@ #define GVIR_DOMAIN_DISK_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN_DISK, GVirDomainDiskPrivate)) -struct _GVirDomainDiskPrivate -{ -gchar *path; -}; - G_DEFINE_TYPE(GVirDomainDisk, gvir_domain_disk, GVIR_TYPE_DOMAIN_DEVICE); -enum { -PROP_0, -PROP_PATH, -}; - #define GVIR_DOMAIN_DISK_ERROR gvir_domain_disk_error_quark() - static GQuark gvir_domain_disk_error_quark(void) { return g_quark_from_static_string(gvir-domain-disk); } -static void gvir_domain_disk_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ -GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); -GVirDomainDiskPrivate *priv = self-priv; - -switch (prop_id) { -case PROP_PATH: -g_value_set_string(value, priv-path); -break; - -default: -G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); -} -} - - -static void gvir_domain_disk_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ -GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); -GVirDomainDiskPrivate *priv = self-priv; - -switch (prop_id) { -case PROP_PATH: -g_free(priv-path); -priv-path = g_value_dup_string(value); -break; - -default: -G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); -} -} - - static void gvir_domain_disk_finalize(GObject *object) { GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); -GVirDomainDiskPrivate *priv = self-priv; g_debug(Finalize GVirDomainDisk=%p, self); -g_free(priv-path); - G_OBJECT_CLASS(gvir_domain_disk_parent_class)-finalize(object); } @@ -111,27 +58,11 @@ static void gvir_domain_disk_class_init(GVirDomainDiskClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class-finalize = gvir_domain_disk_finalize; -object_class-get_property = gvir_domain_disk_get_property; -object_class-set_property = gvir_domain_disk_set_property; - -g_object_class_install_property(object_class, -PROP_PATH, -g_param_spec_string(path, -Path, -The disk path, -NULL, -G_PARAM_READWRITE | -G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - -g_type_class_add_private(klass, sizeof(GVirDomainDiskPrivate)); } static void gvir_domain_disk_init(GVirDomainDisk *self) { g_debug(Init GVirDomainDisk=%p, self); - -self-priv = GVIR_DOMAIN_DISK_GET_PRIVATE(self); } static GVirDomainDiskStats * @@ -151,6 +82,15 @@ gvir_domain_disk_stats_free(GVirDomainDiskStats *stats) G_DEFINE_BOXED_TYPE(GVirDomainDiskStats, gvir_domain_disk_stats, gvir_domain_disk_stats_copy, gvir_domain_disk_stats_free) +static const gchar *gvir_domain_disk_get_path(GVirDomainDisk *self) +{ +GVirConfigDomainDevice *config; + +config = gvir_domain_device_get_config(GVIR_DOMAIN_DEVICE(self)); + +return gvir_config_domain_disk_get_target_dev (GVIR_CONFIG_DOMAIN_DISK (config)); +} + /** * gvir_domain_disk_get_stats: * @self: the domain disk @@ -166,15 +106,15 @@ GVirDomainDiskStats *gvir_domain_disk_get_stats(GVirDomainDisk *self, GError **e { GVirDomainDiskStats *ret = NULL; virDomainBlockStatsStruct stats; -GVirDomainDiskPrivate *priv; virDomainPtr handle; +const gchar *path; g_return_val_if_fail(GVIR_IS_DOMAIN_DISK(self), NULL); -priv = self-priv; handle =
Re: [libvirt] [PATCH 3/4] libvirt-guests: Check if URI is reachable before launching commands
On 02/28/2012 11:00 AM, Peter Krempa wrote: This patch adds a check to the libvirt-guests script to check for the URI to be alive before attempting any calls. This avoids nasty error messages and allows us to fail gracefuly and continue on other URIs s/gracefuly/gracefully/ configured in the script. --- tools/libvirt-guests.init.sh | 24 +++- 1 files changed, 19 insertions(+), 5 deletions(-) ACK. -- Eric Blake ebl...@redhat.com+1-919-301-3266 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 4/4] libvirt-guests: Add parallel startup and shutdown of guests
On 02/28/2012 11:00 AM, Peter Krempa wrote: With this patch, it's possible to shut down guests in parallel. Parallel startup was possible before, but this functionality was not documented properly. To enable parallel startup set the START_DELAY to 0. Parallel shutdown has a configurable parameter PARALLEL_SHUTDOWN that defines the number of machines being shut down in parallel. Enabling this feature changes the semantics of SHUTDOWN_TIMEOUT parameter that is applied as a cumulative timeout to shutdown all guests on a URI. --- tools/libvirt-guests.init.sh | 140 +++-- tools/libvirt-guests.sysconf | 10 +++- 2 files changed, 141 insertions(+), 9 deletions(-) Missing an initialization of PARALLEL_SHUTDOWN=0 alongside SHUTDOWN_TIMEOUT=0 before sourcing the user's values. + +# check_domains_shutdown URI GUESTS +# check if shutdown is complete on guests in GUESTS and returns only +# guests that are still shutting down +check_domains_shutdown() +{ +uri=$1 +guests=$2 + +guests_up= +for guest in $guests; do +guest_is_on $uri $dom 21 /dev/null || continue You want '/dev/null 21' (order matters, when silencing a command and using it just for its side effects). But are we sure we want to silently ignore a guest_is_on failure, or should we emit a message stating that we are no longer able to track the shutdown status of that guest? +print_domains_shutdown() +{ +uri=$1 +before=$2 +after=$3 + +for guest in $before; do +found=false +for running in $after; do + if [ $guest = $running ]; then + found=true + break + fi +done slightly faster to do: for guest in $before; do found=false; case $after in * $guest *) found=true ;; esac But what you have is functionally correct. + +if ! $found; then +name=$(guest_name $uri $guest) +eval_gettext Shutdown of guest \$name complete. +echo +fi +done +} + +# shutdown_guests_parallel URI GUESTS +# Shutdown guests GUESTS on machine URI in parallel +shutdown_guests_parallel() +{ +uri=$1 +guests=$2 + +on_shutdown= +timeout=$SHUTDOWN_TIMEOUT If SHUTDOWN_TIMEOUT is the default of 0, then this function times out right away; shouldn't that really mean that we have no maximum timeout, and wait until everything has shut down? I think you need another variable, based on whether $timeout is 0 on entry, and skip the $((timeout - 1)) calculation if that variable is true. +while [ -n $on_shutdown ] || [ -n $guests ]; do +while [ -n $guests ] + [ $(guest_count $on_shutdown) -lt $PARALLEL_SHUTDOWN ]; do +guest=$(guest_first $guests) +guests=$(guest_remove $guest $guests) Faster to avoid these two sub-shells by doing: set -- $guests guest=$1 shift guests=$* and might even get rid of the need for some helper functions. But what you have is functionally correct. @@ -23,7 +24,12 @@ # value suitable for your guests. #ON_SHUTDOWN=suspend -# number of seconds we're willing to wait for a guest to shut down +# If set to non-zero, shutdown will suspend domains concurently. Number of domains s/concurently/concurrently/ I think it's probably worth a v2 (or is it v3?) for just this patch. -- Eric Blake ebl...@redhat.com+1-919-301-3266 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] storage: fix a typo
* src/storage/storage_driver.c (storageVolumeWipeInternal): s/shneier/schneier. http://code.google.com/p/diskscrub/ Signed-off-by: Alex Jia a...@redhat.com --- src/storage/storage_driver.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index df0e291..540e5d7 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1931,7 +1931,7 @@ storageVolumeWipeInternal(virStorageVolDefPtr def, alg_char = gutmann; break; case VIR_STORAGE_VOL_WIPE_ALG_SCHNEIER: -alg_char = shneier; +alg_char = schneier; break; case VIR_STORAGE_VOL_WIPE_ALG_PFITZNER7: alg_char = pfitzner7; -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] util: fix a typo
* src/util/event_poll.c: (virEventPollRunOnce): s/imeout/timeout/. Signed-off-by: Alex Jia a...@redhat.com --- src/util/event_poll.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/util/event_poll.c b/src/util/event_poll.c index 30dec74..038e75f 100644 --- a/src/util/event_poll.c +++ b/src/util/event_poll.c @@ -615,7 +615,7 @@ int virEventPollRunOnce(void) { retry: PROBE(EVENT_POLL_RUN, - nhandles=%d imeout=%d, + nhandles=%d timeout=%d, nfds, timeout); ret = poll(fds, nfds, timeout); if (ret 0) { -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Do not include binaries in EXTRA_DIST
commit f27f616ff899732fe90ce1f0f4abb3887cea5e17 broke make dist by adding qemumonitortest which is a generated binary to the EXTRA_DIST, hence breaking make dist Pushed as trivial build breaker. diff --git a/tests/Makefile.am b/tests/Makefile.am index 3e505a5..0c8cf37 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -72,7 +72,6 @@ EXTRA_DIST = \ nwfilterxml2xmlout \ oomtrace.pl \ qemuhelpdata \ - qemumonitortest \ qemuxml2argvdata \ qemuxml2xmloutdata \ qemuxmlnsdata \ -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ dan...@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list