You need to sign in or sign up before continuing.
提交 5eaf6054 编写于 作者: E Eric Blake

storage: make it easier to find file within chain

In order to temporarily label files read/write during a commit
operation, we need to crawl the backing chain and find the absolute
file name that needs labeling in the first place, as well as the
name of the file that owns the backing file.

* src/util/storage_file.c (virStorageFileChainLookup): New
function.
* src/util/storage_file.h: Declare it.
* src/libvirt_private.syms (storage_file.h): Export it.
上级 82507838
...@@ -1132,6 +1132,7 @@ virStorageGenerateQcowPassphrase; ...@@ -1132,6 +1132,7 @@ virStorageGenerateQcowPassphrase;
# storage_file.h # storage_file.h
virStorageFileChainLookup;
virStorageFileFormatTypeFromString; virStorageFileFormatTypeFromString;
virStorageFileFormatTypeToString; virStorageFileFormatTypeToString;
virStorageFileFreeMetadata; virStorageFileFreeMetadata;
......
...@@ -1262,3 +1262,67 @@ const char *virStorageFileGetSCSIKey(const char *path) ...@@ -1262,3 +1262,67 @@ const char *virStorageFileGetSCSIKey(const char *path)
return NULL; return NULL;
} }
#endif #endif
/* Given a CHAIN that starts at the named file START, return a string
* pointing to either START or within CHAIN that gives the preferred
* name for the backing file NAME within that chain. Pass NULL for
* NAME to find the base of the chain. If META is not NULL, set *META
* to the point in the chain that describes NAME (or to NULL if the
* backing element is not a file). If PARENT is not NULL, set *PARENT
* to the preferred name of the parent (or to NULL if NAME matches
* START). Since the results point within CHAIN, they must not be
* independently freed. */
const char *
virStorageFileChainLookup(virStorageFileMetadataPtr chain, const char *start,
const char *name, virStorageFileMetadataPtr *meta,
const char **parent)
{
virStorageFileMetadataPtr owner;
const char *tmp;
if (!parent)
parent = &tmp;
*parent = NULL;
if (name ? STREQ(start, name) || virFileLinkPointsTo(start, name) :
!chain->backingStore) {
if (meta)
*meta = chain;
return start;
}
owner = chain;
*parent = start;
while (owner) {
if (!owner->backingStore)
goto error;
if (!name) {
if (!owner->backingMeta ||
!owner->backingMeta->backingStore)
break;
} else if (STREQ_NULLABLE(name, owner->backingStoreRaw) ||
STREQ(name, owner->backingStore)) {
break;
} else if (owner->backingStoreIsFile) {
char *absName = absolutePathFromBaseFile(*parent, name);
if (absName && STREQ(absName, owner->backingStore)) {
VIR_FREE(absName);
break;
}
VIR_FREE(absName);
}
*parent = owner->backingStore;
owner = owner->backingMeta;
}
if (!owner)
goto error;
if (meta)
*meta = owner->backingMeta;
return owner->backingStore;
error:
*parent = NULL;
if (meta)
*meta = NULL;
return NULL;
}
...@@ -78,6 +78,13 @@ virStorageFileMetadataPtr virStorageFileGetMetadataFromFD(const char *path, ...@@ -78,6 +78,13 @@ virStorageFileMetadataPtr virStorageFileGetMetadataFromFD(const char *path,
int fd, int fd,
int format); int format);
const char *virStorageFileChainLookup(virStorageFileMetadataPtr chain,
const char *start,
const char *name,
virStorageFileMetadataPtr *meta,
const char **parent)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void virStorageFileFreeMetadata(virStorageFileMetadataPtr meta); void virStorageFileFreeMetadata(virStorageFileMetadataPtr meta);
int virStorageFileResize(const char *path, unsigned long long capacity); int virStorageFileResize(const char *path, unsigned long long capacity);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册