Re: [libvirt] [RFC v1 4/6] migration: Migration support for ephemeral hostdevs

2015-05-13 Thread Chen Fan


On 05/13/2015 04:36 PM, Peter Krempa wrote:

On Wed, May 13, 2015 at 11:36:30 +0800, Chen Fan wrote:

add migration support for ephemeral host devices, introduce
two 'detach' and 'restore' functions to unplug/plug host devices
during migration.

Signed-off-by: Chen Fan 
---
  src/qemu/qemu_migration.c | 171 --
  src/qemu/qemu_migration.h |   9 +++
  src/qemu/qemu_process.c   |  11 +++
  3 files changed, 187 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 56112f9..d5a698f 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3384,6 +3384,158 @@ qemuMigrationPrepareDef(virQEMUDriverPtr driver,
  return def;
  }
  
+int

+qemuMigrationDetachEphemeralDevices(virQEMUDriverPtr driver,
+virDomainObjPtr vm,
+bool live)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virDomainHostdevDefPtr hostdev;
+virDomainNetDefPtr net;
+virDomainDeviceDef dev;
+virDomainDeviceDefPtr dev_copy = NULL;
+virCapsPtr caps = NULL;
+int actualType;
+int ret = -1;
+size_t i;
+
+VIR_DEBUG("Rum domain detach ephemeral devices");
+
+if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+return ret;
+
+for (i = 0; i < vm->def->nnets;) {
+net = vm->def->nets[i];
+
+actualType = virDomainNetGetActualType(net);
+if (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+i++;
+continue;
+}
+
+hostdev = virDomainNetGetActualHostdev(net);
+if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
+hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI 
||
+!hostdev->ephemeral) {
+i++;
+continue;
+}
+
+dev.type = VIR_DOMAIN_DEVICE_NET;
+dev.data.net = net;
+
+dev_copy = virDomainDeviceDefCopy(&dev, vm->def,
+  caps, driver->xmlopt);
+if (!dev_copy)
+goto cleanup;
+
+if (live) {
+/* nnets reduced */
+if (qemuDomainDetachNetDevice(driver, vm, dev_copy) < 0)
+goto cleanup;

So this is where the fun begins. qemuDomainDetachNetDevice is not
designed to be called this way since the detach API where it's used
normally returns 0 in the following two cases:

1) The detach was successfull, the guest removed the device
2) The detach request was successful, but guest did not remove the
device yet

In the latter case you need to wait for a event to successfully know
when the device was removed. Since this might very well happen the code
will need to be changed to take that option into account. Please note
that that step will make all the things really complicated.


did you said the event is "DEVICE_DELETED" ?
I saw the code  the funcition qemuDomainWaitForDeviceRemoval
has been used for waiting device removed from guest.

Thanks,
Chen




Peter



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


Re: [libvirt] [RFC v1 4/6] migration: Migration support for ephemeral hostdevs

2015-05-13 Thread Chen Fan


On 05/13/2015 10:30 PM, Laine Stump wrote:

On 05/13/2015 05:57 AM, Daniel P. Berrange wrote:

On Wed, May 13, 2015 at 11:36:30AM +0800, Chen Fan wrote:

add migration support for ephemeral host devices, introduce
two 'detach' and 'restore' functions to unplug/plug host devices
during migration.

Signed-off-by: Chen Fan 
---
  src/qemu/qemu_migration.c | 171 --
  src/qemu/qemu_migration.h |   9 +++
  src/qemu/qemu_process.c   |  11 +++
  3 files changed, 187 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 56112f9..d5a698f 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
+void
+qemuMigrationRestoreEphemeralDevices(virQEMUDriverPtr driver,
+ virConnectPtr conn,
+ virDomainObjPtr vm,
+ bool live)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virDomainDeviceDefPtr dev;
+int ret = -1;
+size_t i;
+
+VIR_DEBUG("Rum domain restore ephemeral devices");
+
+for (i = 0; i < priv->nEphemeralDevices; i++) {
+dev = priv->ephemeralDevices[i];
+
+switch ((virDomainDeviceType) dev->type) {
+case VIR_DOMAIN_DEVICE_NET:
+if (live) {
+ret = qemuDomainAttachNetDevice(conn, driver, vm,
+dev->data.net);
+} else {
+ret = virDomainNetInsert(vm->def, dev->data.net);
+}
+
+if (!ret)
+dev->data.net = NULL;
+break;
+case VIR_DOMAIN_DEVICE_HOSTDEV:
+if (live) {
+ret = qemuDomainAttachHostDevice(conn, driver, vm,
+ dev->data.hostdev);
+   } else {
+ret =virDomainHostdevInsert(vm->def, dev->data.hostdev);
+}

This re-attach step is where we actually have far far far worse problems
than with detach. This is blindly assuming that the guest on the target
host can use the same hostdev that it was using on the source host.

(kind of pointless to comment on, since pkrempa has changed my opinion
by forcing me to think about the "failure to reattach" condition, but
could be useful info for others)

For a , yes, but not for  (which
would point to a libvirt network pool of VFs).


This
is essentially useless in the real world.

Agreed (for plain )


Even if the same vendor/model
device is available on the target host, it is very unlikely to be available
at the same bus/slot/function that it was on the source. It is quite likely
neccessary to allocate a complete different NIC, or if using SRIOV allocate
a different function. It is also not uncommon to have different vendor/models,
so a completely different NIC may be required.

In the case of a network device, a different brand/model of NIC at a
different PCI address using a different guest driver shouldn't be a
problem for the guest, as long as the MAC address is the same (for a
Linux guest anyway; not sure what a Windows guest would do with a NIC
that had the same MAC but used a different driver). This points out the
folly of trying to do migration with attached hostdevs (managed at *any*
level), for anything other than SRIOV VFs (which can have their MAC
address set before attach, unlike non-SRIOV NICs).

.
So should we focus on implementing the feature that support migration 
with SRIOV

VFs at first?

I think that is simple to achieve my original target that implement NIC 
passthrough
device migration. because sometimes we assign a native NIC to guest to 
keep the
performance of network I/O, due to the MAC limitation of the non-SRIOV 
NICs, as

laine said the cost of SRIOV NIC is cheaper than what we try.

Thanks,
Chen


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


Re: [libvirt] [RFC v1 3/6] qemu: add check ephemeral devices only for PCI host devices

2015-05-13 Thread Chen Fan


On 05/13/2015 04:17 PM, Peter Krempa wrote:

On Wed, May 13, 2015 at 11:36:29 +0800, Chen Fan wrote:

currently, we only support PCI host devices with ephemeral flag.
and USB already supports migration. so maybe in the near future we
can support SCSI.

Signed-off-by: Chen Fan 
---
  src/qemu/qemu_command.c   | 10 ++
  src/qemu/qemu_migration.c | 11 +++
  2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index fc81214..5acd8b4 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10182,6 +10182,16 @@ qemuBuildCommandLine(virConnectPtr conn,
  
  /* PCI */

  if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB 
&&
+(hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI 
&&
+ hostdev->ephemeral)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("non-USB and non-PCI device assignment with ephemeral 
"
+ "flag are not supported by this version of 
qemu"));

This functionality is not based on qemu support but on libvirt
implementation so the error message is incorrect.

indeed.

thanks for pointing out this.

Chen

+goto error;
+}
+
+if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
  hostdev->source.subsys.type == 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
  int backend = hostdev->source.subsys.u.pci.backend;
  
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c

index 83be435..56112f9 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1981,21 +1981,24 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, 
virDomainObjPtr vm,
  def = vm->def;
  }
  
-/* Migration with USB host devices is allowed, all other devices are

- * forbidden.
+/*
+ * Migration with USB and ephemeral PCI host devices host devices are 
allowed,
+ * all other devices are forbidden.
   */
  forbid = false;
  for (i = 0; i < def->nhostdevs; i++) {
  virDomainHostdevDefPtr hostdev = def->hostdevs[i];
  if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
-hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) 
{
+(hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB 
&&
+!hostdev->ephemeral)) {
  forbid = true;
  break;
  }
  }
  if (forbid) {
  virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-   _("domain has assigned non-USB host devices"));
+   _("domain has assigned non-USB and "
+ "non-ephemeral host devices"));
  return false;
  }

This patch has to be moved after you actually implement the ephemeral
device unplug code, since an intermediate state would allow to bypass
the check while the devices actually would not be unplugged.

Peter


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


[libvirt] [RFC v1 0/6] Live Migration with ephemeral host NIC devices

2015-05-12 Thread Chen Fan
my main goal is to add support migration with host NIC
passthrough devices and keep the network connectivity.

this series patch base on Shradha's patches on
https://www.redhat.com/archives/libvir-list/2012-November/msg01324.html
which is add migration support for host passthrough devices.

 1) unplug the ephemeral devices before migration

 2) do native migration

 3) when migration finished, hotplug the ephemeral devices


TODO:
  keep network connectivity on guest level by bonding device.

Chen Fan (6):
  conf: add ephemeral element for hostdev supporting migration
  qemu: Save ephemeral devices into qemuDomainObjPrivate
  qemu: add check ephemeral devices only for PCI host devices
  migration: Migration support for ephemeral hostdevs
  managedsave: move the domain xml handling forward to stop CPU
  managedsave: add managedsave support for ephemeral host devices

 docs/schemas/domaincommon.rng  |  10 ++
 docs/schemas/network.rng   |   5 +
 src/conf/domain_conf.c |  14 +-
 src/conf/domain_conf.h |   1 +
 src/conf/network_conf.c|  13 ++
 src/conf/network_conf.h|   1 +
 src/network/bridge_driver.c|   1 +
 src/qemu/qemu_command.c|  11 ++
 src/qemu/qemu_domain.c |   5 +
 src/qemu/qemu_domain.h |   3 +
 src/qemu/qemu_driver.c |  48 +++---
 src/qemu/qemu_migration.c  | 182 -
 src/qemu/qemu_migration.h  |   9 +
 src/qemu/qemu_process.c|  12 ++
 tests/networkxml2xmlin/hostdev-pf.xml  |   2 +-
 tests/networkxml2xmlin/hostdev.xml |   2 +-
 tests/networkxml2xmlout/hostdev-pf.xml |   2 +-
 tests/networkxml2xmlout/hostdev.xml|   2 +-
 .../qemuxml2argv-controller-order.xml  |   2 +-
 .../qemuxml2argv-hostdev-pci-address-device.xml|   2 +-
 .../qemuxml2argv-hostdev-pci-address.xml   |   2 +-
 .../qemuxml2argv-hostdev-scsi-autogen-address.xml  |  22 +--
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.xml   |   4 +-
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi.xml|   4 +-
 .../qemuxml2argv-hostdev-scsi-lsi.xml  |   2 +-
 .../qemuxml2argv-hostdev-scsi-rawio.xml|   2 +-
 .../qemuxml2argv-hostdev-scsi-readonly.xml |   2 +-
 .../qemuxml2argv-hostdev-scsi-sgio.xml |   2 +-
 .../qemuxml2argv-hostdev-scsi-shareable.xml|   2 +-
 ...qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.xml |   4 +-
 .../qemuxml2argv-hostdev-scsi-virtio-iscsi.xml |   4 +-
 .../qemuxml2argv-hostdev-scsi-virtio-scsi.xml  |   2 +-
 ...emuxml2argv-hostdev-usb-address-device-boot.xml |   2 +-
 .../qemuxml2argv-hostdev-usb-address-device.xml|   2 +-
 .../qemuxml2argv-hostdev-usb-address.xml   |   2 +-
 .../qemuxml2argv-hostdev-vfio-multidomain.xml  |   2 +-
 .../qemuxml2argvdata/qemuxml2argv-hostdev-vfio.xml |   2 +-
 .../qemuxml2argv-net-hostdev-multidomain.xml   |   2 +-
 .../qemuxml2argv-net-hostdev-vfio-multidomain.xml  |   2 +-
 .../qemuxml2argv-net-hostdev-vfio.xml  |   2 +-
 .../qemuxml2argvdata/qemuxml2argv-net-hostdev.xml  |   2 +-
 tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml|   4 +-
 ...qemuxml2xmlout-hostdev-scsi-autogen-address.xml |  22 +--
 43 files changed, 340 insertions(+), 83 deletions(-)

-- 
1.9.3

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


[libvirt] [RFC v1 1/6] conf: add ephemeral element for hostdev supporting migration

2015-05-12 Thread Chen Fan
the ephemeral flag helps support migration with PCI-passthrough.
An ephemeral hostdev is automatically unplugged before migration
and replugged (if one is available on the destination) after
migration.

Signed-off-by: Chen Fan 
---
 docs/schemas/domaincommon.rng  | 10 ++
 docs/schemas/network.rng   |  5 +
 src/conf/domain_conf.c | 14 +-
 src/conf/domain_conf.h |  1 +
 src/conf/network_conf.c| 13 +
 src/conf/network_conf.h|  1 +
 src/network/bridge_driver.c|  1 +
 src/qemu/qemu_command.c|  1 +
 tests/networkxml2xmlin/hostdev-pf.xml  |  2 +-
 tests/networkxml2xmlin/hostdev.xml |  2 +-
 tests/networkxml2xmlout/hostdev-pf.xml |  2 +-
 tests/networkxml2xmlout/hostdev.xml|  2 +-
 .../qemuxml2argv-controller-order.xml  |  2 +-
 .../qemuxml2argv-hostdev-pci-address-device.xml|  2 +-
 .../qemuxml2argv-hostdev-pci-address.xml   |  2 +-
 .../qemuxml2argv-hostdev-scsi-autogen-address.xml  | 22 +++---
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.xml   |  4 ++--
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi.xml|  4 ++--
 .../qemuxml2argv-hostdev-scsi-lsi.xml  |  2 +-
 .../qemuxml2argv-hostdev-scsi-rawio.xml|  2 +-
 .../qemuxml2argv-hostdev-scsi-readonly.xml |  2 +-
 .../qemuxml2argv-hostdev-scsi-sgio.xml |  2 +-
 .../qemuxml2argv-hostdev-scsi-shareable.xml|  2 +-
 ...qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.xml |  4 ++--
 .../qemuxml2argv-hostdev-scsi-virtio-iscsi.xml |  4 ++--
 .../qemuxml2argv-hostdev-scsi-virtio-scsi.xml  |  2 +-
 ...emuxml2argv-hostdev-usb-address-device-boot.xml |  2 +-
 .../qemuxml2argv-hostdev-usb-address-device.xml|  2 +-
 .../qemuxml2argv-hostdev-usb-address.xml   |  2 +-
 .../qemuxml2argv-hostdev-vfio-multidomain.xml  |  2 +-
 .../qemuxml2argvdata/qemuxml2argv-hostdev-vfio.xml |  2 +-
 .../qemuxml2argv-net-hostdev-multidomain.xml   |  2 +-
 .../qemuxml2argv-net-hostdev-vfio-multidomain.xml  |  2 +-
 .../qemuxml2argv-net-hostdev-vfio.xml  |  2 +-
 .../qemuxml2argvdata/qemuxml2argv-net-hostdev.xml  |  2 +-
 tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml|  4 ++--
 ...qemuxml2xmlout-hostdev-scsi-autogen-address.xml | 22 +++---
 37 files changed, 99 insertions(+), 55 deletions(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index b1d883f..6f4551c 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2261,6 +2261,11 @@
   
 
   
+  
+
+  
+
+  
   
 
   
@@ -3717,6 +3722,11 @@
 
   
 
+
+  
+
+  
+
 
   
   
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 4edb6eb..d63b066 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -115,6 +115,11 @@
 
   
 
+
+  
+
+  
+
 
   
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3d05844..a1a0602 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4823,6 +4823,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
 {
 xmlNodePtr sourcenode;
 char *managed = NULL;
+char *ephemeral = NULL;
 char *sgio = NULL;
 char *rawio = NULL;
 char *backendStr = NULL;
@@ -4841,6 +4842,11 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
 def->managed = true;
 }
 
+if ((ephemeral = virXMLPropString(node, "ephemeral")) != NULL) {
+if (STREQ(ephemeral, "yes"))
+def->ephemeral = true;
+}
+
 sgio = virXMLPropString(node, "sgio");
 rawio = virXMLPropString(node, "rawio");
 
@@ -18064,8 +18070,10 @@ virDomainActualNetDefFormat(virBufferPtr buf,
 virBufferAsprintf(buf, "managed)
+if (hostdef && hostdef->managed)
 virBufferAddLit(buf, " managed='yes'");
+if (hostdef && hostdef->ephemeral)
+virBufferAddLit(buf, " ephemeral='yes'");
 }
 if (def->trustGuestRxFilters)
 virBufferAsprintf(buf, " trustGuestRxFilters='%s'",
@@ -18236,6 +18244,8 @@ virDomainNetDefFormat(virBufferPtr buf,
 virBufferAsprintf(buf, "managed)
 virBufferAddLit(buf, " managed='yes'");
+if (hostdef && hostdef->ephemeral)
+virBufferAddLit(buf, " ephemeral='yes'");
 if 

[libvirt] [RFC v1 5/6] managedsave: move the domain xml handling forward to stop CPU

2015-05-12 Thread Chen Fan
we should save the XML information to image head before we
hotunplug the ephemeral devices. so here we handle XML
ahead.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_driver.c | 40 
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b3263ac..86d93d2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3179,26 +3179,6 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, 
virDomainPtr dom,
 
 priv->job.current->type = VIR_DOMAIN_JOB_UNBOUNDED;
 
-/* Pause */
-if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
-was_running = true;
-if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_SAVE,
-QEMU_ASYNC_JOB_SAVE) < 0)
-goto endjob;
-
-if (!virDomainObjIsActive(vm)) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("guest unexpectedly quit"));
-goto endjob;
-}
-}
-
-   /* libvirt.c already guaranteed these two flags are exclusive.  */
-if (flags & VIR_DOMAIN_SAVE_RUNNING)
-was_running = true;
-else if (flags & VIR_DOMAIN_SAVE_PAUSED)
-was_running = false;
-
 /* Get XML for the domain.  Restore needs only the inactive xml,
  * including secure.  We should get the same result whether xmlin
  * is NULL or whether it was the live xml of the domain moments
@@ -3225,6 +3205,26 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, 
virDomainPtr dom,
 goto endjob;
 }
 
+/* Pause */
+if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
+was_running = true;
+if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_SAVE,
+QEMU_ASYNC_JOB_SAVE) < 0)
+goto endjob;
+
+if (!virDomainObjIsActive(vm)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("guest unexpectedly quit"));
+goto endjob;
+}
+}
+
+   /* libvirt.c already guaranteed these two flags are exclusive.  */
+if (flags & VIR_DOMAIN_SAVE_RUNNING)
+was_running = true;
+else if (flags & VIR_DOMAIN_SAVE_PAUSED)
+was_running = false;
+
 ret = qemuDomainSaveMemory(driver, vm, path, xml, compressed,
was_running, flags, QEMU_ASYNC_JOB_SAVE);
 if (ret < 0)
-- 
1.9.3

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


[libvirt] [RFC v1 4/6] migration: Migration support for ephemeral hostdevs

2015-05-12 Thread Chen Fan
add migration support for ephemeral host devices, introduce
two 'detach' and 'restore' functions to unplug/plug host devices
during migration.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_migration.c | 171 --
 src/qemu/qemu_migration.h |   9 +++
 src/qemu/qemu_process.c   |  11 +++
 3 files changed, 187 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 56112f9..d5a698f 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3384,6 +3384,158 @@ qemuMigrationPrepareDef(virQEMUDriverPtr driver,
 return def;
 }
 
+int
+qemuMigrationDetachEphemeralDevices(virQEMUDriverPtr driver,
+virDomainObjPtr vm,
+bool live)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virDomainHostdevDefPtr hostdev;
+virDomainNetDefPtr net;
+virDomainDeviceDef dev;
+virDomainDeviceDefPtr dev_copy = NULL;
+virCapsPtr caps = NULL;
+int actualType;
+int ret = -1;
+size_t i;
+
+VIR_DEBUG("Rum domain detach ephemeral devices");
+
+if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+return ret;
+
+for (i = 0; i < vm->def->nnets;) {
+net = vm->def->nets[i];
+
+actualType = virDomainNetGetActualType(net);
+if (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+i++;
+continue;
+}
+
+hostdev = virDomainNetGetActualHostdev(net);
+if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
+hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI 
||
+!hostdev->ephemeral) {
+i++;
+continue;
+}
+
+dev.type = VIR_DOMAIN_DEVICE_NET;
+dev.data.net = net;
+
+dev_copy = virDomainDeviceDefCopy(&dev, vm->def,
+  caps, driver->xmlopt);
+if (!dev_copy)
+goto cleanup;
+
+if (live) {
+/* nnets reduced */
+if (qemuDomainDetachNetDevice(driver, vm, dev_copy) < 0)
+goto cleanup;
+} else {
+virDomainNetDefFree(virDomainNetRemove(vm->def, i));
+}
+if (VIR_APPEND_ELEMENT(priv->ephemeralDevices,
+   priv->nEphemeralDevices,
+   dev_copy) < 0) {
+goto cleanup;
+}
+dev_copy = NULL;
+}
+
+for (i = 0; i < vm->def->nhostdevs;) {
+hostdev = vm->def->hostdevs[i];
+
+if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
+hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI 
||
+!hostdev->ephemeral) {
+i++;
+continue;
+}
+
+dev.type = VIR_DOMAIN_DEVICE_HOSTDEV;
+dev.data.hostdev = hostdev;
+
+VIR_FREE(dev_copy);
+dev_copy = virDomainDeviceDefCopy(&dev, vm->def,
+  caps, driver->xmlopt);
+if (!dev_copy)
+goto cleanup;
+
+if (live) {
+/* nhostdevs reduced */
+if (qemuDomainDetachHostDevice(driver, vm, dev_copy) < 0)
+goto cleanup;
+} else {
+virDomainHostdevDefFree(virDomainHostdevRemove(vm->def, i));
+}
+if (VIR_APPEND_ELEMENT(priv->ephemeralDevices,
+   priv->nEphemeralDevices,
+   dev_copy) < 0) {
+goto cleanup;
+}
+dev_copy = NULL;
+}
+
+ret = 0;
+ cleanup:
+virDomainDeviceDefFree(dev_copy);
+virObjectUnref(caps);
+
+return ret;
+}
+
+void
+qemuMigrationRestoreEphemeralDevices(virQEMUDriverPtr driver,
+ virConnectPtr conn,
+ virDomainObjPtr vm,
+ bool live)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virDomainDeviceDefPtr dev;
+int ret = -1;
+size_t i;
+
+VIR_DEBUG("Rum domain restore ephemeral devices");
+
+for (i = 0; i < priv->nEphemeralDevices; i++) {
+dev = priv->ephemeralDevices[i];
+
+switch ((virDomainDeviceType) dev->type) {
+case VIR_DOMAIN_DEVICE_NET:
+if (live) {
+ret = qemuDomainAttachNetDevice(conn, driver, vm,
+dev->data.net);
+} else {
+ret = virDomainNetInsert(vm->def, dev->data.net);
+}
+
+if (!ret)
+dev->data.net = NULL;
+break;
+case VIR_DOMAIN_DEVICE_HOSTDEV:
+if (live) {
+ret = qemuDomainAttachHostDevice(conn, driver

[libvirt] [RFC v1 3/6] qemu: add check ephemeral devices only for PCI host devices

2015-05-12 Thread Chen Fan
currently, we only support PCI host devices with ephemeral flag.
and USB already supports migration. so maybe in the near future we
can support SCSI.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_command.c   | 10 ++
 src/qemu/qemu_migration.c | 11 +++
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index fc81214..5acd8b4 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10182,6 +10182,16 @@ qemuBuildCommandLine(virConnectPtr conn,
 
 /* PCI */
 if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB 
&&
+(hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI 
&&
+ hostdev->ephemeral)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("non-USB and non-PCI device assignment with 
ephemeral "
+ "flag are not supported by this version of 
qemu"));
+goto error;
+}
+
+if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
 hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) 
{
 int backend = hostdev->source.subsys.u.pci.backend;
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 83be435..56112f9 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1981,21 +1981,24 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, 
virDomainObjPtr vm,
 def = vm->def;
 }
 
-/* Migration with USB host devices is allowed, all other devices are
- * forbidden.
+/*
+ * Migration with USB and ephemeral PCI host devices host devices are 
allowed,
+ * all other devices are forbidden.
  */
 forbid = false;
 for (i = 0; i < def->nhostdevs; i++) {
 virDomainHostdevDefPtr hostdev = def->hostdevs[i];
 if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
-hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) 
{
+(hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB 
&&
+!hostdev->ephemeral)) {
 forbid = true;
 break;
 }
 }
 if (forbid) {
 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-   _("domain has assigned non-USB host devices"));
+   _("domain has assigned non-USB and "
+ "non-ephemeral host devices"));
 return false;
 }
 
-- 
1.9.3

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


[libvirt] [RFC v1 6/6] managedsave: add managedsave support for ephemeral host devices

2015-05-12 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/qemu/qemu_driver.c  | 8 
 src/qemu/qemu_process.c | 3 ++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 86d93d2..112acb1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3208,6 +3208,10 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, 
virDomainPtr dom,
 /* Pause */
 if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
 was_running = true;
+/* Detach ephemeral host devices first */
+if (qemuMigrationDetachEphemeralDevices(driver, vm, true) < 0)
+goto endjob;
+
 if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_SAVE,
 QEMU_ASYNC_JOB_SAVE) < 0)
 goto endjob;
@@ -3249,6 +3253,8 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, 
virDomainPtr dom,
   
VIR_DOMAIN_EVENT_SUSPENDED,
   
VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR);
 }
+qemuMigrationRestoreEphemeralDevices(driver, dom->conn, vm, true);
+
 virSetError(save_err);
 virFreeError(save_err);
 }
@@ -6404,6 +6410,8 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
 if (event)
 qemuDomainEventQueue(driver, event);
 
+/* Restore ephemeral devices */
+qemuMigrationRestoreEphemeralDevices(driver, NULL, vm, true);
 
 /* If it was running before, resume it now unless caller requested pause. 
*/
 if (header->was_running && !start_paused) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 904c447..6519477 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4501,7 +4501,8 @@ int qemuProcessStart(virConnectPtr conn,
  * during migration. hence we should remove the reserved
  * PCI address for ephemeral device.
  */
-if (vmop == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START)
+if (vmop == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START ||
+vmop == VIR_NETDEV_VPORT_PROFILE_OP_RESTORE)
 if (qemuMigrationDetachEphemeralDevices(driver, vm, false) < 0)
 goto cleanup;
 
-- 
1.9.3

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


[libvirt] [RFC v1 2/6] qemu: Save ephemeral devices into qemuDomainObjPrivate

2015-05-12 Thread Chen Fan
after migration we should restore the ephemeral devices.
so we save them to qemuDomainObjPrivate.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_domain.c | 5 +
 src/qemu/qemu_domain.h | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d8a2087..5ce933d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -425,6 +425,7 @@ static void
 qemuDomainObjPrivateFree(void *data)
 {
 qemuDomainObjPrivatePtr priv = data;
+size_t i;
 
 virObjectUnref(priv->qemuCaps);
 
@@ -441,6 +442,10 @@ qemuDomainObjPrivateFree(void *data)
 virCondDestroy(&priv->unplugFinished);
 virChrdevFree(priv->devs);
 
+for (i = 0; i < priv->nEphemeralDevices; i++)
+virDomainDeviceDefFree(priv->ephemeralDevices[i]);
+VIR_FREE(priv->ephemeralDevices);
+
 /* This should never be non-NULL if we get here, but just in case... */
 if (priv->mon) {
 VIR_ERROR(_("Unexpected QEMU monitor still active during domain 
deletion"));
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index fe3e2b1..e75c828 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -180,6 +180,9 @@ struct _qemuDomainObjPrivate {
 size_t ncleanupCallbacks;
 size_t ncleanupCallbacks_max;
 
+virDomainDeviceDefPtr *ephemeralDevices;
+size_t nEphemeralDevices;
+
 virCgroupPtr cgroup;
 
 virCond unplugFinished; /* signals that unpluggingDevice was unplugged */
-- 
1.9.3

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


Re: [libvirt] [RFC 0/7] Live Migration with Pass-through Devices proposal

2015-04-23 Thread Chen Fan


On 04/20/2015 06:29 AM, Laine Stump wrote:

On 04/17/2015 04:53 AM, Chen Fan wrote:

backgrond:
Live migration is one of the most important features of virtualization 
technology.
With regard to recent virtualization techniques, performance of network I/O is 
critical.
Current network I/O virtualization (e.g. Para-virtualized I/O, VMDq) has a 
significant
performance gap with native network I/O. Pass-through network devices have near
native performance, however, they have thus far prevented live migration. No 
existing
methods solve the problem of live migration with pass-through devices perfectly.

There was an idea to solve the problem in website:
https://www.kernel.org/doc/ols/2008/ols2008v2-pages-261-267.pdf
Please refer to above document for detailed information.

This functionality has been on my mind/bug list for a long time, but I
haven't been able to pursue it much. See this BZ, along with the
original patches submitted by Shradha Shah from SolarFlare:

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

(I was a bit optimistic in my initial review of the patches - there are
actually a lot of issues that weren't handled by those patches.)


So I think this problem maybe could be solved by using the combination of 
existing
technology. and the following steps are we considering to implement:

-  before boot VM, we anticipate to specify two NICs for creating bonding device
(one plugged and one virtual NIC) in XML. here we can specify the NIC's mac 
addresses
in XML, which could facilitate qemu-guest-agent to find the network 
interfaces in guest.

An interesting idea, but I think that is a 2nd level enhancement, not
necessary initially (and maybe not ever, due to the high possibility of
it being extremely difficult to get right in 100% of the cases).


-  when qemu-guest-agent startup in guest it would send a notification to 
libvirt,
then libvirt will call the previous registered initialize callbacks. so 
through
the callback functions, we can create the bonding device according to the 
XML
configuration. and here we use netcf tool which can facilitate to create 
bonding device
easily.

This isn't quite making sense - the bond will be on the guest, which may
not have netcf installed. Anyway, I think it should be up to the guest's
own system network config to have the bond already setup. If you try to
impose it from outside that infrastructure, you run too much risk of
running afoul of something on the guest (e.g. NetworkManager)



-  during migration, unplug the passthroughed NIC. then do native migration.

Correct. This is the most important part. But not just unplugging it,
you also need to wait until the unplug operation completes (it is
asynchronous). (After this point, the emulated NIC that is part of the
bond would get all of the traffic).


-  on destination side, check whether need to hotplug new NIC according to 
specified XML.
usually, we use migrate "--xml" command option to specify the destination 
host NIC mac
address to hotplug a new NIC, because source side passthrough NIC mac 
address is different,
then hotplug the deivce according to the destination XML configuration.

Why does the MAC address need to be different? Are you suggesting doing
this with passed-through non-SRIOV NICs? An SRIOV virtual function gets
its MAC address from the libvirt config, so it's very simple to use the
same MAC address across the migration. Any network card that would be
able to do this on any sort of useful scale will be SRIOV-capable (or
should be replaced with one that is - some of them are not that expensive).

Hi Laine,

I think SRIOV virtual NIC to support migration is good idea,
but I also think some passthrough NIC without SRIOV-capable. for
these NIC devices we only able to use  to specify the passthrough
function, so for these NIC I think we should support too.

Thanks,
Chen





TODO:
   1.  when hot add a new NIC in destination side after migration finished, the 
NIC device
   need to re-enslave on bonding device in guest. otherwise, it is offline. 
maybe
   we should consider bonding driver to support add interfaces dynamically.

I never looked at the details of how SolarFlare's code handled the guest
side (they have/had their own patchset they maintained for some older
version of libvirt which integrated with some sort of enhanced bonding
driver on the guests). I assumed the bond driver could handle this
already, but have to say I never investigated.



This is an example on how this might work, so I want to hear some voices about 
this scenario.

Thanks,
Chen

Chen Fan (7):
   qemu-agent: add agent init callback when detecting guest setup
   qemu: add guest init event callback to do the initialize work for
 guest
   hostdev: add a 'bond' type element in  element


Putting this into  is the wrong approach, for two reasons: 1)
it doesn't account for the device to be used being i

Re: [libvirt] [RFC 0/7] Live Migration with Pass-through Devices proposal

2015-04-21 Thread Chen Fan

Hi Laine,

Thanks for your review for my patches.

and do you know that solarflare's patches have made some update version
since

https://www.redhat.com/archives/libvir-list/2012-November/msg01324.html

?

if not, I hope to go on to complete this work. ;)

Thanks,
Chen


On 04/20/2015 06:29 AM, Laine Stump wrote:

On 04/17/2015 04:53 AM, Chen Fan wrote:

backgrond:
Live migration is one of the most important features of virtualization 
technology.
With regard to recent virtualization techniques, performance of network I/O is 
critical.
Current network I/O virtualization (e.g. Para-virtualized I/O, VMDq) has a 
significant
performance gap with native network I/O. Pass-through network devices have near
native performance, however, they have thus far prevented live migration. No 
existing
methods solve the problem of live migration with pass-through devices perfectly.

There was an idea to solve the problem in website:
https://www.kernel.org/doc/ols/2008/ols2008v2-pages-261-267.pdf
Please refer to above document for detailed information.

This functionality has been on my mind/bug list for a long time, but I
haven't been able to pursue it much. See this BZ, along with the
original patches submitted by Shradha Shah from SolarFlare:

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

(I was a bit optimistic in my initial review of the patches - there are
actually a lot of issues that weren't handled by those patches.)


So I think this problem maybe could be solved by using the combination of 
existing
technology. and the following steps are we considering to implement:

-  before boot VM, we anticipate to specify two NICs for creating bonding device
(one plugged and one virtual NIC) in XML. here we can specify the NIC's mac 
addresses
in XML, which could facilitate qemu-guest-agent to find the network 
interfaces in guest.

An interesting idea, but I think that is a 2nd level enhancement, not
necessary initially (and maybe not ever, due to the high possibility of
it being extremely difficult to get right in 100% of the cases).


-  when qemu-guest-agent startup in guest it would send a notification to 
libvirt,
then libvirt will call the previous registered initialize callbacks. so 
through
the callback functions, we can create the bonding device according to the 
XML
configuration. and here we use netcf tool which can facilitate to create 
bonding device
easily.

This isn't quite making sense - the bond will be on the guest, which may
not have netcf installed. Anyway, I think it should be up to the guest's
own system network config to have the bond already setup. If you try to
impose it from outside that infrastructure, you run too much risk of
running afoul of something on the guest (e.g. NetworkManager)



-  during migration, unplug the passthroughed NIC. then do native migration.

Correct. This is the most important part. But not just unplugging it,
you also need to wait until the unplug operation completes (it is
asynchronous). (After this point, the emulated NIC that is part of the
bond would get all of the traffic).


-  on destination side, check whether need to hotplug new NIC according to 
specified XML.
usually, we use migrate "--xml" command option to specify the destination 
host NIC mac
address to hotplug a new NIC, because source side passthrough NIC mac 
address is different,
then hotplug the deivce according to the destination XML configuration.

Why does the MAC address need to be different? Are you suggesting doing
this with passed-through non-SRIOV NICs? An SRIOV virtual function gets
its MAC address from the libvirt config, so it's very simple to use the
same MAC address across the migration. Any network card that would be
able to do this on any sort of useful scale will be SRIOV-capable (or
should be replaced with one that is - some of them are not that expensive).



TODO:
   1.  when hot add a new NIC in destination side after migration finished, the 
NIC device
   need to re-enslave on bonding device in guest. otherwise, it is offline. 
maybe
   we should consider bonding driver to support add interfaces dynamically.

I never looked at the details of how SolarFlare's code handled the guest
side (they have/had their own patchset they maintained for some older
version of libvirt which integrated with some sort of enhanced bonding
driver on the guests). I assumed the bond driver could handle this
already, but have to say I never investigated.



This is an example on how this might work, so I want to hear some voices about 
this scenario.

Thanks,
Chen

Chen Fan (7):
   qemu-agent: add agent init callback when detecting guest setup
   qemu: add guest init event callback to do the initialize work for
 guest
   hostdev: add a 'bond' type element in  element


Putting this into  is the wrong approach, for two reasons: 1)
it doesn't account for the device to be used being i

[libvirt] [RFC 4/7] qemu-agent: add qemuAgentCreateBond interface

2015-04-17 Thread Chen Fan
via initialize callback to create bond device.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_agent.c   | 118 
 src/qemu/qemu_agent.h   |  10 
 src/qemu/qemu_domain.c  |  70 
 src/qemu/qemu_domain.h  |   7 +++
 src/qemu/qemu_process.c |   4 ++
 5 files changed, 209 insertions(+)

diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index cee0f8b..b8eba01 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -2169,3 +2169,121 @@ qemuAgentGetInterfaces(qemuAgentPtr mon,
 
 goto cleanup;
 }
+
+static virDomainInterfacePtr
+findInterfaceByMac(virDomainInterfacePtr *info,
+   size_t len,
+   const char *macstr)
+{
+size_t i;
+bool found = false;
+
+for (i = 0; i < len; i++) {
+if (info[i]->hwaddr &&
+STREQ(info[i]->hwaddr, macstr)) {
+found = true;
+break;
+}
+}
+
+if (found) {
+return info[i];
+}
+
+return NULL;
+}
+
+/*
+ * qemuAgentSetInterface:
+ */
+int
+qemuAgentCreateBond(qemuAgentPtr mon,
+virDomainHostdevSubsysPCIPtr pcisrc)
+{
+int ret = -1;
+virJSONValuePtr cmd = NULL;
+virJSONValuePtr reply = NULL;
+size_t i;
+char macstr[VIR_MAC_STRING_BUFLEN];
+virDomainInterfacePtr *interfaceInfo = NULL;
+virDomainInterfacePtr interface;
+virJSONValuePtr new_interface = NULL;
+virJSONValuePtr subInterfaces = NULL;
+virJSONValuePtr subInterface = NULL;
+int len;
+
+if (!(pcisrc->nmac || pcisrc->macs))
+return ret;
+
+len = qemuAgentGetInterfaces(mon, &interfaceInfo);
+if (len < 0)
+return ret;
+
+if (!(new_interface = virJSONValueNewObject()))
+goto cleanup;
+
+if (virJSONValueObjectAppendString(new_interface, "type", "bond") < 0)
+goto cleanup;
+
+if (virJSONValueObjectAppendString(new_interface, "name", "bond0") < 0)
+goto cleanup;
+
+if (virJSONValueObjectAppendString(new_interface, "onboot", "onboot") < 0)
+goto cleanup;
+
+if (!(subInterfaces = virJSONValueNewArray()))
+goto cleanup;
+
+for (i = 0; i < pcisrc->nmac; i++) {
+virMacAddrFormat(&pcisrc->macs[i], macstr);
+interface = findInterfaceByMac(interfaceInfo, len, macstr);
+if (!interface) {
+goto cleanup;
+}
+
+if (!(subInterface = virJSONValueNewObject()))
+goto cleanup;
+
+if (virJSONValueObjectAppendString(subInterface, "name", 
interface->name) < 0)
+goto cleanup;
+
+if (virJSONValueArrayAppend(subInterfaces, subInterface) < 0)
+goto cleanup;
+
+subInterface = NULL;
+}
+
+if (i && virJSONValueObjectAppend(new_interface, "subInterfaces", 
subInterfaces) < 0)
+goto cleanup;
+
+cmd = qemuAgentMakeCommand("guest-network-set-interface",
+   "a:interface", new_interface,
+   NULL);
+
+if (!cmd)
+goto cleanup;
+
+subInterfaces = NULL;
+new_interface = NULL;
+
+if (qemuAgentCommand(mon, cmd, &reply, true,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+goto cleanup;
+
+if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("malformed return value"));
+}
+
+ cleanup:
+virJSONValueFree(subInterfaces);
+virJSONValueFree(subInterface);
+virJSONValueFree(new_interface);
+virJSONValueFree(cmd);
+virJSONValueFree(reply);
+if (interfaceInfo)
+for (i = 0; i < len; i++)
+virDomainInterfaceFree(interfaceInfo[i]);
+VIR_FREE(interfaceInfo);
+return ret;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 42414a7..744cb0a 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -97,6 +97,13 @@ struct _qemuAgentCPUInfo {
 bool offlinable;/* true if the CPU can be offlined */
 };
 
+typedef struct _qemuAgentInterfaceInfo qemuAgentInterfaceInfo;
+typedef qemuAgentInterfaceInfo *qemuAgentInterfaceInfoPtr;
+struct _qemuAgentInterfaceInfo {
+char *name;
+char *hardware_address;
+};
+
 int qemuAgentGetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr *info);
 int qemuAgentSetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr cpus, size_t 
ncpus);
 int qemuAgentUpdateCPUInfo(unsigned int nvcpus,
@@ -114,4 +121,7 @@ int qemuAgentSetTime(qemuAgentPtr mon,
 int qemuAgentGetInterfaces(qemuAgentPtr mon,
virDomainInterfacePtr **ifaces);
 
+int qemuAgentCreateBond(qemuAgentPtr mon,
+virDomainHostdevSubsysPCIPtr pcisrc);
+
 #en

[libvirt] [RFC 1/7] qemu-agent: add agent init callback when detecting guest setup

2015-04-17 Thread Chen Fan
sometimes, we want to do some initialize work in guest when guest startup,
but currently, qemu-agent doesn't support that. so here we add an init
callback, when guest startup, notify libvirt it has been up, then
libvirt can do some work for guest.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_agent.c   | 26 +++---
 src/qemu/qemu_agent.h   |  2 ++
 src/qemu/qemu_process.c |  6 ++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index 548d580..cee0f8b 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -92,6 +92,7 @@ struct _qemuAgent {
 int watch;
 
 bool connectPending;
+bool connected;
 
 virDomainObjPtr vm;
 
@@ -306,6 +307,7 @@ qemuAgentIOProcessLine(qemuAgentPtr mon,
 virJSONValuePtr obj = NULL;
 int ret = -1;
 unsigned long long id;
+const char *status;
 
 VIR_DEBUG("Line [%s]", line);
 
@@ -318,7 +320,11 @@ qemuAgentIOProcessLine(qemuAgentPtr mon,
 goto cleanup;
 }
 
-if (virJSONValueObjectHasKey(obj, "QMP") == 1) {
+if (virJSONValueObjectHasKey(obj, "QMP") == 1 ||
+virJSONValueObjectHasKey(obj, "status") == 1) {
+status = virJSONValueObjectGetString(obj, "status");
+if (STREQ(status, "connected"))
+mon->connected = true;
 ret = 0;
 } else if (virJSONValueObjectHasKey(obj, "event") == 1) {
 ret = qemuAgentIOProcessEvent(mon, obj);
@@ -700,8 +706,22 @@ qemuAgentIO(int watch, int fd, int events, void *opaque)
 VIR_DEBUG("Triggering error callback");
 (errorNotify)(mon, vm);
 } else {
-virObjectUnlock(mon);
-virObjectUnref(mon);
+if (mon->connected) {
+void (*init)(qemuAgentPtr, virDomainObjPtr)
+= mon->cb->init;
+virDomainObjPtr vm = mon->vm;
+
+mon->connected = false;
+
+virObjectUnlock(mon);
+virObjectUnref(mon);
+
+VIR_DEBUG("Triggering init callback");
+(init)(mon, vm);
+} else {
+virObjectUnlock(mon);
+virObjectUnref(mon);
+}
 }
 }
 
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 1cd5749..42414a7 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -34,6 +34,8 @@ typedef qemuAgent *qemuAgentPtr;
 typedef struct _qemuAgentCallbacks qemuAgentCallbacks;
 typedef qemuAgentCallbacks *qemuAgentCallbacksPtr;
 struct _qemuAgentCallbacks {
+void (*init)(qemuAgentPtr mon,
+ virDomainObjPtr vm);
 void (*destroy)(qemuAgentPtr mon,
 virDomainObjPtr vm);
 void (*eofNotify)(qemuAgentPtr mon,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 276837e..e6fc53a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -194,8 +194,14 @@ static void qemuProcessHandleAgentDestroy(qemuAgentPtr 
agent,
 virObjectUnref(vm);
 }
 
+static void qemuProcessHandleAgentInit(qemuAgentPtr agent ATTRIBUTE_UNUSED,
+   virDomainObjPtr vm)
+{
+VIR_DEBUG("Received init from agent on %p '%s'", vm, vm->def->name);
+}
 
 static qemuAgentCallbacks agentCallbacks = {
+.init = qemuProcessHandleAgentInit,
 .destroy = qemuProcessHandleAgentDestroy,
 .eofNotify = qemuProcessHandleAgentEOF,
 .errorNotify = qemuProcessHandleAgentError,
-- 
1.9.3

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


[libvirt] [RFC 0/3] add support migration with passthrough device

2015-04-17 Thread Chen Fan
the patches is for libvirt to support migration with passthrough
device using existing feacture.

Chen Fan (3):
  qemu-agent: add guest-network-set-interface command
  qemu-agent: add guest-network-delete-interface command
  qemu-agent: add notify for qemu-ga boot

 configure|  16 +++
 qga/commands-posix.c | 312 +++
 qga/commands-win32.c |  13 +++
 qga/main.c   |  13 +++
 qga/qapi-schema.json |  65 +++
 5 files changed, 419 insertions(+)

-- 
1.9.3

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


[libvirt] [RFC 5/7] hostdev: add parse ip and route for bond configure

2015-04-17 Thread Chen Fan
bond device always need to configure the ip address and
route way address. so here we add the interface.

xml like:

  
  






Signed-off-by: Chen Fan 
---
 docs/schemas/domaincommon.rng | 21 +++
 src/conf/domain_conf.c| 87 ---
 src/conf/domain_conf.h| 24 
 src/conf/networkcommon_conf.c | 17 -
 src/conf/networkcommon_conf.h | 17 +
 src/qemu/qemu_agent.c | 58 +++--
 6 files changed, 183 insertions(+), 41 deletions(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 0cf82cb..4056cbd 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3779,6 +3779,27 @@
   
 
   
+
+  
+
+  
+  
+
+  
+
+  
+  
+
+  
+
+  
+  
+
+  
+  
+
+  
+  
 
   
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 14bcae1..7d1cd3e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -797,6 +797,8 @@ static virClassPtr virDomainXMLOptionClass;
 static void virDomainObjDispose(void *obj);
 static void virDomainObjListDispose(void *obj);
 static void virDomainXMLOptionClassDispose(void *obj);
+static virDomainNetIpDefPtr virDomainNetIpParseXML(xmlNodePtr node);
+
 
 static int virDomainObjOnceInit(void)
 {
@@ -1914,8 +1916,17 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
 }
 } else if (def->source.subsys.type == 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
 virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
-if (pcisrc->device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND)
-VIR_FREE(pcisrc->macs);
+if (pcisrc->device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND) {
+for (i = 0; i < pcisrc->net.nmacs; i++)
+VIR_FREE(pcisrc->net.macs[i]);
+VIR_FREE(pcisrc->net.macs);
+for (i = 0; i < pcisrc->net.nips; i++)
+VIR_FREE(pcisrc->net.ips[i]);
+VIR_FREE(pcisrc->net.ips);
+for (i = 0; i < pcisrc->net.nroutes; i++)
+VIR_FREE(pcisrc->net.routes[i]);
+VIR_FREE(pcisrc->net.routes);
+}
 }
 break;
 }
@@ -5102,26 +5113,68 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
 if (device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND) {
 xmlNodePtr *macs = NULL;
 int n = 0;
-int i;
+size_t i;
 char *macStr = NULL;
+xmlNodePtr *ipnodes = NULL;
+int nipnodes;
+xmlNodePtr *routenodes = NULL;
+int nroutenodes;
 
 if (!(virXPathNode("./bond", ctxt))) {
 virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("missing  node specified by bond 
type"));
+   _("missing  node specified by bond 
type"));
 goto error;
 }
 
+if ((nipnodes = virXPathNodeSet("./bond/ip", ctxt, &ipnodes)) < 0)
+goto error;
+
+if (nipnodes) {
+for (i = 0; i < nipnodes; i++) {
+virDomainNetIpDefPtr ip = 
virDomainNetIpParseXML(ipnodes[i]);
+
+if (!ip)
+goto error;
+
+if (VIR_APPEND_ELEMENT(pcisrc->net.ips,
+   pcisrc->net.nips, ip) < 0) {
+VIR_FREE(ip);
+goto error;
+}
+}
+}
+
+if ((nroutenodes = virXPathNodeSet("./bond/route", ctxt, 
&routenodes)) < 0)
+goto error;
+
+if (nroutenodes) {
+for (i = 0; i < nroutenodes; i++) {
+virNetworkRouteDefPtr route = NULL;
+
+if (!(route = virNetworkRouteDefParseXML(_("Domain hostdev 
device"),
+ routenodes[i],
+ ctxt)))
+goto error;
+
+if (VIR_APPEND_ELEMENT(pcisrc->net.routes,
+   pcisrc->net.nroutes, route) < 0) {
+virNetworkRouteDefFree(route);
+goto error;
+}
+}
+}
+
 if ((n = virXPathNodeSet("

[libvirt] [RFC 2/3] qemu-agent: add guest-network-delete-interface command

2015-04-17 Thread Chen Fan
Add a corresponding command to guest-network-set-interface.

Signed-off-by: Chen Fan 
---
 qga/commands-posix.c | 51 +++
 qga/commands-win32.c |  6 ++
 qga/qapi-schema.json | 11 +++
 3 files changed, 68 insertions(+)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 5ee7949..058085f 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1971,6 +1971,51 @@ int64_t 
qmp_guest_network_set_interface(GuestNetworkInterface2 *interface,
 
 return 0;
 }
+
+int64_t qmp_guest_network_delete_interface(const char *name, Error **errp)
+{
+struct netcf_if *iface;
+int ret = -1;
+unsigned int flags = 0;
+
+/* open netcf */
+if (netcf == NULL) {
+if (ncf_init(&netcf, NULL) != 0) {
+error_setg(errp, "netcf init failed");
+return ret;
+}
+}
+
+iface = ncf_lookup_by_name(netcf, name);
+if (!iface) {
+   error_setg(errp, "couldn't find interface named '%s'", name);
+   return ret;
+}
+
+if (ncf_if_status(iface, &flags) < 0) {
+error_setg(errp, "netcf interface get status failed");
+goto cleanup;
+}
+
+if (flags & NETCF_IFACE_ACTIVE) {
+ret = ncf_if_down(iface);
+if (ret < 0) {
+error_setg(errp, "netcf interface stop failed");
+goto cleanup;
+}
+}
+
+ret = ncf_if_undefine(iface);
+if (ret < 0) {
+error_setg(errp, "netcf interface delete failed");
+goto cleanup;
+}
+
+ret = 0;
+cleanup:
+ncf_if_free(iface);
+return ret;
+}
 #else
 int64_t qmp_guest_network_set_interface(GuestNetworkInterface2 *interface,
 Error **errp)
@@ -1978,6 +2023,12 @@ int64_t 
qmp_guest_network_set_interface(GuestNetworkInterface2 *interface,
 error_set(errp, QERR_UNSUPPORTED);
 return -1;
 }
+
+int64_t qmp_guest_network_delete_interface(const char *name, Error **errp)
+{
+error_set(errp, QERR_UNSUPPORTED);
+return -1;
+}
 #endif
 
 #define SYSCONF_EXACT(name, errp) sysconf_exact((name), #name, (errp))
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 4c14514..52f6e47 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -453,6 +453,12 @@ int64_t 
qmp_guest_network_set_interface(GuestNetworkInterface2 *interface,
 return -1;
 }
 
+int64_t qmp_guest_network_delete_interface(const char *name, Error **errp)
+{
+error_set(errp, QERR_UNSUPPORTED);
+return -1;
+}
+
 /* add unsupported commands to the blacklist */
 GList *ga_command_blacklist_init(GList *blacklist)
 {
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 77f499b..b886f97 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -642,6 +642,17 @@
   'returns': 'int' }
 
 ##
+# @guest-network-delete-interface:
+#
+# @name: interface name.
+#
+# Since: 2.3
+##
+{ 'command': 'guest-network-delete-interface',
+  'data'   : {'name': 'str' },
+  'returns': 'int' }
+
+##
 # @GuestLogicalProcessor:
 #
 # @logical-id: Arbitrary guest-specific unique identifier of the VCPU.
-- 
1.9.3

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


[libvirt] [RFC 0/7] Live Migration with Pass-through Devices proposal

2015-04-17 Thread Chen Fan
backgrond:
Live migration is one of the most important features of virtualization 
technology.
With regard to recent virtualization techniques, performance of network I/O is 
critical.
Current network I/O virtualization (e.g. Para-virtualized I/O, VMDq) has a 
significant
performance gap with native network I/O. Pass-through network devices have near
native performance, however, they have thus far prevented live migration. No 
existing
methods solve the problem of live migration with pass-through devices perfectly.

There was an idea to solve the problem in website:
https://www.kernel.org/doc/ols/2008/ols2008v2-pages-261-267.pdf
Please refer to above document for detailed information.

So I think this problem maybe could be solved by using the combination of 
existing
technology. and the following steps are we considering to implement:

-  before boot VM, we anticipate to specify two NICs for creating bonding device
   (one plugged and one virtual NIC) in XML. here we can specify the NIC's mac 
addresses
   in XML, which could facilitate qemu-guest-agent to find the network 
interfaces in guest.

-  when qemu-guest-agent startup in guest it would send a notification to 
libvirt,
   then libvirt will call the previous registered initialize callbacks. so 
through
   the callback functions, we can create the bonding device according to the XML
   configuration. and here we use netcf tool which can facilitate to create 
bonding device
   easily.

-  during migration, unplug the passthroughed NIC. then do native migration.

-  on destination side, check whether need to hotplug new NIC according to 
specified XML.
   usually, we use migrate "--xml" command option to specify the destination 
host NIC mac
   address to hotplug a new NIC, because source side passthrough NIC mac 
address is different,
   then hotplug the deivce according to the destination XML configuration.

TODO:
  1.  when hot add a new NIC in destination side after migration finished, the 
NIC device
  need to re-enslave on bonding device in guest. otherwise, it is offline. 
maybe
  we should consider bonding driver to support add interfaces dynamically.

This is an example on how this might work, so I want to hear some voices about 
this scenario.

Thanks,
Chen

Chen Fan (7):
  qemu-agent: add agent init callback when detecting guest setup
  qemu: add guest init event callback to do the initialize work for
guest
  hostdev: add a 'bond' type element in  element
  qemu-agent: add qemuAgentCreateBond interface
  hostdev: add parse ip and route for bond configure
  migrate: hot remove hostdev at perform phase for bond device
  migrate: add hostdev migrate status to support hostdev migration

 docs/schemas/basictypes.rng   |   6 ++
 docs/schemas/domaincommon.rng |  37 
 src/conf/domain_conf.c| 195 ++---
 src/conf/domain_conf.h|  40 +++--
 src/conf/networkcommon_conf.c |  17 
 src/conf/networkcommon_conf.h |  17 
 src/libvirt_private.syms  |   1 +
 src/qemu/qemu_agent.c | 196 +-
 src/qemu/qemu_agent.h |  12 +++
 src/qemu/qemu_command.c   |   3 +
 src/qemu/qemu_domain.c|  70 +++
 src/qemu/qemu_domain.h|  14 +++
 src/qemu/qemu_driver.c|  38 
 src/qemu/qemu_hotplug.c   |   8 +-
 src/qemu/qemu_migration.c |  91 
 src/qemu/qemu_migration.h |   4 +
 src/qemu/qemu_process.c   |  32 +++
 src/util/virhostdev.c |   3 +
 18 files changed, 745 insertions(+), 39 deletions(-)

-- 
1.9.3

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


[libvirt] [RFC 1/3] qemu-agent: add guest-network-set-interface command

2015-04-17 Thread Chen Fan
Nowadays, qemu has supported physical NIC hotplug for high network
throughput. but it's in conflict with live migration feature, to keep
network connectivity, we could to create bond device interface which
provides a mechanism for enslaving multiple network interfaces into a
single "bond" interface. the active-backup mode can be used for an
automatic switch. so this patch is adding a guest-network-set-interface
command for creating bond device. so the management can easy to create
a bond device dynamically when guest running.

Signed-off-by: Chen Fan 
---
 configure|  16 
 qga/commands-posix.c | 261 +++
 qga/commands-win32.c |   7 ++
 qga/qapi-schema.json |  54 +++
 4 files changed, 338 insertions(+)

diff --git a/configure b/configure
index f185dd0..ebfcc6a 100755
--- a/configure
+++ b/configure
@@ -3618,6 +3618,18 @@ if test "$darwin" != "yes" -a "$mingw32" != "yes" -a 
"$solaris" != yes -a \
 fi
 
 ##
+# Do we need netcf
+netcf=no
+cat > $TMPC << EOF
+#include 
+int main(void) { return 0; }
+EOF
+if compile_prog "" "-lnetcf" ; then
+netcf=yes
+libs_qga="$libs_qga -lnetcf"
+fi
+
+##
 # spice probe
 if test "$spice" != "no" ; then
   cat > $TMPC << EOF
@@ -4697,6 +4709,10 @@ if test "$spice" = "yes" ; then
   echo "CONFIG_SPICE=y" >> $config_host_mak
 fi
 
+if test "$netcf" = "yes" ; then
+  echo "CONFIG_NETCF=y" >> $config_host_mak
+fi
+
 if test "$smartcard_nss" = "yes" ; then
   echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak
   echo "NSS_LIBS=$nss_libs" >> $config_host_mak
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index f6f3e3c..5ee7949 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -46,6 +46,10 @@ extern char **environ;
 #include 
 #include 
 
+#ifdef CONFIG_NETCF
+#include 
+#endif
+
 #ifdef FIFREEZE
 #define CONFIG_FSFREEZE
 #endif
@@ -1719,6 +1723,263 @@ error:
 return NULL;
 }
 
+#ifdef CONFIG_NETCF
+static const char *interface_type_string[] = {
+"bond",
+};
+
+static const char *ip_address_type_string[] = {
+"ipv4",
+"ipv6",
+};
+
+static char *parse_options(const char *str, const char *needle)
+{
+char *start, *end, *buffer = NULL;
+char *ret = NULL;
+
+buffer = g_strdup(str);
+start = buffer;
+if ((start = strstr(start, needle))) {
+start += strlen(needle);
+end = strchr(start, ' ');
+if (end) {
+*end = '\0';
+}
+if (strlen(start) == 0) {
+goto cleanup;
+}
+ret = g_strdup(start);
+}
+
+cleanup:
+g_free(buffer);
+return ret;
+}
+
+/**
+ * @buffer: xml string data to be formatted
+ * @indent: indent number relative to first line
+ *
+ */
+static void adjust_indent(char **buffer, int indent)
+{
+char spaces[1024];
+int i;
+
+if (!*buffer) {
+return;
+}
+
+if (indent < 0 || indent >= 1024) {
+return;
+}
+memset(spaces, 0, sizeof(spaces));
+for (i = 0; i < indent; i++) {
+spaces[i] = ' ';
+}
+
+sprintf(*buffer + strlen(*buffer), "%s", spaces);
+}
+
+static char *create_bond_interface(GuestNetworkInterface2 *interface)
+{
+char *target_xml;
+
+target_xml = g_malloc0(1024);
+if (!target_xml) {
+return NULL;
+}
+
+sprintf(target_xml, "\n",
+interface_type_string[interface->type], interface->name);
+adjust_indent(&target_xml, 2);
+sprintf(target_xml + strlen(target_xml), "\n",
+interface->has_onboot ? interface->onboot : "none");
+if (interface->has_ip_address) {
+GuestIpAddress *address_item = interface->ip_address;
+
+adjust_indent(&target_xml, 2);
+sprintf(target_xml + strlen(target_xml), "\n",
+ip_address_type_string[address_item->ip_address_type]);
+adjust_indent(&target_xml, 4);
+sprintf(target_xml + strlen(target_xml), "\n",
+address_item->ip_address, address_item->prefix);
+if (address_item->has_gateway) {
+adjust_indent(&target_xml, 4);
+sprintf(target_xml + strlen(target_xml), "\n",
+address_item->gateway);
+}
+adjust_indent(&target_xml, 2);
+sprintf(target_xml + strlen(target_xml), "%s\n", "");
+}
+
+adjust_indent(&target_xml, 2);
+if (interface->has_options) {
+char *value;
+
+value = parse_

[libvirt] [RFC 6/7] migrate: hot remove hostdev at perform phase for bond device

2015-04-17 Thread Chen Fan
For bond device, we can support the migrate, we can simple
to hot remove the device from source side, and after migration
end, we hot add the new device at destination side.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_driver.c| 57 +++
 src/qemu/qemu_migration.c |  7 ++
 2 files changed, 64 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7368145..0ba9e4a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12353,6 +12353,58 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
   cookieout, cookieoutlen, flags);
 }
 
+static int
+qemuDomainRemovePciPassThruDevices(virConnectPtr conn,
+   virDomainObjPtr vm)
+{
+virQEMUDriverPtr driver = conn->privateData;
+virDomainDeviceDef dev;
+virDomainDeviceDefPtr dev_copy = NULL;
+virCapsPtr caps = NULL;
+int ret = -1;
+size_t i;
+
+if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+goto cleanup;
+
+if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT))
+goto cleanup;
+
+/* unplug passthrough bond device */
+for (i = 0; i < vm->def->nhostdevs; i++) {
+virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+
+if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI 
&&
+hostdev->source.subsys.u.pci.backend == 
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
+hostdev->source.subsys.u.pci.device == 
VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND) {
+
+dev.type = VIR_DOMAIN_DEVICE_HOSTDEV;
+dev.data.hostdev = hostdev;
+
+dev_copy = virDomainDeviceDefCopy(&dev, vm->def, caps, 
driver->xmlopt);
+if (!dev_copy)
+goto cleanup;
+
+if (qemuDomainDetachHostDevice(driver, vm, dev_copy) < 0) {
+virDomainDeviceDefFree(dev_copy);
+goto cleanup;
+}
+
+virDomainDeviceDefFree(dev_copy);
+if (qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE) < 
0)
+goto cleanup;
+}
+}
+
+ret = 0;
+
+ cleanup:
+virObjectUnref(caps);
+
+return ret;
+}
+
 static char *
 qemuDomainMigrateBegin3Params(virDomainPtr domain,
   virTypedParameterPtr params,
@@ -12688,6 +12740,11 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
 return -1;
 }
 
+if (qemuDomainRemovePciPassThruDevices(dom->conn, vm) < 0) {
+qemuDomObjEndAPI(&vm);
+return -1;
+}
+
 return qemuMigrationPerform(driver, dom->conn, vm, dom_xml,
 dconnuri, uri, graphicsuri, listenAddress,
 cookiein, cookieinlen, cookieout, cookieoutlen,
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 611f53a..9ea83df 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2000,6 +2000,13 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, 
virDomainObjPtr vm,
 forbid = false;
 for (i = 0; i < def->nhostdevs; i++) {
 virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+
+if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI 
&&
+hostdev->source.subsys.u.pci.backend == 
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
+hostdev->source.subsys.u.pci.device == 
VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND)
+continue;
+
 if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) 
{
 forbid = true;
-- 
1.9.3

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


[libvirt] [RFC 3/3] qemu-agent: add notify for qemu-ga boot

2015-04-17 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 qga/main.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/qga/main.c b/qga/main.c
index 9939a2b..f011ce0 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1170,6 +1170,19 @@ int main(int argc, char **argv)
 g_critical("failed to initialize guest agent channel");
 goto out_bad;
 }
+
+/* send a notification to path */
+if (ga_state->channel) {
+QDict *qdict = qdict_new();
+int ret;
+
+qdict_put_obj(qdict, "status", QOBJECT(qstring_from_str("connected")));
+ret = send_response(s, QOBJECT(qdict));
+if (ret < 0) {
+g_warning("error sending connected status");
+}
+}
+
 #ifndef _WIN32
 g_main_loop_run(ga_state->main_loop);
 #else
-- 
1.9.3

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


[libvirt] [RFC 2/7] qemu: add guest init event callback to do the initialize work for guest

2015-04-17 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/qemu/qemu_domain.h  |  7 +++
 src/qemu/qemu_driver.c  | 32 
 src/qemu/qemu_process.c | 22 ++
 3 files changed, 61 insertions(+)

diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 3225abb..19f4b27 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -136,6 +136,8 @@ struct qemuDomainJobObj {
 typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver,
   virDomainObjPtr vm);
 
+typedef void (*qemuDomainInitCallback)(virDomainObjPtr vm);
+
 typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
 typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
 struct _qemuDomainObjPrivate {
@@ -185,6 +187,10 @@ struct _qemuDomainObjPrivate {
 size_t ncleanupCallbacks;
 size_t ncleanupCallbacks_max;
 
+qemuDomainInitCallback *initCallbacks;
+size_t nInitCallbacks;
+size_t nInitCallbacks_max;
+
 virCgroupPtr cgroup;
 
 virCond unplugFinished; /* signals that unpluggingDevice was unplugged */
@@ -205,6 +211,7 @@ typedef enum {
 QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED,
 QEMU_PROCESS_EVENT_SERIAL_CHANGED,
 QEMU_PROCESS_EVENT_BLOCK_JOB,
+QEMU_PROCESS_EVENT_GUESTINIT,
 
 QEMU_PROCESS_EVENT_LAST
 } qemuProcessEventType;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f37b95d..7368145 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4073,6 +4073,35 @@ processGuestPanicEvent(virQEMUDriverPtr driver,
 
 
 static void
+processGuestInitEvent(virQEMUDriverPtr driver,
+  virDomainObjPtr vm)
+{
+qemuDomainObjPrivatePtr priv;
+int i;
+
+VIR_DEBUG("init guest from domain %p %s",
+  vm, vm->def->name);
+
+if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+return;
+
+if (!virDomainObjIsActive(vm)) {
+VIR_DEBUG("Domain is not running");
+goto endjob;
+}
+
+priv = vm->privateData;
+
+for (i = 0; i < priv->nInitCallbacks; i++) {
+if (priv->initCallbacks[i])
+priv->initCallbacks[i](vm);
+}
+
+ endjob:
+qemuDomainObjEndJob(driver, vm);
+}
+
+static void
 processDeviceDeletedEvent(virQEMUDriverPtr driver,
   virDomainObjPtr vm,
   char *devAlias)
@@ -4627,6 +4656,9 @@ static void qemuProcessEventHandler(void *data, void 
*opaque)
  processEvent->action,
  processEvent->status);
 break;
+case QEMU_PROCESS_EVENT_GUESTINIT:
+processGuestInitEvent(driver, vm);
+break;
 case QEMU_PROCESS_EVENT_LAST:
 break;
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e6fc53a..fcc0566 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -197,7 +197,29 @@ static void qemuProcessHandleAgentDestroy(qemuAgentPtr 
agent,
 static void qemuProcessHandleAgentInit(qemuAgentPtr agent ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
 {
+struct qemuProcessEvent *processEvent = NULL;
+virQEMUDriverPtr driver = qemu_driver;
+
+virObjectLock(vm);
+
 VIR_DEBUG("Received init from agent on %p '%s'", vm, vm->def->name);
+
+if (VIR_ALLOC(processEvent) < 0)
+goto cleanup;
+
+processEvent->eventType = QEMU_PROCESS_EVENT_GUESTINIT;
+processEvent->vm = vm;
+
+virObjectRef(vm);
+if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
+if (!virObjectUnref(vm))
+vm = NULL;
+VIR_FREE(processEvent);
+}
+
+ cleanup:
+if (vm)
+virObjectUnlock(vm);
 }
 
 static qemuAgentCallbacks agentCallbacks = {
-- 
1.9.3

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


[libvirt] [RFC 7/7] migrate: add hostdev migrate status to support hostdev migration

2015-04-17 Thread Chen Fan
we add a migrate status for hostdev to specify the device don't
need to initialze when VM startup, after migration end, we add
the migrate status hostdev, so can support hostdev migration.

Signed-off-by: Chen Fan 
---
 src/conf/domain_conf.c|  3 ++
 src/conf/domain_conf.h|  7 
 src/qemu/qemu_command.c   |  3 ++
 src/qemu/qemu_driver.c| 53 +--
 src/qemu/qemu_hotplug.c   |  8 +++--
 src/qemu/qemu_migration.c | 92 ---
 src/qemu/qemu_migration.h |  4 +++
 src/util/virhostdev.c |  3 ++
 8 files changed, 114 insertions(+), 59 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7d1cd3e..b56c6fa 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3035,6 +3035,9 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
 device.type = VIR_DOMAIN_DEVICE_HOSTDEV;
 for (i = 0; i < def->nhostdevs; i++) {
 device.data.hostdev = def->hostdevs[i];
+if (device.data.hostdev->state == 
VIR_DOMAIN_HOSTDEV_STATE_READY_FOR_MIGRATE)
+continue;
+
 if (cb(def, &device, def->hostdevs[i]->info, opaque) < 0)
 return -1;
 }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 723f07b..4b7b4c9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -543,6 +543,12 @@ struct _virDomainHostdevCaps {
 } u;
 };
 
+typedef enum {
+VIR_DOMAIN_HOSTDEV_STATE_DEFAULT,
+VIR_DOMAIN_HOSTDEV_STATE_READY_FOR_MIGRATE,
+
+VIR_DOMAIN_HOSTDEV_STATE_LAST
+} virDomainHostdevState;
 
 /* basic device for direct passthrough */
 struct _virDomainHostdevDef {
@@ -559,6 +565,7 @@ struct _virDomainHostdevDef {
 } source;
 virDomainHostdevOrigStates origstates;
 virDomainDeviceInfoPtr info; /* Guest address */
+int state;
 };
 
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e7e0937..dc5245a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10365,6 +10365,9 @@ qemuBuildCommandLine(virConnectPtr conn,
 virDomainHostdevDefPtr hostdev = def->hostdevs[i];
 char *devstr;
 
+if (hostdev->state == VIR_DOMAIN_HOSTDEV_STATE_READY_FOR_MIGRATE)
+continue;
+
 if (hostdev->info->bootIndex) {
 if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
 (hostdev->source.subsys.type != 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0ba9e4a..4724171 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12353,57 +12353,6 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
   cookieout, cookieoutlen, flags);
 }
 
-static int
-qemuDomainRemovePciPassThruDevices(virConnectPtr conn,
-   virDomainObjPtr vm)
-{
-virQEMUDriverPtr driver = conn->privateData;
-virDomainDeviceDef dev;
-virDomainDeviceDefPtr dev_copy = NULL;
-virCapsPtr caps = NULL;
-int ret = -1;
-size_t i;
-
-if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
-goto cleanup;
-
-if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT))
-goto cleanup;
-
-/* unplug passthrough bond device */
-for (i = 0; i < vm->def->nhostdevs; i++) {
-virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
-
-if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
-hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI 
&&
-hostdev->source.subsys.u.pci.backend == 
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
-hostdev->source.subsys.u.pci.device == 
VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND) {
-
-dev.type = VIR_DOMAIN_DEVICE_HOSTDEV;
-dev.data.hostdev = hostdev;
-
-dev_copy = virDomainDeviceDefCopy(&dev, vm->def, caps, 
driver->xmlopt);
-if (!dev_copy)
-goto cleanup;
-
-if (qemuDomainDetachHostDevice(driver, vm, dev_copy) < 0) {
-virDomainDeviceDefFree(dev_copy);
-goto cleanup;
-}
-
-virDomainDeviceDefFree(dev_copy);
-if (qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE) < 
0)
-goto cleanup;
-}
-}
-
-ret = 0;
-
- cleanup:
-virObjectUnref(caps);
-
-return ret;
-}
 
 static char *
 qemuDomainMigrateBegin3Params(virDomainPtr domain,
@@ -12740,7 +12689,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
 return -1;
 }
 
-if (qemuDomainRemovePciPassThruDevices(dom->conn, vm) < 0) {
+if (qemuDomainMigratePciPassThruDevices(driver, vm, false) < 0) {
 qemuDomObjEndAPI(&vm);
 return -1;
 }
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f07c54d..13a7338 100

[libvirt] [RFC 3/7] hostdev: add a 'bond' type element in element

2015-04-17 Thread Chen Fan
this 'bond' element is to create bond device when guest startup,
the xml like:



  
  



Signed-off-by: Chen Fan 
---
 docs/schemas/basictypes.rng   |   6 ++
 docs/schemas/domaincommon.rng |  16 ++
 src/conf/domain_conf.c| 131 ++
 src/conf/domain_conf.h|  13 +
 src/libvirt_private.syms  |   1 +
 5 files changed, 157 insertions(+), 10 deletions(-)

diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
index f086ad2..aef24fe 100644
--- a/docs/schemas/basictypes.rng
+++ b/docs/schemas/basictypes.rng
@@ -66,6 +66,12 @@
 
   
 
+  
+
+  
+
+  
+
   
 
   
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 03fd541..0cf82cb 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3766,9 +3766,25 @@
   xen
 
   
+  
+
+  
+bond
+  
+
+  
   
 
   
+  
+
+  
+
+  
+
+  
+
+  
   
 
   
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4d7e3c9..14bcae1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -610,6 +610,11 @@ VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend,
   "vfio",
   "xen")
 
+VIR_ENUM_IMPL(virDomainHostdevSubsysPCIDevice,
+  VIR_DOMAIN_HOSTDEV_PCI_DEVICE_TYPE_LAST,
+  "default",
+  "bond")
+
 VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIProtocol,
   VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_LAST,
   "adapter",
@@ -1907,6 +1912,10 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
 } else {
 VIR_FREE(scsisrc->u.host.adapter);
 }
+} else if (def->source.subsys.type == 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
+if (pcisrc->device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND)
+VIR_FREE(pcisrc->macs);
 }
 break;
 }
@@ -4978,7 +4987,9 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
 char *sgio = NULL;
 char *rawio = NULL;
 char *backendStr = NULL;
+char *deviceStr = NULL;
 int backend;
+int device;
 int ret = -1;
 virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
 virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
@@ -5077,6 +5088,68 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
 }
 pcisrc->backend = backend;
 
+device =  VIR_DOMAIN_HOSTDEV_PCI_DEVICE_DEFAULT;
+if ((deviceStr = virXPathString("string(./driver/@type)", ctxt)) &&
+(((device = 
virDomainHostdevSubsysPCIDeviceTypeFromString(deviceStr)) < 0) ||
+ device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_DEFAULT)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("Unknown PCI device  "
+ "has been specified"), deviceStr);
+goto error;
+}
+pcisrc->device = device;
+
+if (device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND) {
+xmlNodePtr *macs = NULL;
+int n = 0;
+int i;
+char *macStr = NULL;
+
+if (!(virXPathNode("./bond", ctxt))) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("missing  node specified by bond 
type"));
+goto error;
+}
+
+if ((n = virXPathNodeSet("./bond/interface", ctxt, &macs)) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Cannot extract interface nodes"));
+goto error;
+}
+
+VIR_FREE(pcisrc->macs);
+if (VIR_ALLOC_N(pcisrc->macs, n) < 0)
+goto error;
+
+pcisrc->nmac = n;
+for (i = 0; i < n; i++) {
+xmlNodePtr cur_node = macs[i];
+
+macStr = virXMLPropString(cur_node, "address");
+if (!macStr) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Missing required address attribute "
+   "in interface element"));
+goto error;
+}
+if (virMacAddrParse((const char *)macStr, &pcisrc->macs[i]) < 
0) {
+virReportError(VIR_ERR_XML_ERROR,
+   _("unable t

[libvirt] [PATCH 0/2] fix domain documentation error

2015-03-24 Thread Chen Fan
Chen Fan (2):
  docs: no 'via' attribute in route element
  docs: route element must specify network address

 docs/formatdomain.html.in | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

-- 
1.9.3

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


[libvirt] [PATCH 1/2] docs: no 'via' attribute in route element

2015-03-24 Thread Chen Fan
via -> gateway

Signed-off-by: Chen Fan 
---
 docs/formatdomain.html.in | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 82aa14f..3b3d2d9 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4471,8 +4471,8 @@ qemu-kvm -net nic,model=? /dev/null
   <source network='default'/>
   <target dev='vnet0'/>
   <ip address='192.168.122.5' prefix='24'/>
-  <route family='ipv4' address='192.168.122.0' prefix='24' 
via='192.168.122.1'/>
-  <route family='ipv4' via='192.168.122.1'/>
+  <route family='ipv4' address='192.168.122.0' prefix='24' 
gateway='192.168.122.1'/>
+  <route family='ipv4' gateway='192.168.122.1'/>
 </interface>
 ...
 <hostdev mode='capabilities' type='net'>
@@ -4480,8 +4480,8 @@ qemu-kvm -net nic,model=? /dev/null
 <interface>eth0</interface>
   </source>
   <ip address='192.168.122.6' prefix='24'/>
-  <route family='ipv4' address='192.168.122.0' prefix='24' 
via='192.168.122.1'/>
-  <route family='ipv4' via='192.168.122.1'/>
+  <route family='ipv4' address='192.168.122.0' prefix='24' 
gateway='192.168.122.1'/>
+  <route family='ipv4' gateway='192.168.122.1'/>
 </hostdev>
 
   </devices>
-- 
1.9.3

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


[libvirt] [PATCH 2/2] docs: route element must specify network address

2015-03-24 Thread Chen Fan
because network address is required by route, so
here we should add one avoid user misunderstand.

Signed-off-by: Chen Fan 
---
 docs/formatdomain.html.in | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 3b3d2d9..d7fe942 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4472,7 +4472,7 @@ qemu-kvm -net nic,model=? /dev/null
   <target dev='vnet0'/>
   <ip address='192.168.122.5' prefix='24'/>
   <route family='ipv4' address='192.168.122.0' prefix='24' 
gateway='192.168.122.1'/>
-  <route family='ipv4' gateway='192.168.122.1'/>
+  <route family='ipv4' address='192.168.122.8' 
gateway='192.168.122.1'/>
 </interface>
 ...
 <hostdev mode='capabilities' type='net'>
@@ -4481,7 +4481,7 @@ qemu-kvm -net nic,model=? /dev/null
   </source>
   <ip address='192.168.122.6' prefix='24'/>
   <route family='ipv4' address='192.168.122.0' prefix='24' 
gateway='192.168.122.1'/>
-  <route family='ipv4' gateway='192.168.122.1'/>
+  <route family='ipv4' address='192.168.122.8' 
gateway='192.168.122.1'/>
 </hostdev>
 
   </devices>
-- 
1.9.3

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


Re: [libvirt] [PATCH] qemu: fix memory leak in qemuAgentGetFSInfo

2015-03-10 Thread Chen Fan


On 03/10/2015 05:32 PM, Ján Tomko wrote:

On Tue, Mar 10, 2015 at 01:56:11PM +0800, Chen Fan wrote:

in virDomainFSInfoFree(), don't free the virDomainFSInfo data.

==10670== 80 bytes in 2 blocks are definitely lost in loss record 576 of 793
==10670==at 0x4A06BC3: calloc (vg_replace_malloc.c:618)
==10670==by 0x509DEBD: virAlloc (viralloc.c:144)
==10670==by 0x19FBD558: qemuAgentGetFSInfo (qemu_agent.c:1837)
==10670==by 0x1A03CF91: qemuDomainGetFSInfo (qemu_driver.c:19238)

Signed-off-by: Chen Fan 
---
  src/libvirt-domain.c | 2 ++
  1 file changed, 2 insertions(+)

This does fix the memory leak and makes the function behave like it's
documented in virDomainGetFSInfo and virDomainFSInfoFree:
http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetFSInfo
http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainFSInfoFree

But it changes the public API - if there are applications that already
work around this function by freeing the info, this change would
introduce a double free.

I would NACK this if the documentation for both APIs didn't say that's
how this function should behave.

I'd like to hear a second opinion.

I don't think this documentation make any confusable.
for using the function virDomainGetFSInfo(), user also need
to call virDomainFSInfoFree() on each array element, and call free() info.
example:

virDomainFSInfoPtr *info;

ndata = virDomainGetFSInfo(dom, &info, 0);

for (i = 0; i < ndata; i++)
virDomainFSInfoFree(info[i]);
VIR_FREE(info);

Thanks,
Chen


Jan


diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 04545fd..7f8a7ce 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11337,4 +11337,6 @@ virDomainFSInfoFree(virDomainFSInfoPtr info)
  for (i = 0; i < info->ndevAlias; i++)
  VIR_FREE(info->devAlias[i]);
  VIR_FREE(info->devAlias);
+
+VIR_FREE(info);
  }
--
1.9.3

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



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


[libvirt] [PATCH] qemu: fix memory leak in qemuAgentGetFSInfo

2015-03-09 Thread Chen Fan
in virDomainFSInfoFree(), don't free the virDomainFSInfo data.

==10670== 80 bytes in 2 blocks are definitely lost in loss record 576 of 793
==10670==at 0x4A06BC3: calloc (vg_replace_malloc.c:618)
==10670==by 0x509DEBD: virAlloc (viralloc.c:144)
==10670==by 0x19FBD558: qemuAgentGetFSInfo (qemu_agent.c:1837)
==10670==by 0x1A03CF91: qemuDomainGetFSInfo (qemu_driver.c:19238)

Signed-off-by: Chen Fan 
---
 src/libvirt-domain.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 04545fd..7f8a7ce 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11337,4 +11337,6 @@ virDomainFSInfoFree(virDomainFSInfoPtr info)
 for (i = 0; i < info->ndevAlias; i++)
 VIR_FREE(info->devAlias[i]);
 VIR_FREE(info->devAlias);
+
+VIR_FREE(info);
 }
-- 
1.9.3

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


[libvirt] [PATCH] docs: network: fix some trivial typos in docs/formatnetwork.html

2014-12-05 Thread Chen Fan
this patch fix some weird typos:
   1. < hostdev> => 
   2. < type>=> 
   3.  => 
   4. redundant comma
   5. missing right-half bracket

Signed-off-by: Chen Fan 
---
 docs/formatnetwork.html.in | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index dc438ae..7bcf316 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -288,7 +288,7 @@
 (Single Root I/O Virtualization) virtual function (VF)
 devices can be assigned in this manner; to assign a
 standard single-port PCI or PCIe ethernet card to a guest,
-use the traditional < hostdev> device
+use the traditional <hostdev> device
 definition.  Since 0.10.0
 
 
@@ -312,9 +312,9 @@
 
 Note that this "intelligent passthrough" of network
 devices is very similar to the functionality of a
-standard < hostdev> device, the
+standard <hostdev> device, the
 difference being that this method allows specifying a MAC
-address, vlan tag, and <virtualport >
+address, vlan tag, and <virtualport>
 for the passed-through device. If these capabilities are
 not required, if you have a standard single-port PCI,
 PCIe, or USB network card that doesn't support SR-IOV (and
@@ -383,9 +383,9 @@
   since 0.10.0 When using forward
   mode 'hostdev', the interface pool is specified with a list
   of <address> elements, each of which has
-  < type> (must always be 'pci',
+  <type> (must always be 'pci'),
   <domain>, <bus>,
-  <slot>, and <function>
+  <slot>and <function>
   attributes.
 
 
-- 
1.9.3

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


[libvirt] [PATCH] docs: fix a typo in formatdomain.html

2014-11-20 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 docs/formatdomain.html.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 9364eb5..6a15074 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3413,7 +3413,7 @@
   setting for the attribute is no for security
   reasons and support depends on the guest network device model as
   well as the type of connection on the host - currently it is
-  only supported for the virtio ddevice model and for macvtap
+  only supported for the virtio device model and for macvtap
   connections on the host.
 
 
-- 
1.9.3

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


[libvirt] [PATCH] virnuma: add notset NULL check in virNumaSetupMemoryPolicy

2014-11-07 Thread Chen Fan
introduce by commit c63ef0452b, when nodeset is NULL, validation
will pass in virNumaSetupMemoryPolicy, but virBitmapNextSetBit
must ensure bitmap is not Null. there will cause a segmentation
fault. this patch fixed it.

Signed-off-by: Chen Fan 
---
 src/util/virnuma.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 06520f7..b8d76f4 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -97,6 +97,9 @@ virNumaSetupMemoryPolicy(virDomainNumatuneMemMode mode,
 size_t i;
 int maxnode = 0;
 
+if (!nodeset)
+return 0;
+
 if (!virNumaNodesetIsAvailable(nodeset))
 return -1;
 
-- 
1.9.3

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


[libvirt] [PATCH v5 3/3] virnuma: use virNumaNodesetIsAvailable checking nodeset in virNumaSetupMemoryPolicy

2014-11-03 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/util/virnuma.c | 15 ---
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 2540bd2..89435de 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -98,16 +98,13 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 int maxnode = 0;
 virBitmapPtr tmp_nodemask = NULL;
 
+if (!virNumaNodesetIsAvailable(numatune))
+return -1;
+
 tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
 if (!tmp_nodemask)
 return 0;
 
-if (numa_available() < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   "%s", _("Host kernel is not aware of NUMA."));
-return -1;
-}
-
 maxnode = numa_max_node();
 maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
 
@@ -347,12 +344,8 @@ int
 virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
  virBitmapPtr nodemask ATTRIBUTE_UNUSED)
 {
-if (virDomainNumatuneGetNodeset(numatune, NULL, -1)) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("libvirt is compiled without NUMA tuning support"));
-
+if (!virNumaNodesetIsAvailable(numatune))
 return -1;
-}
 
 return 0;
 }
-- 
1.9.3

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


[libvirt] [PATCH v5 1/3] bitmap: add virBitmapLastSetBit for finding the last bit position of bitmap

2014-11-03 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/libvirt_private.syms |  1 +
 src/util/virbitmap.c | 45 +
 src/util/virbitmap.h |  3 +++
 tests/virbitmaptest.c| 13 -
 4 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d63a8f0..1e2bc0a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1011,6 +1011,7 @@ virBitmapFree;
 virBitmapGetBit;
 virBitmapIsAllClear;
 virBitmapIsAllSet;
+virBitmapLastSetBit;
 virBitmapNew;
 virBitmapNewCopy;
 virBitmapNewData;
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
index b6bd074..04a2388 100644
--- a/src/util/virbitmap.c
+++ b/src/util/virbitmap.c
@@ -651,6 +651,51 @@ virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
 }
 
 /**
+ * virBitmapLastSetBit:
+ * @bitmap: the bitmap
+ *
+ * Search for the last set bit in bitmap @bitmap.
+ *
+ * Returns the position of the found bit, or -1 if no bit is set.
+ */
+ssize_t
+virBitmapLastSetBit(virBitmapPtr bitmap)
+{
+ssize_t i;
+int unusedBits;
+ssize_t sz;
+unsigned long bits;
+
+unusedBits = bitmap->map_len * VIR_BITMAP_BITS_PER_UNIT - bitmap->max_bit;
+
+sz = bitmap->map_len - 1;
+if (unusedBits > 0) {
+bits = bitmap->map[sz] & (VIR_BITMAP_BIT(VIR_BITMAP_BITS_PER_UNIT - 
unusedBits) - 1);
+if (bits != 0)
+goto found;
+
+sz--;
+}
+
+for (; sz >= 0; sz--) {
+bits = bitmap->map[sz];
+if (bits != 0)
+goto found;
+}
+
+if (bits == 0)
+return -1;
+
+ found:
+for (i = VIR_BITMAP_BITS_PER_UNIT - 1; i >= 0; i--) {
+if (bits & 1UL << i)
+return i + sz * VIR_BITMAP_BITS_PER_UNIT;
+}
+
+return -1;
+}
+
+/**
  * virBitmapNextClearBit:
  * @bitmap: the bitmap
  * @pos: the position after which to search for a clear bit
diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h
index 4493cc9..565264c 100644
--- a/src/util/virbitmap.h
+++ b/src/util/virbitmap.h
@@ -105,6 +105,9 @@ bool virBitmapIsAllClear(virBitmapPtr bitmap)
 ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
 ATTRIBUTE_NONNULL(1);
 
+ssize_t virBitmapLastSetBit(virBitmapPtr bitmap)
+ATTRIBUTE_NONNULL(1);
+
 ssize_t virBitmapNextClearBit(virBitmapPtr bitmap, ssize_t pos)
 ATTRIBUTE_NONNULL(1);
 
diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c
index ea832ad..ac5f298 100644
--- a/tests/virbitmaptest.c
+++ b/tests/virbitmaptest.c
@@ -171,7 +171,7 @@ test3(const void *data ATTRIBUTE_UNUSED)
 return ret;
 }
 
-/* test for virBitmapNextSetBit, virBitmapNextClearBit */
+/* test for virBitmapNextSetBit, virBitmapLastSetBit, virBitmapNextClearBit */
 static int
 test4(const void *data ATTRIBUTE_UNUSED)
 {
@@ -200,6 +200,9 @@ test4(const void *data ATTRIBUTE_UNUSED)
 if (virBitmapNextSetBit(bitmap, -1) != -1)
 goto error;
 
+if (virBitmapLastSetBit(bitmap) != -1)
+goto error;
+
 for (i = 0; i < size; i++) {
 if (virBitmapNextClearBit(bitmap, i - 1) != i)
 goto error;
@@ -232,6 +235,11 @@ test4(const void *data ATTRIBUTE_UNUSED)
 if (virBitmapNextSetBit(bitmap, i) != -1)
 goto error;
 
+j = sizeof(bitsPos)/sizeof(int) - 1;
+
+if (virBitmapLastSetBit(bitmap) != bitsPos[j])
+goto error;
+
 j = 0;
 i = -1;
 
@@ -255,6 +263,9 @@ test4(const void *data ATTRIBUTE_UNUSED)
 if (virBitmapNextSetBit(bitmap, i) != -1)
 goto error;
 
+if (virBitmapLastSetBit(bitmap) != size - 1)
+goto error;
+
 if (virBitmapNextClearBit(bitmap, -1) != -1)
 goto error;
 
-- 
1.9.3

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


[libvirt] [PATCH v5 0/3] add nodeset check in numatune

2014-11-03 Thread Chen Fan
when setting elements memnode and nodeset in attribute numatune more
than the host nodes in XML file, VM boot should fail. so add check for
that.

Chen Fan (3):
  bitmap: add virBitmapLastSetBit for finding the last bit position of
bitmap
  numatune: add check for numatune nodeset range
  virnuma: use virNumaNodesetIsAvailable checking nodeset in
virNumaSetupMemoryPolicy

 src/conf/numatune_conf.c   | 28 
 src/conf/numatune_conf.h   |  1 +
 src/libvirt_private.syms   |  2 +
 src/qemu/qemu_command.c|  4 ++
 src/util/virbitmap.c   | 45 ++
 src/util/virbitmap.h   |  3 ++
 src/util/virnuma.c | 53 +-
 src/util/virnuma.h |  1 +
 ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 35 ++
 tests/qemuxml2argvmock.c   |  9 
 tests/qemuxml2argvtest.c   |  2 +
 tests/virbitmaptest.c  | 13 +-
 12 files changed, 184 insertions(+), 12 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml

-- 
1.9.3

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


[libvirt] [PATCH v5 2/3] numatune: add check for numatune nodeset range

2014-11-03 Thread Chen Fan
There was no check for 'nodeset' attribute in numatune-related
elements.  This patch adds validation that any nodeset specified does
not exceed maximum host node.

Signed-off-by: Chen Fan 
---
 src/conf/numatune_conf.c   | 28 
 src/conf/numatune_conf.h   |  1 +
 src/libvirt_private.syms   |  1 +
 src/qemu/qemu_command.c|  4 +++
 src/util/virnuma.c | 38 ++
 src/util/virnuma.h |  1 +
 ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 35 
 tests/qemuxml2argvmock.c   |  9 +
 tests/qemuxml2argvtest.c   |  2 ++
 9 files changed, 119 insertions(+)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml

diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
index 21d9a64..6986739 100644
--- a/src/conf/numatune_conf.c
+++ b/src/conf/numatune_conf.c
@@ -612,3 +612,31 @@ virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr 
numatune)
 
 return false;
 }
+
+int
+virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune)
+{
+int ret = -1;
+virBitmapPtr nodemask = NULL;
+size_t i;
+int bit;
+
+if (!numatune)
+return ret;
+
+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1);
+if (nodemask)
+ret = virBitmapLastSetBit(nodemask);
+
+for (i = 0; i < numatune->nmem_nodes; i++) {
+nodemask = numatune->mem_nodes[i].nodeset;
+if (!nodemask)
+continue;
+
+bit = virBitmapLastSetBit(nodemask);
+if (bit > ret)
+ret = bit;
+}
+
+return ret;
+}
diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
index 5254629..15dc0d6 100644
--- a/src/conf/numatune_conf.h
+++ b/src/conf/numatune_conf.h
@@ -102,4 +102,5 @@ bool virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr 
numatune);
 
 bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
 
+int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune);
 #endif /* __NUMATUNE_CONF_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1e2bc0a..4a30ad7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1729,6 +1729,7 @@ virNumaGetPageInfo;
 virNumaGetPages;
 virNumaIsAvailable;
 virNumaNodeIsAvailable;
+virNumaNodesetIsAvailable;
 virNumaSetPagePoolSize;
 virNumaSetupMemoryPolicy;
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2e5af4f..d2c5f0c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -53,6 +53,7 @@
 #include "virstoragefile.h"
 #include "virtpm.h"
 #include "virscsi.h"
+#include "virnuma.h"
 #if defined(__linux__)
 # include 
 #endif
@@ -6663,6 +6664,9 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
 goto cleanup;
 }
 
+if (!virNumaNodesetIsAvailable(def->numatune))
+goto cleanup;
+
 for (i = 0; i < def->mem.nhugepages; i++) {
 ssize_t next_bit, pos = 0;
 
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 690615f..2540bd2 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -165,6 +165,33 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 return ret;
 }
 
+bool
+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
+{
+int maxnode;
+int bit;
+
+if (!numatune)
+return true;
+
+bit = virDomainNumatuneSpecifiedMaxNode(numatune);
+if (bit < 0)
+return true;
+
+if ((maxnode = virNumaGetMaxNode()) < 0)
+return false;
+
+maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
+if (bit > maxnode)
+goto error;
+
+return true;
+
+ error:
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("NUMA node %d is out of range"), bit);
+return false;
+}
 
 bool
 virNumaIsAvailable(void)
@@ -330,6 +357,17 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 return 0;
 }
 
+bool
+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
+{
+if (virDomainNumatuneSpecifiedMaxNode(numatune) >= 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("libvirt is compiled without NUMA tuning support"));
+return false;
+}
+
+return true;
+}
 
 bool
 virNumaIsAvailable(void)
diff --git a/src/util/virnuma.h b/src/util/virnuma.h
index 04b6b8c..5bb37b8 100644
--- a/src/util/virnuma.h
+++ b/src/util/virnuma.h
@@ -34,6 +34,7 @@ char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
 int virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
  virBitmapPtr nodemask);
 
+bool virNumaNodesetIsAvailable(virDomainNumatunePtr numatune);
 bool virNumaIsAvailable(void);
 in

Re: [libvirt] [PATCH v4 0/3] add nodeset check in numatune

2014-11-03 Thread Chen, Fan
On Mon, 2014-11-03 at 14:18 +0100, Martin Kletzander wrote: 
> On Thu, Oct 30, 2014 at 01:44:16PM +0800, Chen Fan wrote:
> >when setting elements memnode and nodeset in attribute numatune more
> >than the host nodes in XML file, VM boot should fail. so add check for
> >that.
> >
> 
> You should run "make syntax-check" and "make check" on those patches,
> it would find at least two things ;)
> 
> Anyway, ACK series with the changes I mentioned.  If you're OK with
> them, I'll push the series.

I will send a new series after change them.
and Thanks for your review.

Chen


> 
> Martin


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


Re: [libvirt] [PATCH v4 3/3] virnuma: use virNumaNodesetIsAvailable checking nodeset in virNumaSetupMemoryPolicy

2014-11-03 Thread Chen, Fan
On Mon, 2014-11-03 at 14:18 +0100, Martin Kletzander wrote: 
> On Thu, Oct 30, 2014 at 01:44:19PM +0800, Chen Fan wrote:
> >Signed-off-by: Chen Fan 
> >---
> > src/util/virnuma.c | 23 ---
> > 1 file changed, 4 insertions(+), 19 deletions(-)
> >
> >diff --git a/src/util/virnuma.c b/src/util/virnuma.c
> >index 4188ef5..613a43c 100644
> >--- a/src/util/virnuma.c
> >+++ b/src/util/virnuma.c
> >@@ -95,31 +95,19 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
> > int ret = -1;
> > int bit = 0;
> > size_t i;
> >-int maxnode = 0;
> > virBitmapPtr tmp_nodemask = NULL;
> >
> >+if (!virNumaNodesetIsAvailable(numatune))
> >+return -1;
> >+
> > tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
> > if (!tmp_nodemask)
> > return 0;
> >
> >-if (numa_available() < 0) {
> >-virReportError(VIR_ERR_INTERNAL_ERROR,
> >-   "%s", _("Host kernel is not aware of NUMA."));
> >-return -1;
> >-}
> >-
> >-maxnode = numa_max_node();
> >-maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
> >-
> > /* Convert nodemask to NUMA bitmask. */
> > nodemask_zero(&mask);
> > bit = -1;
> > while ((bit = virBitmapNextSetBit(tmp_nodemask, bit)) >= 0) {
> >-if (bit > maxnode) {
> >-virReportError(VIR_ERR_INTERNAL_ERROR,
> >-   _("NUMA node %d is out of range"), bit);
> >-return -1;
> >-}
> > nodemask_set(&mask, bit);
> > }
> >
> 
> I think this is safe, "numad" returning nodeset that's not on the host
> would be weird error and it is easy to find in the logs.
I think virNumaNodesetIsAvailable() has checked the case, but retain it 
here is ok.

> 
> >@@ -347,10 +335,7 @@ int
> > virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
> >  virBitmapPtr nodemask ATTRIBUTE_UNUSED)
> > {
> >-if (virDomainNumatuneGetNodeset(numatune, NULL, -1)) {
> >-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> >-   _("libvirt is compiled without NUMA tuning 
> >support"));
> >-
> >+if (!virNumaNodesetIsAvailable(numatune)) {
> > return -1;
> > }
> 
> This makes the square brackets obsolete.


Thanks,
Chen


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


Re: [libvirt] [PATCH v4 2/3] numatune: add check for numatune nodeset range

2014-11-03 Thread Chen, Fan
On Mon, 2014-11-03 at 14:18 +0100, Martin Kletzander wrote: 
> On Thu, Oct 30, 2014 at 01:44:18PM +0800, Chen Fan wrote:
> >There was no check for 'nodeset' attribute in numatune-related
> >elements.  This patch adds validation that any nodeset specified does
> >not exceed maximum host node.
> >
> >Signed-off-by: Chen Fan 
> >---
> > src/conf/numatune_conf.c   | 28 
> > src/conf/numatune_conf.h   |  1 +
> > src/libvirt_private.syms   |  1 +
> > src/qemu/qemu_command.c|  4 +++
> > src/util/virnuma.c | 38 
> > ++
> > src/util/virnuma.h |  1 +
> > ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 36 
> > tests/qemuxml2argvmock.c   |  9 +
> > tests/qemuxml2argvtest.c   |  1 +
> > 9 files changed, 119 insertions(+)
> > create mode 100644 
> > tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml
> >
> >diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
> >index 21d9a64..6986739 100644
> >--- a/src/conf/numatune_conf.c
> >+++ b/src/conf/numatune_conf.c
> >@@ -612,3 +612,31 @@ virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr 
> >numatune)
> >
> > return false;
> > }
> >+
> >+int
> >+virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune)
> >+{
> >+int ret = -1;
> >+virBitmapPtr nodemask = NULL;
> >+size_t i;
> >+int bit;
> >+
> >+if (!numatune)
> >+return ret;
> >+
> >+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1);
> >+if (nodemask)
> >+ret = virBitmapLastSetBit(nodemask);
> >+
> >+for (i = 0; i < numatune->nmem_nodes; i++) {
> >+nodemask = numatune->mem_nodes[i].nodeset;
> >+if (!nodemask)
> >+continue;
> >+
> >+bit = virBitmapLastSetBit(nodemask);
> >+if (bit > ret)
> >+ret = bit;
> >+}
> >+
> >+return ret;
> >+}
> >diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
> >index 5254629..15dc0d6 100644
> >--- a/src/conf/numatune_conf.h
> >+++ b/src/conf/numatune_conf.h
> >@@ -102,4 +102,5 @@ bool 
> >virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune);
> >
> > bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
> >
> >+int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune);
> > #endif /* __NUMATUNE_CONF_H__ */
> >diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> >index 1e2bc0a..4a30ad7 100644
> >--- a/src/libvirt_private.syms
> >+++ b/src/libvirt_private.syms
> >@@ -1729,6 +1729,7 @@ virNumaGetPageInfo;
> > virNumaGetPages;
> > virNumaIsAvailable;
> > virNumaNodeIsAvailable;
> >+virNumaNodesetIsAvailable;
> > virNumaSetPagePoolSize;
> > virNumaSetupMemoryPolicy;
> >
> >diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> >index 2e5af4f..d2c5f0c 100644
> >--- a/src/qemu/qemu_command.c
> >+++ b/src/qemu/qemu_command.c
> >@@ -53,6 +53,7 @@
> > #include "virstoragefile.h"
> > #include "virtpm.h"
> > #include "virscsi.h"
> >+#include "virnuma.h"
> > #if defined(__linux__)
> > # include 
> > #endif
> >@@ -6663,6 +6664,9 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
> > goto cleanup;
> > }
> >
> >+if (!virNumaNodesetIsAvailable(def->numatune))
> >+goto cleanup;
> >+
> > for (i = 0; i < def->mem.nhugepages; i++) {
> > ssize_t next_bit, pos = 0;
> >
> >diff --git a/src/util/virnuma.c b/src/util/virnuma.c
> >index 690615f..4188ef5 100644
> >--- a/src/util/virnuma.c
> >+++ b/src/util/virnuma.c
> >@@ -165,6 +165,33 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
> > return ret;
> > }
> >
> >+bool
> >+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
> >+{
> >+int maxnode;
> >+int bit;
> >+
> >+if (!numatune)
> >+return true;
> >+
> >+bit = virDomainNumatuneSpecifiedMaxNode(numatune);
> >+if (bit == -1)
> 
> (bit < 0) would go with the rest of the code, the functions can be
> then modified t

Re: [libvirt] [PATCH v4 1/3] bitmap: add virBitmapLastSetBit for finding the last bit position of bitmap

2014-11-03 Thread Chen, Fan
On Mon, 2014-11-03 at 14:18 +0100, Martin Kletzander wrote: 
> On Thu, Oct 30, 2014 at 01:44:17PM +0800, Chen Fan wrote:
> >Signed-off-by: Chen Fan 
> >---
> > src/libvirt_private.syms |  1 +
> > src/util/virbitmap.c | 45 +
> > src/util/virbitmap.h |  3 +++
> > tests/virbitmaptest.c| 13 -
> > 4 files changed, 61 insertions(+), 1 deletion(-)
> >
> >diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> >index d63a8f0..1e2bc0a 100644
> >--- a/src/libvirt_private.syms
> >+++ b/src/libvirt_private.syms
> >@@ -1011,6 +1011,7 @@ virBitmapFree;
> > virBitmapGetBit;
> > virBitmapIsAllClear;
> > virBitmapIsAllSet;
> >+virBitmapLastSetBit;
> > virBitmapNew;
> > virBitmapNewCopy;
> > virBitmapNewData;
> >diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
> >index b6bd074..3e7269e 100644
> >--- a/src/util/virbitmap.c
> >+++ b/src/util/virbitmap.c
> >@@ -651,6 +651,51 @@ virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
> > }
> >
> > /**
> >+ * virBitmapLastSetBit:
> >+ * @bitmap: the bitmap
> >+ *
> >+ * Search for the last set bit in bitmap @bitmap.
> >+ *
> >+ * Returns the position of the found bit, or -1 if no bit found.
> 
> s/found/is set/
> 
> >+ */
> >+ssize_t
> >+virBitmapLastSetBit(virBitmapPtr bitmap)
> >+{
> >+ssize_t i;
> >+int unusedBits;
> >+ssize_t sz;
> >+unsigned long bits;
> >+
> >+unusedBits = bitmap->map_len * VIR_BITMAP_BITS_PER_UNIT - 
> >bitmap->max_bit;
> >+
> >+sz = bitmap->map_len - 1;
> >+if (unusedBits > 0) {
> >+bits = bitmap->map[sz] & (VIR_BITMAP_BIT(VIR_BITMAP_BITS_PER_UNIT - 
> >unusedBits) - 1);
> >+if (bits != 0)
> >+goto found;
> >+
> >+sz--;
> >+}
> >+
> >+for (; sz >= 0; sz--) {
> >+bits = bitmap->map[sz];
> >+if (bits != 0)
> >+goto found;
> >+}
> >+
> >+if (bits == 0)
> >+return -1;
> >+
> >+found:
> 
> Missing space before label.  "make syntax-check" would tell you that
> instead of me ;)

Thanks for your remind. I will do that.

Chen


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


Re: [libvirt] [PATCH v3 1/3] numatune: add check for numatune nodeset range

2014-10-30 Thread Chen, Fan
On Thu, 2014-10-30 at 07:55 +0100, Martin Kletzander wrote: 
> On Thu, Oct 30, 2014 at 02:23:00AM +0000, Chen, Fan wrote:
> >On Wed, 2014-10-29 at 14:20 +0100, Martin Kletzander wrote:
> >> On Wed, Oct 29, 2014 at 08:33:32PM +0800, Chen Fan wrote:
> >> >diff --git a/src/util/virnuma.c b/src/util/virnuma.c
> >> >@@ -373,6 +400,12 @@ virNumaGetNodeCPUs(int node ATTRIBUTE_UNUSED,
> >> >_("NUMA isn't available on this host"));
> >> > return -1;
> >> > }
> >> >+
> >> >+bool
> >> >+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
> >> >+{
> >> >+return true;
> >> >+}
> >> > #endif
> >> >
> >>
> >> In what case would you like this to return true?
> >
> >when libvirt does not support numa, we can not check it.
> >maybe we should return false if setting nodeset.
> >
> 
> That was my idea, I just wanted to make sure we're on the same page.
> The thing is that if you want something that's not available, it makes
> more sense to say "NO" then just allow it because libvirt doesn't
> know.  Make the user fix it :)
Yes, I had made a v4 and sent it, please help to review.

Thanks,
Chen

> 
> Martin


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


[libvirt] [PATCH v4 3/3] virnuma: use virNumaNodesetIsAvailable checking nodeset in virNumaSetupMemoryPolicy

2014-10-29 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/util/virnuma.c | 23 ---
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 4188ef5..613a43c 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -95,31 +95,19 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 int ret = -1;
 int bit = 0;
 size_t i;
-int maxnode = 0;
 virBitmapPtr tmp_nodemask = NULL;
 
+if (!virNumaNodesetIsAvailable(numatune))
+return -1;
+
 tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
 if (!tmp_nodemask)
 return 0;
 
-if (numa_available() < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   "%s", _("Host kernel is not aware of NUMA."));
-return -1;
-}
-
-maxnode = numa_max_node();
-maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
-
 /* Convert nodemask to NUMA bitmask. */
 nodemask_zero(&mask);
 bit = -1;
 while ((bit = virBitmapNextSetBit(tmp_nodemask, bit)) >= 0) {
-if (bit > maxnode) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("NUMA node %d is out of range"), bit);
-return -1;
-}
 nodemask_set(&mask, bit);
 }
 
@@ -347,10 +335,7 @@ int
 virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
  virBitmapPtr nodemask ATTRIBUTE_UNUSED)
 {
-if (virDomainNumatuneGetNodeset(numatune, NULL, -1)) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("libvirt is compiled without NUMA tuning support"));
-
+if (!virNumaNodesetIsAvailable(numatune)) {
 return -1;
 }
 
-- 
1.9.3

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


[libvirt] [PATCH v4 2/3] numatune: add check for numatune nodeset range

2014-10-29 Thread Chen Fan
There was no check for 'nodeset' attribute in numatune-related
elements.  This patch adds validation that any nodeset specified does
not exceed maximum host node.

Signed-off-by: Chen Fan 
---
 src/conf/numatune_conf.c   | 28 
 src/conf/numatune_conf.h   |  1 +
 src/libvirt_private.syms   |  1 +
 src/qemu/qemu_command.c|  4 +++
 src/util/virnuma.c | 38 ++
 src/util/virnuma.h |  1 +
 ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 36 
 tests/qemuxml2argvmock.c   |  9 +
 tests/qemuxml2argvtest.c   |  1 +
 9 files changed, 119 insertions(+)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml

diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
index 21d9a64..6986739 100644
--- a/src/conf/numatune_conf.c
+++ b/src/conf/numatune_conf.c
@@ -612,3 +612,31 @@ virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr 
numatune)
 
 return false;
 }
+
+int
+virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune)
+{
+int ret = -1;
+virBitmapPtr nodemask = NULL;
+size_t i;
+int bit;
+
+if (!numatune)
+return ret;
+
+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1);
+if (nodemask)
+ret = virBitmapLastSetBit(nodemask);
+
+for (i = 0; i < numatune->nmem_nodes; i++) {
+nodemask = numatune->mem_nodes[i].nodeset;
+if (!nodemask)
+continue;
+
+bit = virBitmapLastSetBit(nodemask);
+if (bit > ret)
+ret = bit;
+}
+
+return ret;
+}
diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
index 5254629..15dc0d6 100644
--- a/src/conf/numatune_conf.h
+++ b/src/conf/numatune_conf.h
@@ -102,4 +102,5 @@ bool virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr 
numatune);
 
 bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
 
+int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune);
 #endif /* __NUMATUNE_CONF_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1e2bc0a..4a30ad7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1729,6 +1729,7 @@ virNumaGetPageInfo;
 virNumaGetPages;
 virNumaIsAvailable;
 virNumaNodeIsAvailable;
+virNumaNodesetIsAvailable;
 virNumaSetPagePoolSize;
 virNumaSetupMemoryPolicy;
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2e5af4f..d2c5f0c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -53,6 +53,7 @@
 #include "virstoragefile.h"
 #include "virtpm.h"
 #include "virscsi.h"
+#include "virnuma.h"
 #if defined(__linux__)
 # include 
 #endif
@@ -6663,6 +6664,9 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
 goto cleanup;
 }
 
+if (!virNumaNodesetIsAvailable(def->numatune))
+goto cleanup;
+
 for (i = 0; i < def->mem.nhugepages; i++) {
 ssize_t next_bit, pos = 0;
 
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 690615f..4188ef5 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -165,6 +165,33 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 return ret;
 }
 
+bool
+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
+{
+int maxnode;
+int bit;
+
+if (!numatune)
+return true;
+
+bit = virDomainNumatuneSpecifiedMaxNode(numatune);
+if (bit == -1)
+return true;
+
+if ((maxnode = virNumaGetMaxNode()) < 0)
+return false;
+
+maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
+if (bit > maxnode)
+goto error;
+
+return true;
+
+ error:
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("NUMA node %d is out of range"), bit);
+return false;
+}
 
 bool
 virNumaIsAvailable(void)
@@ -330,6 +357,17 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 return 0;
 }
 
+bool
+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
+{
+if (virDomainNumatuneSpecifiedMaxNode(numatune) != -1) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("libvirt is compiled without NUMA tuning support"));
+return false;
+}
+
+return true;
+}
 
 bool
 virNumaIsAvailable(void)
diff --git a/src/util/virnuma.h b/src/util/virnuma.h
index 04b6b8c..5bb37b8 100644
--- a/src/util/virnuma.h
+++ b/src/util/virnuma.h
@@ -34,6 +34,7 @@ char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
 int virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
  virBitmapPtr nodemask);
 
+bool virNumaNodesetIsAvailable(virDomainNumatunePtr numatune);
 bool virNumaIsAvailable(void);
 int virN

[libvirt] [PATCH v4 1/3] bitmap: add virBitmapLastSetBit for finding the last bit position of bitmap

2014-10-29 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/libvirt_private.syms |  1 +
 src/util/virbitmap.c | 45 +
 src/util/virbitmap.h |  3 +++
 tests/virbitmaptest.c| 13 -
 4 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d63a8f0..1e2bc0a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1011,6 +1011,7 @@ virBitmapFree;
 virBitmapGetBit;
 virBitmapIsAllClear;
 virBitmapIsAllSet;
+virBitmapLastSetBit;
 virBitmapNew;
 virBitmapNewCopy;
 virBitmapNewData;
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
index b6bd074..3e7269e 100644
--- a/src/util/virbitmap.c
+++ b/src/util/virbitmap.c
@@ -651,6 +651,51 @@ virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
 }
 
 /**
+ * virBitmapLastSetBit:
+ * @bitmap: the bitmap
+ *
+ * Search for the last set bit in bitmap @bitmap.
+ *
+ * Returns the position of the found bit, or -1 if no bit found.
+ */
+ssize_t
+virBitmapLastSetBit(virBitmapPtr bitmap)
+{
+ssize_t i;
+int unusedBits;
+ssize_t sz;
+unsigned long bits;
+
+unusedBits = bitmap->map_len * VIR_BITMAP_BITS_PER_UNIT - bitmap->max_bit;
+
+sz = bitmap->map_len - 1;
+if (unusedBits > 0) {
+bits = bitmap->map[sz] & (VIR_BITMAP_BIT(VIR_BITMAP_BITS_PER_UNIT - 
unusedBits) - 1);
+if (bits != 0)
+goto found;
+
+sz--;
+}
+
+for (; sz >= 0; sz--) {
+bits = bitmap->map[sz];
+if (bits != 0)
+goto found;
+}
+
+if (bits == 0)
+return -1;
+
+found:
+for (i = VIR_BITMAP_BITS_PER_UNIT - 1; i >= 0; i--) {
+if (bits & 1UL << i)
+return i + sz * VIR_BITMAP_BITS_PER_UNIT;
+}
+
+return -1;
+}
+
+/**
  * virBitmapNextClearBit:
  * @bitmap: the bitmap
  * @pos: the position after which to search for a clear bit
diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h
index 4493cc9..565264c 100644
--- a/src/util/virbitmap.h
+++ b/src/util/virbitmap.h
@@ -105,6 +105,9 @@ bool virBitmapIsAllClear(virBitmapPtr bitmap)
 ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
 ATTRIBUTE_NONNULL(1);
 
+ssize_t virBitmapLastSetBit(virBitmapPtr bitmap)
+ATTRIBUTE_NONNULL(1);
+
 ssize_t virBitmapNextClearBit(virBitmapPtr bitmap, ssize_t pos)
 ATTRIBUTE_NONNULL(1);
 
diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c
index ea832ad..ac5f298 100644
--- a/tests/virbitmaptest.c
+++ b/tests/virbitmaptest.c
@@ -171,7 +171,7 @@ test3(const void *data ATTRIBUTE_UNUSED)
 return ret;
 }
 
-/* test for virBitmapNextSetBit, virBitmapNextClearBit */
+/* test for virBitmapNextSetBit, virBitmapLastSetBit, virBitmapNextClearBit */
 static int
 test4(const void *data ATTRIBUTE_UNUSED)
 {
@@ -200,6 +200,9 @@ test4(const void *data ATTRIBUTE_UNUSED)
 if (virBitmapNextSetBit(bitmap, -1) != -1)
 goto error;
 
+if (virBitmapLastSetBit(bitmap) != -1)
+goto error;
+
 for (i = 0; i < size; i++) {
 if (virBitmapNextClearBit(bitmap, i - 1) != i)
 goto error;
@@ -232,6 +235,11 @@ test4(const void *data ATTRIBUTE_UNUSED)
 if (virBitmapNextSetBit(bitmap, i) != -1)
 goto error;
 
+j = sizeof(bitsPos)/sizeof(int) - 1;
+
+if (virBitmapLastSetBit(bitmap) != bitsPos[j])
+goto error;
+
 j = 0;
 i = -1;
 
@@ -255,6 +263,9 @@ test4(const void *data ATTRIBUTE_UNUSED)
 if (virBitmapNextSetBit(bitmap, i) != -1)
 goto error;
 
+if (virBitmapLastSetBit(bitmap) != size - 1)
+goto error;
+
 if (virBitmapNextClearBit(bitmap, -1) != -1)
 goto error;
 
-- 
1.9.3

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


[libvirt] [PATCH v4 0/3] add nodeset check in numatune

2014-10-29 Thread Chen Fan
when setting elements memnode and nodeset in attribute numatune more
than the host nodes in XML file, VM boot should fail. so add check for
that.

Chen Fan (3):
  bitmap: add virBitmapLastSetBit for finding the last bit position of
bitmap
  numatune: add check for numatune nodeset range
  virnuma: use virNumaNodesetIsAvailable checking nodeset in
virNumaSetupMemoryPolicy

 src/conf/numatune_conf.c   | 28 ++
 src/conf/numatune_conf.h   |  1 +
 src/libvirt_private.syms   |  2 +
 src/qemu/qemu_command.c|  4 ++
 src/util/virbitmap.c   | 45 
 src/util/virbitmap.h   |  3 ++
 src/util/virnuma.c | 61 +++---
 src/util/virnuma.h |  1 +
 ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 36 +
 tests/qemuxml2argvmock.c   |  9 
 tests/qemuxml2argvtest.c   |  1 +
 tests/virbitmaptest.c  | 13 -
 12 files changed, 184 insertions(+), 20 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml

-- 
1.9.3

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


Re: [libvirt] [PATCH v3 1/3] numatune: add check for numatune nodeset range

2014-10-29 Thread Chen, Fan
On Wed, 2014-10-29 at 14:20 +0100, Martin Kletzander wrote: 
> On Wed, Oct 29, 2014 at 08:33:32PM +0800, Chen Fan wrote:
> >For memnode in numatune element, the range of attribute 'nodeset'
> >was not validated. on my host maxnodes was 1, but when setting nodeset
> >to '0-2' or more, guest also started succuss. there probably was qemu's
> >bug too.
> >
> 
> How about rewording this as:
> 
> There was no check for 'nodeset' attribute in numatune-related
> elements.  This patch adds validation that any nodeset specified does
> not exceed maximum host node.

Look good to me.

> 
> >Signed-off-by: Chen Fan 
> >---
> > src/conf/numatune_conf.c   | 28 +
> > src/conf/numatune_conf.h   |  1 +
> > src/libvirt_private.syms   |  2 +
> > src/qemu/qemu_command.c|  3 ++
> > src/qemu/qemu_command.h|  1 +
> > src/util/virbitmap.c   | 49 
> > ++
> > src/util/virbitmap.h   |  3 ++
> > src/util/virnuma.c | 33 +++
> > src/util/virnuma.h |  2 +
> > ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 35 
> > tests/qemuxml2argvmock.c   |  9 
> > tests/qemuxml2argvtest.c   |  1 +
> > tests/virbitmaptest.c  | 26 +++-
> > 13 files changed, 192 insertions(+), 1 deletion(-)
> > create mode 100644 
> > tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml
> >
> >diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
> >index 21d9a64..54f309a 100644
> >--- a/src/conf/numatune_conf.c
> >+++ b/src/conf/numatune_conf.c
> >@@ -612,3 +612,31 @@ virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr 
> >numatune)
> >
> > return false;
> > }
> >+
> >+int
> >+virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune)
> >+{
> >+int ret = -1;
> >+virBitmapPtr nodemask = NULL;
> >+size_t i;
> >+
> >+if (!numatune)
> >+return ret;
> >+
> >+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1);
> >+if (nodemask) {
> >+ret = virBitmapLastSetBit(nodemask, -1);
> >+}
> >+for (i = 0; i < numatune->nmem_nodes; i++) {
> 
> Well, you're using the advantage of accessible structure members here
> (numatune->nmem_nodes), but using accessors around.  These particular
> ones are useless here when you don't need any of the logic they
> provide.
right, I should use numatune->mem_nodes[i].nodeset directly.

> 
> >+int bit = -1;
> >+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, i);
> >+if (!nodemask)
> >+continue;
> >+
> >+bit = virBitmapLastSetBit(nodemask, -1);
> >+if (bit > ret)
> >+ret = bit;
> >+}
> >+
> >+return ret;
> >+}
> >diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
> >index 5254629..15dc0d6 100644
> >--- a/src/conf/numatune_conf.h
> >+++ b/src/conf/numatune_conf.h
> >@@ -102,4 +102,5 @@ bool 
> >virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune);
> >
> > bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
> >
> >+int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune);
> > #endif /* __NUMATUNE_CONF_H__ */
> >diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> >index d63a8f0..4a30ad7 100644
> >--- a/src/libvirt_private.syms
> >+++ b/src/libvirt_private.syms
> >@@ -1011,6 +1011,7 @@ virBitmapFree;
> > virBitmapGetBit;
> > virBitmapIsAllClear;
> > virBitmapIsAllSet;
> >+virBitmapLastSetBit;
> > virBitmapNew;
> > virBitmapNewCopy;
> > virBitmapNewData;
> >@@ -1728,6 +1729,7 @@ virNumaGetPageInfo;
> > virNumaGetPages;
> > virNumaIsAvailable;
> > virNumaNodeIsAvailable;
> >+virNumaNodesetIsAvailable;
> > virNumaSetPagePoolSize;
> > virNumaSetupMemoryPolicy;
> >
> >diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> >index 2e5af4f..9757d3e 100644
> >--- a/src/qemu/qemu_command.c
> >+++ b/src/qemu/qemu_command.c
> >@@ -6663,6 +6663,9 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
> > goto cleanup;

Re: [libvirt] [PATCH v3 3/3] virnuma: remove redundant check for numanode

2014-10-29 Thread Chen, Fan
On Wed, 2014-10-29 at 14:23 +0100, Martin Kletzander wrote: 
> On Wed, Oct 29, 2014 at 08:33:34PM +0800, Chen Fan wrote:
> >Signed-off-by: Chen Fan 
> >---
> > src/util/virnuma.c | 15 ---
> > 1 file changed, 15 deletions(-)
> >
> 
> I think this harmless check may prevent future problems (if
> SetupMemoryPolicy is called from some new codepath.  Either keep it
> here or call virNumaNodesetIsAvailable() in the start of the function.
call virNumaNodesetIsAvailable() in the start of the function will be 
fine.

Thanks,
Chen

> 
> >diff --git a/src/util/virnuma.c b/src/util/virnuma.c
> >index fbe8fd1..5a08049 100644
> >--- a/src/util/virnuma.c
> >+++ b/src/util/virnuma.c
> >@@ -95,31 +95,16 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
> > int ret = -1;
> > int bit = 0;
> > size_t i;
> >-int maxnode = 0;
> > virBitmapPtr tmp_nodemask = NULL;
> >
> > tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
> > if (!tmp_nodemask)
> > return 0;
> >
> >-if (numa_available() < 0) {
> >-virReportError(VIR_ERR_INTERNAL_ERROR,
> >-   "%s", _("Host kernel is not aware of NUMA."));
> >-return -1;
> >-}
> >-
> >-maxnode = numa_max_node();
> >-maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
> >-
> > /* Convert nodemask to NUMA bitmask. */
> > nodemask_zero(&mask);
> > bit = -1;
> > while ((bit = virBitmapNextSetBit(tmp_nodemask, bit)) >= 0) {
> >-if (bit > maxnode) {
> >-virReportError(VIR_ERR_INTERNAL_ERROR,
> >-   _("NUMA node %d is out of range"), bit);
> >-return -1;
> >-}
> > nodemask_set(&mask, bit);
> > }
> >
> >--
> >1.9.3
> >


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


[libvirt] [PATCH v3 3/3] virnuma: remove redundant check for numanode

2014-10-29 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/util/virnuma.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index fbe8fd1..5a08049 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -95,31 +95,16 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 int ret = -1;
 int bit = 0;
 size_t i;
-int maxnode = 0;
 virBitmapPtr tmp_nodemask = NULL;
 
 tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
 if (!tmp_nodemask)
 return 0;
 
-if (numa_available() < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   "%s", _("Host kernel is not aware of NUMA."));
-return -1;
-}
-
-maxnode = numa_max_node();
-maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
-
 /* Convert nodemask to NUMA bitmask. */
 nodemask_zero(&mask);
 bit = -1;
 while ((bit = virBitmapNextSetBit(tmp_nodemask, bit)) >= 0) {
-if (bit > maxnode) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("NUMA node %d is out of range"), bit);
-return -1;
-}
 nodemask_set(&mask, bit);
 }
 
-- 
1.9.3

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


[libvirt] [PATCH v3 1/3] numatune: add check for numatune nodeset range

2014-10-29 Thread Chen Fan
For memnode in numatune element, the range of attribute 'nodeset'
was not validated. on my host maxnodes was 1, but when setting nodeset
to '0-2' or more, guest also started succuss. there probably was qemu's
bug too.

Signed-off-by: Chen Fan 
---
 src/conf/numatune_conf.c   | 28 +
 src/conf/numatune_conf.h   |  1 +
 src/libvirt_private.syms   |  2 +
 src/qemu/qemu_command.c|  3 ++
 src/qemu/qemu_command.h|  1 +
 src/util/virbitmap.c   | 49 ++
 src/util/virbitmap.h   |  3 ++
 src/util/virnuma.c | 33 +++
 src/util/virnuma.h |  2 +
 ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 35 
 tests/qemuxml2argvmock.c   |  9 
 tests/qemuxml2argvtest.c   |  1 +
 tests/virbitmaptest.c  | 26 +++-
 13 files changed, 192 insertions(+), 1 deletion(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml

diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
index 21d9a64..54f309a 100644
--- a/src/conf/numatune_conf.c
+++ b/src/conf/numatune_conf.c
@@ -612,3 +612,31 @@ virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr 
numatune)
 
 return false;
 }
+
+int
+virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune)
+{
+int ret = -1;
+virBitmapPtr nodemask = NULL;
+size_t i;
+
+if (!numatune)
+return ret;
+
+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1);
+if (nodemask) {
+ret = virBitmapLastSetBit(nodemask, -1);
+}
+for (i = 0; i < numatune->nmem_nodes; i++) {
+int bit = -1;
+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, i);
+if (!nodemask)
+continue;
+
+bit = virBitmapLastSetBit(nodemask, -1);
+if (bit > ret)
+ret = bit;
+}
+
+return ret;
+}
diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
index 5254629..15dc0d6 100644
--- a/src/conf/numatune_conf.h
+++ b/src/conf/numatune_conf.h
@@ -102,4 +102,5 @@ bool virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr 
numatune);
 
 bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
 
+int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune);
 #endif /* __NUMATUNE_CONF_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d63a8f0..4a30ad7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1011,6 +1011,7 @@ virBitmapFree;
 virBitmapGetBit;
 virBitmapIsAllClear;
 virBitmapIsAllSet;
+virBitmapLastSetBit;
 virBitmapNew;
 virBitmapNewCopy;
 virBitmapNewData;
@@ -1728,6 +1729,7 @@ virNumaGetPageInfo;
 virNumaGetPages;
 virNumaIsAvailable;
 virNumaNodeIsAvailable;
+virNumaNodesetIsAvailable;
 virNumaSetPagePoolSize;
 virNumaSetupMemoryPolicy;
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2e5af4f..9757d3e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6663,6 +6663,9 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
 goto cleanup;
 }
 
+if (!virNumaNodesetIsAvailable(def->numatune))
+goto cleanup;
+
 for (i = 0; i < def->mem.nhugepages; i++) {
 ssize_t next_bit, pos = 0;
 
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index aa40c9e..f263665 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -27,6 +27,7 @@
 # include "domain_addr.h"
 # include "domain_conf.h"
 # include "vircommand.h"
+# include "virnuma.h"
 # include "capabilities.h"
 # include "qemu_conf.h"
 # include "qemu_domain.h"
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
index b6bd074..aed525a 100644
--- a/src/util/virbitmap.c
+++ b/src/util/virbitmap.c
@@ -651,6 +651,55 @@ virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
 }
 
 /**
+ * virBitmapLastSetBit:
+ * @bitmap: the bitmap
+ * @pos: the position after which to search for a set bit
+ *
+ * Search for the last set bit before position @pos in bitmap @bitmap.
+ * @pos can be -1 to search for the last set bit. Position starts
+ * at max_bit.
+ *
+ * Returns the position of the found bit, or -1 if no bit found.
+ */
+ssize_t
+virBitmapLastSetBit(virBitmapPtr bitmap, ssize_t pos)
+{
+size_t nl;
+size_t nb;
+unsigned long bits;
+size_t i;
+
+if (pos < 0)
+pos = bitmap->max_bit;
+
+pos--;
+
+if (pos >= bitmap->max_bit)
+return -1;
+
+nl = pos / VIR_BITMAP_BITS_PER_UNIT;
+nb = pos % VIR_BITMAP_BITS_PER_UNIT;
+
+bits = bitmap->map[nl] & ((1UL << (nb + 1)) -

[libvirt] [PATCH v3 0/3] add nodeset check in numatune

2014-10-29 Thread Chen Fan
when setting elements memnode and nodeset in attribute numatune more
than the host nodes in XML file, VM boot should fail. so add check for
that.

Chen Fan (3):
  numatune: add check for numatune nodeset range
  lxc controller: add check for numatune
  virnuma: remove redundant check for numanode

 src/conf/numatune_conf.c   | 28 +
 src/conf/numatune_conf.h   |  1 +
 src/libvirt_private.syms   |  2 +
 src/lxc/lxc_controller.c   |  1 +
 src/qemu/qemu_command.c|  3 ++
 src/qemu/qemu_command.h|  1 +
 src/util/virbitmap.c   | 49 ++
 src/util/virbitmap.h   |  3 ++
 src/util/virnuma.c | 48 ++---
 src/util/virnuma.h |  2 +
 ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 35 
 tests/qemuxml2argvmock.c   |  9 
 tests/qemuxml2argvtest.c   |  1 +
 tests/virbitmaptest.c  | 26 +++-
 14 files changed, 193 insertions(+), 16 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml

-- 
1.9.3

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


[libvirt] [PATCH v3 2/3] lxc controller: add check for numatune

2014-10-29 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/lxc/lxc_controller.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 1861dd6..a23dff7 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -689,6 +689,7 @@ static int 
virLXCControllerSetupResourceLimits(virLXCControllerPtr ctrl)
 int ret = -1;
 
 if (virLXCControllerGetNumadAdvice(ctrl, &nodemask) < 0 ||
+!virNumaNodesetIsAvailable (ctrl->def->numatune) ||
 virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0)
 goto cleanup;
 
-- 
1.9.3

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


Re: [libvirt] [PATCH v2 1/3] numatune: add check for numatune nodeset range

2014-10-29 Thread Chen, Fan
On Wed, 2014-10-29 at 07:58 +0100, Martin Kletzander wrote: 
> On Tue, Oct 28, 2014 at 04:22:21PM +0800, Chen Fan wrote:
> >For memnode in numatune element, the range of attribute 'nodeset'
> >was not validated. on my host maxnodes was 1, but when setting nodeset
> >to '0-2' or more, guest also started succuss. there probably was qemu's
> >bug too.
> >
> >Signed-off-by: Chen Fan 
> >---
> > src/conf/numatune_conf.c   | 21 -
> > src/conf/numatune_conf.h   | 19 
> > src/libvirt_private.syms   |  1 +
> > src/qemu/qemu_command.c|  3 ++
> > src/qemu/qemu_command.h|  1 +
> > src/util/virnuma.c | 55 
> > ++
> > src/util/virnuma.h |  2 +
> > ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 35 ++
> > tests/qemuxml2argvmock.c   |  9 
> > tests/qemuxml2argvtest.c   |  1 +
> > 10 files changed, 126 insertions(+), 21 deletions(-)
> > create mode 100644 
> > tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml
> >
> >diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
> >index 21d9a64..d440b86 100644
> >--- a/src/conf/numatune_conf.c
> >+++ b/src/conf/numatune_conf.c
> >@@ -42,27 +42,6 @@ VIR_ENUM_IMPL(virDomainNumatunePlacement,
> >   "static",
> >   "auto");
> >
> >-typedef struct _virDomainNumatuneNode virDomainNumatuneNode;
> >-typedef virDomainNumatuneNode *virDomainNumatuneNodePtr;
> >-
> >-struct _virDomainNumatune {
> >-struct {
> >-bool specified;
> >-virBitmapPtr nodeset;
> >-virDomainNumatuneMemMode mode;
> >-virDomainNumatunePlacement placement;
> >-} memory;   /* pinning for all the memory */
> >-
> >-struct _virDomainNumatuneNode {
> >-virBitmapPtr nodeset;
> >-virDomainNumatuneMemMode mode;
> >-} *mem_nodes;   /* fine tuning per guest node */
> >-size_t nmem_nodes;
> >-
> >-/* Future NUMA tuning related stuff should go here. */
> >-};
> >-
> >-
> > static inline bool
> > virDomainNumatuneNodeSpecified(virDomainNumatunePtr numatune,
> >int cellid)
> >diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
> >index 5254629..650b6e7 100644
> >--- a/src/conf/numatune_conf.h
> >+++ b/src/conf/numatune_conf.h
> >@@ -45,6 +45,25 @@ typedef enum {
> > VIR_ENUM_DECL(virDomainNumatunePlacement)
> > VIR_ENUM_DECL(virDomainNumatuneMemMode)
> >
> >+typedef struct _virDomainNumatuneNode virDomainNumatuneNode;
> >+typedef virDomainNumatuneNode *virDomainNumatuneNodePtr;
> >+
> >+struct _virDomainNumatune {
> >+struct {
> >+bool specified;
> >+virBitmapPtr nodeset;
> >+virDomainNumatuneMemMode mode;
> >+virDomainNumatunePlacement placement;
> >+} memory;   /* pinning for all the memory */
> >+
> >+struct _virDomainNumatuneNode {
> >+virBitmapPtr nodeset;
> >+virDomainNumatuneMemMode mode;
> >+} *mem_nodes;   /* fine tuning per guest node */
> >+size_t nmem_nodes;
> >+
> >+/* Future NUMA tuning related stuff should go here. */
> >+};
> >
> > void virDomainNumatuneFree(virDomainNumatunePtr numatune);
> >
> 
> NACK to these two hunks.  The point of the structure being hidden in
> the .c file was to abstract it.  You can provide accessors to those
> members you need if they are not available already.

Got it!

> 
> >diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> >index d63a8f0..16a5864 100644
> >--- a/src/libvirt_private.syms
> >+++ b/src/libvirt_private.syms
> >@@ -1728,6 +1728,7 @@ virNumaGetPageInfo;
> > virNumaGetPages;
> > virNumaIsAvailable;
> > virNumaNodeIsAvailable;
> >+virNumaNodesetIsAvailable;
> > virNumaSetPagePoolSize;
> > virNumaSetupMemoryPolicy;
> >
> >diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> >index 2e5af4f..9757d3e 100644
> >--- a/src/qemu/qemu_command.c
> >+++ b/src/qemu/qemu_command.c
> >@@ -6663,6 +6663,9 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
> > goto cleanup;
> > }
> >
> >+if (

Re: [libvirt] [PATCH v2 2/3] lxc controller: add check for numatune

2014-10-29 Thread Chen, Fan
On Wed, 2014-10-29 at 08:00 +0100, Martin Kletzander wrote: 
> On Tue, Oct 28, 2014 at 04:22:22PM +0800, Chen Fan wrote:
> >Signed-off-by: Chen Fan 
> >---
> > src/lxc/lxc_controller.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> >diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
> >index 1861dd6..1ee89ab 100644
> >--- a/src/lxc/lxc_controller.c
> >+++ b/src/lxc/lxc_controller.c
> >@@ -689,7 +689,8 @@ static int 
> >virLXCControllerSetupResourceLimits(virLXCControllerPtr ctrl)
> > int ret = -1;
> >
> > if (virLXCControllerGetNumadAdvice(ctrl, &nodemask) < 0 ||
> >-virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0)
> >+(virNumaNodesetIsAvailable (ctrl->def->numatune) &&
> >+ virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0))
> > goto cleanup;
> >
> 
> This would mean it will succeed if the numa node is not available on
> the host.  Don't you want to error out?  By the way, it would make
> sense to make the check in virNumaSetupMemoryPolicy() itself.

Oh, you are right. As for output because virNumaNodesetIsAvailable is
self error output. so I think it not necessary.

I think the check
!virNumaNodesetIsAvailable (ctrl->def->numatune) ||
  virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0
would be OK.

Thanks,
Chen

> 
> Martin


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


[libvirt] [PATCH v2 2/3] lxc controller: add check for numatune

2014-10-28 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/lxc/lxc_controller.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 1861dd6..1ee89ab 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -689,7 +689,8 @@ static int 
virLXCControllerSetupResourceLimits(virLXCControllerPtr ctrl)
 int ret = -1;
 
 if (virLXCControllerGetNumadAdvice(ctrl, &nodemask) < 0 ||
-virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0)
+(virNumaNodesetIsAvailable (ctrl->def->numatune) &&
+ virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0))
 goto cleanup;
 
 if (virLXCControllerSetupCpuAffinity(ctrl) < 0)
-- 
1.9.3

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


[libvirt] [PATCH v2 0/3] add nodeset check in numatune

2014-10-28 Thread Chen Fan
when setting elements memnode and nodeset in attribute numatune more
than the host nodes in XML file, VM boot should fail. so add check for
that.

Chen Fan (3):
  numatune: add check for numatune nodeset range
  lxc controller: add check for numatune
  virnuma: remove redundant check for numanode

 src/conf/numatune_conf.c   | 21 ---
 src/conf/numatune_conf.h   | 19 ++
 src/libvirt_private.syms   |  1 +
 src/lxc/lxc_controller.c   |  3 +-
 src/qemu/qemu_command.c|  3 +
 src/qemu/qemu_command.h|  1 +
 src/util/virnuma.c | 70 +-
 src/util/virnuma.h |  2 +
 ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 35 +++
 tests/qemuxml2argvmock.c   |  9 +++
 tests/qemuxml2argvtest.c   |  1 +
 11 files changed, 128 insertions(+), 37 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml

-- 
1.9.3

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


[libvirt] [PATCH v2 1/3] numatune: add check for numatune nodeset range

2014-10-28 Thread Chen Fan
For memnode in numatune element, the range of attribute 'nodeset'
was not validated. on my host maxnodes was 1, but when setting nodeset
to '0-2' or more, guest also started succuss. there probably was qemu's
bug too.

Signed-off-by: Chen Fan 
---
 src/conf/numatune_conf.c   | 21 -
 src/conf/numatune_conf.h   | 19 
 src/libvirt_private.syms   |  1 +
 src/qemu/qemu_command.c|  3 ++
 src/qemu/qemu_command.h|  1 +
 src/util/virnuma.c | 55 ++
 src/util/virnuma.h |  2 +
 ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 35 ++
 tests/qemuxml2argvmock.c   |  9 
 tests/qemuxml2argvtest.c   |  1 +
 10 files changed, 126 insertions(+), 21 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml

diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
index 21d9a64..d440b86 100644
--- a/src/conf/numatune_conf.c
+++ b/src/conf/numatune_conf.c
@@ -42,27 +42,6 @@ VIR_ENUM_IMPL(virDomainNumatunePlacement,
   "static",
   "auto");
 
-typedef struct _virDomainNumatuneNode virDomainNumatuneNode;
-typedef virDomainNumatuneNode *virDomainNumatuneNodePtr;
-
-struct _virDomainNumatune {
-struct {
-bool specified;
-virBitmapPtr nodeset;
-virDomainNumatuneMemMode mode;
-virDomainNumatunePlacement placement;
-} memory;   /* pinning for all the memory */
-
-struct _virDomainNumatuneNode {
-virBitmapPtr nodeset;
-virDomainNumatuneMemMode mode;
-} *mem_nodes;   /* fine tuning per guest node */
-size_t nmem_nodes;
-
-/* Future NUMA tuning related stuff should go here. */
-};
-
-
 static inline bool
 virDomainNumatuneNodeSpecified(virDomainNumatunePtr numatune,
int cellid)
diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
index 5254629..650b6e7 100644
--- a/src/conf/numatune_conf.h
+++ b/src/conf/numatune_conf.h
@@ -45,6 +45,25 @@ typedef enum {
 VIR_ENUM_DECL(virDomainNumatunePlacement)
 VIR_ENUM_DECL(virDomainNumatuneMemMode)
 
+typedef struct _virDomainNumatuneNode virDomainNumatuneNode;
+typedef virDomainNumatuneNode *virDomainNumatuneNodePtr;
+
+struct _virDomainNumatune {
+struct {
+bool specified;
+virBitmapPtr nodeset;
+virDomainNumatuneMemMode mode;
+virDomainNumatunePlacement placement;
+} memory;   /* pinning for all the memory */
+
+struct _virDomainNumatuneNode {
+virBitmapPtr nodeset;
+virDomainNumatuneMemMode mode;
+} *mem_nodes;   /* fine tuning per guest node */
+size_t nmem_nodes;
+
+/* Future NUMA tuning related stuff should go here. */
+};
 
 void virDomainNumatuneFree(virDomainNumatunePtr numatune);
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d63a8f0..16a5864 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1728,6 +1728,7 @@ virNumaGetPageInfo;
 virNumaGetPages;
 virNumaIsAvailable;
 virNumaNodeIsAvailable;
+virNumaNodesetIsAvailable;
 virNumaSetPagePoolSize;
 virNumaSetupMemoryPolicy;
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2e5af4f..9757d3e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6663,6 +6663,9 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
 goto cleanup;
 }
 
+if (!virNumaNodesetIsAvailable(def->numatune))
+goto cleanup;
+
 for (i = 0; i < def->mem.nhugepages; i++) {
 ssize_t next_bit, pos = 0;
 
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index aa40c9e..f263665 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -27,6 +27,7 @@
 # include "domain_addr.h"
 # include "domain_conf.h"
 # include "vircommand.h"
+# include "virnuma.h"
 # include "capabilities.h"
 # include "qemu_conf.h"
 # include "qemu_domain.h"
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 690615f..411719d 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -312,6 +312,55 @@ virNumaGetNodeCPUs(int node,
 
 return ret;
 }
+
+bool
+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
+{
+int maxnode;
+int bit = -1;
+size_t i;
+virBitmapPtr nodemask = NULL;
+
+if (!numatune)
+return true;
+
+if ((maxnode = virNumaGetMaxNode()) < 0)
+return false;
+
+maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
+
+/* verify  and  element in  */
+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1);
+if (nodemask) 

[libvirt] [PATCH v2 3/3] virnuma: remove redundant check for numanode

2014-10-28 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/util/virnuma.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 411719d..8431b3c 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -95,31 +95,16 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 int ret = -1;
 int bit = 0;
 size_t i;
-int maxnode = 0;
 virBitmapPtr tmp_nodemask = NULL;
 
 tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
 if (!tmp_nodemask)
 return 0;
 
-if (numa_available() < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   "%s", _("Host kernel is not aware of NUMA."));
-return -1;
-}
-
-maxnode = numa_max_node();
-maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
-
 /* Convert nodemask to NUMA bitmask. */
 nodemask_zero(&mask);
 bit = -1;
 while ((bit = virBitmapNextSetBit(tmp_nodemask, bit)) >= 0) {
-if (bit > maxnode) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("NUMA node %d is out of range"), bit);
-return -1;
-}
 nodemask_set(&mask, bit);
 }
 
-- 
1.9.3

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


[libvirt] [PATCH] conf: fix an memory leak in virSocketAddrIsNumericLocalhost()

2014-10-15 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/util/virsocketaddr.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
index 8c9f05f..5f54e68 100644
--- a/src/util/virsocketaddr.c
+++ b/src/util/virsocketaddr.c
@@ -894,19 +894,24 @@ virSocketAddrIsNumericLocalhost(const char *addr)
 struct in_addr tmp = { .s_addr = htonl(INADDR_LOOPBACK) };
 struct sockaddr_in *inet4;
 struct sockaddr_in6 *inet6;
+bool ret = false;
 
 if (virSocketAddrParseInternal(&res, addr, AF_UNSPEC, false) < 0)
-return false;
+return ret;
 
 switch (res->ai_addr->sa_family) {
 case AF_INET:
 inet4 = (struct sockaddr_in*) res->ai_addr;
-return memcmp(&inet4->sin_addr.s_addr, &tmp.s_addr,
-  sizeof(inet4->sin_addr.s_addr)) == 0;
+ret = memcmp(&inet4->sin_addr.s_addr, &tmp.s_addr,
+ sizeof(inet4->sin_addr.s_addr)) == 0;
+break;
 case AF_INET6:
 inet6 = (struct sockaddr_in6*) res->ai_addr;
-return IN6_IS_ADDR_LOOPBACK(&(inet6->sin6_addr));
+ret = IN6_IS_ADDR_LOOPBACK(&(inet6->sin6_addr));
+break;
 }
-return false;
+
+freeaddrinfo(res);
+return ret;
 
 }
-- 
1.9.3

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


Re: [libvirt] [PATCH v3 2/3] conf: add check if migration_host is a localhost address

2014-10-15 Thread Chen, Fan
On Wed, 2014-10-15 at 04:46 -0400, John Ferlan wrote: 
> This patch has triggered a Coverity RESOURCE_LEAK (3 actually)
Right, I will make a patch to fix it.

Thank you for catching that.


> 
> On 10/08/2014 09:54 PM, Chen, Fan wrote:
> > On Wed, 2014-10-08 at 12:33 +0200, Ján Tomko wrote: 
> >> On 10/07/2014 06:07 AM, Chen Fan wrote:
> >>>  Signed-off-by: Chen Fan 
> >> diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
> >> index 6d36689..a19e3af 100644
> >> --- a/src/util/virsocketaddr.c
> >> +++ b/src/util/virsocketaddr.c
> >> @@ -889,15 +889,24 @@ virSocketAddrNumericFamily(const char *address)
> >>   *  false otherwise
> >>   */
> >>  bool
> >> -virSocketAddrIsNumericLocalhost(const virSocketAddr *addr)
> >> +virSocketAddrIsNumericLocalhost(const char *addr)
> >>  {
> >> +struct addrinfo *res;
> >>  struct in_addr tmp = { .s_addr = htonl(INADDR_LOOPBACK) };
> >> -switch (addr->data.stor.ss_family) {
> >> +struct sockaddr_in *inet4;
> >> +struct sockaddr_in6 *inet6;
> >> +
> >> +if (virSocketAddrParseInternal(&res, addr, AF_UNSPEC, false) < 0)
> >> +return false;
> >> +
> 
> 'res' allocates something that must be free'd
> 
> 
> >> +switch (res->ai_addr->sa_family) {
> >>  case AF_INET:
> >> -return memcmp(&addr->data.inet4.sin_addr.s_addr, &tmp.s_addr,
> >> -  sizeof(addr->data.inet4.sin_addr.s_addr)) == 0;
> >> +inet4 = (struct sockaddr_in*) res->ai_addr;
> 
> Leak #1
> 
> >> +return memcmp(&inet4->sin_addr.s_addr, &tmp.s_addr,
> >> +  sizeof(inet4->sin_addr.s_addr)) == 0;
> >>  case AF_INET6:
> >> -return IN6_IS_ADDR_LOOPBACK(&addr->data.inet6.sin6_addr);
> >> +inet6 = (struct sockaddr_in6*) res->ai_addr;
> 
> Leak #2
> 
> >> +return IN6_IS_ADDR_LOOPBACK(&(inet6->sin6_addr));
> >>  }
> 
> Leak #3
> >>  return false;
> >>
> 
> Other callers will call 'freeaddrinfo(res);'

> 
> In order to resolve - you probably need to create a local ret = false,
> then assign ret = to either memcmp/IN6_IS_ADDR_LOOPBACK return, then
> call freeaddrinfo() before return ret
> 
> John


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

[libvirt] [PATCH] conf: fix a wrong comment in virSocketAddrNumericFamily()

2014-10-15 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/util/virsocketaddr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
index a19e3af..8c9f05f 100644
--- a/src/util/virsocketaddr.c
+++ b/src/util/virsocketaddr.c
@@ -859,8 +859,7 @@ virSocketAddrGetIpPrefix(const virSocketAddr *address,
  * virSocketAddrNumericFamily:
  * @address: address to check
  *
- * Check if passed address is an IP address in numeric format. and
- * return the address family, otherwise return 0.
+ * Check if passed address is an IP address in numeric format.
  *
  * Returns: AF_INET or AF_INET6 if @address is an numeric IP address,
  *  -1 otherwise.
-- 
1.9.3

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


[libvirt] [PATCH] conf: fix a wrong comment in virSocketAddrNumericFamily()

2014-10-15 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/util/virsocketaddr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
index a19e3af..8c9f05f 100644
--- a/src/util/virsocketaddr.c
+++ b/src/util/virsocketaddr.c
@@ -859,8 +859,7 @@ virSocketAddrGetIpPrefix(const virSocketAddr *address,
  * virSocketAddrNumericFamily:
  * @address: address to check
  *
- * Check if passed address is an IP address in numeric format. and
- * return the address family, otherwise return 0.
+ * Check if passed address is an IP address in numeric format.
  *
  * Returns: AF_INET or AF_INET6 if @address is an numeric IP address,
  *  -1 otherwise.
-- 
1.9.3

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


Re: [libvirt] [PATCH 0/3] lxc: Implement emulator pin APIs to set/get cpuset

2014-10-09 Thread Chen, Fan
On Fri, 2014-10-10 at 13:58 +0800, Wang Rui wrote: 
> Ping?
I found some wrong indentation in the 3 patches.
like following in patch 1/3:

+static int virLXCCgroupSetupCpusetTuneForEmulator(virDomainDefPtr def,
+   virCgroupPtr cgroup,
+   virBitmapPtr nodemask)


Thanks,
Chen

> 
> On 2014/9/4 15:52, Wang Rui wrote:
> > We can specify cpuset for a container defined with the xml
> > like  to achieve cpu
> > isolation. It works when container is started. But there
> > is no implements we can use to either change or get cpuset.
> > 
> > The following patches implement the lxc driver methods for
> > virDomainPinEmulator and virDomainGetEmulatorPinInfo. Also
> > support container startup with emulator affinity info in xml.
> > 
> > After these patches, we can set and get libvirt_lxc cpuset.
> > 
> > Yue Wenyuan (3):
> >   lxc: Implement pin emulator for container startup
> >   lxc: Implement emulator pin API in lxc driver
> >   lxc: Implement geting emulator pin info API in lxc driver
> > 
> >  src/lxc/lxc_cgroup.c |  88 
> >  src/lxc/lxc_cgroup.h |   7 ++
> >  src/lxc/lxc_controller.c |   4 +
> >  src/lxc/lxc_driver.c | 206 
> > +++
> >  4 files changed, 305 insertions(+)
> > 
> 
> 
> --
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list


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


Re: [libvirt] [PATCH v3 0/3] Check migration configuration

2014-10-09 Thread Chen, Fan
On Thu, 2014-10-09 at 14:54 +0200, Ján Tomko wrote: 
> On 10/07/2014 06:07 AM, Chen Fan wrote:
> > add some check in migration configuration.
> > 
> > Chen Fan (3):
> >   migration: add migration_host support for Ipv6 address without
> > brackets
> >   conf: add check if migration_host is a localhost address
> >   conf: Check migration_address whether is localhost
> > 
> >  src/libvirt_private.syms   |  3 +-
> >  src/qemu/qemu.conf |  2 +-
> >  src/qemu/qemu_conf.c   | 58 
> > ++
> >  src/qemu/qemu_conf.h   |  2 ++
> >  src/qemu/qemu_migration.c  | 49 
> >  src/qemu/test_libvirtd_qemu.aug.in |  2 +-
> >  src/util/virsocketaddr.c   | 43 +---
> >  src/util/virsocketaddr.h   |  4 ++-
> >  tests/sockettest.c |  2 +-
> >  9 files changed, 125 insertions(+), 40 deletions(-)
> > 
> 
> Now pushed.

Thanks,
Chen

> 
> Jan
> 


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

Re: [libvirt] [PATCH v3 2/3] conf: add check if migration_host is a localhost address

2014-10-08 Thread Chen, Fan
On Wed, 2014-10-08 at 12:33 +0200, Ján Tomko wrote: 
> On 10/07/2014 06:07 AM, Chen Fan wrote:
> >  Signed-off-by: Chen Fan 
> > ---
> >  src/libvirt_private.syms |  1 +
> >  src/qemu/qemu_conf.c | 50 
> > 
> >  src/qemu/qemu_conf.h |  2 ++
> >  src/util/virsocketaddr.c | 24 +++
> >  src/util/virsocketaddr.h |  2 ++
> >  5 files changed, 79 insertions(+)
> > 
> > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> > index 8ab1394..a104bc6 100644
> > --- a/src/libvirt_private.syms
> > +++ b/src/libvirt_private.syms
> > @@ -1911,6 +1911,7 @@ virSocketAddrGetIpPrefix;
> >  virSocketAddrGetPort;
> >  virSocketAddrGetRange;
> >  virSocketAddrIsNetmask;
> > +virSocketAddrIsNumericLocalhost;
> >  virSocketAddrIsPrivate;
> >  virSocketAddrIsWildcard;
> >  virSocketAddrMask;
> > diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> > index adc6caf..6b0ac5c 100644
> > --- a/src/qemu/qemu_conf.c
> > +++ b/src/qemu/qemu_conf.c
> > @@ -707,6 +707,15 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr 
> > cfg,
> >  GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
> >  
> >  GET_VALUE_STR("migration_host", cfg->migrateHost);
> > +if (cfg->migrateHost &&
> > +qemuCheckLocalhost(cfg->migrateHost)) {
> > +virReportError(VIR_ERR_CONF_SYNTAX,
> > +   _("migration_host must not be the address of"
> > + " the local machine: %s"),
> > +   cfg->migrateHost);
> > +goto cleanup;
> > +}
> > +
> >  GET_VALUE_STR("migration_address", cfg->migrationAddress);
> >  
> >  GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
> > @@ -1371,3 +1380,44 @@ qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
> >  
> >  return qemuGetHugepagePath(&hugetlbfs[i]);
> >  }
> > +
> > +bool
> > +qemuCheckLocalhost(const char *addrStr)
> > +{
> > +virSocketAddr addr;
> > +char *hostname, *tmp;
> > +bool encloseAddress = false;
> > +int family;
> > +bool ret = true;
> > +
> > +if (VIR_STRDUP(hostname, addrStr) < 0)
> > +return false;
> > +
> > +tmp = hostname;
> > +
> > +if (STRPREFIX(hostname, "[")) {
> > +char *end = strchr(hostname, ']');
> > +if (end) {
> > +*end = '\0';
> > +hostname++;
> > +encloseAddress = true;
> > +}
> > +}
> 
> We don't format the qemu.conf back and we don't need the brackets for
> anything. We can just store the migration host without them in 
> cfg->migrationHost
> 
> > +
> > +if (STRPREFIX(hostname, "localhost"))
> > +goto cleanup;
> > +
> > +family = virSocketAddrNumericFamily(hostname);
> > +if ((family == AF_INET && !encloseAddress) ||
> > +family == AF_INET6) {
> > +if (virSocketAddrParse(&addr, hostname, family) > 0 &&
> > +virSocketAddrIsNumericLocalhost(&addr)) {
> > +goto cleanup;
> > +}
> > +}
> 
> There's no need to check for family upfront.
> 
> > +
> > +ret = false;
> > +cleanup:
> > +VIR_FREE(tmp);
> > +return ret;
> > +}
> > diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
> > index cb01fb6..c9ce53c 100644
> > --- a/src/qemu/qemu_conf.h
> > +++ b/src/qemu/qemu_conf.h
> > @@ -322,4 +322,6 @@ int qemuTranslateSnapshotDiskSourcePool(virConnectPtr 
> > conn,
> >  char * qemuGetHugepagePath(virHugeTLBFSPtr hugepage);
> >  char * qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
> >size_t nhugetlbfs);
> > +
> > +bool qemuCheckLocalhost(const char *addrStr);
> >  #endif /* __QEMUD_CONF_H */
> > diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
> > index 7fe7a15..6d36689 100644
> > --- a/src/util/virsocketaddr.c
> > +++ b/src/util/virsocketaddr.c
> > @@ -878,3 +878,27 @@ virSocketAddrNumericFamily(const char *address)
> >  freeaddrinfo(res);
> >  return family;
> >  }
> > +
> > +/**
> > + * virSocketAddrIsNumericLocalhost:
> > + * @address: address to check
> > + *
> >

Re: [libvirt] [PATCH v3 1/3] migration: add migration_host support for Ipv6 address without brackets

2014-10-07 Thread Chen, Fan
On Tue, 2014-10-07 at 11:08 +0200, Ján Tomko wrote: 
> On 10/07/2014 06:07 AM, Chen Fan wrote:
> > if specifying migration_host to an Ipv6 address without brackets,
> > it was resolved to an incorrect address, such as:
> > tcp:2001:0DB8::1428:,
> > but the correct address should be:
> > tcp:[2001:0DB8::1428]:
> > so we should add brackets when parsing it.
> > 
> > Signed-off-by: Chen Fan 
> > ---
> >  src/libvirt_private.syms  |  2 +-
> >  src/qemu/qemu_migration.c | 49 
> > +++
> >  src/util/virsocketaddr.c  | 19 +-
> >  src/util/virsocketaddr.h  |  2 +-
> >  tests/sockettest.c|  2 +-
> >  5 files changed, 36 insertions(+), 38 deletions(-)
> 
> ACK

Thanks.

> 
> Jan
> 


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

Re: [libvirt] [PATCH v2 3/4] conf: add virSocketAddrIsLocalhost to Check migration_host

2014-10-06 Thread Chen, Fan
On Fri, 2014-10-03 at 15:58 +0200, Ján Tomko wrote: 
> On 09/23/2014 06:04 AM, Chen Fan wrote:
> > Signed-off-by: Chen Fan 
> > ---
> >  src/libvirt_private.syms |  1 +
> >  src/qemu/qemu_conf.c |  8 
> >  src/util/virsocketaddr.c | 35 +++
> >  src/util/virsocketaddr.h |  3 +++
> >  4 files changed, 47 insertions(+)
> > 
> > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> > index 51a692b..f7172b0 100644
> > --- a/src/libvirt_private.syms
> > +++ b/src/libvirt_private.syms
> > @@ -1885,6 +1885,7 @@ virSocketAddrGetPort;
> >  virSocketAddrGetRange;
> >  virSocketAddrIsNetmask;
> >  virSocketAddrIsNumeric;
> > +virSocketAddrIsLocalhost;
> >  virSocketAddrIsPrivate;
> >  virSocketAddrIsWildcard;
> >  virSocketAddrMask;
> > diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> > index adc6caf..30169cf 100644
> > --- a/src/qemu/qemu_conf.c
> > +++ b/src/qemu/qemu_conf.c
> > @@ -707,6 +707,14 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr 
> > cfg,
> >  GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
> >  
> >  GET_VALUE_STR("migration_host", cfg->migrateHost);
> > +if (cfg->migrateHost &&
> > +virSocketAddrIsLocalhost(cfg->migrateHost)) {
> > +virReportError(VIR_ERR_CONF_SYNTAX,
> > +   _("migration_host must not be 'localhost' address: 
> > %s"),
> > +   cfg->migrateHost);
> > +goto cleanup;
> > +}
> > +
> >  GET_VALUE_STR("migration_address", cfg->migrationAddress);
> >  
> >  GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
> > diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
> > index 64409a6..dfcaf72 100644
> > --- a/src/util/virsocketaddr.c
> > +++ b/src/util/virsocketaddr.c
> > @@ -884,3 +884,38 @@ virSocketAddrIsNumeric(const char *address, int 
> > *family)
> >  }
> >  return sa_family == AF_INET || sa_family == AF_INET6;
> >  }
> > +
> > +/**
> > + * virSocketAddrIsLocalhost:
> > + * @address: address to check
> > + *
> > + * Check if passed address is a 'localhost' address.
> > + *
> > + * Returns: true if @address is 'localhost' address,
> > + *  false otherwise
> > + */
> > +bool
> > +virSocketAddrIsLocalhost(const char *address)
> 
> I think this function should be named 'IsNumericLocalhost' and only check for
> the numeric representation of localhost. If the address is numeric, we can
> parse it and catch all the cases (like 127.0.0.1, 2130706433, 0177.0.0.1,
> 0:0:0::1). But we can't check if a hostname points to localhost without
> resolving it.
> 
> > +{
> > +   int family;
> > +
> > +   if (virSocketAddrIsNumeric(address, &family)) {
> > +   if (family == AF_INET) {
> > +   if (STREQ(address, "127.0.0.1"))
> > +   return true;
> > +   }
> > +
> 
> This should do what virSocketAddrIsWildcard does, only using
> INADDR_LOOPBACK instead of INADDR_ANY
> and IN6_IS_ADDR_LOOPBACK instead of IN6_IS_ADDR_UNSPECIFIED.
> 
> > +   if (family == AF_INET6) {
> > +   if (STREQ(address, "::1"))
> > +   return true;
> > +   }
> > +   } else {
> > +   if (STRPREFIX(address, "localhost"))
> > +   return true;
> 
> I'd put this check in qemu_conf.c.
> 
> > +
> > +   if (STREQ(address, "[::1]"))
> > +   return true;
> 
> And strip the brackets before calling virSocketAddrParse.

I had sent V3 patch that including the above solution.
please help to review it.

Thanks,
Chen 
> 
> Jan
> 
> > +   }
> > +
> > +   return false;
> > +}
> > diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h
> > index 7b11afb..5269f35 100644
> > --- a/src/util/virsocketaddr.h
> > +++ b/src/util/virsocketaddr.h
> > @@ -126,4 +126,7 @@ bool virSocketAddrIsPrivate(const virSocketAddr *addr);
> >  bool virSocketAddrIsWildcard(const virSocketAddr *addr);
> >  
> >  bool virSocketAddrIsNumeric(const char *address, int *family);
> > +
> > +bool virSocketAddrIsLocalhost(const char *address);
> > +
> >  #endif /* __VIR_SOCKETADDR_H__ */
> > 
> 
> 


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

[libvirt] [PATCH v3 0/3] Check migration configuration

2014-10-06 Thread Chen Fan
add some check in migration configuration.

Chen Fan (3):
  migration: add migration_host support for Ipv6 address without
brackets
  conf: add check if migration_host is a localhost address
  conf: Check migration_address whether is localhost

 src/libvirt_private.syms   |  3 +-
 src/qemu/qemu.conf |  2 +-
 src/qemu/qemu_conf.c   | 58 ++
 src/qemu/qemu_conf.h   |  2 ++
 src/qemu/qemu_migration.c  | 49 
 src/qemu/test_libvirtd_qemu.aug.in |  2 +-
 src/util/virsocketaddr.c   | 43 +---
 src/util/virsocketaddr.h   |  4 ++-
 tests/sockettest.c |  2 +-
 9 files changed, 125 insertions(+), 40 deletions(-)

-- 
1.9.3

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


[libvirt] [PATCH v3 3/3] conf: Check migration_address whether is localhost

2014-10-06 Thread Chen Fan
When enabling the migration_address option, by default it is
set to "127.0.0.1", but it's not a valid address for migration.
so we should add verification and set the default migration_address
to "0.0.0.0".

Signed-off-by: Chen Fan 
---
 src/qemu/qemu.conf | 2 +-
 src/qemu/qemu_conf.c   | 8 
 src/qemu/test_libvirtd_qemu.aug.in | 2 +-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 92ca715..c6db568 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -467,7 +467,7 @@
 
 # Override the listen address for all incoming migrations. Defaults to
 # 0.0.0.0, or :: if both host and qemu are capable of IPv6.
-#migration_address = "127.0.0.1"
+#migration_address = "0.0.0.0"
 
 
 # The default hostname or IP address which will be used by a migration
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 6b0ac5c..f34fa06 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -717,6 +717,14 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 }
 
 GET_VALUE_STR("migration_address", cfg->migrationAddress);
+if (cfg->migrationAddress &&
+qemuCheckLocalhost(cfg->migrationAddress)) {
+virReportError(VIR_ERR_CONF_SYNTAX,
+   _("migration_address must not be the address of"
+ " the local machine: %s"),
+   cfg->migrationAddress);
+goto cleanup;
+}
 
 GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
 
diff --git a/src/qemu/test_libvirtd_qemu.aug.in 
b/src/qemu/test_libvirtd_qemu.aug.in
index d2bc2c0..30fd27e 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -69,7 +69,7 @@ module Test_libvirtd_qemu =
 { "keepalive_interval" = "5" }
 { "keepalive_count" = "5" }
 { "seccomp_sandbox" = "1" }
-{ "migration_address" = "127.0.0.1" }
+{ "migration_address" = "0.0.0.0" }
 { "migration_host" = "host.example.com" }
 { "migration_port_min" = "49152" }
 { "migration_port_max" = "49215" }
-- 
1.9.3

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


[libvirt] [PATCH v3 1/3] migration: add migration_host support for Ipv6 address without brackets

2014-10-06 Thread Chen Fan
if specifying migration_host to an Ipv6 address without brackets,
it was resolved to an incorrect address, such as:
tcp:2001:0DB8::1428:,
but the correct address should be:
tcp:[2001:0DB8::1428]:
so we should add brackets when parsing it.

Signed-off-by: Chen Fan 
---
 src/libvirt_private.syms  |  2 +-
 src/qemu/qemu_migration.c | 49 +++
 src/util/virsocketaddr.c  | 19 +-
 src/util/virsocketaddr.h  |  2 +-
 tests/sockettest.c|  2 +-
 5 files changed, 36 insertions(+), 38 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7cbc35b..8ab1394 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1911,11 +1911,11 @@ virSocketAddrGetIpPrefix;
 virSocketAddrGetPort;
 virSocketAddrGetRange;
 virSocketAddrIsNetmask;
-virSocketAddrIsNumeric;
 virSocketAddrIsPrivate;
 virSocketAddrIsWildcard;
 virSocketAddrMask;
 virSocketAddrMaskByPrefix;
+virSocketAddrNumericFamily;
 virSocketAddrParse;
 virSocketAddrParseIPv4;
 virSocketAddrParseIPv6;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 284cd5a..e135249 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2605,7 +2605,6 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
 if (VIR_STRDUP(migrateFrom, "stdio") < 0)
 goto cleanup;
 } else {
-virSocketAddr listenAddressSocket;
 bool encloseAddress = false;
 bool hostIPv6Capable = false;
 bool qemuIPv6Capable = false;
@@ -2627,28 +2626,21 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
 virObjectUnref(qemuCaps);
 
 if (listenAddress) {
-if (virSocketAddrIsNumeric(listenAddress)) {
-/* listenAddress is numeric IPv4 or IPv6 */
-if (virSocketAddrParse(&listenAddressSocket, listenAddress, 
AF_UNSPEC) < 0)
+if (virSocketAddrNumericFamily(listenAddress) == AF_INET6) {
+if (!qemuIPv6Capable) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("qemu isn't capable of IPv6"));
 goto cleanup;
-
-/* address parsed successfully */
-if (VIR_SOCKET_ADDR_IS_FAMILY(&listenAddressSocket, AF_INET6)) 
{
-if (!qemuIPv6Capable) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("qemu isn't capable of IPv6"));
-goto cleanup;
-}
-if (!hostIPv6Capable) {
-virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-   _("host isn't capable of IPv6"));
-goto cleanup;
-}
-/* IPv6 address must be escaped in brackets on the cmd 
line */
-encloseAddress = true;
 }
+if (!hostIPv6Capable) {
+virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+   _("host isn't capable of IPv6"));
+goto cleanup;
+}
+/* IPv6 address must be escaped in brackets on the cmd line */
+encloseAddress = true;
 } else {
-/* listenAddress is a hostname */
+/* listenAddress is a hostname or IPv4 */
 }
 } else if (qemuIPv6Capable && hostIPv6Capable) {
 /* Listen on :: instead of 0.0.0.0 if QEMU understands it
@@ -2950,15 +2942,17 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
  * to be a correct hostname which refers to the target machine).
  */
 if (uri_in == NULL) {
+bool encloseAddress = false;
+const char *incFormat;
+
 if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
 goto cleanup;
 
 if (migrateHost != NULL) {
-if (virSocketAddrIsNumeric(migrateHost) &&
-virSocketAddrParse(NULL, migrateHost, AF_UNSPEC) < 0)
-goto cleanup;
+if (virSocketAddrNumericFamily(migrateHost) == AF_INET6)
+encloseAddress = true;
 
-   if (VIR_STRDUP(hostname, migrateHost) < 0)
+if (VIR_STRDUP(hostname, migrateHost) < 0)
 goto cleanup;
 } else {
 if ((hostname = virGetHostname()) == NULL)
@@ -2977,7 +2971,12 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
  * compatibility with old targets. We at least make the
  * new targets accept both syntaxes though.
  */
-if (virAsprintf(uri_out, "tcp:%s:%d", hostname, port) < 0)
+if (enclose

[libvirt] [PATCH v3 2/3] conf: add check if migration_host is a localhost address

2014-10-06 Thread Chen Fan
 Signed-off-by: Chen Fan 
---
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_conf.c | 50 
 src/qemu/qemu_conf.h |  2 ++
 src/util/virsocketaddr.c | 24 +++
 src/util/virsocketaddr.h |  2 ++
 5 files changed, 79 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8ab1394..a104bc6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1911,6 +1911,7 @@ virSocketAddrGetIpPrefix;
 virSocketAddrGetPort;
 virSocketAddrGetRange;
 virSocketAddrIsNetmask;
+virSocketAddrIsNumericLocalhost;
 virSocketAddrIsPrivate;
 virSocketAddrIsWildcard;
 virSocketAddrMask;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index adc6caf..6b0ac5c 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -707,6 +707,15 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
 
 GET_VALUE_STR("migration_host", cfg->migrateHost);
+if (cfg->migrateHost &&
+qemuCheckLocalhost(cfg->migrateHost)) {
+virReportError(VIR_ERR_CONF_SYNTAX,
+   _("migration_host must not be the address of"
+ " the local machine: %s"),
+   cfg->migrateHost);
+goto cleanup;
+}
+
 GET_VALUE_STR("migration_address", cfg->migrationAddress);
 
 GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
@@ -1371,3 +1380,44 @@ qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
 
 return qemuGetHugepagePath(&hugetlbfs[i]);
 }
+
+bool
+qemuCheckLocalhost(const char *addrStr)
+{
+virSocketAddr addr;
+char *hostname, *tmp;
+bool encloseAddress = false;
+int family;
+bool ret = true;
+
+if (VIR_STRDUP(hostname, addrStr) < 0)
+return false;
+
+tmp = hostname;
+
+if (STRPREFIX(hostname, "[")) {
+char *end = strchr(hostname, ']');
+if (end) {
+*end = '\0';
+hostname++;
+encloseAddress = true;
+}
+}
+
+if (STRPREFIX(hostname, "localhost"))
+goto cleanup;
+
+family = virSocketAddrNumericFamily(hostname);
+if ((family == AF_INET && !encloseAddress) ||
+family == AF_INET6) {
+if (virSocketAddrParse(&addr, hostname, family) > 0 &&
+virSocketAddrIsNumericLocalhost(&addr)) {
+goto cleanup;
+}
+}
+
+ret = false;
+cleanup:
+VIR_FREE(tmp);
+return ret;
+}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index cb01fb6..c9ce53c 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -322,4 +322,6 @@ int qemuTranslateSnapshotDiskSourcePool(virConnectPtr conn,
 char * qemuGetHugepagePath(virHugeTLBFSPtr hugepage);
 char * qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
   size_t nhugetlbfs);
+
+bool qemuCheckLocalhost(const char *addrStr);
 #endif /* __QEMUD_CONF_H */
diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
index 7fe7a15..6d36689 100644
--- a/src/util/virsocketaddr.c
+++ b/src/util/virsocketaddr.c
@@ -878,3 +878,27 @@ virSocketAddrNumericFamily(const char *address)
 freeaddrinfo(res);
 return family;
 }
+
+/**
+ * virSocketAddrIsNumericLocalhost:
+ * @address: address to check
+ *
+ * Check if passed address is a numeric 'localhost' address.
+ *
+ * Returns: true if @address is a numeric 'localhost' address,
+ *  false otherwise
+ */
+bool
+virSocketAddrIsNumericLocalhost(const virSocketAddr *addr)
+{
+struct in_addr tmp = { .s_addr = htonl(INADDR_LOOPBACK) };
+switch (addr->data.stor.ss_family) {
+case AF_INET:
+return memcmp(&addr->data.inet4.sin_addr.s_addr, &tmp.s_addr,
+  sizeof(addr->data.inet4.sin_addr.s_addr)) == 0;
+case AF_INET6:
+return IN6_IS_ADDR_LOOPBACK(&addr->data.inet6.sin6_addr);
+}
+return false;
+
+}
diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h
index 35c9c1a..fa9e98b 100644
--- a/src/util/virsocketaddr.h
+++ b/src/util/virsocketaddr.h
@@ -126,4 +126,6 @@ bool virSocketAddrIsPrivate(const virSocketAddr *addr);
 bool virSocketAddrIsWildcard(const virSocketAddr *addr);
 
 int virSocketAddrNumericFamily(const char *address);
+
+bool virSocketAddrIsNumericLocalhost(const virSocketAddr *addr);
 #endif /* __VIR_SOCKETADDR_H__ */
-- 
1.9.3

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


Re: [libvirt] [PATCH v2 2/4] migration: add migration_host support for Ipv6 address without brackets

2014-10-05 Thread Chen, Fan
On Fri, 2014-10-03 at 15:58 +0200, Ján Tomko wrote: 
> On 09/23/2014 06:04 AM, Chen Fan wrote:
> > if specifying migration_host to an Ipv6 address without brackets,
> > it was resolved to an incorrect address, such as:
> > tcp:2001:0DB8::1428:,
> > but the correct address should be:
> > tcp:[2001:0DB8::1428]:
> > so we should add brackets when parsing it.
> > 
> > Signed-off-by: Chen Fan 
> > ---
> >  src/qemu/qemu_migration.c | 24 +---
> >  1 file changed, 13 insertions(+), 11 deletions(-)
> > 
> > diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> > index 155f5b9..016d131 100644
> > --- a/src/qemu/qemu_migration.c
> > +++ b/src/qemu/qemu_migration.c
> > @@ -2544,7 +2544,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
> >  if (VIR_STRDUP(migrateFrom, "stdio") < 0)
> >  goto cleanup;
> >  } else {
> > -virSocketAddr listenAddressSocket;
> > +int listenAddressFamily;
> >  bool encloseAddress = false;
> >  bool hostIPv6Capable = false;
> >  bool qemuIPv6Capable = false;
> > @@ -2565,13 +2565,9 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
> >  virObjectUnref(qemuCaps);
> >  
> >  if (listenAddress) {
> > -if (virSocketAddrIsNumeric(listenAddress, NULL)) {
> > +if (virSocketAddrIsNumeric(listenAddress, 
> > &listenAddressFamily)) {
> 
> Both uses of this function are in this patch (I didn't realize that when
> reviewing v1).
> 
> We can rename it to virSocketAddrNumericFamily and do
> if (virSocketAddrNumericFamily(listenAddress) == AF_INET6), removing the need
> for a temporary variable.
Right, Agreed.

> 
> >  /* listenAddress is numeric IPv4 or IPv6 */
> > -if (virSocketAddrParse(&listenAddressSocket, 
> > listenAddress, AF_UNSPEC) < 0)
> > -goto cleanup;
> > -
> > -/* address parsed successfully */
> > -if (VIR_SOCKET_ADDR_IS_FAMILY(&listenAddressSocket, 
> > AF_INET6)) {
> > +if (listenAddressFamily == AF_INET6) {
> >  if (!qemuIPv6Capable) {
> >  virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
> > _("qemu isn't capable of IPv6"));
> > @@ -2850,11 +2846,17 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
> >  goto cleanup;
> >  
> >  if (migrateHost != NULL) {
> > -if (virSocketAddrIsNumeric(migrateHost, NULL) &&
> > -virSocketAddrParse(NULL, migrateHost, AF_UNSPEC) < 0)
> > -goto cleanup;
> > +int family;
> > +bool migrateHostisIpv6Address = false;
> > +
> > +if (virSocketAddrIsNumeric(migrateHost, &family) &&
> > +(family == AF_INET6))
> > +migrateHostisIpv6Address = true;
> >  
> > -   if (VIR_STRDUP(hostname, migrateHost) < 0)
> > +if ((migrateHostisIpv6Address &&
> > + virAsprintf(&hostname, "[%s]", migrateHost) < 0) ||
> > +(!migrateHostisIpv6Address &&
> > + virAsprintf(&hostname, "%s", migrateHost) < 0))
> >  goto cleanup;
> 
> In qemuMigrationPrepareAny, we have:
> if (encloseAddress)
> incFormat = "%s:[%s]:%d";
> else
> incFormat = "%s:%s:%d";
> if (virAsprintf(&migrateFrom, incFormat,
> protocol, listenAddress, port) < 0)
> goto cleanup;
> 
> Using the same pattern here as well would make it more readable.
> 

Thanks,
Chen


> Jan
> 
> >  } else {
> >  if ((hostname = virGetHostname()) == NULL)
> > 
> 
> 


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

Re: [libvirt] [PATCH v2 0/4] Check migration configuration

2014-09-30 Thread Chen, Fan
any feedback?

Thanks,
Chen

On Thu, 2014-09-25 at 01:10 +, Chen, Fan wrote: 
> ping? 
> 
> 
> On Tue, 2014-09-23 at 12:04 +0800, Chen Fan wrote: 
> > add some check in migration configuration.
> > 
> > Chen Fan (4):
> >   virsocketaddr: return address family in virSocketAddrIsNumeric
> >   migration: add migration_host support for Ipv6 address without
> > brackets
> >   conf: add virSocketAddrIsLocalhost to Check migration_host
> >   conf: Check migration_address whether is localhost
> > 
> >  src/libvirt_private.syms   |  1 +
> >  src/qemu/qemu.conf |  2 +-
> >  src/qemu/qemu_conf.c   | 15 
> >  src/qemu/qemu_migration.c  | 24 ++-
> >  src/qemu/test_libvirtd_qemu.aug.in |  2 +-
> >  src/util/virsocketaddr.c   | 48 
> > ++
> >  src/util/virsocketaddr.h   |  5 +++-
> >  tests/sockettest.c |  2 +-
> >  8 files changed, 80 insertions(+), 19 deletions(-)
> > 
> 
> 
> --
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list


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


Re: [libvirt] [PATCH v2 0/4] Check migration configuration

2014-09-24 Thread Chen, Fan
ping? 


On Tue, 2014-09-23 at 12:04 +0800, Chen Fan wrote: 
> add some check in migration configuration.
> 
> Chen Fan (4):
>   virsocketaddr: return address family in virSocketAddrIsNumeric
>   migration: add migration_host support for Ipv6 address without
> brackets
>   conf: add virSocketAddrIsLocalhost to Check migration_host
>   conf: Check migration_address whether is localhost
> 
>  src/libvirt_private.syms   |  1 +
>  src/qemu/qemu.conf |  2 +-
>  src/qemu/qemu_conf.c   | 15 
>  src/qemu/qemu_migration.c  | 24 ++-
>  src/qemu/test_libvirtd_qemu.aug.in |  2 +-
>  src/util/virsocketaddr.c   | 48 
> ++
>  src/util/virsocketaddr.h   |  5 +++-
>  tests/sockettest.c |  2 +-
>  8 files changed, 80 insertions(+), 19 deletions(-)
> 


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


Re: [libvirt] [PATCH 2/2] numatune: move up verification codes in virNumaSetupMemoryPolicy

2014-09-23 Thread Chen, Fan
On Tue, 2014-09-23 at 14:42 +0200, Michal Privoznik wrote: 
> On 23.09.2014 11:34, Chen Fan wrote:
> > use virDomainNumatuneNodeSetIsAvailable() to verify momory.nodeset
> > whether is out of range. and move up the verification.
> >
> > Signed-off-by: Chen Fan 
> > ---
> >   src/conf/numatune_conf.c |  3 +++
> >   src/util/virnuma.c   | 15 ---
> >   2 files changed, 3 insertions(+), 15 deletions(-)
> 
> I'd expect a test case for this.
Ok, I will add it.

thanks,
Chen

> 
> >
> > diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
> > index a9b20aa..8b43167 100644
> > --- a/src/conf/numatune_conf.c
> > +++ b/src/conf/numatune_conf.c
> > @@ -278,6 +278,9 @@ virDomainNumatuneParseXML(virDomainNumatunePtr 
> > *numatunePtr,
> >nodeset) < 0)
> >   goto cleanup;
> >
> > +if (!virDomainNumatuneNodeSetIsAvailable(*numatunePtr, -1))
> > +goto cleanup;
> > +
> >   if (virDomainNumatuneNodeParseXML(numatunePtr, ncells, ctxt) < 0)
> >   goto cleanup;
> >
> > diff --git a/src/util/virnuma.c b/src/util/virnuma.c
> > index 1a34398..4766f16 100644
> > --- a/src/util/virnuma.c
> > +++ b/src/util/virnuma.c
> > @@ -95,31 +95,16 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
> >   int ret = -1;
> >   int bit = 0;
> >   size_t i;
> > -int maxnode = 0;
> >   virBitmapPtr tmp_nodemask = NULL;
> >
> >   tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
> >   if (!tmp_nodemask)
> >   return 0;
> >
> > -if (numa_available() < 0) {
> > -virReportError(VIR_ERR_INTERNAL_ERROR,
> > -   "%s", _("Host kernel is not aware of NUMA."));
> > -return -1;
> > -}
> > -
> > -maxnode = numa_max_node();
> > -maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
> > -
> >   /* Convert nodemask to NUMA bitmask. */
> >   nodemask_zero(&mask);
> >   bit = -1;
> >   while ((bit = virBitmapNextSetBit(tmp_nodemask, bit)) >= 0) {
> > -if (bit > maxnode) {
> > -virReportError(VIR_ERR_INTERNAL_ERROR,
> > -   _("NUMA node %d is out of range"), bit);
> > -return -1;
> > -}
> >   nodemask_set(&mask, bit);
> >   }
> >
> >
> 
> Yet again, this suffers the same problem that 1/2 does: domain may be lost.
> 
> Michal


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


Re: [libvirt] [PATCH 1/2] numatune: add check for memnode.nodeset range

2014-09-23 Thread Chen, Fan
On Tue, 2014-09-23 at 14:41 +0200, Michal Privoznik wrote: 
> On 23.09.2014 11:34, Chen Fan wrote:
> > For memnode in numatune element, the range of attribute 'nodeset'
> > was not validated. on my host maxnodes was 1, but when setting nodeset
> > to '0-2' or more, guest also started succuss. there probably was qemu's
> > bug too.
> >
> > Signed-off-by: Chen Fan 
> > ---
> >   src/conf/numatune_conf.c | 29 +
> >   src/conf/numatune_conf.h |  4 
> >   2 files changed, 33 insertions(+)
> >
> > diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
> > index 21d9a64..a9b20aa 100644
> > --- a/src/conf/numatune_conf.c
> > +++ b/src/conf/numatune_conf.c
> > @@ -183,6 +183,9 @@ virDomainNumatuneNodeParseXML(virDomainNumatunePtr 
> > *numatunePtr,
> >  VIR_DOMAIN_CPUMASK_LEN) < 0)
> >   goto cleanup;
> >   VIR_FREE(tmp);
> > +
> > +if (!virDomainNumatuneNodeSetIsAvailable(numatune, cellid))
> > +goto cleanup;
> 
> Well, if there already exists such configuration within an existing 
> domain, this will cause a failure on XML parsing when the daemon is 
> starting and hence domain is lost.
Right, I would move this check to VM start routine.


> 
> >   }
> >
> >   ret = 0;
> > @@ -612,3 +615,29 @@ 
> > virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune)
> >
> >   return false;
> >   }
> > +
> > +bool
> > +virDomainNumatuneNodeSetIsAvailable(virDomainNumatunePtr numatune,
> > +int cellid)
> > +{
> > +int maxnode;
> > +int bit = -1;
> > +virBitmapPtr nodemask = NULL;
> > +
> > +nodemask = virDomainNumatuneGetNodeset(numatune, NULL, cellid);
> > +if (!nodemask)
> > +return false;
> > +
> > +if ((maxnode = virNumaGetMaxNode()) < 0)
> > +return false;
> 
> This will work in real environment, but won't work in tests. You need to 
> mock this to get predictable max numa node.
I will add test case for this.


Thanks,
Chen 
> 
> > +
> > +while ((bit = virBitmapNextSetBit(nodemask, bit)) >= 0) {
> > +if (bit > maxnode) {
> > +virReportError(VIR_ERR_INTERNAL_ERROR,
> > +   _("NUMA node %d is out of range"), bit);
> > +return false;
> > +}
> > +}
> > +
> > +return true;
> > +}
> > diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
> > index 5254629..cab0b83 100644
> > --- a/src/conf/numatune_conf.h
> > +++ b/src/conf/numatune_conf.h
> > @@ -102,4 +102,8 @@ bool 
> > virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune);
> >
> >   bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
> >
> > +extern int virNumaGetMaxNode(void);
> > +bool virDomainNumatuneNodeSetIsAvailable(virDomainNumatunePtr numatune,
> > + int cellid);
> > +
> >   #endif /* __NUMATUNE_CONF_H__ */
> >
> 
> Michal


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


[libvirt] [PATCH 0/2] add nodeset check in numatune

2014-09-23 Thread Chen Fan
for memnode.nodeset in numatune, when setting it more
than the host nodes, it should fail.

Chen Fan (2):
  numatune: add check for memnode.nodeset range
  numatune: move up verification codes in virNumaSetupMemoryPolicy

 src/conf/numatune_conf.c | 32 
 src/conf/numatune_conf.h |  4 
 src/util/virnuma.c   | 15 ---
 3 files changed, 36 insertions(+), 15 deletions(-)

-- 
1.9.3

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


[libvirt] [PATCH 2/2] numatune: move up verification codes in virNumaSetupMemoryPolicy

2014-09-23 Thread Chen Fan
use virDomainNumatuneNodeSetIsAvailable() to verify momory.nodeset
whether is out of range. and move up the verification.

Signed-off-by: Chen Fan 
---
 src/conf/numatune_conf.c |  3 +++
 src/util/virnuma.c   | 15 ---
 2 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
index a9b20aa..8b43167 100644
--- a/src/conf/numatune_conf.c
+++ b/src/conf/numatune_conf.c
@@ -278,6 +278,9 @@ virDomainNumatuneParseXML(virDomainNumatunePtr *numatunePtr,
  nodeset) < 0)
 goto cleanup;
 
+if (!virDomainNumatuneNodeSetIsAvailable(*numatunePtr, -1))
+goto cleanup;
+
 if (virDomainNumatuneNodeParseXML(numatunePtr, ncells, ctxt) < 0)
 goto cleanup;
 
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 1a34398..4766f16 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -95,31 +95,16 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
 int ret = -1;
 int bit = 0;
 size_t i;
-int maxnode = 0;
 virBitmapPtr tmp_nodemask = NULL;
 
 tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
 if (!tmp_nodemask)
 return 0;
 
-if (numa_available() < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   "%s", _("Host kernel is not aware of NUMA."));
-return -1;
-}
-
-maxnode = numa_max_node();
-maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
-
 /* Convert nodemask to NUMA bitmask. */
 nodemask_zero(&mask);
 bit = -1;
 while ((bit = virBitmapNextSetBit(tmp_nodemask, bit)) >= 0) {
-if (bit > maxnode) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("NUMA node %d is out of range"), bit);
-return -1;
-}
 nodemask_set(&mask, bit);
 }
 
-- 
1.9.3

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


[libvirt] [PATCH 1/2] numatune: add check for memnode.nodeset range

2014-09-23 Thread Chen Fan
For memnode in numatune element, the range of attribute 'nodeset'
was not validated. on my host maxnodes was 1, but when setting nodeset
to '0-2' or more, guest also started succuss. there probably was qemu's
bug too.

Signed-off-by: Chen Fan 
---
 src/conf/numatune_conf.c | 29 +
 src/conf/numatune_conf.h |  4 
 2 files changed, 33 insertions(+)

diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
index 21d9a64..a9b20aa 100644
--- a/src/conf/numatune_conf.c
+++ b/src/conf/numatune_conf.c
@@ -183,6 +183,9 @@ virDomainNumatuneNodeParseXML(virDomainNumatunePtr 
*numatunePtr,
VIR_DOMAIN_CPUMASK_LEN) < 0)
 goto cleanup;
 VIR_FREE(tmp);
+
+if (!virDomainNumatuneNodeSetIsAvailable(numatune, cellid))
+goto cleanup;
 }
 
 ret = 0;
@@ -612,3 +615,29 @@ virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr 
numatune)
 
 return false;
 }
+
+bool
+virDomainNumatuneNodeSetIsAvailable(virDomainNumatunePtr numatune,
+int cellid)
+{
+int maxnode;
+int bit = -1;
+virBitmapPtr nodemask = NULL;
+
+nodemask = virDomainNumatuneGetNodeset(numatune, NULL, cellid);
+if (!nodemask)
+return false;
+
+if ((maxnode = virNumaGetMaxNode()) < 0)
+return false;
+
+while ((bit = virBitmapNextSetBit(nodemask, bit)) >= 0) {
+if (bit > maxnode) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("NUMA node %d is out of range"), bit);
+return false;
+}
+}
+
+return true;
+}
diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
index 5254629..cab0b83 100644
--- a/src/conf/numatune_conf.h
+++ b/src/conf/numatune_conf.h
@@ -102,4 +102,8 @@ bool virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr 
numatune);
 
 bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
 
+extern int virNumaGetMaxNode(void);
+bool virDomainNumatuneNodeSetIsAvailable(virDomainNumatunePtr numatune,
+ int cellid);
+
 #endif /* __NUMATUNE_CONF_H__ */
-- 
1.9.3

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


[libvirt] [PATCH v2 3/4] conf: add virSocketAddrIsLocalhost to Check migration_host

2014-09-22 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_conf.c |  8 
 src/util/virsocketaddr.c | 35 +++
 src/util/virsocketaddr.h |  3 +++
 4 files changed, 47 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 51a692b..f7172b0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1885,6 +1885,7 @@ virSocketAddrGetPort;
 virSocketAddrGetRange;
 virSocketAddrIsNetmask;
 virSocketAddrIsNumeric;
+virSocketAddrIsLocalhost;
 virSocketAddrIsPrivate;
 virSocketAddrIsWildcard;
 virSocketAddrMask;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index adc6caf..30169cf 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -707,6 +707,14 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
 
 GET_VALUE_STR("migration_host", cfg->migrateHost);
+if (cfg->migrateHost &&
+virSocketAddrIsLocalhost(cfg->migrateHost)) {
+virReportError(VIR_ERR_CONF_SYNTAX,
+   _("migration_host must not be 'localhost' address: %s"),
+   cfg->migrateHost);
+goto cleanup;
+}
+
 GET_VALUE_STR("migration_address", cfg->migrationAddress);
 
 GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
index 64409a6..dfcaf72 100644
--- a/src/util/virsocketaddr.c
+++ b/src/util/virsocketaddr.c
@@ -884,3 +884,38 @@ virSocketAddrIsNumeric(const char *address, int *family)
 }
 return sa_family == AF_INET || sa_family == AF_INET6;
 }
+
+/**
+ * virSocketAddrIsLocalhost:
+ * @address: address to check
+ *
+ * Check if passed address is a 'localhost' address.
+ *
+ * Returns: true if @address is 'localhost' address,
+ *  false otherwise
+ */
+bool
+virSocketAddrIsLocalhost(const char *address)
+{
+   int family;
+
+   if (virSocketAddrIsNumeric(address, &family)) {
+   if (family == AF_INET) {
+   if (STREQ(address, "127.0.0.1"))
+   return true;
+   }
+
+   if (family == AF_INET6) {
+   if (STREQ(address, "::1"))
+   return true;
+   }
+   } else {
+   if (STRPREFIX(address, "localhost"))
+   return true;
+
+   if (STREQ(address, "[::1]"))
+   return true;
+   }
+
+   return false;
+}
diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h
index 7b11afb..5269f35 100644
--- a/src/util/virsocketaddr.h
+++ b/src/util/virsocketaddr.h
@@ -126,4 +126,7 @@ bool virSocketAddrIsPrivate(const virSocketAddr *addr);
 bool virSocketAddrIsWildcard(const virSocketAddr *addr);
 
 bool virSocketAddrIsNumeric(const char *address, int *family);
+
+bool virSocketAddrIsLocalhost(const char *address);
+
 #endif /* __VIR_SOCKETADDR_H__ */
-- 
1.9.3

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


[libvirt] [PATCH v2 0/4] Check migration configuration

2014-09-22 Thread Chen Fan
add some check in migration configuration.

Chen Fan (4):
  virsocketaddr: return address family in virSocketAddrIsNumeric
  migration: add migration_host support for Ipv6 address without
brackets
  conf: add virSocketAddrIsLocalhost to Check migration_host
  conf: Check migration_address whether is localhost

 src/libvirt_private.syms   |  1 +
 src/qemu/qemu.conf |  2 +-
 src/qemu/qemu_conf.c   | 15 
 src/qemu/qemu_migration.c  | 24 ++-
 src/qemu/test_libvirtd_qemu.aug.in |  2 +-
 src/util/virsocketaddr.c   | 48 ++
 src/util/virsocketaddr.h   |  5 +++-
 tests/sockettest.c |  2 +-
 8 files changed, 80 insertions(+), 19 deletions(-)

-- 
1.9.3

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


[libvirt] [PATCH v2 2/4] migration: add migration_host support for Ipv6 address without brackets

2014-09-22 Thread Chen Fan
if specifying migration_host to an Ipv6 address without brackets,
it was resolved to an incorrect address, such as:
tcp:2001:0DB8::1428:,
but the correct address should be:
tcp:[2001:0DB8::1428]:
so we should add brackets when parsing it.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_migration.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 155f5b9..016d131 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2544,7 +2544,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
 if (VIR_STRDUP(migrateFrom, "stdio") < 0)
 goto cleanup;
 } else {
-virSocketAddr listenAddressSocket;
+int listenAddressFamily;
 bool encloseAddress = false;
 bool hostIPv6Capable = false;
 bool qemuIPv6Capable = false;
@@ -2565,13 +2565,9 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
 virObjectUnref(qemuCaps);
 
 if (listenAddress) {
-if (virSocketAddrIsNumeric(listenAddress, NULL)) {
+if (virSocketAddrIsNumeric(listenAddress, &listenAddressFamily)) {
 /* listenAddress is numeric IPv4 or IPv6 */
-if (virSocketAddrParse(&listenAddressSocket, listenAddress, 
AF_UNSPEC) < 0)
-goto cleanup;
-
-/* address parsed successfully */
-if (VIR_SOCKET_ADDR_IS_FAMILY(&listenAddressSocket, AF_INET6)) 
{
+if (listenAddressFamily == AF_INET6) {
 if (!qemuIPv6Capable) {
 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("qemu isn't capable of IPv6"));
@@ -2850,11 +2846,17 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
 goto cleanup;
 
 if (migrateHost != NULL) {
-if (virSocketAddrIsNumeric(migrateHost, NULL) &&
-virSocketAddrParse(NULL, migrateHost, AF_UNSPEC) < 0)
-goto cleanup;
+int family;
+bool migrateHostisIpv6Address = false;
+
+if (virSocketAddrIsNumeric(migrateHost, &family) &&
+(family == AF_INET6))
+migrateHostisIpv6Address = true;
 
-   if (VIR_STRDUP(hostname, migrateHost) < 0)
+if ((migrateHostisIpv6Address &&
+ virAsprintf(&hostname, "[%s]", migrateHost) < 0) ||
+(!migrateHostisIpv6Address &&
+ virAsprintf(&hostname, "%s", migrateHost) < 0))
 goto cleanup;
 } else {
 if ((hostname = virGetHostname()) == NULL)
-- 
1.9.3

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


[libvirt] [PATCH v2 1/4] virsocketaddr: return address family in virSocketAddrIsNumeric

2014-09-22 Thread Chen Fan
nowadays, virSocketAddrIsNumeric only validated the income address
if numeric, but sometimes we need to know whether the address is
an IPv4 or an IPv6 address.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_migration.c |  4 ++--
 src/util/virsocketaddr.c  | 13 +
 src/util/virsocketaddr.h  |  2 +-
 tests/sockettest.c|  2 +-
 4 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index ce1a5cd..155f5b9 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2565,7 +2565,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
 virObjectUnref(qemuCaps);
 
 if (listenAddress) {
-if (virSocketAddrIsNumeric(listenAddress)) {
+if (virSocketAddrIsNumeric(listenAddress, NULL)) {
 /* listenAddress is numeric IPv4 or IPv6 */
 if (virSocketAddrParse(&listenAddressSocket, listenAddress, 
AF_UNSPEC) < 0)
 goto cleanup;
@@ -2850,7 +2850,7 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
 goto cleanup;
 
 if (migrateHost != NULL) {
-if (virSocketAddrIsNumeric(migrateHost) &&
+if (virSocketAddrIsNumeric(migrateHost, NULL) &&
 virSocketAddrParse(NULL, migrateHost, AF_UNSPEC) < 0)
 goto cleanup;
 
diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
index 7cc4bde..64409a6 100644
--- a/src/util/virsocketaddr.c
+++ b/src/util/virsocketaddr.c
@@ -858,6 +858,7 @@ virSocketAddrGetIpPrefix(const virSocketAddr *address,
 /**
  * virSocketAddrIsNumeric:
  * @address: address to check
+ * @family: where to store the address family, optional.
  *
  * Check if passed address is an IP address in numeric format. For
  * instance, for 0.0.0.0 true is returned, for 'examplehost"
@@ -867,15 +868,19 @@ virSocketAddrGetIpPrefix(const virSocketAddr *address,
  *  false otherwise
  */
 bool
-virSocketAddrIsNumeric(const char *address)
+virSocketAddrIsNumeric(const char *address, int *family)
 {
 struct addrinfo *res;
-unsigned short family;
+unsigned short sa_family;
 
 if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, false) < 0)
 return false;
 
-family = res->ai_addr->sa_family;
+sa_family = res->ai_addr->sa_family;
 freeaddrinfo(res);
-return family == AF_INET || family == AF_INET6;
+
+if (family != NULL) {
+*family = sa_family;
+}
+return sa_family == AF_INET || sa_family == AF_INET6;
 }
diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h
index 27defa0..7b11afb 100644
--- a/src/util/virsocketaddr.h
+++ b/src/util/virsocketaddr.h
@@ -125,5 +125,5 @@ bool virSocketAddrIsPrivate(const virSocketAddr *addr);
 
 bool virSocketAddrIsWildcard(const virSocketAddr *addr);
 
-bool virSocketAddrIsNumeric(const char *address);
+bool virSocketAddrIsNumeric(const char *address, int *family);
 #endif /* __VIR_SOCKETADDR_H__ */
diff --git a/tests/sockettest.c b/tests/sockettest.c
index 68b0536..dde0bb8 100644
--- a/tests/sockettest.c
+++ b/tests/sockettest.c
@@ -229,7 +229,7 @@ testIsNumericHelper(const void *opaque)
 {
 const struct testIsNumericData *data = opaque;
 
-if (virSocketAddrIsNumeric(data->addr))
+if (virSocketAddrIsNumeric(data->addr, NULL))
 return data->pass ? 0 : -1;
 return data->pass ? -1 : 0;
 }
-- 
1.9.3

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


[libvirt] [PATCH v2 4/4] conf: Check migration_address whether is localhost

2014-09-22 Thread Chen Fan
When enabling the migration_address option, by default it is
set to "127.0.0.1", but it's not a valid address for migration.
so we should add verification and set the default migration_address
to "0.0.0.0".

Signed-off-by: Chen Fan 
---
 src/qemu/qemu.conf | 2 +-
 src/qemu/qemu_conf.c   | 7 +++
 src/qemu/test_libvirtd_qemu.aug.in | 2 +-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 79bba36..666c303 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -459,7 +459,7 @@
 
 # Override the listen address for all incoming migrations. Defaults to
 # 0.0.0.0, or :: if both host and qemu are capable of IPv6.
-#migration_address = "127.0.0.1"
+#migration_address = "0.0.0.0"
 
 
 # The default hostname or IP address which will be used by a migration
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 30169cf..65f98d7 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -716,6 +716,13 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 }
 
 GET_VALUE_STR("migration_address", cfg->migrationAddress);
+if (cfg->migrationAddress &&
+virSocketAddrIsLocalhost(cfg->migrationAddress)) {
+virReportError(VIR_ERR_CONF_SYNTAX,
+   _("migration_address must not be 'localhost' address: 
%s"),
+   cfg->migrationAddress);
+goto cleanup;
+}
 
 GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
 
diff --git a/src/qemu/test_libvirtd_qemu.aug.in 
b/src/qemu/test_libvirtd_qemu.aug.in
index d2bc2c0..30fd27e 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -69,7 +69,7 @@ module Test_libvirtd_qemu =
 { "keepalive_interval" = "5" }
 { "keepalive_count" = "5" }
 { "seccomp_sandbox" = "1" }
-{ "migration_address" = "127.0.0.1" }
+{ "migration_address" = "0.0.0.0" }
 { "migration_host" = "host.example.com" }
 { "migration_port_min" = "49152" }
 { "migration_port_max" = "49215" }
-- 
1.9.3

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


Re: [libvirt] [PATCH v1 1/3] migration: add migration_host support for Ipv6 address without brackets

2014-09-22 Thread Chen, Fan
On Mon, 2014-09-22 at 15:34 +0200, Ján Tomko wrote: 
> On 09/12/2014 06:31 AM, Chen Fan wrote:
> > when specifying migration_host to an Ipv6 address without brackets,
> > it was resolved to an incorrect address, such as:
> >tcp:2001:0DB8::1428:,
> > but the correct address should be:
> >tcp:[2001:0DB8::1428]:
> > so we should add brackets when parsing it.
> > 
> > Signed-off-by: Chen Fan 
> > ---
> >  src/qemu/qemu_migration.c | 19 +++
> >  1 file changed, 15 insertions(+), 4 deletions(-)
> > 
> > diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> > index e4b664b..c7eb305 100644
> > --- a/src/qemu/qemu_migration.c
> > +++ b/src/qemu/qemu_migration.c
> > @@ -2850,11 +2850,22 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
> >  goto cleanup;
> >  
> >  if (migrateHost != NULL) {
> > -if (virSocketAddrIsNumeric(migrateHost) &&
> > -virSocketAddrParse(NULL, migrateHost, AF_UNSPEC) < 0)
> > -goto cleanup;
> 
> Hmm, I'm not sure what this check was doing - if the address was succesfully
> parsed in AddrIsNumeric, it should be parsed by virSocketAddrParse as well.

agreed.

> 
> > +virSocketAddr migrateHostSocket;
> > +bool migrateHostisIpv6Address = false;
> > +
> > +if (virSocketAddrIsNumeric(migrateHost)) {
> > +if (virSocketAddrParse(&migrateHostSocket, migrateHost, 
> > AF_UNSPEC) < 0)
> > +goto cleanup;
> > +
> > +if (VIR_SOCKET_ADDR_IS_FAMILY(&migrateHostSocket, 
> > AF_INET6)) {
> > +migrateHostisIpv6Address = true;
> > +}
> > +}
> >  
> 
> We also do this parsing to chceck for numeric IPv6 addresses in
> qemuMigrationPrepareAny. It would be nicer to create a new
> 'virSocketAddrIsNumericIPv6' function and use it in both of them.

I will follow this.

Thanks,
Chen


> 
> Jan
> 
> > -   if (VIR_STRDUP(hostname, migrateHost) < 0)
> > +if ((migrateHostisIpv6Address &&
> > + virAsprintf(&hostname, "[%s]", migrateHost) < 0) ||
> > +(!migrateHostisIpv6Address &&
> > + virAsprintf(&hostname, "%s", migrateHost) < 0))
> >  goto cleanup;
> >  } else {
> >  if ((hostname = virGetHostname()) == NULL)
> > 
> 
> 


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

[libvirt] [PATCH] cpu: fix wrong single quote mark

2014-09-22 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/conf/cpu_conf.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 6c454ee..116aa58 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -413,7 +413,7 @@ virCPUDefParseXML(xmlNodePtr node,
 for (j = 0; j < i; j++) {
 if (STREQ(name, def->features[j].name)) {
 virReportError(VIR_ERR_XML_ERROR,
-   _("CPU feature `%s' specified more than once"),
+   _("CPU feature '%s' specified more than once"),
name);
 VIR_FREE(name);
 goto error;
@@ -731,7 +731,7 @@ virCPUDefUpdateFeatureInternal(virCPUDefPtr def,
 }
 
 virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("CPU feature `%s' specified more than once"),
+   _("CPU feature '%s' specified more than once"),
name);
 
 return -1;
-- 
1.9.3

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


Re: [libvirt] [PATCH v1 2/3] conf: Check migration_host is localhost or not during restart

2014-09-22 Thread Chen, Fan
On Mon, 2014-09-22 at 15:34 +0200, Ján Tomko wrote: 
> On 09/12/2014 06:33 AM, Chen Fan wrote:
> > Signed-off-by: Chen Fan 
> > ---
> >  src/qemu/qemu_conf.c | 11 +++
> >  1 file changed, 11 insertions(+)
> > 
> > diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> > index ac10b64..013f3de 100644
> > --- a/src/qemu/qemu_conf.c
> > +++ b/src/qemu/qemu_conf.c
> > @@ -707,6 +707,17 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr 
> > cfg,
> >  GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
> >  
> >  GET_VALUE_STR("migration_host", cfg->migrateHost);
> > +if (cfg->migrateHost) {
> > +if (STRPREFIX(cfg->migrateHost, "localhost") ||
> > +STREQ(cfg->migrateHost, "127.0.0.1") ||
> > +STREQ(cfg->migrateHost, "::1") ||
> > +STREQ(cfg->migrateHost, "[::1]")) {\
> 
> I think we need a 'virSocketAddrIsLocalhost' function similar to
> virSocketAddrIsWildcard, which would check any numeric represnation of the
> address:
> 
> if (STRPREFIX(cfg->migrateHost, "localhost") ||
> virSocketAddrIsLocalhost(cfg->migrateHost))

It's a good point.


> 
> > +virReportError(VIR_ERR_CONF_SYNTAX, "%s",
> > +   _("migration_host must be a valid address or 
> > hostname"));
> 
> Something more specific, like: "migration_host must not be localhost" is more
> user-friendly.
I will update the output.


Thanks,
Chen

> 
> Jan
> 
> > +goto cleanup;
> > +}
> > +}
> > +
> >  GET_VALUE_STR("migration_address", cfg->migrationAddress);
> >  
> >  GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
> > 
> 
> 


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

Re: [libvirt] [PATCH v1 0/3] Check migration configuration

2014-09-15 Thread Chen, Fan
Hi jiri,

   Please help to review this patches.

Thanks,
Chen

On Fri, 2014-09-12 at 12:32 +0800, Chen Fan wrote: 
> This version differs from the patch set
> "conf: Check migration_host is valid or not during libvirt restarts"
> I posted 2 weeks ago, I droped checking the migration_host on target
> host. and find an issue when setting migration_host.
> 
> Chen Fan (3):
>   migration: add migration_host support for Ipv6 address without
> brackets
>   conf: Check migration_host is localhost or not during restart
>   conf: Check migration_address is valid or not during restart
> 
>  src/qemu/qemu.conf |  2 +-
>  src/qemu/qemu_conf.c   | 21 +
>  src/qemu/qemu_migration.c  | 19 +++
>  src/qemu/test_libvirtd_qemu.aug.in |  2 +-
>  4 files changed, 38 insertions(+), 6 deletions(-)
> 


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


[libvirt] [PATCH v1 3/3] conf: Check migration_address is valid or not during restart

2014-09-11 Thread Chen Fan
When enabling the migration_address option, by default it is
set to "127.0.0.1", but it's not a valid address for migration.
so we should add verification and set the default migration_address
to "0.0.0.0".

Signed-off-by: Chen Fan 
---
 src/qemu/qemu.conf |  2 +-
 src/qemu/qemu_conf.c   | 10 ++
 src/qemu/test_libvirtd_qemu.aug.in |  2 +-
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 79bba36..666c303 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -459,7 +459,7 @@
 
 # Override the listen address for all incoming migrations. Defaults to
 # 0.0.0.0, or :: if both host and qemu are capable of IPv6.
-#migration_address = "127.0.0.1"
+#migration_address = "0.0.0.0"
 
 
 # The default hostname or IP address which will be used by a migration
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 013f3de..2cbf2a6 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -719,6 +719,16 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 }
 
 GET_VALUE_STR("migration_address", cfg->migrationAddress);
+if (cfg->migrationAddress) {
+if (STRPREFIX(cfg->migrationAddress, "localhost") ||
+STREQ(cfg->migrationAddress, "127.0.0.1") ||
+STREQ(cfg->migrationAddress, "::1") ||
+STREQ(cfg->migrationAddress, "[::1]")) {
+virReportError(VIR_ERR_CONF_SYNTAX, "%s",
+   _("migration_address must be a valid address or 
hostname"));
+goto cleanup;
+}
+}
 
 GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
 
diff --git a/src/qemu/test_libvirtd_qemu.aug.in 
b/src/qemu/test_libvirtd_qemu.aug.in
index d2bc2c0..30fd27e 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -69,7 +69,7 @@ module Test_libvirtd_qemu =
 { "keepalive_interval" = "5" }
 { "keepalive_count" = "5" }
 { "seccomp_sandbox" = "1" }
-{ "migration_address" = "127.0.0.1" }
+{ "migration_address" = "0.0.0.0" }
 { "migration_host" = "host.example.com" }
 { "migration_port_min" = "49152" }
 { "migration_port_max" = "49215" }
-- 
1.9.3

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


[libvirt] [PATCH v1 2/3] conf: Check migration_host is localhost or not during restart

2014-09-11 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/qemu/qemu_conf.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index ac10b64..013f3de 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -707,6 +707,17 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
 
 GET_VALUE_STR("migration_host", cfg->migrateHost);
+if (cfg->migrateHost) {
+if (STRPREFIX(cfg->migrateHost, "localhost") ||
+STREQ(cfg->migrateHost, "127.0.0.1") ||
+STREQ(cfg->migrateHost, "::1") ||
+STREQ(cfg->migrateHost, "[::1]")) {
+virReportError(VIR_ERR_CONF_SYNTAX, "%s",
+   _("migration_host must be a valid address or 
hostname"));
+goto cleanup;
+}
+}
+
 GET_VALUE_STR("migration_address", cfg->migrationAddress);
 
 GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
-- 
1.9.3

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


[libvirt] [PATCH v1 0/3] Check migration configuration

2014-09-11 Thread Chen Fan
This version differs from the patch set
"conf: Check migration_host is valid or not during libvirt restarts"
I posted 2 weeks ago, I droped checking the migration_host on target
host. and find an issue when setting migration_host.

Chen Fan (3):
  migration: add migration_host support for Ipv6 address without
brackets
  conf: Check migration_host is localhost or not during restart
  conf: Check migration_address is valid or not during restart

 src/qemu/qemu.conf |  2 +-
 src/qemu/qemu_conf.c   | 21 +
 src/qemu/qemu_migration.c  | 19 +++
 src/qemu/test_libvirtd_qemu.aug.in |  2 +-
 4 files changed, 38 insertions(+), 6 deletions(-)

-- 
1.9.3

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


[libvirt] [PATCH v1 1/3] migration: add migration_host support for Ipv6 address without brackets

2014-09-11 Thread Chen Fan
when specifying migration_host to an Ipv6 address without brackets,
it was resolved to an incorrect address, such as:
   tcp:2001:0DB8::1428:,
but the correct address should be:
   tcp:[2001:0DB8::1428]:
so we should add brackets when parsing it.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_migration.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index e4b664b..c7eb305 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2850,11 +2850,22 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
 goto cleanup;
 
 if (migrateHost != NULL) {
-if (virSocketAddrIsNumeric(migrateHost) &&
-virSocketAddrParse(NULL, migrateHost, AF_UNSPEC) < 0)
-goto cleanup;
+virSocketAddr migrateHostSocket;
+bool migrateHostisIpv6Address = false;
+
+if (virSocketAddrIsNumeric(migrateHost)) {
+if (virSocketAddrParse(&migrateHostSocket, migrateHost, 
AF_UNSPEC) < 0)
+goto cleanup;
+
+if (VIR_SOCKET_ADDR_IS_FAMILY(&migrateHostSocket, AF_INET6)) {
+migrateHostisIpv6Address = true;
+}
+}
 
-   if (VIR_STRDUP(hostname, migrateHost) < 0)
+if ((migrateHostisIpv6Address &&
+ virAsprintf(&hostname, "[%s]", migrateHost) < 0) ||
+(!migrateHostisIpv6Address &&
+ virAsprintf(&hostname, "%s", migrateHost) < 0))
 goto cleanup;
 } else {
 if ((hostname = virGetHostname()) == NULL)
-- 
1.9.3

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


[libvirt] [PATCH] conf: Check migration_host is valid or not during libvirt restarts

2014-08-29 Thread Chen Fan
if user specified an invalid strings as migration hostname,
like setting: migration_host = "XXX", libvirt should check
it and return error during lbivirt restart.

Signed-off-by: Chen Fan 
---
 src/qemu/qemu_conf.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index e2ec54f..450ac5b 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "virerror.h"
 #include "qemu_conf.h"
@@ -650,6 +651,45 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
 
 GET_VALUE_STR("migration_host", cfg->migrateHost);
+if (cfg->migrateHost) {
+struct addrinfo hints;
+struct addrinfo *res;
+
+memset(&hints, 0, sizeof(hints));
+hints.ai_flags = AI_ADDRCONFIG;
+hints.ai_family = AF_UNSPEC;
+
+if (getaddrinfo(cfg->migrateHost, NULL, &hints, &res) != 0) {
+virReportError(VIR_ERR_CONF_SYNTAX,
+   _("migration_host: '%s' is not a valid hostname"),
+   cfg->migrateHost);
+goto cleanup;
+}
+
+if (res == NULL) {
+virReportError(VIR_ERR_CONF_SYNTAX,
+   _("No IP address for host '%s' found"),
+   cfg->migrateHost);
+goto cleanup;
+}
+
+freeaddrinfo(res);
+
+if (STRPREFIX(cfg->migrateHost, "localhost")) {
+virReportError(VIR_ERR_CONF_SYNTAX, "%s",
+   _("setting migration_host to 'localhost' is not 
allowed"));
+goto cleanup;
+}
+
+if (STREQ(cfg->migrateHost, "127.0.0.1") ||
+STREQ(cfg->migrateHost, "::1")) {
+virReportError(VIR_ERR_CONF_SYNTAX, "%s",
+   _("setting migration_host to '127.0.0.1' or '::1' "
+ "is not allowed"));
+goto cleanup;
+}
+}
+
 GET_VALUE_STR("migration_address", cfg->migrationAddress);
 
 GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
-- 
1.9.3

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


[libvirt] [PATCH] storage: remove unused 'canonPath' in virStorageFileGetMetadata

2014-08-25 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/storage/storage_driver.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 3604613..5ddc23a 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -2892,7 +2892,6 @@ virStorageFileGetMetadata(virStorageSourcePtr src,
   src->path, src->format, (int)uid, (int)gid, allow_probe);
 
 virHashTablePtr cycle = NULL;
-char *canonPath = NULL;
 int ret = -1;
 
 if (!(cycle = virHashCreate(5, NULL)))
@@ -2904,7 +2903,6 @@ virStorageFileGetMetadata(virStorageSourcePtr src,
 ret = virStorageFileGetMetadataRecurse(src, uid, gid,
allow_probe, cycle);
 
-VIR_FREE(canonPath);
 virHashFree(cycle);
 return ret;
 }
-- 
1.9.3

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


[libvirt] [PATCH] domain conf: Fix whitespace around judgement operation when parsing 'managed' attribute.

2014-06-25 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 src/conf/domain_conf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 02c394f..b7aa4f5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4261,7 +4261,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
  * element that might be (pure hostdev, or higher level device
  * (e.g. ) with type='hostdev')
  */
-if ((managed = virXMLPropString(node, "managed"))!= NULL) {
+if ((managed = virXMLPropString(node, "managed")) != NULL) {
 if (STREQ(managed, "yes"))
 def->managed = true;
 }
-- 
1.9.3

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


[libvirt] [PATCH 2/3] conf: add memdev device in XML

2014-06-24 Thread Chen Fan
Since qemu has supported memory-backend-ram and memory-backend-file object,
so we should add a new 'memdev' device type in  XML to introduce the
memory element, Its definition like the following:

  
ram0
1000

  

then we enable to support -numa memdev=ram0 command line for binding guest
numa nodes to host numa nodes.

Signed-off-by: Chen Fan 
---
 src/conf/domain_conf.c   | 203 ++-
 src/conf/domain_conf.h   |  42 +
 src/libvirt_private.syms |   4 +
 src/qemu/qemu_capabilities.c |   4 +
 src/qemu/qemu_capabilities.h |   2 +
 src/qemu/qemu_command.c  |  74 
 src/qemu/qemu_command.h  |   4 +
 src/qemu/qemu_hotplug.c  |   1 +
 8 files changed, 333 insertions(+), 1 deletion(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index be81dbe..c55bf47 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -204,7 +204,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
   "chr",
   "memballoon",
   "nvram",
-  "rng")
+  "rng",
+  "memdev")
 
 VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
   "none",
@@ -454,6 +455,16 @@ VIR_ENUM_IMPL(virDomainMemballoonModel, 
VIR_DOMAIN_MEMBALLOON_MODEL_LAST,
   "xen",
   "none")
 
+VIR_ENUM_IMPL(virDomainMemDev, VIR_DOMAIN_MEMDEV_LAST,
+  "ram",
+  "file")
+
+VIR_ENUM_IMPL(virDomainHostNodePolicy, VIR_DOMAIN_HOST_NODE_POLICY_LAST,
+  "default",
+  "preferred",
+  "bind",
+  "interleave")
+
 VIR_ENUM_IMPL(virDomainSmbiosMode, VIR_DOMAIN_SMBIOS_LAST,
   "none",
   "emulate",
@@ -770,6 +781,10 @@ static void virDomainObjDispose(void *obj);
 static void virDomainObjListDispose(void *obj);
 static void virDomainXMLOptionClassDispose(void *obj);
 
+static int
+virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt,
+ unsigned long long *mem, bool required);
+
 static int virDomainObjOnceInit(void)
 {
 if (!(virDomainObjClass = virClassNew(virClassForObjectLockable(),
@@ -1661,6 +1676,18 @@ void 
virDomainMemballoonDefFree(virDomainMemballoonDefPtr def)
 VIR_FREE(def);
 }
 
+void virDomainMemDevDefFree(virDomainMemDevDefPtr def)
+{
+if (!def)
+return;
+
+VIR_FREE(def->name);
+VIR_FREE(def->mempath);
+VIR_FREE(def->hostnodes);
+VIR_FREE(def);
+}
+
+
 void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def)
 {
 if (!def)
@@ -1864,6 +1891,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
 case VIR_DOMAIN_DEVICE_NVRAM:
 virDomainNVRAMDefFree(def->data.nvram);
 break;
+case VIR_DOMAIN_DEVICE_MEMDEV:
+virDomainMemDevDefFree(def->data.memdev);
+break;
 case VIR_DOMAIN_DEVICE_LAST:
 case VIR_DOMAIN_DEVICE_NONE:
 break;
@@ -2543,6 +2573,7 @@ virDomainDeviceGetInfo(virDomainDeviceDefPtr device)
 /* The following devices do not contain virDomainDeviceInfo */
 case VIR_DOMAIN_DEVICE_LEASE:
 case VIR_DOMAIN_DEVICE_GRAPHICS:
+case VIR_DOMAIN_DEVICE_MEMDEV:
 case VIR_DOMAIN_DEVICE_LAST:
 case VIR_DOMAIN_DEVICE_NONE:
 break;
@@ -2780,6 +2811,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
 case VIR_DOMAIN_DEVICE_NVRAM:
 case VIR_DOMAIN_DEVICE_LAST:
 case VIR_DOMAIN_DEVICE_RNG:
+case VIR_DOMAIN_DEVICE_MEMDEV:
 break;
 }
 
@@ -9192,6 +9224,104 @@ virDomainMemballoonDefParseXML(xmlNodePtr node,
 goto cleanup;
 }
 
+static virDomainMemDevDefPtr
+virDomainMemDevDefParseXML(xmlNodePtr node,
+   xmlXPathContextPtr ctxt)
+{
+char *type;
+virDomainMemDevDefPtr def;
+xmlNodePtr save = ctxt->node;
+char *tmp = NULL;
+char *policy = NULL;
+
+if (VIR_ALLOC(def) < 0)
+return NULL;
+
+type = virXMLPropString(node, "type");
+if (type == NULL) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("memory device must contain a type name"));
+goto error;
+}
+
+if ((def->type = virDomainMemDevTypeFromString(type)) < 0) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("unknown memory device type '%s'"), type);
+goto error;
+}
+
+if ((tmp = virXMLPropString(node, "merge")) != NULL) {
+if (STREQ(tmp, "yes"))
+def->merge = true;
+VIR_FREE(tmp);
+}
+
+if ((tmp = virXMLPropString(node, "dump")) != NULL) {
+if (STREQ(tmp, "yes"))
+def->dump = t

[libvirt] [PATCH 3/3] tests: add numa -memdev testing and docs support

2014-06-24 Thread Chen Fan
Signed-off-by: Chen Fan 
---
 docs/formatdomain.html.in  | 71 +++-
 docs/schemas/domaincommon.rng  | 76 +-
 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.args |  9 +++
 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml  | 35 ++
 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa4.args | 10 +++
 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa4.xml  | 35 ++
 tests/qemuxml2argvtest.c   |  2 +
 7 files changed, 233 insertions(+), 5 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa4.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa4.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 1b6ced8..5313c76 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1032,6 +1032,9 @@
 <numa>
   <cell cpus='0-3' memory='512000'/>
   <cell cpus='4-7' memory='512000'/>
+  <!-- OR -->
+  <cell cpus='0-3' memdev='ram0'/>
+  <cell cpus='4-7' memdev='ram1'/>
 </numa>
 ...
   </cpu>
@@ -1041,8 +1044,11 @@
   Each cell element specifies a NUMA cell or a NUMA node.
   cpus specifies the CPU or range of CPUs that are part of
   the node. memory specifies the node memory in kibibytes
-  (i.e. blocks of 1024 bytes). Each cell or node is assigned cellid
-  or nodeid in the increasing order starting from 0.
+  (i.e. blocks of 1024 bytes). Since 2.1,
+  memdev specifies the Host NUMA node that the Guest NUMA
+  node bind to. if memdev specified for one node, it must
+  be specified for all nodes. Each cell or node is assigned cellid or
+  nodeid in the increasing order starting from 0.
 
 
 
@@ -5249,6 +5255,67 @@ qemu-kvm -net nic,model=? /dev/null
 
   
 
+memory device
+
+  A memory device can be added to guest via memdev element.
+  Since 2.1, QEMU and KVM only
+
+
+  Example: usage of memory device configuration
+
+
+  ...
+  <devices>
+<memdev type='ram' merge='yes' dump='yes' prealloc='yes'>
+  <name>ram0</name>
+  <capacity unit='KiB'>102400</capacity>
+  <source host-nodes='0-1' policy='bind'/>
+</memdev>
+  </devices>
+  ...
+
+  
+type
+
+  
+The required type attribute specifies what type of memory device
+is provided. Valid type are:
+  
+
+  'ram' — memory ram backend.
+  'file' — memory file backend.
+
+
+merge
+
+  
+The optional merge attribute enables memory merge support.
+  
+
+dump
+
+  
+The optional dump attribute enables to dump memory device's memory in a
+core dump file.
+  
+
+prealloc
+
+  
+The optional prealloc attribute enables memory preallocation.
+  
+
+ source
+  The source element describes the device as seen from the host.
+  the optional mem-path element is required when specified 
type = 'file'.
+  the optional host-nodes element specified the Host nodes 
ids that the
+  Guest memory device binds to. the optional policy element 
specified the
+  memory policy of memory device. the policy is either 
"default", "preferred",
+  "bind", "interleave". defaults to "default".
+  
+  
+
+
 Security label
 
 
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 6cc922c..0334b28 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3148,6 +3148,32 @@
   
 
   
+  
+
+  
+
+   ram
+   file
+
+  
+  
+
+  yes
+
+  
+  
+
+  yes
+
+  
+  
+
+  yes
+
+  
+  
+
+  
   
 
   
@@ -3671,6 +3697,7 @@
 
 
 
+
   
 
 
@@ -3895,9 +3922,18 @@
   
 
   
-  
-
-  
+  
+
+  
+
+  
+
+
+  
+
+  
+
+  
 
   
 
@@ -4527,6 +4563,40 @@
 
 
   
+  
+
+  
+
+
+  
+
+
+  
+
+  
+
+  
+
+
+  
+
+  [a-zA-Z0-9\-_]+
+
+  
+
+
+  
+
+

[libvirt] [PATCH 0/3] add binding guest numa nodes to host numa nodes support

2014-06-24 Thread Chen Fan
Since qemu has supported numa option -memdev config:
   -object 
memory-backend-ram,size=1024M,policy=membind,host-nodes=0,id=ram-node0 \
   -numa node,nodeid=0,cpus=0,memdev=ram-node0 \
for binding guest numa nodes to host numa nodes.

 So we introduce this capability in libvirt by configuration
 domain XML like:
  ...
  

  

  
  ...

 
   
 ram0
 1000
 
   
 

Chen Fan (3):
  numa: add '-numa memdev=' support
  conf: add memdev device in  XML
  tests: add numa -memdev testing and docs support

 docs/formatdomain.html.in  |  71 ++-
 docs/schemas/domaincommon.rng  |  76 +++-
 src/conf/cpu_conf.c|  73 ++--
 src/conf/cpu_conf.h|  13 +-
 src/conf/domain_conf.c | 203 -
 src/conf/domain_conf.h |  42 +
 src/libvirt_private.syms   |   4 +
 src/qemu/qemu_capabilities.c   |   4 +
 src/qemu/qemu_capabilities.h   |   2 +
 src/qemu/qemu_command.c|  84 -
 src/qemu/qemu_command.h|   4 +
 src/qemu/qemu_hotplug.c|   1 +
 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.args |   9 +
 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml  |  35 
 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa4.args |  10 +
 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa4.xml  |  35 
 tests/qemuxml2argvtest.c   |   2 +
 17 files changed, 644 insertions(+), 24 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa4.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa4.xml

-- 
1.9.3

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


[libvirt] [PATCH 1/3] numa: add '-numa memdev=' support

2014-06-24 Thread Chen Fan
Since qemu has supported '-numa memdev=ram0' command option, so libvirt
should add numa element to support specified memdev attrubute in XML.

Signed-off-by: Chen Fan 
---
 src/conf/cpu_conf.c | 73 +++--
 src/conf/cpu_conf.h | 13 -
 src/qemu/qemu_command.c | 10 +--
 3 files changed, 78 insertions(+), 18 deletions(-)

diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index ebdaa19..2d0980e 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -29,6 +29,7 @@
 #include "cpu_conf.h"
 #include "domain_conf.h"
 #include "virstring.h"
+#include "c-ctype.h"
 
 #define VIR_FROM_THIS VIR_FROM_CPU
 
@@ -84,6 +85,8 @@ virCPUDefFree(virCPUDefPtr def)
 for (i = 0; i < def->ncells; i++) {
 virBitmapFree(def->cells[i].cpumask);
 VIR_FREE(def->cells[i].cpustr);
+if (def->cells[i].memtype == VIR_CPU_CELL_MEMORY_DEV)
+VIR_FREE(def->cells[i].data.memstr);
 }
 VIR_FREE(def->cells);
 VIR_FREE(def->vendor_id);
@@ -153,7 +156,13 @@ virCPUDefCopy(const virCPUDef *cpu)
 
 for (i = 0; i < cpu->ncells; i++) {
 copy->cells[i].cellid = cpu->cells[i].cellid;
-copy->cells[i].mem = cpu->cells[i].mem;
+copy->cells[i].memtype = cpu->cells[i].memtype;
+if (cpu->cells[i].memtype == VIR_CPU_CELL_MEMORY_DEV) {
+if (VIR_STRDUP(copy->cells[i].data.memstr, 
cpu->cells[i].data.memstr) < 0)
+goto error;
+} else {
+copy->cells[i].data.mem = cpu->cells[i].data.mem;
+}
 
 copy->cells[i].cpumask = virBitmapNewCopy(cpu->cells[i].cpumask);
 
@@ -436,7 +445,7 @@ virCPUDefParseXML(xmlNodePtr node,
 def->ncells = n;
 
 for (i = 0; i < n; i++) {
-char *cpus, *memory;
+char *cpus, *memory, *memdev;
 int ret, ncpus = 0;
 
 def->cells[i].cellid = i;
@@ -455,20 +464,52 @@ virCPUDefParseXML(xmlNodePtr node,
 def->cells_cpus += ncpus;
 
 memory = virXMLPropString(nodes[i], "memory");
-if (!memory) {
-virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("Missing 'memory' attribute in NUMA cell"));
-goto error;
-}
-
-ret  = virStrToLong_ui(memory, NULL, 10, &def->cells[i].mem);
-if (ret == -1) {
+memdev = virXMLPropString(nodes[i], "memdev");
+if (memory || memdev) {
+if (memory && memdev) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Both 'memory' and 'memdev' attribute in 
NUMA cell is not allowed"));
+goto error;
+}
+
+if (memory) {
+ret  = virStrToLong_ui(memory, NULL, 10, 
&def->cells[i].data.mem);
+if (ret == -1) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Invalid 'memory' attribute in NUMA 
cell"));
+VIR_FREE(memory);
+goto error;
+}
+def->cells[i].memtype = VIR_CPU_CELL_MEMORY_SIZE;
+VIR_FREE(memory);
+} else {
+if (strlen(memdev) < 1) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Empty 'memdev' attribute in NUMA 
cell"));
+VIR_FREE(memdev);
+goto error;
+}
+
+if (!c_isalpha(memdev[0])) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Invalid 'memdev' attribute name in 
NUMA cell, "
+ "it must begin with a letter"));
+VIR_FREE(memdev);
+goto error;
+}
+
+if (VIR_STRDUP(def->cells[i].data.memstr, memdev) < 0) {
+VIR_FREE(memdev);
+goto error;
+}
+def->cells[i].memtype = VIR_CPU_CELL_MEMORY_DEV;
+VIR_FREE(memdev);
+}
+} else {
 virReportError(VIR_ERR_XML_ERROR, "%s",
-   _("Invalid 'memory' attribute in NUMA cell"));
-VIR_FREE(memory);
+   _("Missing 'memory&#

[libvirt] [patch v2 1/1] manual: Add virsh manual about specified migration host

2014-06-09 Thread Chen Fan
the 'migration_host' description maybe have a bit of difficulty to
understand for user, so add this manual for them.

Signed-off-by: Chen Fan 
---
 tools/virsh.pod | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/tools/virsh.pod b/tools/virsh.pod
index 02671b4..7b30292 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1208,7 +1208,8 @@ such as GFS2 or GPFS. If you are sure the migration is 
safe or you just do not
 care, use I<--unsafe> to force the migration.
 
 The I is the connection URI of the destination host, and
-I is the migration URI, which usually can be omitted (see below).
+I is the migration URI for specifying which IP address/URI of the
+destination host to tansfer migration data, which usually can be omitted (see 
below).
 I is used for renaming the domain to new name during migration, which
 also usually can be omitted.  Likewise, I<--xml> B is usually
 omitted, but can be used to supply an alternative XML file for use on
@@ -1238,6 +1239,15 @@ seen from the source machine.
 
 When I is not specified, libvirt will automatically determine the
 hypervisor specific URI, by looking up the target host's configured hostname.
+
+For QEMU/KVM hypervisor, when I is not specified, at first libvirt
+will ask the destination side whether the optional "migration_host" is 
specified
+or not, if the "migration_host" is specified, libvirt will use the specified
+network for transferring migration data(the "migrateion_host" is useful when
+hosts has multiple network interface). if the "migrateion_host" is not 
specified
+too, libvirt will automatically determine the hypervisor specific URI, by 
looking
+up the target host's configured hostname.
+
 There are a few scenarios where specifying I may help:
 
 =over 4
-- 
1.9.3

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


[libvirt] [PATCH] manual: Add virsh manual about specified migration host

2014-05-29 Thread Chen Fan
the 'migration_host' description maybe have a bit of difficulty to
understand for user, so add this manual for them.

Signed-off-by: Chen Fan 
---
 tools/virsh.pod | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/virsh.pod b/tools/virsh.pod
index de9a4f7..8d77a2f 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1238,6 +1238,11 @@ seen from the source machine.
 
 When I is not specified, libvirt will automatically determine the
 hypervisor specific URI, by looking up the target host's configured hostname.
+In particular, some hypervisors support having this migration hostname 
specified
+separately by setting 'migration_host' in definition file, if 'migration_host'
+is specified, the hostname or IP address will be used to as the default 
I
+while running migration from source host. if 'migration_host' is not specified,
+the migration hostname is set to the host's configured hostname by default.
 There are a few scenarios where specifying I may help:
 
 =over 4
@@ -1251,7 +1256,9 @@ explicitly specified, using an IP address, or a correct 
hostname.
 interfaces, it might be desirable for the migration data stream to be sent over
 a specific interface for either security or performance reasons.  In this case
 I should be explicitly specified, using an IP address associated
-with the network to be used.
+with the network to be used. In particular, Some hypervisors could be easy to
+specify the default network interface by setting 'migration_host'. then the
+I can be omitted.
 
 =item * The firewall restricts what ports are available.  When libvirt 
generates
 a migration URI, it will pick a port number using hypervisor specific rules.
-- 
1.9.3

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


  1   2   >