Add code to convert a regular guest volume into a ephemeral pool.
---
src/storage/storage_driver.c | 154 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 151 insertions(+), 3 deletions(-)
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index c82c620..00bf8a5 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -2627,6 +2627,107 @@ storageEphemeralGenerateUniquePoolID(virStoragePoolDefPtr def)
static virStoragePoolPtr
+storageEphemeralCreateGlusterPool(virConnectPtr conn,
+ const char *source,
+ virDomainDiskHostDefPtr host)
+{
+ virStorageDriverStatePtr driver = conn->storagePrivateData;
+ virStoragePoolDefPtr def = NULL;
+ virStoragePoolObjPtr pool = NULL;
+ virStorageBackendPtr backend;
+ virStoragePoolPtr ret = NULL;
+
+ char *volume = NULL;
+ char *path = NULL;
+ char *tmp;
+
+ if (VIR_STRDUP(volume, source) < 0)
+ goto cleanup;
+
+ if ((tmp = strchr(volume, '/')))
+ *tmp++ = '\0';
+
+ if (tmp && virAsprintf(&path, "/%s", tmp) < 0)
+ goto cleanup;
+
+ if (VIR_ALLOC(def) < 0)
+ goto cleanup;
+
+ if (VIR_ALLOC_N(def->source.hosts, 1))
+ goto cleanup;
+
+ def->source.nhost = 1;
+
+ if (VIR_STRDUP(def->source.hosts->name, host->name) < 0)
+ goto cleanup;
+
+ if (host->port &&
+ virStrToLong_i(host->port, NULL, 10, &def->source.hosts->port) <
0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("failed to parse port number '%s'"),
+ host->port);
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC_N(def->name, VIR_UUID_STRING_BUFLEN) < 0)
+ goto cleanup;
+
+ def->source.name = volume;
+ volume = NULL;
+
+ def->source.dir = path;
+ path = NULL;
+
+ def->type = VIR_STORAGE_POOL_GLUSTER;
+
+ storageDriverLock(driver);
+
+ /* generate a unique name */
+ do {
+ if (pool) {
+ virStoragePoolObjUnlock(pool);
+ pool = NULL;
+ }
+
+ storageEphemeralGenerateUniquePoolID(def);
+
+ if ((pool = virStoragePoolObjFindByUUID(&driver->pools, def->uuid)))
+ continue;
+
+ pool = virStoragePoolObjFindByName(&driver->pools, def->name);
+ } while (pool);
+
+ if (!(backend = virStorageBackendForType(def->type)))
+ goto cleanup;
+
+ if (!(pool = virStoragePoolObjAssignDef(&driver->pools, def)))
+ goto cleanup;
+ def = NULL;
+
+ if (backend->startPool &&
+ backend->startPool(conn, pool) < 0) {
+ virStoragePoolObjRemove(&driver->pools, pool);
+ pool = NULL;
+ goto cleanup;
+ }
+
+ pool->active = 1;
+ pool->internal = true;
+
+ ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
+ NULL, NULL);
+
+cleanup:
+ virStoragePoolDefFree(def);
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+ storageDriverUnlock(driver);
+ return ret;
+}
+
+
+
+static virStoragePoolPtr
storageEphemeralCreateDirPool(virConnectPtr conn,
const char *source)
{
@@ -2752,6 +2853,9 @@ static virStorageEphemeralPtr
storageEphemeralCreate(virConnectPtr conn,
int type,
const char *source,
+ int protocol,
+ size_t nhosts,
+ virDomainDiskHostDefPtr hosts,
virDomainDiskSourcePoolDefPtr srcpool)
{
virStorageEphemeralPtr ret = NULL;
@@ -2783,9 +2887,47 @@ storageEphemeralCreate(virConnectPtr conn,
break;
case VIR_DOMAIN_DISK_TYPE_NETWORK:
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("ephemeral network based volumes are not yet
supported"));
- goto error;
+ switch ((enum virDomainDiskProtocol) protocol) {
+ case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
+ if (nhosts != 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Gluster disk supports only 1 source"));
+ goto error;
+ }
+
+ if (!(dirname = mdir_name(source))) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (VIR_STRDUP(filename, last_component(source)) < 1)
+ goto error;
+
+ if (!(ret->pool = storageEphemeralCreateGlusterPool(conn, dirname,
hosts)))
+ goto error;
+
+ if (!(ret->vol = storageEphemeralCreateVol(ret->pool, filename)))
+ goto error;
+
+ break;
+
+ case VIR_DOMAIN_DISK_PROTOCOL_NBD:
+ case VIR_DOMAIN_DISK_PROTOCOL_RBD:
+ case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
+ case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
+ case VIR_DOMAIN_DISK_PROTOCOL_HTTP:
+ case VIR_DOMAIN_DISK_PROTOCOL_HTTPS:
+ case VIR_DOMAIN_DISK_PROTOCOL_FTP:
+ case VIR_DOMAIN_DISK_PROTOCOL_FTPS:
+ case VIR_DOMAIN_DISK_PROTOCOL_TFTP:
+ case VIR_DOMAIN_DISK_PROTOCOL_LAST:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("ephemeral network based volumes using '%s'
"
+ "protocol are not yet supported"),
+ virDomainDiskProtocolTypeToString(protocol));
+ goto error;
+ break;
+ }
break;
case VIR_DOMAIN_DISK_TYPE_VOLUME:
@@ -2820,6 +2962,9 @@ storageEphemeralFromDiskDef(virConnectPtr conn,
return storageEphemeralCreate(conn,
def->type,
def->src,
+ def->protocol,
+ def->nhosts,
+ def->hosts,
def->srcpool);
}
@@ -2832,6 +2977,9 @@ storageEphemeralFromSnapshotDiskDef(virConnectPtr conn,
return storageEphemeralCreate(conn,
def->type,
def->file,
+ def->protocol,
+ def->nhosts,
+ def->hosts,
NULL);
}
--
1.8.5.2