Re: [libvirt] Re: OpenVZ : The restriction of domain name should be addressed

2009-09-24 Thread Yuji NISHIDA

Thanks, Chris and Daniel

I corrected the code that I posted here according to your comments.
Chris, I now need to handle openvz containers by character(name) not  
integer(id) at all.


diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 54bcaa9..3b8505d 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -156,12 +156,13 @@ openvzDomainDefineCmd(virConnectPtr conn,
 fclose(fp);

 if (max_veid == 0) {
-max_veid = 100;
+/* OpenVZ reserves the IDs ranging from 0 to 100 */
+max_veid = 101;
 } else {
 max_veid++;
 }

-sprintf(str_id, %d, max_veid++);
+snprintf(str_id, sizeof(str_id), %d, max_veid);
 ADD_ARG_LIT(str_id);

 ADD_ARG_LIT(--name);
--
1.5.2.2


-
Yuji Nishida
nish...@nict.go.jp

On 2009/09/23, at 23:45, Daniel Veillard wrote:


On Wed, Sep 23, 2009 at 10:22:51AM +0200, Chris Lalancette wrote:

Yuji NISHIDA wrote:

Hi Daniel

Fixed patch according to your comments in openvzDomainDefineCmd  
func.


--- a/src/openvz_driver.c
+++ b/src/openvz_driver.c
@@ -101,6 +101,9 @@ static int openvzDomainDefineCmd(virConnectPtr  
conn,

 virDomainDefPtr vmdef)
{
int narg;
+int veid;
+int max_veid;
+FILE *fp;

for (narg = 0; narg  maxarg; narg++)
args[narg] = NULL;
@@ -130,6 +133,38 @@ static int openvzDomainDefineCmd(virConnectPtr
conn,
ADD_ARG_LIT(VZCTL);
ADD_ARG_LIT(--quiet);
ADD_ARG_LIT(create);
+
+if ((fp = popen(VZLIST  -a -ovpsid -H 2/dev/null, r)) ==
NULL) {
+openvzError(NULL, VIR_ERR_INTERNAL_ERROR, %s, _(popen
failed));
+return -1;
+}
+max_veid = 0;
+while(!feof(fp)) {
+if (fscanf(fp, %d\n, veid ) != 1) {
+if (feof(fp))
+break;
+
+openvzError(NULL, VIR_ERR_INTERNAL_ERROR,
+%s, _(Failed to parse vzlist output));
+goto cleanup;
+}
+if(veid  max_veid){
+max_veid = veid;
+}
+}
+fclose(fp);
+
+if(max_veid == 0){
+max_veid = 100;
+}else{
+max_veid++;
+}


You might want to add a comment saying that vpsid's below 100 are  
reserved for
OpenVZ internal use; otherwise, it looks like an odd place to begin  
numbering.


 good point.


+
+char str_id[10];
+sprintf( str_id, %d, max_veid++ );


You'll want to use snprintf here, like:

snprintf(str_id, sizeof(str_id), %d, max_veid++);

(bear with me on this part, since I don't know much about OpenVZ).

Besides that, though, I'm not sure you necessarily want to do it  
like this,
since you aren't really tracking the ID's properly.  The problem I  
see is that
if you do it like this, start the container, and then do virsh  
dumpxml
openvz, you won't see the ID in the output XML, like you do for  
the other
drivers.  Is that intentional?  If not, I think you'll want to  
store the id in
the virDomainDef-id member so that the information will be  
properly printed to

the user.


 I actually applied that patch on monday (after a couple of cleanups)
and apparently my reply mail is part of the set that got lost :-(
Author: Yuji NISHIDA nish...@nict.go.jp  2009-09-22 12:19:09
Committer: Daniel Veillard veill...@redhat.com  2009-09-22  
12:19:09

0c85095e46f3aba09ac401f559b76df0b0bea998

the snprintf wasn't looking critical because I don't think a %d can
generate more than 9 characters, but you're right in the absolute :-)

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] Miscellaneous fixes to build with -Werror

2009-09-24 Thread Chris Lalancette
Charles Duffy wrote:
 HACKING suggests compiling with --enable-compile-warnings=error before 
 submitting any patches; however, current master fails for me on this 
 account (CentOS 5.3; gcc 4.1.2).
 
 Please see attached. I suspect most of these should be uncontroversial 
 -- but wonder if perhaps virStrcpy uses would be better converted to 
 virStrcpyStatic rather than adding virStrcpy to the symbol list as done 

That's not possible in general.  The problem with virStrcpyStatic is that it
*has* to be a macro, and not only that, the users *have* to know that
sizeof(src) returns something meaningful.  Some callers do not, and cannot,
provide for that, so those callsites have to use virStrcpy.  I think adding it
to the symbol table will have to suffice, although I'm curious about warnings
themselves (since I compiled on RHEL-5.4 yesterday, and don't remember seeing
any warnings at all).  Can you post the warnings that you are seeing?

-- 
Chris Lalancette

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


Re: [libvirt] [PATCH] Fix a typo in virDiskHasValidPciAddr()

2009-09-24 Thread Chris Lalancette
Jiri Denemark wrote:
 Signed-off-by: Jiri Denemark jdene...@redhat.com
 ---
  src/conf/domain_conf.h |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
 index 09368d9..d494e54 100644
 --- a/src/conf/domain_conf.h
 +++ b/src/conf/domain_conf.h
 @@ -125,7 +125,7 @@ struct _virDomainDiskDef {
  static inline int
  virDiskHasValidPciAddr(virDomainDiskDefPtr def)
  {
 -return def-pci_addr.domain || def-pci_addr.domain || 
 def-pci_addr.slot;
 +return def-pci_addr.domain || def-pci_addr.bus || def-pci_addr.slot;
  }

Eek, good catch.

ACK

-- 
Chris Lalancette

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


Re: [libvirt] Miscellaneous fixes to build with -Werror

2009-09-24 Thread Chris Lalancette
Chris Lalancette wrote:
 Charles Duffy wrote:
 HACKING suggests compiling with --enable-compile-warnings=error before 
 submitting any patches; however, current master fails for me on this 
 account (CentOS 5.3; gcc 4.1.2).

 Please see attached. I suspect most of these should be uncontroversial 
 -- but wonder if perhaps virStrcpy uses would be better converted to 
 virStrcpyStatic rather than adding virStrcpy to the symbol list as done 
 
 That's not possible in general.  The problem with virStrcpyStatic is that it
 *has* to be a macro, and not only that, the users *have* to know that
 sizeof(src) returns something meaningful.  Some callers do not, and cannot,
 provide for that, so those callsites have to use virStrcpy.  I think adding it
 to the symbol table will have to suffice, although I'm curious about warnings
 themselves (since I compiled on RHEL-5.4 yesterday, and don't remember seeing
 any warnings at all).  Can you post the warnings that you are seeing?

Actually, I take this (partially) back.  I had forgotten to add on the
--enable-compile-warnings=error, so I missed the warnings in the sea of output.
 So all of your fixes except for the virStrcpy() one I saw, and in point of fact
those are all real bugs.  (The log_level fix in qemudSetLogging() does also seem
right; it's possible that we don't set the var_name in GET_CONF_INT if we don't
find it in the config file, so initializing it to 0 seems to be the right thing
to do).

I didn't see the error about the virStrcpy one, so I would still be curious as
to what you are seeing there.

-- 
Chris Lalancette

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


Re: [libvirt] Miscellaneous fixes to build with -Werror

2009-09-24 Thread Mark McLoughlin
Interesting that gcc-4.41 isn't giving me any warnings

On Wed, 2009-09-23 at 12:32 -0500, Charles Duffy wrote:
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index af215ca..25d983e 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -6132,7 +6132,7 @@ static int
 qemudDomainDetachHostPciDevice(virConnectPtr conn,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
  {
 -virDomainHostdevDefPtr detach;
 +virDomainHostdevDefPtr detach = NULL;
  char *cmd, *reply;
  int i, ret;
  pciDevice *pci;

Looks like a very real bug, so I just went ahead and pused this one

Thanks,
Mark.

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


Re: [libvirt] [PATCH] Fix a typo in virDiskHasValidPciAddr()

2009-09-24 Thread Mark McLoughlin
On Wed, 2009-09-23 at 18:46 +0200, Jiri Denemark wrote:
 Signed-off-by: Jiri Denemark jdene...@redhat.com
 ---
  src/conf/domain_conf.h |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
 index 09368d9..d494e54 100644
 --- a/src/conf/domain_conf.h
 +++ b/src/conf/domain_conf.h
 @@ -125,7 +125,7 @@ struct _virDomainDiskDef {
  static inline int
  virDiskHasValidPciAddr(virDomainDiskDefPtr def)
  {
 -return def-pci_addr.domain || def-pci_addr.domain || 
 def-pci_addr.slot;
 +return def-pci_addr.domain || def-pci_addr.bus || def-pci_addr.slot;
  }
  

Nice catch, I've pushed this and the same fix for
virNetHasValidPciAddr()

Thanks,
Mark.

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


Re: [libvirt] qemu_driver migrateuri handling broken?

2009-09-24 Thread Gregor Schaffrath
On Wed, Sep 23, 2009 at 10:05:36AM +0200, Chris Lalancette wrote:
  We are working on a new tunnelled migration scheme that will be
  uniform across drivers.
  ic - To be honest, I was confused by the migrateuri anyhow, since I
  considered the situation where libvirt traffic is tunneled via SSH, but
  Xen-/KVM-/foo communication may be direct a rather rare exception (or am
  I mistaken?) (I understood that this was the rationale behind the
  hostname-Query in the first place)
 
 Well, the rationale is that you may have two paths to get to a machine, and 
 you
 may only want to allow migration traffic on one of them (say, a direct
 cross-over) since the data goes across unencrypted.  So you might have a 
 machine
 with eth0 and eth1, where eth0 is exposed to the world, and you have libvirtd
 listening on eth0.  But then when you actually do the migration, you want it 
 to
 send the data across on eth1.
 
 Note also that libvirt traffic tunnelled via ssh isn't the only method, you 
 can
 also attach to libvirtd via TLS and TCP (with SASL encryption).
Hm - I acknowledge that there might be such situation, so you want to
have this feature. 
And as long as there's a way around the assumption that the remote hostname - 
especially without a domain part - is resolvable at the sending side, my only
concern would be a unified migrateuri syntax, which seems to be on the
way :) .

I guess my actual confusion is rather about the choice of the default
behaviour, than the feature's existence (since I never had the
split-path-situation in this context, but definitely had an environment where 
`hostname` output would not be resolvable, and I deemed the latter more probable
than the prior) - but that's certainly debatable.

  the part doesn't do much besides setting the port - the hostname is even
  ignored ;) ... and the error comes from the receiving side - not the
  sending one.
  
  Therefore as far as I see, the only thing broken is that now the sending
  side can't choose the listening port number on the receiving side (is
  this a debugging feature?)
 
 Not exactly a debugging feature, more a give more control to the admin.  If
 you do not supply a migrateuri, then libvirtd will choose a port between 49152
 and 49216.  However, if you don't want to open up all of those ports on your
 firewall, you can specify a migrateuri to say use *this* port, and then you
 only have to open up one port in the firewall.  So we do need to allow the
 migrateuri, and removing it isn't really feasible.
Again acknowledged, but then I would request a possibility to
specify the IP, while leaving the port choice up to the receiving side
(basically making the port specification optional rather than
mandatory).

My rationale for the request would be that when you consider scripted
(i.e. automated) management of virtual nodes along with the possibility
of several concurrent migrations, the port choice on the sending side
is likely to turn out awkward, even though you may have an environment
without DNS, or with dual-homing (and therefore need to specify the 
migrateuri).

 
 The tunnelled migration stuff should make this a bit easier, although we'll
 still have to allow the migrateuri type stuff for the dual-homed situation.
Hm - I don't know what exactly you have in mind (not familiar with the
plans). But I'd like to bring forward the point that as a user I was quite
confused, because I intuitively expected a different default behaviour
than the one libvirt currently exhibits (i.e., I was not prepared to get
a 'hostname could not be resolved' type of error, when I specified an IP
as migration destination ;) ).

Cheers,
Gregor.

 
 -- 
 Chris Lalancette

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


Re: [libvirt] [PATCH 1/9] Clarify documentation for private symbols

2009-09-24 Thread Daniel P. Berrange
On Fri, Sep 18, 2009 at 05:26:08PM +0200, Wolfgang Mauerer wrote:
 The instruction See Makefile.am in libvirt.private_syms
 always makes me think that this file is autogenerated
 and should not be touched manually. This patch spares
 every reader of libvirt.private_syms the hassle of
 reading Makefile.am before augmenting libvirt.private_syms.
 
 Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
 Signed-off-by: Jan Kiszka jan.kis...@siemens.com
 ---
  src/libvirt_private.syms |3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)
 
 diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
 index 867678f..f724493 100644
 --- a/src/libvirt_private.syms
 +++ b/src/libvirt_private.syms
 @@ -1,5 +1,6 @@
  #
 -# General private symbols. See Makefile.am.
 +# General private symbols. Add symbols here, and see Makefile.am for
 +# more details.
  #


ACK, this is fine

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

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


Re: [libvirt] [PATCH 2/9] Extend disk element with controller information

2009-09-24 Thread Daniel P. Berrange
On Fri, Sep 18, 2009 at 05:26:09PM +0200, Wolfgang Mauerer wrote:
 This allows us to connect a disk with a specific controller,
 which is required for disk hotadd/remove. A new XML child
 element is added to the disk container:
 
 disk
 ...
   controller pci_addr=addr id=identifier bus=number 
 unit=number/
 /disk
 
 Either id _or_ pci_addr can be specified. When the controller
 has been brought into the system via tghe hotplug mechanism also
 included in this patch series, it will typically have an ID.
 In other cases, the controller can also be specified with
 the PCI address.

I think it would be desriable to make 'id' the mandatory
argument and not use 'pci_addr' in this area of the XML.

controller id=identifier bus=number unit=number/

If fact I think it'd be good to rename 'id' to 'name'
since in libvirt context we typically use 'id' to be
be positive integer identifier. 'name' reflects the
fact that this device idenifier is really a string.

Outside the scope of your patches, I think it would be 
worth adding a 'name' attribute to all devices in the
libvirt XML as a standardized unique identifier. We
already have to keep track of a 'name' internally for
NIC hotplug with QEMU, and with QEMU's qdev work we're
going to end up having to track a 'name' for pretty much
all devices. Thus we might as well expose it in the XML

  memmove(target, target+6, strlen(target)-5);
 +} else if ((controller == NULL) 
 +   (xmlStrEqual(cur-name, BAD_CAST controller))) {
 +   controller_id = virXMLPropString(cur, id);
 +   bus_id = virXMLPropString(cur, bus);
 +   unit_id = virXMLPropString(cur, unit);
  } else if ((driverName == NULL) 
 (xmlStrEqual(cur-name, BAD_CAST driver))) {
  driverName = virXMLPropString(cur, name);
 @@ -800,6 +811,24 @@ virDomainDiskDefParseXML(virConnectPtr conn,
  }
  }
  
 +if (controller) {
 +def-controller_id = controller_id;
 +
 + def-bus_id = -1;
 + if (bus_id  virStrToLong_i(bus_id, NULL, 10, def-bus_id)  0) {
 + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
 +  _(Cannot parse controller 'bus' attribute));
 + goto error;
 +  } 
 +
 + def-unit_id = -1;
 + if (unit_id  virStrToLong_i(unit_id, NULL, 10, def-unit_id)  0) {
 + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
 +  _(Cannot parse controller 'unit' attribute));
 + goto error;
 + } 
 +}
 +

There's a few whitespace issues here - I guess some tabs crept
into the patch


Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

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


Re: [libvirt] [PATCH 3/9] Add new domain device: controller

2009-09-24 Thread Daniel P. Berrange
On Fri, Sep 18, 2009 at 05:26:10PM +0200, Wolfgang Mauerer wrote:
 This augments virDomainDevice with a controller element
 that is used to represent disk controllers (e.g., scsi
 controllers). The XML format is given by
 
 controller type=scsi id=my_id
bus addr=Domain:Bus:Slot
 /controller
 
 where type denotes the disk interface (scsi, ide,...), id
 is an arbitrary string that identifies the controller for
 disk hotadd/remove, and bus addr denotes the controller address
 on the PCI bus.
 
 The bus element can be omitted; in this case,
 an address will be assigned automatically. Currently,
 only hotplugging scsi controllers on a PCI bus
 is supported, and this only for qemu guests

As mentioned in the previous patch, I reckon 'id' is better
called 'name'. 

For PCI addresses, it is desirable to fully normalize the XML
format, by which I mean have separate attributes for domain,
bus and slot. We already have a syntax for PCI addresses used
for host device passthrough, so it'd make sense to use the
same syntax here for controllers. More broadly, we're probably
going to have to add a PCI address element to all our devices.
While it is unlikely we'll need non-PCI addresses, it doesn't
hurt to make it explicit by adding a type='pci' attribute

Thus I'd suggest

address type='pci' domain='0x' bus='0x06' slot='0x12'/

Instead of

bus addr=Domain:Bus:Slot

In the domain_conf.c/.h parser, we could have a datatype like

   enum {
  VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI,

  VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
   };

   typedef struct _virDomainDevicePCIAddress virDomainDevicePCIAddress;
   struct _virDomainDevicePCIAddress {
unsigned domain;
unsigned bus;
unsigned slot;
unsigned function;
   };
   typedef struct _virDomainDeviceAddress virDomainDeviceAddress;
   struct _virDomainDeviceAddress {
  int type;
  union {
 virDomainDevicePCIAddress pci;
  } data;
   };


Which we then use in all the places in domain_conf.h wanting
address information. Obviously we'd not use the 'function'
field in most places, but doesn't hurt to have it.

And a pair of methods for parsing/formatting this address info
we can call from all the appropriate locations.


 diff --git a/src/domain_conf.h b/src/domain_conf.h
 index 898f6c9..6b3cb09 100644
 --- a/src/domain_conf.h
 +++ b/src/domain_conf.h
 @@ -111,6 +111,11 @@ struct _virDomainDiskDef {
  char *src;
  char *dst;
  char *controller_id;
 +struct {
 +unsigned domain;
 +unsigned bus;
 +unsigned slot;
 +} controller_pci_addr;

I think we should stick to just using the controller name
as the mandatory identifier for cross-referencing disks
to controllers.

  char *driverName;
  char *driverType;
  char *serial;
 @@ -125,6 +130,19 @@ struct _virDomainDiskDef {
  virStorageEncryptionPtr encryption;
  };
  
 +/* Stores the virtual disk controller configuration */
 +typedef struct _virDomainControllerDef virDomainControllerDef;
 +typedef virDomainControllerDef *virDomainControllerDefPtr;
 +struct _virDomainControllerDef {
 +int type;
 +char *id;
 +struct {
 +unsigned domain;
 +unsigned bus;
 +unsigned slot;
 +} pci_addr;
 +};

With the generic address data type and s/id/name/, this would be just

  struct _virDomainControllerDef {
 int type;
 char *name;
 virDomainDeviceAddress addr;
  };


Regards,
Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

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


Re: [libvirt] [PATCH 5/9] Implement controller hotplugging

2009-09-24 Thread Daniel P. Berrange
On Fri, Sep 18, 2009 at 05:26:12PM +0200, Wolfgang Mauerer wrote:
 This enables to hot-add disk controllers without attached
 disks into the system. Previously, it was only possible to
 (implicitly) add disk controllers in the static machine
 configuration.
 
 Notice that the actual functionality is only available
 for qemu at present, but other emulators can be extended
 likewise.

Any idea what we can do about initial startup? eg, if we start
a guest with 1 SCSI controller and 1 disk, and then we've then
hotplugged a 2nd controller, and 1 disk.  When we later boot
or migrate the same guest, we need to have suitable QEMU command
line args to make sure we get 2 controllers each with the same
disk, rather than 1 controller with 2 disks. I'm not sure how
we do this in QEMU, hopefully the existing args support it in
some way I've not realized, or failing that the new qdev -device
args might help us.

 Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
 Signed-off-by: Jan Kiszka jan.kis...@siemens.com
 ---
  src/domain_conf.c|   26 +++---
  src/domain_conf.h|2 ++
  src/libvirt_private.syms |1 +
  src/qemu_driver.c|   21 +
  4 files changed, 43 insertions(+), 7 deletions(-)
 
 diff --git a/src/domain_conf.c b/src/domain_conf.c
 index d0fda64..ea51fda 100644
 --- a/src/domain_conf.c
 +++ b/src/domain_conf.c
 @@ -647,7 +647,6 @@ void virDomainRemoveInactive(virDomainObjListPtr doms,
  
  }
  
 -
  /* Parse the XML definition for a disk
   * @param node XML nodeset to parse for disk definition
   */
 @@ -2554,6 +2553,27 @@ virDomainDeviceDefPtr 
 virDomainDeviceDefParse(virConnectPtr conn,
  #endif
  
  
 +static int virDomainControllerCompare(virDomainControllerDefPtr a,
 +  virDomainControllerDefPtr b) {
 +if (a-pci_addr.bus == b-pci_addr.bus) {
 +if (a-pci_addr.domain == b-pci_addr.domain) 
 +return a-pci_addr.slot - b-pci_addr.slot;
 +
 +return a-pci_addr.domain - b-pci_addr.domain;
 +}
 +
 +return a-pci_addr.bus - b-pci_addr.bus;
 +}
 +
 +
 +int virDomainControllerQSort(const void *a, const void *b)
 +{
 +const virDomainControllerDefPtr *da = a;
 +const virDomainControllerDefPtr *db = b;
 +
 +return virDomainControllerCompare(*da, *db);
 +}
 +

I know we used todo this for disk devices, but I'd recommand not
going a qsort of devices when hotplugging/unplugging. For hotplug
always append to the list, for unplug just shuffle down later 
devices in the list to fill the hole.

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

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


Re: [libvirt] [PATCH 7/9] Remove surprises in the semantics of disk-hotadd

2009-09-24 Thread Daniel P. Berrange
On Fri, Sep 18, 2009 at 05:26:14PM +0200, Wolfgang Mauerer wrote:
 When a disk is added without an explicitly specified
 controller as host, then try to find the first available
 controller. If none exists, do not (as in previous versions)
 add a new PCI controller device with the disk attached,
 but bail out with an error. Notice that this patch changes
 the behaviour as compared to older libvirt releases, as
 has been discussed on the mailing list (see
 http://thread.gmane.org/gmane.comp.emulators.libvirt/15860)

Yes, I still think is the good way to go

Daniel

 
 Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
 Signed-off-by: Jan Kiszka jan.kis...@siemens.com
 ---
  src/qemu_driver.c |  172 
 ++---
  1 files changed, 85 insertions(+), 87 deletions(-)
 
 diff --git a/src/qemu_driver.c b/src/qemu_driver.c
 index 990f05a..f1c2a45 100644
 --- a/src/qemu_driver.c
 +++ b/src/qemu_driver.c
 @@ -5417,68 +5417,81 @@ try_command:
  controller_specified = 1;
  }
  
 -if (controller_specified) {
 -if (dev-data.disk-controller_id) {
 -for (i = 0 ; i  vm-def-ncontrollers ; i++) {
 -if (STREQ(dev-data.disk-controller_id, 
 -  vm-def-controllers[i]-id)) {
 -break;
 -}
 -}
 -
 -if (i == vm-def-ncontrollers) {
 -qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
 - _(Controller does not exist));
 -return -1;
 -}
 +if (!controller_specified) {
 +/* Find an appropriate controller for disk-hotadd. Notice that
 +   the admissible controller types (SCSI, virtio) have already
 +   been checked in qemudDomainAttachDevice. */
 +for (i = 0 ; i  vm-def-ncontrollers ; i++) {
 +if (vm-def-controllers[i]-type ==  dev-data.disk-type)
 +break;
 +}
 +
 +if (i == vm-def-ncontrollers) {
 +qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
 +  _(Cannot find appropriate controller for 
 hot-add));
 +return -1;
 +}
  
 -domain = vm-def-controllers[i]-pci_addr.domain;
 -bus= vm-def-controllers[i]-pci_addr.bus;
 -slot   = vm-def-controllers[i]-pci_addr.slot;
 -} else {
 -domain = dev-data.disk-controller_pci_addr.domain;
 -bus= dev-data.disk-controller_pci_addr.bus;
 -slot   = dev-data.disk-controller_pci_addr.slot;
 -
 -for (i = 0 ; i  vm-def-ncontrollers ; i++) {
 -if (domain ==  vm-def-controllers[i]-pci_addr.domain 
 -bus==  vm-def-controllers[i]-pci_addr.bus 
 -slot   ==  vm-def-controllers[i]-pci_addr.slot)
 -break;
 -}
 +domain = vm-def-controllers[i]-pci_addr.domain;
 +bus= vm-def-controllers[i]-pci_addr.bus;
 +slot   = vm-def-controllers[i]-pci_addr.slot;
 +}
  
 -if (i == vm-def-ncontrollers) {
 -qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
 - _(Controller does not exist));
 -return -1;
 +if (controller_specified  dev-data.disk-controller_id) {
 +for (i = 0 ; i  vm-def-ncontrollers ; i++) {
 +if (STREQ(dev-data.disk-controller_id, 
 +  vm-def-controllers[i]-id)) {
 +break;
  }
 - }
 -
 -if (dev-data.disk-bus_id != -1) {
 -virBufferVSprintf(buf, ,bus=%d, dev-data.disk-bus_id);
  }
  
 -if (dev-data.disk-unit_id != -1) {
 -virBufferVSprintf(buf, ,unit=%d, dev-data.disk-unit_id);
 +if (i == vm-def-ncontrollers) {
 +qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
 + _(Controller does not exist));
 +return -1;
 +}
 +
 +domain = vm-def-controllers[i]-pci_addr.domain;
 +bus= vm-def-controllers[i]-pci_addr.bus;
 +slot   = vm-def-controllers[i]-pci_addr.slot;
 +} else if (controller_specified) {
 +domain = dev-data.disk-controller_pci_addr.domain;
 +bus= dev-data.disk-controller_pci_addr.bus;
 +slot   = dev-data.disk-controller_pci_addr.slot;
 +
 +for (i = 0 ; i  vm-def-ncontrollers ; i++) {
 +if (domain ==  vm-def-controllers[i]-pci_addr.domain 
 +bus==  vm-def-controllers[i]-pci_addr.bus 
 +slot   ==  vm-def-controllers[i]-pci_addr.slot)
 +break;
  }
 +
 +if (i == vm-def-ncontrollers) {
 +qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
 + _(Controller does not exist));
 + 

Re: [libvirt] Miscellaneous fixes to build with -Werror

2009-09-24 Thread Chris Lalancette
Charles Duffy wrote:
 HACKING suggests compiling with --enable-compile-warnings=error before 
 submitting any patches; however, current master fails for me on this 
 account (CentOS 5.3; gcc 4.1.2).
 
 Please see attached. I suspect most of these should be uncontroversial 
 -- but wonder if perhaps virStrcpy uses would be better converted to 
 virStrcpyStatic rather than adding virStrcpy to the symbol list as done 
 here, and am curious about whether the need for explicit initialization 
 to silence a warning regarding qemudSetLogging's log_level indicates a 
 bug in the macro later used to assign that value.
 
 diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
 index 2bae782..ec2eab1 100644
 --- a/daemon/libvirtd.c
 +++ b/daemon/libvirtd.c
 @@ -2492,7 +2492,7 @@ remoteReadSaslAllowedUsernameList (virConfPtr conf 
 ATTRIBUTE_UNUSED,
   */
  static int
  qemudSetLogging(virConfPtr conf, const char *filename) {
 -int log_level;
 +int log_level = 0;
  char *log_filters = NULL;
  char *log_outputs = NULL;
  int ret = -1;

Looking at this more, I'm not sure.  The comment above GET_CONF_INT(log_level)
looks to be bogus; GET_CONF_INT does *not* return 0 if the value is not in the
config file, it doesn't change anything at all.  Still, I don't quite know the
reasoning behind the original change (back in early August), so I'm
uncomfortable changing it.

 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index af215ca..25d983e 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -6132,7 +6132,7 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr 
 conn,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
  {
 -virDomainHostdevDefPtr detach;
 +virDomainHostdevDefPtr detach = NULL;
  char *cmd, *reply;
  int i, ret;
  pciDevice *pci;

Mark McLoughlin pushed this one.

 diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
 index 20a3fa8..9c4102e 100644
 --- a/src/secret/secret_driver.c
 +++ b/src/secret/secret_driver.c
 @@ -432,7 +432,7 @@ static virSecretEntryPtr
  secretLoad(virConnectPtr conn, virSecretDriverStatePtr driver,
 const char *xml_basename)
  {
 -virSecretDefPtr def;
 +virSecretDefPtr def = NULL;
  virSecretEntryPtr secret = NULL, ret = NULL;
  char *xml_filename;

I just pushed this one because it's an obvious bugfix.

-- 
Chris Lalancette

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


[libvirt] [PATCH 21/27] Add API for issuing 'getfd' and 'closefd' monitor commands

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorCloseFileHandle and qemuMonitorSendFileHandle
  APIs for processing file handles
* src/qemu/qemu_driver.c: Convert NIC hotplug method over to
  use   qemuMonitorCloseFileHandle and qemuMonitorSendFileHandle
---
 src/qemu/qemu_driver.c   |   40 +++--
 src/qemu/qemu_monitor_text.c |   78 ++
 src/qemu/qemu_monitor_text.h |6 +++
 3 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b447a87..f8710a6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4619,7 +4619,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 {
 virDomainNetDefPtr net = dev-data.net;
 char *cmd = NULL, *reply = NULL, *remove_cmd = NULL;
-char *tapfd_name = NULL, *tapfd_close = NULL;
+char *tapfd_name = NULL;
 int i, tapfd = -1;
 unsigned domain, bus, slot;
 
@@ -4662,32 +4662,8 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 if (virAsprintf(tapfd_name, fd-%s, net-hostnet_name)  0)
 goto no_memory;
 
-if (virAsprintf(tapfd_close, closefd %s, tapfd_name)  0)
-goto no_memory;
-
-if (virAsprintf(cmd, getfd %s, tapfd_name)  0)
-goto no_memory;
-
-if (qemudMonitorCommandWithFd(vm, cmd, tapfd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(failed to pass fd to qemu with '%s'), cmd);
+if (qemuMonitorSendFileHandle(vm, tapfd_name, tapfd)  0)
 goto cleanup;
-}
-
-DEBUG(%s: getfd reply: %s, vm-def-name, reply);
-
-/* If the command isn't supported then qemu prints:
- * unknown command: getfd */
-if (strstr(reply, unknown command:)) {
-qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
- %s,
- _(bridge/network interface attach not supported: 

-   qemu 'getfd' monitor command not available));
-goto cleanup;
-}
-
-VIR_FREE(reply);
-VIR_FREE(cmd);
 }
 
 if (qemuBuildHostNetStr(conn, net, host_net_add , ' ',
@@ -4713,7 +4689,6 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 VIR_FREE(reply);
 VIR_FREE(cmd);
 VIR_FREE(tapfd_name);
-VIR_FREE(tapfd_close);
 if (tapfd != -1)
 close(tapfd);
 tapfd = -1;
@@ -4760,12 +4735,10 @@ try_remove:
 try_tapfd_close:
 VIR_FREE(reply);
 
-if (tapfd_close) {
-if (qemudMonitorCommand(vm, tapfd_close, reply)  0)
-VIR_WARN(_(Failed to close tapfd with '%s'\n), tapfd_close);
-else
-VIR_DEBUG(%s: closefd: %s\n, vm-def-name, reply);
-}
+if (tapfd_name 
+qemuMonitorCloseFileHandle(vm, tapfd_name)  0)
+VIR_WARN(_(Failed to close tapfd with '%s'\n), tapfd_name);
+
 goto cleanup;
 
 no_memory:
@@ -4774,7 +4747,6 @@ cleanup:
 VIR_FREE(cmd);
 VIR_FREE(reply);
 VIR_FREE(remove_cmd);
-VIR_FREE(tapfd_close);
 VIR_FREE(tapfd_name);
 if (tapfd != -1)
 close(tapfd);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 765a482..92a2dbd 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1551,3 +1551,81 @@ cleanup:
 VIR_FREE(reply);
 return ret;
 }
+
+
+int qemuMonitorSendFileHandle(const virDomainObjPtr vm,
+  const char *fdname,
+  int fd)
+{
+char *cmd;
+char *reply = NULL;
+int ret = -1;
+
+if (virAsprintf(cmd, getfd %s, fdname)  0) {
+virReportOOMError(NULL);
+return -1;
+}
+
+if (qemudMonitorCommandWithFd(vm, cmd, fd, reply)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _(failed to pass fd to qemu with '%s'), cmd);
+goto cleanup;
+}
+
+DEBUG(%s: getfd reply: %s, vm-def-name, reply);
+
+/* If the command isn't supported then qemu prints:
+ * unknown command: getfd */
+if (strstr(reply, unknown command:)) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT,
+ _(qemu does not support sending of file handles: 
%s),
+ reply);
+goto cleanup;
+}
+
+ret = 0;
+
+cleanup:
+VIR_FREE(cmd);
+VIR_FREE(reply);
+return ret;
+}
+
+
+int qemuMonitorCloseFileHandle(const virDomainObjPtr vm,
+   const char *fdname)
+{
+char *cmd;
+char *reply = NULL;
+int ret = -1;
+
+if (virAsprintf(cmd, closefd %s, fdname)  0) {
+virReportOOMError(NULL);
+return -1;
+}
+
+if (qemudMonitorCommand(vm, cmd, reply)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _(failed to 

[libvirt] [PATCH 05/27] Add API for 'stop' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add a new
  qemuMonitorStopCPUs() API
* src/qemu/qemu_driver.c: Replace direct monitor commands for 'stop'
  with qemuMonitorStopCPUs()
---
 src/qemu/qemu_driver.c   |   28 
 src/qemu/qemu_monitor_text.c |   13 +
 src/qemu/qemu_monitor_text.h |1 +
 3 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1717cbd..5ebd4b7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2749,7 +2749,6 @@ cleanup:
 
 static int qemudDomainSuspend(virDomainPtr dom) {
 struct qemud_driver *driver = dom-conn-privateData;
-char *info;
 virDomainObjPtr vm;
 int ret = -1;
 virDomainEventPtr event = NULL;
@@ -2770,17 +2769,12 @@ static int qemudDomainSuspend(virDomainPtr dom) {
 goto cleanup;
 }
 if (vm-state != VIR_DOMAIN_PAUSED) {
-if (qemudMonitorCommand(vm, stop, info)  0) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(suspend operation failed));
+if (qemuMonitorStopCPUs(vm)  0)
 goto cleanup;
-}
 vm-state = VIR_DOMAIN_PAUSED;
-qemudDebug(Reply %s, info);
 event = virDomainEventNewFromObj(vm,
  VIR_DOMAIN_EVENT_SUSPENDED,
  VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
-VIR_FREE(info);
 }
 if (virDomainSaveStatus(dom-conn, driver-stateDir, vm)  0)
 goto cleanup;
@@ -3365,13 +3359,9 @@ static int qemudDomainSave(virDomainPtr dom,
 /* Pause */
 if (vm-state == VIR_DOMAIN_RUNNING) {
 header.was_running = 1;
-if (qemudMonitorCommand(vm, stop, info)  0) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(suspend operation failed));
+if (qemuMonitorStopCPUs(vm)  0)
 goto cleanup;
-}
 vm-state = VIR_DOMAIN_PAUSED;
-qemudDebug(Reply %s, info);
 VIR_FREE(info);
 }
 
@@ -3527,13 +3517,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
 
 /* Pause domain for non-live dump */
 if (vm-state == VIR_DOMAIN_RUNNING) {
-if (qemudMonitorCommand (vm, stop, info)  0) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(suspending before dump failed));
+if (qemuMonitorStopCPUs(vm)  0)
 goto cleanup;
-}
-DEBUG (%s: stop reply: %s, vm-def-name, info);
-VIR_FREE(info);
 paused = 1;
 }
 
@@ -6747,13 +6732,8 @@ qemudDomainMigratePerform (virDomainPtr dom,
 
 if (!(flags  VIR_MIGRATE_LIVE)) {
 /* Pause domain for non-live migration */
-if (qemudMonitorCommand (vm, stop, info)  0) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(off-line migration specified, but 
suspend operation failed));
+if (qemuMonitorStopCPUs(vm)  0)
 goto cleanup;
-}
-DEBUG (%s: stop reply: %s, vm-def-name, info);
-VIR_FREE(info);
 paused = 1;
 
 event = virDomainEventNewFromObj(vm,
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 3c12073..ec30e72 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -438,6 +438,19 @@ qemuMonitorStartCPUs(virConnectPtr conn,
 }
 
 
+int
+qemuMonitorStopCPUs(const virDomainObjPtr vm) {
+char *info;
+
+if (qemudMonitorCommand(vm, stop, info)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ %s, _(cannot stop CPU execution));
+return -1;
+}
+VIR_FREE(info);
+return 0;
+}
+
 int qemuMonitorGetCPUInfo(const virDomainObjPtr vm,
   int **pids)
 {
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 2632ecf..eb1ba44 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -67,6 +67,7 @@ int qemudMonitorCommandExtra(const virDomainObjPtr vm,
 
 int qemuMonitorStartCPUs(virConnectPtr conn,
  const virDomainObjPtr vm);
+int qemuMonitorStopCPUs(const virDomainObjPtr vm);
 
 int qemuMonitorGetCPUInfo(const virDomainObjPtr vm,
   int **pids);
-- 
1.6.2.5

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


[libvirt] [PATCH 25/27] Remove low level monitor APIs from header file

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.h: Remove qemudMonitorCommand,
  qemudMonitorCommandWithFd, qemudMonitorCommandWithHandler,
  qemudMonitorCommandExtra low level APIs
* src/qemu/qemu_monitor.c: Replace s/qemud/qemuMonitor/
---
 src/qemu/qemu_monitor_text.c |  166 ++
 src/qemu/qemu_monitor_text.h |   33 
 2 files changed, 88 insertions(+), 111 deletions(-)

diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 0675bf5..2c41288 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -41,7 +41,17 @@
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
-static char *qemudEscape(const char *in, int shell)
+#define QEMU_CMD_PROMPT \n(qemu) 
+#define QEMU_PASSWD_PROMPT Password: 
+
+/* Return -1 for error, 0 for success */
+typedef int qemuMonitorExtraPromptHandler(const virDomainObjPtr vm,
+  const char *buf,
+  const char *prompt,
+  void *data);
+
+
+static char *qemuMonitorEscape(const char *in, int shell)
 {
 int len = 0;
 int i, j;
@@ -113,14 +123,14 @@ static char *qemudEscape(const char *in, int shell)
 return out;
 }
 
-static char *qemudEscapeMonitorArg(const char *in)
+static char *qemuMonitorEscapeArg(const char *in)
 {
-return qemudEscape(in, 0);
+return qemuMonitorEscape(in, 0);
 }
 
-static char *qemudEscapeShellArg(const char *in)
+static char *qemuMonitorEscapeShell(const char *in)
 {
-return qemudEscape(in, 1);
+return qemuMonitorEscape(in, 1);
 }
 
 /* Throw away any data available on the monitor
@@ -144,10 +154,10 @@ qemuMonitorDiscardPendingData(virDomainObjPtr vm) {
 }
 
 static int
-qemudMonitorSendUnix(const virDomainObjPtr vm,
- const char *cmd,
- size_t cmdlen,
- int scm_fd)
+qemuMonitorSendUnix(const virDomainObjPtr vm,
+const char *cmd,
+size_t cmdlen,
+int scm_fd)
 {
 struct msghdr msg;
 struct iovec iov[1];
@@ -183,9 +193,9 @@ qemudMonitorSendUnix(const virDomainObjPtr vm,
 }
 
 static int
-qemudMonitorSend(const virDomainObjPtr vm,
- const char *cmd,
- int scm_fd)
+qemuMonitorSend(const virDomainObjPtr vm,
+const char *cmd,
+int scm_fd)
 {
 char *full;
 size_t len;
@@ -198,7 +208,7 @@ qemudMonitorSend(const virDomainObjPtr vm,
 
 switch (vm-monitor_chr-type) {
 case VIR_DOMAIN_CHR_TYPE_UNIX:
-if (qemudMonitorSendUnix(vm, full, len, scm_fd)  0)
+if (qemuMonitorSendUnix(vm, full, len, scm_fd)  0)
 goto out;
 break;
 default:
@@ -214,14 +224,14 @@ out:
 return ret;
 }
 
-int
-qemudMonitorCommandWithHandler(const virDomainObjPtr vm,
-   const char *cmd,
-   const char *extraPrompt,
-   qemudMonitorExtraPromptHandler extraHandler,
-   void *handlerData,
-   int scm_fd,
-   char **reply) {
+static int
+qemuMonitorCommandWithHandler(const virDomainObjPtr vm,
+  const char *cmd,
+  const char *extraPrompt,
+  qemuMonitorExtraPromptHandler extraHandler,
+  void *handlerData,
+  int scm_fd,
+  char **reply) {
 int size = 0;
 char *buf = NULL;
 
@@ -233,7 +243,7 @@ qemudMonitorCommandWithHandler(const virDomainObjPtr vm,
 qemuMonitorDiscardPendingData(vm);
 
 VIR_DEBUG(Send '%s', cmd);
-if (qemudMonitorSend(vm, cmd, scm_fd)  0)
+if (qemuMonitorSend(vm, cmd, scm_fd)  0)
 return -1;
 
 *reply = NULL;
@@ -324,23 +334,23 @@ struct extraHandlerData
 };
 
 static int
-qemudMonitorCommandSimpleExtraHandler(const virDomainObjPtr vm,
-  const char *buf ATTRIBUTE_UNUSED,
-  const char *prompt ATTRIBUTE_UNUSED,
-  void *data_)
+qemuMonitorCommandSimpleExtraHandler(const virDomainObjPtr vm,
+ const char *buf ATTRIBUTE_UNUSED,
+ const char *prompt ATTRIBUTE_UNUSED,
+ void *data_)
 {
 struct extraHandlerData *data = data_;
 
 if (!data-first)
 return 0;
-if (qemudMonitorSend(vm, data-reply, -1)  0)
+if (qemuMonitorSend(vm, data-reply, -1)  0)
 return -1;
 data-first = false;
 return 0;
 }
 
-int
-qemudMonitorCommandExtra(const virDomainObjPtr vm,
+static int
+qemuMonitorCommandExtra(const virDomainObjPtr vm,
  const char *cmd,
  const char *extra,
  

[libvirt] [PATCH 17/27] Add APIs for sending 'usb_add' command for host devices

2009-09-24 Thread Daniel P. Berrange
One API adds an exact device based on bus+dev, the other adds
any device matching vendor+product

* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorAddUSBDeviceExact() and qemuMonitorAddUSBDeviceMatch()
  commands.
* src/qemu/qemu_driver.c: Switch over to using the new
qemuMonitorAddUSBDeviceExact() and qemuMonitorAddUSBDeviceMatch()
---
 src/qemu/qemu_driver.c   |   43 +---
 src/qemu/qemu_monitor_text.c |   73 ++
 src/qemu/qemu_monitor_text.h |7 
 3 files changed, 89 insertions(+), 34 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 635fb84..f33c24e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4984,7 +4984,6 @@ static int qemudDomainAttachHostUsbDevice(virConnectPtr 
conn,
   virDomainDeviceDefPtr dev)
 {
 int ret;
-char *cmd, *reply;
 
 if (VIR_REALLOC_N(vm-def-hostdevs, vm-def-nhostdevs+1)  0) {
 virReportOOMError(conn);
@@ -4992,43 +4991,19 @@ static int qemudDomainAttachHostUsbDevice(virConnectPtr 
conn,
 }
 
 if (dev-data.hostdev-source.subsys.u.usb.vendor) {
-ret = virAsprintf(cmd, usb_add host:%.4x:%.4x,
-  dev-data.hostdev-source.subsys.u.usb.vendor,
-  dev-data.hostdev-source.subsys.u.usb.product);
+ret = qemuMonitorAddUSBDeviceMatch(vm,
+   
dev-data.hostdev-source.subsys.u.usb.vendor,
+   
dev-data.hostdev-source.subsys.u.usb.product);
 } else {
-ret = virAsprintf(cmd, usb_add host:%.3d.%.3d,
-  dev-data.hostdev-source.subsys.u.usb.bus,
-  dev-data.hostdev-source.subsys.u.usb.device);
-}
-if (ret == -1) {
-virReportOOMError(conn);
-return -1;
-}
-
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(cannot attach usb device));
-VIR_FREE(cmd);
-return -1;
+ret = qemuMonitorAddUSBDeviceExact(vm,
+   
dev-data.hostdev-source.subsys.u.usb.bus,
+   
dev-data.hostdev-source.subsys.u.usb.device);
 }
 
-DEBUG (%s: attach_usb reply: %s, vm-def-name, reply);
-/* If the command failed qemu prints:
- * Could not add ... */
-if (strstr(reply, Could not add )) {
-qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  %s,
-  _(adding usb device failed));
-VIR_FREE(reply);
-VIR_FREE(cmd);
-return -1;
-}
-
-vm-def-hostdevs[vm-def-nhostdevs++] = dev-data.hostdev;
+if (ret != -1)
+vm-def-hostdevs[vm-def-nhostdevs++] = dev-data.hostdev;
 
-VIR_FREE(reply);
-VIR_FREE(cmd);
-return 0;
+return ret;
 }
 
 static int qemudDomainAttachHostDevice(virConnectPtr conn,
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index fd50cf2..0e0334c 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1242,3 +1242,76 @@ cleanup:
 VIR_FREE(safepath);
 return ret;
 }
+
+
+static int qemuMonitorAddUSBDevice(const virDomainObjPtr vm,
+   const char *addr)
+{
+char *cmd;
+char *reply = NULL;
+int ret = -1;
+
+if (virAsprintf(cmd, usb_add %s, addr)  0) {
+virReportOOMError(NULL);
+return -1;
+}
+
+if (qemudMonitorCommand(vm, cmd, reply)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ %s, _(cannot attach usb device));
+goto cleanup;
+}
+
+DEBUG (%s: attach_usb reply: %s, vm-def-name, reply);
+/* If the command failed qemu prints:
+ * Could not add ... */
+if (strstr(reply, Could not add )) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ %s, _(adding usb device failed));
+goto cleanup;
+}
+
+ret = 0;
+
+cleanup:
+VIR_FREE(cmd);
+VIR_FREE(reply);
+return ret;
+}
+
+
+int qemuMonitorAddUSBDeviceExact(const virDomainObjPtr vm,
+ int bus,
+ int dev)
+{
+int ret;
+char *addr;
+
+if (virAsprintf(addr, host:%.3d.%.3d, bus, dev)  0) {
+virReportOOMError(NULL);
+return -1;
+}
+
+ret = qemuMonitorAddUSBDevice(vm, addr);
+
+VIR_FREE(addr);
+return ret;
+}
+
+int qemuMonitorAddUSBDeviceMatch(const virDomainObjPtr vm,
+ int vendor,
+ int product)
+{
+int ret;
+char *addr;
+
+if (virAsprintf(addr, host:%.4x:%.4x, vendor, product)  0) {
+virReportOOMError(NULL);
+return -1;
+}
+
+  

[libvirt] [PATCH 15/27] Add API for issugin 'migrate' command with exec protocol

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorMigrateToCommand() API
* src/qemu/qemu_driver.c: Switch over to using the
  qemuMonitorMigrateToCommand() API for core dumps and save
  to file APIs
---
 src/libvirt_private.syms |1 +
 src/qemu/qemu_driver.c   |  119 --
 src/qemu/qemu_monitor_text.c |   63 +--
 src/qemu/qemu_monitor_text.h |4 ++
 4 files changed, 86 insertions(+), 101 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a6668f3..f8598c7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -453,6 +453,7 @@ virGetGroupID;
 virFileFindMountPoint;
 virFileWaitForDevices;
 virFileMatchesNameSuffix;
+virArgvToString;
 
 
 # usb.h
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f234639..da08af9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3170,11 +3170,6 @@ static char *qemudEscapeMonitorArg(const char *in)
 return qemudEscape(in, 0);
 }
 
-static char *qemudEscapeShellArg(const char *in)
-{
-return qemudEscape(in, 1);
-}
-
 #define QEMUD_SAVE_MAGIC LibvirtQemudSave
 #define QEMUD_SAVE_VERSION 2
 
@@ -3217,15 +3212,11 @@ static int qemudDomainSave(virDomainPtr dom,
 {
 struct qemud_driver *driver = dom-conn-privateData;
 virDomainObjPtr vm = NULL;
-char *command = NULL;
-char *info = NULL;
 int fd = -1;
-char *safe_path = NULL;
 char *xml = NULL;
 struct qemud_save_header header;
 int ret = -1;
 virDomainEventPtr event = NULL;
-int internalret;
 
 memset(header, 0, sizeof(header));
 memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
@@ -3267,7 +3258,6 @@ static int qemudDomainSave(virDomainPtr dom,
 if (qemuMonitorStopCPUs(vm)  0)
 goto cleanup;
 vm-state = VIR_DOMAIN_PAUSED;
-VIR_FREE(info);
 }
 
 /* Get XML for the domain */
@@ -3306,55 +3296,21 @@ static int qemudDomainSave(virDomainPtr dom,
 }
 fd = -1;
 
-/* Migrate to file */
-safe_path = qemudEscapeShellArg(path);
-if (!safe_path) {
-virReportOOMError(dom-conn);
-goto cleanup;
-}
-
-{
+if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
+const char *args[] = { cat, NULL };
+ret = qemuMonitorMigrateToCommand(vm, args, path);
+} else {
 const char *prog = qemudSaveCompressionTypeToString(header.compressed);
-const char *args;
-
-if (prog == NULL) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _(Invalid compress format %d), 
header.compressed);
-goto cleanup;
-}
-
-if (STREQ (prog, raw)) {
-prog = cat;
-args = ;
-} else {
-args = -c;
-}
-internalret = virAsprintf(command, migrate \exec:
-  %s %s  '%s' 2/dev/null\, prog, args,
-  safe_path);
-}
-
-if (internalret  0) {
-virReportOOMError(dom-conn);
-goto cleanup;
-}
-
-if (qemudMonitorCommand(vm, command, info)  0) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(migrate operation failed));
-goto cleanup;
+const char *args[] = {
+prog,
+-c,
+NULL
+};
+ret = qemuMonitorMigrateToCommand(vm, args, path);
 }
 
-DEBUG (%s: migrate reply: %s, vm-def-name, info);
-
-/* If the command isn't supported then qemu prints:
- * unknown command: migrate */
-if (strstr(info, unknown command:)) {
-qemudReportError (dom-conn, dom, NULL, VIR_ERR_NO_SUPPORT,
-  %s,
-  _('migrate' not supported by this qemu));
+if (ret  0)
 goto cleanup;
-}
 
 /* Shut it down */
 qemudShutdownVMDaemon(dom-conn, driver, vm);
@@ -3366,15 +3322,11 @@ static int qemudDomainSave(virDomainPtr dom,
 vm);
 vm = NULL;
 }
-ret = 0;
 
 cleanup:
 if (fd != -1)
 close(fd);
 VIR_FREE(xml);
-VIR_FREE(safe_path);
-VIR_FREE(command);
-VIR_FREE(info);
 if (ret != 0)
 unlink(path);
 if (vm)
@@ -3391,11 +3343,12 @@ static int qemudDomainCoreDump(virDomainPtr dom,
int flags ATTRIBUTE_UNUSED) {
 struct qemud_driver *driver = dom-conn-privateData;
 virDomainObjPtr vm;
-char *command = NULL;
-char *info = NULL;
-char *safe_path = NULL;
 int resume = 0, paused = 0;
 int ret = -1;
+const char *args[] = {
+cat,
+NULL,
+};
 
 qemuDriverLock(driver);
 vm = virDomainFindByUUID(driver-domains, dom-uuid);
@@ -3427,43 +3380,9 @@ static int qemudDomainCoreDump(virDomainPtr dom,
 paused = 1;
 }
 
-/* Migrate to file 

[libvirt] [PATCH 20/27] Add API for issuing 'pci_add storage' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  API qemuMonitorAddPCIDisk()
* src/qemu/qemu_driver.c: Convert over to using the new
  qemuMonitorAddPCIDisk() method, and remove now obsolete
  qemudEscape() method
---
 src/qemu/qemu_driver.c   |  130 ++---
 src/qemu/qemu_monitor_text.c |   55 ++
 src/qemu/qemu_monitor_text.h |   13 
 3 files changed, 75 insertions(+), 123 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 10fc09a..b447a87 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3093,83 +3093,6 @@ cleanup:
 }
 
 
-static char *qemudEscape(const char *in, int shell)
-{
-int len = 0;
-int i, j;
-char *out;
-
-/* To pass through the QEMU monitor, we need to use escape
-   sequences: \r, \n, \, \\
-
-   To pass through both QEMU + the shell, we need to escape
-   the single character ' as the five characters '\\''
-*/
-
-for (i = 0; in[i] != '\0'; i++) {
-switch(in[i]) {
-case '\r':
-case '\n':
-case '':
-case '\\':
-len += 2;
-break;
-case '\'':
-if (shell)
-len += 5;
-else
-len += 1;
-break;
-default:
-len += 1;
-break;
-}
-}
-
-if (VIR_ALLOC_N(out, len + 1)  0)
-return NULL;
-
-for (i = j = 0; in[i] != '\0'; i++) {
-switch(in[i]) {
-case '\r':
-out[j++] = '\\';
-out[j++] = 'r';
-break;
-case '\n':
-out[j++] = '\\';
-out[j++] = 'n';
-break;
-case '':
-case '\\':
-out[j++] = '\\';
-out[j++] = in[i];
-break;
-case '\'':
-if (shell) {
-out[j++] = '\'';
-out[j++] = '\\';
-out[j++] = '\\';
-out[j++] = '\'';
-out[j++] = '\'';
-} else {
-out[j++] = in[i];
-}
-break;
-default:
-out[j++] = in[i];
-break;
-}
-}
-out[j] = '\0';
-
-return out;
-}
-
-static char *qemudEscapeMonitorArg(const char *in)
-{
-return qemudEscape(in, 0);
-}
-
 #define QEMUD_SAVE_MAGIC LibvirtQemudSave
 #define QEMUD_SAVE_VERSION 2
 
@@ -4626,12 +4549,8 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr 
conn,
   virDomainObjPtr vm,
   virDomainDeviceDefPtr dev)
 {
-int ret, i;
-char *cmd, *reply;
-char *safe_path;
+int i;
 const char* type = virDomainDiskBusTypeToString(dev-data.disk-bus);
-int tryOldSyntax = 0;
-unsigned domain, bus, slot;
 
 for (i = 0 ; i  vm-def-ndisks ; i++) {
 if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
@@ -4646,48 +4565,13 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr 
conn,
 return -1;
 }
 
-try_command:
-safe_path = qemudEscapeMonitorArg(dev-data.disk-src);
-if (!safe_path) {
-virReportOOMError(conn);
-return -1;
-}
-
-ret = virAsprintf(cmd, pci_add %s storage file=%s,if=%s,
-  (tryOldSyntax ? 0: pci_addr=auto), safe_path, type);
-VIR_FREE(safe_path);
-if (ret == -1) {
-virReportOOMError(conn);
-return ret;
-}
-
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(cannot attach %s disk), type);
-VIR_FREE(cmd);
+if (qemuMonitorAddPCIDisk(vm,
+  dev-data.disk-src,
+  type,
+  dev-data.disk-pci_addr.domain,
+  dev-data.disk-pci_addr.bus,
+  dev-data.disk-pci_addr.slot)  0)
 return -1;
-}
-
-VIR_FREE(cmd);
-
-if (qemudParsePciAddReply(vm, reply, domain, bus, slot)  0) {
-if (!tryOldSyntax  strstr(reply, invalid char in expression)) {
-VIR_FREE(reply);
-tryOldSyntax = 1;
-goto try_command;
-}
-
-qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  _(adding %s disk failed: %s), type, reply);
-VIR_FREE(reply);
-return -1;
-}
-
-VIR_FREE(reply);
-
-dev-data.disk-pci_addr.domain = domain;
-dev-data.disk-pci_addr.bus= bus;
-dev-data.disk-pci_addr.slot   = slot;
 
 virDomainDiskInsertPreAlloced(vm-def, dev-data.disk);
 
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 290dcce..765a482 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1437,6 +1437,61 @@ cleanup:
 }
 
 
+int qemuMonitorAddPCIDisk(const virDomainObjPtr vm,
+

[libvirt] [PATCH 18/27] Add API for issugin 'pci_add host' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  API qemuMonitorAddPCIHostDevice()
* src/qemu/qemu_driver.c: Switch to using qemuMonitorAddPCIHostDevice()
  for PCI host device hotplug
---
 src/qemu/qemu_driver.c   |   46 +++-
 src/qemu/qemu_monitor_text.c |  121 ++
 src/qemu/qemu_monitor_text.h |   11 
 3 files changed, 140 insertions(+), 38 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f33c24e..e9e7543 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4903,8 +4903,6 @@ static int qemudDomainAttachHostPciDevice(virConnectPtr 
conn,
   virDomainDeviceDefPtr dev)
 {
 virDomainHostdevDefPtr hostdev = dev-data.hostdev;
-char *cmd, *reply;
-unsigned domain, bus, slot;
 pciDevice *pci;
 
 if (VIR_REALLOC_N(vm-def-hostdevs, vm-def-nhostdevs+1)  0) {
@@ -4931,51 +4929,23 @@ static int qemudDomainAttachHostPciDevice(virConnectPtr 
conn,
 return -1;
 }
 
-cmd = reply = NULL;
-
-if (virAsprintf(cmd, pci_add pci_addr=auto host host=%.2x:%.2x.%.1x,
-hostdev-source.subsys.u.pci.bus,
-hostdev-source.subsys.u.pci.slot,
-hostdev-source.subsys.u.pci.function)  0) {
-virReportOOMError(conn);
-goto error;
-}
-
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(cannot attach host pci device));
+if (qemuMonitorAddPCIHostDevice(vm,
+hostdev-source.subsys.u.pci.domain,
+hostdev-source.subsys.u.pci.bus,
+hostdev-source.subsys.u.pci.slot,
+hostdev-source.subsys.u.pci.function,
+
hostdev-source.subsys.u.pci.guest_addr.domain,
+
hostdev-source.subsys.u.pci.guest_addr.bus,
+
hostdev-source.subsys.u.pci.guest_addr.slot)  0)
 goto error;
-}
-
-if (strstr(reply, invalid type: host)) {
-qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, %s,
- _(PCI device assignment is not supported by this 
version of qemu));
-goto error;
-}
-
-if (qemudParsePciAddReply(vm, reply, domain, bus, slot)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(parsing pci_add reply failed: %s), reply);
-goto error;
-}
-
-hostdev-source.subsys.u.pci.guest_addr.domain = domain;
-hostdev-source.subsys.u.pci.guest_addr.bus= bus;
-hostdev-source.subsys.u.pci.guest_addr.slot   = slot;
 
 vm-def-hostdevs[vm-def-nhostdevs++] = hostdev;
 
-VIR_FREE(reply);
-VIR_FREE(cmd);
-
 return 0;
 
 error:
 pciDeviceListDel(conn, driver-activePciHostdevs, pci);
 
-VIR_FREE(reply);
-VIR_FREE(cmd);
-
 return -1;
 }
 
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 0e0334c..ca84fc6 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1315,3 +1315,124 @@ int qemuMonitorAddUSBDeviceMatch(const virDomainObjPtr 
vm,
 VIR_FREE(addr);
 return ret;
 }
+
+
+static int
+qemuMonitorParsePciAddReply(virDomainObjPtr vm,
+const char *reply,
+unsigned *domain,
+unsigned *bus,
+unsigned *slot)
+{
+char *s, *e;
+
+DEBUG(%s: pci_add reply: %s, vm-def-name, reply);
+
+/* If the command succeeds qemu prints:
+ * OK bus 0, slot XXX...
+ * or
+ * OK domain 0, bus 0, slot XXX
+ */
+if (!(s = strstr(reply, OK )))
+return -1;
+
+s += 3;
+
+if (STRPREFIX(s, domain )) {
+s += strlen(domain );
+
+if (virStrToLong_ui(s, e, 10, domain) == -1) {
+VIR_WARN(_(Unable to parse domain number '%s'\n), s);
+return -1;
+}
+
+if (!STRPREFIX(e, , )) {
+VIR_WARN(_(Expected ', ' parsing pci_add reply '%s'\n), s);
+return -1;
+}
+s = e + 2;
+}
+
+if (!STRPREFIX(s, bus )) {
+VIR_WARN(_(Expected 'bus ' parsing pci_add reply '%s'\n), s);
+return -1;
+}
+s += strlen(bus );
+
+if (virStrToLong_ui(s, e, 10, bus) == -1) {
+VIR_WARN(_(Unable to parse bus number '%s'\n), s);
+return -1;
+}
+
+if (!STRPREFIX(e, , )) {
+VIR_WARN(_(Expected ', ' parsing pci_add reply '%s'\n), s);
+return -1;
+}
+s = e + 2;
+
+if (!STRPREFIX(s, slot )) {
+VIR_WARN(_(Expected 'slot ' parsing pci_add reply '%s'\n), s);
+return -1;
+}
+s += strlen(slot );
+
+if (virStrToLong_ui(s, e, 10, slot) == -1) {
+

[libvirt] [PATCH 27/27] Fix crash in device hotplug cleanup code

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_driver.c: Fix crash in scenario where XML
  parsing of hotplugged device failed  thus 'dev' is NULL
---
 src/qemu/qemu_driver.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index da72913..7dc9353 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4880,7 +4880,7 @@ cleanup:
 if (cgroup)
 virCgroupFree(cgroup);
 
-if (ret  0) {
+if (ret  0  dev != NULL) {
 if (qemuDomainSetDeviceOwnership(dom-conn, driver, dev, 1)  0)
 VIR_WARN0(Fail to restore disk device ownership);
 virDomainDeviceDefFree(dev);
-- 
1.6.2.5

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


[libvirt] [PATCH 03/27] Add API for 'change vnc password' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add a
  new qemuMonitorSetVNCPassword() API
* src/qemu/qemu_driver.c: Refactor qemudInitPasswords to
  call qemuMonitorSetVNCPassword()
---
 src/qemu/qemu_driver.c   |   24 
 src/qemu/qemu_monitor_text.c |   15 +++
 src/qemu/qemu_monitor_text.h |3 +++
 3 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 30d1468..e0b7c84 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1275,29 +1275,21 @@ qemudInitCpus(virConnectPtr conn,
 
 
 static int
-qemudInitPasswords(virConnectPtr conn,
-   struct qemud_driver *driver,
+qemudInitPasswords(struct qemud_driver *driver,
virDomainObjPtr vm) {
-char *info = NULL;
+int ret = 0;
 
 if ((vm-def-ngraphics == 1) 
 vm-def-graphics[0]-type == VIR_DOMAIN_GRAPHICS_TYPE_VNC 
 (vm-def-graphics[0]-data.vnc.passwd || driver-vncPassword)) {
 
-if (qemudMonitorCommandExtra(vm, change vnc password,
- vm-def-graphics[0]-data.vnc.passwd ?
- vm-def-graphics[0]-data.vnc.passwd :
- driver-vncPassword,
- QEMU_PASSWD_PROMPT,
- -1, info)  0) {
-qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- %s, _(setting VNC password failed));
-return -1;
-}
-VIR_FREE(info);
+ret = qemuMonitorSetVNCPassword(vm,
+vm-def-graphics[0]-data.vnc.passwd ?
+vm-def-graphics[0]-data.vnc.passwd :
+driver-vncPassword);
 }
 
-return 0;
+return ret;
 }
 
 
@@ -2144,7 +2136,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
 if ((qemudWaitForMonitor(conn, driver, vm, pos)  0) ||
 (qemuDetectVcpuPIDs(conn, vm)  0) ||
 (qemudInitCpus(conn, vm, migrateFrom)  0) ||
-(qemudInitPasswords(conn, driver, vm)  0) ||
+(qemudInitPasswords(driver, vm)  0) ||
 (qemudDomainSetMemoryBalloon(conn, vm, vm-def-memory)  0) ||
 (virDomainSaveStatus(conn, driver-stateDir, vm)  0)) {
 qemudShutdownVMDaemon(conn, driver, vm);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index d93e475..ba28f02 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -520,3 +520,18 @@ error:
 }
 
 
+int qemuMonitorSetVNCPassword(const virDomainObjPtr vm,
+  const char *password)
+{
+char *info = NULL;
+if (qemudMonitorCommandExtra(vm, change vnc password,
+ password,
+ QEMU_PASSWD_PROMPT,
+ -1, info)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ %s, _(setting VNC password failed));
+return -1;
+}
+VIR_FREE(info);
+return 0;
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 973c3b6..fd0fa61 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -71,4 +71,7 @@ int qemudMonitorSendCont(virConnectPtr conn,
 int qemuMonitorGetCPUInfo(const virDomainObjPtr vm,
   int **pids);
 
+int qemuMonitorSetVNCPassword(const virDomainObjPtr vm,
+  const char *password);
+
 #endif /* QEMU_MONITOR_TEXT_H */
-- 
1.6.2.5

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


[libvirt] [PATCH 16/27] Add API for using 'usb_add' for disk devices

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorAddUSBDisk() API
* src/qemu/qemu_driver.c: Switch USB disk hotplug to the new
  src/qemu/qemu_driver.c API.
---
 src/qemu/qemu_driver.c   |   41 ++-
 src/qemu/qemu_monitor_text.c |   43 ++
 src/qemu/qemu_monitor_text.h |4 +++
 3 files changed, 54 insertions(+), 34 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index da08af9..635fb84 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4698,59 +4698,32 @@ static int 
qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
  virDomainObjPtr vm,
  virDomainDeviceDefPtr dev)
 {
-int ret, i;
-char *safe_path;
-char *cmd, *reply;
+int i;
 
 for (i = 0 ; i  vm-def-ndisks ; i++) {
 if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_(target %s already exists), dev-data.disk-dst);
 return -1;
 }
 }
 
-if (VIR_REALLOC_N(vm-def-disks, vm-def-ndisks+1)  0) {
-virReportOOMError(conn);
-return -1;
-}
-
-safe_path = qemudEscapeMonitorArg(dev-data.disk-src);
-if (!safe_path) {
-virReportOOMError(conn);
+if (!dev-data.disk-src) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ %s, _(disk source path is missing));
 return -1;
 }
 
-ret = virAsprintf(cmd, usb_add disk:%s, safe_path);
-VIR_FREE(safe_path);
-if (ret == -1) {
+if (VIR_REALLOC_N(vm-def-disks, vm-def-ndisks+1)  0) {
 virReportOOMError(conn);
-return ret;
-}
-
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(cannot attach usb disk));
-VIR_FREE(cmd);
 return -1;
 }
 
-DEBUG (%s: attach_usb reply: %s,vm-def-name,  reply);
-/* If the command failed qemu prints:
- * Could not add ... */
-if (strstr(reply, Could not add )) {
-qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  %s,
-  _(adding usb disk failed));
-VIR_FREE(reply);
-VIR_FREE(cmd);
+if (qemuMonitorAddUSBDisk(vm, dev-data.disk-src)  0)
 return -1;
-}
 
 virDomainDiskInsertPreAlloced(vm-def, dev-data.disk);
 
-VIR_FREE(reply);
-VIR_FREE(cmd);
 return 0;
 }
 
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index c154019..fd50cf2 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1199,3 +1199,46 @@ cleanup:
 VIR_FREE(dest);
 return ret;
 }
+
+
+int qemuMonitorAddUSBDisk(const virDomainObjPtr vm,
+  const char *path)
+{
+char *cmd = NULL;
+char *safepath;
+int ret = -1;
+char *info = NULL;
+
+safepath = qemudEscapeMonitorArg(path);
+if (!safepath) {
+virReportOOMError(NULL);
+return -1;
+}
+
+if (virAsprintf(cmd, usb_add disk:%s, safepath)  0) {
+virReportOOMError(NULL);
+goto cleanup;
+}
+
+if (qemudMonitorCommand(vm, cmd, info)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ %s, _(cannot run monitor command to add usb 
disk));
+goto cleanup;
+}
+
+DEBUG (%s: usb_add reply: %s, vm-def-name, info);
+/* If the command failed qemu prints:
+ * Could not add ... */
+if (strstr(info, Could not add )) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _(unable to add USB disk %s: %s), path, info);
+goto cleanup;
+}
+
+ret = 0;
+
+cleanup:
+VIR_FREE(cmd);
+VIR_FREE(safepath);
+return ret;
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index ffed049..138e7a0 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -136,4 +136,8 @@ int qemuMonitorMigrateToCommand(const virDomainObjPtr vm,
 const char * const *argv,
 const char *target);
 
+
+int qemuMonitorAddUSBDisk(const virDomainObjPtr vm,
+  const char *path);
+
 #endif /* QEMU_MONITOR_TEXT_H */
-- 
1.6.2.5

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


[libvirt] [PATCH 00/27] Refactor QEMU monitor command handling

2009-09-24 Thread Daniel P. Berrange
In the QEMU driver source code the methods which talk to the QEMU
monitor currently all just call qemudMonitorCommand() directly
with the raw command string, and then parse the raw reply.

In the not too distant future QEMU is introducing a new machine
parsable monitor syntax. With the current way the code is structured
supporting this new mode will be seriously unpleasant.

This large series of patches, moves all the monitor command 
formatting and parsing code out into a separate source file
src/qemu/qemu_monitor_text.c.  There is one API in that file
for each logical monitor command we wish to issue, accepting
(mostly) strongly typed arguments. The exception is the NIC
hotplug method which still takes the raw NIC string for now.

The main qemu_driver.c file now directly calls the appropriate
monitor command APIs, making logic there much cleaner.

When we add support for the new QEMU monitor syntax we'll gain
another file src/qemu/qemu_monitor_json.c  which implements all
the same APIs as src/qemu/qemu_monitor_text.c, but using the
new JSON syntax instead of raw text strings

This patch series is soo large, because I did it in many
small steps, one command at a time.

It is also now much easier to debug the monitor by just setting
the env variables

LIBVIRT_LOG_OUTPUTS=1:stderr LIBVIRT_LOG_FILTERS=1:qemu_monitor

And you'll get the command  reply of each monitor interaction
printed

I've tested basic handling of every new method with the exception
of the migration ones, since I don't have a convenient target host
when on my laptop.

Overall we get a small increase in code size, but huge increase
in readability !

 Makefile.am  |1 
 libvirt_private.syms |1 
 qemu/qemu_conf.c |   20 
 qemu/qemu_conf.h |2 
 qemu/qemu_driver.c   | 1669 +---
 qemu/qemu_monitor_text.c | 1777 +++
 qemu/qemu_monitor_text.h |  173 
 7 files changed, 2171 insertions(+), 1472 deletions(-)


Daniel

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


[libvirt] [PATCH 11/27] Add API for issuing 'info blockstats' command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add a new
  qemuMonitorGetBlockStatsInfo() command
* src/qemu/qemu_driver.c: Remove directly use of blockstats in
  favour of calling qemuMonitorGetBlockStatsInfo()
---
 src/qemu/qemu_driver.c   |   95 +++--
 src/qemu/qemu_monitor_text.c |  105 ++
 src/qemu/qemu_monitor_text.h |8 +++
 3 files changed, 121 insertions(+), 87 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9c09024..f95c473 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5958,10 +5958,7 @@ qemudDomainBlockStats (virDomainPtr dom,
struct _virDomainBlockStats *stats)
 {
 struct qemud_driver *driver = dom-conn-privateData;
-char *dummy, *info = NULL;
-const char *p, *eol;
 const char *qemu_dev_name = NULL;
-size_t len;
 int i, ret = -1;
 virDomainObjPtr vm;
 virDomainDiskDefPtr disk = NULL;
@@ -5998,95 +5995,19 @@ qemudDomainBlockStats (virDomainPtr dom,
 qemu_dev_name = qemudDiskDeviceName(dom-conn, disk);
 if (!qemu_dev_name)
 goto cleanup;
-len = strlen (qemu_dev_name);
 
-if (qemudMonitorCommand (vm, info blockstats, info)  0) {
-qemudReportError (dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  %s, _('info blockstats' command failed));
-goto cleanup;
-}
-DEBUG (%s: info blockstats reply: %s, vm-def-name, info);
-
-/* If the command isn't supported then qemu prints the supported
- * info commands, so the output starts info .  Since this is
- * unlikely to be the name of a block device, we can use this
- * to detect if qemu supports the command.
- */
-if (strstr(info, \ninfo )) {
-qemudReportError (dom-conn, dom, NULL, VIR_ERR_NO_SUPPORT,
-  %s,
-  _('info blockstats' not supported by this qemu));
+if (qemuMonitorGetBlockStatsInfo(vm, qemu_dev_name,
+ stats-rd_req,
+ stats-rd_bytes,
+ stats-wr_req,
+ stats-wr_bytes,
+ stats-errs)  0)
 goto cleanup;
-}
-
-stats-rd_req = -1;
-stats-rd_bytes = -1;
-stats-wr_req = -1;
-stats-wr_bytes = -1;
-stats-errs = -1;
-
-/* The output format for both qemu  KVM is:
- *   blockdevice: rd_bytes=% wr_bytes=% rd_operations=% wr_operations=%
- *   (repeated for each block device)
- * where '%' is a 64 bit number.
- */
-p = info;
-
-while (*p) {
-if (STREQLEN (p, qemu_dev_name, len)
- p[len] == ':'  p[len+1] == ' ') {
-
-eol = strchr (p, '\n');
-if (!eol)
-eol = p + strlen (p);
-
-p += len+2; /* Skip to first label. */
-
-while (*p) {
-if (STRPREFIX (p, rd_bytes=)) {
-p += 9;
-if (virStrToLong_ll (p, dummy, 10, stats-rd_bytes) == 
-1)
-DEBUG (%s: error reading rd_bytes: %s,
-   vm-def-name, p);
-} else if (STRPREFIX (p, wr_bytes=)) {
-p += 9;
-if (virStrToLong_ll (p, dummy, 10, stats-wr_bytes) == 
-1)
-DEBUG (%s: error reading wr_bytes: %s,
-   vm-def-name, p);
-} else if (STRPREFIX (p, rd_operations=)) {
-p += 14;
-if (virStrToLong_ll (p, dummy, 10, stats-rd_req) == -1)
-DEBUG (%s: error reading rd_req: %s,
-   vm-def-name, p);
-} else if (STRPREFIX (p, wr_operations=)) {
-p += 14;
-if (virStrToLong_ll (p, dummy, 10, stats-wr_req) == -1)
-DEBUG (%s: error reading wr_req: %s,
-   vm-def-name, p);
-} else
-DEBUG (%s: unknown block stat near %s, vm-def-name, p);
-
-/* Skip to next label. */
-p = strchr (p, ' ');
-if (!p || p = eol) break;
-p++;
-}
-ret = 0;
-goto cleanup;
-}
 
-/* Skip to next line. */
-p = strchr (p, '\n');
-if (!p) break;
-p++;
-}
+ret = 0;
 
-/* If we reach here then the device was not found. */
-qemudReportError (dom-conn, dom, NULL, VIR_ERR_INVALID_ARG,
-  _(device not found: %s (%s)), path, qemu_dev_name);
- cleanup:
+cleanup:
 VIR_FREE(qemu_dev_name);
-VIR_FREE(info);
 if (vm)
 virDomainObjUnlock(vm);
 return ret;
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index a5f43c5..f35b1ef 100644
--- 

[libvirt] [PATCH 02/27] Add API for 'info cpus' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.h, src/qemu/qemu_monitor.c: Add a new
  qemuMonitorGetCPUInfo() command
* src/qemu/qemu_driver.c: Refactor qemudDetectVcpuPIDs to
  use qemuMonitorGetCPUInfo()
---
 src/qemu/qemu_driver.c   |  114 ++
 src/qemu/qemu_monitor_text.c |   85 +++
 src/qemu/qemu_monitor_text.h |4 +-
 3 files changed, 115 insertions(+), 88 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9f17aae..30d1468 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -110,8 +110,8 @@ static int qemudDomainGetMaxVcpus(virDomainPtr dom);
 static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
virDomainObjPtr vm,
unsigned long newmem);
-static int qemudDetectVcpuPIDs(virConnectPtr conn,
-   virDomainObjPtr vm);
+static int qemuDetectVcpuPIDs(virConnectPtr conn,
+  virDomainObjPtr vm);
 
 static int qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
virDomainDefPtr def);
@@ -1186,100 +1186,40 @@ qemudWaitForMonitor(virConnectPtr conn,
 }
 
 static int
-qemudDetectVcpuPIDs(virConnectPtr conn,
-virDomainObjPtr vm) {
-char *qemucpus = NULL;
-char *line;
-int lastVcpu = -1;
-
-/* Only KVM has seperate threads for CPUs,
-   others just use main QEMU process for CPU */
-if (vm-def-virtType != VIR_DOMAIN_VIRT_KVM)
-vm-nvcpupids = 1;
-else
-vm-nvcpupids = vm-def-vcpus;
-
-if (VIR_ALLOC_N(vm-vcpupids, vm-nvcpupids)  0) {
-virReportOOMError(conn);
-return -1;
-}
+qemuDetectVcpuPIDs(virConnectPtr conn,
+   virDomainObjPtr vm) {
+pid_t *cpupids = NULL;
+int ncpupids;
 
 if (vm-def-virtType != VIR_DOMAIN_VIRT_KVM) {
+vm-nvcpupids = 1;
+if (VIR_ALLOC_N(vm-vcpupids, vm-nvcpupids)  0) {
+virReportOOMError(conn);
+return -1;
+}
 vm-vcpupids[0] = vm-pid;
 return 0;
 }
 
-if (qemudMonitorCommand(vm, info cpus, qemucpus)  0) {
-qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- %s, _(cannot run monitor command to fetch CPU 
thread info));
-VIR_FREE(vm-vcpupids);
-vm-nvcpupids = 0;
-return -1;
-}
-
-/*
- * This is the gross format we're about to parse :-{
- *
- * (qemu) info cpus
- * * CPU #0: pc=0x000f0c4a thread_id=30019
- *   CPU #1: pc=0xfff0 thread_id=30020
- *   CPU #2: pc=0xfff0 thread_id=30021
- *
- */
-line = qemucpus;
-do {
-char *offset = strchr(line, '#');
-char *end = NULL;
-int vcpu = 0, tid = 0;
-
-/* See if we're all done */
-if (offset == NULL)
-break;
+/* What follows is now all KVM specific */
 
-/* Extract VCPU number */
-if (virStrToLong_i(offset + 1, end, 10, vcpu)  0)
-goto error;
-if (end == NULL || *end != ':')
-goto error;
-
-/* Extract host Thread ID */
-if ((offset = strstr(line, thread_id=)) == NULL)
-goto error;
-if (virStrToLong_i(offset + strlen(thread_id=), end, 10, tid)  0)
-goto error;
-if (end == NULL || !c_isspace(*end))
-goto error;
-
-/* Validate the VCPU is in expected range  order */
-if (vcpu  vm-nvcpupids ||
-vcpu != (lastVcpu + 1))
-goto error;
-
-lastVcpu = vcpu;
-vm-vcpupids[vcpu] = tid;
-
-/* Skip to next data line */
-line = strchr(offset, '\r');
-if (line == NULL)
-line = strchr(offset, '\n');
-} while (line != NULL);
-
-/* Validate we got data for all VCPUs we expected */
-if (lastVcpu != (vm-def-vcpus - 1))
-goto error;
+if ((ncpupids = qemuMonitorGetCPUInfo(vm, cpupids))  0)
+return -1;
 
-VIR_FREE(qemucpus);
-return 0;
+/* Treat failure to get VCPU-PID mapping as non-fatal */
+if (ncpupids == 0)
+return 0;
 
-error:
-VIR_FREE(vm-vcpupids);
-vm-nvcpupids = 0;
-VIR_FREE(qemucpus);
+if (ncpupids != vm-def-vcpus) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _(got wrong number of vCPU pids from QEMU monitor. 
got %d, wanted %d),
+ ncpupids, (int)vm-def-vcpus);
+VIR_FREE(cpupids);
+return -1;
+}
 
-/* Explicitly return success, not error. Older KVM does
-   not have vCPU - Thread mapping info and we don't
-   want to break its use. This merely disables ability
-   to pin vCPUS with libvirt */
+vm-nvcpupids = ncpupids;
+vm-vcpupids = cpupids;
 return 0;
 }
 
@@ -2202,7 +2142,7 @@ static int 

[libvirt] [PATCH 12/27] Add API for issuing the 'migrate_set_speed' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_driver.c: Use new qemuMonitorSetMigrationSpeed()
  API during migration
* src/qemu/qemu_monitor.h, src/qemu/qemu_monitor.c: Add new
  qemuMonitorSetMigrationSpeed() API
---
 src/qemu/qemu_driver.c   |   11 +++
 src/qemu/qemu_monitor_text.c |   28 
 src/qemu/qemu_monitor_text.h |3 +++
 3 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f95c473..ccc13c4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6530,14 +6530,9 @@ qemudDomainMigratePerform (virDomainPtr dom,
 event = NULL;
 }
 
-if (resource  0) {
-/* Issue migrate_set_speed command.  Don't worry if it fails. */
-snprintf (cmd, sizeof cmd, migrate_set_speed %lum, resource);
-qemudMonitorCommand (vm, cmd, info);
-
-DEBUG (%s: migrate_set_speed reply: %s, vm-def-name, info);
-VIR_FREE (info);
-}
+if (resource  0 
+qemuMonitorSetMigrationSpeed(vm, resource)  0)
+goto cleanup;
 
 /* Issue the migrate command. */
 safe_uri = qemudEscapeMonitorArg (uri);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index f35b1ef..d9227a2 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -969,3 +969,31 @@ int qemuMonitorSavePhysicalMemory(const virDomainObjPtr vm,
 {
 return qemuMonitorSaveMemory(vm, pmemsave, offset, length, path);
 }
+
+
+int qemuMonitorSetMigrationSpeed(const virDomainObjPtr vm,
+ unsigned long bandwidth)
+{
+char *cmd = NULL;
+char *info = NULL;
+int ret = -1;
+
+if (virAsprintf(cmd, migrate_set_speed %lum, bandwidth)  0) {
+virReportOOMError(NULL);
+goto cleanup;
+}
+
+if (qemudMonitorCommand (vm, cmd, info)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ %s, _(could restrict migration speed));
+goto cleanup;
+}
+
+DEBUG (%s: migrate_set_speed reply: %s, vm-def-name, info);
+ret = 0;
+
+cleanup:
+VIR_FREE (info);
+VIR_FREE(cmd);
+return ret;
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index a047eba..0591f3c 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -109,4 +109,7 @@ int qemuMonitorSavePhysicalMemory(const virDomainObjPtr vm,
   size_t length,
   const char *path);
 
+int qemuMonitorSetMigrationSpeed(const virDomainObjPtr vm,
+ unsigned long bandwidth);
+
 #endif /* QEMU_MONITOR_TEXT_H */
-- 
1.6.2.5

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


[libvirt] [PATCH 14/27] Add API for issuing a 'migrate' monitor command for TCP

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new API
  qemuMonitorMigrateToHost() for doing TCP migration
* src/qemu/qemu_driver.c: Convert to use qemuMonitorMigrateToHost().
  Also handle proper URIs (tcp:// as well as tcp:)
---
 src/qemu/qemu_driver.c   |   40 -
 src/qemu/qemu_monitor_text.c |   56 ++
 src/qemu/qemu_monitor_text.h |4 +++
 3 files changed, 77 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a6300c9..f234639 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6494,12 +6494,10 @@ qemudDomainMigratePerform (virDomainPtr dom,
 struct qemud_driver *driver = dom-conn-privateData;
 virDomainObjPtr vm;
 virDomainEventPtr event = NULL;
-char *safe_uri;
-char cmd[HOST_NAME_MAX+50];
-char *info = NULL;
 int ret = -1;
 int paused = 0;
 int status;
+xmlURIPtr uribits = NULL;
 unsigned long long transferred, remaining, total;
 
 qemuDriverLock(driver);
@@ -6537,34 +6535,29 @@ qemudDomainMigratePerform (virDomainPtr dom,
 goto cleanup;
 
 /* Issue the migrate command. */
-safe_uri = qemudEscapeMonitorArg (uri);
-if (!safe_uri) {
-virReportOOMError (dom-conn);
-goto cleanup;
+if (STRPREFIX(uri, tcp:)  !STRPREFIX(uri, tcp://)) {
+char *tmpuri;
+if (virAsprintf(tmpuri, tcp://%s, uri + strlen(tcp:))  0) {
+virReportOOMError(dom-conn);
+goto cleanup;
+}
+uribits = xmlParseURI(tmpuri);
+VIR_FREE(tmpuri);
+} else {
+uribits = xmlParseURI(uri);
 }
-snprintf (cmd, sizeof cmd, migrate \%s\, safe_uri);
-VIR_FREE (safe_uri);
-
-if (qemudMonitorCommand (vm, cmd, info)  0) {
-qemudReportError (dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  %s, _(migrate operation failed));
+if (!uribits) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _(cannot parse URI %s), uri);
 goto cleanup;
 }
 
-DEBUG (%s: migrate reply: %s, vm-def-name, info);
-
-/* Now check for fail in the output string */
-if (strstr(info, fail) != NULL) {
-qemudReportError (dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  _(migrate failed: %s), info);
+if (qemuMonitorMigrateToHost(vm, uribits-server, uribits-port)  0)
 goto cleanup;
-}
 
 /* it is also possible that the migrate didn't fail initially, but
  * rather failed later on.  Check the output of info migrate
  */
-VIR_FREE(info);
-
 if (qemuMonitorGetMigrationStatus(vm, status,
   transferred,
   remaining,
@@ -6608,7 +6601,8 @@ cleanup:
  VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
 }
 
-VIR_FREE(info);
+if (uribits)
+xmlFreeURI(uribits);
 if (vm)
 virDomainObjUnlock(vm);
 if (event)
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 0b746b9..4f8d72e 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1088,3 +1088,59 @@ cleanup:
 VIR_FREE(reply);
 return ret;
 }
+
+
+static int qemuMonitorMigrate(const virDomainObjPtr vm,
+  const char *dest)
+{
+char *cmd = NULL;
+char *info = NULL;
+int ret = -1;
+
+if (virAsprintf(cmd, migrate %s, cmd)  0) {
+virReportOOMError(NULL);
+return -1;
+}
+
+if (qemudMonitorCommand(vm, cmd, info)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _(unable to start migration to %s), dest);
+goto cleanup;
+}
+
+DEBUG (%s: migrate reply: %s, vm-def-name, info);
+
+/* Now check for fail in the output string */
+if (strstr(info, fail) != NULL) {
+qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+  _(migration to '%s' failed: %s), dest, info);
+goto cleanup;
+}
+
+
+ret = 0;
+
+cleanup:
+VIR_FREE(info);
+VIR_FREE(cmd);
+return ret;
+}
+
+int qemuMonitorMigrateToHost(const virDomainObjPtr vm,
+ const char *hostname,
+ int port)
+{
+char *uri;
+int ret;
+
+if (virAsprintf(uri, tcp:%s:%d, hostname, port)  0) {
+virReportOOMError(NULL);
+return -1;
+}
+
+ret = qemuMonitorMigrate(vm, uri);
+
+VIR_FREE(uri);
+
+return ret;
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index c972672..0d34b6b 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -128,4 +128,8 @@ int qemuMonitorGetMigrationStatus(const virDomainObjPtr vm,
   unsigned long long *remaining,
  

[libvirt] [PATCH 26/27] Standardize debugging messages in QEMU monitor code

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor_text.c: Always print command and reply
  in qemuMonitorCommandWithHandler. Print all args in each monitor
  command API  remove redundant relpy printing
---
 src/qemu/qemu_monitor_text.c |   82 ++---
 1 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 2c41288..abb2c0a 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -242,7 +242,7 @@ qemuMonitorCommandWithHandler(const virDomainObjPtr vm,
 
 qemuMonitorDiscardPendingData(vm);
 
-VIR_DEBUG(Send '%s', cmd);
+VIR_DEBUG(cmd='%s' extraPrompt='%s', cmd, NULLSTR(extraPrompt));
 if (qemuMonitorSend(vm, cmd, scm_fd)  0)
 return -1;
 
@@ -282,6 +282,7 @@ qemuMonitorCommandWithHandler(const virDomainObjPtr vm,
 (foundPrompt = strstr(buf, extraPrompt)) != NULL) {
 char *promptEnd;
 
+DEBUG(prompt='%s' handler=%p, extraPrompt, extraHandler);
 if (extraHandler(vm, buf, foundPrompt, handlerData)  0)
 return -1;
 /* Discard output so far, necessary to detect whether
@@ -320,6 +321,7 @@ qemuMonitorCommandWithHandler(const virDomainObjPtr vm,
 }
 }
 *reply = buf;
+DEBUG(reply='%s', buf);
 return 0;
 
  error:
@@ -521,11 +523,13 @@ qemuMonitorStartCPUs(virConnectPtr conn,
  const virDomainObjPtr vm) {
 char *reply;
 
+DEBUG(vm=%p, pid=%d, id=%d, name=%s, vm, vm-pid, vm-def-id, 
vm-def-name);
+
 if (qemuMonitorCommandWithHandler(vm, cont, ) is encrypted.,
   qemuMonitorSendVolumePassphrase, conn,
   -1, reply)  0)
 return -1;
-qemudDebug (%s: cont reply: %s, vm-def-name, info);
+
 VIR_FREE(reply);
 return 0;
 }
@@ -535,6 +539,8 @@ int
 qemuMonitorStopCPUs(const virDomainObjPtr vm) {
 char *info;
 
+DEBUG(vm=%p, pid=%d, id=%d, name=%s, vm, vm-pid, vm-def-id, 
vm-def-name);
+
 if (qemuMonitorCommand(vm, stop, info)  0) {
 qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
  %s, _(cannot stop CPU execution));
@@ -548,6 +554,8 @@ qemuMonitorStopCPUs(const virDomainObjPtr vm) {
 int qemuMonitorSystemPowerdown(const virDomainObjPtr vm) {
 char *info;
 
+DEBUG(vm=%p, pid=%d, id=%d, name=%s, vm, vm-pid, vm-def-id, 
vm-def-name);
+
 if (qemuMonitorCommand(vm, system_powerdown, info)  0) {
 qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
  %s, _(system shutdown operation failed));
@@ -567,6 +575,8 @@ int qemuMonitorGetCPUInfo(const virDomainObjPtr vm,
 pid_t *cpupids = NULL;
 size_t ncpupids = 0;
 
+DEBUG(vm=%p, pid=%d, id=%d, name=%s, vm, vm-pid, vm-def-id, 
vm-def-name);
+
 if (qemuMonitorCommand(vm, info cpus, qemucpus)  0) {
 qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
  %s, _(cannot run monitor command to fetch CPU 
thread info));
@@ -614,6 +624,7 @@ int qemuMonitorGetCPUInfo(const virDomainObjPtr vm,
 if (VIR_REALLOC_N(cpupids, ncpupids+1)  0)
 goto error;
 
+DEBUG(vcpu=%d pid=%d, vcpu, tid);
 cpupids[ncpupids++] = tid;
 lastVcpu = vcpu;
 
@@ -655,13 +666,14 @@ int qemuMonitorGetBalloonInfo(const virDomainObjPtr vm,
 int ret = -1;
 char *offset;
 
+DEBUG(vm=%p, pid=%d, id=%d, name=%s, vm, vm-pid, vm-def-id, 
vm-def-name);
+
 if (qemuMonitorCommand(vm, info balloon, reply)  0) {
 qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
  %s, _(could not query memory balloon allocation));
 return -1;
 }
 
-DEBUG (%s: balloon reply: '%s', vm-def-name, reply);
 if ((offset = strstr(reply, BALLOON_PREFIX)) != NULL) {
 unsigned int memMB;
 char *end;
@@ -700,12 +712,13 @@ int qemuMonitorGetBlockStatsInfo(const virDomainObjPtr vm,
 const char *p, *eol;
 int devnamelen = strlen(devname);
 
+DEBUG(vm=%p, pid=%d, id=%d, name=%s dev=%s, vm, vm-pid, vm-def-id, 
vm-def-name, devname);
+
 if (qemuMonitorCommand (vm, info blockstats, info)  0) {
 qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
   %s, _('info blockstats' command failed));
 goto cleanup;
 }
-DEBUG (%s: info blockstats reply: %s, vm-def-name, info);
 
 /* If the command isn't supported then qemu prints the supported
  * info commands, so the output starts info .  Since this is
@@ -795,6 +808,9 @@ int qemuMonitorSetVNCPassword(const virDomainObjPtr vm,
   const char *password)
 {
 char *info = NULL;
+
+DEBUG(vm=%p, pid=%d, id=%d, name=%s, vm, vm-pid, vm-def-id, 
vm-def-name);
+
 if (qemuMonitorCommandExtra(vm, change vnc password,
 password,
 

[libvirt] [PATCH 04/27] Rename qemudMonitorSendCont to qemuMonitorStartCPUs

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Rename
  Rename qemudMonitorSendCont to qemuMonitorStartCPUs
* src/qemu/qemu_driver.c: Update callers for new name
---
 src/qemu/qemu_driver.c   |   18 +-
 src/qemu/qemu_monitor_text.c |2 +-
 src/qemu/qemu_monitor_text.h |2 +-
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e0b7c84..1717cbd 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1262,7 +1262,7 @@ qemudInitCpus(virConnectPtr conn,
 
 if (migrateFrom == NULL) {
 /* Allow the CPUS to start executing */
-if (qemudMonitorSendCont(conn, vm)  0) {
+if (qemuMonitorStartCPUs(conn, vm)  0) {
 if (virGetLastError() == NULL)
 qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
  %s, _(resume operation failed));
@@ -1275,8 +1275,8 @@ qemudInitCpus(virConnectPtr conn,
 
 
 static int
-qemudInitPasswords(struct qemud_driver *driver,
-   virDomainObjPtr vm) {
+qemuInitPasswords(struct qemud_driver *driver,
+  virDomainObjPtr vm) {
 int ret = 0;
 
 if ((vm-def-ngraphics == 1) 
@@ -2136,7 +2136,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
 if ((qemudWaitForMonitor(conn, driver, vm, pos)  0) ||
 (qemuDetectVcpuPIDs(conn, vm)  0) ||
 (qemudInitCpus(conn, vm, migrateFrom)  0) ||
-(qemudInitPasswords(driver, vm)  0) ||
+(qemuInitPasswords(driver, vm)  0) ||
 (qemudDomainSetMemoryBalloon(conn, vm, vm-def-memory)  0) ||
 (virDomainSaveStatus(conn, driver-stateDir, vm)  0)) {
 qemudShutdownVMDaemon(conn, driver, vm);
@@ -2819,7 +2819,7 @@ static int qemudDomainResume(virDomainPtr dom) {
 goto cleanup;
 }
 if (vm-state == VIR_DOMAIN_PAUSED) {
-if (qemudMonitorSendCont(dom-conn, vm)  0) {
+if (qemuMonitorStartCPUs(dom-conn, vm)  0) {
 if (virGetLastError() == NULL)
 qemudReportError(dom-conn, dom, NULL, 
VIR_ERR_OPERATION_FAILED,
  %s, _(resume operation failed));
@@ -3579,7 +3579,7 @@ cleanup:
will support synchronous operations so we always get here after
the migration is complete.  */
 if (resume  paused) {
-if (qemudMonitorSendCont(dom-conn, vm)  0) {
+if (qemuMonitorStartCPUs(dom-conn, vm)  0) {
 if (virGetLastError() == NULL)
 qemudReportError(dom-conn, dom, NULL, 
VIR_ERR_OPERATION_FAILED,
  %s, _(resuming after dump failed));
@@ -4095,7 +4095,7 @@ static int qemudDomainRestore(virConnectPtr conn,
 
 /* If it was running before, resume it now. */
 if (header.was_running) {
-if (qemudMonitorSendCont(conn, vm)  0) {
+if (qemuMonitorStartCPUs(conn, vm)  0) {
 if (virGetLastError() == NULL)
 qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
  %s, _(failed to resume domain));
@@ -6828,7 +6828,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
 cleanup:
 if (paused) {
 /* we got here through some sort of failure; start the domain again */
-if (qemudMonitorSendCont(dom-conn, vm)  0) {
+if (qemuMonitorStartCPUs(dom-conn, vm)  0) {
 /* Hm, we already know we are in error here.  We don't want to
  * overwrite the previous error, though, so we just throw something
  * to the logs and hope for the best
@@ -6884,7 +6884,7 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
  * = 0.10.6 to work properly.  This isn't strictly necessary on
  * older qemu's, but it also doesn't hurt anything there
  */
-if (qemudMonitorSendCont(dconn, vm)  0) {
+if (qemuMonitorStartCPUs(dconn, vm)  0) {
 if (virGetLastError() == NULL)
 qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
  %s, _(resume operation failed));
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index ba28f02..3c12073 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -424,7 +424,7 @@ qemudMonitorSendVolumePassphrase(const virDomainObjPtr vm,
 }
 
 int
-qemudMonitorSendCont(virConnectPtr conn,
+qemuMonitorStartCPUs(virConnectPtr conn,
  const virDomainObjPtr vm) {
 char *reply;
 
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index fd0fa61..2632ecf 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -65,7 +65,7 @@ int qemudMonitorCommandExtra(const virDomainObjPtr vm,
 
 /* Formal APIs for each required monitor command */
 
-int qemudMonitorSendCont(virConnectPtr conn,
+int qemuMonitorStartCPUs(virConnectPtr conn,
  const virDomainObjPtr vm);
 
 int 

[libvirt] [PATCH 07/27] Add API for running 'info balloon' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Pull old
  qemudDomainGetMemoryBalloon() code into a new method called
  qemuMonitorGetBalloonInfo()
* src/qemu/qemu_driver.c: Update to call qemuMonitorGetBalloonInfo()
  and remove qemudDomainGetMemoryBalloon().
---
 src/qemu/qemu_driver.c   |   62 ++---
 src/qemu/qemu_monitor_text.c |   42 
 src/qemu/qemu_monitor_text.h |2 +
 3 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 841ab68..8d3c9b6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2999,53 +2999,6 @@ cleanup:
 }
 
 
-/* The reply from QEMU contains 'ballon: actual=421' where value is in MB */
-#define BALLOON_PREFIX balloon: actual=
-
-/*
- * Returns: 0 if balloon not supported, +1 if balloon query worked
- * or -1 on failure
- */
-static int qemudDomainGetMemoryBalloon(virConnectPtr conn,
-   virDomainObjPtr vm,
-   unsigned long *currmem) {
-char *reply = NULL;
-int ret = -1;
-char *offset;
-
-if (!virDomainIsActive(vm))
-return 0;
-
-if (qemudMonitorCommand(vm, info balloon, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(could not query memory balloon allocation));
-goto cleanup;
-}
-
-DEBUG (%s: balloon reply: '%s', vm-def-name, reply);
-if ((offset = strstr(reply, BALLOON_PREFIX)) != NULL) {
-unsigned int memMB;
-char *end;
-offset += strlen(BALLOON_PREFIX);
-if (virStrToLong_ui(offset, end, 10, memMB)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(could not parse memory balloon 
allocation));
-goto cleanup;
-}
-*currmem = memMB * 1024;
-ret = 1;
-} else {
-/* We don't raise an error here, since its to be expected that
- * many QEMU's don't support ballooning
- */
-ret = 0;
-}
-
-cleanup:
-VIR_FREE(reply);
-return ret;
-}
-
 /*
  * Returns: 0 if balloon not supported, +1 if balloon query worked
  * or -1 on failure
@@ -3161,7 +3114,7 @@ static int qemudDomainGetInfo(virDomainPtr dom,
 info-maxMem = vm-def-maxmem;
 
 if (virDomainIsActive(vm)) {
-err = qemudDomainGetMemoryBalloon(dom-conn, vm, balloon);
+err = qemuMonitorGetBalloonInfo(vm, balloon);
 if (err  0)
 goto cleanup;
 
@@ -4122,11 +4075,14 @@ static char *qemudDomainDumpXML(virDomainPtr dom,
 }
 
 /* Refresh current memory based on balloon info */
-err = qemudDomainGetMemoryBalloon(dom-conn, vm, balloon);
-if (err  0)
-goto cleanup;
-if (err  0)
-vm-def-memory = balloon;
+if (virDomainIsActive(vm)) {
+err = qemuMonitorGetBalloonInfo(vm, balloon);
+if (err  0)
+goto cleanup;
+if (err  0)
+vm-def-memory = balloon;
+/* err == 0 indicates no balloon support, so ignore it */
+}
 
 ret = virDomainDefFormat(dom-conn,
  (flags  VIR_DOMAIN_XML_INACTIVE)  vm-newDef ?
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index ec5f670..2a20db3 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -547,6 +547,48 @@ error:
 }
 
 
+
+/* The reply from QEMU contains 'ballon: actual=421' where value is in MB */
+#define BALLOON_PREFIX balloon: actual=
+
+int qemuMonitorGetBalloonInfo(const virDomainObjPtr vm,
+  unsigned long *currmem)
+{
+char *reply = NULL;
+int ret = -1;
+char *offset;
+
+if (qemudMonitorCommand(vm, info balloon, reply)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ %s, _(could not query memory balloon allocation));
+return -1;
+}
+
+DEBUG (%s: balloon reply: '%s', vm-def-name, reply);
+if ((offset = strstr(reply, BALLOON_PREFIX)) != NULL) {
+unsigned int memMB;
+char *end;
+offset += strlen(BALLOON_PREFIX);
+if (virStrToLong_ui(offset, end, 10, memMB)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _(could not parse memory balloon allocation from 
'%s'), reply);
+goto cleanup;
+}
+*currmem = memMB * 1024;
+ret = 1;
+} else {
+/* We don't raise an error here, since its to be expected that
+ * many QEMU's don't support ballooning
+ */
+ret = 0;
+}
+
+cleanup:
+VIR_FREE(reply);
+return ret;
+}
+
+
 int qemuMonitorSetVNCPassword(const virDomainObjPtr vm,
   const char *password)
 {
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 

[libvirt] [PATCH 24/27] Add API for issuing 'host_net_remove' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.h, src/qemu/qemu_monitor.c: Add new
  qemuMonitorRemoveHostNetwork() command for removing host
  networks
* src/qemu/qemu_driver.c: Convert NIC hotplug methods over
  to use qemuMonitorRemoveHostNetwork()
---
 src/qemu/qemu_driver.c   |   65 ++---
 src/qemu/qemu_monitor_text.c |   32 
 src/qemu/qemu_monitor_text.h |4 ++
 3 files changed, 52 insertions(+), 49 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dfd5359..da72913 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4552,11 +4552,11 @@ static int qemudDomainAttachNetDevice(virConnectPtr 
conn,
   unsigned int qemuCmdFlags)
 {
 virDomainNetDefPtr net = dev-data.net;
-char *cmd = NULL, *reply = NULL, *remove_cmd = NULL;
 char *tapfd_name = NULL;
 int i, tapfd = -1;
 char *nicstr = NULL;
 char *netstr = NULL;
+int ret = -1;
 
 if (!(qemuCmdFlags  QEMUD_CMD_FLAG_HOST_NET_ADD)) {
 qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, %s,
@@ -4605,18 +4605,9 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 net-vlan, tapfd_name, netstr)  0)
 goto try_tapfd_close;
 
-remove_cmd = NULL;
-if (net-vlan = 0  net-hostnet_name 
-virAsprintf(remove_cmd, host_net_remove %d %s,
-net-vlan, net-hostnet_name)  0) {
-virReportOOMError(conn);
-goto try_tapfd_close;
-}
-
 if (qemuMonitorAddHostNetwork(vm, netstr)  0)
 goto try_tapfd_close;
 
-VIR_FREE(tapfd_name);
 if (tapfd != -1)
 close(tapfd);
 tapfd = -1;
@@ -4630,28 +4621,28 @@ static int qemudDomainAttachNetDevice(virConnectPtr 
conn,
  net-pci_addr.slot)  0)
 goto try_remove;
 
-VIR_FREE(netstr);
-VIR_FREE(nicstr);
-VIR_FREE(remove_cmd);
+ret = 0;
 
 vm-def-nets[vm-def-nnets++] = net;
 
-return 0;
+cleanup:
+VIR_FREE(nicstr);
+VIR_FREE(netstr);
+VIR_FREE(tapfd_name);
+if (tapfd != -1)
+close(tapfd);
 
-try_remove:
-VIR_FREE(reply);
+return ret;
 
-if (!remove_cmd)
+try_remove:
+if (!net-hostnet_name || net-vlan == 0)
 VIR_WARN0(_(Unable to remove network backend\n));
-else if (qemudMonitorCommand(vm, remove_cmd, reply)  0)
-VIR_WARN(_(Failed to remove network backend with '%s'\n), 
remove_cmd);
-else
-VIR_DEBUG(%s: host_net_remove reply: %s\n, vm-def-name, reply);
+else if (qemuMonitorRemoveHostNetwork(vm, net-vlan, net-hostnet_name)  
0)
+VIR_WARN(_(Failed to remove network backend for vlan %d, net %s),
+ net-vlan, net-hostnet_name);
 goto cleanup;
 
 try_tapfd_close:
-VIR_FREE(reply);
-
 if (tapfd_name 
 qemuMonitorCloseFileHandle(vm, tapfd_name)  0)
 VIR_WARN(_(Failed to close tapfd with '%s'\n), tapfd_name);
@@ -4660,16 +4651,7 @@ try_tapfd_close:
 
 no_memory:
 virReportOOMError(conn);
-cleanup:
-VIR_FREE(nicstr);
-VIR_FREE(netstr);
-VIR_FREE(cmd);
-VIR_FREE(reply);
-VIR_FREE(remove_cmd);
-VIR_FREE(tapfd_name);
-if (tapfd != -1)
-close(tapfd);
-return -1;
+goto cleanup;
 }
 
 static int qemudDomainAttachHostPciDevice(virConnectPtr conn,
@@ -4968,8 +4950,6 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
virDomainDeviceDefPtr dev)
 {
 int i, ret = -1;
-char *cmd = NULL;
-char *reply = NULL;
 virDomainNetDefPtr detach = NULL;
 
 for (i = 0 ; i  vm-def-nnets ; i++) {
@@ -5002,19 +4982,8 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
detach-pci_addr.slot)  0)
 goto cleanup;
 
-if (virAsprintf(cmd, host_net_remove %d %s,
-detach-vlan, detach-hostnet_name)  0) {
-virReportOOMError(conn);
+if (qemuMonitorRemoveHostNetwork(vm, detach-vlan, detach-hostnet_name)  
0)
 goto cleanup;
-}
-
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
-  _(network device dettach command '%s' failed), 
cmd);
-goto cleanup;
-}
-
-DEBUG(%s: host_net_remove reply: %s, vm-def-name,  reply);
 
 if (vm-def-nnets  1) {
 memmove(vm-def-nets + i,
@@ -5034,8 +5003,6 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
 ret = 0;
 
 cleanup:
-VIR_FREE(reply);
-VIR_FREE(cmd);
 return ret;
 }
 
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 5bff427..0675bf5 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1695,3 +1695,35 @@ cleanup:
 VIR_FREE(reply);
 return ret;
 }
+
+
+int qemuMonitorRemoveHostNetwork(const virDomainObjPtr vm,
+ int vlan,
+ const char 

[libvirt] [PATCH 09/27] Add APIs for issuing 'eject' and 'change dev' monitor commands

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new APis
  qemuMonitorChangeMedia and qemuMonitorEjectMedia. Pull in code
  for qemudEscape
* src/qemu/qemu_driver.c: Remove code that directly issues 'eject'
  and 'change' commands in favour of API calls.
---
 src/qemu/qemu_driver.c   |   52 +++---
 src/qemu/qemu_monitor_text.c |  159 ++
 src/qemu/qemu_monitor_text.h |   10 +++
 3 files changed, 178 insertions(+), 43 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a0b5e49..b15dc03 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4573,9 +4573,9 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr 
conn,
unsigned int qemuCmdFlags)
 {
 virDomainDiskDefPtr origdisk = NULL, newdisk;
-char *cmd, *reply, *safe_path;
 char *devname = NULL;
 int i;
+int ret;
 
 origdisk = NULL;
 newdisk = dev-data.disk;
@@ -4621,52 +4621,18 @@ static int 
qemudDomainChangeEjectableMedia(virConnectPtr conn,
 }
 
 if (newdisk-src) {
-safe_path = qemudEscapeMonitorArg(newdisk-src);
-if (!safe_path) {
-virReportOOMError(conn);
-VIR_FREE(devname);
-return -1;
-}
-if (virAsprintf(cmd, change %s \%s\, devname, safe_path) == -1) {
-virReportOOMError(conn);
-VIR_FREE(safe_path);
-VIR_FREE(devname);
-return -1;
-}
-VIR_FREE(safe_path);
-
-} else if (virAsprintf(cmd, eject %s, devname) == -1) {
-virReportOOMError(conn);
-VIR_FREE(devname);
-return -1;
-}
-VIR_FREE(devname);
-
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(could not change cdrom media));
-VIR_FREE(cmd);
-return -1;
+ret = qemuMonitorChangeMedia(vm, devname, newdisk-src);
+} else {
+ret = qemuMonitorEjectMedia(vm, devname);
 }
 
-/* If the command failed qemu prints:
- * device not found, device is locked ...
- * No message is printed on success it seems */
-DEBUG (%s: ejectable media change reply: %s, vm-def-name, reply);
-if (strstr(reply, \ndevice )) {
-qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  _(changing cdrom media failed: %s), reply);
-VIR_FREE(reply);
-VIR_FREE(cmd);
-return -1;
+if (ret == 0) {
+VIR_FREE(origdisk-src);
+origdisk-src = newdisk-src;
+newdisk-src = NULL;
+origdisk-type = newdisk-type;
 }
-VIR_FREE(reply);
-VIR_FREE(cmd);
 
-VIR_FREE(origdisk-src);
-origdisk-src = newdisk-src;
-newdisk-src = NULL;
-origdisk-type = newdisk-type;
 return 0;
 }
 
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index be13dce..8be8047 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -40,6 +40,84 @@
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
+static char *qemudEscape(const char *in, int shell)
+{
+int len = 0;
+int i, j;
+char *out;
+
+/* To pass through the QEMU monitor, we need to use escape
+   sequences: \r, \n, \, \\
+
+   To pass through both QEMU + the shell, we need to escape
+   the single character ' as the five characters '\\''
+*/
+
+for (i = 0; in[i] != '\0'; i++) {
+switch(in[i]) {
+case '\r':
+case '\n':
+case '':
+case '\\':
+len += 2;
+break;
+case '\'':
+if (shell)
+len += 5;
+else
+len += 1;
+break;
+default:
+len += 1;
+break;
+}
+}
+
+if (VIR_ALLOC_N(out, len + 1)  0)
+return NULL;
+
+for (i = j = 0; in[i] != '\0'; i++) {
+switch(in[i]) {
+case '\r':
+out[j++] = '\\';
+out[j++] = 'r';
+break;
+case '\n':
+out[j++] = '\\';
+out[j++] = 'n';
+break;
+case '':
+case '\\':
+out[j++] = '\\';
+out[j++] = in[i];
+break;
+case '\'':
+if (shell) {
+out[j++] = '\'';
+out[j++] = '\\';
+out[j++] = '\\';
+out[j++] = '\'';
+out[j++] = '\'';
+} else {
+out[j++] = in[i];
+}
+break;
+default:
+out[j++] = in[i];
+break;
+}
+}
+out[j] = '\0';
+
+return out;
+}
+
+static char *qemudEscapeMonitorArg(const char *in)
+{
+return qemudEscape(in, 0);
+}
+
+
 /* Throw away any data available on the monitor
  * This is done before executing a command, in order
  * to allow 

[libvirt] [PATCH 08/27] Add API for issuing 'balloon' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorSetBalloon() based on existing code in
  qemudDomainSetMemoryBalloon
* src/qemu/qemu_driver.c: Remove use of qemudDomainSetMemoryBalloon()
  in favour of qemuMonitorSetBalloon(). Fix error code when balloon
  is not supported
---
 src/qemu/qemu_driver.c   |   56 -
 src/qemu/qemu_monitor_text.c |   47 +++
 src/qemu/qemu_monitor_text.h |2 +
 3 files changed, 55 insertions(+), 50 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8d3c9b6..a0b5e49 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -107,9 +107,6 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
 
 static int qemudDomainGetMaxVcpus(virDomainPtr dom);
 
-static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
-   virDomainObjPtr vm,
-   unsigned long newmem);
 static int qemuDetectVcpuPIDs(virConnectPtr conn,
   virDomainObjPtr vm);
 
@@ -2137,7 +2134,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
 (qemuDetectVcpuPIDs(conn, vm)  0) ||
 (qemudInitCpus(conn, vm, migrateFrom)  0) ||
 (qemuInitPasswords(driver, vm)  0) ||
-(qemudDomainSetMemoryBalloon(conn, vm, vm-def-memory)  0) ||
+(qemuMonitorSetBalloon(vm, vm-def-memory)  0) ||
 (virDomainSaveStatus(conn, driver-stateDir, vm)  0)) {
 qemudShutdownVMDaemon(conn, driver, vm);
 ret = -1;
@@ -2999,50 +2996,6 @@ cleanup:
 }
 
 
-/*
- * Returns: 0 if balloon not supported, +1 if balloon query worked
- * or -1 on failure
- */
-static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
-   virDomainObjPtr vm,
-   unsigned long newmem) {
-char *cmd;
-char *reply = NULL;
-int ret = -1;
-
-/*
- * 'newmem' is in KB, QEMU monitor works in MB, and we all wish
- * we just worked in bytes with unsigned long long everywhere.
- */
-if (virAsprintf(cmd, balloon %lu, (newmem / 1024))  0) {
-virReportOOMError(conn);
-goto cleanup;
-}
-
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(could not balloon memory allocation));
-VIR_FREE(cmd);
-goto cleanup;
-}
-VIR_FREE(cmd);
-
-/* If the command failed qemu prints: 'unknown command'
- * No message is printed on success it seems */
-DEBUG (%s: balloon reply: %s,vm-def-name,  reply);
-if (strstr(reply, \nunknown command:)) {
-/* Don't set error - it is expected memory balloon fails on many qemu 
*/
-ret = 0;
-} else {
-ret = 1;
-}
-
-cleanup:
-VIR_FREE(reply);
-return ret;
-}
-
-
 static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
 struct qemud_driver *driver = dom-conn-privateData;
 virDomainObjPtr vm;
@@ -3066,10 +3019,13 @@ static int qemudDomainSetMemory(virDomainPtr dom, 
unsigned long newmem) {
 }
 
 if (virDomainIsActive(vm)) {
-ret = qemudDomainSetMemoryBalloon(dom-conn, vm, newmem);
-if (ret == 0)
+ret = qemuMonitorSetBalloon(vm, newmem);
+/* Turn lack of balloon support into a fatal error */
+if (ret == 0) {
 qemudReportError(dom-conn, dom, NULL, VIR_ERR_NO_SUPPORT,
  %s, _(cannot set memory of an active domain));
+ret = -1;
+}
 } else {
 vm-def-memory = newmem;
 ret = 0;
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 2a20db3..be13dce 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -551,6 +551,10 @@ error:
 /* The reply from QEMU contains 'ballon: actual=421' where value is in MB */
 #define BALLOON_PREFIX balloon: actual=
 
+/*
+ * Returns: 0 if balloon not supported, +1 if balloon query worked
+ * or -1 on failure
+ */
 int qemuMonitorGetBalloonInfo(const virDomainObjPtr vm,
   unsigned long *currmem)
 {
@@ -604,3 +608,46 @@ int qemuMonitorSetVNCPassword(const virDomainObjPtr vm,
 VIR_FREE(info);
 return 0;
 }
+
+/*
+ * Returns: 0 if balloon not supported, +1 if balloon adjust worked
+ * or -1 on failure
+ */
+int qemuMonitorSetBalloon(const virDomainObjPtr vm,
+  unsigned long newmem)
+{
+char *cmd;
+char *reply = NULL;
+int ret = -1;
+
+/*
+ * 'newmem' is in KB, QEMU monitor works in MB, and we all wish
+ * we just worked in bytes with unsigned long long everywhere.
+ */
+if (virAsprintf(cmd, balloon %lu, (newmem / 1024))  0) {
+virReportOOMError(NULL);
+return -1;
+}
+
+if (qemudMonitorCommand(vm, cmd, reply)  0) {
+qemudReportError(NULL, 

[libvirt] [PATCH 10/27] Add APIs for issuing 'memsave' and 'pmemsave' monitor commands

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.h, src/qemu/qemu_monitor.c: Add new APIs
  qemuMonitorSaveVirtualMemory() and qemuMonitorSavePhysicalMemory()
* src/qemu/qemu_driver.c: Use the new qemuMonitorSaveVirtualMemory()
  and qemuMonitorSavePhysicalMemory() APIs
---
 src/qemu/qemu_driver.c   |   21 ---
 src/qemu/qemu_monitor_text.c |   54 ++
 src/qemu/qemu_monitor_text.h |   10 +++
 3 files changed, 70 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b15dc03..9c09024 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6233,7 +6233,6 @@ qemudDomainMemoryPeek (virDomainPtr dom,
 {
 struct qemud_driver *driver = dom-conn-privateData;
 virDomainObjPtr vm;
-char cmd[256], *info = NULL;
 char *tmp = NULL;
 int fd = -1, ret = -1;
 
@@ -6273,21 +6272,14 @@ qemudDomainMemoryPeek (virDomainPtr dom,
 goto cleanup;
 }
 
-if (flags == VIR_MEMORY_VIRTUAL)
-/* Issue the memsave command. */
-snprintf (cmd, sizeof cmd, memsave %llu %zi \%s\, offset, size, 
tmp);
-else
-/* Issue the pmemsave command. */
-snprintf (cmd, sizeof cmd, pmemsave %llu %zi \%s\, offset, size, 
tmp);
-
-if (qemudMonitorCommand (vm, cmd, info)  0) {
-qemudReportError (dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  %s, _('memsave' command failed));
-goto cleanup;
+if (flags == VIR_MEMORY_VIRTUAL) {
+if (qemuMonitorSaveVirtualMemory(vm, offset, size, tmp)  0)
+goto cleanup;
+} else {
+if (qemuMonitorSavePhysicalMemory(vm, offset, size, tmp)  0)
+goto cleanup;
 }
 
-DEBUG (%s: (p)memsave reply: %s, vm-def-name, info);
-
 /* Read the memory file into buffer. */
 if (saferead (fd, buffer, size) == (ssize_t) -1) {
 virReportSystemError (dom-conn, errno,
@@ -6300,7 +6292,6 @@ qemudDomainMemoryPeek (virDomainPtr dom,
 
 cleanup:
 VIR_FREE(tmp);
-VIR_FREE(info);
 if (fd = 0) close (fd);
 unlink (tmp);
 if (vm)
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 8be8047..a5f43c5 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -810,3 +810,57 @@ cleanup:
 return ret;
 }
 
+static int qemuMonitorSaveMemory(const virDomainObjPtr vm,
+ const char *cmdtype,
+ unsigned long long offset,
+ size_t length,
+ const char *path)
+{
+char *cmd = NULL;
+char *reply = NULL;
+char *safepath = NULL;
+int ret = -1;
+
+if (!(safepath = qemudEscapeMonitorArg(path))) {
+virReportOOMError(NULL);
+goto cleanup;
+}
+
+if (virAsprintf(cmd, %s %llu %zi \%s\, cmdtype, offset, length, 
safepath)  0) {
+virReportOOMError(NULL);
+goto cleanup;
+}
+
+if (qemudMonitorCommand(vm, cmd, reply)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _(could save memory region to '%s'), path);
+goto cleanup;
+}
+
+/* XXX what is printed on failure ? */
+
+ret = 0;
+
+cleanup:
+VIR_FREE(cmd);
+VIR_FREE(reply);
+VIR_FREE(safepath);
+return ret;
+}
+
+
+int qemuMonitorSaveVirtualMemory(const virDomainObjPtr vm,
+ unsigned long long offset,
+ size_t length,
+ const char *path)
+{
+return qemuMonitorSaveMemory(vm, memsave, offset, length, path);
+}
+
+int qemuMonitorSavePhysicalMemory(const virDomainObjPtr vm,
+  unsigned long long offset,
+  size_t length,
+  const char *path)
+{
+return qemuMonitorSaveMemory(vm, pmemsave, offset, length, path);
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index d05dea1..dfe3445 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -91,4 +91,14 @@ int qemuMonitorChangeMedia(const virDomainObjPtr vm,
const char *devname,
const char *newmedia);
 
+
+int qemuMonitorSaveVirtualMemory(const virDomainObjPtr vm,
+ unsigned long long offset,
+ size_t length,
+ const char *path);
+int qemuMonitorSavePhysicalMemory(const virDomainObjPtr vm,
+  unsigned long long offset,
+  size_t length,
+  const char *path);
+
 #endif /* QEMU_MONITOR_TEXT_H */
-- 
1.6.2.5

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


[libvirt] [PATCH 23/27] Add API for issuing 'host_net_add' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_conf.h, src/qemu/qemu_conf.c: Remove prefix arg
  from qemuBuildHostNetStr which is no longer required
* src/qemu/qemu_driver.c: Refactor to use qemuMonitorAddHostNetwork()
  API for adding host network
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorAddHostNetwork() method for adding host networks
---
 src/qemu/qemu_conf.c |   14 --
 src/qemu/qemu_conf.h |1 -
 src/qemu/qemu_driver.c   |   16 ++--
 src/qemu/qemu_monitor_text.c |   30 ++
 src/qemu/qemu_monitor_text.h |7 +++
 5 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index c531454..1d98637 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1287,7 +1287,6 @@ qemuBuildNicStr(virConnectPtr conn,
 int
 qemuBuildHostNetStr(virConnectPtr conn,
 virDomainNetDefPtr net,
-const char *prefix,
 char type_sep,
 int vlan,
 const char *tapfd,
@@ -1296,8 +1295,7 @@ qemuBuildHostNetStr(virConnectPtr conn,
 switch (net-type) {
 case VIR_DOMAIN_NET_TYPE_NETWORK:
 case VIR_DOMAIN_NET_TYPE_BRIDGE:
-if (virAsprintf(str, %stap%cfd=%s,vlan=%d%s%s,
-prefix ? prefix : ,
+if (virAsprintf(str, tap%cfd=%s,vlan=%d%s%s,
 type_sep, tapfd, vlan,
 (net-hostnet_name ? ,name= : ),
 (net-hostnet_name ? net-hostnet_name : ))  0) {
@@ -1310,8 +1308,6 @@ qemuBuildHostNetStr(virConnectPtr conn,
 {
 virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-if (prefix)
-virBufferAdd(buf, prefix, strlen(prefix));
 virBufferAddLit(buf, tap);
 if (net-ifname) {
 virBufferVSprintf(buf, %cifname=%s, type_sep, net-ifname);
@@ -1355,8 +1351,7 @@ qemuBuildHostNetStr(virConnectPtr conn,
 break;
 }
 
-if (virAsprintf(str, %ssocket%c%s=%s:%d,vlan=%d%s%s,
-prefix ? prefix : ,
+if (virAsprintf(str, socket%c%s=%s:%d,vlan=%d%s%s,
 type_sep, mode,
 net-data.socket.address,
 net-data.socket.port,
@@ -1371,8 +1366,7 @@ qemuBuildHostNetStr(virConnectPtr conn,
 
 case VIR_DOMAIN_NET_TYPE_USER:
 default:
-if (virAsprintf(str, %suser%cvlan=%d%s%s,
-prefix ? prefix : ,
+if (virAsprintf(str, user%cvlan=%d%s%s,
 type_sep, vlan,
 (net-hostnet_name ? ,name= : ),
 (net-hostnet_name ? net-hostnet_name : ))  0) {
@@ -2014,7 +2008,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
 goto no_memory;
 }
 
-if (qemuBuildHostNetStr(conn, net, NULL, ',',
+if (qemuBuildHostNetStr(conn, net, ',',
 net-vlan, tapfd_name, host)  0) {
 VIR_FREE(tapfd_name);
 goto error;
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 6ff5f0d..96b7c0c 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -170,7 +170,6 @@ int qemudBuildCommandLine   (virConnectPtr conn,
 
 int qemuBuildHostNetStr (virConnectPtr conn,
  virDomainNetDefPtr net,
- const char *prefix,
  char type_sep,
  int vlan,
  const char *tapfd,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6363edc..dfd5359 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4556,6 +4556,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 char *tapfd_name = NULL;
 int i, tapfd = -1;
 char *nicstr = NULL;
+char *netstr = NULL;
 
 if (!(qemuCmdFlags  QEMUD_CMD_FLAG_HOST_NET_ADD)) {
 qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, %s,
@@ -4600,8 +4601,8 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 goto cleanup;
 }
 
-if (qemuBuildHostNetStr(conn, net, host_net_add , ' ',
-net-vlan, tapfd_name, cmd)  0)
+if (qemuBuildHostNetStr(conn, net, ' ',
+net-vlan, tapfd_name, netstr)  0)
 goto try_tapfd_close;
 
 remove_cmd = NULL;
@@ -4612,16 +4613,9 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 goto try_tapfd_close;
 }
 
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(failed to add network backend with '%s'), cmd);
+if (qemuMonitorAddHostNetwork(vm, netstr)  

[libvirt] [PATCH 06/27] Add API for the 'system_powerdown' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_driver.c: Remove use of 'system_powerdown'
* src/qemu/qemu_monitor.h, src/qemu/qemu_monitor.c: Add a new
  qemuMonitorSystemPowerdown() api call
---
 src/qemu/qemu_driver.c   |8 ++--
 src/qemu/qemu_monitor_text.c |   14 ++
 src/qemu/qemu_monitor_text.h |2 ++
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5ebd4b7..841ab68 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2841,7 +2841,6 @@ cleanup:
 static int qemudDomainShutdown(virDomainPtr dom) {
 struct qemud_driver *driver = dom-conn-privateData;
 virDomainObjPtr vm;
-char* info;
 int ret = -1;
 
 qemuDriverLock(driver);
@@ -2862,12 +2861,9 @@ static int qemudDomainShutdown(virDomainPtr dom) {
 goto cleanup;
 }
 
-if (qemudMonitorCommand(vm, system_powerdown, info)  0) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- %s, _(shutdown operation failed));
+if (qemuMonitorSystemPowerdown(vm)  0)
 goto cleanup;
-}
-VIR_FREE(info);
+
 ret = 0;
 
 cleanup:
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index ec30e72..ec5f670 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -451,6 +451,20 @@ qemuMonitorStopCPUs(const virDomainObjPtr vm) {
 return 0;
 }
 
+
+int qemuMonitorSystemPowerdown(const virDomainObjPtr vm) {
+char *info;
+
+if (qemudMonitorCommand(vm, system_powerdown, info)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ %s, _(system shutdown operation failed));
+return -1;
+}
+VIR_FREE(info);
+return 0;
+}
+
+
 int qemuMonitorGetCPUInfo(const virDomainObjPtr vm,
   int **pids)
 {
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index eb1ba44..342a3f3 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -69,6 +69,8 @@ int qemuMonitorStartCPUs(virConnectPtr conn,
  const virDomainObjPtr vm);
 int qemuMonitorStopCPUs(const virDomainObjPtr vm);
 
+int qemuMonitorSystemPowerdown(const virDomainObjPtr vm);
+
 int qemuMonitorGetCPUInfo(const virDomainObjPtr vm,
   int **pids);
 
-- 
1.6.2.5

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


[libvirt] [PATCH 13/27] Add API for running 'info migration' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorGetMigrationStatus() command.
* src/qemu/qemu_driver.c: Use new qemuMonitorGetMigrationStatus()
  command to check completion status.
---
 src/qemu/qemu_driver.c   |   15 +--
 src/qemu/qemu_monitor_text.c |   91 ++
 src/qemu/qemu_monitor_text.h |   16 +++
 3 files changed, 117 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ccc13c4..a6300c9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6499,6 +6499,8 @@ qemudDomainMigratePerform (virDomainPtr dom,
 char *info = NULL;
 int ret = -1;
 int paused = 0;
+int status;
+unsigned long long transferred, remaining, total;
 
 qemuDriverLock(driver);
 vm = virDomainFindByUUID(driver-domains, dom-uuid);
@@ -6562,14 +6564,17 @@ qemudDomainMigratePerform (virDomainPtr dom,
  * rather failed later on.  Check the output of info migrate
  */
 VIR_FREE(info);
-if (qemudMonitorCommand(vm, info migrate, info)  0) {
-qemudReportError (dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  %s, _(could not get info about migration));
+
+if (qemuMonitorGetMigrationStatus(vm, status,
+  transferred,
+  remaining,
+  total)  0) {
 goto cleanup;
 }
-if (strstr(info, fail) != NULL) {
+
+if (status != QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
 qemudReportError (dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  _(migrate failed: %s), info);
+  %s, _(migrate did not successfully complete));
 goto cleanup;
 }
 
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index d9227a2..0b746b9 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -28,6 +28,7 @@
 #include sys/un.h
 #include poll.h
 #include unistd.h
+#include string.h
 
 #include qemu_monitor_text.h
 #include qemu_conf.h
@@ -997,3 +998,93 @@ cleanup:
 VIR_FREE(cmd);
 return ret;
 }
+
+
+#define MIGRATION_PREFIX Migration status: 
+#define MIGRATION_TRANSFER_PREFIX transferred ram: 
+#define MIGRATION_REMAINING_PREFIX remaining ram: 
+#define MIGRATION_TOTAL_PREFIX total ram: 
+
+VIR_ENUM_DECL(qemuMonitorMigrationStatus)
+VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
+  QEMU_MONITOR_MIGRATION_STATUS_LAST,
+  inactive, active, completed, failed, cancelled)
+
+int qemuMonitorGetMigrationStatus(const virDomainObjPtr vm,
+  int *status,
+  unsigned long long *transferred,
+  unsigned long long *remaining,
+  unsigned long long *total) {
+char *reply;
+char *tmp;
+char *end;
+int ret = -1;
+
+*status = QEMU_MONITOR_MIGRATION_STATUS_INACTIVE;
+*transferred = 0;
+*remaining = 0;
+*total = 0;
+
+if (qemudMonitorCommand(vm, info migration, reply)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ %s, _(cannot query migration status));
+return -1;
+}
+
+if ((tmp = strstr(reply, MIGRATION_PREFIX)) != NULL) {
+tmp += strlen(MIGRATION_PREFIX);
+end = strchr(tmp, '\n');
+*end = '\0';
+
+if ((*status = qemuMonitorMigrationStatusTypeFromString(tmp))  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _(unexpected migration status in %s), reply);
+goto cleanup;
+}
+
+if (*status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
+tmp = end + 1;
+
+if (!(tmp = strstr(tmp, MIGRATION_TRANSFER_PREFIX)))
+goto done;
+tmp += strlen(MIGRATION_TRANSFER_PREFIX);
+
+if (virStrToLong_ull(tmp, NULL, 10, transferred)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _(cannot parse migration data transferred 
statistic %s), tmp);
+goto cleanup;
+}
+*transferred *= 1024;
+
+if (!(tmp = strstr(tmp, MIGRATION_REMAINING_PREFIX)))
+goto done;
+tmp += strlen(MIGRATION_REMAINING_PREFIX);
+
+if (virStrToLong_ull(tmp, NULL, 10, remaining)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _(cannot parse migration data remaining 
statistic %s), tmp);
+goto cleanup;
+}
+*remaining *= 1024;
+
+if (!(tmp = strstr(tmp, MIGRATION_TOTAL_PREFIX)))
+goto done;
+tmp += strlen(MIGRATION_TOTAL_PREFIX);
+
+if (virStrToLong_ull(tmp, NULL, 10, 

[libvirt] [PATCH 22/27] Add API for issuing 'pci_add nic' monitor command

2009-09-24 Thread Daniel P. Berrange
* src/qemu/qemu_conf.c: Remove separator from qemuBuildNicStr()
  args, and remove hardcoded 'nic' prefix. Leave it upto callers
  instead
* src/qemu/qemu_driver.c: Switch over to using the new
  qemuMonitorAddPCINetwork() method for NIC hotplug
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorAddPCINetwork API for PCI network device hotplug
---
 src/qemu/qemu_conf.c |6 +--
 src/qemu/qemu_conf.h |1 -
 src/qemu/qemu_driver.c   |   93 --
 src/qemu/qemu_monitor_text.c |   36 
 src/qemu/qemu_monitor_text.h |9 
 5 files changed, 55 insertions(+), 90 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 309f171..c531454 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1263,14 +1263,12 @@ int
 qemuBuildNicStr(virConnectPtr conn,
 virDomainNetDefPtr net,
 const char *prefix,
-char type_sep,
 int vlan,
 char **str)
 {
 if (virAsprintf(str,
-
%snic%cmacaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s%s%s,
+%smacaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s%s%s,
 prefix ? prefix : ,
-type_sep,
 net-mac[0], net-mac[1],
 net-mac[2], net-mac[3],
 net-mac[4], net-mac[5],
@@ -1988,7 +1986,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
 qemuAssignNetNames(def, net)  0)
 goto no_memory;
 
-if (qemuBuildNicStr(conn, net, NULL, ',', net-vlan, nic)  0)
+if (qemuBuildNicStr(conn, net, nic,, net-vlan, nic)  0)
 goto error;
 
 if ((qargv[qargc++] = strdup(-net)) == NULL) {
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 82eb89f..6ff5f0d 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -179,7 +179,6 @@ int qemuBuildHostNetStr (virConnectPtr conn,
 int qemuBuildNicStr (virConnectPtr conn,
  virDomainNetDefPtr net,
  const char *prefix,
- char type_sep,
  int vlan,
  char **str);
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f8710a6..6363edc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4478,72 +4478,6 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr 
conn,
 return 0;
 }
 
-static int
-qemudParsePciAddReply(virDomainObjPtr vm,
-  const char *reply,
-  unsigned *domain,
-  unsigned *bus,
-  unsigned *slot)
-{
-char *s, *e;
-
-DEBUG(%s: pci_add reply: %s, vm-def-name, reply);
-
-/* If the command succeeds qemu prints:
- * OK bus 0, slot XXX...
- * or
- * OK domain 0, bus 0, slot XXX
- */
-if (!(s = strstr(reply, OK )))
-return -1;
-
-s += 3;
-
-if (STRPREFIX(s, domain )) {
-s += strlen(domain );
-
-if (virStrToLong_ui(s, e, 10, domain) == -1) {
-VIR_WARN(_(Unable to parse domain number '%s'\n), s);
-return -1;
-}
-
-if (!STRPREFIX(e, , )) {
-VIR_WARN(_(Expected ', ' parsing pci_add reply '%s'\n), s);
-return -1;
-}
-s = e + 2;
-}
-
-if (!STRPREFIX(s, bus )) {
-VIR_WARN(_(Expected 'bus ' parsing pci_add reply '%s'\n), s);
-return -1;
-}
-s += strlen(bus );
-
-if (virStrToLong_ui(s, e, 10, bus) == -1) {
-VIR_WARN(_(Unable to parse bus number '%s'\n), s);
-return -1;
-}
-
-if (!STRPREFIX(e, , )) {
-VIR_WARN(_(Expected ', ' parsing pci_add reply '%s'\n), s);
-return -1;
-}
-s = e + 2;
-
-if (!STRPREFIX(s, slot )) {
-VIR_WARN(_(Expected 'slot ' parsing pci_add reply '%s'\n), s);
-return -1;
-}
-s += strlen(slot );
-
-if (virStrToLong_ui(s, e, 10, slot) == -1) {
-VIR_WARN(_(Unable to parse slot number '%s'\n), s);
-return -1;
-}
-
-return 0;
-}
 
 static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
   virDomainObjPtr vm,
@@ -4621,7 +4555,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 char *cmd = NULL, *reply = NULL, *remove_cmd = NULL;
 char *tapfd_name = NULL;
 int i, tapfd = -1;
-unsigned domain, bus, slot;
+char *nicstr = NULL;
 
 if (!(qemuCmdFlags  QEMUD_CMD_FLAG_HOST_NET_ADD)) {
 qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, %s,
@@ -4693,30 +4627,18 @@ static int qemudDomainAttachNetDevice(virConnectPtr 
conn,
 close(tapfd);
 tapfd = -1;
 
-if (qemuBuildNicStr(conn, net,
-   

[libvirt] [PATCH 01/27] Pull QEMU monitor interaction out to separate file

2009-09-24 Thread Daniel P. Berrange
Pull out all the QEMU monitor interaction code to a separate
file. This will make life easier when we need to drop in a
new implementation for the forthcoming QMP machine friendly
monitor support.

Next step is to add formal APIs for each monitor command,
and remove direct commands for sending/receiving generic
data.

* src/Makefile.am: Add qemu_monitor.c to build
* src/qemu/qemu_driver.c: Remove code for monitor interaction
* src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: New
  file for monitor interaction
---
 src/Makefile.am  |1 +
 src/qemu/qemu_driver.c   |  426 +
 src/qemu/qemu_monitor_text.c |  437 ++
 src/qemu/qemu_monitor_text.h |   72 +++
 4 files changed, 511 insertions(+), 425 deletions(-)
 create mode 100644 src/qemu/qemu_monitor_text.c
 create mode 100644 src/qemu/qemu_monitor_text.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 9cbec47..7520e96 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -169,6 +169,7 @@ VBOX_DRIVER_EXTRA_DIST = vbox/vbox_tmpl.c vbox/README
 
 QEMU_DRIVER_SOURCES =  \
qemu/qemu_conf.c qemu/qemu_conf.h   \
+   qemu/qemu_monitor_text.c qemu/qemu_monitortext.h\
qemu/qemu_driver.c qemu/qemu_driver.h
 
 UML_DRIVER_SOURCES =   \
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 25d983e..9f17aae 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -55,6 +55,7 @@
 #include datatypes.h
 #include qemu_driver.h
 #include qemu_conf.h
+#include qemu_monitor_text.h
 #include c-ctype.h
 #include event.h
 #include buf.h
@@ -74,9 +75,6 @@
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
-#define QEMU_CMD_PROMPT \n(qemu) 
-#define QEMU_PASSWD_PROMPT Password: 
-
 static int qemudShutdown(void);
 
 static void qemuDriverLock(struct qemud_driver *driver)
@@ -88,12 +86,6 @@ static void qemuDriverUnlock(struct qemud_driver *driver)
 virMutexUnlock(driver-lock);
 }
 
-/* Return -1 for error, 0 for success */
-typedef int qemudMonitorExtraPromptHandler(const virDomainObjPtr vm,
-   const char *buf,
-   const char *prompt,
-   void *data);
-
 static void qemuDomainEventFlush(int timer, void *opaque);
 static void qemuDomainEventQueue(struct qemud_driver *driver,
  virDomainEventPtr event);
@@ -115,28 +107,6 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
 
 static int qemudDomainGetMaxVcpus(virDomainPtr dom);
 
-static int qemudMonitorCommand(const virDomainObjPtr vm,
-   const char *cmd,
-   char **reply);
-static int qemudMonitorCommandWithFd(const virDomainObjPtr vm,
- const char *cmd,
- int scm_fd,
- char **reply);
-static int qemudMonitorCommandWithHandler(const virDomainObjPtr vm,
-  const char *cmd,
-  const char *extraPrompt,
-  qemudMonitorExtraPromptHandler 
extraHandler,
-  void *handlerData,
-  int scm_fd,
-  char **reply);
-static int qemudMonitorCommandExtra(const virDomainObjPtr vm,
-const char *cmd,
-const char *extra,
-const char *extraPrompt,
-int scm_fd,
-char **reply);
-static int qemudMonitorSendCont(virConnectPtr conn,
-const virDomainObjPtr vm);
 static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
virDomainObjPtr vm,
unsigned long newmem);
@@ -2411,400 +2381,6 @@ cleanup:
 }
 
 
-/* Throw away any data available on the monitor
- * This is done before executing a command, in order
- * to allow re-synchronization if something went badly
- * wrong in the past. it also deals with problem of
- * QEMU *sometimes* re-printing its initial greeting
- * when we reconnect to the monitor after restarts.
- */
-static void
-qemuMonitorDiscardPendingData(virDomainObjPtr vm) {
-char buf[1024];
-int ret = 0;
-
-/* Monitor is non-blocking, so just loop till we
- * get -1 or 0. Don't bother with detecting
- * errors, since we'll deal with that better later */
-do {
-ret = read(vm-monitor, buf, sizeof (buf)-1);
-} while (ret  0);
-}
-
-static int
-qemudMonitorSendUnix(const virDomainObjPtr vm,
- const 

[libvirt] [PATCH] Remove hand-crafted UUID parsers

2009-09-24 Thread Daniel P. Berrange
* src/libvirt.c: Remove hand-crafted UUID parsers in favour of
  calling virParseUUID
---
 src/libvirt.c |   56 +---
 1 files changed, 5 insertions(+), 51 deletions(-)

diff --git a/src/libvirt.c b/src/libvirt.c
index 9fb0617..74d62a4 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1839,26 +1839,11 @@ virDomainLookupByUUIDString(virConnectPtr conn, const 
char *uuidstr)
 virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 goto error;
 }
-/* XXX: sexpr_uuid() also supports '---' format.
- *  We needn't it here. Right?
- */
-ret = sscanf(uuidstr,
- %02x%02x%02x%02x-
- %02x%02x-
- %02x%02x-
- %02x%02x-
- %02x%02x%02x%02x%02x%02x,
- raw + 0, raw + 1, raw + 2, raw + 3,
- raw + 4, raw + 5, raw + 6, raw + 7,
- raw + 8, raw + 9, raw + 10, raw + 11,
- raw + 12, raw + 13, raw + 14, raw + 15);
-
-if (ret!=VIR_UUID_BUFLEN) {
+
+if (virUUIDParse(uuidstr, uuid)  0) {
 virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 goto error;
 }
-for (i = 0; i  VIR_UUID_BUFLEN; i++)
-uuid[i] = raw[i]  0xFF;
 
 return virDomainLookupByUUID(conn, uuid[0]);
 
@@ -5038,26 +5023,10 @@ virNetworkLookupByUUIDString(virConnectPtr conn, const 
char *uuidstr)
 goto error;
 }
 
-/* XXX: sexpr_uuid() also supports '---' format.
- *  We needn't it here. Right?
- */
-ret = sscanf(uuidstr,
- %02x%02x%02x%02x-
- %02x%02x-
- %02x%02x-
- %02x%02x-
- %02x%02x%02x%02x%02x%02x,
- raw + 0, raw + 1, raw + 2, raw + 3,
- raw + 4, raw + 5, raw + 6, raw + 7,
- raw + 8, raw + 9, raw + 10, raw + 11,
- raw + 12, raw + 13, raw + 14, raw + 15);
-
-if (ret!=VIR_UUID_BUFLEN) {
+if (virUUIDParse(uuidstr, uuid)  0) {
 virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 goto error;
 }
-for (i = 0; i  VIR_UUID_BUFLEN; i++)
-uuid[i] = raw[i]  0xFF;
 
 return virNetworkLookupByUUID(conn, uuid[0]);
 
@@ -8887,26 +8856,11 @@ virSecretLookupByUUIDString(virConnectPtr conn, const 
char *uuidstr)
 virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 goto error;
 }
-/* XXX: sexpr_uuid() also supports '---' format.
- *  We needn't it here. Right?
- */
-ret = sscanf(uuidstr,
- %02x%02x%02x%02x-
- %02x%02x-
- %02x%02x-
- %02x%02x-
- %02x%02x%02x%02x%02x%02x,
- raw + 0, raw + 1, raw + 2, raw + 3,
- raw + 4, raw + 5, raw + 6, raw + 7,
- raw + 8, raw + 9, raw + 10, raw + 11,
- raw + 12, raw + 13, raw + 14, raw + 15);
-
-if (ret!=VIR_UUID_BUFLEN) {
+
+if (virUUIDParse(uuidstr, uuid)  0) {
 virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 goto error;
 }
-for (i = 0; i  VIR_UUID_BUFLEN; i++)
-uuid[i] = raw[i]  0xFF;
 
 return virSecretLookupByUUID(conn, uuid[0]);
 
-- 
1.6.2.5

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


[libvirt] node device devicekit backend

2009-09-24 Thread Dave Allan
I've been looking at implementing a libudev backed node device, and I 
noticed that the devicekit node device backend doesn't build.  Since I 
believe DeviceKit is deprecated for this sort of use, and AFAIK the 
DeviceKit support was never functionally equivalent to the HAL support, 
I'm wondering if we can just drop DeviceKit support.  It also drags in 
glib, which is a separate problem.  Opinions?


Dave

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


Re: [libvirt] 0.7.1 compile fails on opensuse 11.1

2009-09-24 Thread Jim Fehlig
Pritesh Kothari wrote:
 it seems openSuSE 11.1 does not come with a pkgconfig for the
 device-mapper-devel package. I created a bug [1] for opensuse but was
 also told to mention it here so configure.in could be patched once the
 bug was fixed.
 

 Hi All,

 Just fixed this for ubuntu (should work now for suse as well) with some help 
 from danpb and DV.

 The patch is attached below.
   

ACK to this patch btw, it does solve the problem in SuSE distros where
device-mapper-devel is missing pkgconfig file.  But the problem is
really a bug in the devel package, so will this workaround be committed
to libvirt configure script?

Thanks,
Jim

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


Re: [libvirt] PATCH] Stop double free

2009-09-24 Thread Mark Hamzy

The stack trace is as follows:

Program received signal SIGABRT, Aborted.
0x0035ad830265 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x0035ad830265 in raise () from /lib64/libc.so.6
#1  0x0035ad831d10 in abort () from /lib64/libc.so.6
#2  0x0035ad86a84b in __libc_message () from /lib64/libc.so.6
#3  0x0035ad8722ef in _int_free () from /lib64/libc.so.6.
#4  0x0035ad87273b in free () from /lib64/libc.so.6.
#5  0x00406771 in vshDeinit (ctl=0x7fffd35d35e0) at virsh.c:8244
#6  0x004069a5 in vshError (ctl=0x7fffd35d35e0, doexit=value
optimized out, format=0x414f66 %s) at virsh.c:7861
#7  0x004067c4 in vshDeinit (ctl=0x7fffd35d35e0) at virsh.c:8248
#8  0x0041335e in main (argc=3, argv=0x7fffd35d3748) at
virsh.c:8493

I am trying to run libvirt-0.7.1-0.1.git3ef2e05.fc12.src.rpm on RHEL5.4.

vshDeinit gets called twice, so ctl-name is freed twice.

How about this patch then?

(See attached file: 0001-Fix-possible-double-free.patch)

--
Mark

You must be the change you wish to see in the world. -- Mahatma Gandhi
Worrying is praying for that you do not wish to happen.


   
 Chris Lalancette  
 clala...@redhat. 
 com   To
   Mark Hamzy/Austin/i...@ibmus 
 09/16/2009 06:30   cc
 AMlibvir-list@redhat.com  
   Subject
   Re: [libvirt] PATCH] Stop double
   free
   
   
   
   
   
   




Mark Hamzy wrote:
 diff --git a/src/virsh.c b/src/virsh.c
 index 4825f1c..5fc6c8f 100644
 --- a/src/virsh.c
 +++ b/src/virsh.c
 @@ -8201,7 +8201,7 @@ vshError(vshControl *ctl, int doexit, const char
 *format, ...)
 fputc('\n', stderr);

 if (doexit) {
 - if (ctl)
 + if (ctl  ctl-conn)
 vshDeinit(ctl);
 exit(EXIT_FAILURE);
 }

I don't think this patch is right.  vshDeinit() already has a check for
ctl-conn, and if you put it higher up in the call chain like this, you'll
leak
the ctl-name memory and the ctrl-log_fd file descriptors.  Do you have a
stack
trace with line numbers in it (i.e. debugging information)?  Also, what
version
of libvirt are you using?  That might shed a bit more light on what the
problem is.

--
Chris Lalancette
inline: graycol.gifinline: pic31299.gifinline: ecblank.gif

0001-Fix-possible-double-free.patch
Description: Binary data
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] Remove hand-crafted UUID parsers

2009-09-24 Thread Matthias Bolte
2009/9/24 Daniel P. Berrange berra...@redhat.com:
 * src/libvirt.c: Remove hand-crafted UUID parsers in favour of
  calling virParseUUID

s/virParseUUID/virUUIDParse/

 ---
  src/libvirt.c |   56 +---
  1 files changed, 5 insertions(+), 51 deletions(-)

 diff --git a/src/libvirt.c b/src/libvirt.c
 index 9fb0617..74d62a4 100644
 --- a/src/libvirt.c
 +++ b/src/libvirt.c
 @@ -1839,26 +1839,11 @@ virDomainLookupByUUIDString(virConnectPtr conn, const 
 char *uuidstr)
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         goto error;
     }
 -    /* XXX: sexpr_uuid() also supports '---' format.
 -     *      We needn't it here. Right?
 -     */
 -    ret = sscanf(uuidstr,
 -                 %02x%02x%02x%02x-
 -                 %02x%02x-
 -                 %02x%02x-
 -                 %02x%02x-
 -                 %02x%02x%02x%02x%02x%02x,
 -                 raw + 0, raw + 1, raw + 2, raw + 3,
 -                 raw + 4, raw + 5, raw + 6, raw + 7,
 -                 raw + 8, raw + 9, raw + 10, raw + 11,
 -                 raw + 12, raw + 13, raw + 14, raw + 15);
 -
 -    if (ret!=VIR_UUID_BUFLEN) {
 +
 +    if (virUUIDParse(uuidstr, uuid)  0) {
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         goto error;
     }
 -    for (i = 0; i  VIR_UUID_BUFLEN; i++)
 -        uuid[i] = raw[i]  0xFF;

     return virDomainLookupByUUID(conn, uuid[0]);

 @@ -5038,26 +5023,10 @@ virNetworkLookupByUUIDString(virConnectPtr conn, 
 const char *uuidstr)
         goto error;
     }

 -    /* XXX: sexpr_uuid() also supports '---' format.
 -     *      We needn't it here. Right?
 -     */
 -    ret = sscanf(uuidstr,
 -                 %02x%02x%02x%02x-
 -                 %02x%02x-
 -                 %02x%02x-
 -                 %02x%02x-
 -                 %02x%02x%02x%02x%02x%02x,
 -                 raw + 0, raw + 1, raw + 2, raw + 3,
 -                 raw + 4, raw + 5, raw + 6, raw + 7,
 -                 raw + 8, raw + 9, raw + 10, raw + 11,
 -                 raw + 12, raw + 13, raw + 14, raw + 15);
 -
 -    if (ret!=VIR_UUID_BUFLEN) {
 +    if (virUUIDParse(uuidstr, uuid)  0) {
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         goto error;
     }
 -    for (i = 0; i  VIR_UUID_BUFLEN; i++)
 -        uuid[i] = raw[i]  0xFF;

     return virNetworkLookupByUUID(conn, uuid[0]);

 @@ -8887,26 +8856,11 @@ virSecretLookupByUUIDString(virConnectPtr conn, const 
 char *uuidstr)
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         goto error;
     }
 -    /* XXX: sexpr_uuid() also supports '---' format.
 -     *      We needn't it here. Right?
 -     */
 -    ret = sscanf(uuidstr,
 -                 %02x%02x%02x%02x-
 -                 %02x%02x-
 -                 %02x%02x-
 -                 %02x%02x-
 -                 %02x%02x%02x%02x%02x%02x,
 -                 raw + 0, raw + 1, raw + 2, raw + 3,
 -                 raw + 4, raw + 5, raw + 6, raw + 7,
 -                 raw + 8, raw + 9, raw + 10, raw + 11,
 -                 raw + 12, raw + 13, raw + 14, raw + 15);
 -
 -    if (ret!=VIR_UUID_BUFLEN) {
 +
 +    if (virUUIDParse(uuidstr, uuid)  0) {
         virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         goto error;
     }
 -    for (i = 0; i  VIR_UUID_BUFLEN; i++)
 -        uuid[i] = raw[i]  0xFF;

     return virSecretLookupByUUID(conn, uuid[0]);

 --
 1.6.2.5


You removed the usage of raw, i and ret in this 3 functions, but
forgot to remove the variable definitions as well.

ACK, beside the two comments.

Matthias

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


Re: [libvirt] [PATCH 2/9] Extend disk element with controller information

2009-09-24 Thread Matthias Bolte
2009/9/24 Daniel P. Berrange berra...@redhat.com:

 Outside the scope of your patches, I think it would be
 worth adding a 'name' attribute to all devices in the
 libvirt XML as a standardized unique identifier. We
 already have to keep track of a 'name' internally for
 NIC hotplug with QEMU, and with QEMU's qdev work we're
 going to end up having to track a 'name' for pretty much
 all devices. Thus we might as well expose it in the XML


Would this device name be read-only, or would it be editable/writable
by the user (e.g. through virsh edit)? If it should be read-only, I
see no problem supporting device names in the ESX driver. But If it
should be editable/writable it may be a problem to implement this for
the ESX driver, as I'm currently not aware of any sensible way to
store such an custom device name in a persistent manner on an ESX
server.

Matthias

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


Re: [libvirt] Some problem with the save function

2009-09-24 Thread Paolo Bonzini

On 09/18/2009 03:09 AM, Charles Duffy wrote:

Daniel P. Berrange wrote:

Hmm, bad error message :-( We might also need todo a chown()
in the restore path to allow QEMU to read it. NB there is no
compatability between QEMU version, so if you have upgraded
your install of QEMU between the time you saved  restored
it is very likely to crash  burn.


How difficult would it be to set up named pipes for save and restore
operations, and splice from those pipes to the actual files on the
libvirtd side? Seems much preferable from a security perspective to
chown'ing things around, and (unlike pipes set up ahead of time with
pipe() and friends) shouldn't be disrupted by a libvirtd restart.


For a recent enough QEMU, you could also use the 
migrate-to-file-descriptor functionality which uses SCM_RIGHTS.  It is 
in QEMU 0.12 only, but since the plumbing is in 0.11 too we could ask 
for a backport.


Paolo

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