[libvirt] [PATCH] storage: fix the error message when encrypted raw volume resize

2018-08-20 Thread Shivaprasad G Bhat
The vol-dumpxml shows the volume target format type as raw for
encrypted volumes. The error message when attempting to resize
with prealloc is confusing here.

Signed-off-by: Shivaprasad G Bhat 
---
 src/storage/storage_util.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c
index 42a9b6abf0..2abedb24b0 100644
--- a/src/storage/storage_util.c
+++ b/src/storage/storage_util.c
@@ -2343,7 +2343,7 @@ virStorageBackendVolResizeLocal(virStoragePoolObjPtr pool,
 } else if (vol->target.format == VIR_STORAGE_FILE_RAW && 
vol->target.encryption) {
 if (pre_allocate) {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("preallocate is only supported for raw "
+   _("preallocate is only supported for unencrypted 
raw "
  "type volume"));
 return -1;
 }

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


Re: [libvirt] [RFC PATCH 00/28] Enable multifunction pci hotplug

2018-03-15 Thread Shivaprasad G Bhat



On 03/15/2018 08:03 PM, Daniel P. Berrangé wrote:

On Thu, Mar 15, 2018 at 07:54:47PM +0530, Shivaprasad G Bhat wrote:


On 03/15/2018 03:31 PM, Daniel P. Berrangé wrote:

On Wed, Mar 14, 2018 at 10:44:30PM +0530, Shivaprasad G Bhat wrote:

Hi All,

I have revisited/rewritten my previously posted patches. Here is
the RFC. Since this patchset is a complete rewrite, I am starting
with v1 here.

The semantics is as discussed before
https://www.redhat.com/archives/libvir-list/2016-April/msg01057.html

As I went on to refactor the code to support multifunction virtio devices,
I realised the abort/cleanup path would be a nightmare there, in case of
failures. So, dropped that attempt. The current RFC limits to the real
practical use cases of Multifunction PCI hostdevices. All new test code
to support multifunction PCI hostdevices and test cases are added to
prove the functionality.

I guess I'm not really understanding the use case here.  With SRIOV
devices, you can already choose between assigning either the physical
function (which gives the guest access to all virtual functions), or
to assign an arbitrary set of individiual functions to various guests.
Why do we need to be able to list many  at the same time
when hotplugging to assign multiple functions.

Basically can you provide a full description of the problem you are
trying to solve and why existing functionality isn't sufficient.

Hi Daniel,

This is for cards which may not necessarily be networking cards. Or may be a
mix of
networking and storage.

Suppose, user has below card
0005:01:00.0 Ethernet controller: Emulex Corporation OneConnect NIC (Lancer)
(rev 10)
0005:01:00.1 Ethernet controller: Emulex Corporation OneConnect NIC (Lancer)
(rev 10)
0005:01:00.2 Ethernet controller: Emulex Corporation OneConnect NIC (Lancer)
(rev 10)
0005:01:00.3 Ethernet controller: Emulex Corporation OneConnect NIC (Lancer)
(rev 10)
0005:01:00.4 Fibre Channel: Emulex Corporation OneConnect FCoE Initiator
(Lancer) (rev 10)
0005:01:00.5 Fibre Channel: Emulex Corporation OneConnect FCoE Initiator
(Lancer) (rev 10)

Ok, so this is a device with many functions, but which isn't SRIOV
based, and the goal is to assign the physical device to the guest,
such that guest has all functions available.


If user wants to hotplug this card to guest, He has to detach all the
functions from host driver,
then hotplug 0005:01:00.0, 0005:01:00.1, so on individually. But, today with
each hotplug
of the function, each  goes to different guest slot. Whereas, PCI
requires all of
them to be on the same slot. This is not supported on libvirt today.

The multifunction cards cant be hotplugged to guest today with the
individual
, as the operation is queued by qemu till the function zero of
guest slot is
hotplugged. On function zero hotplug, the qemu sends out the event to guest
for device probing where all the previously hotplugged functions from the
same slot are discovered. So, grouping the s within the 
would become necessary to make the whole thing a single operation.

So IIUC, from the patches, if the user wants to assign the physical
device to the guest, they would need to provide XML that looked like
this to the virDomainAttachDevice() method:

 
   
 
 
   
 
   
   
 
 
   
 
   
   
 
 
   
 
   
   
 
 
   
 
   
   
 
 
   
 
   
   
 
 
   
 
   
 


Where as if the device were SRIOV based, they would only have to
provide

 
   
 
 
   
 
   
 

for the guest to get access to all functions.

I find this difference in behaviour and approach really unpleasant.

I think that they user should only need to provide the the address
of the physical device, in both cases. At most perhaps we need a
new attribute  multifunction="on" on the source address to tell
libvirt that it should attach all the functions, not just the
first

 
   
 
 
   
 
   
 


But with this approach the user can not prevent few functions from being 
assigned
to guest if he wants to. It will be all or none. The PCI requires only 
function zero to be

present and so, partial assignment is expected to work.

So user should have that control?



Regards,
Daniel


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

Re: [libvirt] [RFC PATCH 00/28] Enable multifunction pci hotplug

2018-03-15 Thread Shivaprasad G Bhat



On 03/15/2018 03:31 PM, Daniel P. Berrangé wrote:

On Wed, Mar 14, 2018 at 10:44:30PM +0530, Shivaprasad G Bhat wrote:

Hi All,

I have revisited/rewritten my previously posted patches. Here is
the RFC. Since this patchset is a complete rewrite, I am starting
with v1 here.

The semantics is as discussed before
https://www.redhat.com/archives/libvir-list/2016-April/msg01057.html

As I went on to refactor the code to support multifunction virtio devices,
I realised the abort/cleanup path would be a nightmare there, in case of
failures. So, dropped that attempt. The current RFC limits to the real
practical use cases of Multifunction PCI hostdevices. All new test code
to support multifunction PCI hostdevices and test cases are added to
prove the functionality.

I guess I'm not really understanding the use case here.  With SRIOV
devices, you can already choose between assigning either the physical
function (which gives the guest access to all virtual functions), or
to assign an arbitrary set of individiual functions to various guests.
Why do we need to be able to list many  at the same time
when hotplugging to assign multiple functions.

Basically can you provide a full description of the problem you are
trying to solve and why existing functionality isn't sufficient.


Hi Daniel,

This is for cards which may not necessarily be networking cards. Or may 
be a mix of

networking and storage.

Suppose, user has below card
0005:01:00.0 Ethernet controller: Emulex Corporation OneConnect NIC 
(Lancer) (rev 10)
0005:01:00.1 Ethernet controller: Emulex Corporation OneConnect NIC 
(Lancer) (rev 10)
0005:01:00.2 Ethernet controller: Emulex Corporation OneConnect NIC 
(Lancer) (rev 10)
0005:01:00.3 Ethernet controller: Emulex Corporation OneConnect NIC 
(Lancer) (rev 10)
0005:01:00.4 Fibre Channel: Emulex Corporation OneConnect FCoE Initiator 
(Lancer) (rev 10)
0005:01:00.5 Fibre Channel: Emulex Corporation OneConnect FCoE Initiator 
(Lancer) (rev 10)


If user wants to hotplug this card to guest, He has to detach all the 
functions from host driver,
then hotplug 0005:01:00.0, 0005:01:00.1, so on individually. But, today 
with each hotplug
of the function, each  goes to different guest slot. Whereas, 
PCI requires all of

them to be on the same slot. This is not supported on libvirt today.

The multifunction cards cant be hotplugged to guest today with the 
individual
, as the operation is queued by qemu till the function zero of 
guest slot is

hotplugged. On function zero hotplug, the qemu sends out the event to guest
for device probing where all the previously hotplugged functions from the
same slot are discovered. So, grouping the s within the 
would become necessary to make the whole thing a single operation.

The patches try to fix this aspect of the use case.

Thanks,
Shivaprasad


Regards,
Daniel


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

[libvirt] [RFC PATCH 03/28] tests: pci: Mock the iommu groups and vfio

2018-03-15 Thread Shivaprasad G Bhat
The iommu group, /dev/vfio/ behaviours
of the host are mocked. This patch implments support for
multifunction/multiple devices per iommu groups and emulates
the /dev/vfio/ file correctly.

This code helps adding necessary testcases for pci-hotplug
code.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 tests/virpcimock.c   |  178 +++---
 tests/virpcitestdata/0005-90-01.1.config |  Bin
 tests/virpcitestdata/0005-90-01.2.config |  Bin
 tests/virpcitestdata/0005-90-01.3.config |  Bin
 4 files changed, 162 insertions(+), 16 deletions(-)
 create mode 100644 tests/virpcitestdata/0005-90-01.3.config

diff --git a/tests/virpcimock.c b/tests/virpcimock.c
index 2a7e9216b2..22adc740b8 100644
--- a/tests/virpcimock.c
+++ b/tests/virpcimock.c
@@ -51,7 +51,13 @@ static DIR * (*real_opendir)(const char *name);
 char *fakerootdir;
 char *fakesysfspcidir;
 
+struct pciIommuGroup {
+int iommu;
+size_t nDevicesBoundToVFIO;/* Indicates the devices in the group */
+};
+
 # define SYSFS_PCI_PREFIX "/sys/bus/pci/"
+# define SYSFS_KERNEL_PREFIX "/sys/kernel/"
 
 # define STDERR(...) \
 fprintf(stderr, "%s %zu: ", __FUNCTION__, (size_t) __LINE__); \
@@ -142,6 +148,9 @@ size_t nPCIDevices = 0;
 struct pciDriver **pciDrivers = NULL;
 size_t nPCIDrivers = 0;
 
+struct pciIommuGroup **pciIommuGroups = NULL;
+size_t npciIommuGroups = 0;
+
 struct fdCallback *callbacks = NULL;
 size_t nCallbacks = 0;
 
@@ -191,7 +200,7 @@ make_file(const char *path,
 VIR_FREE(filepath);
 }
 
-static void
+static void ATTRIBUTE_UNUSED
 make_symlink(const char *path,
   const char *name,
   const char *target)
@@ -255,6 +264,13 @@ getrealpath(char **newpath,
 errno = ENOMEM;
 return -1;
 }
+} else if (STRPREFIX(path, SYSFS_KERNEL_PREFIX)) {
+if (virAsprintfQuiet(newpath, "%s/%s",
+ fakerootdir,
+ path) < 0) {
+errno = ENOMEM;
+return -1;
+}
 } else {
 if (VIR_STRDUP_QUIET(*newpath, path) < 0)
 return -1;
@@ -465,6 +481,101 @@ pci_device_autobind(struct pciDevice *dev)
 return pci_driver_bind(driver, dev);
 }
 
+static void
+pci_iommu_new(int num)
+{
+char *iommupath, *kerneldir;
+struct pciIommuGroup *iommuGroup;
+
+if (VIR_ALLOC_QUIET(iommuGroup) < 0)
+ABORT_OOM();
+
+iommuGroup->iommu = num;
+iommuGroup->nDevicesBoundToVFIO = 0; /* No device bound to vfio by default 
*/
+
+if (virAsprintfQuiet(, "%s%s",
+ fakerootdir, SYSFS_KERNEL_PREFIX) < 0)
+ABORT_OOM();
+
+if (virAsprintfQuiet(, "%s/iommu_groups/%d/devices", kerneldir, 
num) < 0)
+ABORT_OOM();
+VIR_FREE(kerneldir);
+
+if (virFileMakePath(iommupath) < 0)
+ABORT("Unable to create: %s", iommupath);
+VIR_FREE(iommupath);
+
+if (VIR_APPEND_ELEMENT_QUIET(pciIommuGroups, npciIommuGroups, iommuGroup) 
< 0)
+ABORT_OOM();
+}
+
+static int
+pci_vfio_release_iommu(struct pciDevice *device)
+{
+char *vfiopath = NULL;
+int ret = -1;
+size_t i = 0;
+
+for (i = 0; i < npciIommuGroups; i++) {
+if (pciIommuGroups[i]->iommu == device->iommuGroup)
+break;
+}
+
+if (i != npciIommuGroups) {
+if (pciIommuGroups[i]->nDevicesBoundToVFIO == 0) {
+ret = 0;
+goto cleanup;
+}
+pciIommuGroups[i]->nDevicesBoundToVFIO--;
+if (!pciIommuGroups[i]->nDevicesBoundToVFIO) {
+if (virAsprintfQuiet(, "%s/dev/vfio/%d",
+ fakesysfspcidir, device->iommuGroup) < 0) {
+errno = ENOMEM;
+goto cleanup;
+}
+if (unlink(vfiopath) < 0)
+goto cleanup;
+}
+}
+
+ret = 0;
+ cleanup:
+VIR_FREE(vfiopath);
+return ret;
+}
+
+static int
+pci_vfio_lock_iommu(struct pciDevice *device)
+{
+char *vfiopath = NULL;
+int ret = -1;
+size_t i = 0;
+int fd = -1;
+
+for (i = 0; i < npciIommuGroups; i++) {
+if (pciIommuGroups[i]->iommu == device->iommuGroup)
+break;
+}
+
+if (i != npciIommuGroups) {
+if (!pciIommuGroups[i]->nDevicesBoundToVFIO) {
+if (virAsprintfQuiet(, "%s/dev/vfio/%d",
+ fakesysfspcidir, device->iommuGroup) < 0) {
+errno = ENOMEM;
+goto cleanup;
+}
+if ((fd = real_open(vfiopath, O_CREAT)) < 0)
+goto cleanup;
+}
+pciIommuGroups[i]->nDevicesBoundToVFIO++;
+}
+
+ret = 0;
+ cleanup:
+real_close(fd);
+VIR_FREE(vfiopath);
+return ret;
+}
 
 /*
  * PCI Driver functions
@@ -588,6 +699,10 @@ pci_driver

[libvirt] [RFC PATCH 07/28] tests: Add a baseline test for multifunction pci device use case

2018-03-15 Thread Shivaprasad G Bhat
There are already good number of test cases with hostdevices,
few have multifunction devices but none having more than one
than one multifunction cards.

This patch adds a case where there are two multifunction cards
and two Virtual functions part of the same XML.

0001:01:00.X & 0005:09:00.X - are Multifunction PCI cards.
:06:12.[5|6] - are SRIOV Virtual functions

The next few commits improve on automatically detecting the multifunction
cards and auto-assinging the addresses appropriately.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 .../hostdev-pci-multifunction.args |   29 +++
 .../qemuxml2argvdata/hostdev-pci-multifunction.xml |   59 +++
 tests/qemuxml2argvtest.c   |5 +
 .../hostdev-pci-multifunction.xml  |   79 
 tests/qemuxml2xmltest.c|1 
 5 files changed, 173 insertions(+)
 create mode 100644 tests/qemuxml2argvdata/hostdev-pci-multifunction.args
 create mode 100644 tests/qemuxml2argvdata/hostdev-pci-multifunction.xml
 create mode 100644 tests/qemuxml2xmloutdata/hostdev-pci-multifunction.xml

diff --git a/tests/qemuxml2argvdata/hostdev-pci-multifunction.args 
b/tests/qemuxml2argvdata/hostdev-pci-multifunction.args
new file mode 100644
index 00..6b57f5713f
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-pci-multifunction.args
@@ -0,0 +1,29 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name delete \
+-S \
+-M pc \
+-m 256 \
+-smp 4,sockets=4,cores=1,threads=1 \
+-uuid 583a8e8e-f0ce-4f53-89ab-092862148b25 \
+-nographic \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-delete/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline \
+-no-acpi \
+-boot c \
+-usb \
+-device vfio-pci,host=0005:90:01.0,id=hostdev0,bus=pci.0,addr=0x3 \
+-device vfio-pci,host=0001:01:00.1,id=hostdev1,bus=pci.0,addr=0x4 \
+-device vfio-pci,host=0001:01:00.0,id=hostdev2,bus=pci.0,addr=0x5 \
+-device vfio-pci,host=0005:90:01.2,id=hostdev3,bus=pci.0,addr=0x6 \
+-device vfio-pci,host=0005:90:01.3,id=hostdev4,bus=pci.0,addr=0x7 \
+-device vfio-pci,host=06:12.1,id=hostdev5,bus=pci.0,addr=0x8 \
+-device vfio-pci,host=06:12.2,id=hostdev6,bus=pci.0,addr=0x9 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0xa
diff --git a/tests/qemuxml2argvdata/hostdev-pci-multifunction.xml 
b/tests/qemuxml2argvdata/hostdev-pci-multifunction.xml
new file mode 100644
index 00..06c889c64d
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-pci-multifunction.xml
@@ -0,0 +1,59 @@
+
+  delete
+  583a8e8e-f0ce-4f53-89ab-092862148b25
+  262144
+  4
+  
+hvm
+  
+  
+/usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+  
+  
+
+  
+
+
+  
+  
+
+  
+
+
+  
+  
+
+  
+
+
+  
+  
+
+  
+
+
+  
+  
+
+  
+
+
+  
+  
+
+  
+
+
+  
+  
+
+  
+
+  
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 731db9ed52..1e00eb167a 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1604,6 +1604,11 @@ mymain(void)
 DO_TEST("hostdev-vfio-multidomain",
 QEMU_CAPS_NODEFCONFIG,
 QEMU_CAPS_DEVICE_VFIO_PCI, QEMU_CAPS_HOST_PCI_MULTIDOMAIN);
+DO_TEST("hostdev-pci-multifunction",
+QEMU_CAPS_KVM,
+QEMU_CAPS_DEVICE_VFIO_PCI,
+   QEMU_CAPS_HOST_PCI_MULTIDOMAIN,
+QEMU_CAPS_PCI_MULTIFUNCTION);
 DO_TEST("hostdev-mdev-precreated",
 QEMU_CAPS_NODEFCONFIG,
 QEMU_CAPS_DEVICE_VFIO_PCI);
diff --git a/tests/qemuxml2xmloutdata/hostdev-pci-multifunction.xml 
b/tests/qemuxml2xmloutdata/hostdev-pci-multifunction.xml
new file mode 100644
index 00..52ed86e305
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/hostdev-pci-multifunction.xml
@@ -0,0 +1,79 @@
+
+  delete
+  583a8e8e-f0ce-4f53-89ab-092862148b25
+  262144
+  262144
+  4
+  
+hvm
+
+  
+  
+  destroy
+  restart
+  destroy
+  
+/usr/bin/qemu-system-x86_64
+
+  
+
+
+  
+
+
+
+
+
+  
+  
+
+  
+  
+
+
+  
+  
+
+  
+  
+
+
+  
+  
+
+  
+  
+
+
+  
+  
+
+  
+  
+
+
+  
+  
+
+  
+  
+
+
+  
+  
+
+  
+  
+
+
+  
+  
+
+  
+  
+
+
+  
+
+  
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 28ba46efb2..91e3285109 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -473,6 +473,7 @@ mymain(void)
 
 DO_TEST("hostdev-u

[libvirt] [RFC PATCH 25/28] qemu: hotplug: Implement multifunction device hotplug

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.c |2 
 src/qemu/qemu_domain_address.c |   68 +
 src/qemu/qemu_domain_address.h |5 +
 src/qemu/qemu_driver.c |   66 ++--
 src/qemu/qemu_hotplug.c|   82 
 src/qemu/qemu_hotplug.h|4 +
 tests/qemuhotplugtest.c|   39 --
 .../qemuhotplug-multifunction-hostdev-pci-2.xml|   14 +++
 .../qemuhotplug-multifunction-hostdev-pci.xml  |   20 +
 ...hotplug-base-live+multifunction-hostdev-pci.xml |   76 +++
 ...eries-base-live+multifunction-hostdev-pci-2.xml |   61 +++
 ...pseries-base-live+multifunction-hostdev-pci.xml |   69 +
 12 files changed, 475 insertions(+), 31 deletions(-)
 create mode 100644 
tests/qemuhotplugtestdevices/qemuhotplug-multifunction-hostdev-pci-2.xml
 create mode 100644 
tests/qemuhotplugtestdevices/qemuhotplug-multifunction-hostdev-pci.xml
 create mode 100644 
tests/qemuhotplugtestdomains/qemuhotplug-base-live+multifunction-hostdev-pci.xml
 create mode 100644 
tests/qemuhotplugtestdomains/qemuhotplug-pseries-base-live+multifunction-hostdev-pci-2.xml
 create mode 100644 
tests/qemuhotplugtestdomains/qemuhotplug-pseries-base-live+multifunction-hostdev-pci.xml

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c0a0af525f..1cfaf01540 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -33,6 +33,8 @@
 #include "qemu_capabilities.h"
 #include "qemu_migration.h"
 #include "qemu_security.h"
+#include "qemu_hotplug.h"
+#include "qemu_hostdev.h"
 #include "viralloc.h"
 #include "virlog.h"
 #include "virerror.h"
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 7bee4fb937..ee743321dd 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -25,6 +25,7 @@
 
 #include "qemu_domain_address.h"
 #include "qemu_domain.h"
+#include "domain_conf.h"
 #include "viralloc.h"
 #include "virhostdev.h"
 #include "virerror.h"
@@ -3206,6 +3207,73 @@ qemuDomainEnsurePCIAddress(virDomainObjPtr obj,
  info->pciConnectFlags);
 }
 
+
+int
+qemuDomainPCIMultifunctionHostdevEnsurePCIAddresses(virDomainObjPtr vm,
+virDomainDeviceDefListPtr 
devlist,
+virQEMUDriverPtr driver)
+{
+int ret = -1, aggrslotidx = 0;
+virBitmapPtr slotmap = NULL;
+size_t i;
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virDomainPCIMultifunctionAddressInfoPtr devinfos = NULL;
+
+if (devlist->count > VIR_PCI_MAX_FUNCTIONS) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+   _("More devices per slot found"));
+return -1;
+}
+
+for (i = 0; i < devlist->count; i++)
+qemuDomainFillDevicePCIConnectFlags(vm->def, devlist->devs[i], 
priv->qemuCaps, driver);
+
+if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + devlist->count) 
< 0)
+return -1;
+
+/* Temporarily add the devices to the domain def to get the
+ * next aggregateIdx */
+for (i = 0; i < devlist->count; i++)
+vm->def->hostdevs[vm->def->nhostdevs++] = 
devlist->devs[i]->data.hostdev;
+
+for (i = 0; i < devlist->count; i++) {
+if (qemuDomainIsPSeries(vm->def)) {
+/* Isolation groups are only relevant for pSeries guests */
+if (qemuDomainFillDeviceIsolationGroup(vm->def, devlist->devs[i]) 
< 0)
+return -1;
+}
+qemuDomainSetDeviceSlotAggregateIdx(vm->def, devlist->devs[i]);
+aggrslotidx = aggrslotidx ? aggrslotidx : 
devlist->devs[i]->data.hostdev->info->aggregateSlotIdx;
+if (aggrslotidx != 
devlist->devs[i]->data.hostdev->info->aggregateSlotIdx) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Devices belong to different PCI slots"));
+return -1;
+}
+}
+
+for (i = 0; i < devlist->count; i++)
+vm->def->hostdevs[--(vm->def->nhostdevs)] = NULL;
+
+slotmap = virDomainDefHostdevGetPCIOnlineFunctionMap(vm->def, aggrslotidx);
+if (!virBitmapIsAllClear(slotmap)) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+   _("Device already assigned to guest"));
+return -1;
+}
+
+if (VIR_ALLOC(devinfos) < 0)
+retur

[libvirt] [RFC PATCH 23/28] qemu: hotplug: Queue and wait for multiple devices

2018-03-15 Thread Shivaprasad G Bhat
With multifunction devices, multiple delete requests are sent
to qemu and all the requests should be queued up.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.h  |3 ++-
 src/qemu/qemu_hotplug.c |   38 --
 2 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 339d0ba82c..85cbc2b5e8 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -195,7 +195,8 @@ typedef enum {
 typedef struct _qemuDomainUnpluggingDevice qemuDomainUnpluggingDevice;
 typedef qemuDomainUnpluggingDevice *qemuDomainUnpluggingDevicePtr;
 struct _qemuDomainUnpluggingDevice {
-const char *alias;
+const char **aliases;
+size_t naliases;
 qemuDomainUnpluggingDeviceStatus status;
 };
 
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 007ecb0923..7dffaf9502 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4542,16 +4542,21 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
 
 static void
 qemuDomainMarkDeviceAliasForRemoval(virDomainObjPtr vm,
-const char *alias)
+const char *alias,
+bool fresh)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
 
-memset(>unplug, 0, sizeof(priv->unplug));
+if (fresh)
+memset(>unplug, 0, sizeof(priv->unplug));
 
 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
 return;
 
-priv->unplug.alias = alias;
+if (VIR_REALLOC_N(priv->unplug.aliases, priv->unplug.naliases + 1) < 0)
+return;
+
+priv->unplug.aliases[priv->unplug.naliases++] = alias;
 }
 
 
@@ -4560,7 +4565,7 @@ qemuDomainMarkDeviceForRemoval(virDomainObjPtr vm,
virDomainDeviceInfoPtr info)
 
 {
-qemuDomainMarkDeviceAliasForRemoval(vm, info->alias);
+qemuDomainMarkDeviceAliasForRemoval(vm, info->alias, true);
 }
 
 
@@ -4568,7 +4573,8 @@ static void
 qemuDomainResetDeviceRemoval(virDomainObjPtr vm)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
-priv->unplug.alias = NULL;
+VIR_FREE(priv->unplug.aliases);
+priv->unplug.naliases = 0;
 }
 
 /* Returns:
@@ -4596,13 +4602,14 @@ qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
 return 1;
 until += qemuDomainRemoveDeviceWaitTime;
 
-while (priv->unplug.alias) {
+/* All devices should get released around same time*/
+while (priv->unplug.naliases) {
 if ((rc = virDomainObjWaitUntil(vm, until)) == 1)
 return 0;
 
 if (rc < 0) {
 VIR_WARN("Failed to wait on unplug condition for domain '%s' "
- "device '%s'", vm->def->name, priv->unplug.alias);
+ "device '%s'", vm->def->name, priv->unplug.aliases[0]);
 return 1;
 }
 }
@@ -4627,14 +4634,17 @@ qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
   const char *devAlias,
   qemuDomainUnpluggingDeviceStatus status)
 {
+size_t i;
 qemuDomainObjPrivatePtr priv = vm->privateData;
 
-if (STREQ_NULLABLE(priv->unplug.alias, devAlias)) {
-VIR_DEBUG("Removal of device '%s' continues in waiting thread", 
devAlias);
-qemuDomainResetDeviceRemoval(vm);
-priv->unplug.status = status;
-virDomainObjBroadcast(vm);
-return true;
+for (i = 0; i < priv->unplug.naliases; i++) {
+if (STREQ_NULLABLE(priv->unplug.aliases[i], devAlias)) {
+VIR_DEBUG("Removal of device '%s' continues in waiting thread", 
devAlias);
+VIR_DELETE_ELEMENT(priv->unplug.aliases, i, priv->unplug.naliases);
+priv->unplug.status = status;
+virDomainObjBroadcast(vm);
+return true;
+}
 }
 return false;
 }
@@ -5675,7 +5685,7 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
 return -1;
 }
 
-qemuDomainMarkDeviceAliasForRemoval(vm, vcpupriv->alias);
+qemuDomainMarkDeviceAliasForRemoval(vm, vcpupriv->alias, true);
 
 qemuDomainObjEnterMonitor(driver, vm);
 

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


[libvirt] [RFC PATCH 13/28] util: make virHostdevIsVirtualFunction() public

2018-03-15 Thread Shivaprasad G Bhat
This function will be useful in qemu_domain_address.c,
so promote it from static.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/libvirt_private.syms |1 +
 src/util/virhostdev.c|2 +-
 src/util/virhostdev.h|3 +++
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 68b648ba31..b092c240d8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1918,6 +1918,7 @@ virHostdevFindUSBDevice;
 virHostdevHostSupportsPassthroughKVM;
 virHostdevHostSupportsPassthroughVFIO;
 virHostdevIsSCSIDevice;
+virHostdevIsVirtualFunction;
 virHostdevManagerGetDefault;
 virHostdevPCIDevicesBelongToSameSlot;
 virHostdevPCINodeDeviceDetach;
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 9508a29954..454ae3568c 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -289,7 +289,7 @@ virHostdevPCISysfsPath(virDomainHostdevDefPtr hostdev,
 }
 
 
-static int
+int
 virHostdevIsVirtualFunction(virDomainHostdevDefPtr hostdev)
 {
 char *sysfs_path = NULL;
diff --git a/src/util/virhostdev.h b/src/util/virhostdev.h
index ded7620355..d696b5fdcc 100644
--- a/src/util/virhostdev.h
+++ b/src/util/virhostdev.h
@@ -196,6 +196,9 @@ virHostdevReAttachDomainDevices(virHostdevManagerPtr mgr,
 bool
 virHostdevIsSCSIDevice(virDomainHostdevDefPtr hostdev)
 ATTRIBUTE_NONNULL(1);
+int
+virHostdevIsVirtualFunction(virDomainHostdevDefPtr hostdev)
+ATTRIBUTE_NONNULL(1);
 
 /* functions used by NodeDevDetach/Reattach/Reset */
 int virHostdevPCINodeDeviceDetach(virHostdevManagerPtr mgr,

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


[libvirt] [RFC PATCH 00/28] Enable multifunction pci hotplug

2018-03-15 Thread Shivaprasad G Bhat
Hi All,

I have revisited/rewritten my previously posted patches. Here is
the RFC. Since this patchset is a complete rewrite, I am starting
with v1 here.

The semantics is as discussed before
https://www.redhat.com/archives/libvir-list/2016-April/msg01057.html

As I went on to refactor the code to support multifunction virtio devices,
I realised the abort/cleanup path would be a nightmare there, in case of
failures. So, dropped that attempt. The current RFC limits to the real
practical use cases of Multifunction PCI hostdevices. All new test code
to support multifunction PCI hostdevices and test cases are added to
prove the functionality.

So, to summarise
=
Patch 1 - is a bug fix
Patch 2-6   - Adds all PCI/VFIO/Multifunction/multiple devices per IOMMU group
  support to our mock test environment.
Patches till here, are kind of basic and independent but necessary for the
remaining patches.
=
Patch 7-14  - Detect and auto-address PCI multifunction devices.
=
Patch 15-25 - Refactor/Prepare for hotplug/unplug
Patch 26-28 - Finally implement Hotplug/Unplug

Thanks,
Shivaprasad

---

Shivaprasad G Bhat (28):
  Fix the iommu group path in mock pci
  util: move the hostdev passthrough support functions to utility
  tests: pci: Mock the iommu groups and vfio
  virpcitest: Change the stub driver to vfio from pci-stub
  virpcimock: Mock the SRIOV Virtual functions
  tests: qemu: Add test case for pci-hostdev hotplug
  tests: Add a baseline test for multifunction pci device use case
  util: virpci: detect if the device is a multifunction device from sysfs
  tests: qemu: mock pci environment for qemuargv2xmltests
  virhostdev: Introduce virHostdevPCIDevicesBelongToSameSlot
  qemu: address: Separate the slots into multiple aggregates
  qemu: address: Enable auto addressing multifunction cards
  util: make virHostdevIsVirtualFunction() public
  conf: qemu: validate multifunction hostdevice domain configs
  conf: Add helper to get active functions of a slot of domain
  qemu: hostdev: Move the hostdev preparation to a separate function
  qemu: hotplug: Move the detach of PCI device to the beginnging of live 
hotplug
  qemu: hotplug: move assignment outside qemuDomainAttachHostPCIDevice
  Introduce virDomainDeviceDefParseXMLMany
  Introduce qemuDomainDeviceParseXMLMany
  qemu: refactor qemuDomain[Attach|Detach]DeviceConfig
  qemu: refactor qemuDomain[Attach|Detach]DeviceLive
  qemu: hotplug: Queue and wait for multiple devices
  domain: addr: Introduce virDomainPCIAddressEnsureMultifunctionAddress
  qemu: hotplug: Implement multifunction device hotplug
  qemu: hotplug : Prevent updates to mulitfunction device
  qemu: hotplug: Move out the Single function check
  qemu: hotplug: Implement multifunction device unplug


 src/conf/device_conf.h |7 
 src/conf/domain_addr.c |  127 ++-
 src/conf/domain_addr.h |   41 +-
 src/conf/domain_conf.c |  194 +-
 src/conf/domain_conf.h |   39 ++
 src/libvirt_private.syms   |   14 +
 src/node_device/node_device_udev.c |2 
 src/qemu/qemu_capabilities.c   |5 
 src/qemu/qemu_domain.c |   72 
 src/qemu/qemu_domain.h |   19 +
 src/qemu/qemu_domain_address.c |  375 ++-
 src/qemu/qemu_domain_address.h |   15 +
 src/qemu/qemu_driver.c |  197 +++---
 src/qemu/qemu_hostdev.c|   70 
 src/qemu/qemu_hostdev.h|3 
 src/qemu/qemu_hotplug.c|  389 
 src/qemu/qemu_hotplug.h|   14 +
 src/util/virhostdev.c  |   96 +
 src/util/virhostdev.h  |   11 +
 src/util/virpci.c  |   22 +
 src/util/virpci.h  |8 
 src/util/virprocess.h  |2 
 tests/Makefile.am  |7 
 tests/qemuargv2xmldata/hostdev-pci-address.args|2 
 tests/qemuargv2xmldata/hostdev-pci-address.xml |2 
 tests/qemuargv2xmltest.c   |   18 +
 tests/qemuhotplugtest.c|   98 -
 .../qemuhotplug-hostdev-pci.xml|6 
 .../qemuhotplug-multifunction-hostdev-pci-2.xml|   14 +
 .../qemuhotplug-multifunction-hostdev-pci.xml  |   20 +
 .../qemuhotplug-base-live+hostdev-pci.xml  |   60 +++
 ...hotplug-base-live+multifunction-hostdev-pci.xml |   76 
 .../qemuhotplug-pseries-base-live+hostdev-pci.xml  |   53

[libvirt] [RFC PATCH 02/28] util: move hostdev passthrough support functions to utility

2018-03-15 Thread Shivaprasad G Bhat
There is some duplicity of code here. Move them to common place.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/libvirt_private.syms |2 +
 src/qemu/qemu_capabilities.c |5 +--
 src/qemu/qemu_driver.c   |5 +--
 src/qemu/qemu_hostdev.c  |   70 ++
 src/qemu/qemu_hostdev.h  |3 --
 src/util/virhostdev.c|   63 ++
 src/util/virhostdev.h|3 ++
 tests/virhostdevtest.c   |   31 ---
 8 files changed, 75 insertions(+), 107 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c67bce7389..e1bdaa127e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1915,6 +1915,8 @@ virHostCPUStatsAssign;
 
 # util/virhostdev.h
 virHostdevFindUSBDevice;
+virHostdevHostSupportsPassthroughKVM;
+virHostdevHostSupportsPassthroughVFIO;
 virHostdevIsSCSIDevice;
 virHostdevManagerGetDefault;
 virHostdevPCINodeDeviceDetach;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 3eb5ed6d1a..943e92a3d3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -42,7 +42,6 @@
 #include "virhostcpu.h"
 #include "qemu_monitor.h"
 #include "virstring.h"
-#include "qemu_hostdev.h"
 #include "qemu_domain.h"
 #define __QEMU_CAPSPRIV_H_ALLOW__
 #include "qemu_capspriv.h"
@@ -5725,8 +5724,8 @@ static int
 virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
virDomainCapsDeviceHostdevPtr hostdev)
 {
-bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();
-bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();
+bool supportsPassthroughKVM = virHostdevHostSupportsPassthroughKVM();
+bool supportsPassthroughVFIO = virHostdevHostSupportsPassthroughVFIO();
 
 hostdev->supported = true;
 /* VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES is for containers only */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8c872c1f08..0ade86d6a9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -52,7 +52,6 @@
 #include "qemu_command.h"
 #include "qemu_parse_command.h"
 #include "qemu_cgroup.h"
-#include "qemu_hostdev.h"
 #include "qemu_hotplug.h"
 #include "qemu_monitor.h"
 #include "qemu_process.h"
@@ -12963,8 +12962,8 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
 int ret = -1;
 virNodeDeviceDefPtr def = NULL;
 char *xml = NULL;
-bool legacy = qemuHostdevHostSupportsPassthroughLegacy();
-bool vfio = qemuHostdevHostSupportsPassthroughVFIO();
+bool legacy = virHostdevHostSupportsPassthroughKVM();
+bool vfio = virHostdevHostSupportsPassthroughVFIO();
 virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
 
 virCheckFlags(0, -1);
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 73d26f4c63..c110cf7816 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -121,78 +121,14 @@ qemuHostdevUpdateActiveDomainDevices(virQEMUDriverPtr 
driver,
 return 0;
 }
 
-bool
-qemuHostdevHostSupportsPassthroughVFIO(void)
-{
-DIR *iommuDir = NULL;
-struct dirent *iommuGroup = NULL;
-bool ret = false;
-int direrr;
-
-/* condition 1 - /sys/kernel/iommu_groups/ contains entries */
-if (virDirOpenQuiet(, "/sys/kernel/iommu_groups/") < 0)
-goto cleanup;
-
-while ((direrr = virDirRead(iommuDir, , NULL)) > 0) {
-/* assume we found a group */
-break;
-}
-
-if (direrr < 0 || !iommuGroup)
-goto cleanup;
-/* okay, iommu is on and recognizes groups */
-
-/* condition 2 - /dev/vfio/vfio exists */
-if (!virFileExists("/dev/vfio/vfio"))
-goto cleanup;
-
-ret = true;
-
- cleanup:
-VIR_DIR_CLOSE(iommuDir);
-return ret;
-}
-
-
-#if HAVE_LINUX_KVM_H
-# include 
-bool
-qemuHostdevHostSupportsPassthroughLegacy(void)
-{
-int kvmfd = -1;
-bool ret = false;
-
-if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0)
-goto cleanup;
-
-# ifdef KVM_CAP_IOMMU
-if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0)
-goto cleanup;
-
-ret = true;
-# endif
-
- cleanup:
-VIR_FORCE_CLOSE(kvmfd);
-
-return ret;
-}
-#else
-bool
-qemuHostdevHostSupportsPassthroughLegacy(void)
-{
-return false;
-}
-#endif
-
 
 static bool
 qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDefPtr *hostdevs,
  size_t nhostdevs,
  virQEMUCapsPtr qemuCaps)
 {
-bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();
-bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();
+bool supportsPassthroughKVM = virHostdevHost

[libvirt] [RFC PATCH 26/28] qemu: hotplug : Prevent updates to mulitfunction device

2018-03-15 Thread Shivaprasad G Bhat
The PCI hostdevs once part of the domain, cant be changed.
So, prevent attempts.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c |   18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index fb14475d8c..94f76979e5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8646,6 +8646,8 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
 virQEMUDriverPtr driver = dom->conn->privateData;
 virDomainObjPtr vm = NULL;
 virDomainDefPtr vmdef = NULL;
+virDomainDeviceDefListPtr devlist;
+virDomainDeviceDefListData data = {.xmlopt = driver->xmlopt, .caps = NULL};
 virDomainDeviceDefPtr dev = NULL, dev_copy = NULL;
 bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0;
 int ret = -1;
@@ -8663,9 +8665,11 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
 
 if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
 goto cleanup;
+data.caps = caps;
 
 if (!(vm = qemuDomObjFromDomain(dom)))
 goto cleanup;
+data.def = vm->def;
 
 if (virDomainUpdateDeviceFlagsEnsureACL(dom->conn, vm->def, flags) < 0)
 goto cleanup;
@@ -8673,12 +8677,18 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
 if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
 goto cleanup;
 
-dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
- caps, driver->xmlopt,
- parse_flags);
-if (dev == NULL)
+devlist = qemuDomainDeviceParseXMLMany(xml, , parse_flags);
+if (!devlist)
 goto endjob;
 
+if (devlist->count > 1) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+   _("update of device multifunction devices is not 
supported"));
+goto endjob;
+}
+
+dev = dev_copy = devlist->devs[0];
+
 if (virDomainObjUpdateModificationImpact(vm, ) < 0)
 goto endjob;
 

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


[libvirt] [RFC PATCH 27/28] qemu: hotplug: Move out the Single function check

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |   19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a339e92bfa..5f6302eaf9 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4993,17 +4993,8 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
   virDomainHostdevDefPtr detach)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
-virDomainHostdevSubsysPCIPtr pcisrc = >source.subsys.u.pci;
 int ret;
 
-if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
-virReportError(VIR_ERR_OPERATION_FAILED,
-   _("cannot hot unplug multifunction PCI device: 
%.4x:%.2x:%.2x.%.1x"),
-   pcisrc->addr.domain, pcisrc->addr.bus,
-   pcisrc->addr.slot, pcisrc->addr.function);
-return -1;
-}
-
 qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
 qemuDomainObjEnterMonitor(driver, vm);
@@ -5094,12 +5085,22 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
virDomainHostdevDefPtr detach)
 {
 int ret = -1;
+virDomainHostdevSubsysPtr subsys = >source.subsys;
+virDomainHostdevSubsysPCIPtr pcisrc = >u.pci;
 
 if (qemuAssignDeviceHostdevAlias(vm->def, >info->alias, -1) < 0)
 return -1;
 
 switch (detach->source.subsys.type) {
 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
+virReportError(VIR_ERR_OPERATION_FAILED,
+   _("cannot hot unplug multifunction PCI device: 
%.4x:%.2x:%.2x.%.1x"),
+   pcisrc->addr.domain, pcisrc->addr.bus,
+   pcisrc->addr.slot, pcisrc->addr.function);
+return -1;
+}
+
 ret = qemuDomainDetachHostPCIDevice(driver, vm, detach);
 break;
 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:

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


[libvirt] [RFC PATCH 04/28] virpcitest: Change the stub driver to vfio from pci-stub

2018-03-15 Thread Shivaprasad G Bhat
The pci-stub is obsolete for a while now. Upcoming test cases try
to test the VFIO hotplug/unplug cases.

Change the default test driver to vfio-pci instead of pci-stub,
and fail bind for pci-stub instead.


Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 tests/virhostdevtest.c |8 
 tests/virpcimock.c |5 ++---
 tests/virpcitest.c |   12 ++--
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/tests/virhostdevtest.c b/tests/virhostdevtest.c
index e4fee567a2..41062ebf3c 100644
--- a/tests/virhostdevtest.c
+++ b/tests/virhostdevtest.c
@@ -97,7 +97,7 @@ myInit(void)
 subsys.u.pci.addr.bus = 0;
 subsys.u.pci.addr.slot = i + 1;
 subsys.u.pci.addr.function = 0;
-subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;
+subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
 hostdevs[i]->source.subsys = subsys;
 }
 
@@ -105,7 +105,7 @@ myInit(void)
 if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)))
 goto cleanup;
 
-virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_KVM);
+virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_VFIO);
 }
 
 if (VIR_ALLOC(mgr) < 0)
@@ -485,7 +485,7 @@ testVirHostdevRoundtripManaged(const void *opaque 
ATTRIBUTE_UNUSED)
 {
 int ret = -1;
 
-if (virHostdevHostSupportsPassthroughKVM()) {
+if (virHostdevHostSupportsPassthroughVFIO()) {
 if (testVirHostdevPreparePCIHostdevs_managed(false) < 0)
 goto out;
 if (testVirHostdevReAttachPCIHostdevs_managed(false) < 0)
@@ -517,7 +517,7 @@ testVirHostdevRoundtripMixed(const void *opaque 
ATTRIBUTE_UNUSED)
 
 if (testVirHostdevDetachPCINodeDevice() < 0)
 goto out;
-if (virHostdevHostSupportsPassthroughKVM()) {
+if (virHostdevHostSupportsPassthroughVFIO()) {
 if (testVirHostdevPreparePCIHostdevs_managed(true) < 0)
 goto out;
 if (testVirHostdevReAttachPCIHostdevs_managed(true) < 0)
diff --git a/tests/virpcimock.c b/tests/virpcimock.c
index 22adc740b8..c9b7434c9a 100644
--- a/tests/virpcimock.c
+++ b/tests/virpcimock.c
@@ -982,9 +982,8 @@ init_env(void)
 
 MAKE_PCI_DRIVER("iwlwifi", 0x8086, 0x0044);
 MAKE_PCI_DRIVER("i915", 0x8086, 0x0046, 0x8086, 0x0047);
-MAKE_PCI_DRIVER("pci-stub", -1, -1);
-pci_driver_new("vfio-pci", PCI_ACTION_BIND, -1, -1);
-
+pci_driver_new("pci-stub", PCI_ACTION_BIND, -1, -1);
+MAKE_PCI_DRIVER("vfio-pci", -1, -1);
 
 # define MAKE_PCI_DEVICE(Id, Vendor, Device, ...) \
 do { \
diff --git a/tests/virpcitest.c b/tests/virpcitest.c
index 80e994ae52..fa7acb85a2 100644
--- a/tests/virpcitest.c
+++ b/tests/virpcitest.c
@@ -110,12 +110,12 @@ testVirPCIDeviceDetach(const void *opaque 
ATTRIBUTE_UNUSED)
 if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)))
 goto cleanup;
 
-virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_KVM);
+virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_VFIO);
 
 if (virPCIDeviceDetach(dev[i], activeDevs, inactiveDevs) < 0)
 goto cleanup;
 
-if (testVirPCIDeviceCheckDriver(dev[i], "pci-stub") < 0)
+if (testVirPCIDeviceCheckDriver(dev[i], "vfio-pci") < 0)
 goto cleanup;
 
 CHECK_LIST_COUNT(activeDevs, 0);
@@ -249,7 +249,7 @@ testVirPCIDeviceDetachSingle(const void *opaque)
 if (!dev)
 goto cleanup;
 
-virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_KVM);
+virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_VFIO);
 
 if (virPCIDeviceDetach(dev, NULL, NULL) < 0)
 goto cleanup;
@@ -271,7 +271,7 @@ testVirPCIDeviceDetachFail(const void *opaque)
 if (!dev)
 goto cleanup;
 
-virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_VFIO);
+virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_KVM);
 
 if (virPCIDeviceDetach(dev, NULL, NULL) < 0) {
 if (virTestGetVerbose() || virTestGetDebug())
@@ -282,7 +282,7 @@ testVirPCIDeviceDetachFail(const void *opaque)
 virReportError(VIR_ERR_INTERNAL_ERROR,
"Attaching device %s to %s should have failed",
virPCIDeviceGetName(dev),
-   virPCIStubDriverTypeToString(VIR_PCI_STUB_DRIVER_VFIO));
+   virPCIStubDriverTypeToString(VIR_PCI_STUB_DRIVER_KVM));
 }
 
  cleanup:
@@ -441,7 +441,7 @@ mymain(void)
 /* Detach an unbound device */
 DO_TEST_PCI_DRIVER(0, 0x0a, 2, 0, NULL);
 DO_TEST_PCI(testVirPCIDeviceDetachSingle, 0, 0x0a, 2, 0);
-DO_TEST_PCI_DRIVER(0, 0x0a, 2, 0, "pci-stub");
+DO_TEST_PCI_DRIVER(0, 0x0a, 2, 0, "vfio-pci");
 
 /* Reattach an unknown unbound device */
 DO_TEST_PCI_DRIVER(0, 0x0a, 3, 0, NULL);

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


[libvirt] [RFC PATCH 17/28] qemu: hotplug: Move the detach of PCI device to the beginnging of live hotplug

2018-03-15 Thread Shivaprasad G Bhat
The hostdevices are the only devices which have dependencies
outside of themselves such that, other functions of the PCI
card should also have been detached from host driver before
attempting the hotplug.

This patch moves the detach to the beginning of the hotplug
so that the following patch can detach all funtions first before
attempting to hotplug any.

We need not move the detach for net devices using SRIOV as
all SRIOV devices are single function devices and can be independently
detached as usual.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |   27 ++-
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1bf87d963e..214e169980 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -888,6 +888,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
 bool charDevPlugged = false;
 bool netdevPlugged = false;
 bool hostPlugged = false;
+virDomainHostdevDefPtr hostdev = NULL;
 
 /* preallocate new slot for device */
 if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
@@ -998,9 +999,16 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
  * as a hostdev (the hostdev code will reach over into the
  * netdev-specific code as appropriate), then also added to
  * the nets list (see cleanup:) if successful.
+ *
+ * qemuDomainAttachHostDevice uses a connection to resolve
+ * a SCSI hostdev secret, which is not this case, so pass NULL.
  */
-ret = qemuDomainAttachHostDevice(driver, vm,
- virDomainNetGetActualHostdev(net));
+hostdev = virDomainNetGetActualHostdev(net);
+if (qemuDomainAttachPCIHostDevicePrepare(driver, vm->def,
+ hostdev, priv->qemuCaps) < 0)
+goto cleanup;
+if ((ret = qemuDomainAttachHostDevice(driver, vm, hostdev)) < 0)
+qemuHostdevReAttachPCIDevices(driver, vm->def->name, , 1);
 goto cleanup;
 break;
 
@@ -1312,10 +1320,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
 return -1;
 
-if (qemuDomainAttachPCIHostDevicePrepare(driver, vm->def,
- hostdev, priv->qemuCaps) < 0)
-return -1;
-
 backend = hostdev->source.subsys.u.pci.backend;
 
 /* Temporarily add the hostdev to the domain definition. This is needed
@@ -1405,8 +1409,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 if (releaseaddr)
 qemuDomainReleaseDeviceAddress(vm, info, NULL);
 
-qemuHostdevReAttachPCIDevices(driver, vm->def->name, , 1);
-
 VIR_FREE(devstr);
 VIR_FREE(configfd_name);
 VIR_FORCE_CLOSE(configfd);
@@ -2588,6 +2590,8 @@ qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev)
 {
+qemuDomainObjPrivatePtr priv = vm->privateData;
+
 if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("hotplug is not supported for hostdev mode '%s'"),
@@ -2597,9 +2601,14 @@ qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
 
 switch (hostdev->source.subsys.type) {
 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+if (qemuDomainAttachPCIHostDevicePrepare(driver, vm->def,
+ hostdev, priv->qemuCaps) < 0)
+goto error;
 if (qemuDomainAttachHostPCIDevice(driver, vm,
-  hostdev) < 0)
+  hostdev) < 0) {
+qemuHostdevReAttachPCIDevices(driver, vm->def->name, , 1);
 goto error;
+}
 break;
 
 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:

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


[libvirt] [RFC PATCH 15/28] conf: Add helper to get active functions of a slot of domain

2018-03-15 Thread Shivaprasad G Bhat
In some cases it may be better to have a bitmap representing state of
individual functions rather than iterating the definition. The new helper
creates a bitmap representing the state from the domain definition.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/conf/domain_conf.c   |   25 +
 src/conf/domain_conf.h   |3 +++
 src/libvirt_private.syms |1 +
 3 files changed, 29 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 86fc275116..3deed8eb4d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16146,6 +16146,31 @@ virDomainHostdevFind(virDomainDefPtr def,
 return *found ? i : -1;
 }
 
+#define PCI_MAX_SLOT_FUNCTIONS 8
+/**
+ * virDomainDefHostdevGetPCIOnlineFunctionMap:
+ * @def: domain definition
+ * @aggrSlotIdx: slot aggregation index
+ * Returns a bitmap representing state of individual functions of a slot.
+ */
+virBitmapPtr
+virDomainDefHostdevGetPCIOnlineFunctionMap(virDomainDefPtr def,
+   int aggrSlotIdx)
+{
+size_t i;
+virBitmapPtr ret = NULL;
+
+if (!(ret = virBitmapNew(PCI_MAX_SLOT_FUNCTIONS)))
+return NULL;
+
+for (i = 0; i < def->nhostdevs; i++) {
+if (def->hostdevs[i]->info->aggregateSlotIdx == aggrSlotIdx)
+ignore_value(virBitmapSetBit(ret, 
def->hostdevs[i]->source.subsys.u.pci.addr.function));
+}
+
+return ret;
+}
+
 static bool
 virDomainDiskControllerMatch(int controller_type, int disk_bus)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 61379e50fe..a3d686a5ca 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3067,6 +3067,9 @@ virDomainHostdevDefPtr
 virDomainHostdevRemove(virDomainDefPtr def, size_t i);
 int virDomainHostdevFind(virDomainDefPtr def, virDomainHostdevDefPtr match,
  virDomainHostdevDefPtr *found);
+virBitmapPtr virDomainDefHostdevGetPCIOnlineFunctionMap(virDomainDefPtr def,
+int aggrSlotIdx);
+
 
 virDomainGraphicsListenDefPtr
 virDomainGraphicsGetListen(virDomainGraphicsDefPtr def, size_t i);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b092c240d8..b0e8f2ca61 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -278,6 +278,7 @@ virDomainDefHasMemballoon;
 virDomainDefHasMemoryHotplug;
 virDomainDefHasUSB;
 virDomainDefHasVcpusOffline;
+virDomainDefHostdevGetPCIOnlineFunctionMap;
 virDomainDefLifecycleActionAllowed;
 virDomainDefMaybeAddController;
 virDomainDefMaybeAddInput;

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


[libvirt] [RFC PATCH 09/28] tests: qemu: mock pci environment for qemuargv2xmltests

2018-03-15 Thread Shivaprasad G Bhat
The upcoming patches verify the sysfs for pci hostdevs.
So, preload the mock library and change the device to
what exists on the mock environment to avoid a failure.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 tests/qemuargv2xmldata/hostdev-pci-address.args |2 +-
 tests/qemuargv2xmldata/hostdev-pci-address.xml  |2 +-
 tests/qemuargv2xmltest.c|   18 --
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/tests/qemuargv2xmldata/hostdev-pci-address.args 
b/tests/qemuargv2xmldata/hostdev-pci-address.args
index 4d24ce3b75..111dff773f 100644
--- a/tests/qemuargv2xmldata/hostdev-pci-address.args
+++ b/tests/qemuargv2xmldata/hostdev-pci-address.args
@@ -20,4 +20,4 @@ QEMU_AUDIO_DRV=none \
 -net none \
 -serial none \
 -parallel none \
--pcidevice host=06:12.5
+-pcidevice host=06:12.1
diff --git a/tests/qemuargv2xmldata/hostdev-pci-address.xml 
b/tests/qemuargv2xmldata/hostdev-pci-address.xml
index d6b9ce1d25..fd0bff62e6 100644
--- a/tests/qemuargv2xmldata/hostdev-pci-address.xml
+++ b/tests/qemuargv2xmldata/hostdev-pci-address.xml
@@ -31,7 +31,7 @@
 
 
   
-
+
   
   
 
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index cb010268c4..a68c13fead 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -144,12 +144,25 @@ testCompareXMLToArgvHelper(const void *data)
 return result;
 }
 
-
+# define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XX"
 
 static int
 mymain(void)
 {
 int ret = 0;
+char *fakerootdir;
+
+if (VIR_STRDUP_QUIET(fakerootdir, FAKEROOTDIRTEMPLATE) < 0) {
+fprintf(stderr, "Out of memory\n");
+abort();
+}
+
+if (!mkdtemp(fakerootdir)) {
+fprintf(stderr, "Cannot create fakerootdir");
+abort();
+}
+
+setenv("LIBVIRT_FAKE_ROOT_DIR", fakerootdir, 1);
 
 if (qemuTestDriverInit() < 0)
 return EXIT_FAILURE;
@@ -298,7 +311,8 @@ mymain(void)
 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
-VIR_TEST_MAIN(mymain)
+VIR_TEST_MAIN_PRELOAD(mymain,
+  abs_builddir "/.libs/virpcimock.so")
 
 #else
 

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


[libvirt] [RFC PATCH 06/28] tests: qemu: Add test case for pci-hostdev hotplug

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/util/virprocess.h  |2 -
 tests/Makefile.am  |7 ++
 tests/qemuhotplugtest.c|   42 ++
 .../qemuhotplug-hostdev-pci.xml|6 ++
 .../qemuhotplug-base-live+hostdev-pci.xml  |   60 
 .../qemuhotplug-pseries-base-live+hostdev-pci.xml  |   53 ++
 .../qemuhotplug-pseries-base-live.xml  |   45 +++
 tests/virprocessmock.c |   28 +
 8 files changed, 241 insertions(+), 2 deletions(-)
 create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-hostdev-pci.xml
 create mode 100644 
tests/qemuhotplugtestdomains/qemuhotplug-base-live+hostdev-pci.xml
 create mode 100644 
tests/qemuhotplugtestdomains/qemuhotplug-pseries-base-live+hostdev-pci.xml
 create mode 100644 
tests/qemuhotplugtestdomains/qemuhotplug-pseries-base-live.xml
 create mode 100644 tests/virprocessmock.c

diff --git a/src/util/virprocess.h b/src/util/virprocess.h
index 3c5a882772..5e68b47744 100644
--- a/src/util/virprocess.h
+++ b/src/util/virprocess.h
@@ -72,7 +72,7 @@ int virProcessGetNamespaces(pid_t pid,
 int virProcessSetNamespaces(size_t nfdlist,
 int *fdlist);
 
-int virProcessSetMaxMemLock(pid_t pid, unsigned long long bytes);
+int virProcessSetMaxMemLock(pid_t pid, unsigned long long bytes) 
ATTRIBUTE_NOINLINE;
 int virProcessSetMaxProcesses(pid_t pid, unsigned int procs);
 int virProcessSetMaxFiles(pid_t pid, unsigned int files);
 int virProcessSetMaxCoreSize(pid_t pid, unsigned long long bytes);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 15c8cc8158..9ff78ad382 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -213,6 +213,7 @@ test_libraries = libshunload.la \
virpcimock.la \
virnetdevmock.la \
virrandommock.la \
+   virprocessmock.la \
virhostcpumock.la \
domaincapsmock.la \
virfilecachemock.la \
@@ -1149,6 +1150,12 @@ virrandommock_la_SOURCES = \
 virrandommock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
 virrandommock_la_LIBADD = $(MOCKLIBS_LIBS)
 
+virprocessmock_la_SOURCES = \
+virprocessmock.c
+virprocessmock_la_CFLAGS = $(AM_CFLAGS)
+virprocessmock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
+virprocessmock_la_LIBADD = $(MOCKLIBS_LIBS)
+
 virhostcpumock_la_SOURCES = \
virhostcpumock.c
 virhostcpumock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c
index d42f8e12cb..31ce8d43b9 100644
--- a/tests/qemuhotplugtest.c
+++ b/tests/qemuhotplugtest.c
@@ -26,6 +26,7 @@
 #include "qemumonitortestutils.h"
 #include "testutils.h"
 #include "testutilsqemu.h"
+#include "virhostdev.h"
 #include "virerror.h"
 #include "virstring.h"
 #include "virthread.h"
@@ -78,6 +79,8 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt,
 virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_IVSHMEM_PLAIN);
 virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_IVSHMEM_DOORBELL);
 virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SCSI_DISK_WWN);
+virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI);
+virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE);
 if (event)
 virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT);
 
@@ -131,6 +134,9 @@ testQemuHotplugAttach(virDomainObjPtr vm,
 case VIR_DOMAIN_DEVICE_WATCHDOG:
 ret = qemuDomainAttachWatchdog(, vm, dev->data.watchdog);
 break;
+case VIR_DOMAIN_DEVICE_HOSTDEV:
+ret = qemuDomainAttachHostDevice(, vm, dev->data.hostdev);
+break;
 default:
 VIR_TEST_VERBOSE("device type '%s' cannot be attached\n",
 virDomainDeviceTypeToString(dev->type));
@@ -159,6 +165,9 @@ testQemuHotplugDetach(virDomainObjPtr vm,
 case VIR_DOMAIN_DEVICE_WATCHDOG:
 ret = qemuDomainDetachWatchdog(, vm, dev->data.watchdog);
 break;
+case VIR_DOMAIN_DEVICE_HOSTDEV:
+ret = qemuDomainDetachHostDevice(, vm, dev);
+break;
 default:
 VIR_TEST_VERBOSE("device type '%s' cannot be detached\n",
 virDomainDeviceTypeToString(dev->type));
@@ -579,6 +588,7 @@ testQemuHotplugCpuIndividual(const void *opaque)
 }
 
 
+#define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XX"
 
 static int
 mymain(void)
@@ -586,6 +596,20 @@ mymain(void)
 int ret = 0;
 struct qemuHotplugTestData data = {0};
 struct testQemuHotplugCpuParams cpudata;
+char *fakerootdir;
+
+if (VIR_STRDUP_QUIET(fakerootdir, FAKEROOTDIRTEMPLATE) < 0) {
+fprintf(stderr, "Out of memory\n");
+abort();
+}
+
+if (!mkdtemp(fakerootdir)) {
+fprintf(stderr, "Cannot create fakerootdir")

[libvirt] [RFC PATCH 18/28] qemu: hotplug: move assignment outside qemuDomainAttachHostPCIDevice

2018-03-15 Thread Shivaprasad G Bhat
No functional change.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |   28 +---
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 214e169980..007ecb0923 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1304,14 +1304,11 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
   virDomainHostdevDefPtr hostdev)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
-virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV,
-   { .hostdev = hostdev } };
 virDomainDeviceInfoPtr info = hostdev->info;
 int ret;
 char *devstr = NULL;
 int configfd = -1;
 char *configfd_name = NULL;
-bool releaseaddr = false;
 bool teardowncgroup = false;
 bool teardownlabel = false;
 bool teardowndevice = false;
@@ -1350,15 +1347,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 if (qemuAssignDeviceHostdevAlias(vm->def, >alias, -1) < 0)
 goto error;
 
-if (qemuDomainIsPSeries(vm->def)) {
-/* Isolation groups are only relevant for pSeries guests */
-if (qemuDomainFillDeviceIsolationGroup(vm->def, ) < 0)
-goto error;
-}
-
-if (qemuDomainEnsurePCIAddress(vm, , driver) < 0)
-goto error;
-releaseaddr = true;
 if (backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
 configfd = qemuOpenPCIConfig(hostdev);
@@ -1406,9 +1394,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
 VIR_WARN("Unable to remove host device from /dev");
 
-if (releaseaddr)
-qemuDomainReleaseDeviceAddress(vm, info, NULL);
-
 VIR_FREE(devstr);
 VIR_FREE(configfd_name);
 VIR_FORCE_CLOSE(configfd);
@@ -2591,6 +2576,8 @@ qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
virDomainHostdevDefPtr hostdev)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
+virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV,
+   { .hostdev = hostdev } };
 
 if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -2604,8 +2591,19 @@ qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
 if (qemuDomainAttachPCIHostDevicePrepare(driver, vm->def,
  hostdev, priv->qemuCaps) < 0)
 goto error;
+
+if (qemuDomainIsPSeries(vm->def)) {
+/* Isolation groups are only relevant for pSeries guests */
+if (qemuDomainFillDeviceIsolationGroup(vm->def, ) < 0)
+goto error;
+}
+
+if (qemuDomainEnsurePCIAddress(vm, , driver) < 0)
+goto error;
+
 if (qemuDomainAttachHostPCIDevice(driver, vm,
   hostdev) < 0) {
+qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
 qemuHostdevReAttachPCIDevices(driver, vm->def->name, , 1);
 goto error;
 }

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


[libvirt] [RFC PATCH 11/28] qemu: address: Separate the slots into multiple aggregates

2018-03-15 Thread Shivaprasad G Bhat
Today's aggregate flag with the slot being true for pcie-root-ports is not
enough as there will more number of aggregates depending on the number of
Multifuntion PCI cards assigned to the domain.

The aggregate is changed to unsigned int and Zero means Not Applicable, 1 is
reserved for the pcie-root-ports and >= 2 for the the PCI multifunction
cards(coming..).

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/conf/device_conf.h |1 
 src/conf/domain_addr.c |   43 ++---
 src/conf/domain_addr.h |   36 -
 src/qemu/qemu_domain_address.c |   83 +---
 src/qemu/qemu_domain_address.h |8 
 5 files changed, 123 insertions(+), 48 deletions(-)

diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index f87d6f1fc6..cdb2040fb8 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -163,6 +163,7 @@ struct _virDomainDeviceInfo {
  * assignment, never saved and never reported.
  */
 int pciConnectFlags; /* enum virDomainPCIConnectFlags */
+unsigned int aggregateSlotIdx; /* Used when the aggregate flag is set */
 char *loadparm;
 
 /* PCI devices will only be automatically placed on a PCI bus
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index 0c914fe25c..c4a0b99628 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -63,7 +63,7 @@ 
virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model)
 return VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE;
 
 case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
-return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT | 
VIR_PCI_CONNECT_AGGREGATE_SLOT;
+return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT;
 
 case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
 return VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT;
@@ -565,6 +565,7 @@ 
virDomainPCIAddressReserveAddrInternal(virDomainPCIAddressSetPtr addrs,
virPCIDeviceAddressPtr addr,
virDomainPCIConnectFlags flags,
unsigned int isolationGroup,
+   unsigned int aggregateSlotIdx,
bool fromConfig)
 {
 int ret = -1;
@@ -598,8 +599,13 @@ 
virDomainPCIAddressReserveAddrInternal(virDomainPCIAddressSetPtr addrs,
  * slot, set the slot's aggregate flag.
 */
 if (!bus->slot[addr->slot].functions &&
-flags & VIR_PCI_CONNECT_AGGREGATE_SLOT) {
-bus->slot[addr->slot].aggregate = true;
+aggregateSlotIdx > 0) {
+bus->slot[addr->slot].aggregateSlotIdx = aggregateSlotIdx;
+} else if (bus->slot[addr->slot].aggregateSlotIdx != aggregateSlotIdx && 
fromConfig) {
+bus->slot[addr->slot].aggregateSlotIdx = 0;
+VIR_DEBUG("PCI functions of %.4x:%.2x is aggregated to slot %u"
+  "because of user assigned address %s",
+  addr->domain, addr->bus, aggregateSlotIdx, addrStr);
 }
 
 if (virDomainPCIAddressBusIsEmpty(bus) && !bus->isolationGroupLocked) {
@@ -624,8 +630,8 @@ 
virDomainPCIAddressReserveAddrInternal(virDomainPCIAddressSetPtr addrs,
 
 /* mark the requested function as reserved */
 bus->slot[addr->slot].functions |= (1 << addr->function);
-VIR_DEBUG("Reserving PCI address %s (aggregate='%s')", addrStr,
-  bus->slot[addr->slot].aggregate ? "true" : "false");
+VIR_DEBUG("Reserving PCI address %s (aggregateSlotIdx='%d')", addrStr,
+  bus->slot[addr->slot].aggregateSlotIdx);
 
 ret = 0;
  cleanup:
@@ -638,10 +644,11 @@ int
 virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
virPCIDeviceAddressPtr addr,
virDomainPCIConnectFlags flags,
-   unsigned int isolationGroup)
+   unsigned int isolationGroup,
+   unsigned int aggregateSlotIdx)
 {
 return virDomainPCIAddressReserveAddrInternal(addrs, addr, flags,
-  isolationGroup, true);
+  isolationGroup, 
aggregateSlotIdx, true);
 }
 
 int
@@ -678,6 +685,7 @@ virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr 
addrs,
 
 ret = virDomainPCIAddressReserveAddrInternal(addrs, >addr.pci,
  flags, 
dev->isolationGroup,
+ dev->aggregateSlotIdx,
  true);
 } else {
 ret = virDomainPCIAddressReserveNextAddr(addrs, dev, fl

[libvirt] [RFC PATCH 05/28] virpcimock: Mock the SRIOV Virtual functions

2018-03-15 Thread Shivaprasad G Bhat
The softlink to physfn is the way to know if the device is
VF or not. So, the patch softlinks 'physfn' to the parent function.
The multifunction PCI devices dont have 'physfn' softlinks.

The patch adds few Virtual functions to the mock environment and changes
the existing test xmls using the VFs to use the newly added VFs
for their use case.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 .../hostdev-pci-address-device.args|2 +-
 .../hostdev-pci-address-device.xml |2 +-
 tests/qemuxml2argvdata/hostdev-pci-address.args|2 +-
 tests/qemuxml2argvdata/hostdev-pci-address.xml |2 +-
 .../qemuxml2argvdata/hostdev-vfio-multidomain.args |2 +-
 .../qemuxml2argvdata/hostdev-vfio-multidomain.xml  |2 +-
 tests/qemuxml2argvdata/hostdev-vfio.args   |2 +-
 tests/qemuxml2argvdata/hostdev-vfio.xml|2 +-
 tests/qemuxml2argvdata/net-hostdev-fail.xml|2 +-
 .../qemuxml2argvdata/net-hostdev-multidomain.args  |2 +-
 tests/qemuxml2argvdata/net-hostdev-multidomain.xml |2 +-
 tests/qemuxml2argvdata/net-hostdev-vfio.args   |2 +-
 tests/qemuxml2argvdata/net-hostdev-vfio.xml|2 +-
 tests/qemuxml2argvdata/net-hostdev.args|2 +-
 tests/qemuxml2argvdata/net-hostdev.xml |2 +-
 tests/qemuxml2argvdata/pci-rom.args|4 ++--
 tests/qemuxml2argvdata/pci-rom.xml |4 ++--
 tests/qemuxml2xmloutdata/hostdev-pci-address.xml   |2 +-
 tests/qemuxml2xmloutdata/hostdev-vfio.xml  |2 +-
 tests/qemuxml2xmloutdata/net-hostdev-vfio.xml  |2 +-
 tests/qemuxml2xmloutdata/net-hostdev.xml   |2 +-
 tests/qemuxml2xmloutdata/pci-rom.xml   |4 ++--
 tests/virpcimock.c |   14 ++
 tests/virpcitestdata/-06-12.0.config   |  Bin
 tests/virpcitestdata/-06-12.1.config   |  Bin
 tests/virpcitestdata/-06-12.2.config   |  Bin
 26 files changed, 39 insertions(+), 25 deletions(-)
 create mode 100644 tests/virpcitestdata/-06-12.0.config
 create mode 100644 tests/virpcitestdata/-06-12.1.config
 create mode 100644 tests/virpcitestdata/-06-12.2.config

diff --git a/tests/qemuxml2argvdata/hostdev-pci-address-device.args 
b/tests/qemuxml2argvdata/hostdev-pci-address-device.args
index a250082e1e..93221b6e9d 100644
--- a/tests/qemuxml2argvdata/hostdev-pci-address-device.args
+++ b/tests/qemuxml2argvdata/hostdev-pci-address-device.args
@@ -22,5 +22,5 @@ server,nowait \
 -usb \
 -drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
--device pci-assign,host=06:12.5,id=hostdev0,bus=pci.0,addr=0x3 \
+-device pci-assign,host=06:12.1,id=hostdev0,bus=pci.0,addr=0x3 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/hostdev-pci-address-device.xml 
b/tests/qemuxml2argvdata/hostdev-pci-address-device.xml
index 814fdcc271..492031d5a9 100644
--- a/tests/qemuxml2argvdata/hostdev-pci-address-device.xml
+++ b/tests/qemuxml2argvdata/hostdev-pci-address-device.xml
@@ -20,7 +20,7 @@
 
 
   
-
+
   
 
 
diff --git a/tests/qemuxml2argvdata/hostdev-pci-address.args 
b/tests/qemuxml2argvdata/hostdev-pci-address.args
index 1f3a2443bf..728712a1c1 100644
--- a/tests/qemuxml2argvdata/hostdev-pci-address.args
+++ b/tests/qemuxml2argvdata/hostdev-pci-address.args
@@ -21,4 +21,4 @@ server,nowait \
 -usb \
 -drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
--device pci-assign,host=06:12.5,id=hostdev0,bus=pci.0,addr=0x3
+-device pci-assign,host=06:12.1,id=hostdev0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/hostdev-pci-address.xml 
b/tests/qemuxml2argvdata/hostdev-pci-address.xml
index 17968350ff..af7e300c57 100644
--- a/tests/qemuxml2argvdata/hostdev-pci-address.xml
+++ b/tests/qemuxml2argvdata/hostdev-pci-address.xml
@@ -27,7 +27,7 @@
 
 
   
-
+
   
 
 
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-multidomain.args 
b/tests/qemuxml2argvdata/hostdev-vfio-multidomain.args
index 492e9b35e0..87ea9e7e09 100644
--- a/tests/qemuxml2argvdata/hostdev-vfio-multidomain.args
+++ b/tests/qemuxml2argvdata/hostdev-vfio-multidomain.args
@@ -22,5 +22,5 @@ server,nowait \
 -usb \
 -drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
--device vfio-pci,host=55aa:20:0f.3,id=hostdev0,bus=pci.0,addr=0x3 \
+-device vfio-pci,host=0021:de:1f.1,id=hostdev0,bus=pci.0,addr=0x3 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/hostdev-vfio-multidomain.xml 
b/tests/qemuxml2argvdata/hostdev-vfio-multidomain.xml
index 8324

[libvirt] [RFC PATCH 19/28] Introduce virDomainDeviceDefParseXMLMany

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/conf/domain_conf.c   |  169 --
 src/conf/domain_conf.h   |   36 ++
 src/libvirt_private.syms |6 ++
 3 files changed, 190 insertions(+), 21 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3deed8eb4d..5f4a5127d4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -963,6 +963,83 @@ virDomainXMLOptionClassDispose(void *obj)
 (xmlopt->config.privFree)(xmlopt->config.priv);
 }
 
+/* virDomainDeviceDefListAddCopy - add a *copy* of the device to this list */
+int
+virDomainDeviceDefListAddCopy(virDomainDeviceDefListPtr list,
+  virDomainDeviceDefPtr dev,
+  virDomainDeviceDefListDataPtr data)
+{
+virDomainDeviceDefPtr copy = virDomainDeviceDefCopy(dev, data->def, 
data->caps, data->xmlopt);
+
+if (!copy)
+return -1;
+if (VIR_APPEND_ELEMENT(list->devs, list->count, copy) < 0) {
+virDomainDeviceDefFree(copy);
+return -1;
+}
+return 0;
+}
+
+void virDomainDeviceDefListFree(virDomainDeviceDefListPtr list)
+{
+size_t i;
+
+if (!list)
+return;
+for (i = 0; i < list->count; i++)
+virDomainDeviceDefFree(list->devs[i]);
+VIR_FREE(list->devs);
+}
+
+void virDomainDeviceDefListFreeShallow(virDomainDeviceDefListPtr list)
+{
+size_t i;
+
+if (!list)
+return;
+for (i = 0; i < list->count; i++)
+VIR_FREE(list->devs[i]);
+}
+
+
+/* virDomainDeviceDefListIter - Iterate through the list with the callback*/
+int
+virDomainDeviceDefListIterate(virDomainDeviceDefListPtr list,
+  virDomainDeviceDefListIterCallback cb,
+  void *data)
+{
+size_t i;
+
+for (i = 0; i < list->count; i++)
+if (cb(list->devs[i], data))
+return -1;
+
+return 0;
+}
+
+virDomainDeviceDefListPtr
+virDomainDeviceDefListCopy(virDomainDeviceDefListPtr list,
+   virDomainDeviceDefListDataPtr data)
+{
+size_t i;
+virDomainDeviceDefListPtr devlist = NULL;
+
+if (list && (VIR_ALLOC(devlist) < 0))
+goto cleanup;
+
+for (i = 0; i < list->count; i++) {
+if (virDomainDeviceDefListAddCopy(devlist, list->devs[i], data) < 0)
+goto cleanup;
+}
+
+return devlist;
+ cleanup:
+virDomainDeviceDefListFree(devlist);
+return NULL;
+}
+
+
+
 /**
  * virDomainKeyWrapCipherDefParseXML:
  *
@@ -15677,25 +15754,16 @@ virDomainIOMMUDefParseXML(xmlNodePtr node,
 return ret;
 }
 
-
-virDomainDeviceDefPtr
-virDomainDeviceDefParse(const char *xmlStr,
-const virDomainDef *def,
-virCapsPtr caps,
-virDomainXMLOptionPtr xmlopt,
-unsigned int flags)
+static
+virDomainDeviceDefPtr virDomainDeviceDefParseXML(xmlNodePtr node,
+ const virDomainDef *def,
+ virCapsPtr caps,
+ virDomainXMLOptionPtr xmlopt,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
 {
-xmlDocPtr xml;
-xmlNodePtr node;
-xmlXPathContextPtr ctxt = NULL;
 virDomainDeviceDefPtr dev = NULL;
 char *netprefix;
-
-if (!(xml = virXMLParseStringCtxt(xmlStr, _("(device_definition)"), 
)))
-goto error;
-
-node = ctxt->node;
-
 if (VIR_ALLOC(dev) < 0)
 goto error;
 
@@ -15846,14 +15914,33 @@ virDomainDeviceDefParse(const char *xmlStr,
 if (virDomainDeviceDefValidate(dev, def, flags, xmlopt) < 0)
 goto error;
 
- cleanup:
+return dev;
+ error:
+return NULL;
+}
+
+virDomainDeviceDefPtr
+virDomainDeviceDefParse(const char *xmlStr,
+const virDomainDef *def,
+virCapsPtr caps,
+virDomainXMLOptionPtr xmlopt,
+unsigned int flags)
+{
+xmlDocPtr xml;
+xmlNodePtr node;
+xmlXPathContextPtr ctxt = NULL;
+virDomainDeviceDefPtr dev = NULL;
+
+if (!(xml = virXMLParseStringCtxt(xmlStr, _("(device_definition)"), 
)))
+return NULL;
+
+node = ctxt->node;
+
+dev = virDomainDeviceDefParseXML(node, def, caps, xmlopt, ctxt, flags);
+
 xmlFreeDoc(xml);
 xmlXPathFreeContext(ctxt);
 return dev;
-
- error:
-VIR_FREE(dev);
-goto cleanup;
 }
 
 
@@ -29394,3 +29481,43 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr 
def)
 virStoragePoolDefFree(pooldef);
 return ret;
 }
+
+virDomainDeviceDefListPtr
+virDomainDeviceDefParseXMLMany(const char *xml,
+   const virDom

[libvirt] [RFC PATCH 20/28] Introduce qemuDomainDeviceParseXMLMany

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.c |   67 
 src/qemu/qemu_domain.h |5 
 2 files changed, 72 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 12ed68a89b..c0a0af525f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11842,3 +11842,70 @@ qemuProcessEventFree(struct qemuProcessEvent *event)
 }
 VIR_FREE(event);
 }
+
+
+static bool isPCIMultifunctionDeviceXML(const char *xml)
+{
+   xmlDocPtr xmlptr;
+
+   if (!(xmlptr = virXMLParse(NULL, xml, _("(device_definition)" {
+   /* We report error anyway later */
+   return false;
+   }
+
+   return STREQ((const char *)(xmlDocGetRootElement(xmlptr))->name, "devices");
+}
+
+static
+int qemuDomainValidateMultifunctionDeviceList(virDomainDeviceDefListPtr 
devlist)
+{
+size_t i;
+virDomainHostdevDefPtr hostdev = NULL;
+virDomainDeviceInfoPtr info;
+
+for (i = 0; i < devlist->count; i++) {
+   info = virDomainDeviceGetInfo(devlist->devs[i]);
+   if (devlist->devs[i]->type == VIR_DOMAIN_DEVICE_HOSTDEV)
+   hostdev = devlist->devs[i]->data.hostdev;
+
+   if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+   return -1;
+
+   if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+   info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+   return -1;
+   }
+   }
+   return 0;
+}
+
+
+virDomainDeviceDefListPtr
+qemuDomainDeviceParseXMLMany(const char *xml,
+ virDomainDeviceDefListDataPtr data,
+ unsigned int parse_flags)
+{
+virDomainDeviceDefListPtr devlist = NULL;
+
+if (isPCIMultifunctionDeviceXML(xml)) {
+if (!(devlist = virDomainDeviceDefParseXMLMany(xml, data->def,
+   data->caps, 
data->xmlopt,
+   parse_flags)))
+goto cleanup;
+
+if (qemuDomainValidateMultifunctionDeviceList(devlist) < 0)
+goto cleanup;
+} else {
+virDomainDeviceDefPtr dev = virDomainDeviceDefParse(xml, data->def,
+data->caps, 
data->xmlopt,
+parse_flags);
+if (!dev || VIR_ALLOC(devlist) < 0)
+goto cleanup;
+
+if (VIR_APPEND_ELEMENT(devlist->devs, devlist->count, dev) < 0)
+goto cleanup;
+}
+
+ cleanup:
+return devlist;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index fbfc994652..339d0ba82c 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1011,4 +1011,9 @@ qemuDomainPrepareDiskSource(virDomainDiskDefPtr disk,
 qemuDomainObjPrivatePtr priv,
 virQEMUDriverConfigPtr cfg);
 
+virDomainDeviceDefListPtr
+qemuDomainDeviceParseXMLMany(const char *xml,
+ virDomainDeviceDefListDataPtr data,
+ unsigned int parse_flags);
+
 #endif /* __QEMU_DOMAIN_H__ */

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


[libvirt] [RFC PATCH 10/28] virhostdev: Introduce virHostdevPCIDevicesBelongToSameSlot

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/libvirt_private.syms |2 ++
 src/util/virhostdev.c|   29 +
 src/util/virhostdev.h|5 +
 src/util/virpci.c|2 +-
 src/util/virpci.h|3 +++
 5 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 53e174a223..68b648ba31 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1919,6 +1919,7 @@ virHostdevHostSupportsPassthroughKVM;
 virHostdevHostSupportsPassthroughVFIO;
 virHostdevIsSCSIDevice;
 virHostdevManagerGetDefault;
+virHostdevPCIDevicesBelongToSameSlot;
 virHostdevPCINodeDeviceDetach;
 virHostdevPCINodeDeviceReAttach;
 virHostdevPCINodeDeviceReset;
@@ -2443,6 +2444,7 @@ virPCIDeviceAddressGetIOMMUGroupAddresses;
 virPCIDeviceAddressGetIOMMUGroupNum;
 virPCIDeviceAddressGetSysfsFile;
 virPCIDeviceAddressIOMMUGroupIterate;
+virPCIDeviceAddressIsEqual;
 virPCIDeviceAddressParse;
 virPCIDeviceCopy;
 virPCIDeviceDetach;
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 807caf567a..9508a29954 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -306,6 +306,35 @@ virHostdevIsVirtualFunction(virDomainHostdevDefPtr hostdev)
 }
 
 
+bool
+virHostdevPCIDevicesBelongToSameSlot(virDomainHostdevDefPtr dev1,
+ virDomainHostdevDefPtr dev2)
+{
+virPCIDeviceAddressPtr devAddr1 = NULL, devAddr2 = NULL;
+
+if (!dev1 || !dev2)
+return false;
+
+devAddr1 = >source.subsys.u.pci.addr;
+devAddr2 = >source.subsys.u.pci.addr;
+if ((devAddr1->domain != devAddr2->domain) ||
+(devAddr1->bus != devAddr2->bus) ||
+(devAddr1->slot != devAddr2->slot) ||
+(virPCIDeviceAddressIsEqual(devAddr1, devAddr2))) {
+return false;
+}
+
+/* The Virtual Functions have multifunction false even though they have 
same
+ * domain:bus:slot as the Physical function. They are to be treated
+ * like non-multifunction devices
+ */
+if (virHostdevIsVirtualFunction(dev1) || virHostdevIsVirtualFunction(dev2))
+return false;
+
+return true;
+}
+
+
 static int
 virHostdevNetDevice(virDomainHostdevDefPtr hostdev,
 int pfNetDevIdx,
diff --git a/src/util/virhostdev.h b/src/util/virhostdev.h
index d5efffbac2..ded7620355 100644
--- a/src/util/virhostdev.h
+++ b/src/util/virhostdev.h
@@ -155,6 +155,11 @@ virHostdevUpdateActiveUSBDevices(virHostdevManagerPtr mgr,
  const char *drv_name,
  const char *dom_name)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
+
+bool
+virHostdevPCIDevicesBelongToSameSlot(virDomainHostdevDefPtr dev1,
+ virDomainHostdevDefPtr dev2);
+
 int
 virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
   virDomainHostdevDefPtr *hostdevs,
diff --git a/src/util/virpci.c b/src/util/virpci.c
index a827b3bc0f..987db605cc 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2603,7 +2603,7 @@ virPCIDeviceAddressParse(char *address,
 /*
  * returns true if equal
  */
-static bool
+bool
 virPCIDeviceAddressIsEqual(virPCIDeviceAddressPtr bdf1,
virPCIDeviceAddressPtr bdf2)
 {
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 179249677a..5830fb4c12 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -188,6 +188,9 @@ int virPCIDeviceIsAssignable(virPCIDevicePtr dev,
  int strict_acs_check);
 int virPCIDeviceWaitForCleanup(virPCIDevicePtr dev, const char *matcher);
 
+bool
+virPCIDeviceAddressIsEqual(virPCIDeviceAddressPtr bdf1,
+   virPCIDeviceAddressPtr bdf2);
 virPCIDeviceAddressPtr
 virPCIGetDeviceAddressFromSysfsLink(const char *device_link);
 

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


[libvirt] [RFC PATCH 16/28] qemu: hostdev: Move the hostdev preparation to a separate function

2018-03-15 Thread Shivaprasad G Bhat
No functional change.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |   90 +--
 src/qemu/qemu_hotplug.h |5 +++
 2 files changed, 60 insertions(+), 35 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e0a5300f08..1bf87d963e 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -688,6 +688,57 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr 
driver,
 return 0;
 }
 
+int qemuDomainAttachPCIHostDevicePrepare(virQEMUDriverPtr driver,
+ virDomainDefPtr def,
+ virDomainHostdevDefPtr hostdev,
+ virQEMUCapsPtr qemuCaps)
+{
+virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+unsigned int flags = 0;
+int ret = -1;
+int backend;
+
+if (!cfg->relaxedACS)
+flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
+if (qemuHostdevPreparePCIDevices(driver, def->name, def->uuid,
+ , 1, qemuCaps, flags) < 0)
+goto exit;
+
+/* this could have been changed by qemuHostdevPreparePCIDevices */
+backend = hostdev->source.subsys.u.pci.backend;
+
+switch ((virDomainHostdevSubsysPCIBackendType) backend) {
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
+if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("VFIO PCI device assignment is not "
+ "supported by this version of qemu"));
+goto error;
+}
+break;
+
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
+break;
+
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("QEMU does not support device assignment mode '%s'"),
+   virDomainHostdevSubsysPCIBackendTypeToString(backend));
+goto error;
+break;
+}
+
+ret = 0;
+ exit:
+virObjectUnref(cfg);
+return ret;
+ error:
+qemuHostdevReAttachPCIDevices(driver, def->name, , 1);
+goto exit;
+}
+
 
 int
 qemuDomainAttachDeviceDiskLive(virQEMUDriverPtr driver,
@@ -1257,44 +1308,16 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 bool teardownlabel = false;
 bool teardowndevice = false;
 int backend;
-virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
-unsigned int flags = 0;
 
 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
-goto cleanup;
+return -1;
 
-if (!cfg->relaxedACS)
-flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
-if (qemuHostdevPreparePCIDevices(driver, vm->def->name, vm->def->uuid,
- , 1, priv->qemuCaps, flags) < 0)
-goto cleanup;
+if (qemuDomainAttachPCIHostDevicePrepare(driver, vm->def,
+ hostdev, priv->qemuCaps) < 0)
+return -1;
 
-/* this could have been changed by qemuHostdevPreparePCIDevices */
 backend = hostdev->source.subsys.u.pci.backend;
 
-switch ((virDomainHostdevSubsysPCIBackendType) backend) {
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
-if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("VFIO PCI device assignment is not "
- "supported by this version of qemu"));
-goto error;
-}
-break;
-
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
-break;
-
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-   _("QEMU does not support device assignment mode '%s'"),
-   virDomainHostdevSubsysPCIBackendTypeToString(backend));
-goto error;
-break;
-}
-
 /* Temporarily add the hostdev to the domain definition. This is needed
  * because qemuDomainAdjustMaxMemLock() requires the hostdev to be already
  * part of the domain definition, but other functions like
@@ -1366,7 +1389,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 VIR_FREE(devstr);
 VIR_FREE(configfd_name);
 VIR_FORCE_CLOSE(configfd);
-virObjectUnref(cfg);
 
 return 0;
 
@@ -1389,8 +1411,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 VIR_FREE(configfd_name);
 VIR_FORCE_CLOSE(configfd);
 
- cleanup:
-virObjectUnref(cfg);
 retu

[libvirt] [RFC PATCH 12/28] qemu: address: Enable auto addressing multifunction cards

2018-03-15 Thread Shivaprasad G Bhat
For existing domains using the primary function alone of a multifunction card,
the card is still treated as a multifunction card. This is done to prevent
hotplug of other functions when the primary function is already hotplugged.

If the secondary functions are part of the xml without the primary function
being part of the xml, this has never been supported. So, the libvirt doesn't
consider this either as a multifunction card.



Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.h |   11 +
 src/qemu/qemu_domain_address.c |  169 +++-
 tests/qemuhotplugtest.c|1 
 .../hostdev-pci-multifunction.args |   18 +-
 tests/qemuxml2argvdata/pseries-hostdevs-1.args |5 -
 tests/qemuxml2argvdata/pseries-hostdevs-3.args |5 -
 tests/qemuxml2argvtest.c   |5 -
 .../hostdev-pci-multifunction.xml  |   16 +-
 tests/qemuxml2xmloutdata/pseries-hostdevs-1.xml|4 
 tests/qemuxml2xmloutdata/pseries-hostdevs-3.xml|4 
 10 files changed, 207 insertions(+), 31 deletions(-)

diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 6d3e6eb5e3..fbfc994652 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -473,6 +473,17 @@ struct _qemuDomainSaveCookie {
 
 qemuDomainSaveCookiePtr qemuDomainSaveCookieNew(virDomainObjPtr vm);
 
+typedef struct _qemuDomainPCIHostdevdata qemuDomainPCIHostdevdata;
+typedef qemuDomainPCIHostdevdata *qemuDomainPCIHostdevDataPtr;
+struct _qemuDomainPCIHostdevdata {
+const virDomainDef *def;
+virDomainPCIAddressSetPtr addrs;
+virDomainHostdevDefPtr device;
+};
+
+typedef int (*virDomainPCIHostdevCallback)(qemuDomainPCIHostdevDataPtr data,
+   virDomainHostdevDefPtr hostdev);
+
 const char *qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job,
 int phase);
 int qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job,
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 424b56dac9..bc72b6e94c 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1186,11 +1186,155 @@ qemuDomainSetupIsolationGroups(virDomainDefPtr def)
 }
 
 
+#define PCI_MAX_BRIDGE_NUMBER 0xff
+#define PCI_MAX_DEVICES 32
+
+
+/**
+ * qemuDomainPCIHostDevicesIter:
+ * @data - The data->device is the one which is called-back with for
+ * each hostdev
+ * cb() - callback to be called for each hostdev
+ * Return :
+ * If the callback for any of the hostdev fails, the Iter returns
+ * with the return value for that callback.
+ * Zero on success.
+ */
+static
+int qemuDomainPCIHostDevicesIter(qemuDomainPCIHostdevDataPtr data,
+ virDomainPCIHostdevCallback cb)
+{
+size_t i;
+int ret = -1;
+
+/* Iterate through the PCI Hostdevices, the Mdev source is of type
+ * UUID, so skip that. */
+for (i = 0; i < data->def->nhostdevs; i++) {
+virDomainHostdevSubsysPtr subsys = 
>def->hostdevs[i]->source.subsys;
+virDomainHostdevDefPtr hostdev = data->def->hostdevs[i];
+if (data->device == hostdev)
+continue;
+if (data->def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+continue;
+if (subsys->type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+subsys->type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST &&
+(subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV &&
+ subsys->u.mdev.model == VIR_MDEV_MODEL_TYPE_VFIO_PCI)) {
+continue;
+}
+
+if ((ret = cb(data, hostdev)) != 0)
+return ret;
+}
+
+return 0;
+}
+
+
+
+static int
+qemuDomainFindNextAggregationSlotIdxIter(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainDeviceDefPtr dev 
ATTRIBUTE_UNUSED,
+ virDomainDeviceInfoPtr info,
+ void *opaque)
+{
+int *aggregationSlotIdx = opaque;
+
+if (info && info->aggregateSlotIdx == *aggregationSlotIdx)
+return -1;
+
+return 0;
+}
+
+
+static unsigned int
+qemuDomainFindNextSlotAggregationIdx(virDomainDefPtr def)
+{
+int aggregateSlotIdx = 2;
+
+while (aggregateSlotIdx < PCI_MAX_BRIDGE_NUMBER * PCI_MAX_DEVICES  &&
+   virDomainDeviceInfoIterate(def,
+  qemuDomainFindNextAggregationSlotIdxIter,
+  ) < 0) {
+aggregateSlotIdx++;
+}
+
+return aggregateSlotIdx;
+}
+
+
+static int
+qemuDomainDefHostdevGetSlotAggregateIdx(qemuDomainPCIHostdevDataPtr data,
+virDomainHostdevDefPtr hostdev)
+{
+if (da

[libvirt] [RFC PATCH 28/28] qemu: hotplug: Implement multifunction device unplug

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c  |   48 +---
 src/qemu/qemu_hotplug.c |  111 +++
 src/qemu/qemu_hotplug.h |5 ++
 tests/qemuhotplugtest.c |   26 ---
 4 files changed, 165 insertions(+), 25 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 94f76979e5..0640395b00 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7858,12 +7858,18 @@ qemuDomainDetachDeviceLiveInternal(virDomainObjPtr vm,
 
 static int
 qemuDomainDetachDeviceLive(virDomainObjPtr vm,
-   virDomainDeviceDefPtr dev,
+   virDomainDeviceDefListPtr devlist,
virQEMUDriverPtr driver)
 {
 int ret = -1;
+virDomainDeviceDefPtr dev = devlist->devs[0];
+
+if (devlist->count > 1) {
+ret = qemuDomainDetachMultifunctionDevice(vm, devlist, driver);
+} else {
+ret = qemuDomainDetachDeviceLiveInternal(vm, dev, driver);
+}
 
-ret = qemuDomainDetachDeviceLiveInternal(vm, dev, driver);
 if (ret == 0)
 ret = qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE);
 
@@ -8392,17 +8398,24 @@ qemuDomainDetachDeviceConfigInternal(virDomainDefPtr 
vmdef,
 
 static int
 qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev,
+ virDomainDeviceDefListPtr devlist,
  virCapsPtr caps,
  unsigned int parse_flags,
  virDomainXMLOptionPtr xmlopt)
 {
-if (qemuDomainDetachDeviceConfigInternal(vmdef, dev))
-return -1;
+size_t i;
+for (i = 0; i < devlist->count; i++)
+if (qemuDomainDetachDeviceConfigInternal(vmdef, devlist->devs[i]))
+return -1;
 
 if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL) < 0)
 return -1;
 
+/* Dont allow removing the primary function alone for a multifunction
+ * device leading to guest start failure later. */
+if (devlist->count > 1 && qemuDomainDefValidatePCIHostdevs(vmdef) < 0)
+return -1;
+
 return 0;
 }
 
@@ -8765,8 +8778,9 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr 
driver,
 {
 virCapsPtr caps = NULL;
 virQEMUDriverConfigPtr cfg = NULL;
-virDomainDeviceDefPtr dev = NULL, dev_copy = NULL;
 unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE;
+virDomainDeviceDefListPtr devlist = NULL, devcopylist = NULL;
+virDomainDeviceDefListData data = {.def = vm->def, .xmlopt = 
driver->xmlopt, .caps = NULL};
 virDomainDefPtr vmdef = NULL;
 int ret = -1;
 
@@ -8775,6 +8789,7 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr 
driver,
 
 if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
 goto cleanup;
+data.caps = caps;
 
 cfg = virQEMUDriverGetConfig(driver);
 
@@ -8782,11 +8797,10 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr 
driver,
 !(flags & VIR_DOMAIN_AFFECT_LIVE))
 parse_flags |= VIR_DOMAIN_DEF_PARSE_INACTIVE;
 
-dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
- caps, driver->xmlopt,
- parse_flags);
-if (dev == NULL)
+devlist = qemuDomainDeviceParseXMLMany(xml, , parse_flags);
+if (!devlist)
 goto cleanup;
+devcopylist = devlist;
 
 if (flags & VIR_DOMAIN_AFFECT_CONFIG &&
 flags & VIR_DOMAIN_AFFECT_LIVE) {
@@ -8794,8 +8808,8 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr 
driver,
  * create a deep copy of device as adding
  * to CONFIG takes one instance.
  */
-dev_copy = virDomainDeviceDefCopy(dev, vm->def, caps, driver->xmlopt);
-if (!dev_copy)
+devcopylist =  virDomainDeviceDefListCopy(devlist, );
+if (!devcopylist)
 goto cleanup;
 }
 
@@ -8805,14 +8819,14 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr 
driver,
 if (!vmdef)
 goto cleanup;
 
-if ((ret = qemuDomainDetachDeviceConfig(vmdef, dev, caps,
+if ((ret = qemuDomainDetachDeviceConfig(vmdef, devlist, caps,
 parse_flags,
 driver->xmlopt)) < 0)
 goto cleanup;
 }
 
 if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-if ((ret = qemuDomainDetachDeviceLive(vm, dev_copy, driver)) < 0)
+if ((ret = qemuDomainDetachDeviceLive(vm, devcopylist, driver)) < 0)
 goto cleanup;
 /*
  * update domain status forcibly because the domain status may be
@@ -8837,9 +8851,9 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr 
driver,
  cleanup:
 virObje

[libvirt] [RFC PATCH 14/28] conf: qemu: validate multifunction hostdevice domain configs

2018-03-15 Thread Shivaprasad G Bhat
It is invalid to have secondary functions without the primary
functions part of the domain. Prevents new domain define, but
existing ones would not vanish.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.c |3 +
 src/qemu/qemu_domain_address.c |   57 
 src/qemu/qemu_domain_address.h |2 +
 .../hostdev-pci-no-primary-function.xml|   23 
 tests/qemuxml2argvdata/hostdev-pci-validate.args   |   25 +
 tests/qemuxml2argvdata/hostdev-pci-validate.xml|   29 ++
 tests/qemuxml2argvtest.c   |9 +++
 7 files changed, 148 insertions(+)
 create mode 100644 tests/qemuxml2argvdata/hostdev-pci-no-primary-function.xml
 create mode 100644 tests/qemuxml2argvdata/hostdev-pci-validate.args
 create mode 100644 tests/qemuxml2argvdata/hostdev-pci-validate.xml

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2d108bec1b..12ed68a89b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3565,6 +3565,9 @@ qemuDomainDefValidate(const virDomainDef *def,
 if (qemuDomainDefValidateFeatures(def) < 0)
 goto cleanup;
 
+if (qemuDomainDefValidatePCIHostdevs(def) < 0)
+goto cleanup;
+
 ret = 0;
 
  cleanup:
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index bc72b6e94c..7bee4fb937 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1996,6 +1996,63 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDefPtr 
def,
 }
 
 
+static int
+qemuDomainDefPCIHostdevIsPrimaryFunction(qemuDomainPCIHostdevDataPtr data,
+ virDomainHostdevDefPtr hostdev)
+{
+if (!data->device || !hostdev)
+return 0;
+
+if ((hostdev->source.subsys.u.pci.addr.function == 0) &&
+(virHostdevPCIDevicesBelongToSameSlot(data->device, hostdev)))
+return 1;
+
+return 0;
+}
+
+
+static int 
qemuDomainDefValidatePCIMultifunctionHostdev(qemuDomainPCIHostdevDataPtr data,
+virDomainHostdevDefPtr 
hostdev)
+{
+int ret = 0;
+qemuDomainPCIHostdevdata hostdevIterData = {data->def, NULL, hostdev};
+
+if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI ||
+hostdev->source.subsys.u.pci.addr.function == 0)
+goto skip;
+
+if (virHostdevIsVirtualFunction(hostdev))
+goto skip;
+
+/* If the device is non-zero function but its Primary function is not
+ * part of the domain, then error out.
+ */
+if (!qemuDomainPCIHostDevicesIter(,
+  
qemuDomainDefPCIHostdevIsPrimaryFunction)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("Secondary functions of a PCI multifunction card "
+ "cannot be assigned to a domain without the "
+ "Primary function."));
+ret = -1;
+}
+
+ skip:
+return ret;
+}
+
+int qemuDomainDefValidatePCIHostdevs(const virDomainDef *def)
+{
+qemuDomainPCIHostdevdata hostdevdata = {def, NULL, NULL};
+
+if (qemuDomainPCIHostDevicesIter(,
+ 
qemuDomainDefValidatePCIMultifunctionHostdev)) {
+return -1;
+}
+
+return 0;
+}
+
+
 /*
  * This assigns static PCI slots to all configured devices.
  * The ordering here is chosen to match the ordering used
diff --git a/src/qemu/qemu_domain_address.h b/src/qemu/qemu_domain_address.h
index 650f977cf7..e1cc467714 100644
--- a/src/qemu/qemu_domain_address.h
+++ b/src/qemu/qemu_domain_address.h
@@ -62,6 +62,8 @@ int
 qemuDomainDefDeviceFindSlotAggregateIdx(virDomainDefPtr def,
 virDomainDeviceDefPtr dev);
 
+int qemuDomainDefValidatePCIHostdevs(const virDomainDef *def);
+
 
 void qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
 virDomainDeviceInfoPtr info,
diff --git a/tests/qemuxml2argvdata/hostdev-pci-no-primary-function.xml 
b/tests/qemuxml2argvdata/hostdev-pci-no-primary-function.xml
new file mode 100644
index 00..7106ab73b1
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-pci-no-primary-function.xml
@@ -0,0 +1,23 @@
+
+  delete
+  583a8e8e-f0ce-4f53-89ab-092862148b25
+  262144
+  4
+  
+hvm
+  
+  
+/usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+  
+  
+
+  
+
+  
+
diff --git a/tests/qemuxml2argvdata/hostdev-pci-validate.args 
b/tests/qemuxml2argvdata/hostdev-pci-validate.args
new file mode 100644
index 00..bda8cab6c9
--- /dev/null
+++ b/tests/qemuxml2argvdata/hostdev-pci-validate.args
@@ -0,0 +1,25 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-syst

[libvirt] [RFC PATCH 08/28] util: virpci: detect if the device is a multifunction device from sysfs

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/libvirt_private.syms   |1 +
 src/node_device/node_device_udev.c |2 +-
 src/util/virhostdev.c  |2 +-
 src/util/virpci.c  |   20 ++--
 src/util/virpci.h  |3 ++-
 5 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e1bdaa127e..53e174a223 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2462,6 +2462,7 @@ virPCIDeviceGetUnbindFromStub;
 virPCIDeviceGetUsedBy;
 virPCIDeviceHasPCIExpressLink;
 virPCIDeviceIsAssignable;
+virPCIDeviceIsMultifunction;
 virPCIDeviceIsPCIExpress;
 virPCIDeviceListAdd;
 virPCIDeviceListAddCopy;
diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index e87eb32a85..99b936bb5c 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -455,7 +455,7 @@ udevProcessPCI(struct udev_device *device,
 
 /* We need to be root to read PCI device configs */
 if (privileged) {
-if (virPCIGetHeaderType(pciDev, _dev->hdrType) < 0)
+if (virPCIGetHeaderType(pciDev, _dev->hdrType, NULL) < 0)
 goto cleanup;
 
 if (virPCIDeviceIsPCIExpress(pciDev) > 0) {
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index e0133cdeec..807caf567a 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -693,7 +693,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
 struct virHostdevIsPCINodeDeviceUsedData data = { mgr, dom_name, 
usesVFIO };
 int hdrType = -1;
 
-if (virPCIGetHeaderType(pci, ) < 0)
+if (virPCIGetHeaderType(pci, , NULL) < 0)
 goto cleanup;
 
 if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 55e4c3e492..a827b3bc0f 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -936,7 +936,7 @@ virPCIDeviceReset(virPCIDevicePtr dev,
 int fd = -1;
 int hdrType = -1;
 
-if (virPCIGetHeaderType(dev, ) < 0)
+if (virPCIGetHeaderType(dev, , NULL) < 0)
 return -1;
 
 if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
@@ -3169,6 +3169,18 @@ virPCIGetMdevTypes(const char *sysfspath 
ATTRIBUTE_UNUSED,
 }
 #endif /* __linux__ */
 
+bool
+virPCIDeviceIsMultifunction(virPCIDevicePtr dev)
+{
+bool multifunction = false;
+int hdrType = -1;
+
+if (virPCIGetHeaderType(dev, , ) < 0)
+return false;
+
+return multifunction;
+}
+
 int
 virPCIDeviceIsPCIExpress(virPCIDevicePtr dev)
 {
@@ -3254,10 +3266,11 @@ virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
 }
 
 
-int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
+int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType, bool *multiFunc)
 {
 int fd;
 uint8_t type;
+bool multi = false;
 
 *hdrType = -1;
 
@@ -3268,6 +3281,7 @@ int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
 
 virPCIDeviceConfigClose(dev, fd);
 
+multi = type & PCI_HEADER_TYPE_MULTI;
 type &= PCI_HEADER_TYPE_MASK;
 if (type >= VIR_PCI_HEADER_LAST) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -3276,6 +3290,8 @@ int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
 }
 
 *hdrType = type;
+if (multiFunc)
+*multiFunc = multi;
 
 return 0;
 }
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 794b7e59db..179249677a 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -199,6 +199,7 @@ int virPCIGetVirtualFunctions(const char *sysfs_path,
   size_t *num_virtual_functions,
   unsigned int *max_virtual_functions);
 
+bool virPCIDeviceIsMultifunction(virPCIDevicePtr dev);
 int virPCIIsVirtualFunction(const char *vf_sysfs_device_link);
 
 int virPCIGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
@@ -246,7 +247,7 @@ int virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
   unsigned int *sta_speed,
   unsigned int *sta_width);
 
-int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType);
+int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType, bool *multiFunc);
 
 void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev);
 

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


[libvirt] [RFC PATCH 24/28] domain: addr: Introduce virDomainPCIAddressEnsureMultifunctionAddress

2018-03-15 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/conf/device_conf.h   |6 +++
 src/conf/domain_addr.c   |   84 ++
 src/conf/domain_addr.h   |5 +++
 src/libvirt_private.syms |1 +
 src/util/virpci.h|2 +
 5 files changed, 98 insertions(+)

diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index cdb2040fb8..ae7a651ee0 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -177,6 +177,12 @@ struct _virDomainDeviceInfo {
 bool isolationGroupLocked;
 };
 
+typedef struct _virDomainPCIMultifunctionAddressInfo 
virDomainPCIMultifunctionAddressInfo;
+typedef virDomainPCIMultifunctionAddressInfo 
*virDomainPCIMultifunctionAddressInfoPtr;
+struct _virDomainPCIMultifunctionAddressInfo {
+   virDomainDeviceInfoPtr infos[VIR_PCI_MAX_FUNCTIONS];
+};
+
 int virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst,
 virDomainDeviceInfoPtr src);
 void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info);
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index c4a0b99628..43227a4b25 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -27,6 +27,7 @@
 #include "virlog.h"
 #include "virstring.h"
 #include "domain_addr.h"
+#include "device_conf.h"
 
 #define VIR_FROM_THIS VIR_FROM_DOMAIN
 
@@ -697,6 +698,89 @@ virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr 
addrs,
 }
 
 
+/*
+ *virDomainPCIAddressEnsureMultifunctionAddress:
+ *
+ *
+ *
+ */
+
+int
+virDomainPCIAddressEnsureMultifunctionAddress(virDomainPCIAddressSetPtr addrs,
+  
virDomainPCIMultifunctionAddressInfoPtr pcicard)
+{
+size_t i;
+int ret = 0;
+virPCIDeviceAddressPtr addr1 = NULL, addr2 = NULL;
+virDomainDeviceInfoPtr dev = NULL;
+char *addrStr = NULL;
+
+if (!pcicard->infos[0]) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Function-Zero missing on the slot"));
+return -1;
+}
+
+/* If the address is given by the user, make sure they belong
+ * to same slot */
+for (i = 0; i < VIR_PCI_MAX_FUNCTIONS; i++) {
+dev = pcicard->infos[i];
+if (dev && !dev->pciConnectFlags) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Not a PCI Multifunction device."));
+goto cleanup;
+}
+if (dev && virDeviceInfoPCIAddressPresent(dev)) {
+/* Pick one and compare against rest of the user given */
+addr1 = addr1 ? addr1 : >addr.pci;
+addr2 = >addr.pci;
+if (!(addrStr = virDomainPCIAddressAsString(addr2)))
+goto cleanup;
+if (!virDomainPCIAddressValidate(addrs, addr2,
+ addrStr, dev->pciConnectFlags, 
true))
+goto cleanup;
+if (!(addr1->domain == addr2->domain && addr1->bus == addr2->bus &&
+  addr1->slot == addr2->slot)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+_("Addresses belong to different PCI slots"));
+goto cleanup;
+}
+VIR_FREE(addrStr);
+}
+}
+
+/* Reserve all the user given addresses. */
+for (i = 0; i < VIR_PCI_MAX_FUNCTIONS; i++) {
+dev = pcicard->infos[i];
+if (dev && virDeviceInfoPCIAddressPresent(dev)) {
+ret = virDomainPCIAddressReserveAddrInternal(addrs, >addr.pci,
+ dev->pciConnectFlags, 
dev->isolationGroup,
+ dev->aggregateSlotIdx,
+ true);
+if (ret < 0)
+goto cleanup;
+}
+}
+
+/* If the user has not given addresses, start with function zero */
+for (i = 0; i < VIR_PCI_MAX_FUNCTIONS; i++) {
+dev = pcicard->infos[i];
+if (dev && !virDeviceInfoPCIAddressPresent(dev)) {
+ret = virDomainPCIAddressReserveNextAddr(addrs, dev, 
dev->pciConnectFlags, i);
+if (ret < 0)
+goto cleanup;
+}
+}
+
+/* Set multi on overriding what user has set. */
+pcicard->infos[0]->addr.pci.multi = VIR_TRISTATE_SWITCH_ON;
+
+ cleanup:
+VIR_FREE(addrStr);
+return ret;
+}
+
+
 void
 virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
virPCIDeviceAddressPtr addr)
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
index fa98b67e5c..e80e1e9089 100644
--- a/src/conf/domain_addr.h
+++ b/src/conf/domain_addr.h
@@ -162,6 +162,11 @@ int 

[libvirt] [RFC PATCH 22/28] qemu: refactor qemuDomain[Attach|Detach]DeviceLive

2018-03-15 Thread Shivaprasad G Bhat
Helps calling multiple time per device
---
 src/qemu/qemu_driver.c |   41 +++--
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 18e88f05bb..d2e10082ea 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7599,9 +7599,9 @@ qemuDomainUndefine(virDomainPtr dom)
 }
 
 static int
-qemuDomainAttachDeviceLive(virDomainObjPtr vm,
-   virDomainDeviceDefPtr dev,
-   virQEMUDriverPtr driver)
+qemuDomainAttachDeviceLiveInternal(virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   virQEMUDriverPtr driver)
 {
 int ret = -1;
 const char *alias = NULL;
@@ -7739,12 +7739,25 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
 qemuDomainEventQueue(driver, event);
 }
 
+return ret;
+}
+
+static int
+qemuDomainAttachDeviceLive(virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   virQEMUDriverPtr driver)
+{
+int ret = -1;
+
+if (virDomainDefCompatibleDevice(vm->def, dev, NULL) < 0)
+return -1;
+
+ret = qemuDomainAttachDeviceLiveInternal(vm, dev, driver);
 if (ret == 0)
 ret = qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE);
 
 return ret;
 }
-
 static int
 qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver,
  virDomainObjPtr vm,
@@ -7766,9 +7779,9 @@ qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr 
driver,
 }
 
 static int
-qemuDomainDetachDeviceLive(virDomainObjPtr vm,
-   virDomainDeviceDefPtr dev,
-   virQEMUDriverPtr driver)
+qemuDomainDetachDeviceLiveInternal(virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   virQEMUDriverPtr driver)
 {
 int ret = -1;
 
@@ -7829,6 +7842,17 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
 break;
 }
 
+return ret;
+}
+
+static int
+qemuDomainDetachDeviceLive(virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   virQEMUDriverPtr driver)
+{
+int ret = -1;
+
+ret = qemuDomainDetachDeviceLiveInternal(vm, dev, driver);
 if (ret == 0)
 ret = qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE);
 
@@ -8518,9 +8542,6 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
 }
 
 if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-if (virDomainDefCompatibleDevice(vm->def, dev_copy, NULL) < 0)
-goto cleanup;
-
 if ((ret = qemuDomainAttachDeviceLive(vm, dev_copy, driver)) < 0)
 goto cleanup;
 /*

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


[libvirt] [RFC PATCH 21/28] qemu: refactor qemuDomain[Attach|Detach]DeviceConfig

2018-03-15 Thread Shivaprasad G Bhat
This helps calling the routines with a list of devices.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c |   45 ++---
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0ade86d6a9..18e88f05bb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7969,11 +7969,8 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm,
 }
 
 static int
-qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev,
- virCapsPtr caps,
- unsigned int parse_flags,
- virDomainXMLOptionPtr xmlopt)
+qemuDomainAttachDeviceConfigInternal(virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev)
 {
 virDomainDiskDefPtr disk;
 virDomainNetDefPtr net;
@@ -8151,20 +8148,34 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
  return -1;
 }
 
-if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL) < 0)
-return -1;
-
 return 0;
 }
 
 
 static int
-qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
+qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
  virDomainDeviceDefPtr dev,
  virCapsPtr caps,
  unsigned int parse_flags,
  virDomainXMLOptionPtr xmlopt)
 {
+if (virDomainDefCompatibleDevice(vmdef, dev, NULL) < 0)
+return -1;
+
+if (qemuDomainAttachDeviceConfigInternal(vmdef, dev))
+return -1;
+
+if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL) < 0)
+return -1;
+
+return 0;
+}
+
+
+static int
+qemuDomainDetachDeviceConfigInternal(virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev)
+{
 virDomainDiskDefPtr disk, det_disk;
 virDomainNetDefPtr net;
 virDomainHostdevDefPtr hostdev, det_hostdev;
@@ -8334,6 +8345,20 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
 return -1;
 }
 
+return 0;
+}
+
+
+static int
+qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev,
+ virCapsPtr caps,
+ unsigned int parse_flags,
+ virDomainXMLOptionPtr xmlopt)
+{
+if (qemuDomainDetachDeviceConfigInternal(vmdef, dev))
+return -1;
+
 if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL) < 0)
 return -1;
 
@@ -8486,8 +8511,6 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
 if (!vmdef)
 goto cleanup;
 
-if (virDomainDefCompatibleDevice(vmdef, dev, NULL) < 0)
-goto cleanup;
 if ((ret = qemuDomainAttachDeviceConfig(vmdef, dev, caps,
 parse_flags,
 driver->xmlopt)) < 0)

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


[libvirt] [RFC PATCH 01/28] tests: Fix the iommu group path in mock pci

2018-03-15 Thread Shivaprasad G Bhat
The mocked path falls into /sys/bus/kernel/iommu_groups instead of
/sys/kernel/iommu_groups. Needed for adding some new test cases.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 tests/virpcimock.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/virpcimock.c b/tests/virpcimock.c
index 176c64d654..2a7e9216b2 100644
--- a/tests/virpcimock.c
+++ b/tests/virpcimock.c
@@ -404,7 +404,7 @@ pci_device_new_from_stub(const struct pciDevice *data)
 make_file(devpath, "class", tmp, -1);
 
 if (snprintf(tmp, sizeof(tmp),
- "%s/../../../kernel/iommu_groups/%d",
+ "%s/../../../../kernel/iommu_groups/%d",
  devpath, dev->iommuGroup) < 0) {
 ABORT("@tmp overflow");
 }
@@ -412,7 +412,7 @@ pci_device_new_from_stub(const struct pciDevice *data)
 ABORT("Unable to create %s", tmp);
 
 if (snprintf(tmp, sizeof(tmp),
- "../../../kernel/iommu_groups/%d", dev->iommuGroup) < 0) {
+ "../../../../kernel/iommu_groups/%d", dev->iommuGroup) < 0) {
 ABORT("@tmp overflow");
 }
 make_symlink(devpath, "iommu_group", tmp);

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


Re: [libvirt] [PATCH v4] virt-aa-helper: Set the supported features

2018-02-06 Thread Shivaprasad G Bhat

Actually Christian


On 02/06/2018 07:12 PM, Peter Krempa wrote:

On Tue, Feb 06, 2018 at 08:08:14 -0500, Shivaprasad G Bhat wrote:

The virt-aa-helper fails to parse the xmls with the memory/cpu
hotplug features or user assigned aliases. Set the features in
xmlopt->config for the parsing to succeed.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
  src/conf/domain_conf.h|2 ++
  src/security/virt-aa-helper.c |8 +++-
  2 files changed, 9 insertions(+), 1 deletion(-)

ACK from my side, but I'll wait for a while for the debian/ubuntu guys
chiming in.
ActuallyChristian Ehrhardt already replied on this implementation(v2 
patch) before,

and I missed to add
Tested-By: Christian Ehrhardt  <christian.ehrha...@canonical.com>

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

[libvirt] [PATCH v4] virt-aa-helper: Set the supported features

2018-02-06 Thread Shivaprasad G Bhat
The virt-aa-helper fails to parse the xmls with the memory/cpu
hotplug features or user assigned aliases. Set the features in
xmlopt->config for the parsing to succeed.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/conf/domain_conf.h|2 ++
 src/security/virt-aa-helper.c |8 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 21e004515..25d0b8187 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2532,6 +2532,8 @@ typedef bool (*virDomainObjListACLFilter)(virConnectPtr 
conn,
   virDomainDefPtr def);
 
 
+/* NB: Any new flag to this list be considered to be set in
+ * virt-aa-helper code if the flag prevents parsing. */
 typedef enum {
 VIR_DOMAIN_DEF_FEATURE_WIDE_SCSI = (1 << 0),
 VIR_DOMAIN_DEF_FEATURE_MEMORY_HOTPLUG = (1 << 1),
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index f7ccae0b0..29a459da2 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -654,6 +654,11 @@ caps_mockup(vahControl * ctl, const char *xmlStr)
 return rc;
 }
 
+virDomainDefParserConfig virAAHelperDomainDefParserConfig = {
+.features = VIR_DOMAIN_DEF_FEATURE_MEMORY_HOTPLUG |
+VIR_DOMAIN_DEF_FEATURE_OFFLINE_VCPUPIN |
+VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS,
+};
 
 static int
 get_definition(vahControl * ctl, const char *xmlStr)
@@ -673,7 +678,8 @@ get_definition(vahControl * ctl, const char *xmlStr)
 goto exit;
 }
 
-if (!(ctl->xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL))) {
+if (!(ctl->xmlopt = 
virDomainXMLOptionNew(,
+  NULL, NULL, NULL, NULL))) {
 vah_error(ctl, 0, _("Failed to create XML config object"));
 goto exit;
 }

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


[libvirt] [PATCH v3] virt-aa-helper: Skip feature support checks while parsing

2018-02-05 Thread Shivaprasad G Bhat
virt-aa-helper need not verify the feature support as
libvirt does it during domain creation anyway.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/conf/domain_conf.c|3 +++
 src/conf/domain_conf.h|1 +
 src/security/virt-aa-helper.c |6 +-
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e827b2a81..92929a289 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4736,6 +4736,9 @@ static int
 virDomainDefPostParseCheckFeatures(virDomainDefPtr def,
virDomainXMLOptionPtr xmlopt)
 {
+if (!UNSUPPORTED(VIR_DOMAIN_DEF_FEATURE_SKIP_VALIDATE))
+return 0;
+
 if (UNSUPPORTED(VIR_DOMAIN_DEF_FEATURE_MEMORY_HOTPLUG) &&
 virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
 return -1;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 21e004515..c36d29fd9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2539,6 +2539,7 @@ typedef enum {
 VIR_DOMAIN_DEF_FEATURE_NAME_SLASH = (1 << 3),
 VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS = (1 << 4),
 VIR_DOMAIN_DEF_FEATURE_USER_ALIAS = (1 << 5),
+VIR_DOMAIN_DEF_FEATURE_SKIP_VALIDATE = (1 << 6),
 } virDomainDefFeatures;
 
 
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index f7ccae0b0..b15fea7eb 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -654,6 +654,9 @@ caps_mockup(vahControl * ctl, const char *xmlStr)
 return rc;
 }
 
+virDomainDefParserConfig virAAHelperDomainDefParserConfig = {
+.features = VIR_DOMAIN_DEF_FEATURE_SKIP_VALIDATE,
+};
 
 static int
 get_definition(vahControl * ctl, const char *xmlStr)
@@ -673,7 +676,8 @@ get_definition(vahControl * ctl, const char *xmlStr)
 goto exit;
 }
 
-if (!(ctl->xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL))) {
+if (!(ctl->xmlopt = 
virDomainXMLOptionNew(,
+  NULL, NULL, NULL, NULL))) {
 vah_error(ctl, 0, _("Failed to create XML config object"));
 goto exit;
 }

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


[libvirt] [PATCH v2] virt-aa-helper: Set the supported features

2018-01-19 Thread Shivaprasad G Bhat
The virt-aa-helper fails to parse the xmls with the memory/cpu
hotplug features or user assigned aliases. Set the features in
xmlopt->config for the parsing to succeed.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/security/virt-aa-helper.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index f7ccae0..29a459d 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -654,6 +654,11 @@ caps_mockup(vahControl * ctl, const char *xmlStr)
 return rc;
 }
 
+virDomainDefParserConfig virAAHelperDomainDefParserConfig = {
+.features = VIR_DOMAIN_DEF_FEATURE_MEMORY_HOTPLUG |
+VIR_DOMAIN_DEF_FEATURE_OFFLINE_VCPUPIN |
+VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS,
+};
 
 static int
 get_definition(vahControl * ctl, const char *xmlStr)
@@ -673,7 +678,8 @@ get_definition(vahControl * ctl, const char *xmlStr)
 goto exit;
 }
 
-if (!(ctl->xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL))) {
+if (!(ctl->xmlopt = 
virDomainXMLOptionNew(,
+  NULL, NULL, NULL, NULL))) {
 vah_error(ctl, 0, _("Failed to create XML config object"));
 goto exit;
 }

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


[libvirt] [PATCH] virt-aa-helper: Allow parsing supported features for qemu/kvm

2018-01-11 Thread Shivaprasad G Bhat
The virt-aa-helper fails to parse the xmls with the memory/cpu
hotplug features or user assigned aliases. Set the features in
xmlopt->config for the parsing to succeed.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/conf/domain_conf.c|   21 -
 src/conf/domain_conf.h|   21 +
 src/security/virt-aa-helper.c |7 +++
 3 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a1c2506..20ce83e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -64,27 +64,6 @@
 
 VIR_LOG_INIT("conf.domain_conf");
 
-/* This structure holds various callbacks and data needed
- * while parsing and creating domain XMLs */
-struct _virDomainXMLOption {
-virObject parent;
-
-/* XML parser callbacks and defaults */
-virDomainDefParserConfig config;
-
-/* domain private data management callbacks */
-virDomainXMLPrivateDataCallbacks privateData;
-
-/* XML namespace callbacks */
-virDomainXMLNamespace ns;
-
-/* ABI stability callbacks */
-virDomainABIStability abi;
-
-/* Private data for save image stored in snapshot XML */
-virSaveCookieCallbacks saveCookie;
-};
-
 #define VIR_DOMAIN_DEF_FORMAT_COMMON_FLAGS \
 (VIR_DOMAIN_DEF_FORMAT_SECURE | \
  VIR_DOMAIN_DEF_FORMAT_INACTIVE | \
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6f7f96b..aacb88a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2662,6 +2662,27 @@ struct _virDomainABIStability {
 virDomainABIStabilityDomain domain;
 };
 
+/* This structure holds various callbacks and data needed
+ * while parsing and creating domain XMLs */
+struct _virDomainXMLOption {
+virObject parent;
+
+/* XML parser callbacks and defaults */
+virDomainDefParserConfig config;
+
+/* domain private data management callbacks */
+virDomainXMLPrivateDataCallbacks privateData;
+
+/* XML namespace callbacks */
+virDomainXMLNamespace ns;
+
+/* ABI stability callbacks */
+virDomainABIStability abi;
+
+/* Private data for save image stored in snapshot XML */
+virSaveCookieCallbacks saveCookie;
+};
+
 virDomainXMLOptionPtr virDomainXMLOptionNew(virDomainDefParserConfigPtr config,
 
virDomainXMLPrivateDataCallbacksPtr priv,
 virDomainXMLNamespacePtr xmlns,
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index f7ccae0..8b0ca46 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -699,6 +699,13 @@ get_definition(vahControl * ctl, const char *xmlStr)
 goto exit;
 }
 
+if (virtType == VIR_DOMAIN_VIRT_QEMU || virtType == VIR_DOMAIN_VIRT_KVM) {
+ctl->xmlopt->config.features = VIR_DOMAIN_DEF_FEATURE_MEMORY_HOTPLUG |
+   VIR_DOMAIN_DEF_FEATURE_OFFLINE_VCPUPIN |
+   VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS 
|
+   VIR_DOMAIN_DEF_FEATURE_USER_ALIAS;
+}
+
 if (virCapabilitiesAddGuestDomain(guest,
   virtType,
   NULL,

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


[libvirt] [PATCH v2 2/2] qemu: Add support for pseries machine's max-cpu-compat= parameter

2018-01-05 Thread Shivaprasad G Bhat
When the -machine pseries,max-cpu-compat=X is supported use
machine parameter instead of -cpu host,compat=X parameter as
that is deprecated now with qemu > v2.10.

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

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_command.c|   11 ++
 .../pseries-machine-max-cpu-compat.args|   21 
 .../pseries-machine-max-cpu-compat.xml |   17 
 tests/qemuxml2argvtest.c   |5 +
 4 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args
 create mode 100644 tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4d0c141..1051a5c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6923,8 +6923,10 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
 case VIR_CPU_MODE_HOST_MODEL:
 if (ARCH_IS_PPC64(def->os.arch)) {
 virBufferAddLit(buf, "host");
-if (cpu->model)
+if (cpu->model &&
+!(qemuDomainIsPSeries(def) && virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT))) {
 virBufferAsprintf(buf, ",compat=%s", cpu->model);
+}
 } else {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected host-model CPU for %s architecture"),
@@ -7414,6 +7416,7 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
 } else {
 virTristateSwitch vmport = def->features[VIR_DOMAIN_FEATURE_VMPORT];
 virTristateSwitch smm = def->features[VIR_DOMAIN_FEATURE_SMM];
+virCPUDefPtr cpu = def->cpu;
 
 virCommandAddArg(cmd, "-machine");
 virBufferAdd(, def->os.machine, -1);
@@ -7588,6 +7591,12 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
 virBufferAsprintf(, ",resize-hpt=%s", str);
 }
 
+if (qemuDomainIsPSeries(def) && cpu && cpu->model &&
+cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
+virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT)) {
+virBufferAsprintf(, ",max-cpu-compat=%s", cpu->model);
+}
+
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
 virQEMUCapsGet(qemuCaps, QEMU_CAPS_LOADPARM))
 qemuAppendLoadparmMachineParm(, def);
diff --git a/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args 
b/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args
new file mode 100644
index 000..2796d23
--- /dev/null
+++ b/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args
@@ -0,0 +1,21 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-ppc64 \
+-name QEMUGuest1 \
+-S \
+-machine pseries,accel=kvm,max-cpu-compat=power7 \
+-cpu host \
+-m 256 \
+-smp 4,sockets=4,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefconfig \
+-nodefaults \
+-chardev 
socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline \
+-boot c
diff --git a/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml 
b/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml
new file mode 100644
index 000..19668c7
--- /dev/null
+++ b/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml
@@ -0,0 +1,17 @@
+
+  QEMUGuest1
+  c7a5fdbd-edaf-9455-926a-d65c16db1809
+  219100
+  4
+  
+hvm
+  
+  
+power7
+  
+  
+  /usr/bin/qemu-system-ppc64
+  
+  
+  
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index fe15072..be32d89 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1816,6 +1816,11 @@ mymain(void)
 DO_TEST("pseries-cpu-compat", QEMU_CAPS_KVM,
 QEMU_CAPS_DEVICE_SPAPR_VTY,
 QEMU_CAPS_NODEFCONFIG);
+DO_TEST("pseries-machine-max-cpu-compat",
+QEMU_CAPS_KVM,
+QEMU_CAPS_MACHINE_OPT,
+QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT,
+QEMU_CAPS_NODEFCONFIG);
 DO_TEST("pseries-cpu-le", QEMU_CAPS_KVM,
 QEMU_CAPS_DEVICE_SPAPR_VTY,
 QEMU_CAPS_NODEFCONFIG);

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


[libvirt] [PATCH v2 1/2] qemu: Add capability for pseries machine's max-cpu-compat= parameter

2018-01-05 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_capabilities.c |7 +++
 src/qemu/qemu_capabilities.h |1 +
 tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml |1 +
 3 files changed, 9 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 9673ef8..5a554df 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -456,6 +456,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
 
   /* 280 */
   "pl011",
+  "machine.pseries.max-cpu-compat",
 );
 
 
@@ -4836,6 +4837,12 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 if (qemuCaps->version >= 201)
 virQEMUCapsSet(qemuCaps, QEMU_CAPS_NUMA_DIST);
 
+/* no way to query max-cpu-compat */
+if (qemuCaps->version >= 201 &&
+ARCH_IS_PPC64(qemuCaps->arch)) {
+virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT);
+}
+
 if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
 goto cleanup;
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index e73dbaa..f0690af 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -442,6 +442,7 @@ typedef enum {
 
 /* 280 */
 QEMU_CAPS_DEVICE_PL011, /* -device pl011 (not user-instantiable) */
+QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT, /* -machine 
pseries,max-cpu-compat= */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml 
b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
index ca55e11..37fed23 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
@@ -183,6 +183,7 @@
   
   
   
+  
   201
   0
(v2.10.0)

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


[libvirt] [PATCH v2 0/2] Enable pseries machine's max-cpu-compat parameter

2018-01-05 Thread Shivaprasad G Bhat
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1519146
---

Shivaprasad G Bhat (2):
  qemu: Add capability for pseries machine's max-cpu-compat= parameter
  qemu: Add support for pseries machine's max-cpu-compat= parameter


 src/qemu/qemu_capabilities.c   |7 +++
 src/qemu/qemu_capabilities.h   |1 +
 src/qemu/qemu_command.c|   11 ++
 tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml   |1 +
 .../pseries-machine-max-cpu-compat.args|   21 
 .../pseries-machine-max-cpu-compat.xml |   17 
 tests/qemuxml2argvtest.c   |5 +
 7 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args
 create mode 100644 tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml

--
Signature

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


[libvirt] [PATCH 2/2] qemu: Add support for pseries machine's max-cpu-compat= parameter

2018-01-04 Thread Shivaprasad G Bhat
When the -machine pseries,max-cpu-compat=X is supported use
machine parameter instead of -cpu host,compat=X parameter as
that is deprecated now with qemu > v2.10.

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

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_command.c|   14 ++--
 .../pseries-machine-max-cpu-compat.args|   23 
 .../pseries-machine-max-cpu-compat.xml |   21 ++
 tests/qemuxml2argvtest.c   |5 
 4 files changed, 60 insertions(+), 3 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args
 create mode 100644 tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4d0c141..966ad75 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6922,9 +6922,12 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
 
 case VIR_CPU_MODE_HOST_MODEL:
 if (ARCH_IS_PPC64(def->os.arch)) {
-virBufferAddLit(buf, "host");
-if (cpu->model)
-virBufferAsprintf(buf, ",compat=%s", cpu->model);
+if (!virQEMUCapsGet(qemuCaps,
+QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT)) {
+virBufferAddLit(buf, "host");
+if (cpu->model)
+virBufferAsprintf(buf, ",compat=%s", cpu->model);
+}
 } else {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected host-model CPU for %s architecture"),
@@ -7414,6 +7417,7 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
 } else {
 virTristateSwitch vmport = def->features[VIR_DOMAIN_FEATURE_VMPORT];
 virTristateSwitch smm = def->features[VIR_DOMAIN_FEATURE_SMM];
+virCPUDefPtr cpu = def->cpu;
 
 virCommandAddArg(cmd, "-machine");
 virBufferAdd(, def->os.machine, -1);
@@ -7588,6 +7592,10 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
 virBufferAsprintf(, ",resize-hpt=%s", str);
 }
 
+if (cpu && cpu->model && cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
+virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT))
+virBufferAsprintf(, ",max-cpu-compat=%s", cpu->model);
+
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
 virQEMUCapsGet(qemuCaps, QEMU_CAPS_LOADPARM))
 qemuAppendLoadparmMachineParm(, def);
diff --git a/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args 
b/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args
new file mode 100644
index 000..f53db85
--- /dev/null
+++ b/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args
@@ -0,0 +1,23 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-ppc64 \
+-name QEMUGuest1 \
+-S \
+-machine pseries,accel=kvm,max-cpu-compat=power7 \
+-m 256 \
+-smp 4,sockets=4,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefconfig \
+-nodefaults \
+-chardev 
socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline \
+-boot c \
+-usb \
+-chardev pty,id=charserial0 \
+-device spapr-vty,chardev=charserial0,id=serial0,reg=0x3000
diff --git a/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml 
b/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml
new file mode 100644
index 000..f6c9516
--- /dev/null
+++ b/tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml
@@ -0,0 +1,21 @@
+
+  QEMUGuest1
+  c7a5fdbd-edaf-9455-926a-d65c16db1809
+  219100
+  219100
+  4
+  
+hvm
+  
+  
+power7
+  
+  
+  
+  /usr/bin/qemu-system-ppc64
+  
+
+  
+  
+  
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index fe15072..e5699ea 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1816,6 +1816,11 @@ mymain(void)
 DO_TEST("pseries-cpu-compat", QEMU_CAPS_KVM,
 QEMU_CAPS_DEVICE_SPAPR_VTY,
 QEMU_CAPS_NODEFCONFIG);
+DO_TEST("pseries-machine-max-cpu-compat", QEMU_CAPS_KVM,
+QEMU_CAPS_MACHINE_OPT,
+QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT,
+QEMU_CAPS_DEVICE_SPAPR_VTY,
+QEMU_CAPS_NODEFCONFIG);
 DO_TEST("pseries-cpu-le", QEMU_CAPS_KVM,
 QEMU_CAPS_DEVICE_SPAPR_VTY,
 QEMU_CAPS_NODEFCONFIG);

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


[libvirt] [PATCH 1/2] qemu: Add capability for pseries machine's max-cpu-compat= parameter

2018-01-04 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_capabilities.c |7 +++
 src/qemu/qemu_capabilities.h |2 ++
 tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml |1 +
 3 files changed, 10 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 9673ef8..fdc8b37 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -456,6 +456,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
 
   /* 280 */
   "pl011",
+  "machine.pseries.max-cpu-compat",
 );
 
 
@@ -4836,6 +4837,12 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 if (qemuCaps->version >= 201)
 virQEMUCapsSet(qemuCaps, QEMU_CAPS_NUMA_DIST);
 
+/* no way to query max-cpu-comapt */
+if (qemuCaps->version >= 201 &&
+ARCH_IS_PPC64(qemuCaps->arch)) {
+virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT);
+}
+
 if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
 goto cleanup;
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index e73dbaa..f041324 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -442,6 +442,8 @@ typedef enum {
 
 /* 280 */
 QEMU_CAPS_DEVICE_PL011, /* -device pl011 (not user-instantiable) */
+QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT, /* -machine
+   *  pseries,max-cpu-compat=xxx */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml 
b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
index ca55e11..37fed23 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
@@ -183,6 +183,7 @@
   
   
   
+  
   201
   0
(v2.10.0)

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


[libvirt] [PATCH 0/2] Enable pseries machine's max-cpu-compat parameter

2018-01-04 Thread Shivaprasad G Bhat
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1519146

---

Shivaprasad G Bhat (2):
  qemu: Add capability for pseries machine's max-cpu-compat= parameter
  qemu: Add support for pseries machine's max-cpu-compat= parameter


 src/qemu/qemu_capabilities.c   |7 ++
 src/qemu/qemu_capabilities.h   |2 ++
 src/qemu/qemu_command.c|   14 ++--
 tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml   |1 +
 .../pseries-machine-max-cpu-compat.args|   23 
 .../pseries-machine-max-cpu-compat.xml |   21 ++
 tests/qemuxml2argvtest.c   |5 
 7 files changed, 70 insertions(+), 3 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.args
 create mode 100644 tests/qemuxml2argvdata/pseries-machine-max-cpu-compat.xml

--
Signature

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


[libvirt] [PATCH] qemu_capabilities: Fix the formatting with a space

2017-07-23 Thread Shivaprasad G Bhat
It was observed while adding new property that there should be a space
before closing a curly brace in intel-iommu object property definition.
Fixing it as a separate patch.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_capabilities.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 5fb6fd4..3f2c089 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1908,7 +1908,7 @@ static struct virQEMUCapsObjectTypeProps 
virQEMUCapsObjectProps[] = {
   -1 },
 { "intel-iommu", virQEMUCapsObjectPropsIntelIOMMU,
   ARRAY_CARDINALITY(virQEMUCapsObjectPropsIntelIOMMU),
-  QEMU_CAPS_DEVICE_INTEL_IOMMU},
+  QEMU_CAPS_DEVICE_INTEL_IOMMU },
 { "spapr-pci-host-bridge", virQEMUCapsObjectPropsSpaprPCIHostBridge,
   ARRAY_CARDINALITY(virQEMUCapsObjectPropsSpaprPCIHostBridge),
   QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE },

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


Re: [libvirt] [PATCH v2 2/3] qemu: capabilitity: Introduce QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE

2017-07-21 Thread Shivaprasad G Bhat



On 07/19/2017 07:08 PM, Andrea Bolognani wrote:

On Mon, 2017-07-17 at 21:28 +0530, Shivaprasad G Bhat wrote:
[...]

@@ -1900,6 +1905,9 @@ static struct virQEMUCapsObjectTypeProps 
virQEMUCapsObjectProps[] = {
   { "intel-iommu", virQEMUCapsObjectPropsIntelIOMMU,
 ARRAY_CARDINALITY(virQEMUCapsObjectPropsIntelIOMMU),
 QEMU_CAPS_DEVICE_INTEL_IOMMU},
+{ "spapr-pci-host-bridge", virQEMUCapsObjectPropsSpaprPCIHostBridge,
+  ARRAY_CARDINALITY(virQEMUCapsObjectPropsSpaprPCIHostBridge),
+  QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE},

There should be a space before the closing curly brace.

Thanks.. I was just following the previous pattern at  " 
QEMU_CAPS_DEVICE_INTEL_IOMMU},"


Will fix that along. :)


Reviewed-by: Andrea Bolognani <abolo...@redhat.com>

--
Andrea Bolognani / Red Hat / Virtualization



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


Re: [libvirt] [PATCH v2 3/3] qemu: Enable NUMA node tag in pci-root for PPC64

2017-07-21 Thread Shivaprasad G Bhat

Hi Andrea,


On 07/20/2017 09:16 PM, Andrea Bolognani wrote:

On Mon, 2017-07-17 at 21:29 +0530, Shivaprasad G Bhat wrote:

@@ -3786,6 +3786,11 @@
   part of the specified NUMA node (it is up to the user of the
   libvirt API to attach host devices to the correct
   pci-expander-bus when assigning them to the domain).
+On PPC64, the PCI devices can be specified to be part of a NUMA
+node using only the pci-root controller with an optional
+node subelement within the
+target subelement. The PCI devices on the
+given pci-root controller will be part of the specified NUMA node.

Instead of adding an entire new sentence here, it would make
more sense to rephrase what's already present, something like:

   Some PCI controllers (pci-expander-bus for the pc machine
   type, pcie-expander-bus for the q35 machine type and
   pci-root for the pseries machine type) can have an optional
subelement [...]

@@ -9457,6 +9457,12 @@ virDomainControllerDefParseXML(xmlNodePtr node,
   goto error;
   }
   }
+if (def->idx == 0 && numaNode >= 0) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Only the PCI controller with index != 0 can "
+ "have NUMA node property specified"));
+goto error;
+}
   if (numaNode >= 0)
   def->opts.pciopts.numaNode = numaNode;

The check you're adding can be merged with the one below it.

The error message should also be reworded, something like:

   The PCI controller with index=0 can't be associated with
   a NUMA node.

@@ -3458,9 +3458,14 @@ 
qemuDomainControllerDefPostParse(virDomainControllerDefPtr cont,
* that NUMA node is configured in the guest 
* array. NUMA cell id's in this array are numbered
* from 0 .. size-1.
+ *
+ * On PSeries, the NUMA node is set at the PHB.

As above, reworking the existing comment would work better
than merely appending to it.


*/
-if ((cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS ||
- cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS) &&
+if (((qemuDomainIsPSeries(def) &&
+  cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
+  cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) ||
+ (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS ||
+  cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS)) &&
   (int) virDomainNumaGetNodeCount(def->numa)
   <= cont->opts.pciopts.numaNode) {

I actually don't see any point in the condition being this
complex: it could just be

   if (cont->opts.pciopts.numaNode >= 0 &&
   cont->opts.pciopts.numaNode >=
   (int) virDomainNumaGetNodeCount(def->numa))

because we've already made sure, while parsing, that numaNode
is only set for controllers that allow it.


+++ b/tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-host-bridge-numa-node.xml
@@ -0,0 +1,54 @@
+
+  QEMUGuest1
+  87eedafe-eedc-4336-8130-ed9fe5dc90c8
+  2097152
+  2048

You don't need 


+  8
+  
+
+  
+  
+
+
+  
+  
+
+  
+  
+hvm
+

 is unnecessary.


+  
+  
+  destroy
+  restart
+  destroy

 and <on_*> can be removed.


+  
+/usr/bin/qemu-system-ppc64
+
+  
+  
+  
+  
+

 is irrelevant for the test case at hand.


+

The model should be 'none'.


+

The SCSI controller is also not useful here.


+
+  
+
+
+  
+1
+  
+
+
+  
+
+
+  
+0
+  
+
+
+

You can omit .


+++ b/tests/qemuxml2argvtest.c
@@ -2739,6 +2739,9 @@ mymain(void)
   DO_TEST_PARSE_ERROR("cpu-cache-emulate-l2", QEMU_CAPS_KVM);
   DO_TEST_PARSE_ERROR("cpu-cache-passthrough3", QEMU_CAPS_KVM);
   DO_TEST_PARSE_ERROR("cpu-cache-passthrough-l3", QEMU_CAPS_KVM);
+DO_TEST("spapr-pci-host-bridge-numa-node", QEMU_CAPS_NUMA,
+QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE);

This should be moved up to be close to the pserie-phb* test
cases, and renamed to something like 'pseries-phb-numa-node'.

There should be one capability per line.

You also need to have an identical test case in qemuxml2xml,
and at least one negative test to show that trying to
assign the default PHB to a NUMA node will result in failure.

Agree to all your comments. Fixing them all.

As I relook at my test case, I realize the numatune should be for the 
memnode
instead of memory for this use case. Fixing that as well. For 
pci-expander-bus

test cases I see no numatune in the xml, will fix them later.



--
Andrea Bolognani / Red Hat / Virtualization



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


[libvirt] [PATCH v3 3/3] qemu: Enable NUMA node tag in pci-root for PPC64

2017-07-21 Thread Shivaprasad G Bhat
This patch addresses the same aspects on PPC the bug 1103314 addressed
on x86.

PCI expander bus creates multiple primary PCI busses, where each of these
busses can be assigned a specific NUMA affinity, which, on x86 is
advertised through ACPI on a per-bus basis.

For SPAPR, a PHB's NUMA affinities are assigned on a per-PHB basis, and
there is no mechanism for advertising NUMA affinities to a guest on a
per-bus basis. So, even if qemu-ppc manages to get some sort of multi-bus
topology working using PXB, there is no way to expose the affinities
of these busses to the guest. It can only be exposed on a per-PHB/per-domain
basis.

So patch enables NUMA node tag in pci-root controller on PPC.

The way to set the NUMA node is through the numa_node option of
spapr-pci-host-bridge device. However for the implicit PHB, the only way
to set the numa_node is from the -global option. The -global option applies
to all the PHBs unless explicitly specified with the option on the
respective PHB of CLI. The default PHB has the emulated devices only, so
the patch prevents setting the NUMA node for the default PHB.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 docs/formatdomain.html.in  |4 +-
 src/conf/domain_conf.c |9 +++
 src/qemu/qemu_command.c|   10 
 src/qemu/qemu_domain.c |   13 ++---
 .../qemuxml2argv-pseries-default-phb-numa-node.xml |   29 +++
 .../qemuxml2argv-pseries-phb-numa-node.args|   28 +++
 .../qemuxml2argv-pseries-phb-numa-node.xml |   41 
 tests/qemuxml2argvtest.c   |6 ++
 .../qemuxml2xmlout-pseries-phb-numa-node.xml   |   52 
 tests/qemuxml2xmltest.c|4 ++
 10 files changed, 187 insertions(+), 9 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-pseries-default-phb-numa-node.xml
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-pseries-phb-numa-node.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-pseries-phb-numa-node.xml
 create mode 100644 
tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-phb-numa-node.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c12efcf..04f31aa 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3778,7 +3778,9 @@
   
   node
   
-pci-expander-bus controllers can have an
+Some PCI controllers (pci-expander-bus for the pc machine
+type, pcie-expander-bus for the q35 machine type and
+pci-root for the pseries machine type) can have an
 optional node subelement within
 the target subelement, which is used to
 set the NUMA node reported to the guest OS for that bus - the
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3feeccb..8c4133c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9457,8 +9457,15 @@ virDomainControllerDefParseXML(xmlNodePtr node,
 goto error;
 }
 }
-if (numaNode >= 0)
+if (numaNode >= 0) {
 def->opts.pciopts.numaNode = numaNode;
+if (def->idx == 0) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("The PCI controller with index=0 can't "
+ "be associated with a NUMA node."));
+goto error;
+}
+}
 break;
 
 default:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6ac26af..83b277b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3038,6 +3038,16 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
 virBufferAsprintf(, "%s,index=%d,id=%s",
   modelName, def->opts.pciopts.targetIndex,
   def->info.alias);
+
+if (def->opts.pciopts.numaNode != -1) {
+if (!virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("the spapr-pci-host-bridge controller "
+ "doesn't support numa_node on this QEMU 
binary"));
+goto error;
+}
+virBufferAsprintf(, ",numa_node=%d", 
def->opts.pciopts.numaNode);
+}
 break;
 case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
 case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 464d3a1..8609e6c 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3454,15 +3454,14 @@ 
qemuDomainControllerDefPostParse(virDomainControllerDefP

[libvirt] [PATCH v3 2/3] qemu: capabilitity: Introduce QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE

2017-07-21 Thread Shivaprasad G Bhat
The patch adds a capability for spapr-pci-host-bridge.numa_node.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
Reviewed-by: Andrea Bolognani <abolo...@redhat.com>
---
 src/qemu/qemu_capabilities.c   |   10 ++
 src/qemu/qemu_capabilities.h   |1 
 .../caps_2.6.0.ppc64le.replies |   60 +++-
 .../caps_2.9.0.ppc64le.replies |  100 +++-
 tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml  |1 
 5 files changed, 157 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 04aa8d5..a43bc46 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -431,6 +431,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
   "virtio.ats",
   "loadparm",
   "spapr-pci-host-bridge",
+  "spapr-pci-host-bridge.numa_node",
 );
 
 
@@ -1700,6 +1701,10 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsObjectPropsVirtioNet[] = {
 { "host_mtu", QEMU_CAPS_VIRTIO_NET_HOST_MTU },
 };
 
+static struct virQEMUCapsStringFlags 
virQEMUCapsObjectPropsSpaprPCIHostBridge[] = {
+{ "numa_node", QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE },
+};
+
 static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioSCSI[] = {
 { "iothread", QEMU_CAPS_VIRTIO_SCSI_IOTHREAD },
 };
@@ -1899,7 +1904,10 @@ static struct virQEMUCapsObjectTypeProps 
virQEMUCapsObjectProps[] = {
   -1 },
 { "intel-iommu", virQEMUCapsObjectPropsIntelIOMMU,
   ARRAY_CARDINALITY(virQEMUCapsObjectPropsIntelIOMMU),
-  QEMU_CAPS_DEVICE_INTEL_IOMMU},
+  QEMU_CAPS_DEVICE_INTEL_IOMMU },
+{ "spapr-pci-host-bridge", virQEMUCapsObjectPropsSpaprPCIHostBridge,
+  ARRAY_CARDINALITY(virQEMUCapsObjectPropsSpaprPCIHostBridge),
+  QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE },
 };
 
 struct virQEMUCapsPropTypeObjects {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 8250b57..65bc350 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -417,6 +417,7 @@ typedef enum {
 QEMU_CAPS_VIRTIO_PCI_ATS, /* virtio-*-pci.ats */
 QEMU_CAPS_LOADPARM, /* -machine loadparm */
 QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, /* -device spapr-pci-host-bridge */
+QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, /* 
spapr-pci-host-bridge.numa_node= */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.replies 
b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.replies
index 6350269..2e4fa72 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.replies
+++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.replies
@@ -3812,6 +3812,52 @@
 {
   "return": [
 {
+  "name": "dynamic-reconfiguration",
+  "type": "bool"
+},
+{
+  "name": "dma_win_size",
+  "type": "uint64"
+},
+{
+  "name": "dma_win_addr",
+  "type": "uint64"
+},
+{
+  "name": "io_win_size",
+  "type": "uint64"
+},
+{
+  "name": "mem_win_size",
+  "type": "uint64"
+},
+{
+  "name": "buid",
+  "type": "uint64"
+},
+{
+  "name": "io_win_addr",
+  "type": "uint64"
+},
+{
+  "name": "liobn",
+  "type": "uint32"
+},
+{
+  "name": "mem_win_addr",
+  "type": "uint64"
+},
+{
+  "name": "index",
+  "type": "uint32"
+}
+  ],
+  "id": "libvirt-41"
+}
+
+{
+  "return": [
+{
   "name": "ref405ep",
   "cpu-max": 1
 },
@@ -3878,7 +3924,7 @@
   "cpu-max": 255
 }
   ],
-  "id": "libvirt-41"
+  "id": "libvirt-42"
 }
 
 {
@@ -5180,19 +5226,19 @@
   "name": "MPC8541E_v11"
 }
   ],
-  "id": "libvirt-42"
+  "id": "libvirt-43"
 }
 
 {
   "return": [
   ],
-  "id": "libvirt-43"
+  "id": "libvirt-44"
 }
 
 {
   "return": [
   ],
-  "id": "libvirt-44"
+  "id": "libvirt-45"
 }
 
 {
@@ -6159,7 +6205,7 @@
   "option": "drive"
 }
   ],
-  "id": "libvirt-45"
+  "id": "libvirt-46"
 }
 
 {
@@ -6193,7 +6239,7 @@
   "capabili

[libvirt] [PATCH v2 3/3] qemu: Enable NUMA node tag in pci-root for PPC64

2017-07-17 Thread Shivaprasad G Bhat
This patch addresses the same aspects on PPC the bug 1103314 addressed
on x86.

PCI expander bus creates multiple primary PCI busses, where each of these
busses can be assigned a specific NUMA affinity, which, on x86 is
advertised through ACPI on a per-bus basis.

For SPAPR, a PHB's NUMA affinities are assigned on a per-PHB basis, and
there is no mechanism for advertising NUMA affinities to a guest on a
per-bus basis. So, even if qemu-ppc manages to get some sort of multi-bus
topology working using PXB, there is no way to expose the affinities
of these busses to the guest. It can only be exposed on a per-PHB/per-domain
basis.

So patch enables NUMA node tag in pci-root controller on PPC.

The way to set the NUMA node is through the numa_node option of
spapr-pci-host-bridge device. However for the implicit PHB, the only way
to set the numa_node is from the -global option. The -global option applies
to all the PHBs unless explicitly specified with the option on the
respective PHB of CLI. The default PHB has the emulated devices only, so
the patch prevents setting the NUMA node for the default PHB.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 docs/formatdomain.html.in  |5 ++
 src/conf/domain_conf.c |6 ++
 src/qemu/qemu_command.c|   10 
 src/qemu/qemu_domain.c |9 +++
 ...muxml2argv-spapr-pci-host-bridge-numa-node.args |   29 +++
 ...emuxml2argv-spapr-pci-host-bridge-numa-node.xml |   54 
 tests/qemuxml2argvtest.c   |3 +
 7 files changed, 114 insertions(+), 2 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-host-bridge-numa-node.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-host-bridge-numa-node.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c12efcf..64fe241 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3786,6 +3786,11 @@
 part of the specified NUMA node (it is up to the user of the
 libvirt API to attach host devices to the correct
 pci-expander-bus when assigning them to the domain).
+On PPC64, the PCI devices can be specified to be part of a NUMA
+node using only the pci-root controller with an optional
+node subelement within the
+target subelement. The PCI devices on the
+given pci-root controller will be part of the specified NUMA node.
   
   index
   
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3feeccb..b8cdcd1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9457,6 +9457,12 @@ virDomainControllerDefParseXML(xmlNodePtr node,
 goto error;
 }
 }
+if (def->idx == 0 && numaNode >= 0) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("Only the PCI controller with index != 0 can "
+ "have NUMA node property specified"));
+goto error;
+}
 if (numaNode >= 0)
 def->opts.pciopts.numaNode = numaNode;
 break;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6ac26af..83b277b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3038,6 +3038,16 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
 virBufferAsprintf(, "%s,index=%d,id=%s",
   modelName, def->opts.pciopts.targetIndex,
   def->info.alias);
+
+if (def->opts.pciopts.numaNode != -1) {
+if (!virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("the spapr-pci-host-bridge controller "
+ "doesn't support numa_node on this QEMU 
binary"));
+goto error;
+}
+virBufferAsprintf(, ",numa_node=%d", 
def->opts.pciopts.numaNode);
+}
 break;
 case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
 case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 464d3a1..7732fa1 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3458,9 +3458,14 @@ 
qemuDomainControllerDefPostParse(virDomainControllerDefPtr cont,
  * that NUMA node is configured in the guest 
  * array. NUMA cell id's in this array are numbered
  * from 0 .. size-1.
+ *
+ * On PSeries, the NUMA node is set at the PHB.
  */
-if ((cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS

[libvirt] [PATCH v2 2/3] qemu: capabilitity: Introduce QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE

2017-07-17 Thread Shivaprasad G Bhat
The patch adds a capability for spapr-pci-host-bridge.numa_node.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_capabilities.c   |8 ++
 src/qemu/qemu_capabilities.h   |1 
 .../caps_2.6.0.ppc64le.replies |   60 +++-
 .../caps_2.9.0.ppc64le.replies |  100 +++-
 tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml  |1 
 5 files changed, 156 insertions(+), 14 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 04aa8d5..b158e75 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -431,6 +431,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
   "virtio.ats",
   "loadparm",
   "spapr-pci-host-bridge",
+  "spapr-pci-host-bridge.numa_node",
 );
 
 
@@ -1700,6 +1701,10 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsObjectPropsVirtioNet[] = {
 { "host_mtu", QEMU_CAPS_VIRTIO_NET_HOST_MTU },
 };
 
+static struct virQEMUCapsStringFlags 
virQEMUCapsObjectPropsSpaprPCIHostBridge[] = {
+{ "numa_node", QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE },
+};
+
 static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioSCSI[] = {
 { "iothread", QEMU_CAPS_VIRTIO_SCSI_IOTHREAD },
 };
@@ -1900,6 +1905,9 @@ static struct virQEMUCapsObjectTypeProps 
virQEMUCapsObjectProps[] = {
 { "intel-iommu", virQEMUCapsObjectPropsIntelIOMMU,
   ARRAY_CARDINALITY(virQEMUCapsObjectPropsIntelIOMMU),
   QEMU_CAPS_DEVICE_INTEL_IOMMU},
+{ "spapr-pci-host-bridge", virQEMUCapsObjectPropsSpaprPCIHostBridge,
+  ARRAY_CARDINALITY(virQEMUCapsObjectPropsSpaprPCIHostBridge),
+  QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE},
 };
 
 struct virQEMUCapsPropTypeObjects {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 8250b57..65bc350 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -417,6 +417,7 @@ typedef enum {
 QEMU_CAPS_VIRTIO_PCI_ATS, /* virtio-*-pci.ats */
 QEMU_CAPS_LOADPARM, /* -machine loadparm */
 QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, /* -device spapr-pci-host-bridge */
+QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, /* 
spapr-pci-host-bridge.numa_node= */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.replies 
b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.replies
index 6350269..2e4fa72 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.replies
+++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.replies
@@ -3812,6 +3812,52 @@
 {
   "return": [
 {
+  "name": "dynamic-reconfiguration",
+  "type": "bool"
+},
+{
+  "name": "dma_win_size",
+  "type": "uint64"
+},
+{
+  "name": "dma_win_addr",
+  "type": "uint64"
+},
+{
+  "name": "io_win_size",
+  "type": "uint64"
+},
+{
+  "name": "mem_win_size",
+  "type": "uint64"
+},
+{
+  "name": "buid",
+  "type": "uint64"
+},
+{
+  "name": "io_win_addr",
+  "type": "uint64"
+},
+{
+  "name": "liobn",
+  "type": "uint32"
+},
+{
+  "name": "mem_win_addr",
+  "type": "uint64"
+},
+{
+  "name": "index",
+  "type": "uint32"
+}
+  ],
+  "id": "libvirt-41"
+}
+
+{
+  "return": [
+{
   "name": "ref405ep",
   "cpu-max": 1
 },
@@ -3878,7 +3924,7 @@
   "cpu-max": 255
 }
   ],
-  "id": "libvirt-41"
+  "id": "libvirt-42"
 }
 
 {
@@ -5180,19 +5226,19 @@
   "name": "MPC8541E_v11"
 }
   ],
-  "id": "libvirt-42"
+  "id": "libvirt-43"
 }
 
 {
   "return": [
   ],
-  "id": "libvirt-43"
+  "id": "libvirt-44"
 }
 
 {
   "return": [
   ],
-  "id": "libvirt-44"
+  "id": "libvirt-45"
 }
 
 {
@@ -6159,7 +6205,7 @@
   "option": "drive"
 }
   ],
-  "id": "libvirt-45"
+  "id": "libvirt-46"
 }
 
 {
@@ -6193,7 +6239,7 @@
   "capability": "postcopy-ram"
 }
   ],
-  "id": "libvirt-46"
+  "id": "

[libvirt] [PATCH v2 0/3] qemu: Enable NUMA node tag in pci-root for PPC64

2017-07-17 Thread Shivaprasad G Bhat
This series addresses the same aspects on PPC the bug 1103314 addressed
on x86. It sets the target numa node in the pci-root instead of
using the pci-expander-bus.

The patch 2 & 3 were sent earlier and was suggested to wait for the multi-phb
support. Here, 
https://www.redhat.com/archives/libvir-list/2016-November/msg00403.html

Now that multi-phb support is in, this version takes the multi-phb scenarios
into account. Specifying NUMA node for the default PHB is prevented and let
me know if that should be allowed. Patch 3 has more details. 

Relavent discussion :
https://www.redhat.com/archives/libvir-list/2017-July/msg00383.html

---

Shivaprasad G Bhat (3):
  Add capabilities for qemu-2.9.0 ppc64
  qemu: capabilitity: Introduce QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE
  qemu: Enable NUMA node tag in pci-root for PPC64


 docs/formatdomain.html.in  |5 
 src/conf/domain_conf.c |6 
 src/qemu/qemu_capabilities.c   |8 
 src/qemu/qemu_capabilities.h   |1 
 src/qemu/qemu_command.c|   10 
 src/qemu/qemu_domain.c |9 
 .../caps_2.6.0.ppc64le.replies |   60 
 .../caps_2.9.0.ppc64le.replies |19274 
 tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml  | 1063 +
 tests/qemucapabilitiestest.c   |1 
 ...muxml2argv-spapr-pci-host-bridge-numa-node.args |   29 
 ...emuxml2argv-spapr-pci-host-bridge-numa-node.xml |   54 
 tests/qemuxml2argvtest.c   |3 
 13 files changed, 20514 insertions(+), 9 deletions(-)
 create mode 100644 tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.replies
 create mode 100644 tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-host-bridge-numa-node.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-host-bridge-numa-node.xml

--
Signature

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


Re: [libvirt] [PATCH] spapr: make default PHB optionnal

2017-07-12 Thread Shivaprasad G Bhat



On 07/12/2017 04:25 PM, Andrea Bolognani wrote:

[libvir-list added to the loop]

On Tue, 2017-07-04 at 10:47 +0200, Greg Kurz wrote:

On Tue, 4 Jul 2017 17:29:01 +1000 David Gibson  
wrote:

On Mon, Jul 03, 2017 at 06:48:25PM +0200, Greg Kurz wrote:
  
The sPAPR machine always create a default PHB during initialization, even

if -nodefaults was passed on the command line. This forces the user to
rely on -global if she wants to set properties of the default PHB, such
as numa_node.
  
This patch introduces a new machine create-default-phb property to control

whether the default PHB must be created or not. It defaults to on in order
to preserve old setups (which is also the motivation to not alter the
current behavior of -nodefaults).
  
If create-default-phb is set to off, the default PHB isn't created, nor

any other device usually created with it. It is mandatory to provide
a PHB on the command line to be able to use PCI devices (otherwise QEMU
won't start). For example, the following creates a PHB with the same
mappings as the default PHB and also sets the NUMA affinity:
  
  -machine type=pseries,create-default-phb=off \

  -numa node,nodeid=0 -device spapr-pci-host-bridge,index=0,numa_node=0
  
So, I agree that the distinction between default devices that are

disabled with -nodefaults and default devices that aren't is a big
mess in qemu configuration.  But on the other hand this only addresses
one tiny aspect of that, and in the meantime means we will silently
ignore some other configuration options in some conditions.
  
So, what's the immediate benefit / use case for this?


Setting numa_node for emulated devices is the benefit for now. On x86, I 
figured there is
no way to set the numa_node for the root controller and the emulated 
devices sitting there
all have numa_node set to -1. Only the devices on the pxb can have a 
sensible value specified.
Does it mean, the emulated devices/drivers don't care about the 
numa_node they are on?


Would it be fine on PPC to disallow setting the NUMA node for the 
default PHB because that is where

all the emulated devices sit ?

  
With the current code base, the only way to set properties of the default

PHB, is to pass -global spapr-pci-host-bridge.prop=value for each property.
The immediate benefit of this patch is to unify the way libvirt passes
PHB description to the command line:
  
ie, do:
  
  -machine type=pseries,create-default-phb=off \

  -device spapr-pci-host-bridge,prop1=a,prop2=b,prop3=c \
  -device spapr-pci-host-bridge,prop1=d,prop2=e,prop3=f
  
instead of:
  
  -machine type=pseries \

  -global spapr-pci-host-bridge.prop1=a \
  -global spapr-pci-host-bridge.prop2=b \
  -global spapr-pci-host-bridge.prop3=c \
  -device spapr-pci-host-bridge,prop1=d,prop2=e,prop3=f

So, I'm thinking about this mostly in terms of NUMA nodes
because that's the use case I'm aware of.

The problem with using -global is not that it requires using
a different syntax to set properties for the default PHB,
but rather that such properties are then inherited by all
other PHBs unless explicitly overridden. Not creating the
default PHB at all would solve the issue.

On the other hand, libvirt would then need to either

   1) only allow setting NUMA nodes for PHBs if QEMU supports
  the new option, leaving QEMU < 2.10 users behind; or

   2) implement handling for both the new and old behavior.

I'm not sure we could get away with 1), and going for 2)
means more work both for QEMU and libvirt developers for
very little actual gain, so I'd be inclined to scrap this
and just build the libvirt glue on top of the existing
interface.

That is, of course, unless

   1) having a random selection of PHBs not assigned to any
  NUMA node is a sensible use case. This is something
  we just can't do reliably with the current interface:
  we can decide to set the NUMA node only for say, PHBs
  1 and 3 leaving 0 and 2 alone, but once we set it for
  the default PHB we *have* to set it for all remaining
  ones as well. libvirt will by default assign emulated
  devices to the default PHB, so I would rather expect
  users to leave that one alone and set a NUMA node for
  all other PHBs; or

   2) there are other properties outside of numa_node we
  might want to deal with; or

   3) it turns out it's okay to require a recent QEMU :)

--
Andrea Bolognani / Red Hat / Virtualization



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


[libvirt] [PATCH] qemu: Take all PHBs into account while calculating memlock limits

2017-06-30 Thread Shivaprasad G Bhat
Now that the multi-phb support series is in, work on the TODO at
qemuDomainGetMemLockLimitBytes() to arrive at the correct memlock limit
value.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
This patch should be applied on top of Andrea's multi-phb support
patchset.

 src/qemu/qemu_domain.c  |   12 
 tests/qemumemlocktest.c |2 +-
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index a3ce10a..a8293b4 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -6674,12 +6674,16 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
 unsigned long long memory;
 unsigned long long baseLimit;
 unsigned long long passthroughLimit;
-size_t nPCIHostBridges;
+size_t nPCIHostBridges = 0;
 bool usesVFIO = false;
 
-/* TODO: Detect at runtime once we start using more than just
- *   the default PCI Host Bridge */
-nPCIHostBridges = 1;
+for (i = 0; i < def->ncontrollers; i++) {
+if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI ||
+def->controllers[i]->model != 
VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
+continue;
+}
+nPCIHostBridges++;
+}
 
 for (i = 0; i < def->nhostdevs; i++) {
 virDomainHostdevDefPtr dev = def->hostdevs[i];
diff --git a/tests/qemumemlocktest.c b/tests/qemumemlocktest.c
index c0f1dc3..268563d 100644
--- a/tests/qemumemlocktest.c
+++ b/tests/qemumemlocktest.c
@@ -131,7 +131,7 @@ mymain(void)
 
 DO_TEST("pseries-hardlimit", 2147483648);
 DO_TEST("pseries-locked", VIR_DOMAIN_MEMORY_PARAM_UNLIMITED);
-DO_TEST("pseries-hostdev", 2168455168);
+DO_TEST("pseries-hostdev", 4320133120);
 
 DO_TEST("pseries-hardlimit+locked", 2147483648);
 DO_TEST("pseries-hardlimit+hostdev", 2147483648);

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


[libvirt] [PATCH] qemu: hotplug: Release address properly when redirected device attach failure

2017-05-30 Thread Shivaprasad G Bhat
The virDomainUSBAddressEnsure returns 0 or -1 and checking for 1 is wrong.
Fix it.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 4a7d997..f339148 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1707,7 +1707,6 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
virDomainRedirdevDefPtr redirdev)
 {
 int ret = -1;
-int rc;
 qemuDomainObjPrivatePtr priv = vm->privateData;
 virDomainDefPtr def = vm->def;
 char *charAlias = NULL;
@@ -1724,10 +1723,9 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
 if (!(charAlias = qemuAliasChardevFromDevAlias(redirdev->info.alias)))
 goto cleanup;
 
-if ((rc = virDomainUSBAddressEnsure(priv->usbaddrs, >info)) < 0)
+if ((virDomainUSBAddressEnsure(priv->usbaddrs, >info)) < 0)
 goto cleanup;
-if (rc == 1)
-need_release = true;
+need_release = true;
 
 if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, priv->qemuCaps)))
 goto cleanup;

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


[libvirt] [PATCH] virpci: Enable GEN4 card Link speed (16GT/s)

2017-03-01 Thread Shivaprasad G Bhat
This enables GEN4 link speed (16GT/s) property to be fetched properly and thus
allows the detach/reattach/dumpxml to work.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
Verified on Mellanox MT27800 Family ConnectX-5 IB card.
# lspci -kvvvs 0001:01:00.4
0001:01:00.4 Infiniband controller: Mellanox Technologies MT27800 Family 
[ConnectX-5 Virtual Function]
Subsystem: IBM MT28800 Family [ConnectX-5 Virtual Function]
Control: I/O- Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- 
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- SERR- 
  pci_0001_01_00_4
  /sys/devices/pci0001:00/0001:00:00.0/0001:01:00.4
  pci_0001_00_00_0
  
vfio-pci
  
  
1
1
0
4
MT27800 Family [ConnectX-5 Virtual Function]
Mellanox Technologies

  


  



  
  

  

# virsh  nodedev-detach  pci_0001_01_00_4
error: Failed to detach device pci_0001_01_00_4
error: malformed 'speed' attribute: (null)

After Fix:
# ./run tools/virsh  nodedev-dumpxml  pci_0001_01_00_4

  pci_0001_01_00_4
  /sys/devices/pci0001:00/0001:00:00.0/0001:01:00.4
  pci_0001_00_00_0
  
mlx5_core
  
  
1
1
0
4
MT27800 Family [ConnectX-5 Virtual Function]
Mellanox Technologies

  


  



  
  

  


# ./run tools/virsh  nodedev-detach  pci_0001_01_00_4
Device pci_0001_01_00_4 detached
---
 src/util/virpci.c |4 ++--
 src/util/virpci.h |1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/util/virpci.c b/src/util/virpci.c
index 3c1e13b..1e0d903 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -53,7 +53,7 @@ VIR_LOG_INIT("util.pci");
 #define PCI_ADDR_LEN 13 /* ":XX:XX.X" */
 
 VIR_ENUM_IMPL(virPCIELinkSpeed, VIR_PCIE_LINK_SPEED_LAST,
-  "", "2.5", "5", "8")
+  "", "2.5", "5", "8", "16")
 
 VIR_ENUM_IMPL(virPCIStubDriver, VIR_PCI_STUB_DRIVER_LAST,
   "none",
@@ -147,7 +147,7 @@ struct _virPCIDeviceList {
 #define PCI_EXP_DEVCAP  0x4 /* Device capabilities */
 #define PCI_EXP_DEVCAP_FLR (1<<28)  /* Function Level Reset */
 #define PCI_EXP_LNKCAP  0xc /* Link Capabilities */
-#define PCI_EXP_LNKCAP_SPEED0xf /* Maximum Link Speed */
+#define PCI_EXP_LNKCAP_SPEED0x0001f /* Maximum Link Speed */
 #define PCI_EXP_LNKCAP_WIDTH0x003f0 /* Maximum Link Width */
 #define PCI_EXP_LNKSTA  0x12/* Link Status */
 #define PCI_EXP_LNKSTA_SPEED0x000f  /* Negotiated Link Speed */
diff --git a/src/util/virpci.h b/src/util/virpci.h
index a5e8d00..50e8b3c 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -58,6 +58,7 @@ typedef enum {
 VIR_PCIE_LINK_SPEED_25,
 VIR_PCIE_LINK_SPEED_5,
 VIR_PCIE_LINK_SPEED_8,
+VIR_PCIE_LINK_SPEED_16,
 VIR_PCIE_LINK_SPEED_LAST
 } virPCIELinkSpeed;
 

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


[libvirt] [PATCH] qemu: Use iohelper during restore

2017-01-27 Thread Shivaprasad G Bhat
Commit afe6e58 & c4caab53 made necessary changes to use io-helpers
during save and restore. The commit c4caab53 missed to remove the
redundant check in qemuDomainSaveImageOpen() because of which
virFileWrapperFdNew() is not called if bypass_cache is false.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c |7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 516a851..ac89372 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6150,9 +6150,11 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver,
 virDomainDefPtr def = NULL;
 int oflags = open_write ? O_RDWR : O_RDONLY;
 virCapsPtr caps = NULL;
+unsigned int wrapperFlags = VIR_FILE_WRAPPER_NON_BLOCKING;
 
 if (bypass_cache) {
 int directFlag = virFileDirectFdFlag();
+wrapperFlags |= VIR_FILE_WRAPPER_BYPASS_CACHE;
 if (directFlag < 0) {
 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("bypass cache unsupported by this system"));
@@ -6166,9 +6168,8 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver,
 
 if ((fd = qemuOpenFile(driver, NULL, path, oflags, NULL, NULL)) < 0)
 goto error;
-if (bypass_cache &&
-!(*wrapperFd = virFileWrapperFdNew(, path,
-   VIR_FILE_WRAPPER_BYPASS_CACHE)))
+if (wrapperFd &&
+!(*wrapperFd = virFileWrapperFdNew(, path, wrapperFlags)))
 goto error;
 
 if (saferead(fd, , sizeof(header)) != sizeof(header)) {

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


Re: [libvirt] [PATCH v2] util: disallow assigning or resetting a pci-bridge device

2017-01-23 Thread Shivaprasad G Bhat

Hi Laine,


On 01/21/2017 01:50 AM, Laine Stump wrote:

On 01/18/2017 11:10 AM, Martin Kletzander wrote:

On Wed, Jan 18, 2017 at 07:29:29PM +0530, Shivaprasad G Bhat wrote:

It is destructive to attempt reset on a pci-bridge, the host can crash.
The bridges won't contain any guest data and neither they can be
passed through using vfio/stub. So, no point in allowing a reset on 
them.




Wasn't resetting non-endpoint the only way in some cases when you needed
to passthrough 2 endpoint devices when none of them could be reset?  I
might be very easily wrong, though.


What you're thinking of is the code in virPCIDeviceReset() that 
attempts to do a "secondary bus reset" on the parent of an endpoint 
device if the reset of the endpoint device itself fails. This is never 
initiated directly by the user (or the top level of the libvirt API) 
though, but only done internally when attempts to reset an endpoint 
device fail (libvirt then tries doing a secondary bus reset of the 
endpoint's parent device).


Of course *all* of the PCI reset stuff in libvirt is a moot point if 
you're using vfio anyway - vfio itself will handle any device resets 
that need to be done at the appropriate time. That's why 
virPCIDeviceReset() returns success almost immediately if the device 
is bound to vfio-pci. Since the only time the device would *not* be 
bound to vfio-pci would be 1) if a domain was using legacy KVM device 
assignment (which is deprecated, and I think may even be completely 
removed from new kernels) or 2) if a user manually requested a device 
reset with libvirt's virNodeDeviceReset() API (which realistically 
speaking nobody should ever need to do), there's really not much 
chance of this making an actual difference. (This makes me wonder 
where Shivaprasad encountered this in the real world...)



I encountered this with virsh nodedev-reset on a pci-bridge.



Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
src/util/virhostdev.c |   10 ++
src/util/virpci.c |   11 +++
2 files changed, 21 insertions(+)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 0673afb..16b96f3 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -532,6 +532,16 @@ 
virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
bool strict_acs_check = !!(flags & 
VIR_HOSTDEV_STRICT_ACS_CHECK);
bool usesVFIO = (virPCIDeviceGetStubDriver(pci) == 
VIR_PCI_STUB_DRIVER_VFIO);
struct virHostdevIsPCINodeDeviceUsedData data = { mgr, 
dom_name, usesVFIO };

+int hdrType = -1;
+
+if (virPCIGetHeaderType(pci, ) < 0)
+goto cleanup;
+
+if (hdrType == VIR_PCI_HEADER_PCI_BRIDGE) {


I verified with the VFIO author/maintainer (Alex Williamson) that vfio 
will assign only endpoint devices - cardbus bridge devices and PCI 
bridge devices are both not allowed. So I think that this check should 
also be for "hdrType != VIR_PCI_HEADER_ENDPOINT".


Also, it's kind of nit-picking, but I think this chunk should be in a 
separate patch from the other. One is preventing attempts to assign a 
device that isn't an endpoint, and the otehr is preventing attemps to 
reset a device that isn't an endpoint.




+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("PCI bridge devices"
+   " cannot be assigned to guests"));


When a string is split into multiple lines, the final character of 
each line's substring must be a space (this is in the contribution 
guidelines and is enforced by make syntax-check)


I don't see a make syntax-check failure on my system though. Moved the 
space to the previous line.



+goto cleanup;
+}

if (!usesVFIO && !virPCIDeviceIsAssignable(pci, 
strict_acs_check)) {

virReportError(VIR_ERR_OPERATION_INVALID,
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 0601f49..f205abf 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -933,6 +933,17 @@ virPCIDeviceReset(virPCIDevicePtr dev,
char *drvName = NULL;
int ret = -1;
int fd = -1;
+int hdrType = -1;
+
+if (virPCIGetHeaderType(dev, ) < 0)
+return -1;
+
+if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Invalid attempt to reset non-endpoint PCI 
device %s."
+ " Only PCI endpoint devices can be 
reset"), dev->name);


Same problem. make syntax-check will catch it.


If you split this in two, change the first check to be for != endpoint 
rather than == bridge, and fix the strings, then these can be pushed.



Posted the v2 as suggested.

Thanks,
Shivaprasad

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


[libvirt] [PATCH v2 2/2] util: disallow resetting a pci-bridge device

2017-01-23 Thread Shivaprasad G Bhat
It is destructive to attempt reset on a pci-bridge, the host can crash.
The bridges won't contain any guest data and neither they can be
passed through using vfio/stub. So, no point in allowing a reset on them.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/util/virpci.c |   11 +++
 1 file changed, 11 insertions(+)

diff --git a/src/util/virpci.c b/src/util/virpci.c
index 0601f49..ae72587 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -933,6 +933,17 @@ virPCIDeviceReset(virPCIDevicePtr dev,
 char *drvName = NULL;
 int ret = -1;
 int fd = -1;
+int hdrType = -1;
+
+if (virPCIGetHeaderType(dev, ) < 0)
+return -1;
+
+if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
+virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid attempt to reset "
+   "non-endpoint PCI device %s. Only PCI endpoint "
+   "devices can be reset"), dev->name);
+return -1;
+}
 
 if (activeDevs && virPCIDeviceListFind(activeDevs, dev)) {
 virReportError(VIR_ERR_INTERNAL_ERROR,

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


[libvirt] [PATCH v2 1/2] util: virhostdev: disallow assigning a pci-bridge to a guest

2017-01-23 Thread Shivaprasad G Bhat
Non-endpoint devices like pci-bridges cannot be passedthrough to guests.
Prevent such attempts.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/util/virhostdev.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 0673afb..b23fe1f 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -532,6 +532,16 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
 bool strict_acs_check = !!(flags & VIR_HOSTDEV_STRICT_ACS_CHECK);
 bool usesVFIO = (virPCIDeviceGetStubDriver(pci) == 
VIR_PCI_STUB_DRIVER_VFIO);
 struct virHostdevIsPCINodeDeviceUsedData data = { mgr, dom_name, 
usesVFIO };
+int hdrType = -1;
+
+if (virPCIGetHeaderType(pci, ) < 0)
+goto cleanup;
+
+if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("PCI bridge devices 
"
+   "cannot be assigned to guests"));
+goto cleanup;
+}
 
 if (!usesVFIO && !virPCIDeviceIsAssignable(pci, strict_acs_check)) {
 virReportError(VIR_ERR_OPERATION_INVALID,

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


[libvirt] [PATCH v2] util: disallow assigning or resetting a pci-bridge device

2017-01-18 Thread Shivaprasad G Bhat
It is destructive to attempt reset on a pci-bridge, the host can crash.
The bridges won't contain any guest data and neither they can be
passed through using vfio/stub. So, no point in allowing a reset on them.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/util/virhostdev.c |   10 ++
 src/util/virpci.c |   11 +++
 2 files changed, 21 insertions(+)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 0673afb..16b96f3 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -532,6 +532,16 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
 bool strict_acs_check = !!(flags & VIR_HOSTDEV_STRICT_ACS_CHECK);
 bool usesVFIO = (virPCIDeviceGetStubDriver(pci) == 
VIR_PCI_STUB_DRIVER_VFIO);
 struct virHostdevIsPCINodeDeviceUsedData data = { mgr, dom_name, 
usesVFIO };
+int hdrType = -1;
+
+if (virPCIGetHeaderType(pci, ) < 0)
+goto cleanup;
+
+if (hdrType == VIR_PCI_HEADER_PCI_BRIDGE) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("PCI bridge devices"
+   " cannot be assigned to guests"));
+goto cleanup;
+}
 
 if (!usesVFIO && !virPCIDeviceIsAssignable(pci, strict_acs_check)) {
 virReportError(VIR_ERR_OPERATION_INVALID,
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 0601f49..f205abf 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -933,6 +933,17 @@ virPCIDeviceReset(virPCIDevicePtr dev,
 char *drvName = NULL;
 int ret = -1;
 int fd = -1;
+int hdrType = -1;
+
+if (virPCIGetHeaderType(dev, ) < 0)
+return -1;
+
+if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Invalid attempt to reset non-endpoint PCI device %s."
+ " Only PCI endpoint devices can be reset"), 
dev->name);
+return -1;
+}
 
 if (activeDevs && virPCIDeviceListFind(activeDevs, dev)) {
 virReportError(VIR_ERR_INTERNAL_ERROR,

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


[libvirt] [PATCH] util: disallow resetting a pci-bridge device

2017-01-17 Thread Shivaprasad G Bhat
It is distructive to attempt a reset on pci-bridge, the host can crash.
The bridges won't contain any guest data and neither they can be
passed through using vfio/stub. So, no point in allowing a reset for them.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/util/virpci.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/src/util/virpci.c b/src/util/virpci.c
index 0601f49..860f7aa 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -933,6 +933,16 @@ virPCIDeviceReset(virPCIDevicePtr dev,
 char *drvName = NULL;
 int ret = -1;
 int fd = -1;
+int hdrType = -1;
+
+if (virPCIGetHeaderType(dev, ) < 0)
+return -1;
+
+if (hdrType == VIR_PCI_HEADER_PCI_BRIDGE) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Resetting a pci-bridge device is not allowed"));
+return -1;
+}
 
 if (activeDevs && virPCIDeviceListFind(activeDevs, dev)) {
 virReportError(VIR_ERR_INTERNAL_ERROR,

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


Re: [libvirt] [PATCH] NEWS: Update after virtio console on ppc64 fix

2016-12-21 Thread Shivaprasad G Bhat

Hi Andrea,

On 12/21/2016 11:06 PM, Andrea Bolognani wrote:

+  qemu: Make virtio console usable on ppc64 guests
+  The chardev detection code has been improved and can now handle this
+  configuration properly.
+  
Thanks for this patch. Missed it, I am yet to get full hang of the new 
process around news.html. :)


ACK.

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


Re: [libvirt] [PATCH 2/2] qemu: Enable NUMA node tag in pci-root for PPC64

2016-11-14 Thread Shivaprasad G Bhat

Hi Daniel,

Can we have this patch for now ? Or should it come along with 
multiple-phb support ?


Thanks,
Shivaprasad

On 11/08/2016 07:40 PM, Shivaprasad G Bhat wrote:



On 11/08/2016 05:59 PM, Daniel P. Berrange wrote:

That doesn't really solve the bug above properly - your solution here
only works if all the PCI devices (whether emulated or host-assigned)
are to be associated with the same guest NUMA node. This is a pretty
restrictive setup and so of limited use IMHO.


Yes. It is restrictive. There can be no 1:1 pinning of host to guest 
nodes. But, one can have multiple host nodes pinned to 1 guest node 
which the host bridge is pinned to.


This helps only to the extent that, the guest drivers wont find -1 in 
the sysfs/numa_node. Some drivers are known to crash when they find 
-1. The patch addresses that part of the problem.



It seems like to solve this requires that we create multiple PCI Host
Bridges ?


Yes. That will be the actual fix to have 1:1 pinning. The current 
approach keeps that in mind and we can have the numa_node attribute 
set at the indivudual spapr-pci-host-bridge level when we have it. 
Then, the individual  can have different target node as 
I have in this patch.


Thanks,
Shivaprasad

Daniel



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


Re: [libvirt] [PATCH 2/2] qemu: Enable NUMA node tag in pci-root for PPC64

2016-11-08 Thread Shivaprasad G Bhat



On 11/08/2016 05:59 PM, Daniel P. Berrange wrote:

That doesn't really solve the bug above properly - your solution here
only works if all the PCI devices (whether emulated or host-assigned)
are to be associated with the same guest NUMA node. This is a pretty
restrictive setup and so of limited use IMHO.


Yes. It is restrictive. There can be no 1:1 pinning of host to guest 
nodes. But, one can have multiple host nodes pinned to 1 guest node 
which the host bridge is pinned to.


This helps only to the extent that, the guest drivers wont find -1 in 
the sysfs/numa_node. Some drivers are known to crash when they find -1. 
The patch addresses that part of the problem.



It seems like to solve this requires that we create multiple PCI Host
Bridges ?


Yes. That will be the actual fix to have 1:1 pinning. The current 
approach keeps that in mind and we can have the numa_node attribute set 
at the indivudual spapr-pci-host-bridge level when we have it. Then, the 
individual  can have different target node as I have in 
this patch.


Thanks,
Shivaprasad

Daniel


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


[libvirt] [PATCH 2/2] qemu: Enable NUMA node tag in pci-root for PPC64

2016-11-08 Thread Shivaprasad G Bhat
This patch addresses the same aspects on PPC the bug 1103314 addressed
on x86.

PCI expander bus creates multiple primary PCI busses, where each of these
busses can be assigned a specific NUMA affinity, which, on x86 is
advertised through ACPI on a per-bus basis.

For SPAPR, a PHB's NUMA affinities are assigned on a per-PHB basis, and
there is no mechanism for advertising NUMA affinities to a guest on a
per-bus basis. So, even if qemu-ppc manages to get some sort of multi-bus
topology working using PXB, there is no way to expose the affinities
of these busses to the guest. It can only be exposed on a per-PHB/per-domain
basis.

So, enable NUMA node tag in pci-root controller on PPC.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 docs/formatdomain.html.in  |5 ++
 src/qemu/qemu_command.c|   25 +++-
 src/qemu/qemu_domain.c |   15 ---
 ...emuxml2argv-spapr-pci-hos-bridge-numa-node.args |   26 
 ...qemuxml2argv-spapr-pci-hos-bridge-numa-node.xml |   43 
 tests/qemuxml2argvtest.c   |2 +
 6 files changed, 109 insertions(+), 7 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-hos-bridge-numa-node.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-hos-bridge-numa-node.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 11b3330..ea45146 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3492,6 +3492,11 @@
 part of the specified NUMA node (it is up to the user of the
 libvirt API to attach host devices to the correct
 pci-expander-bus when assigning them to the domain).
+On PPC64, the PCI devices can be specified to be part of a NUMA
+node using only the pci-root controller with an optional
+node subelement within the
+target subelement. All the PCI devices of
+the guest will be part of the specified NUMA node.
   
 
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9adf0fe..ec794f0 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3055,6 +3055,25 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
 return NULL;
 }
 
+static int qemuBuildSPAPRGlobalPCIRootNodeCommandLine(virCommandPtr cmd,
+  
virDomainControllerDefPtr def,
+  virQEMUCapsPtr qemuCaps)
+{
+if (def->opts.pciopts.numaNode != -1) {
+if (!virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("the numa_node option with spapr-pci-host-bridge 
controller "
+ "is not supported in this QEMU binary"));
+return -1;
+}
+virCommandAddArg(cmd, "-global");
+virCommandAddArgFormat(cmd, "spapr-pci-host-bridge.numa_node=%d",
+   def->opts.pciopts.numaNode);
+}
+
+return 0;
+}
+
 
 static int
 qemuBuildControllerDevCommandLine(virCommandPtr cmd,
@@ -3107,8 +3126,12 @@ qemuBuildControllerDevCommandLine(virCommandPtr cmd,
 /* skip pci-root/pcie-root */
 if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
 (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
- cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT))
+ cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
+if (ARCH_IS_PPC64(def->os.arch))
+if (qemuBuildSPAPRGlobalPCIRootNodeCommandLine(cmd, cont, 
qemuCaps) < 0)
+return -1;
 continue;
+}
 
 /* first SATA controller on Q35 machines is implicit */
 if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA &&
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8cba755..b5f89a6 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3058,12 +3058,14 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
 /* if a PCI expander bus has a NUMA node set, make sure
  * that NUMA node is configured in the guest 
  * array. NUMA cell id's in this array are numbered
- * from 0 .. size-1.
+ * from 0 .. size-1. Or On PPC, if the pci/pcie-root has the
+ * NUMA node set, do the same.
  */
-if ((cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS ||
- cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS) 
&&
-(int) virDomainNumaGetNodeCount(def->numa)
-<= cont->opts.pcio

[libvirt] [PATCH 1/2] qemu: capabilitity: Introduce QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE

2016-11-08 Thread Shivaprasad G Bhat
The patch adds a capability for spapr-pci-host-bridge.numa_node.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_capabilities.c   |7 ++
 src/qemu/qemu_capabilities.h   |1 
 .../qemucapabilitiesdata/caps_1.2.2.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.3.1.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.4.2.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.5.3.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.6.0.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.7.0.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_2.1.1.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_2.4.0.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_2.5.0.x86_64.replies |   22 +--
 .../caps_2.6.0-gicv2.aarch64.replies   |   22 +--
 .../caps_2.6.0-gicv3.aarch64.replies   |   24 +---
 .../caps_2.6.0.ppc64le.replies |   60 ++--
 .../qemucapabilitiesdata/caps_2.6.0.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_2.7.0.x86_64.replies |   22 +--
 16 files changed, 257 insertions(+), 99 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 747226c..5fe63a3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -350,6 +350,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
   "ivshmem-plain",
 
   "ivshmem-doorbell", /* 240 */
+  "spapr-pci-host-bridge.numa_node",
 );
 
 
@@ -1614,6 +1615,10 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsObjectPropsVirtioNet[] = {
 { "rx_queue_size", QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE },
 };
 
+static struct virQEMUCapsStringFlags 
virQEMUCapsObjectPropsSpaprPCIHostBridge[] = {
+{ "numa_node", QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE },
+};
+
 static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioSCSI[] = {
 { "iothread", QEMU_CAPS_VIRTIO_SCSI_IOTHREAD },
 };
@@ -1766,6 +1771,8 @@ static struct virQEMUCapsObjectTypeProps 
virQEMUCapsObjectProps[] = {
   ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon) },
 { "nec-usb-xhci", virQEMUCapsObjectPropsUSBNECXHCI,
   ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBNECXHCI) },
+{ "spapr-pci-host-bridge", virQEMUCapsObjectPropsSpaprPCIHostBridge,
+  ARRAY_CARDINALITY(virQEMUCapsObjectPropsSpaprPCIHostBridge) },
 };
 
 struct virQEMUCapsPropTypeObjects {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d104404..ebab9ea 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -385,6 +385,7 @@ typedef enum {
 
 /* 240 */
 QEMU_CAPS_DEVICE_IVSHMEM_DOORBELL, /* -device ivshmem-doorbell */
+QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, /* 
spapr-pci-host-bridge.numa_node= */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.replies 
b/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.replies
index dff9788..b4f7b9e 100644
--- a/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.replies
@@ -1701,6 +1701,14 @@
 }
 
 {
+  "id": "libvirt-39",
+  "error": {
+"class": "DeviceNotFound",
+"desc": "Device 'spapr-pci-host-bridge' not found"
+  }
+}
+
+{
   "return": [
 {
   "name": "isapc"
@@ -1738,7 +1746,7 @@
   "name": "none"
 }
   ],
-  "id": "libvirt-39"
+  "id": "libvirt-40"
 }
 
 {
@@ -1810,7 +1818,7 @@
   "name": "Opteron_G4"
 }
   ],
-  "id": "libvirt-40"
+  "id": "libvirt-41"
 }
 
 {
@@ -1818,11 +1826,11 @@
 "enabled": false,
 "present": true
   },
-  "id": "libvirt-41"
+  "id": "libvirt-42"
 }
 
 {
-  "id": "libvirt-42",
+  "id": "libvirt-43",
   "error": {
 "class": "CommandNotFound",
 "desc": "The command query-tpm-models has not been found"
@@ -1830,7 +1838,7 @@
 }
 
 {
-  "id": "libvirt-43",
+  "id": "libvirt-44",
   "error": {
 "class": "CommandNotFound",
 "desc": "The command query-tpm-types has not been found"
@@ -1838,7 +1846,7 @@
 }
 
 {
-  "id": "libvirt-44",
+  "id": "libvirt-45",
   "error": {
 "class": "CommandNotFound",
 "desc": "The command query-command

[libvirt] [PATCH 0/2] qemu: Enable NUMA node tag in pci-root for PPC64

2016-11-08 Thread Shivaprasad G Bhat
This patch addresses the same aspects on PPC the bug 1103314 addressed
on x86. It sets the target numa node in the pci-root instead of
using the pci-expander-bus.

The pci-expander-bus is of not much use on PPC, and the approach is
to set the value globally for reasons mentioned in Patch 2 commit
message.

Known issue :
If the destination doesn't recognize the NUMA node in the target,
then thats dropped during parsing. There is no ABI failure and the
migration will be successful. The issue needs us to relook on how
to make sure the unparsed tags on the destination which dont fail the ABI
could be enforced during migration. Not addressing that in these two patches.

---

Shivaprasad G Bhat (2):
  qemu: capabilitity: Introduce QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE
  qemu: Enable NUMA node tag in pci-root for PPC


 docs/formatdomain.html.in  |5 ++
 src/qemu/qemu_capabilities.c   |7 ++
 src/qemu/qemu_capabilities.h   |1 
 src/qemu/qemu_command.c|   25 
 src/qemu/qemu_domain.c |   15 +++--
 .../qemucapabilitiesdata/caps_1.2.2.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.3.1.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.4.2.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.5.3.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.6.0.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_1.7.0.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_2.1.1.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_2.4.0.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_2.5.0.x86_64.replies |   22 +--
 .../caps_2.6.0-gicv2.aarch64.replies   |   22 +--
 .../caps_2.6.0-gicv3.aarch64.replies   |   24 +---
 .../caps_2.6.0.ppc64le.replies |   60 ++--
 .../qemucapabilitiesdata/caps_2.6.0.x86_64.replies |   22 +--
 .../qemucapabilitiesdata/caps_2.7.0.x86_64.replies |   22 +--
 ...emuxml2argv-spapr-pci-hos-bridge-numa-node.args |   26 +
 ...qemuxml2argv-spapr-pci-hos-bridge-numa-node.xml |   43 ++
 tests/qemuxml2argvtest.c   |2 +
 22 files changed, 366 insertions(+), 106 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-hos-bridge-numa-node.args
 create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-spapr-pci-hos-bridge-numa-node.xml

--
Signature

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


[libvirt] [PATCH] Allow virtio-console on PPC64

2016-10-19 Thread Shivaprasad G Bhat
virQEMUCapsSupportsChardev existing checks returns true
for spapr-vty alone. Instead verify spapr-vty validity
and let the logic to return true for other device types
so that virtio-console passes.

The non-pseries machines dont have spapr-vio-bus. So, the
function always returned false for them before.

Fixes - https://bugzilla.redhat.com/show_bug.cgi?id=1257813

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_capabilities.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6eee85d..784496b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4286,9 +4286,12 @@ virQEMUCapsSupportsChardev(const virDomainDef *def,
 return false;
 
 if ((def->os.arch == VIR_ARCH_PPC) || ARCH_IS_PPC64(def->os.arch)) {
+if (!qemuDomainMachineIsPSeries(def))
+return false;
 /* only pseries need -device spapr-vty with -chardev */
-return (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
-chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO);
+if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
+chr->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO)
+return false;
 }
 
 if ((def->os.arch != VIR_ARCH_ARMV7L) && (def->os.arch != 
VIR_ARCH_AARCH64))

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


Re: [libvirt] [PATCH 7/7] qemu: Allow making vcpus hotpluggable with virDomainSetVcpusFlags

2016-09-29 Thread Shivaprasad G Bhat



On 09/29/2016 05:50 PM, Peter Krempa wrote:

On Thu, Sep 29, 2016 at 17:37:53 +0530, Shivaprasad G Bhat wrote:


On 09/29/2016 05:32 PM, Peter Krempa wrote:

On Thu, Sep 29, 2016 at 16:29:13 +0530, Shivaprasad G Bhat wrote:

On 09/21/2016 05:19 PM, Peter Krempa wrote:

Implement support for VIR_DOMAIN_VCPU_HOTPLUGGABLE so that users can
choose to make vcpus added by the API removable.
---
src/qemu/qemu_driver.c | 22 --
1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 357be4e..8453628 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4912,7 +4912,8 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
 */
static void
qemuDomainSetVcpusConfig(virDomainDefPtr def,
- unsigned int nvcpus)
+ unsigned int nvcpus,
+ bool hotpluggable)
{
virDomainVcpuDefPtr vcpu;

Here  if (curvcpus == nvcpus)

   return
  we still need to allow if someone wants to switch from hotpluggable
= yes to no/ vice versa.

No. As no new vcpus were added there's nothing to turn to hotpluggable.
The flag turns only the newly added vcpus as hotpluggable.

What if someone had the hotplug = yes. And He wants to make it "no".  ?
With no changes to the vcpus.

You can make two calls to the API, decreasing and re-increasing the
count. Or edit the XML directly since its a non-simple change. If the
API call would change existing vcpus to either hotpluggable or not it
would break configurations. Eg. as PPC requires first 8 vcpus to be non
hotpluggable vs. just one on intel.


Agreed. Thanks!

ACK the series.

-Shivaprasad

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


Re: [libvirt] [PATCH 7/7] qemu: Allow making vcpus hotpluggable with virDomainSetVcpusFlags

2016-09-29 Thread Shivaprasad G Bhat



On 09/29/2016 05:32 PM, Peter Krempa wrote:

On Thu, Sep 29, 2016 at 16:29:13 +0530, Shivaprasad G Bhat wrote:

On 09/21/2016 05:19 PM, Peter Krempa wrote:

Implement support for VIR_DOMAIN_VCPU_HOTPLUGGABLE so that users can
choose to make vcpus added by the API removable.
---
   src/qemu/qemu_driver.c | 22 --
   1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 357be4e..8453628 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4912,7 +4912,8 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
*/
   static void
   qemuDomainSetVcpusConfig(virDomainDefPtr def,
- unsigned int nvcpus)
+ unsigned int nvcpus,
+ bool hotpluggable)
   {
   virDomainVcpuDefPtr vcpu;

Here  if (curvcpus == nvcpus)

  return
 we still need to allow if someone wants to switch from hotpluggable
= yes to no/ vice versa.

No. As no new vcpus were added there's nothing to turn to hotpluggable.
The flag turns only the newly added vcpus as hotpluggable.


What if someone had the hotplug = yes. And He wants to make it "no".  ? 
With no changes to the vcpus.





   size_t curvcpus = virDomainDefGetVcpus(def);
@@ -4933,7 +4934,12 @@ qemuDomainSetVcpusConfig(virDomainDefPtr def,
   continue;

   vcpu->online = true;
-vcpu->hotpluggable = VIR_TRISTATE_BOOL_NO;
+if (hotpluggable) {
+vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES;
+def->individualvcpus = true;
+} else {
+vcpu->hotpluggable = VIR_TRISTATE_BOOL_NO;
+}

   if (++curvcpus == nvcpus)
   break;

Can we add checks here to see on PPC, the config is valid with a check
when topology is given in xml to see (curvcpus%threads_per_core == 0)

No. For PPC and all the weird archs that don't have thread level hotplug
we can't really know what to use and what is a legitimate configuration
until we start the VM and query qemu.


Otherwise with virsh setvcpus rhel71 13 --config --hotpluggable
for a guest with topology 
we would see,
2016-09-29 10:12:05.929+: 1137: error :
qemuProcessValidateHotpluggableVcpus:4829 : unsupported configuration:
vcpus '12' and '13' are in the same hotplug group but differ in
configuration

Yes, you can configure the same thing manually in the XML.


OR

Even when setvcpus live to a number not leading to a complete core, we
have checks leading to sensible error (error: unsupported configuration:
target vm vcpu granularity does not allow the desired vcpu count ) . So,
in case of --config also may be we can add the check to bring the
consistency.

As said above. Libvirt can't surely detect that the "weird" approach is
needed.

Peter


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


Re: [libvirt] [PATCH 7/7] qemu: Allow making vcpus hotpluggable with virDomainSetVcpusFlags

2016-09-29 Thread Shivaprasad G Bhat


On 09/21/2016 05:19 PM, Peter Krempa wrote:

Implement support for VIR_DOMAIN_VCPU_HOTPLUGGABLE so that users can
choose to make vcpus added by the API removable.
---
  src/qemu/qemu_driver.c | 22 --
  1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 357be4e..8453628 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4912,7 +4912,8 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
   */
  static void
  qemuDomainSetVcpusConfig(virDomainDefPtr def,
- unsigned int nvcpus)
+ unsigned int nvcpus,
+ bool hotpluggable)
  {
  virDomainVcpuDefPtr vcpu;

Here  if (curvcpus == nvcpus)

return
   we still need to allow if someone wants to switch from hotpluggable 
= yes to no/ vice versa.




  size_t curvcpus = virDomainDefGetVcpus(def);
@@ -4933,7 +4934,12 @@ qemuDomainSetVcpusConfig(virDomainDefPtr def,
  continue;

  vcpu->online = true;
-vcpu->hotpluggable = VIR_TRISTATE_BOOL_NO;
+if (hotpluggable) {
+vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES;
+def->individualvcpus = true;
+} else {
+vcpu->hotpluggable = VIR_TRISTATE_BOOL_NO;
+}

  if (++curvcpus == nvcpus)
  break;


Can we add checks here to see on PPC, the config is valid with a check 
when topology is given in xml to see (curvcpus%threads_per_core == 0)


Otherwise with virsh setvcpus rhel71 13 --config --hotpluggable
for a guest with topology 
we would see,
2016-09-29 10:12:05.929+: 1137: error : 
qemuProcessValidateHotpluggableVcpus:4829 : unsupported configuration: 
vcpus '12' and '13' are in the same hotplug group but differ in 
configuration


OR

Even when setvcpus live to a number not leading to a complete core, we 
have checks leading to sensible error (error: unsupported configuration: 
target vm vcpu granularity does not allow the desired vcpu count ) . So, 
in case of --config also may be we can add the check to bring the 
consistency.


Otherwise the series looks good with the above two cases addressed . ACK

Thanks,
Shivaprasad



@@ -4960,7 +4966,8 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver,
 virDomainObjPtr vm,
 virDomainDefPtr def,
 virDomainDefPtr persistentDef,
-   unsigned int nvcpus)
+   unsigned int nvcpus,
+   bool hotpluggable)
  {
  virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
  int ret = -1;
@@ -4985,7 +4992,7 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver,
  goto cleanup;

  if (persistentDef) {
-qemuDomainSetVcpusConfig(persistentDef, nvcpus);
+qemuDomainSetVcpusConfig(persistentDef, nvcpus, hotpluggable);

  if (virDomainSaveConfig(cfg->configDir, driver->caps, persistentDef) 
< 0)
  goto cleanup;
@@ -5008,12 +5015,14 @@ qemuDomainSetVcpusFlags(virDomainPtr dom,
  virDomainObjPtr vm = NULL;
  virDomainDefPtr def;
  virDomainDefPtr persistentDef;
+bool hotpluggable = !!(flags & VIR_DOMAIN_VCPU_HOTPLUGGABLE);
  int ret = -1;

  virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM |
-  VIR_DOMAIN_VCPU_GUEST, -1);
+  VIR_DOMAIN_VCPU_GUEST |
+  VIR_DOMAIN_VCPU_HOTPLUGGABLE, -1);

  if (!(vm = qemuDomObjFromDomain(dom)))
  goto cleanup;
@@ -5032,7 +5041,8 @@ qemuDomainSetVcpusFlags(virDomainPtr dom,
  else if (flags & VIR_DOMAIN_VCPU_MAXIMUM)
  ret = qemuDomainSetVcpusMax(driver, def, persistentDef, nvcpus);
  else
-ret = qemuDomainSetVcpusInternal(driver, vm, def, persistentDef, 
nvcpus);
+ret = qemuDomainSetVcpusInternal(driver, vm, def, persistentDef,
+ nvcpus, hotpluggable);

   endjob:
  qemuDomainObjEndJob(driver, vm);


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


Re: [libvirt] [PATCH] virsh: use virConnectGetDomainCapabilities with maxvcpus

2016-09-15 Thread Shivaprasad G Bhat

Hi Peter,

This saves few lines of code for sure :) I see the ignore_error for 
virXPathInt(). I see no issues.


ACK

Thanks a lot!

-Shivaprasad

On 09/15/2016 01:47 PM, Peter Krempa wrote:

From: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>

virsh maxvcpus --type kvm output is useless on PPC. Also, in
commit e6806d79 we documented not rely on virConnectGetMaxVcpus
output. Fix the  maxvcpus to use virConnectGetDomainCapabilities
now to make it useful. The call is made to use the default emulator
binary and to check for the host machine and arch which is what the
command intends to show anyway.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
  tools/virsh-host.c | 30 ++
  1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 57f0c0e..2337ce8 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -606,18 +606,40 @@ static bool
  cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
  {
  const char *type = NULL;
-int vcpus;
+int vcpus = -1;
+char *caps = NULL;
+xmlDocPtr xml = NULL;
+xmlXPathContextPtr ctxt = NULL;
  virshControlPtr priv = ctl->privData;
+bool ret = false;

  if (vshCommandOptStringReq(ctl, cmd, "type", ) < 0)
  return false;

-if ((vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)
-return false;
+if ((caps = virConnectGetDomainCapabilities(priv->conn, NULL, NULL, NULL,
+type, 0))) {
+if (!(xml = virXMLParseStringCtxt(caps, _("(domainCapabilities)"), 
)))
+goto cleanup;
+
+ignore_value(virXPathInt("string(./vcpu[1]/@max)", ctxt, ));
+} else {
+if (last_error && last_error->code != VIR_ERR_NO_SUPPORT)
+goto cleanup;
+
+   vshResetLibvirtError();
+}
+
+if (vcpus < 0 && (vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)
+goto cleanup;

  vshPrint(ctl, "%d\n", vcpus);
+ret = true;

-return true;
+ cleanup:
+xmlXPathFreeContext(ctxt);
+xmlFreeDoc(xml);
+VIR_FREE(caps);
+return ret;
  }

  /*


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


Re: [libvirt] [PATCH] virsh: use virConnectGetDomainCapabilities with maxvcpus

2016-09-07 Thread Shivaprasad G Bhat



On 09/06/2016 05:56 PM, Peter Krempa wrote:

On Tue, Sep 06, 2016 at 16:59:09 +0530, Shivaprasad G Bhat wrote:

virsh maxvcpus --type kvm output is useless on PPC. Also, in
commit e6806d79 we documented not rely on virConnectGetMaxVcpus
output. Fix the  maxvcpus to use virConnectGetDomainCapabilities
now to make it useful. The call is made to use the default emulator
binary and to check for the host machine and arch which is what the
command intends to show anyway.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
  tools/virsh-host.c |   28 +---
  1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 57f0c0e..505cfbb 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -607,16 +607,38 @@ cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
  {
  const char *type = NULL;
  int vcpus;
+char *caps = NULL;
+const unsigned int flags = 0; /* No flags so far */
+xmlDocPtr xml = NULL;
+xmlXPathContextPtr ctxt = NULL;
  virshControlPtr priv = ctl->privData;
  
  if (vshCommandOptStringReq(ctl, cmd, "type", ) < 0)

  return false;
  
-if ((vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)

-return false;
+caps = virConnectGetDomainCapabilities(priv->conn, NULL, NULL, NULL, type, 
flags);
+if (caps) {
+xml = virXMLParseStringCtxt(caps, _("(domainCapabilities)"), );
+if (!xml) {
+VIR_FREE(caps);
+return false;
+}
  
-vshPrint(ctl, "%d\n", vcpus);

+virXPathInt("string(./vcpu[1]/@max)", ctxt, );

This doesn't handle the case when the capability XML does not contain
the required data. This still should fall back to the legacy approach.
Ah bhyve doesn't report the vcpus in domcapabilities. Thanks. Fixed it 
in next version I posted just now.


Regards,
Shivaprasad

Additionally virXPathInt does not initialize vcpus on failure and since
it's not initialized when declared this would trigger a compiler
warning.


+xmlXPathFreeContext(ctxt);
+xmlFreeDoc(xml);
+VIR_FREE(caps);


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


[libvirt] [PATCH v4] virsh: use virConnectGetDomainCapabilities with maxvcpus

2016-09-07 Thread Shivaprasad G Bhat
virsh maxvcpus --type kvm output is useless on PPC. Also, in
commit e6806d79 we documented not rely on virConnectGetMaxVcpus
output. Fix the  maxvcpus to use virConnectGetDomainCapabilities
now to make it useful. The call is made to use the default emulator
binary and to check for the host machine and arch which is what the
command intends to show anyway.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 tools/virsh-host.c |   34 +++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 57f0c0e..dbdf23d 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -606,18 +606,46 @@ static bool
 cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
 {
 const char *type = NULL;
-int vcpus;
+int vcpus = -1;
+char *caps = NULL;
+const unsigned int flags = 0; /* No flags so far */
+xmlDocPtr xml = NULL;
+xmlXPathContextPtr ctxt = NULL;
 virshControlPtr priv = ctl->privData;
 
 if (vshCommandOptStringReq(ctl, cmd, "type", ) < 0)
 return false;
 
-if ((vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)
+caps = virConnectGetDomainCapabilities(priv->conn, NULL, NULL, NULL, type, 
flags);
+if (!caps) {
+if (last_error && last_error->code != VIR_ERR_NO_SUPPORT)
+return false;
+
+vshResetLibvirtError();
+goto fallback;
+}
+
+xml = virXMLParseStringCtxt(caps, _("(domainCapabilities)"), );
+if (!xml) {
+VIR_FREE(caps);
 return false;
+}
 
-vshPrint(ctl, "%d\n", vcpus);
+virXPathInt("string(./vcpu[1]/@max)", ctxt, );
+xmlXPathFreeContext(ctxt);
+xmlFreeDoc(xml);
+VIR_FREE(caps);
 
+if (vcpus < 0)
+goto fallback;
+
+ exit:
+vshPrint(ctl, "%d\n", vcpus);
 return true;
+ fallback:
+if ((vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)
+return false;
+goto exit;
 }
 
 /*

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


[libvirt] [PATCH] virsh: use virConnectGetDomainCapabilities with maxvcpus

2016-09-06 Thread Shivaprasad G Bhat
virsh maxvcpus --type kvm output is useless on PPC. Also, in
commit e6806d79 we documented not rely on virConnectGetMaxVcpus
output. Fix the  maxvcpus to use virConnectGetDomainCapabilities
now to make it useful. The call is made to use the default emulator
binary and to check for the host machine and arch which is what the
command intends to show anyway.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 tools/virsh-host.c |   28 +---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 57f0c0e..505cfbb 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -607,16 +607,38 @@ cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
 {
 const char *type = NULL;
 int vcpus;
+char *caps = NULL;
+const unsigned int flags = 0; /* No flags so far */
+xmlDocPtr xml = NULL;
+xmlXPathContextPtr ctxt = NULL;
 virshControlPtr priv = ctl->privData;
 
 if (vshCommandOptStringReq(ctl, cmd, "type", ) < 0)
 return false;
 
-if ((vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)
-return false;
+caps = virConnectGetDomainCapabilities(priv->conn, NULL, NULL, NULL, type, 
flags);
+if (caps) {
+xml = virXMLParseStringCtxt(caps, _("(domainCapabilities)"), );
+if (!xml) {
+VIR_FREE(caps);
+return false;
+}
 
-vshPrint(ctl, "%d\n", vcpus);
+virXPathInt("string(./vcpu[1]/@max)", ctxt, );
+xmlXPathFreeContext(ctxt);
+xmlFreeDoc(xml);
+VIR_FREE(caps);
+} else {
+if (last_error && last_error->code != VIR_ERR_NO_SUPPORT)
+return false;
+
+vshResetLibvirtError();
 
+if ((vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)
+return false;
+}
+
+vshPrint(ctl, "%d\n", vcpus);
 return true;
 }
 

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


Re: [libvirt] [PATCH v2 08/23] qemu: monitor: Add algorithm for combining query-(hotpluggable-)-cpus data

2016-08-23 Thread Shivaprasad G Bhat



On 08/19/2016 08:08 PM, Peter Krempa wrote:

For hotplug purposes it's necessary to retrieve data using
query-hotpluggable-cpus while the old query-cpus API report thread IDs
and order of hotplug.

This patch adds code that merges the data using a rather non-trivial
algorithm and fills the data to the qemuMonitorCPUInfo structure for
adding to appropriate place in the domain definition.
---

Notes:
 v2:
 - fixed loop in the fallback info populator function
 - fixed debug message

  src/qemu/qemu_domain.c  |   2 +-
  src/qemu/qemu_monitor.c | 197 ++--
  src/qemu/qemu_monitor.h |  23 +-
  3 files changed, 212 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c56dc75..45ded03 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5804,7 +5804,7 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
  if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
  return -1;

-rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), , maxvcpus);
+rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), , maxvcpus, 
false);

  if (qemuDomainObjExitMonitor(driver, vm) < 0)
  goto cleanup;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index f87f431..451786b 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1656,13 +1656,36 @@ qemuMonitorSystemReset(qemuMonitorPtr mon)
  }


+static void
+qemuMonitorCPUInfoClear(qemuMonitorCPUInfoPtr cpus,
+size_t ncpus)
+{
+size_t i;
+
+for (i = 0; i < ncpus; i++) {
+cpus[i].id = 0;
+cpus[i].socket_id = -1;
+cpus[i].core_id = -1;
+cpus[i].thread_id = -1;
+cpus[i].vcpus = 0;
+cpus[i].tid = 0;
+
+VIR_FREE(cpus[i].qom_path);
+VIR_FREE(cpus[i].alias);
+VIR_FREE(cpus[i].type);
+}
+}
+
+
  void
  qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr cpus,
-   size_t ncpus ATTRIBUTE_UNUSED)
+   size_t ncpus)
  {
  if (!cpus)
  return;

+qemuMonitorCPUInfoClear(cpus, ncpus);
+
  VIR_FREE(cpus);
  }

@@ -1683,10 +1706,148 @@ qemuMonitorQueryCpusFree(struct 
qemuMonitorQueryCpusEntry *entries,


  /**
+ * Legacy approach doesn't allow out of order cpus, thus no complex matching
+ * algorithm is necessary */
+static void
+qemuMonitorGetCPUInfoLegacy(struct qemuMonitorQueryCpusEntry *cpuentries,
+size_t ncpuentries,
+qemuMonitorCPUInfoPtr vcpus,
+size_t maxvcpus)
+{
+size_t i;
+
+for (i = 0; i < maxvcpus; i++) {
+if (i < ncpuentries)
+vcpus[i].tid = cpuentries[i].tid;
+
+/* for legacy hotplug to work we need to fake the vcpu count added by
+ * enabling a given vcpu */
+vcpus[i].vcpus = 1;
+}
+}
+
+
+/**
+ * qemuMonitorGetCPUInfoHotplug:
+ *
+ * This function stitches together data retrieved via query-hotpluggable-cpus
+ * which returns entities on the hotpluggable level (which may describe more
+ * than one guest logical vcpu) with the output of query-cpus, having an entry
+ * per enabled guest logical vcpu.
+ *
+ * query-hotpluggable-cpus conveys following information:
+ * - topology information and number of logical vcpus this entry creates
+ * - device type name of the entry that needs to be used when hotplugging
+ * - qom path in qemu which can be used to map the entry against query-cpus
+ *
+ * query-cpus conveys following information:
+ * - thread id of a given guest logical vcpu
+ * - order in which the vcpus were inserted
+ * - qom path to allow mapping the two together
+ *
+ * The libvirt's internal structure has an entry for each possible (even
+ * disabled) guest vcpu. The purpose is to map the data together so that we are
+ * certain of the thread id mapping and the information required for vcpu
+ * hotplug.
+ *
+ * This function returns 0 on success and -1 on error, but does not report
+ * libvirt errors so that fallback approach can be used.
+ */
+static int
+qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry 
*hotplugvcpus,
+ size_t nhotplugvcpus,
+ struct qemuMonitorQueryCpusEntry *cpuentries,
+ size_t ncpuentries,
+ qemuMonitorCPUInfoPtr vcpus,
+ size_t maxvcpus)
+{
+int order = 1;
+size_t totalvcpus = 0;
+size_t i;
+size_t j;
+
+/* ensure that the total vcpu count reported by query-hotpluggable-cpus 
equals
+ * to the libvirt maximum cpu count */
+for (i = 0; i < nhotplugvcpus; i++)
+totalvcpus += hotplugvcpus[i].vcpus;
+
+if (totalvcpus != maxvcpus) {
+VIR_DEBUG("expected '%zu' total vcpus got '%zu'", maxvcpus, 
totalvcpus);
+return -1;
+}
+
+/* Note the order in which the 

[libvirt] [PATCH v2] virsh: use virConnectGetDomainCapabilities with maxvcpus

2016-07-29 Thread Shivaprasad G Bhat
virsh maxvcpus --type kvm output is useless on PPC. Also, in
commit e6806d79 we documented not rely on virConnectGetMaxVcpus
output. Fix the  maxvcpus to use virConnectGetDomainCapabilities
now to make it useful. The call is made to use the default emulator
binary and to check for the host machine and arch which is what the
command intends to show anyway.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 tools/virsh-host.c |   26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 57f0c0e..dd6ff4e 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -606,15 +606,37 @@ static bool
 cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
 {
 const char *type = NULL;
-int vcpus;
+int vcpus = -1;
+char *caps = NULL;
+const unsigned int flags = 0; /* No flags so far */
+xmlDocPtr xml = NULL;
+xmlXPathContextPtr ctxt = NULL;
 virshControlPtr priv = ctl->privData;
 
 if (vshCommandOptStringReq(ctl, cmd, "type", ) < 0)
 return false;
 
+caps = virConnectGetDomainCapabilities(priv->conn, NULL, NULL, NULL, type, 
flags);
+if (!caps)
+goto fallback;
+
+xml = virXMLParseStringCtxt(caps, _("(domainCapabilities)"), );
+if (!xml) {
+VIR_FREE(caps);
+goto fallback;
+}
+
+virXPathInt("string(./vcpu[1]/@max)", ctxt, );
+
+xmlXPathFreeContext(ctxt);
+xmlFreeDoc(xml);
+if (vcpus > 0)
+goto exit;
+
+ fallback:
 if ((vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)
 return false;
-
+ exit:
 vshPrint(ctl, "%d\n", vcpus);
 
 return true;

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


[libvirt] [PATCH] virsh: use virConnectGetDomainCapabilities with maxvcpus

2016-07-27 Thread Shivaprasad G Bhat
The following patch fixes the maxvcpus output on PPC64.
Earlier I tried fixing this in kvmGetMaxVcpus() which was
later decided to be document not use the virConnectGetMaxVcpus() instead
use the virConnectGetDomainCapabilities api.

I have not implemented the suggestedcpus as mentioned in my previous
patches in this yet.

Previous series fixing the virConnectGetDomainCapabilities can be found here.
https://www.redhat.com/archives/libvir-list/2016-June/msg01873.html

---

Shivaprasad G Bhat (1):
  virsh: use virConnectGetDomainCapabilities with maxvcpus


 tools/virsh-host.c |   33 +
 1 file changed, 29 insertions(+), 4 deletions(-)

--
Signature

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


[libvirt] [PATCH] virsh: use virConnectGetDomainCapabilities with maxvcpus

2016-07-27 Thread Shivaprasad G Bhat
virsh maxvcpus --type kvm output is useless on PPC. Also, in
commit e6806d79 we documented not rely on virConnectGetMaxVcpus
output. Fix the  maxvcpus to use virConnectGetDomainCapabilities
now to make it useful. The call is made to use the default qemu
binary and to check for the host machine and arch which is what the
command intends to do anyway.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 tools/virsh-host.c |   33 +
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 57f0c0e..cf001c6 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -606,18 +606,43 @@ static bool
 cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
 {
 const char *type = NULL;
-int vcpus;
+unsigned int vcpus;
+char *caps = NULL;
+const unsigned int flags = 0; /* No flags so far */
+xmlDocPtr xml = NULL;
+xmlXPathContextPtr ctxt = NULL;
+bool ret = false;
 virshControlPtr priv = ctl->privData;
 
 if (vshCommandOptStringReq(ctl, cmd, "type", ) < 0)
 return false;
 
-if ((vcpus = virConnectGetMaxVcpus(priv->conn, type)) < 0)
-return false;
+caps = virConnectGetDomainCapabilities(priv->conn, NULL, NULL, NULL, type, 
flags);
+if (!caps) {
+vshError(ctl, "%s", _("failed to get domain capabilities"));
+goto cleanup;
+}
+
+xml = virXMLParseStringCtxt(caps, _("(domainCapabilities)"), );
+if (!xml) {
+vshError(ctl, "%s", _("unable to parse domain capabilities"));
+goto cleanup;
+}
+
+if ((virXPathUInt("string(./vcpu[1]/@max)", ctxt, )) < 0) {
+vshError(ctl, "%s", _("unable to get maxvcpus"));
+goto cleanup;
+}
 
 vshPrint(ctl, "%d\n", vcpus);
 
-return true;
+ret = true;
+ cleanup:
+VIR_FREE(caps);
+xmlXPathFreeContext(ctxt);
+xmlFreeDoc(xml);
+
+return ret;
 }
 
 /*

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


[libvirt] [PATCH] qemu: Adjust the cur_ballon on coldplug/unplug of dimms

2016-07-21 Thread Shivaprasad G Bhat
The cur_balloon also increases/decreases with dimm hotplug/unplug.
To be consistent, adjust the value for coldplug too. This was inconsistently
taken care when cur_ballon != memory to begin with. The patch fixes it
irrespective of that.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/conf/domain_conf.c |3 +--
 src/qemu/qemu_driver.c |3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 6dfcf81..8b0b790 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14674,8 +14674,7 @@ virDomainMemoryRemove(virDomainDefPtr def,
 VIR_DELETE_ELEMENT(def->mems, idx, def->nmems);
 
 /* fix up balloon size */
-if (def->mem.cur_balloon > virDomainDefGetMemoryTotal(def))
-def->mem.cur_balloon = virDomainDefGetMemoryTotal(def);
+def->mem.cur_balloon -= ret->size;
 
 /* fix total memory size of the domain */
 virDomainDefSetMemoryTotal(def, memory - ret->size);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index cda85f6..3824e1d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7769,8 +7769,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
 return -1;
 }
 
-if (vmdef->mem.cur_balloon == virDomainDefGetMemoryTotal(vmdef))
-vmdef->mem.cur_balloon += dev->data.memory->size;
+vmdef->mem.cur_balloon += dev->data.memory->size;
 
 if (virDomainMemoryInsert(vmdef, dev->data.memory) < 0)
 return -1;

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


[libvirt] [PATCH v2 3/3] Document to not rely on virConnectGetMaxVcpus API

2016-06-24 Thread Shivaprasad G Bhat
The API virConnectGetMaxVcpus doesn't really reflect the actual usable number
of cpus as the maximum limits can be different for kvm and/or qemu. So update
the documentation to use virConnectGetDomainCapabilities() instead.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/libvirt-host.c |5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index 24277b7..2a3de03 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -313,7 +313,10 @@ virConnectGetSysinfo(virConnectPtr conn, unsigned int 
flags)
  *
  * Provides the maximum number of virtual CPUs supported for a guest VM of a
  * specific type. The 'type' parameter here corresponds to the 'type'
- * attribute in the  element of the XML.
+ * attribute in the  element of the XML. This API doesn't take emulator
+ * limits into consideration, hence the returned value is not guaranteed to be
+ * usable. It is recommended to use virConnectGetDomainCapabilities() and look
+ * for "" in its output instead.
  *
  * Returns the maximum of virtual CPU or -1 in case of error.
  */

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


[libvirt] [PATCH v2 2/3] qemu: check the kvm host cpu max limits in virConnectGetDomainCapabilities

2016-06-24 Thread Shivaprasad G Bhat
The qemu limit and host limit both should be considered for
the domain vcpu max limits.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_capabilities.c |   11 ---
 src/qemu/qemu_capabilities.h |3 ++-
 src/qemu/qemu_driver.c   |2 +-
 tests/domaincapstest.c   |3 ++-
 4 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 01466fc..ff5ad19 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -38,6 +38,7 @@
 #include "virbitmap.h"
 #include "virnodesuspend.h"
 #include "virnuma.h"
+#include "virhostcpu.h"
 #include "qemu_monitor.h"
 #include "virstring.h"
 #include "qemu_hostdev.h"
@@ -4336,16 +4337,20 @@ int
 virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
   virQEMUCapsPtr qemuCaps,
   virFirmwarePtr *firmwares,
-  size_t nfirmwares)
+  size_t nfirmwares,
+  virDomainVirtType virttype)
 {
 virDomainCapsOSPtr os = >os;
 virDomainCapsDeviceDiskPtr disk = >disk;
 virDomainCapsDeviceHostdevPtr hostdev = >hostdev;
 virDomainCapsDeviceGraphicsPtr graphics = >graphics;
 virDomainCapsDeviceVideoPtr video = >video;
-int maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, domCaps->machine);
 
-domCaps->maxvcpus = maxvcpus;
+domCaps->maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, 
domCaps->machine);
+if (virttype == VIR_DOMAIN_VIRT_KVM) {
+int hostmaxvcpus = virHostCPUGetKVMMaxVCPUs();
+domCaps->maxvcpus = MIN(domCaps->maxvcpus, hostmaxvcpus);
+}
 
 if (virQEMUCapsFillDomainOSCaps(os, firmwares, nfirmwares) < 0 ||
 virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps,
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index affb639..9d891c8 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -492,6 +492,7 @@ int virQEMUCapsInitGuestFromBinary(virCapsPtr caps,
 int virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
   virQEMUCapsPtr qemuCaps,
   virFirmwarePtr *firmwares,
-  size_t nfirmwares);
+  size_t nfirmwares,
+  virDomainVirtType virttype);
 
 #endif /* __QEMU_CAPABILITIES_H__*/
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4e6e4c9..59b657b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18475,7 +18475,7 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
 goto cleanup;
 
 if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps,
-  cfg->firmwares, cfg->nfirmwares) < 0)
+  cfg->firmwares, cfg->nfirmwares, virttype) < 
0)
 goto cleanup;
 
 ret = virDomainCapsFormat(domCaps);
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index ae31146..01ebfcc 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -129,7 +129,8 @@ fillQemuCaps(virDomainCapsPtr domCaps,
 
 if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps,
   cfg->firmwares,
-  cfg->nfirmwares) < 0)
+  cfg->nfirmwares,
+  VIR_DOMAIN_VIRT_QEMU) < 0)
 goto cleanup;
 
 /* The function above tries to query host's KVM & VFIO capabilities by

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


[libvirt] [PATCH v2 0/3] Fix the domain capabilities wrt maxvcpus

2016-06-24 Thread Shivaprasad G Bhat
This series drops the suggested cpu in the domcapabilties output which was
implemented in previous version. So, this has just the fix for the
domcapabililties output wrt maxvcpus.

I'll follow up this series with suggested cpus and the virsh maxvcpus fix.

The previous version is available here.
http://www.redhat.com/archives/libvir-list/2016-June/msg00947.html


---

Shivaprasad G Bhat (3):
  Rename kvmGetMaxVCPUs() to virHostCPUGetKVMMaxVCPUs()
  Check the kvm host cpu max limits in virConnectGetDomainCapabilities
  Document to not rely on virConnectGetMaxVcpus API


 src/libvirt-host.c   |5 +++-
 src/libvirt_private.syms |1 +
 src/qemu/qemu_capabilities.c |   11 ++---
 src/qemu/qemu_capabilities.h |3 ++
 src/qemu/qemu_driver.c   |   54 ++
 src/util/virhostcpu.c|   36 
 src/util/virhostcpu.h|2 ++
 tests/domaincapstest.c   |3 ++
 8 files changed, 57 insertions(+), 58 deletions(-)

--
Signature

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


[libvirt] [PATCH v2 1/3] Rename kvmGetMaxVCPUs() to virHostCPUGetKVMMaxVCPUs()

2016-06-24 Thread Shivaprasad G Bhat
This kvmGetMaxVCPUs() needs to be used at two different places
so move it to utils with appropriate name and mark it as private
global now.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/libvirt_private.syms |1 +
 src/qemu/qemu_driver.c   |   52 +-
 src/util/virhostcpu.c|   36 
 src/util/virhostcpu.h|2 ++
 4 files changed, 40 insertions(+), 51 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ef30f7f..a9eda05 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1072,6 +1072,7 @@ virLogManagerNew;
 nodeCapsInitNUMA;
 nodeGetInfo;
 virHostCPUGetCount;
+virHostCPUGetKVMMaxVCPUs;
 virHostCPUGetMap;
 virHostCPUGetOnlineBitmap;
 virHostCPUGetPresentBitmap;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dd3d624..4e6e4c9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -124,24 +124,6 @@ VIR_LOG_INIT("qemu.qemu_driver");
 
 #define QEMU_GUEST_VCPU_MAX_ID 4096
 
-#if HAVE_LINUX_KVM_H
-# include 
-#endif
-
-/* device for kvm ioctls */
-#define KVM_DEVICE "/dev/kvm"
-
-/* add definitions missing in older linux/kvm.h */
-#ifndef KVMIO
-# define KVMIO 0xAE
-#endif
-#ifndef KVM_CHECK_EXTENSION
-# define KVM_CHECK_EXTENSION   _IO(KVMIO,   0x03)
-#endif
-#ifndef KVM_CAP_NR_VCPUS
-# define KVM_CAP_NR_VCPUS 9   /* returns max vcpus per vm */
-#endif
-
 #define QEMU_NB_BLKIO_PARAM  6
 
 #define QEMU_NB_BANDWIDTH_PARAM 7
@@ -1261,38 +1243,6 @@ static int qemuConnectIsAlive(virConnectPtr conn 
ATTRIBUTE_UNUSED)
 }
 
 
-static int
-kvmGetMaxVCPUs(void)
-{
-int fd;
-int ret;
-
-if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) {
-virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE);
-return -1;
-}
-
-#ifdef KVM_CAP_MAX_VCPUS
-/* at first try KVM_CAP_MAX_VCPUS to determine the maximum count */
-if ((ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS)) > 0)
-goto cleanup;
-#endif /* KVM_CAP_MAX_VCPUS */
-
-/* as a fallback get KVM_CAP_NR_VCPUS (the recommended maximum number of
- * vcpus). Note that on most machines this is set to 160. */
-if ((ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS)) > 0)
-goto cleanup;
-
-/* if KVM_CAP_NR_VCPUS doesn't exist either, kernel documentation states
- * that 4 should be used as the maximum number of cpus */
-ret = 4;
-
- cleanup:
-VIR_FORCE_CLOSE(fd);
-return ret;
-}
-
-
 static char *
 qemuConnectGetSysinfo(virConnectPtr conn, unsigned int flags)
 {
@@ -1330,7 +1280,7 @@ qemuConnectGetMaxVcpus(virConnectPtr conn 
ATTRIBUTE_UNUSED, const char *type)
 return 16;
 
 if (STRCASEEQ(type, "kvm"))
-return kvmGetMaxVCPUs();
+return virHostCPUGetKVMMaxVCPUs();
 
 if (STRCASEEQ(type, "kqemu"))
 return 1;
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index f38fbec..a528af7 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -37,6 +37,7 @@
 #if HAVE_LINUX_KVM_H
 # include 
 #endif
+#define KVM_DEVICE "/dev/kvm"
 
 #if defined(__FreeBSD__) || defined(__APPLE__)
 # include 
@@ -1286,3 +1287,38 @@ virHostCPUGetThreadsPerSubcore(virArch arch 
ATTRIBUTE_UNUSED)
 }
 
 #endif /* HAVE_LINUX_KVM_H && defined(KVM_CAP_PPC_SMT) */
+
+#ifndef KVM_CAP_NR_VCPUS
+# define KVM_CAP_NR_VCPUS 9   /* returns max vcpus per vm */
+#endif
+
+int
+virHostCPUGetKVMMaxVCPUs(void)
+{
+int fd;
+int ret;
+
+if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) {
+virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE);
+return -1;
+}
+
+#ifdef KVM_CAP_MAX_VCPUS
+/* at first try KVM_CAP_MAX_VCPUS to determine the maximum count */
+if ((ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS)) > 0)
+goto cleanup;
+#endif /* KVM_CAP_MAX_VCPUS */
+
+/* as a fallback get KVM_CAP_NR_VCPUS (the recommended maximum number of
+ * vcpus). Note that on most machines this is set to 160. */
+if ((ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS)) > 0)
+goto cleanup;
+
+/* if KVM_CAP_NR_VCPUS doesn't exist either, kernel documentation states
+ * that 4 should be used as the maximum number of cpus */
+ret = 4;
+
+ cleanup:
+VIR_FORCE_CLOSE(fd);
+return ret;
+}
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
index e5ffc70..bc9cf98 100644
--- a/src/util/virhostcpu.h
+++ b/src/util/virhostcpu.h
@@ -51,4 +51,6 @@ int virHostCPUGetInfo(virArch hostarch,
   unsigned int *cores,
   unsigned int *threads);
 
+int virHostCPUGetKVMMaxVCPUs(void);
+
 #endif /* __VIR_HOSTCPU_H__*/

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


Re: [libvirt] [PATCH 0/4] Fix the domain capabilities wrt maxvcpus

2016-06-24 Thread Shivaprasad G Bhat


On 06/22/2016 08:55 PM, Andrea Bolognani wrote:

On Wed, 2016-06-15 at 09:54 +, Shivaprasad G Bhat wrote:

This series addresses the comments to my patch in
http://www.redhat.com/archives/libvir-list/2016-May/msg00218.html
  
The v2 got quite a lot of criticism to not to change the virConnectGetMaxVCPUS()

instead document to use the virConnectGetDomainCapabilities().
The virConnectGetDomainCapabilities() is extended to check for the host limits
and the NR_CPUs are also returned. I am planning to follow up this series
with possible fixes to maxvcpus command once this merged.

Sorry for being late in reviewing this series.

If you can post a v2 addressing my comments in the next
couple of days, there's still time for it to be merged
in time for 2.0.0 - the freeze is on Sunday.
Thanks Andrea. As discussed with you on IRC, I am dropping my changes 
for "suggested" cpus in
the next version and follow it up separately, so just the bug fix is 
easier for the build.

Please note that it doesn't apply cleanly on top of
current master, but the conflict is easy enough to fix.

--
Andrea Bolognani
Software Engineer - Virtualization Team



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


[libvirt] [PATCH 4/4] Check the kvm host cpu max limits in virConnectGetDomainCapabilities()

2016-06-15 Thread Shivaprasad G Bhat
The qemu limit and host limit both should be considered for
the domain vcpu max limits.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 docs/formatdomaincaps.html.in  |4 ++--
 src/conf/domain_capabilities.c |   10 +++---
 src/conf/domain_capabilities.h |1 +
 src/qemu/qemu_capabilities.c   |   13 ++---
 src/qemu/qemu_capabilities.h   |3 ++-
 src/qemu/qemu_driver.c |2 +-
 tests/domaincapstest.c |3 ++-
 7 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
index d5a8414..d28a5b6 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -86,14 +86,14 @@
 
 domainCapabilities
   ...
-  vcpu max='255'/
+  vcpu max='255' suggested='96'/
   ...
 /domainCapabilities
 
 
 
   vcpu
-  The maximum number of supported virtual CPUs
+  The maximum number of supported virtual CPUs. The suggested 
attribute if present, gives the recommended maximum vcpus for the KVM host.
 
 
 BIOS bootloader
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index 1676f0e..452cad4 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -329,9 +329,13 @@ virDomainCapsFormatInternal(virBufferPtr buf,
 virBufferAsprintf(buf, "%s\n", caps->machine);
 virBufferAsprintf(buf, "%s\n", arch_str);
 
-if (caps->maxvcpus)
-virBufferAsprintf(buf, "\n", caps->maxvcpus);
-
+if (caps->maxvcpus) {
+if (!caps->suggestedvcpus)
+virBufferAsprintf(buf, "\n", caps->maxvcpus);
+else
+virBufferAsprintf(buf, "\n",
+  caps->maxvcpus, caps->suggestedvcpus);
+}
 virDomainCapsOSFormat(buf, >os);
 
 virBufferAddLit(buf, "\n");
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 492a9cf..f440436 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -112,6 +112,7 @@ struct _virDomainCaps {
 
 /* Some machine specific info */
 int maxvcpus;
+int suggestedvcpus;
 
 virDomainCapsOS os;
 virDomainCapsDeviceDisk disk;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1ef5937..df10aa8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -38,6 +38,7 @@
 #include "virbitmap.h"
 #include "virnodesuspend.h"
 #include "virnuma.h"
+#include "virhostcpu.h"
 #include "qemu_monitor.h"
 #include "virstring.h"
 #include "qemu_hostdev.h"
@@ -4333,16 +4334,22 @@ int
 virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
   virQEMUCapsPtr qemuCaps,
   virFirmwarePtr *firmwares,
-  size_t nfirmwares)
+  size_t nfirmwares,
+  virDomainVirtType virttype)
 {
 virDomainCapsOSPtr os = >os;
 virDomainCapsDeviceDiskPtr disk = >disk;
 virDomainCapsDeviceHostdevPtr hostdev = >hostdev;
 virDomainCapsDeviceGraphicsPtr graphics = >graphics;
 virDomainCapsDeviceVideoPtr video = >video;
-int maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, domCaps->machine);
+int hostmaxvcpus = 0;
 
-domCaps->maxvcpus = maxvcpus;
+domCaps->maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, 
domCaps->machine);
+if (virttype == VIR_DOMAIN_VIRT_KVM) {
+hostmaxvcpus = virHostCPUGetKVMVCPUs(VIR_HOSTCPU_KVM_MAXVCPUS);
+domCaps->suggestedvcpus = 
virHostCPUGetKVMVCPUs(VIR_HOSTCPU_KVM_NR_VCPUS);
+domCaps->maxvcpus = MIN(domCaps->maxvcpus, hostmaxvcpus);
+}
 
 if (virQEMUCapsFillDomainOSCaps(os, firmwares, nfirmwares) < 0 ||
 virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps,
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index f7ede4a..ffe07e5 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -494,6 +494,7 @@ int virQEMUCapsInitGuestFromBinary(virCapsPtr caps,
 int virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
   virQEMUCapsPtr qemuCaps,
   virFirmwarePtr *firmwares,
-  size_t nfirmwares);
+  size_t nfirmwares,
+  virDomainVirtType virttype);
 
 #endif /* __QEMU_CAPABILITIES_H__*/
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6b316a0..21aa053 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18485,7 +18485,7 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
 goto cleanup;
 
 if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps,
-  cfg->firmwares, cfg->nfirmwares) < 0)
+

[libvirt] [PATCH 3/4] Check for VFIO too where the Legacy passthrough is checked

2016-06-15 Thread Shivaprasad G Bhat
On PPC the Legacy patthrough is not supported and only
VFIO is supported. So, the checks at places to confirm if the
host is passthrough capable checks only Legacy, fix it. This
is seen at only one place now.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 65ef68c..6b316a0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18413,7 +18413,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
 
 cfg = virQEMUDriverGetConfig(driver);
 
-if (qemuHostdevHostSupportsPassthroughLegacy())
+if (qemuHostdevHostSupportsPassthroughLegacy() ||
+qemuHostdevHostSupportsPassthroughVFIO())
 virttype = VIR_DOMAIN_VIRT_KVM;
 else
 virttype = VIR_DOMAIN_VIRT_QEMU;

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


[libvirt] [PATCH 2/4] Rename and move kvmGetMaxVCPUs to utils and extend it

2016-06-15 Thread Shivaprasad G Bhat
This function needs to be used at two different places and make it global
now. Also, extend it to return the NR_CPUs when needed.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/libvirt_private.syms |1 +
 src/qemu/qemu_driver.c   |   52 +-
 src/util/virhostcpu.c|   37 +
 src/util/virhostcpu.h|7 ++
 4 files changed, 46 insertions(+), 51 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e939de3..569f8e8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1066,6 +1066,7 @@ virLogManagerNew;
 nodeCapsInitNUMA;
 nodeGetInfo;
 virHostCPUGetCount;
+virHostCPUGetKVMVCPUs;
 virHostCPUGetMap;
 virHostCPUGetOnlineBitmap;
 virHostCPUGetPresentBitmap;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a45fd55..65ef68c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -122,24 +122,6 @@ VIR_LOG_INIT("qemu.qemu_driver");
 #define QEMU_SCHED_MIN_QUOTA   1000LL
 #define QEMU_SCHED_MAX_QUOTA  18446744073709551LL
 
-#if HAVE_LINUX_KVM_H
-# include 
-#endif
-
-/* device for kvm ioctls */
-#define KVM_DEVICE "/dev/kvm"
-
-/* add definitions missing in older linux/kvm.h */
-#ifndef KVMIO
-# define KVMIO 0xAE
-#endif
-#ifndef KVM_CHECK_EXTENSION
-# define KVM_CHECK_EXTENSION   _IO(KVMIO,   0x03)
-#endif
-#ifndef KVM_CAP_NR_VCPUS
-# define KVM_CAP_NR_VCPUS 9   /* returns max vcpus per vm */
-#endif
-
 #define QEMU_NB_BLKIO_PARAM  6
 
 #define QEMU_NB_BANDWIDTH_PARAM 7
@@ -1269,38 +1251,6 @@ static int qemuConnectIsAlive(virConnectPtr conn 
ATTRIBUTE_UNUSED)
 }
 
 
-static int
-kvmGetMaxVCPUs(void)
-{
-int fd;
-int ret;
-
-if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) {
-virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE);
-return -1;
-}
-
-#ifdef KVM_CAP_MAX_VCPUS
-/* at first try KVM_CAP_MAX_VCPUS to determine the maximum count */
-if ((ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS)) > 0)
-goto cleanup;
-#endif /* KVM_CAP_MAX_VCPUS */
-
-/* as a fallback get KVM_CAP_NR_VCPUS (the recommended maximum number of
- * vcpus). Note that on most machines this is set to 160. */
-if ((ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS)) > 0)
-goto cleanup;
-
-/* if KVM_CAP_NR_VCPUS doesn't exist either, kernel documentation states
- * that 4 should be used as the maximum number of cpus */
-ret = 4;
-
- cleanup:
-VIR_FORCE_CLOSE(fd);
-return ret;
-}
-
-
 static char *
 qemuConnectGetSysinfo(virConnectPtr conn, unsigned int flags)
 {
@@ -1338,7 +1288,7 @@ qemuConnectGetMaxVcpus(virConnectPtr conn 
ATTRIBUTE_UNUSED, const char *type)
 return 16;
 
 if (STRCASEEQ(type, "kvm"))
-return kvmGetMaxVCPUs();
+return virHostCPUGetKVMVCPUs(VIR_HOSTCPU_KVM_MAXVCPUS);
 
 if (STRCASEEQ(type, "kqemu"))
 return 1;
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 00c09cd..5712eda 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -37,6 +37,7 @@
 #if HAVE_LINUX_KVM_H
 # include 
 #endif
+#define KVM_DEVICE "/dev/kvm"
 
 #if defined(__FreeBSD__) || defined(__APPLE__)
 # include 
@@ -1297,3 +1298,39 @@ virHostCPUGetThreadsPerSubcore(virArch arch 
ATTRIBUTE_UNUSED)
 }
 
 #endif /* HAVE_LINUX_KVM_H && defined(KVM_CAP_PPC_SMT) */
+
+#ifndef KVM_CAP_NR_VCPUS
+# define KVM_CAP_NR_VCPUS 9   /* returns max vcpus per vm */
+#endif
+
+int
+virHostCPUGetKVMVCPUs(virHostCPUKVMWrapperFlags flag)
+{
+int fd;
+int ret;
+
+if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) {
+virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE);
+return -1;
+}
+
+#ifdef KVM_CAP_MAX_VCPUS
+/* at first try KVM_CAP_MAX_VCPUS to determine the maximum count */
+if (flag & VIR_HOSTCPU_KVM_MAXVCPUS &&
+(ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS)) > 0)
+goto cleanup;
+#endif /* KVM_CAP_MAX_VCPUS */
+
+/* as a fallback get KVM_CAP_NR_VCPUS (the recommended maximum number of
+ * vcpus). Note that on most machines this is set to 160. */
+if ((flag & VIR_HOSTCPU_KVM_MAXVCPUS || flag & VIR_HOSTCPU_KVM_NR_VCPUS) &&
+(ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS)) > 0)
+ goto cleanup;
+/* if KVM_CAP_NR_VCPUS doesn't exist either, kernel documentation states
+ * that 4 should be used as the maximum number of cpus */
+ret = 4;
+
+ cleanup:
+VIR_FORCE_CLOSE(fd);
+return ret;
+}
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
index e5ffc70..c1b855a 100644
--- a/src/util/virhostcpu.h
+++ b/src/util/virhostcpu.h
@@ -51,4 +51,11 @@ int virHostCPUGetInfo(virArch hostarch,
   unsigned int *cores,
  

[libvirt] [PATCH 1/4] Document to not rely on virConnectGetMaxVcpus API

2016-06-15 Thread Shivaprasad G Bhat
The API virConnectGetMaxVcpus doesnt really reflect the actual usable number
of cpus as the maximum limits can be different for kvm and/or qemu. So update
the documentation to use virConnectGetDomainCapabilities() instead.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/libvirt-host.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index 24277b7..f6b0c30 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -313,7 +313,11 @@ virConnectGetSysinfo(virConnectPtr conn, unsigned int 
flags)
  *
  * Provides the maximum number of virtual CPUs supported for a guest VM of a
  * specific type. The 'type' parameter here corresponds to the 'type'
- * attribute in the  element of the XML.
+ * attribute in the  element of the XML. The API doesn't take emulator
+ * limits into consideration. Hence the maximum reported here can be limited by
+ * the emulator max limits. It is recommended to use the
+ * virConnectGetDomainCapabilities() API specifying the emulator details to get
+ * the accurate results.
  *
  * Returns the maximum of virtual CPU or -1 in case of error.
  */

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


[libvirt] [PATCH 0/4] Fix the domain capabilities wrt maxvcpus

2016-06-15 Thread Shivaprasad G Bhat
This series addresses the comments to my patch in 
http://www.redhat.com/archives/libvir-list/2016-May/msg00218.html

The v2 got quite a lot of criticism to not to change the virConnectGetMaxVCPUS()
instead document to use the virConnectGetDomainCapabilities().
The virConnectGetDomainCapabilities() is extended to check for the host limits
and the NR_CPUs are also returned. I am planning to follow up this series
with possible fixes to maxvcpus command once this merged.

---

Shivaprasad G Bhat (4):
  Document to not rely on virConnectGetMaxVcpus API
  Rename and move kvmGetMaxVCPUs to utils and extend it
  Check for VFIO too where the Legacy passthrough is checked
  Check the kvm host cpu max limits in virConnectGetDomainCapabilities()


 docs/formatdomaincaps.html.in  |4 +--
 src/conf/domain_capabilities.c |   10 +--
 src/conf/domain_capabilities.h |1 +
 src/libvirt-host.c |6 
 src/libvirt_private.syms   |1 +
 src/qemu/qemu_capabilities.c   |   13 +++--
 src/qemu/qemu_capabilities.h   |3 +-
 src/qemu/qemu_driver.c |   57 +++-
 src/util/virhostcpu.c  |   37 ++
 src/util/virhostcpu.h  |7 +
 tests/domaincapstest.c |3 +-
 11 files changed, 78 insertions(+), 64 deletions(-)

--
Signature

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


[libvirt] [PATCH] Call qemuDomainObjEndJob when qemuCaps is null during hotplug

2016-05-25 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 249393a..3f26f1f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8237,7 +8237,7 @@ qemuDomainAttachDeviceFlags(virDomainPtr dom,
 if (priv->qemuCaps)
 qemuCaps = virObjectRef(priv->qemuCaps);
 else if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, 
vm->def->emulator)))
-goto cleanup;
+goto endjob;
 
 if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
 /* Make a copy for updated domain. */
@@ -8490,7 +8490,7 @@ qemuDomainDetachDeviceFlags(virDomainPtr dom,
 if (priv->qemuCaps)
 qemuCaps = virObjectRef(priv->qemuCaps);
 else if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, 
vm->def->emulator)))
-goto cleanup;
+goto endjob;
 
 if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
 /* Make a copy for updated domain. */

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


[libvirt] [PATCH] Unref the cfg in qemuDomainAttachHostPCIDevice()

2016-05-25 Thread Shivaprasad G Bhat
Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 807aaf8..41a0e4f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1164,7 +1164,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 unsigned int flags = 0;
 
 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
-return -1;
+goto cleanup;
 
 if (!cfg->relaxedACS)
 flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;

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


[libvirt] [PATCH v3 05/13] Separate the hostdevice preparation and checks to a new funtion

2016-05-23 Thread Shivaprasad G Bhat
No Functional change.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |   90 +--
 src/qemu/qemu_hotplug.h |5 +++
 2 files changed, 61 insertions(+), 34 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f40b34d..7ae7bf3 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -705,6 +705,59 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr 
driver,
 goto cleanup;
 }
 
+int qemuDomainAttachPCIHostDevicePrepare(virQEMUDriverPtr driver,
+ virDomainDefPtr def,
+ virDomainHostdevDefPtr hostdev,
+ virQEMUCapsPtr qemuCaps)
+{
+virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+unsigned int flags = 0;
+int ret = -1;
+int backend;
+
+if (!cfg->relaxedACS)
+flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
+if (qemuHostdevPreparePCIDevices(driver, def->name, def->uuid,
+ , 1, qemuCaps, flags) < 0)
+goto exit;
+
+/* this could have been changed by qemuHostdevPreparePCIDevices */
+backend = hostdev->source.subsys.u.pci.backend;
+
+switch ((virDomainHostdevSubsysPCIBackendType) backend) {
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
+if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("VFIO PCI device assignment is not "
+ "supported by this version of qemu"));
+goto error;
+}
+break;
+
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
+break;
+
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
+case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("QEMU does not support device assignment mode '%s'"),
+   virDomainHostdevSubsysPCIBackendTypeToString(backend));
+goto error;
+break;
+}
+
+ret = 0;
+ exit:
+virObjectUnref(cfg);
+return ret;
+ error:
+qemuHostdevReAttachPCIDevices(driver, def->name, , 1);
+goto exit;
+}
+
+
+
 
 int
 qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
@@ -1191,44 +1244,16 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 bool teardowncgroup = false;
 bool teardownlabel = false;
 int backend;
-virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
-unsigned int flags = 0;
 
 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
 return -1;
 
-if (!cfg->relaxedACS)
-flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
-if (qemuHostdevPreparePCIDevices(driver, vm->def->name, vm->def->uuid,
- , 1, priv->qemuCaps, flags) < 0)
-goto cleanup;
+if (qemuDomainAttachPCIHostDevicePrepare(driver, vm->def,
+ hostdev, priv->qemuCaps) < 0)
+return -1;
 
-/* this could have been changed by qemuHostdevPreparePCIDevices */
 backend = hostdev->source.subsys.u.pci.backend;
 
-switch ((virDomainHostdevSubsysPCIBackendType) backend) {
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
-if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("VFIO PCI device assignment is not "
- "supported by this version of qemu"));
-goto error;
-}
-break;
-
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
-break;
-
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
-case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-   _("QEMU does not support device assignment mode '%s'"),
-   virDomainHostdevSubsysPCIBackendTypeToString(backend));
-goto error;
-break;
-}
-
 /* Temporarily add the hostdev to the domain definition. This is needed
  * because qemuDomainAdjustMaxMemLock() requires the hostdev to be already
  * part of the domain definition, but other functions like
@@ -1291,7 +1316,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 VIR_FREE(devstr);
 VIR_FREE(configfd_name);
 VIR_FORCE_CLOSE(configfd);
-virObjectUnref(cfg);
 
 return 0;
 
@@ -1312,8 +1336,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 VIR_FREE(configfd_name);
 VIR_FORCE_CLOSE(configfd);
 
- cleanup:
-virObjectUnref(cfg);
 return -1;
 }
 
diff --git a/sr

[libvirt] [PATCH v3 12/13] Pass virDomainDeviceDefListPtr to hotplug functions

2016-05-23 Thread Shivaprasad G Bhat
This actually does all the things as though there were more than one
device in list.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.c  |   50 +++---
 src/qemu/qemu_domain.h  |6 +--
 src/qemu/qemu_driver.c  |   82 +++-
 src/qemu/qemu_hotplug.c |  108 ---
 src/qemu/qemu_hotplug.h |6 +--
 5 files changed, 176 insertions(+), 76 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index da5f97d..9f9ad3a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5528,14 +5528,21 @@ qemuDomainAttachDeviceConfigInternal(virQEMUCapsPtr 
qemuCaps,
 int
 qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
  virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev,
+ virDomainDeviceDefListPtr devlist,
  virConnectPtr conn)
 {
-if (virDomainDefCompatibleDevice(vmdef, dev,
- VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0)
-return -1;
+size_t i;
+
+for (i = 0; i < devlist->count; i++)
+ if (virDomainDefCompatibleDevice(vmdef, devlist->devs[i],
+  VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0)
+ return -1;
 
-return qemuDomainAttachDeviceConfigInternal(qemuCaps, vmdef, dev, conn);
+for (i = 0; i < devlist->count; i++)
+ if (qemuDomainAttachDeviceConfigInternal(qemuCaps, vmdef, 
devlist->devs[i], conn) < 0)
+ return -1;
+
+return 0;
 }
 
 
@@ -5676,13 +5683,20 @@ qemuDomainDetachDeviceConfigInternal(virDomainDefPtr 
vmdef,
 
 int
 qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev)
+ virDomainDeviceDefListPtr devlist)
 {
-if (virDomainDefCompatibleDevice(vmdef, dev,
- VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0)
-return -1;
+size_t i;
+
+for (i = 0; i < devlist->count; i++)
+if (virDomainDefCompatibleDevice(vmdef, devlist->devs[i],
+ VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0)
+return -1;
 
-return qemuDomainDetachDeviceConfigInternal(vmdef, dev);
+for (i = 0; i < devlist->count; i++)
+if (qemuDomainDetachDeviceConfigInternal(vmdef, devlist->devs[i]) < 0)
+return -1;
+
+return 0;
 }
 
 
@@ -5784,11 +5798,17 @@ qemuDomainUpdateDeviceConfigInternal(virQEMUCapsPtr 
qemuCaps,
 int
 qemuDomainUpdateDeviceConfig(virQEMUCapsPtr qemuCaps,
  virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev)
+ virDomainDeviceDefListPtr devlist)
 {
-if (virDomainDefCompatibleDevice(vmdef, dev,
- VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0)
-return -1;
+size_t i;
+for (i = 0; i < devlist->count; i++)
+if (virDomainDefCompatibleDevice(vmdef, devlist->devs[i],
+ VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0)
+return -1;
+
+for (i = 0; i < devlist->count; i++)
+if (qemuDomainUpdateDeviceConfigInternal(qemuCaps, vmdef, 
devlist->devs[i]) < 0)
+return -1;
 
-return qemuDomainUpdateDeviceConfigInternal(qemuCaps, vmdef, dev);
+return 0;
 }
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 82e3308..acb3c4c 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -672,18 +672,18 @@ int qemuDomainDefValidateDiskLunSource(const 
virStorageSource *src)
 int
 qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
  virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev,
+ virDomainDeviceDefListPtr dev,
  virConnectPtr conn);
 
 int
 qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev);
+ virDomainDeviceDefListPtr dev);
 
 
 int
 qemuDomainUpdateDeviceConfig(virQEMUCapsPtr qemuCaps,
  virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev);
+ virDomainDeviceDefListPtr dev);
 
 
 #endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9484576..e970ad6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7460,7 +7460,8 @@ static int qemuDomainAttachDeviceFlags(virDomainPtr dom, 
const char *xml,
 virQEMUDriverPtr driver = dom->conn->privateData;
 virDomainObjPtr vm = NULL;
 virDomainDefPtr vmdef = NULL;
-virDomainDeviceDefPtr dev = NULL, dev_copy = NULL;
+virDomainDeviceD

[libvirt] [PATCH v3 13/13] Enable PCI Multifunction hotplug/unplug

2016-05-23 Thread Shivaprasad G Bhat
The flow is to parse and create a list of devices and pass onto the
hotplug functions.

The patch also removes all checks forbidding the multifunction hotplug.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c  |  166 ++-
 src/qemu/qemu_hotplug.c |   66 +--
 2 files changed, 140 insertions(+), 92 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e970ad6..0519a33 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7453,6 +7453,77 @@ qemuDomainUndefine(virDomainPtr dom)
 return qemuDomainUndefineFlags(dom, 0);
 }
 
+static bool
+qemuDomainPCIAddressIsSingleFunctionAddr(virDomainDeviceDefPtr dev)
+{
+
+virDomainDeviceInfoPtr info = NULL;
+switch ((virDomainDeviceType) dev->type) {
+case VIR_DOMAIN_DEVICE_DISK:
+info = >data.disk->info;
+break;
+case VIR_DOMAIN_DEVICE_NET:
+info = >data.net->info;
+break;
+case VIR_DOMAIN_DEVICE_RNG:
+info = >data.rng->info;
+break;
+case VIR_DOMAIN_DEVICE_HOSTDEV:
+info = dev->data.hostdev->info;
+break;
+case VIR_DOMAIN_DEVICE_CONTROLLER:
+info = >data.controller->info;
+break;
+case VIR_DOMAIN_DEVICE_CHR:
+info = >data.chr->info;
+break;
+case VIR_DOMAIN_DEVICE_FS:
+case VIR_DOMAIN_DEVICE_INPUT:
+case VIR_DOMAIN_DEVICE_SOUND:
+case VIR_DOMAIN_DEVICE_VIDEO:
+case VIR_DOMAIN_DEVICE_WATCHDOG:
+case VIR_DOMAIN_DEVICE_HUB:
+case VIR_DOMAIN_DEVICE_SMARTCARD:
+case VIR_DOMAIN_DEVICE_MEMBALLOON:
+case VIR_DOMAIN_DEVICE_NVRAM:
+case VIR_DOMAIN_DEVICE_SHMEM:
+case VIR_DOMAIN_DEVICE_LEASE:
+case VIR_DOMAIN_DEVICE_REDIRDEV:
+case VIR_DOMAIN_DEVICE_MEMORY:
+case VIR_DOMAIN_DEVICE_NONE:
+case VIR_DOMAIN_DEVICE_TPM:
+case VIR_DOMAIN_DEVICE_PANIC:
+case VIR_DOMAIN_DEVICE_GRAPHICS:
+case VIR_DOMAIN_DEVICE_LAST:
+break;
+}
+
+if (info && info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+/* We do not support hotplug multi-function PCI device now, so we 
should
+ * reserve the whole slot. The function of the PCI device must be 0.
+ */
+if (info->addr.pci.function != 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Single function device addresses with function=0"
+ " expected"));
+return false;
+}
+}
+return true;
+}
+
+static bool isMultifunctionDeviceXML(const char *xml)
+{
+   xmlDocPtr xmlptr;
+
+   if (!(xmlptr = virXMLParse(NULL, xml, _("(device_definition)" {
+   /* We report error anyway later */
+   return false;
+   }
+
+   return STREQ((const char *)(xmlDocGetRootElement(xmlptr))->name, "devices");
+}
+
 
 static int qemuDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
unsigned int flags)
@@ -7469,6 +7540,8 @@ static int qemuDomainAttachDeviceFlags(virDomainPtr dom, 
const char *xml,
 qemuDomainObjPrivatePtr priv;
 virQEMUDriverConfigPtr cfg = NULL;
 virCapsPtr caps = NULL;
+bool multifunction = false;
+size_t i;
 
 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -7494,14 +7567,25 @@ static int qemuDomainAttachDeviceFlags(virDomainPtr 
dom, const char *xml,
 if (virDomainObjUpdateModificationImpact(vm, ) < 0)
 goto endjob;
 
-dev = virDomainDeviceDefParse(xml, vm->def,
- caps, driver->xmlopt,
- parse_flags);
-if (!dev || VIR_ALLOC(devlist) < 0)
-goto endjob;
+multifunction = isMultifunctionDeviceXML(xml);
 
-if (VIR_APPEND_ELEMENT(devlist->devs, devlist->count, dev) < 0)
-goto endjob;
+if (multifunction) {
+if (!(devlist = virDomainDeviceDefParseXMLMany(xml, vm->def,
+   caps, driver->xmlopt,
+   parse_flags)))
+goto endjob;
+if 
(virDomainPCIMultifunctionDeviceAddressValidateAssign(priv->pciaddrs, devlist) 
< 0)
+goto endjob;
+} else {
+dev = virDomainDeviceDefParse(xml, vm->def,
+  caps, driver->xmlopt,
+  parse_flags);
+if (!dev || VIR_ALLOC(devlist) < 0)
+goto endjob;
+if (!qemuDomainPCIAddressIsSingleFunctionAddr(dev) ||
+VIR_APPEND_ELEMENT(devlist->devs, devlist->count, dev) < 0)
+goto endjob;
+}
 
 devcopylist = devlist;
 
@@ -7513,15 +7

[libvirt] [PATCH v3 11/13] Move the detach of PCI device to the beginnging of live hotplug

2016-05-23 Thread Shivaprasad G Bhat
The hostdevices are the only devices which have dependencies
outside of themselves such that, other functions of the PCI
card should also have been detached from host driver before
attempting the hotplug.

This patch moves the detach to the beginning of the hotplug
so that the following patch can detach all funtions first before
attempting to hotplug any.

We need not move the detach for net devices using SRIOV as
all SRIOV devices are single function devices and can be independently
detached as usual.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |   43 ++-
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9a546e2..6821ed5 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -899,6 +899,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
 actualType = virDomainNetGetActualType(net);
 
 if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net);
 /* This is really a "smart hostdev", so it should be attached
  * as a hostdev (the hostdev code will reach over into the
  * netdev-specific code as appropriate), then also added to
@@ -907,8 +908,14 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
  * qemuDomainAttachHostDevice uses a connection to resolve
  * a SCSI hostdev secret, which is not this case, so pass NULL.
  */
-ret = qemuDomainAttachHostDevice(NULL, driver, vm,
- virDomainNetGetActualHostdev(net));
+if (qemuDomainAttachPCIHostDevicePrepare(driver, vm->def,
+ hostdev, priv->qemuCaps) < 0)
+goto cleanup;
+
+ret = qemuDomainAttachHostDevice(NULL, driver, vm, hostdev);
+if (!ret)
+qemuHostdevReAttachPCIDevices(driver, vm->def->name, , 1);
+
 goto cleanup;
 }
 
@@ -1248,10 +1255,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
 return -1;
 
-if (qemuDomainAttachPCIHostDevicePrepare(driver, vm->def,
- hostdev, priv->qemuCaps) < 0)
-return -1;
-
 backend = hostdev->source.subsys.u.pci.backend;
 
 /* Temporarily add the hostdev to the domain definition. This is needed
@@ -1330,8 +1333,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 if (releaseaddr)
 qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
 
-qemuHostdevReAttachPCIDevices(driver, vm->def->name, , 1);
-
 VIR_FREE(devstr);
 VIR_FREE(configfd_name);
 VIR_FORCE_CLOSE(configfd);
@@ -4386,11 +4387,35 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
virDomainDeviceDefPtr dev,
virDomainPtr dom)
 {
+virQEMUDriverPtr driver = dom->conn->privateData;
+virQEMUCapsPtr qemuCaps = NULL;
+qemuDomainObjPrivatePtr priv = vm->privateData;
+
+if (priv->qemuCaps)
+qemuCaps = virObjectRef(priv->qemuCaps);
+else if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, 
vm->def->emulator)))
+return -1;
+
 if (virDomainDefCompatibleDevice(vm->def, dev,
  VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0)
 return -1;
 
-return qemuDomainAttachDeviceLiveInternal(vm, dev, dom);
+if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
+dev->data.hostdev->source.subsys.type == 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+qemuDomainAttachPCIHostDevicePrepare(driver, vm->def, 
dev->data.hostdev, qemuCaps) < 0)
+return -1;
+
+if (qemuDomainAttachDeviceLiveInternal(vm, dev, dom) < 0)
+goto undoprepare;
+
+return 0;
+
+ undoprepare:
+if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
+dev->data.hostdev->source.subsys.type == 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+qemuHostdevReAttachPCIDevices(driver, vm->def->name, 
>data.hostdev, 1);
+
+return -1;
 }
 
 static int

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


[libvirt] [PATCH v3 10/13] Move the virDomainDefCompatibleDevice checks a level down

2016-05-23 Thread Shivaprasad G Bhat
The checks need to be performed per device and its better to do
them a level down in stack as we prepare for multifunction hotplug.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.c  |   12 
 src/qemu/qemu_driver.c  |   24 
 src/qemu/qemu_hotplug.c |   12 
 3 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index bf91db3..da5f97d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5531,6 +5531,10 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
  virDomainDeviceDefPtr dev,
  virConnectPtr conn)
 {
+if (virDomainDefCompatibleDevice(vmdef, dev,
+ VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0)
+return -1;
+
 return qemuDomainAttachDeviceConfigInternal(qemuCaps, vmdef, dev, conn);
 }
 
@@ -5674,6 +5678,10 @@ int
 qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
  virDomainDeviceDefPtr dev)
 {
+if (virDomainDefCompatibleDevice(vmdef, dev,
+ VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0)
+return -1;
+
 return qemuDomainDetachDeviceConfigInternal(vmdef, dev);
 }
 
@@ -5778,5 +5786,9 @@ qemuDomainUpdateDeviceConfig(virQEMUCapsPtr qemuCaps,
  virDomainDefPtr vmdef,
  virDomainDeviceDefPtr dev)
 {
+if (virDomainDefCompatibleDevice(vmdef, dev,
+ VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0)
+return -1;
+
 return qemuDomainUpdateDeviceConfigInternal(qemuCaps, vmdef, dev);
 }
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 98e0bfd..9484576 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7521,20 +7521,12 @@ static int qemuDomainAttachDeviceFlags(virDomainPtr 
dom, const char *xml,
 if (!vmdef)
 goto endjob;
 
-if (virDomainDefCompatibleDevice(vmdef, dev,
- VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0)
-goto endjob;
-
 if ((ret = qemuDomainAttachDeviceConfig(qemuCaps, vmdef, dev,
 dom->conn)) < 0)
 goto endjob;
 }
 
 if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-if (virDomainDefCompatibleDevice(vm->def, dev_copy,
- VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0)
-goto endjob;
-
 if ((ret = qemuDomainAttachDeviceLive(vm, dev_copy, dom)) < 0)
 goto endjob;
 /*
@@ -7648,19 +7640,11 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
 if (!vmdef)
 goto endjob;
 
-if (virDomainDefCompatibleDevice(vmdef, dev,
- VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0)
-goto endjob;
-
 if ((ret = qemuDomainUpdateDeviceConfig(qemuCaps, vmdef, dev)) < 0)
 goto endjob;
 }
 
 if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-if (virDomainDefCompatibleDevice(vm->def, dev_copy,
- VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0)
-goto endjob;
-
 if ((ret = qemuDomainUpdateDeviceLive(dom->conn, vm, dev_copy, dom, 
force)) < 0)
 goto endjob;
 /*
@@ -7768,19 +7752,11 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr 
dom, const char *xml,
 if (!vmdef)
 goto endjob;
 
-if (virDomainDefCompatibleDevice(vmdef, dev,
- VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0)
-goto endjob;
-
 if ((ret = qemuDomainDetachDeviceConfig(vmdef, dev)) < 0)
 goto endjob;
 }
 
 if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-if (virDomainDefCompatibleDevice(vm->def, dev_copy,
- VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0)
-goto endjob;
-
 if ((ret = qemuDomainDetachDeviceLive(vm, dev_copy, dom)) < 0)
 goto endjob;
 /*
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 96caef3..9a546e2 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4386,6 +4386,10 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
virDomainDeviceDefPtr dev,
virDomainPtr dom)
 {
+if (virDomainDefCompatibleDevice(vm->def, dev,
+ VIR_DOMAIN_DEVICE_ACTION_ATTACH) < 0)
+return -1;
+
 return qemuDomainAttachDeviceLiveInternal(vm, dev, dom);
 }
 
@@ -4477,6 +4481,10 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
virDomainDeviceDefPtr dev,
   

[libvirt] [PATCH v3 09/13] Introduce qemuDomain*DeviceConfigInternal

2016-05-23 Thread Shivaprasad G Bhat
This helps moving some checks into the top function
before actually going ahead with the operation.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.c |   45 -
 1 file changed, 36 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e1d3824..bf91db3 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5354,11 +5354,11 @@ qemuDomainDefValidateDiskLunSource(const 
virStorageSource *src)
 return 0;
 }
 
-int
-qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
- virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev,
- virConnectPtr conn)
+static int
+qemuDomainAttachDeviceConfigInternal(virQEMUCapsPtr qemuCaps,
+ virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev,
+ virConnectPtr conn)
 {
 virDomainDiskDefPtr disk;
 virDomainNetDefPtr net;
@@ -5524,9 +5524,20 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
 return 0;
 }
 
+
 int
-qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
- virDomainDeviceDefPtr dev)
+qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
+ virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev,
+ virConnectPtr conn)
+{
+return qemuDomainAttachDeviceConfigInternal(qemuCaps, vmdef, dev, conn);
+}
+
+
+static int
+qemuDomainDetachDeviceConfigInternal(virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev)
 {
 virDomainDiskDefPtr disk, det_disk;
 virDomainNetDefPtr net;
@@ -5660,10 +5671,18 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
 }
 
 int
-qemuDomainUpdateDeviceConfig(virQEMUCapsPtr qemuCaps,
- virDomainDefPtr vmdef,
+qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
  virDomainDeviceDefPtr dev)
 {
+return qemuDomainDetachDeviceConfigInternal(vmdef, dev);
+}
+
+
+static int
+qemuDomainUpdateDeviceConfigInternal(virQEMUCapsPtr qemuCaps,
+ virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev)
+{
 virDomainDiskDefPtr orig, disk;
 virDomainGraphicsDefPtr newGraphics;
 virDomainNetDefPtr net;
@@ -5753,3 +5772,11 @@ qemuDomainUpdateDeviceConfig(virQEMUCapsPtr qemuCaps,
 }
 return 0;
 }
+
+int
+qemuDomainUpdateDeviceConfig(virQEMUCapsPtr qemuCaps,
+ virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev)
+{
+return qemuDomainUpdateDeviceConfigInternal(qemuCaps, vmdef, dev);
+}

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


[libvirt] [PATCH v3 06/13] Move the qemu[*]DomainDeviceConfig to qemu_domain.c

2016-05-23 Thread Shivaprasad G Bhat
No functional change.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_domain.c |  401 
 src/qemu/qemu_domain.h |   17 ++
 src/qemu/qemu_driver.c |  401 
 3 files changed, 418 insertions(+), 401 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b0eb3b6..e1d3824 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -30,6 +30,7 @@
 #include "qemu_parse_command.h"
 #include "qemu_capabilities.h"
 #include "qemu_migration.h"
+#include "qemu_hotplug.h"
 #include "viralloc.h"
 #include "virlog.h"
 #include "virerror.h"
@@ -5352,3 +5353,403 @@ qemuDomainDefValidateDiskLunSource(const 
virStorageSource *src)
 
 return 0;
 }
+
+int
+qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
+ virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr dev,
+ virConnectPtr conn)
+{
+virDomainDiskDefPtr disk;
+virDomainNetDefPtr net;
+virDomainHostdevDefPtr hostdev;
+virDomainLeaseDefPtr lease;
+virDomainControllerDefPtr controller;
+virDomainFSDefPtr fs;
+
+switch ((virDomainDeviceType) dev->type) {
+case VIR_DOMAIN_DEVICE_DISK:
+disk = dev->data.disk;
+if (virDomainDiskIndexByName(vmdef, disk->dst, true) >= 0) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("target %s already exists"), disk->dst);
+return -1;
+}
+if (virStorageTranslateDiskSourcePool(conn, disk) < 0)
+return -1;
+if (qemuCheckDiskConfig(disk) < 0)
+return -1;
+if (virDomainDiskInsert(vmdef, disk))
+return -1;
+/* vmdef has the pointer. Generic codes for vmdef will do all jobs */
+dev->data.disk = NULL;
+if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
+if (virDomainDefAddImplicitDevices(vmdef) < 0)
+return -1;
+if (qemuDomainAssignAddresses(vmdef, qemuCaps, NULL) < 0)
+return -1;
+break;
+
+case VIR_DOMAIN_DEVICE_NET:
+net = dev->data.net;
+if (virDomainNetInsert(vmdef, net))
+return -1;
+dev->data.net = NULL;
+if (qemuDomainAssignAddresses(vmdef, qemuCaps, NULL) < 0)
+return -1;
+break;
+
+case VIR_DOMAIN_DEVICE_HOSTDEV:
+hostdev = dev->data.hostdev;
+if (virDomainHostdevFind(vmdef, hostdev, NULL) >= 0) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+   _("device is already in the domain configuration"));
+return -1;
+}
+if (virDomainHostdevInsert(vmdef, hostdev))
+return -1;
+dev->data.hostdev = NULL;
+if (virDomainDefAddImplicitDevices(vmdef) < 0)
+return -1;
+if (qemuDomainAssignAddresses(vmdef, qemuCaps, NULL) < 0)
+return -1;
+break;
+
+case VIR_DOMAIN_DEVICE_LEASE:
+lease = dev->data.lease;
+if (virDomainLeaseIndex(vmdef, lease) >= 0) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("Lease %s in lockspace %s already exists"),
+   lease->key, NULLSTR(lease->lockspace));
+return -1;
+}
+if (virDomainLeaseInsert(vmdef, lease) < 0)
+return -1;
+
+/* vmdef has the pointer. Generic codes for vmdef will do all jobs */
+dev->data.lease = NULL;
+break;
+
+case VIR_DOMAIN_DEVICE_CONTROLLER:
+controller = dev->data.controller;
+if (virDomainControllerFind(vmdef, controller->type,
+controller->idx) >= 0) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+   _("Target already exists"));
+return -1;
+}
+
+if (virDomainControllerInsert(vmdef, controller) < 0)
+return -1;
+dev->data.controller = NULL;
+
+if (qemuDomainAssignAddresses(vmdef, qemuCaps, NULL) < 0)
+return -1;
+break;
+
+case VIR_DOMAIN_DEVICE_CHR:
+if (qemuDomainChrInsert(vmdef, dev->data.chr) < 0)
+return -1;
+dev->data.chr = NULL;
+if (virDomainDefAddImplicitDevices(vmdef) < 0)
+return -1;
+if (qemuDomainAssignAddresses(vmdef, qemuCaps, NULL) < 0)
+return -1;
+break;
+
+case VIR_DOMAIN_DEVICE_FS:
+fs = dev->data.fs;
+if (virDomainFSIndexByName(vmdef, fs->dst) >= 0) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+ 

[libvirt] [PATCH v3 08/13] Introduce qemuDomain*DeviceLiveInternal

2016-05-23 Thread Shivaprasad G Bhat
This helps moving some checks into the top function
before actually going ahead with the operation.

Signed-off-by: Shivaprasad G Bhat <sb...@linux.vnet.ibm.com>
---
 src/qemu/qemu_hotplug.c |   47 +++
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index c191919..96caef3 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4256,8 +4256,9 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
 return ret;
 }
 
-int
-qemuDomainAttachDeviceLive(virDomainObjPtr vm,
+
+static int
+qemuDomainAttachDeviceLiveInternal(virDomainObjPtr vm,
virDomainDeviceDefPtr dev,
virDomainPtr dom)
 {
@@ -4380,6 +4381,14 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
 return ret;
 }
 
+int
+qemuDomainAttachDeviceLive(virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   virDomainPtr dom)
+{
+return qemuDomainAttachDeviceLiveInternal(vm, dev, dom);
+}
+
 static int
 qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver,
  virDomainObjPtr vm,
@@ -4400,10 +4409,10 @@ qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr 
driver,
 return ret;
 }
 
-int
-qemuDomainDetachDeviceLive(virDomainObjPtr vm,
-   virDomainDeviceDefPtr dev,
-   virDomainPtr dom)
+static int
+qemuDomainDetachDeviceLiveInternal(virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   virDomainPtr dom)
 {
 virQEMUDriverPtr driver = dom->conn->privateData;
 int ret = -1;
@@ -4462,6 +4471,16 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
 return ret;
 }
 
+
+int
+qemuDomainDetachDeviceLive(virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   virDomainPtr dom)
+{
+return qemuDomainDetachDeviceLiveInternal(vm, dev, dom);
+}
+
+
 static int
 qemuDomainChangeDiskLive(virConnectPtr conn,
  virDomainObjPtr vm,
@@ -4542,8 +4561,9 @@ qemuDomainChangeDiskLive(virConnectPtr conn,
 goto cleanup;
 }
 
-int
-qemuDomainUpdateDeviceLive(virConnectPtr conn,
+
+static int
+qemuDomainUpdateDeviceLiveInternal(virConnectPtr conn,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev,
virDomainPtr dom,
@@ -4592,3 +4612,14 @@ qemuDomainUpdateDeviceLive(virConnectPtr conn,
 
 return ret;
 }
+
+int
+qemuDomainUpdateDeviceLive(virConnectPtr conn,
+   virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   virDomainPtr dom,
+   bool force)
+{
+return qemuDomainUpdateDeviceLiveInternal(conn, vm, dev,
+  dom, force);
+}

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


  1   2   3   >