[libvirt] [PATCH 5/6] Implement translateDiskSourcePool

Osier Yang jyang at redhat.com
Wed Jan 23 11:04:37 UTC 2013


It iterates over all the domain disks, and translate the source for
all the disks of 'pool' source type.

Disks of type 'file', 'block', and 'dir' are supported now. Network
type is not supported yet, it will be another patch.

src/storage/storage_driver.c:
  * New helper storagePoolObjFindByDiskSource to find the specified
    pool by either name or uuid.
  * Implement translateDiskSourcePool as storageTranslateDomainDiskSourcePool
---
 src/storage/storage_driver.c |  207 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 207 insertions(+), 0 deletions(-)

diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index e98c18c..1faa3cb 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -47,6 +47,8 @@
 #include "virlog.h"
 #include "virfile.h"
 #include "fdstream.h"
+#include "domain_conf.h"
+#include "domain_storage.h"
 #include "configmake.h"
 
 #define VIR_FROM_THIS VIR_FROM_STORAGE
@@ -2367,6 +2369,205 @@ storageListAllPools(virConnectPtr conn,
     return ret;
 }
 
+static virStoragePoolObjPtr
+storagePoolObjFindByDiskSource(virConnectPtr conn,
+                               virDomainDiskSourcePoolDefPtr def)
+{
+    virStorageDriverStatePtr driver = conn->storagePrivateData;
+    virStoragePoolObjPtr pool = NULL;
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    bool isActive;
+
+    storageDriverLock(driver);
+    if (def->poolType ==
+        VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_UUID) {
+        pool = virStoragePoolObjFindByUUID(&driver->pools,
+                                           def->pool.uuid);
+    } else if (def->poolType ==
+        VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_NAME) {
+        pool = virStoragePoolObjFindByName(&driver->pools,
+                                           def->pool.name);
+    }
+    storageDriverUnlock(driver);
+
+    if (!pool || !(isActive = virStoragePoolObjIsActive(pool))) {
+        if (def->poolType ==
+            VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_UUID) {
+            virUUIDFormat(def->pool.uuid, uuidstr);
+        }
+    }
+
+    if (!pool) {
+        if (def->poolType ==
+            VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_UUID) {
+            virReportError(VIR_ERR_NO_STORAGE_POOL,
+                           ("no storage pool with matching uuid '%s'"),
+                           uuidstr);
+            goto error;
+        } else if (def->poolType ==
+                   VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_NAME) {
+            virReportError(VIR_ERR_NO_STORAGE_POOL,
+                           _("no storage pool with matching name '%s'"),
+                           def->pool.name);
+            goto error;
+        }
+    }
+
+    if (!isActive) {
+        if (def->poolType ==
+            VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_UUID)
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                           _("The specified pool '%s' is not active"),
+                           uuidstr);
+        else if (def->poolType ==
+                 VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_NAME)
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                           _("The specified pool '%s' is not active"),
+                           def->pool.name);
+        goto error;
+    }
+
+    return pool;
+error:
+    if (pool)
+        virStoragePoolObjUnlock(pool);
+    return NULL;
+}
+
+static int
+storageTranslateDomainDiskSourcePool(virConnectPtr conn,
+                                     virDomainDefPtr def)
+{
+    virStorageDriverStatePtr driver = conn->storagePrivateData;
+    virStoragePoolObjPtr pool = NULL;
+    virStorageVolDefPtr vol = NULL;
+    int i;
+    int ret = -1;
+
+    for (i = 0; i < def->ndisks; i++) {
+        virDomainDiskDefPtr disk = def->disks[i];
+
+        if (disk->source_type != VIR_DOMAIN_DISK_SOURCE_TYPE_POOL)
+            continue;
+
+        /* FIXME: Network disk should also be supported */
+        if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
+            continue;
+
+        if (disk->srcpool->poolType !=
+            VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_NONE &&
+            !(pool = storagePoolObjFindByDiskSource(conn, disk->srcpool)))
+            goto cleanup;
+
+        switch (disk->srcpool->volType) {
+        case VIR_DOMAIN_DISK_SOURCE_VOL_TYPE_PATH:
+            if (pool) {
+                vol = virStorageVolDefFindByPath(pool,
+                                                 disk->srcpool->vol.path);
+            } else {
+                storageDriverLock(driver);
+                for (i = 0 ; i < driver->pools.count && !vol; i++) {
+                    virStoragePoolObjLock(driver->pools.objs[i]);
+                    if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
+                        vol = virStorageVolDefFindByPath(driver->pools.objs[i],
+                                                         disk->srcpool->vol.path);
+                    }
+
+                    /* Reflect the found pool to domain's XML */
+                    if (vol) {
+                        disk->srcpool->poolType = VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_NAME;
+                        disk->srcpool->pool.name = strdup(driver->pools.objs[i]->def->name);
+                    }
+                    virStoragePoolObjUnlock(driver->pools.objs[i]);
+                }
+                storageDriverUnlock(driver);
+            }
+
+            if (!vol) {
+                if (pool)
+                    virReportError(VIR_ERR_NO_STORAGE_VOL,
+                                  _("no storage vol of specified pool with "
+                                    "matching path '%s'"),
+                                  disk->srcpool->vol.path);
+                else
+                    virReportError(VIR_ERR_NO_STORAGE_VOL,
+                                  _("no storage vol with matching path '%s'"),
+                                  disk->srcpool->vol.path);
+                goto cleanup;
+            }
+
+            disk->src = strdup(vol->target.path);
+            vol = NULL;
+            break;
+        case VIR_DOMAIN_DISK_SOURCE_VOL_TYPE_NAME:
+            if (!(vol = virStorageVolDefFindByName(pool, disk->srcpool->vol.name))) {
+                virReportError(VIR_ERR_NO_STORAGE_VOL,
+                              _("no storage vol of specified pool with "
+                                "matching name '%s'"),
+                              disk->srcpool->vol.name);
+                goto cleanup;
+            }
+
+            disk->src = strdup(vol->target.path);
+            vol = NULL;
+            break;
+        case VIR_DOMAIN_DISK_SOURCE_VOL_TYPE_KEY:
+            if (pool) {
+                vol = virStorageVolDefFindByKey(pool,
+                                                disk->srcpool->vol.key);
+            } else {
+                storageDriverLock(driver);
+                for (i = 0 ; i < driver->pools.count && !vol; i++) {
+                    virStoragePoolObjLock(driver->pools.objs[i]);
+                    if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
+                        vol = virStorageVolDefFindByKey(driver->pools.objs[i],
+                                                        disk->srcpool->vol.key);
+                    }
+
+                    /* Reflect the found pool to domain's XML */
+                    if (vol) {
+                        disk->srcpool->poolType = VIR_DOMAIN_DISK_SOURCE_POOL_TYPE_NAME;
+                        disk->srcpool->pool.name = strdup(driver->pools.objs[i]->def->name);
+                    }
+                    virStoragePoolObjUnlock(driver->pools.objs[i]);
+                }
+                storageDriverUnlock(driver);
+            }
+
+            if (!vol) {
+                if (pool)
+                    virReportError(VIR_ERR_NO_STORAGE_VOL,
+                                  _("no storage vol of specified pool with "
+                                    "matching key '%s'"),
+                                  disk->srcpool->vol.key);
+                else
+                    virReportError(VIR_ERR_NO_STORAGE_VOL,
+                                  _("no storage vol with matching key '%s'"),
+                                  disk->srcpool->vol.key);
+                goto cleanup;
+            }
+
+            disk->src = strdup(vol->target.path);
+            vol = NULL;
+            break;
+        default:
+            /* Tell the compiler to shutup */
+            break;
+        }
+        if (pool) {
+            virStoragePoolObjUnlock(pool);
+            pool = NULL;
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    if (pool)
+        virStoragePoolObjUnlock(pool);
+    return ret;
+}
+
 static virStorageDriver storageDriver = {
     .name = "storage",
     .open = storageOpen, /* 0.4.0 */
@@ -2423,8 +2624,14 @@ static virStateDriver stateDriver = {
     .reload = storageDriverReload,
 };
 
+static virDomainStorageDriver domainStorageDriver = {
+    .translateDiskSourcePool = storageTranslateDomainDiskSourcePool,
+};
+
+
 int storageRegister(void) {
     virRegisterStorageDriver(&storageDriver);
     virRegisterStateDriver(&stateDriver);
+    virRegisterDomainStorageDriver(&domainStorageDriver);
     return 0;
 }
-- 
1.7.7.6




More information about the libvir-list mailing list