[PATCH] Introduce the <watchcat> device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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>
+...
+&lt;devices&gt;
+  &lt;watchcat breed='siamese'/&gt;
+&lt;/devices&gt;
+...
+</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




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux