]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Allow multiple panic devices
authorDmitry Andreev <dandreev@virtuozzo.com>
Tue, 24 Nov 2015 12:26:36 +0000 (15:26 +0300)
committerJiri Denemark <jdenemar@redhat.com>
Wed, 25 Nov 2015 13:46:21 +0000 (14:46 +0100)
'model' attribute was added to a panic device but only one panic
device is allowed. This patch changes panic device presence
from 'optional' to 'zeroOrMore'.

docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c
src/qemu/qemu_domain.c
tests/qemuxml2argvdata/qemuxml2argv-panic-double.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-panic-double.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tests/qemuxml2xmltest.c

index 32b196dd2b7a3dd0ffccfc2f1f52e3b1d5b68e03..06aec4b144dec1fcaf005a14f868f3d355032c77 100644 (file)
@@ -6152,6 +6152,7 @@ qemu-kvm -net nic,model=? /dev/null
 <pre>
   ...
   &lt;devices&gt;
+    &lt;panic model='hyperv'/&gt;
     &lt;panic model='isa'&gt;
       &lt;address type='isa' iobase='0x505'/&gt;
     &lt;/panic&gt;
index 9d21650e8f38ef73962fad30a3da1e00a0ccb837..7e7fd583f9a715c74a42dd6803001f3274fc7050 100644 (file)
         <optional>
           <ref name="nvram"/>
         </optional>
-        <optional>
+        <zeroOrMore>
           <ref name="panic"/>
-        </optional>
+        </zeroOrMore>
       </interleave>
     </element>
   </define>
index 58a2d18f43e522a6256550c886434455e87e1cb8..2bddb67e0d26e2b8b349a93681c9c93bffc978ef 100644 (file)
@@ -2538,7 +2538,9 @@ void virDomainDefFree(virDomainDefPtr def)
 
     virDomainTPMDefFree(def->tpm);
 
-    virDomainPanicDefFree(def->panic);
+    for (i = 0; i < def->npanics; i++)
+        virDomainPanicDefFree(def->panics[i]);
+    VIR_FREE(def->panics);
 
     VIR_FREE(def->idmap.uidmap);
     VIR_FREE(def->idmap.gidmap);
@@ -3617,10 +3619,10 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
         if (cb(def, &device, &def->tpm->info, opaque) < 0)
             return -1;
     }
-    if (def->panic) {
-        device.type = VIR_DOMAIN_DEVICE_PANIC;
-        device.data.panic = def->panic;
-        if (cb(def, &device, &def->panic->info, opaque) < 0)
+    device.type = VIR_DOMAIN_DEVICE_PANIC;
+    for (i = 0; i < def->npanics; i++) {
+        device.data.panic = def->panics[i];
+        if (cb(def, &device, &def->panics[i]->info, opaque) < 0)
             return -1;
     }
 
@@ -16406,23 +16408,19 @@ virDomainDefParseXML(xmlDocPtr xml,
     VIR_FREE(nodes);
 
     /* analysis of the panic devices */
-    def->panic = NULL;
     if ((n = virXPathNodeSet("./devices/panic", ctxt, &nodes)) < 0)
         goto error;
-    if (n > 1) {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("only a single panic device is supported"));
+    if (n && VIR_ALLOC_N(def->panics, n) < 0)
         goto error;
-    }
-    if (n > 0) {
+    for (i = 0; i < n; i++) {
         virDomainPanicDefPtr panic =
-            virDomainPanicDefParseXML(nodes[0]);
+            virDomainPanicDefParseXML(nodes[i]);
         if (!panic)
             goto error;
 
-        def->panic = panic;
-        VIR_FREE(nodes);
+        def->panics[def->npanics++] = panic;
     }
+    VIR_FREE(nodes);
 
     /* analysis of the shmem devices */
     if ((n = virXPathNodeSet("./devices/shmem", ctxt, &nodes)) < 0)
@@ -17635,17 +17633,6 @@ static bool
 virDomainPanicDefCheckABIStability(virDomainPanicDefPtr src,
                                    virDomainPanicDefPtr dst)
 {
-    if (!src && !dst)
-        return true;
-
-    if (!src || !dst) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("Target domain panic device count '%d' "
-                         "does not match source count '%d'"),
-                       src ? 1 : 0, dst ? 1 : 0);
-        return false;
-    }
-
     if (src->model != dst->model) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target panic model '%s' does not match source '%s'"),
@@ -18132,8 +18119,17 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
         if (!virDomainRNGDefCheckABIStability(src->rngs[i], dst->rngs[i]))
             goto error;
 
-    if (!virDomainPanicDefCheckABIStability(src->panic, dst->panic))
+    if (src->npanics != dst->npanics) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain panic device count %zu "
+                         "does not match source %zu"), dst->npanics, src->npanics);
         goto error;
+    }
+
+    for (i = 0; i < src->npanics; i++) {
+        if (!virDomainPanicDefCheckABIStability(src->panics[i], dst->panics[i]))
+            goto error;
+    }
 
     if (src->nshmems != dst->nshmems) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -22451,9 +22447,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
     if (def->nvram)
         virDomainNVRAMDefFormat(buf, def->nvram, flags);
 
-    if (def->panic &&
-        virDomainPanicDefFormat(buf, def->panic) < 0)
-        goto error;
+    for (n = 0; n < def->npanics; n++)
+        if (virDomainPanicDefFormat(buf, def->panics[n]) < 0)
+            goto error;
 
     for (n = 0; n < def->nshmems; n++)
         if (virDomainShmemDefFormat(buf, def->shmems[n], flags) < 0)
index 11d891fb5e454e73ed26a97fd4a2434e6ce35ebc..038d65b059af076f6e79bde84080be0db1ae38ae 100644 (file)
@@ -2316,6 +2316,9 @@ struct _virDomainDef {
     size_t nmems;
     virDomainMemoryDefPtr *mems;
 
+    size_t npanics;
+    virDomainPanicDefPtr *panics;
+
     /* Only 1 */
     virDomainWatchdogDefPtr watchdog;
     virDomainMemballoonDefPtr memballoon;
@@ -2324,7 +2327,6 @@ struct _virDomainDef {
     virCPUDefPtr cpu;
     virSysinfoDefPtr sysinfo;
     virDomainRedirFilterDefPtr redirfilter;
-    virDomainPanicDefPtr panic;
 
     void *namespaceData;
     virDomainXMLNamespace ns;
index e83be585e9b1b3d1400965d6e2417900739ab598..a0947b2aa3bb07d8d510a0e28628a8deec0c1913 100644 (file)
@@ -7577,14 +7577,16 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
         }
     }
 
-    if (def->panic &&
-        def->panic->model == VIR_DOMAIN_PANIC_MODEL_HYPERV) {
-        if (!have_cpu) {
-            virBufferAdd(&buf, default_model, -1);
-            have_cpu = true;
-        }
+    for (i = 0; i < def->npanics; i++) {
+        if (def->panics[i]->model == VIR_DOMAIN_PANIC_MODEL_HYPERV) {
+            if (!have_cpu) {
+                virBufferAdd(&buf, default_model, -1);
+                have_cpu = true;
+            }
 
-        virBufferAddLit(&buf, ",hv_crash");
+            virBufferAddLit(&buf, ",hv_crash");
+            break;
+        }
     }
 
     if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
@@ -11059,8 +11061,8 @@ qemuBuildCommandLine(virConnectPtr conn,
         goto error;
     }
 
-    if (def->panic) {
-        switch ((virDomainPanicModel) def->panic->model) {
+    for (i = 0; i < def->npanics; i++) {
+        switch ((virDomainPanicModel) def->panics[i]->model) {
         case VIR_DOMAIN_PANIC_MODEL_HYPERV:
             /* Panic with model 'hyperv' is not a device, it should
              * be configured in cpu commandline. The address
@@ -11071,7 +11073,7 @@ qemuBuildCommandLine(virConnectPtr conn,
                                  "panic device of model 'hyperv'"));
                 goto error;
             }
-            if (def->panic->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+            if (def->panics[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                _("setting the panic device address is not "
                                  "supported for model 'hyperv'"));
@@ -11090,7 +11092,7 @@ qemuBuildCommandLine(virConnectPtr conn,
                                  "of model 'pseries'"));
                 goto error;
             }
-            if (def->panic->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+            if (def->panics[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                _("setting the panic device address is not "
                                  "supported for model 'pseries'"));
@@ -11106,11 +11108,11 @@ qemuBuildCommandLine(virConnectPtr conn,
                 goto error;
             }
 
-            switch (def->panic->info.type) {
+            switch (def->panics[i]->info.type) {
             case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA:
                 virCommandAddArg(cmd, "-device");
                 virCommandAddArgFormat(cmd, "pvpanic,ioport=%d",
-                                       def->panic->info.addr.isa.iobase);
+                                       def->panics[i]->info.addr.isa.iobase);
                 break;
 
             case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
@@ -12480,12 +12482,22 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
                     goto cleanup;
             }
         } else if (STREQ(tokens[i], "hv_crash")) {
-            virDomainPanicDefPtr panic;
-            if (VIR_ALLOC(panic) < 0)
-                goto cleanup;
-
-            panic->model = VIR_DOMAIN_PANIC_MODEL_HYPERV;
-            dom->panic = panic;
+            size_t j;
+            for (j = 0; j < dom->npanics; j++) {
+                 if (dom->panics[j]->model == VIR_DOMAIN_PANIC_MODEL_HYPERV)
+                     break;
+            }
+
+            if (j == dom->npanics) {
+                virDomainPanicDefPtr panic;
+                if (VIR_ALLOC(panic) < 0 ||
+                    VIR_APPEND_ELEMENT_COPY(dom->panics,
+                                            dom->npanics, panic) < 0) {
+                    VIR_FREE(panic);
+                    goto cleanup;
+                }
+                panic->model = VIR_DOMAIN_PANIC_MODEL_HYPERV;
+            }
         } else if (STRPREFIX(tokens[i], "hv_")) {
             const char *token = tokens[i] + 3; /* "hv_" */
             const char *feature, *value;
index 689abc2830ce768051ec9b6b479b60497ecf12ae..8e6c0380b36807d25201f93f16b9e2770b9c981e 100644 (file)
@@ -1178,12 +1178,23 @@ qemuDomainDefPostParse(virDomainDefPtr def,
                                   VIR_DOMAIN_INPUT_BUS_USB) < 0)
         goto cleanup;
 
-    if (addPanicDevice && !def->panic) {
-        virDomainPanicDefPtr panic;
-        if (VIR_ALLOC(panic) < 0)
-            goto cleanup;
+    if (addPanicDevice) {
+        size_t j;
+        for (j = 0; j < def->npanics; j++) {
+            if (def->panics[j]->model == VIR_DOMAIN_PANIC_MODEL_DEFAULT ||
+                def->panics[j]->model == VIR_DOMAIN_PANIC_MODEL_PSERIES)
+                break;
+        }
 
-        def->panic = panic;
+        if (j == def->npanics) {
+            virDomainPanicDefPtr panic;
+            if (VIR_ALLOC(panic) < 0 ||
+                VIR_APPEND_ELEMENT_COPY(def->panics,
+                                        def->npanics, panic) < 0) {
+                VIR_FREE(panic);
+                goto cleanup;
+            }
+        }
     }
 
     ret = 0;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-panic-double.args b/tests/qemuxml2argvdata/qemuxml2argv-panic-double.args
new file mode 100644 (file)
index 0000000..0d3a385
--- /dev/null
@@ -0,0 +1,21 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-cpu qemu32,hv_crash \
+-m 214 \
+-smp 6 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefconfig \
+-nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-boot n \
+-usb \
+-device pvpanic,ioport=1285
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-panic-double.xml b/tests/qemuxml2argvdata/qemuxml2argv-panic-double.xml
new file mode 100644 (file)
index 0000000..aadb758
--- /dev/null
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>6</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='network'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <controller type='usb' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='none'/>
+    <panic model='hyperv'/>
+    <panic model='isa'>
+      <address type='isa' iobase='0x505'/>
+    </panic>
+  </devices>
+</domain>
index a15305d2a5b5f9473054a688cfb32f6594957087..ea16c9829a920cb536793b46ca16139481accd8a 100644 (file)
@@ -1633,6 +1633,8 @@ mymain(void)
 
     DO_TEST("panic", QEMU_CAPS_DEVICE_PANIC,
             QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
+    DO_TEST("panic-double", QEMU_CAPS_DEVICE_PANIC,
+            QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
 
     DO_TEST("panic-no-address", QEMU_CAPS_DEVICE_PANIC,
             QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
index 0e43ee92de27155c5cb2c95ce4e45754147caa7c..fd58331c96a0f26ef815095954f394a2d0fd4e57 100644 (file)
@@ -594,6 +594,7 @@ mymain(void)
     DO_TEST_DIFFERENT("panic");
     DO_TEST("panic-isa");
     DO_TEST("panic-pseries");
+    DO_TEST("panic-double");
     DO_TEST("panic-no-address");
 
     DO_TEST_DIFFERENT("disk-backing-chains");