--- /dev/null
+/*
+ * storage_capabilities.c: storage pool capabilities XML processing
+ *
+ * Copyright (C) 2019 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/>.
+ */
+
+#include <config.h>
+
+#include "virerror.h"
+#include "datatypes.h"
+#include "capabilities.h"
+#include "storage_capabilities.h"
+#include "storage_conf.h"
+#include "virlog.h"
+
+#define VIR_FROM_THIS VIR_FROM_CAPABILITIES
+
+VIR_LOG_INIT("conf.storage_capabilities");
+
+static virClassPtr virStoragePoolCapsClass;
+
+
+static void
+virStoragePoolCapsDispose(void *obj)
+{
+ virStoragePoolCapsPtr caps = obj;
+ VIR_DEBUG("obj=%p", caps);
+
+ virObjectUnref(caps->driverCaps);
+}
+
+
+static int
+virStoragePoolCapsOnceInit(void)
+{
+ if (!VIR_CLASS_NEW(virStoragePoolCaps, virClassForObjectLockable()))
+ return -1;
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virStoragePoolCaps);
+
+
+virStoragePoolCapsPtr
+virStoragePoolCapsNew(virCapsPtr driverCaps)
+{
+ virStoragePoolCapsPtr caps = NULL;
+
+ if (virStoragePoolCapsInitialize() < 0)
+ return NULL;
+
+ if (!(caps = virObjectLockableNew(virStoragePoolCapsClass)))
+ return NULL;
+
+ caps->driverCaps = virObjectRef(driverCaps);
+
+ return caps;
+}
+
+
+static bool
+virStoragePoolCapsIsLoaded(virCapsPtr driverCaps,
+ int poolType)
+{
+ size_t i;
+
+ if (!driverCaps)
+ return false;
+
+ for (i = 0; i < driverCaps->npools; i++) {
+ if (driverCaps->pools[i]->type == poolType)
+ return true;
+ }
+
+ return false;
+}
+
+
+static int
+virStoragePoolCapsFormatPool(virBufferPtr buf,
+ int poolType,
+ virStoragePoolCapsPtr const caps)
+{
+ bool isLoaded = virStoragePoolCapsIsLoaded(caps->driverCaps, poolType);
+
+ virBufferAsprintf(buf, "<pool type='%s' supported='%s'>\n",
+ virStoragePoolTypeToString(poolType),
+ isLoaded ? "yes" : "no");
+ virBufferAdjustIndent(buf, 2);
+
+ if (virStoragePoolOptionsFormatPool(buf, poolType) < 0)
+ return -1;
+
+ if (virStoragePoolOptionsFormatVolume(buf, poolType) < 0)
+ return -1;
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</pool>\n");
+ return 0;
+}
+
+
+char *
+virStoragePoolCapsFormat(virStoragePoolCapsPtr const caps)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ size_t i;
+
+ virBufferAddLit(&buf, "<storagepoolCapabilities>\n");
+ virBufferAdjustIndent(&buf, 2);
+ for (i = 0; i < VIR_STORAGE_POOL_LAST; i++) {
+ if (virStoragePoolCapsFormatPool(&buf, i, caps) < 0) {
+ virBufferFreeAndReset(&buf);
+ return NULL;
+ }
+ }
+ virBufferAdjustIndent(&buf, -2);
+ virBufferAddLit(&buf, "</storagepoolCapabilities>\n");
+
+ return virBufferContentAndReset(&buf);
+}
typedef virStorageVolOptions *virStorageVolOptionsPtr;
struct _virStorageVolOptions {
int defaultFormat;
+ int lastFormat;
virStorageVolFormatToString formatToString;
virStorageVolFormatFromString formatFromString;
};
struct _virStoragePoolOptions {
unsigned int flags;
int defaultFormat;
+ int lastFormat;
virStoragePoolXMLNamespace ns;
.flags = (VIR_STORAGE_POOL_SOURCE_NAME |
VIR_STORAGE_POOL_SOURCE_DEVICE),
.defaultFormat = VIR_STORAGE_POOL_LOGICAL_LVM2,
+ .lastFormat = VIR_STORAGE_POOL_LOGICAL_LAST,
.formatFromString = virStoragePoolFormatLogicalTypeFromString,
.formatToString = virStoragePoolFormatLogicalTypeToString,
},
{.poolType = VIR_STORAGE_POOL_DIR,
.volOptions = {
.defaultFormat = VIR_STORAGE_FILE_RAW,
+ .lastFormat = VIR_STORAGE_FILE_LAST,
.formatFromString = virStorageVolumeFormatFromString,
.formatToString = virStorageFileFormatTypeToString,
},
.poolOptions = {
.flags = (VIR_STORAGE_POOL_SOURCE_DEVICE),
.defaultFormat = VIR_STORAGE_POOL_FS_AUTO,
+ .lastFormat = VIR_STORAGE_POOL_FS_LAST,
.formatFromString = virStoragePoolFormatFileSystemTypeFromString,
.formatToString = virStoragePoolFormatFileSystemTypeToString,
},
.volOptions = {
.defaultFormat = VIR_STORAGE_FILE_RAW,
+ .lastFormat = VIR_STORAGE_FILE_LAST,
.formatFromString = virStorageVolumeFormatFromString,
.formatToString = virStorageFileFormatTypeToString,
},
.flags = (VIR_STORAGE_POOL_SOURCE_HOST |
VIR_STORAGE_POOL_SOURCE_DIR),
.defaultFormat = VIR_STORAGE_POOL_NETFS_AUTO,
+ .lastFormat = VIR_STORAGE_POOL_NETFS_LAST,
.formatFromString = virStoragePoolFormatFileSystemNetTypeFromString,
.formatToString = virStoragePoolFormatFileSystemNetTypeToString,
},
.volOptions = {
.defaultFormat = VIR_STORAGE_FILE_RAW,
+ .lastFormat = VIR_STORAGE_FILE_LAST,
.formatFromString = virStorageVolumeFormatFromString,
.formatToString = virStorageFileFormatTypeToString,
},
},
.volOptions = {
.defaultFormat = VIR_STORAGE_FILE_RAW,
+ .lastFormat = VIR_STORAGE_FILE_LAST,
.formatToString = virStorageFileFormatTypeToString,
.formatFromString = virStorageVolumeFormatFromString,
}
.poolOptions = {
.flags = (VIR_STORAGE_POOL_SOURCE_DEVICE),
.defaultFormat = VIR_STORAGE_POOL_DISK_UNKNOWN,
+ .lastFormat = VIR_STORAGE_POOL_DISK_LAST,
.formatFromString = virStoragePoolFormatDiskTypeFromString,
.formatToString = virStoragePoolFormatDiskTypeToString,
},
.volOptions = {
.defaultFormat = VIR_STORAGE_VOL_DISK_NONE,
+ .lastFormat = VIR_STORAGE_VOL_DISK_LAST,
.formatFromString = virStorageVolFormatDiskTypeFromString,
.formatToString = virStorageVolFormatDiskTypeToString,
},
},
.volOptions = {
.defaultFormat = VIR_STORAGE_FILE_RAW,
+ .lastFormat = VIR_STORAGE_FILE_LAST,
.formatFromString = virStorageVolumeFormatFromString,
.formatToString = virStorageFileFormatTypeToString,
},
}
+int
+virStoragePoolOptionsFormatPool(virBufferPtr buf,
+ int type)
+{
+ virStoragePoolOptionsPtr poolOptions;
+
+ if (!(poolOptions = virStoragePoolOptionsForPoolType(type)))
+ return -1;
+
+ if (!poolOptions->formatToString && !poolOptions->flags)
+ return 0;
+
+ virBufferAddLit(buf, "<poolOptions>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ if (poolOptions->formatToString) {
+ size_t i;
+
+ virBufferAsprintf(buf, "<defaultFormat type='%s'/>\n",
+ (poolOptions->formatToString)(poolOptions->defaultFormat));
+
+ virBufferAddLit(buf, "<enum name='sourceFormatType'>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ for (i = 0; i < poolOptions->lastFormat; i++)
+ virBufferAsprintf(buf, "<value>%s</value>\n",
+ (poolOptions->formatToString)(i));
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</enum>\n");
+ }
+
+ if (poolOptions->flags) {
+ virBufferAddLit(buf, "<enum name='requiredSourceElements'>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_HOST)
+ virBufferAddLit(buf, "<value>host</value>\n");
+ if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_DEVICE)
+ virBufferAddLit(buf, "<value>device</value>\n");
+ if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_DIR)
+ virBufferAddLit(buf, "<value>dir</value>\n");
+ if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER)
+ virBufferAddLit(buf, "<value>adapter</value>\n");
+ if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_NAME)
+ virBufferAddLit(buf, "<value>name</value>\n");
+ if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_INITIATOR_IQN)
+ virBufferAddLit(buf, "<value>initiator</value>\n");
+ if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_NETWORK)
+ virBufferAddLit(buf, "<value>network</value>\n");
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</enum>\n");
+ }
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</poolOptions>\n");
+ return 0;
+}
+
+
+int
+virStoragePoolOptionsFormatVolume(virBufferPtr buf,
+ int type)
+{
+ size_t i;
+ virStorageVolOptionsPtr volOptions;
+
+ if (!(volOptions = virStorageVolOptionsForPoolType(type)))
+ return -1;
+
+ if (!volOptions->formatToString)
+ return 0;
+
+ virBufferAddLit(buf, "<volOptions>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ virBufferAsprintf(buf, "<defaultFormat type='%s'/>\n",
+ (volOptions->formatToString)(volOptions->defaultFormat));
+
+ virBufferAddLit(buf, "<enum name='targetFormatType'>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ for (i = 0; i < volOptions->lastFormat; i++)
+ virBufferAsprintf(buf, "<value>%s</value>\n",
+ (volOptions->formatToString)(i));
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</enum>\n");
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</volOptions>\n");
+
+ return 0;
+}
+
+
void
virStorageVolDefFree(virStorageVolDefPtr def)
{