提交 9d0a630f 编写于 作者: D Daniel P. Berrange

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()
上级 bf80fc68
...@@ -45,6 +45,7 @@ ...@@ -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: ...@@ -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, ...@@ -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; ...@@ -225,6 +225,7 @@ virDomainSnapshotDefFormat;
virDomainSnapshotAssignDef; virDomainSnapshotAssignDef;
virDomainObjAssignDef; virDomainObjAssignDef;
virDomainChrDefForeach; virDomainChrDefForeach;
virDomainDiskDefForeachPath;
# domain_event.h # domain_event.h
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册