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;
|
break;
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
||||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
if (scsisrc->protocol ==
|
||||||
if (virAsprintfQuiet(&address, "%s:%d:%d:%d",
|
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||||
scsihostsrc->adapter, scsihostsrc->bus,
|
/* Follow virDomainAuditDisk && virDomainAuditGenericDev
|
||||||
scsihostsrc->target, scsihostsrc->unit) < 0) {
|
* and don't audit the networked device.
|
||||||
VIR_WARN("OOM while encoding audit message");
|
*/
|
||||||
goto cleanup;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1695,6 +1695,17 @@ virDomainHostdevDefPtr virDomainHostdevDefAlloc(void)
|
|||||||
return def;
|
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)
|
void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
|
||||||
{
|
{
|
||||||
if (!def)
|
if (!def)
|
||||||
@ -1725,8 +1736,15 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
|
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
|
||||||
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
|
||||||
VIR_FREE(def->source.subsys.u.scsi.u.host.adapter);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4306,8 +4324,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sgio) {
|
if (sgio) {
|
||||||
if (def->source.subsys.type !=
|
if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
|
||||||
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
|
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("sgio is only supported for scsi host device"));
|
_("sgio is only supported for scsi host device"));
|
||||||
goto error;
|
goto error;
|
||||||
@ -10255,6 +10272,22 @@ virDomainHostdevMatchSubsysSCSIHost(virDomainHostdevDefPtr first,
|
|||||||
return 0;
|
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
|
static int
|
||||||
virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
|
virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
|
||||||
virDomainHostdevDefPtr b)
|
virDomainHostdevDefPtr b)
|
||||||
@ -10268,7 +10301,11 @@ virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
|
|||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||||
return virDomainHostdevMatchSubsysUSB(a, b);
|
return virDomainHostdevMatchSubsysUSB(a, b);
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -388,6 +388,15 @@ typedef enum {
|
|||||||
|
|
||||||
VIR_ENUM_DECL(virDomainHostdevSubsysPCIBackend)
|
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 struct _virDomainHostdevSubsysUSB virDomainHostdevSubsysUSB;
|
||||||
typedef virDomainHostdevSubsysUSB *virDomainHostdevSubsysUSBPtr;
|
typedef virDomainHostdevSubsysUSB *virDomainHostdevSubsysUSBPtr;
|
||||||
struct _virDomainHostdevSubsysUSB {
|
struct _virDomainHostdevSubsysUSB {
|
||||||
@ -416,12 +425,23 @@ struct _virDomainHostdevSubsysSCSIHost {
|
|||||||
unsigned unit;
|
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 struct _virDomainHostdevSubsysSCSI virDomainHostdevSubsysSCSI;
|
||||||
typedef virDomainHostdevSubsysSCSI *virDomainHostdevSubsysSCSIPtr;
|
typedef virDomainHostdevSubsysSCSI *virDomainHostdevSubsysSCSIPtr;
|
||||||
struct _virDomainHostdevSubsysSCSI {
|
struct _virDomainHostdevSubsysSCSI {
|
||||||
|
int protocol; /* enum virDomainHostdevSCSIProtocolType */
|
||||||
int sgio; /* enum virDomainDeviceSGIO */
|
int sgio; /* enum virDomainDeviceSGIO */
|
||||||
union {
|
union {
|
||||||
virDomainHostdevSubsysSCSIHost host;
|
virDomainHostdevSubsysSCSIHost host;
|
||||||
|
virDomainHostdevSubsysSCSIiSCSI iscsi;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -307,18 +307,31 @@ qemuSetupHostdevCGroup(virDomainObjPtr vm,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
||||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
if (scsisrc->protocol ==
|
||||||
if ((scsi = virSCSIDeviceNew(NULL,
|
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||||
scsihostsrc->adapter, scsihostsrc->bus,
|
virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
|
||||||
scsihostsrc->target, scsihostsrc->unit,
|
/* Follow qemuSetupDiskCgroup() and qemuSetImageCgroupInternal()
|
||||||
dev->readonly,
|
* which does nothing for non local storage
|
||||||
dev->shareable)) == NULL)
|
*/
|
||||||
goto cleanup;
|
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,
|
if (virSCSIDeviceFileIterate(scsi,
|
||||||
qemuSetupHostSCSIDeviceCgroup,
|
qemuSetupHostSCSIDeviceCgroup,
|
||||||
vm) < 0)
|
vm) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5124,13 +5124,11 @@ qemuBuildUSBHostdevUSBDevStr(virDomainHostdevDefPtr dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
static char *
|
||||||
qemuBuildSCSIHostdevDrvStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
qemuBuildSCSIHostHostdevDrvStr(virDomainHostdevDefPtr dev,
|
||||||
virDomainHostdevDefPtr dev,
|
virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
|
||||||
virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
|
qemuBuildCommandLineCallbacksPtr callbacks)
|
||||||
qemuBuildCommandLineCallbacksPtr callbacks)
|
|
||||||
{
|
{
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
||||||
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
||||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||||
char *sg = NULL;
|
char *sg = NULL;
|
||||||
@ -5140,10 +5138,64 @@ qemuBuildSCSIHostdevDrvStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
scsihostsrc->bus,
|
scsihostsrc->bus,
|
||||||
scsihostsrc->target,
|
scsihostsrc->target,
|
||||||
scsihostsrc->unit);
|
scsihostsrc->unit);
|
||||||
if (!sg)
|
return sg;
|
||||||
goto error;
|
}
|
||||||
|
|
||||||
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",
|
virBufferAsprintf(&buf, ",id=%s-%s",
|
||||||
virDomainDeviceAddressTypeToString(dev->info->type),
|
virDomainDeviceAddressTypeToString(dev->info->type),
|
||||||
dev->info->alias);
|
dev->info->alias);
|
||||||
@ -5162,10 +5214,10 @@ qemuBuildSCSIHostdevDrvStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
if (virBufferCheckError(&buf) < 0)
|
if (virBufferCheckError(&buf) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
VIR_FREE(sg);
|
VIR_FREE(source);
|
||||||
return virBufferContentAndReset(&buf);
|
return virBufferContentAndReset(&buf);
|
||||||
error:
|
error:
|
||||||
VIR_FREE(sg);
|
VIR_FREE(source);
|
||||||
virBufferFreeAndReset(&buf);
|
virBufferFreeAndReset(&buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1575,11 +1575,18 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
|
|||||||
if (qemuPrepareHostdevSCSIDevices(driver, vm->def->name,
|
if (qemuPrepareHostdevSCSIDevices(driver, vm->def->name,
|
||||||
&hostdev, 1)) {
|
&hostdev, 1)) {
|
||||||
virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
|
virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
|
||||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
|
||||||
_("Unable to prepare scsi hostdev: %s:%d:%d:%d"),
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
scsihostsrc->adapter, scsihostsrc->bus,
|
_("Unable to prepare scsi hostdev for iSCSI: %s"),
|
||||||
scsihostsrc->target, scsihostsrc->unit);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3400,11 +3407,20 @@ int qemuDomainDetachHostDevice(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
||||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
if (scsisrc->protocol ==
|
||||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||||
_("host scsi device %s:%d:%d.%d not found"),
|
virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
|
||||||
scsihostsrc->adapter, scsihostsrc->bus,
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
scsihostsrc->target, scsihostsrc->unit);
|
_("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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -825,6 +825,12 @@ AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||||
return 0;
|
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)
|
if (profile_loaded(secdef->imagelabel) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -520,6 +520,12 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||||
return 0;
|
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.manager = mgr;
|
||||||
cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
|
cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
|
||||||
|
|
||||||
@ -648,6 +654,12 @@ virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||||
return 0;
|
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) {
|
switch ((virDomainHostdevSubsysType) dev->source.subsys.type) {
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
||||||
virUSBDevicePtr usb;
|
virUSBDevicePtr usb;
|
||||||
|
@ -1324,6 +1324,12 @@ virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def,
|
|||||||
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
||||||
int ret = -1;
|
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) {
|
switch (dev->source.subsys.type) {
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
||||||
virUSBDevicePtr usb;
|
virUSBDevicePtr usb;
|
||||||
@ -1511,6 +1517,12 @@ virSecuritySELinuxRestoreSecurityHostdevSubsysLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
|
||||||
int ret = -1;
|
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) {
|
switch (dev->source.subsys.type) {
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
||||||
virUSBDevicePtr usb;
|
virUSBDevicePtr usb;
|
||||||
|
@ -920,6 +920,43 @@ virHostdevUpdateActiveUSBDevices(virHostdevManagerPtr mgr,
|
|||||||
return ret;
|
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
|
int
|
||||||
virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
|
virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
|
||||||
virDomainHostdevDefPtr *hostdevs,
|
virDomainHostdevDefPtr *hostdevs,
|
||||||
@ -930,40 +967,26 @@ virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
|
|||||||
virDomainHostdevDefPtr hostdev = NULL;
|
virDomainHostdevDefPtr hostdev = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
virSCSIDevicePtr scsi = NULL;
|
|
||||||
virSCSIDevicePtr tmp = NULL;
|
|
||||||
|
|
||||||
if (!nhostdevs)
|
if (!nhostdevs)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
virObjectLock(mgr->activeSCSIHostdevs);
|
virObjectLock(mgr->activeSCSIHostdevs);
|
||||||
for (i = 0; i < nhostdevs; i++) {
|
for (i = 0; i < nhostdevs; i++) {
|
||||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc;
|
virDomainHostdevSubsysSCSIPtr scsisrc;
|
||||||
hostdev = hostdevs[i];
|
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 ||
|
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(scsi = virSCSIDeviceNew(NULL,
|
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||||
scsihostsrc->adapter, scsihostsrc->bus,
|
continue; /* Not supported for iSCSI */
|
||||||
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 {
|
} else {
|
||||||
if (virSCSIDeviceSetUsedBy(scsi, drv_name, dom_name) < 0 ||
|
if (virHostdevUpdateActiveSCSIHostDevices(mgr, hostdev, scsisrc,
|
||||||
virSCSIDeviceListAdd(mgr->activeSCSIHostdevs, scsi) < 0) {
|
drv_name, dom_name) < 0)
|
||||||
virSCSIDeviceFree(scsi);
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -1193,6 +1216,38 @@ virHostdevPrepareUSBDevices(virHostdevManagerPtr hostdev_mgr,
|
|||||||
return ret;
|
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
|
int
|
||||||
virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
||||||
const char *drv_name,
|
const char *drv_name,
|
||||||
@ -1219,29 +1274,17 @@ virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
|||||||
/* Loop 1: build temporary list */
|
/* Loop 1: build temporary list */
|
||||||
for (i = 0; i < nhostdevs; i++) {
|
for (i = 0; i < nhostdevs; i++) {
|
||||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc =
|
virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
|
||||||
&hostdev->source.subsys.u.scsi.u.host;
|
|
||||||
virSCSIDevicePtr scsi;
|
|
||||||
|
|
||||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (hostdev->managed) {
|
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
continue; /* Not supported for iSCSI */
|
||||||
_("SCSI host device doesn't support managed mode"));
|
} else {
|
||||||
goto cleanup;
|
if (virHostdevPrepareSCSIHostDevices(hostdev, scsisrc, list) < 0)
|
||||||
}
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,6 +1409,48 @@ virHostdevReAttachUSBDevices(virHostdevManagerPtr hostdev_mgr,
|
|||||||
virObjectUnlock(hostdev_mgr->activeUSBHostdevs);
|
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
|
void
|
||||||
virHostdevReAttachSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
virHostdevReAttachSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
||||||
const char *drv_name,
|
const char *drv_name,
|
||||||
@ -1381,44 +1466,17 @@ virHostdevReAttachSCSIDevices(virHostdevManagerPtr hostdev_mgr,
|
|||||||
virObjectLock(hostdev_mgr->activeSCSIHostdevs);
|
virObjectLock(hostdev_mgr->activeSCSIHostdevs);
|
||||||
for (i = 0; i < nhostdevs; i++) {
|
for (i = 0; i < nhostdevs; i++) {
|
||||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc =
|
virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
|
||||||
&hostdev->source.subsys.u.scsi.u.host;
|
|
||||||
virSCSIDevicePtr scsi;
|
|
||||||
virSCSIDevicePtr tmp;
|
|
||||||
|
|
||||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(scsi = virSCSIDeviceNew(NULL,
|
if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
||||||
scsihostsrc->adapter, scsihostsrc->bus,
|
continue; /* Not supported for iSCSI */
|
||||||
scsihostsrc->target, scsihostsrc->unit,
|
else
|
||||||
hostdev->readonly, hostdev->shareable))) {
|
virHostdevReAttachSCSIHostDevices(hostdev_mgr, hostdev, scsisrc,
|
||||||
VIR_WARN("Unable to reattach SCSI device %s:%d:%d:%d on domain %s",
|
drv_name, dom_name);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
virObjectUnlock(hostdev_mgr->activeSCSIHostdevs);
|
virObjectUnlock(hostdev_mgr->activeSCSIHostdevs);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user