Use virStorageFileSimplifyPathInternal to canonicalize gluster paths
via a callback and use it for the unique volume path retrieval API.
---
src/storage/storage_backend_gluster.c | 81 +++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/src/storage/storage_backend_gluster.c
b/src/storage/storage_backend_gluster.c
index 1a844c9..25d2aed 100644
--- a/src/storage/storage_backend_gluster.c
+++ b/src/storage/storage_backend_gluster.c
@@ -533,6 +533,7 @@ typedef virStorageFileBackendGlusterPriv
*virStorageFileBackendGlusterPrivPtr;
struct _virStorageFileBackendGlusterPriv {
glfs_t *vol;
+ char *uid;
};
@@ -547,6 +548,7 @@ virStorageFileBackendGlusterDeinit(virStorageSourcePtr src)
if (priv->vol)
glfs_fini(priv->vol);
+ VIR_FREE(priv->uid);
VIR_FREE(priv);
src->drv->priv = NULL;
@@ -712,6 +714,81 @@ virStorageFileBackendGlusterAccess(virStorageSourcePtr src,
return glfs_access(priv->vol, src->path, mode);
}
+static int
+virStorageFileBackendGlusterReadlinkCallback(const char *path,
+ char **link,
+ void *data)
+{
+ virStorageFileBackendGlusterPrivPtr priv = data;
+ char *buf = NULL;
+ size_t bufsiz = 0;
+ ssize_t ret;
+ struct stat st;
+
+ *link = NULL;
+
+ if (glfs_stat(priv->vol, path, &st) < 0) {
+ virReportSystemError(errno,
+ _("failed to stat gluster path '%s'"),
+ path);
+ return -1;
+ }
+
+ if (!S_ISLNK(st.st_mode))
+ return 1;
+
+ realloc:
+ if (VIR_EXPAND_N(buf, bufsiz, 256) < 0)
+ goto error;
+
+ if ((ret = glfs_readlink(priv->vol, path, buf, bufsiz)) < 0) {
+ virReportSystemError(errno,
+ _("failed to read link of gluster file
'%s'"),
+ path);
+ goto error;
+ }
+
+ if (ret == bufsiz)
+ goto realloc;
+
+ buf[ret] = '\0';
+
+ *link = buf;
+
+ return 0;
+
+ error:
+ VIR_FREE(buf);
+ return -1;
+}
+
+
+static const char *
+virStorageFileBackendGlusterGetUniqueIdentifier(virStorageSourcePtr src)
+{
+ virStorageFileBackendGlusterPrivPtr priv = src->drv->priv;
+ char *canonPath = NULL;
+
+ if (priv->uid)
+ return priv->uid;
+
+ if (!(canonPath = virStorageFileSimplifyPathInternal(src->path,
+ false,
+
virStorageFileBackendGlusterReadlinkCallback,
+ priv)))
+ return NULL;
+
+ ignore_value(virAsprintf(&priv->uid, "gluster://%s:%s/%s/%s",
+ src->hosts->name,
+ src->hosts->port,
+ src->volume,
+ canonPath));
+
+ VIR_FREE(canonPath);
+
+ return priv->uid;
+}
+
virStorageFileBackend virStorageFileBackendGluster = {
.type = VIR_STORAGE_TYPE_NETWORK,
@@ -724,4 +801,8 @@ virStorageFileBackend virStorageFileBackendGluster = {
.storageFileStat = virStorageFileBackendGlusterStat,
.storageFileReadHeader = virStorageFileBackendGlusterReadHeader,
.storageFileAccess = virStorageFileBackendGlusterAccess,
+
+ .storageFileGetUniqueIdentifier = virStorageFileBackendGlusterGetUniqueIdentifier,
+
+
};
--
1.9.3