'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'. --- v5: part of the code was moved out from this commit docs/formatdomain.html.in | 1 + docs/schemas/domaincommon.rng | 4 ++-- src/conf/domain_conf.c | 53 ++++++++++++++++++++----------------------- src/conf/domain_conf.h | 4 +++- src/qemu/qemu_command.c | 50 ++++++++++++++++++++++++---------------- src/qemu/qemu_domain.c | 21 +++++++++++++---- 6 files changed, 77 insertions(+), 56 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 32b196d..06aec4b 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 9d21650..7e7fd58 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 b8738af..ef322f5 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; } @@ -16412,23 +16414,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) @@ -17641,17 +17639,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'"), @@ -18138,8 +18125,16 @@ 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, @@ -22457,9 +22452,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 11d891f..038d65b 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 bb6d5fe..5eb8ac0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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'")); @@ -11084,7 +11086,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'")); @@ -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; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 689abc2..8e6c038 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -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; -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list