
On 2012年12月13日 01:16, Daniel P. Berrange wrote:
On Tue, Dec 11, 2012 at 09:37:18PM +0800, Osier Yang wrote:
This introduces a hash table for qemu driver, to store the shared disk's info as (@disk_path, {@ref_count, @orig_cdbfilter}). @ref_count is the number of domains which shares the disk. @orig_cdbfilter is the original cdbfilter setting of the shared disk, it will be used to restore the the disk's cdbfilter setting to original value by later patches.
* src/qemu/qemu_conf.h: (Add member 'sharedDisks' of type virHashTablePtr; New struct qemuSharedDiskEntry; Declare helpers qemuAddSharedDisk, qemuRemoveSharedDisk) * src/qemu/qemu_conf.c (Implement the two helpers) * src/qemu/qemu_process.c (Update 'sharedDisks' when domain starting and shutdown) * src/qemu/qemu_driver.c (Update 'sharedDisks' when attaching or detaching disk).
0 is passed for orig_cdbfilter temporarily, later patches will update it. --- src/qemu/qemu_conf.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_conf.h | 18 +++++++++++++++++ src/qemu/qemu_driver.c | 17 ++++++++++++++++ src/qemu/qemu_process.c | 17 +++++++++++++++- 4 files changed, 99 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 8d380a1..2b21186 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -556,3 +556,51 @@ qemuDriverCloseCallbackRunAll(virQEMUDriverPtr driver,
virHashForEach(driver->closeCallbacks, qemuDriverCloseCallbackRun,&data); } + +/* Increase ref count if the entry already exists, otherwise + * add a new entry. + */ +int +qemuAddSharedDisk(virHashTablePtr sharedDisks, + const char *disk_path, + int orig_cdbfilter) +{ + qemuSharedDiskEntryPtr entry = NULL; + + if ((entry = virHashLookup(sharedDisks, disk_path))) { + entry->ref++; + } else { + if (VIR_ALLOC(entry)< 0) + return -1; + + entry->ref = 1; + entry->orig_cdbfilter = orig_cdbfilter; + + if (virHashAddEntry(sharedDisks, disk_path, entry)) + return -1; + } + + return 0; +} + +/* Decrease the ref count if the entry already exists, otherwise + * remove the entry. + */ +int +qemuRemoveSharedDisk(virHashTablePtr sharedDisks, + const char *disk_path) +{ + qemuSharedDiskEntryPtr entry = NULL; + + if (!(entry = virHashLookup(sharedDisks, disk_path))) + return -1; + + if (entry->ref != 1) { + entry->ref--; + } else { + if (virHashRemoveEntry(sharedDisks, disk_path)< 0) + return -1; + } + + return 0; +} diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index d0d25ce..df901f6 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -147,6 +147,8 @@ struct _virQEMUDriver { /* The devices which is are not in use by the host or any guest. */ pciDeviceList *inactivePciHostdevs;
+ virHashTablePtr sharedDisks; + virBitmapPtr reservedRemotePorts;
virSysinfoDefPtr hostsysinfo; @@ -193,6 +195,13 @@ struct qemuDomainDiskInfo { int io_status; };
+typedef struct qemuSharedDiskEntry qemuSharedDiskEntry; +typedef qemuSharedDiskEntry *qemuSharedDiskEntryPtr; +struct qemuSharedDiskEntry { + size_t ref; /* ref count of the shared disk */ + int orig_cdbfilter; /* Original disk's cdbfilter setting */ +};
Storing the original value here doesn't work in context of libvirtd restarts, because you've no way to re-populate it
Yeah, I thought as long as it works without libvirtd restarting, it should be better.