mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 01:34:11 +03:00
qemu: add helper functions for diskchain checking
*src/util/virstoragefile.c: Add a helper function to get the first name of missing backing files, if the name is NULL, it means the diskchain is not broken. *src/qemu/qemu_domain.c: qemuDiskChainCheckBroken(disk) to check if its chain is broken
This commit is contained in:
parent
e2ccc96cf0
commit
d7b7aa2c20
@ -1883,6 +1883,7 @@ virSocketAddrSetPort;
|
||||
|
||||
|
||||
# util/virstoragefile.h
|
||||
virStorageFileChainGetBroken;
|
||||
virStorageFileChainLookup;
|
||||
virStorageFileFeatureTypeFromString;
|
||||
virStorageFileFeatureTypeToString;
|
||||
|
@ -2186,6 +2186,28 @@ qemuDomainCleanupRun(virQEMUDriverPtr driver,
|
||||
priv->ncleanupCallbacks_max = 0;
|
||||
}
|
||||
|
||||
int
|
||||
qemuDiskChainCheckBroken(virDomainDiskDefPtr disk)
|
||||
{
|
||||
char *brokenFile = NULL;
|
||||
|
||||
if (!disk->src || !disk->backingChain)
|
||||
return 0;
|
||||
|
||||
if (virStorageFileChainGetBroken(disk->backingChain, &brokenFile) < 0)
|
||||
return -1;
|
||||
|
||||
if (brokenFile) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("Backing file '%s' of image '%s' is missing."),
|
||||
brokenFile, disk->src);
|
||||
VIR_FREE(brokenFile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
|
||||
virDomainDiskDefPtr disk,
|
||||
|
@ -347,6 +347,9 @@ bool qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv,
|
||||
int qemuDomainCheckDiskPresence(virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm,
|
||||
bool start_with_state);
|
||||
|
||||
int qemuDiskChainCheckBroken(virDomainDiskDefPtr disk);
|
||||
|
||||
int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
|
||||
virDomainDiskDefPtr disk,
|
||||
bool force);
|
||||
|
@ -572,6 +572,13 @@ virFindBackingFile(const char *start, bool start_is_dir, const char *path,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virFileAccessibleAs(combined, F_OK, getuid(), getgid()) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Cannot access backing file '%s'"),
|
||||
combined);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(*canonical = canonicalize_file_name(combined))) {
|
||||
virReportSystemError(errno,
|
||||
_("Can't canonicalize path '%s'"), path);
|
||||
@ -1096,6 +1103,45 @@ virStorageFileGetMetadata(const char *path, int format,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* virStorageFileChainCheckBroken
|
||||
*
|
||||
* If CHAIN is broken, set *brokenFile to the broken file name,
|
||||
* otherwise set it to NULL. Caller MUST free *brokenFile after use.
|
||||
* Return 0 on success, negative on error.
|
||||
*/
|
||||
int
|
||||
virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
|
||||
char **brokenFile)
|
||||
{
|
||||
virStorageFileMetadataPtr tmp;
|
||||
int ret = -1;
|
||||
|
||||
if (!chain)
|
||||
return 0;
|
||||
|
||||
*brokenFile = NULL;
|
||||
|
||||
tmp = chain;
|
||||
while (tmp) {
|
||||
/* Break if no backing store or backing store is not file */
|
||||
if (!tmp->backingStoreRaw)
|
||||
break;
|
||||
if (!tmp->backingStore) {
|
||||
if (VIR_STRDUP(*brokenFile, tmp->backingStoreRaw) < 0)
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
tmp = tmp->backingMeta;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virStorageFileFreeMetadata:
|
||||
*
|
||||
|
@ -90,6 +90,8 @@ virStorageFileMetadataPtr virStorageFileGetMetadata(const char *path,
|
||||
virStorageFileMetadataPtr virStorageFileGetMetadataFromFD(const char *path,
|
||||
int fd,
|
||||
int format);
|
||||
int virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
|
||||
char **broken_file);
|
||||
|
||||
const char *virStorageFileChainLookup(virStorageFileMetadataPtr chain,
|
||||
const char *start,
|
||||
|
Loading…
Reference in New Issue
Block a user