]> xenbits.xensource.com Git - libvirt.git/commitdiff
nodedev_udev: Enumerate scsi generic device
authorOsier Yang <jyang@redhat.com>
Mon, 3 Jun 2013 10:05:32 +0000 (18:05 +0800)
committerOsier Yang <jyang@redhat.com>
Tue, 18 Jun 2013 09:17:06 +0000 (17:17 +0800)
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>

src/conf/node_device_conf.c
src/conf/node_device_conf.h
src/node_device/node_device_udev.c

index cc6f297b2a78121ebfc90b2d76c6a65001eee2fa..92fa18c57039271f8d1722ea7c6a231d4468a203 100644 (file)
@@ -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,10 @@ 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);
+            break;
         case VIR_NODE_DEV_CAP_FC_HOST:
         case VIR_NODE_DEV_CAP_VPORTS:
         case VIR_NODE_DEV_CAP_LAST:
@@ -1412,6 +1417,9 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
         VIR_FREE(data->storage.serial);
         VIR_FREE(data->storage.media_label);
         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_VPORTS:
     case VIR_NODE_DEV_CAP_LAST:
index 1c5855c3553351df56503571cd1f503be42641ee..e326e8265b31683ac3033523fd4b83669959ebb6 100644 (file)
@@ -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 */
 };
index b8f5e5b06339505490ab05d868300cf2fc1b995f..b94be8057fdd346df98180daaa12e55c7f8e211c 100644 (file)
@@ -1121,6 +1121,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
 udevHasDeviceProperty(struct udev_device *dev,
                       const char *key)
@@ -1136,6 +1151,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);
@@ -1167,6 +1183,13 @@ udevGetDeviceType(struct udev_device *device,
          * property exists, we have a network device. */
         if (udevHasDeviceProperty(device, "INTERFACE"))
             *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)
@@ -1213,6 +1236,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;