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