diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 379787dbb1..f55c9c76c3 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -46,6 +46,7 @@ VIR_ENUM_IMPL(virNodeDevCap, VIR_NODE_DEV_CAP_LAST,
"usb",
"net",
"scsi_host",
+ "scsi_target",
"scsi",
"storage")
@@ -387,6 +388,12 @@ char *virNodeDeviceDefFormat(virConnectPtr conn,
}
break;
+
+ case VIR_NODE_DEV_CAP_SCSI_TARGET:
+ virBufferVSprintf(&buf, " %s\n",
+ data->scsi_target.name);
+ break;
+
case VIR_NODE_DEV_CAP_SCSI:
virBufferVSprintf(&buf, " %d\n", data->scsi.host);
virBufferVSprintf(&buf, " %d\n", data->scsi.bus);
@@ -660,6 +667,36 @@ out:
return ret;
}
+
+static int
+virNodeDevCapScsiTargetParseXML(virConnectPtr conn,
+ xmlXPathContextPtr ctxt,
+ virNodeDeviceDefPtr def,
+ xmlNodePtr node,
+ union _virNodeDevCapData *data)
+{
+ xmlNodePtr orignode;
+ int ret = -1;
+
+ orignode = ctxt->node;
+ ctxt->node = node;
+
+ data->scsi_target.name = virXPathString(conn, "string(./name[1])", ctxt);
+ if (!data->scsi_target.name) {
+ virNodeDeviceReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("no target name supplied for '%s'"),
+ def->name);
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ ctxt->node = orignode;
+ return ret;
+}
+
+
static int
virNodeDevCapScsiHostParseXML(virConnectPtr conn,
xmlXPathContextPtr ctxt,
@@ -1064,6 +1101,9 @@ virNodeDevCapsDefParseXML(virConnectPtr conn,
case VIR_NODE_DEV_CAP_SCSI_HOST:
ret = virNodeDevCapScsiHostParseXML(conn, ctxt, def, node, &caps->data, create);
break;
+ case VIR_NODE_DEV_CAP_SCSI_TARGET:
+ ret = virNodeDevCapScsiTargetParseXML(conn, ctxt, def, node, &caps->data);
+ break;
case VIR_NODE_DEV_CAP_SCSI:
ret = virNodeDevCapScsiParseXML(conn, ctxt, def, node, &caps->data);
break;
@@ -1387,6 +1427,9 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
VIR_FREE(data->scsi_host.wwnn);
VIR_FREE(data->scsi_host.wwpn);
break;
+ case VIR_NODE_DEV_CAP_SCSI_TARGET:
+ VIR_FREE(data->scsi_target.name);
+ break;
case VIR_NODE_DEV_CAP_SCSI:
VIR_FREE(data->scsi.type);
break;
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index e97242ada9..639a7e7a70 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -41,6 +41,7 @@ enum virNodeDevCapType {
VIR_NODE_DEV_CAP_USB_INTERFACE, /* USB interface */
VIR_NODE_DEV_CAP_NET, /* Network device */
VIR_NODE_DEV_CAP_SCSI_HOST, /* SCSI Host Bus Adapter */
+ VIR_NODE_DEV_CAP_SCSI_TARGET, /* SCSI Target */
VIR_NODE_DEV_CAP_SCSI, /* SCSI device */
VIR_NODE_DEV_CAP_STORAGE, /* Storage device */
VIR_NODE_DEV_CAP_LAST
@@ -132,6 +133,9 @@ struct _virNodeDevCapsDef {
char *wwpn;
unsigned flags;
} scsi_host;
+ struct {
+ char *name;
+ } scsi_target;
struct {
unsigned host;
unsigned bus;
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index d608b764ea..010ff75489 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -601,6 +601,32 @@ out:
}
+static int udevProcessSCSITarget(struct udev_device *device ATTRIBUTE_UNUSED,
+ virNodeDeviceDefPtr def)
+{
+ int ret = -1;
+ const char *sysname = NULL;
+ union _virNodeDevCapData *data = &def->caps->data;
+
+ sysname = udev_device_get_sysname(device);
+
+ data->scsi_target.name = strdup(sysname);
+ if (data->scsi_target.name == NULL) {
+ virReportOOMError(NULL);
+ goto out;
+ }
+
+ if (udevGenerateDeviceName(device, def, NULL) != 0) {
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
static int udevGetSCSIType(unsigned int type, char **typestring)
{
int ret = 0;
@@ -948,6 +974,11 @@ static int udevGetDeviceType(struct udev_device *device,
goto out;
}
+ if (devtype != NULL && STREQ(devtype, "scsi_target")) {
+ *type = VIR_NODE_DEV_CAP_SCSI_TARGET;
+ goto out;
+ }
+
if (devtype != NULL && STREQ(devtype, "scsi_device")) {
*type = VIR_NODE_DEV_CAP_SCSI;
goto out;
@@ -1008,6 +1039,9 @@ static int udevGetDeviceDetails(struct udev_device *device,
case VIR_NODE_DEV_CAP_SCSI_HOST:
ret = udevProcessSCSIHost(device, def);
break;
+ case VIR_NODE_DEV_CAP_SCSI_TARGET:
+ ret = udevProcessSCSITarget(device, def);
+ break;
case VIR_NODE_DEV_CAP_SCSI:
ret = udevProcessSCSIDevice(device, def);
break;