mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
storage: backend: Add unique id retrieval API
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.
This commit is contained in:
parent
b20060bae2
commit
684ec651e9
@ -195,6 +195,8 @@ typedef ssize_t
|
|||||||
ssize_t max_len,
|
ssize_t max_len,
|
||||||
char **buf);
|
char **buf);
|
||||||
|
|
||||||
|
typedef const char *
|
||||||
|
(*virStorageFileBackendGetUniqueIdentifier)(virStorageSourcePtr src);
|
||||||
|
|
||||||
virStorageFileBackendPtr virStorageFileBackendForType(int type, int protocol);
|
virStorageFileBackendPtr virStorageFileBackendForType(int type, int protocol);
|
||||||
|
|
||||||
@ -211,6 +213,7 @@ struct _virStorageFileBackend {
|
|||||||
virStorageFileBackendInit backendInit;
|
virStorageFileBackendInit backendInit;
|
||||||
virStorageFileBackendDeinit backendDeinit;
|
virStorageFileBackendDeinit backendDeinit;
|
||||||
virStorageFileBackendReadHeader storageFileReadHeader;
|
virStorageFileBackendReadHeader storageFileReadHeader;
|
||||||
|
virStorageFileBackendGetUniqueIdentifier storageFileGetUniqueIdentifier;
|
||||||
|
|
||||||
/* The following group of callbacks is expected to set errno
|
/* The following group of callbacks is expected to set errno
|
||||||
* and return -1 on error. No libvirt error shall be reported */
|
* and return -1 on error. No libvirt error shall be reported */
|
||||||
|
@ -1333,6 +1333,14 @@ virStorageBackend virStorageBackendNetFileSystem = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _virStorageFileBackendFsPriv virStorageFileBackendFsPriv;
|
||||||
|
typedef virStorageFileBackendFsPriv *virStorageFileBackendFsPrivPtr;
|
||||||
|
|
||||||
|
struct _virStorageFileBackendFsPriv {
|
||||||
|
char *canonpath; /* unique file identifier (canonical path) */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virStorageFileBackendFileDeinit(virStorageSourcePtr src)
|
virStorageFileBackendFileDeinit(virStorageSourcePtr src)
|
||||||
{
|
{
|
||||||
@ -1340,16 +1348,27 @@ virStorageFileBackendFileDeinit(virStorageSourcePtr src)
|
|||||||
virStorageTypeToString(virStorageSourceGetActualType(src)),
|
virStorageTypeToString(virStorageSourceGetActualType(src)),
|
||||||
src->path);
|
src->path);
|
||||||
|
|
||||||
|
virStorageFileBackendFsPrivPtr priv = src->drv->priv;
|
||||||
|
|
||||||
|
VIR_FREE(priv->canonpath);
|
||||||
|
VIR_FREE(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virStorageFileBackendFileInit(virStorageSourcePtr src)
|
virStorageFileBackendFileInit(virStorageSourcePtr src)
|
||||||
{
|
{
|
||||||
|
virStorageFileBackendFsPrivPtr priv = NULL;
|
||||||
|
|
||||||
VIR_DEBUG("initializing FS storage file %p (%s:%s)", src,
|
VIR_DEBUG("initializing FS storage file %p (%s:%s)", src,
|
||||||
virStorageTypeToString(virStorageSourceGetActualType(src)),
|
virStorageTypeToString(virStorageSourceGetActualType(src)),
|
||||||
src->path);
|
src->path);
|
||||||
|
|
||||||
|
if (VIR_ALLOC(priv) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
src->drv->priv = priv;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,6 +1416,23 @@ virStorageFileBackendFileReadHeader(virStorageSourcePtr src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
virStorageFileBackendFileGetUniqueIdentifier(virStorageSourcePtr src)
|
||||||
|
{
|
||||||
|
virStorageFileBackendFsPrivPtr priv = src->drv->priv;
|
||||||
|
|
||||||
|
if (!priv->canonpath) {
|
||||||
|
if (!(priv->canonpath = canonicalize_file_name(src->path))) {
|
||||||
|
virReportSystemError(errno, _("can't canonicalize path '%s'"),
|
||||||
|
src->path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return priv->canonpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virStorageFileBackend virStorageFileBackendFile = {
|
virStorageFileBackend virStorageFileBackendFile = {
|
||||||
.type = VIR_STORAGE_TYPE_FILE,
|
.type = VIR_STORAGE_TYPE_FILE,
|
||||||
|
|
||||||
@ -1406,6 +1442,8 @@ virStorageFileBackend virStorageFileBackendFile = {
|
|||||||
.storageFileUnlink = virStorageFileBackendFileUnlink,
|
.storageFileUnlink = virStorageFileBackendFileUnlink,
|
||||||
.storageFileStat = virStorageFileBackendFileStat,
|
.storageFileStat = virStorageFileBackendFileStat,
|
||||||
.storageFileReadHeader = virStorageFileBackendFileReadHeader,
|
.storageFileReadHeader = virStorageFileBackendFileReadHeader,
|
||||||
|
|
||||||
|
.storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1417,7 +1455,18 @@ virStorageFileBackend virStorageFileBackendBlock = {
|
|||||||
|
|
||||||
.storageFileStat = virStorageFileBackendFileStat,
|
.storageFileStat = virStorageFileBackendFileStat,
|
||||||
.storageFileReadHeader = virStorageFileBackendFileReadHeader,
|
.storageFileReadHeader = virStorageFileBackendFileReadHeader,
|
||||||
|
|
||||||
|
.storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
virStorageFileBackend virStorageFileBackendDir = {
|
||||||
|
.type = VIR_STORAGE_TYPE_DIR,
|
||||||
|
|
||||||
|
.backendInit = virStorageFileBackendFileInit,
|
||||||
|
.backendDeinit = virStorageFileBackendFileDeinit,
|
||||||
|
|
||||||
|
.storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier,
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* WITH_STORAGE_FS */
|
#endif /* WITH_STORAGE_FS */
|
||||||
|
@ -2987,3 +2987,33 @@ virStorageFileReadHeader(virStorageSourcePtr src,
|
|||||||
|
|
||||||
return ret;
|
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 and is valid until the storage file is
|
||||||
|
* deinitialized. 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);
|
||||||
|
}
|
||||||
|
@ -41,6 +41,7 @@ int virStorageFileStat(virStorageSourcePtr src,
|
|||||||
ssize_t virStorageFileReadHeader(virStorageSourcePtr src,
|
ssize_t virStorageFileReadHeader(virStorageSourcePtr src,
|
||||||
ssize_t max_len,
|
ssize_t max_len,
|
||||||
char **buf);
|
char **buf);
|
||||||
|
const char *virStorageFileGetUniqueIdentifier(virStorageSourcePtr src);
|
||||||
|
|
||||||
int storageRegister(void);
|
int storageRegister(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user