Re: [libvirt] [PATCH] qemu: never send SIGKILL to qemu process unless specifically requested
On 30.01.2012 21:30, Laine Stump wrote: On 01/30/2012 06:02 AM, Daniel P. Berrange wrote: On Fri, Jan 27, 2012 at 01:35:35PM -0500, Laine Stump wrote: When libvirt is shutting down the qemu process, it first sends SIGTERM, then waits for 1.6 seconds and, if it sees the process still there, sends a SIGKILL. There have been reports that this behavior can lead to data loss because the guest running in qemu doesn't have time to flush it's disk cache buffers before it's unceremoniously whacked. One suggestion on how to solve that problem was to remove SIGKILL from the normal virDomainDestroyFlags, but still provide the ability to kill qemu with SIGKILL by using a new flag to virDomainDestroyFlags. This patch is a quick attempt at that in order to start a conversation on the topic. So what are your opinions? Is this the right way to solve the problem? No, we can't change the default semantics of virDomainDestroy in this case. Applications expect that we do absolutely everything possible to kill of the guest. This is particularly important for cluster fencing usage. If we only use SIGTERM, then we're introducing unacceptable risk to apps relying on this. We could do the opposite though - have a flag to do a gracefully destroy, leaving the default as un-graceful. virDomainShutdown ends up calling qemuProcessKill() too. So, I guess we need to add a flag there too. In the meantime, shouldn't we at least wait longer before resorting to SIGKILL? (especially since it appears the current timeout is quite often too short). (If we don't at least do that, what we're saying is the behavior of virDomainShutdown / virDomainDestroy is to lose your data unless you're lucky. If you don't want this behavior, you need to use virDomainXXXFlags, and specify the VIR_DOMAIN_DONT_TRASH_MY_DATA flag :-P). I should probably hop into this as I've tried to solve this issue earlier but got sidetracked and then forgot about it. Increasing the delay could be temporary workaround, but we should keep in mind that if we change the delay to X (units of time), I bet in some cases it will take qemu X+1 units to flush caches. Therefore I lean to the flag DONT_SENT_SIGKILL and leave the default to what it is now. However, as a qemu developer pointed out (Luiz?), even with -no-shutdown qemu will terminate itself after receiving SIGINT and flushing own caches. So this might be the right way to solve this. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] resize: slightly alter signature
On 30.01.2012 20:04, Eric Blake wrote: Our existing virDomainBlockResize takes an unsigned long long argument; if that command is later taught a DELTA and SHRINK flag, we cannot change its type without breaking API (but at least such a change would be ABI compatible). Meanwhile, the only time a negative size makes sense is if both DELTA and SHRINK are used together, but if we keep the argument unsigned, applications can pass the positive delta amount by which they would like to shrink the system, and have the flags imply the negative value. So, since this API has not yet been released, and in the interest of consistency with existing API, we swap virStorageVolResize to always pass an unsigned value. * include/libvirt/libvirt.h.in (virStorageVolResize): Use unsigned argument. * src/libvirt.c (virStorageVolResize): Likewise. * src/driver.h (virDrvStorageVolUpload): Adjust clients. * src/remote/remote_protocol.x (remote_storage_vol_resize_args): Likewise. * src/remote_protocol-structs: Regenerate. Suggested by Daniel P. Berrange. --- include/libvirt/libvirt.h.in |2 +- src/driver.h |2 +- src/libvirt.c| 17 + src/remote/remote_protocol.x |2 +- src/remote_protocol-structs |2 +- 5 files changed, 13 insertions(+), 12 deletions(-) ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [test-API][PATCH 2/2] Add and update functions in streamAPI
* only accpet stream object as parameter in __init__ * remove newStream() from each function stream object should be pass in as parameter, not create new at each function. function also need flags parameter. * Add 5 new functions screenshot(self, domain, screen, flags = 0) download(self, vol, offset, length, flags = 0) upload(self, vol, offset, length, flags = 0) recvAll(self, handler, opaque) sendAll(self, handler, opaque) for recvAll and sendAll, handler is a user defined function which write/read data to/from file. --- lib/streamAPI.py | 84 + 1 files changed, 58 insertions(+), 26 deletions(-) diff --git a/lib/streamAPI.py b/lib/streamAPI.py index bc7d217..a1b2d0d 100644 --- a/lib/streamAPI.py +++ b/lib/streamAPI.py @@ -38,76 +38,108 @@ append_path(result.group(0)) import exception class StreamAPI(object): -def __init__(self, connection): -self.conn = connection +def __init__(self, stream): +self.stream_obj = stream -def abort(self, flag = 0): +def abort(self): try: -stream_obj = newStream(flag) -return stream_obj.abort() +return self.stream_obj.abort() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def connect(self, flag = 0): +def connect(self): try: -stream_obj = newStream(flag) -return stream_obj.connect() +return self.stream_obj.connect() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def finish(self, flag = 0): +def finish(self): try: -stream_obj = newStream(flag) -return stream_obj.finish() +return self.stream_obj.finish() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def recv(self, flag = 0, data, nbytes): +def recv(self, nbytes): try: -stream_obj = newStream(flag) -return stream_obj.recv(data, nbytes) +return self.stream_obj.recv(nbytes) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def send(self, flag = 0, data, nbytes): +def send(self, data): try: -stream_obj = newStream(flag) -return stream_obj.send(data, nbytes) +return self.stream_obj.send(data) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventAddCallback(self, flag = 0, cb, opaque): +def eventAddCallback(self, cb, opaque): try: -stream_obj = newStream(flag) -return stream_obj.eventAddCallback(cb, opaque) +return self.stream_obj.eventAddCallback(cb, opaque) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventRemoveCallback(self, flag = 0): +def eventRemoveCallback(self): try: -stream_obj = newStream(flag) -return stream_obj.eventRemoveCallback() +return self.stream_obj.eventRemoveCallback() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventUpdateCallback(self, flag = 0, events) +def eventUpdateCallback(self, events): try: -stream_obj = newStream(flag) -return stream_obj.eventUpdateCallback(events) +return self.stream_obj.eventUpdateCallback(events) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise exception.LibvirtAPI(message, code) + +def screenshot(self, domain, screen, flags = 0): +try: +return self.stream_obj.screenshot(domain, screen, flags) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise exception.LibvirtAPI(message, code) + +def download(self, vol, offset, length, flags = 0): +try: +return self.stream_obj.download(vol, offset, length, flags) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise
[libvirt] [test-API][PATCH 1/2] Add 2 new functions in storageAPI
* download(self, poolname, volname, stream, offset, length, flags = 0) * upload(self, poolname, volname, stream, offset, length, flags = 0) --- lib/storageAPI.py | 17 + 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/lib/storageAPI.py b/lib/storageAPI.py index 6c9d286..b0733f8 100644 --- a/lib/storageAPI.py +++ b/lib/storageAPI.py @@ -466,3 +466,20 @@ class StorageAPI(object): code = e.get_error_code() raise exception.LibvirtAPI(message, code) +def download(self, poolname, volname, stream, offset, length, flags = 0): +try: +volobj = self.get_volume_obj(poolname, volname) +return volobj.download(stream, offset, length, flags) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise exception.LibvirtAPI(message, code) + +def upload(self, poolname, volname, stream, offset, length, flags = 0): +try: +volobj = self.get_volume_obj(poolname, volname) +return volobj.upload(stream, offset, length, flags) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise exception.LibvirtAPI(message, code) -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC: setting mac address on network devices being assigned to a guest via PCI passthrough (hostdev)
On 01/30/2012 08:16 PM, Roopa Prabhu wrote: Laine, I haven't gone through your whole email yet. Was just curious about one quick thing, For sriov VF's, are we expecting that a net device (eth interface) be present on the host if its being used as a hostdev ?. Either should be possible. If the VF is bound to a net dev, it can be specified either with dev='ethxx' or using its pci address, and will be unbound before assigning to the guest. If it's not bound to a net dev, then a pci address must be used to describe it in the config. If yes, then libvirt will need to do an unbind of the driver on the VF before assigning it to the VM. Which today it does not do (correct me if I am wrong). That may have been the case in the past, but with libvirt-0.9.9 (the first version that I've tested with sriov and PCI passthrough - I'm a newbie to both), the net driver is unbound prior to assigning to the guest, and when the the device is detached from the guest, the net driver is once again bound to the device. Which is still ok. Just wanted to call that out. Plus ideally it would be nice to not have an expectation that a vf netdevice be present on the host. Because for sriov vf's, it would mean that the vf driver has to be loaded on the host. Which is really not required for vfs because mac and port profile can be set via the pf with the vf index as argument. Right. For sriov VFs, I intend that the MAC address will always be set via the PF. I hadn't previously thought through the details for non-sriov devices, but your event sequence list below made me realize that, at least for non-sriov, the MAC address and virtual port setup will need to be done *before* unbinding the driver (my intent, for sriov at least, was that this would happen *after* unbinding the driver). I guess that will take some experimentation. Anyway, at the moment I'm slogging around in the data structures. Basically, For non-sriov network devices on host, - find netdevice - set mac on netdevice - If required set port profile on the netdevice - unbind netdevice driver - assign net pci device to guest For sriov vf network devices on host, - find pf netdevice - set mac for vf via the pf netdevice - If required set port profile on the vf via the pf netdevice - unbind vf driver if its loaded on the vf /* not mandatory */ - assign vf pci device to guest Thanks! -Roopa -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: never send SIGKILL to qemu process unless specifically requested
On 01/31/2012 03:30 AM, Michal Privoznik wrote: On 30.01.2012 21:30, Laine Stump wrote: On 01/30/2012 06:02 AM, Daniel P. Berrange wrote: On Fri, Jan 27, 2012 at 01:35:35PM -0500, Laine Stump wrote: When libvirt is shutting down the qemu process, it first sends SIGTERM, then waits for 1.6 seconds and, if it sees the process still there, sends a SIGKILL. There have been reports that this behavior can lead to data loss because the guest running in qemu doesn't have time to flush it's disk cache buffers before it's unceremoniously whacked. One suggestion on how to solve that problem was to remove SIGKILL from the normal virDomainDestroyFlags, but still provide the ability to kill qemu with SIGKILL by using a new flag to virDomainDestroyFlags. This patch is a quick attempt at that in order to start a conversation on the topic. So what are your opinions? Is this the right way to solve the problem? No, we can't change the default semantics of virDomainDestroy in this case. Applications expect that we do absolutely everything possible to kill of the guest. But not that we get it all done within 1.6 seconds, right? :-) This is particularly important for cluster fencing usage. If we only use SIGTERM, then we're introducing unacceptable risk to apps relying on this. We could do the opposite though - have a flag to do a gracefully destroy, leaving the default as un-graceful. virDomainShutdown ends up calling qemuProcessKill() too. So, I guess we need to add a flag there too. In the meantime, shouldn't we at least wait longer before resorting to SIGKILL? (especially since it appears the current timeout is quite often too short). (If we don't at least do that, what we're saying is the behavior of virDomainShutdown / virDomainDestroy is to lose your data unless you're lucky. If you don't want this behavior, you need to use virDomainXXXFlags, and specify the VIR_DOMAIN_DONT_TRASH_MY_DATA flag :-P). I should probably hop into this as I've tried to solve this issue earlier but got sidetracked and then forgot about it. Increasing the delay could be temporary workaround, but we should keep in mind that if we change the delay to X (units of time), I bet in some cases it will take qemu X+1 units to flush caches. Therefore I lean to the flag DONT_SENT_SIGKILL and leave the default to what it is now. Sure, even if you increase the timeout, there will still be cases where it fails. But we can't magically cause every piece of management software to switch to using the DONT_SEND_SIGKILL flag overnight, and in the meantime increasing the timeout will lead to fewer failures, and won't cause a longer delay than currently *unless it was going to cause a failure anyway* (since the loop exits as soon as it detects the process has exited). So, I don't see a downside to increasing the timeout (in addition to adding the flag, *not* instead of it). The current timeout is arbitrary, so why not make it a bit larger arbitrary amount? However, as a qemu developer pointed out (Luiz?), even with -no-shutdown qemu will terminate itself after receiving SIGINT and flushing own caches. So this might be the right way to solve this. Please define this more specifically :-) (maybe in patch form?) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: never send SIGKILL to qemu process unless specifically requested
On Mon, Jan 30, 2012 at 03:30:18PM -0500, Laine Stump wrote: On 01/30/2012 06:02 AM, Daniel P. Berrange wrote: On Fri, Jan 27, 2012 at 01:35:35PM -0500, Laine Stump wrote: When libvirt is shutting down the qemu process, it first sends SIGTERM, then waits for 1.6 seconds and, if it sees the process still there, sends a SIGKILL. There have been reports that this behavior can lead to data loss because the guest running in qemu doesn't have time to flush it's disk cache buffers before it's unceremoniously whacked. One suggestion on how to solve that problem was to remove SIGKILL from the normal virDomainDestroyFlags, but still provide the ability to kill qemu with SIGKILL by using a new flag to virDomainDestroyFlags. This patch is a quick attempt at that in order to start a conversation on the topic. So what are your opinions? Is this the right way to solve the problem? No, we can't change the default semantics of virDomainDestroy in this case. Applications expect that we do absolutely everything possible to kill of the guest. This is particularly important for cluster fencing usage. If we only use SIGTERM, then we're introducing unacceptable risk to apps relying on this. We could do the opposite though - have a flag to do a gracefully destroy, leaving the default as un-graceful. virDomainShutdown ends up calling qemuProcessKill() too. So, I guess we need to add a flag there too. In the meantime, shouldn't we at least wait longer before resorting to SIGKILL? (especially since it appears the current timeout is quite often too short). (If we don't at least do that, what we're saying is the behavior of virDomainShutdown / virDomainDestroy is to lose your data unless you're lucky. If you don't want this behavior, you need to use virDomainXXXFlags, and specify the VIR_DOMAIN_DONT_TRASH_MY_DATA flag :-P). If you add a flag to trigger a graceful kill(SIGINT) only, then we don't need to change the timeout. The application now has the ability to wait as long as they like, before issuing another virDomainDestroy() Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [test-API][PATCH 2/2] Add and update functions in streamAPI
On 01/31/2012 04:46 PM, Wayne Sun wrote: * only accpet stream object as parameter in __init__ * remove newStream() from each function stream object should be pass in as parameter, not create new at each function. function also need flags parameter. * Add 5 new functions screenshot(self, domain, screen, flags = 0) download(self, vol, offset, length, flags = 0) upload(self, vol, offset, length, flags = 0) recvAll(self, handler, opaque) sendAll(self, handler, opaque) for recvAll and sendAll, handler is a user defined function which write/read data to/from file. --- lib/streamAPI.py | 84 + 1 files changed, 58 insertions(+), 26 deletions(-) diff --git a/lib/streamAPI.py b/lib/streamAPI.py index bc7d217..a1b2d0d 100644 --- a/lib/streamAPI.py +++ b/lib/streamAPI.py @@ -38,76 +38,108 @@ append_path(result.group(0)) import exception class StreamAPI(object): -def __init__(self, connection): -self.conn = connection +def __init__(self, stream): +self.stream_obj = stream Need a 'stream' instance to initialize class StreamAPI? how to do this? users must to do 'stream = con.newStream(0)' then StreamAPI(stream), right? maybe, we may do this like this: class StreamAPI(object): def __init__(self, connection, flag = 0): self.conn = connection self.stream_obj = newStream(flag) Alex -def abort(self, flag = 0): +def abort(self): try: -stream_obj = newStream(flag) -return stream_obj.abort() +return self.stream_obj.abort() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def connect(self, flag = 0): +def connect(self): try: -stream_obj = newStream(flag) -return stream_obj.connect() +return self.stream_obj.connect() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def finish(self, flag = 0): +def finish(self): try: -stream_obj = newStream(flag) -return stream_obj.finish() +return self.stream_obj.finish() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def recv(self, flag = 0, data, nbytes): +def recv(self, nbytes): try: -stream_obj = newStream(flag) -return stream_obj.recv(data, nbytes) +return self.stream_obj.recv(nbytes) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def send(self, flag = 0, data, nbytes): +def send(self, data): try: -stream_obj = newStream(flag) -return stream_obj.send(data, nbytes) +return self.stream_obj.send(data) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventAddCallback(self, flag = 0, cb, opaque): +def eventAddCallback(self, cb, opaque): try: -stream_obj = newStream(flag) -return stream_obj.eventAddCallback(cb, opaque) +return self.stream_obj.eventAddCallback(cb, opaque) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventRemoveCallback(self, flag = 0): +def eventRemoveCallback(self): try: -stream_obj = newStream(flag) -return stream_obj.eventRemoveCallback() +return self.stream_obj.eventRemoveCallback() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventUpdateCallback(self, flag = 0, events) +def eventUpdateCallback(self, events): try: -stream_obj = newStream(flag) -return stream_obj.eventUpdateCallback(events) +return self.stream_obj.eventUpdateCallback(events) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise exception.LibvirtAPI(message, code) + +def screenshot(self, domain, screen, flags = 0): +try: +return self.stream_obj.screenshot(domain, screen, flags) +except libvirt.libvirtError, e: +message =
Re: [libvirt] [PATCH V4 3/5] add nodeGetCPUmap.
On Sat, Jan 28, 2012 at 03:24:04PM +0900, KAMEZAWA Hiroyuki wrote: add nodeGetCPUmap() for getting available CPU IDs in a bitmap. add virBitmapParseCommaSeparetedFormat() for parsing bitmap in comma separeted ascii format. This format of bitmap is used in Linux sysfs and cpuset. * cpuacct's percpu usage information is provided based on /sys/devices/system/cpu/present cpu map. So, this kind of call is required. This routine itself may be useful for other purpose. libvirt_private.syms |2 + nodeinfo.c | 51 nodeinfo.h |4 +++ util/bitmap.c| 65 +++ util/bitmap.h|6 +++- 5 files changed, 127 insertions(+), 1 deletion(-) --- src/libvirt_private.syms |2 + src/nodeinfo.c | 51 src/nodeinfo.h |4 +++ src/util/bitmap.c| 65 ++ src/util/bitmap.h|6 +++- 5 files changed, 127 insertions(+), 1 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 915a43f..fd44322 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -17,6 +17,7 @@ virBitmapFree; virBitmapGetBit; virBitmapSetBit; virBitmapString; +virBitmapParseCommaSeparatedFormat; # buf.h @@ -800,6 +801,7 @@ nodeGetCellsFreeMemory; nodeGetFreeMemory; nodeGetInfo; nodeGetMemoryStats; +nodeGetCPUmap; # nwfilter_conf.h diff --git a/src/nodeinfo.c b/src/nodeinfo.c index e0b66f7..92bada7 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -47,6 +47,7 @@ #include count-one-bits.h #include intprops.h #include virfile.h +#include bitmap.h #define VIR_FROM_THIS VIR_FROM_NONE @@ -569,6 +570,33 @@ int linuxNodeGetMemoryStats(FILE *meminfo, cleanup: return ret; } + +/* + * Linux maintains cpu bit map. For example, if cpuid=5's flag is not set + * and max cpu is 7. The map file shows 0-4,6-7. This functin parse + * it and returns bitmap. + */ +static virBitmapPtr linuxParseCPUmap(int *max_cpuid, const char *path) +{ +char str[1024]; +FILE *fp; +virBitmapPtr map = NULL; + +fp = fopen(path, r); +if (!fp) { +virReportSystemError(errno, _(cannot open %s), path); +goto cleanup; +} +if (fgets(str, sizeof(str), fp) == NULL) { +virReportSystemError(errno, _(cannot read from %s), path); +goto cleanup; +} +map = virBitmapParseCommaSeparatedFormat(str, max_cpuid); + +cleanup: +VIR_FORCE_FCLOSE(fp); +return map; +} #endif int nodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr nodeinfo) { @@ -712,6 +740,29 @@ int nodeGetMemoryStats(virConnectPtr conn ATTRIBUTE_UNUSED, #endif } +virBitmapPtr nodeGetCPUmap(virConnectPtr conn ATTRIBUTE_UNUSED, + int *max_id, + const char *mapname) +{ +#ifdef __linux__ +char *path; +virBitmapPtr map; + +if (virAsprintf(path, CPU_SYS_PATH /%s, mapname) 0) { +virReportOOMError(); +return NULL; +} + +map = linuxParseCPUmap(max_id, path); +VIR_FREE(path); +return map; +#else + nodeReportError(VIR_ERR_NO_SUPPORT, %s, + _(node cpumap not implemented on this platform)); + return -1; +#endif +} + #if HAVE_NUMACTL # if LIBNUMA_API_VERSION = 1 # define NUMA_MAX_N_CPUS 4096 diff --git a/src/nodeinfo.h b/src/nodeinfo.h index 4766152..7f26b77 100644 --- a/src/nodeinfo.h +++ b/src/nodeinfo.h @@ -26,6 +26,7 @@ # include libvirt/libvirt.h # include capabilities.h +# include bitmap.h int nodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo); int nodeCapsInitNUMA(virCapsPtr caps); @@ -46,4 +47,7 @@ int nodeGetCellsFreeMemory(virConnectPtr conn, int maxCells); unsigned long long nodeGetFreeMemory(virConnectPtr conn); +virBitmapPtr nodeGetCPUmap(virConnectPtr conn, + int *max_id, + const char *mapname); #endif /* __VIR_NODEINFO_H__*/ diff --git a/src/util/bitmap.c b/src/util/bitmap.c index 8c326c4..c7e1a81 100644 --- a/src/util/bitmap.c +++ b/src/util/bitmap.c @@ -33,6 +33,11 @@ #include bitmap.h #include memory.h #include buf.h +#include c-ctype.h +#include util.h +#include virterror_internal.h + +#define VIR_FROM_THIS VIR_FROM_NONE struct _virBitmap { @@ -180,3 +185,63 @@ char *virBitmapString(virBitmapPtr bitmap) return virBufferContentAndReset(buf); } + +/** + * virBitmapParseCommaSeparatedFormat: + * + * When bitmap is printed in ascii format, expecially in Linux, s/expecially/especially/ + * comma-separated format is sometimes used. For example, a bitmap 1011 is + * represetned as 0-4,6-7. This function
Re: [libvirt] [test-API][PATCH 2/2] Add and update functions in streamAPI
On 01/31/2012 06:07 PM, Alex Jia wrote: On 01/31/2012 04:46 PM, Wayne Sun wrote: * only accpet stream object as parameter in __init__ * remove newStream() from each function stream object should be pass in as parameter, not create new at each function. function also need flags parameter. * Add 5 new functions screenshot(self, domain, screen, flags = 0) download(self, vol, offset, length, flags = 0) upload(self, vol, offset, length, flags = 0) recvAll(self, handler, opaque) sendAll(self, handler, opaque) for recvAll and sendAll, handler is a user defined function which write/read data to/from file. --- lib/streamAPI.py | 84 + 1 files changed, 58 insertions(+), 26 deletions(-) diff --git a/lib/streamAPI.py b/lib/streamAPI.py index bc7d217..a1b2d0d 100644 --- a/lib/streamAPI.py +++ b/lib/streamAPI.py @@ -38,76 +38,108 @@ append_path(result.group(0)) import exception class StreamAPI(object): -def __init__(self, connection): -self.conn = connection +def __init__(self, stream): +self.stream_obj = stream Need a 'stream' instance to initialize class StreamAPI? how to do this? users must to do 'stream = con.newStream(0)' then StreamAPI(stream), right? maybe, we may do this like this: class StreamAPI(object): def __init__(self, connection, flag = 0): self.conn = connection self.stream_obj = newStream(flag) It should be 'self.stream_obj = self.conn.newStream(flag)' Alex -def abort(self, flag = 0): +def abort(self): try: -stream_obj = newStream(flag) -return stream_obj.abort() +return self.stream_obj.abort() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def connect(self, flag = 0): +def connect(self): try: -stream_obj = newStream(flag) -return stream_obj.connect() +return self.stream_obj.connect() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def finish(self, flag = 0): +def finish(self): try: -stream_obj = newStream(flag) -return stream_obj.finish() +return self.stream_obj.finish() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def recv(self, flag = 0, data, nbytes): +def recv(self, nbytes): try: -stream_obj = newStream(flag) -return stream_obj.recv(data, nbytes) +return self.stream_obj.recv(nbytes) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def send(self, flag = 0, data, nbytes): +def send(self, data): try: -stream_obj = newStream(flag) -return stream_obj.send(data, nbytes) +return self.stream_obj.send(data) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventAddCallback(self, flag = 0, cb, opaque): +def eventAddCallback(self, cb, opaque): try: -stream_obj = newStream(flag) -return stream_obj.eventAddCallback(cb, opaque) +return self.stream_obj.eventAddCallback(cb, opaque) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventRemoveCallback(self, flag = 0): +def eventRemoveCallback(self): try: -stream_obj = newStream(flag) -return stream_obj.eventRemoveCallback() +return self.stream_obj.eventRemoveCallback() except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code) -def eventUpdateCallback(self, flag = 0, events) +def eventUpdateCallback(self, events): try: -stream_obj = newStream(flag) -return stream_obj.eventUpdateCallback(events) +return self.stream_obj.eventUpdateCallback(events) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise exception.LibvirtAPI(message, code) + +def screenshot(self, domain, screen, flags = 0): +try: +return
[libvirt] [[libvirt-glib PATCHv2]] API to get/set custom metadata from/to domain config
Based on a patch from Zeeshan Ali (Khattak) zeesha...@gnome.org --- libvirt-gconfig/libvirt-gconfig-domain.c | 60 + libvirt-gconfig/libvirt-gconfig-domain.h |7 +++ libvirt-gconfig/libvirt-gconfig-helpers-private.h |1 + libvirt-gconfig/libvirt-gconfig-helpers.c | 23 - libvirt-gconfig/libvirt-gconfig-object-private.h |3 + libvirt-gconfig/libvirt-gconfig-object.c | 20 +++ libvirt-gconfig/libvirt-gconfig.sym |2 + 7 files changed, 115 insertions(+), 1 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c index 61af625..606f5a4 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain.c +++ b/libvirt-gconfig/libvirt-gconfig-domain.c @@ -449,3 +449,63 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain) return data.devices; } + +gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain, + const gchar *xml, + const gchar *ns, + const gchar *ns_uri, + GError **error) +{ +GVirConfigObject *metadata; +GVirConfigObject *custom_xml; + +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE); +g_return_val_if_fail(xml != NULL, FALSE); +g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + +metadata = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain), metadata); + +custom_xml = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_OBJECT, NULL, NULL, xml, error); +if (error != NULL *error != NULL) +return FALSE; + +gvir_config_object_set_namespace(custom_xml, ns, ns_uri); + +gvir_config_object_attach_replace(metadata, custom_xml); + +return TRUE; +} + +struct LookupNamespacedNodeData { +const char *ns_uri; +xmlNodePtr node; +}; + +static gboolean lookup_namespaced_node(xmlNodePtr node, gpointer opaque) +{ +struct LookupNamespacedNodeData* data = opaque; + +if (node-ns == NULL) +return TRUE; + +if (g_strcmp0((char *)node-ns-href, data-ns_uri) == 0) { +data-node = node; +return FALSE; +} + +return TRUE; +} + +gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain, + const gchar *ns_uri) +{ +struct LookupNamespacedNodeData data = { NULL, NULL }; + +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL); +g_return_val_if_fail(ns_uri != NULL, NULL); + +data.ns_uri = ns_uri; +gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), metadata, + lookup_namespaced_node, data); +return gvir_config_xml_node_to_string(data.node); +} diff --git a/libvirt-gconfig/libvirt-gconfig-domain.h b/libvirt-gconfig/libvirt-gconfig-domain.h index 6cdaec9..769d2f0 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain.h +++ b/libvirt-gconfig/libvirt-gconfig-domain.h @@ -126,6 +126,13 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain); void gvir_config_domain_set_lifecycle(GVirConfigDomain *domain, GVirConfigDomainLifecycleEvent event, GVirConfigDomainLifecycleAction action); +gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain, + const gchar *xml, + const gchar *ns, + const gchar *ns_uri, + GError **error); +gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain, + const gchar *ns_uri); G_END_DECLS diff --git a/libvirt-gconfig/libvirt-gconfig-helpers-private.h b/libvirt-gconfig/libvirt-gconfig-helpers-private.h index 96ec02e..514aeb0 100644 --- a/libvirt-gconfig/libvirt-gconfig-helpers-private.h +++ b/libvirt-gconfig/libvirt-gconfig-helpers-private.h @@ -56,6 +56,7 @@ char *gvir_config_xml_get_child_element_content_glib (xmlNode *node, const char *child_name); xmlChar *gvir_config_xml_get_attribute_content(xmlNodePtr node, const char *attr_name); +char *gvir_config_xml_node_to_string(xmlNodePtr node); char *gvir_config_xml_get_attribute_content_glib(xmlNodePtr node, const char *attr_name); const char *gvir_config_genum_get_nick (GType enum_type, gint value); diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c b/libvirt-gconfig/libvirt-gconfig-helpers.c index fecf3eb..a324d0e 100644 --- a/libvirt-gconfig/libvirt-gconfig-helpers.c +++ b/libvirt-gconfig/libvirt-gconfig-helpers.c @@ -148,7 +148,8 @@ gvir_config_xml_parse(const char *xml, const char *root_node, GError
[libvirt] [[libvirt-glib PATCHv2] 2/4] Don't use g_error in xxx_get_name
g_error will trigger an abort of the running process so it's not desirable to call it in a library. This commit adds a GError ** parameter to all _get_name methods which were calling g_error. --- libvirt-gobject/libvirt-gobject-connection.c | 10 -- libvirt-gobject/libvirt-gobject-domain-snapshot.c |5 - libvirt-gobject/libvirt-gobject-domain.c |7 +-- libvirt-gobject/libvirt-gobject-domain.h |2 +- libvirt-gobject/libvirt-gobject-interface.c |7 +-- libvirt-gobject/libvirt-gobject-interface.h |2 +- libvirt-gobject/libvirt-gobject-network-filter.c |8 ++-- libvirt-gobject/libvirt-gobject-network-filter.h |2 +- libvirt-gobject/libvirt-gobject-network.c |7 +-- libvirt-gobject/libvirt-gobject-network.h |2 +- libvirt-gobject/libvirt-gobject-node-device.c |7 +-- libvirt-gobject/libvirt-gobject-node-device.h |2 +- libvirt-gobject/libvirt-gobject-storage-pool.c|7 +-- libvirt-gobject/libvirt-gobject-storage-pool.h|2 +- 14 files changed, 49 insertions(+), 21 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c index a90581a..c19e411 100644 --- a/libvirt-gobject/libvirt-gobject-connection.c +++ b/libvirt-gobject/libvirt-gobject-connection.c @@ -1112,7 +1112,10 @@ GVirDomain *gvir_connection_find_domain_by_name(GVirConnection *conn, while (g_hash_table_iter_next(iter, key, value)) { GVirDomain *dom = value; -const gchar *thisname = gvir_domain_get_name(dom); +const gchar *thisname = gvir_domain_get_name(dom, NULL); + +if (thisname == NULL) +continue; if (strcmp(thisname, name) == 0) { g_object_ref(dom); @@ -1143,7 +1146,10 @@ GVirStoragePool *gvir_connection_find_storage_pool_by_name(GVirConnection *conn, while (g_hash_table_iter_next(iter, key, value)) { GVirStoragePool *pool = value; -const gchar *thisname = gvir_storage_pool_get_name(pool); +const gchar *thisname = gvir_storage_pool_get_name(pool, NULL); + +if (thisname == NULL) +continue; if (strcmp(thisname, name) == 0) { g_object_ref(pool); diff --git a/libvirt-gobject/libvirt-gobject-domain-snapshot.c b/libvirt-gobject/libvirt-gobject-domain-snapshot.c index 950555a..0560595 100644 --- a/libvirt-gobject/libvirt-gobject-domain-snapshot.c +++ b/libvirt-gobject/libvirt-gobject-domain-snapshot.c @@ -166,7 +166,10 @@ const gchar *gvir_domain_snapshot_get_name(GVirDomainSnapshot *snapshot) const char *name; if (!(name = virDomainSnapshotGetName(priv-handle))) { -g_error(Failed to get domain_snapshot name on %p, priv-handle); +gvir_set_error(err, GVIR_DOMAIN_SNAPSHOT_ERROR, 0, + Failed to get domain_snapshot name on %p, + priv-handle); +return NULL; } return name; diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c index c1a67a5..bfbb80f 100644 --- a/libvirt-gobject/libvirt-gobject-domain.c +++ b/libvirt-gobject/libvirt-gobject-domain.c @@ -264,13 +264,16 @@ G_DEFINE_BOXED_TYPE(GVirDomainInfo, gvir_domain_info, gvir_domain_info_copy, gvir_domain_info_free) -const gchar *gvir_domain_get_name(GVirDomain *dom) +const gchar *gvir_domain_get_name(GVirDomain *dom, GError **err) { GVirDomainPrivate *priv = dom-priv; const char *name; if (!(name = virDomainGetName(priv-handle))) { -g_error(Failed to get domain name on %p, priv-handle); +gvir_set_error(err, GVIR_DOMAIN_ERROR, 0, + Failed to get domain name on %p, + priv-handle); +return NULL; } return name; diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h index 20388f2..d912b21 100644 --- a/libvirt-gobject/libvirt-gobject-domain.h +++ b/libvirt-gobject/libvirt-gobject-domain.h @@ -102,7 +102,7 @@ GType gvir_domain_get_type(void); GType gvir_domain_info_get_type(void); GType gvir_domain_handle_get_type(void); -const gchar *gvir_domain_get_name(GVirDomain *dom); +const gchar *gvir_domain_get_name(GVirDomain *dom, GError **error); const gchar *gvir_domain_get_uuid(GVirDomain *dom); gint gvir_domain_get_id(GVirDomain *dom, GError **err); diff --git a/libvirt-gobject/libvirt-gobject-interface.c b/libvirt-gobject/libvirt-gobject-interface.c index f7bdde8..095e22a 100644 --- a/libvirt-gobject/libvirt-gobject-interface.c +++ b/libvirt-gobject/libvirt-gobject-interface.c @@ -157,13 +157,16 @@ gvir_interface_handle_free(GVirInterfaceHandle *src) G_DEFINE_BOXED_TYPE(GVirInterfaceHandle, gvir_interface_handle, gvir_interface_handle_copy, gvir_interface_handle_free) -const gchar
[libvirt] [[libvirt-glib PATCHv2] 3/4] Output runtime warning when *_get_name fails
*_get_name failures used to trigger a crash of the application because of the use of g_error. Now that it's removed, such failures may go unnoticed and unchecked. Add a runtime warning when a failure occurs. --- libvirt-gobject/libvirt-gobject-domain-snapshot.c |1 + libvirt-gobject/libvirt-gobject-domain.c |1 + libvirt-gobject/libvirt-gobject-interface.c |1 + libvirt-gobject/libvirt-gobject-network-filter.c |1 + libvirt-gobject/libvirt-gobject-network.c |1 + libvirt-gobject/libvirt-gobject-node-device.c |1 + libvirt-gobject/libvirt-gobject-storage-pool.c|1 + libvirt-gobject/libvirt-gobject-storage-vol.c |2 ++ 8 files changed, 9 insertions(+), 0 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain-snapshot.c b/libvirt-gobject/libvirt-gobject-domain-snapshot.c index 0560595..3784b60 100644 --- a/libvirt-gobject/libvirt-gobject-domain-snapshot.c +++ b/libvirt-gobject/libvirt-gobject-domain-snapshot.c @@ -169,6 +169,7 @@ const gchar *gvir_domain_snapshot_get_name(GVirDomainSnapshot *snapshot) gvir_set_error(err, GVIR_DOMAIN_SNAPSHOT_ERROR, 0, Failed to get domain_snapshot name on %p, priv-handle); +g_warn_if_reached(); return NULL; } diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c index bfbb80f..0f64833 100644 --- a/libvirt-gobject/libvirt-gobject-domain.c +++ b/libvirt-gobject/libvirt-gobject-domain.c @@ -273,6 +273,7 @@ const gchar *gvir_domain_get_name(GVirDomain *dom, GError **err) gvir_set_error(err, GVIR_DOMAIN_ERROR, 0, Failed to get domain name on %p, priv-handle); +g_warn_if_reached(); return NULL; } diff --git a/libvirt-gobject/libvirt-gobject-interface.c b/libvirt-gobject/libvirt-gobject-interface.c index 095e22a..83d4136 100644 --- a/libvirt-gobject/libvirt-gobject-interface.c +++ b/libvirt-gobject/libvirt-gobject-interface.c @@ -166,6 +166,7 @@ const gchar *gvir_interface_get_name(GVirInterface *iface, GError **err) gvir_set_error(err, GVIR_INTERFACE_ERROR, 0, Failed to get interface name on %p, priv-handle); +g_warn_if_reached(); return NULL; } diff --git a/libvirt-gobject/libvirt-gobject-network-filter.c b/libvirt-gobject/libvirt-gobject-network-filter.c index 473ef5d..efefdf4 100644 --- a/libvirt-gobject/libvirt-gobject-network-filter.c +++ b/libvirt-gobject/libvirt-gobject-network-filter.c @@ -183,6 +183,7 @@ const gchar *gvir_network_filter_get_name(GVirNetworkFilter *filter, gvir_set_error(err, GVIR_NETWORK_FILTER_ERROR, 0, Failed to get network_filter name on %p, priv-handle); +g_warn_if_reached(); return NULL; } diff --git a/libvirt-gobject/libvirt-gobject-network.c b/libvirt-gobject/libvirt-gobject-network.c index 143e80b..43c1a52 100644 --- a/libvirt-gobject/libvirt-gobject-network.c +++ b/libvirt-gobject/libvirt-gobject-network.c @@ -180,6 +180,7 @@ const gchar *gvir_network_get_name(GVirNetwork *network, GError **err) gvir_set_error(err, GVIR_NETWORK_ERROR, 0, Failed to get network name on %p, priv-handle); +g_warn_if_reached(); return NULL; } diff --git a/libvirt-gobject/libvirt-gobject-node-device.c b/libvirt-gobject/libvirt-gobject-node-device.c index 55f7098..e34d37b 100644 --- a/libvirt-gobject/libvirt-gobject-node-device.c +++ b/libvirt-gobject/libvirt-gobject-node-device.c @@ -166,6 +166,7 @@ const gchar *gvir_node_device_get_name(GVirNodeDevice *device, GError **err) gvir_set_error(err, GVIR_NODE_DEVICE_ERROR, 0, Failed to get node_device name on %p, priv-handle); +g_warn_if_reached(); return NULL; } diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.c b/libvirt-gobject/libvirt-gobject-storage-pool.c index d2ee6d6..ef8617f 100644 --- a/libvirt-gobject/libvirt-gobject-storage-pool.c +++ b/libvirt-gobject/libvirt-gobject-storage-pool.c @@ -212,6 +212,7 @@ const gchar *gvir_storage_pool_get_name(GVirStoragePool *pool, GError **err) gvir_set_error(err, GVIR_STORAGE_POOL_ERROR, 0, Failed to get storage_pool name on %p, priv-handle); +g_warn_if_reached(); return NULL; } diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c index c427e42..c27cfb7 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.c +++ b/libvirt-gobject/libvirt-gobject-storage-vol.c @@ -181,6 +181,7 @@ const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol, GError **error) gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0,
[libvirt] [[libvirt-glib PATCHv2] 1/4] Add proper error reporting to GVirStorageVol getters
gvir_storage_vol_get_name and gvir_storage_vol_get_path currently call g_error when an error occurs. Since g_error trigger a coredump, calling it in a library is harmful. Replace this with proper GError error reporting. --- libvirt-gobject/libvirt-gobject-storage-pool.c | 10 +++--- libvirt-gobject/libvirt-gobject-storage-vol.c | 14 ++ libvirt-gobject/libvirt-gobject-storage-vol.h |4 ++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.c b/libvirt-gobject/libvirt-gobject-storage-pool.c index bf25641..a88699e 100644 --- a/libvirt-gobject/libvirt-gobject-storage-pool.c +++ b/libvirt-gobject/libvirt-gobject-storage-pool.c @@ -528,6 +528,7 @@ GVirStorageVol *gvir_storage_pool_create_volume const gchar *xml; virStorageVolPtr handle; GVirStoragePoolPrivate *priv = pool-priv; +const char *name; xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf)); @@ -545,11 +546,14 @@ GVirStorageVol *gvir_storage_pool_create_volume volume = GVIR_STORAGE_VOL(g_object_new(GVIR_TYPE_STORAGE_VOL, handle, handle, NULL)); +name = gvir_storage_vol_get_name(volume, err); +if (name == NULL) { +g_object_unref(G_OBJECT(volume)); +return NULL; +} g_mutex_lock(priv-lock); -g_hash_table_insert(priv-volumes, -g_strdup(gvir_storage_vol_get_name(volume)), -volume); +g_hash_table_insert(priv-volumes, g_strdup(name), volume); g_mutex_unlock(priv-lock); return g_object_ref(volume); diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c index 5b18877..c427e42 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.c +++ b/libvirt-gobject/libvirt-gobject-storage-vol.c @@ -172,25 +172,31 @@ gvir_storage_vol_info_free(GVirStorageVolInfo *info) G_DEFINE_BOXED_TYPE(GVirStorageVolInfo, gvir_storage_vol_info, gvir_storage_vol_info_copy, gvir_storage_vol_info_free) -const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol) +const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol, GError **error) { GVirStorageVolPrivate *priv = vol-priv; const char *name; if (!(name = virStorageVolGetName(priv-handle))) { -g_error(Failed to get storage_vol name on %p, priv-handle); +gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0, + Failed to get storage_vol name on %p, + priv-handle); +return NULL; } return name; } -const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol) +const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error) { GVirStorageVolPrivate *priv = vol-priv; const char *path; if (!(path = virStorageVolGetPath(priv-handle))) { -g_error(Failed to get storage_vol path on %p, priv-handle); +gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0, + Failed to get storage_vol path on %p, + priv-handle); +return NULL; } return path; diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.h b/libvirt-gobject/libvirt-gobject-storage-vol.h index db63865..fd2be80 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.h +++ b/libvirt-gobject/libvirt-gobject-storage-vol.h @@ -77,8 +77,8 @@ GType gvir_storage_vol_get_type(void); GType gvir_storage_vol_info_get_type(void); GType gvir_storage_vol_handle_get_type(void); -const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol); -const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol); +const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol, GError **error); +const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error); gboolean gvir_storage_vol_delete(GVirStorageVol *vol, guint flags, -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [[libvirt-glib PATCHv2] 4/4] Replace g_error with g_warning in constructors
g_error generates a fatal error message, meaning it will abort the currently running process. It's nicer to use g_warning here. --- libvirt-gobject/libvirt-gobject-domain.c |4 +++- libvirt-gobject/libvirt-gobject-network-filter.c |4 +++- libvirt-gobject/libvirt-gobject-network.c|4 +++- libvirt-gobject/libvirt-gobject-secret.c |4 +++- libvirt-gobject/libvirt-gobject-storage-pool.c |4 +++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c index 0f64833..e4d480a 100644 --- a/libvirt-gobject/libvirt-gobject-domain.c +++ b/libvirt-gobject/libvirt-gobject-domain.c @@ -134,7 +134,9 @@ static void gvir_domain_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virDomainGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get domain UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +g_warning(Failed to get domain UUID on %p: %s, + priv-handle, verr-message); } } diff --git a/libvirt-gobject/libvirt-gobject-network-filter.c b/libvirt-gobject/libvirt-gobject-network-filter.c index efefdf4..eb9cc82 100644 --- a/libvirt-gobject/libvirt-gobject-network-filter.c +++ b/libvirt-gobject/libvirt-gobject-network-filter.c @@ -119,7 +119,9 @@ static void gvir_network_filter_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virNWFilterGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get network filter UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +g_warning(Failed to get network filter UUID on %p: %s, + priv-handle, verr-message); } } diff --git a/libvirt-gobject/libvirt-gobject-network.c b/libvirt-gobject/libvirt-gobject-network.c index 43c1a52..dcd2300 100644 --- a/libvirt-gobject/libvirt-gobject-network.c +++ b/libvirt-gobject/libvirt-gobject-network.c @@ -118,7 +118,9 @@ static void gvir_network_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virNetworkGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get network UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +g_warning(Failed to get network UUID on %p: %s, + priv-handle, verr-message); } } diff --git a/libvirt-gobject/libvirt-gobject-secret.c b/libvirt-gobject/libvirt-gobject-secret.c index bc5ee3b..cd819a5 100644 --- a/libvirt-gobject/libvirt-gobject-secret.c +++ b/libvirt-gobject/libvirt-gobject-secret.c @@ -119,7 +119,9 @@ static void gvir_secret_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virSecretGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get secret UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +g_warning(Failed to get secret UUID on %p: %s, + priv-handle, verr-message); } } diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.c b/libvirt-gobject/libvirt-gobject-storage-pool.c index ef8617f..ffb8b26 100644 --- a/libvirt-gobject/libvirt-gobject-storage-pool.c +++ b/libvirt-gobject/libvirt-gobject-storage-pool.c @@ -129,7 +129,9 @@ static void gvir_storage_pool_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virStoragePoolGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get storage pool UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +g_warning(Failed to get storage pool UUID on %p: %s, + priv-handle, verr-message); } } -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Qemu text monitor
Hello All, I am currently working with libvirt on RHEL6.2. There are a few points I have noticed regarding the QEMU monitor. When I hotplug a device into the guest, the Qemu text monitor receives a device_add command and adds the device to its current devices list (I found this list via the qemu-monitor-command info pci). When I hot-unplug the device from the guest, the Qemu text monitor receives the device_del command but does not remove the device from its current devices list (qemu-monitor-command info pci still shows the device). The result of this is that the next hotplug of the device fails giving an error Duplicate id. I was wondering if any of you have hit this issue before or know about any qemu-monitor bugs I may not be aware of? Many Thanks in advance, Regards, Shradha Shah -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] g_error considered harmful
On Mon, Jan 30, 2012 at 07:22:54PM +0100, Marc-André Lureau wrote: Hi In general I agree with the patch series dropping g_error() in favour of normal GError reporting, so programs can cope with errors. However, it removes the forced logging and it's too easy for the caller to ignore them, making it hard to track down when something goes wrong. I added a patch to the series to add a g_warn_if_reached when this is triggered I think this is even more relevant, because libvirt-glib is logging *tons* of normal/useless runtime messages To be honest I didn't really notice that... What kind of useless messages are you getting ? Christophe pgpk3E5TsjUSz.pgp Description: PGP signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Build issue with libvirt 0.9.8
On Fri, Dec 09, 2011 at 02:18:02PM +0100, Christophe Fergeau wrote: Hi, On Fri, Dec 09, 2011 at 11:18:48AM +, Daniel P. Berrange wrote: There is something odd about the way it is being built: The combination of these 3 sets of messages, makes me think you have confused libtool into linking to the old binary What arguments are you passing to 'configure' and what if any variables are you passing to 'make install' ? Yes, jhbuild is being a bit convoluted when building things, it uses ./configure --prefix $prefix ..., but then it does a make install DESTDIR=$prefix/_jhbuild (or something like this), and then it moves the files to the right place in $prefix after cleaning up the old version of the library that might be there. I just tried without using jhbuild to build libvirt, but just the tarballs, and I can reproduce when using make install DESTDIR=... and then cleaning $prefix from libvirt libs, and then copying what's in DESTDIR to $prefix. Not sure it's worth spending a lot of time on this convoluted scenario :) I looked some more into it, and I think what happens is that: - libvirt.so gets installed to $DESTDIR/$libdir - libvirt-qemu.so gets relinked by libtool during installation, but uses libvirt from $libdir for this relink - $libdir/libvirt.so gets replaced with $DESDIR/$libdir/libvirt.so - libvirt-qemu.so now has some references to a library that has now disappeared http://www.gnu.org/software/libtool/manual/html_node/Install-mode.html seems to indicate this scenario cannot be supported correctly :( For systems where fast installation can not be turned on, relinking may be needed. In this case, a ‘DESTDIR’ install will fail. Currently it is not generally possible to install into a temporary staging area that contains needed third-party libraries which are not yet visible at their final location. (I think linux doesn't have fast installation) Christophe pgpuJ0Mx4fx2b.pgp Description: PGP signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Qemu text monitor
On 31.01.2012 12:12, Shradha Shah wrote: Hello All, I am currently working with libvirt on RHEL6.2. There are a few points I have noticed regarding the QEMU monitor. When I hotplug a device into the guest, the Qemu text monitor receives a device_add command and adds the device to its current devices list (I found this list via the qemu-monitor-command info pci). When I hot-unplug the device from the guest, the Qemu text monitor receives the device_del command but does not remove the device from its current devices list (qemu-monitor-command info pci still shows the device). The result of this is that the next hotplug of the device fails giving an error Duplicate id. I was wondering if any of you have hit this issue before or know about any qemu-monitor bugs I may not be aware of? Yeah, it's a known issue https://bugzilla.redhat.com/show_bug.cgi?id=758658 but I don't know if/when it will be fixed. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC Incomplete Patch] Libvirt + Openvswitch
On Fri, Jan 27, 2012 at 02:58:58AM -0800, Dan Wendlandt wrote: Hello all, I know of many people who want to spin up VMs using libvirt + kvm/qemu and attach those VMs to an openvswitch bridge (see: http://www.openvswitch.org). However, the only way I know of to get this working is a kludge that uses to tap devices along with interface type=ethernet while running ovs-vsctl outside of libvirt. Even worse, doing this on RHEL/Fedora seems to require privilege tweaks (e.g., running qemu as root, not dropping capabilities), which may not be acceptable for production deployments (see: http://fedoraproject.org/wiki/How_to_debug_Virtualization_problems#Errors_using_.3Cinterface_type.3D.27ethernet.27.2F.3E). So I would like to start taking steps toward better libvirt/openvswitch integration. My initial step has the fairly limit goal of enabling kvm/qemu VM NICs to attach to an openvswitch bridge in much the same way VM NIC can already attached to the linux bridge. For example, specifying: interface type=openvswitch source bridge=br0/ mac address=ca:fe:de;ad:be:ef/ /interface IMHO we should not be introducing a new type for OpenVSwitch. Contrary to common understanding, type='bridge' is not referring explicitly to Linux software bridging. Rather it refers to the concept of bridging the guest to the LAN at the network level, of which Linux software briding is one possible impl. OpenVSwitch is another possible impl. Other hypervisors have different impls too of course. If OpenVSwitch is available in the kernel, is there really any reason to *not* use it ? ie, could we just have interface type=bridge source bridge=br0/ mac address=ca:fe:de;ad:be:ef/ /interface and if we see that 'br0' is using OpenVSwitch, then libvirt can know to just do the right thing. That way every application that uses libvirt today will automatically be able to take advantage of the benefits OpenVSwitch brings without further work I also wanted to add a new child element of interface that can be used to specify some OVS specific configuration. To start, I just want to expose a single 'interfaceid' value (this parameter is specific to openvswitch). Extending the previous example: interface type=openvswitch source bridge=br0/ mac address=ca:fe:de;ad:be:ef/ openvswitchport interfaceid=interface-xyz/ /interface We already have a virtualport element under interface that we use for setting 802.1Qb[gh] parameters. It seems to me that we can use this existing syntax to cope with the openvswitch port interfaceid perhaps ? Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC Incomplete Patch] Libvirt + Openvswitch
On Mon, Jan 30, 2012 at 02:49:03PM -0600, kmestery wrote: On Jan 30, 2012, at 2:41 PM, Dan Wendlandt wrote: Hi Kyle! Funny how we keep bumping into each other... I hope you're keeping warm in Minnesota :) On Fri, Jan 27, 2012 at 11:22 AM, kmestery kmest...@cisco.com wrote: Hi Dan: We at Cisco have been looking at this as well, and in fact were going to propose some things in this area as well. Our proposal (which frankly just builds on top of what you have): I agree, I think the two proposals are complementary. Our first goal was to enable the basic mode of plugging an interface into an OVS bridge that was created outside of libvirt. This would require changes to the interface XML only, and would mirror how libvirt already let's one plug into an existing bridge using interface type=bridge. This makes sense. The second step would be to also allow libvirt to actually create + configure the OVS bridges as well. This I believe would map very closely to the XML you and Roopa have suggested. We would need to put some thought into what of the many configuration options on an OVS bridge need to be exposed as part of the OVS network XML (e.g., how to configure an OpenFlow controller, etc.). These are definitely discussions worth having, but I was hoping to start out with a fairly clean initial patch to achieve our first goal. OK, this makes sense too. I do like the idea of using the virtual port construct even in the initial interface only case. For example: interface type='bridge' bridge name='br0' virtualport type=openvswitch parameters interfaceid='xyzzy'/ /virtualport /interface This would seem to create a nice parallel with the model you proposed where virtualport is used with interface type=network. I'm still not sure whether the type=openvswitch should be an attribute of the interface, bridge, or virtualport element. Either way, I think the underlying code will be treating OVS + Linux Bridge as two different cases, so I believe this is really just a matter of consistently of presentation in XML. Yes, I prefer this design to the initial proposal. I think fundamentally an Open vSwitch bridge is different from a standard Linux, thus the type=openvswitch needs to be a part of the bridge for sure. I like adding it to the virtualport element above. NB, type='bridge' technically refers to the *concept* of bridging an interface to a LAN, not the implemntation of Linux software bridging. Thus it shouldn't change for OpenVSwitch which is also providing bridging to the LAN here. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 3/4] util: extend virExecWithHook()
On Tue, Jan 31, 2012 at 01:51:22PM +0900, Taku Izumi wrote: This patch extends virExecWithHook() to receive capability information. Signed-off-by: Taku Izumi izumi.t...@jp.fujitsu.com Signed-off-by: Shota Hirae m11g1...@hibikino.ne.jp --- src/util/command.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) Index: libvirt/src/util/command.c === --- libvirt.orig/src/util/command.c +++ libvirt/src/util/command.c @@ -393,6 +393,7 @@ prepareStdFd(int fd, int std) * @hook optional virExecHook function to call prior to exec * @data data to pass to the hook function * @pidfile path to use as pidfile for daemonized process (needs DAEMON flag) + * @capabilities capabilities to keep */ static int virExecWithHook(const char *const*argv, @@ -404,7 +405,8 @@ virExecWithHook(const char *const*argv, unsigned int flags, virExecHook hook, void *data, -char *pidfile) +char *pidfile, +unsigned long long capabilities) { pid_t pid; int null = -1, i, openmax; @@ -633,9 +635,9 @@ virExecWithHook(const char *const*argv, /* The steps above may need todo something privileged, so * we delay clearing capabilities until the last minute */ -if ((flags VIR_EXEC_CLEAR_CAPS) -virClearCapabilities() 0) -goto fork_error; +if (capabilities || (flags VIR_EXEC_CLEAR_CAPS)) +if (virSetCapabilities(capabilities) 0) +goto fork_error; /* Close logging again to ensure no FDs leak to child */ virLogReset(); @@ -723,7 +725,8 @@ virExecWithHook(const char *const*argv A int flags_unused ATTRIBUTE_UNUSED, virExecHook hook ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED, -char *pidfile ATTRIBUTE_UNUSED) +char *pidfile ATTRIBUTE_UNUSED, +unsigned long long capabilities ATTRIBUTE_UNUSED) { /* XXX: Some day we can implement pieces of virCommand/virExec on * top of _spawn() or CreateProcess(), but we can't implement @@ -2171,7 +2174,8 @@ virCommandRunAsync(virCommandPtr cmd, pi cmd-flags, virCommandHook, cmd, - cmd-pidfile); + cmd-pidfile, + cmd-capabilities); VIR_DEBUG(Command result %d, with PID %d, ret, (int)cmd-pid); ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/4] conf: add rawio attribute to disk element of domain XML
On Tue, Jan 31, 2012 at 01:49:11PM +0900, Taku Izumi wrote: @@ -3156,6 +3159,26 @@ virDomainDiskDefParseXML(virCapsPtr caps def-snapshot = VIR_DOMAIN_DISK_SNAPSHOT_NO; } +def-rawio = -1; /* unspecified */ +if (rawio) { +if (def-device == VIR_DOMAIN_DISK_DEVICE_LUN) { +if (STREQ(rawio, yes)) { +def-rawio = 1; +} else if (STREQ(rawio, no)) { +def-rawio = 0; +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(unknown disk rawio setting '%s'), + rawio); +goto error; +} +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, %s, +_(rawio can be used only with device='lun')); s/INTERNAL_ERROR/XML_ERROR/ ACK with that change Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/4] util: add functions to keep capabilities
On Tue, Jan 31, 2012 at 01:50:42PM +0900, Taku Izumi wrote: This patch introduces virSetCapabilities() function and implements virCommandAllowCap() function. Existing virClearCapabilities() is function to clear all capabilities. Instead virSetCapabilities() is function to set arbitrary capabilities. Signed-off-by: Taku Izumi izumi.t...@jp.fujitsu.com Signed-off-by: Shota Hirae m11g1...@hibikino.ne.jp --- src/util/command.c | 43 +-- src/util/command.h |2 -- 2 files changed, 37 insertions(+), 8 deletions(-) Index: libvirt/src/util/command.c === --- libvirt.orig/src/util/command.c +++ libvirt/src/util/command.c @@ -103,6 +103,8 @@ struct _virCommand { pid_t pid; char *pidfile; bool reap; + +unsigned long long capabilities; }; /* @@ -182,6 +184,33 @@ static int virClearCapabilities(void) return 0; } + +/** + * virSetCapabilities: + * @capabilities - capability flag to set. + * In case of 0, this function is identical to + * virClearCapabilities() + * + */ +static int virSetCapabilities(unsigned long long capabilities) +{ +int ret, i; + +capng_clear(CAPNG_SELECT_BOTH); + +for (i = 0; i = CAP_LAST_CAP; i++) { +if (capabilities (1ULL i)) +capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i); +} + +if ((ret = capng_apply(CAPNG_SELECT_BOTH)) 0) { +virCommandError(VIR_ERR_INTERNAL_ERROR, +_(cannot apply process capabilities %d), ret); +return -1; +} + +return 0; +} # else static int virClearCapabilities(void) { @@ -189,6 +218,11 @@ static int virClearCapabilities(void) // capabilities); return 0; } + +static int virSetCapabilities(unsigned long long capabilities) +{ +return 0; +} # endif /** @@ -883,26 +917,23 @@ virCommandClearCaps(virCommandPtr cmd) cmd-flags |= VIR_EXEC_CLEAR_CAPS; } -#if 0 /* XXX Enable if we have a need for capability management. */ - /** * virCommandAllowCap: * @cmd: the command to modify * @capability: what to allow * - * Re-allow a specific capability + * Allow specific capabilities */ void virCommandAllowCap(virCommandPtr cmd, - int capability ATTRIBUTE_UNUSED) + int capability) { if (!cmd || cmd-has_error) return; -/* XXX ? */ +cmd-capabilities |= (1ULL capability); } -#endif /* 0 */ /** Index: libvirt/src/util/command.h === --- libvirt.orig/src/util/command.h +++ libvirt/src/util/command.h @@ -60,10 +60,8 @@ void virCommandSetPidFile(virCommandPtr void virCommandClearCaps(virCommandPtr cmd); -# if 0 void virCommandAllowCap(virCommandPtr cmd, int capability); -# endif void virCommandDaemonize(virCommandPtr cmd); ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 4/4] qemu: make qemu processes to retain rawio capability
On Tue, Jan 31, 2012 at 01:52:27PM +0900, Taku Izumi wrote: This patch revises qemuProcessStart() function for qemu processes to retain CAP_SYS_RAWIO if needed. And in case of that, add taint flag to domain. Signed-off-by: Taku Izumi izumi.t...@jp.fujitsu.com Signed-off-by: Shota Hirae m11g1...@hibikino.ne.jp --- src/qemu/qemu_domain.c |3 +++ src/qemu/qemu_process.c |8 2 files changed, 11 insertions(+) Index: libvirt/src/qemu/qemu_process.c === --- libvirt.orig/src/qemu/qemu_process.c +++ libvirt/src/qemu/qemu_process.c @@ -27,6 +27,7 @@ #include sys/stat.h #include sys/time.h #include sys/resource.h +#include linux/capability.h #include qemu_process.h #include qemu_domain.h @@ -3083,6 +3084,7 @@ int qemuProcessStart(virConnectPtr conn, virCommandPtr cmd = NULL; struct qemuProcessHookData hookData; unsigned long cur_balloon; +int i; hookData.conn = conn; hookData.vm = vm; @@ -3335,6 +3337,12 @@ int qemuProcessStart(virConnectPtr conn, if (driver-clearEmulatorCapabilities) virCommandClearCaps(cmd); +/* in case a certain disk is desirous of CAP_SYS_RAWIO, add this */ +for (i = 0; i vm-def-ndisks; i++) { +if (vm-def-disks[i]-rawio == 1) +virCommandAllowCap(cmd, CAP_SYS_RAWIO); +} + virCommandSetPreExecHook(cmd, qemuProcessHook, hookData); virCommandSetOutputFD(cmd, logfile); Index: libvirt/src/qemu/qemu_domain.c === --- libvirt.orig/src/qemu/qemu_domain.c +++ libvirt/src/qemu/qemu_domain.c @@ -1259,6 +1259,9 @@ void qemuDomainObjCheckDiskTaint(struct if (!disk-driverType driver-allowDiskFormatProbing) qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_DISK_PROBING, logFD); + +if (disk-rawio) +qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_HIGH_PRIVILEGES, logFD); } ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [[libvirt-glib PATCHv2] 1/4] Add proper error reporting to GVirStorageVol getters
On Tue, Jan 31, 2012 at 12:00:20PM +0100, Christophe Fergeau wrote: gvir_storage_vol_get_name and gvir_storage_vol_get_path currently call g_error when an error occurs. Since g_error trigger a coredump, calling it in a library is harmful. Replace this with proper GError error reporting. --- libvirt-gobject/libvirt-gobject-storage-pool.c | 10 +++--- libvirt-gobject/libvirt-gobject-storage-vol.c | 14 ++ libvirt-gobject/libvirt-gobject-storage-vol.h |4 ++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.c b/libvirt-gobject/libvirt-gobject-storage-pool.c index bf25641..a88699e 100644 --- a/libvirt-gobject/libvirt-gobject-storage-pool.c +++ b/libvirt-gobject/libvirt-gobject-storage-pool.c @@ -528,6 +528,7 @@ GVirStorageVol *gvir_storage_pool_create_volume const gchar *xml; virStorageVolPtr handle; GVirStoragePoolPrivate *priv = pool-priv; +const char *name; xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf)); @@ -545,11 +546,14 @@ GVirStorageVol *gvir_storage_pool_create_volume volume = GVIR_STORAGE_VOL(g_object_new(GVIR_TYPE_STORAGE_VOL, handle, handle, NULL)); +name = gvir_storage_vol_get_name(volume, err); +if (name == NULL) { +g_object_unref(G_OBJECT(volume)); +return NULL; +} g_mutex_lock(priv-lock); -g_hash_table_insert(priv-volumes, -g_strdup(gvir_storage_vol_get_name(volume)), -volume); +g_hash_table_insert(priv-volumes, g_strdup(name), volume); g_mutex_unlock(priv-lock); return g_object_ref(volume); diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c index 5b18877..c427e42 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.c +++ b/libvirt-gobject/libvirt-gobject-storage-vol.c @@ -172,25 +172,31 @@ gvir_storage_vol_info_free(GVirStorageVolInfo *info) G_DEFINE_BOXED_TYPE(GVirStorageVolInfo, gvir_storage_vol_info, gvir_storage_vol_info_copy, gvir_storage_vol_info_free) -const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol) +const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol, GError **error) { GVirStorageVolPrivate *priv = vol-priv; const char *name; if (!(name = virStorageVolGetName(priv-handle))) { -g_error(Failed to get storage_vol name on %p, priv-handle); +gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0, + Failed to get storage_vol name on %p, + priv-handle); +return NULL; } return name; } -const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol) +const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error) { GVirStorageVolPrivate *priv = vol-priv; const char *path; if (!(path = virStorageVolGetPath(priv-handle))) { -g_error(Failed to get storage_vol path on %p, priv-handle); +gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0, + Failed to get storage_vol path on %p, + priv-handle); +return NULL; } return path; diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.h b/libvirt-gobject/libvirt-gobject-storage-vol.h index db63865..fd2be80 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.h +++ b/libvirt-gobject/libvirt-gobject-storage-vol.h @@ -77,8 +77,8 @@ GType gvir_storage_vol_get_type(void); GType gvir_storage_vol_info_get_type(void); GType gvir_storage_vol_handle_get_type(void); -const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol); -const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol); +const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol, GError **error); +const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error); gboolean gvir_storage_vol_delete(GVirStorageVol *vol, guint flags, ACK for the change to get_path, but we don't need todo this for get_name. The virStorageVolGetName() method will always succeed, unless passed an invalid pointer, since it is not involving any RPC. It merely returns the static string in the virStorageVolPtr struct. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [[libvirt-glib PATCHv2] 2/4] Don't use g_error in xxx_get_name
On Tue, Jan 31, 2012 at 12:00:21PM +0100, Christophe Fergeau wrote: g_error will trigger an abort of the running process so it's not desirable to call it in a library. This commit adds a GError ** parameter to all _get_name methods which were calling g_error. --- libvirt-gobject/libvirt-gobject-connection.c | 10 -- libvirt-gobject/libvirt-gobject-domain-snapshot.c |5 - libvirt-gobject/libvirt-gobject-domain.c |7 +-- libvirt-gobject/libvirt-gobject-domain.h |2 +- libvirt-gobject/libvirt-gobject-interface.c |7 +-- libvirt-gobject/libvirt-gobject-interface.h |2 +- libvirt-gobject/libvirt-gobject-network-filter.c |8 ++-- libvirt-gobject/libvirt-gobject-network-filter.h |2 +- libvirt-gobject/libvirt-gobject-network.c |7 +-- libvirt-gobject/libvirt-gobject-network.h |2 +- libvirt-gobject/libvirt-gobject-node-device.c |7 +-- libvirt-gobject/libvirt-gobject-node-device.h |2 +- libvirt-gobject/libvirt-gobject-storage-pool.c|7 +-- libvirt-gobject/libvirt-gobject-storage-pool.h|2 +- 14 files changed, 49 insertions(+), 21 deletions(-) I think that you can just replace g_error with g_warning. The vir*GetName() methods will never fail unless passed an invalid pointer, since they just return a const string from the struct, avoiding any RPC Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [[libvirt-glib PATCHv2] 4/4] Replace g_error with g_warning in constructors
On Tue, Jan 31, 2012 at 12:00:23PM +0100, Christophe Fergeau wrote: g_error generates a fatal error message, meaning it will abort the currently running process. It's nicer to use g_warning here. --- libvirt-gobject/libvirt-gobject-domain.c |4 +++- libvirt-gobject/libvirt-gobject-network-filter.c |4 +++- libvirt-gobject/libvirt-gobject-network.c|4 +++- libvirt-gobject/libvirt-gobject-secret.c |4 +++- libvirt-gobject/libvirt-gobject-storage-pool.c |4 +++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c index 0f64833..e4d480a 100644 --- a/libvirt-gobject/libvirt-gobject-domain.c +++ b/libvirt-gobject/libvirt-gobject-domain.c @@ -134,7 +134,9 @@ static void gvir_domain_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virDomainGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get domain UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +g_warning(Failed to get domain UUID on %p: %s, + priv-handle, verr-message); } } This is what I think we should be doing for GetName() too, since it has the same error scenarios as GetUUID*(). NB, for extra paranoia you shouldn't assume verr is non-NULL. eg,verr ? verr-message : NULL Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [[libvirt-glib PATCHv2]] API to get/set custom metadata from/to domain config
On Tue, Jan 31, 2012 at 12:02:05PM +0100, Christophe Fergeau wrote: Based on a patch from Zeeshan Ali (Khattak) zeesha...@gnome.org --- libvirt-gconfig/libvirt-gconfig-domain.c | 60 + libvirt-gconfig/libvirt-gconfig-domain.h |7 +++ libvirt-gconfig/libvirt-gconfig-helpers-private.h |1 + libvirt-gconfig/libvirt-gconfig-helpers.c | 23 - libvirt-gconfig/libvirt-gconfig-object-private.h |3 + libvirt-gconfig/libvirt-gconfig-object.c | 20 +++ libvirt-gconfig/libvirt-gconfig.sym |2 + 7 files changed, 115 insertions(+), 1 deletions(-) ACK, if one question is answered. diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c index 61af625..606f5a4 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain.c +++ b/libvirt-gconfig/libvirt-gconfig-domain.c @@ -449,3 +449,63 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain) return data.devices; } + +gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain, + const gchar *xml, + const gchar *ns, + const gchar *ns_uri, + GError **error) +{ +GVirConfigObject *metadata; +GVirConfigObject *custom_xml; + +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE); +g_return_val_if_fail(xml != NULL, FALSE); Shouldn't we allow NULL 'xml' here, as a means to remove the existing element under that namespace ? Alternatively we can add an explicit API to delete custom XML nodes. +g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + +metadata = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain), metadata); + +custom_xml = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_OBJECT, NULL, NULL, xml, error); +if (error != NULL *error != NULL) +return FALSE; + +gvir_config_object_set_namespace(custom_xml, ns, ns_uri); + +gvir_config_object_attach_replace(metadata, custom_xml); + +return TRUE; +} Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] tests: virnettlscontexttest needs gnutls-2.6.0
On Mon, Jan 30, 2012 at 12:10:57PM -0700, Eric Blake wrote: On 01/30/2012 10:44 AM, Philipp Hahn wrote: virnettlscontexttest uses gnutls_x509_crt_set_subject_alt_name() and GNUTLS_FSAN_APPEND, which - according to http://www.gnu.org/software/gnutls/manual/gnutls.html - are only available since 2.6.0. Since libvirt still works fine with gnutls-1.0.25 from RHEL5, only enable the test when the version of GNUTLS is at least 2.6.0. Signed-off-by: Philipp Hahn h...@univention.de --- tests/virnettlscontexttest.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c index 51f75b4..6dd42d4 100644 --- a/tests/virnettlscontexttest.c +++ b/tests/virnettlscontexttest.c @@ -36,7 +36,7 @@ #include virsocketaddr.h #include gnutls_1_0_compat.h -#if !defined WIN32 HAVE_LIBTASN1_H !defined GNUTLS_1_0_COMPAT +#if !defined WIN32 HAVE_LIBTASN1_H !defined GNUTLS_1_0_COMPAT LIBGNUTLS_VERSION_NUMBER 0x020600 Isn't that what GNUTLS_1_0_COMPAT is already doing? That is, GNUTLS_1_0_COMPAT should only be defined if we are already dealing with a newer gnutls, and should not be present when using RHEL5 1.0.25. What version of gnutls are you using, where this patch made a difference? The GNUTLS_1_0_COMPAT code is only dealing with versions = 2.0.0. This check is making it more strict to also skip any version in between 2.0.0 and 2.6.0 Perhaps, this allows us to now remove the GNUTLS_1_0_COMPAT, but I can't remember if the 1.0.x GNUTLS had LIBGNUTLS_VERSION_NUMBER defined or not. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Implement virStorageVolResize() for FS backend
On Mon, Jan 30, 2012 at 09:40:11AM +0200, Zeeshan Ali (Khattak) wrote: From: Zeeshan Ali (Khattak) zeesha...@gnome.org Currently only VIR_STORAGE_VOL_RESIZE_DELTA flag is supported. --- src/storage/storage_backend.h|6 +++ src/storage/storage_backend_fs.c | 53 +++ src/storage/storage_driver.c | 88 ++ src/util/storage_file.c | 16 +++ src/util/storage_file.h |2 + 5 files changed, 165 insertions(+), 0 deletions(-) ACK, looks ok to me. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [[libvirt-glib PATCHv2]] API to get/set custom metadata from/to domain config
On Tue, Jan 31, 2012 at 12:11:31PM +, Daniel P. Berrange wrote: On Tue, Jan 31, 2012 at 12:02:05PM +0100, Christophe Fergeau wrote: Based on a patch from Zeeshan Ali (Khattak) zeesha...@gnome.org --- libvirt-gconfig/libvirt-gconfig-domain.c | 60 + libvirt-gconfig/libvirt-gconfig-domain.h |7 +++ libvirt-gconfig/libvirt-gconfig-helpers-private.h |1 + libvirt-gconfig/libvirt-gconfig-helpers.c | 23 - libvirt-gconfig/libvirt-gconfig-object-private.h |3 + libvirt-gconfig/libvirt-gconfig-object.c | 20 +++ libvirt-gconfig/libvirt-gconfig.sym |2 + 7 files changed, 115 insertions(+), 1 deletions(-) ACK, if one question is answered. diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c index 61af625..606f5a4 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain.c +++ b/libvirt-gconfig/libvirt-gconfig-domain.c @@ -449,3 +449,63 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain) return data.devices; } + +gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain, + const gchar *xml, + const gchar *ns, + const gchar *ns_uri, + GError **error) +{ +GVirConfigObject *metadata; +GVirConfigObject *custom_xml; + +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE); +g_return_val_if_fail(xml != NULL, FALSE); Shouldn't we allow NULL 'xml' here, as a means to remove the existing element under that namespace ? Alternatively we can add an explicit API to delete custom XML nodes. Allowing NULL makes sense, I'll look at changing that. Christophe pgpGY4dZTCdnj.pgp Description: PGP signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: Clenup qemuDomainSetInterfaceParameters
which contained some useless lines, copied code, NULL dereference. --- src/libvirt.c |4 ++-- src/qemu/qemu_driver.c | 44 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index e702a34..433ae0a 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -7226,8 +7226,8 @@ error: * * Change a subset or all parameters of interface; currently this * includes bandwidth parameters. The value of @flags should be - * either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of values from - * VIR_DOMAIN_AFFECT_LIVE and VIR_DOMAIN_AFFECT_CURRENT, although + * either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of values + * VIR_DOMAIN_AFFECT_LIVE and VIR_DOMAIN_AFFECT_CONFIG, although * hypervisors vary in which flags are supported. * * This function may require privileged access to the hypervisor. diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1b147a9..b1d0b7f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7779,20 +7779,12 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, } } -if (VIR_ALLOC(bandwidth) 0) { +if ((VIR_ALLOC(bandwidth) 0) || +(VIR_ALLOC(bandwidth-in) 0) || +(VIR_ALLOC(bandwidth-out) 0)) { virReportOOMError(); goto cleanup; } -if (VIR_ALLOC(bandwidth-in) 0) { -virReportOOMError(); -goto cleanup; -} -memset(bandwidth-in, 0, sizeof(*bandwidth-in)); -if (VIR_ALLOC(bandwidth-out) 0) { -virReportOOMError(); -goto cleanup; -} -memset(bandwidth-out, 0, sizeof(*bandwidth-out)); for (i = 0; i nparams; i++) { virTypedParameterPtr param = params[i]; @@ -7817,11 +7809,9 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, * inbound/outbound to not be set. */ if (!bandwidth-in-average) { VIR_FREE(bandwidth-in); -bandwidth-in = NULL; } if (!bandwidth-out-average) { VIR_FREE(bandwidth-out); -bandwidth-out = NULL; } if (flags VIR_DOMAIN_AFFECT_LIVE) { @@ -7833,29 +7823,27 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, /* virNetDevBandwidthSet() will clear any previous value of * bandwidth parameters, so merge with old bandwidth parameters * here to prevent them from being lost. */ -if (bandwidth-in || net-bandwidth-in) { +if (bandwidth-in || +(net-bandwidth net-bandwidth-in)) { if (VIR_ALLOC(newBandwidth-in) 0) { virReportOOMError(); goto cleanup; } -if (bandwidth-in) -memcpy(newBandwidth-in, bandwidth-in, - sizeof(*newBandwidth-in)); -else if (net-bandwidth-in) -memcpy(newBandwidth-in, net-bandwidth-in, - sizeof(*newBandwidth-in)); -} -if (bandwidth-out || net-bandwidth-out) { + +memcpy(newBandwidth-in, + bandwidth-in ? bandwidth-in : net-bandwidth-in, + sizeof(*newBandwidth-in)); +} +if (bandwidth-out || +(net-bandwidth net-bandwidth-out)) { if (VIR_ALLOC(newBandwidth-out) 0) { virReportOOMError(); goto cleanup; } -if (bandwidth-out) -memcpy(newBandwidth-out, bandwidth-out, - sizeof(*newBandwidth-out)); -else if (net-bandwidth-out) -memcpy(newBandwidth-out, net-bandwidth-out, - sizeof(*newBandwidth-out)); + +memcpy(newBandwidth-out, + bandwidth-out ? bandwidth-out : net-bandwidth-out, + sizeof(*newBandwidth-out)); } if (virNetDevBandwidthSet(net-ifname, newBandwidth) 0) { -- 1.7.3.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] tests: virnettlscontexttest needs gnutls-2.6.0
Hello Eric, Am Montag 30 Januar 2012 20:10:57 schrieb Eric Blake: +#if !defined WIN32 HAVE_LIBTASN1_H !defined GNUTLS_1_0_COMPAT LIBGNUTLS_VERSION_NUMBER 0x020600 Isn't that what GNUTLS_1_0_COMPAT is already doing? That is, GNUTLS_1_0_COMPAT should only be defined if we are already dealing with a newer gnutls, and should not be present when using RHEL5 1.0.25. What version of gnutls are you using, where this patch made a difference? I'm trying to build libvirt-git on an older Debian-Lenny box. There running the check target fails: # make virnettlscontexttest gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I.. -I../gnulib/lib -I../gnulib/lib -I../include -I../include -I../src -I../src -I../src/util -I../src/conf -Dabs_builddir=\/root/libvirt/tests\ -I/usr/include/libxml2 -Wall -W -Wformat-y2k -Wformat-security -Winit-self -Wmissing-include-dirs -Wunused -Wunknown-pragmas -Wstrict-aliasing -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wwrite-strings -Wlogical-op -Waggregate-return -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls -Wnested-externs -Winline -Winvalid-pch -Wvolatile-register-var -Wdisabled-optimization -Wattributes -Wcoverage-mismatch -Wmultichar -Wdeprecated-declarations -Wdiv-by-zero -Wendif-labels -Wextra -Wformat-contains-nul -Wformat-extra-args -Wformat-zero-length -Wformat=2 -Wmultichar -Wnormalized=nfc -Woverflow -Wpointer-to-int-cast -Wpragmas -Wno-missing-field-initializers -Wno-sign-compare -Wno-format-nonliteral -fstack-protector-all --param=ssp-buffer-size=4 -fexceptions -fasynchronous-unwind-tables -fdiagnostics-show-option -funit-at-a-time -fipa-pure-const -Wno-suggest-attribute=pure -Wno-suggest-attribute=const -g -O2 -MT virnettlscontexttest-virnettlscontexttest.o -MD -MP -MF .deps/virnettlscontexttest-virnettlscontexttest.Tpo -c -o virnettlscontexttest-virnettlscontexttest.o `test -f 'virnettlscontexttest.c' || echo './'`virnettlscontexttest.c virnettlscontexttest.c: In function ‘testTLSGenerateCert’: virnettlscontexttest.c:207: warning: implicit declaration of function ‘gnutls_x509_crt_set_subject_alt_name’ virnettlscontexttest.c:207: warning: nested extern declaration of ‘gnutls_x509_crt_set_subject_alt_name’ [-Wnested-externs] virnettlscontexttest.c:210: error: ‘GNUTLS_FSAN_APPEND’ undeclared (first use in this function) virnettlscontexttest.c:210: error: (Each undeclared identifier is reported only once virnettlscontexttest.c:210: error: for each function it appears in.) # egrep '(LIB)?GNUTLS_VERSION_NUMBER|GNUTLS_1_0_COMPAT|GNUTLS_FSAN_APPEND' /usr/include/gnutls/* /usr/include/gnutls/gnutls.h:#define LIBGNUTLS_VERSION_NUMBER 0x020402 # dpkg -S /usr/include/gnutls/gnutls.h libgnutls-dev: /usr/include/gnutls/gnutls.h # dpkg -l libgnutls-dev ii libgnutls-dev 2.4.2-6.8.200910141301 the GNU TLS library - development files If you look at http://www.gnu.org/software/gnutls/manual/gnutls.html#gnutls_005fx509_005fcrt_005fset_005fsubject_005falt_005fname that function is described as available only since 2.6.0. From a newer Debian-Squeeze box for comparison: # egrep '(LIB)?GNUTLS_VERSION_NUMBER|GNUTLS_1_0_COMPAT|GNUTLS_FSAN_APPEND' /usr/include/gnutls/* /usr/include/gnutls/compat.h:#define LIBGNUTLS_VERSION_NUMBER GNUTLS_VERSION_NUMBER /usr/include/gnutls/gnutls.h:#define GNUTLS_VERSION_NUMBER 0x020806 /usr/include/gnutls/x509.h:#define GNUTLS_FSAN_APPEND 1 BYtE Philipp -- Philipp Hahn Open Source Software Engineer h...@univention.de Univention GmbHLinux for Your Businessfon: +49 421 22 232- 0 Mary-Somerville-Str.1 D-28359 Bremen fax: +49 421 22 232-99 http://www.univention.de/ signature.asc Description: This is a digitally signed message part. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [[libvirt-glib PATCHv3] 1/3] Add proper error reporting to gvir_storage_vol_get_path
gvir_storage_vol_get_name currently call g_error when an error occurs. Since g_error trigger a coredump, calling it in a library is harmful. Replace this with proper GError error reporting. --- libvirt-gobject/libvirt-gobject-storage-vol.c |7 +-- libvirt-gobject/libvirt-gobject-storage-vol.h |2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c index 5b18877..5e83e1b 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.c +++ b/libvirt-gobject/libvirt-gobject-storage-vol.c @@ -184,13 +184,16 @@ const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol) return name; } -const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol) +const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error) { GVirStorageVolPrivate *priv = vol-priv; const char *path; if (!(path = virStorageVolGetPath(priv-handle))) { -g_error(Failed to get storage_vol path on %p, priv-handle); +gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0, + Failed to get storage_vol path on %p, + priv-handle); +return NULL; } return path; diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.h b/libvirt-gobject/libvirt-gobject-storage-vol.h index db63865..25f683a 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.h +++ b/libvirt-gobject/libvirt-gobject-storage-vol.h @@ -78,7 +78,7 @@ GType gvir_storage_vol_info_get_type(void); GType gvir_storage_vol_handle_get_type(void); const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol); -const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol); +const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error); gboolean gvir_storage_vol_delete(GVirStorageVol *vol, guint flags, -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [[libvirt-glib PATCHv3] 3/3] Replace g_error with g_warning in constructors
g_error generates a fatal error message, meaning it will abort the currently running process. It's nicer to use g_warning here. --- libvirt-gobject/libvirt-gobject-domain.c |9 - libvirt-gobject/libvirt-gobject-network-filter.c |9 - libvirt-gobject/libvirt-gobject-network.c|9 - libvirt-gobject/libvirt-gobject-secret.c |8 +++- libvirt-gobject/libvirt-gobject-storage-pool.c |8 +++- 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c index 82da0c3..d9e4c00 100644 --- a/libvirt-gobject/libvirt-gobject-domain.c +++ b/libvirt-gobject/libvirt-gobject-domain.c @@ -134,7 +134,14 @@ static void gvir_domain_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virDomainGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get domain UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +if (verr) { +g_warning(Failed to get domain UUID on %p: %s, + priv-handle, verr-message); +} else { +g_warning(Failed to get domain UUID on %p, + priv-handle); +} } } diff --git a/libvirt-gobject/libvirt-gobject-network-filter.c b/libvirt-gobject/libvirt-gobject-network-filter.c index b1543a3..5956a3d 100644 --- a/libvirt-gobject/libvirt-gobject-network-filter.c +++ b/libvirt-gobject/libvirt-gobject-network-filter.c @@ -119,7 +119,14 @@ static void gvir_network_filter_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virNWFilterGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get network filter UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +if (verr) { +g_warning(Failed to get network filter UUID on %p: %s, + priv-handle, verr-message); +} else { +g_warning(Failed to get network filter UUID on %p, + priv-handle); +} } } diff --git a/libvirt-gobject/libvirt-gobject-network.c b/libvirt-gobject/libvirt-gobject-network.c index 8cbea07..16cd2f1 100644 --- a/libvirt-gobject/libvirt-gobject-network.c +++ b/libvirt-gobject/libvirt-gobject-network.c @@ -118,7 +118,14 @@ static void gvir_network_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virNetworkGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get network UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +if (verr) { +g_warning(Failed to get network UUID on %p: %s, + priv-handle, verr-message); +} else { +g_warning(Failed to get network UUID on %p, + priv-handle); +} } } diff --git a/libvirt-gobject/libvirt-gobject-secret.c b/libvirt-gobject/libvirt-gobject-secret.c index bc5ee3b..3c9da86 100644 --- a/libvirt-gobject/libvirt-gobject-secret.c +++ b/libvirt-gobject/libvirt-gobject-secret.c @@ -119,7 +119,13 @@ static void gvir_secret_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virSecretGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get secret UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +if (verr) { +g_warning(Failed to get secret UUID on %p: %s, + priv-handle, verr-message); +} else { +g_warning(Failed to get secret UUID on %p, priv-handle); +} } } diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.c b/libvirt-gobject/libvirt-gobject-storage-pool.c index aa71029..db496f3 100644 --- a/libvirt-gobject/libvirt-gobject-storage-pool.c +++ b/libvirt-gobject/libvirt-gobject-storage-pool.c @@ -129,7 +129,13 @@ static void gvir_storage_pool_constructed(GObject *object) /* xxx we may want to turn this into an initable */ if (virStoragePoolGetUUIDString(priv-handle, priv-uuid) 0) { -g_error(Failed to get storage pool UUID on %p, priv-handle); +virErrorPtr verr = virGetLastError(); +if (verr) { +g_warning(Failed to get storage pool UUID on %p: %s, + priv-handle, verr-message); +} else { +g_warning(Failed to get storage pool UUID on %p, priv-handle); +} } } -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [[libvirt-glib PATCHv3] 2/3] Don't use g_error in xxx_get_name
g_error will trigger an abort of the running process so it's not desirable to call it in a library. This commit uses g_warning when this occurs and returns NULL. libvirt will only return NULL for these strings if some kind of memory corruption is going on, or if we are using an invalid pointer. --- libvirt-gobject/libvirt-gobject-connection.c |6 ++ libvirt-gobject/libvirt-gobject-domain-snapshot.c |3 ++- libvirt-gobject/libvirt-gobject-domain.c |3 ++- libvirt-gobject/libvirt-gobject-interface.c |3 ++- libvirt-gobject/libvirt-gobject-network-filter.c |3 ++- libvirt-gobject/libvirt-gobject-network.c |3 ++- libvirt-gobject/libvirt-gobject-node-device.c |3 ++- libvirt-gobject/libvirt-gobject-storage-pool.c| 13 + libvirt-gobject/libvirt-gobject-storage-vol.c |3 ++- 9 files changed, 29 insertions(+), 11 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c index a90581a..cb19e9d 100644 --- a/libvirt-gobject/libvirt-gobject-connection.c +++ b/libvirt-gobject/libvirt-gobject-connection.c @@ -1114,6 +1114,9 @@ GVirDomain *gvir_connection_find_domain_by_name(GVirConnection *conn, GVirDomain *dom = value; const gchar *thisname = gvir_domain_get_name(dom); +if (thisname == NULL) +continue; + if (strcmp(thisname, name) == 0) { g_object_ref(dom); g_mutex_unlock(priv-lock); @@ -1145,6 +1148,9 @@ GVirStoragePool *gvir_connection_find_storage_pool_by_name(GVirConnection *conn, GVirStoragePool *pool = value; const gchar *thisname = gvir_storage_pool_get_name(pool); +if (thisname == NULL) +continue; + if (strcmp(thisname, name) == 0) { g_object_ref(pool); g_mutex_unlock(priv-lock); diff --git a/libvirt-gobject/libvirt-gobject-domain-snapshot.c b/libvirt-gobject/libvirt-gobject-domain-snapshot.c index 950555a..c386491 100644 --- a/libvirt-gobject/libvirt-gobject-domain-snapshot.c +++ b/libvirt-gobject/libvirt-gobject-domain-snapshot.c @@ -166,7 +166,8 @@ const gchar *gvir_domain_snapshot_get_name(GVirDomainSnapshot *snapshot) const char *name; if (!(name = virDomainSnapshotGetName(priv-handle))) { -g_error(Failed to get domain_snapshot name on %p, priv-handle); +g_warning(Failed to get domain_snapshot name on %p, priv-handle); +return NULL; } return name; diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c index c1a67a5..82da0c3 100644 --- a/libvirt-gobject/libvirt-gobject-domain.c +++ b/libvirt-gobject/libvirt-gobject-domain.c @@ -270,7 +270,8 @@ const gchar *gvir_domain_get_name(GVirDomain *dom) const char *name; if (!(name = virDomainGetName(priv-handle))) { -g_error(Failed to get domain name on %p, priv-handle); +g_warning(Failed to get domain name on %p, priv-handle); +return NULL; } return name; diff --git a/libvirt-gobject/libvirt-gobject-interface.c b/libvirt-gobject/libvirt-gobject-interface.c index f7bdde8..892db8b 100644 --- a/libvirt-gobject/libvirt-gobject-interface.c +++ b/libvirt-gobject/libvirt-gobject-interface.c @@ -163,7 +163,8 @@ const gchar *gvir_interface_get_name(GVirInterface *iface) const char *name; if (!(name = virInterfaceGetName(priv-handle))) { -g_error(Failed to get interface name on %p, priv-handle); +g_warning(Failed to get interface name on %p, priv-handle); +return NULL; } return name; diff --git a/libvirt-gobject/libvirt-gobject-network-filter.c b/libvirt-gobject/libvirt-gobject-network-filter.c index fe1a042..b1543a3 100644 --- a/libvirt-gobject/libvirt-gobject-network-filter.c +++ b/libvirt-gobject/libvirt-gobject-network-filter.c @@ -179,7 +179,8 @@ const gchar *gvir_network_filter_get_name(GVirNetworkFilter *filter) const char *name; if (!(name = virNWFilterGetName(priv-handle))) { -g_error(Failed to get network_filter name on %p, priv-handle); +g_warning(Failed to get network_filter name on %p, priv-handle); +return NULL; } return name; diff --git a/libvirt-gobject/libvirt-gobject-network.c b/libvirt-gobject/libvirt-gobject-network.c index 75e010d..8cbea07 100644 --- a/libvirt-gobject/libvirt-gobject-network.c +++ b/libvirt-gobject/libvirt-gobject-network.c @@ -177,7 +177,8 @@ const gchar *gvir_network_get_name(GVirNetwork *network) const char *name; if (!(name = virNetworkGetName(priv-handle))) { -g_error(Failed to get network name on %p, priv-handle); +g_warning(Failed to get network name on %p, priv-handle); +return NULL; } return name; diff --git a/libvirt-gobject/libvirt-gobject-node-device.c b/libvirt-gobject/libvirt-gobject-node-device.c index f8d536e..b565052 100644 ---
Re: [libvirt] RFC: setting mac address on network devices being assigned to a guest via PCI passthrough (hostdev)
On 1/31/12 1:16 AM, Laine Stump la...@laine.org wrote: On 01/30/2012 08:16 PM, Roopa Prabhu wrote: Laine, I haven't gone through your whole email yet. Was just curious about one quick thing, For sriov VF's, are we expecting that a net device (eth interface) be present on the host if its being used as a hostdev ?. Either should be possible. If the VF is bound to a net dev, it can be specified either with dev='ethxx' or using its pci address, and will be unbound before assigning to the guest. If it's not bound to a net dev, then a pci address must be used to describe it in the config. If yes, then libvirt will need to do an unbind of the driver on the VF before assigning it to the VM. Which today it does not do (correct me if I am wrong). That may have been the case in the past, but with libvirt-0.9.9 (the first version that I've tested with sriov and PCI passthrough - I'm a newbie to both), the net driver is unbound prior to assigning to the guest, and when the the device is detached from the guest, the net driver is once again bound to the device. Which is still ok. Just wanted to call that out. Plus ideally it would be nice to not have an expectation that a vf netdevice be present on the host. Because for sriov vf's, it would mean that the vf driver has to be loaded on the host. Which is really not required for vfs because mac and port profile can be set via the pf with the vf index as argument. Right. For sriov VFs, I intend that the MAC address will always be set via the PF. I hadn't previously thought through the details for non-sriov devices, but your event sequence list below made me realize that, at least for non-sriov, the MAC address and virtual port setup will need to be done *before* unbinding the driver (my intent, for sriov at least, was that this would happen *after* unbinding the driver). I guess that will take some experimentation. Anyway, at the moment I'm slogging around in the data structures. ok. Thanks Laine. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [[libvirt-glib PATCHv3] 1/3] Add proper error reporting to gvir_storage_vol_get_path
On Tue, Jan 31, 2012 at 03:34:09PM +0100, Christophe Fergeau wrote: gvir_storage_vol_get_name currently call g_error when an error occurs. Since g_error trigger a coredump, calling it in a library is harmful. Replace this with proper GError error reporting. --- libvirt-gobject/libvirt-gobject-storage-vol.c |7 +-- libvirt-gobject/libvirt-gobject-storage-vol.h |2 +- 2 files changed, 6 insertions(+), 3 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [[libvirt-glib PATCHv3] 2/3] Don't use g_error in xxx_get_name
On Tue, Jan 31, 2012 at 03:34:10PM +0100, Christophe Fergeau wrote: g_error will trigger an abort of the running process so it's not desirable to call it in a library. This commit uses g_warning when this occurs and returns NULL. libvirt will only return NULL for these strings if some kind of memory corruption is going on, or if we are using an invalid pointer. --- libvirt-gobject/libvirt-gobject-connection.c |6 ++ libvirt-gobject/libvirt-gobject-domain-snapshot.c |3 ++- libvirt-gobject/libvirt-gobject-domain.c |3 ++- libvirt-gobject/libvirt-gobject-interface.c |3 ++- libvirt-gobject/libvirt-gobject-network-filter.c |3 ++- libvirt-gobject/libvirt-gobject-network.c |3 ++- libvirt-gobject/libvirt-gobject-node-device.c |3 ++- libvirt-gobject/libvirt-gobject-storage-pool.c| 13 + libvirt-gobject/libvirt-gobject-storage-vol.c |3 ++- 9 files changed, 29 insertions(+), 11 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] tests: dynamically replace dnsmasq path
Hello Eric, Am Montag 30 Januar 2012 20:18:15 schrieb Eric Blake: +if (diff 0) { +tmp = realloc((void *)*buf, new_len); We should not be using realloc in this file, but should be using VIR_RESIZE_N or similar. Okay, makes the code even more readable. +memmove(token_start, replacement, replacement_len); But this would be more efficient as memcpy, since replacement (better not) overlap with token_start. I know of some projects which forbid memcpy() because of the missing overlap handling. But if this is okay with libvirt, I'll use it. I hope performance will never be a problem with this simple test scenario, because then doing one realloc() instead of one for each found would be better. +if (diff 0) { +tmp = realloc((void *)*buf, new_len); No need to downsize the allocation - it's okay to leave junk in the tail end of the buffer, as long as we have a trailing NUL to stop us in time. Fine with me for this simple test case, but if that would be generalized and be used in other places, this might become a problem. I'll add a comment. Sincerely Philipp -- Philipp Hahn Open Source Software Engineer h...@univention.de Univention GmbHLinux for Your Businessfon: +49 421 22 232- 0 Mary-Somerville-Str.1 D-28359 Bremen fax: +49 421 22 232-99 http://www.univention.de/ signature.asc Description: This is a digitally signed message part. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] tests: virnettlscontexttest needs gnutls-2.6.0
Hello, On Monday 30 January 2012 18:44:13 Philipp Hahn wrote: +#if !defined WIN32 HAVE_LIBTASN1_H !defined GNUTLS_1_0_COMPAT LIBGNUTLS_VERSION_NUMBER 0x020600 That should probably be = instead of , but I haven't checked the gnutls source code history. Sincerely Philipp -- Philipp Hahn Open Source Software Engineer h...@univention.de Univention GmbHLinux for Your Businessfon: +49 421 22 232- 0 Mary-Somerville-Str.1 D-28359 Bremen fax: +49 421 22 232-99 http://www.univention.de/ signature.asc Description: This is a digitally signed message part. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] virDomainNetGetActualBridgeName doesn't return the actual bridge
On 01/30/2012 08:15 AM, Hendrik Schwartke wrote: Hi, calling virDomainNetGetActualBridgeName on a bridge with type VIR_DOMAIN_NET_TYPE_NETWORK seems to return NULL in any case, because iface-data.network.actual is NULL. Is that intented? What is the best way to determine the bridge the interface is connected to? For the virtual network case, you could do it in a round about way by getting the network name from the domain interface block, then parsing the bridge name from the equivalent of virsh net-dumpxml netname But if we are providing an API like that it should probably work for virtual networks (but then again I don't know the specific use case that API was meant to address so it may be conceptually wrong). - Cole -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: Don't jump to endjob if no job was even started
In qemuDomainShutdownFlags if we try to use guest agent, which has error or is not configured, we jump go endjob label even if we haven't started any job yet. This may lead to the daemon crash: 1) virsh shutdown --mode agent on a domain without agent configured 2) wait until domain quits 3) virsh edit --- src/qemu/qemu_driver.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1b147a9..7945c5d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1546,12 +1546,12 @@ static int qemuDomainShutdownFlags(virDomainPtr dom, unsigned int flags) { if (priv-agentError) { qemuReportError(VIR_ERR_INTERNAL_ERROR, %s, _(QEMU guest agent is not available due to an error)); -goto endjob; +goto cleanup; } if (!priv-agent) { qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, _(QEMU guest agent is not configured)); -goto endjob; +goto cleanup; } } -- 1.7.3.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] RFC API proposal: virDomainBlockRebase
Right now, the existing virDomainBlockPull API has a tough limitation - it is an all-or-none approach. In all my examples below, I'm starting from the following relationship, where '-' means 'is a backing file of': template - intermediate - current virDomainBlockPull can only convert things in a forward direction, with the merge destination being the current image, resulting in: merge template and intermediate into current, creating: current Meanwhile, qemu is adding support for a partial block pull operation, still on the current image as the merge destination, but where you can now specify an optional argument to limit the pull to just the intermediate files and altering the current image to be backed by an ancestor file, as in: merge intermediate into current, creating: template - current For 0.9.10, I'd like to add the following API: /** * virDomainBlockRebase: * @dom: pointer to domain object * @disk: path to the block device, or device shorthand * @base: new base image, or NULL for entire block pull * @bandwidth: (optional) specify copy bandwidth limit in Mbps * @flags: extra flags; not used yet, so callers should always pass 0 * * Populate a disk image with data from its backing image chain, and * setting the new backing image to @base, where base is the absolute * path of one of the backing images in the chain. If @base is NULL, * then this operation is identical to virDomainBlockPull(). Once all * data from its backing image chain has been pulled, the disk no * longer depends on those intermediate backing images. This function * pulls data for the entire device in the background. Progress of the * operation can be checked with virDomainGetBlockJobInfo() and * the operation can be aborted with virDomainBlockJobAbort(). When * finished, an asynchronous event is raised to indicate the final * status. * * The @disk, @bandwidth, and @flags parameters are handled as in * virDomainBlockPull(). * * Returns 0 if the operation has started, -1 on failure. */ int virDomainBlockRebase(virDomainPtr dom, const char *disk, const char *base, unsigned long bandwidth, unsigned int flags); Given that Adam has a pending patch to support a VIR_DOMAIN_BLOCK_PULL_ASYNC flag, this same flag would have to be supported in virDomainBlockRebase. I've also been chatting with Federico Simoncelli about how the above operation would work for VDSM purposes in doing a live block move, while preserving a common template base file: start with: vda: template - current1 create a disk-only snapshot, with: tmpsnap = virDomainSnapshotCreateXML(dom, domainsnapshot\n disks\n disk name='vda'\n source/path/to/current2/source\n /disk\n disks\n /domainsnapshot, VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) where the xml calls out the destination file name, resulting in: vda: template - current1 - current2 perform the block rebase, with: virDomainBlockRebase(dom, vda, /path/to/template, VIR_DOMAIN_BLOCK_PULL_ASYNC) as well as waiting for the event (or polling status) to wait for completion, resulting in: vda: template - current2 delete the disk-only snapshot metadata as no longer useful, with: virDomainSnapshotDelete(tmpsnap, VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY) At one point, I thought of creating a single libvirt API that performs all of those steps in one call; but right now, I'm not proposing that, because of the fact that qemu has no way to undo a snapshot. In other words, without an undo operation, if the snapshot phase succeeds but the block rebase phase fails, a single API would have to report failure even though the domain was altered, while the ideal scenario is that reporting failure means things were in the same state as before the API started. Beyond 0.9.10, there are some additional useful merge patterns that might be worth exposing. All of these operations are already possible on offline images, using qemu-img; but none of them are possible on live images using current qemu, which is why I'm thinking it is something for another day. I'm also hoping to someday enhance the set of virStorageVol APIs to make backing file manipulation of offline images easier. At any rate, the addition merge operations are: forward live merge with a non-current image as the merge destination, as in: merge template into intermediate, creating: intermediate - current backward merge of a current image (that is, undoing a current snapshot): merge current into intermediate, creating: template - intermediate and backward merge of a non-current image (that is, undoing an earlier snapshot, but by modifying the template rather than the current image): merge intermediate into base, creating: template - current Backward merge of the current image seems like something easy to fit into my proposed API (add a new flag, maybe called VIR_DOMAIN_BLOCK_REBASE_BACKWARD). Manipulations of anything that does not involve the current image
[libvirt] [PATCH v2] tests: virnettlscontexttest needs gnutls-2.6.0
virnettlscontexttest uses gnutls_x509_crt_set_subject_alt_name() and GNUTLS_FSAN_APPEND, which - according to http://www.gnu.org/software/gnutls/manual/gnutls.html - are only available since 2.6.0. Since libvirt still works fine with gnutls-1.0.25 from RHEL5, only enable the test when the version of GNUTLS is at least 2.6.0. v2: greater-equal 2.6.0 instead of strictly greater. Signed-off-by: Philipp Hahn h...@univention.de --- tests/virnettlscontexttest.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c index 51f75b4..508617a 100644 --- a/tests/virnettlscontexttest.c +++ b/tests/virnettlscontexttest.c @@ -36,7 +36,7 @@ #include virsocketaddr.h #include gnutls_1_0_compat.h -#if !defined WIN32 HAVE_LIBTASN1_H !defined GNUTLS_1_0_COMPAT +#if !defined WIN32 HAVE_LIBTASN1_H !defined GNUTLS_1_0_COMPAT LIBGNUTLS_VERSION_NUMBER = 0x020600 # include libtasn1.h # include rpc/virnettlscontext.h -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2] tests: dynamically replace dnsmasq path
The path to the dnsmasq binary can be configured while in the test data the path is hard-coded to /usr/bin/. This break the test suite if a the binary is located in a different location, like /usr/local/sbin/. Replace the hard coded path in the test data by a token, which is dynamically replaced in networkxml2argvtest with the configured path after the test data has been loaded. (Another option would have been to modify configure.ac to generate the test data during configure, but I do not know of an easy way do trick configure into mass-generate those test files without listing every single one, which I consider less flexible.) v2: - Use VIR_REALLOC_N() instead of realloc() - Use memcpy() for replacement - Skip shrinking buffer - Add missing update of token_end - simplify code after the changes above - unit-test the unit-test: #include assert.h #define TEST(in,token,rep,out) { char *buf = strdup(in); assert(!replaceTokens(buf, token, rep) !strcmp(buf, out)); free(buf); } TEST(, AA, B, ); TEST(A, AA, B, A); TEST(AA, AA, B, B); TEST(AAA, AA, B, BA); TEST(AA, AA, BB, BB); TEST(AA, AA, BBB, BBB); TEST(AA, AA, B, B); TEST(AA, AA, BB, BB); TEST(AA, AA, BBB, BBB); TEST(AA, AA, B, B); TEST(AA, AA, BB, BB); TEST(AA, AA, BBB, BBB); TEST(AA, AA, B, B); TEST(AA, AA, BB, BB); TEST(AA, AA, BBB, BBB); TEST(AA|AA, AA, B, B|B); TEST(AA|AA, AA, BB, BB|BB); TEST(AA|AA, AA, BBB, BBB|BBB); TEST(, AA, B, BB); TEST(, AA, BB, ); TEST(, AA, BBB, BB); TEST(, AA, B, BB); TEST(, AA, BB, ); TEST(, AA, BBB, BB); TEST(, AA, B, BB); TEST(, AA, BB, ); TEST(, AA, BBB, BB); alarm(1); /* no infinit loop */ TEST(A, A, A, A); TEST(AA, A, A, AA); alarm(0); Signed-off-by: Philipp Hahn h...@univention.de --- tests/networkxml2argvdata/isolated-network.argv|2 +- .../networkxml2argvdata/nat-network-dns-hosts.argv |2 +- .../nat-network-dns-srv-record-minimal.argv|2 +- .../nat-network-dns-srv-record.argv|2 +- .../nat-network-dns-txt-record.argv|2 +- tests/networkxml2argvdata/nat-network.argv |2 +- tests/networkxml2argvdata/netboot-network.argv |2 +- .../networkxml2argvdata/netboot-proxy-network.argv |2 +- tests/networkxml2argvdata/routed-network.argv |2 +- tests/networkxml2argvtest.c| 33 10 files changed, 42 insertions(+), 9 deletions(-) diff --git a/tests/networkxml2argvdata/isolated-network.argv b/tests/networkxml2argvdata/isolated-network.argv index 7ea2e94..a9beb05 100644 --- a/tests/networkxml2argvdata/isolated-network.argv +++ b/tests/networkxml2argvdata/isolated-network.argv @@ -1,4 +1,4 @@ -/usr/sbin/dnsmasq --strict-order --bind-interfaces --conf-file= \ +@DNSMASQ@ --strict-order --bind-interfaces --conf-file= \ --except-interface lo --dhcp-option=3 --no-resolv \ --listen-address 192.168.152.1 \ --dhcp-range 192.168.152.2,192.168.152.254 \ diff --git a/tests/networkxml2argvdata/nat-network-dns-hosts.argv b/tests/networkxml2argvdata/nat-network-dns-hosts.argv index 2158df8..c7e4967 100644 --- a/tests/networkxml2argvdata/nat-network-dns-hosts.argv +++ b/tests/networkxml2argvdata/nat-network-dns-hosts.argv @@ -1,3 +1,3 @@ -/usr/sbin/dnsmasq --strict-order --bind-interfaces --domain example.com \ +@DNSMASQ@ --strict-order --bind-interfaces --domain example.com \ --conf-file= --except-interface lo --listen-address 192.168.122.1 \ --expand-hosts --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\ diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv index 021e8f0..ea1da6d 100644 --- a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv +++ b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv @@ -1,4 +1,4 @@ -/usr/sbin/dnsmasq \ +@DNSMASQ@ \ --strict-order \ --bind-interfaces \ --conf-file= \ diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv index 85afbba..84c2d2f 100644 --- a/tests/networkxml2argvdata/nat-network-dns-srv-record.argv +++ b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv @@ -1,4 +1,4 @@ -/usr/sbin/dnsmasq \ +@DNSMASQ@ \ --strict-order \ --bind-interfaces \ --conf-file= \ diff --git a/tests/networkxml2argvdata/nat-network-dns-txt-record.argv b/tests/networkxml2argvdata/nat-network-dns-txt-record.argv index be6ba4b..bed309f 100644 --- a/tests/networkxml2argvdata/nat-network-dns-txt-record.argv +++ b/tests/networkxml2argvdata/nat-network-dns-txt-record.argv @@ -1,4 +1,4 @@ -/usr/sbin/dnsmasq --strict-order --bind-interfaces --conf-file= \ +@DNSMASQ@ --strict-order --bind-interfaces --conf-file= \ --except-interface lo --txt-record=example,example value \ --listen-address 192.168.122.1 --listen-address 192.168.123.1 \
Re: [libvirt] virDomainNetGetActualBridgeName doesn't return the actual bridge
On 01/30/2012 08:15 AM, Hendrik Schwartke wrote: Hi, calling virDomainNetGetActualBridgeName on a bridge with type VIR_DOMAIN_NET_TYPE_NETWORK seems to return NULL in any case, because iface-data.network.actual is NULL. Is that intented? Yes, that's how it was intended to work. It has a very narrow purpose, only to be used for interfaces that end up being connected to host bridges not managed by libvirt (i.e., either the interface type is VIR_DOMAIN_NET_TYPE_BRIDGE, or the type is NETWORK, and the network has forward mode='bridge'). It's an internal API, so that purpose could change, but I would need to look and see if that would have any adverse side effect. What is the best way to determine the bridge the interface is connected to? I'm guessing you're writing the packet sniffing code you asked about the other day. Do you really want the bridge device that the guest is connecting to? I think the device you actually want to watch is the tap device that connects the guest to the bridge. That is in net-ifname (net being the virDomainNetDef containing the configuration for the interface); qemu uses that value directly when setting up the guests' interfaces. If you really do need to get the device that the guest tap is connected to (which might be a bridge, or might be a physical ethernet, or might be ???), where that is depends on the type of interface: 1) for interface actualType=VIR_DOMAIN_NET_TYPE_NETWORK, currently you would need to call the public API virNetworkGetBridgeName (that requires you to first call virNetworkLookupByName). 2) for interface actualType=VIR_DOMAIN_NET_TYPE_DIRECT you would want to call virDomainNetGetActualDirectDev() - this gives you a physical interface which the guest connects to in one of the mavctap modes. 3) for interface actualType=VIR_DOMAIN_NET_TYPE_BRIDGE you would call virDomainNetGetActualBridgeName(). Note that in all cases, I'm talking about using the result of virDomainNetGetActualType(net), *not* just looking at net-type. (the latter is what's in the config, the former is what is figured out at runtime based on the config). (Still, I'm guessing what you really want is just net-ifname). -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] virDomainNetGetActualBridgeName doesn't return the actual bridge
On 01/31/2012 11:55 AM, Laine Stump wrote: On 01/30/2012 08:15 AM, Hendrik Schwartke wrote: Hi, calling virDomainNetGetActualBridgeName on a bridge with type VIR_DOMAIN_NET_TYPE_NETWORK seems to return NULL in any case, because iface-data.network.actual is NULL. Is that intented? Yes, that's how it was intended to work. It has a very narrow purpose, only to be used for interfaces that end up being connected to host bridges not managed by libvirt (i.e., either the interface type is VIR_DOMAIN_NET_TYPE_BRIDGE, or the type is NETWORK, and the network has forward mode='bridge'). It's an internal API, so that purpose could change, but I would need to look and see if that would have any adverse side effect. What is the best way to determine the bridge the interface is connected to? I'm guessing you're writing the packet sniffing code you asked about the other day. Do you really want the bridge device that the guest is connecting to? Heh. I just made the connection that you were also doing a patch to hot-switch the bridge that a guest is connected to, so you actually *do* want the bridge (as well as the tap device). In that case, the 2nd part of my earlier response applies. I think the device you actually want to watch is the tap device that connects the guest to the bridge. That is in net-ifname (net being the virDomainNetDef containing the configuration for the interface); qemu uses that value directly when setting up the guests' interfaces. If you really do need to get the device that the guest tap is connected to (which might be a bridge, or might be a physical ethernet, or might be ???), where that is depends on the type of interface: 1) for interface actualType=VIR_DOMAIN_NET_TYPE_NETWORK, currently you would need to call the public API virNetworkGetBridgeName (that requires you to first call virNetworkLookupByName). 2) for interface actualType=VIR_DOMAIN_NET_TYPE_DIRECT you would want to call virDomainNetGetActualDirectDev() - this gives you a physical interface which the guest connects to in one of the mavctap modes. 3) for interface actualType=VIR_DOMAIN_NET_TYPE_BRIDGE you would call virDomainNetGetActualBridgeName(). Note that in all cases, I'm talking about using the result of virDomainNetGetActualType(net), *not* just looking at net-type. (the latter is what's in the config, the former is what is figured out at runtime based on the config). (Still, I'm guessing what you really want is just net-ifname). -- 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] qemu: Don't jump to endjob if no job was even started
On 01/31/2012 11:16 AM, Michal Privoznik wrote: In qemuDomainShutdownFlags if we try to use guest agent, which has error or is not configured, we jump go endjob label even if we haven't started any job yet. This may lead to the daemon crash: 1) virsh shutdown --mode agent on a domain without agent configured 2) wait until domain quits 3) virsh edit ACK. --- src/qemu/qemu_driver.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1b147a9..7945c5d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1546,12 +1546,12 @@ static int qemuDomainShutdownFlags(virDomainPtr dom, unsigned int flags) { if (priv-agentError) { qemuReportError(VIR_ERR_INTERNAL_ERROR, %s, _(QEMU guest agent is not available due to an error)); -goto endjob; +goto cleanup; } if (!priv-agent) { qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, _(QEMU guest agent is not configured)); -goto endjob; +goto cleanup; } } -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 4/4] qemu: make qemu processes to retain rawio capability
On 01/31/2012 07:04 AM, Daniel P. Berrange wrote: On Tue, Jan 31, 2012 at 01:52:27PM +0900, Taku Izumi wrote: This patch revises qemuProcessStart() function for qemu processes to retain CAP_SYS_RAWIO if needed. And in case of that, add taint flag to domain. ACK Pushed. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/4] util: add functions to keep capabilities
On 01/31/2012 07:03 AM, Daniel P. Berrange wrote: ACK Pushed. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 3/4] util: extend virExecWithHook()
On 01/31/2012 07:04 AM, Daniel P. Berrange wrote: On Tue, Jan 31, 2012 at 01:51:22PM +0900, Taku Izumi wrote: This patch extends virExecWithHook() to receive capability information. ACK Pushed. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/4] conf: add rawio attribute to disk element of domain XML
On 01/31/2012 07:03 AM, Daniel P. Berrange wrote: On Tue, Jan 31, 2012 at 01:49:11PM +0900, Taku Izumi wrote: @@ -3156,6 +3159,26 @@ virDomainDiskDefParseXML(virCapsPtr caps def-snapshot = VIR_DOMAIN_DISK_SNAPSHOT_NO; } +def-rawio = -1; /* unspecified */ +if (rawio) { +if (def-device == VIR_DOMAIN_DISK_DEVICE_LUN) { +if (STREQ(rawio, yes)) { +def-rawio = 1; +} else if (STREQ(rawio, no)) { +def-rawio = 0; +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _(unknown disk rawio setting '%s'), + rawio); +goto error; +} +} else { +virDomainReportError(VIR_ERR_INTERNAL_ERROR, %s, +_(rawio can be used only with device='lun')); s/INTERNAL_ERROR/XML_ERROR/ ACK with that change I've pushed this patch with that, and some other, changes (see attached diff for all changes aside from what you pointed out - I managed to squash that in before I thought to save a diff). Just now I realize I had misinterpreted your comment as being only about the first of those two messages (my brain stopped looking at the email as soon as I hit the first one - you should have done s/.../.../g :-), but when I looked at the file I saw the 2nd, I decided it should be VIR_ERR_CONFIG_UNSUPPORTED. Should I push a change to XML_ERROR, or leave it as is? (I *still* get confused about which is more appropriate where, but this one is in kind of a gray area.) I also found that make check wouldn't pass, which was mostly traced to the concept of making the default value of rawio -1. The problem with this is that there are other functions that create and fill-in domain structures, and they hadn't been taught about this default value. I changed the object to have a bool rawio_specified, and modified the parse and format functions accordingly. Also there was no test that exercised the rawio attribute - I added that into the virtio-lun test. (and just now, I realize that I forgot to add a blurb in the docs. I'll do that when I'm done with these emails) Also change default of rawio from -1 to 0, and add rawio_specified bool to the object to differentiate between being unset, and setting it explicitly to 0. Prior to this, it would fail make check. --- src/conf/domain_conf.c | 12 +++- src/conf/domain_conf.h |3 ++- .../qemuxml2argvdata/qemuxml2argv-virtio-lun.args |6 +++--- tests/qemuxml2argvdata/qemuxml2argv-virtio-lun.xml | 13 ++--- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 4f13ac2..35cb7a4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3159,8 +3159,8 @@ virDomainDiskDefParseXML(virCapsPtr caps, def-snapshot = VIR_DOMAIN_DISK_SNAPSHOT_NO; } -def-rawio = -1; /* unspecified */ if (rawio) { +def-rawio_specified = true; if (def-device == VIR_DOMAIN_DISK_DEVICE_LUN) { if (STREQ(rawio, yes)) { def-rawio = 1; @@ -9995,10 +9995,12 @@ virDomainDiskDefFormat(virBufferPtr buf, virBufferAsprintf(buf, disk type='%s' device='%s', type, device); -if (def-rawio == 1) { -virBufferAddLit(buf, rawio='yes'); -} else if (def-rawio == 0) { -virBufferAddLit(buf, rawio='no'); +if (def-rawio_specified) { +if (def-rawio == 1) { +virBufferAddLit(buf, rawio='yes'); +} else if (def-rawio == 0) { +virBufferAddLit(buf, rawio='no'); +} } if (def-snapshot !(def-snapshot == VIR_DOMAIN_DISK_SNAPSHOT_NO def-readonly)) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index b01f0b1..503684f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -413,7 +413,8 @@ struct _virDomainDiskDef { unsigned int transient : 1; virDomainDeviceInfo info; virStorageEncryptionPtr encryption; -int rawio; /* unspecified = -1, no = 0, yes = 1 */ +bool rawio_specified; +int rawio; /* no = 0, yes = 1 */ }; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-lun.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-lun.args index 5df9182..b229f2a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-lun.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-lun.args @@ -4,8 +4,8 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -boot dc -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 \ -drive file=/dev/sdfake,if=none,id=drive-virtio-disk0 \ -device virtio-blk-pci,scsi=on,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0 \ --drive
Re: [libvirt] [PATCH] Xen: Fix clock handling
Hello Daniel, On Tuesday 17 January 2012 22:24:11 Daniel P. Berrange wrote: On Tue, Jan 17, 2012 at 05:02:14PM +0100, Philipp Hahn wrote: For PV, Xen implements the clock offset='utc' and clock offset='localtime' behaviour, while for HV it implements clock offset='variable'. This difference is important for domUs, which switch daylight saving on there own, since the state is kept inside the VM and must be in sync with the RTC provided by Xen. What versions of Xen is that true for ? I didn't think that old versions behaved this way for HVM. The libvirt Xen driver is still intended to support the RHEL5 vintage Xen code (which is based on 3.0.3) To me it looks like CentOS5 (since I don't have RHEL5) has the Xen-3.0.3 user-land XenD (rpm -q xen → xen-3.0.3-132.el5) but the Xen-3.1.2 hypervisor (xm info → 3.1.2-.2-274.el5). Relevant for this change seems only the version of XenD, which returns xendConfigVersion=2. This is a version without managed domain support, which was added in the 3.1.x branch http://xenbits.xen.org/hg/xen-3.1-testing.hg/rev/7e431ea834a8. The generation bump to xendConfig_version=3 happend in 3.0.4 for Live Cycle support http://xenbits.xen.org/hg/xen-3.0.4-testing.hg/rev/1c51c580dc05. The bump to 4 was in the 3.0.5 → 3.1.0 transition http://xenbits.xen.org/hg/xen-3.1-testing.hg/rev/887fa548f650 So for XenD version _ its _: - 3.1: utc or localtime (because there is no XenD keeping track of the modified rtc_timeoffset) - = 3.1: managed HV domains: variable (XenD keeps track) - = 3.1: managed PV domains: utc or localtime (they don't have a RTC but can access a PV-clock, which gets initialized to either utc or localtime. As far as I know the offset can't be changed by the domU and is not visible in any tool, only the is_utc/localtime flag is visible) - = 3.1: xm domains: same as with managed domains. The variable offset is tracked by XenD and survives a reboot, but as with other transient domains, the information is lost after destroy. Patch will (hopefully) follow soon. Sincerely Philipp -- Philipp Hahn Open Source Software Engineer h...@univention.de Univention GmbHLinux for Your Businessfon: +49 421 22 232- 0 Mary-Somerville-Str.1 D-28359 Bremen fax: +49 421 22 232-99 http://www.univention.de/ signature.asc Description: This is a digitally signed message part. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] xen_xs: name xendConfigVersion magic numbers
libvirt supports 4 different versions of the user-land XenD daemon. When queried the daemon just returns its generation number, which is hard to match to the version of the Xen tools. Replace the magic generation numbers by named macro definitions to improve code readability. Signed-off-by: Philipp Hahn h...@univention.de --- .../0013-improve-getting-xen-vcpu-counts.patch |2 +- .../0014-improve-setting-xen-vcpu-counts.patch |6 +- docs/api_extension/0015-remove-dead-xen-code.patch |2 +- src/xen/xen_driver.c | 14 ++-- src/xen/xend_internal.c| 70 ++-- src/xenxs/xen_sxpr.c | 24 src/xenxs/xen_sxpr.h |5 ++ src/xenxs/xen_xm.c | 14 ++-- src/xenxs/xenxs_private.h |7 +- 9 files changed, 75 insertions(+), 69 deletions(-) diff --git a/docs/api_extension/0013-improve-getting-xen-vcpu-counts.patch b/docs/api_extension/0013-improve-getting-xen-vcpu-counts.patch index 047bc7b..c1aad03 100644 --- a/docs/api_extension/0013-improve-getting-xen-vcpu-counts.patch +++ b/docs/api_extension/0013-improve-getting-xen-vcpu-counts.patch @@ -100,7 +100,7 @@ index dfc6415..3642296 100644 +/* If xendConfigVersion is 2, then we can only report _LIVE (and + * xm_internal reports _CONFIG). If it is 3, then _LIVE and + * _CONFIG are always in sync for a running system. */ -+if (domain-id 0 priv-xendConfigVersion 3) ++if (domain-id 0 priv-xendConfigVersion XEND_CONFIG_VERSION_3_0_4) +return -2; +if (domain-id 0 (flags VIR_DOMAIN_VCPU_LIVE)) { +virXendError(VIR_ERR_OPERATION_INVALID, %s, diff --git a/docs/api_extension/0014-improve-setting-xen-vcpu-counts.patch b/docs/api_extension/0014-improve-setting-xen-vcpu-counts.patch index 76dc948..3adbd75 100644 --- a/docs/api_extension/0014-improve-setting-xen-vcpu-counts.patch +++ b/docs/api_extension/0014-improve-setting-xen-vcpu-counts.patch @@ -110,7 +110,7 @@ index fe2ff86..66e8518 100644 + * depends on xendConfigVersion. */ +if (dom) { +priv = dom-conn-privateData; -+if (priv-xendConfigVersion = 3) ++if (priv-xendConfigVersion = XEND_CONFIG_VERSION_3_0_4) +flags |= VIR_DOMAIN_VCPU_CONFIG; +} +return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, flags); @@ -163,14 +163,14 @@ index 3642296..55c2cc4 100644 + +priv = (xenUnifiedPrivatePtr) domain-conn-privateData; + -+if ((domain-id 0 priv-xendConfigVersion 3) || ++if ((domain-id 0 priv-xendConfigVersion XEND_CONFIG_VERSION_3_0_4) || +(flags VIR_DOMAIN_VCPU_MAXIMUM)) +return -2; + +/* With xendConfigVersion 2, only _LIVE is supported. With + * xendConfigVersion 3, only _LIVE|_CONFIG is supported for + * running domains, or _CONFIG for inactive domains. */ -+if (priv-xendConfigVersion 3) { ++if (priv-xendConfigVersion XEND_CONFIG_VERSION_3_0_4) { +if (flags VIR_DOMAIN_VCPU_CONFIG) { +virXendError(VIR_ERR_OPERATION_INVALID, %s, + _(Xend version does not support modifying diff --git a/docs/api_extension/0015-remove-dead-xen-code.patch b/docs/api_extension/0015-remove-dead-xen-code.patch index 56b99a3..64e0d98 100644 --- a/docs/api_extension/0015-remove-dead-xen-code.patch +++ b/docs/api_extension/0015-remove-dead-xen-code.patch @@ -122,7 +122,7 @@ index 55c2cc4..b90c331 100644 - -priv = (xenUnifiedPrivatePtr) domain-conn-privateData; - --if (domain-id 0 priv-xendConfigVersion 3) +-if (domain-id 0 priv-xendConfigVersion XEND_CONFIG_VERSION_3_0_4) -return(-1); - -snprintf(buf, sizeof(buf), %d, vcpus); diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 12d7eb0..94cafde 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -354,7 +354,7 @@ xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags) /* XenD is active, so try the xm xs drivers too, both requird to * succeed if root, optional otherwise */ -if (priv-xendConfigVersion = 2) { +if (priv-xendConfigVersion = XEND_CONFIG_VERSION_3_0_3) { VIR_DEBUG(Trying XM sub-driver); if (xenXMOpen(conn, auth, flags) == VIR_DRV_OPEN_SUCCESS) { VIR_DEBUG(Activated XM sub-driver); @@ -1161,7 +1161,7 @@ xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus) * depends on xendConfigVersion. */ if (dom) { priv = dom-conn-privateData; -if (priv-xendConfigVersion = 3) +if (priv-xendConfigVersion = XEND_CONFIG_VERSION_3_0_4) flags |= VIR_DOMAIN_VCPU_CONFIG; } return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, flags); @@ -1239,7 +1239,7 @@ xenUnifiedDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
Re: [libvirt] [RFC Incomplete Patch] Libvirt + Openvswitch
On Jan 31, 2012, at 6:01 AM, Daniel P. Berrange wrote: On Mon, Jan 30, 2012 at 02:49:03PM -0600, kmestery wrote: On Jan 30, 2012, at 2:41 PM, Dan Wendlandt wrote: Hi Kyle! Funny how we keep bumping into each other... I hope you're keeping warm in Minnesota :) On Fri, Jan 27, 2012 at 11:22 AM, kmestery kmest...@cisco.com wrote: Hi Dan: We at Cisco have been looking at this as well, and in fact were going to propose some things in this area as well. Our proposal (which frankly just builds on top of what you have): I agree, I think the two proposals are complementary. Our first goal was to enable the basic mode of plugging an interface into an OVS bridge that was created outside of libvirt. This would require changes to the interface XML only, and would mirror how libvirt already let's one plug into an existing bridge using interface type=bridge. This makes sense. The second step would be to also allow libvirt to actually create + configure the OVS bridges as well. This I believe would map very closely to the XML you and Roopa have suggested. We would need to put some thought into what of the many configuration options on an OVS bridge need to be exposed as part of the OVS network XML (e.g., how to configure an OpenFlow controller, etc.). These are definitely discussions worth having, but I was hoping to start out with a fairly clean initial patch to achieve our first goal. OK, this makes sense too. I do like the idea of using the virtual port construct even in the initial interface only case. For example: interface type='bridge' bridge name='br0' virtualport type=openvswitch parameters interfaceid='xyzzy'/ /virtualport /interface This would seem to create a nice parallel with the model you proposed where virtualport is used with interface type=network. I'm still not sure whether the type=openvswitch should be an attribute of the interface, bridge, or virtualport element. Either way, I think the underlying code will be treating OVS + Linux Bridge as two different cases, so I believe this is really just a matter of consistently of presentation in XML. Yes, I prefer this design to the initial proposal. I think fundamentally an Open vSwitch bridge is different from a standard Linux, thus the type=openvswitch needs to be a part of the bridge for sure. I like adding it to the virtualport element above. NB, type='bridge' technically refers to the *concept* of bridging an interface to a LAN, not the implemntation of Linux software bridging. Thus it shouldn't change for OpenVSwitch which is also providing bridging to the LAN here. Regards, Daniel Dan and I working together to modify the patches in this direction. We'll send them out for review once we have them formatted and tested. Thanks, Kyle -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 1/5] virDomainGetDiskErrors public API
We already provide ways to detect when a domain has been paused as a result of I/O error, but there was no way of getting the exact error or even the device that experienced it. This new API may be used for both. --- include/libvirt/libvirt.h.in | 32 python/generator.py |3 +- src/driver.h |7 src/libvirt.c| 65 ++ src/libvirt_public.syms |1 + 5 files changed, 107 insertions(+), 1 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index d9b9b95..cf53cf2 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1967,6 +1967,38 @@ virDomainGetBlockIoTune(virDomainPtr dom, int *nparams, unsigned int flags); +/** + * virDomainDiskErrorCode: + * + * Disk I/O error. + */ +typedef enum { +VIR_DOMAIN_DISK_ERROR_NONE = 0, /* no error */ +VIR_DOMAIN_DISK_ERROR_UNSPEC= 1, /* unspecified I/O error */ +VIR_DOMAIN_DISK_ERROR_NO_SPACE = 2, /* no space left on the device */ + +#ifdef VIR_ENUM_SENTINELS +VIR_DOMAIN_DISK_ERROR_LAST +#endif +} virDomainDiskErrorCode; + +/** + * virDomainDiskError: + * + */ +typedef struct _virDomainDiskError virDomainDiskError; +typedef virDomainDiskError *virDomainDiskErrorPtr; + +struct _virDomainDiskError { +char *disk; /* disk target */ +int error; /* virDomainDiskErrorCode */ +}; + +int virDomainGetDiskErrors(virDomainPtr dom, + virDomainDiskErrorPtr errors, + unsigned int maxerrors, + unsigned int flags); + /* * NUMA support diff --git a/python/generator.py b/python/generator.py index 6f813ae..b514af5 100755 --- a/python/generator.py +++ b/python/generator.py @@ -423,7 +423,8 @@ skip_impl = ( 'virDomainGetBlockIoTune', 'virDomainSetInterfaceParameters', 'virDomainGetInterfaceParameters', -'virDomainGetCPUStats' # not implemented now. +'virDomainGetCPUStats', # not implemented now. +'virDomainGetDiskErrors', ) qemu_skip_impl = ( diff --git a/src/driver.h b/src/driver.h index 2e2042e..9ff5edf 100644 --- a/src/driver.h +++ b/src/driver.h @@ -810,6 +810,12 @@ typedef int unsigned int ncpus, unsigned int flags); +typedef int +(*virDrvDomainGetDiskErrors)(virDomainPtr dom, + virDomainDiskErrorPtr errors, + unsigned int maxerrors, + unsigned int flags); + /** * _virDriver: * @@ -981,6 +987,7 @@ struct _virDriver { virDrvDomainSetBlockIoTune domainSetBlockIoTune; virDrvDomainGetBlockIoTune domainGetBlockIoTune; virDrvDomainGetCPUStats domainGetCPUStats; +virDrvDomainGetDiskErrors domainGetDiskErrors; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index c609202..e84447e 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -18282,3 +18282,68 @@ error: virDispatchError(domain-conn); return -1; } + +/** + * virDomainGetDiskErrors: + * @dom: a domain object + * @errors: array to populate on output + * @maxerrors: size of @errors array + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * The function populates @errors array with all disks that encountered an + * I/O error. Disks with no error will not be returned in the @errors array. + * Each disk is identified by its target (the dev attribute of target + * subelement in domain XML), such as vda, and accompanied with the error + * that was seen on it. The caller is also responsible for calling free() + * on each disk name returned. + * + * In a special case when @errors is NULL and @maxerrors is 0, the function + * returns preferred size of @errors that the caller should use to get all + * disk errors. + * + * Since calling virDomainGetDiskErrors(dom, NULL, 0, 0) to get preferred size + * of @errors array and getting the errors are two separate operations, new + * disks may be hotplugged to the domain and new errors may be encountered + * between the two calls. Thus, this function may not return all disk errors + * because the supplied array is not large enough. Such errors may, however, + * be detected by listening to domain events. + * + * Returns number of disks with errors filled in the @errors array or -1 on + * error. + */ +int +virDomainGetDiskErrors(virDomainPtr dom, + virDomainDiskErrorPtr errors, + unsigned int maxerrors, + unsigned int flags) +{ +VIR_DOMAIN_DEBUG(dom, errors=%p, maxerrors=%u, flags=%x, + errors, maxerrors, flags); + +virResetLastError(); + +if (!VIR_IS_DOMAIN(dom)) { +virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); +virDispatchError(NULL); +return -1; +} + +
Re: [libvirt] [RFC Incomplete Patch] Libvirt + Openvswitch
On 01/31/2012 06:57 AM, Daniel P. Berrange wrote: On Fri, Jan 27, 2012 at 02:58:58AM -0800, Dan Wendlandt wrote: Hello all, I know of many people who want to spin up VMs using libvirt + kvm/qemu and attach those VMs to an openvswitch bridge (see: http://www.openvswitch.org). However, the only way I know of to get this working is a kludge that uses to tap devices along withinterface type=ethernet while running ovs-vsctl outside of libvirt. Even worse, doing this on RHEL/Fedora seems to require privilege tweaks (e.g., running qemu as root, not dropping capabilities), which may not be acceptable for production deployments (see: http://fedoraproject.org/wiki/How_to_debug_Virtualization_problems#Errors_using_.3Cinterface_type.3D.27ethernet.27.2F.3E). So I would like to start taking steps toward better libvirt/openvswitch integration. My initial step has the fairly limit goal of enabling kvm/qemu VM NICs to attach to an openvswitch bridge in much the same way VM NIC can already attached to the linux bridge. For example, specifying: interface type=openvswitch source bridge=br0/ mac address=ca:fe:de;ad:be:ef/ /interface IMHO we should not be introducing a new type for OpenVSwitch. Contrary to common understanding, type='bridge' is not referring explicitly to Linux software bridging. Rather it refers to the concept of bridging the guest to the LAN at the network level, of which Linux software briding is one possible impl. OpenVSwitch is another possible impl. Other hypervisors have different impls too of course. If OpenVSwitch is available in the kernel, is there really any reason to *not* use it ? ie, could we just have interface type=bridge source bridge=br0/ mac address=ca:fe:de;ad:be:ef/ /interface and if we see that 'br0' is using OpenVSwitch, then libvirt can know to just do the right thing. Of course! facepalm/ If the code can tell that br0 is an openvswitch bridge rather than a linux host bridge, we don't even have to add type='openvswitch' to the source element! I definitely like this the best, too. That way every application that uses libvirt today will automatically be able to take advantage of the benefits OpenVSwitch brings without further work Except that an interfaceid is needed (or is that optional?) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 2/5] Remote protocol for virDomainGetDiskErrors
--- daemon/remote.c | 103 ++ src/remote/remote_driver.c | 77 +++ src/remote/remote_protocol.x | 23 +- src/remote_protocol-structs | 17 +++ 4 files changed, 219 insertions(+), 1 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index cb8423a..3d7021a 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -98,6 +98,12 @@ remoteDeserializeTypedParameters(remote_typed_param *args_params_val, int limit, int *nparams); +static int +remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors, +int nerrors, +remote_domain_disk_error **ret_errors_val, +u_int *ret_errors_len); + #include remote_dispatch.h #include qemu_dispatch.h @@ -3595,6 +3601,69 @@ cleanup: return rv; } +static int remoteDispatchDomainGetDiskErrors( +virNetServerPtr server ATTRIBUTE_UNUSED, +virNetServerClientPtr client, +virNetMessagePtr msg ATTRIBUTE_UNUSED, +virNetMessageErrorPtr rerr, +remote_domain_get_disk_errors_args *args, +remote_domain_get_disk_errors_ret *ret) +{ +int rv = -1; +virDomainPtr dom = NULL; +virDomainDiskErrorPtr errors = NULL; +int len; +struct daemonClientPrivate *priv = +virNetServerClientGetPrivateData(client); + +if (!priv-conn) { +virNetError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open)); +goto cleanup; +} + +if (!(dom = get_nonnull_domain(priv-conn, args-dom))) +goto cleanup; + +if (args-maxerrors REMOTE_DOMAIN_DISK_ERRORS_MAX) { +virNetError(VIR_ERR_INTERNAL_ERROR, %s, +_(maxerrors too large)); +goto cleanup; +} + +if (args-maxerrors +VIR_ALLOC_N(errors, args-maxerrors) 0) { +virReportOOMError(); +goto cleanup; +} + +if ((len = virDomainGetDiskErrors(dom, errors, + args-maxerrors, + args-flags)) 0) +goto cleanup; + +ret-nerrors = len; +if (errors +remoteSerializeDomainDiskErrors(errors, len, +ret-errors.errors_val, +ret-errors.errors_len) 0) +goto cleanup; + +rv = 0; + +cleanup: +if (rv 0) +virNetMessageSaveError(rerr); +if (dom) +virDomainFree(dom); +if (errors) { +int i; +for (i = 0; i len; i++) +VIR_FREE(errors[i].disk); +} +VIR_FREE(errors); +return rv; +} + /*- Helpers. -*/ /* get_nonnull_domain and get_nonnull_network turn an on-wire @@ -3725,3 +3794,37 @@ make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDo snapshot_dst-name = strdup(snapshot_src-name); make_nonnull_domain(snapshot_dst-dom, snapshot_src-domain); } + +static int +remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors, +int nerrors, +remote_domain_disk_error **ret_errors_val, +u_int *ret_errors_len) +{ +remote_domain_disk_error *val = NULL; +int i = 0; + +if (VIR_ALLOC_N(val, nerrors) 0) +goto no_memory; + +for (i = 0; i nerrors; i++) { +if (!(val[i].disk = strdup(errors[i].disk))) +goto no_memory; +val[i].error = errors[i].error; +} + +*ret_errors_len = nerrors; +*ret_errors_val = val; + +return 0; + +no_memory: +if (val) { +int j; +for (j = 0; j i; j++) +VIR_FREE(val[j].disk); +VIR_FREE(val); +} +virReportOOMError(); +return -1; +} diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 61b96e9..9c3dbab 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -1427,6 +1427,39 @@ cleanup: } static int +remoteDeserializeDomainDiskErrors(remote_domain_disk_error *ret_errors_val, + u_int ret_errors_len, + int limit, + virDomainDiskErrorPtr errors, + int maxerrors) +{ +int i = 0; +int j; + +if (ret_errors_len limit || ret_errors_len maxerrors) { +remoteError(VIR_ERR_RPC, %s, +_(returned number of disk errors exceeds limit)); +goto error; +} + +for (i = 0; i ret_errors_len; i++) { +if (!(errors[i].disk = strdup(ret_errors_val[i].disk))) { +virReportOOMError(); +goto error; +} +errors[i].error = ret_errors_val[i].error; +} + +return 0; + +error: +for (j = 0; j i; j++) +VIR_FREE(errors[i].disk); + +return -1; +} + +static int
[libvirt] [PATCH v3 5/5] python: Add binding for virDomainGetDiskErrors
--- python/libvirt-override-api.xml |6 python/libvirt-override.c | 50 +++ 2 files changed, 56 insertions(+), 0 deletions(-) diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index 704fee9..b2b8152 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -421,5 +421,11 @@ arg name='flags' type='unsigned int' info='an ORapos;ed set of virDomainMemoryFlags'/ return type='char *' info='the returned buffer or None in case of error'/ /function +function name='virDomainGetDiskErrors' file='python' + infoExtract errors on disk devices./info + return type='virDomainDiskErrorPtr' info='dictionary of disks and their errors or None in case of error'/ + arg name='domain' type='virDomainPtr' info='a domain object'/ + arg name='flags' type='unsigned int' info='unused, always pass 0'/ +/function /symbols /api diff --git a/python/libvirt-override.c b/python/libvirt-override.c index d2aad0f..7f1c093 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -3484,6 +3484,55 @@ libvirt_virDomainGetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED, return(pyreply); } +static PyObject * +libvirt_virDomainGetDiskErrors(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ +PyObject *py_retval = VIR_PY_NONE; +virDomainPtr domain; +PyObject *pyobj_domain; +unsigned int flags; +virDomainDiskErrorPtr disks = NULL; +unsigned int ndisks; +int count; +int i; + +if (!PyArg_ParseTuple(args, (char *) Oi:virDomainGetDiskErrors, + pyobj_domain, flags)) +return NULL; + +domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); + +if ((count = virDomainGetDiskErrors(domain, NULL, 0, 0)) 0) +return VIR_PY_NONE; +ndisks = count; + +if (ndisks) { +if (!(disks = malloc(sizeof(*disks) * ndisks))) +return VIR_PY_NONE; + +LIBVIRT_BEGIN_ALLOW_THREADS; +count = virDomainGetDiskErrors(domain, disks, ndisks, 0); +LIBVIRT_END_ALLOW_THREADS; + +if (count 0) +goto cleanup; +} + +if (!(py_retval = PyDict_New())) +goto cleanup; + +for (i = 0; i count; i++) { +PyDict_SetItem(py_retval, + libvirt_charPtrWrap(disks[i].disk), + libvirt_intWrap(disks[i].error)); +} + +cleanup: +free(disks); +return py_retval; +} + /*** * Helper functions to avoid importing modules * for every callback @@ -5206,6 +5255,7 @@ static PyMethodDef libvirtMethods[] = { {(char *) virDomainMigrateGetMaxSpeed, libvirt_virDomainMigrateGetMaxSpeed, METH_VARARGS, NULL}, {(char *) virDomainBlockPeek, libvirt_virDomainBlockPeek, METH_VARARGS, NULL}, {(char *) virDomainMemoryPeek, libvirt_virDomainMemoryPeek, METH_VARARGS, NULL}, +{(char *) virDomainGetDiskErrors, libvirt_virDomainGetDiskErrors, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; -- 1.7.8.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 4/5] virsh: Implement domblkerror command
This command lists all disk devices with errors --- tools/virsh.c | 78 +++ tools/virsh.pod |7 + 2 files changed, 85 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 3a59746..23962bf 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -16037,6 +16037,83 @@ cleanup: } /* + * domblkerror command + */ +static const char * +vshDomainIOErrorToString(int error) +{ +switch ((virDomainDiskErrorCode) error) { +case VIR_DOMAIN_DISK_ERROR_NONE: +return _(no error); +case VIR_DOMAIN_DISK_ERROR_UNSPEC: +return _(unspecified error); +case VIR_DOMAIN_DISK_ERROR_NO_SPACE: +return _(no space); +case VIR_DOMAIN_DISK_ERROR_LAST: +; +} + +return _(unknown error); +} + +static const vshCmdInfo info_domblkerror[] = { +{help, N_(Show errors on block devices)}, +{desc, N_(Show block device errors)}, +{NULL, NULL} +}; + +static const vshCmdOptDef opts_domblkerror[] = { +{domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id, or uuid)}, +{NULL, 0, 0, NULL} +}; + +static bool +cmdDomBlkError(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom; +virDomainDiskErrorPtr disks = NULL; +unsigned int ndisks; +int i; +int count; +bool ret = false; + +if (!vshConnectionUsability(ctl, ctl-conn)) +return false; + +if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) +return false; + +if ((count = virDomainGetDiskErrors(dom, NULL, 0, 0)) 0) +goto cleanup; +ndisks = count; + +if (ndisks) { +if (VIR_ALLOC_N(disks, ndisks) 0) +goto cleanup; + +if ((count = virDomainGetDiskErrors(dom, disks, ndisks, 0)) == -1) +goto cleanup; +} + +if (count == 0) { +vshPrint(ctl, _(No errors found\n)); +} else { +for (i = 0; i count; i++) { +vshPrint(ctl, %s: %s\n, + disks[i].disk, + vshDomainIOErrorToString(disks[i].error)); +} +} + +ret = true; + +cleanup: +VIR_FREE(disks); +virDomainFree(dom); +return ret; +} + +/* * qemu-monitor-command command */ static const vshCmdInfo info_qemu_monitor_command[] = { @@ -16236,6 +16313,7 @@ static const vshCmdDef domManagementCmds[] = { }; static const vshCmdDef domMonitoringCmds[] = { +{domblkerror, cmdDomBlkError, opts_domblkerror, info_domblkerror, 0}, {domblkinfo, cmdDomblkinfo, opts_domblkinfo, info_domblkinfo, 0}, {domblklist, cmdDomblklist, opts_domblklist, info_domblklist, 0}, {domblkstat, cmdDomblkstat, opts_domblkstat, info_domblkstat, 0}, diff --git a/tools/virsh.pod b/tools/virsh.pod index 4bc25bf..e9598ac 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -507,6 +507,13 @@ on hypervisor. Get memory stats for a running domain. +=item Bdomblkerror Idomain-id + +Show errors on block devices. This command usually comes handy when +Bdomstate command says that a domain was paused due to I/O error. +The Bdomblkerror command lists all block devices in error state and +the error seen on each of them. + =item Bdomblkinfo Idomain Iblock-device Get block device size info for a domain. A Iblock-device corresponds -- 1.7.8.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 3/5] qemu: Implement virDomainGetDiskErrors
--- src/qemu/qemu_conf.h |1 + src/qemu/qemu_driver.c | 86 ++ src/qemu/qemu_monitor.c | 40 +++ src/qemu/qemu_monitor.h |1 + src/qemu/qemu_monitor_json.c |8 src/qemu/qemu_monitor_text.c | 15 +++ 6 files changed, 151 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 7d79823..0b65d7d 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -175,6 +175,7 @@ struct qemuDomainDiskInfo { bool removable; bool locked; bool tray_open; +int io_status; }; #endif /* __QEMUD_CONF_H */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1b147a9..a7ac75a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11740,6 +11740,91 @@ cleanup: return ret; } +static int +qemuDomainGetDiskErrors(virDomainPtr dom, +virDomainDiskErrorPtr errors, +unsigned int nerrors, +unsigned int flags) +{ +struct qemud_driver *driver = dom-conn-privateData; +virDomainObjPtr vm = NULL; +qemuDomainObjPrivatePtr priv; +char uuidstr[VIR_UUID_STRING_BUFLEN]; +virHashTablePtr table = NULL; +int ret = -1; +int i; +int n = 0; + +virCheckFlags(0, -1); + +qemuDriverLock(driver); +virUUIDFormat(dom-uuid, uuidstr); +vm = virDomainFindByUUID(driver-domains, dom-uuid); +qemuDriverUnlock(driver); + +if (!vm) { +qemuReportError(VIR_ERR_NO_DOMAIN, +_(no domain with matching uuid '%s'), uuidstr); +goto cleanup; +} + +priv = vm-privateData; + +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) 0) +goto cleanup; + +if (!virDomainObjIsActive(vm)) { +qemuReportError(VIR_ERR_OPERATION_INVALID, +%s, _(domain is not running)); +goto endjob; +} + +if (!errors) { +ret = vm-def-ndisks; +goto endjob; +} + +qemuDomainObjEnterMonitor(driver, vm); +table = qemuMonitorGetBlockInfo(priv-mon); +qemuDomainObjExitMonitor(driver, vm); +if (!table) +goto endjob; + +for (i = n = 0; i vm-def-ndisks; i++) { +struct qemuDomainDiskInfo *info; +virDomainDiskDefPtr disk = vm-def-disks[i]; + +if ((info = virHashLookup(table, disk-info.alias)) +info-io_status != VIR_DOMAIN_DISK_ERROR_NONE) { +if (n == nerrors) +break; + +if (!(errors[n].disk = strdup(disk-dst))) { +virReportOOMError(); +goto endjob; +} +errors[n].error = info-io_status; +n++; +} +} + +ret = n; + +endjob: +if (qemuDomainObjEndJob(driver, vm) == 0) +vm = NULL; + +cleanup: +if (vm) +virDomainObjUnlock(vm); +virHashFree(table); +if (ret 0) { +for (i = 0; i n; i++) +VIR_FREE(errors[i].disk); +} +return ret; +} + static virDriver qemuDriver = { .no = VIR_DRV_QEMU, .name = QEMU, @@ -11893,6 +11978,7 @@ static virDriver qemuDriver = { .domainGetNumaParameters = qemuDomainGetNumaParameters, /* 0.9.9 */ .domainGetInterfaceParameters = qemuDomainGetInterfaceParameters, /* 0.9.9 */ .domainSetInterfaceParameters = qemuDomainSetInterfaceParameters, /* 0.9.9 */ +.domainGetDiskErrors = qemuDomainGetDiskErrors, /* 0.9.10 */ }; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index dda0521..7872e3d 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -87,6 +87,20 @@ VIR_ENUM_IMPL(qemuMonitorVMStatus, postmigrate, prelaunch, finish-migrate, restore-vm, running, save-vm, shutdown, watchdog) +typedef enum { +QEMU_MONITOR_BLOCK_IO_STATUS_OK, +QEMU_MONITOR_BLOCK_IO_STATUS_FAILED, +QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE, + +QEMU_MONITOR_BLOCK_IO_STATUS_LAST +} qemuMonitorBlockIOStatus; + +VIR_ENUM_DECL(qemuMonitorBlockIOStatus) + +VIR_ENUM_IMPL(qemuMonitorBlockIOStatus, + QEMU_MONITOR_BLOCK_IO_STATUS_LAST, + ok, failed, nospace) + char *qemuMonitorEscapeArg(const char *in) { int len = 0; @@ -1227,6 +1241,32 @@ int qemuMonitorGetMemoryStats(qemuMonitorPtr mon, return ret; } +int +qemuMonitorBlockIOStatusToError(const char *status) +{ +int st = qemuMonitorBlockIOStatusTypeFromString(status); + +if (st 0) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(unknown block IO status: %s), status); +return -1; +} + +switch ((qemuMonitorBlockIOStatus) st) { +case QEMU_MONITOR_BLOCK_IO_STATUS_OK: +return VIR_DOMAIN_DISK_ERROR_NONE; +case QEMU_MONITOR_BLOCK_IO_STATUS_FAILED: +return VIR_DOMAIN_DISK_ERROR_UNSPEC; +case QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE: +return VIR_DOMAIN_DISK_ERROR_NO_SPACE;
Re: [libvirt] [PATCH v2 1/3] virDomainGetDiskErrors public API and remote protocol
On Mon, Jan 30, 2012 at 15:56:11 -0700, Eric Blake wrote: On 01/30/2012 09:00 AM, Jiri Denemark wrote: We already provide ways to detect when a domain has been paused as a result of I/O error, but there was no way of getting the exact error or even the device that experienced it. This new API may be used for both. --- daemon/remote.c | 40 include/libvirt/libvirt.h.in | 32 + python/generator.py |3 +- src/driver.h |7 + src/libvirt.c| 52 ++ src/libvirt_public.syms |1 + src/remote/remote_driver.c | 34 +++ src/remote/remote_protocol.x | 22 +- src/remote_protocol-structs | 16 + src/rpc/gendispatch.pl | 47 + 10 files changed, 252 insertions(+), 2 deletions(-) This is big enough that I might have split it into public API (include, python, src/{driver.h,libvirt.c,libvirt_public.syms}) and RPC implementation (daemon, src/remote, src/rpc). But I'll go ahead and review this, whether or not you split it. I did so and addressed the other comments in v3. ... /*- Protocol. -*/ @@ -2708,7 +2727,8 @@ enum remote_procedure { REMOTE_PROC_STORAGE_VOL_RESIZE = 260, /* autogen autogen */ REMOTE_PROC_DOMAIN_PM_SUSPEND_FOR_DURATION = 261, /* autogen autogen */ -REMOTE_PROC_DOMAIN_GET_CPU_STATS = 262 /* skipgen skipgen */ +REMOTE_PROC_DOMAIN_GET_CPU_STATS = 262, /* skipgen skipgen */ +REMOTE_PROC_DOMAIN_GET_DISK_ERRORS = 263 /* autogen autogen */ Nice that you figured out how to autogen the serialize/deserialize calls. Yeah, although I didn't try so hard after making this a multi-return call, so v3 now uses skipgen skipgen :-) We should probably do the same for a lot of the virTypedParameter clients someday The generator already seems to know how to deal with virTypedParameter but only for APIs with only one item in their *_ret structure. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 0/5] Add virDomainGetDiskErrors API
We already provide ways to detect when a domain has been paused as a result of I/O error, but there was no way of getting the exact error or even the device that experienced it. This new API may be used for both. Changes in version 3: - special case errors == NULL, maxerrors == 0 returns size of the array the caller should pass - explicitly document that disks with no error are not returned and that the caller must free disk names - explicitly document what happens when maxerrors is lower then the actual number of disk errors - maxerrors turned unsigned - the first patch was split into two (public API and RPC) - python binding is back Changes in version 2: - the API is now called virDomainGetDiskErrors - it returns a list (allocated by caller) of disks with errors instead so that users don't have to call it multiple times to get all errors - there's no python API yet since it can't be autogenerated; I'll send a patch for it tomorrow Jiri Denemark (5): virDomainGetDiskErrors public API Remote protocol for virDomainGetDiskErrors qemu: Implement virDomainGetDiskErrors virsh: Implement domblkerror command python: Add binding for virDomainGetDiskErrors daemon/remote.c | 103 +++ include/libvirt/libvirt.h.in| 32 python/generator.py |3 +- python/libvirt-override-api.xml |6 ++ python/libvirt-override.c | 50 +++ src/driver.h|7 +++ src/libvirt.c | 65 src/libvirt_public.syms |1 + src/qemu/qemu_conf.h|1 + src/qemu/qemu_driver.c | 86 src/qemu/qemu_monitor.c | 40 +++ src/qemu/qemu_monitor.h |1 + src/qemu/qemu_monitor_json.c|8 +++ src/qemu/qemu_monitor_text.c| 15 ++ src/remote/remote_driver.c | 77 + src/remote/remote_protocol.x| 23 - src/remote_protocol-structs | 17 ++ tools/virsh.c | 78 + tools/virsh.pod |7 +++ 19 files changed, 618 insertions(+), 2 deletions(-) -- 1.7.8.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/3] qemu: Implement virDomainGetDiskErrors
On Mon, Jan 30, 2012 at 16:13:37 -0700, Eric Blake wrote: On 01/30/2012 09:01 AM, Jiri Denemark wrote: --- src/qemu/qemu_conf.h |1 + src/qemu/qemu_driver.c | 83 ++ src/qemu/qemu_monitor.c | 40 src/qemu/qemu_monitor.h |1 + src/qemu/qemu_monitor_json.c |8 src/qemu/qemu_monitor_text.c | 15 6 files changed, 148 insertions(+), 0 deletions(-) ... +++ b/src/qemu/qemu_monitor_text.c @@ -839,6 +839,21 @@ int qemuMonitorTextGetBlockInfo(qemuMonitorPtr mon, VIR_DEBUG(error reading tray_open: %s, p); Do we still need to implement this in qemu_monitor_text, now that we require JSON for any qemu version new enough to actually provide this information in the first place? I guess we don't but v1 predates your patch and I tested the code worked so I just didn't remove it :-) Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 3/3] virsh: Implement domblkerror command
On Mon, Jan 30, 2012 at 16:20:07 -0700, Eric Blake wrote: On 01/30/2012 09:01 AM, Jiri Denemark wrote: This command lists all disk devices with errors --- tools/virsh.c | 89 +++ tools/virsh.pod |7 2 files changed, 96 insertions(+), 0 deletions(-) ... +static const vshCmdOptDef opts_domblkerror[] = { +{domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id, or uuid)}, +{NULL, 0, 0, NULL} Should we also allow this additional usage: virsh domblkerror dom vda which lists the status of just vda (no error, no space left, ...)? That would mean adding: {disk, VSH_OT_DATA, VSH_OFLAG_OPT, N_(particular disk to check)} then filtering through the libvirt API to match just that disk? You can say no, that's overkill and not implement it, and I won't be hurt. I think grep/sed/awk and similar friends can do similar job here if anyone wants to get the error status of just one specific disk. +if ((count = virDomainGetDiskErrors(dom, disks, ndisks, 0)) == -1) +goto cleanup; + +for (i = 0; i count; i++) { +vshPrint(ctl, %s: %s\n, + disks[i].disk, + vshDomainIOErrorToString(disks[i].error)); +} Are we okay that if there are no disk errors (count is 0), we have no output, not even mentioning that the command succeeded? I guess we are not and I changed that. I also made this command consistent with python API which reports no disk errors for domain without disks instead of complaining that the domain has no disks. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] docs: fill out rawio description
The original doc entry for rawio didn't mention the values it could have, the default, or the fact that setting it to yes for one disk effectively set it to yes for all disks in the domain. --- Pushed under the trivial rule. docs/formatdomain.html.in | 11 --- 1 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index a025a8e..d58a5e1 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1097,9 +1097,14 @@ actual raw devices, never for individual partitions or LVM partitions (in those cases, the kernel will reject the generic SCSI commands, making it identical to device='disk'). -The optional coderawio/code attribute indicates that the disk -is desirous of rawio capability. This attribute is only valid when -device is lun. +The optional coderawio/code attribute +(span class=sincesince 0.9.10/span) indicates whether +the disk is needs rawio capability; valid settings are yes +or no (default is no). If any one disk in a domain has +rawio='yes', rawio capability will be enabled for all disks in +the domain (because, in the case of QEMU, this capability can +only be set on a per-process basis). This attribute is only +valid when device is lun. The optional codesnapshot/code attribute indicates the default behavior of the disk during disk snapshots: internal requires a file format such as qcow2 that can store both the -- 1.7.7.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv3] simplify block of codes
From: Alex Jia a...@redhat.com Using new function 'virTypedParameterArrayClear' to simplify block of codes. * daemon/remote.c, src/remote/remote_driver.c: simplify codes. Signed-off-by: Alex Jia a...@redhat.com --- daemon/remote.c|6 +- src/remote/remote_driver.c | 19 +-- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index cb8423a..e7d9b2f 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -848,11 +848,7 @@ remoteDeserializeTypedParameters(remote_typed_param *args_params_val, cleanup: if (rv 0) { -int j; -for (j = 0; j i; ++j) { -if (params[j].type == VIR_TYPED_PARAM_STRING) -VIR_FREE(params[j].value.s); -} +virTypedParameterArrayClear(params, i); VIR_FREE(params); } return params; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 61b96e9..031becd 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -46,6 +46,7 @@ #include virfile.h #include command.h #include intprops.h +#include virtypedparam.h #define VIR_FROM_THIS VIR_FROM_REMOTE @@ -1417,12 +1418,8 @@ remoteDeserializeTypedParameters(remote_typed_param *ret_params_val, rv = 0; cleanup: -if (rv 0) { -int j; -for (j = 0; j i; j++) -if (params[j].type == VIR_TYPED_PARAM_STRING) -VIR_FREE(params[j].value.s); -} +if (rv 0) +virTypedParameterArrayClear(params, i); return rv; } @@ -2384,15 +2381,9 @@ static int remoteDomainGetCPUStats(virDomainPtr domain, rv = ret.nparams; cleanup: -if (rv 0) { -int max = nparams * ncpus; -int i; +if (rv 0) +virTypedParameterArrayClear(params, nparams * ncpus); -for (i = 0; i max; i++) { -if (params[i].type == VIR_TYPED_PARAM_STRING) -VIR_FREE(params[i].value.s); -} -} xdr_free ((xdrproc_t) xdr_remote_domain_get_cpu_stats_ret, (char *) ret); done: -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC API proposal: virDomainBlockRebase
On Tue, Jan 31, 2012 at 09:28:51AM -0700, Eric Blake wrote: Right now, the existing virDomainBlockPull API has a tough limitation - it is an all-or-none approach. In all my examples below, I'm starting from the following relationship, where '-' means 'is a backing file of': template - intermediate - current virDomainBlockPull can only convert things in a forward direction, with the merge destination being the current image, resulting in: merge template and intermediate into current, creating: current Meanwhile, qemu is adding support for a partial block pull operation, still on the current image as the merge destination, but where you can now specify an optional argument to limit the pull to just the intermediate files and altering the current image to be backed by an ancestor file, as in: merge intermediate into current, creating: template - current For 0.9.10, I'd like to add the following API: /** * virDomainBlockRebase: * @dom: pointer to domain object * @disk: path to the block device, or device shorthand * @base: new base image, or NULL for entire block pull * @bandwidth: (optional) specify copy bandwidth limit in Mbps * @flags: extra flags; not used yet, so callers should always pass 0 What is the format of the @base arg? My first thought would be a path, but what if the desired image file is not directly known to libvirt? * Populate a disk image with data from its backing image chain, and * setting the new backing image to @base, where base is the absolute * path of one of the backing images in the chain. If @base is NULL, * then this operation is identical to virDomainBlockPull(). Once all * data from its backing image chain has been pulled, the disk no * longer depends on those intermediate backing images. This function * pulls data for the entire device in the background. Progress of the * operation can be checked with virDomainGetBlockJobInfo() and * the operation can be aborted with virDomainBlockJobAbort(). When * finished, an asynchronous event is raised to indicate the final * status. * * The @disk, @bandwidth, and @flags parameters are handled as in * virDomainBlockPull(). * * Returns 0 if the operation has started, -1 on failure. */ int virDomainBlockRebase(virDomainPtr dom, const char *disk, const char *base, unsigned long bandwidth, unsigned int flags); Given that Adam has a pending patch to support a VIR_DOMAIN_BLOCK_PULL_ASYNC flag, this same flag would have to be supported in virDomainBlockRebase. That patch only applies to virDomainBlockJobCancel(). The blockJob initiators (virDomainBlockPull and this new one) already use an async mode of operation because the call simply starts the block job. I've also been chatting with Federico Simoncelli about how the above operation would work for VDSM purposes in doing a live block move, while preserving a common template base file: start with: vda: template - current1 create a disk-only snapshot, with: tmpsnap = virDomainSnapshotCreateXML(dom, domainsnapshot\n disks\n disk name='vda'\n source/path/to/current2/source\n /disk\n disks\n /domainsnapshot, VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) where the xml calls out the destination file name, resulting in: vda: template - current1 - current2 perform the block rebase, with: virDomainBlockRebase(dom, vda, /path/to/template, VIR_DOMAIN_BLOCK_PULL_ASYNC) as well as waiting for the event (or polling status) to wait for completion, resulting in: vda: template - current2 delete the disk-only snapshot metadata as no longer useful, with: virDomainSnapshotDelete(tmpsnap, VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY) Yep, seems like a very good method. At one point, I thought of creating a single libvirt API that performs all of those steps in one call; but right now, I'm not proposing that, because of the fact that qemu has no way to undo a snapshot. In other words, without an undo operation, if the snapshot phase succeeds but the block rebase phase fails, a single API would have to report failure even though the domain was altered, while the ideal scenario is that reporting failure means things were in the same state as before the API started. Beyond 0.9.10, there are some additional useful merge patterns that might be worth exposing. All of these operations are already possible on offline images, using qemu-img; but none of them are possible on live images using current qemu, which is why I'm thinking it is something for another day. I'm also hoping to someday enhance the set of virStorageVol APIs to make backing file manipulation of offline images easier. At any rate, the addition merge operations are: forward live merge with a non-current image as the merge destination, as in: merge template into intermediate, creating: intermediate - current backward merge of a
Re: [libvirt] [PATCH] qemu: never send SIGKILL to qemu process unless specifically requested
On 01/31/2012 02:53 AM, Daniel P. Berrange wrote: In the meantime, shouldn't we at least wait longer before resorting to SIGKILL? (especially since it appears the current timeout is quite often too short). (If we don't at least do that, what we're saying is the behavior of virDomainShutdown / virDomainDestroy is to lose your data unless you're lucky. If you don't want this behavior, you need to use virDomainXXXFlags, and specify the VIR_DOMAIN_DONT_TRASH_MY_DATA flag :-P). If you add a flag to trigger a graceful kill(SIGINT) only, then we don't need to change the timeout. The application now has the ability to wait as long as they like, before issuing another virDomainDestroy() The new flag only benefits new apps that are compiled to use the new flag. I see nothing wrong with lengthening the timeout when no flag is present, to also benefit the older apps that have not yet been recompiled to use the new flag, since as was pointed out, the loop gives up as soon as the process is gone, so in the common case, it won't change behavior, and in the timeout case, we are waiting longer and thus less likely to lose data. In other words, I'm in favor of both approaches (new flag and longer default timeout when no flag is used). -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC API proposal: virDomainBlockRebase
On 01/31/2012 01:53 PM, Adam Litke wrote: On Tue, Jan 31, 2012 at 09:28:51AM -0700, Eric Blake wrote: Right now, the existing virDomainBlockPull API has a tough limitation - it is an all-or-none approach. In all my examples below, I'm starting from the following relationship, where '-' means 'is a backing file of': template - intermediate - current Meanwhile, qemu is adding support for a partial block pull operation, still on the current image as the merge destination, but where you can now specify an optional argument to limit the pull to just the intermediate files and altering the current image to be backed by an ancestor file, as in: merge intermediate into current, creating: template - current For 0.9.10, I'd like to add the following API: /** * virDomainBlockRebase: * @dom: pointer to domain object * @disk: path to the block device, or device shorthand * @base: new base image, or NULL for entire block pull * @bandwidth: (optional) specify copy bandwidth limit in Mbps * @flags: extra flags; not used yet, so callers should always pass 0 What is the format of the @base arg? My first thought would be a path, but what if the desired image file is not directly known to libvirt? Libvirt already has to know the absolute paths of all disks in the backing file chain, in order to properly SELinux label them prior to invoking qemu. So I'm envisioning the absolute path of the backing file in the chain that will be preserved. That is, with: touch 10M /path/to/template qemu-img create -f qcow2 \ -o backing_file /path/to/template /path/to/intermediate qemu-img create -f qcow2 \ -o backing_file /path/to/intermediate /path/to/current followed by virDomainBlockRebase(dom, vda, /path/to/template, 0) would result in /path/to/current referring to /path/to/template as its primary backing file. I also had an idea down below where, with the addition of a new flags value, base could refer to a well-formed XML block rather than a single file name, such that we could then populate that XML block with more complex instructions; but I'm not proposing doing that extension in the 0.9.10 timeframe, so much as trying to argue that this API is extensible and we won't need yet a third API for block pull if qemu ever allows more complex merging scenarios. Given that Adam has a pending patch to support a VIR_DOMAIN_BLOCK_PULL_ASYNC flag, this same flag would have to be supported in virDomainBlockRebase. That patch only applies to virDomainBlockJobCancel(). The blockJob initiators (virDomainBlockPull and this new one) already use an async mode of operation because the call simply starts the block job. Ah, right. I'm getting slightly confused with all the patches that still need review :) virDomainBlockPull has always been asynchronous, so no flag is needed there or in this new API. and backward merge of a non-current image (that is, undoing an earlier snapshot, but by modifying the template rather than the current image): merge intermediate into base, creating: template - current Don't these raise some security concerns about modifying a potentially shared intermediate image? Yes, the management app has to be careful to not remove backing files that are in use in other chains. But we already have a lock manager setup, so of course, part of the libvirt work is integrating this work so that no image is ever reverted if the lock manager says a file is in use; libvirt can also check all registered storage pools and prevent a rebase if the storage pool tracks files that serve as base images to more than one other images, and prevent modifying base images in those cases (there's probably still a lot of work to be done in libvirt to make it bulletproof, but that's okay, since again, my ideas about reverse merges are post-0.9.10 and would also require more work from qemu). At any rate, you responded favorably to the first half of my email (the proposal for what to implement in 0.9.10), even if you got scared by my musings about possible future extensions at later releases. I'll take that as a good sign that I have a) come up with a good API worth adding now, and b) divided things appropriately into what is reasonable to do now vs. what is complex enough to be worth delaying until we have more experience with the use cases and ramifications of adding the complexity. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] docs: fill out rawio description
On 01/31/2012 12:58 PM, Laine Stump wrote: The original doc entry for rawio didn't mention the values it could have, the default, or the fact that setting it to yes for one disk effectively set it to yes for all disks in the domain. That's true for now, but hopefully something we can change in the future (then again, if we change it in the future, we can also update the docs at that time). The idea is that the kernel already has the ability to maintain whitelists of valid ioctls per device, and it already has a cgroup for maintaining which devices can be accessed by various process groups. The logical conclusion - we need a new cgroup control file under the 'devices' cgroup which lets us tune the per-device whitelist of whether rawio ioctls are allowed. Once that is in place in the kernel, then libvirt can be taught to expose rawio only for the specified device, rather than its current behavior of forcing the enablement of rawio on all other devices tied to the process. --- Pushed under the trivial rule. docs/formatdomain.html.in | 11 --- 1 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index a025a8e..d58a5e1 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1097,9 +1097,14 @@ actual raw devices, never for individual partitions or LVM partitions (in those cases, the kernel will reject the generic SCSI commands, making it identical to device='disk'). -The optional coderawio/code attribute indicates that the disk -is desirous of rawio capability. This attribute is only valid when -device is lun. +The optional coderawio/code attribute +(span class=sincesince 0.9.10/span) indicates whether +the disk is needs rawio capability; valid settings are yes +or no (default is no). If any one disk in a domain has +rawio='yes', rawio capability will be enabled for all disks in +the domain (because, in the case of QEMU, this capability can +only be set on a per-process basis). This attribute is only +valid when device is lun. If anything, it might be worth tweaking this wording to state: Currently, if any one disk in a domain has rawio='yes', this implies that all other devices can use rawio; but this is expected to change in the future if the kernel is improved to limit rawio to a per-device rather than a per-process basis. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/4] conf: add rawio attribute to disk element of domain XML
On 01/31/2012 11:53 AM, Laine Stump wrote: I also found that make check wouldn't pass, which was mostly traced to the concept of making the default value of rawio -1. The problem with this is that there are other functions that create and fill-in domain structures, and they hadn't been taught about this default value. I changed the object to have a bool rawio_specified, and modified the parse and format functions accordingly. We could have also solved this by using a three-state enum with the default state being 0 rather than -1: enum { VIR_DOMAIN_DISK_RAWIO_DEFAULT = 0, VIR_DOMAIN_DISK_RAWIO_NO = 1, VIR_DOMAIN_DISK_RAWIO_YES = 2, } which we have done for other setups, as that avoids the need for a separate bool value. But I'm not too worried about what you did to bother changing things. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Qemu text monitor
Shradha Shah wrote: Hello All, I am currently working with libvirt on RHEL6.2. There are a few points I have noticed regarding the QEMU monitor. When I hotplug a device into the guest, the Qemu text monitor receives a device_add command and adds the device to its current devices list (I found this list via the qemu-monitor-command info pci). When I hot-unplug the device from the guest, the Qemu text monitor receives the device_del command but does not remove the device from its current devices list (qemu-monitor-command info pci still shows the device). The result of this is that the next hotplug of the device fails giving an error Duplicate id. I was wondering if any of you have hit this issue before or know about any qemu-monitor bugs I may not be aware of? I had noticed this behavior as well with some of my SLES guests, but in my case was due to acpiphp module not being loaded in the guests. Regards, Jim -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC API proposal: virDomainBlockRebase
On Tue, Jan 31, 2012 at 03:00:40PM -0700, Eric Blake wrote: On 01/31/2012 01:53 PM, Adam Litke wrote: On Tue, Jan 31, 2012 at 09:28:51AM -0700, Eric Blake wrote: Right now, the existing virDomainBlockPull API has a tough limitation - it is an all-or-none approach. In all my examples below, I'm starting from the following relationship, where '-' means 'is a backing file of': template - intermediate - current Meanwhile, qemu is adding support for a partial block pull operation, still on the current image as the merge destination, but where you can now specify an optional argument to limit the pull to just the intermediate files and altering the current image to be backed by an ancestor file, as in: merge intermediate into current, creating: template - current For 0.9.10, I'd like to add the following API: /** * virDomainBlockRebase: * @dom: pointer to domain object * @disk: path to the block device, or device shorthand * @base: new base image, or NULL for entire block pull * @bandwidth: (optional) specify copy bandwidth limit in Mbps * @flags: extra flags; not used yet, so callers should always pass 0 What is the format of the @base arg? My first thought would be a path, but what if the desired image file is not directly known to libvirt? Libvirt already has to know the absolute paths of all disks in the backing file chain, in order to properly SELinux label them prior to invoking qemu. So I'm envisioning the absolute path of the backing file in the chain that will be preserved. That is, with: Ok. That is clear. Thanks. touch 10M /path/to/template qemu-img create -f qcow2 \ -o backing_file /path/to/template /path/to/intermediate qemu-img create -f qcow2 \ -o backing_file /path/to/intermediate /path/to/current followed by virDomainBlockRebase(dom, vda, /path/to/template, 0) would result in /path/to/current referring to /path/to/template as its primary backing file. I also had an idea down below where, with the addition of a new flags value, base could refer to a well-formed XML block rather than a single file name, such that we could then populate that XML block with more complex instructions; but I'm not proposing doing that extension in the 0.9.10 timeframe, so much as trying to argue that this API is extensible and we won't need yet a third API for block pull if qemu ever allows more complex merging scenarios. Given that Adam has a pending patch to support a VIR_DOMAIN_BLOCK_PULL_ASYNC flag, this same flag would have to be supported in virDomainBlockRebase. That patch only applies to virDomainBlockJobCancel(). The blockJob initiators (virDomainBlockPull and this new one) already use an async mode of operation because the call simply starts the block job. Ah, right. I'm getting slightly confused with all the patches that still need review :) virDomainBlockPull has always been asynchronous, so no flag is needed there or in this new API. and backward merge of a non-current image (that is, undoing an earlier snapshot, but by modifying the template rather than the current image): merge intermediate into base, creating: template - current Don't these raise some security concerns about modifying a potentially shared intermediate image? Yes, the management app has to be careful to not remove backing files that are in use in other chains. But we already have a lock manager setup, so of course, part of the libvirt work is integrating this work so that no image is ever reverted if the lock manager says a file is in use; libvirt can also check all registered storage pools and prevent a rebase if the storage pool tracks files that serve as base images to more than one other images, and prevent modifying base images in those cases (there's probably still a lot of work to be done in libvirt to make it bulletproof, but that's okay, since again, my ideas about reverse merges are post-0.9.10 and would also require more work from qemu). At any rate, you responded favorably to the first half of my email (the proposal for what to implement in 0.9.10), even if you got scared by my musings about possible future extensions at later releases. I'll take that as a good sign that I have a) come up with a good API worth adding now, and b) divided things appropriately into what is reasonable to do now vs. what is complex enough to be worth delaying until we have more experience with the use cases and ramifications of adding the complexity. Yes, exactly. Seems like a good plan. I am happy to see that the blockJob API family will be extended as we initially intended. -- Adam Litke a...@us.ibm.com IBM Linux Technology Center -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv2] schema: Relax schema for domain name
On 01/25/2012 08:49 AM, Peter Krempa wrote: The domain schema enforced restrictions on the domain name string that the code doesn't. This patch relaxes the check, leaving the restrictions on the driver or hypervisor. The only invalid character is a newline. --- docs/schemas/domaincommon.rng |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4fa968d..ecf3484 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3030,7 +3030,7 @@ /define define name=domainName data type=string - param name=pattern[A-Za-z0-9_\.\+\-amp;:/]+/param + param name=pattern[^\n]+/param Phooey. This patch is causing a test failure on RHEL 6.2. Apparently, the version of libxml2-2.7.6-4.el6_2.1.x86_64 is treating that as a regular expression that forbids literal 'n'; whereas on Fedora 16, libxml2-2.7.8-6.fc16.x86_64 treats it as forbidding newline. Interestingly enough, using a literal newline made the test patch in both platforms. I'm checking this in under the build-breaker rule, and we'll need the same hack when we check in the XML for title: From c3c2cc653408dd51f2f87371dfb0b00f7181fc00 Mon Sep 17 00:00:00 2001 From: Eric Blake ebl...@redhat.com Date: Tue, 31 Jan 2012 16:51:36 -0700 Subject: [PATCH] build: fix text regression Commit 8a09ee410 tickles a bug in libxml2-2.7.6 on RHEL 6.2, where libxml2 treats the pattern [^\n] as excluding literal backslash and n, instead of the intended newline, thus failing to validate any domain name containing 'n'. * docs/schemas/domaincommon.rng: Use literal newline instead. --- docs/schemas/domaincommon.rng |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 66e5491..2423154 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3058,7 +3058,9 @@ /define define name=domainName data type=string - param name=pattern[^\n]+/param + !-- Use literal newline instead of \n for bug in libxml2 2.7.6 -- + param name=pattern[^ +]+/param /data /define define name=diskSerial -- 1.7.7.6 -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv3] simplify block of codes
On 01/30/2012 08:25 PM, alex@redhat.com wrote: From: Alex Jia a...@redhat.com Using new function 'virTypedParameterArrayClear' to simplify block of codes. * daemon/remote.c, src/remote/remote_driver.c: simplify codes. Signed-off-by: Alex Jia a...@redhat.com --- daemon/remote.c|6 +- src/remote/remote_driver.c | 19 +-- 2 files changed, 6 insertions(+), 19 deletions(-) ACK. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv3] network: Avoid memory leaks on networkBuildDnsmasqArgv
On 01/31/2012 12:15 AM, Alex Jia wrote: What I'd suggest is: declare variables outside the loop, start the for loop by freeing any state from previous iterations, and also free all state in the cleanup label at which point, you _don't_ have to follow the v1 approach of trying to free variables before every goto or break (and missing some). Something like: char *record = NULL; for (i = 0; i dns-nsrrvrecords; i++) { /* free previous iteration */ VIR_FREE(record); Hi Eric, thanks for your nice comment, the 'record' variable is allocated memory in previous for loop, but we free it in here, the issue is 'dns-ntxtrecords' = 'dns-nsrrvrecord' ? if not, is it also okay? That's why you _also_ free things in the cleanup label. If every iteration of the loop frees the previous iteration, then the first iteration of the loop is a no-op, and the cleanup code frees the last iteration, no matter whether you get to the cleanup code via a goto or whether the last iteration exited normally. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Implement virStorageVolResize() for FS backend
On 01/31/2012 05:15 AM, Daniel P. Berrange wrote: On Mon, Jan 30, 2012 at 09:40:11AM +0200, Zeeshan Ali (Khattak) wrote: From: Zeeshan Ali (Khattak) zeesha...@gnome.org Currently only VIR_STORAGE_VOL_RESIZE_DELTA flag is supported. --- src/storage/storage_backend.h|6 +++ src/storage/storage_backend_fs.c | 53 +++ src/storage/storage_driver.c | 88 ++ src/util/storage_file.c | 16 +++ src/util/storage_file.h |2 + 5 files changed, 165 insertions(+), 0 deletions(-) ACK, looks ok to me. For closure purposes, Laine pushed my patch changing capacity to unsigned long long, then this patch with the correct type. You're still welcome to implement support for more flags between now and 0.9.10. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-glib] Add gvir_storage_vol_resize()
From: Zeeshan Ali (Khattak) zeesha...@gnome.org Add wrapper for virStorageVolResize(). --- libvirt-gobject/libvirt-gobject-storage-vol.c | 45 + libvirt-gobject/libvirt-gobject-storage-vol.h | 20 +++ libvirt-gobject/libvirt-gobject.sym |1 + 3 files changed, 66 insertions(+), 0 deletions(-) diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c index 491e2e6..f6f0c50 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.c +++ b/libvirt-gobject/libvirt-gobject-storage-vol.c @@ -299,3 +299,48 @@ gboolean gvir_storage_vol_delete(GVirStorageVol *vol, return TRUE; } + +/** + * gvir_storage_vol_resize: + * @vol: the storage volume to resize + * @capacity: the new capacity of the volume + * @flags: the flags + * @err: Return location for errors, or NULL + * + * Changes the capacity of the storage volume @vol to @capacity. + * + * Returns: the new capacity of the volume on success, 0 otherwise + */ +gboolean gvir_storage_vol_resize(GVirStorageVol *vol, + guint64 capacity, + GVirStorageVolResizeFlags flags, + GError **err) +{ +GVirStoragePoolInfo* pool_info = NULL; +GVirStorageVolInfo* volume_info = NULL; +gboolean ret = FALSE; + +pool_info = gvir_storage_pool_get_info (vol-priv-pool, err); +if (err != NULL *err != NULL) +goto cleanup; +volume_info = gvir_storage_vol_get_info (vol, err); +if (err != NULL *err != NULL) +goto cleanup; + +if (virStorageVolResize(vol-priv-handle, capacity, flags) 0) { +gvir_set_error_literal(err, + GVIR_STORAGE_VOL_ERROR, + 0, + Unable to resize volume storage); +goto cleanup; +} + +ret = TRUE; + +cleanup: +if (pool_info) +g_boxed_free(GVIR_TYPE_STORAGE_POOL_INFO, pool_info); +if (volume_info) +gvir_storage_vol_info_free(volume_info); +return ret; +} diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.h b/libvirt-gobject/libvirt-gobject-storage-vol.h index 25f683a..459a2ac 100644 --- a/libvirt-gobject/libvirt-gobject-storage-vol.h +++ b/libvirt-gobject/libvirt-gobject-storage-vol.h @@ -23,6 +23,7 @@ #if !defined(__LIBVIRT_GOBJECT_H__) !defined(LIBVIRT_GOBJECT_BUILD) #error Only libvirt-gobject/libvirt-gobject.h can be included directly. #endif +#include libvirt/libvirt.h #ifndef __LIBVIRT_GOBJECT_STORAGE_VOL_H__ #define __LIBVIRT_GOBJECT_STORAGE_VOL_H__ @@ -65,6 +66,21 @@ typedef enum { GVIR_STORAGE_VOL_STATE_DIR = 2, /* Directory-passthrough based volume */ } GVirStorageVolType; +/** + * GVirStorageVolResizeFlags: + * @GVIR_STORAGE_VOL_RESIZE_NONE: No flags + * @GVIR_STORAGE_VOL_RESIZE_ALLOCATE: force allocation of new size + * @GVIR_STORAGE_VOL_RESIZE_DELTA: size is relative to current + * @GVIR_STORAGE_VOL_RESIZE_SHRINK: allow decrease in capacity. This combined + * with #GVIR_STORAGE_VOL_RESIZE_DELTA, implies a negative delta. + */ +typedef enum { +GVIR_STORAGE_VOL_RESIZE_NONE = 0, +GVIR_STORAGE_VOL_RESIZE_ALLOCATE = VIR_STORAGE_VOL_RESIZE_ALLOCATE, +GVIR_STORAGE_VOL_RESIZE_DELTA= VIR_STORAGE_VOL_RESIZE_DELTA, +GVIR_STORAGE_VOL_RESIZE_SHRINK = VIR_STORAGE_VOL_RESIZE_SHRINK, +} GVirStorageVolResizeFlags; + typedef struct _GVirStorageVolInfo GVirStorageVolInfo; struct _GVirStorageVolInfo { @@ -89,6 +105,10 @@ GVirConfigStorageVol *gvir_storage_vol_get_config(GVirStorageVol *vol, GError **err); GVirStorageVolInfo *gvir_storage_vol_get_info(GVirStorageVol *vol, GError **err); +gboolean gvir_storage_vol_resize(GVirStorageVol *vol, + guint64 capacity, + GVirStorageVolResizeFlags flags, + GError **err); G_END_DECLS diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index a4f03f7..468bf65 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -126,6 +126,7 @@ LIBVIRT_GOBJECT_0.0.4 { gvir_storage_vol_get_config; gvir_storage_vol_get_info; gvir_storage_vol_delete; + gvir_storage_vol_resize; gvir_connection_handle_get_type; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Clenup qemuDomainSetInterfaceParameters
On 01/31/2012 05:51 AM, Michal Privoznik wrote: which contained some useless lines, copied code, NULL dereference. --- src/libvirt.c |4 ++-- src/qemu/qemu_driver.c | 44 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index e702a34..433ae0a 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -7226,8 +7226,8 @@ error: * * Change a subset or all parameters of interface; currently this * includes bandwidth parameters. The value of @flags should be - * either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of values from - * VIR_DOMAIN_AFFECT_LIVE and VIR_DOMAIN_AFFECT_CURRENT, although + * either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of values + * VIR_DOMAIN_AFFECT_LIVE and VIR_DOMAIN_AFFECT_CONFIG, although It took me a couple reads to see what typo you were fixing :) ACK. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] tests: dynamically replace dnsmasq path
On 01/31/2012 07:58 AM, Philipp Hahn wrote: Hello Eric, Am Montag 30 Januar 2012 20:18:15 schrieb Eric Blake: +if (diff 0) { +tmp = realloc((void *)*buf, new_len); We should not be using realloc in this file, but should be using VIR_RESIZE_N or similar. Okay, makes the code even more readable. +memmove(token_start, replacement, replacement_len); But this would be more efficient as memcpy, since replacement (better not) overlap with token_start. I know of some projects which forbid memcpy() because of the missing overlap handling. But if this is okay with libvirt, I'll use it. memcpy() is safe when the code is provably visiting non-overlapping strings, as is the case with your second use of memmove(). memcpy() is a mistake where the code is provably visiting overlapping strings, as is the case with your first memmove(). On some libc, memmove and memcpy are the same function; but since the standards allow memcpy to be more efficient than memmove by exploiting the non-overlap guarantee, you might as well use the more efficient method in the cases where things really are non-overlapping. Libvirt isn't so strict as to pessimize correct uses of memcpy() just because it can sometime be misused. It also helps that static analyzers like Coverity are getting pretty good at pointing out mis-uses of memcpy(). I hope performance will never be a problem with this simple test scenario, because then doing one realloc() instead of one for each found would be better. You do have a valid counterpoint here - this is a test, and not a hot path, so the savings of memcpy() vs. memmove() are in the noise compared to any extra realloc(); thankfully, neither overhead is worth worrying about too much. At any rate, I'll review your v2 now. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: fix my typo at commit 74e034964c32edb1732d0ff7642f3977f3587d72
Fix my typo at commit 74e034964c32edb1732d0ff7642f3977f3587d72 disk-rawio == -1 indicates that this value is not specified. So in case of this, domain must not be tainted. Signed-off-by: Taku Izumi izumi.t...@jp.fujitsu.com --- src/qemu/qemu_domain.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: libvirt/src/qemu/qemu_domain.c === --- libvirt.orig/src/qemu/qemu_domain.c +++ libvirt/src/qemu/qemu_domain.c @@ -1260,7 +1260,7 @@ void qemuDomainObjCheckDiskTaint(struct driver-allowDiskFormatProbing) qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_DISK_PROBING, logFD); -if (disk-rawio) +if (disk-rawio == 1) qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_HIGH_PRIVILEGES, logFD); } -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] ANNOUNCE: virt-manager 0.9.1 and virtinst 0.600.1 released
I'm happy to announce two new releases: virt-manager 0.9.1: virt-manager is a desktop application for managing KVM and Xen virtual machines via libvirt. virtinst 0.600.1: virtinst is a collection of command line tools for provisioning libvirt virtual machines, including virt-install and virt-clone. The releases can be downloaded from: http://virt-manager.org/download.html The direct download links are: http://virt-manager.org/download/sources/virt-manager/virt-manager-0.9.1.tar.gz http://virt-manager.org/download/sources/virtinst/virtinst-0.600.1.tar.gz The virt-manager release includes: - Support for adding usb redirection devices (Marc-André Lureau) - Option to switch usb controller to support usb2.0 (Marc-André Lureau) - Option to specify machine type for non-x86 guests (Li Zhang) - Support for filesystem device type and write policy (Deepak C Shetty) - Many bug fixes! The virtinst release includes: - virt-install: --redir option for usb redirection (Marc-André Lureau) - virt-install: Advanced --controller support for usb2 (Marc-André Lureau) - Many bug fixes and minor improvments. Thanks to everyone who has contributed to this release through testing, bug reporting, submitting patches, and otherwise sending in feedback! Thanks, Cole -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: fix my typo at commit 74e034964c32edb1732d0ff7642f3977f3587d72
On 01/31/2012 05:54 PM, Taku Izumi wrote: Fix my typo at commit 74e034964c32edb1732d0ff7642f3977f3587d72 disk-rawio == -1 indicates that this value is not specified. So in case of this, domain must not be tainted. Signed-off-by: Taku Izumi izumi.t...@jp.fujitsu.com --- src/qemu/qemu_domain.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) ACK and pushed. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 1/5] virDomainGetDiskErrors public API
On 01/31/2012 12:26 PM, Jiri Denemark wrote: We already provide ways to detect when a domain has been paused as a result of I/O error, but there was no way of getting the exact error or even the device that experienced it. This new API may be used for both. --- include/libvirt/libvirt.h.in | 32 python/generator.py |3 +- src/driver.h |7 src/libvirt.c| 65 ++ src/libvirt_public.syms |1 + 5 files changed, 107 insertions(+), 1 deletions(-) + * + * Since calling virDomainGetDiskErrors(dom, NULL, 0, 0) to get preferred size + * of @errors array and getting the errors are two separate operations, new + * disks may be hotplugged to the domain and new errors may be encountered + * between the two calls. Thus, this function may not return all disk errors + * because the supplied array is not large enough. Such errors may, however, + * be detected by listening to domain events. I like it. Nice improvement from v1. ACK. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 2/5] Remote protocol for virDomainGetDiskErrors
On 01/31/2012 12:26 PM, Jiri Denemark wrote: --- daemon/remote.c | 103 ++ src/remote/remote_driver.c | 77 +++ src/remote/remote_protocol.x | 23 +- src/remote_protocol-structs | 17 +++ 4 files changed, 219 insertions(+), 1 deletions(-) ACK. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 3/5] qemu: Implement virDomainGetDiskErrors
On 01/31/2012 12:26 PM, Jiri Denemark wrote: --- src/qemu/qemu_conf.h |1 + src/qemu/qemu_driver.c | 86 ++ src/qemu/qemu_monitor.c | 40 +++ src/qemu/qemu_monitor.h |1 + src/qemu/qemu_monitor_json.c |8 src/qemu/qemu_monitor_text.c | 15 +++ 6 files changed, 151 insertions(+), 0 deletions(-) ACK. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 4/5] virsh: Implement domblkerror command
On 01/31/2012 12:26 PM, Jiri Denemark wrote: This command lists all disk devices with errors --- tools/virsh.c | 78 +++ tools/virsh.pod |7 + 2 files changed, 85 insertions(+), 0 deletions(-) ACK. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 5/5] python: Add binding for virDomainGetDiskErrors
On 01/31/2012 12:26 PM, Jiri Denemark wrote: --- python/libvirt-override-api.xml |6 python/libvirt-override.c | 50 +++ 2 files changed, 56 insertions(+), 0 deletions(-) +if ((count = virDomainGetDiskErrors(domain, NULL, 0, 0)) 0) +return VIR_PY_NONE; This one's good. +ndisks = count; + +if (ndisks) { +if (!(disks = malloc(sizeof(*disks) * ndisks))) +return VIR_PY_NONE; You're not the first offender, so I don't care if you check this in as-is and let a subsequent patch clean this up, but this should be a place where we return a python OOM exception rather than None. + +LIBVIRT_BEGIN_ALLOW_THREADS; +count = virDomainGetDiskErrors(domain, disks, ndisks, 0); +LIBVIRT_END_ALLOW_THREADS; + +if (count 0) +goto cleanup; +} + +if (!(py_retval = PyDict_New())) +goto cleanup; This properly propagates the python exception. + +for (i = 0; i count; i++) { +PyDict_SetItem(py_retval, + libvirt_charPtrWrap(disks[i].disk), + libvirt_intWrap(disks[i].error)); Also a case where you're not the first offender (so fixing it can be saved for a later global cleanup), but we should: 1. check that libvirt_charPtrWrap() and libvirt_intWrap() aren't returning NULL (since PyDict_SetItem doesn't handle NULL well), and 2. check for PyDict_SetItem failures (in which case we free the portion of the dictionary collected so far and propagate the python exception). +} + +cleanup: +free(disks); I think this is a memory leak - if I'm correct, libvirt_charPtrWrap creates a new object that copies the incoming string to the new object's content, rather than stealing a reference to your malloc'd string. That means you need to loop over count and free each disk name before freeing disks. ACK with the memory leak in cleanup: fixed; you can leave the other issues for a later global cleanup of the python overrides. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/3] block rebase: wire up remote protocol
Nice and simple. * src/remote/remote_protocol.x (REMOTE_PROC_DOMAIN_BLOCK_REBASE): New RPC. * src/remote/remote_driver.c (remote_driver): Wire it up. * src/remote_protocol-structs: Regenerate. --- src/remote/remote_driver.c |1 + src/remote/remote_protocol.x | 10 +- src/remote_protocol-structs |8 3 files changed, 18 insertions(+), 1 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 031becd..d7bd561 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -4832,6 +4832,7 @@ static virDriver remote_driver = { .domainGetBlockJobInfo = remoteDomainGetBlockJobInfo, /* 0.9.4 */ .domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */ .domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */ +.domainBlockRebase = remoteDomainBlockRebase, /* 0.9.10 */ .setKeepAlive = remoteSetKeepAlive, /* 0.9.8 */ .isAlive = remoteIsAlive, /* 0.9.8 */ .nodeSuspendForDuration = remoteNodeSuspendForDuration, /* 0.9.8 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index b2c8426..6f035a9 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1147,6 +1147,13 @@ struct remote_domain_block_pull_args { unsigned hyper bandwidth; unsigned int flags; }; +struct remote_domain_block_rebase_args { +remote_nonnull_domain dom; +remote_nonnull_string path; +remote_string base; +unsigned hyper bandwidth; +unsigned int flags; +}; struct remote_domain_set_block_io_tune_args { remote_nonnull_domain dom; @@ -2708,7 +2715,8 @@ enum remote_procedure { REMOTE_PROC_STORAGE_VOL_RESIZE = 260, /* autogen autogen */ REMOTE_PROC_DOMAIN_PM_SUSPEND_FOR_DURATION = 261, /* autogen autogen */ -REMOTE_PROC_DOMAIN_GET_CPU_STATS = 262 /* skipgen skipgen */ +REMOTE_PROC_DOMAIN_GET_CPU_STATS = 262, /* skipgen skipgen */ +REMOTE_PROC_DOMAIN_BLOCK_REBASE = 263 /* autogen autogen */ /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index e9137a9..66965f8 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -813,6 +813,13 @@ struct remote_domain_block_pull_args { uint64_t bandwidth; u_int flags; }; +struct remote_domain_block_rebase_args { +remote_nonnull_domain dom; +remote_nonnull_string path; +remote_string base; +uint64_t bandwidth; +u_int flags; +}; struct remote_domain_set_block_io_tune_args { remote_nonnull_domain dom; remote_nonnull_string disk; @@ -2129,4 +2136,5 @@ enum remote_procedure { REMOTE_PROC_STORAGE_VOL_RESIZE = 260, REMOTE_PROC_DOMAIN_PM_SUSPEND_FOR_DURATION = 261, REMOTE_PROC_DOMAIN_GET_CPU_STATS = 262, +REMOTE_PROC_DOMAIN_BLOCK_REBASE = 263, }; -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/3] block rebase: initial qemu implementation
This is a trivial implementation, which works with the current released qemu 1.0 with backports of preliminary block pull but no partial rebase. Future patches will update the monitor handling to support an optional parameter for partial rebase; but as qemu 1.1 is unreleased, it can be in later patches, designed to be backported on top of the supported API. * src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Add parameter, and adjust callers. Drop redundant check. (qemuDomainBlockPull): Move guts... (qemuDomainBlockRebase): ...to new function. --- src/qemu/qemu_driver.c | 40 ++-- 1 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1b147a9..beb6e71 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11308,7 +11308,7 @@ cleanup: } static int -qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, +qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, const char *base, unsigned long bandwidth, virDomainBlockJobInfoPtr info, int mode) { @@ -11328,16 +11328,18 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, goto cleanup; } -if (!virDomainObjIsActive(vm)) { -qemuReportError(VIR_ERR_OPERATION_INVALID, -%s, _(domain is not running)); -goto cleanup; -} - device = qemuDiskPathToAlias(vm, path); if (!device) { goto cleanup; } +/* XXX - add a qemu capability check; if qemu 1.1 or newer, then + * validate and convert non-NULL base into something that can + * be passed as optional base argument. */ +if (base) { +qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, +_(partial block pull is not supported with this QEMU binary)); +goto cleanup; +} if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) 0) goto cleanup; @@ -11371,7 +11373,7 @@ static int qemuDomainBlockJobAbort(virDomainPtr dom, const char *path, unsigned int flags) { virCheckFlags(0, -1); -return qemuDomainBlockJobImpl(dom, path, 0, NULL, BLOCK_JOB_ABORT); +return qemuDomainBlockJobImpl(dom, path, NULL, 0, NULL, BLOCK_JOB_ABORT); } static int @@ -11379,7 +11381,7 @@ qemuDomainGetBlockJobInfo(virDomainPtr dom, const char *path, virDomainBlockJobInfoPtr info, unsigned int flags) { virCheckFlags(0, -1); -return qemuDomainBlockJobImpl(dom, path, 0, info, BLOCK_JOB_INFO); +return qemuDomainBlockJobImpl(dom, path, NULL, 0, info, BLOCK_JOB_INFO); } static int @@ -11387,24 +11389,33 @@ qemuDomainBlockJobSetSpeed(virDomainPtr dom, const char *path, unsigned long bandwidth, unsigned int flags) { virCheckFlags(0, -1); -return qemuDomainBlockJobImpl(dom, path, bandwidth, NULL, BLOCK_JOB_SPEED); +return qemuDomainBlockJobImpl(dom, path, NULL, bandwidth, NULL, + BLOCK_JOB_SPEED); } static int -qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth, -unsigned int flags) +qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base, + unsigned long bandwidth, unsigned int flags) { int ret; virCheckFlags(0, -1); -ret = qemuDomainBlockJobImpl(dom, path, bandwidth, NULL, BLOCK_JOB_PULL); +ret = qemuDomainBlockJobImpl(dom, path, base, bandwidth, NULL, + BLOCK_JOB_PULL); if (ret == 0 bandwidth != 0) -ret = qemuDomainBlockJobImpl(dom, path, bandwidth, NULL, +ret = qemuDomainBlockJobImpl(dom, path, NULL, bandwidth, NULL, BLOCK_JOB_SPEED); return ret; } static int +qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth, +unsigned int flags) +{ +return qemuDomainBlockRebase(dom, path, NULL, bandwidth, flags); +} + +static int qemuDomainOpenGraphics(virDomainPtr dom, unsigned int idx, int fd, @@ -11885,6 +11896,7 @@ static virDriver qemuDriver = { .domainGetBlockJobInfo = qemuDomainGetBlockJobInfo, /* 0.9.4 */ .domainBlockJobSetSpeed = qemuDomainBlockJobSetSpeed, /* 0.9.4 */ .domainBlockPull = qemuDomainBlockPull, /* 0.9.4 */ +.domainBlockRebase = qemuDomainBlockRebase, /* 0.9.10 */ .isAlive = qemuIsAlive, /* 0.9.8 */ .nodeSuspendForDuration = nodeSuspendForDuration, /* 0.9.8 */ .domainSetBlockIoTune = qemuDomainSetBlockIoTune, /* 0.9.8 */ -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/3] add virDomainBlockRebase
As discussed here: https://www.redhat.com/archives/libvir-list/2012-January/msg01448.html Qemu patch series here: https://lists.gnu.org/archive/html/qemu-devel/2012-01/msg03488.html This is the bare-minimum implementation for getting the API in place prior to the 0.9.10 rc1 freeze; I can later do patches to wire up the new optional argument to the qemu block_stream monitor command to actually make use of the new base argument. Eric Blake (3): block rebase: add new API virDomainBlockRebase block rebase: wire up remote protocol block rebase: initial qemu implementation docs/apibuild.py |1 + include/libvirt/libvirt.h.in |9 +++- src/driver.h |5 ++ src/libvirt.c| 84 ++ src/libvirt_public.syms |1 + src/qemu/qemu_driver.c | 40 +--- src/remote/remote_driver.c |1 + src/remote/remote_protocol.x | 10 - src/remote_protocol-structs |8 src/rpc/gendispatch.pl |1 + 10 files changed, 143 insertions(+), 17 deletions(-) -- 1.7.7.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/3] block rebase: add new API virDomainBlockRebase
Qemu is adding the ability to do a partial rebase. That is, given: base - intermediate - current virDomainBlockPull will produce: current but qemu now has the ability to leave base in the chain, to produce: base - current Note that current qemu can only do a forward merge, and only with the current image as the destination, which is fully described by this API without flags. But in the future, it may be possible to enhance this API for additional scenarios by using flags: Merging the current image back into a previous image (that is, undoing a live snapshot), could be done by passing base as the destination and flags with a bit requesting a backward merge. Merging any other part of the image chain, whether forwards (the backing image contents are pulled into the newer file) or backwards (the deltas recorded in the newer file are merged back into the backing file), could also be done by passing a new flag that says that base should be treated as an XML snippet rather than an absolute path name, where the XML could then supply the additional instructions of which part of the image chain is being merged into any other part. * include/libvirt/libvirt.h.in (virDomainBlockRebase): New declaration. * src/libvirt.c (virDomainBlockRebase): Implement it. * src/libvirt_public.syms (LIBVIRT_0.9.10): Export it. * src/driver.h (virDrvDomainBlockRebase): New driver callback. * src/rpc/gendispatch.pl (long_legacy): Add exemption. * docs/apibuild.py (long_legacy_functions): Likewise. --- docs/apibuild.py |1 + include/libvirt/libvirt.h.in |9 +++- src/driver.h |5 ++ src/libvirt.c| 84 ++ src/libvirt_public.syms |1 + src/rpc/gendispatch.pl |1 + 6 files changed, 99 insertions(+), 2 deletions(-) diff --git a/docs/apibuild.py b/docs/apibuild.py index c8b5994..1ac0281 100755 --- a/docs/apibuild.py +++ b/docs/apibuild.py @@ -1649,6 +1649,7 @@ class CParser: virDomainSetMemoryFlags: (False, (memory)), virDomainBlockJobSetSpeed : (False, (bandwidth)), virDomainBlockPull : (False, (bandwidth)), +virDomainBlockRebase : (False, (bandwidth)), virDomainMigrateGetMaxSpeed: (False, (bandwidth)) } def checkLongLegacyFunction(self, name, return_type, signature): diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index d9b9b95..40ad2f8 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1864,7 +1864,8 @@ int virDomainUpdateDeviceFlags(virDomainPtr domain, /** * virDomainBlockJobType: * - * VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull) + * VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull or + * virDomainBlockRebase) */ typedef enum { VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN = 0, @@ -1903,6 +1904,9 @@ intvirDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk, int virDomainBlockPull(virDomainPtr dom, const char *disk, unsigned long bandwidth, unsigned int flags); +int virDomainBlockRebase(virDomainPtr dom, const char *disk, + const char *base, unsigned long bandwidth, + unsigned int flags); /* Block I/O throttling support */ @@ -3502,7 +3506,8 @@ typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn, /** * virConnectDomainEventBlockJobStatus: * - * The final status of a virDomainBlockPullAll() operation + * The final status of a virDomainBlockPull() or virDomainBlockRebase() + * operation */ typedef enum { VIR_DOMAIN_BLOCK_JOB_COMPLETED = 0, diff --git a/src/driver.h b/src/driver.h index 2e2042e..79d845a 100644 --- a/src/driver.h +++ b/src/driver.h @@ -780,6 +780,10 @@ typedef int typedef int (*virDrvDomainBlockPull)(virDomainPtr dom, const char *path, unsigned long bandwidth, unsigned int flags); +typedef int +(*virDrvDomainBlockRebase)(virDomainPtr dom, const char *path, + const char *base, unsigned long bandwidth, + unsigned int flags); typedef int (*virDrvSetKeepAlive)(virConnectPtr conn, @@ -975,6 +979,7 @@ struct _virDriver { virDrvDomainGetBlockJobInfo domainGetBlockJobInfo; virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed; virDrvDomainBlockPull domainBlockPull; +virDrvDomainBlockRebase domainBlockRebase; virDrvSetKeepAlive setKeepAlive; virDrvConnectIsAlive isAlive; virDrvNodeSuspendForDuration nodeSuspendForDuration; diff --git a/src/libvirt.c b/src/libvirt.c index c609202..65d460d 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -1,6 +1,8 @@ error: * suitable default. Some hypervisors do not support this feature and will * return an error if bandwidth is not 0. * + * This is shorthand for
Re: [libvirt] [test-API][PATCH 1/2] Add 2 new functions in storageAPI
On 01/31/2012 04:45 PM, Wayne Sun wrote: * download(self, poolname, volname, stream, offset, length, flags = 0) * upload(self, poolname, volname, stream, offset, length, flags = 0) --- lib/storageAPI.py | 17 + 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/lib/storageAPI.py b/lib/storageAPI.py index 6c9d286..b0733f8 100644 --- a/lib/storageAPI.py +++ b/lib/storageAPI.py @@ -466,3 +466,20 @@ class StorageAPI(object): code = e.get_error_code() raise exception.LibvirtAPI(message, code) +def download(self, poolname, volname, stream, offset, length, flags = 0): +try: +volobj = self.get_volume_obj(poolname, volname) +return volobj.download(stream, offset, length, flags) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise exception.LibvirtAPI(message, code) + +def upload(self, poolname, volname, stream, offset, length, flags = 0): +try: +volobj = self.get_volume_obj(poolname, volname) +return volobj.upload(stream, offset, length, flags) +except libvirt.libvirtError, e: +message = e.get_error_message() +code = e.get_error_code() +raise exception.LibvirtAPI(message, code) ACK Guannan Ren -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] python: correct a copy-paste error
From: Alex Jia a...@redhat.com * python/libvirt-override-virStream.py: fix a copy-paste error in sendAll(). Signed-off-by: Alex Jia a...@redhat.com --- python/libvirt-override-virStream.py |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py index ff53a16..b5cec2a 100644 --- a/python/libvirt-override-virStream.py +++ b/python/libvirt-override-virStream.py @@ -86,7 +86,7 @@ ret = self.send(got) if ret == -2: -raise libvirtError(cannot use recvAll with +raise libvirtError(cannot use sendAll with nonblocking stream) def recv(self, nbytes): -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list