[libvirt] [PATCH RFC 08/22] storage: backend: Add unique id retrieval API

Peter Krempa pkrempa at redhat.com
Tue May 6 13:36:57 UTC 2014


Different protocols have different means to uniquely identify a storage
file. This patch implements a storage driver API to retrieve a unique
string describing a volume. The current implementation works for local
storage only and returns the canonical path of the volume.

To add caching support the local filesystem driver now has a private
structure holding the cached string, which is created only when it's
initially accessed.

This patch provides the implementation for local files only for start.
---
 src/storage/storage_backend.h    |  3 +++
 src/storage/storage_backend_fs.c | 49 ++++++++++++++++++++++++++++++++++++++++
 src/storage/storage_driver.c     | 30 ++++++++++++++++++++++++
 src/storage/storage_driver.h     |  1 +
 4 files changed, 83 insertions(+)

diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 6be5ca7..5d71cde 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -195,6 +195,8 @@ typedef ssize_t
                                    ssize_t max_len,
                                    char **buf);

+typedef const char *
+(*virStorageFileBackendGetUniqueIdentifier)(virStorageSourcePtr src);

 virStorageFileBackendPtr virStorageFileBackendForType(int type, int protocol);

@@ -211,6 +213,7 @@ struct _virStorageFileBackend {
     virStorageFileBackendInit backendInit;
     virStorageFileBackendDeinit backendDeinit;
     virStorageFileBackendReadHeader storageFileReadHeader;
+    virStorageFileBackendGetUniqueIdentifier storageFileGetUniqueIdentifier;

     /* The following group of callbacks is expected to set errno
      * and return -1 on error. No libvirt error shall be reported */
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 33551e7..1f436fa 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1339,6 +1339,14 @@ virStorageBackend virStorageBackendNetFileSystem = {
 };


+typedef struct _virStorageFileBackendFsPriv virStorageFileBackendFsPriv;
+typedef virStorageFileBackendFsPriv *virStorageFileBackendFsPrivPtr;
+
+struct _virStorageFileBackendFsPriv {
+    char *uid; /* unique file identifier (canonical path) */
+};
+
+
 static void
 virStorageFileBackendFileDeinit(virStorageSourcePtr src)
 {
@@ -1346,16 +1354,27 @@ virStorageFileBackendFileDeinit(virStorageSourcePtr src)
               virStorageTypeToString(virStorageSourceGetActualType(src)),
               src->path);

+    virStorageFileBackendFsPrivPtr priv = src->drv->priv;
+
+    VIR_FREE(priv->uid);
+    VIR_FREE(priv);
 }


 static int
 virStorageFileBackendFileInit(virStorageSourcePtr src)
 {
+    virStorageFileBackendFsPrivPtr priv = NULL;
+
     VIR_DEBUG("initializing FS storage file %p (%s:%s)", src,
               virStorageTypeToString(virStorageSourceGetActualType(src)),
               src->path);

+    if (VIR_ALLOC(priv) < 0)
+        return -1;
+
+    src->drv->priv = priv;
+
     return 0;
 }

@@ -1403,6 +1422,23 @@ virStorageFileBackendFileReadHeader(virStorageSourcePtr src,
 }


+static const char *
+virStorageFileBackendFileGetUniqueIdentifier(virStorageSourcePtr src)
+{
+    virStorageFileBackendFsPrivPtr priv = src->drv->priv;
+
+    if (!priv->uid) {
+        if (!(priv->uid = canonicalize_file_name(src->path))) {
+            virReportSystemError(errno, _("can't canonicalize path '%s'"),
+                                 src->path);
+            return NULL;
+        }
+    }
+
+    return priv->uid;
+}
+
+
 virStorageFileBackend virStorageFileBackendFile = {
     .type = VIR_STORAGE_TYPE_FILE,

@@ -1412,6 +1448,8 @@ virStorageFileBackend virStorageFileBackendFile = {
     .storageFileUnlink = virStorageFileBackendFileUnlink,
     .storageFileStat = virStorageFileBackendFileStat,
     .storageFileReadHeader = virStorageFileBackendFileReadHeader,
+
+    .storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier,
 };


@@ -1423,7 +1461,18 @@ virStorageFileBackend virStorageFileBackendBlock = {

     .storageFileStat = virStorageFileBackendFileStat,
     .storageFileReadHeader = virStorageFileBackendFileReadHeader,
+
+    .storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier,
 };


+virStorageFileBackend virStorageFileBackendDir = {
+    .type = VIR_STORAGE_TYPE_DIR,
+
+    .backendInit = virStorageFileBackendFileInit,
+    .backendDeinit = virStorageFileBackendFileDeinit,
+
+    .storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier,
+};
+
 #endif /* WITH_STORAGE_FS */
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 8da8386..2fb70f2 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -2960,3 +2960,33 @@ virStorageFileReadHeader(virStorageSourcePtr src,

     return ret;
 }
+
+
+/*
+ * virStorageFileGetUniqueIdentifier: Get a unique string describing the volume
+ *
+ * @src: file structure pointing to the file
+ *
+ * Returns a string uniquely describing a single volume (canonical path).
+ * The string shall not be freed. Returns NULL on error and sets a libvirt
+ * error code */
+const char *
+virStorageFileGetUniqueIdentifier(virStorageSourcePtr src)
+{
+    if (!virStorageFileIsInitialized(src)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("storage file backend not initialized"));
+        return NULL;
+    }
+
+    if (!src->drv->backend->storageFileGetUniqueIdentifier) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unique storage file identifier not implemented for "
+                          "storage type %s (protocol: %s)'"),
+                       virStorageTypeToString(src->type),
+                       virStorageNetProtocolTypeToString(src->protocol));
+        return NULL;
+    }
+
+    return src->drv->backend->storageFileGetUniqueIdentifier(src);
+}
diff --git a/src/storage/storage_driver.h b/src/storage/storage_driver.h
index d67d74b..9280ef0 100644
--- a/src/storage/storage_driver.h
+++ b/src/storage/storage_driver.h
@@ -41,6 +41,7 @@ int virStorageFileStat(virStorageSourcePtr src,
 ssize_t virStorageFileReadHeader(virStorageSourcePtr src,
                                  ssize_t max_len,
                                  char **buf);
+const char *virStorageFileGetUniqueIdentifier(virStorageSourcePtr src);

 int storageRegister(void);

-- 
1.9.2




More information about the libvir-list mailing list