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))
+ 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;
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;
+ } else {
return 0;
+ }
qemuDriverLock(driver);
- if (!(key = qemuGetSharedDeviceKey(disk->src)))
- goto cleanup;
+
+ if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+ 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)))
goto cleanup;
ret = 0;
cleanup:
qemuDriverUnlock(driver);
+ VIR_FREE(dev_name);
+ VIR_FREE(dev_path);
VIR_FREE(key);
return ret;
}
int *index)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-int qemuAddSharedDisk(virQEMUDriverPtr driver,
- virDomainDiskDefPtr disk,
- const char *name)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
-
-int qemuRemoveSharedDisk(virQEMUDriverPtr driver,
- virDomainDiskDefPtr disk,
- const char *name)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
-
char * qemuGetSharedDeviceKey(const char *disk_path)
ATTRIBUTE_NONNULL(1);
void qemuSharedDeviceEntryFree(void *payload, const void *name)
ATTRIBUTE_NONNULL(1);
+int qemuAddSharedDevice(virQEMUDriverPtr driver,
+ virDomainDeviceDefPtr dev,
+ const char *name)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
+int qemuRemoveSharedDevice(virQEMUDriverPtr driver,
+ virDomainDeviceDefPtr dev,
+ const char *name)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
int qemuDriverAllocateID(virQEMUDriverPtr driver);
virDomainXMLOptionPtr virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver);
if (qemuTranslateDiskSourcePool(conn, disk) < 0)
goto end;
- if (qemuAddSharedDisk(driver, disk, vm->def->name) < 0)
+ if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0)
goto end;
if (qemuSetUnprivSGIO(disk) < 0)
* if the operation is either ejecting or updating.
*/
if (ret == 0)
- ignore_value(qemuRemoveSharedDisk(driver, dev_copy->data.disk,
- vm->def->name));
+ ignore_value(qemuRemoveSharedDevice(driver, dev_copy,
+ vm->def->name));
break;
case VIR_DOMAIN_DISK_DEVICE_DISK:
case VIR_DOMAIN_DISK_DEVICE_LUN:
end:
if (ret != 0)
- ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
+ ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name));
virObjectUnref(caps);
virDomainDeviceDefFree(dev_copy);
return ret;
}
if (ret == 0)
- ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
+ ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name));
return ret;
}
dev->data.disk = tmp;
/* Add the new disk src into shared disk hash table */
- if (qemuAddSharedDisk(driver, dev->data.disk, vm->def->name) < 0)
+ if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0)
goto end;
ret = qemuDomainChangeEjectableMedia(driver, vm, disk, orig_disk, force);
*/
if (ret == 0) {
dev->data.disk = NULL;
- ignore_value(qemuRemoveSharedDisk(driver, dev_copy->data.disk,
- vm->def->name));
+ ignore_value(qemuRemoveSharedDevice(driver, dev_copy,
+ vm->def->name));
}
break;
default:
* qemu_driver->sharedDevices.
*/
for (i = 0; i < obj->def->ndisks; i++) {
+ virDomainDeviceDef dev;
+
if (qemuTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0)
goto error;
- if (qemuAddSharedDisk(driver, obj->def->disks[i],
- obj->def->name) < 0)
+
+ dev.type = VIR_DOMAIN_DEVICE_DISK;
+ dev.data.disk = obj->def->disks[i];
+ if (qemuAddSharedDevice(driver, &dev, obj->def->name) < 0)
goto error;
}
/* in case a certain disk is desirous of CAP_SYS_RAWIO, add this */
for (i = 0; i < vm->def->ndisks; i++) {
+ virDomainDeviceDef dev;
virDomainDiskDefPtr disk = vm->def->disks[i];
if (vm->def->disks[i]->rawio == 1)
_("Raw I/O is not supported on this platform"));
#endif
- if (qemuAddSharedDisk(driver, disk, vm->def->name) < 0)
+ dev.type = VIR_DOMAIN_DEVICE_DISK;
+ dev.data.disk = disk;
+ if (qemuAddSharedDevice(driver, &dev, vm->def->name) < 0)
goto cleanup;
if (qemuSetUnprivSGIO(disk) < 0)
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
for (i = 0; i < vm->def->ndisks; i++) {
+ virDomainDeviceDef dev;
virDomainDiskDefPtr disk = vm->def->disks[i];
- ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
+
+ dev.type = VIR_DOMAIN_DEVICE_DISK;
+ dev.data.disk = disk;
+ ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
}
/* Clear out dynamically assigned labels */