
On Wed, Feb 20, 2013 at 03:43:55PM +0800, Osier Yang wrote:
The hash entry is changed from "ref" to {ref, @domains}. With this, the caller can simply call qemuRemoveSharedDisk, without afraid of removing the entry belongs to other domains. qemuProcessStart will obviously benifit from it on error codepath (which calls qemuProcessStop to do the cleanup). --- src/qemu/qemu_conf.c | 169 +++++++++++++++++++++++++++++++++++++++++----- src/qemu/qemu_conf.h | 22 +++++- src/qemu/qemu_driver.c | 6 +- src/qemu/qemu_process.c | 4 +- 4 files changed, 173 insertions(+), 28 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index e54227f..0bd6be0 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -824,6 +824,11 @@ qemuDriverCloseCallbackRunAll(virQEMUDriverPtr driver, qemuDriverUnlock(driver); }
+struct _qemuSharedDiskEntry { + size_t ref; + char **domains; /* array of domain names */ +}; + /* Construct the hash key for sharedDisks as "major:minor" */ char * qemuGetSharedDiskKey(const char *disk_path) @@ -858,10 +863,9 @@ static int qemuCheckSharedDisk(virHashTablePtr sharedDisks, virDomainDiskDefPtr disk) { - int val; - size_t *ref = NULL; char *sysfs_path = NULL; char *key = NULL; + int val; int ret = 0;
/* The only conflicts between shared disk we care about now @@ -881,7 +885,6 @@ qemuCheckSharedDisk(virHashTablePtr sharedDisks, if (!virFileExists(sysfs_path)) goto cleanup;
- if (!(key = qemuGetSharedDiskKey(disk->src))) { ret = -1; goto cleanup; @@ -890,7 +893,7 @@ qemuCheckSharedDisk(virHashTablePtr sharedDisks, /* It can't be conflict if no other domain is * is sharing it. */ - if (!(ref = virHashLookup(sharedDisks, key))) + if (!(virHashLookup(sharedDisks, key))) goto cleanup;
if (virGetDeviceUnprivSGIO(disk->src, NULL, &val) < 0) { @@ -916,14 +919,84 @@ cleanup: return ret; }
-/* Increase ref count if the entry already exists, otherwise - * add a new entry. +bool +qemuSharedDiskEntryDomainExists(qemuSharedDiskEntryPtr entry, + const char *name, + int *idx) +{ + size_t i; + + for (i = 0; i < entry->ref; i++) { + if (STREQ(entry->domains[i], name)) { + if (idx) + *idx = i; + return true; + } + } + + return false; +} + +void +qemuSharedDiskEntryFree(void *payload, const void *name ATTRIBUTE_UNUSED) +{ + qemuSharedDiskEntryPtr entry = (qemuSharedDiskEntryPtr)payload;
No need for that cast - void * casts to anything.
+ size_t i; + + for (i = 0; i < entry->ref; i++) { + VIR_FREE(entry->domains[i]); + } + VIR_FREE(entry->domains); + VIR_FREE(entry); +}
ACK if the cast is removed Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|