Re: [libvirt] [PATCH] qemu: qxl devices don't support multifunction yet

2011-09-30 Thread Laine Stump

On 09/27/2011 05:13 AM, Daniel P. Berrange wrote:

On Tue, Sep 27, 2011 at 01:19:20AM -0400, Laine Stump wrote:

On 09/19/2011 01:32 PM, Daniel P. Berrange wrote:

On Mon, Sep 19, 2011 at 07:16:22PM +0200, Marc-André Lureau wrote:

Hi hi

On Fri, Sep 16, 2011 at 1:38 PM, Marc-André Lureaumlur...@redhat.com   wrote:

How do we allow other devices to share the slot? It seems to me that
qemuDomainPCIAddressSetNextAddr() only allocate whole slot, while
making sure there is no conflicts on the same slot.

So, if the user wants to use multi function pci device, he should
specify the
pci address.

So adding a check such as:

if (!multiFunc   info-addr.pci.function != 0)
   return error(The %s device doesn't support multifunction address)


Wen, does that sound reasonable to you?

Daniel, did you had time to verify that PCI allocation is per-slot?

(It would be nice to get this workaround for the next release)

IMHO this kind of hack doesn't belong in libvirt. It is fine for distro
vendors to consider as a one off quick-hack for their packages of libvirt,
if they don't have time to fix the real QXL bug, but not for libvirt
upstream releases. QXL/QEMU should really be fixed since that's where the
problem appears to lie.

As it stands, Fedora 16 (currently using unpatched libvirt-0.9.6)
will be going into beta with QXL video broken for Windows guests, so
we need some kind of Fedora-only patch very soon (see the schedule
here: https://fedoraproject.org/wiki/Releases/16/Schedule -
fortunately just delayed another week)

The original patch in this thread:

   https://www.redhat.com/archives/libvir-list/2011-September/msg00534.html

of course doesn't include the above mentioned additional code, and
there isn't a followup patch. It would be very good to push a patch
to the F16 git for this so it would hopefully get into the beta, but
want to make sure what I push is the right thing, so a final
patch (and some testing by people with F16 hosts) would be very
helpful!

When we originally enabled multifunction for all PCI devices, we did so
in the belief that this was effectively a no-op for guest OSes. ie it
should not have changed guest OS behaviour at all, unless multiple devices
were actually inserted in the slot.

Evidentally this turns out to be incorrect. In other words we introduced
a guest ABI change. This is very bad, because our stated goal is to have
a stable guest ABI across libvirt  QEMU releases.

Thus IMHO we need to disable *all* setting of the 'multifunction=on'
parameter for all guests by default, to unbreak the ABI compatibility.

Then we should introduce a new parameter 'multifunction='on' in the
address type=pci  element to allow it to be optionally enabled per
device.


I just sent a patch to do this, in a separate thread so it doesn't get 
buried:


  https://www.redhat.com/archives/libvir-list/2011-September/msg01291.html

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] bug: try to take disk snapshot for LVM2 Volume

2011-09-30 Thread MATSUDA, Daiki
(2011/09/30 14:26), MATSUDA, Daiki wrote:
 I tried the new snapshot function implemented by Eric Blake.
 
 It works very well for QCOW2 disk image system.
 But I often use LVM2 volume for QEMU virtual machines and tried to take
 disk snapshot by virsh command ( snapshot-create DOMNAME --disk-only).
 So, finally qemu monitor command 'snapshot_blkdev' accepts the LVM2
 volume and create QCOW2 snapshot image. In addition, domain's
 configuration file is replaced to use snapshot disk image instead of
 LVM2 volume.
 
 configuration file
 from
 
 disk type='block' device='disk
driver name='qemu' type='raw' cache='none'/
source dev='dev/VG1/LVM2_dom'/
 
 
 to
 disk type='block' device='disk
driver name='qemu' type='qcow2' cache='none'/
source dev='dev/VG1/LVM2_dom.1317357844'/
 
 After then, the domain runs well till it is shutdowned. I started the
 domain, but it does not with following error
 virtsh # start LVM2_dom
 error: Failed to start domain LVM2_dom
 error: 内部エラー Process exited while reading console log output: char

Sorry, upper is
error: internal error Process exited while reading console log output: char

 device redirected to /dev/pts/7
 qemu: could not open disk image /dev/VG1/LVM2_dom.1317357844: Invalid
 argument.
 
 I think that if the volume but qcow2 is given libvirt should be refuse,
 e.g. in qemuDomainSnapshotCreateDiskActive() with voulme driver type.
 But currently the structures concerning with snapshot or disk has no
 member to hold such a volume driver information. In addition, as we want
 to add the LVM2 and other volume snapshot function, we hope you add its
 information and fix.
 
 Regards
 MATSUDA Daiki
 
 --
 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: Check for outstanding async job too

2011-09-30 Thread Michal Privoznik
On 29.09.2011 17:26, Eric Blake wrote:
 On 09/29/2011 09:01 AM, Michal Privoznik wrote:
 Currently, qemuDomainGetXMLDesc and qemudDomainGetInfo check for
 outstanding synchronous job before (eventual) monitor entering.
 However, there can be already async job set, e.g. migration.
 ---
   src/qemu/qemu_domain.c |   12 +---
   src/qemu/qemu_domain.h |2 ++
   src/qemu/qemu_driver.c |4 ++--
   3 files changed, 13 insertions(+), 5 deletions(-)
 
 Looks reasonable.  ACK.
 

Thanks, pushed.

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/2] conf: remove unused VIR_ENUM_DECL

2011-09-30 Thread Daniel Veillard
On Fri, Sep 30, 2011 at 01:40:45AM -0400, Laine Stump wrote:
 While adding a new enum, I noticed a VIR_ENUM_DECL for a type that
 doesn't exist. There is also of course no matching VIR_ENUM_IMPL for
 it.
 ---
  src/conf/domain_conf.h |1 -
  1 files changed, 0 insertions(+), 1 deletions(-)
 
 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
 index 0bc0042..4a99ea4 100644
 --- a/src/conf/domain_conf.h
 +++ b/src/conf/domain_conf.h
 @@ -1830,7 +1830,6 @@ VIR_ENUM_DECL(virDomainLifecycle)
  VIR_ENUM_DECL(virDomainLifecycleCrash)
  VIR_ENUM_DECL(virDomainDevice)
  VIR_ENUM_DECL(virDomainDeviceAddress)
 -VIR_ENUM_DECL(virDomainDeviceAddressMode)
  VIR_ENUM_DECL(virDomainDisk)
  VIR_ENUM_DECL(virDomainDiskDevice)
  VIR_ENUM_DECL(virDomainDiskBus)

 ACK,

 Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 2/2] qemu: make PCI multifunction support more manual

2011-09-30 Thread Daniel Veillard
On Fri, Sep 30, 2011 at 01:40:46AM -0400, Laine Stump wrote:
 When support for was added for PCI multifunction cards (in commit
 9f8baf, first included in libvirt 0.9.3), it was done by always
 turning on the multifunction bit for all PCI devices. Since that time
 it has been realized that this is not an ideal solution, and that the
 multifunction bit must be selectively turned on. For example, see
 
   https://bugzilla.redhat.com/show_bug.cgi?id=728174
 
 and the discussion before and after
 
   https://www.redhat.com/archives/libvir-list/2011-September/msg01036.html
 
 This patch modifies multifunction support so that the multifunction=on
 option is only added to the qemu commandline for a device if its PCI
 address definition has the attribute multifunction='on', e.g.:
 
   address type='pci' domain='0x' bus='0x00'
slot='0x04' function='0x0' multifunction='on'/
[...]
 diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
 index 4972fac..cffaac2 100644
 --- a/docs/schemas/domaincommon.rng
 +++ b/docs/schemas/domaincommon.rng
 @@ -2118,6 +2118,14 @@
  attribute name=function
ref name=pciFunc/
  /attribute
 +optional
 +  attribute name=multifunction
 +choice
 +  valueon/value
 +  valueoff/value
 +/choice
 +  /attribute
 +/optional
/define
define name=driveaddress
  optional

 okay

[...]
 +VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti,
 +  VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST,
 +  default,
 +  on,
 +  off)
 +
  VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
block,
file,
 @@ -1652,6 +1658,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
info-addr.pci.bus,
info-addr.pci.slot,
info-addr.pci.function);
[...]
  
 +if (multi 
 +((addr-multi = virDomainDeviceAddressPciMultiTypeFromString(multi)) 
  0)) {
 +virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 + _(Unknown value '%s' for address 
 'multifunction' attribute),
 + multi);
 +goto cleanup;
 +
 +}

  This code allows mutifunction=default input

  if you make the test = 0 then it should reject default as
  expected...

  if (!virDomainDevicePCIAddressIsValid(addr)) {
  virDomainReportError(VIR_ERR_INTERNAL_ERROR, %s,
   _(Insufficient specification for PCI 
 address));
[...]
 @@ -1391,11 +1397,11 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
  virBufferAsprintf(buf, ,bus=pci.0);
  else
  virBufferAsprintf(buf, ,bus=pci);
 -if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION))
 -virBufferAsprintf(buf, ,multifunction=on,addr=0x%x.0x%x,
 -  info-addr.pci.slot, info-addr.pci.function);
 -else
 -virBufferAsprintf(buf, ,addr=0x%x, info-addr.pci.slot);
 +if (info-addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON)
 +virBufferAddLit(buf, ,multifunction=on);


  Hum seems to me that if the users explicitely specified mutifunction=off
then that ought to be saved, and hence
   else if (info-addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_OFF)
   virBufferAddLit(buf, ,multifunction=off);

need to be added (since it's not the default which is 0 that won't
pollute XML where it's not specified).

 +virBufferAsprintf(buf, ,addr=0x%x, info-addr.pci.slot);
 +if (info-addr.pci.function != 0)
 +   virBufferAsprintf(buf, .0x%x, info-addr.pci.function);
  } else if (info-type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
  virBufferAsprintf(buf, ,bus=);
  qemuUsbId(buf, info-addr.usb.bus);

  ACK with those 2 problems fixed

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/2] snapshot: implement getparent for esx

2011-09-30 Thread Daniel Veillard
On Thu, Sep 29, 2011 at 02:38:24PM -0600, Eric Blake wrote:
 Pretty easy to paste together compared to existing functions.
 
 * src/esx/esx_driver.c (esxDomainSnapshotGetParent): New function.
 ---
 
 I can only compile-test this; I'm relying on someone with an actual
 esx setup to actually test it.  Also, I didn't see anything in
 existing code that would efficiently implement
 virDomainSnapshotNumChildren; there may an API that I'm not aware of,
 but someone else will have to implement that API (Matthias?)

  The 2 patches looks just fine to me but agreed someone with the
setup should check those and give the final ACK :-)

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] Improve the daemon man page

2011-09-30 Thread Daniel Veillard
Add informations about the handling of USR2 and fatal signals
and document the default log location.

diff --git a/daemon/libvirtd.pod.in b/daemon/libvirtd.pod.in
index 6e699b8..269e81f 100644
--- a/daemon/libvirtd.pod.in
+++ b/daemon/libvirtd.pod.in
@@ -69,6 +69,10 @@ Display version information then exit.
 =head1 SIGNALS
 
 On receipt of BSIGHUP libvirtd will reload its configuration.
+On receipt of BSIGUSR2 or other fatal signals like BSIGFPE,
+BSIGSEGV, BSIGILL, BSIGABRT or BSIGBUS, libvirtd will dump
+its internal debug message buffer content to the default log output,
+usually B@localstatedir@/log/libvirt/libvirtd.log
 
 =head1 FILES
 
@@ -105,6 +109,11 @@ The TLS BServer private key libvirtd will use.
 
 The PID file to use, unless overridden by the B-p|B--pid-file option.
 
+=item F@localstatedir@/log/libvirt/libvirtd.log
+
+The default file where libvirtd will save its logs, this can be overriden
+from the B@sysconfdir@/libvirtd.conf configuration file.
+
 =back
 
 =head1 EXAMPLES

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/2] snapshot: implement getparent for esx

2011-09-30 Thread Matthias Bolte
2011/9/30 Daniel Veillard veill...@redhat.com:
 On Thu, Sep 29, 2011 at 02:38:24PM -0600, Eric Blake wrote:
 Pretty easy to paste together compared to existing functions.

 * src/esx/esx_driver.c (esxDomainSnapshotGetParent): New function.
 ---

 I can only compile-test this; I'm relying on someone with an actual
 esx setup to actually test it.  Also, I didn't see anything in
 existing code that would efficiently implement
 virDomainSnapshotNumChildren; there may an API that I'm not aware of,
 but someone else will have to implement that API (Matthias?)

  The 2 patches looks just fine to me but agreed someone with the
 setup should check those and give the final ACK :-)

 Daniel

I'll probably have some time this weekend to have a look at it.

-- 
Matthias Bolte
http://photron.blogspot.com

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/1] [RFC] Parallels Server Bare Metal driver stub

2011-09-30 Thread Dmitry Mishin
On Wednesday, September 28, 2011 06:10:19 PM Daniel P. Berrange wrote:
 Any pointers ? All I found was
 http://www.parallels.com/ptn/download/sdk/
  
   and it's quite silent on code availability and Licence for the
   libraries.
  
  It has a proprietary license and not open sourced now. Is it a problem? 
 
 If the license is not LGPLv2+ compatible, then it can't be used
 by libvirt, regardless of whether it is directly linked, or
 dlopened. In other words using 'dlopen' doesn't magically solve
 the license compatibility problem.
Will we solve the issue if libvirt will be statically linked with SDK library 
(as Daniel requests) and SDK library itself will be distributed in binary form 
under BSD license conditions (which is LGPLv2 compatible)?
 
-- 
Thanks,
Dmitry.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/1] [RFC] Parallels Server Bare Metal driver stub

2011-09-30 Thread Dmitry Mishin
 libvirt will be statically linked with SDK library
Sorry, I meant dynamically but at compilation stage instead of dlopen()

On Friday, September 30, 2011 12:21:05 PM Dmitry Mishin wrote:
 On Wednesday, September 28, 2011 06:10:19 PM Daniel P. Berrange wrote:
  Any pointers ? All I found was
  http://www.parallels.com/ptn/download/sdk/

and it's quite silent on code availability and Licence for the
libraries.
   
   It has a proprietary license and not open sourced now. Is it a problem?
  
  If the license is not LGPLv2+ compatible, then it can't be used
  by libvirt, regardless of whether it is directly linked, or
  dlopened. In other words using 'dlopen' doesn't magically solve
  the license compatibility problem.
 
 Will we solve the issue if libvirt will be statically linked with SDK
 library (as Daniel requests) and SDK library itself will be distributed in
 binary form under BSD license conditions (which is LGPLv2 compatible)?

-- 
Thanks,
Dmitry.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/1] [RFC] Parallels Server Bare Metal driver stub

2011-09-30 Thread Daniel P. Berrange
On Fri, Sep 30, 2011 at 12:21:05PM +0400, Dmitry Mishin wrote:
 On Wednesday, September 28, 2011 06:10:19 PM Daniel P. Berrange wrote:
  Any pointers ? All I found was
  http://www.parallels.com/ptn/download/sdk/
   
and it's quite silent on code availability and Licence for the
libraries.
   
   It has a proprietary license and not open sourced now. Is it a problem? 
  
  If the license is not LGPLv2+ compatible, then it can't be used
  by libvirt, regardless of whether it is directly linked, or
  dlopened. In other words using 'dlopen' doesn't magically solve
  the license compatibility problem.
 Will we solve the issue if libvirt will be statically linked with SDK library 
 (as Daniel requests) and SDK library itself will be distributed in binary 
 form 
 under BSD license conditions (which is LGPLv2 compatible)?

Yes, linking to a BSD licensed library is fine from a licensing point
of view.

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] Adding new filesystem 'proxy' to 9p

2011-09-30 Thread Daniel P. Berrange
On Thu, Sep 29, 2011 at 11:42:47PM +0530, M. Mohan Kumar wrote:
 On Wednesday, September 28, 2011 08:29:06 PM Daniel P. Berrange wrote:
  On Wed, Sep 28, 2011 at 07:49:34PM +0530, M. Mohan Kumar wrote:
   Pass-through security model in QEMU 9p server needs root privilege to do
   few file operations (like chown, chmod to any mode/uid:gid).  There are
   two issues in pass-through security model
   
   1) TOCTTOU vulnerability: Following symbolic links in the server could
   provide access to files beyond 9p export path.
   
   2) When libvirt is configured to run qemu as non-root user (for example,
   if qemu is configured to run as normal user 'qemu'), running file
   operations on pass-through security model would fail because it needs
   root privileges.
   
   To overcome above issues, following approach is suggested: A new
   filesytem type 'proxy' is introduced. Proxy FS uses chroot + socket
   combination for securing the vulnerability known with following symbolic
   links. Intention of adding a new filesystem type is to allow qemu to run
   in non-root mode, but doing privileged operations using socket IO.
   
   A new binary (known as proxy helper) will be provided as part of qemu.
   Proxy helper will chroot into 9p export path and create a socket pair or
   a named socket based on the command line parameter. Qemu and proxy
   helper will communicate using this socket.
   
   We need following changes in the libvirt code to accomodate new 'proxy'
   filesystem type:
   If qemu 9p server is configured to use 'proxy' FS, libvirt will do
   * Create a socket pair
   * invoke proxy_helper binary with one of the socket id from the pair as
   command line parameters to it with root privilege
   * invoke qemu with one of socket id from the pair as paramter to qemu
   virtfs after dropping to the configured user privilege.
   
   ie, libvirt will invoke proxy_helper as:
   proxy_helper -i socket_fd_from_socket_pair -p 9p-path-to-export
   
   and qemu will be invoked with following virtfs parameter:
   -virtfs proxy,id=id,sock_fd=socket_fd_from_socket_pair
 
 ,path=/tmp/,security_model=prox,mount_tag=v_pass
 
 
 Thank you Daniel for the quick response, I was on leave and I could not 
 respond to you immediately.
   
  Interesting proposal. Explicitly comparing the security characteristics
  of running QEMU as root, vs using the proxy helper
  
   * QEMU run as root
  
   - QEMU is root, with full capabilities
   - QEMU has read/write any file/dir, regardless of whether it is
 exported via 9p
  
   * QEMU run as non-root, with proxy_helper root
  
   - QEMU is non-root, with no capabilities
   - QEMU has write to only files with matching UID/GID
   - proxy_helper is root, with full capabilities
   - proxy_helper has read/write to any file/dir
  
  Since QEMU can send arbitrary FS calls to the proxy_helper, the overall
  security of the system clearly depends on the security of the proxy_helper
  process.
 QEMU can't send arbitrary FS calls to the proxy helper. All interfaces are 
 defined and if qemu sends arbitrary FS command, proxy helper would return an 
 EIO. For example T_OPEN is one of the supported interface between 9p qemu 
 server and proxy helper. For more information please look at my chroot 
 patchset that I posted to qemu-devel few weeks ago. 
 http://lists.gnu.org/archive/html/qemu-devel/2011-09/msg00671.html

Ok, perhaps I didn't explain what I meant by 'arbitrary FS calls' very
well here.

Lets, say the communication protocol between QEMU and the proxy helper
has a set of FS calls to cover 'read', 'write', 'open', 'unlink', 'link'.
And we have a 9pfs directory to give to the guest '/export/to-the-guest'.

In normal use, the QEMU process can send things like

open(/export/to-the-guest/somefile).

A malicious QEMU can send 

open(/etc/shadow)

Or any other path that it cares about, whether or not, the path is within
the location exported to the 9pfs server. The security of the overall
system, thus relies on the proxy helper enforcing that the arbitrary
FS calls from QEMU, are in fact only within '/export/to-the-guest' and
not other directories.

  If we assume that QEMU gets exploited, and that QEMU can find some flaw
  in the proxy_helper that it can exploit, what damage can the proxy_helper
  do ?  Clearly we want it to not be able to read/write any files other
  than those exported, even when it becomes compromised, ideally also
  without requiring SELinux/AppArmour to make it safe. If proxy_helper
  is running as root with full capabilities, it can trivially escape
  the chroot[1], so this isn't all that nice for overall system security.

 When proxy helper process is forked, its made sure that all open file 
 descriptor are closed except the socket descriptor, so that proxy helper 
 can't 
 escape chroot jail.

Unfortunately that is not sufficient. Even if you have closed all
file descriptors except the socket, you can still 

[libvirt] [RFC PATCH 0/2] Add some systemtap probes to RPC code

2011-09-30 Thread Daniel P. Berrange
Trying to investigate  debug the keepalive series I decided we
needed a better way to trace the RPC protocol than the regular
debug messages. Ideally we'd have a wireshark dissector but that
seems like it will be an awful lot of work todo. So instead I
have added a few systemtap probes to the RPC call which fire
everytime an RPC message is queued for dispatch, or a completed
RPC message is read off the wire

Now I can see all communications using a script like this

# cat  watch.stp EOF
function msginfo(prefix, prog, version, proc, type, status, serial)
{
  if (type == 0)
typestr = call
  else if (type == 1)
typestr = reply
  else if (type == 2)
typestr = message
  else if (type == 3)
typestr = stream
  else
typestr = unknown

  if (status == 0)
statusstr = ok
  else if (status == 1)
statusstr = error
  else if (status == 2)
statusstr = continue
  else
statusstr = unknown

  printf(%s program: %-10d version: %d procedure: %-4d type: %u:%-9s status: 
%u:%-9s serial: %-4d\n,
 prefix, prog, version, proc, type, typestr, status, statusstr, serial);
}

probe libvirt.rpc.server_msg_rx {
   msginfo(S, prog, vers, proc, type, status, serial)
}
probe libvirt.rpc.server_msg_tx {
   msginfo(S, prog, vers, proc, type, status, serial)
}
probe libvirt.rpc.client_msg_rx {
   msginfo(C, prog, vers, proc, type, status, serial)
}
probe libvirt.rpc.client_msg_tx {
   msginfo(C, prog, vers, proc, type, status, serial)
}
EOF

# stap  watch.stp 
C program: 536903814  version: 1 procedure: 66   type: 0:call  status: 
0:okserial: 0   
S program: 536903814  version: 1 procedure: 66   type: 0:call  status: 
0:okserial: 0   
S program: 536903814  version: 1 procedure: 66   type: 1:reply status: 
0:okserial: 0   
C program: 536903814  version: 1 procedure: 66   type: 1:reply status: 
0:okserial: 0   
C program: 536903814  version: 1 procedure: 1type: 0:call  status: 
0:okserial: 1   
S program: 536903814  version: 1 procedure: 1type: 0:call  status: 
0:okserial: 1   
S program: 536903814  version: 1 procedure: 1type: 1:reply status: 
0:okserial: 1   
C program: 536903814  version: 1 procedure: 1type: 1:reply status: 
0:okserial: 1   
C program: 536903814  version: 1 procedure: 110  type: 0:call  status: 
0:okserial: 2   
S program: 536903814  version: 1 procedure: 110  type: 0:call  status: 
0:okserial: 2   
S program: 536903814  version: 1 procedure: 110  type: 1:reply status: 
0:okserial: 2   
C program: 536903814  version: 1 procedure: 110  type: 1:reply status: 
0:okserial: 2   
C program: 536903814  version: 1 procedure: 23   type: 0:call  status: 
0:okserial: 3   
S program: 536903814  version: 1 procedure: 23   type: 0:call  status: 
0:okserial: 3   
S program: 536903814  version: 1 procedure: 23   type: 1:reply status: 
0:okserial: 3   
C program: 536903814  version: 1 procedure: 23   type: 1:reply status: 
0:okserial: 3   
C program: 536903814  version: 1 procedure: 19   type: 0:call  status: 
0:okserial: 4   
S program: 536903814  version: 1 procedure: 19   type: 0:call  status: 
0:okserial: 4   
S program: 536903814  version: 1 procedure: 19   type: 1:reply status: 
0:okserial: 4   
C program: 536903814  version: 1 procedure: 19   type: 1:reply status: 
0:okserial: 4   
C program: 536903814  version: 1 procedure: 16   type: 0:call  status: 
0:okserial: 5   
S program: 536903814  version: 1 procedure: 16   type: 0:call  status: 
0:okserial: 5   
S program: 536903814  version: 1 procedure: 16   type: 1:reply status: 
0:okserial: 5   
C program: 536903814  version: 1 procedure: 16   type: 1:reply status: 
0:okserial: 5   
C program: 536903814  version: 1 procedure: 151  type: 0:call  status: 
0:okserial: 6   
S program: 536903814  version: 1 procedure: 151  type: 0:call  status: 
0:okserial: 6   
S program: 536903814  version: 1 procedure: 151  type: 1:reply status: 
0:okserial: 6   
C program: 536903814  version: 1 procedure: 151  type: 1:reply status: 
0:okserial: 6   
C program: 536903814  version: 1 procedure: 15   type: 0:call  status: 
0:okserial: 7   
S program: 536903814  version: 1 procedure: 15   type: 0:call  status: 
0:okserial: 7   
S program: 536903814  version: 1 procedure: 15   type: 1:reply status: 
0:okserial: 7   
C program: 536903814  version: 1 procedure: 15   type: 1:reply status: 
0:okserial: 7   
C program: 536903814  version: 1 procedure: 183  type: 0:call  status: 
0:okserial: 8   
S program: 536903814  version: 1 procedure: 183  type: 0:call  status: 
0:okserial: 8   
S program: 536903814  version: 1 procedure: 183  type: 1:reply 

[libvirt] [PATCH 2/2] Add some DTrace/SystemTAP probes to the RPC code

2011-09-30 Thread Daniel P. Berrange
From: Daniel P. Berrange berra...@redhat.com

---
 daemon/libvirtd.h|   28 +---
 src/Makefile.am  |   28 +++--
 src/internal.h   |   70 ++
 src/libvirt.stp  |   35 +
 src/probes.d |7 
 src/rpc/virnetclient.c   |   13 +--
 src/rpc/virnetserverclient.c |9 +
 7 files changed, 157 insertions(+), 33 deletions(-)
 create mode 100644 src/libvirt.stp
 create mode 100644 src/probes.d

diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index 6d6460e..43f5921 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -45,32 +45,8 @@
 #   include probes.h
 #  endif /* LIBVIRTD_PROBES_H */
 
-/* Systemtap 1.2 headers have a bug where they cannot handle a
- * variable declared with array type.  Work around this by casting all
- * arguments.  This is some gross use of the preprocessor because
- * PROBE is a var-arg macro, but it is better than the alternative of
- * making all callers to PROBE have to be aware of the issues.  And
- * hopefully, if we ever add a call to PROBE with other than 2 or 3
- * end arguments, you can figure out the pattern to extend this hack.
- */
-#  define VIR_COUNT_ARGS(...) VIR_ARG5(__VA_ARGS__, 4, 3, 2, 1)
-#  define VIR_ARG5(_1, _2, _3, _4, _5, ...) _5
-#  define VIR_ADD_CAST_EXPAND(a, b, ...) VIR_ADD_CAST_PASTE(a, b, __VA_ARGS__)
-#  define VIR_ADD_CAST_PASTE(a, b, ...) a##b(__VA_ARGS__)
-
-/* The double cast is necessary to silence gcc warnings; any pointer
- * can safely go to intptr_t and back to void *, which collapses
- * arrays into pointers; while any integer can be widened to intptr_t
- * then cast to void *.  */
-#  define VIR_ADD_CAST(a) ((void *)(intptr_t)(a))
-#  define VIR_ADD_CAST2(a, b)   \
-VIR_ADD_CAST(a), VIR_ADD_CAST(b)
-#  define VIR_ADD_CAST3(a, b, c)\
-VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c)
-
-#  define VIR_ADD_CASTS(...)\
-VIR_ADD_CAST_EXPAND(VIR_ADD_CAST, VIR_COUNT_ARGS(__VA_ARGS__),  \
-__VA_ARGS__)
+# undef PROBE_EXPAND
+# undef PROBE
 
 #  define PROBE_EXPAND(NAME, ARGS) NAME(ARGS)
 #  define PROBE(NAME, FMT, ...)  \
diff --git a/src/Makefile.am b/src/Makefile.am
index 7281802..d974904 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,6 +25,9 @@ AM_LDFLAGS = $(COVERAGE_LDFLAGS)
 EXTRA_DIST = $(conf_DATA) util/keymaps.csv
 
 BUILT_SOURCES =
+CLEANFILES =
+DISTCLEANFILES =
+MAINTAINERCLEANFILES =
 
 if WITH_NETWORK
 UUID=$(shell uuidgen 2/dev/null)
@@ -1248,6 +1251,25 @@ libvirt_la_CFLAGS = -DIN_LIBVIRT $(AM_CFLAGS)
 # picked out for us.
 libvirt_la_DEPENDENCIES = $(libvirt_la_BUILT_LIBADD) $(LIBVIRT_SYMBOL_FILE)
 
+if WITH_DTRACE
+libvirt_la_LIBADD += probes.o
+nodist_libvirt_la_SOURCES = probes.h
+
+BUILT_SOURCES += probes.h
+
+tapsetdir = $(datadir)/systemtap/tapset
+tapset_DATA = libvirt.stp
+
+probes.h: probes.d
+   $(AM_V_GEN)$(DTRACE) -o $@ -h -s $
+
+probes.o: probes.d
+   $(AM_V_GEN)$(DTRACE) -o $@ -G -s $
+
+CLEANFILES += probes.h probes.o
+endif
+
+
 # Create an automake convenience library version of libvirt_la,
 # just for testing, since the test harness requires access to internal
 # bits and pieces that we don't want to make publicly accessible.
@@ -1549,6 +1571,6 @@ if WITH_NETWORK
 endif
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt ||:
 
-CLEANFILES = *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda *.i *.s
-DISTCLEANFILES = $(GENERATED_SYM_FILES)
-MAINTAINERCLEANFILES = $(REMOTE_DRIVER_GENERATED) $(VIR_NET_RPC_GENERATED) 
$(ESX_DRIVER_GENERATED)
+CLEANFILES += *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda *.i *.s
+DISTCLEANFILES += $(GENERATED_SYM_FILES)
+MAINTAINERCLEANFILES += $(REMOTE_DRIVER_GENERATED) $(VIR_NET_RPC_GENERATED) 
$(ESX_DRIVER_GENERATED)
diff --git a/src/internal.h b/src/internal.h
index 1997031..18867fd 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -242,4 +242,74 @@
 /* divide value by size, rounding up */
 # define VIR_DIV_UP(value, size) (((value) + (size) - 1) / (size))
 
+
+# if WITH_DTRACE
+#  ifndef LIBVIRT_PROBES_H
+#   define LIBVIRT_PROBES_H
+#   include probes.h
+#  endif /* LIBVIRT_PROBES_H */
+
+/* Systemtap 1.2 headers have a bug where they cannot handle a
+ * variable declared with array type.  Work around this by casting all
+ * arguments.  This is some gross use of the preprocessor because
+ * PROBE is a var-arg macro, but it is better than the alternative of
+ * making all callers to PROBE have to be aware of the issues.  And
+ * hopefully, if we ever add a call to PROBE with other than 2 or 3
+ * end arguments, you can figure out the pattern to extend this hack.
+ */
+#  define VIR_COUNT_ARGS(...) VIR_ARG9(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)
+#  define VIR_ARG9(_1, _2, _3, _4, _5, _6, _7, _8, _9, ...) _9
+#  define VIR_ADD_CAST_EXPAND(a, b, ...) 

[libvirt] [PATCH 1/2] Make libvirt.so include the RPC server code

2011-09-30 Thread Daniel P. Berrange
From: Daniel P. Berrange berra...@redhat.com

To avoid static linking libvirtd to the RPC server code, which
then prevents sane introduction of DTrace probes, put it all
in the libvirt.so, and export it

* daemon/Makefile.am: Don't link to RPC libraries
* src/Makefile.am: Link all RPC libraries to libvirt.so
* src/libvirt_private.syms: Export all RPC functions
---
 daemon/Makefile.am   |2 -
 src/Makefile.am  |2 +-
 src/libvirt_private.syms |   76 ++
 3 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 690bf85..046bff3 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -110,8 +110,6 @@ libvirtd_LDADD =\
$(POLKIT_LIBS)
 
 libvirtd_LDADD += \
-   ../src/libvirt-net-rpc-server.la \
-   ../src/libvirt-net-rpc.la \
../src/libvirt-qemu.la
 
 if ! WITH_DRIVER_MODULES
diff --git a/src/Makefile.am b/src/Makefile.am
index d983d28..7281802 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -612,7 +612,7 @@ libvirt_driver_remote_la_CFLAGS =   
\
-I@top_srcdir@/src/rpc  \
$(AM_CFLAGS)
 libvirt_driver_remote_la_LDFLAGS = $(AM_LDFLAGS)
-libvirt_driver_remote_la_LIBADD = $(GNUTLS_LIBS) libvirt-net-rpc-client.la 
libvirt-net-rpc.la
+libvirt_driver_remote_la_LIBADD = $(GNUTLS_LIBS) libvirt-net-rpc-client.la 
libvirt-net-rpc-server.la libvirt-net-rpc.la
 if WITH_DRIVER_MODULES
 libvirt_driver_remote_la_LIBADD += ../gnulib/lib/libgnu.la
 libvirt_driver_remote_la_LDFLAGS += -module -avoid-version
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c2a3fab..e086253 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1162,6 +1162,82 @@ virFileDirectFdNew;
 virFileFclose;
 virFileFdopen;
 
+# rpc
+virNetMessageClear;
+virNetMessageEncodeHeader;
+virNetMessageEncodePayload;
+virNetMessageFree;
+virNetMessageNew;
+virNetMessageQueuePush;
+virNetMessageQueueServe;
+virNetMessageSaveError;
+virNetSASLContextCheckIdentity;
+virNetSASLContextNewServer;
+virNetSASLSessionExtKeySize;
+virNetSASLSessionFree;
+virNetSASLSessionGetIdentity;
+virNetSASLSessionGetKeySize;
+virNetSASLSessionListMechanisms;
+virNetSASLSessionNewServer;
+virNetSASLSessionSecProps;
+virNetSASLSessionServerStart;
+virNetSASLSessionServerStep;
+virNetServerAddProgram;
+virNetServerAddService;
+virNetServerAddSignalHandler;
+virNetServerAutoShutdown;
+virNetServerClientAddFilter;
+virNetServerClientClose;
+virNetServerClientDelayedClose;
+virNetServerClientFree;
+virNetServerClientGetAuth;
+virNetServerClientGetFD;
+virNetServerClientGetLocalIdentity;
+virNetServerClientGetPrivateData;
+virNetServerClientGetReadonly;
+virNetServerClientGetTLSKeySize;
+virNetServerClientHasTLSSession;
+virNetServerClientImmediateClose;
+virNetServerClientIsSecure;
+virNetServerClientLocalAddrString;
+virNetServerClientRef;
+virNetServerClientRemoteAddrString;
+virNetServerClientRemoveFilter;
+virNetServerClientSendMessage;
+virNetServerClientSetCloseHook;
+virNetServerClientSetIdentity;
+virNetServerClientSetPrivateData;
+virNetServerClientSetSASLSession;
+virNetServerClose;
+virNetServerFree;
+virNetServerIsPrivileged;
+virNetServerNew;
+virNetServerProgramFree;
+virNetServerProgramGetID;
+virNetServerProgramGetVersion;
+virNetServerProgramMatches;
+virNetServerProgramNew;
+virNetServerProgramRef;
+virNetServerProgramSendReplyError;
+virNetServerProgramSendStreamData;
+virNetServerProgramSendStreamError;
+virNetServerQuit;
+virNetServerRef;
+virNetServerRun;
+virNetServerServiceFree;
+virNetServerServiceNewTCP;
+virNetServerServiceNewUNIX;
+virNetServerUpdateServices;
+virNetSocketDupFD;
+virNetSocketFree;
+virNetSocketGetFD;
+virNetSocketListen;
+virNetSocketNewConnectTCP;
+virNetSocketNewListenUNIX;
+virNetTLSContextFree;
+virNetTLSContextNewServer;
+virNetTLSContextNewServerPath;
+
 
 # virpidfile.h
 virPidFileAcquire;
-- 
1.7.6.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] build: Add missing package and c:include in gir

2011-09-30 Thread Marc-André Lureau
This is required for generating source-level bindings, for vala
---
 libvirt-gconfig/Makefile.am |2 ++
 libvirt-glib/Makefile.am|2 ++
 libvirt-gobject/Makefile.am |2 ++
 3 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/libvirt-gconfig/Makefile.am b/libvirt-gconfig/Makefile.am
index 6f1c628..180d5ee 100644
--- a/libvirt-gconfig/Makefile.am
+++ b/libvirt-gconfig/Makefile.am
@@ -72,6 +72,8 @@ LibvirtGConfig-1.0.gir: libvirt-gconfig-1.0.la 
$(G_IR_SCANNER) Makefile.am
 -I$(top_builddir) \
 --verbose \
 --pkg=gobject-2.0 \
+--c-include=libvirt-gconfig/libvirt-gconfig.h \
+--pkg-export=libvirt-gconfig-1.0 \
$(srcdir)/libvirt-gconfig.h \
 $(GCONFIG_SOURCE_FILES:%=$(srcdir)/%) \
 $(GCONFIG_HEADER_FILES:%=$(srcdir)/%)
diff --git a/libvirt-glib/Makefile.am b/libvirt-glib/Makefile.am
index 4da0a84..0638a64 100644
--- a/libvirt-glib/Makefile.am
+++ b/libvirt-glib/Makefile.am
@@ -53,6 +53,8 @@ LibvirtGLib-1.0.gir: libvirt-glib-1.0.la $(G_IR_SCANNER) 
Makefile.am
 -I$(srcdir) \
 --pkg=glib-2.0 \
 --pkg=gthread-2.0 \
+--c-include=libvirt-glib/libvirt-glib.h \
+--pkg-export=libvirt-glib-1.0 \
 $(libvirt_glib_1_0_la_SOURCES:%=$(srcdir)/%)
 
 girdir = $(datadir)/gir-1.0
diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am
index a50878f..9430d40 100644
--- a/libvirt-gobject/Makefile.am
+++ b/libvirt-gobject/Makefile.am
@@ -117,6 +117,8 @@ LibvirtGObject-1.0.gir: libvirt-gobject-1.0.la 
$(G_IR_SCANNER) Makefile.am
 --verbose \
 --pkg=gobject-2.0 \
 --pkg=gthread-2.0 \
+--c-include=libvirt-gobject/libvirt-gobject.h \
+--pkg-export=libvirt-gobject-1.0 \
 $(srcdir)/libvirt-gobject.h \
 $(GOBJECT_SOURCE_FILES:%=$(srcdir)/%) \
 $(GOBJECT_HEADER_FILES:%=$(srcdir)/%) \
-- 
1.7.6.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [Openstack] [RFC PATCH] lxc: don't return error on GetInfo when cgroups not yet set up

2011-09-30 Thread Serge Hallyn
Quoting Serge E. Hallyn (serge.hal...@canonical.com):
 Quoting Daniel P. Berrange (berra...@redhat.com):
  On Wed, Sep 28, 2011 at 02:14:52PM -0500, Serge E. Hallyn wrote:
   Nova (openstack) calls libvirt to create a container, then
   periodically checks using GetInfo to see whether the container
   is up.  If it does this too quickly, then libvirt returns an
   error, which in libvirt.py causes an exception to be raised,
   the same type as if the container was bad.
  lxcDomainGetInfo(), holds a mutex on 'dom' for the duration of
  its execution. It checks for virDomainObjIsActive() before
  trying to use the cgroups.
 
 Yes, it does, but
 
  lxcDomainStart(), holds the mutex on 'dom' for the duration of
  its execution, and does not return until the container is running
  and cgroups are present.
 
 No.  It calls the lxc_controller with --background.  The controller
 main task in turn exits before the cgroups have been set up.  There
 is the race.

So what is the right fix here?  Should the controller write out another
file when it is past the part which should be locked, and the driver
waits for that file to exist before it drops the driver mutex?  If we
do that, do we risk having the driver hang when the controller has
hung?

-serge

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [RFC PATCH] lxc: don't return error on GetInfo when cgroups not yet set up

2011-09-30 Thread Daniel P. Berrange
On Thu, Sep 29, 2011 at 10:12:17PM -0500, Serge E. Hallyn wrote:
 Quoting Daniel P. Berrange (berra...@redhat.com):
  On Wed, Sep 28, 2011 at 02:14:52PM -0500, Serge E. Hallyn wrote:
   Nova (openstack) calls libvirt to create a container, then
   periodically checks using GetInfo to see whether the container
   is up.  If it does this too quickly, then libvirt returns an
   error, which in libvirt.py causes an exception to be raised,
   the same type as if the container was bad.
  lxcDomainGetInfo(), holds a mutex on 'dom' for the duration of
  its execution. It checks for virDomainObjIsActive() before
  trying to use the cgroups.
 
 Yes, it does, but
 
  lxcDomainStart(), holds the mutex on 'dom' for the duration of
  its execution, and does not return until the container is running
  and cgroups are present.
 
 No.  It calls the lxc_controller with --background.  The controller
 main task in turn exits before the cgroups have been set up.  There
 is the race.

The lxcDomainStart() method isn't actually waiting on the child
pid directly, so the --background flag ought not to matter. We
have a pipe that we pass into the controller, which we wait on
for a notification after running the process. The controller
does not notify the 'handshake' FD until after cgroups have
been setup, unless I'm mis-interpreting our code


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 PATCH] lxc: don't return error on GetInfo when cgroups not yet set up

2011-09-30 Thread Serge Hallyn
Quoting Daniel P. Berrange (berra...@redhat.com):
 On Thu, Sep 29, 2011 at 10:12:17PM -0500, Serge E. Hallyn wrote:
  Quoting Daniel P. Berrange (berra...@redhat.com):
   On Wed, Sep 28, 2011 at 02:14:52PM -0500, Serge E. Hallyn wrote:
Nova (openstack) calls libvirt to create a container, then
periodically checks using GetInfo to see whether the container
is up.  If it does this too quickly, then libvirt returns an
error, which in libvirt.py causes an exception to be raised,
the same type as if the container was bad.
   lxcDomainGetInfo(), holds a mutex on 'dom' for the duration of
   its execution. It checks for virDomainObjIsActive() before
   trying to use the cgroups.
  
  Yes, it does, but
  
   lxcDomainStart(), holds the mutex on 'dom' for the duration of
   its execution, and does not return until the container is running
   and cgroups are present.
  
  No.  It calls the lxc_controller with --background.  The controller
  main task in turn exits before the cgroups have been set up.  There
  is the race.
 
 The lxcDomainStart() method isn't actually waiting on the child
 pid directly, so the --background flag ought not to matter. We
 have a pipe that we pass into the controller, which we wait on
 for a notification after running the process. The controller
 does not notify the 'handshake' FD until after cgroups have
 been setup, unless I'm mis-interpreting our code

That's the call to lxcContainerWaitForContinue(), right?  If so, that's
done by lxcContainerChild(), which is called by the lxc_controller.
AFAICS there is nothing in the lxc_driver which will wait on that
before dropping the driver-lock mutex.

-serge

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC PATCH] snapshot: better virsh handling of missing current, parent

2011-09-30 Thread Eric Blake
Previously, virsh 'snapshot-parent' and 'snapshot-current' were
completely silent in the case where the code conclusively proved
there was no parent or current snapshot, but differed in exit
status; this silence caused some confusion on whether the commands
worked.  Furthermore, commit d1be48f introduced a regression where
snapshot-parent would leak output about an unknown function, but
only on the first attempt, when talking to an older server that
lacks virDomainSnapshotGetParent.  This changes things to consistenly
report an error message and exit with status 1 when no snapshot
exists, and to avoid leaking unknown function warnings when using
fallbacks.

* tools/virsh.c (vshGetSnapshotParent): Alter signature, to
distinguish between real error and missing parent.  Don't pollute
last_error on success.
(cmdSnapshotParent): Adjust caller.  Always output message on
failure.
(vshGetSnapshotParent): Adjust caller.
(cmdSnapshotCurrent): Always output message on failure.
---

This patch is an RFC because of backwards-compatibility concerns:

Currently, snapshot-current outputs nothing but has status 0 if
there is no current snapshot; but snapshot-parent outputs nothing
but has status 1 if there is no parent snapshot.  Either way, we
have an inconsistency that needs to be fixed, and gaining consistency
means breaking backwards compatibility with at least one command.

Approach 1 (this patch): change snapshot-parent and snapshot-current
to always output something, whether to stdout on success or to
stderr on failure, with lack of a snapshot being considered a
failure (where snapshot-current used to treat it as success).

Approach 2 (not written) since snapshot-current existed much longer,
makesnapshot-parent consistent by giving status 0 when it is silent.

Preferences?  (I guess mine is approach 1, by evidence of this patch).

 tools/virsh.c |   54 +++---
 1 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 1909dce..179cda5 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -12945,6 +12945,7 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
 char *xml = NULL;
 const char *snapshotname = NULL;
 unsigned int flags = 0;
+const char *domname;

 if (vshCommandOptBool(cmd, security-info))
 flags |= VIR_DOMAIN_XML_SECURE;
@@ -12952,7 +12953,7 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
 if (!vshConnectionUsability(ctl, ctl-conn))
 goto cleanup;

-dom = vshCommandOptDomain(ctl, cmd, NULL);
+dom = vshCommandOptDomain(ctl, cmd, domname);
 if (dom == NULL)
 goto cleanup;

@@ -12986,9 +12987,12 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
 }

 current = virDomainHasCurrentSnapshot(dom, 0);
-if (current  0)
+if (current  0) {
+goto cleanup;
+} else if (!current) {
+vshError(ctl, _(domain '%s' has no current snapshot), domname);
 goto cleanup;
-else if (current) {
+} else {
 const char *name = NULL;

 if (!(snapshot = virDomainSnapshotCurrent(dom, 0)))
@@ -13010,6 +13014,8 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
 ret = true;

 cleanup:
+if (!ret)
+virshReportError(ctl);
 VIR_FREE(xml);
 if (snapshot)
 virDomainSnapshotFree(snapshot);
@@ -13020,26 +13026,33 @@ cleanup:
 }

 /* Helper function to get the name of a snapshot's parent.  Caller
- * must free the result.  */
-static char *
-vshGetSnapshotParent(vshControl *ctl, virDomainSnapshotPtr snapshot)
+ * must free the result.  Returns 0 on success (including when it was
+ * proven no parent exists), and -1 on failure with error reported
+ * (such as no snapshot support or domain deleted in meantime).  */
+static int
+vshGetSnapshotParent(vshControl *ctl, virDomainSnapshotPtr snapshot,
+ char **parent_name)
 {
 virDomainSnapshotPtr parent = NULL;
 char *xml = NULL;
 xmlDocPtr xmldoc = NULL;
 xmlXPathContextPtr ctxt = NULL;
-char *parent_name = NULL;
+int ret = -1;
+
+*parent_name = NULL;

 /* Try new API, since it is faster. */
 if (!ctl-useSnapshotGetXML) {
 parent = virDomainSnapshotGetParent(snapshot, 0);
 if (parent) {
-/* API works, and virDomainSnapshotGetName will succeed */
-parent_name = vshStrdup(ctl, virDomainSnapshotGetName(parent));
+/* API works, and virDomainSnapshotGetName will be accurate */
+*parent_name = vshStrdup(ctl, virDomainSnapshotGetName(parent));
+ret = 0;
 goto cleanup;
 }
 if (last_error-code == VIR_ERR_NO_DOMAIN_SNAPSHOT) {
 /* API works, and we found a root with no parent */
+ret = 0;
 goto cleanup;
 }
 /* API didn't work, fall back to XML scraping. */
@@ -13054,15 +13067,23 @@ vshGetSnapshotParent(vshControl *ctl, 

[libvirt] [libvirt-glib] RFC: delay event handle freeing to avoid dead lock

2011-09-30 Thread Marc-André Lureau
Can be reproduced with the updated test.
---
 examples/conn-test.c  |   20 +++-
 libvirt-glib/libvirt-glib-event.c |   17 +
 2 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/examples/conn-test.c b/examples/conn-test.c
index 08045a4..8ea5ad7 100644
--- a/examples/conn-test.c
+++ b/examples/conn-test.c
@@ -31,12 +31,19 @@ do_connection_open(GObject *source,
 {
 GVirConnection *conn = GVIR_CONNECTION(source);
 GError *err = NULL;
-GMainLoop *loop = opaque;
 
 if (!gvir_connection_open_finish(conn, res, err)) {
 g_error(%s, err-message);
 }
 g_print(Connected to libvirt\n);
+g_object_unref(conn);
+}
+
+static void quit(gpointer data,
+ GObject *where_the_object_was)
+{
+GMainLoop *loop = data;
+
 g_main_loop_quit(loop);
 }
 
@@ -47,19 +54,22 @@ int main(int argc, char **argv)
 
 gvir_init_object(argc, argv);
 
-if (argc != 2)
+if (argc != 2) {
 g_error(syntax: %s URI, argv[0]);
-
-conn = gvir_connection_new(argv[1]);
+return 1;
+}
 
 loop = g_main_loop_new(g_main_context_default(),
TRUE);
 
-gvir_connection_open_async(conn, NULL, do_connection_open, loop);
+conn = gvir_connection_new(argv[1]);
+g_object_weak_ref(G_OBJECT(conn), quit, loop);
+
 gvir_connection_open_async(conn, NULL, do_connection_open, loop);
 
 g_main_loop_run(loop);
 
+
 return 0;
 }
 
diff --git a/libvirt-glib/libvirt-glib-event.c 
b/libvirt-glib/libvirt-glib-event.c
index a785c93..8b1bddf 100644
--- a/libvirt-glib/libvirt-glib-event.c
+++ b/libvirt-glib/libvirt-glib-event.c
@@ -195,6 +195,18 @@ cleanup:
 g_mutex_unlock(eventlock);
 }
 
+static gboolean
+_handle_remove(gpointer data)
+{
+struct gvir_event_handle *h = data;
+
+if (h-ff)
+(h-ff)(h-opaque);
+free(h);
+
+return FALSE;
+}
+
 static int
 gvir_event_handle_remove(int watch)
 {
@@ -217,10 +229,7 @@ gvir_event_handle_remove(int watch)
 g_source_remove(data-source);
 data-source = 0;
 data-events = 0;
-if (data-ff)
-(data-ff)(data-opaque);
-free(data);
-
+g_idle_add(_handle_remove, data);
 ret = 0;
 
 cleanup:
-- 
1.7.6.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv2 2/2] qemu: make PCI multifunction support more manual

2011-09-30 Thread Laine Stump
(V2: address Daniel Veillard's two review points (don't allow
multifunction='default', and add multifunction=off to the qemu
commandline when that's what the XML says), and modify the checks for
duplicate PCI address usage attempts to account for multifunction=off
on a device's function 0, per IRC discussion with Dan Berrange (see
new qemuCollectPCIAddress()). As a side effect, attempts to re-use the
same PCI address are now logged rather than silently generating an
error.)

When support for was added for PCI multifunction cards (in commit
9f8baf, first included in libvirt 0.9.3), it was done by always
turning on the multifunction bit for all PCI devices. Since that time
it has been realized that this is not an ideal solution, and that the
multifunction bit must be selectively turned on. For example, see

  https://bugzilla.redhat.com/show_bug.cgi?id=728174

and the discussion before and after

  https://www.redhat.com/archives/libvir-list/2011-September/msg01036.html

This patch modifies multifunction support so that the multifunction=on
option is only added to the qemu commandline for a device if its PCI
address definition has the attribute multifunction='on', e.g.:

  address type='pci' domain='0x' bus='0x00'
   slot='0x04' function='0x0' multifunction='on'/

In practice, the multifunction bit should only be turned on if
function='0' AND other functions will be used in the same slot - it
usually isn't needed for functions 1-7 (although there are apparently
some exceptions, e.g. the Intel X53 according to the QEMU source
code), and should never be set if only function 0 will be used in the
slot. The test cases have been changed accordingly to illustrate.

With this patch in place, if a user attempts to assign multiple
functions in a slot without setting the multifunction bit for function
0, libvirt will issue an error when the domain is defined, and the
define operation will fail. In the future, we may decide to detect
this situation and automatically add multifunction=on to avoid the
error; even then it will still be useful to have a manual method of
turning on multifunction since, as stated above, there are some
devices that excpect it to be turned on for all functions in a slot.

A side effect of this patch is that attempts to use the same PCI
address for two different devices will now log an error (previously
this would cause the domain define operation to fail, but there would
be no log message generated). Because the function doing this log was
almost completely rewritten, I didn't think it worthwhile to make a
separate patch for that fix (the entire patch would immediately be
obsoleted).
---
 docs/formatdomain.html.in  |   29 +--
 docs/schemas/domaincommon.rng  |8 ++
 src/conf/domain_conf.c |   22 +-
 src/conf/domain_conf.h |   10 +++
 src/libvirt_private.syms   |2 +
 src/qemu/qemu_command.c|   81 
 .../qemuxml2argv-multifunction-pci-device.args |   18 ++--
 .../qemuxml2argv-multifunction-pci-device.xml  |6 +-
 .../qemuxml2argv-usb-ich9-companion.args   |   10 +-
 .../qemuxml2argv-usb-ich9-companion.xml|2 +-
 .../qemuxml2argv-usb-ich9-ehci-addr.args   |2 +-
 .../qemuxml2argv-usb-piix3-controller.args |2 +-
 tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args |   10 +-
 tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml  |2 +-
 tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args |   20 +++---
 tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml  |4 +-
 16 files changed, 165 insertions(+), 63 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 49a2c09..6308ebc 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1118,10 +1118,14 @@
 The codetype/code attribute is mandatory, and is typically
 pci or drive.  For a pci controller, additional
 attributes for codebus/code, codeslot/code,
-and codefunction/code must be present, as well as an
-optional codedomain/code.  For a drive controller,
-additional attributes codecontroller/code, codebus/code,
+and codefunction/code must be present, as well as
+optional codedomain/code
+and codemultifunction/codespan class=sincesince
+0.9.7, requires QEMU 0.13/span (defaults to 'off').  For a
+drive controller, additional attributes
+codecontroller/code, codebus/code,
 and codeunit/code are available, each defaulting to 0.
+
   /dd
 /dl
 
@@ -1298,7 +1302,7 @@
 lt;/controllergt;
 lt;controller type='usb' index='0' model='ich9-uhci1'gt;
   lt;master startport='0'/gt;
-  lt;address type='pci' domain='0' bus='0' slot='4' function='0'/gt;
+  lt;address type='pci' domain='0' bus='0' slot='4' function='0' 

[libvirt] [PATCH 0/2] snapshot: add force for risky reverts

2011-09-30 Thread Eric Blake
I first documented the need for force back in my RFC:
https://www.redhat.com/archives/libvir-list/2011-August/msg00361.html
but only now got around to implementing it.

At the moment, I'm posting the code for early review.  I'm still
in the process of testing out multiple scenarios, and will send
followup mail detailing the actual steps I took using virsh to
cover the multiple scenarios.

Eric Blake (2):
  snapshot: add REVERT_FORCE to API
  snapshot: enforce REVERT_FORCE on qemu

 include/libvirt/libvirt.h.in |1 +
 include/libvirt/virterror.h  |2 +
 src/libvirt.c|   22 +++
 src/qemu/qemu_driver.c   |   47 +-
 src/util/virterror.c |6 +
 tools/virsh.c|   19 -
 tools/virsh.pod  |   17 +++
 7 files changed, 103 insertions(+), 11 deletions(-)

-- 
1.7.4.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 1/2] snapshot: add REVERT_FORCE to API

2011-09-30 Thread Eric Blake
Although reverting to a snapshot is a form of data loss, this is
normally expected.  However, there are two cases where additional
surprises (failure to run the reverted state, or a break in
connectivity to the domain) can come into play.  Requiring extra
acknowledgment in these cases will make it less likely that
someone can get into an unrecoverable state due to a default revert.

Also create a new error code, so users can distinguish when forcing
would make a difference, rather than having to blindly request force.

* include/libvirt/libvirt.h.in (VIR_DOMAIN_SNAPSHOT_REVERT_FORCE):
New flag.
* src/libvirt.c (virDomainRevertToSnapshot): Document it.
* include/libvirt/virterror.h (VIR_ERR_SNAPSHOT_REVERT_RISKY): New
error value.
* src/util/virterror.c (virErrorMsg): Implement it.
* tools/virsh.c (cmdDomainSnapshotRevert): Add --force to virsh.
* tools/virsh.pod (snapshot-revert): Document it.
---
 include/libvirt/libvirt.h.in |1 +
 include/libvirt/virterror.h  |2 ++
 src/libvirt.c|   22 ++
 src/util/virterror.c |6 ++
 tools/virsh.c|   19 ++-
 tools/virsh.pod  |   17 +
 6 files changed, 66 insertions(+), 1 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 3c7f278..7403a9a 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2736,6 +2736,7 @@ virDomainSnapshotPtr 
virDomainSnapshotGetParent(virDomainSnapshotPtr snapshot,
 typedef enum {
 VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING = 1  0, /* Run after revert */
 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED  = 1  1, /* Pause after revert */
+VIR_DOMAIN_SNAPSHOT_REVERT_FORCE   = 1  2, /* Allow risky reverts */
 } virDomainSnapshotRevertFlags;

 /* Revert the domain to a point-in-time snapshot.  The
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 0aae622..0c98014 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -237,6 +237,8 @@ typedef enum {
the given driver */
 VIR_ERR_STORAGE_PROBE_FAILED = 75,  /* storage pool proble failed */
 VIR_ERR_STORAGE_POOL_BUILT = 76,/* storage pool already built */
+VIR_ERR_SNAPSHOT_REVERT_RISKY = 77, /* force was not requested for a
+   risky domain snapshot revert */
 } virErrorNumber;

 /**
diff --git a/src/libvirt.c b/src/libvirt.c
index 2b2f6be..c2aabf7 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -16373,6 +16373,28 @@ error:
  * into an inactive state, so transient domains require the use of one
  * of these two flags.
  *
+ * Reverting to any snapshot discards all configuration changes made since
+ * the last snapshot.  Additionally, reverting to a snapshot from a running
+ * domain is a form of data loss, since it discards whatever is in the
+ * guest's RAM at the time.  However, the very nature of keeping snapshots
+ * implies the intent to roll back state, so no additional confirmation is
+ * normally required for these effects.
+ *
+ * However, there are two particular situations where reverting will
+ * be refused by default, and where @flags must include
+ * VIR_DOMAIN_SNAPSHOT_REVERT_FORCE to acknowledge the risks.  1) Any
+ * attempt to revert to a snapshot that lacks the metadata to perform
+ * ABI compatibility checks (generally the case for snapshots that
+ * lack a full domain when listed by virDomainSnapshotGetXMLDesc(),
+ * such as those created prior to libvirt 0.9.5).  2) Any attempt to
+ * revert a running domain to an active state that requires starting a
+ * new hypervisor instance rather than reusing the existing hypervisor
+ * (since this would terminate all connections to the domain, such as
+ * such as VNC or Spice graphics) - this condition arises from active
+ * snapshots that are provably ABI incomaptible, as well as from
+ * inactive snapshots with a request to start the domain after the
+ * revert.
+ *
  * Returns 0 if the creation is successful, -1 on error.
  */
 int
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 26c4981..5006fa2 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1204,6 +1204,12 @@ virErrorMsg(virErrorNumber error, const char *info)
 else
 errmsg = _(argument unsupported: %s);
 break;
+case VIR_ERR_SNAPSHOT_REVERT_RISKY:
+if (info == NULL)
+errmsg = _(revert requires force);
+else
+errmsg = _(revert requires force: %s);
+break;
 }
 return (errmsg);
 }
diff --git a/tools/virsh.c b/tools/virsh.c
index 655378c..4e79325 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -13571,6 +13571,7 @@ static const vshCmdOptDef opts_snapshot_revert[] = {
 {snapshotname, VSH_OT_DATA, VSH_OFLAG_REQ, N_(snapshot name)},
 {running, VSH_OT_BOOL, 0, N_(after reverting, change state to 
running)},

[libvirt] [PATCH 2/2] snapshot: enforce REVERT_FORCE on qemu

2011-09-30 Thread Eric Blake
Implements the documentation for snapshot revert vs. force.

Part of the patch tightens existing behavior (previously, reverting
to an old snapshot without domain was blindly attempted, now it
requires force), while part of it relaxes behavior (previously, it
was not possible to revert an active domain to an ABI-incompatible
active snapshot, now force allows this transition).

* src/qemu/qemu_driver.c (qemuDomainRevertToSnapshot): Check for
risky situations, and allow force to get past them.
---
 src/qemu/qemu_driver.c |   47 +--
 1 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5110102..efd60a7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9753,7 +9753,8 @@ static int 
qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
  * 7. paused   - inactive: EVENT_STOPPED
  * 8. paused   - running:  EVENT_RESUMED
  * 9. paused   - paused:   none
- * Also, several transitions occur even if we fail partway through.
+ * Also, several transitions occur even if we fail partway through,
+ * and use of FORCE can cause multiple transitions.
  */

 qemuDriverLock(driver);
@@ -9789,6 +9790,24 @@ static int 
qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
   yet));
 goto cleanup;
 }
+if (!(flags  VIR_DOMAIN_SNAPSHOT_REVERT_FORCE)) {
+if (!snap-def-dom) {
+qemuReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY,
+_(snapshot lacks domain '%s' rollback details),
+snap-def-name);
+goto cleanup;
+}
+if (virDomainObjIsActive(vm) 
+!(snap-def-state == VIR_DOMAIN_RUNNING
+  || snap-def-state == VIR_DOMAIN_PAUSED) 
+(flags  (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
+  VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED))) {
+qemuReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY,
+_(must respawn qemu to start inactive snapshot));
+goto cleanup;
+}
+}
+

 if (vm-current_snapshot) {
 vm-current_snapshot-def-current = false;
@@ -9818,11 +9837,6 @@ static int 
qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
 VIR_FREE(xml);
 if (!config)
 goto cleanup;
-} else {
-/* XXX Fail if VIR_DOMAIN_REVERT_FORCE is not set, rather than
- * blindly hoping for the best.  */
-VIR_WARN(snapshot is lacking rollback information for domain '%s',
- snap-def-name);
 }

 if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY)  0)
@@ -9843,10 +9857,22 @@ static int 
qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
 /* Transitions 5, 6, 8, 9 */
 /* Check for ABI compatibility.  */
 if (config  !virDomainDefCheckABIStability(vm-def, config)) {
-/* XXX Add VIR_DOMAIN_REVERT_FORCE to permit killing
- * and restarting a new qemu, since loadvm monitor
- * command won't work.  */
-goto endjob;
+if (!(flags  VIR_DOMAIN_SNAPSHOT_REVERT_FORCE)) {
+/* Alter existing error to give correct category. */
+virErrorPtr err = virGetLastError();
+err-code = VIR_ERR_SNAPSHOT_REVERT_RISKY;
+goto endjob;
+}
+qemuProcessStop(driver, vm, 0,
+VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT);
+virDomainAuditStop(vm, from-snapshot);
+detail = VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT;
+event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ detail);
+if (event)
+qemuDomainEventQueue(driver, event);
+goto load;
 }

 priv = vm-privateData;
@@ -9882,6 +9908,7 @@ static int 
qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
 virDomainObjAssignDef(vm, config, false);
 } else {
 /* Transitions 2, 3 */
+load:
 was_stopped = true;
 if (config)
 virDomainObjAssignDef(vm, config, false);
-- 
1.7.4.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCHv2 2/2] qemu: make PCI multifunction support more manual

2011-09-30 Thread Eric Blake

On 09/30/2011 12:02 PM, Laine Stump wrote:

(V2: address Daniel Veillard's two review points (don't allow
multifunction='default', and add multifunction=off to the qemu
commandline when that's what the XML says), and modify the checks for
duplicate PCI address usage attempts to account for multifunction=off
on a device's function 0, per IRC discussion with Dan Berrange (see
new qemuCollectPCIAddress()). As a side effect, attempts to re-use the
same PCI address are now logged rather than silently generating an
error.)


Yep, I can see those enhancements over v1.



A side effect of this patch is that attempts to use the same PCI
address for two different devices will now log an error (previously
this would cause the domain define operation to fail, but there would
be no log message generated). Because the function doing this log was
almost completely rewritten, I didn't think it worthwhile to make a
separate patch for that fix (the entire patch would immediately be
obsoleted).


Agree - no easy way to split it.


@@ -1118,10 +1118,14 @@
  Thecodetype/code  attribute is mandatory, and is typically
  pci or drive.  For a pci controller, additional
  attributes forcodebus/code,codeslot/code,
-andcodefunction/code  must be present, as well as an
-optionalcodedomain/code.  For a drive controller,
-additional attributescodecontroller/code,codebus/code,
+andcodefunction/code  must be present, as well as
+optionalcodedomain/code
+andcodemultifunction/codespan class=sincesince
+0.9.7, requires QEMU 0.13/span  (defaults to 'off').  For a


This wording makes it sound like both domain and multifunction were 
first introduced in 0.9.7, rather than the intended fact that 
'multifunction' is the only newcomer attribute.  Maybe reword along the 
lines of:


...as well as optional 'domain' and 'multifunction'.  Multifunction 
defaults to 'off', any other value requires QEMU 0.13 and span 
class=sincelibvirt 0.9.7/span.



+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-ehci-addr.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M 
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev 
socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon 
chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device 
ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M 
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev 
socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon 
chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device 
ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3


These are some rather long lines.  While you are touching them, it would 
be worth splitting them with \-newline pairs to fit in more reasonable 
limits.


ACK with those nits fixed.

--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] Improve the daemon man page

2011-09-30 Thread Eric Blake

On 09/30/2011 01:56 AM, Daniel Veillard wrote:

Add informations about the handling of USR2 and fatal signals
and document the default log location.

diff --git a/daemon/libvirtd.pod.in b/daemon/libvirtd.pod.in
index 6e699b8..269e81f 100644
--- a/daemon/libvirtd.pod.in
+++ b/daemon/libvirtd.pod.in
@@ -69,6 +69,10 @@ Display version information then exit.
  =head1 SIGNALS

  On receipt of BSIGHUP  libvirtd will reload its configuration.
+On receipt of BSIGUSR2  or other fatal signals like BSIGFPE,


SIGUSR2 is not fatal.  I'd word this:

On receipt of BSIGUSR2, or on fatal signals like BSIGFPE, ...


+BSIGSEGV, BSIGILL, BSIGABRT  or BSIGBUS, libvirtd will dump
+its internal debug message buffer content to the default log output,
+usually B@localstatedir@/log/libvirt/libvirtd.log

  =head1 FILES

@@ -105,6 +109,11 @@ The TLS BServer  private key libvirtd will use.

  The PID file to use, unless overridden by the B-p|B--pid-file  option.

+=item F@localstatedir@/log/libvirt/libvirtd.log
+
+The default file where libvirtd will save its logs, this can be overriden


s/overriden/overridden/


+from the B@sysconfdir@/libvirtd.conf  configuration file.


ACK with nits fixed.

--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] bug: try to take disk snapshot for LVM2 Volume

2011-09-30 Thread Eric Blake
On 09/29/2011 11:26 PM, MATSUDA, Daiki wrote:
 I tried the new snapshot function implemented by Eric Blake.
 
 It works very well for QCOW2 disk image system.
 But I often use LVM2 volume for QEMU virtual machines and tried to take
 disk snapshot by virsh command ( snapshot-create DOMNAME --disk-only).
 So, finally qemu monitor command 'snapshot_blkdev' accepts the LVM2
 volume and create QCOW2 snapshot image. In addition, domain's
 configuration file is replaced to use snapshot disk image instead of
 LVM2 volume.

It sounds like virsh did what it was told, but that you told it so
little information that it had to fill in the gaps and choose its own
destination file name (hence the .1317357844 suffix after the action).
Your situation sounds like a case where you may want a bit more control
over the destination file name.

 
 configuration file
 from
 
 disk type='block' device='disk
driver name='qemu' type='raw' cache='none'/
source dev='dev/VG1/LVM2_dom'/
 
 
 to
 disk type='block' device='disk
driver name='qemu' type='qcow2' cache='none'/
source dev='dev/VG1/LVM2_dom.1317357844'/

Are you pasting literal chunks, or retyping this?  You're missing the /
in front of dev/VG1, so I can't help but wonder what else might have
been mistyped.


 After then, the domain runs well till it is shutdowned.

I'm surprised that it got that far - generally, libvirt can't create
random regular files under the /dev/VG1/ device-mapper hierarchy, and if
a file can't be created, then what was open() doing, and what did qemu
actually do?  It may be worth looking at lsof says that qemu has open,
if you still have it running.  Or it may be that you've found a bug in
libvirt and/or qemu for not accurately reporting failure to create the
snapshot image.

I think we need to step back a bit and look at the bigger picture.  Do
you want your new qcow2 file to be its own LVM volume (in which case,
I'd suggest that you pre-create the LVM volume, and pass in the file
name within /dev/VG1/ of the existing block device to use), or are you
okay with it being a regular file (in which case, I'd suggest that you
do not pre-create the file, but that you still pass in the desired
filename to some absolute path that lives outside of /dev/)?

Either way, it sounds like you do _not_ want libvirt to be generating
its own filename, since libvirt only knows how to generate a name in the
same directory as the snapshot is taking place, but your lvm is in a
special directory.  To do this, you either need to create an XML file
yourself, and call 'virsh snapshot-create dom --disk-only file', or you
need to have virsh create the xml for you with 'virsh snapshot-create-as
dom --disk-only vda,file=/path/to/file'.  You can see the xml that
snapshot-create-as would generate (in case you need to further fine-tune
it for your own use in snapshot-create) via the --print-xml option.

 I started the
 domain, but it does not with following error
 virtsh # start LVM2_dom
 error: Failed to start domain LVM2_dom
 error: 内部エラー Process exited while reading console log output: char
 device redirected to /dev/pts/7
 qemu: could not open disk image /dev/VG1/LVM2_dom.1317357844: Invalid
 argument.

That makes sense, if that file doesn't exist (but why qemu didn't reject
the snapshot in the first place still remains to be investigated).

 
 I think that if the volume but qcow2 is given libvirt should be refuse,

No, qemu does just fine with a non-qcow2 backing file.  The real problem
here is that the new qcow2 file was not created, not the type of the
original file.

 e.g. in qemuDomainSnapshotCreateDiskActive() with voulme driver type.
 But currently the structures concerning with snapshot or disk has no
 member to hold such a volume driver information. In addition, as we want
 to add the LVM2 and other volume snapshot function, we hope you add its
 information and fix.

Yes, I have much longer-term plans for refactoring device snapshots to
move the work into more virStorageVolPtr operations, and teach
virDomainSnapshotCreateXML to reuse virStorageVol actions rather than
hard-coding the actions itself, at which point we can then use lvm
snapshots rather than qcow2 snapshots.  But that's a lot more effort, so
no promise of how long it will take me to get to that point.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/2] Make libvirt.so include the RPC server code

2011-09-30 Thread Eric Blake

On 09/30/2011 07:54 AM, Daniel P. Berrange wrote:

From: Daniel P. Berrangeberra...@redhat.com

To avoid static linking libvirtd to the RPC server code, which
then prevents sane introduction of DTrace probes, put it all
in the libvirt.so, and export it

* daemon/Makefile.am: Don't link to RPC libraries
* src/Makefile.am: Link all RPC libraries to libvirt.so
* src/libvirt_private.syms: Export all RPC functions
---
  daemon/Makefile.am   |2 -
  src/Makefile.am  |2 +-
  src/libvirt_private.syms |   76 ++
  3 files changed, 77 insertions(+), 3 deletions(-)




+++ b/src/Makefile.am
@@ -612,7 +612,7 @@ libvirt_driver_remote_la_CFLAGS =   
\
-I@top_srcdir@/src/rpc  \
$(AM_CFLAGS)
  libvirt_driver_remote_la_LDFLAGS = $(AM_LDFLAGS)
-libvirt_driver_remote_la_LIBADD = $(GNUTLS_LIBS) libvirt-net-rpc-client.la 
libvirt-net-rpc.la
+libvirt_driver_remote_la_LIBADD = $(GNUTLS_LIBS) libvirt-net-rpc-client.la 
libvirt-net-rpc-server.la libvirt-net-rpc.la


Use \-newline wrapping to make this not be quite so long.



  if WITH_DRIVER_MODULES
  libvirt_driver_remote_la_LIBADD += ../gnulib/lib/libgnu.la
  libvirt_driver_remote_la_LDFLAGS += -module -avoid-version
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c2a3fab..e086253 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1162,6 +1162,82 @@ virFileDirectFdNew;
  virFileFclose;
  virFileFdopen;

+# rpc


Hmm, that's not really the .h where they are declared, although it is 
the right directory.  As is, sticking 'rpc' between 'virfile.h' and 
'virpidfile.h' doesn't sort very well.  It shouldn't be too much more 
effort to break this into multiple sections, one for each relevant .h...


virnetmessage.h:


+virNetMessageClear;
+virNetMessageEncodeHeader;
+virNetMessageEncodePayload;
+virNetMessageFree;
+virNetMessageNew;
+virNetMessageQueuePush;
+virNetMessageQueueServe;
+virNetMessageSaveError;


virnetsaslcontext.h


+virNetSASLContextCheckIdentity;
+virNetSASLContextNewServer;
+virNetSASLSessionExtKeySize;
+virNetSASLSessionFree;
+virNetSASLSessionGetIdentity;
+virNetSASLSessionGetKeySize;
+virNetSASLSessionListMechanisms;
+virNetSASLSessionNewServer;
+virNetSASLSessionSecProps;
+virNetSASLSessionServerStart;
+virNetSASLSessionServerStep;


virnetserver.h


+virNetServerAddProgram;
+virNetServerAddService;
+virNetServerAddSignalHandler;
+virNetServerAutoShutdown;


virnetserverclient.h


+virNetServerClientAddFilter;
+virNetServerClientClose;
+virNetServerClientDelayedClose;
+virNetServerClientFree;
+virNetServerClientGetAuth;
+virNetServerClientGetFD;
+virNetServerClientGetLocalIdentity;
+virNetServerClientGetPrivateData;
+virNetServerClientGetReadonly;
+virNetServerClientGetTLSKeySize;
+virNetServerClientHasTLSSession;
+virNetServerClientImmediateClose;
+virNetServerClientIsSecure;
+virNetServerClientLocalAddrString;
+virNetServerClientRef;
+virNetServerClientRemoteAddrString;
+virNetServerClientRemoveFilter;
+virNetServerClientSendMessage;
+virNetServerClientSetCloseHook;
+virNetServerClientSetIdentity;
+virNetServerClientSetPrivateData;
+virNetServerClientSetSASLSession;


move these to be with the rest of virnetserver.h


+virNetServerClose;
+virNetServerFree;
+virNetServerIsPrivileged;
+virNetServerNew;


virnetserverprogram.h


+virNetServerProgramFree;
+virNetServerProgramGetID;
+virNetServerProgramGetVersion;
+virNetServerProgramMatches;
+virNetServerProgramNew;
+virNetServerProgramRef;
+virNetServerProgramSendReplyError;
+virNetServerProgramSendStreamData;
+virNetServerProgramSendStreamError;
+virNetServerQuit;
+virNetServerRef;
+virNetServerRun;


virnetserverservice.h


+virNetServerServiceFree;
+virNetServerServiceNewTCP;
+virNetServerServiceNewUNIX;
+virNetServerUpdateServices;


virnetsocket.h


+virNetSocketDupFD;
+virNetSocketFree;
+virNetSocketGetFD;
+virNetSocketListen;
+virNetSocketNewConnectTCP;
+virNetSocketNewListenUNIX;


virnettlscontext.h


+virNetTLSContextFree;
+virNetTLSContextNewServer;
+virNetTLSContextNewServerPath;
+

  # virpidfile.h
  virPidFileAcquire;



But all of those are just layout nits, not technical objections, so I'm 
okay giving:


ACK with changes

--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 2/2] Add some DTrace/SystemTAP probes to the RPC code

2011-09-30 Thread Eric Blake

On 09/30/2011 07:54 AM, Daniel P. Berrange wrote:

From: Daniel P. Berrangeberra...@redhat.com



Not much of a commit comment.  Even mentioning that half of the patch is 
code motion rather than new content might be useful.



+
+/* Systemtap 1.2 headers have a bug where they cannot handle a
+ * variable declared with array type.  Work around this by casting all
+ * arguments.  This is some gross use of the preprocessor because
+ * PROBE is a var-arg macro, but it is better than the alternative of
+ * making all callers to PROBE have to be aware of the issues.  And
+ * hopefully, if we ever add a call to PROBE with other than 2 or 3


s/other than 2 or 3/more than 7/


+ * end arguments, you can figure out the pattern to extend this hack.
+ */
+#  define VIR_COUNT_ARGS(...) VIR_ARG9(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)
+#  define VIR_ARG9(_1, _2, _3, _4, _5, _6, _7, _8, _9, ...) _9
+#  define VIR_ADD_CAST_EXPAND(a, b, ...) VIR_ADD_CAST_PASTE(a, b, __VA_ARGS__)
+#  define VIR_ADD_CAST_PASTE(a, b, ...) a##b(__VA_ARGS__)
+
+/* The double cast is necessary to silence gcc warnings; any pointer
+ * can safely go to intptr_t and back to void *, which collapses
+ * arrays into pointers; while any integer can be widened to intptr_t
+ * then cast to void *.  */
+#  define VIR_ADD_CAST(a) ((void *)(intptr_t)(a))


Now that you've expanded the list, it looks awkward not having 
VIR_ADD_CAST1(a) VIR_ADD_CAST(a)



+#  define VIR_ADD_CAST2(a, b)   \
+VIR_ADD_CAST(a), VIR_ADD_CAST(b)
+#  define VIR_ADD_CAST3(a, b, c)\
+VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c)
+#  define VIR_ADD_CAST4(a, b, c, d)   \
+VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c),\
+VIR_ADD_CAST(d)
+#  define VIR_ADD_CAST5(a, b, c, d, e)\
+VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c),\
+VIR_ADD_CAST(d), VIR_ADD_CAST(e)
+#  define VIR_ADD_CAST6(a, b, c, d, e, f) \
+VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c),\
+VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f)
+#  define VIR_ADD_CAST7(a, b, c, d, e, f, g)  \
+VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
+VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f),  \
+VIR_ADD_CAST(g)


Up to here is reachable...


+#  define VIR_ADD_CAST8(a, b, c, d, e, f, g, h)   \
+VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c),\
+VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f),  \
+VIR_ADD_CAST(g), VIR_ADD_CAST(h)
+#  define VIR_ADD_CAST9(a, b, c, d, e, f, g, h, i)\
+VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c),  \
+VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f),  \
+VIR_ADD_CAST(g), VIR_ADD_CAST(h), VIR_ADD_CAST(i)


but these two are impossible given your definition of VIR_COUNT_ARGS. 
To really support 9 arguments, VIR_COUNT_ARGS needs to call 
VIR_ARG11(__VA_ARGS__, 10, 9, ...).


ACK with that fixed.  Everything else looks like a lot of stap black 
magic, but the end result is indeed a setup that can be easily traced to 
track traffic.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] RPM build failure on Redhat6

2011-09-30 Thread Eric Blake

On 09/28/2011 10:48 PM, Wayne Xia wrote:

Hi, I want to build rpm for latest libvit version on Redhat6, but when
I type:
./autogen.sh --system
make rpm -j4

error happens:

  sitemap.html.tmp index.html.tmp archdomain.html.tmp downloads.html.tmp
auth.html.tmp internals/locking.html.tmp archnode.html.tmp
hvsupport.html.tmp bugs.html.tmp java.html.tmp locking.html.tmp
logging.html.tmp testapi.html.tmp formatnetwork.html.tmp
bindings.html.tmp uri.html.tmp drvtest.html.tmp contact.html.tmp
formatnwfilter.html.tmp intro.html.tmp drvxen.html.tmp drvesx.html.tmp
drvqemu.html.tmp drvvmware.html.tmp testsuites.html.tmp
devguide.html.tmp firewall.html.tmp architecture.html.tmp todo.html.tmp
formatsnapshot.html.tmp formatstorage.html.tmp deployment.html.tmp
internals.html.tmp api_extension.html.tmp drvuml.html.tmp
virshcmdref.html.tmp csharp.html.tmp python.html.tmp drvremote.html.tmp
archstorage.html.tmp remote.html.tmp drivers.html.tmp formatnode.html.tmp
make[2]: Leaving directory
`/home/xiawenc/WorkDir/Source/libvirt/libvirt/docs'
make[1]: *** [distdir] Error 1


That's not the actual error (which happened several lines before where 
you started pasting).


I'm not sure what's going on, but I will add that I have sometimes seen 
a 'make -j2' failure when the makefile gets to the point of generating 
todo.html.  I'm not sure where the missing make dependency is, but 
hopefully next time someone sees it, and accurately reports it, we can 
patch docs/Makefile.am to avoid these parallel make problems.


In the meantime, 'make -C docs' without -j should get you past this issue.

--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/1] lvm storage backend: handle command_names=1 in lvm.conf (v2)

2011-09-30 Thread Eric Blake

On 09/28/2011 02:08 PM, Serge E. Hallyn wrote:

[ Thanks for the feedback, Eric.  Hopefully I correctly incorporated it
in this version.  This version still tests fine with and without
lvm.conf command_names=1 ]


Glad that it passed testing (as I had not tested my suggestions).



If the regexes supported (?:pvs)?, then we could handle this by
optionally matching but not returning the initial command name.  But it
doesn't.  So add a new char* argument to
virStorageBackendRunProgRegex().  If that argument is NULL then we act
as usual.  Otherwise, if the string at that argument is found at the
start of a returned line, we drop that before running the regex.

With this patch, virt-manager shows me lvs with command_names 1 or 0.

The definitions of PVS_BASE etc may want to be moved into the configure
scripts (though given how PVS is found, IIUC that could only happen if
pvs was a link to pvs_real), but in any case no sense dealing with that
until we're sure this is an ok way to handle it.

Changelog:
   Sep 28: Use STRSKIP and make cmd_to_ignore arg const, as per Eric's
   feedback.


I'll tweak the commit a bit (information like this is useful to the 
patch review, but less useful in 'git log' - so the best place to stick 
it is after the --- divider, so that 'git am' will know that it is not 
part of the official commit message).



@@ -1460,13 +1460,20 @@ virStorageBackendRunProgRegex(virStoragePoolObjPtr pool,
  }

  while (fgets(line, sizeof(line), list) != NULL) {
+char *p = NULL;
  /* Strip trailing newline */
  int len = strlen(line);
  if (len  line[len-1] == '\n')
  line[len-1] = '\0';

+/* if cmd_to_ignore is specified, then ignore it */


I'll tweak this comment slightly to mention that we are skipping a 
prefix, if it is present, and not ignoring the entire command line.



+++ b/src/storage/storage_backend_logical.c
@@ -205,13 +205,14 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
  pool-def-source.name, NULL
  };

+#define LVS_BASE lvs
  if (virStorageBackendRunProgRegex(pool,
prog,
1,
regexes,
vars,
virStorageBackendLogicalMakeVol,
-  vol)  0) {
+  vol, LVS_BASE)  0) {


I'm not a big fan of in-function #define, especially if it's for a 
one-shot string literal.  I generally either float the #define up to the 
top of the file (out of the function), or in this case, inline the 
string constant into its lone usage point (we can refactor into a 
#define later, if we need to use the string more than once).


ACK and pushed with this squashed in:

diff --git i/src/storage/storage_backend.c w/src/storage/storage_backend.c
index dd7e36b..64c35c2 100644
--- i/src/storage/storage_backend.c
+++ w/src/storage/storage_backend.c
@@ -1400,7 +1400,7 @@ virStorageBackendRunProgRegex(virStoragePoolObjPtr 
pool,

   const char **regex,
   int *nvars,
   virStorageBackendListVolRegexFunc func,
-  void *data, const char *cmd_to_ignore)
+  void *data, const char *prefix)
 {
 int fd = -1, err, ret = -1;
 FILE *list = NULL;
@@ -1466,9 +1466,9 @@ virStorageBackendRunProgRegex(virStoragePoolObjPtr 
pool,

 if (len  line[len-1] == '\n')
 line[len-1] = '\0';

-/* if cmd_to_ignore is specified, then ignore it */
-if (cmd_to_ignore)
-p = STRSKIP(line, cmd_to_ignore);
+/* ignore any command prefix */
+if (prefix)
+p = STRSKIP(line, prefix);
 if (!p)
 p = line;

diff --git i/src/storage/storage_backend_logical.c 
w/src/storage/storage_backend_logical.c

index 7923b71..589f486 100644
--- i/src/storage/storage_backend_logical.c
+++ w/src/storage/storage_backend_logical.c
@@ -205,14 +205,13 @@ 
virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,

 pool-def-source.name, NULL
 };

-#define LVS_BASE lvs
 if (virStorageBackendRunProgRegex(pool,
   prog,
   1,
   regexes,
   vars,
   virStorageBackendLogicalMakeVol,
-  vol, LVS_BASE)  0) {
+  vol, lvs)  0) {
 return -1;
 }

@@ -328,10 +327,9 @@ 
virStorageBackendLogicalFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,

 memset(sourceList, 0, sizeof(sourceList));
 sourceList.type = VIR_STORAGE_POOL_LOGICAL;

-#define PVS_BASE pvs
 if (virStorageBackendRunProgRegex(NULL, prog, 1, 

[libvirt] [libvirt-glib] gir: fix introspection of asyncs and array delegate

2011-09-30 Thread Marc-André Lureau
---
 libvirt-gobject/libvirt-gobject-connection.c   |   24 
 libvirt-gobject/libvirt-gobject-connection.h   |6 +++---
 libvirt-gobject/libvirt-gobject-storage-pool.c |8 
 libvirt-gobject/libvirt-gobject-storage-pool.h |2 +-
 libvirt-gobject/libvirt-gobject-stream.h   |2 +-
 5 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/libvirt-gobject/libvirt-gobject-connection.c 
b/libvirt-gobject/libvirt-gobject-connection.c
index 90d1566..5fc0a9e 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -431,19 +431,19 @@ gvir_connection_open_helper(GSimpleAsyncResult *res,
  * gvir_connection_open_async:
  * @conn: the connection
  * @cancellable: (allow-none)(transfer none): cancellation object
- * @callback: (transfer none): completion callback
- * @opaque: (transfer none)(allow-none): opaque data for callback
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
  */
 void gvir_connection_open_async(GVirConnection *conn,
 GCancellable *cancellable,
 GAsyncReadyCallback callback,
-gpointer opaque)
+gpointer user_data)
 {
 GSimpleAsyncResult *res;
 
 res = g_simple_async_result_new(G_OBJECT(conn),
 callback,
-opaque,
+user_data,
 gvir_connection_open);
 g_simple_async_result_run_in_thread(res,
 gvir_connection_open_helper,
@@ -828,19 +828,19 @@ gvir_connection_fetch_domains_helper(GSimpleAsyncResult 
*res,
  * gvir_connection_fetch_domains_async:
  * @conn: the connection
  * @cancellable: (allow-none)(transfer none): cancellation object
- * @callback: (transfer none): completion callback
- * @opaque: (transfer none)(allow-none): opaque data for callback
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
  */
 void gvir_connection_fetch_domains_async(GVirConnection *conn,
  GCancellable *cancellable,
  GAsyncReadyCallback callback,
- gpointer opaque)
+ gpointer user_data)
 {
 GSimpleAsyncResult *res;
 
 res = g_simple_async_result_new(G_OBJECT(conn),
 callback,
-opaque,
+user_data,
 gvir_connection_fetch_domains);
 g_simple_async_result_run_in_thread(res,
 gvir_connection_fetch_domains_helper,
@@ -889,19 +889,19 @@ gvir_connection_fetch_pools_helper(GSimpleAsyncResult 
*res,
  * gvir_connection_fetch_storage_pools_async:
  * @conn: the connection
  * @cancellable: (allow-none)(transfer none): cancellation object
- * @callback: (transfer none): completion callback
- * @opaque: (transfer none)(allow-none): opaque data for callback
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
  */
 void gvir_connection_fetch_storage_pools_async(GVirConnection *conn,
GCancellable *cancellable,
GAsyncReadyCallback callback,
-   gpointer opaque)
+   gpointer user_data)
 {
 GSimpleAsyncResult *res;
 
 res = g_simple_async_result_new(G_OBJECT(conn),
 callback,
-opaque,
+user_data,
 gvir_connection_fetch_storage_pools);
 g_simple_async_result_run_in_thread(res,
 gvir_connection_fetch_pools_helper,
diff --git a/libvirt-gobject/libvirt-gobject-connection.h 
b/libvirt-gobject/libvirt-gobject-connection.h
index d05f792..2eb58ec 100644
--- a/libvirt-gobject/libvirt-gobject-connection.h
+++ b/libvirt-gobject/libvirt-gobject-connection.h
@@ -77,7 +77,7 @@ gboolean gvir_connection_open(GVirConnection *conn,
 void gvir_connection_open_async(GVirConnection *conn,
 GCancellable *cancellable,
 GAsyncReadyCallback callback,
-gpointer opaque);
+gpointer user_data);
 gboolean gvir_connection_open_finish(GVirConnection *conn,
  GAsyncResult *result,
  GError **err);
@@ -90,7 +90,7 @@ gboolean gvir_connection_fetch_domains(GVirConnection *conn,
 

Re: [libvirt] [PATCH 2.6/4] snapshot: virsh fallback for snapshot-list --from children

2011-09-30 Thread Eric Blake

On 09/29/2011 04:02 PM, Eric Blake wrote:

Iterating over one level of children requires parsing all snapshots
and their parents; a bit of code shuffling makes it pretty easy
to do this as well.

* tools/virsh.c (cmdSnapshotList): Add another fallback.
---

Applies anywhere after 2.5/4, but again, easiest to test against the
same version of libvirtd if applied before 3/4.




+if (numsnaps  0) {
+/* XXX also want to emulate --descendants without --tree */
+if ((!descendants || tree)
+last_error-code == VIR_ERR_NO_SUPPORT) {


This doesn't even compile.  Let me send a cleaned up v2.

--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv2 3/7] snapshot: virsh fallback for snapshot-list --tree --from

2011-09-30 Thread Eric Blake
Emulating --from requires grabbing the entire list of snapshots
and their parents, and recursively iterating over the list from
the point of interest - but we already do that for --tree.  This
turns on emulation for that situation.

* tools/virsh.c (__vshControl): Rename member.
(vshReconnect, cmdConnect, vshGetSnapshotParent): Update clients.
(cmdSnapshotList): Add fallback.
---

v2: reuse existing ctl flag, so that virsh in shell mode doesn't
repeatedly try non-working commands

 tools/virsh.c |   43 +--
 1 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index adafe86..e3bc364 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -246,8 +246,8 @@ typedef struct __vshControl {
 char *historyfile;  /* readline history file name */
 bool useGetInfo;/* must use virDomainGetInfo, since
virDomainGetState is not supported */
-bool useSnapshotGetXML; /* must use virDomainSnapshotGetXMLDesc, since
-   virDomainSnapshotGetParent is missing */
+bool useSnapshotOld;/* cannot use virDomainSnapshotGetParent or
+   virDomainSnapshotNumChildren */
 } __vshControl;

 typedef struct vshCmdGrp {
@@ -599,7 +599,7 @@ vshReconnect(vshControl *ctl)
 vshError(ctl, %s, _(Reconnected to the hypervisor));
 disconnected = 0;
 ctl-useGetInfo = false;
-ctl-useSnapshotGetXML = false;
+ctl-useSnapshotOld = false;
 }

 /* ---
@@ -747,7 +747,7 @@ cmdConnect(vshControl *ctl, const vshCmd *cmd)
 ctl-name = vshStrdup(ctl, name);

 ctl-useGetInfo = false;
-ctl-useSnapshotGetXML = false;
+ctl-useSnapshotOld = false;
 ctl-readonly = ro;

 ctl-conn = virConnectOpenAuth(ctl-name, virConnectAuthPtrDefault,
@@ -13042,7 +13042,7 @@ vshGetSnapshotParent(vshControl *ctl, 
virDomainSnapshotPtr snapshot,
 *parent_name = NULL;

 /* Try new API, since it is faster. */
-if (!ctl-useSnapshotGetXML) {
+if (!ctl-useSnapshotOld) {
 parent = virDomainSnapshotGetParent(snapshot, 0);
 if (parent) {
 /* API works, and virDomainSnapshotGetName will be accurate */
@@ -13056,7 +13056,7 @@ vshGetSnapshotParent(vshControl *ctl, 
virDomainSnapshotPtr snapshot,
 goto cleanup;
 }
 /* API didn't work, fall back to XML scraping. */
-ctl-useSnapshotGetXML = true;
+ctl-useSnapshotOld = true;
 }

 xml = virDomainSnapshotGetXMLDesc(snapshot, 0);
@@ -13181,10 +13181,22 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 if (vshCommandOptBool(cmd, descendants) || tree) {
 flags |= VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
 }
-numsnaps = virDomainSnapshotNumChildren(start, flags);
-if (numsnaps = 0  tree)
-numsnaps++;
-/* XXX Is it worth emulating --from on older servers?  */
+numsnaps = ctl-useSnapshotOld ? -1 :
+virDomainSnapshotNumChildren(start, flags);
+/* XXX Is it worth emulating --from without --tree on older servers?  
*/
+if (tree) {
+if (numsnaps = 0) {
+numsnaps++;
+} else if (ctl-useSnapshotOld ||
+   last_error-code == VIR_ERR_NO_SUPPORT) {
+/* We can emulate --tree --from.  */
+virFreeError(last_error);
+last_error = NULL;
+ctl-useSnapshotOld = true;
+flags = ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
+numsnaps = virDomainSnapshotNum(dom, flags);
+}
+}
 } else {
 numsnaps = virDomainSnapshotNum(dom, flags);

@@ -13199,8 +13211,11 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 }
 }

-if (numsnaps  0)
+if (numsnaps  0) {
+if (!last_error)
+vshError(ctl, _(missing support));
 goto cleanup;
+}

 if (!tree) {
 if (parent_filter  0)
@@ -13222,7 +13237,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 if (VIR_ALLOC_N(names, numsnaps)  0)
 goto cleanup;

-if (from) {
+if (from  !ctl-useSnapshotOld) {
 /* When mixing --from and --tree, we want to start the tree at the
  * given snapshot.  Without --tree, only list the children.  */
 if (tree) {
@@ -13247,7 +13262,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 if (tree) {
 char indentBuf[INDENT_BUFLEN];
 char **parents = vshCalloc(ctl, sizeof(char *), actual);
-for (i = (from ? 1 : 0); i  actual; i++) {
+for (i = (from  !ctl-useSnapshotOld); i  actual; i++) {
 /* free up memory from previous iterations of the loop */
 if (snapshot)
 virDomainSnapshotFree(snapshot);
@@ -13262,7 +13277,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 }
 

[libvirt] [PATCHv2 0/7] snapshot: listing children

2011-09-30 Thread Eric Blake
Cleaned up the rebase goofs present throughout my v1:
https://www.redhat.com/archives/libvir-list/2011-September/msg01270.html

Eric Blake (7):
  snapshot: new virDomainSnapshotListChildrenNames API
  snapshot: virsh snapshot-list and children
  snapshot: virsh fallback for snapshot-list --tree --from
  snapshot: virsh fallback for snapshot-list --from children
  snapshot: virsh fallback for snapshot-list --descendants --from
  snapshot: remote protocol for snapshot children
  snapshot: implement snapshot children listing in qemu

 include/libvirt/libvirt.h.in|   27 +--
 python/generator.py |4 +
 python/libvirt-override-api.xml |   12 ++-
 python/libvirt-override.c   |   45 +
 src/conf/domain_conf.c  |   51 +++
 src/conf/domain_conf.h  |7 ++
 src/driver.h|   12 +++
 src/libvirt.c   |  111 +++
 src/libvirt_private.syms|2 +
 src/libvirt_public.syms |2 +
 src/qemu/qemu_driver.c  |   87 ++
 src/remote/remote_driver.c  |2 +
 src/remote/remote_protocol.x|   25 +-
 src/remote_protocol-structs |   20 
 tools/virsh.c   |  190 --
 tools/virsh.pod |9 ++-
 16 files changed, 564 insertions(+), 42 deletions(-)

-- 
1.7.4.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv2 1/7] snapshot: new virDomainSnapshotListChildrenNames API

2011-09-30 Thread Eric Blake
The previous API addition allowed traversal up the hierarchy;
this one makes it easier to traverse down the hierarchy.

In the python bindings, virDomainSnapshotNumChildren can be
generated, but virDomainSnapshotListChildrenNames had to copy
from the hand-written example of virDomainSnapshotListNames.

* include/libvirt/libvirt.h.in (virDomainSnapshotNumChildren)
(virDomainSnapshotListChildrenNames): New prototypes.
(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS): New flag alias.
* src/libvirt.c (virDomainSnapshotNumChildren)
(virDomainSnapshotListChildrenNames): New functions.
* src/libvirt_public.syms: Export them.
* src/driver.h (virDrvDomainSnapshotNumChildren)
(virDrvDomainSnapshotListChildrenNames): New callbacks.
* python/generator.py (skip_impl, nameFixup): Update lists.
* python/libvirt-override-api.xml: Likewise.
* python/libvirt-override.c
(libvirt_virDomainSnapshotListChildrenNames): New wrapper function.
---

v2: no change

 include/libvirt/libvirt.h.in|   27 +++--
 python/generator.py |4 ++
 python/libvirt-override-api.xml |   12 +++-
 python/libvirt-override.c   |   45 
 src/driver.h|   12 
 src/libvirt.c   |  111 +++
 src/libvirt_public.syms |2 +
 7 files changed, 204 insertions(+), 9 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a832b65..7403a9a 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2686,13 +2686,19 @@ virDomainSnapshotPtr 
virDomainSnapshotCreateXML(virDomainPtr domain,
 char *virDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
   unsigned int flags);

-/* Flags valid for both virDomainSnapshotNum() and
- * virDomainSnapshotListNames().  */
+/* Flags valid for virDomainSnapshotNum(),
+ * virDomainSnapshotListNames(), virDomainSnapshotNumChildren(), and
+ * virDomainSnapshotListChildrenNames().  Note that the interpretation
+ * of flag (10) depends on which function it is passed to.  */
 typedef enum {
-VIR_DOMAIN_SNAPSHOT_LIST_ROOTS= (1  0), /* Filter by snapshots which
- have no parents */
-VIR_DOMAIN_SNAPSHOT_LIST_METADATA = (1  1), /* Filter by snapshots which
- have metadata */
+VIR_DOMAIN_SNAPSHOT_LIST_ROOTS   = (1  0), /* Filter by snapshots
+with no parents, when
+listing a domain */
+VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS = (1  0), /* List all descendants,
+not just children, when
+listing a snapshot */
+VIR_DOMAIN_SNAPSHOT_LIST_METADATA= (1  1), /* Filter by snapshots
+which have metadata */
 } virDomainSnapshotListFlags;

 /* Return the number of snapshots for this domain */
@@ -2702,6 +2708,15 @@ int virDomainSnapshotNum(virDomainPtr domain, unsigned 
int flags);
 int virDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
unsigned int flags);

+/* Return the number of child snapshots for this snapshot */
+int virDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot,
+ unsigned int flags);
+
+/* Get the names of all child snapshots for this snapshot */
+int virDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
+   char **names, int nameslen,
+   unsigned int flags);
+
 /* Get a handle to a named snapshot */
 virDomainSnapshotPtr virDomainSnapshotLookupByName(virDomainPtr domain,
const char *name,
diff --git a/python/generator.py b/python/generator.py
index 79558dd..71afdb7 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -352,6 +352,7 @@ skip_impl = (
 'virConnectListDefinedInterfaces',
 'virConnectListNWFilters',
 'virDomainSnapshotListNames',
+'virDomainSnapshotListChildrenNames',
 'virConnGetLastError',
 'virGetLastError',
 'virDomainGetInfo',
@@ -963,6 +964,9 @@ def nameFixup(name, classe, type, file):
 elif name[0:26] == virDomainSnapshotListNames:
 func = name[9:]
 func = string.lower(func[0:1]) + func[1:]
+elif name[0:28] == virDomainSnapshotNumChildren:
+func = name[17:]
+func = string.lower(func[0:1]) + func[1:]
 elif name[0:20] == virDomainSnapshotNum:
 func = name[9:]
 func = string.lower(func[0:1]) + func[1:]
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 3013e46..ef02f34 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ 

[libvirt] [PATCHv2 4/7] snapshot: virsh fallback for snapshot-list --from children

2011-09-30 Thread Eric Blake
Iterating over one level of children requires parsing all snapshots
and their parents; a bit of code shuffling makes it pretty easy
to do this as well.

* tools/virsh.c (cmdSnapshotList): Add another fallback.
---

v2: fix compilation error, rebase around ctl flag

 tools/virsh.c |   48 
 1 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index e3bc364..b2523d3 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -13117,6 +13117,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
   information needed, 1 for parent column */
 int numsnaps;
 char **names = NULL;
+char **parents = NULL;
 int actual = 0;
 int i;
 xmlDocPtr xml = NULL;
@@ -13132,6 +13133,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 bool tree = vshCommandOptBool(cmd, tree);
 const char *from = NULL;
 virDomainSnapshotPtr start = NULL;
+bool descendants = false;

 if (vshCommandOptString(cmd, from, from)  0) {
 vshError(ctl, _(invalid from argument '%s'), from);
@@ -13175,27 +13177,29 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;

 if (from) {
+descendants = vshCommandOptBool(cmd, descendants);
 start = virDomainSnapshotLookupByName(dom, from, 0);
 if (!start)
 goto cleanup;
-if (vshCommandOptBool(cmd, descendants) || tree) {
+if (descendants || tree) {
 flags |= VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
 }
 numsnaps = ctl-useSnapshotOld ? -1 :
 virDomainSnapshotNumChildren(start, flags);
-/* XXX Is it worth emulating --from without --tree on older servers?  
*/
-if (tree) {
-if (numsnaps = 0) {
-numsnaps++;
-} else if (ctl-useSnapshotOld ||
-   last_error-code == VIR_ERR_NO_SUPPORT) {
-/* We can emulate --tree --from.  */
+if (numsnaps  0) {
+/* XXX also want to emulate --descendants without --tree */
+if ((!descendants || tree) 
+(ctl-useSnapshotOld ||
+ last_error-code == VIR_ERR_NO_SUPPORT)) {
+/* We can emulate --from.  */
 virFreeError(last_error);
 last_error = NULL;
 ctl-useSnapshotOld = true;
 flags = ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
 numsnaps = virDomainSnapshotNum(dom, flags);
 }
+} else if (tree) {
+numsnaps++;
 }
 } else {
 numsnaps = virDomainSnapshotNum(dom, flags);
@@ -13259,9 +13263,11 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 if (actual  0)
 goto cleanup;

-if (tree) {
-char indentBuf[INDENT_BUFLEN];
-char **parents = vshCalloc(ctl, sizeof(char *), actual);
+if (!tree)
+qsort(names[0], actual, sizeof(char*), namesorter);
+
+if (tree || ctl-useSnapshotOld) {
+parents = vshCalloc(ctl, sizeof(char *), actual);
 for (i = (from  !ctl-useSnapshotOld); i  actual; i++) {
 /* free up memory from previous iterations of the loop */
 if (snapshot)
@@ -13275,6 +13281,9 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 }
 }
+}
+if (tree) {
+char indentBuf[INDENT_BUFLEN];
 for (i = 0 ; i  actual ; i++) {
 memset(indentBuf, '\0', sizeof indentBuf);
 if (ctl-useSnapshotOld ? STREQ(names[i], from) : !parents[i])
@@ -13288,16 +13297,19 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 0,
 indentBuf);
 }
-for (i = 0 ; i  actual ; i++)
-VIR_FREE(parents[i]);
-VIR_FREE(parents);

 ret = true;
 goto cleanup;
 } else {
-qsort(names[0], actual, sizeof(char*), namesorter);
+if (ctl-useSnapshotOld  descendants) {
+/* XXX emulate --descendants as well */
+goto cleanup;
+}

 for (i = 0; i  actual; i++) {
+if (ctl-useSnapshotOld  STRNEQ_NULLABLE(parents[i], from))
+continue;
+
 /* free up memory from previous iterations of the loop */
 VIR_FREE(parent);
 VIR_FREE(state);
@@ -13362,9 +13374,13 @@ cleanup:
 xmlXPathFreeContext(ctxt);
 xmlFreeDoc(xml);
 VIR_FREE(doc);
-for (i = 0; i  actual; i++)
+for (i = 0; i  actual; i++) {
 VIR_FREE(names[i]);
+if (parents)
+VIR_FREE(parents[i]);
+}
 VIR_FREE(names);
+VIR_FREE(parents);
 if (dom)
 virDomainFree(dom);

-- 
1.7.4.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv2 2/7] snapshot: virsh snapshot-list and children

2011-09-30 Thread Eric Blake
Sometimes, we only care about one branch of the snapshot hierarchy.
Make it easier to list a single branch, by using the new APIs.

Technically, I could emulate these new virsh options on old servers
by doing a complete dump, then scraping xml to filter out just the
snapshots that I care about, but I didn't want to do that in this patch.

* tools/virsh.c (cmdSnapshotList): Add --from, --descendants.
* tools/virsh.pod (snapshot-list): Document them.
---

v2: minor rebase cleanups

 tools/virsh.c   |   76 ---
 tools/virsh.pod |9 ++-
 2 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 955b8df..adafe86 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -13102,6 +13102,8 @@ static const vshCmdOptDef opts_snapshot_list[] = {
 {metadata, VSH_OT_BOOL, 0,
  N_(list only snapshots that have metadata that would prevent undefine)},
 {tree, VSH_OT_BOOL, 0, N_(list snapshots in a tree)},
+{from, VSH_OT_DATA, 0, N_(limit list to children of given snapshot)},
+{descendants, VSH_OT_BOOL, 0, N_(with --from, list all descendants)},
 {NULL, 0, 0, NULL}
 };

@@ -13128,25 +13130,36 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 char timestr[100];
 struct tm time_info;
 bool tree = vshCommandOptBool(cmd, tree);
+const char *from = NULL;
+virDomainSnapshotPtr start = NULL;
+
+if (vshCommandOptString(cmd, from, from)  0) {
+vshError(ctl, _(invalid from argument '%s'), from);
+goto cleanup;
+}

 if (vshCommandOptBool(cmd, parent)) {
 if (vshCommandOptBool(cmd, roots)) {
 vshError(ctl, %s,
- _(--parent and --roots are mutually exlusive));
+ _(--parent and --roots are mutually exclusive));
 return false;
 }
 if (tree) {
 vshError(ctl, %s,
- _(--parent and --tree are mutually exlusive));
+ _(--parent and --tree are mutually exclusive));
 return false;
 }
 parent_filter = 1;
 } else if (vshCommandOptBool(cmd, roots)) {
 if (tree) {
 vshError(ctl, %s,
- _(--roots and --tree are mutually exlusive));
+ _(--roots and --tree are mutually exclusive));
 return false;
 }
+if (from) {
+vshError(ctl, %s,
+ _(--roots and --from are mutually exclusive));
+}
 flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
 }

@@ -13161,16 +13174,29 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 if (dom == NULL)
 goto cleanup;

-numsnaps = virDomainSnapshotNum(dom, flags);
-
-/* Fall back to simulation if --roots was unsupported.  */
-if (numsnaps  0  last_error-code == VIR_ERR_INVALID_ARG 
-(flags  VIR_DOMAIN_SNAPSHOT_LIST_ROOTS)) {
-virFreeError(last_error);
-last_error = NULL;
-parent_filter = -1;
-flags = ~VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
+if (from) {
+start = virDomainSnapshotLookupByName(dom, from, 0);
+if (!start)
+goto cleanup;
+if (vshCommandOptBool(cmd, descendants) || tree) {
+flags |= VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
+}
+numsnaps = virDomainSnapshotNumChildren(start, flags);
+if (numsnaps = 0  tree)
+numsnaps++;
+/* XXX Is it worth emulating --from on older servers?  */
+} else {
 numsnaps = virDomainSnapshotNum(dom, flags);
+
+/* Fall back to simulation if --roots was unsupported. */
+if (numsnaps  0  last_error-code == VIR_ERR_INVALID_ARG 
+(flags  VIR_DOMAIN_SNAPSHOT_LIST_ROOTS)) {
+virFreeError(last_error);
+last_error = NULL;
+parent_filter = -1;
+flags = ~VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
+numsnaps = virDomainSnapshotNum(dom, flags);
+}
 }

 if (numsnaps  0)
@@ -13196,14 +13222,32 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 if (VIR_ALLOC_N(names, numsnaps)  0)
 goto cleanup;

-actual = virDomainSnapshotListNames(dom, names, numsnaps, flags);
+if (from) {
+/* When mixing --from and --tree, we want to start the tree at the
+ * given snapshot.  Without --tree, only list the children.  */
+if (tree) {
+if (numsnaps)
+actual = virDomainSnapshotListChildrenNames(start, names + 1,
+numsnaps - 1,
+flags);
+if (actual = 0) {
+actual++;
+names[0] = vshStrdup(ctl, from);
+}
+} else {
+actual = virDomainSnapshotListChildrenNames(start, names,
+numsnaps, flags);

[libvirt] [PATCHv2 6/7] snapshot: remote protocol for snapshot children

2011-09-30 Thread Eric Blake
Very mechanical.  I'm so glad we've automated the generation of things,
compared to what it was in 0.8.x days, where this would be much longer.

* src/remote/remote_protocol.x
(REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN)
(REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES): New rpcs.
(remote_domain_snapshot_num_children_args)
(remote_domain_snapshot_num_children_ret)
(remote_domain_snapshot_list_children_names_args)
(remote_domain_snapshot_list_children_names_ret): New structs.
* src/remote/remote_driver.c (remote_driver): Use it.
* src/remote_protocol-structs: Update.
---

v2: fix typo in remote_protocol-structs

 src/remote/remote_driver.c   |2 ++
 src/remote/remote_protocol.x |   25 +++--
 src/remote_protocol-structs  |   20 
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 83f4f3c..0e303df 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -4411,6 +4411,8 @@ static virDriver remote_driver = {
 .domainSnapshotGetXMLDesc = remoteDomainSnapshotGetXMLDesc, /* 0.8.0 */
 .domainSnapshotNum = remoteDomainSnapshotNum, /* 0.8.0 */
 .domainSnapshotListNames = remoteDomainSnapshotListNames, /* 0.8.0 */
+.domainSnapshotNumChildren = remoteDomainSnapshotNumChildren, /* 0.9.7 */
+.domainSnapshotListChildrenNames = remoteDomainSnapshotListChildrenNames, 
/* 0.9.7 */
 .domainSnapshotLookupByName = remoteDomainSnapshotLookupByName, /* 0.8.0 */
 .domainHasCurrentSnapshot = remoteDomainHasCurrentSnapshot, /* 0.8.0 */
 .domainSnapshotGetParent = remoteDomainSnapshotGetParent, /* 0.9.7 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index c8a92fd..f95253e 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2067,6 +2067,25 @@ struct remote_domain_snapshot_list_names_ret {
 remote_nonnull_string namesREMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX; /* 
insert@1 */
 };

+struct remote_domain_snapshot_num_children_args {
+remote_nonnull_domain_snapshot snap;
+unsigned int flags;
+};
+
+struct remote_domain_snapshot_num_children_ret {
+int num;
+};
+
+struct remote_domain_snapshot_list_children_names_args {
+remote_nonnull_domain_snapshot snap;
+int maxnames;
+unsigned int flags;
+};
+
+struct remote_domain_snapshot_list_children_names_ret {
+remote_nonnull_string namesREMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX; /* 
insert@1 */
+};
+
 struct remote_domain_snapshot_lookup_by_name_args {
 remote_nonnull_domain dom;
 remote_nonnull_string name;
@@ -2524,8 +2543,10 @@ enum remote_procedure {
 REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241, /* skipgen skipgen */
 REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_SPEED = 242, /* autogen autogen */
 REMOTE_PROC_DOMAIN_BLOCK_STATS_FLAGS = 243, /* skipgen skipgen */
-REMOTE_PROC_DOMAIN_SNAPSHOT_GET_PARENT = 244, /* autogen autogen */
-REMOTE_PROC_DOMAIN_RESET = 245 /* autogen autogen */
+REMOTE_PROC_DOMAIN_SNAPSHOT_GET_PARENT = 244, /* autogen autogen 
priority:high */
+REMOTE_PROC_DOMAIN_RESET = 245, /* autogen autogen */
+REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN = 246, /* autogen autogen 
priority:high */
+REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247 /* autogen autogen 
priority:high */

 /*
  * Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 69175cc..7894441 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1557,6 +1557,24 @@ struct remote_domain_snapshot_list_names_ret {
 remote_nonnull_string * names_val;
 } names;
 };
+struct remote_domain_snapshot_num_children_args {
+remote_nonnull_domain_snapshot snap;
+u_int  flags;
+};
+struct remote_domain_snapshot_num_children_ret {
+intnum;
+};
+struct remote_domain_snapshot_list_children_names_args {
+remote_nonnull_domain_snapshot snap;
+intmaxnames;
+u_int  flags;
+};
+struct remote_domain_snapshot_list_children_names_ret {
+struct {
+u_int  names_len;
+remote_nonnull_string * names_val;
+} names;
+};
 struct remote_domain_snapshot_lookup_by_name_args {
 remote_nonnull_domain  dom;
 remote_nonnull_string  name;
@@ -1971,4 +1989,6 @@ enum remote_procedure {
 REMOTE_PROC_DOMAIN_BLOCK_STATS_FLAGS = 243,
 REMOTE_PROC_DOMAIN_SNAPSHOT_GET_PARENT = 244,
 REMOTE_PROC_DOMAIN_RESET = 245,
+REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN = 246,
+REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247,
 };
-- 
1.7.4.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv2 7/7] snapshot: implement snapshot children listing in qemu

2011-09-30 Thread Eric Blake
Not too hard to wire up.  The trickiest part is realizing that
listing children of a snapshot cannot use SNAPSHOT_LIST_ROOTS,
and that we overloaded that bit to also mean SNAPSHOT_LIST_DESCENDANTS;
we use that bit to decide which iteration to use, but don't want
the existing counting/listing functions to see that bit.

* src/conf/domain_conf.h (virDomainSnapshotObjListNumFrom)
(virDomainSnapshotObjListGetNamesFrom): New prototypes.
* src/conf/domain_conf.c (virDomainSnapshotObjListNumFrom)
(virDomainSnapshotObjListGetNamesFrom): New functions.
* src/libvirt_private.syms (domain_conf.h): Export them.
* src/qemu/qemu_driver.c (qemuDomainSnapshotNumChildren)
(qemuDomainSnapshotListChildrenNames): New functions.
---

v2: no change, but now virsh changes have been tested both with
and without this patch

 src/conf/domain_conf.c   |   51 +++
 src/conf/domain_conf.h   |7 
 src/libvirt_private.syms |2 +
 src/qemu/qemu_driver.c   |   87 ++
 4 files changed, 147 insertions(+), 0 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c141982..438e3b6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -12138,6 +12138,37 @@ cleanup:
 return -1;
 }

+int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot,
+ virDomainSnapshotObjListPtr snapshots,
+ char **const names, int maxnames,
+ unsigned int flags)
+{
+struct virDomainSnapshotNameData data = { 0, 0, maxnames, names, 0 };
+int i;
+
+data.flags = flags  ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
+
+if (flags  VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS)
+virDomainSnapshotForEachDescendant(snapshots, snapshot,
+   virDomainSnapshotObjListCopyNames,
+   data);
+else
+virDomainSnapshotForEachChild(snapshots, snapshot,
+  virDomainSnapshotObjListCopyNames, 
data);
+
+if (data.oom) {
+virReportOOMError();
+goto cleanup;
+}
+
+return data.numnames;
+
+cleanup:
+for (i = 0; i  data.numnames; i++)
+VIR_FREE(data.names[i]);
+return -1;
+}
+
 struct virDomainSnapshotNumData {
 int count;
 unsigned int flags;
@@ -12165,6 +12196,26 @@ int 
virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
 return data.count;
 }

+int
+virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot,
+virDomainSnapshotObjListPtr snapshots,
+unsigned int flags)
+{
+struct virDomainSnapshotNumData data = { 0, 0 };
+
+data.flags = flags  ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
+
+if (flags  VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS)
+virDomainSnapshotForEachDescendant(snapshots, snapshot,
+   virDomainSnapshotObjListCount,
+   data);
+else
+virDomainSnapshotForEachChild(snapshots, snapshot,
+  virDomainSnapshotObjListCount, data);
+
+return data.count;
+}
+
 virDomainSnapshotObjPtr
 virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
 const char *name)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0bc0042..1258740 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1488,6 +1488,13 @@ int 
virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots,
  unsigned int flags);
 int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
 unsigned int flags);
+int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot,
+ virDomainSnapshotObjListPtr snapshots,
+ char **const names, int maxnames,
+ unsigned int flags);
+int virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot,
+virDomainSnapshotObjListPtr snapshots,
+unsigned int flags);
 virDomainSnapshotObjPtr virDomainSnapshotFindByName(const 
virDomainSnapshotObjListPtr snapshots,
 const char *name);
 void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c2a3fab..6b9ceaa 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -413,7 +413,9 @@ virDomainSnapshotForEachChild;
 virDomainSnapshotForEachDescendant;
 virDomainSnapshotHasChildren;
 virDomainSnapshotObjListGetNames;
+virDomainSnapshotObjListGetNamesFrom;
 

[libvirt] [PATCHv2 5/7] snapshot: virsh fallback for snapshot-list --descendants --from

2011-09-30 Thread Eric Blake
Given a list of snapshots and their parents, finding all descendants
requires a hairy traversal.  This code is O(n^3); it could maybe be
made to scale O(n^2) with the use of a hash table, but that costs more
memory.  Hopefully there aren't too many people with a hierarchy
so large as to approach REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX (1024).

* tools/virsh.c (cmdSnapshotList): Add final fallback.
---

v2: rebase around ctl flag

 tools/virsh.c |   67 +++--
 1 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index b2523d3..ec6f854 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -13133,6 +13133,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 bool tree = vshCommandOptBool(cmd, tree);
 const char *from = NULL;
 virDomainSnapshotPtr start = NULL;
+int start_index = -1;
 bool descendants = false;

 if (vshCommandOptString(cmd, from, from)  0) {
@@ -13187,10 +13188,8 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 numsnaps = ctl-useSnapshotOld ? -1 :
 virDomainSnapshotNumChildren(start, flags);
 if (numsnaps  0) {
-/* XXX also want to emulate --descendants without --tree */
-if ((!descendants || tree) 
-(ctl-useSnapshotOld ||
- last_error-code == VIR_ERR_NO_SUPPORT)) {
+if (ctl-useSnapshotOld ||
+last_error-code == VIR_ERR_NO_SUPPORT) {
 /* We can emulate --from.  */
 virFreeError(last_error);
 last_error = NULL;
@@ -13269,6 +13268,11 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 if (tree || ctl-useSnapshotOld) {
 parents = vshCalloc(ctl, sizeof(char *), actual);
 for (i = (from  !ctl-useSnapshotOld); i  actual; i++) {
+if (ctl-useSnapshotOld  STREQ(names[i], from)) {
+start_index = i;
+continue;
+}
+
 /* free up memory from previous iterations of the loop */
 if (snapshot)
 virDomainSnapshotFree(snapshot);
@@ -13302,12 +13306,61 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 goto cleanup;
 } else {
 if (ctl-useSnapshotOld  descendants) {
-/* XXX emulate --descendants as well */
-goto cleanup;
+bool changed = false;
+
+/* Make multiple passes over the list - first pass NULLs
+ * out all roots except start, remaining passes NULL out
+ * any entry whose parent is not still in list.  Also, we
+ * NULL out parent when name is known to be in list.
+ * Sorry, this is O(n^3) - hope your hierarchy isn't huge.  */
+if (start_index  0) {
+vshError(ctl, _(snapshot %s disappeared from list), from);
+goto cleanup;
+}
+for (i = 0; i  actual; i++) {
+if (i == start_index)
+continue;
+if (!parents[i]) {
+VIR_FREE(names[i]);
+} else if (STREQ(parents[i], from)) {
+VIR_FREE(parents[i]);
+changed = true;
+}
+}
+if (!changed) {
+ret = true;
+goto cleanup;
+}
+while (changed) {
+changed = false;
+for (i = 0; i  actual; i++) {
+bool found = false;
+int j;
+
+if (!names[i] || !parents[i])
+continue;
+for (j = 0; j  actual; j++) {
+if (!names[j] || i == j)
+continue;
+if (STREQ(parents[i], names[j])) {
+found = true;
+if (!parents[j])
+VIR_FREE(parents[i]);
+break;
+}
+}
+if (!found) {
+changed = true;
+VIR_FREE(names[i]);
+}
+}
+}
+VIR_FREE(names[start_index]);
 }

 for (i = 0; i  actual; i++) {
-if (ctl-useSnapshotOld  STRNEQ_NULLABLE(parents[i], from))
+if (ctl-useSnapshotOld 
+(descendants ? !names[i] : STRNEQ_NULLABLE(parents[i], from)))
 continue;

 /* free up memory from previous iterations of the loop */
-- 
1.7.4.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] virsh: do not unlink NULL file

2011-09-30 Thread Marc-André Lureau
error:could not take a screenshot of xp
==6216== Syscall param unlink(pathname) points to unaddressable byte(s)
==6216==at 0x373A0D4937: unlink (syscall-template.S:82)
==6216==by 0x40FD73: cmdScreenshot (virsh.c:3070)
==6216==by 0x42BA0D: vshCommandRun (virsh.c:14920)
==6216==by 0x42EC97: main (virsh.c:16379)
==6216==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6216==
error:Requested operation is not valid: domain is not running
---
 tools/virsh.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 1909dce..89d355f 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -3004,7 +3004,7 @@ cmdScreenshot(vshControl *ctl, const vshCmd *cmd)
 unsigned int screen = 0;
 unsigned int flags = 0; /* currently unused */
 int ret = false;
-bool created = true;
+bool created = false;
 bool generated = false;
 char *mime = NULL;
 
@@ -3039,13 +3039,13 @@ cmdScreenshot(vshControl *ctl, const vshCmd *cmd)
 }
 
 if ((fd = open(file, O_WRONLY|O_CREAT|O_EXCL, 0666))  0) {
-created = false;
 if (errno != EEXIST ||
 (fd = open(file, O_WRONLY|O_TRUNC, 0666))  0) {
 vshError(ctl, _(cannot create file %s), file);
 goto cleanup;
 }
-}
+} else
+created = true;
 
 if (virStreamRecvAll(st, vshStreamSink, fd)  0) {
 vshError(ctl, _(could not receive data from domain %s), name);
-- 
1.7.6.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] virsh: do not unlink NULL file

2011-09-30 Thread Eric Blake

On 09/30/2011 07:05 PM, Marc-André Lureau wrote:

error:could not take a screenshot of xp
==6216== Syscall param unlink(pathname) points to unaddressable byte(s)
==6216==at 0x373A0D4937: unlink (syscall-template.S:82)
==6216==by 0x40FD73: cmdScreenshot (virsh.c:3070)
==6216==by 0x42BA0D: vshCommandRun (virsh.c:14920)
==6216==by 0x42EC97: main (virsh.c:16379)
==6216==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6216==
error:Requested operation is not valid: domain is not running
---
  tools/virsh.c |6 +++---
  1 files changed, 3 insertions(+), 3 deletions(-)


ACK.



-}
+} else
+created = true;


Style.  Any if-else that requires {} on one arm should use {} on both 
arms.  I fixed that and pushed.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] Set to NULL members that have been freed to prevent crashes

2011-09-30 Thread Marc-André Lureau
Do not crash if virStreamFinish is called after error.

==11000== Invalid read of size 4
==11000==at 0x373A8099A0: pthread_mutex_lock (pthread_mutex_lock.c:51)
==11000==by 0x4C7CADE: virMutexLock (threads-pthread.c:85)
==11000==by 0x4D57C31: virNetClientStreamRaiseError 
(virnetclientstream.c:203)
==11000==by 0x4D385E4: remoteStreamFinish (remote_driver.c:3541)
==11000==by 0x4D182F9: virStreamFinish (libvirt.c:14157)
==11000==by 0x40FDC4: cmdScreenshot (virsh.c:3075)
==11000==by 0x42BA40: vshCommandRun (virsh.c:14922)
==11000==by 0x42ECCA: main (virsh.c:16381)
==11000==  Address 0x59b86c0 is 16 bytes inside a block of size 216 free'd
==11000==at 0x4A06928: free (vg_replace_malloc.c:427)
==11000==by 0x4C69E2B: virFree (memory.c:310)
==11000==by 0x4D57B56: virNetClientStreamFree (virnetclientstream.c:184)
==11000==by 0x4D3DB7A: remoteDomainScreenshot (remote_client_bodies.h:1812)
==11000==by 0x4CFD245: virDomainScreenshot (libvirt.c:2903)
==11000==by 0x40FB73: cmdScreenshot (virsh.c:3029)
==11000==by 0x42BA40: vshCommandRun (virsh.c:14922)
==11000==by 0x42ECCA: main (virsh.c:16381)
---
 src/rpc/gendispatch.pl |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
index 039d785..b7ac3c8 100755
--- a/src/rpc/gendispatch.pl
+++ b/src/rpc/gendispatch.pl
@@ -1480,6 +1480,8 @@ elsif ($opt_k) {
 if ($call-{streamflag} ne none) {
 print virNetClientRemoveStream(priv-client, netst);\n;
 print virNetClientStreamFree(netst);\n;
+print st-driver = NULL;\n;
+print st-privateData = NULL;\n;
 }
 
 print goto done;\n;
-- 
1.7.6.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list