[libvirt] [PATCH 18/25] qemu: Refactor the helpers to track shared scsi host device
Osier Yang
jyang at redhat.com
Thu May 16 16:34:11 UTC 2013
On 08/05/13 02:57, John Ferlan wrote:
> On 05/03/2013 02:07 PM, Osier Yang wrote:
>> This changes the helpers qemu{Add,Remove}SharedDisk into
>> qemu{Add,Remove}SharedDevice, as most of the code in the helpers
>> can be reused for scsi host device.
>>
>> To track the shared scsi host device, first it finds out the
>> device path (e.g. /dev/s[dr]*) which is mapped to the sg device,
>> and use device ID of the found device path (/dev/s[dr]*) as the
>> hash key. This is because of the device ID is not unique between
>> between /dev/s[dr]* and /dev/sg*, e.g.
>>
>> % sg_map
>> /dev/sg0 /dev/sda
>> /dev/sg1 /dev/sr0
>>
>> % ls -l /dev/sda
>> brw-rw----. 1 root disk 8, 0 May 2 19:26 /dev/sda
>>
>> %ls -l /dev/sg0
>> crw-rw----. 1 root disk 21, 0 May 2 19:26 /dev/sg0
>> ---
>> src/qemu/qemu_conf.c | 143 ++++++++++++++++++++++++++++++++++++------------
>> src/qemu/qemu_conf.h | 20 +++----
>> src/qemu/qemu_driver.c | 16 +++---
>> src/qemu/qemu_process.c | 19 +++++--
>> 4 files changed, 140 insertions(+), 58 deletions(-)
>>
>> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
>> index 244795d..ebcd176 100644
>> --- a/src/qemu/qemu_conf.c
>> +++ b/src/qemu/qemu_conf.c
>> @@ -1084,47 +1084,80 @@ cleanup:
>> return NULL;
>> }
>>
>> -/* qemuAddSharedDisk:
>> +/* qemuAddSharedDevice:
>> * @driver: Pointer to qemu driver struct
>> - * @disk: The disk def
>> + * @dev: The device def
>> * @name: The domain name
>> *
>> * Increase ref count and add the domain name into the list which
>> - * records all the domains that use the shared disk if the entry
>> + * records all the domains that use the shared device if the entry
>> * already exists, otherwise add a new entry.
>> */
>> int
>> -qemuAddSharedDisk(virQEMUDriverPtr driver,
>> - virDomainDiskDefPtr disk,
>> - const char *name)
>> +qemuAddSharedDevice(virQEMUDriverPtr driver,
>> + virDomainDeviceDefPtr dev,
>> + const char *name)
>> {
>> qemuSharedDeviceEntry *entry = NULL;
>> qemuSharedDeviceEntry *new_entry = NULL;
>> + virDomainDiskDefPtr disk = NULL;
>> + virDomainHostdevDefPtr hostdev = NULL;
>> + char *dev_name = NULL;
>> + char *dev_path = NULL;
>> char *key = NULL;
>> int ret = -1;
>>
>> - /* Currently the only conflicts we have to care about
>> - * for the shared disk is "sgio" setting, which is only
>> - * valid for block disk.
>> + /* Currently the only conflicts we have to care about for
>> + * the shared disk and shared host device is "sgio" setting,
>> + * which is only valid for block disk and scsi host device.
>> */
>> - if (!disk->shared ||
>> - !disk->src ||
>> - (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK &&
>> - !(disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME &&
>> - disk->srcpool &&
>> - disk->srcpool->voltype == VIR_STORAGE_VOL_BLOCK)))
>> + if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
>> + disk = dev->data.disk;
>> +
>> + if (disk->shared ||
>> + !disk->src ||
>> + (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK &&
>> + !(disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME &&
>> + disk->srcpool &&
>> + disk->srcpool->voltype == VIR_STORAGE_VOL_BLOCK)))
>> + return 0;
>> + } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
>> + hostdev = dev->data.hostdev;
>> +
>> + if (!hostdev->shareable ||
>> + (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
>> + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI))
> And this is the controller that's being OR'd so I think this is right,
> but making sure :-)
>
> Over time HPVM was asked to allow a whole controller to be shareable
> because the guest would control/manage the luns...
>
>
>> + return 0;
>> + } else {
>> return 0;
>> + }
>>
>> qemuDriverLock(driver);
>> - if (qemuCheckSharedDisk(driver->sharedDevices, disk) < 0)
>> - goto cleanup;
>> + if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
>> + if (qemuCheckSharedDisk(driver->sharedDevices, disk) < 0)
>> + goto cleanup;
>>
>> - if (!(key = qemuGetSharedDeviceKey(disk->src)))
>> - goto cleanup;
>> + if (!(key = qemuGetSharedDeviceKey(disk->src)))
>> + goto cleanup;
>> + } else {
>> + if (!(dev_name = virSCSIDeviceGetDevName(hostdev->source.subsys.u.scsi.adapter,
>> + hostdev->source.subsys.u.scsi.bus,
>> + hostdev->source.subsys.u.scsi.target,
>> + hostdev->source.subsys.u.scsi.unit)))
>> + goto cleanup;
>> +
>> + if (virAsprintf(&dev_path, "/dev/%s", dev_name) < 0) {
>> + virReportOOMError();
>> + goto cleanup;
>> + }
>> +
>> + if (!(key = qemuGetSharedDeviceKey(dev_path)))
>> + goto cleanup;
>> + }
>>
>> if ((entry = virHashLookup(driver->sharedDevices, key))) {
>> - /* Nothing to do if the shared disk is already recorded
>> - * in the table.
>> + /* Nothing to do if the shared scsi host device is already
>> + * recorded in the table.
>> */
>> if (qemuSharedDeviceEntryDomainExists(entry, name, NULL)) {
>> ret = 0;
>> @@ -1163,41 +1196,77 @@ qemuAddSharedDisk(virQEMUDriverPtr driver,
>> ret = 0;
>> cleanup:
>> qemuDriverUnlock(driver);
>> + VIR_FREE(dev_name);
>> + VIR_FREE(dev_path);
>> VIR_FREE(key);
>> return ret;
>> }
>>
>> -/* qemuRemoveSharedDisk:
>> +/* qemuRemoveSharedDevice:
>> * @driver: Pointer to qemu driver struct
>> - * @disk: The disk def
>> + * @device: The device def
>> * @name: The domain name
>> *
>> * Decrease ref count and remove the domain name from the list which
>> - * records all the domains that use the shared disk if ref is not 1,
>> - * otherwise remove the entry.
>> + * records all the domains that use the shared device if ref is not
>> + * 1, otherwise remove the entry.
>> */
>> int
>> -qemuRemoveSharedDisk(virQEMUDriverPtr driver,
>> - virDomainDiskDefPtr disk,
>> - const char *name)
>> +qemuRemoveSharedDevice(virQEMUDriverPtr driver,
>> + virDomainDeviceDefPtr dev,
>> + const char *name)
>> {
>> qemuSharedDeviceEntryPtr entry = NULL;
>> qemuSharedDeviceEntryPtr new_entry = NULL;
>> + virDomainDiskDefPtr disk = NULL;
>> + virDomainHostdevDefPtr hostdev = NULL;
>> char *key = NULL;
>> + char *dev_name = NULL;
>> + char *dev_path = NULL;
>> int ret = -1;
>> int idx;
>>
>> - if (!disk->shared ||
>> - !disk->src ||
>> - (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK &&
>> - !(disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME &&
>> - disk->srcpool &&
>> - disk->srcpool->voltype == VIR_STORAGE_VOL_BLOCK)))
>> + if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
>> + disk = dev->data.disk;
>> +
>> + if (!disk->shared ||
>> + !disk->src ||
>> + (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK &&
>> + !(disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME &&
>> + disk->srcpool &&
>> + disk->srcpool->voltype == VIR_STORAGE_VOL_BLOCK)))
>> + return 0;
>> + } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
>> + hostdev = dev->data.hostdev;
>> +
>> + if (!hostdev->shareable ||
>> + (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
>> + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI))
>> + return 0;
> Same in reverse...
>
>
> ACK on the remainder
>
pushed.
More information about the libvir-list
mailing list