mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 12:35:17 +00:00
hostdev: Introduce virDomainHostdevSubsysSCSIiSCSI
Create the structures and API's to hold and manage the iSCSI host device. This extends the 'scsi_host' definitions added in commit id '5c811dce'. A future patch will add the XML parsing, but that code requires some infrastructure to be in place first in order to handle the differences between a 'scsi_host' and an 'iSCSI host' device.
This commit is contained in:
parent
a062d1a1cc
commit
17bddc46f4
@ -424,12 +424,22 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr hostdev,
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
if (virAsprintfQuiet(&address, "%s:%d:%d:%d",
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit) < 0) {
|
||||
VIR_WARN("OOM while encoding audit message");
|
||||
if (scsisrc->protocol ==
|
||||
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||
/* Follow virDomainAuditDisk && virDomainAuditGenericDev
|
||||
* and don't audit the networked device.
|
||||
*/
|
||||
goto cleanup;
|
||||
} else {
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc =
|
||||
&scsisrc->u.host;
|
||||
if (virAsprintfQuiet(&address, "%s:%d:%d:%d",
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target,
|
||||
scsihostsrc->unit) < 0) {
|
||||
VIR_WARN("OOM while encoding audit message");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1695,6 +1695,17 @@ virDomainHostdevDefPtr virDomainHostdevDefAlloc(void)
|
||||
return def;
|
||||
}
|
||||
|
||||
static void
|
||||
virDomainHostdevSubsysSCSIiSCSIClear(virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc)
|
||||
{
|
||||
if (!iscsisrc)
|
||||
return;
|
||||
VIR_FREE(iscsisrc->path);
|
||||
virStorageNetHostDefFree(iscsisrc->nhosts, iscsisrc->hosts);
|
||||
virStorageAuthDefFree(iscsisrc->auth);
|
||||
iscsisrc->auth = NULL;
|
||||
}
|
||||
|
||||
void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
|
||||
{
|
||||
if (!def)
|
||||
@ -1725,8 +1736,15 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
|
||||
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
||||
VIR_FREE(def->source.subsys.u.scsi.u.host.adapter);
|
||||
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
|
||||
if (scsisrc->protocol ==
|
||||
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||
virDomainHostdevSubsysSCSIiSCSIClear(&scsisrc->u.iscsi);
|
||||
} else {
|
||||
VIR_FREE(scsisrc->u.host.adapter);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4306,8 +4324,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
||||
}
|
||||
|
||||
if (sgio) {
|
||||
if (def->source.subsys.type !=
|
||||
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
|
||||
if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("sgio is only supported for scsi host device"));
|
||||
goto error;
|
||||
@ -10255,6 +10272,22 @@ virDomainHostdevMatchSubsysSCSIHost(virDomainHostdevDefPtr first,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
virDomainHostdevMatchSubsysSCSIiSCSI(virDomainHostdevDefPtr first,
|
||||
virDomainHostdevDefPtr second)
|
||||
{
|
||||
virDomainHostdevSubsysSCSIiSCSIPtr first_iscsisrc =
|
||||
&first->source.subsys.u.scsi.u.iscsi;
|
||||
virDomainHostdevSubsysSCSIiSCSIPtr second_iscsisrc =
|
||||
&second->source.subsys.u.scsi.u.iscsi;
|
||||
|
||||
if (STREQ(first_iscsisrc->hosts[0].name, second_iscsisrc->hosts[0].name) &&
|
||||
STREQ(first_iscsisrc->hosts[0].port, second_iscsisrc->hosts[0].port) &&
|
||||
STREQ(first_iscsisrc->path, second_iscsisrc->path))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
|
||||
virDomainHostdevDefPtr b)
|
||||
@ -10268,7 +10301,11 @@ virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||
return virDomainHostdevMatchSubsysUSB(a, b);
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
|
||||
return virDomainHostdevMatchSubsysSCSIHost(a, b);
|
||||
if (a->source.subsys.u.scsi.protocol ==
|
||||
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
||||
return virDomainHostdevMatchSubsysSCSIiSCSI(a, b);
|
||||
else
|
||||
return virDomainHostdevMatchSubsysSCSIHost(a, b);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -388,6 +388,15 @@ typedef enum {
|
||||
|
||||
VIR_ENUM_DECL(virDomainHostdevSubsysPCIBackend)
|
||||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE,
|
||||
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI,
|
||||
|
||||
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_LAST,
|
||||
} virDomainHostdevSCSIProtocolType;
|
||||
|
||||
VIR_ENUM_DECL(virDomainHostdevSubsysSCSIProtocol)
|
||||
|
||||
typedef struct _virDomainHostdevSubsysUSB virDomainHostdevSubsysUSB;
|
||||
typedef virDomainHostdevSubsysUSB *virDomainHostdevSubsysUSBPtr;
|
||||
struct _virDomainHostdevSubsysUSB {
|
||||
@ -416,12 +425,23 @@ struct _virDomainHostdevSubsysSCSIHost {
|
||||
unsigned unit;
|
||||
};
|
||||
|
||||
typedef struct _virDomainHostdevSubsysSCSIiSCSI virDomainHostdevSubsysSCSIiSCSI;
|
||||
typedef virDomainHostdevSubsysSCSIiSCSI *virDomainHostdevSubsysSCSIiSCSIPtr;
|
||||
struct _virDomainHostdevSubsysSCSIiSCSI {
|
||||
char *path;
|
||||
size_t nhosts;
|
||||
virStorageNetHostDefPtr hosts;
|
||||
virStorageAuthDefPtr auth;
|
||||
};
|
||||
|
||||
typedef struct _virDomainHostdevSubsysSCSI virDomainHostdevSubsysSCSI;
|
||||
typedef virDomainHostdevSubsysSCSI *virDomainHostdevSubsysSCSIPtr;
|
||||
struct _virDomainHostdevSubsysSCSI {
|
||||
int protocol; /* enum virDomainHostdevSCSIProtocolType */
|
||||
int sgio; /* enum virDomainDeviceSGIO */
|
||||
union {
|
||||
virDomainHostdevSubsysSCSIHost host;
|
||||
virDomainHostdevSubsysSCSIiSCSI iscsi;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -307,18 +307,31 @@ qemuSetupHostdevCGroup(virDomainObjPtr vm,
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
if ((scsi = virSCSIDeviceNew(NULL,
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit,
|
||||
dev->readonly,
|
||||
dev->shareable)) == NULL)
|
||||
goto cleanup;
|
||||
if (scsisrc->protocol ==
|
||||
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||
virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
|
||||
/* Follow qemuSetupDiskCgroup() and qemuSetImageCgroupInternal()
|
||||
* which does nothing for non local storage
|
||||
*/
|
||||
VIR_DEBUG("Not updating cgroups for hostdev iSCSI path '%s'",
|
||||
iscsisrc->path);
|
||||
} else {
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc =
|
||||
&scsisrc->u.host;
|
||||
if ((scsi = virSCSIDeviceNew(NULL,
|
||||
scsihostsrc->adapter,
|
||||
scsihostsrc->bus,
|
||||
scsihostsrc->target,
|
||||
scsihostsrc->unit,
|
||||
dev->readonly,
|
||||
dev->shareable)) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if (virSCSIDeviceFileIterate(scsi,
|
||||
qemuSetupHostSCSIDeviceCgroup,
|
||||
vm) < 0)
|
||||
goto cleanup;
|
||||
if (virSCSIDeviceFileIterate(scsi,
|
||||
qemuSetupHostSCSIDeviceCgroup,
|
||||
vm) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5124,13 +5124,11 @@ qemuBuildUSBHostdevUSBDevStr(virDomainHostdevDefPtr dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
qemuBuildSCSIHostdevDrvStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainHostdevDefPtr dev,
|
||||
virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
|
||||
qemuBuildCommandLineCallbacksPtr callbacks)
|
||||
static char *
|
||||
qemuBuildSCSIHostHostdevDrvStr(virDomainHostdevDefPtr dev,
|
||||
virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
|
||||
qemuBuildCommandLineCallbacksPtr callbacks)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
char *sg = NULL;
|
||||
@ -5140,10 +5138,64 @@ qemuBuildSCSIHostdevDrvStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
scsihostsrc->bus,
|
||||
scsihostsrc->target,
|
||||
scsihostsrc->unit);
|
||||
if (!sg)
|
||||
goto error;
|
||||
return sg;
|
||||
}
|
||||
|
||||
virBufferAsprintf(&buf, "file=/dev/%s,if=none", sg);
|
||||
static char *
|
||||
qemuBuildSCSIiSCSIHostdevDrvStr(virConnectPtr conn,
|
||||
virDomainHostdevDefPtr dev)
|
||||
{
|
||||
char *source = NULL;
|
||||
char *secret = NULL;
|
||||
char *username = NULL;
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
||||
virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
|
||||
|
||||
if (conn && iscsisrc->auth) {
|
||||
const char *protocol =
|
||||
virStorageNetProtocolTypeToString(VIR_STORAGE_NET_PROTOCOL_ISCSI);
|
||||
bool encode = false;
|
||||
int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;
|
||||
|
||||
username = iscsisrc->auth->username;
|
||||
if (!(secret = qemuGetSecretString(conn, protocol, encode,
|
||||
iscsisrc->auth, secretType)))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Rather than pull what we think we want - use the network disk code */
|
||||
source = qemuBuildNetworkDriveURI(VIR_STORAGE_NET_PROTOCOL_ISCSI,
|
||||
iscsisrc->path,
|
||||
NULL, /* volume */
|
||||
iscsisrc->nhosts,
|
||||
iscsisrc->hosts,
|
||||
username, secret);
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(secret);
|
||||
return source;
|
||||
}
|
||||
|
||||
char *
|
||||
qemuBuildSCSIHostdevDrvStr(virConnectPtr conn,
|
||||
virDomainHostdevDefPtr dev,
|
||||
virQEMUCapsPtr qemuCaps,
|
||||
qemuBuildCommandLineCallbacksPtr callbacks)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
char *source = NULL;
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
||||
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||
if (!(source = qemuBuildSCSIiSCSIHostdevDrvStr(conn, dev)))
|
||||
goto error;
|
||||
virBufferAsprintf(&buf, "file=%s,if=none,format=raw", source);
|
||||
} else {
|
||||
if (!(source = qemuBuildSCSIHostHostdevDrvStr(dev, qemuCaps,
|
||||
callbacks)))
|
||||
goto error;
|
||||
virBufferAsprintf(&buf, "file=/dev/%s,if=none", source);
|
||||
}
|
||||
virBufferAsprintf(&buf, ",id=%s-%s",
|
||||
virDomainDeviceAddressTypeToString(dev->info->type),
|
||||
dev->info->alias);
|
||||
@ -5162,10 +5214,10 @@ qemuBuildSCSIHostdevDrvStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
if (virBufferCheckError(&buf) < 0)
|
||||
goto error;
|
||||
|
||||
VIR_FREE(sg);
|
||||
VIR_FREE(source);
|
||||
return virBufferContentAndReset(&buf);
|
||||
error:
|
||||
VIR_FREE(sg);
|
||||
VIR_FREE(source);
|
||||
virBufferFreeAndReset(&buf);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1575,11 +1575,18 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
|
||||
if (qemuPrepareHostdevSCSIDevices(driver, vm->def->name,
|
||||
&hostdev, 1)) {
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Unable to prepare scsi hostdev: %s:%d:%d:%d"),
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit);
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||
virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Unable to prepare scsi hostdev for iSCSI: %s"),
|
||||
iscsisrc->path);
|
||||
} else {
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Unable to prepare scsi hostdev: %s:%d:%d:%d"),
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -3400,11 +3407,20 @@ int qemuDomainDetachHostDevice(virConnectPtr conn,
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
_("host scsi device %s:%d:%d.%d not found"),
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit);
|
||||
if (scsisrc->protocol ==
|
||||
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||
virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
_("host scsi iSCSI path %s not found"),
|
||||
iscsisrc->path);
|
||||
} else {
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc =
|
||||
&scsisrc->u.host;
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
_("host scsi device %s:%d:%d.%d not found"),
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -825,6 +825,12 @@ AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
return 0;
|
||||
|
||||
/* Like AppArmorRestoreSecurityImageLabel() for a networked disk,
|
||||
* do nothing for an iSCSI hostdev
|
||||
*/
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
||||
return 0;
|
||||
|
||||
if (profile_loaded(secdef->imagelabel) < 0)
|
||||
return 0;
|
||||
|
||||
|
@ -520,6 +520,12 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
return 0;
|
||||
|
||||
/* Like virSecurityDACSetSecurityImageLabel() for a networked disk,
|
||||
* do nothing for an iSCSI hostdev
|
||||
*/
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
||||
return 0;
|
||||
|
||||
cbdata.manager = mgr;
|
||||
cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
|
||||
|
||||
@ -648,6 +654,12 @@ virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
return 0;
|
||||
|
||||
/* Like virSecurityDACRestoreSecurityImageLabelInt() for a networked disk,
|
||||
* do nothing for an iSCSI hostdev
|
||||
*/
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
||||
return 0;
|
||||
|
||||
switch ((virDomainHostdevSubsysType) dev->source.subsys.type) {
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
||||
virUSBDevicePtr usb;
|
||||
|
@ -1324,6 +1324,12 @@ virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def,
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
||||
int ret = -1;
|
||||
|
||||
/* Like virSecuritySELinuxSetSecurityImageLabelInternal() for a networked
|
||||
* disk, do nothing for an iSCSI hostdev
|
||||
*/
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
||||
return 0;
|
||||
|
||||
switch (dev->source.subsys.type) {
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
||||
virUSBDevicePtr usb;
|
||||
@ -1511,6 +1517,12 @@ virSecuritySELinuxRestoreSecurityHostdevSubsysLabel(virSecurityManagerPtr mgr,
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
||||
int ret = -1;
|
||||
|
||||
/* Like virSecuritySELinuxRestoreSecurityImageLabelInt() for a networked
|
||||
* disk, do nothing for an iSCSI hostdev
|
||||
*/
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
||||
return 0;
|
||||
|
||||
switch (dev->source.subsys.type) {
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
||||
virUSBDevicePtr usb;
|
||||
|
@ -920,6 +920,43 @@ virHostdevUpdateActiveUSBDevices(virHostdevManagerPtr mgr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
virHostdevUpdateActiveSCSIHostDevices(virHostdevManagerPtr mgr,
|
||||
virDomainHostdevDefPtr hostdev,
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc,
|
||||
const char *drv_name,
|
||||
const char *dom_name)
|
||||
{
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
virSCSIDevicePtr scsi = NULL;
|
||||
virSCSIDevicePtr tmp = NULL;
|
||||
int ret = -1;
|
||||
|
||||
if (!(scsi = virSCSIDeviceNew(NULL,
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit,
|
||||
hostdev->readonly, hostdev->shareable)))
|
||||
goto cleanup;
|
||||
|
||||
if ((tmp = virSCSIDeviceListFind(mgr->activeSCSIHostdevs, scsi))) {
|
||||
if (virSCSIDeviceSetUsedBy(tmp, drv_name, dom_name) < 0) {
|
||||
virSCSIDeviceFree(scsi);
|
||||
goto cleanup;
|
||||
}
|
||||
virSCSIDeviceFree(scsi);
|
||||
} else {
|
||||
if (virSCSIDeviceSetUsedBy(scsi, drv_name, dom_name) < 0 ||
|
||||
virSCSIDeviceListAdd(mgr->activeSCSIHostdevs, scsi) < 0) {
|
||||
virSCSIDeviceFree(scsi);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
@ -930,40 +967,26 @@ virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
|
||||
virDomainHostdevDefPtr hostdev = NULL;
|
||||
size_t i;
|
||||
int ret = -1;
|
||||
virSCSIDevicePtr scsi = NULL;
|
||||
virSCSIDevicePtr tmp = NULL;
|
||||
|
||||
if (!nhostdevs)
|
||||
return 0;
|
||||
|
||||
virObjectLock(mgr->activeSCSIHostdevs);
|
||||
for (i = 0; i < nhostdevs; i++) {
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc;
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc;
|
||||
hostdev = hostdevs[i];
|
||||
scsihostsrc = &hostdev->source.subsys.u.scsi.u.host;
|
||||
scsisrc = &hostdev->source.subsys.u.scsi;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
||||
continue;
|
||||
|
||||
if (!(scsi = virSCSIDeviceNew(NULL,
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit,
|
||||
hostdev->readonly, hostdev->shareable)))
|
||||
goto cleanup;
|
||||
|
||||
if ((tmp = virSCSIDeviceListFind(mgr->activeSCSIHostdevs, scsi))) {
|
||||
if (virSCSIDeviceSetUsedBy(tmp, drv_name, dom_name) < 0) {
|
||||
virSCSIDeviceFree(scsi);
|
||||
goto cleanup;
|
||||
}
|
||||
virSCSIDeviceFree(scsi);
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||
continue; /* Not supported for iSCSI */
|
||||
} else {
|
||||
if (virSCSIDeviceSetUsedBy(scsi, drv_name, dom_name) < 0 ||
|
||||
virSCSIDeviceListAdd(mgr->activeSCSIHostdevs, scsi) < 0) {
|
||||
virSCSIDeviceFree(scsi);
|
||||
if (virHostdevUpdateActiveSCSIHostDevices(mgr, hostdev, scsisrc,
|
||||
drv_name, dom_name) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
@ -1193,6 +1216,38 @@ virHostdevPrepareUSBDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
virHostdevPrepareSCSIHostDevices(virDomainHostdevDefPtr hostdev,
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc,
|
||||
virSCSIDeviceListPtr list)
|
||||
{
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
virSCSIDevicePtr scsi;
|
||||
int ret = -1;
|
||||
|
||||
if (hostdev->managed) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("SCSI host device doesn't support managed mode"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(scsi = virSCSIDeviceNew(NULL,
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit,
|
||||
hostdev->readonly, hostdev->shareable)))
|
||||
goto cleanup;
|
||||
|
||||
if (virSCSIDeviceListAdd(list, scsi) < 0) {
|
||||
virSCSIDeviceFree(scsi);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
const char *drv_name,
|
||||
@ -1219,29 +1274,17 @@ virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
/* Loop 1: build temporary list */
|
||||
for (i = 0; i < nhostdevs; i++) {
|
||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc =
|
||||
&hostdev->source.subsys.u.scsi.u.host;
|
||||
virSCSIDevicePtr scsi;
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.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,
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit,
|
||||
hostdev->readonly, hostdev->shareable)))
|
||||
goto cleanup;
|
||||
|
||||
if (scsi && virSCSIDeviceListAdd(list, scsi) < 0) {
|
||||
virSCSIDeviceFree(scsi);
|
||||
goto cleanup;
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||
continue; /* Not supported for iSCSI */
|
||||
} else {
|
||||
if (virHostdevPrepareSCSIHostDevices(hostdev, scsisrc, list) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1366,6 +1409,48 @@ virHostdevReAttachUSBDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
virObjectUnlock(hostdev_mgr->activeUSBHostdevs);
|
||||
}
|
||||
|
||||
static void
|
||||
virHostdevReAttachSCSIHostDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
virDomainHostdevDefPtr hostdev,
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc,
|
||||
const char *drv_name,
|
||||
const char *dom_name)
|
||||
{
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
virSCSIDevicePtr scsi;
|
||||
virSCSIDevicePtr tmp;
|
||||
|
||||
if (!(scsi = virSCSIDeviceNew(NULL,
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit,
|
||||
hostdev->readonly, hostdev->shareable))) {
|
||||
VIR_WARN("Unable to reattach SCSI device %s:%d:%d:%d on domain %s",
|
||||
scsihostsrc->adapter, scsihostsrc->bus, scsihostsrc->target,
|
||||
scsihostsrc->unit, dom_name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only delete the devices which are marked as being used by @name,
|
||||
* because qemuProcessStart could fail half way through. */
|
||||
|
||||
if (!(tmp = virSCSIDeviceListFind(hostdev_mgr->activeSCSIHostdevs, scsi))) {
|
||||
VIR_WARN("Unable to find device %s:%d:%d:%d "
|
||||
"in list of active SCSI devices",
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit);
|
||||
virSCSIDeviceFree(scsi);
|
||||
return;
|
||||
}
|
||||
|
||||
VIR_DEBUG("Removing %s:%d:%d:%d dom=%s from activeSCSIHostdevs",
|
||||
scsihostsrc->adapter, scsihostsrc->bus, scsihostsrc->target,
|
||||
scsihostsrc->unit, dom_name);
|
||||
|
||||
virSCSIDeviceListDel(hostdev_mgr->activeSCSIHostdevs, tmp,
|
||||
drv_name, dom_name);
|
||||
virSCSIDeviceFree(scsi);
|
||||
}
|
||||
|
||||
void
|
||||
virHostdevReAttachSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
const char *drv_name,
|
||||
@ -1381,44 +1466,17 @@ virHostdevReAttachSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
virObjectLock(hostdev_mgr->activeSCSIHostdevs);
|
||||
for (i = 0; i < nhostdevs; i++) {
|
||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc =
|
||||
&hostdev->source.subsys.u.scsi.u.host;
|
||||
virSCSIDevicePtr scsi;
|
||||
virSCSIDevicePtr tmp;
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
||||
continue;
|
||||
|
||||
if (!(scsi = virSCSIDeviceNew(NULL,
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit,
|
||||
hostdev->readonly, hostdev->shareable))) {
|
||||
VIR_WARN("Unable to reattach SCSI device %s:%d:%d:%d on domain %s",
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit, dom_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only delete the devices which are marked as being used by @name,
|
||||
* because qemuProcessStart could fail on the half way. */
|
||||
|
||||
if (!(tmp = virSCSIDeviceListFind(hostdev_mgr->activeSCSIHostdevs, scsi))) {
|
||||
VIR_WARN("Unable to find device %s:%d:%d:%d "
|
||||
"in list of active SCSI devices",
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit);
|
||||
virSCSIDeviceFree(scsi);
|
||||
continue;
|
||||
}
|
||||
|
||||
VIR_DEBUG("Removing %s:%d:%d:%d dom=%s from activeSCSIHostdevs",
|
||||
scsihostsrc->adapter, scsihostsrc->bus,
|
||||
scsihostsrc->target, scsihostsrc->unit, dom_name);
|
||||
|
||||
virSCSIDeviceListDel(hostdev_mgr->activeSCSIHostdevs, tmp,
|
||||
drv_name, dom_name);
|
||||
virSCSIDeviceFree(scsi);
|
||||
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
||||
continue; /* Not supported for iSCSI */
|
||||
else
|
||||
virHostdevReAttachSCSIHostDevices(hostdev_mgr, hostdev, scsisrc,
|
||||
drv_name, dom_name);
|
||||
}
|
||||
virObjectUnlock(hostdev_mgr->activeSCSIHostdevs);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user