As one wise man once said about those furry things with no practical purpose: a cat is like a self-aware moving bonsai tree with an attitude. Inspired by this profound quote, introduce a <watchcat> device. A counterpart to <watchdog> that does nothing. If the domain crashes, it just watches. Or purrs. Or wanders around. XML format: <devices> <watchcat breed='persian'/> </devices> Available breeds also include chihuahua, because dogs under 50 lbs are as pointless as cats. Just ask Ron Swanson. Signed-off-by: Ján Tomko <jtomko@xxxxxxxxxx> --- docs/formatdomain.html.in | 26 ++++++++ docs/schemas/domaincommon.rng | 19 ++++++ src/conf/domain_conf.c | 106 +++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 22 +++++++ src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain_address.c | 1 + src/qemu/qemu_driver.c | 6 ++ src/qemu/qemu_hotplug.c | 1 + src/qemu/qemu_process.c | 5 ++ tests/genericxml2xmlindata/watchcat.xml | 18 ++++++ tests/genericxml2xmltest.c | 2 + 11 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 tests/genericxml2xmlindata/watchcat.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 08dc74b6b..bc47b85f1 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8032,6 +8032,32 @@ qemu-kvm -net nic,model=? /dev/null </dd> </dl> + <h4><a id="elementsWatchcat">Watchcat</a></h4> + + <p> + The <code>watchcat</code> element can be used to add a watchcat. + <span class="since">Since 2.4.0</span> + </p> + + <p> + Example: + </p> +<pre> +... +<devices> + <watchcat breed='siamese'/> +</devices> +... +</pre> + <dl> + <dt><code>breed</code></dt> + <dd> + <p> + This attribute is intentionally left undocumented + </p> + </dd> + </dl> + <h3><a id="seclabel">Security label</a></h3> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 8165e699d..58630f68a 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4179,6 +4179,22 @@ </element> </define> + <define name="watchcat"> + <element name="watchcat"> + <attribute name="breed"> + <choice> + <value>persian</value> + <value>blue-swedish</value> + <value>abyssinian</value> + <value>british-shorthair</value> + <value>turkish-angora</value> + <value>chihuahua</value> + <value>siamese</value> + </choice> + </attribute> + </element> + </define> + <define name="input"> <element name="input"> <optional> @@ -4691,6 +4707,9 @@ <optional> <ref name="iommu"/> </optional> + <optional> + <ref name="watchcat"/> + </optional> </interleave> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ae7c0d9b7..d45d40ee8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -59,6 +59,7 @@ #include "virnetdevmacvlan.h" #include "virhostdev.h" #include "virmdev.h" +#include "virrandom.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN @@ -256,7 +257,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, "tpm", "panic", "memory", - "iommu") + "iommu", + "watchcat") VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "none", @@ -929,6 +931,15 @@ VIR_ENUM_IMPL(virDomainShmemModel, VIR_DOMAIN_SHMEM_MODEL_LAST, "ivshmem-plain", "ivshmem-doorbell") +VIR_ENUM_IMPL(virDomainWatchcatBreed, VIR_DOMAIN_WATCHCAT_BREED_LAST, + "persian", + "blue-swedish", + "abyssinian", + "british-shorthair", + "turkish-angora", + "chihuahua", + "siamese") + static virClassPtr virDomainObjClass; static virClassPtr virDomainXMLOptionClass; static void virDomainObjDispose(void *obj); @@ -2739,6 +2750,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def) case VIR_DOMAIN_DEVICE_IOMMU: VIR_FREE(def->data.iommu); break; + case VIR_DOMAIN_DEVICE_WATCHCAT: + VIR_FREE(def->data.watchcat); + break; case VIR_DOMAIN_DEVICE_LAST: case VIR_DOMAIN_DEVICE_NONE: break; @@ -3608,6 +3622,7 @@ virDomainDeviceGetInfo(virDomainDeviceDefPtr device) case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_GRAPHICS: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: case VIR_DOMAIN_DEVICE_NONE: break; @@ -3834,6 +3849,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def, case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: break; } #endif @@ -5010,6 +5026,12 @@ virDomainDefPostParseCommon(virDomainDefPtr def, } } + if (def->watchcat && + def->watchcat->breed == VIR_DOMAIN_WATCHCAT_BREED_CHIHUAHUA) { + virDomainWatchdogDefPtr dawg = def->watchdog; + VIR_FREE(dawg); + } + /* clean up possibly duplicated metadata entries */ virXMLNodeSanitizeNamespaces(def->metadata); @@ -5550,6 +5572,7 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; @@ -15685,6 +15708,39 @@ virDomainIOMMUDefParseXML(xmlNodePtr node, } +static virDomainWatchcatDefPtr +virDomainWatchcatDefParseXML(xmlNodePtr node) +{ + virDomainWatchcatDefPtr watchcat = NULL, ret = NULL; + char *tmp = NULL; + int val; + + if (VIR_ALLOC(watchcat) < 0) + goto cleanup; + + if (!(tmp = virXMLPropString(node, "breed"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing breed for Watchcat device")); + goto cleanup; + } + + if ((val = virDomainWatchcatBreedTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_XML_ERROR, _("unknown Watchcat breed: %s"), tmp); + goto cleanup; + } + + watchcat->breed = val; + + ret = watchcat; + watchcat = NULL; + + cleanup: + VIR_FREE(watchcat); + VIR_FREE(tmp); + return ret; +} + + virDomainDeviceDefPtr virDomainDeviceDefParse(const char *xmlStr, const virDomainDef *def, @@ -15840,6 +15896,10 @@ virDomainDeviceDefParse(const char *xmlStr, if (!(dev->data.iommu = virDomainIOMMUDefParseXML(node, ctxt))) goto error; break; + case VIR_DOMAIN_DEVICE_WATCHCAT: + if (!(dev->data.watchcat = virDomainWatchcatDefParseXML(node))) + goto error; + break; case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; @@ -20243,6 +20303,21 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(nodes); + if ((n = virXPathNodeSet("./devices/watchcat", ctxt, &nodes)) < 0) + goto error; + + if (n > 1) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single Watchcat is supported")); + goto error; + } + + if (n > 0) { + if (!(def->watchcat = virDomainWatchcatDefParseXML(nodes[0]))) + goto error; + } + VIR_FREE(nodes); + /* analysis of the user namespace mapping */ if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0) goto error; @@ -22287,6 +22362,7 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src, case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: break; } #endif @@ -26463,6 +26539,27 @@ virDomainIOMMUDefFormat(virBufferPtr buf, } +static int +virDomainWatchcatDefFormat(virBufferPtr buf, + const virDomainWatchcatDef *watchcat) +{ + virBuffer attrBuf = VIR_BUFFER_INITIALIZER; + int ret = -1; + + virBufferAsprintf(&attrBuf, " breed='%s'", + virDomainWatchcatBreedTypeToString(watchcat->breed)); + + if (virXMLFormatElement(buf, "watchcat", &attrBuf, NULL) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virBufferFreeAndReset(&attrBuf); + return ret; +} + + /* This internal version appends to an existing buffer * (possibly with auto-indent), rather than flattening * to string. @@ -27244,6 +27341,12 @@ virDomainDefFormatInternal(virDomainDefPtr def, virDomainIOMMUDefFormat(buf, def->iommu) < 0) goto error; + if (def->watchcat) { + if (virDomainWatchcatDefFormat(buf, def->watchcat) < 0) + goto error; + if (virRandomInt(100) < 2) + VIR_FREE(def->watchcat); + } virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</devices>\n"); @@ -28370,6 +28473,7 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src, case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_INTERNAL_ERROR, _("Copying definition of '%d' type " diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 61379e50f..6fd4ee6eb 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -157,6 +157,9 @@ typedef virDomainTPMDef *virDomainTPMDefPtr; typedef struct _virDomainIOMMUDef virDomainIOMMUDef; typedef virDomainIOMMUDef *virDomainIOMMUDefPtr; +typedef struct _virDomainWatchcatDef virDomainWatchcatDef; +typedef virDomainWatchcatDef *virDomainWatchcatDefPtr; + typedef struct _virDomainVirtioOptions virDomainVirtioOptions; typedef virDomainVirtioOptions *virDomainVirtioOptionsPtr; @@ -186,6 +189,7 @@ typedef enum { VIR_DOMAIN_DEVICE_PANIC, VIR_DOMAIN_DEVICE_MEMORY, VIR_DOMAIN_DEVICE_IOMMU, + VIR_DOMAIN_DEVICE_WATCHCAT, VIR_DOMAIN_DEVICE_LAST } virDomainDeviceType; @@ -218,6 +222,7 @@ struct _virDomainDeviceDef { virDomainPanicDefPtr panic; virDomainMemoryDefPtr memory; virDomainIOMMUDefPtr iommu; + virDomainWatchcatDefPtr watchcat; } data; }; @@ -2303,6 +2308,21 @@ struct _virDomainIOMMUDef { virTristateSwitch iotlb; }; +typedef enum { + VIR_DOMAIN_WATCHCAT_BREED_PERSIAN, + VIR_DOMAIN_WATCHCAT_BREED_BLUE_SWEDISH, + VIR_DOMAIN_WATCHCAT_BREED_ABYSSINIAN, + VIR_DOMAIN_WATCHCAT_BREED_BRITISH_SHORTHAIR, + VIR_DOMAIN_WATCHCAT_BREED_TURKISH_ANGORA, + VIR_DOMAIN_WATCHCAT_BREED_CHIHUAHUA, + VIR_DOMAIN_WATCHCAT_BREED_SIAMESE, + VIR_DOMAIN_WATCHCAT_BREED_LAST +} virDomainWatchcatBreed; + +struct _virDomainWatchcatDef { + virDomainWatchcatBreed breed; +}; + struct _virDomainVirtioOptions { virTristateSwitch iommu; virTristateSwitch ats; @@ -2448,6 +2468,7 @@ struct _virDomainDef { virSysinfoDefPtr sysinfo; virDomainRedirFilterDefPtr redirfilter; virDomainIOMMUDefPtr iommu; + virDomainWatchcatDefPtr watchcat; void *namespaceData; virDomainXMLNamespace ns; @@ -3345,6 +3366,7 @@ VIR_ENUM_DECL(virDomainMemorySource) VIR_ENUM_DECL(virDomainMemoryAllocation) VIR_ENUM_DECL(virDomainIOMMUModel) VIR_ENUM_DECL(virDomainShmemModel) +VIR_ENUM_DECL(virDomainWatchcatBreed) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainNostateReason) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 580e0f830..c75ce26eb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4978,6 +4978,7 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 37473ebf1..f789cbe92 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -851,6 +851,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev, case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_GRAPHICS: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: case VIR_DOMAIN_DEVICE_NONE: return 0; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7bcc4936d..5ede1edb7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7734,6 +7734,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("live attach of device '%s' is not supported"), @@ -7833,6 +7834,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("live detach of device '%s' is not supported"), @@ -7969,6 +7971,7 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("live update of device '%s' is not supported"), @@ -8155,6 +8158,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent attach of device '%s' is not supported"), @@ -8338,6 +8342,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent detach of device '%s' is not supported"), @@ -8436,6 +8441,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent update of device '%s' is not supported"), diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 49af4d4ff..e8ba3e967 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4507,6 +4507,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_WATCHCAT: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("don't know how to remove a %s device"), diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 1afb71f11..3bd08720b 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2849,6 +2849,9 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuDomainObjPrivatePtr priv = vm->privateData; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + if (vm->def->watchcat) + VIR_WARN("Meow!"); + /* Bring up netdevs before starting CPUs */ if (qemuInterfaceStartDevices(vm->def) < 0) goto cleanup; @@ -4190,6 +4193,8 @@ qemuProcessBeginJob(virQEMUDriverPtr driver, return -1; qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE); + if (vm->def->watchcat) + VIR_WARN("purrr"); return 0; } diff --git a/tests/genericxml2xmlindata/watchcat.xml b/tests/genericxml2xmlindata/watchcat.xml new file mode 100644 index 000000000..daeebfa43 --- /dev/null +++ b/tests/genericxml2xmlindata/watchcat.xml @@ -0,0 +1,18 @@ +<domain type='qemu'> + <name>foo-fighters</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>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> + <watchcat breed='blue-swedish'/> + </devices> +</domain> diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c index d8270a6ca..6438ab2a3 100644 --- a/tests/genericxml2xmltest.c +++ b/tests/genericxml2xmltest.c @@ -141,6 +141,8 @@ mymain(void) DO_TEST_FULL("cachetune-colliding-types", false, true, TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); + DO_TEST("watchcat"); + virObjectUnref(caps); virObjectUnref(xmlopt); -- 2.13.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list