mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Add an API for iterating over disk paths
There is duplicated code which iterates over disk backing stores performing some action. Provide a convenient helper for doing this to eliminate duplication & risk of mistakes with disk format probing * src/conf/domain_conf.c, src/conf/domain_conf.h, src/libvirt_private.syms: Add virDomainDiskDefForeachPath()
This commit is contained in:
parent
bf80fc68ca
commit
9d0a630f51
@ -45,6 +45,7 @@
|
|||||||
#include "macvtap.h"
|
#include "macvtap.h"
|
||||||
#include "nwfilter_conf.h"
|
#include "nwfilter_conf.h"
|
||||||
#include "ignore-value.h"
|
#include "ignore-value.h"
|
||||||
|
#include "storage_file.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
||||||
|
|
||||||
@ -7273,4 +7274,102 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
||||||
|
bool allowProbing,
|
||||||
|
bool ignoreOpenFailure,
|
||||||
|
virDomainDiskDefPathIterator iter,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virHashTablePtr paths;
|
||||||
|
int format;
|
||||||
|
int ret = -1;
|
||||||
|
size_t depth = 0;
|
||||||
|
char *nextpath = NULL;
|
||||||
|
|
||||||
|
if (!disk->src)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (disk->driverType) {
|
||||||
|
const char *formatStr = disk->driverType;
|
||||||
|
if (STREQ(formatStr, "aio"))
|
||||||
|
formatStr = "raw"; /* Xen compat */
|
||||||
|
|
||||||
|
if ((format = virStorageFileFormatTypeFromString(formatStr)) < 0) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unknown disk format '%s' for %s"),
|
||||||
|
disk->driverType, disk->src);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (allowProbing) {
|
||||||
|
format = VIR_STORAGE_FILE_AUTO;
|
||||||
|
} else {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("no disk format for %s and probing is disabled"),
|
||||||
|
disk->src);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paths = virHashCreate(5);
|
||||||
|
|
||||||
|
do {
|
||||||
|
virStorageFileMetadata meta;
|
||||||
|
const char *path = nextpath ? nextpath : disk->src;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (iter(disk, path, depth, opaque) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virHashLookup(paths, path)) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("backing store for %s is self-referential"),
|
||||||
|
disk->src);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fd = open(path, O_RDONLY)) < 0) {
|
||||||
|
if (ignoreOpenFailure) {
|
||||||
|
char ebuf[1024];
|
||||||
|
VIR_WARN("Ignoring open failure on %s: %s", path,
|
||||||
|
virStrerror(errno, ebuf, sizeof(ebuf)));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("unable to open disk path %s"),
|
||||||
|
path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virStorageFileGetMetadataFromFD(path, fd, format, &meta) < 0) {
|
||||||
|
close(fd);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if (virHashAddEntry(paths, path, (void*)0x1) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
depth++;
|
||||||
|
nextpath = meta.backingStore;
|
||||||
|
|
||||||
|
format = meta.backingStoreFormat;
|
||||||
|
|
||||||
|
if (format == VIR_STORAGE_FILE_AUTO &&
|
||||||
|
!allowProbing)
|
||||||
|
format = VIR_STORAGE_FILE_RAW; /* Stops further recursion */
|
||||||
|
} while (nextpath);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virHashFree(paths, NULL);
|
||||||
|
VIR_FREE(nextpath);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* ! PROXY */
|
#endif /* ! PROXY */
|
||||||
|
@ -1079,6 +1079,17 @@ int virDomainChrDefForeach(virDomainDefPtr def,
|
|||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
|
||||||
|
const char *path,
|
||||||
|
size_t depth,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
|
int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
||||||
|
bool allowProbing,
|
||||||
|
bool ignoreOpenFailure,
|
||||||
|
virDomainDiskDefPathIterator iter,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
VIR_ENUM_DECL(virDomainVirt)
|
VIR_ENUM_DECL(virDomainVirt)
|
||||||
VIR_ENUM_DECL(virDomainBoot)
|
VIR_ENUM_DECL(virDomainBoot)
|
||||||
VIR_ENUM_DECL(virDomainFeature)
|
VIR_ENUM_DECL(virDomainFeature)
|
||||||
|
@ -225,6 +225,7 @@ virDomainSnapshotDefFormat;
|
|||||||
virDomainSnapshotAssignDef;
|
virDomainSnapshotAssignDef;
|
||||||
virDomainObjAssignDef;
|
virDomainObjAssignDef;
|
||||||
virDomainChrDefForeach;
|
virDomainChrDefForeach;
|
||||||
|
virDomainDiskDefForeachPath;
|
||||||
|
|
||||||
|
|
||||||
# domain_event.h
|
# domain_event.h
|
||||||
|
Loading…
Reference in New Issue
Block a user