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.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/conf/domain_audit.c | 20 +++-
src/conf/domain_conf.c | 47 ++++++++-
src/conf/domain_conf.h | 20 ++++
src/qemu/qemu_cgroup.c | 35 ++++---
src/qemu/qemu_command.c | 74 ++++++++++++---
src/qemu/qemu_hotplug.c | 36 +++++--
src/security/security_apparmor.c | 6 ++
src/security/security_dac.c | 12 +++
src/security/security_selinux.c | 12 +++
src/util/virhostdev.c | 200 +++++++++++++++++++++++++--------------
10 files changed, 349 insertions(+), 113 deletions(-)
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index ee9baa2..3ad58b0 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -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;
}
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 55c0822..758b907 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1702,6 +1702,17 @@ virDomainHostdevDefPtr virDomainHostdevDefAlloc(void)
return def;
}
+static void
+virDomainHostdevSubsysSCSIiSCSIFree(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)
@@ -1732,8 +1743,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) {
+ virDomainHostdevSubsysSCSIiSCSIFree(&scsisrc->u.iscsi);
+ } else {
+ VIR_FREE(scsisrc->u.host.adapter);
+ }
+ }
break;
}
}
@@ -4313,8 +4331,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;
@@ -10161,6 +10178,22 @@ virDomainHostdevMatchSubsysSCSIHost(virDomainHostdevDefPtr a,
}
static int
+virDomainHostdevMatchSubsysSCSIiSCSI(virDomainHostdevDefPtr a,
+ virDomainHostdevDefPtr b)
+{
+ virDomainHostdevSubsysSCSIiSCSIPtr aiscsisrc =
+ &a->source.subsys.u.scsi.u.iscsi;
+ virDomainHostdevSubsysSCSIiSCSIPtr biscsisrc =
+ &b->source.subsys.u.scsi.u.iscsi;
+
+ if (STREQ(aiscsisrc->hosts[0].name, biscsisrc->hosts[0].name) &&
+ STREQ(aiscsisrc->hosts[0].port, biscsisrc->hosts[0].port) &&
+ STREQ(aiscsisrc->path, biscsisrc->path))
+ return 1;
+ return 0;
+}
+
+static int
virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
virDomainHostdevDefPtr b)
{
@@ -10173,7 +10206,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;
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e9a4214..e6aa1db 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -390,6 +390,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 {
@@ -418,12 +427,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;
};
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 9a5459b..e109c33 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -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;
}
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1ab3ade..4a2a5ea 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5119,13 +5119,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;
@@ -5135,10 +5133,64 @@ qemuBuildSCSIHostdevDrvStr(virConnectPtr conn ATTRIBUTE_UNUSED,
scsihostsrc->bus,
scsihostsrc->target,
scsihostsrc->unit);
- if (!sg)
- goto error;
+ return 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);
- virBufferAsprintf(&buf, "file=/dev/%s,if=none", sg);
+ 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);
@@ -5157,10 +5209,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;
}
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6773d50..729744c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -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:
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 40c667e..af9de2d 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -814,6 +814,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;
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 08f5041..0f92194 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -477,6 +477,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);
@@ -605,6 +611,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;
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index f32816f..c078cab 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -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;
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 83f85aa..53da626 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -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 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);
+ 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);
}
--
1.9.3