From db19834a0a0c9f3f78e862df1ea7a57bca821187 Mon Sep 17 00:00:00 2001 From: David Allan Date: Thu, 12 Nov 2009 23:03:47 +0100 Subject: [PATCH] Add scsi_target device type * src/conf/node_device_conf.h src/conf/node_device_conf.c: add specific support for SCSI target in node device capabilities * src/node_device/node_device_udev.c: add some extra detection code when handling udev output --- src/conf/node_device_conf.c | 43 ++++++++++++++++++++++++++++++ src/conf/node_device_conf.h | 4 +++ src/node_device/node_device_udev.c | 34 +++++++++++++++++++++++ 3 files changed, 81 insertions(+) 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;