nodedev_udev: Enumerate scsi generic device

Since scsi generic device doesn't have DEVTYPE property set, the
only way to know if it's a  scsi generic device or not is to read
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>
This commit is contained in:
Osier Yang 2013-06-03 18:05:32 +08:00
parent 0ad9025ef4
commit 92fd4c09a4
3 changed files with 40 additions and 1 deletions

View File

@ -49,7 +49,8 @@ VIR_ENUM_IMPL(virNodeDevCap, VIR_NODE_DEV_CAP_LAST,
"scsi", "scsi",
"storage", "storage",
"fc_host", "fc_host",
"vports") "vports",
"scsi_generic")
VIR_ENUM_IMPL(virNodeDevNetCap, VIR_NODE_DEV_CAP_NET_LAST, VIR_ENUM_IMPL(virNodeDevNetCap, VIR_NODE_DEV_CAP_NET_LAST,
"80203", "80203",
@ -472,6 +473,10 @@ char *virNodeDeviceDefFormat(const virNodeDeviceDefPtr def)
virBufferAddLit(&buf, virBufferAddLit(&buf,
" <capability type='hotpluggable' />\n"); " <capability type='hotpluggable' />\n");
break; break;
case VIR_NODE_DEV_CAP_SCSI_GENERIC:
virBufferEscapeString(&buf, " <char>%s</char>\n",
data->sg.path);
break;
case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_FC_HOST:
case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_VPORTS:
case VIR_NODE_DEV_CAP_LAST: case VIR_NODE_DEV_CAP_LAST:
@ -1412,6 +1417,9 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
VIR_FREE(data->storage.serial); VIR_FREE(data->storage.serial);
VIR_FREE(data->storage.media_label); VIR_FREE(data->storage.media_label);
break; break;
case VIR_NODE_DEV_CAP_SCSI_GENERIC:
VIR_FREE(data->sg.path);
break;
case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_FC_HOST:
case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_VPORTS:
case VIR_NODE_DEV_CAP_LAST: case VIR_NODE_DEV_CAP_LAST:

View File

@ -48,6 +48,8 @@ enum virNodeDevCapType {
VIR_NODE_DEV_CAP_STORAGE, /* Storage device */ VIR_NODE_DEV_CAP_STORAGE, /* Storage device */
VIR_NODE_DEV_CAP_FC_HOST, /* FC Host Bus Adapter */ 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_VPORTS, /* HBA which is capable of vports */
VIR_NODE_DEV_CAP_SCSI_GENERIC, /* SCSI generic device */
VIR_NODE_DEV_CAP_LAST VIR_NODE_DEV_CAP_LAST
}; };
@ -165,6 +167,9 @@ struct _virNodeDevCapsDef {
char *media_label; char *media_label;
unsigned int flags; /* virNodeDevStorageCapFlags bits */ unsigned int flags; /* virNodeDevStorageCapFlags bits */
} storage; } storage;
struct {
char *path;
} sg; /* SCSI generic device */
} data; } data;
virNodeDevCapsDefPtr next; /* next capability */ virNodeDevCapsDefPtr next; /* next capability */
}; };

View File

@ -1121,6 +1121,21 @@ out:
return ret; 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 static bool
udevHasDeviceProperty(struct udev_device *dev, udevHasDeviceProperty(struct udev_device *dev,
const char *key) const char *key)
@ -1136,6 +1151,7 @@ udevGetDeviceType(struct udev_device *device,
enum virNodeDevCapType *type) enum virNodeDevCapType *type)
{ {
const char *devtype = NULL; const char *devtype = NULL;
char *subsystem = NULL;
int ret = -1; int ret = -1;
devtype = udev_device_get_devtype(device); devtype = udev_device_get_devtype(device);
@ -1167,6 +1183,13 @@ udevGetDeviceType(struct udev_device *device,
* property exists, we have a network device. */ * property exists, we have a network device. */
if (udevHasDeviceProperty(device, "INTERFACE")) if (udevHasDeviceProperty(device, "INTERFACE"))
*type = VIR_NODE_DEV_CAP_NET; *type = VIR_NODE_DEV_CAP_NET;
/* SCSI generic device doesn't set DEVTYPE property */
if (udevGetStringProperty(device, "SUBSYSTEM", &subsystem) ==
PROPERTY_FOUND &&
STREQ(subsystem, "scsi_generic"))
*type = VIR_NODE_DEV_CAP_SCSI_GENERIC;
VIR_FREE(subsystem);
} }
if (!*type) if (!*type)
@ -1213,6 +1236,9 @@ static int udevGetDeviceDetails(struct udev_device *device,
case VIR_NODE_DEV_CAP_STORAGE: case VIR_NODE_DEV_CAP_STORAGE:
ret = udevProcessStorage(device, def); ret = udevProcessStorage(device, def);
break; break;
case VIR_NODE_DEV_CAP_SCSI_GENERIC:
ret = udevProcessScsiGeneric(device, def);
break;
default: default:
VIR_ERROR(_("Unknown device type %d"), def->caps->type); VIR_ERROR(_("Unknown device type %d"), def->caps->type);
ret = -1; ret = -1;