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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list