168 lines
5.4 KiB
Diff
168 lines
5.4 KiB
Diff
|
>From 494b96317334716f846436a5ec485963411cb4a3 Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel P. Berrange <berrange@redhat.com>
|
||
|
Date: Mon, 14 Jun 2010 18:09:15 +0100
|
||
|
Subject: [PATCH 05/10] 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()
|
||
|
---
|
||
|
src/conf/domain_conf.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
src/conf/domain_conf.h | 11 +++++
|
||
|
src/libvirt_private.syms | 1 +
|
||
|
3 files changed, 111 insertions(+), 0 deletions(-)
|
||
|
|
||
|
Index: libvirt-0.8.1/src/conf/domain_conf.c
|
||
|
===================================================================
|
||
|
--- libvirt-0.8.1.orig/src/conf/domain_conf.c
|
||
|
+++ libvirt-0.8.1/src/conf/domain_conf.c
|
||
|
@@ -45,6 +45,7 @@
|
||
|
#include "macvtap.h"
|
||
|
#include "nwfilter_conf.h"
|
||
|
#include "ignore-value.h"
|
||
|
+#include "storage_file.h"
|
||
|
|
||
|
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
||
|
|
||
|
@@ -6928,4 +6929,102 @@ int virDomainSnapshotHasChildren(virDoma
|
||
|
}
|
||
|
|
||
|
|
||
|
+int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
||
|
+ bool allowProbing,
|
||
|
+ bool ignoreOpenFailure,
|
||
|
+ virDomainDiskDefPathIterator iter,
|
||
|
+ void *opaque)
|
||
|
+{
|
||
|
+ virHashTablePtr paths;
|
||
|
+ int format;
|
||
|
+ int ret = -1;
|
||
|
+ int 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 */
|
||
|
Index: libvirt-0.8.1/src/conf/domain_conf.h
|
||
|
===================================================================
|
||
|
--- libvirt-0.8.1.orig/src/conf/domain_conf.h
|
||
|
+++ libvirt-0.8.1/src/conf/domain_conf.h
|
||
|
@@ -1057,6 +1057,17 @@ int virDomainObjListGetInactiveNames(vir
|
||
|
int maxnames);
|
||
|
|
||
|
|
||
|
+typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
|
||
|
+ const char *path,
|
||
|
+ unsigned int depth,
|
||
|
+ void *opaque);
|
||
|
+
|
||
|
+int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
||
|
+ bool allowProbing,
|
||
|
+ bool ignoreOpenFailure,
|
||
|
+ virDomainDiskDefPathIterator iter,
|
||
|
+ void *opaque);
|
||
|
+
|
||
|
VIR_ENUM_DECL(virDomainVirt)
|
||
|
VIR_ENUM_DECL(virDomainBoot)
|
||
|
VIR_ENUM_DECL(virDomainFeature)
|
||
|
Index: libvirt-0.8.1/src/libvirt_private.syms
|
||
|
===================================================================
|
||
|
--- libvirt-0.8.1.orig/src/libvirt_private.syms
|
||
|
+++ libvirt-0.8.1/src/libvirt_private.syms
|
||
|
@@ -223,6 +223,7 @@ virDomainSnapshotObjUnref;
|
||
|
virDomainSnapshotDefParseString;
|
||
|
virDomainSnapshotDefFormat;
|
||
|
virDomainSnapshotAssignDef;
|
||
|
+virDomainDiskDefForeachPath;
|
||
|
|
||
|
|
||
|
# domain_event.h
|