>From d610d29eb338a2d49429b2e18aa86d855b636c3d Mon Sep 17 00:00:00 2001 From: David Allan Date: Tue, 3 Nov 2009 14:52:43 -0500 Subject: [PATCH 3/4] Add scsi_target device type Having libvirt understand scsi targets makes the node device tree look a bit better; there isn't a lot of use for them otherwise. The device tree is still not perfect, but one step at a time. --- src/conf/node_device_conf.c | 43 ++++++++++++++++++++++++++++++++++++ src/conf/node_device_conf.h | 4 +++ src/node_device/node_device_udev.c | 37 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 0 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 5a9f648..d45ed01 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") @@ -396,6 +397,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); @@ -663,6 +670,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, @@ -1067,6 +1104,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; @@ -1388,6 +1428,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 91ef94e..ba32b10 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 @@ -136,6 +137,9 @@ struct _virNodeDevCapsDef { unsigned flags; } scsi_host; struct { + char *name; + } scsi_target; + struct { unsigned host; unsigned bus; unsigned target; diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 90b005f..10d09fe 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -503,6 +503,35 @@ 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); + if (sysname == NULL) { + goto out; + } + + 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; @@ -813,6 +842,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; @@ -870,6 +904,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; -- 1.6.5.1