[3/8] qemu: Assign device addresses in PostParse

Message ID 209031ef4d69aabf415b64b180139fe6de82b033.1457454944.git.crobinso@redhat.com
State New
Headers show

Commit Message

Cole Robinson March 8, 2016, 4:36 p.m.
In order to make this work, we need to short circuit the normal
virDomainDefPostParse ordering, and manually add stock devices
ourselves, since we need them in the XML before assigning addresses.

The motivation for this is that upcoming patches will want to perform
generic PostParse checks that need to run _after_ the driver has
assigned all its addresses.

Peter objected to this here:
https://www.redhat.com/archives/libvir-list/2016-January/msg00200.html

Suggesting adding an extra PostParse callback instead. I argued
that change isn't necessarily sufficient either, and that this
method should be safe since all these functions already need to be
idemptotent.

The lone test suite change is due to DomainNativeToXML now calling
qemuDomainAssignAddresses... apparently that's the only test which
hits qemu specific address logic.

There's still quite a few manual callers of qemuDomainAssignAddresses
that could be dropped too but it would need additional testing, and
they shouldn't disrupt anything in the interim since extra calls
will be no-ops.
---
 src/qemu/qemu_domain.c                               | 13 ++++++++++++-
 tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml |  4 +++-
 tests/qemuxml2argvtest.c                             | 20 +++++++-------------
 tests/qemuxml2xmltest.c                              | 12 ++++--------
 4 files changed, 26 insertions(+), 23 deletions(-)

-- 
2.5.0

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

Comments

Cole Robinson March 20, 2016, 9:03 p.m. | #1
On 03/14/2016 02:42 PM, John Ferlan wrote:
> 

> 

> On 03/08/2016 11:36 AM, Cole Robinson wrote:

>> In order to make this work, we need to short circuit the normal

>> virDomainDefPostParse ordering, and manually add stock devices

>> ourselves, since we need them in the XML before assigning addresses.

>>

>> The motivation for this is that upcoming patches will want to perform

>> generic PostParse checks that need to run _after_ the driver has

>> assigned all its addresses.

>>

> 

> Do you mean you need to perform the generic DevicePostParse checks after

> the driver has assigned all its addresses or the generic (domain)

> PostParse checks. Based on reading patch 6 of this series, it seems the

> latter, but the ImplicitDevices check is involved.

> 


After patch #6 I want the control flow to be

virDomainDefPostParse->
   qemuDomainPostParse
     AddImplicitDevices
     qemuDomainAssignAddresses
   virDomainCheckUnallocatedDeviceAddrs

AddImplicitDevices needs to come before qemuDomainAssignAddresses, so the
implicit controllers get addresses allocated by the qemu driver

virDomainCheckUnallocatedDeviceAddrs needs to come after
qemuDomainAssignAddresses.

I want virDomainCheckUnallocatedDeviceAddrs in generic code, so we don't need
to cram it in every HVs PostParse callback.

> <snip>

> 

>> Peter objected to this here:

>> https://www.redhat.com/archives/libvir-list/2016-January/msg00200.html

>>

>> Suggesting adding an extra PostParse callback instead. I argued

>> that change isn't necessarily sufficient either, and that this

>> method should be safe since all these functions already need to be

>> idemptotent.

> 

> 

> The preceding hunk seems to have been more relevant for something after

> the '---' so as to not be included in git history.

> 

> </snip>

> 

> Even without the upcoming patches - it seems to me this patch is

> designed to ensure that once the qemuDomainDefPostParse code adds

> DefaultDevices that we make sure that those devices and the existing

> ones for the domain go through the device post parse processing before

> adding implicit devices and assigning addresses for any devices without one.

> 

> The key of course being the assign addresses which needs to be called

> after each device has been addressed.

> 

> So the problems are:

> 

>  1. We don't add the ImplicitDevices early enough

>  2. We don't assign the DeviceAddress early enough

> 

> where "early enough" is defined as before virDomainDefPostParseInternal

> during virDomainDefPostParse. The chicken/egg problem being that the

> PostParseInternal function calls virDomainDefAddImplicitControllers.

> 

> Another "option" it seems would be to add a 3rd callback mechanism to

> assign addresses for all domains (if supported/necessary). This would be

> called in virDomainDefPostParse before the *DefPostParseInternal. Going

> this way I don't think you need current patch 2...

> 

> So starting with the implicit devices - it doesn't seem there is

> anything in the *PostParseInternal that's adding a device, so instead of

> the current patch 2, can we move that call to virDomainDefPostParse?

> 

> Then patch 3 could add a call to a device address assignment callback,

> such as the following:

> 

> 

> virDomainDefPostParse

>     .domainDefPostCallback (qemuDomainDefPostParse)

>         ...

>         qemuDomainAddDefaultDevices

>         ...

> 

>     virDomainDeviceInfoIterateInternal

>         for each device

>             .devicesPostParseCallback

> 

>     virDomainDefAddImplicitControllers

> 

>     .deviceAssignAddrsPostParseCallback (qemuDomainAssignAddresses)

> 

>     virDomainDefPostParseInternal

> 

> 

> As compared to how I read this patch:

> 

> virDomainDefPostParse

>     .domainDefPostCallback (qemuDomainDefPostParse)

>         ...

>         qemuDomainAddDefaultDevices

>         virDomainDefPostParseDevices

>             for each device

>                 .devicesPostParseCallback

>         virDomainDefAddImplicitDevices

>         qemuDomainAssignAddresses

>         ...

> 

>     virDomainDefPostParseDevices    NOTE: Duplicated for qemu...

>         for each device                   and shouldn't do anything

>             .devicesPostParseCallback

> 

>     virDomainDefPostParseInternal

> 

> FWIW: The rest of this was written first, then I started trying to

> figure out what problem was being solved...  I'll leave the comments as

> is since they point out my thinking while reviewing.

> 


Thank you for your comments. I think the idea of adding a new post parse
callback specifically for assigning addresses is a good one; giving it an
explicit purpose makes it more clear when hv drivers should actually implement
it. And it's probably the lowest effort way to implement all this :)

I'm not going to respond in detail to every point, since if your above
suggestion will eliminate some of the code you responded to.


>> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c

>> index d29073d..aaec9de 100644

>> --- a/tests/qemuxml2argvtest.c

>> +++ b/tests/qemuxml2argvtest.c

>> @@ -277,6 +277,11 @@ static int testCompareXMLToArgvFiles(const char *xml,

>>      if (virBitmapParse("0-3", '\0', &nodeset, 4) < 0)

>>          goto out;

>>  

>> +    virQEMUCapsSetList(extraFlags,

>> +                       QEMU_CAPS_NO_ACPI,

>> +                       QEMU_CAPS_DEVICE,

>> +                       QEMU_CAPS_LAST);

>> +

> 

> Why is this moved unless perhaps the goal was to use the flags in the

> following call...  The 'extraFlags' is only used later anyway in the

> virQEMUCapsFilterByMachineType. Since qemuDomainAssignAddresses was

> removed and the series involves erroring during parse, I started to

> wonder...  especially since the removed call used the extraFlags.

> 


The code now does

virDomainDefParseFile->...->qemuDomainAssignAddresses

and the latter bit depends heavily on QEMU_CAPS flags. extraFlags in this
context is already indirectly wedged into the fake qemu driver state, so its
implicitly sent to qemuDomainAssignAddresses

- Cole

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

Patch hide | download patch | download mbox

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 9044792..d697e99 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1369,7 +1369,7 @@  qemuCanonicalizeMachine(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
 static int
 qemuDomainDefPostParse(virDomainDefPtr def,
                        virCapsPtr caps,
-                       unsigned int parseFlags ATTRIBUTE_UNUSED,
+                       unsigned int parseFlags,
                        void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
@@ -1408,6 +1408,17 @@  qemuDomainDefPostParse(virDomainDefPtr def,
     if (virSecurityManagerVerify(driver->securityManager, def) < 0)
         goto cleanup;
 
+    /* Device defaults are normally set after calling the driver specific
+       PostParse routine (this function), but we need them earlier. */
+    if (virDomainDefPostParseDevices(def, caps,
+                                     parseFlags, driver->xmlopt) < 0)
+        goto cleanup;
+    if (virDomainDefAddImplicitDevices(def) < 0)
+        goto cleanup;
+
+    if (qemuDomainAssignAddresses(def, qemuCaps, NULL) < 0)
+        goto cleanup;
+
     ret = 0;
  cleanup:
     virObjectUnref(qemuCaps);
diff --git a/tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml b/tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml
index 97225f4..c0d7e94 100644
--- a/tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml
+++ b/tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml
@@ -29,7 +29,9 @@ 
     </disk>
     <controller type='usb' index='0'/>
     <controller type='pci' index='0' model='pci-root'/>
-    <controller type='scsi' index='0'/>
+    <controller type='scsi' index='0'>
+      <address type='spapr-vio' reg='0x2000'/>
+    </controller>
     <input type='keyboard' bus='usb'/>
     <input type='mouse' bus='usb'/>
     <graphics type='sdl'/>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index d29073d..aaec9de 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -277,6 +277,11 @@  static int testCompareXMLToArgvFiles(const char *xml,
     if (virBitmapParse("0-3", '\0', &nodeset, 4) < 0)
         goto out;
 
+    virQEMUCapsSetList(extraFlags,
+                       QEMU_CAPS_NO_ACPI,
+                       QEMU_CAPS_DEVICE,
+                       QEMU_CAPS_LAST);
+
     if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt,
                                         (VIR_DOMAIN_DEF_PARSE_INACTIVE |
                                          parseFlags)))) {
@@ -302,11 +307,6 @@  static int testCompareXMLToArgvFiles(const char *xml,
     if (qemuProcessPrepareMonitorChr(&monitor_chr, domainLibDir) < 0)
         goto out;
 
-    virQEMUCapsSetList(extraFlags,
-                       QEMU_CAPS_NO_ACPI,
-                       QEMU_CAPS_DEVICE,
-                       QEMU_CAPS_LAST);
-
     if (STREQ(vmdef->os.machine, "pc") &&
         STREQ(vmdef->emulator, "/usr/bin/qemu-system-x86_64")) {
         VIR_FREE(vmdef->os.machine);
@@ -316,12 +316,6 @@  static int testCompareXMLToArgvFiles(const char *xml,
 
     virQEMUCapsFilterByMachineType(extraFlags, vmdef->os.machine);
 
-    if (qemuDomainAssignAddresses(vmdef, extraFlags, NULL)) {
-        if (flags & FLAG_EXPECT_ERROR)
-            goto ok;
-        goto out;
-    }
-
     log = virtTestLogContentAndReset();
     VIR_FREE(log);
     virResetLastError();
@@ -1420,7 +1414,7 @@  mymain(void)
             QEMU_CAPS_PCI_OHCI, QEMU_CAPS_PCI_MULTIFUNCTION);
     DO_TEST("pseries-vio-user-assigned",
             QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG);
-    DO_TEST_ERROR("pseries-vio-address-clash",
+    DO_TEST_PARSE_ERROR("pseries-vio-address-clash",
             QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG);
     DO_TEST("pseries-nvram", QEMU_CAPS_DEVICE_NVRAM);
     DO_TEST("pseries-usb-kbd", QEMU_CAPS_PCI_OHCI,
@@ -1583,7 +1577,7 @@  mymain(void)
             QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
             QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL);
 
-    DO_TEST_ERROR("pcie-root-port-too-many",
+    DO_TEST_PARSE_ERROR("pcie-root-port-too-many",
             QEMU_CAPS_DEVICE_PCI_BRIDGE,
             QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
             QEMU_CAPS_DEVICE_IOH3420,
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 0735677..251effd 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -37,12 +37,11 @@  struct testInfo {
 };
 
 static int
-qemuXML2XMLPreFormatCallback(virDomainDefPtr def, const void *opaque)
+qemuXML2XMLPreFormatCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+                             const void *opaque ATTRIBUTE_UNUSED)
 {
-    const struct testInfo *info = opaque;
-
-    if (qemuDomainAssignAddresses(def, info->qemuCaps, NULL))
-        return -1;
+    /* Unused for now. But can eventually be used to test
+       qemuAssignDeviceAliases for example */
 
     return 0;
 }
@@ -151,9 +150,6 @@  testCompareStatusXMLToXMLFiles(const void *opaque)
         goto cleanup;
     }
 
-    if (qemuDomainAssignAddresses(obj->def, data->qemuCaps, NULL))
-        goto cleanup;
-
     /* format it back */
     if (!(actual = virDomainObjFormat(driver.xmlopt, obj, NULL,
                                       VIR_DOMAIN_DEF_FORMAT_SECURE))) {