Support multiple watchdog devices

This is already possible with qemu, and actually already happening with
q35 machines and a specified watchdog since q35 already includes a
watchdog we do not include in the XML.  In order to express such
posibility multiple watchdogs need to be supported.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Martin Kletzander 2022-11-08 09:10:57 +01:00
parent c5340d5420
commit 1c61bd718a
17 changed files with 290 additions and 91 deletions

View File

@ -3899,7 +3899,9 @@ void virDomainDefFree(virDomainDef *def)
def->blkio.ndevices); def->blkio.ndevices);
g_free(def->blkio.devices); g_free(def->blkio.devices);
virDomainWatchdogDefFree(def->watchdog); for (i = 0; i < def->nwatchdogs; i++)
virDomainWatchdogDefFree(def->watchdogs[i]);
g_free(def->watchdogs);
virDomainMemballoonDefFree(def->memballoon); virDomainMemballoonDefFree(def->memballoon);
virDomainNVRAMDefFree(def->nvram); virDomainNVRAMDefFree(def->nvram);
@ -4676,10 +4678,10 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def,
if ((rc = cb(def, &device, &def->fss[i]->info, opaque)) != 0) if ((rc = cb(def, &device, &def->fss[i]->info, opaque)) != 0)
return rc; return rc;
} }
if (def->watchdog) { device.type = VIR_DOMAIN_DEVICE_WATCHDOG;
device.type = VIR_DOMAIN_DEVICE_WATCHDOG; for (i = 0; i < def->nwatchdogs; i++) {
device.data.watchdog = def->watchdog; device.data.watchdog = def->watchdogs[i];
if ((rc = cb(def, &device, &def->watchdog->info, opaque)) != 0) if ((rc = cb(def, &device, &def->watchdogs[i]->info, opaque)) != 0)
return rc; return rc;
} }
if (def->memballoon) { if (def->memballoon) {
@ -18909,24 +18911,21 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
VIR_FREE(nodes); VIR_FREE(nodes);
/* analysis of the watchdog devices */ /* analysis of the watchdog devices */
def->watchdog = NULL; n = virXPathNodeSet("./devices/watchdog", ctxt, &nodes);
if ((n = virXPathNodeSet("./devices/watchdog", ctxt, &nodes)) < 0) if (n < 0)
return NULL; return NULL;
if (n > 1) { if (n)
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", def->watchdogs = g_new0(virDomainWatchdogDef *, n);
_("only a single watchdog device is supported")); for (i = 0; i < n; i++) {
return NULL;
}
if (n > 0) {
virDomainWatchdogDef *watchdog; virDomainWatchdogDef *watchdog;
watchdog = virDomainWatchdogDefParseXML(xmlopt, nodes[0], ctxt, flags); watchdog = virDomainWatchdogDefParseXML(xmlopt, nodes[i], ctxt, flags);
if (!watchdog) if (!watchdog)
return NULL; return NULL;
def->watchdog = watchdog; def->watchdogs[def->nwatchdogs++] = watchdog;
VIR_FREE(nodes);
} }
VIR_FREE(nodes);
/* analysis of the memballoon devices */ /* analysis of the memballoon devices */
def->memballoon = NULL; def->memballoon = NULL;
@ -21370,18 +21369,18 @@ virDomainDefCheckABIStabilityFlags(virDomainDef *src,
dst->redirfilter)) dst->redirfilter))
goto error; goto error;
if ((!src->watchdog && dst->watchdog) ||
(src->watchdog && !dst->watchdog)) { if (src->nwatchdogs != dst->nwatchdogs) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target domain watchdog count %d " _("Target domain watchdog device count %zu does not match source %zu"),
"does not match source %d"), dst->nwatchdogs, src->nwatchdogs);
dst->watchdog ? 1 : 0, src->watchdog ? 1 : 0);
goto error; goto error;
} }
if (src->watchdog && for (i = 0; i < src->nwatchdogs; i++) {
!virDomainWatchdogDefCheckABIStability(src->watchdog, dst->watchdog)) if (!virDomainWatchdogDefCheckABIStability(src->watchdogs[i], dst->watchdogs[i]))
goto error; goto error;
}
if ((!src->memballoon && dst->memballoon) || if ((!src->memballoon && dst->memballoon) ||
(src->memballoon && !dst->memballoon)) { (src->memballoon && !dst->memballoon)) {
@ -27672,8 +27671,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
return -1; return -1;
} }
if (def->watchdog) for (n = 0; n < def->nwatchdogs; n++)
virDomainWatchdogDefFormat(buf, def->watchdog, flags); virDomainWatchdogDefFormat(buf, def->watchdogs[n], flags);
if (def->memballoon) if (def->memballoon)
virDomainMemballoonDefFormat(buf, def->memballoon, flags); virDomainMemballoonDefFormat(buf, def->memballoon, flags);
@ -30736,3 +30735,33 @@ virDomainDefHasSpiceGraphics(const virDomainDef *def)
return false; return false;
} }
ssize_t
virDomainWatchdogDefFind(const virDomainDef *def,
const virDomainWatchdogDef *watchdog)
{
size_t i;
for (i = 0; i < def->nwatchdogs; i++) {
const virDomainWatchdogDef *tmp = def->watchdogs[i];
if (tmp->model != watchdog->model)
continue;
if (tmp->action != watchdog->action)
continue;
if (watchdog->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
!virDomainDeviceInfoAddressIsEqual(&watchdog->info, &tmp->info))
continue;
if (watchdog->info.alias &&
STRNEQ_NULLABLE(watchdog->info.alias, tmp->info.alias))
continue;
return i;
}
return -1;
}

View File

@ -3092,15 +3092,18 @@ struct _virDomainDef {
size_t nsysinfo; size_t nsysinfo;
virSysinfoDef **sysinfo; virSysinfoDef **sysinfo;
size_t ncryptos; size_t ncryptos;
virDomainCryptoDef **cryptos; virDomainCryptoDef **cryptos;
size_t nwatchdogs;
virDomainWatchdogDef **watchdogs;
/* At maximum 2 TPMs on the domain if a TPM Proxy is present. */ /* At maximum 2 TPMs on the domain if a TPM Proxy is present. */
size_t ntpms; size_t ntpms;
virDomainTPMDef **tpms; virDomainTPMDef **tpms;
/* Only 1 */ /* Only 1 */
virDomainWatchdogDef *watchdog;
virDomainMemballoonDef *memballoon; virDomainMemballoonDef *memballoon;
virDomainNVRAMDef *nvram; virDomainNVRAMDef *nvram;
virCPUDef *cpu; virCPUDef *cpu;
@ -3562,6 +3565,10 @@ virDomainSoundDef *virDomainSoundDefRemove(virDomainDef *def, size_t idx);
void virDomainAudioDefFree(virDomainAudioDef *def); void virDomainAudioDefFree(virDomainAudioDef *def);
void virDomainMemballoonDefFree(virDomainMemballoonDef *def); void virDomainMemballoonDefFree(virDomainMemballoonDef *def);
void virDomainNVRAMDefFree(virDomainNVRAMDef *def); void virDomainNVRAMDefFree(virDomainNVRAMDef *def);
ssize_t
virDomainWatchdogDefFind(const virDomainDef *def,
const virDomainWatchdogDef *watchdog)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
void virDomainWatchdogDefFree(virDomainWatchdogDef *def); void virDomainWatchdogDefFree(virDomainWatchdogDef *def);
virDomainVideoDef *virDomainVideoDefNew(virDomainXMLOption *xmlopt); virDomainVideoDef *virDomainVideoDefNew(virDomainXMLOption *xmlopt);
void virDomainVideoDefFree(virDomainVideoDef *def); void virDomainVideoDefFree(virDomainVideoDef *def);

View File

@ -6429,9 +6429,9 @@
<ref name="crypto"/> <ref name="crypto"/>
</choice> </choice>
</zeroOrMore> </zeroOrMore>
<optional> <zeroOrMore>
<ref name="watchdog"/> <ref name="watchdog"/>
</optional> </zeroOrMore>
<optional> <optional>
<ref name="memballoon"/> <ref name="memballoon"/>
</optional> </optional>

View File

@ -699,6 +699,7 @@ virDomainVsockDefFree;
virDomainVsockDefNew; virDomainVsockDefNew;
virDomainWatchdogActionTypeFromString; virDomainWatchdogActionTypeFromString;
virDomainWatchdogActionTypeToString; virDomainWatchdogActionTypeToString;
virDomainWatchdogDefFind;
virDomainWatchdogDefFree; virDomainWatchdogDefFree;
virDomainWatchdogModelTypeFromString; virDomainWatchdogModelTypeFromString;
virDomainWatchdogModelTypeToString; virDomainWatchdogModelTypeToString;

View File

@ -555,12 +555,26 @@ qemuAssignDeviceShmemAlias(virDomainDef *def,
void void
qemuAssignDeviceWatchdogAlias(virDomainWatchdogDef *watchdog) qemuAssignDeviceWatchdogAlias(virDomainDef *def,
virDomainWatchdogDef *watchdog,
int idx)
{ {
/* Currently, there's just one watchdog per domain */ ssize_t i = 0;
if (!watchdog->info.alias) if (watchdog->info.alias)
watchdog->info.alias = g_strdup("watchdog0"); return;
if (idx == -1) {
for (i = 0; i < def->nwatchdogs; i++) {
int cur_idx = qemuDomainDeviceAliasIndex(&def->watchdogs[i]->info, "watchdog");
if (cur_idx > idx)
idx = cur_idx;
}
idx++;
}
watchdog->info.alias = g_strdup_printf("watchdog%d", idx);
} }
@ -686,8 +700,8 @@ qemuAssignDeviceAliases(virDomainDef *def)
for (i = 0; i < def->nsmartcards; i++) { for (i = 0; i < def->nsmartcards; i++) {
qemuAssignDeviceSmartcardAlias(def->smartcards[i], i); qemuAssignDeviceSmartcardAlias(def->smartcards[i], i);
} }
if (def->watchdog) { for (i = 0; i < def->nwatchdogs; i++) {
qemuAssignDeviceWatchdogAlias(def->watchdog); qemuAssignDeviceWatchdogAlias(def, def->watchdogs[i], i);
} }
if (def->memballoon && if (def->memballoon &&
def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) { def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) {

View File

@ -61,7 +61,10 @@ void qemuAssignDeviceShmemAlias(virDomainDef *def,
virDomainShmemDef *shmem, virDomainShmemDef *shmem,
int idx); int idx);
void qemuAssignDeviceWatchdogAlias(virDomainWatchdogDef *watchdog); void
qemuAssignDeviceWatchdogAlias(virDomainDef *def,
virDomainWatchdogDef *watchdog,
int idx);
void qemuAssignDeviceInputAlias(virDomainDef *def, void qemuAssignDeviceInputAlias(virDomainDef *def,
virDomainInputDef *input, virDomainInputDef *input,

View File

@ -4050,26 +4050,34 @@ qemuBuildWatchdogCommandLine(virCommand *cmd,
const virDomainDef *def, const virDomainDef *def,
virQEMUCaps *qemuCaps) virQEMUCaps *qemuCaps)
{ {
virDomainWatchdogDef *watchdog = def->watchdog; virDomainWatchdogDef *watchdog = NULL;
g_autoptr(virJSONValue) props = NULL;
const char *action; const char *action;
int actualAction; int actualAction;
ssize_t i = 0;
if (!def->watchdog) if (def->nwatchdogs == 0)
return 0; return 0;
if (qemuCommandAddExtDevice(cmd, &def->watchdog->info, def, qemuCaps) < 0) for (i = 0; i < def->nwatchdogs; i++) {
return -1; g_autoptr(virJSONValue) props = NULL;
if (!(props = qemuBuildWatchdogDevProps(def, watchdog))) watchdog = def->watchdogs[i];
return -1;
if (qemuBuildDeviceCommandlineFromJSON(cmd, props, def, qemuCaps)) if (qemuCommandAddExtDevice(cmd, &watchdog->info, def, qemuCaps) < 0)
return -1; return -1;
if (!(props = qemuBuildWatchdogDevProps(def, watchdog)))
return -1;
if (qemuBuildDeviceCommandlineFromJSON(cmd, props, def, qemuCaps))
return -1;
}
/* qemu doesn't have a 'dump' action; we tell qemu to 'pause', then /* qemu doesn't have a 'dump' action; we tell qemu to 'pause', then
libvirt listens for the watchdog event, and we perform the dump libvirt listens for the watchdog event, and we perform the dump
ourselves. so convert 'dump' to 'pause' for the qemu cli */ ourselves. so convert 'dump' to 'pause' for the qemu cli. The
validator already checked that all watchdogs have the same action.
*/
actualAction = watchdog->action; actualAction = watchdog->action;
if (watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) if (watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP)
actualAction = VIR_DOMAIN_WATCHDOG_ACTION_PAUSE; actualAction = VIR_DOMAIN_WATCHDOG_ACTION_PAUSE;

View File

@ -2342,10 +2342,10 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def,
} }
/* A watchdog - check if it is a PCI device */ /* A watchdog - check if it is a PCI device */
if (def->watchdog && for (i = 0; i < def->nwatchdogs; i++) {
def->watchdog->model == VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB && if (def->watchdogs[i]->model == VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB &&
virDeviceInfoPCIAddressIsWanted(&def->watchdog->info)) { virDeviceInfoPCIAddressIsWanted(&def->watchdogs[i]->info) &&
if (qemuDomainPCIAddressReserveNextAddr(addrs, &def->watchdog->info) < 0) qemuDomainPCIAddressReserveNextAddr(addrs, &def->watchdogs[i]->info) < 0)
return -1; return -1;
} }

View File

@ -7260,12 +7260,13 @@ qemuDomainAttachDeviceConfig(virDomainDef *vmdef,
break; break;
case VIR_DOMAIN_DEVICE_WATCHDOG: case VIR_DOMAIN_DEVICE_WATCHDOG:
if (vmdef->watchdog) { if (virDomainWatchdogDefFind(vmdef, dev->data.watchdog) >= 0) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s", virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain already has a watchdog")); _("device is already in the domain configuration"));
return -1; return -1;
} }
vmdef->watchdog = g_steal_pointer(&dev->data.watchdog);
VIR_APPEND_ELEMENT(vmdef->watchdogs, vmdef->nwatchdogs, dev->data.watchdog);
break; break;
case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_INPUT:
@ -7460,12 +7461,13 @@ qemuDomainDetachDeviceConfig(virDomainDef *vmdef,
case VIR_DOMAIN_DEVICE_WATCHDOG: case VIR_DOMAIN_DEVICE_WATCHDOG:
if (!vmdef->watchdog) { idx = virDomainWatchdogDefFind(vmdef, dev->data.watchdog);
if (idx < 0) {
virReportError(VIR_ERR_DEVICE_MISSING, "%s", virReportError(VIR_ERR_DEVICE_MISSING, "%s",
_("domain has no watchdog")); _("no matching watchdog was found"));
return -1; return -1;
} }
g_clear_pointer(&vmdef->watchdog, virDomainWatchdogDefFree); VIR_DELETE_ELEMENT(vmdef->watchdogs, idx, vmdef->nwatchdogs);
break; break;
case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_INPUT:

View File

@ -2926,15 +2926,9 @@ qemuDomainAttachWatchdog(virDomainObj *vm,
virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_WATCHDOG, { .watchdog = watchdog } }; virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_WATCHDOG, { .watchdog = watchdog } };
g_autoptr(virJSONValue) props = NULL; g_autoptr(virJSONValue) props = NULL;
bool releaseAddress = false; bool releaseAddress = false;
int rv; int rv = 0;
if (vm->def->watchdog) { qemuAssignDeviceWatchdogAlias(vm->def, watchdog, -1);
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain already has a watchdog"));
return -1;
}
qemuAssignDeviceWatchdogAlias(watchdog);
if (watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB) { if (watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@ -2952,10 +2946,13 @@ qemuDomainAttachWatchdog(virDomainObj *vm,
qemuDomainObjEnterMonitor(vm); qemuDomainObjEnterMonitor(vm);
/* QEMU doesn't have a 'dump' action; we tell qemu to 'pause', then if (vm->def->nwatchdogs) {
libvirt listens for the watchdog event, and we perform the dump /* Domain already has a watchdog and all must have the same action. */
ourselves. so convert 'dump' to 'pause' for the qemu cli */ rv = 0;
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SET_ACTION)) { } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SET_ACTION)) {
/* QEMU doesn't have a 'dump' action; we tell qemu to 'pause', then
libvirt listens for the watchdog event, and we perform the dump
ourselves. so convert 'dump' to 'pause' for the qemu cli */
qemuMonitorActionWatchdog watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_KEEP; qemuMonitorActionWatchdog watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_KEEP;
switch (watchdog->action) { switch (watchdog->action) {
@ -3013,7 +3010,7 @@ qemuDomainAttachWatchdog(virDomainObj *vm,
goto cleanup; goto cleanup;
releaseAddress = false; releaseAddress = false;
vm->def->watchdog = watchdog; VIR_APPEND_ELEMENT_COPY(vm->def->watchdogs, vm->def->nwatchdogs, watchdog);
ret = 0; ret = 0;
cleanup: cleanup:
@ -4846,11 +4843,20 @@ static int
qemuDomainRemoveWatchdog(virDomainObj *vm, qemuDomainRemoveWatchdog(virDomainObj *vm,
virDomainWatchdogDef *watchdog) virDomainWatchdogDef *watchdog)
{ {
size_t i = 0;
VIR_DEBUG("Removing watchdog %s from domain %p %s", VIR_DEBUG("Removing watchdog %s from domain %p %s",
watchdog->info.alias, vm, vm->def->name); watchdog->info.alias, vm, vm->def->name);
for (i = 0; i < vm->def->nwatchdogs; i++) {
if (vm->def->watchdogs[i] == watchdog)
break;
}
qemuDomainReleaseDeviceAddress(vm, &watchdog->info); qemuDomainReleaseDeviceAddress(vm, &watchdog->info);
g_clear_pointer(&vm->def->watchdog, virDomainWatchdogDefFree); virDomainWatchdogDefFree(watchdog);
VIR_DELETE_ELEMENT(vm->def->watchdogs, i, vm->def->nwatchdogs);
return 0; return 0;
} }
@ -5603,33 +5609,20 @@ qemuDomainDetachPrepWatchdog(virDomainObj *vm,
virDomainWatchdogDef *match, virDomainWatchdogDef *match,
virDomainWatchdogDef **detach) virDomainWatchdogDef **detach)
{ {
virDomainWatchdogDef *watchdog; ssize_t idx = virDomainWatchdogDefFind(vm->def, match);
*detach = watchdog = vm->def->watchdog; if (idx < 0) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
if (!watchdog) { _("no matching watchdog was found"));
virReportError(VIR_ERR_DEVICE_MISSING, "%s",
_("watchdog device not present in domain configuration"));
return -1; return -1;
} }
/* While domains can have up to one watchdog, the one supplied by the user *detach = vm->def->watchdogs[idx];
* doesn't necessarily match the one domain has. Refuse to detach in such
* case. */
if (!(watchdog->model == match->model &&
watchdog->action == match->action &&
virDomainDeviceInfoAddressIsEqual(&match->info, &watchdog->info))) {
virReportError(VIR_ERR_DEVICE_MISSING,
_("model '%s' watchdog device not present "
"in domain configuration"),
virDomainWatchdogModelTypeToString(watchdog->model));
return -1;
}
if (watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB) { if ((*detach)->model != VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("hot unplug of watchdog of model %s is not supported"), _("hot unplug of watchdog of model %s is not supported"),
virDomainWatchdogModelTypeToString(watchdog->model)); virDomainWatchdogModelTypeToString((*detach)->model));
return -1; return -1;
} }

View File

@ -804,7 +804,8 @@ qemuProcessHandleWatchdog(qemuMonitor *mon G_GNUC_UNUSED,
qemuDomainSaveStatus(vm); qemuDomainSaveStatus(vm);
} }
if (vm->def->watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) { if (vm->def->nwatchdogs &&
vm->def->watchdogs[0]->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) {
qemuProcessEventSubmit(vm, QEMU_PROCESS_EVENT_WATCHDOG, qemuProcessEventSubmit(vm, QEMU_PROCESS_EVENT_WATCHDOG,
VIR_DOMAIN_WATCHDOG_ACTION_DUMP, 0, NULL); VIR_DOMAIN_WATCHDOG_ACTION_DUMP, 0, NULL);
} }

View File

@ -1188,6 +1188,28 @@ qemuValidateDomainDefTPMs(const virDomainDef *def)
} }
static int
qemuValidateDomainDefWatchdogs(const virDomainDef *def)
{
ssize_t i = 0;
for (i = 1; i < def->nwatchdogs; i++) {
/* We could theoretically support different watchdogs having dump and
* pause, but let's be honest, we support multiple watchdogs only
* because we need to be able to add a second, implicit one, not because
* it is a brilliant idea to have multiple watchdogs. */
if (def->watchdogs[i]->action != def->watchdogs[0]->action) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("watchdogs with different actions are not supported "
"with this QEMU binary"));
return -1;
}
}
return 0;
}
int int
qemuValidateLifecycleAction(virDomainLifecycleAction onPoweroff, qemuValidateLifecycleAction(virDomainLifecycleAction onPoweroff,
virDomainLifecycleAction onReboot, virDomainLifecycleAction onReboot,
@ -1388,6 +1410,9 @@ qemuValidateDomainDef(const virDomainDef *def,
if (qemuValidateDomainDefTPMs(def) < 0) if (qemuValidateDomainDefTPMs(def) < 0)
return -1; return -1;
if (qemuValidateDomainDefWatchdogs(def) < 0)
return -1;
if (def->sec) { if (def->sec) {
switch ((virDomainLaunchSecurity) def->sec->sectype) { switch ((virDomainLaunchSecurity) def->sec->sectype) {
case VIR_DOMAIN_LAUNCH_SECURITY_SEV: case VIR_DOMAIN_LAUNCH_SECURITY_SEV:

View File

@ -0,0 +1,39 @@
LC_ALL=C \
PATH=/bin \
HOME=/tmp/lib/domain--1-QEMUGuest1 \
USER=test \
LOGNAME=test \
XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
/usr/bin/qemu-system-x86_64 \
-name guest=QEMUGuest1,debug-threads=on \
-S \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \
-machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram \
-accel tcg \
-cpu qemu64 \
-m 214 \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
-smp 1,sockets=1,cores=1,threads=1 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
-display none \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=utc \
-no-shutdown \
-no-acpi \
-boot strict=on \
-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \
-device '{"driver":"pcie-pci-bridge","id":"pci.2","bus":"pci.1","addr":"0x0"}' \
-device '{"driver":"pcie-root-port","port":9,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x1"}' \
-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.2","addr":"0x1"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
-device '{"driver":"ib700","id":"watchdog0"}' \
-device '{"driver":"i6300esb","id":"watchdog1","bus":"pci.2","addr":"0x2"}' \
-watchdog-action poweroff \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on

View File

@ -0,0 +1,25 @@
<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'>1</vcpu>
<os>
<type arch='x86_64' machine='q35'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<controller type='pci' index='0' model='pcie-root'/>
<controller type='usb' index='0'/>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<watchdog model='ib700' action='poweroff'/>
<watchdog model='i6300esb' action='poweroff'/>
<memballoon model='none'/>
</devices>
</domain>

View File

@ -1756,6 +1756,7 @@ mymain(void)
DO_TEST_CAPS_LATEST("watchdog-device"); DO_TEST_CAPS_LATEST("watchdog-device");
DO_TEST_CAPS_LATEST("watchdog-dump"); DO_TEST_CAPS_LATEST("watchdog-dump");
DO_TEST_CAPS_LATEST("watchdog-injectnmi"); DO_TEST_CAPS_LATEST("watchdog-injectnmi");
DO_TEST_CAPS_LATEST("watchdog-q35-multiple");
DO_TEST_CAPS_ARCH_LATEST("watchdog-diag288", "s390x"); DO_TEST_CAPS_ARCH_LATEST("watchdog-diag288", "s390x");
DO_TEST_NOCAPS("balloon-device"); DO_TEST_NOCAPS("balloon-device");
DO_TEST("balloon-device-deflate", DO_TEST("balloon-device-deflate",

View File

@ -0,0 +1,50 @@
<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'>1</vcpu>
<os>
<type arch='x86_64' machine='q35'>hvm</type>
<boot dev='hd'/>
</os>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<controller type='pci' index='0' model='pcie-root'/>
<controller type='usb' index='0' model='piix3-uhci'>
<address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
</controller>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
</controller>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x8'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='2' model='pcie-to-pci-bridge'>
<model name='pcie-pci-bridge'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</controller>
<controller type='pci' index='3' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='3' port='0x9'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
<watchdog model='ib700' action='poweroff'/>
<watchdog model='i6300esb' action='poweroff'>
<address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0'/>
</watchdog>
<memballoon model='none'/>
</devices>
</domain>

View File

@ -489,6 +489,7 @@ mymain(void)
QEMU_CAPS_HDA_DUPLEX, QEMU_CAPS_HDA_DUPLEX,
QEMU_CAPS_HDA_OUTPUT); QEMU_CAPS_HDA_OUTPUT);
DO_TEST_NOCAPS("watchdog"); DO_TEST_NOCAPS("watchdog");
DO_TEST_CAPS_LATEST("watchdog-q35-multiple");
DO_TEST("net-bandwidth", QEMU_CAPS_DEVICE_VGA, QEMU_CAPS_VNC); DO_TEST("net-bandwidth", QEMU_CAPS_DEVICE_VGA, QEMU_CAPS_VNC);
DO_TEST("net-bandwidth2", QEMU_CAPS_DEVICE_VGA, QEMU_CAPS_VNC); DO_TEST("net-bandwidth2", QEMU_CAPS_DEVICE_VGA, QEMU_CAPS_VNC);
DO_TEST_NOCAPS("net-mtu"); DO_TEST_NOCAPS("net-mtu");