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:
Guannan Ren 2013-07-29 20:51:15 +08:00
parent e2ccc96cf0
commit d7b7aa2c20
5 changed files with 74 additions and 0 deletions

View File

@ -1883,6 +1883,7 @@ virSocketAddrSetPort;
# util/virstoragefile.h
virStorageFileChainGetBroken;
virStorageFileChainLookup;
virStorageFileFeatureTypeFromString;
virStorageFileFeatureTypeToString;

View File

@ -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,

View File

@ -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);

View File

@ -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:
*

View File

@ -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,