Re: [libvirt] libvirt XML format.
On 18/02/10 05:28, Kumar L Srikanth-B22348 wrote: Now, I created a bridge br0 in the host machine with the IP 172.16.1.10. I want to assign an IP address[172.16.1.15] to the domain, so that the host machine and domain will ping each other. I tried to assign 'default' network to the domain by adding the following XML block to the above XML file: interface type='network' source network='default'/ /interface But, when I start the domain I got the following error in the virsh console: error: Failed to start domain vm1_fedora error: Failed to add veth0 device to virbr0: No such device I'm not at all familiar with LXC domains, however I think I can see the problem. The above network definition is for a managed network called 'default'. You can see its configuration using virsh. Here's mine: # virsh net-dumpxml default network namedefault/name uuid593e1d02-48b6-4ca2-ab49-8b1bca4ddb50/uuid forward mode='nat'/ bridge name='virbr0' stp='on' delay='0' / ip address='192.168.122.1' netmask='255.255.255.0' dhcp range start='192.168.122.2' end='192.168.122.254' / /dhcp /ip /network Note that the bridge is called 'virbr0'. You don't seem to have virbr0 on your system, so my guess is the default network has been stopped or unconfigured somehow. However, it doesn't sound like you want to use a managed network, you want to use your existing bridge. You need to replace your XML above with the following: interface type='bridge' source bridge='br0'/ /interface For more info have a look here: http://libvirt.org/formatdomain.html#elementsNIC Note the sections 'Virtual network' and 'Bridge to LAN'. Matt -- Matthew Booth, RHCA, RHCSS Red Hat Engineering, Virtualisation Team M: +44 (0)7977 267231 GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] virsh: be careful to return FALSE upon OOM
Clang reported this as a dead store to ret. Here's one way to fix it. Or just return FALSE; and remove the preceding assignment. From debb6f5198027a056aa24dca95ea4930184ad3fe Mon Sep 17 00:00:00 2001 From: Jim Meyering meyer...@redhat.com Date: Thu, 18 Feb 2010 11:05:38 +0100 Subject: [PATCH] virsh: be careful to return FALSE upon OOM * tools/virsh.c (cmdCPUBaseline): Add an explicit return statement after the no_memory: label. --- tools/virsh.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index e1d1300..dd916f3 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -7141,6 +7141,7 @@ cleanup: no_memory: vshError(ctl, %s, _(Out of memory)); ret = FALSE; +return ret; } /* Common code for the edit / net-edit / pool-edit functions which follow. */ -- 1.7.0.233.g05e1a -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] get_virtual_functions_linux: would mistakenly always return zero
Clang reported this as a dead store, too. From 016fbfb87fdafb7b6ffdea17f07af223206b0308 Mon Sep 17 00:00:00 2001 From: Jim Meyering meyer...@redhat.com Date: Thu, 18 Feb 2010 11:12:17 +0100 Subject: [PATCH] get_virtual_functions_linux: would mistakenly always return zero * src/node_device/node_device_linux_sysfs.c(get_virtual_functions_linux): Return ret, rather than always returning 0. --- src/node_device/node_device_linux_sysfs.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c index e11fb2e..c4d1d01 100644 --- a/src/node_device/node_device_linux_sysfs.c +++ b/src/node_device/node_device_linux_sysfs.c @@ -375,7 +375,7 @@ out: if (dir) closedir(dir); VIR_FREE(device_link); -return 0; +return ret; } #endif /* __linux__ */ -- 1.7.0.233.g05e1a -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Check out my photos on Facebook
Hi Libvir-list, I set up a Facebook profile where I can post my pictures, videos and events and I want to add you as a friend so you can see it. First, you need to join Facebook! Once you join, you can also create your own profile. Thanks, Anuj To sign up for Facebook, follow the link below: http://www.facebook.com/p.php?i=10789786934k=Z6E3Y5PS3YVAVA1JPB63QTWRU31JYTVNUWFWGK4FURr Already have an account? Add this email address to your account http://www.facebook.com/n/?merge_accounts.phpe=libvir-l...@redhat.comc=1f4bc10bdb10e47dccb429803b117bf5.libvir-l...@redhat.com was invited to join Facebook by Anuj Rampal. If you do not wish to receive this type of email from Facebook in the future, please click on the link below to unsubscribe. http://www.facebook.com/o.php?k=07f024u=10616939699mid=1e71081G5af3354000b3G0G8 Facebook's offices are located at 1601 S. California Ave., Palo Alto, CA 94304. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Fix DSO linking problem for nodeinfotest
On Wed, Feb 17, 2010 at 04:37:17PM +0100, Daniel Veillard wrote: Following changes in Fedora about exposing shared libraries dependancies, libvirt built failed for one of the test binaries because it didn't explicitely required -ldl gcc -DHAVE_CONFIG_H -I. -I.. -I../gnulib/lib -I../gnulib/lib -I../include -I../include -I../src -I../src/util -I../src/conf -I/usr/include/libxml2 -DGETTEXT_PACKAGE=\libvirt\ -Wall -Wformat -Wformat-security -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wextra -Wshadow -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Winline -Wredundant-decls -Wno-sign-compare -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fasynchronous-unwind-tables -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -c nodeinfotest.c CCLD nodeinfotest /usr/bin/ld: ../src/.libs/libvirt_test.a(libvirt_driver_vbox_la-vbox_XPCOMCGlue.o): undefined reference to symbol 'dlopen@@GLIBC_2.1' /usr/bin/ld: note: 'dlopen@@GLIBC_2.1' is defined in DSO /lib/libdl.so.2 so try adding it to the linker command line /lib/libdl.so.2: could not read symbols: Invalid operation collect2: ld returned 1 exit status the following patch fixes it, This isn't corect. nodeinfotest isn't the thing that is ultimately using libdl. The place we need it is in src/Makefile.am against libvirt_driver_vbox_la_LDFLAGS NB, we also need to adjust the configure.ac check Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Add build require for xmlrpc-c-client
On Wed, Feb 17, 2010 at 06:03:53PM +0100, Daniel Veillard wrote: libxmlrpc_client.so.3 moved from xmlrpc-c-devel to xmlrpc-c-client in latest release :-( This is a bug in xmlrpc-c-devel then. xmlrpc-c-devel needs to have a BuildRequires: xmlrpc-c-client added. We shouldn't work-around this broken dep in libvirt Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Update QEMU JSON balloon command handling
On Tue, Feb 16, 2010 at 05:48:41PM +0100, Daniel Veillard wrote: On Tue, Feb 16, 2010 at 04:32:34PM +, Daniel P. Berrange wrote: The QEMU JSON monitor changed balloon commands to return/accept bytes instead of kilobytes. Update libvirt to cope with this * src/qemu/qemu_monitor_json.c: Expect/use bytes for ballooning --- src/qemu/qemu_monitor_json.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index c20d063..4d52ad0 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -729,14 +729,14 @@ int qemuMonitorJSONGetBalloonInfo(qemuMonitorPtr mon, goto cleanup; } -if (virJSONValueObjectGetNumberUlong(data, balloon, mem) 0) { +if (virJSONValueObjectGetNumberUlong(data, actual, mem) 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, %s, _(info balloon reply was missing balloon data)); shouldn't we also update the error message ? Hehe, it was co-incidence that the word 'balloon' matching the data item previously - I hadn't intended it that way :-) ret = -1; goto cleanup; } -*currmem = mem; +*currmem = (mem/1024); ret = 1; } } @@ -891,7 +891,7 @@ int qemuMonitorJSONSetBalloon(qemuMonitorPtr mon, { int ret; virJSONValuePtr cmd = qemuMonitorJSONMakeCommand(balloon, - U:value, (unsigned long long)newmem, + U:value, ((unsigned long long)newmem)*1024, NULL); virJSONValuePtr reply = NULL; if (!cmd) ACK, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/2] Add domain support for virtio channel
On Wed, Feb 17, 2010 at 05:11:00PM +, Matthew Booth wrote: Add support for virtio-serial by defining a new 'virtio' channel target type and a virtio-serial controller. Allows the following to be specified in a domain: controller type='virtio-serial' index='0' max_ports='16' vectors='4'/ channel type='pty' target type='virtio' name='org.linux-kvm.port.0'/ address type='virtio-serial' controller='0' bus='0'/ /channel * docs/schemas/domain.rng: Add virtio-serial controller and virtio channel type. * src/conf/domain_conf.[ch]: Domain parsing/serialization for virtio-serial controller and virtio channel. * tests/qemuxml2xmltest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml : add domain xml parsing test * src/libvirt_private.syms src/qemu/qemu_conf.c: virDomainDefAddDiskControllers() renamed to virDomainDefAddImplicitControllers() --- docs/schemas/domain.rng| 71 +- src/conf/domain_conf.c | 234 +--- src/conf/domain_conf.h | 25 ++- src/libvirt_private.syms |2 +- src/qemu/qemu_conf.c |2 +- .../qemuxml2argv-channel-virtio.xml| 35 +++ tests/qemuxml2xmltest.c|1 + 7 files changed, 320 insertions(+), 50 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 53b82ce..85df8b8 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -523,16 +523,36 @@ /define define name=controller element name=controller - optional -attribute name=type - choice -valuefdc/value -valueide/value -valuescsi/value -valuesata/value - /choice -/attribute - /optional + choice +group + optional +attribute name=type + choice +valuefdc/value +valueide/value +valuescsi/value +valuesata/value + /choice +/attribute + /optional +/group +!-- virtio-serial can have 2 additional attributes -- +group + attribute name=type +valuevirtio-serial/value + /attribute + optional +attribute name=max_ports + ref name=unsignedInt/ +/attribute + /optional + optional +attribute name=vectors + ref name=unsignedInt/ +/attribute + /optional What are these two new attributes doing ? Can't we just auto-assign those values based on the configured channels later int he XML. +/group + /choice attribute name=index ref name=unsignedInt/ /attribute @@ -1139,12 +1159,25 @@ attribute name=port/ /element /define + define name=virtioTarget +element name=target + attribute name=type + valuevirtio/value + /attribute + optional +attribute name=name/ + /optional +/element + /define define name=channel element name=channel ref name=qemucdevSrcType/ interleave ref name=qemucdevSrcDef/ -ref name=guestfwdTarget/ +choice + ref name=guestfwdTarget/ + ref name=virtioTarget/ +/choice optional ref name=address/ /optional @@ -1269,6 +1302,16 @@ ref name=driveUnit/ /attribute /define + define name=virtioserialaddress +attribute name=controller + ref name=driveController/ +/attribute +optional + attribute name=bus +ref name=driveBus/ + /attribute +/optional + /define What is the bus in the content of virtio serial ? @@ -916,7 +930,8 @@ void virDomainDefClearDeviceAliases(virDomainDefPtr def) */ static int virDomainDeviceInfoFormat(virBufferPtr buf, virDomainDeviceInfoPtr info, - int flags) + int flags, + const char *indent) I'm not seeing why we need to pass 'indent' through here? The device info data should always be appearing at exactly the same place in all devices, specifically at /domain/devices/[device type]/, so indent level should always be the same. @@ -1481,10 +1553,49 @@ virDomainControllerDefParseXML(xmlNodePtr node, if (virDomainDeviceInfoParseXML(node, def-info, flags) 0) goto error; +switch (def-type) { +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: +0; /* C
Re: [libvirt] [PATCH 2/2] Add QEMU support for virtio channel
On Wed, Feb 17, 2010 at 05:11:01PM +, Matthew Booth wrote: Support virtio-serial controller and virtio channel in QEMU backend. Will output the following for virtio-serial controller: -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4,max_ports=16,vectors=4 and the following for a virtio channel: -chardev pty,id=channel0 \ -device virtserialport,bus=virtio-serial0.0,chardev=channel0,name=org.linux-kvm.port.0 * src/qemu/qemu_conf.c: Add argument output for virtio * tests/qemuxml2argvtest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args : Add test for QEMU command line generation --- src/qemu/qemu_conf.c | 91 +++- .../qemuxml2argv-channel-virtio.args |1 + tests/qemuxml2argvtest.c |1 + 3 files changed, 92 insertions(+), 1 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 456ee34..110409d 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2168,7 +2168,6 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) } for (i = 0; i def-nchannels ; i++) { /* Nada - none are PCI based (yet) */ -/* XXX virtio-serial will need one */ } if (def-watchdog def-watchdog-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { @@ -2465,6 +2464,23 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def) virBufferVSprintf(buf, ,id=scsi%d, def-idx); break; +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: +if (def-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { +virBufferAddLit(buf, virtio-serial-pci); +} else { +virBufferAddLit(buf, virtio-serial); +} +virBufferVSprintf(buf, ,id=virtio-serial%d, def-idx); +if (def-opts.vioserial.max_ports != -1) { +virBufferVSprintf(buf, ,max_ports=%d, + def-opts.vioserial.max_ports); +} +if (def-opts.vioserial.vectors != -1) { +virBufferVSprintf(buf, ,vectors=%d, + def-opts.vioserial.vectors); +} +break; + /* We always get an IDE controller, whether we want it or not. */ case VIR_DOMAIN_CONTROLLER_TYPE_IDE: default: @@ -3830,6 +3846,79 @@ int qemudBuildCommandLine(virConnectPtr conn, } VIR_FREE(addr); ADD_ARG(devstr); +break; + +case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: +if (!(qemuCmdFlags QEMUD_CMD_FLAG_DEVICE)) { +qemuReportError(VIR_ERR_NO_SUPPORT, %s, +_(virtio channel requires QEMU to support -device)); +goto error; +} + +ADD_ARG_LIT(-chardev); +if (!(devstr = qemuBuildChrChardevStr(channel))) +goto error; +ADD_ARG(devstr); It would be desirable to put the stuff that follows this point, into a qemuBuildVirtioSerialPortDevStr() method, because the main qemudBuildCommandLine() method is far too large unwieldly these days. + +virBuffer virtiodev = VIR_BUFFER_INITIALIZER; +virBufferAddLit(virtiodev, virtserialport); + +if (channel-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { +/* Check it's a virtio-serial address */ +if (channel-info.type != +VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL) +{ +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(virtio serial device has invalid + address type)); +virBufferFreeAndReset(virtiodev); +goto error; +} + +/* Look for the virtio-serial controller */ +const char *vsalias = NULL; +int vs = 0; +int c; +for (c = 0; c def-ncontrollers; c++) { +if (def-controllers[c]-type != +VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) +{ +continue; +} + +if (vs == channel-info.addr.vioserial.controller) { +vsalias = def-controllers[c]-info.alias; +break; +} + +vs++; +} + +if (!vsalias) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(virtio serial device address controller + does not exist)); +virBufferFreeAndReset(virtiodev); +
Re: [libvirt] [PATCH 1/3] virterror: Make SetError work if no previous error was set
On Tue, Feb 16, 2010 at 02:37:00PM -0500, Cole Robinson wrote: virGetLastError returns NULL if no error has been set, not on allocation error like virSetError assumed. Use virLastErrorObject instead. This fixes virSetError when no error is currently stored. Signed-off-by: Cole Robinson crobi...@redhat.com --- src/util/virterror.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/util/virterror.c b/src/util/virterror.c index bbf5021..cbd0ca8 100644 --- a/src/util/virterror.c +++ b/src/util/virterror.c @@ -304,7 +304,7 @@ int virSetError(virErrorPtr newerr) { virErrorPtr err; -err = virGetLastError(); +err = virLastErrorObject(); if (!err) return -1; -- ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] libvirt: Update docs for hotplug only commands
On Tue, Feb 16, 2010 at 02:35:49PM -0500, Cole Robinson wrote: The commands updated are SetMem, SetMaxMem, SetVcpus, and PinVcpu. Signed-off-by: Cole Robinson crobi...@redhat.com --- src/libvirt.c | 12 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 0e5f4a2..be17668 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2758,6 +2758,9 @@ error: * to Domain0 i.e. the domain where the application runs. * This function requires privileged access to the hypervisor. * + * This command only changes the runtime configuration of the domain, + * so can only be called on an active domain. + * * Returns 0 in case of success and -1 in case of failure. */ int @@ -2808,6 +2811,9 @@ error: * to Domain0 i.e. the domain where the application runs. * This function may requires privileged access to the hypervisor. * + * This command only changes the runtime configuration of the domain, + * so can only be called on an active domain. + * * Returns 0 in case of success and -1 in case of failure. */ int @@ -4821,6 +4827,9 @@ error: * does not support it or if growing the number is arbitrary limited. * This function requires privileged access to the hypervisor. * + * This command only changes the runtime configuration of the domain, + * so can only be called on an active domain. + * * Returns 0 in case of success, -1 in case of failure. */ @@ -4879,6 +4888,9 @@ error: * Dynamically change the real CPUs which can be allocated to a virtual CPU. * This function requires privileged access to the hypervisor. * + * This command only changes the runtime configuration of the domain, + * so can only be called on an active domain. + * * Returns 0 in case of success, -1 in case of failure. */ int -- ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 3/3] qemu: Explicitly error if guest virtual network is inactive
On Tue, Feb 16, 2010 at 02:37:02PM -0500, Cole Robinson wrote: Currently we just error with ex. 'virbr0: No such device'. Since we are using public API calls here, we need to ensure that any raised error is properly saved and restored, since API entry points always reset messages. Signed-off-by: Cole Robinson crobi...@redhat.com --- src/qemu/qemu_conf.c | 28 +--- 1 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index c9fe55b..6c64deb 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1482,17 +1482,39 @@ qemudNetworkIfaceConnect(virConnectPtr conn, int template_ifname = 0; if (net-type == VIR_DOMAIN_NET_TYPE_NETWORK) { +int active, fail = 0; +virErrorPtr errobj; virNetworkPtr network = virNetworkLookupByName(conn, - net-data.network.name); + net-data.network.name); if (!network) return -1; -brname = virNetworkGetBridgeName(network); +active = virNetworkIsActive(network); +if (active != 1) { +fail = 1; +if (active == 0) +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(Network '%s' is not active.), +net-data.network.name); +} + +if (!fail) { +brname = virNetworkGetBridgeName(network); +if (brname == NULL) +fail = 1; +} + +/* Make sure any above failure is preserved */ +errobj = virSaveLastError(); virNetworkFree(network); +virSetError(errobj); +virFreeError(errobj); -if (brname == NULL) +errobj = virSaveLastError(); +if (fail) return -1; + } else if (net-type == VIR_DOMAIN_NET_TYPE_BRIDGE) { if (!(brname = strdup(net-data.bridge.brname))) { virReportOOMError(); -- ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 2/3] network: bridge: Fix IsActive, IsPersistent
On Tue, Feb 16, 2010 at 02:37:01PM -0500, Cole Robinson wrote: We were accessing the wrong private data structure, which would cause a segfault. Signed-off-by: Cole Robinson crobi...@redhat.com --- src/network/bridge_driver.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 8cef714..4453707 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1188,7 +1188,7 @@ static int networkListDefinedNetworks(virConnectPtr conn, char **const names, in static int networkIsActive(virNetworkPtr net) { -struct network_driver *driver = net-conn-privateData; +struct network_driver *driver = net-conn-networkPrivateData; virNetworkObjPtr obj; int ret = -1; @@ -1209,7 +1209,7 @@ cleanup: static int networkIsPersistent(virNetworkPtr net) { -struct network_driver *driver = net-conn-privateData; +struct network_driver *driver = net-conn-networkPrivateData; virNetworkObjPtr obj; int ret = -1; -- ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Fix typo in comment
On Wed, Feb 17, 2010 at 02:36:32PM +, Matthew Booth wrote: * src/qemu/qemu_driver.c: Fix typo in comment --- src/qemu/qemu_driver.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8766ca2..b4728e5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2724,7 +2724,7 @@ static int qemudStartVMDaemon(virConnectPtr conn, } /* - * Normally PCI addresses are assigned inhe virDomainCreate + * Normally PCI addresses are assigned in the virDomainCreate * or virDomainDefine methods. We might still need to assign * some here to cope with the question of upgrades. Regardless * we also need to populate the PCi address set cache for later ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] macvtap teardown rework
On Wed, Feb 17, 2010 at 03:05:53PM -0500, Stefan Berger wrote: I have reworked and simplified the teardown of the macvtap device. Basically all devices with the same MAC address and link device are kept alive and not attempted to be torn down. If a macvtap device linked to a physical interface with a certain MAC address 'M' is to be created it will automatically fail if the interface is 'up'ed and another macvtap with the same properties (MAC addr 'M', link dev) happens to be 'up'. This will prevent the VM from starting or the device from being attached to a running VM. Stale interfaces are assumed to be there for some reason and not stem from libvirt. In the VM shutdown path I am assuming that an interface name is always available so that if the device type is DIRECT it can be torn down using its name. Signed-off-by: Stefan Berger stef...@us.ibm.com Index: libvirt-macvtap/src/util/macvtap.h === --- libvirt-macvtap.orig/src/util/macvtap.h +++ libvirt-macvtap/src/util/macvtap.h @@ -35,8 +35,7 @@ int openMacvtapTap(virConnectPtr conn, int mode, char **res_ifname); -int delMacvtapByMACAddress(const unsigned char *macaddress, - int *hasBusyDev); +void delMacvtap(const char *name); #endif /* WITH_MACVTAP */ Index: libvirt-macvtap/src/util/macvtap.c === --- libvirt-macvtap.orig/src/util/macvtap.c +++ libvirt-macvtap/src/util/macvtap.c @@ -447,15 +447,14 @@ buffer_too_small: static int -link_del(const char *type, - const char *name) +link_del(const char *name) { int rc = 0; char nlmsgbuf[256]; struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp; struct nlmsgerr *err; char rtattbuf[64]; -struct rtattr *rta, *rta1; +struct rtattr *rta; struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC }; char *recvbuf = NULL; int recvbuflen; @@ -467,23 +466,6 @@ link_del(const char *type, if (!nlAppend(nlm, sizeof(nlmsgbuf), ifinfo, sizeof(ifinfo))) goto buffer_too_small; -rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_LINKINFO, NULL, 0); -if (!rta) -goto buffer_too_small; - -if (!(rta1 = nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta-rta_len))) -goto buffer_too_small; - -rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_INFO_KIND, - type, strlen(type)); -if (!rta) -goto buffer_too_small; - -if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta-rta_len)) -goto buffer_too_small; - -rta1-rta_len = (char *)nlm + nlm-nlmsg_len - (char *)rta1; - rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME, name, strlen(name)+1); if (!rta) @@ -633,7 +615,8 @@ macvtapModeFromInt(enum virDomainNetdevM } -/* openMacvtapTap: +/** + * openMacvtapTap: * Create an instance of a macvtap device and open its tap character * device. * @conn: Pointer to virConnect object @@ -707,14 +690,17 @@ create_name: rc = ifUp(cr_ifname, 1); if (rc != 0) { virReportSystemError(errno, - _(cannot 'up' interface %s), cr_ifname); + _(cannot 'up' interface %s -- another + macvtap device may be 'up' and have the same + MAC address), + cr_ifname); rc = -1; goto link_del_exit; } rc = openTap(cr_ifname, 10); -if (rc 0) +if (rc = 0) *res_ifname = strdup(cr_ifname); else goto link_del_exit; @@ -722,79 +708,22 @@ create_name: return rc; link_del_exit: -link_del(type, ifname); +link_del(cr_ifname); return rc; } -/* Delete a macvtap type of interface given the MAC address. This - * function will delete all macvtap type of interfaces that have the - * given MAC address. - * @macaddress : Pointer to 6 bytes holding the MAC address of the - *macvtap device(s) to destroy +/** + * delMacvtapByName: + * @ifname : The name of the macvtap interface * - * Returns 0 in case of success, negative value in case of error. + * Delete an interface given its name. */ -int -delMacvtapByMACAddress(const unsigned char *macaddress, - int *hasBusyDev) +void +delMacvtap(const char *ifname) { -struct ifreq ifr; -FILE *file; -char *ifname, *pos; -char buffer[1024]; -off_t oldpos = 0; -int tapfd; - -*hasBusyDev = 0; - -file = fopen(/proc/net/dev, r); - -if (!file) { -virReportSystemError(errno, %s, - _(cannot open file to read network interfaces - from)); -
Re: [libvirt] [PATCH 1/2] Add domain support for virtio channel
On 18/02/10 12:34, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 05:11:00PM +, Matthew Booth wrote: Add support for virtio-serial by defining a new 'virtio' channel target type and a virtio-serial controller. Allows the following to be specified in a domain: controller type='virtio-serial' index='0' max_ports='16' vectors='4'/ channel type='pty' target type='virtio' name='org.linux-kvm.port.0'/ address type='virtio-serial' controller='0' bus='0'/ /channel * docs/schemas/domain.rng: Add virtio-serial controller and virtio channel type. * src/conf/domain_conf.[ch]: Domain parsing/serialization for virtio-serial controller and virtio channel. * tests/qemuxml2xmltest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml : add domain xml parsing test * src/libvirt_private.syms src/qemu/qemu_conf.c: virDomainDefAddDiskControllers() renamed to virDomainDefAddImplicitControllers() --- docs/schemas/domain.rng| 71 +- src/conf/domain_conf.c | 234 +--- src/conf/domain_conf.h | 25 ++- src/libvirt_private.syms |2 +- src/qemu/qemu_conf.c |2 +- .../qemuxml2argv-channel-virtio.xml| 35 +++ tests/qemuxml2xmltest.c|1 + 7 files changed, 320 insertions(+), 50 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 53b82ce..85df8b8 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -523,16 +523,36 @@ /define define name=controller element name=controller - optional -attribute name=type - choice -valuefdc/value -valueide/value -valuescsi/value -valuesata/value - /choice -/attribute - /optional + choice +group + optional +attribute name=type + choice +valuefdc/value +valueide/value +valuescsi/value +valuesata/value + /choice +/attribute + /optional +/group +!-- virtio-serial can have 2 additional attributes -- +group + attribute name=type +valuevirtio-serial/value + /attribute + optional +attribute name=max_ports + ref name=unsignedInt/ +/attribute + /optional + optional +attribute name=vectors + ref name=unsignedInt/ +/attribute + /optional What are these two new attributes doing ? Can't we just auto-assign those values based on the configured channels later int he XML. I'm not 100% sure what vectors does, however I believe this is a resource usage tuning knob and therefore can't be inferred. max_ports we could possibly default. However, virtio-serial also supports hot-plug, although I haven't added libvirt support for it. +/group + /choice attribute name=index ref name=unsignedInt/ /attribute @@ -1139,12 +1159,25 @@ attribute name=port/ /element /define + define name=virtioTarget +element name=target + attribute name=type + valuevirtio/value + /attribute + optional +attribute name=name/ + /optional +/element + /define define name=channel element name=channel ref name=qemucdevSrcType/ interleave ref name=qemucdevSrcDef/ -ref name=guestfwdTarget/ +choice + ref name=guestfwdTarget/ + ref name=virtioTarget/ +/choice optional ref name=address/ /optional @@ -1269,6 +1302,16 @@ ref name=driveUnit/ /attribute /define + define name=virtioserialaddress +attribute name=controller + ref name=driveController/ +/attribute +optional + attribute name=bus +ref name=driveBus/ + /attribute +/optional + /define What is the bus in the content of virtio serial ? -device virtserialport,bus=channel0.0... I've called 'channel0' the controller, and '0' the bus. @@ -916,7 +930,8 @@ void virDomainDefClearDeviceAliases(virDomainDefPtr def) */ static int virDomainDeviceInfoFormat(virBufferPtr buf, virDomainDeviceInfoPtr info, - int flags) + int flags, + const char *indent) I'm not seeing why we need to pass 'indent' through here? The device info data should always
Re: [libvirt] [PATCH 2/2] Add QEMU support for virtio channel
On 18/02/10 12:39, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 05:11:01PM +, Matthew Booth wrote: Support virtio-serial controller and virtio channel in QEMU backend. Will output the following for virtio-serial controller: -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4,max_ports=16,vectors=4 and the following for a virtio channel: -chardev pty,id=channel0 \ -device virtserialport,bus=virtio-serial0.0,chardev=channel0,name=org.linux-kvm.port.0 * src/qemu/qemu_conf.c: Add argument output for virtio * tests/qemuxml2argvtest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args : Add test for QEMU command line generation --- src/qemu/qemu_conf.c | 91 +++- .../qemuxml2argv-channel-virtio.args |1 + tests/qemuxml2argvtest.c |1 + 3 files changed, 92 insertions(+), 1 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 456ee34..110409d 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2168,7 +2168,6 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) } for (i = 0; i def-nchannels ; i++) { /* Nada - none are PCI based (yet) */ -/* XXX virtio-serial will need one */ } if (def-watchdog def-watchdog-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { @@ -2465,6 +2464,23 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def) virBufferVSprintf(buf, ,id=scsi%d, def-idx); break; +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: +if (def-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { +virBufferAddLit(buf, virtio-serial-pci); +} else { +virBufferAddLit(buf, virtio-serial); +} +virBufferVSprintf(buf, ,id=virtio-serial%d, def-idx); +if (def-opts.vioserial.max_ports != -1) { +virBufferVSprintf(buf, ,max_ports=%d, + def-opts.vioserial.max_ports); +} +if (def-opts.vioserial.vectors != -1) { +virBufferVSprintf(buf, ,vectors=%d, + def-opts.vioserial.vectors); +} +break; + /* We always get an IDE controller, whether we want it or not. */ case VIR_DOMAIN_CONTROLLER_TYPE_IDE: default: @@ -3830,6 +3846,79 @@ int qemudBuildCommandLine(virConnectPtr conn, } VIR_FREE(addr); ADD_ARG(devstr); +break; + +case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: +if (!(qemuCmdFlags QEMUD_CMD_FLAG_DEVICE)) { +qemuReportError(VIR_ERR_NO_SUPPORT, %s, +_(virtio channel requires QEMU to support -device)); +goto error; +} + +ADD_ARG_LIT(-chardev); +if (!(devstr = qemuBuildChrChardevStr(channel))) +goto error; +ADD_ARG(devstr); It would be desirable to put the stuff that follows this point, into a qemuBuildVirtioSerialPortDevStr() method, because the main qemudBuildCommandLine() method is far too large unwieldly these days. Would this comment still stand if the code below was simplified to hard-code alias? + +virBuffer virtiodev = VIR_BUFFER_INITIALIZER; +virBufferAddLit(virtiodev, virtserialport); + +if (channel-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { +/* Check it's a virtio-serial address */ +if (channel-info.type != +VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL) +{ +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(virtio serial device has invalid + address type)); +virBufferFreeAndReset(virtiodev); +goto error; +} + +/* Look for the virtio-serial controller */ +const char *vsalias = NULL; +int vs = 0; +int c; +for (c = 0; c def-ncontrollers; c++) { +if (def-controllers[c]-type != +VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) +{ +continue; +} + +if (vs == channel-info.addr.vioserial.controller) { +vsalias = def-controllers[c]-info.alias; +break; +} + +vs++; +} + +if (!vsalias) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(virtio serial device address
Re: [libvirt] [PATCH] Fix DSO linking problem for nodeinfotest
On Thu, Feb 18, 2010 at 10:20:47AM +, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 04:37:17PM +0100, Daniel Veillard wrote: Following changes in Fedora about exposing shared libraries dependancies, libvirt built failed for one of the test binaries because it didn't explicitely required -ldl gcc -DHAVE_CONFIG_H -I. -I.. -I../gnulib/lib -I../gnulib/lib -I../include -I../include -I../src -I../src/util -I../src/conf -I/usr/include/libxml2 -DGETTEXT_PACKAGE=\libvirt\ -Wall -Wformat -Wformat-security -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wextra -Wshadow -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Winline -Wredundant-decls -Wno-sign-compare -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fasynchronous-unwind-tables -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -c nodeinfotest.c CCLD nodeinfotest /usr/bin/ld: ../src/.libs/libvirt_test.a(libvirt_driver_vbox_la-vbox_XPCOMCGlue.o): undefined reference to symbol 'dlopen@@GLIBC_2.1' /usr/bin/ld: note: 'dlopen@@GLIBC_2.1' is defined in DSO /lib/libdl.so.2 so try adding it to the linker command line /lib/libdl.so.2: could not read symbols: Invalid operation collect2: ld returned 1 exit status the following patch fixes it, This isn't corect. nodeinfotest isn't the thing that is ultimately using libdl. The place we need it is in src/Makefile.am against libvirt_driver_vbox_la_LDFLAGS Well, surprizingly nodeinfotest is the only binary exhibiting the build failure, so there must be something else going on ... NB, we also need to adjust the configure.ac check Well we have the check but only for the driver_modules options. I assume you mean doing this check unconditionally and export some autoconf variable holding the -ldl flag. I will rework the patch accordingly, Daniel -- 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
Re: [libvirt] [RFC] Proposal for introduction of network traffic filtering capabilities for filtering of network traffic from and to VMs
libvir-list-boun...@redhat.com wrote on 01/26/2010 08:24:43 AM: Daniel, ok, trying to combine your suggestions: - guest contains a single filter reference per interface guest.xml: -- domain type='kvm' namedemo/name memory256000/memory devices interface type=bridge filter name='demofilter' ipaddr='10.0.0.1'/ /interface /devices /domain As the implementation of this progresses and we make design decision, we now introduced attributes and values for the filters to be passed in the format of att%d='attribute' val%d='value' thus we would rewrite the above example to: domain type='kvm' namedemo/name memory256000/memory devices interface type=bridge filter name='demofilter' att0='IP' val0='10.0.0.1'/ /interface /devices /domain This allows us to pass any necessary parameters to the filters for instantiation in the respective environment. So, if a filter is to be instantiated and holds the variable XYZ, then one may add att1='XYZ' val1='some value' - complex filter include other filter and can contain rules complex demofilter.xml: --- filter name='demofilter' include href='drop-all'/ include href='no-arp-spoofing' srcipaddr='$IP'/ -- include href='no-arp-spoofing' att0='IP' val0='1.2.3.4'. include href='no-mac-spoofing'/ include href='no-ip-spoofing' srcipaddr='$IP'/ !-- no ip spoofing -- rule action='drop' direction='out' ip match='no' srcipaddr='$IP'/ /rule /filter So any referenced filter, also as shown above in the demofilter.xml, could hold environment-specific values for required variables. A filter requiring a variable that is not passed is not instantiated and will prevent interface creation / attachment or the start of the VM. Further, if an attribute value pair (IP) as shown here is passed from the domain XML and another value as shown here in the referenced filter is again set, the one from further 'up' is used, i.e., IP=10.0.0.1 rather than IP=1.2.3.4. Does this sound ok? Regards, Stefan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 2/2] Add QEMU support for virtio channel
On Thu, Feb 18, 2010 at 01:23:57PM +, Matthew Booth wrote: On 18/02/10 12:39, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 05:11:01PM +, Matthew Booth wrote: Support virtio-serial controller and virtio channel in QEMU backend. Will output the following for virtio-serial controller: -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4,max_ports=16,vectors=4 and the following for a virtio channel: -chardev pty,id=channel0 \ -device virtserialport,bus=virtio-serial0.0,chardev=channel0,name=org.linux-kvm.port.0 * src/qemu/qemu_conf.c: Add argument output for virtio * tests/qemuxml2argvtest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args : Add test for QEMU command line generation --- src/qemu/qemu_conf.c | 91 +++- .../qemuxml2argv-channel-virtio.args |1 + tests/qemuxml2argvtest.c |1 + 3 files changed, 92 insertions(+), 1 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 456ee34..110409d 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2168,7 +2168,6 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) } for (i = 0; i def-nchannels ; i++) { /* Nada - none are PCI based (yet) */ -/* XXX virtio-serial will need one */ } if (def-watchdog def-watchdog-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { @@ -2465,6 +2464,23 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def) virBufferVSprintf(buf, ,id=scsi%d, def-idx); break; +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: +if (def-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { +virBufferAddLit(buf, virtio-serial-pci); +} else { +virBufferAddLit(buf, virtio-serial); +} +virBufferVSprintf(buf, ,id=virtio-serial%d, def-idx); +if (def-opts.vioserial.max_ports != -1) { +virBufferVSprintf(buf, ,max_ports=%d, + def-opts.vioserial.max_ports); +} +if (def-opts.vioserial.vectors != -1) { +virBufferVSprintf(buf, ,vectors=%d, + def-opts.vioserial.vectors); +} +break; + /* We always get an IDE controller, whether we want it or not. */ case VIR_DOMAIN_CONTROLLER_TYPE_IDE: default: @@ -3830,6 +3846,79 @@ int qemudBuildCommandLine(virConnectPtr conn, } VIR_FREE(addr); ADD_ARG(devstr); +break; + +case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: +if (!(qemuCmdFlags QEMUD_CMD_FLAG_DEVICE)) { +qemuReportError(VIR_ERR_NO_SUPPORT, %s, +_(virtio channel requires QEMU to support -device)); +goto error; +} + +ADD_ARG_LIT(-chardev); +if (!(devstr = qemuBuildChrChardevStr(channel))) +goto error; +ADD_ARG(devstr); It would be desirable to put the stuff that follows this point, into a qemuBuildVirtioSerialPortDevStr() method, because the main qemudBuildCommandLine() method is far too large unwieldly these days. Would this comment still stand if the code below was simplified to hard-code alias? Yep, because you'll want this method to exist if you ever add the hot-plug support, since that uses the exact same syntax as the main -device arg these days. Which is nice :-) + +virBuffer virtiodev = VIR_BUFFER_INITIALIZER; +virBufferAddLit(virtiodev, virtserialport); + +if (channel-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { +/* Check it's a virtio-serial address */ +if (channel-info.type != +VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL) +{ +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(virtio serial device has invalid + address type)); +virBufferFreeAndReset(virtiodev); +goto error; +} + +/* Look for the virtio-serial controller */ +const char *vsalias = NULL; +int vs = 0; +int c; +for (c = 0; c def-ncontrollers; c++) { +if (def-controllers[c]-type != +VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) +{ +continue; +} + +if (vs ==
Re: [libvirt] [RFC] Proposal for introduction of network traffic filtering capabilities for filtering of network traffic from and to VMs
2010/2/18 Stefan Berger stef...@us.ibm.com: libvir-list-boun...@redhat.com wrote on 01/26/2010 08:24:43 AM: Daniel, ok, trying to combine your suggestions: - guest contains a single filter reference per interface guest.xml: -- domain type='kvm' namedemo/name memory256000/memory devices interface type=bridge filter name='demofilter' ipaddr='10.0.0.1'/ /interface /devices /domain As the implementation of this progresses and we make design decision, we now introduced attributes and values for the filters to be passed in the format of att%d='attribute' val%d='value' thus we would rewrite the above example to: domain type='kvm' namedemo/name memory256000/memory devices interface type=bridge filter name='demofilter' att0='IP' val0='10.0.0.1'/ /interface /devices /domain This allows us to pass any necessary parameters to the filters for instantiation in the respective environment. So, if a filter is to be instantiated and holds the variable XYZ, then one may add att1='XYZ' val1='some value' Passing parameters this way seems a bit unexpected for XML. How about something like this: interface type=bridge filter name='demofilter' parameter name='IP' value='10.0.0.1'/ /filter /interface - complex filter include other filter and can contain rules complex demofilter.xml: --- filter name='demofilter' include href='drop-all'/ include href='no-arp-spoofing' srcipaddr='$IP'/ -- include href='no-arp-spoofing' att0='IP' val0='1.2.3.4'. And the same pattern for the includes: include href='no-arp-spoofing' parameter name='IP' value='1.2.3.4'/ /include Matthias -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] macvtap teardown rework
On Wed, Feb 17, 2010 at 03:05:53PM -0500, Stefan Berger wrote: I have reworked and simplified the teardown of the macvtap device. Basically all devices with the same MAC address and link device are kept alive and not attempted to be torn down. If a macvtap device linked to a physical interface with a certain MAC address 'M' is to be created it will automatically fail if the interface is 'up'ed and another macvtap with the same properties (MAC addr 'M', link dev) happens to be 'up'. This will prevent the VM from starting or the device from being attached to a running VM. Stale interfaces are assumed to be there for some reason and not stem from libvirt. In the VM shutdown path I am assuming that an interface name is always available so that if the device type is DIRECT it can be torn down using its name. Signed-off-by: Stefan Berger stef...@us.ibm.com Okay, applied, I just removed an unused header pointed out by syntax-check :-) Daniel -- 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
Re: [libvirt] [RFC] Proposal for introduction of network traffic filtering capabilities for filtering of network traffic from and to VMs
Matthias Bolte matthias.bo...@googlemail.com wrote on 02/18/2010 09:15:47 AM: thus we would rewrite the above example to: domain type='kvm' namedemo/name memory256000/memory devices interface type=bridge filter name='demofilter' att0='IP' val0='10.0.0.1'/ /interface /devices /domain This allows us to pass any necessary parameters to the filters for instantiation in the respective environment. So, if a filter is to be instantiated and holds the variable XYZ, then one may add att1='XYZ' val1='some value' Passing parameters this way seems a bit unexpected for XML. How about something like this: interface type=bridge filter name='demofilter' parameter name='IP' value='10.0.0.1'/ /filter /interface Also a possibility... Stefan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 3/4] remote: Print ssh stderr on connection failure
On Fri, Feb 12, 2010 at 10:32:16AM -0500, Cole Robinson wrote: --- src/remote/remote_driver.c | 37 ++--- 1 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 13534ce..7f92fd0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -154,6 +154,7 @@ struct private_data { virMutex lock; int sock; /* Socket. */ +int errsock;/* Socket connected to remote stderr */ int watch; /* File handle watch */ pid_t pid; /* PID of tunnel process */ int uses_tls; /* TLS enabled on socket? */ @@ -783,6 +784,7 @@ doRemoteOpen (virConnectPtr conn, case trans_ext: { pid_t pid; int sv[2]; +int errsock[2]; /* Fork off the external process. Use socketpair to create a private * (unnamed) Unix domain socket to the child process so we don't have @@ -794,14 +796,21 @@ doRemoteOpen (virConnectPtr conn, goto failed; } +if (socketpair (PF_UNIX, SOCK_STREAM, 0, errsock) == -1) { +virReportSystemError(errno, %s, + _(unable to create socket pair)); +goto failed; +} I think you just want pipe() here, since this does not want to be a bi-directional channel. + if (virExec((const char**)cmd_argv, NULL, NULL, -pid, sv[1], (sv[1]), NULL, +pid, sv[1], (sv[1]), (errsock[1]), VIR_EXEC_CLEAR_CAPS) 0) goto failed; /* Parent continues here. */ close (sv[1]); priv-sock = sv[0]; +priv-errsock = errsock[0]; priv-pid = pid; /* Do not set 'is_secure' flag since we can't guarentee @@ -827,6 +836,12 @@ doRemoteOpen (virConnectPtr conn, goto failed; } +if ((priv-errsock != -1) virSetNonBlock(priv-errsock) 0) { +virReportSystemError(errno, %s, + _(unable to make socket non-blocking)); +goto failed; +} + if (pipe(wakeupFD) 0) { virReportSystemError(errno, %s, _(unable to make pipe)); @@ -939,6 +954,9 @@ doRemoteOpen (virConnectPtr conn, failed: /* Close the socket if we failed. */ +if (priv-errsock = 0) +close(priv-errsock); + if (priv-sock = 0) { if (priv-uses_tls priv-session) { gnutls_bye (priv-session, GNUTLS_SHUT_RDWR); @@ -986,6 +1004,7 @@ remoteAllocPrivateData(virConnectPtr conn) priv-localUses = 1; priv-watch = -1; priv-sock = -1; +priv-errsock = -1; return priv; } @@ -1408,6 +1427,7 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv) sasl_dispose (priv-saslconn); #endif close (priv-sock); +close (priv-errsock); #ifndef WIN32 if (priv-pid 0) { @@ -7785,12 +7805,23 @@ remoteIOReadBuffer(virConnectPtr conn, if (errno == EWOULDBLOCK) return 0; +char errout[1024] = \0; +if (priv-errsock) { Should be priv-errsock != -1 +recv(priv-errsock, errout, sizeof(errout), 0); +} + virReportSystemError(errno, - %s, _(cannot recv data)); + _(cannot recv data: %s), errout); + } else { +char errout[1024] = \0; +if (priv-errsock) { Likewise here +recv(priv-errsock, errout, sizeof(errout), 0); +} + errorf (in_open ? NULL : conn, VIR_ERR_SYSTEM_ERROR, -%s, _(server closed connection)); +_(server closed connection: %s), errout); } return -1; } -- Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] libvirt: Update docs for hotplug only commands
On 02/18/2010 07:45 AM, Daniel P. Berrange wrote: On Tue, Feb 16, 2010 at 02:35:49PM -0500, Cole Robinson wrote: The commands updated are SetMem, SetMaxMem, SetVcpus, and PinVcpu. Signed-off-by: Cole Robinson crobi...@redhat.com --- src/libvirt.c | 12 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 0e5f4a2..be17668 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2758,6 +2758,9 @@ error: * to Domain0 i.e. the domain where the application runs. * This function requires privileged access to the hypervisor. * + * This command only changes the runtime configuration of the domain, + * so can only be called on an active domain. + * * Returns 0 in case of success and -1 in case of failure. */ int @@ -2808,6 +2811,9 @@ error: * to Domain0 i.e. the domain where the application runs. * This function may requires privileged access to the hypervisor. * + * This command only changes the runtime configuration of the domain, + * so can only be called on an active domain. + * * Returns 0 in case of success and -1 in case of failure. */ int @@ -4821,6 +4827,9 @@ error: * does not support it or if growing the number is arbitrary limited. * This function requires privileged access to the hypervisor. * + * This command only changes the runtime configuration of the domain, + * so can only be called on an active domain. + * * Returns 0 in case of success, -1 in case of failure. */ @@ -4879,6 +4888,9 @@ error: * Dynamically change the real CPUs which can be allocated to a virtual CPU. * This function requires privileged access to the hypervisor. * + * This command only changes the runtime configuration of the domain, + * so can only be called on an active domain. + * * Returns 0 in case of success, -1 in case of failure. */ int -- ACK Daniel Thanks, pushed now. - Cole -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] virtio-serial support
On 02/17/2010 12:10 PM, Matthew Booth wrote: These patches rebase my previously posted virtio-serial patches, add support for max_ports and vectors, and allow multiple virtio-serial devices to be used. I wasn't going to bother with the latter, however it turns out this can be useful if the user wants more than 31 virtserialports. N.B. These apply on top of 2 previously posted patches. Specifically Fix whitespace in domain.rng and Remove unused functions from domain_conf. Would be nice to also get the XML docs updated with these new values (max_ports and vectors). Thanks, Cole -- 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
Re: [libvirt] [PATCH 1/2] Add virFork() function to utils.
On 02/18/2010 07:50 AM, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 02:29:27PM -0500, Laine Stump wrote: virFork() contains bookkeeping that must be done any time a process forks. Currently this includes: 1) Call virLogLock() prior to fork() and virLogUnlock() just after, to avoid a deadlock if some other thread happens to hold that lock during the fork. 2) Reset the logging hooks and send all child process log messages to stderr. 3) Block all signals prior to fork(), then either a) reset the signal mask for the parent process, or b) clear the signal mask for the child process. util.c, util.h: add virFork() function, based on what is currently done in __virExec(). --- src/util/util.c | 115 +++ src/util/util.h |1 + 2 files changed, 116 insertions(+), 0 deletions(-) diff --git a/src/util/util.c b/src/util/util.c index cdab300..f508f6b 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -296,6 +296,121 @@ static int virClearCapabilities(void) } #endif + +/* virFork() - fork a new process while avoiding various race/deadlock conditions + + @pid - a pointer to a pid_t that will receive the return value from + fork() + + on return from virFork(), if *pid 0, the fork failed and there is + no new process. Otherwise, just like fork(), if *pid == 0, it is the + child process returning, and if *pid 0, it is the parent. + + Even if *pid= 0, if the return value from virFork() is 0, it + indicates a failure that occurred in the parent or child process + after the fork. In this case, the child process should call + _exit(1) after doing any additional error reporting. + + */ +int virFork(pid_t *pid) { +sigset_t oldmask, newmask; +struct sigaction sig_action; +int saved_errno, ret = -1; + +*pid = -1; + +/* + * Need to block signals now, so that child process can safely + * kill off caller's signal handlers without a race. + */ +sigfillset(newmask); +if (pthread_sigmask(SIG_SETMASK,newmask,oldmask) != 0) { +saved_errno = errno; +virReportSystemError(errno, + %s, _(cannot block signals)); +goto cleanup; +} + +/* Ensure we hold the logging lock, to protect child processes + * from deadlocking on another thread's inherited mutex state */ +virLogLock(); + +*pid = fork(); +saved_errno = errno; /* save for caller */ + +/* Unlock for both parent and child process */ +virLogUnlock(); + +if (*pid 0) { +virReportSystemError(saved_errno, + %s, _(cannot fork child process)); +goto cleanup; +} Tiny bug here, in that we forget to unblock the parent's signals in this error path. Yow! That actually seems potentially catastrophic to me - if fork() ever fails, libvirtd would ignore all signals until it was kill -9'd. My only defense is that I was replicating existing behavior ;-) Fixed patch coming up. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] get_virtual_functions_linux: would mistakenly always return zero
Dave Allan wrote: On 02/18/2010 05:13 AM, Jim Meyering wrote: Clang reported this as a dead store, too. ... Subject: [PATCH] get_virtual_functions_linux: would mistakenly always return zero ACK Thanks. Pushing now. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 2/2] Add QEMU support for virtio channel
On 18/02/10 14:11, Daniel P. Berrange wrote: On Thu, Feb 18, 2010 at 01:23:57PM +, Matthew Booth wrote: On 18/02/10 12:39, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 05:11:01PM +, Matthew Booth wrote: Support virtio-serial controller and virtio channel in QEMU backend. Will output the following for virtio-serial controller: -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4,max_ports=16,vectors=4 and the following for a virtio channel: -chardev pty,id=channel0 \ -device virtserialport,bus=virtio-serial0.0,chardev=channel0,name=org.linux-kvm.port.0 * src/qemu/qemu_conf.c: Add argument output for virtio * tests/qemuxml2argvtest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args : Add test for QEMU command line generation --- src/qemu/qemu_conf.c | 91 +++- .../qemuxml2argv-channel-virtio.args |1 + tests/qemuxml2argvtest.c |1 + 3 files changed, 92 insertions(+), 1 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 456ee34..110409d 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2168,7 +2168,6 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) } for (i = 0; i def-nchannels ; i++) { /* Nada - none are PCI based (yet) */ -/* XXX virtio-serial will need one */ } if (def-watchdog def-watchdog-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { @@ -2465,6 +2464,23 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def) virBufferVSprintf(buf, ,id=scsi%d, def-idx); break; +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: +if (def-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { +virBufferAddLit(buf, virtio-serial-pci); +} else { +virBufferAddLit(buf, virtio-serial); +} +virBufferVSprintf(buf, ,id=virtio-serial%d, def-idx); +if (def-opts.vioserial.max_ports != -1) { +virBufferVSprintf(buf, ,max_ports=%d, + def-opts.vioserial.max_ports); +} +if (def-opts.vioserial.vectors != -1) { +virBufferVSprintf(buf, ,vectors=%d, + def-opts.vioserial.vectors); +} +break; + /* We always get an IDE controller, whether we want it or not. */ case VIR_DOMAIN_CONTROLLER_TYPE_IDE: default: @@ -3830,6 +3846,79 @@ int qemudBuildCommandLine(virConnectPtr conn, } VIR_FREE(addr); ADD_ARG(devstr); +break; + +case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: +if (!(qemuCmdFlags QEMUD_CMD_FLAG_DEVICE)) { +qemuReportError(VIR_ERR_NO_SUPPORT, %s, +_(virtio channel requires QEMU to support -device)); +goto error; +} + +ADD_ARG_LIT(-chardev); +if (!(devstr = qemuBuildChrChardevStr(channel))) +goto error; +ADD_ARG(devstr); It would be desirable to put the stuff that follows this point, into a qemuBuildVirtioSerialPortDevStr() method, because the main qemudBuildCommandLine() method is far too large unwieldly these days. Would this comment still stand if the code below was simplified to hard-code alias? Yep, because you'll want this method to exist if you ever add the hot-plug support, since that uses the exact same syntax as the main -device arg these days. Which is nice :-) + +virBuffer virtiodev = VIR_BUFFER_INITIALIZER; +virBufferAddLit(virtiodev, virtserialport); + +if (channel-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { +/* Check it's a virtio-serial address */ +if (channel-info.type != +VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL) +{ +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(virtio serial device has invalid + address type)); +virBufferFreeAndReset(virtiodev); +goto error; +} + +/* Look for the virtio-serial controller */ +const char *vsalias = NULL; +int vs = 0; +int c; +for (c = 0; c def-ncontrollers; c++) { +if (def-controllers[c]-type != +VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) +{ +continue; +} + +if (vs == channel-info.addr.vioserial.controller) { +vsalias =
Re: [libvirt] [PATCH 1/2] Add domain support for virtio channel
On 18/02/10 14:09, Daniel P. Berrange wrote: On Thu, Feb 18, 2010 at 01:16:02PM +, Matthew Booth wrote: On 18/02/10 12:34, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 05:11:00PM +, Matthew Booth wrote: Add support for virtio-serial by defining a new 'virtio' channel target type and a virtio-serial controller. Allows the following to be specified in a domain: controller type='virtio-serial' index='0' max_ports='16' vectors='4'/ channel type='pty' target type='virtio' name='org.linux-kvm.port.0'/ address type='virtio-serial' controller='0' bus='0'/ /channel * docs/schemas/domain.rng: Add virtio-serial controller and virtio channel type. * src/conf/domain_conf.[ch]: Domain parsing/serialization for virtio-serial controller and virtio channel. * tests/qemuxml2xmltest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml : add domain xml parsing test * src/libvirt_private.syms src/qemu/qemu_conf.c: virDomainDefAddDiskControllers() renamed to virDomainDefAddImplicitControllers() --- docs/schemas/domain.rng| 71 +- src/conf/domain_conf.c | 234 +--- src/conf/domain_conf.h | 25 ++- src/libvirt_private.syms |2 +- src/qemu/qemu_conf.c |2 +- .../qemuxml2argv-channel-virtio.xml| 35 +++ tests/qemuxml2xmltest.c|1 + 7 files changed, 320 insertions(+), 50 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 53b82ce..85df8b8 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -523,16 +523,36 @@ /define define name=controller element name=controller - optional -attribute name=type - choice -valuefdc/value -valueide/value -valuescsi/value -valuesata/value - /choice -/attribute - /optional + choice +group + optional +attribute name=type + choice +valuefdc/value +valueide/value +valuescsi/value +valuesata/value + /choice +/attribute + /optional +/group +!-- virtio-serial can have 2 additional attributes -- +group + attribute name=type +valuevirtio-serial/value + /attribute + optional +attribute name=max_ports + ref name=unsignedInt/ +/attribute + /optional + optional +attribute name=vectors + ref name=unsignedInt/ +/attribute + /optional What are these two new attributes doing ? Can't we just auto-assign those values based on the configured channels later int he XML. I'm not 100% sure what vectors does, however I believe this is a resource usage tuning knob and therefore can't be inferred. max_ports we could possibly default. However, virtio-serial also supports hot-plug, although I haven't added libvirt support for it. Ok that's a good enough reason. Can we just call it 'ports' though. We don't use '_' in our XML attribute/element naming usually. @@ -1269,6 +1302,16 @@ ref name=driveUnit/ /attribute /define + define name=virtioserialaddress +attribute name=controller + ref name=driveController/ +/attribute +optional + attribute name=bus +ref name=driveBus/ + /attribute +/optional + /define What is the bus in the content of virtio serial ? -device virtserialport,bus=channel0.0... I've called 'channel0' the controller, and '0' the bus. @@ -916,7 +930,8 @@ void virDomainDefClearDeviceAliases(virDomainDefPtr def) */ static int virDomainDeviceInfoFormat(virBufferPtr buf, virDomainDeviceInfoPtr info, - int flags) + int flags, + const char *indent) I'm not seeing why we need to pass 'indent' through here? The device info data should always be appearing at exactly the same place in all devices, specifically at /domain/devices/[device type]/, so indent level should always be the same. I could remove this. I was originally putting address elsewhere, which screwed up the indentation. Ok, your original code was definitely wrong then :-P @@ -1481,10 +1553,49 @@ virDomainControllerDefParseXML(xmlNodePtr node, if (virDomainDeviceInfoParseXML(node, def-info, flags) 0) goto error; +switch (def-type) { +case
[libvirt] [PATCH] Make an error message in PCI util code clearer.
Signed-off-by: Chris Lalancette clala...@redhat.com --- src/util/pci.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/pci.c b/src/util/pci.c index aa8344e..83ed461 100644 --- a/src/util/pci.c +++ b/src/util/pci.c @@ -540,7 +540,7 @@ pciTrySecondaryBusReset(pciDevice *dev, */ if (pciRead(dev, 0, config_space, PCI_CONF_LEN) 0) { pciReportError(VIR_ERR_NO_SUPPORT, - _(Failed to save PCI config space for %s), + _(Failed to read PCI config space for %s), dev-name); goto out; } @@ -586,7 +586,7 @@ pciTryPowerManagementReset(pciDevice *dev) /* Save and restore the device's config space. */ if (pciRead(dev, 0, config_space[0], PCI_CONF_LEN) 0) { pciReportError(VIR_ERR_NO_SUPPORT, - _(Failed to save PCI config space for %s), + _(Failed to read PCI config space for %s), dev-name); return -1; } -- 1.6.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Make virDomainObjFormat static.
Signed-off-by: Chris Lalancette clala...@redhat.com --- src/conf/domain_conf.c |6 +++--- src/conf/domain_conf.h |3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 4b5510b..c13973b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5533,9 +5533,9 @@ char *virDomainDefFormat(virDomainDefPtr def, return NULL; } -char *virDomainObjFormat(virCapsPtr caps, - virDomainObjPtr obj, - int flags) +static char *virDomainObjFormat(virCapsPtr caps, +virDomainObjPtr obj, +int flags) { char *config_xml = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d3a0775..3c672c6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -800,9 +800,6 @@ int virDomainDefAddDiskControllers(virDomainDefPtr def); #endif char *virDomainDefFormat(virDomainDefPtr def, int flags); -char *virDomainObjFormat(virCapsPtr caps, - virDomainObjPtr obj, - int flags); int virDomainCpuSetParse(const char **str, char sep, -- 1.6.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Better error reporting for failed migration.
If the hostname as returned by gethostname resolves to localhost (as it does with the broken Fedora-12 installer), then live migration will fail because the source will try to migrate to itself. Detect this situation up-front and abort the live migration before we do any real work. Signed-off-by: Chris Lalancette clala...@redhat.com --- src/libvirt_private.syms |1 + src/qemu/qemu_driver.c |2 +- src/util/util.c | 37 +++-- src/util/util.h |1 + 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e3806cd..69ad686 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -568,6 +568,7 @@ virExecDaemonize; virSetCloseExec; virSetNonBlock; virFormatMacAddr; +virGetHostnameLocalhost; virGetHostname; virParseMacAddr; virFileDeletePid; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0d8ec04..2123880 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7748,7 +7748,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn, if (port == QEMUD_MIGRATION_NUM_PORTS) port = 0; /* Get hostname */ -if ((hostname = virGetHostname(dconn)) == NULL) +if ((hostname = virGetHostnameLocalhost(0)) == NULL) goto cleanup; /* XXX this really should have been a properly well-formed diff --git a/src/util/util.c b/src/util/util.c index cdab300..72cc222 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2193,11 +2193,11 @@ char *virIndexToDiskName(int idx, const char *prefix) #define AI_CANONIDN 0 #endif -char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) +char *virGetHostnameLocalhost(int allow_localhost) { int r; char hostname[HOST_NAME_MAX+1], *result; -struct addrinfo hints, *info; +struct addrinfo hints, *info, *res; r = gethostname (hostname, sizeof(hostname)); if (r == -1) { @@ -2217,6 +2217,34 @@ char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) hostname, gai_strerror(r)); return NULL; } + +/* if we aren't allowing localhost, then we iterate through the + * list and make sure none of the IPv4 addresses are 127.0.0.1 and + * that none of the IPv6 addresses are ::1 + */ +if (!allow_localhost) { +res = info; +while (res) { +if (res-ai_family == AF_INET) { +if (htonl(((struct sockaddr_in *)res-ai_addr)-sin_addr.s_addr) == INADDR_LOOPBACK) { +virUtilError(VIR_ERR_INTERNAL_ERROR, %s, + _(canonical hostname pointed to localhost, but this is not allowed)); +freeaddrinfo(info); +return NULL; +} +} +else if (res-ai_family == AF_INET6) { +if (IN6_IS_ADDR_LOOPBACK(((struct sockaddr_in6 *)res-ai_addr)-sin6_addr)) { +virUtilError(VIR_ERR_INTERNAL_ERROR, %s, + _(canonical hostname pointed to localhost, but this is not allowed)); +freeaddrinfo(info); +return NULL; +} +} +res = res-ai_next; +} +} + if (info-ai_canonname == NULL) { virUtilError(VIR_ERR_INTERNAL_ERROR, %s, _(could not determine canonical host name)); @@ -2233,6 +2261,11 @@ char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) return result; } +char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) +{ +return virGetHostnameLocalhost(1); +} + /* send signal to a single process */ int virKillProcess(pid_t pid, int sig) { diff --git a/src/util/util.h b/src/util/util.h index 4207508..d024fe1 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -232,6 +232,7 @@ static inline int getuid (void) { return 0; } static inline int getgid (void) { return 0; } #endif +char *virGetHostnameLocalhost(int allow_localhost); char *virGetHostname(virConnectPtr conn); int virKillProcess(pid_t pid, int sig); -- 1.6.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Fix typo in comment
On Wed, Feb 17, 2010 at 02:36:32PM +, Matthew Booth wrote: * src/qemu/qemu_driver.c: Fix typo in comment --- src/qemu/qemu_driver.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8766ca2..b4728e5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2724,7 +2724,7 @@ static int qemudStartVMDaemon(virConnectPtr conn, } /* - * Normally PCI addresses are assigned inhe virDomainCreate + * Normally PCI addresses are assigned in the virDomainCreate * or virDomainDefine methods. We might still need to assign * some here to cope with the question of upgrades. Regardless * we also need to populate the PCi address set cache for later -- 1.6.6 Pushed, thanks ! Daniel -- 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
Re: [libvirt] [RFC] Proposal for introduction of network traffic filtering capabilities for filtering of network traffic from and to VMs
Matthias Bolte matthias.bo...@googlemail.com wrote on 02/18/2010 09:15:47 AM: Daniel P. Berrange, veillard, libvir-list, Vivek Kashyap 2010/2/18 Stefan Berger stef...@us.ibm.com: domain type='kvm' namedemo/name memory256000/memory devices interface type=bridge filter name='demofilter' att0='IP' val0='10.0.0.1'/ /interface /devices /domain This allows us to pass any necessary parameters to the filters for instantiation in the respective environment. So, if a filter is to be instantiated and holds the variable XYZ, then one may add att1='XYZ' val1='some value' Passing parameters this way seems a bit unexpected for XML. How about something like this: interface type=bridge filter name='demofilter' parameter name='IP' value='10.0.0.1'/ /filter /interface I think we'll change this to ... interface type=bridge filterref ref='demofilter' parameter name='IP' value='10.0.0.1'/ /filter /interface - complex filter include other filter and can contain rules complex demofilter.xml: --- filter name='demofilter' include href='drop-all'/ include href='no-arp-spoofing' srcipaddr='$IP'/ -- include href='no-arp-spoofing' att0='IP' val0='1.2.3.4'. And the same pattern for the includes: ... and this to ... include href='no-arp-spoofing' parameter name='IP' value='1.2.3.4'/ /include filterref ref='no-arp-spoofing' parameter name='IP' value='1.2.3.4'/ /include ... to be consistent. Thanks for feedback. Stefan Matthias -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Remove unused functions from domain_conf
On Wed, Feb 17, 2010 at 05:18:40PM +, Matthew Booth wrote: On 17/02/10 17:08, Daniel Veillard wrote: Hum, virDomainDevicePCIAddressEqual is actually exposed in src/libvirt_private.syms so that would have to be cleaned up there too. If no ongoing patches is needing them I'm fine removeing those, Hadn't spotted that. Attached new patch which touches src/libvirt_private.syms. Matt -- Matthew Booth, RHCA, RHCSS Red Hat Engineering, Virtualisation Team M: +44 (0)7977 267231 GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 From 5612c7c7a5969a84cc97f50ad2bdf9070ef95210 Mon Sep 17 00:00:00 2001 From: Matthew Booth mbo...@redhat.com Date: Wed, 17 Feb 2010 13:25:41 + Subject: [PATCH] Remove unused functions from domain_conf Remove virDomainDevicePCIAddressEqual and virDomainDeviceDriveAddressEqual, which are defined but not used anywhere. * src/conf/domain_conf.[ch] src/libvirt_private.syms: Remove virDomainDevicePCIAddressEqual and virDomainDeviceDriveAddressEqual. --- src/conf/domain_conf.c | 24 src/conf/domain_conf.h |4 src/libvirt_private.syms |1 - 3 files changed, 0 insertions(+), 29 deletions(-) Okay, pushed, thanks ! Daniel -- 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
[libvirt] (no subject)
Repost of http://www.redhat.com/archives/libvir-list/2010-February/msg00177.html The virsh output is now scaled to show KB/MB as needed, instead of always bytes. The public API gained extra status VIR_DOMAIN_JOB_COMPLETED = 3, /* Job has finished, but isn't cleaned up */ VIR_DOMAIN_JOB_FAILED= 4, /* Job hit error, but isn't cleaned up */ VIR_DOMAIN_JOB_CANCELLED = 6, /* Job was aborted, but isn't cleaned up */ to allow to more easily detecting end of a job, once we allow for truely async usage -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/9] Introduce public API for domain async job handling
Introduce a new public API that provides a way to get progress info on currently running jobs on a virDomainpPtr. APIs that are initially within scope of this idea are virDomainMigrate virDomainMigrateToURI virDomainSave virDomainRestore virDomainCoreDump These all take a potentially long time and benefit from monitoring. The virDomainJobInfo struct allows for various pieces of information to be reported - Percentage completion - Time - Overall data - Guest memory data - Guest disk/file data * include/libvirt/libvirt.h.in: Add virDomainGetJobInfo * python/generator.py, python/libvirt-override-api.xml, python/libvirt-override.c: Override for virDomainGetJobInfo API * python/typewrappers.c, python/typewrappers.h: Introduce wrapper for unsigned long long type --- include/libvirt/libvirt.h.in| 49 +++ python/generator.py |1 + python/libvirt-override-api.xml |5 python/libvirt-override.c | 36 python/typewrappers.c |8 ++ python/typewrappers.h |1 + 6 files changed, 100 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 260505e..51c0844 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1787,6 +1787,55 @@ char *virConnectBaselineCPU(virConnectPtr conn, unsigned int ncpus, unsigned int flags); +typedef enum { +VIR_DOMAIN_JOB_NONE = 0, /* No job is active */ +VIR_DOMAIN_JOB_BOUNDED = 1, /* Job with a finite completion time */ +VIR_DOMAIN_JOB_UNBOUNDED = 2, /* Job without a finite completion time */ +VIR_DOMAIN_JOB_COMPLETED = 3, /* Job has finished, but isn't cleaned up */ +VIR_DOMAIN_JOB_FAILED= 4, /* Job hit error, but isn't cleaned up */ +VIR_DOMAIN_JOB_CANCELLED = 6, /* Job was aborted, but isn't cleaned up */ +} virDomainJobType; + +typedef struct _virDomainJobInfo virDomainJobInfo; +typedef virDomainJobInfo *virDomainJobInfoPtr; +struct _virDomainJobInfo { +/* One of virDomainJobType */ +int type; + +/* Time is measured in seconds */ +unsigned long long timeElapsed;/* Always set */ +unsigned long long timeRemaining; /* Only for VIR_DOMAIN_JOB_BOUNDED */ + +/* Data is measured in bytes unless otherwise specified + * and is measuring the job as a whole + * + * For VIR_DOMAIN_JOB_UNBOUNDED, dataTotal may be less + * than the final sum of dataProcessed + dataRemaining + * in the event that the hypervisor has to repeat some + * data eg due to dirtied pages during migration + * + * For VIR_DOMAIN_JOB_BOUNDED, dataTotal shall always + * equal sum of dataProcessed + dataRemaining + */ +unsigned long long dataTotal; +unsigned long long dataProcessed; +unsigned long long dataRemaining; + +/* As above, but only tracking guest memory progress */ +unsigned long long memTotal; +unsigned long long memProcessed; +unsigned long long memRemaining; + +/* As above, but only tracking guest disk file progress */ +unsigned long long fileTotal; +unsigned long long fileProcessed; +unsigned long long fileRemaining; +}; + +int virDomainGetJobInfo(virDomainPtr dom, +virDomainJobInfoPtr info); + + #ifdef __cplusplus } #endif diff --git a/python/generator.py b/python/generator.py index 24eaf50..f7625fd 100755 --- a/python/generator.py +++ b/python/generator.py @@ -271,6 +271,7 @@ skip_impl = ( 'virConnGetLastError', 'virGetLastError', 'virDomainGetInfo', +'virDomainGetJobInfo', 'virNodeGetInfo', 'virDomainGetUUID', 'virDomainGetUUIDString', diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index 76a6fd5..1260c0c 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -48,6 +48,11 @@ return type='int *' info='the list of information or None in case of error'/ arg name='domain' type='virDomainPtr' info='a domain object'/ /function +function name='virDomainGetJobInfo' file='python' + infoExtract information about an active job being processed for a domain./info + return type='int *' info='the list of information or None in case of error'/ + arg name='domain' type='virDomainPtr' info='a domain object'/ +/function function name='virNodeGetInfo' file='python' infoExtract hardware information about the Node./info return type='int *' info='the list of information or None in case of error'/ diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 2447ad7..e27bce6 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -2072,6 +2072,41 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, } +static PyObject * +libvirt_virDomainGetJobInfo(PyObject *self
[libvirt] [PATCH 5/9] Introduce public API for cancelling async domain jobs
The new virDomainAbortJob() method provides a way for a second thread to abort an ongoing job run by another thread. This extends to any API with which the virDomainGetJobInfo() API is intended to work. Cancellation is not guarenteed, rather best effort on part of the hypervisor and not required to be implmented. * include/libvirt/libvirt.h.in: Define virDomainAbortJob() --- include/libvirt/libvirt.h.in |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 51c0844..25f10c8 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1834,6 +1834,7 @@ struct _virDomainJobInfo { int virDomainGetJobInfo(virDomainPtr dom, virDomainJobInfoPtr info); +int virDomainAbortJob(virDomainPtr dom); #ifdef __cplusplus -- 1.6.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 8/9] Support job cancellation in QEMU driver
This supports cancellation of jobs for the QEMU driver against the virDomainMigrate, virDomainSave and virDomainCoreDump APIs. It is not yet supported for the virDomainRestore API, although it is desirable. * src/qemu/qemu_driver.c: Issue 'migrate_cancel' command if virDomainAbortJob is issued during a migration operation * tools/virsh.c: Add a domjobabort command --- src/qemu/qemu_driver.c | 66 +--- tools/virsh.c | 37 +++ 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7641fd7..5e787ce 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -84,9 +84,10 @@ typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate; typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr; struct _qemuDomainObjPrivate { virCond jobCond; /* Use in conjunction with main virDomainObjPtr lock */ -int jobActive; /* Non-zero if a job is active. Only 1 job is allowed at any time -* A job includes *all* monitor commands, even those just querying -* information, not merely actions */ +unsigned int jobActive : 1; /* Non-zero if a job is active. Only 1 job is allowed at any time + * A job includes *all* monitor commands, even those just querying + * information, not merely actions */ +unsigned int jobCancel : 1; /* Non-zero if a cancel request from client has arrived */ virDomainJobInfo jobInfo; unsigned long long jobStart; @@ -331,6 +332,7 @@ static int qemuDomainObjBeginJob(virDomainObjPtr obj) } } priv-jobActive = 1; +priv-jobCancel = 0; priv-jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000); memset(priv-jobInfo, 0, sizeof(priv-jobInfo)); @@ -377,6 +379,7 @@ static int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, } } priv-jobActive = 1; +priv-jobCancel = 0; priv-jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000); memset(priv-jobInfo, 0, sizeof(priv-jobInfo)); @@ -401,6 +404,7 @@ static int ATTRIBUTE_RETURN_CHECK qemuDomainObjEndJob(virDomainObjPtr obj) qemuDomainObjPrivatePtr priv = obj-privateData; priv-jobActive = 0; +priv-jobCancel = 0; priv-jobStart = 0; memset(priv-jobInfo, 0, sizeof(priv-jobInfo)); virCondSignal(priv-jobCond); @@ -3945,6 +3949,17 @@ qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr struct timeval now; int rc; +if (priv-jobCancel) { +priv-jobCancel = 0; +VIR_DEBUG0(Cancelling migration at client request); +qemuDomainObjEnterMonitorWithDriver(driver, vm); +rc = qemuMonitorMigrateCancel(priv-mon); +qemuDomainObjExitMonitorWithDriver(driver, vm); +if (rc 0) { +VIR_WARN0(Unable to cancel migration); +} +} + qemuDomainObjEnterMonitorWithDriver(driver, vm); rc = qemuMonitorGetMigrationStatus(priv-mon, status, @@ -8811,6 +8826,49 @@ cleanup: } +static int qemuDomainAbortJob(virDomainPtr dom) { +struct qemud_driver *driver = dom-conn-privateData; +virDomainObjPtr vm; +int ret = -1; +qemuDomainObjPrivatePtr priv; + +qemuDriverLock(driver); +vm = virDomainFindByUUID(driver-domains, dom-uuid); +qemuDriverUnlock(driver); +if (!vm) { +char uuidstr[VIR_UUID_STRING_BUFLEN]; +virUUIDFormat(dom-uuid, uuidstr); +qemuReportError(VIR_ERR_NO_DOMAIN, +_(no domain with matching uuid '%s'), uuidstr); +goto cleanup; +} + +priv = vm-privateData; + +if (virDomainObjIsActive(vm)) { +if (priv-jobActive) { +VIR_DEBUG(Requesting cancellation of job on vm %s, vm-def-name); +priv-jobCancel = 1; +} else { +qemuReportError(VIR_ERR_OPERATION_INVALID, +%s, _(no job is active on the domain)); +goto cleanup; +} +} else { +qemuReportError(VIR_ERR_OPERATION_INVALID, +%s, _(domain is not running)); +goto cleanup; +} + +ret = 0; + +cleanup: +if (vm) +virDomainObjUnlock(vm); +return ret; +} + + static virDriver qemuDriver = { VIR_DRV_QEMU, QEMU, @@ -8891,7 +8949,7 @@ static virDriver qemuDriver = { qemuCPUCompare, /* cpuCompare */ qemuCPUBaseline, /* cpuBaseline */ qemuDomainGetJobInfo, /* domainGetJobInfo */ -NULL, /* domainFinishJob */ +qemuDomainAbortJob, /* domainAbortJob */ }; diff --git a/tools/virsh.c b/tools/virsh.c index 0bf03df..cea92fd 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -1899,6 +1899,42 @@ cleanup: } /* + * domjobabort command + */ +static const vshCmdInfo
[libvirt] [PATCH 3/9] Remote driver implmentation of job info API
* src/remote/remote_protocol.x: Define wire protocol format for virDomainGetJobInfo API * src/remote/remote_driver.c, daemon/remote.c: Implement client and server marshalling code for virDomainGetJobInfo() * daemon/remote_dispatch_args.h, daemon/remote_dispatch_prototypes.h daemon/remote_dispatch_ret.h, daemon/remote_dispatch_table.h, src/remote/remote_protocol.c, src/remote/remote_protocol.h: Rebuild files from src/remote/remote_protocol.x --- daemon/remote.c | 44 +++ daemon/remote_dispatch_args.h |1 + daemon/remote_dispatch_prototypes.h |8 ++ daemon/remote_dispatch_ret.h|1 + daemon/remote_dispatch_table.h |5 src/remote/remote_driver.c | 42 - src/remote/remote_protocol.c| 40 +++ src/remote/remote_protocol.h| 26 src/remote/remote_protocol.x| 27 - 9 files changed, 192 insertions(+), 2 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index eacc6f9..67d663e 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -5386,6 +5386,50 @@ remoteDispatchCpuBaseline(struct qemud_server *server ATTRIBUTE_UNUSED, } ret-cpu = cpu; + +return 0; +} + + +static int +remoteDispatchDomainGetJobInfo (struct qemud_server *server ATTRIBUTE_UNUSED, +struct qemud_client *client ATTRIBUTE_UNUSED, +virConnectPtr conn, +remote_message_header *hdr ATTRIBUTE_UNUSED, +remote_error *rerr, +remote_domain_get_job_info_args *args, +remote_domain_get_job_info_ret *ret) +{ +virDomainPtr dom; +virDomainJobInfo info; + +dom = get_nonnull_domain (conn, args-dom); +if (dom == NULL) { +remoteDispatchConnError(rerr, conn); +return -1; +} + +if (virDomainGetJobInfo (dom, info) == -1) { +virDomainFree(dom); +remoteDispatchConnError(rerr, conn); +return -1; +} + +ret-type = info.type; +ret-timeElapsed = info.timeElapsed; +ret-timeRemaining = info.timeRemaining; +ret-dataTotal = info.dataTotal; +ret-dataProcessed = info.dataProcessed; +ret-dataRemaining = info.dataRemaining; +ret-memTotal = info.memTotal; +ret-memProcessed = info.memProcessed; +ret-memRemaining = info.memRemaining; +ret-fileTotal = info.fileTotal; +ret-fileProcessed = info.fileProcessed; +ret-fileRemaining = info.fileRemaining; + +virDomainFree(dom); + return 0; } diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h index 86a881e..3a40542 100644 --- a/daemon/remote_dispatch_args.h +++ b/daemon/remote_dispatch_args.h @@ -138,3 +138,4 @@ remote_domain_attach_device_flags_args val_remote_domain_attach_device_flags_args; remote_domain_detach_device_flags_args val_remote_domain_detach_device_flags_args; remote_cpu_baseline_args val_remote_cpu_baseline_args; +remote_domain_get_job_info_args val_remote_domain_get_job_info_args; diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h index be67f9a..4b8992e 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -194,6 +194,14 @@ static int remoteDispatchDomainGetInfo( remote_error *err, remote_domain_get_info_args *args, remote_domain_get_info_ret *ret); +static int remoteDispatchDomainGetJobInfo( +struct qemud_server *server, +struct qemud_client *client, +virConnectPtr conn, +remote_message_header *hdr, +remote_error *err, +remote_domain_get_job_info_args *args, +remote_domain_get_job_info_ret *ret); static int remoteDispatchDomainGetMaxMemory( struct qemud_server *server, struct qemud_client *client, diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h index 5c6a78f..aa74480 100644 --- a/daemon/remote_dispatch_ret.h +++ b/daemon/remote_dispatch_ret.h @@ -118,3 +118,4 @@ remote_cpu_compare_ret val_remote_cpu_compare_ret; remote_domain_memory_stats_ret val_remote_domain_memory_stats_ret; remote_cpu_baseline_ret val_remote_cpu_baseline_ret; +remote_domain_get_job_info_ret val_remote_domain_get_job_info_ret; diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h index 428057a..a1b34d4 100644 --- a/daemon/remote_dispatch_table.h +++ b/daemon/remote_dispatch_table.h @@ -817,3 +817,8 @@ .args_filter = (xdrproc_t) xdr_remote_cpu_baseline_args, .ret_filter = (xdrproc_t) xdr_remote_cpu_baseline_ret, }, +{ /* DomainGetJobInfo = 163 */ +.fn = (dispatch_fn) remoteDispatchDomainGetJobInfo, +.args_filter = (xdrproc_t) xdr_remote_domain_get_job_info_args, +.ret_filter = (xdrproc_t)
[libvirt] [PATCH v2] remote: Print ssh stderr on connection failure
Signed-off-by: Cole Robinson crobi...@redhat.com --- src/remote/remote_driver.c | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 13534ce..8914c39 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -154,6 +154,7 @@ struct private_data { virMutex lock; int sock; /* Socket. */ +int errfd;/* File handle connected to remote stderr */ int watch; /* File handle watch */ pid_t pid; /* PID of tunnel process */ int uses_tls; /* TLS enabled on socket? */ @@ -783,6 +784,7 @@ doRemoteOpen (virConnectPtr conn, case trans_ext: { pid_t pid; int sv[2]; +int errfd[2]; /* Fork off the external process. Use socketpair to create a private * (unnamed) Unix domain socket to the child process so we don't have @@ -794,14 +796,22 @@ doRemoteOpen (virConnectPtr conn, goto failed; } +if (pipe(errfd) == -1) { +virReportSystemError(errno, %s, + _(unable to create socket pair)); +goto failed; +} + if (virExec((const char**)cmd_argv, NULL, NULL, -pid, sv[1], (sv[1]), NULL, +pid, sv[1], (sv[1]), (errfd[1]), VIR_EXEC_CLEAR_CAPS) 0) goto failed; /* Parent continues here. */ close (sv[1]); +close (errfd[1]); priv-sock = sv[0]; +priv-errfd = errfd[0]; priv-pid = pid; /* Do not set 'is_secure' flag since we can't guarentee @@ -827,6 +837,12 @@ doRemoteOpen (virConnectPtr conn, goto failed; } +if ((priv-errfd != -1) virSetNonBlock(priv-errfd) 0) { +virReportSystemError(errno, %s, + _(unable to make socket non-blocking)); +goto failed; +} + if (pipe(wakeupFD) 0) { virReportSystemError(errno, %s, _(unable to make pipe)); @@ -939,6 +955,9 @@ doRemoteOpen (virConnectPtr conn, failed: /* Close the socket if we failed. */ +if (priv-errfd = 0) +close(priv-errfd); + if (priv-sock = 0) { if (priv-uses_tls priv-session) { gnutls_bye (priv-session, GNUTLS_SHUT_RDWR); @@ -986,6 +1005,7 @@ remoteAllocPrivateData(virConnectPtr conn) priv-localUses = 1; priv-watch = -1; priv-sock = -1; +priv-errfd = -1; return priv; } @@ -1408,6 +1428,7 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv) sasl_dispose (priv-saslconn); #endif close (priv-sock); +close (priv-errfd); #ifndef WIN32 if (priv-pid 0) { @@ -7785,12 +7806,23 @@ remoteIOReadBuffer(virConnectPtr conn, if (errno == EWOULDBLOCK) return 0; +char errout[1024] = \0; +if (priv-errfd != -1) { +saferead(priv-errfd, errout, sizeof(errout)); +} + virReportSystemError(errno, - %s, _(cannot recv data)); + _(cannot recv data: %s), errout); + } else { +char errout[1024] = \0; +if (priv-errfd != -1) { +saferead(priv-errfd, errout, sizeof(errout)); +} + errorf (in_open ? NULL : conn, VIR_ERR_SYSTEM_ERROR, -%s, _(server closed connection)); +_(server closed connection: %s), errout); } return -1; } -- 1.6.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 9/9] Fix QEMU domain state after a save attempt fails
When a VM save attempt failed, the VM would be left in a paused state. It is neccessary to resume CPU execution upon failure if it was running originally * src/qemu/qemu_driver.c: Resume CPUs upon save failure --- src/qemu/qemu_driver.c | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5e787ce..0a39745 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4221,6 +4221,16 @@ static int qemudDomainSave(virDomainPtr dom, } endjob: +if (ret != 0 header.was_running) { +qemuDomainObjEnterMonitorWithDriver(driver, vm); +rc = qemuMonitorStartCPUs(priv-mon, dom-conn); +qemuDomainObjExitMonitorWithDriver(driver, vm); +if (rc 0) +VIR_WARN0(Unable to resume guest CPUs after save failure); +else +vm-state = VIR_DOMAIN_RUNNING; +} + if (vm qemuDomainObjEndJob(vm) == 0) vm = NULL; -- 1.6.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/9] Add QEMU driver support for job info on migration ops
Introduce support for virDomainGetJobInfo in the QEMU driver. This allows for monitoring of any API that uses the 'info migrate' monitor command. ie virDomainMigrate, virDomainSave and virDomainCoreDump Unfortunately QEMU does not provide a way to monitor incoming migration so we can't wire up virDomainRestore yet. The virsh tool gets a new command 'domjobinfo' to query status * src/qemu/qemu_driver.c: Record virDomainJobInfo and start time in qemuDomainObjPrivatePtr objects. Add generic shared handler for calling 'info migrate' with all migration based APIs. * src/qemu/qemu_monitor_text.c: Fix parsing of 'info migration' reply * tools/virsh.c: add new 'domjobinfo' command to query progress --- src/qemu/qemu_driver.c | 208 +++--- src/qemu/qemu_monitor_text.c |7 +- tools/virsh.c| 129 ++ 3 files changed, 288 insertions(+), 56 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a6dc4f9..b245eb2 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -87,6 +87,8 @@ struct _qemuDomainObjPrivate { int jobActive; /* Non-zero if a job is active. Only 1 job is allowed at any time * A job includes *all* monitor commands, even those just querying * information, not merely actions */ +virDomainJobInfo jobInfo; +unsigned long long jobStart; qemuMonitorPtr mon; virDomainChrDefPtr monConfig; @@ -329,6 +331,8 @@ static int qemuDomainObjBeginJob(virDomainObjPtr obj) } } priv-jobActive = 1; +priv-jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000); +memset(priv-jobInfo, 0, sizeof(priv-jobInfo)); return 0; } @@ -373,6 +377,8 @@ static int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, } } priv-jobActive = 1; +priv-jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000); +memset(priv-jobInfo, 0, sizeof(priv-jobInfo)); virDomainObjUnlock(obj); qemuDriverLock(driver); @@ -395,6 +401,8 @@ static int ATTRIBUTE_RETURN_CHECK qemuDomainObjEndJob(virDomainObjPtr obj) qemuDomainObjPrivatePtr priv = obj-privateData; priv-jobActive = 0; +priv-jobStart = 0; +memset(priv-jobInfo, 0, sizeof(priv-jobInfo)); virCondSignal(priv-jobCond); return virDomainObjUnref(obj); @@ -3919,6 +3927,96 @@ cleanup: } +static int +qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr vm) +{ +int ret = -1; +int status; +unsigned long long memProcessed; +unsigned long long memRemaining; +unsigned long long memTotal; +qemuDomainObjPrivatePtr priv = vm-privateData; + +priv-jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; + +while (priv-jobInfo.type == VIR_DOMAIN_JOB_UNBOUNDED) { +/* Poll every 1/2 second for progress to allow cancellation */ +struct timespec ts = { .tv_sec = 0, .tv_nsec = 500 * 1000ull }; +struct timeval now; +int rc; + +qemuDomainObjEnterMonitorWithDriver(driver, vm); +rc = qemuMonitorGetMigrationStatus(priv-mon, + status, + memProcessed, + memRemaining, + memTotal); +qemuDomainObjExitMonitorWithDriver(driver, vm); + +if (rc 0) { +priv-jobInfo.type = VIR_DOMAIN_JOB_FAILED; +goto cleanup; +} + +if (gettimeofday(now, NULL) 0) { +priv-jobInfo.type = VIR_DOMAIN_JOB_FAILED; +virReportSystemError(errno, %s, + _(cannot get time of day)); +goto cleanup; +} +priv-jobInfo.timeElapsed = +((now.tv_sec * 1000ull) + (now.tv_usec / 1000)) - +priv-jobStart; + +switch (status) { +case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE: +priv-jobInfo.type = VIR_DOMAIN_JOB_NONE; +qemuReportError(VIR_ERR_OPERATION_FAILED, +%s, _(Migration is not active)); +break; + +case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE: +priv-jobInfo.dataTotal = memTotal; +priv-jobInfo.dataRemaining = memRemaining; +priv-jobInfo.dataProcessed = memProcessed; + +priv-jobInfo.memTotal = memTotal; +priv-jobInfo.memRemaining = memRemaining; +priv-jobInfo.memProcessed = memProcessed; +break; + +case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED: +priv-jobInfo.type = VIR_DOMAIN_JOB_COMPLETED; +ret = 0; +break; + +case QEMU_MONITOR_MIGRATION_STATUS_ERROR: +priv-jobInfo.type = VIR_DOMAIN_JOB_FAILED; +qemuReportError(VIR_ERR_OPERATION_FAILED, +%s, _(Migration unexpectedly failed)); +
[libvirt] [PATCH v2] qemu: Check for IA64 kvm
From: Dustin Xiong x_k_...@hotmail.com ACPI feature bit dropped: I asked internally if the -no-acpi option had any meaning for IA64, and was told 'probably not'. Signed-off-by: Cole Robinson crobi...@redhat.com --- src/qemu/qemu_conf.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 79bd1e8..f02db9c 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -394,6 +394,7 @@ static const struct qemu_arch_info const arch_info_hvm[] = { { mipsel, 32, NULL, qemu-system-mipsel, NULL, NULL, 0 }, { sparc, 32, NULL, qemu-system-sparc, NULL, NULL, 0 }, { ppc,32, NULL, qemu-system-ppc,NULL, NULL, 0 }, +{ itanium, 64, NULL, qemu-system-ia64, NULL, NULL, 0 }, }; static const struct qemu_arch_info const arch_info_xen[] = { -- 1.6.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 7/9] Remote driver implementation for the virDomainAbortJob APi
This defines the wire protocol for the new API * src/remote/remote_protocol.x: Wire protocol definition * src/remote/remote_driver.c,daemon/remote.c: Client and server side implementation * daemon/remote_dispatch_args.h, daemon/remote_dispatch_prototypes.h, daemon/remote_dispatch_table.h, src/remote/remote_protocol.c, src/remote/remote_protocol.h: Re-generate from remote_protocol.x --- daemon/remote.c | 29 + daemon/remote_dispatch_args.h |1 + daemon/remote_dispatch_prototypes.h |8 daemon/remote_dispatch_table.h |5 + src/remote/remote_driver.c | 26 +- src/remote/remote_protocol.c|9 + src/remote/remote_protocol.h|8 src/remote/remote_protocol.x|8 +++- 8 files changed, 92 insertions(+), 2 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 67d663e..d4713b2 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -5434,6 +5434,35 @@ remoteDispatchDomainGetJobInfo (struct qemud_server *server ATTRIBUTE_UNUSED, } +static int +remoteDispatchDomainAbortJob (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header *hdr ATTRIBUTE_UNUSED, + remote_error *rerr, + remote_domain_abort_job_args *args, + void *ret ATTRIBUTE_UNUSED) +{ +virDomainPtr dom; + +dom = get_nonnull_domain (conn, args-dom); +if (dom == NULL) { +remoteDispatchConnError(rerr, conn); +return -1; +} + +if (virDomainAbortJob (dom) == -1) { +virDomainFree(dom); +remoteDispatchConnError(rerr, conn); +return -1; +} + +virDomainFree(dom); + +return 0; +} + + /*- Helpers. -*/ /* get_nonnull_domain and get_nonnull_network turn an on-wire diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h index 3a40542..f97155b 100644 --- a/daemon/remote_dispatch_args.h +++ b/daemon/remote_dispatch_args.h @@ -139,3 +139,4 @@ remote_domain_detach_device_flags_args val_remote_domain_detach_device_flags_args; remote_cpu_baseline_args val_remote_cpu_baseline_args; remote_domain_get_job_info_args val_remote_domain_get_job_info_args; +remote_domain_abort_job_args val_remote_domain_abort_job_args; diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h index 4b8992e..b81c8c3 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -66,6 +66,14 @@ static int remoteDispatchCpuCompare( remote_error *err, remote_cpu_compare_args *args, remote_cpu_compare_ret *ret); +static int remoteDispatchDomainAbortJob( +struct qemud_server *server, +struct qemud_client *client, +virConnectPtr conn, +remote_message_header *hdr, +remote_error *err, +remote_domain_abort_job_args *args, +void *ret); static int remoteDispatchDomainAttachDevice( struct qemud_server *server, struct qemud_client *client, diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h index a1b34d4..5ad6bff 100644 --- a/daemon/remote_dispatch_table.h +++ b/daemon/remote_dispatch_table.h @@ -822,3 +822,8 @@ .args_filter = (xdrproc_t) xdr_remote_domain_get_job_info_args, .ret_filter = (xdrproc_t) xdr_remote_domain_get_job_info_ret, }, +{ /* DomainAbortJob = 164 */ +.fn = (dispatch_fn) remoteDispatchDomainAbortJob, +.args_filter = (xdrproc_t) xdr_remote_domain_abort_job_args, +.ret_filter = (xdrproc_t) xdr_void, +}, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 82a82f4..a12f964 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7661,6 +7661,30 @@ done: } +static int +remoteDomainAbortJob (virDomainPtr domain) +{ +int rv = -1; +remote_domain_abort_job_args args; +struct private_data *priv = domain-conn-privateData; + +remoteDriverLock(priv); + +make_nonnull_domain (args.dom, domain); + +if (call (domain-conn, priv, 0, REMOTE_PROC_DOMAIN_ABORT_JOB, + (xdrproc_t) xdr_remote_domain_abort_job_args, (char *) args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) +goto done; + +rv = 0; + +done: +remoteDriverUnlock(priv); +return rv; +} + + /*--*/ @@ -9053,7 +9077,7 @@ static virDriver remote_driver = { remoteCPUCompare, /* cpuCompare */ remoteCPUBaseline, /* cpuBaseline */ remoteDomainGetJobInfo, /* domainGetJobInfo */ -NULL, /* domainFinishJob */ +remoteDomainAbortJob, /* domainFinishJob */ }; static virNetworkDriver network_driver = { diff --git
Re: [libvirt] [PATCH 3/4] remote: Print ssh stderr on connection failure
On 02/18/2010 09:44 AM, Daniel P. Berrange wrote: On Fri, Feb 12, 2010 at 10:32:16AM -0500, Cole Robinson wrote: --- src/remote/remote_driver.c | 37 ++--- 1 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 13534ce..7f92fd0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -154,6 +154,7 @@ struct private_data { virMutex lock; int sock; /* Socket. */ +int errsock;/* Socket connected to remote stderr */ int watch; /* File handle watch */ pid_t pid; /* PID of tunnel process */ int uses_tls; /* TLS enabled on socket? */ @@ -783,6 +784,7 @@ doRemoteOpen (virConnectPtr conn, case trans_ext: { pid_t pid; int sv[2]; +int errsock[2]; /* Fork off the external process. Use socketpair to create a private * (unnamed) Unix domain socket to the child process so we don't have @@ -794,14 +796,21 @@ doRemoteOpen (virConnectPtr conn, goto failed; } +if (socketpair (PF_UNIX, SOCK_STREAM, 0, errsock) == -1) { +virReportSystemError(errno, %s, + _(unable to create socket pair)); +goto failed; +} I think you just want pipe() here, since this does not want to be a bi-directional channel. + if (virExec((const char**)cmd_argv, NULL, NULL, -pid, sv[1], (sv[1]), NULL, +pid, sv[1], (sv[1]), (errsock[1]), VIR_EXEC_CLEAR_CAPS) 0) goto failed; /* Parent continues here. */ close (sv[1]); priv-sock = sv[0]; +priv-errsock = errsock[0]; priv-pid = pid; /* Do not set 'is_secure' flag since we can't guarentee @@ -827,6 +836,12 @@ doRemoteOpen (virConnectPtr conn, goto failed; } +if ((priv-errsock != -1) virSetNonBlock(priv-errsock) 0) { +virReportSystemError(errno, %s, + _(unable to make socket non-blocking)); +goto failed; +} + if (pipe(wakeupFD) 0) { virReportSystemError(errno, %s, _(unable to make pipe)); @@ -939,6 +954,9 @@ doRemoteOpen (virConnectPtr conn, failed: /* Close the socket if we failed. */ +if (priv-errsock = 0) +close(priv-errsock); + if (priv-sock = 0) { if (priv-uses_tls priv-session) { gnutls_bye (priv-session, GNUTLS_SHUT_RDWR); @@ -986,6 +1004,7 @@ remoteAllocPrivateData(virConnectPtr conn) priv-localUses = 1; priv-watch = -1; priv-sock = -1; +priv-errsock = -1; return priv; } @@ -1408,6 +1427,7 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv) sasl_dispose (priv-saslconn); #endif close (priv-sock); +close (priv-errsock); #ifndef WIN32 if (priv-pid 0) { @@ -7785,12 +7805,23 @@ remoteIOReadBuffer(virConnectPtr conn, if (errno == EWOULDBLOCK) return 0; +char errout[1024] = \0; +if (priv-errsock) { Should be priv-errsock != -1 +recv(priv-errsock, errout, sizeof(errout), 0); +} + virReportSystemError(errno, - %s, _(cannot recv data)); + _(cannot recv data: %s), errout); + } else { +char errout[1024] = \0; +if (priv-errsock) { Likewise here +recv(priv-errsock, errout, sizeof(errout), 0); +} + errorf (in_open ? NULL : conn, VIR_ERR_SYSTEM_ERROR, -%s, _(server closed connection)); +_(server closed connection: %s), errout); } return -1; } -- Daniel Thanks, I've sent an updated version. - Cole -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/2] Add virFork() function to utils.
virFork() contains bookkeeping that must be done any time a process forks. Currently this includes: 1) Call virLogLock() prior to fork() and virLogUnlock() just after, to avoid a deadlock if some other thread happens to hold that lock during the fork. 2) Reset the logging hooks and send all child process log messages to stderr. 3) Block all signals prior to fork(), then either a) reset the signal mask for the parent process, or b) clear the signal mask for the child process. Note that the signal mask handling in __virExec erroneously fails to restore the signal mask when fork() fails. virFork() fixes this problem. Other than this, it attempts to behave as closely to fork() as possible (including preserving errno for the caller), with a couple exceptions: 1) The return value is 0 (success) or -1 (failure), while the pid is returned via the pid_t* argument. Like fork(), if pid 0 there is no child process, otherwise both the child and the parent will return to the caller, and both should look at the return value, which will indicate if some of the extra processing outlined above encountered an error. 2) If virFork() returns with pid 0 or with a return value 0 indicating an error condition, the error has already been reported. You can log an additional message if you like, but it isn't necessary, and may be awkwardly extraneous. Note that virFork()'s child process will *never* call _exit() - if a child process is created, it will return to the caller. util.c, util.h: add virFork() function, based on what is currently done in __virExec(). --- src/util/util.c | 118 +++ src/util/util.h |1 + 2 files changed, 119 insertions(+), 0 deletions(-) diff --git a/src/util/util.c b/src/util/util.c index cdab300..d9beddf 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -296,6 +296,124 @@ static int virClearCapabilities(void) } #endif + +/* virFork() - fork a new process while avoiding various race/deadlock conditions + + @pid - a pointer to a pid_t that will receive the return value from + fork() + + on return from virFork(), if *pid 0, the fork failed and there is + no new process. Otherwise, just like fork(), if *pid == 0, it is the + child process returning, and if *pid 0, it is the parent. + + Even if *pid = 0, if the return value from virFork() is 0, it + indicates a failure that occurred in the parent or child process + after the fork. In this case, the child process should call + _exit(1) after doing any additional error reporting. + + */ +int virFork(pid_t *pid) { +sigset_t oldmask, newmask; +struct sigaction sig_action; +int saved_errno, ret = -1; + +*pid = -1; + +/* + * Need to block signals now, so that child process can safely + * kill off caller's signal handlers without a race. + */ +sigfillset(newmask); +if (pthread_sigmask(SIG_SETMASK, newmask, oldmask) != 0) { +saved_errno = errno; +virReportSystemError(errno, + %s, _(cannot block signals)); +goto cleanup; +} + +/* Ensure we hold the logging lock, to protect child processes + * from deadlocking on another thread's inherited mutex state */ +virLogLock(); + +*pid = fork(); +saved_errno = errno; /* save for caller */ + +/* Unlock for both parent and child process */ +virLogUnlock(); + +if (*pid 0) { +/* attempt to restore signal mask, but ignore failure, to + avoid obscuring the fork failure */ +pthread_sigmask(SIG_SETMASK, oldmask, NULL); +virReportSystemError(saved_errno, + %s, _(cannot fork child process)); +goto cleanup; +} + +if (*pid) { + +/* parent process */ + +/* Restore our original signal mask now that the child is + safely running */ +if (pthread_sigmask(SIG_SETMASK, oldmask, NULL) != 0) { +saved_errno = errno; /* save for caller */ +virReportSystemError(errno, %s, _(cannot unblock signals)); +goto cleanup; +} +ret = 0; + +} else { + +/* child process */ + +int logprio; +int i; + +/* Remove any error callback so errors in child now + get sent to stderr where they stand a fighting chance + of being seen / logged */ +virSetErrorFunc(NULL, NULL); + +/* Make sure any hook logging is sent to stderr, since child + * process may close the logfile FDs */ +logprio = virLogGetDefaultPriority(); +virLogReset(); +virLogSetDefaultPriority(logprio); + +/* Clear out all signal handlers from parent so nothing + unexpected can happen in our child once we unblock + signals */ +sig_action.sa_handler = SIG_DFL; +sig_action.sa_flags = 0; +
[libvirt] [PATCH 0/2] Make a wrapper for fork() - Take 2
This is an update to / deprecates the patchset I sent last night: https://www.redhat.com/archives/libvir-list/2010-February/msg00580.html I have corrected the problem found by Dan Berrange (neglecting to restore the signal mask when fork() fails). Aside from that, and corresponding comments in the commit logs, it is unchanged. Here's the original intro email: This was partly prompted by DV's suggestion last week. The first of these patches creates a new function called virFork() which behaves (almost) like fork() but takes care of some important details that pretty much any call to fork() should be doing. The 2nd switches three fork-calling functions in util.c over to using virFork() instead of fork(). In the future, except for odd circumstances, code that needs to fork should call virFork() instead, and if there is anything determined to be universally necessary at fork-time, it should be added to virFork() rather than to the callers of virFork(); hopefully this will ease maintenance and reduce replicated bugs. (Note that, while this is just an overall code health patch, a couple bug fix patches I'll be submitting either tomorrow or Thursday will assume it as a prerequisite). -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/2] Use virFork() in __virExec(), virFileCreate() and virDirCreate()
For __virExec() this is a semantic NOP except for when fork() fails. __virExec() would previously forget to restore the signal mask in this case; virFork() corrects this behavior. virFileCreate() and virDirCreate() gain the code to reset the logging and properly deal with the signal handling race condition. This also removes a log message that had a typo (cannot fork o create file '%s') - this error is now logged in a more generic manner in virFork() (more generic, but really just as informative, since the fact that it's forking to create a file is immaterial to the fact that it simply can't fork) --- src/util/util.c | 100 ++ 1 files changed, 26 insertions(+), 74 deletions(-) diff --git a/src/util/util.c b/src/util/util.c index d9beddf..c3b4084 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -451,20 +451,6 @@ __virExec(const char *const*argv, int pipeerr[2] = {-1,-1}; int childout = -1; int childerr = -1; -int logprio; -sigset_t oldmask, newmask; -struct sigaction sig_action; - -/* - * Need to block signals now, so that child process can safely - * kill off caller's signal handlers without a race. - */ -sigfillset(newmask); -if (pthread_sigmask(SIG_SETMASK, newmask, oldmask) != 0) { -virReportSystemError(errno, - %s, _(cannot block signals)); -return -1; -} if ((null = open(/dev/null, O_RDONLY)) 0) { virReportSystemError(errno, @@ -531,17 +517,9 @@ __virExec(const char *const*argv, childerr = null; } -/* Ensure we hold the logging lock, to protect child processes - * from deadlocking on another threads inheirited mutex state */ -virLogLock(); -pid = fork(); - -/* Unlock for both parent and child process */ -virLogUnlock(); +int forkRet = virFork(pid); if (pid 0) { -virReportSystemError(errno, - %s, _(cannot fork child process)); goto cleanup; } @@ -556,12 +534,8 @@ __virExec(const char *const*argv, *errfd = pipeerr[0]; } -/* Restore our original signal mask now child is safely - running */ -if (pthread_sigmask(SIG_SETMASK, oldmask, NULL) != 0) { -virReportSystemError(errno, - %s, _(cannot unblock signals)); -return -1; +if (forkRet 0) { +goto cleanup; } *retpid = pid; @@ -570,38 +544,10 @@ __virExec(const char *const*argv, /* child */ -/* Remove any error callback too, so errors in child now - get sent to stderr where they stand a fighting chance - of being seen / logged */ -virSetErrorFunc(NULL, NULL); - -/* Make sure any hook logging is sent to stderr, since virExec will - * close any unknown FDs (including logging handlers) before launching - * the new process */ -logprio = virLogGetDefaultPriority(); -virLogReset(); -virLogSetDefaultPriority(logprio); - -/* Clear out all signal handlers from parent so nothing - unexpected can happen in our child once we unblock - signals */ -sig_action.sa_handler = SIG_DFL; -sig_action.sa_flags = 0; -sigemptyset(sig_action.sa_mask); - -for (i = 1 ; i NSIG ; i++) -/* Only possible errors are EFAULT or EINVAL - The former wont happen, the latter we - expect, so no need to check return value */ -sigaction(i, sig_action, NULL); - -/* Unmask all signals in child, since we've no idea - what the caller's done with their signal mask - and don't want to propagate that to children */ -sigemptyset(newmask); -if (pthread_sigmask(SIG_SETMASK, newmask, NULL) != 0) { -virReportSystemError(errno, - %s, _(cannot unblock signals)); +if (forkRet 0) { +/* The fork was sucessful, but after that there was an error + * in the child (which was already logged). +*/ _exit(1); } @@ -1370,14 +1316,10 @@ int virFileCreate(const char *path, mode_t mode, * following dance avoids problems caused by root-squashing * NFS servers. */ -virLogLock(); -pid = fork(); -virLogUnlock(); +int forkRet = virFork(pid); if (pid 0) { ret = errno; -virReportSystemError(errno, - _(cannot fork o create file '%s'), path); return ret; } @@ -1429,7 +1371,15 @@ parenterror: return ret; } -/* child - set desired uid/gid, then attempt to create the file */ + +/* child */ + +if (forkRet 0) { +/* error encountered and logged in virFork() after the fork. */ +goto childerror; +} + +/* set desired uid/gid, then attempt to create the file */ if ((gid != 0) (setgid(gid) != 0)) { ret = errno; @@ -1480,15 +1430,10 @@ int
Re: [libvirt] [PATCH 1/2] Add domain support for virtio channel
On Thu, Feb 18, 2010 at 03:29:13PM +, Matthew Booth wrote: On 18/02/10 14:09, Daniel P. Berrange wrote: On Thu, Feb 18, 2010 at 01:16:02PM +, Matthew Booth wrote: On 18/02/10 12:34, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 05:11:00PM +, Matthew Booth wrote: Add support for virtio-serial by defining a new 'virtio' channel target type and a virtio-serial controller. Allows the following to be specified in a domain: [...] Updated patch attached. [...] @@ -4905,11 +5055,18 @@ virDomainChrDefFormat(virBufferPtr buf, break; } +case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO: +virBufferAddLit(buf, target type='virtio'); +if (def-target.name) { +virBufferVSprintf(buf, name='%s', def-target.name); I changed that to use virBufferEscapeString as the string comes from the user XML input. +} +virBufferAddLit(buf, /\n); +break; + ACK, and pushed, thanks ! Daniel -- 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
Re: [libvirt] [PATCH 2/2] Add QEMU support for virtio channel
On Thu, Feb 18, 2010 at 03:29:51PM +, Matthew Booth wrote: On 18/02/10 14:11, Daniel P. Berrange wrote: On Thu, Feb 18, 2010 at 01:23:57PM +, Matthew Booth wrote: On 18/02/10 12:39, Daniel P. Berrange wrote: On Wed, Feb 17, 2010 at 05:11:01PM +, Matthew Booth wrote: Support virtio-serial controller and virtio channel in QEMU backend. Will output the following for virtio-serial controller: [...] Update patch attached. ACK, looks fine, applied too, thanks ! Daniel -- 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
[libvirt] [PATCH 1/6] Change the internal domain conf representation of localtime/utc
The XML will soon be extended to allow more than just a simple localtime/utc boolean flag. This change replaces the plain 'int localtime' with a separate struct to prepare for future extension * src/conf/domain_conf.c, src/conf/domain_conf.h: Add a new virDomainClockDef structure * src/libvirt_private.syms: Export virDomainClockOffsetTypeToString and virDomainClockOffsetTypeFromString * src/qemu/qemu_conf.c, src/vbox/vbox_tmpl.c, src/xen/xend_internal.c, src/xen/xm_internal.c: Updated to use new structure for localtime --- src/conf/domain_conf.c | 19 +++ src/conf/domain_conf.h | 16 +++- src/libvirt_private.syms |2 ++ src/qemu/qemu_conf.c | 11 +-- src/vbox/vbox_tmpl.c |2 +- src/xen/xend_internal.c | 16 +++- src/xen/xm_internal.c| 21 ++--- 7 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 561fa22..f86b4eb 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -229,6 +229,10 @@ VIR_ENUM_IMPL(virDomainNetdevMacvtap, VIR_DOMAIN_NETDEV_MACVTAP_MODE_LAST, private, bridge) +VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST, + utc, + localtime); + #define virDomainReportError(code, fmt...) \ virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__, \ __FUNCTION__, __LINE__, fmt) @@ -3478,9 +3482,16 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, tmp = virXPathString(string(./clock/@offset), ctxt); -if (tmp STREQ(tmp, localtime)) -def-localtime = 1; -VIR_FREE(tmp); +if (tmp) { +if ((def-clock.offset = virDomainClockOffsetTypeFromString(tmp)) 0) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(unknown clock offset '%s'), tmp); +goto error; +} +VIR_FREE(tmp); +} else { +def-clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC; +} def-os.bootloader = virXPathString(string(./bootloader), ctxt); def-os.bootloaderArgs = virXPathString(string(./bootloader_args), ctxt); @@ -5389,7 +5400,7 @@ char *virDomainDefFormat(virDomainDefPtr def, goto cleanup; virBufferVSprintf(buf, clock offset='%s'/\n, - def-localtime ? localtime : utc); + virDomainClockOffsetTypeToString(def-clock.offset)); if (virDomainLifecycleDefFormat(buf, def-onPoweroff, on_poweroff) 0) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 231d8c8..fbbe683 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -609,6 +609,19 @@ struct _virSecurityLabelDef { int type; }; +enum virDomainClockOffsetType { +VIR_DOMAIN_CLOCK_OFFSET_UTC = 0, +VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME = 1, + +VIR_DOMAIN_CLOCK_OFFSET_LAST, +}; + +typedef struct _virDomainClockDef virDomainClockDef; +typedef virDomainClockDef *virDomainClockDefPtr; +struct _virDomainClockDef { +int offset; +}; + #define VIR_DOMAIN_CPUMASK_LEN 1024 /* Guest VM main configuration */ @@ -637,7 +650,7 @@ struct _virDomainDef { char *emulator; int features; -int localtime; +virDomainClockDef clock; int ngraphics; virDomainGraphicsDefPtr *graphics; @@ -911,6 +924,7 @@ VIR_ENUM_DECL(virDomainGraphics) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainSeclabel) +VIR_ENUM_DECL(virDomainClockOffset) VIR_ENUM_DECL(virDomainNetdevMacvtap) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index aa826d6..1af34bd 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -190,6 +190,8 @@ virDomainDefAddDiskControllers; virDomainDefClearPCIAddresses; virDomainDefClearDeviceAliases; virDomainDeviceInfoIterate; +virDomainClockOffsetTypeToString; +virDomainClockOffsetTypeFromString; # domain_event.h diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index c9fe55b..a207fc7 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -3400,8 +3400,14 @@ int qemudBuildCommandLine(virConnectPtr conn, } } -if (def-localtime) +if (def-clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) ADD_ARG_LIT(-localtime); +else if (def-clock.offset != VIR_DOMAIN_CLOCK_OFFSET_UTC) { +qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, +_(unsupported clock offset '%s'), +virDomainClockOffsetTypeToString(def-clock.offset)); +goto error; +} if ((qemuCmdFlags QEMUD_CMD_FLAG_NO_REBOOT) def-onReboot != VIR_DOMAIN_LIFECYCLE_RESTART) @@ -5218,6 +5224,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, def-id = -1; def-memory = def-maxmem = 64 * 1024; def-vcpus = 1; +
[libvirt] [PATCH 2/6] Add new clock mode allowing variable adjustments
This introduces a third option for clock offset synchronization, that allows an arbitrary / variable adjustment to be set. In essence the XML contains the time delta in seconds, relative to UTC. clock offset='variable' adjustment='123465'/ The difference from 'utc' mode, is that management apps should track adjustments and preserve them at next reboot. * docs/schemas/domain.rng: Schema for new clock mode * src/conf/domain_conf.c, src/conf/domain_conf.h: Parse new clock time delta * src/libvirt_private.syms, src/util/xml.c, src/util/xml.h: Add virXPathLongLong() method --- docs/schemas/domain.rng | 25 +--- src/conf/domain_conf.c | 18 +- src/conf/domain_conf.h |5 src/libvirt_private.syms |1 + src/util/xml.c | 54 ++ src/util/xml.h |5 +++- 6 files changed, 101 insertions(+), 7 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 1ff0944..d295bfe 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -297,12 +297,24 @@ define name=clock optional element name=clock -attribute name=offset - choice + choice + attribute name=offset valuelocaltime/value + /attribute + attribute name=offset valueutc/value - /choice -/attribute + /attribute + group +attribute name=offset + valuevariable/value + /attribute + optional + attribute name=adjustment + ref name=timeDelta/ + /attribute + /optional + /group + /choice empty/ /element /optional @@ -1567,4 +1579,9 @@ param name='pattern'[a-zA-Z0-9\-_]+/param /data /define + define name=timeDelta +data type=string + param name=pattern(-|\+)?[0-9]+/param +/data + /define /grammar diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f86b4eb..49d5d19 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -231,7 +231,8 @@ VIR_ENUM_IMPL(virDomainNetdevMacvtap, VIR_DOMAIN_NETDEV_MACVTAP_MODE_LAST, VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST, utc, - localtime); + localtime, + variable); #define virDomainReportError(code, fmt...) \ virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__, \ @@ -3492,6 +3493,13 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, } else { def-clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC; } +switch (def-clock.offset) { +case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: +if (virXPathLongLong(./clock/@adjustment, ctxt, + def-clock.adjustment) 0) +def-clock.adjustment = 0; +break; +} def-os.bootloader = virXPathString(string(./bootloader), ctxt); def-os.bootloaderArgs = virXPathString(string(./bootloader_args), ctxt); @@ -5399,8 +5407,14 @@ char *virDomainDefFormat(virDomainDefPtr def, if (virCPUDefFormatBuf(buf, def-cpu, , 0) 0) goto cleanup; -virBufferVSprintf(buf, clock offset='%s'/\n, +virBufferVSprintf(buf, clock offset='%s', virDomainClockOffsetTypeToString(def-clock.offset)); +switch (def-clock.offset) { +case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: +virBufferVSprintf(buf, adjustment='%lld', def-clock.adjustment); +break; +} +virBufferAddLit(buf, /\n); if (virDomainLifecycleDefFormat(buf, def-onPoweroff, on_poweroff) 0) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index fbbe683..f5fe016 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -612,6 +612,7 @@ struct _virSecurityLabelDef { enum virDomainClockOffsetType { VIR_DOMAIN_CLOCK_OFFSET_UTC = 0, VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME = 1, +VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2, VIR_DOMAIN_CLOCK_OFFSET_LAST, }; @@ -620,6 +621,10 @@ typedef struct _virDomainClockDef virDomainClockDef; typedef virDomainClockDef *virDomainClockDefPtr; struct _virDomainClockDef { int offset; + +/* Adjustment in seconds, relative to UTC, when + * offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE */ +long long adjustment; }; #define VIR_DOMAIN_CPUMASK_LEN 1024 diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1af34bd..41bde8e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -629,6 +629,7 @@ virXPathStringLimit; virXPathBoolean; virXPathNumber; virXPathULong; +virXPathLongLong; virXPathULongLong; virXPathLongHex; virXPathULongHex; diff --git a/src/util/xml.c b/src/util/xml.c index 46ea9aa..14c8345 100644 --- a/src/util/xml.c +++ b/src/util/xml.c @@ -364,6 +364,60 @@ virXPathULongLong(const
[libvirt] [PATCH 4/6] Allow a timezone to be specified instead of sync to host timezone
This extends the XML to allow for clock offset='timezone' timezone='Europe/Paris'/ This is useful if the admin has not configured any timezone on the host OS, but still wants to synchronize a guest to a specific one. * src/conf/domain_conf.h, src/conf/domain_conf.c: Support extra 'timezone' attribute on clock configuration * docs/schemas/domain.rng: Add 'timezone' attribute * src/xen/xend_internal.c, src/xen/xm_internal.c: Reject configs with a configurable timezone --- docs/schemas/domain.rng | 18 +++--- src/conf/domain_conf.c | 24 src/conf/domain_conf.h | 13 ++--- src/qemu/qemu_conf.c|2 +- src/xen/xend_internal.c | 10 -- src/xen/xm_internal.c | 17 - 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index d295bfe..4a36a97 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -298,9 +298,16 @@ optional element name=clock choice - attribute name=offset -valuelocaltime/value - /attribute + group +attribute name=offset + valuelocaltime/value + /attribute + optional + attribute name=timezone + ref name=timeZone/ + /attribute + /optional + /group attribute name=offset valueutc/value /attribute @@ -1584,4 +1591,9 @@ param name=pattern(-|\+)?[0-9]+/param /data /define + define name=timeZone +data type=string + param name=pattern[a-zA-Z0-9_\.\+\-/]+/param +/data + /define /grammar diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 49d5d19..ed5d9fd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -232,7 +232,8 @@ VIR_ENUM_IMPL(virDomainNetdevMacvtap, VIR_DOMAIN_NETDEV_MACVTAP_MODE_LAST, VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST, utc, localtime, - variable); + variable, + timezone); #define virDomainReportError(code, fmt...) \ virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__, \ @@ -650,6 +651,9 @@ void virDomainDefFree(virDomainDefPtr def) VIR_FREE(def-os.bootloader); VIR_FREE(def-os.bootloaderArgs); +if (def-clock.offset == VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE) +VIR_FREE(def-clock.data.timezone); + VIR_FREE(def-name); VIR_FREE(def-cpumask); VIR_FREE(def-emulator); @@ -3496,8 +3500,17 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, switch (def-clock.offset) { case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: if (virXPathLongLong(./clock/@adjustment, ctxt, - def-clock.adjustment) 0) -def-clock.adjustment = 0; + def-clock.data.adjustment) 0) +def-clock.data.adjustment = 0; +break; + +case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE: +def-clock.data.timezone = virXPathString(string(./clock/@timezone), ctxt); +if (!def-clock.data.timezone) { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, %s, + _(missing 'timezone' attribute for clock with offset='timezone')); +goto error; +} break; } @@ -5411,7 +5424,10 @@ char *virDomainDefFormat(virDomainDefPtr def, virDomainClockOffsetTypeToString(def-clock.offset)); switch (def-clock.offset) { case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: -virBufferVSprintf(buf, adjustment='%lld', def-clock.adjustment); +virBufferVSprintf(buf, adjustment='%lld', def-clock.data.adjustment); +break; +case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE: +virBufferEscapeString(buf, timezone='%s', def-clock.data.timezone); break; } virBufferAddLit(buf, /\n); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f5fe016..1dcfaa5 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -613,6 +613,7 @@ enum virDomainClockOffsetType { VIR_DOMAIN_CLOCK_OFFSET_UTC = 0, VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME = 1, VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2, +VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE = 3, VIR_DOMAIN_CLOCK_OFFSET_LAST, }; @@ -622,9 +623,15 @@ typedef virDomainClockDef *virDomainClockDefPtr; struct _virDomainClockDef { int offset; -/* Adjustment in seconds, relative to UTC, when - * offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE */ -long long adjustment; +union { +/* Adjustment in seconds, relative to UTC, when + * offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE */ +long long adjustment; + +/* Timezone name, when + * offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME */ +char *timezone; +} data; }; #define
[libvirt] [PATCH 0/6] Add more guest clock mods
An update of http://www.redhat.com/archives/libvir-list/2010-February/msg00104.html The two current options are: clock offset='utc'/ clock offset='localtime'/ This introduces a way to set a specific timezone clock offset='timezone' timezone='Europe/Paris'/ And a way to set a completely arbitrary time, by giving the number of seconds offset from UTC. clock offset='variable' adjustment='123456'/ Since last time, I removed the 'timezone' attribute from the existing offset='localtime' option, and introduced the new explicit option offset='timezone'. That way we don't change semantics of the existing options at all. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 5/6] Allow configurable timezones with QEMU
Allow an arbitrary timezone with QEMU by setting the $TZ environment variable when launching QEMU * src/qemu/qemu_conf.c: Set TZ environment variable if a timezone is requested * tests/qemuxml2argvtest.c: Add test case for timezones * tests/qemuxml2argvdata/qemuxml2argv-clock-france.xml, tests/qemuxml2argvdata/qemuxml2argv-clock-france.args: Data for timezone tests --- src/qemu/qemu_conf.c |6 + .../qemuxml2argv-clock-france.args |1 + .../qemuxml2argvdata/qemuxml2argv-clock-france.xml | 24 tests/qemuxml2argvtest.c |2 + 4 files changed, 33 insertions(+), 0 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-france.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-france.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index cd0dd7f..4ed00cb 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2983,6 +2983,7 @@ qemuBuildClockArgStr(virDomainClockDefPtr def) break; case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: +case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE: virBufferAddLit(buf, base=localtime); break; @@ -3462,6 +3463,7 @@ int qemudBuildCommandLine(virConnectPtr conn, } else { switch (def-clock.offset) { case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: +case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE: ADD_ARG_LIT(-localtime); break; @@ -3476,6 +3478,10 @@ int qemudBuildCommandLine(virConnectPtr conn, goto error; } } +if (def-clock.offset == VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE +def-clock.data.timezone) { +ADD_ENV_PAIR(TZ, def-clock.data.timezone); +} if ((qemuCmdFlags QEMUD_CMD_FLAG_NO_REBOOT) def-onReboot != VIR_DOMAIN_LIFECYCLE_RESTART) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-france.args b/tests/qemuxml2argvdata/qemuxml2argv-clock-france.args new file mode 100644 index 000..3c57397 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-france.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test TZ=Europe/Paris /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -rtc base=localtime -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-france.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-france.xml new file mode 100644 index 000..157fdfb --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-france.xml @@ -0,0 +1,24 @@ +domain type='qemu' + nameQEMUGuest1/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory219200/memory + currentMemory219200/currentMemory + vcpu1/vcpu + os +type arch='i686' machine='pc'hvm/type +boot dev='hd'/ + /os + clock offset='timezone' timezone='Europe/Paris'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +emulator/usr/bin/qemu/emulator +disk type='block' device='disk' + source dev='/dev/HostVG/QEMUGuest1'/ + target dev='hda' bus='ide'/ + address type='drive' controller='0' bus='0' unit='0'/ +/disk +controller type='ide' index='0'/ + /devices +/domain diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 510176c..bd41b6c 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -230,6 +230,8 @@ mymain(int argc, char **argv) * Can't be enabled since the absolute timestamp changes every time DO_TEST(clock-variable, QEMUD_CMD_FLAG_RTC); */ +DO_TEST(clock-france, QEMUD_CMD_FLAG_RTC); + DO_TEST(hugepages, QEMUD_CMD_FLAG_MEM_PATH); DO_TEST(disk-cdrom, 0); DO_TEST(disk-cdrom-empty, QEMUD_CMD_FLAG_DRIVE); -- 1.6.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/6] Support variable clock offset mode in QEMU
This allows QEMU guests to be started with an arbitrary clock offset The test case can't actually be enabled, since QEMU argv expects an absolute timestring, and this will obviously change every time the test runs :-( Hopefully QEMU will allow a relative time offset in the future. * src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Use the -rtc arg if available to support variable clock offset mode * tests/qemuhelptest.c: Add QEMUD_CMD_FLAG_RTC for qemu 0.12.1 * qemuxml2argvdata/qemuxml2argv-clock-variable.args, qemuxml2argvdata/qemuxml2argv-clock-variable.xml, qemuxml2argvtest.c: Test case, except we can't actually enable it yet. --- src/qemu/qemu_conf.c | 82 ++-- src/qemu/qemu_conf.h |1 + tests/qemuhelptest.c |3 +- .../qemuxml2argv-clock-variable.args |1 + .../qemuxml2argv-clock-variable.xml| 24 ++ tests/qemuxml2argvtest.c |4 + 6 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-variable.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-variable.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index a207fc7..112a7c2 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1155,6 +1155,9 @@ static unsigned long long qemudComputeCmdFlags(const char *help, flags |= QEMUD_CMD_FLAG_BALLOON; if (strstr(help, -device)) flags |= QEMUD_CMD_FLAG_DEVICE; +/* The trailing ' ' is important to avoid a bogus match */ +if (strstr(help, -rtc )) +flags |= QEMUD_CMD_FLAG_RTC; /* Keep disabled till we're actually ready to turn on netdev mode * The plan is todo it in 0.13.0 QEMU, but lets wait see... */ #if 0 @@ -2969,6 +2972,56 @@ error: } +static char * +qemuBuildClockArgStr(virDomainClockDefPtr def) +{ +virBuffer buf = VIR_BUFFER_INITIALIZER; + +switch (def-offset) { +case VIR_DOMAIN_CLOCK_OFFSET_UTC: +virBufferAddLit(buf, base=utc); +break; + +case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: +virBufferAddLit(buf, base=localtime); +break; + +case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: { +time_t now = time(NULL); +struct tm nowbits; + +now += def-adjustment; +gmtime_r(now, nowbits); + +virBufferVSprintf(buf, base=%d-%d-%dT%d:%d:%d, + nowbits.tm_year, + nowbits.tm_mon, + nowbits.tm_mday, + nowbits.tm_hour, + nowbits.tm_min, + nowbits.tm_sec); +} break; + +default: +qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, +_(unsupported clock offset '%s'), +virDomainClockOffsetTypeToString(def-offset)); +goto error; +} + +if (virBufferError(buf)) { +virReportOOMError(); +goto error; +} + +return virBufferContentAndReset(buf); + +error: +virBufferFreeAndReset(buf); +return NULL; +} + + static int qemuBuildCpuArgStr(const struct qemud_driver *driver, const virDomainDefPtr def, @@ -3400,13 +3453,28 @@ int qemudBuildCommandLine(virConnectPtr conn, } } -if (def-clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) -ADD_ARG_LIT(-localtime); -else if (def-clock.offset != VIR_DOMAIN_CLOCK_OFFSET_UTC) { -qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, -_(unsupported clock offset '%s'), -virDomainClockOffsetTypeToString(def-clock.offset)); -goto error; +if (qemuCmdFlags QEMUD_CMD_FLAG_RTC) { +const char *rtcopt; +ADD_ARG_LIT(-rtc); +if (!(rtcopt = qemuBuildClockArgStr(def-clock))) +goto error; +ADD_ARG(rtcopt); +} else { +switch (def-clock.offset) { +case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: +ADD_ARG_LIT(-localtime); +break; + +case VIR_DOMAIN_CLOCK_OFFSET_UTC: +/* Nothing, its the default */ +break; + +default: +qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, +_(unsupported clock offset '%s'), + virDomainClockOffsetTypeToString(def-clock.offset)); +goto error; +} } if ((qemuCmdFlags QEMUD_CMD_FLAG_NO_REBOOT) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 7041489..e32a3d7 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -82,6 +82,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_SDL = (1 27), /* Is the new -sdl arg available */ QEMUD_CMD_FLAG_SMP_TOPOLOGY = (1 28), /* Is sockets=s,cores=c,threads=t available for -smp? */ QEMUD_CMD_FLAG_NETDEV= (1 29), /* The -netdev
[libvirt] [PATCH 6/6] Expand docs about clock modes
* formatdomain.html.in: Document new clock options --- docs/formatdomain.html.in | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 083a80a..55038e2 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -393,9 +393,41 @@ dl dtcodeclock/code/dt - ddThe codeoffset/code attribute takes either utc or -localtime to specify how the guest clock is initialized -in relation to the host OS. + dd + pThe codeoffset/code attribute takes three possible + values, allowing fine grained control over how the guest + clock is synchronized to the host. NB, not all hypervisors + support all modes./p + dl + dtcodeutc/code/dt + dd + The guest clock will always be synchronized to UTC when + booted/dd + dtcodelocaltime/code/dt + dd + The guest clock will be synchronized to the host's configured + timezone when booted, if any. + /dd + dtcodetimezone/code/dt + dd + The guest clock will be synchronized to the requested timezone + using the codetimezone/code attribute. + /dd + dtcodevariable/code/dt + dd + The guest clock will have an arbitrary offset applied + relative to UTC. The delta relative to UTC is specified + in seconds, using the codeadjustment/code attribute. + The guest is free to adjust the RTC over time an expect + that it will be honoured at next reboot. This is in + contrast to 'utc' mode, where the RTC adjustments are + lost at each reboot. + /dd + /dl + p + NB, at time of writing, only QEMU supports the variable + clock mode, or custom timezones. + /p /dd /dl -- 1.6.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] FW: [PATCH 1/4] Addition of XenAPI support to libvirt
This is a patch to add XenAPI driver support for libvirt version 0.7.6. XenAPI can be used against XenCloud platform and managed through virsh and virt-manger. This patch supports domain related APIs in libvirt. It is possible to get domain information, list active and inactive domains, get Domain XML configuration and Start/stop/pause/shutdown/destroy VMs. There will be more patches after this review to support more libvirt APIs and add remote storage support to XenAPI. In order to run this patch you would require libxenserver library. The XenCloud platform can be downloaded from http://xen.org/products/cloudxen.html diff -ur ./libvirt_org/configure.ac ./libvirt/configure.ac --- ./libvirt_org/configure.ac 2010-02-17 17:39:21.0 + +++ ./libvirt/configure.ac 2010-02-18 11:51:29.0 + @@ -219,6 +219,8 @@ AC_HELP_STRING([--with-libssh2=@:@PFX@:@], [libssh2 location @:@default=/usr/local/lib@:@]),[],[with_libssh2=yes]) AC_ARG_WITH([phyp], AC_HELP_STRING([--with-phyp], [add PHYP support @:@default=check@:@]),[],[with_phyp=check]) +AC_ARG_WITH([xenapi], + AC_HELP_STRING([--with-xenapi], [add XenAPI support @:@default=yes@:@]),[],[with_xenapi=check]) AC_ARG_WITH([vbox], AC_HELP_STRING([--with-vbox], [add VirtualBox support @:@default=yes@:@]),[],[with_vbox=yes]) AC_ARG_WITH([lxc], @@ -307,6 +309,11 @@ fi AM_CONDITIONAL([WITH_VBOX], [test $with_vbox = yes]) +if test $with_xenapi = yes; then +AC_DEFINE_UNQUOTED([WITH_XENAPI], 1, [whether XenAPI driver is enabled]) +fi +AM_CONDITIONAL([WITH_XENAPI], [test $with_xenapi = yes]) + if test $with_libvirtd = no ; then with_qemu=no fi @@ -1894,6 +1901,7 @@ AC_MSG_NOTICE([ UML: $with_uml]) AC_MSG_NOTICE([ OpenVZ: $with_openvz]) AC_MSG_NOTICE([VBox: $with_vbox]) +AC_MSG_NOTICE([ XenAPI: $with_xenapi]) AC_MSG_NOTICE([ LXC: $with_lxc]) AC_MSG_NOTICE([PHYP: $with_phyp]) AC_MSG_NOTICE([ ONE: $with_one]) diff -ur ./libvirt_org/src/Makefile.am ./libvirt/src/Makefile.am --- ./libvirt_org/src/Makefile.am 2010-02-17 17:38:13.0 + +++ ./libvirt/src/Makefile.am 2010-02-18 16:25:55.0 + @@ -3,12 +3,19 @@ # No libraries with the exception of LIBXML should be listed # here. List them against the individual XXX_la_CFLAGS targets # that actually use them + +XENAPI_CFLAGS = -...@top_srcdir@/../libxenserver/include + INCLUDES = \ -I$(top_srcdir)/gnulib/lib \ -I../gnulib/lib \ -I../include\ +-I/usr/include \ -...@top_srcdir@/src/util \ + -...@top_srcdir@/src \ + -...@top_srcdir@/src/xenapi \ -...@top_srcdir@/include \ + $(XENAPI_CFLAGS)\ $(DRIVER_MODULE_CFLAGS) \ $(LIBXML_CFLAGS)\ -DLIBDIR=\$(libdir)\\ @@ -42,6 +49,8 @@ augeastestdir = $(datadir)/augeas/lenses/tests augeastest_DATA = +XENAPI_LIBS = @top_srcdir@/../libxenserver/libxenserver.so + # These files are not related to driver APIs. Simply generic # helper APIs for various purposes UTIL_SOURCES = \ @@ -205,6 +214,10 @@ qemu/qemu_security_dac.h\ qemu/qemu_security_dac.c +XENAPI_DRIVER_SOURCES = \ +xenapi/xenapi_driver.c xenapi/xenapi_driver.h \ +xenapi/xenapi_utils.c xenapi/xenapi_utils.h + UML_DRIVER_SOURCES = \ uml/uml_conf.c uml/uml_conf.h \ uml/uml_driver.c uml/uml_driver.h @@ -466,6 +479,28 @@ libvirt_driver_vbox_la_SOURCES = $(VBOX_DRIVER_SOURCES) endif +if WITH_XENAPI +if WITH_DRIVER_MODULES +mod_LTLIBRARIES += libvirt_driver_xenapi.la +else +noinst_LTLIBRARIES += libvirt_driver_xenapi.la + +libvirt_la_LIBADD += libvirt_driver_xenapi.la \ + $(XENAPI_LIBS) +endif +#libvirt_driver_xenapi_la_LIBADD = $(XENAPI_LIBS) +libvirt_driver_xenapi_la_CFLAGS = $(XEN_CFLAGS) \ + $(shell xml2-config --cflags) \ + $(shell curl-config --cflags) +libvirt_driver_xenapi_la_LDFLAGS = -...@top_srcdir@/../libxenserver/ -lxenserver -g $(shell xml2-config --libs) \ + $(shell curl-config --libs) + +if WITH_DRIVER_MODULES +libvirt_driver_xenapi_la_LDFLAGS += -module -avoid-version +endif +libvirt_driver_xenapi_la_SOURCES = $(XENAPI_DRIVER_SOURCES) +endif + if WITH_QEMU if
[libvirt] [PATCH 2/4] Addition of XenAPI support to libvirt
diff -ur ./libvirt_org/src/libvirt.c ./libvirt/src/libvirt.c --- ./libvirt_org/src/libvirt.c 2010-02-17 17:38:08.0 + +++ ./libvirt/src/libvirt.c 2010-02-18 12:21:43.0 + @@ -64,6 +64,9 @@ #ifdef WITH_ESX #include esx/esx_driver.h #endif +#ifdef WITH_XENAPI +#include xenapi/xenapi_driver.h +#endif #endif #define VIR_FROM_THIS VIR_FROM_NONE @@ -357,6 +360,7 @@ virDriverLoadModule(openvz); virDriverLoadModule(vbox); virDriverLoadModule(esx); +virDriverLoadModule(xenapi); virDriverLoadModule(remote); #else #ifdef WITH_TEST @@ -377,6 +381,9 @@ #ifdef WITH_ESX if (esxRegister() == -1) return -1; #endif +#ifdef WITH_XENAPI +if (xenapiRegister () == -1) return -1; +#endif #ifdef WITH_REMOTE if (remoteRegister () == -1) return -1; #endif @@ -1035,6 +1042,10 @@ if (STRCASEEQ(type, Remote)) *typeVer = remoteVersion(); #endif +#if WITH_XENAPI +if (STRCASEEQ(type, XenAPI)) +*typeVer = LIBVIR_VERSION_NUMBER; +#endif if (*typeVer == 0) { virLibConnError(NULL, VIR_ERR_NO_SUPPORT, type); goto error; diff -ur ./libvirt_org/src/driver.h ./libvirt/src/driver.h --- ./libvirt_org/src/driver.h 2010-02-17 17:38:08.0 + +++ ./libvirt/src/driver.h 2010-02-18 10:45:54.0 + @@ -27,6 +27,7 @@ VIR_DRV_ONE = 9, VIR_DRV_ESX = 10, VIR_DRV_PHYP = 11, +VIR_DRV_XENAPI = 12 } virDrvNo; diff -ur ./libvirt_org/include/libvirt/virterror.h ./libvirt/include/libvirt/virterror.h --- ./libvirt_org/include/libvirt/virterror.h 2010-02-17 17:37:51.0 + +++ ./libvirt/include/libvirt/virterror.h 2010-02-18 12:17:54.0 + @@ -69,6 +69,7 @@ VIR_FROM_PHYP, /* Error from IBM power hypervisor */ VIR_FROM_SECRET,/* Error from secret storage */ VIR_FROM_CPU, /* Error from CPU driver */ +VIR_FROM_XENAPI /* Error from XenAPI */ } virErrorDomain; diff -ur ./libvirt_org/src/util/virterror.c ./libvirt/src/util/virterror.c --- ./libvirt_org/src/util/virterror.c 2010-02-17 17:38:14.0 + +++ ./libvirt/src/util/virterror.c 2010-02-18 12:13:08.0 + @@ -85,6 +85,9 @@ case VIR_FROM_XEN: dom = Xen ; break; +case VIR_FROM_XENAPI: +dom = XenAPI ; +break; case VIR_FROM_XML: dom = XML ; break; Only in ./libvirt/src: xenapi -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/2] rework virFileCreate into virFileOperation w/hook function
(This patchset requires that the virFork() patchset I send a couple hours ago be applied first, otherwise it will fail to apply). virFileCreate just didn't have what it takes to get the job done. It turns out that there are other things that must be done to files as the qemu (or whatever) user, so this patchset adds a hook function that gets called during the child process. That solves a problem I found with creating raw storage volumes on root-squash NFS, and will also be used for an upcoming domain-save-on-root-squash-nfs patch. I'm now beginning to think that virFileCreate/virFileOperation is just too narrow in scope, and it's getting too many options. Possibly it will be better to just make a simpler virCallasUID() function that gets a pointer to a function to execute in the child process as an argument and does nothing but fork/setuid/call the function. That function would then contain *all* of the file operations, including creating/opening/closing the file. But that's too large of a change to contemplate so soon before a release, and this functionality is necessary for two important bug fixes (mentioned above), so... -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/2] Use virFileOperation hook function in virStorageBackendFileSystemVolBuild.
There were a few operations on the storage volume file that were still being done as root, which will fail if the file is on a root-squashed NFS share. The result was that attempts to create a storage volume of type raw on a root-squashed NFS share would fail. This patch uses the newly introduced hook function in virFileOperation to execute all those file operations in the child process that's run under the uid that owns the file (and, presumably, has permission to write to the NFS share). --- src/storage/storage_backend.c | 113 +++- 1 files changed, 54 insertions(+), 59 deletions(-) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 07c116a..8b9ed5d 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -270,61 +270,33 @@ cleanup: return ret; } -int -virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, - virStorageVolDefPtr vol, - virStorageVolDefPtr inputvol, - unsigned int flags ATTRIBUTE_UNUSED) -{ -int fd = -1; -int ret = -1; -int createstat; -unsigned long long remain; -char *buf = NULL; - -if (vol-target.encryption != NULL) { -virStorageReportError(VIR_ERR_NO_SUPPORT, - %s, _(storage pool does not support encrypted - volumes)); -return -1; -} - -if ((createstat = virFileOperation(vol-target.path, O_RDWR | O_CREAT | O_EXCL, - vol-target.perms.mode, - vol-target.perms.uid, vol-target.perms.gid, - NULL, NULL, - VIR_FILE_OP_FORCE_PERMS | - (pool-def-type == VIR_STORAGE_POOL_NETFS -? VIR_FILE_OP_AS_UID : 0))) 0) { -virReportSystemError(createstat, - _(cannot create path '%s'), - vol-target.path); -goto cleanup; -} +struct createRawFileOpHookData { +virStorageVolDefPtr vol; +virStorageVolDefPtr inputvol; +}; -if ((fd = open(vol-target.path, O_RDWR | O_EXCL | O_DSYNC)) 0) { -virReportSystemError(errno, - _(cannot open new path '%s'), - vol-target.path); -goto cleanup; -} +static int createRawFileOpHook(int fd, void *data) { +struct createRawFileOpHookData *hdata = data; +int ret = 0; +unsigned long long remain; /* Seek to the final size, so the capacity is available upfront * for progress reporting */ -if (ftruncate(fd, vol-capacity) 0) { +if (ftruncate(fd, hdata-vol-capacity) 0) { +ret = errno; virReportSystemError(errno, _(cannot extend file '%s'), - vol-target.path); + hdata-vol-target.path); goto cleanup; } -remain = vol-allocation; +remain = hdata-vol-allocation; -if (inputvol) { -int res = virStorageBackendCopyToFD(vol, inputvol, +if (hdata-inputvol) { +int res = virStorageBackendCopyToFD(hdata-vol, hdata-inputvol, fd, remain, 1); if (res 0) +ret = -res; goto cleanup; } @@ -341,11 +313,11 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, if (bytes remain) bytes = remain; -if ((r = safezero(fd, 0, vol-allocation - remain, +if ((r = safezero(fd, 0, hdata-vol-allocation - remain, bytes)) != 0) { -virReportSystemError(r, - _(cannot fill file '%s'), - vol-target.path); +ret = errno; +virReportSystemError(r, _(cannot fill file '%s'), + hdata-vol-target.path); goto cleanup; } remain -= bytes; @@ -354,28 +326,51 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, int r; if ((r = safezero(fd, 0, 0, remain)) != 0) { -virReportSystemError(r, - _(cannot fill file '%s'), - vol-target.path); +ret = errno; +virReportSystemError(r, _(cannot fill file '%s'), + hdata-vol-target.path); goto cleanup; } } } -if (close(fd) 0) { -virReportSystemError(errno, -
[libvirt] [PATCH 1/2] Rename virFileCreate to virFileOperation, and add hook function.
It turns out it is also useful to be able to perform other operations on a file created while running as a different uid (eg, write things to that file), and possibly to do this to a file that already exists. This patch adds an optional hook function to the renamed (for more accuracy of purpose) virFileOperation; the hook will be called after the file has been opened (possibly created) and gid/mode checked/set, before closing it. As with the other operations on the file, if the VIR_FILE_OP_AS_UID flag is set, this hook function will be called in the context of a child process forked from the process that called virFileOperation. The implication here is that, while all data in memory is available to this hook function, any modification to that data will not be seen by the caller - the only indication in memory of what happened in the hook will be the return value (which the hook should set to 0 on success, or one of the standard errno values on failure). Another piece of making the function more flexible was to add an openflags argument. This arg should contain exactly the flags to be passed to open(2), eg O_RDWR | O_EXCL, etc. In the process of adding the hook to virFileOperation, I also realized that the bits to fix up file owner/group/mode settings after creation were being done in the parent process, which could fail, so I moved them to the child process where they should be. util/util.c|h: rename and rework virFileCreate--virFileOperation, and redo flags in virDirCreate. storage/storage_backend.c, storage/storage_backend_fs.c: update the calls to virFileOperation/virDirCreate to reflect changes in the API, but don't yet take advantage of the hook. --- src/storage/storage_backend.c| 11 ++- src/storage/storage_backend_fs.c |7 +- src/util/util.c | 156 -- src/util/util.h | 19 - 4 files changed, 106 insertions(+), 87 deletions(-) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index a12ddc7..07c116a 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -290,10 +290,13 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, return -1; } -if ((createstat = virFileCreate(vol-target.path, vol-target.perms.mode, -vol-target.perms.uid, vol-target.perms.gid, -(pool-def-type == VIR_STORAGE_POOL_NETFS - ? VIR_FILE_CREATE_AS_UID : 0))) 0) { +if ((createstat = virFileOperation(vol-target.path, O_RDWR | O_CREAT | O_EXCL, + vol-target.perms.mode, + vol-target.perms.uid, vol-target.perms.gid, + NULL, NULL, + VIR_FILE_OP_FORCE_PERMS | + (pool-def-type == VIR_STORAGE_POOL_NETFS +? VIR_FILE_OP_AS_UID : 0))) 0) { virReportSystemError(createstat, _(cannot create path '%s'), vol-target.path); diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index bbd5787..8279d78 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -533,9 +533,9 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, pool-def-target.perms.mode, pool-def-target.perms.uid, pool-def-target.perms.gid, -VIR_FILE_CREATE_ALLOW_EXIST | +VIR_DIR_CREATE_FORCE_PERMS | VIR_DIR_CREATE_ALLOW_EXIST | (pool-def-type == VIR_STORAGE_POOL_NETFS - ? VIR_FILE_CREATE_AS_UID : 0)) != 0)) { + ? VIR_DIR_CREATE_AS_UID : 0)) != 0)) { virReportSystemError(err, _(cannot create path '%s'), pool-def-target.path); goto error; @@ -779,8 +779,9 @@ static int createFileDir(virConnectPtr conn ATTRIBUTE_UNUSED, if ((err = virDirCreate(vol-target.path, vol-target.perms.mode, vol-target.perms.uid, vol-target.perms.gid, +VIR_DIR_CREATE_FORCE_PERMS | (pool-def-type == VIR_STORAGE_POOL_NETFS - ? VIR_FILE_CREATE_AS_UID : 0))) != 0) { + ? VIR_DIR_CREATE_AS_UID : 0))) != 0) { virReportSystemError(err, _(cannot create path '%s'), vol-target.path); return -1; diff --git a/src/util/util.c b/src/util/util.c index c3b4084..d3bbfe1 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1212,15 +1212,15 @@ int
[libvirt] [PATCH] qparams.c: do not skip va_end, twice
More coverity-prompted fixes: From 56d339d99b09c5943fa36600ca39939080cc64f4 Mon Sep 17 00:00:00 2001 From: Jim Meyering meyer...@redhat.com Date: Thu, 18 Feb 2010 20:27:22 +0100 Subject: [PATCH] qparams.c: do not skip va_end, twice * src/util/qparams.c (new_qparam_set, append_qparams): Do not skip va_end due to an early return. --- src/util/qparams.c | 14 +- 1 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/util/qparams.c b/src/util/qparams.c index 9535ca4..f6d0713 100644 --- a/src/util/qparams.c +++ b/src/util/qparams.c @@ -1,6 +1,6 @@ -/* Copyright (C) 2007, 2009 Red Hat, Inc. +/* Copyright (C) 2007, 2009-2010 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. @@ -60,11 +60,12 @@ new_qparam_set (int init_alloc, ...) while ((pname = va_arg (args, char *)) != NULL) { pvalue = va_arg (args, char *); if (append_qparam (ps, pname, pvalue) == -1) { free_qparam_set (ps); -return NULL; +ps = NULL; +break; } } va_end (args); return ps; @@ -73,21 +74,24 @@ new_qparam_set (int init_alloc, ...) int append_qparams (struct qparam_set *ps, ...) { va_list args; const char *pname, *pvalue; +int ret = 0; va_start (args, ps); while ((pname = va_arg (args, char *)) != NULL) { pvalue = va_arg (args, char *); -if (append_qparam (ps, pname, pvalue) == -1) -return -1; +if (append_qparam (ps, pname, pvalue) == -1) { +ret = -1; +break; +} } va_end (args); -return 0; +return ret; } /* Ensure there is space to store at least one more parameter * at the end of the set. */ -- 1.7.0.233.g05e1a -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Is there a way to set viridian=1
How can I set viridian=1 using libvirt? Is it possible? I haven't seen any reference about it on the xml format documentation Best Regards, Diego Dias -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] virBufferStrcat: do not skip va_end
Another missed va_end: From b2e727f9dd25f427d634ef4d79733b37af2b29dd Mon Sep 17 00:00:00 2001 From: Jim Meyering meyer...@redhat.com Date: Thu, 18 Feb 2010 20:46:24 +0100 Subject: [PATCH] virBufferStrcat: do not skip va_end * src/util/buf.c (virBufferStrcat): Do not skip va_end due to an early return. --- src/util/buf.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/buf.c b/src/util/buf.c index e683928..cc0a087 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -1,21 +1,21 @@ /* * buf.c: buffers for libvirt * - * Copyright (C) 2005-2008 Red Hat, Inc. + * Copyright (C) 2005-2008, 2010 Red Hat, Inc. * * See COPYING.LIB for the License of this software * * Daniel Veillard veill...@redhat.com */ #include config.h #include stdio.h #include stdlib.h #include string.h #include stdarg.h #include c-ctype.h #define __VIR_BUFFER_C__ #include buf.h @@ -410,25 +410,25 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str) void virBufferStrcat(virBufferPtr buf, ...) { va_list ap; char *str; if (buf-error) return; va_start(ap, buf); while ((str = va_arg(ap, char *)) != NULL) { unsigned int len = strlen(str); unsigned int needSize = buf-use + len + 2; if (needSize buf-size) { if (virBufferGrow(buf, needSize - buf-use) 0) -return; +break; } memcpy(buf-content[buf-use], str, len); buf-use += len; buf-content[buf-use] = 0; } va_end(ap); } -- 1.7.0.233.g05e1a -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] virBufferVSprintf: do not skip va_end
This fixes the last of the varargs problems reported by coverity: va_end(argptr) was never called, and va_end(locarg) would have been skipped upon OOM. From 7a75b9da0d08a54e9f256dd26cca061b59c32c6d Mon Sep 17 00:00:00 2001 From: Jim Meyering meyer...@redhat.com Date: Thu, 18 Feb 2010 21:25:01 +0100 Subject: [PATCH] virBufferVSprintf: do not skip va_end * src/util/buf.c (virBufferVSprintf): Do not omit or skip va_end calls. --- src/util/buf.c |7 +-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/util/buf.c b/src/util/buf.c index cc0a087..caf8ee0 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -246,14 +246,17 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...) grow_size = (count 1000) ? count : 1000; if (virBufferGrow(buf, grow_size) 0) -return; +goto cleanup; size = buf-size - buf-use - 1; va_copy(locarg, argptr); } -va_end(locarg); buf-use += count; buf-content[buf-use] = '\0'; + + cleanup: +va_end(argptr); +va_end(locarg); } /** -- 1.7.0.233.g05e1a -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2] qemu: Check for IA64 kvm
On Thu, Feb 18, 2010 at 10:56:48AM -0500, Cole Robinson wrote: From: Dustin Xiong x_k_...@hotmail.com ACPI feature bit dropped: I asked internally if the -no-acpi option had any meaning for IA64, and was told 'probably not'. Signed-off-by: Cole Robinson crobi...@redhat.com --- src/qemu/qemu_conf.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 79bd1e8..f02db9c 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -394,6 +394,7 @@ static const struct qemu_arch_info const arch_info_hvm[] = { { mipsel, 32, NULL, qemu-system-mipsel, NULL, NULL, 0 }, { sparc, 32, NULL, qemu-system-sparc, NULL, NULL, 0 }, { ppc,32, NULL, qemu-system-ppc,NULL, NULL, 0 }, +{ itanium, 64, NULL, qemu-system-ia64, NULL, NULL, 0 }, }; ACK, Daniel -- 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
[libvirt] Why libvirt does not support -redir (hostfwd) ?
Hello, I would like to use -redir argument for qemu-kvm guest, but I can't find any mention in docs about this option. Is there any way how to arrange port redirection with libvirt? I can't use a bridge for networking, because I can't use an IP address from host's range. Thank you, Jaromír Červenka Official openSUSE community member Web: http://www.cervajz.com/ Jabber: cerv...@cervajz.com MSN: jara.cerve...@seznam.cz Tel.: +420 607 592 687 Alt. e-mails: jaromir.cerve...@opensuse.org, jaromir.cerve...@speel.cz -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2] remote: Print ssh stderr on connection failure
On Thu, Feb 18, 2010 at 10:56:47AM -0500, Cole Robinson wrote: Signed-off-by: Cole Robinson crobi...@redhat.com --- src/remote/remote_driver.c | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 13534ce..8914c39 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -154,6 +154,7 @@ struct private_data { virMutex lock; int sock; /* Socket. */ +int errfd;/* File handle connected to remote stderr */ int watch; /* File handle watch */ pid_t pid; /* PID of tunnel process */ int uses_tls; /* TLS enabled on socket? */ @@ -783,6 +784,7 @@ doRemoteOpen (virConnectPtr conn, case trans_ext: { pid_t pid; int sv[2]; +int errfd[2]; /* Fork off the external process. Use socketpair to create a private * (unnamed) Unix domain socket to the child process so we don't have @@ -794,14 +796,22 @@ doRemoteOpen (virConnectPtr conn, goto failed; } +if (pipe(errfd) == -1) { +virReportSystemError(errno, %s, + _(unable to create socket pair)); +goto failed; +} + if (virExec((const char**)cmd_argv, NULL, NULL, -pid, sv[1], (sv[1]), NULL, +pid, sv[1], (sv[1]), (errfd[1]), VIR_EXEC_CLEAR_CAPS) 0) goto failed; /* Parent continues here. */ close (sv[1]); +close (errfd[1]); priv-sock = sv[0]; +priv-errfd = errfd[0]; priv-pid = pid; /* Do not set 'is_secure' flag since we can't guarentee @@ -827,6 +837,12 @@ doRemoteOpen (virConnectPtr conn, goto failed; } +if ((priv-errfd != -1) virSetNonBlock(priv-errfd) 0) { +virReportSystemError(errno, %s, + _(unable to make socket non-blocking)); +goto failed; +} + if (pipe(wakeupFD) 0) { virReportSystemError(errno, %s, _(unable to make pipe)); @@ -939,6 +955,9 @@ doRemoteOpen (virConnectPtr conn, failed: /* Close the socket if we failed. */ +if (priv-errfd = 0) +close(priv-errfd); + if (priv-sock = 0) { if (priv-uses_tls priv-session) { gnutls_bye (priv-session, GNUTLS_SHUT_RDWR); @@ -986,6 +1005,7 @@ remoteAllocPrivateData(virConnectPtr conn) priv-localUses = 1; priv-watch = -1; priv-sock = -1; +priv-errfd = -1; return priv; } @@ -1408,6 +1428,7 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv) sasl_dispose (priv-saslconn); #endif close (priv-sock); +close (priv-errfd); #ifndef WIN32 if (priv-pid 0) { @@ -7785,12 +7806,23 @@ remoteIOReadBuffer(virConnectPtr conn, if (errno == EWOULDBLOCK) return 0; +char errout[1024] = \0; +if (priv-errfd != -1) { +saferead(priv-errfd, errout, sizeof(errout)); +} + virReportSystemError(errno, - %s, _(cannot recv data)); + _(cannot recv data: %s), errout); + } else { +char errout[1024] = \0; +if (priv-errfd != -1) { +saferead(priv-errfd, errout, sizeof(errout)); +} + errorf (in_open ? NULL : conn, VIR_ERR_SYSTEM_ERROR, -%s, _(server closed connection)); +_(server closed connection: %s), errout); } return -1; } It would be nice if we could have a function to read and allocate from an fd instead of a static stack allocation, but it's not urgent, ACK, Daniel -- 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
Re: [libvirt] [PATCH 0/2] Make a wrapper for fork() - Take 2
On Thu, Feb 18, 2010 at 11:22:26AM -0500, Laine Stump wrote: This is an update to / deprecates the patchset I sent last night: https://www.redhat.com/archives/libvir-list/2010-February/msg00580.html I have corrected the problem found by Dan Berrange (neglecting to restore the signal mask when fork() fails). Aside from that, and corresponding comments in the commit logs, it is unchanged. Here's the original intro email: This was partly prompted by DV's suggestion last week. The first of these patches creates a new function called virFork() which behaves (almost) like fork() but takes care of some important details that pretty much any call to fork() should be doing. The 2nd switches three fork-calling functions in util.c over to using virFork() instead of fork(). In the future, except for odd circumstances, code that needs to fork should call virFork() instead, and if there is anything determined to be universally necessary at fork-time, it should be added to virFork() rather than to the callers of virFork(); hopefully this will ease maintenance and reduce replicated bugs. (Note that, while this is just an overall code health patch, a couple bug fix patches I'll be submitting either tomorrow or Thursday will assume it as a prerequisite). Okay, thanks, the new function looks fine, and the second patch is the logical next step. ACK, applied both ! Daniel -- 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
Re: [libvirt] FW: [PATCH 1/4] Addition of XenAPI support to libvirt
On Thu, Feb 18, 2010 at 06:14:11PM +, Sharadha Prabhakar (3P) wrote: This is a patch to add XenAPI driver support for libvirt version 0.7.6. XenAPI can be used against XenCloud platform and managed through virsh and virt-manger. This patch supports domain related APIs in libvirt. It is possible to get domain information, list active and inactive domains, get Domain XML configuration and Start/stop/pause/shutdown/destroy VMs. There will be more patches after this review to support more libvirt APIs and add remote storage support to XenAPI. In order to run this patch you would require libxenserver library. thanks for the patch, just started to look at it. I assume that by libxenserver you mean the code to be added under src in a following patch, right ? [...] +endif +#libvirt_driver_xenapi_la_LIBADD = $(XENAPI_LIBS) +libvirt_driver_xenapi_la_CFLAGS = $(XEN_CFLAGS) \ + $(shell xml2-config --cflags) \ + $(shell curl-config --cflags) +libvirt_driver_xenapi_la_LDFLAGS = -...@top_srcdir@/../libxenserver/ -lxenserver -g $(shell xml2-config --libs) \ + $(shell curl-config --libs) Hum, libxml2 is already fully detected in configure.ac, use the LIBXML_* variables instead of trying to exec xml2-config. Similary libcurl i looked at in configure.ac for ESX, this need to be modified to be checked more generally and the LIBCURL_* variables need to be used here too. thanks, Daniel -- 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
[libvirt] [PATCH] macvtap IFF_VNET_HDR configuration
This patch sets or unsets the IFF_VNET_HDR flag depending on what device is used in the VM. The manipulation of the flag is done in the open function and is only fatal if the IFF_VNET_HDR flag could not be cleared although it has to be (or if an ioctl generally fails). In that case the macvtap tap is closed again and the macvtap interface torn. This patch also passes 'make syntax-check' :-). Signed-off-by: Stefan Berger stef...@us.ibm.com Index: libvirt-macvtap/src/qemu/qemu_conf.c === --- libvirt-macvtap.orig/src/qemu/qemu_conf.c +++ libvirt-macvtap/src/qemu/qemu_conf.c @@ -1434,14 +1434,20 @@ int qemudPhysIfaceConnect(virConnectPtr conn, virDomainNetDefPtr net, char *linkdev, - int brmode) + int brmode, + unsigned long long qemuCmdFlags) { int rc; #if WITH_MACVTAP char *res_ifname = NULL; +int vnet_hdr = 0; + +if (qemuCmdFlags QEMUD_CMD_FLAG_VNET_HDR +net-model STREQ(net-model, virtio)) +vnet_hdr = 1; rc = openMacvtapTap(conn, net-ifname, net-mac, linkdev, brmode, -res_ifname); +res_ifname, vnet_hdr); if (rc = 0) { VIR_FREE(net-ifname); net-ifname = res_ifname; @@ -1451,6 +1457,7 @@ qemudPhysIfaceConnect(virConnectPtr conn (void)net; (void)linkdev; (void)brmode; +(void)qemuCmdFlags; qemuReportError(VIR_ERR_INTERNAL_ERROR, %s, _(No support for macvtap device)); rc = -1; @@ -3752,7 +3759,8 @@ int qemudBuildCommandLine(virConnectPtr } else if (net-type == VIR_DOMAIN_NET_TYPE_DIRECT) { int tapfd = qemudPhysIfaceConnect(conn, net, net-data.direct.linkdev, - net-data.direct.mode); + net-data.direct.mode, + qemuCmdFlags); if (tapfd 0) goto error; Index: libvirt-macvtap/src/util/macvtap.c === --- libvirt-macvtap.orig/src/util/macvtap.c +++ libvirt-macvtap/src/util/macvtap.c @@ -615,6 +615,64 @@ macvtapModeFromInt(enum virDomainNetdevM /** + * configMacvtapTap: + * @tapfd: file descriptor of the macvtap tap + * @vnet_hdr: 1 to enable IFF_VNET_HDR, 0 to disable it + * + * Returns 0 on success, -1 in case of fatal error, error code otherwise. + * + * Turn the IFF_VNET_HDR flag, if requested and available, make sure + * it's off in the other cases. + * A fatal error is defined as the VNET_HDR flag being set but it cannot + * be turned off for some reason. This is reported with -1. Other fatal + * error is not being able to read the interface flags. In that case the + * macvtap device should not be used. + */ +static int +configMacvtapTap(int tapfd, int vnet_hdr) +{ +unsigned int features; +struct ifreq ifreq; +short new_flags = 0; +int rc_on_fail = 0; +const char *errmsg = NULL; + +memset(ifreq, 0, sizeof(ifreq)); + +if (ioctl(tapfd, TUNGETIFF, ifreq) 0) { +virReportSystemError(errno, %s, + _(cannot get interface flags on macvtap tap)); +return -1; +} + +new_flags = ifreq.ifr_flags; + +if ((ifreq.ifr_flags IFF_VNET_HDR) !vnet_hdr) { +new_flags = ifreq.ifr_flags ~IFF_VNET_HDR; +rc_on_fail = -1; +errmsg = _(cannot clean IFF_VNET_HDR flag on macvtap tap); +} else if ((ifreq.ifr_flags IFF_VNET_HDR) == 0 vnet_hdr) { +if (ioctl(tapfd, TUNGETFEATURES, features) != 0) +return errno; +if ((features IFF_VNET_HDR)) { +new_flags = ifreq.ifr_flags | IFF_VNET_HDR; +errmsg = _(cannot set IFF_VNET_HDR flag on macvtap tap); +} +} + +if (new_flags != ifreq.ifr_flags) { +ifreq.ifr_flags = new_flags; +if (ioctl(tapfd, TUNSETIFF, ifreq) 0) { +virReportSystemError(errno, %s, errmsg); +return rc_on_fail; +} +} + +return 0; +} + + +/** * openMacvtapTap: * Create an instance of a macvtap device and open its tap character * device. @@ -640,7 +698,8 @@ openMacvtapTap(virConnectPtr conn, const unsigned char *macaddress, const char *linkdev, int mode, - char **res_ifname) + char **res_ifname, + int vnet_hdr) { const char *type = macvtap; int c, rc; @@ -699,9 +758,14 @@ create_name: rc = openTap(cr_ifname, 10); -if (rc = 0) +if (rc = 0) { +if (configMacvtapTap(rc, vnet_hdr) 0) { +close(rc); +rc = -1; +goto link_del_exit; +} *res_ifname =
[libvirt] [PATCH 2/3] Format FS pools
* If the user supplies the appropriate flag, create the filesystem on the partition used by the pool. --- configure.ac |5 + include/libvirt/libvirt.h.in |3 ++- src/storage/storage_backend_fs.c | 25 - 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 743a357..616bd03 100644 --- a/configure.ac +++ b/configure.ac @@ -1252,12 +1252,15 @@ AM_CONDITIONAL([WITH_STORAGE_DIR], [test $with_storage_dir = yes]) if test $with_storage_fs = yes -o $with_storage_fs = check; then AC_PATH_PROG([MOUNT], [mount], [], [$PATH:/sbin:/usr/sbin]) AC_PATH_PROG([UMOUNT], [umount], [], [$PATH:/sbin:/usr/sbin]) + AC_PATH_PROG([MKE2FS], [mke2fs], [], [$PATH:/sbin:/usr/sbin]) if test $with_storage_fs = yes ; then if test -z $MOUNT ; then AC_MSG_ERROR([We need mount for FS storage driver]) ; fi if test -z $UMOUNT ; then AC_MSG_ERROR([We need umount for FS storage driver]) ; fi +if test -z $MKE2FS ; then AC_MSG_ERROR([We need mke2fs for FS storage driver]) ; fi else if test -z $MOUNT ; then with_storage_fs=no ; fi if test -z $UMOUNT ; then with_storage_fs=no ; fi +if test -z $MKE2FS ; then with_storage_fs=no ; fi if test $with_storage_fs = check ; then with_storage_fs=yes ; fi fi @@ -1268,6 +1271,8 @@ if test $with_storage_fs = yes -o $with_storage_fs = check; then [Location or name of the mount program]) AC_DEFINE_UNQUOTED([UMOUNT],[$UMOUNT], [Location or name of the mount program]) +AC_DEFINE_UNQUOTED([MKE2FS],[$MKE2FS], +[Location or name of the mke2fs program]) fi fi AM_CONDITIONAL([WITH_STORAGE_FS], [test $with_storage_fs = yes]) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 260505e..a7751b8 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1053,7 +1053,8 @@ typedef enum { typedef enum { VIR_STORAGE_POOL_BUILD_NEW = 0, /* Regular build from scratch */ VIR_STORAGE_POOL_BUILD_REPAIR = 1, /* Repair / reinitialize */ - VIR_STORAGE_POOL_BUILD_RESIZE = 2 /* Extend existing pool */ + VIR_STORAGE_POOL_BUILD_RESIZE = 2, /* Extend existing pool */ + VIR_STORAGE_POOL_CREATE_FORMAT = 3 /* Format filesystem during build */ } virStoragePoolBuildFlags; typedef enum { diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index bbd5787..eedbe2b 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -39,12 +39,14 @@ #include libxml/xpath.h #include virterror_internal.h +#include internal.h #include storage_backend_fs.h #include storage_conf.h #include storage_file.h #include util.h #include memory.h #include xml.h +#include logging.h #define VIR_FROM_THIS VIR_FROM_STORAGE @@ -498,8 +500,9 @@ virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED, static int virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags) { +const char *mke2fsargv[5], *device = NULL, *format = NULL; int err, ret = -1; char *parent; char *p; @@ -540,6 +543,26 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, pool-def-target.path); goto error; } + +if (flags VIR_STORAGE_POOL_CREATE_FORMAT) { +device = pool-def-source.devices[0].path; +format = virStoragePoolFormatFileSystemTypeToString(pool-def-source.format); + +VIR_DEBUG(source device: '%s' format: '%s', device, format); + +mke2fsargv[0] = MKE2FS; +mke2fsargv[1] = -t; +mke2fsargv[2] = format; +mke2fsargv[3] = device; +mke2fsargv[4] = NULL; + +if (virRun(mke2fsargv, NULL) 0) { +VIR_ERROR(Failed to make '%s' filesystem on device '%s', + format, device); +goto error; +} +} + ret = 0; error: VIR_FREE(parent); -- 1.6.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/3] Fixed reference count in pool-build
--- tools/virsh.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index e1d1300..bd6b6be 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -4036,9 +4036,10 @@ cmdPoolBuild(vshControl *ctl, const vshCmd *cmd) } else { vshError(ctl, _(Failed to build pool %s), name); ret = FALSE; -virStoragePoolFree(pool); } +virStoragePoolFree(pool); + return ret; } -- 1.6.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/3] Add virsh option for format flags
--- tools/virsh.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index bd6b6be..de8c67d 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -4015,6 +4015,7 @@ static const vshCmdInfo info_pool_build[] = { static const vshCmdOptDef opts_pool_build[] = { {pool, VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop(pool name or uuid)}, +{format, VSH_OT_BOOL, 0, gettext_noop(format the pool (destructive))}, {NULL, 0, 0, NULL} }; @@ -4023,6 +4024,7 @@ cmdPoolBuild(vshControl *ctl, const vshCmd *cmd) { virStoragePoolPtr pool; int ret = TRUE; +int flags = 0; char *name; if (!vshConnectionUsability(ctl, ctl-conn, TRUE)) @@ -4031,7 +4033,10 @@ cmdPoolBuild(vshControl *ctl, const vshCmd *cmd) if (!(pool = vshCommandOptPool(ctl, cmd, pool, name))) return FALSE; -if (virStoragePoolBuild(pool, 0) == 0) { +if (vshCommandOptBool (cmd, format)) +flags |= VIR_STORAGE_POOL_CREATE_FORMAT; + +if (virStoragePoolBuild(pool, flags) == 0) { vshPrint(ctl, _(Pool %s built\n), name); } else { vshError(ctl, _(Failed to build pool %s), name); -- 1.6.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] PATCH [0/3] Filesystem pool formatting
I finished these patches this afternoon, and I need to do a bit more testing before I'm comfortable having these patches committed, but I'm sending them along so I can get everybody's feedback overnight. In particular, I'm wondering if my move of the pool unref call is correct. Dave -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/1] - for comments/help only, nearly working root-squash-domain-save
(This patch requires that you first apply the virFileOperation patches that I sent to the list yesterday.) I'm hoping someone else's keen eye can see what I'm failing to see here. The patch following this message makes domain save work on root-squash NFS (both the libvirt header and the QEMU state are saved to the file), but the files that it saves don't restore properly, even when simply saving to a local directory w/o forking - the guest screen comes up black, or reboots immediately, or some other such thing. I've looked at the data files and the code, and can't see what difference is causing this - at least the header written by libvirt seems to be the same, and the part written by qemu starts in the same place and looks similar. If anyone's got an idea, please let me know! I'd like to get this figured out and a working patch submitted before the day is done. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Make domain save work on root-squash NFS
Move *all* file operations related to creation and writing of libvirt header to the domain save file into a hook function that is called by virFileOperation. First try to call virFileOperation as root. If that fails with EACCESS, and (in the case of Linux) statfs says that we're trying to save the file on an NFS share, rerun virFileOperation, telling it to fork a child process and setuid to the qemu user. This is the only way we can successfully create a file on a root-squashed NFS server. This patch (along with setting dynamic_ownership=0 in qemu.conf) makes qemudDomainSave work on root-squashed NFS. --- src/qemu/qemu_driver.c | 151 +++ 1 files changed, 125 insertions(+), 26 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0fb2413..4d3784c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -47,6 +47,11 @@ #include sys/ioctl.h #include sys/un.h +#ifdef __linux__ +#include sys/vfs.h +#include linux/magic.h +#endif + #include virterror_internal.h #include logging.h #include datatypes.h @@ -3956,14 +3961,44 @@ struct qemud_save_header { int unused[15]; }; +struct fileOpHookData { +virDomainPtr dom; +const char *path; +char *xml; +struct qemud_save_header *header; +}; + +static int qemudDomainSaveFileOpHook(int fd, void *data) { +struct fileOpHookData *hdata = data; +int ret = 0; + +if (safewrite(fd, hdata-header, sizeof(*hdata-header)) != sizeof(*hdata-header)) { +ret = errno; +qemuReportError(VIR_ERR_OPERATION_FAILED, + _(failed to write save header to '%s'), hdata-path); +goto endjob; +} + +if (safewrite(fd, hdata-xml, hdata-header-xml_len) != hdata-header-xml_len) { +ret = errno; +qemuReportError(VIR_ERR_OPERATION_FAILED, + _(failed to write xml to '%s'), hdata-path); +goto endjob; +} +endjob: +return ret; +} + + static int qemudDomainSave(virDomainPtr dom, const char *path) { struct qemud_driver *driver = dom-conn-privateData; virDomainObjPtr vm = NULL; -int fd = -1; char *xml = NULL; struct qemud_save_header header; +struct fileOpHookData hdata; +int bypassSecurityDriver = 0; int ret = -1; int rc; virDomainEventPtr event = NULL; @@ -4027,34 +4062,99 @@ static int qemudDomainSave(virDomainPtr dom, } header.xml_len = strlen(xml) + 1; +/* Setup hook data needed by virFileOperation hook function */ +hdata.dom = dom; +hdata.path = path; +hdata.xml = xml; +hdata.header = header; + /* Write header to file, followed by XML */ -if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) 0) { -qemuReportError(VIR_ERR_OPERATION_FAILED, -_(failed to create '%s'), path); -goto endjob; -} -if (safewrite(fd, header, sizeof(header)) != sizeof(header)) { -qemuReportError(VIR_ERR_OPERATION_FAILED, -%s, _(failed to write save header)); -goto endjob; -} +/* First try creating the file as root */ +if ((rc = virFileOperation(path, O_CREAT|O_TRUNC|O_WRONLY, + S_IRUSR|S_IWUSR, + getuid(), getgid(), + qemudDomainSaveFileOpHook, hdata, + 0)) != 0) { + +/* If we failed as root, and the error was permission-denied + (EACCES), assume it's on a network-connected share where + root access is restricted (eg, root-squashed NFS). If the + qemu user (driver-user) is non-root, just set a flag to + bypass security driver shenanigans, and retry the operation + after doing setuid to qemu user */ + +if ((rc != EACCES) || +driver-user == getuid()) { +virReportSystemError(rc, _(Failed to create domain save file '%s'), + path); +goto endjob; +} -if (safewrite(fd, xml, header.xml_len) != header.xml_len) { -qemuReportError(VIR_ERR_OPERATION_FAILED, - %s, _(failed to write xml)); -goto endjob; -} +#ifdef __linux__ +/* On Linux we can also verify the FS-type of the directory. */ +struct statfs st; +char *dirpath, *p; -if (close(fd) 0) { -virReportSystemError(errno, - _(unable to save file %s), - path); -goto endjob; +if ((dirpath = strdup(path)) == NULL) { +virReportOOMError(); +goto endjob; +} + +if ((p = strrchr(dirpath, '/')) == NULL) { +qemuReportError(VIR_ERR_INVALID_ARG, +_(Invalid path '%s' for domain save file), +path); +