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

Osier Yang jyang at redhat.com
Wed Dec 12 03:35:52 UTC 2012


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).


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


More information about the libvir-list mailing list