[libvirt] [PATCH RFC 1/4] Introduce domain_capabilities

Michal Privoznik mprivozn at redhat.com
Thu Jun 26 10:18:25 UTC 2014


Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/Makefile.am                |   1 +
 src/conf/domain_capabilities.c | 217 +++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_capabilities.h |  89 +++++++++++++++++
 src/libvirt_private.syms       |   5 +
 4 files changed, 312 insertions(+)
 create mode 100644 src/conf/domain_capabilities.c
 create mode 100644 src/conf/domain_capabilities.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 2b9ac61..e81af0c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -248,6 +248,7 @@ NETDEV_CONF_SOURCES =						\
 DOMAIN_CONF_SOURCES =						\
 		conf/capabilities.c conf/capabilities.h		\
 		conf/domain_addr.c conf/domain_addr.h		\
+		conf/domain_capabilities.c conf/domain_capabilities.h	\
 		conf/domain_conf.c conf/domain_conf.h		\
 		conf/domain_audit.c conf/domain_audit.h		\
 		conf/domain_nwfilter.c conf/domain_nwfilter.h	\
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
new file mode 100644
index 0000000..896aba9
--- /dev/null
+++ b/src/conf/domain_capabilities.c
@@ -0,0 +1,217 @@
+/*
+ * domain_capabilities.c: domain capabilities XML processing
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Michal Privoznik <mprivozn at redhat.com>
+ */
+
+#include <config.h>
+
+#include "domain_capabilities.h"
+#include "domain_conf.h"
+#include "viralloc.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_CAPABILITIES
+
+static virClassPtr virDomainCapsClass;
+
+static void virDomainCapsDispose(void *obj);
+
+static int virDomainCapsOnceInit(void)
+{
+    if (!(virDomainCapsClass = virClassNew(virClassForObjectLockable(),
+                                           "virDomainCapsClass",
+                                           sizeof(virDomainCaps),
+                                           virDomainCapsDispose)))
+        return -1;
+    return 0;
+}
+
+
+VIR_ONCE_GLOBAL_INIT(virDomainCaps)
+
+
+static void
+virDomainCapsDispose(void *obj)
+{
+    virDomainCapsPtr caps = obj;
+
+    VIR_FREE(caps->path);
+    VIR_FREE(caps->machine);
+}
+
+
+virDomainCapsPtr
+virDomainCapsNew(const char *path,
+                 const char *machine,
+                 virArch arch,
+                 virDomainVirtType virttype)
+{
+    virDomainCapsPtr caps = NULL;
+
+    if (virDomainCapsInitialize() < 0)
+        return NULL;
+
+    if (!(caps = virObjectLockableNew(virDomainCapsClass)))
+        return NULL;
+
+    if (VIR_STRDUP(caps->path, path) < 0 ||
+        VIR_STRDUP(caps->machine, machine) < 0)
+        goto error;
+    caps->arch = arch;
+    caps->virttype = virttype;
+
+    return caps;
+ error:
+    virObjectUnref(caps);
+    return NULL;
+}
+
+
+#define FORMAT_PROLOGUE(item)                                       \
+    do {                                                            \
+        virBufferAsprintf(buf, "<" #item " supported='%s'%s\n",     \
+                          item->device.supported ? "yes" : "no",    \
+                          item->device.supported ? ">" : "/>");     \
+        if (!item->device.supported)                                \
+            return;                                                 \
+        virBufferAdjustIndent(buf, 2);                              \
+    } while (0)
+
+#define FORMAT_EPILOGUE(item)                                       \
+    do {                                                            \
+        virBufferAdjustIndent(buf, -2);                             \
+        virBufferAddLit(buf, "</" #item ">\n");                     \
+    } while (0)
+
+static int
+virDomainCapsEnumFormat(virBufferPtr buf,
+                        virDomainCapsEnumPtr capsEnum,
+                        const char *capsEnumName,
+                        virDomainCapsValToStr valToStr)
+{
+    int ret = -1;
+    size_t i;
+
+    virBufferAsprintf(buf, "<enum name='%s'", capsEnumName);
+    if (!capsEnum->values) {
+        virBufferAddLit(buf, "/>\n");
+        ret = 0;
+        goto cleanup;
+    }
+    virBufferAddLit(buf, ">\n");
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < sizeof(capsEnum->values) * CHAR_BIT; i++) {
+        const char *val;
+
+        if (!(capsEnum->values & (1 << i)))
+            continue;
+
+        val = (valToStr)(i);
+        virBufferAsprintf(buf, "<value>%s</value>\n", val);
+    }
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</enum>\n");
+
+    ret = 0;
+ cleanup:
+    return ret;
+}
+
+#define ENUM_PROCESS(master, capsEnum, valToStr)                    \
+    do {                                                            \
+        virDomainCapsEnumFormat(buf, &master->capsEnum,             \
+                                #capsEnum, valToStr);               \
+    } while (0)
+
+static void
+virDomainCapsDeviceDiskFormat(virBufferPtr buf,
+                              virDomainCapsDeviceDiskPtr const disk)
+{
+    FORMAT_PROLOGUE(disk);
+
+    ENUM_PROCESS(disk, diskDevice, virDomainDiskDeviceTypeToString);
+    ENUM_PROCESS(disk, bus, virDomainDiskBusTypeToString);
+
+    FORMAT_EPILOGUE(disk);
+}
+
+
+static void
+virDomainCapsDeviceHostdevFormat(virBufferPtr buf,
+                                 virDomainCapsDeviceHostdevPtr const hostdev)
+{
+    FORMAT_PROLOGUE(hostdev);
+
+    ENUM_PROCESS(hostdev, mode, virDomainHostdevModeTypeToString);
+    ENUM_PROCESS(hostdev, startupPolicy, virDomainStartupPolicyTypeToString);
+    ENUM_PROCESS(hostdev, subsysType, virDomainHostdevSubsysTypeToString);
+    ENUM_PROCESS(hostdev, capsType, virDomainHostdevCapsTypeToString);
+    ENUM_PROCESS(hostdev, pciBackend, virDomainHostdevSubsysPCIBackendTypeToString);
+
+    FORMAT_EPILOGUE(hostdev);
+}
+
+
+static int
+virDomainCapsFormatInternal(virBufferPtr buf,
+                            virDomainCapsPtr const caps)
+{
+    const char *virttype_str = virDomainVirtTypeToString(caps->virttype);
+    const char *arch_str = virArchToString(caps->arch);
+
+    virBufferAddLit(buf, "<emulatorCapabilities>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    virBufferAsprintf(buf, "<path>%s</path>\n", caps->path);
+    virBufferAsprintf(buf, "<domain>%s</domain>\n", virttype_str);
+    virBufferAsprintf(buf, "<machine>%s</machine>\n", caps->machine);
+    virBufferAsprintf(buf, "<arch>%s</arch>\n", arch_str);
+
+    if (caps->maxvcpus)
+        virBufferAsprintf(buf, "<vcpu>%d</vcpu>\n", caps->maxvcpus);
+
+    virBufferAddLit(buf, "<devices>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    virDomainCapsDeviceDiskFormat(buf, &caps->disk);
+    virDomainCapsDeviceHostdevFormat(buf, &caps->hostdev);
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</devices>\n");
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</emulatorCapabilities>\n");
+    return 0;
+}
+
+
+char *
+virDomainCapsFormat(virDomainCapsPtr const caps)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if (virDomainCapsFormatInternal(&buf, caps) < 0) {
+        virBufferFreeAndReset(&buf);
+        return NULL;
+    }
+
+    return virBufferContentAndReset(&buf);
+}
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
new file mode 100644
index 0000000..b42d11f
--- /dev/null
+++ b/src/conf/domain_capabilities.h
@@ -0,0 +1,89 @@
+/*
+ * domain_capabilities.h: domain capabilities XML processing
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Michal Privoznik <mprivozn at redhat.com>
+ */
+
+#ifndef __DOMAIN_CAPABILITIES_H__
+# define __DOMAIN_CAPABILITIES_H__
+
+# include "internal.h"
+# include "domain_conf.h"
+
+typedef const char * (*virDomainCapsValToStr)(int value);
+
+typedef struct _virDomainCaps virDomainCaps;
+typedef virDomainCaps *virDomainCapsPtr;
+
+typedef struct _virDomainCapsEnum virDomainCapsEnum;
+typedef virDomainCapsEnum *virDomainCapsEnumPtr;
+struct _virDomainCapsEnum {
+    unsigned int values; /* Bitmask of values supported in the corresponding enum */
+};
+
+typedef struct _virDomainCapsDevice virDomainCapsDevice;
+typedef virDomainCapsDevice *virDomainCapsDevicePtr;
+struct _virDomainCapsDevice {
+    bool supported; /* true if <devtype> is supported by hypervisor */
+};
+
+typedef struct _virDomainCapsDeviceDisk virDomainCapsDeviceDisk;
+typedef virDomainCapsDeviceDisk *virDomainCapsDeviceDiskPtr;
+struct _virDomainCapsDeviceDisk {
+    virDomainCapsDevice device;
+    virDomainCapsEnum diskDevice;   /* Info about virDomainDiskDevice enum values */
+    virDomainCapsEnum bus;          /* Info about virDomainDiskBus enum values */
+    /* add new fields here */
+};
+
+typedef struct _virDomainCapsDeviceHostdev virDomainCapsDeviceHostdev;
+typedef virDomainCapsDeviceHostdev *virDomainCapsDeviceHostdevPtr;
+struct _virDomainCapsDeviceHostdev {
+    virDomainCapsDevice device;
+    virDomainCapsEnum mode;             /* Info about virDomainHostdevMode */
+    virDomainCapsEnum startupPolicy;    /* Info about virDomainStartupPolicy */
+    virDomainCapsEnum subsysType;       /* Info about virDomainHostdevSubsysType */
+    virDomainCapsEnum capsType;         /* Info about virDomainHostdevCapsType */
+    virDomainCapsEnum pciBackend;       /* Info about virDomainHostdevSubsysPCIBackendType */
+    /* add new fields here */
+};
+
+struct _virDomainCaps {
+    virObjectLockable parent;
+
+    char *path;                     /* path to emulator binary */
+    virDomainVirtType virttype;     /* virtualization type */
+    char *machine;                  /* machine type */
+    virArch arch;                   /* domain architecture */
+
+    /* Some machine specific info */
+    int maxvcpus;
+
+    virDomainCapsDeviceDisk disk;
+    virDomainCapsDeviceHostdev hostdev;
+    /* add new domain devices here */
+};
+
+virDomainCapsPtr virDomainCapsNew(const char *path,
+                                  const char *machine,
+                                  virArch arch,
+                                  virDomainVirtType virttype);
+
+char * virDomainCapsFormat(virDomainCapsPtr const caps);
+#endif /* __DOMAIN_CAPABILITIES_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1e1dd84..6c583b0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -130,6 +130,11 @@ virDomainAuditStop;
 virDomainAuditVcpu;
 
 
+# conf/domain_capabilities.h
+virDomainCapsFormat;
+virDomainCapsNew;
+
+
 # conf/domain_conf.h
 virBlkioDeviceArrayClear;
 virDiskNameToBusDeviceIndex;
-- 
1.8.5.5




More information about the libvir-list mailing list