提交 5035f75f 编写于 作者: C Chunyan Liu 提交者: Daniel P. Berrange

move virHostdevPrepareHostSCSIDevices to virhostdev.c

上级 c82c2745
......@@ -1300,6 +1300,7 @@ virHookPresent;
#util/virhostdev.h
virHostdevManagerGetDefault;
virHostdevPreparePCIDevices;
virHostdevPrepareSCSIDevices;
virHostdevPrepareUSBDevices;
virHostdevReAttachPCIDevices;
virHostdevUpdateActivePciHostdevs;
......
......@@ -245,117 +245,6 @@ qemuPrepareHostUSBDevices(virQEMUDriverPtr driver,
hostdevs, nhostdevs, flags);
}
static int
virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_mgr,
const char *drv_name,
const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs)
{
size_t i, j;
int count;
virSCSIDeviceListPtr list;
virSCSIDevicePtr tmp;
/* To prevent situation where SCSI device is assigned to two domains
* we need to keep a list of currently assigned SCSI devices.
* This is done in several loops which cannot be joined into one big
* loop. See virHostdevPreparePCIDevices()
*/
if (!(list = virSCSIDeviceListNew()))
goto cleanup;
/* Loop 1: build temporary list */
for (i = 0; i < nhostdevs; i++) {
virDomainHostdevDefPtr hostdev = hostdevs[i];
virSCSIDevicePtr scsi;
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
continue;
if (hostdev->managed) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("SCSI host device doesn't support managed mode"));
goto cleanup;
}
if (!(scsi = virSCSIDeviceNew(NULL,
hostdev->source.subsys.u.scsi.adapter,
hostdev->source.subsys.u.scsi.bus,
hostdev->source.subsys.u.scsi.target,
hostdev->source.subsys.u.scsi.unit,
hostdev->readonly,
hostdev->shareable)))
goto cleanup;
if (scsi && virSCSIDeviceListAdd(list, scsi) < 0) {
virSCSIDeviceFree(scsi);
goto cleanup;
}
}
/* Loop 2: Mark devices in temporary list as used by @name
* and add them to driver list. However, if something goes
* wrong, perform rollback.
*/
virObjectLock(hostdev_mgr->activeScsiHostdevs);
count = virSCSIDeviceListCount(list);
for (i = 0; i < count; i++) {
virSCSIDevicePtr scsi = virSCSIDeviceListGet(list, i);
if ((tmp = virSCSIDeviceListFind(hostdev_mgr->activeScsiHostdevs,
scsi))) {
bool scsi_shareable = virSCSIDeviceGetShareable(scsi);
bool tmp_shareable = virSCSIDeviceGetShareable(tmp);
if (!(scsi_shareable && tmp_shareable)) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("SCSI device %s is already in use by "
"other domain(s) as '%s'"),
virSCSIDeviceGetName(tmp),
tmp_shareable ? "shareable" : "non-shareable");
goto error;
}
if (virSCSIDeviceSetUsedBy(tmp, drv_name, name) < 0)
goto error;
} else {
if (virSCSIDeviceSetUsedBy(scsi, drv_name, name) < 0)
goto error;
VIR_DEBUG("Adding %s to activeScsiHostdevs", virSCSIDeviceGetName(scsi));
if (virSCSIDeviceListAdd(hostdev_mgr->activeScsiHostdevs, scsi) < 0)
goto error;
}
}
virObjectUnlock(hostdev_mgr->activeScsiHostdevs);
/* Loop 3: Temporary list was successfully merged with
* driver list, so steal all items to avoid freeing them
* when freeing temporary list.
*/
while (virSCSIDeviceListCount(list) > 0) {
tmp = virSCSIDeviceListGet(list, 0);
virSCSIDeviceListSteal(list, tmp);
}
virObjectUnref(list);
return 0;
error:
for (j = 0; j < i; j++) {
tmp = virSCSIDeviceListGet(list, i);
virSCSIDeviceListSteal(hostdev_mgr->activeScsiHostdevs, tmp);
}
virObjectUnlock(hostdev_mgr->activeScsiHostdevs);
cleanup:
virObjectUnref(list);
return -1;
}
int
qemuPrepareHostdevSCSIDevices(virQEMUDriverPtr driver,
const char *name,
......
......@@ -1140,3 +1140,114 @@ cleanup:
virObjectUnref(list);
return ret;
}
int
virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_mgr,
const char *drv_name,
const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs)
{
size_t i, j;
int count;
virSCSIDeviceListPtr list;
virSCSIDevicePtr tmp;
/* To prevent situation where SCSI device is assigned to two domains
* we need to keep a list of currently assigned SCSI devices.
* This is done in several loops which cannot be joined into one big
* loop. See virHostdevPreparePCIDevices()
*/
if (!(list = virSCSIDeviceListNew()))
goto cleanup;
/* Loop 1: build temporary list */
for (i = 0; i < nhostdevs; i++) {
virDomainHostdevDefPtr hostdev = hostdevs[i];
virSCSIDevicePtr scsi;
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
continue;
if (hostdev->managed) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("SCSI host device doesn't support managed mode"));
goto cleanup;
}
if (!(scsi = virSCSIDeviceNew(NULL,
hostdev->source.subsys.u.scsi.adapter,
hostdev->source.subsys.u.scsi.bus,
hostdev->source.subsys.u.scsi.target,
hostdev->source.subsys.u.scsi.unit,
hostdev->readonly,
hostdev->shareable)))
goto cleanup;
if (scsi && virSCSIDeviceListAdd(list, scsi) < 0) {
virSCSIDeviceFree(scsi);
goto cleanup;
}
}
/* Loop 2: Mark devices in temporary list as used by @name
* and add them to driver list. However, if something goes
* wrong, perform rollback.
*/
virObjectLock(hostdev_mgr->activeScsiHostdevs);
count = virSCSIDeviceListCount(list);
for (i = 0; i < count; i++) {
virSCSIDevicePtr scsi = virSCSIDeviceListGet(list, i);
if ((tmp = virSCSIDeviceListFind(hostdev_mgr->activeScsiHostdevs,
scsi))) {
bool scsi_shareable = virSCSIDeviceGetShareable(scsi);
bool tmp_shareable = virSCSIDeviceGetShareable(tmp);
if (!(scsi_shareable && tmp_shareable)) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("SCSI device %s is already in use by "
"other domain(s) as '%s'"),
virSCSIDeviceGetName(tmp),
tmp_shareable ? "shareable" : "non-shareable");
goto error;
}
if (virSCSIDeviceSetUsedBy(tmp, drv_name, name) < 0)
goto error;
} else {
if (virSCSIDeviceSetUsedBy(scsi, drv_name, name) < 0)
goto error;
VIR_DEBUG("Adding %s to activeScsiHostdevs", virSCSIDeviceGetName(scsi));
if (virSCSIDeviceListAdd(hostdev_mgr->activeScsiHostdevs, scsi) < 0)
goto error;
}
}
virObjectUnlock(hostdev_mgr->activeScsiHostdevs);
/* Loop 3: Temporary list was successfully merged with
* driver list, so steal all items to avoid freeing them
* when freeing temporary list.
*/
while (virSCSIDeviceListCount(list) > 0) {
tmp = virSCSIDeviceListGet(list, 0);
virSCSIDeviceListSteal(list, tmp);
}
virObjectUnref(list);
return 0;
error:
for (j = 0; j < i; j++) {
tmp = virSCSIDeviceListGet(list, i);
virSCSIDeviceListSteal(hostdev_mgr->activeScsiHostdevs, tmp);
}
virObjectUnlock(hostdev_mgr->activeScsiHostdevs);
cleanup:
virObjectUnref(list);
return -1;
}
......@@ -65,6 +65,12 @@ virHostdevPrepareUSBDevices(virHostdevManagerPtr hostdev_mgr,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs,
unsigned int flags);
int
virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_mgr,
const char *drv_name,
const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs);
void
virHostdevReAttachPCIDevices(virHostdevManagerPtr hostdev_mgr,
const char *drv_name,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册