Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- 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@xxxxxxxxxx> + */ + +#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@xxxxxxxxxx> + */ + +#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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list