'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 | 1 + docs/schemas/domaincommon.rng | 4 +-- src/conf/domain_conf.c | 73 ++++++++++++++++++------------------------- src/conf/domain_conf.h | 4 ++- src/qemu/qemu_command.c | 50 ++++++++++++++++++----------- src/qemu/qemu_domain.c | 21 ++++++++++--- 6 files changed, 83 insertions(+), 70 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index ef30624..7a14473 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -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> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index d67b1bf..8965976 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4044,9 +4044,9 @@ <optional> <ref name="nvram"/> </optional> - <optional> + <zeroOrMore> <ref name="panic"/> - </optional> + </zeroOrMore> </interleave> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8339280..2f17675 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -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; } @@ -16407,23 +16409,20 @@ 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) @@ -17633,17 +17632,14 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, } static bool -virDomainPanicCheckABIStability(virDomainPanicDefPtr src, +virDomainPanicDefCheckABIStability(virDomainPanicDefPtr src, virDomainPanicDefPtr dst) { - if (!src && !dst) - return true; - - if (!src || !dst) { + if (src->model != dst->model) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain panic device count '%d' " - "does not match source count '%d'"), - src ? 1 : 0, dst ? 1 : 0); + _("Target panic model '%s' does not match source '%s'"), + virDomainPanicModelTypeToString(dst->model), + virDomainPanicModelTypeToString(src->model)); return false; } @@ -17709,13 +17705,6 @@ virDomainTPMDefCheckABIStability(virDomainTPMDefPtr src, } static bool -virDomainPanicDefCheckABIStability(virDomainPanicDefPtr src, - virDomainPanicDefPtr dst) -{ - return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); -} - -static bool virDomainMemoryDefCheckABIStability(virDomainMemoryDefPtr src, virDomainMemoryDefPtr dst) { @@ -18132,8 +18121,16 @@ virDomainDefCheckABIStability(virDomainDefPtr src, if (!virDomainRNGDefCheckABIStability(src->rngs[i], dst->rngs[i])) goto error; - if (!virDomainPanicCheckABIStability(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, @@ -18157,16 +18154,6 @@ virDomainDefCheckABIStability(virDomainDefPtr src, goto error; } - if (src->panic && dst->panic) { - if (!virDomainPanicDefCheckABIStability(src->panic, dst->panic)) - goto error; - } else if (src->panic || dst->panic) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Either both target and source domains or none of " - "them must have PANIC device present")); - goto error; - } - if (src->nmems != dst->nmems) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain memory device count %zu " @@ -22460,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) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index be18994..43f99ac 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -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; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 2d0cec0..965b68e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7623,14 +7623,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) { @@ -11159,8 +11161,8 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } - if (def->panic) { - virDomainPanicModel model = def->panic->model; + for (i = 0; i < def->npanics; i++) { + virDomainPanicModel model = def->panics[i]->model; if (model == VIR_DOMAIN_PANIC_MODEL_DEFAULT) { if (ARCH_IS_PPC64(def->os.arch) && @@ -11175,7 +11177,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* Panic with model 'hyperv' is not a device, it should * be configured in cpu commandline. The address * cannot be configured by the user */ - 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'")); @@ -11188,7 +11190,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* For pSeries guests, the firmware provides the same * functionality as the pvpanic device. The address * cannot be configured by the user */ - 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'")); @@ -11210,11 +11212,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: @@ -12582,12 +12584,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; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3d2b7a0..19ae5f7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1175,12 +1175,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; -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list