Since scsi generic device doesn't have DEVTYPE property set, the only way to we have to get it's a scsi generic device is from the "SUBSYSTEM" property. The XML of the scsi generic device will be like: <device> <name>scsi_generic_sg0</name> <path>/sys/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/scsi_generic/sg0</path> <parent>scsi_0_0_0_0</parent> <capability type='scsi_generic'> <char>/dev/sg0</char> </capability> </device> --- src/conf/node_device_conf.c | 6 +++++- src/conf/node_device_conf.h | 5 +++++ src/node_device/node_device_udev.c | 24 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index cc6f297..a0b6338 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -49,7 +49,8 @@ VIR_ENUM_IMPL(virNodeDevCap, VIR_NODE_DEV_CAP_LAST, "scsi", "storage", "fc_host", - "vports") + "vports", + "scsi_generic") VIR_ENUM_IMPL(virNodeDevNetCap, VIR_NODE_DEV_CAP_NET_LAST, "80203", @@ -472,6 +473,9 @@ char *virNodeDeviceDefFormat(const virNodeDeviceDefPtr def) virBufferAddLit(&buf, " <capability type='hotpluggable' />\n"); break; + case VIR_NODE_DEV_CAP_SCSI_GENERIC: + virBufferEscapeString(&buf, " <char>%s</char>\n", + data->sg.path); case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_LAST: diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 1c5855c..e326e82 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -48,6 +48,8 @@ enum virNodeDevCapType { VIR_NODE_DEV_CAP_STORAGE, /* Storage device */ VIR_NODE_DEV_CAP_FC_HOST, /* FC Host Bus Adapter */ VIR_NODE_DEV_CAP_VPORTS, /* HBA which is capable of vports */ + VIR_NODE_DEV_CAP_SCSI_GENERIC, /* SCSI generic device */ + VIR_NODE_DEV_CAP_LAST }; @@ -165,6 +167,9 @@ struct _virNodeDevCapsDef { char *media_label; unsigned int flags; /* virNodeDevStorageCapFlags bits */ } storage; + struct { + char *path; + } sg; /* SCSI generic device */ } data; virNodeDevCapsDefPtr next; /* next capability */ }; diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 3c91298..27a48cf 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1099,6 +1099,21 @@ out: return ret; } +static int +udevProcessScsiGeneric(struct udev_device *dev, + virNodeDeviceDefPtr def) +{ + if (udevGetStringProperty(dev, + "DEVNAME", + &def->caps->data.sg.path) != PROPERTY_FOUND) + return -1; + + if (udevGenerateDeviceName(dev, def, NULL) != 0) + return -1; + + return 0; +} + static bool udevDeviceHasProperty(struct udev_device *dev, const char *key) @@ -1117,6 +1132,7 @@ udevGetDeviceType(struct udev_device *device, enum virNodeDevCapType *type) { const char *devtype = NULL; + char *subsystem = NULL; int ret = -1; devtype = udev_device_get_devtype(device); @@ -1148,6 +1164,11 @@ udevGetDeviceType(struct udev_device *device, * property exists, we have a network device. */ if (udevDeviceHasProperty(device, "INTERFACE")) *type = VIR_NODE_DEV_CAP_NET; + + if (udevGetStringProperty(device, "SUBSYSTEM", &subsystem) == + PROPERTY_FOUND && + STREQ(subsystem, "scsi_generic")) + *type = VIR_NODE_DEV_CAP_SCSI_GENERIC; } if (!*type) @@ -1194,6 +1215,9 @@ static int udevGetDeviceDetails(struct udev_device *device, case VIR_NODE_DEV_CAP_STORAGE: ret = udevProcessStorage(device, def); break; + case VIR_NODE_DEV_CAP_SCSI_GENERIC: + ret = udevProcessScsiGeneric(device, def); + break; default: VIR_ERROR(_("Unknown device type %d"), def->caps->type); ret = -1; -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list