mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 20:15:17 +00:00
Allow multiple panic devices
'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'.
This commit is contained in:
parent
ca6ddffe2c
commit
59fc0d0609
@ -6152,6 +6152,7 @@ qemu-kvm -net nic,model=? /dev/null
|
||||
<pre>
|
||||
...
|
||||
<devices>
|
||||
<panic model='hyperv'/>
|
||||
<panic model='isa'>
|
||||
<address type='isa' iobase='0x505'/>
|
||||
</panic>
|
||||
|
@ -4044,9 +4044,9 @@
|
||||
<optional>
|
||||
<ref name="nvram"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<zeroOrMore>
|
||||
<ref name="panic"/>
|
||||
</optional>
|
||||
</zeroOrMore>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
size_t j;
|
||||
for (j = 0; j < dom->npanics; j++) {
|
||||
if (dom->panics[j]->model == VIR_DOMAIN_PANIC_MODEL_HYPERV)
|
||||
break;
|
||||
}
|
||||
|
||||
panic->model = VIR_DOMAIN_PANIC_MODEL_HYPERV;
|
||||
dom->panic = panic;
|
||||
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;
|
||||
|
@ -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;
|
||||
|
21
tests/qemuxml2argvdata/qemuxml2argv-panic-double.args
Normal file
21
tests/qemuxml2argvdata/qemuxml2argv-panic-double.args
Normal file
@ -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
|
28
tests/qemuxml2argvdata/qemuxml2argv-panic-double.xml
Normal file
28
tests/qemuxml2argvdata/qemuxml2argv-panic-double.xml
Normal file
@ -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>
|
@ -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);
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user