[libvirt] [PATCH 01/12] qemu: Add a hash table for the shared disks

Osier Yang jyang at redhat.com
Wed Dec 12 03:39:01 UTC 2012


On 2012年12月12日 11:35, Osier Yang wrote:
> On 2012年12月11日 21:37, 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 */
>> +};
>> +
>> typedef virDomainObjPtr (*qemuDriverCloseCallback)(virQEMUDriverPtr
>> driver,
>> virDomainObjPtr vm,
>> virConnectPtr conn);
>> @@ -211,4 +220,13 @@ qemuDriverCloseCallback
>> qemuDriverCloseCallbackGet(virQEMUDriverPtr driver,
>> void qemuDriverCloseCallbackRunAll(virQEMUDriverPtr driver,
>> virConnectPtr conn);
>>
>> +int qemuAddSharedDisk(virHashTablePtr sharedDisks,
>> + const char *disk_path,
>> + int orig_cdbfilter)
>> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
>> +
>> +int qemuRemoveSharedDisk(virHashTablePtr sharedDisks,
>> + const char *disk_path)
>> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
>> +
>> #endif /* __QEMUD_CONF_H */
>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>> index e099c5c..fdde74d 100644
>> --- a/src/qemu/qemu_driver.c
>> +++ b/src/qemu/qemu_driver.c
>> @@ -810,6 +810,9 @@ qemuStartup(bool privileged,
>> if ((qemu_driver->inactivePciHostdevs = pciDeviceListNew()) == NULL)
>> goto error;
>>
>> + if (!(qemu_driver->sharedDisks = virHashCreate(30, NULL)))
>> + goto error;
>> +
>> if (privileged) {
>> if (chown(qemu_driver->libDir, qemu_driver->user, qemu_driver->group)<
>> 0) {
>> virReportSystemError(errno,
>> @@ -1064,6 +1067,7 @@ qemuShutdown(void) {
>> pciDeviceListFree(qemu_driver->activePciHostdevs);
>> pciDeviceListFree(qemu_driver->inactivePciHostdevs);
>> usbDeviceListFree(qemu_driver->activeUsbHostdevs);
>> + virHashFree(qemu_driver->sharedDisks);
>> virCapabilitiesFree(qemu_driver->caps);
>> qemuCapsCacheFree(qemu_driver->capsCache);
>>
>> @@ -6035,6 +6039,12 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
>> VIR_WARN("Failed to teardown cgroup for disk path %s",
>> NULLSTR(disk->src));
>> }
>> +
>> + if (ret == 0&& disk->shared) {
>> + if (qemuAddSharedDisk(driver->sharedDisks, disk->src, 0)< 0)
>> + VIR_WARN("Failed to add disk '%s' to shared disk table",
>> + disk->src);
>> + }
>> end:
>> if (cgroup)
>> virCgroupFree(&cgroup);
>> @@ -6149,6 +6159,13 @@ qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr
>> driver,
>> virDomainDiskDeviceTypeToString(disk->type));
>> break;
>> }
>> +
>> + if (ret == 0&& disk->shared) {
>> + if (qemuRemoveSharedDisk(driver->sharedDisks, disk->src)< 0)
>> + VIR_WARN("Failed to remove disk '%s' from shared disk table",
>> + disk->src);
>> + }
>> +
>> return ret;
>> }
>>
>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>> index ab04599..89152b8 100644
>> --- a/src/qemu/qemu_process.c
>> +++ b/src/qemu/qemu_process.c
>> @@ -3706,8 +3706,15 @@ int qemuProcessStart(virConnectPtr conn,
>>
>> /* in case a certain disk is desirous of CAP_SYS_RAWIO, add this */
>> for (i = 0; i< vm->def->ndisks; i++) {
>> - if (vm->def->disks[i]->rawio == 1)
>> + virDomainDiskDefPtr disk = vm->def->disks[i];
>> +
>> + if (disk->rawio == 1)
>> virCommandAllowCap(cmd, CAP_SYS_RAWIO);
>> +
>> + if (disk->shared) {
>> + if (qemuAddSharedDisk(driver->sharedDisks, disk->src, 0)< 0)
>> + goto cleanup;
>> + }
>> }
>>
>> virCommandSetPreExecHook(cmd, qemuProcessHook,&hookData);
>> @@ -4104,6 +4111,14 @@ void qemuProcessStop(virQEMUDriverPtr driver,
>> flags& VIR_QEMU_PROCESS_STOP_MIGRATED);
>> virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
>>
>> + for (i = 0; i< vm->def->ndisks; i++) {
>> + virDomainDiskDefPtr disk = vm->def->disks[i];
>> +
>> + if (disk->shared) {
>> + ignore_value(qemuRemoveSharedDisk(driver->sharedDisks, disk->src));
>> + }
>> + }
>> +
>> /* Clear out dynamically assigned labels */
>> for (i = 0; i< vm->def->nseclabels; i++) {
>> if (vm->def->seclabels[i]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
>
> With the diff below squashed in: (the dataFree was missed when
> changing the hash value from only ref count to a struct).
>
>

Ah, sorry, the correct diff is:


>
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: diff
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20121212/11df3877/attachment-0001.ksh>


More information about the libvir-list mailing list