+ struct discover_device *ddev;
+ const char *typestr;
+ const char *uuid;
+ const char *path;
+ const char *node;
+ const char *prop;
+ const char *type;
+ bool cdrom;
+
+ typestr = udev_device_get_devtype(dev);
+ if (!typestr) {
+ pb_debug("udev_device_get_devtype failed\n");
+ return -1;
+ }
+
+ if (!(!strcmp(typestr, "disk") || !strcmp(typestr, "partition"))) {
+ pb_log("SKIP %s: invalid type %s\n", name, typestr);
+ return 0;
+ }
+
+ node = udev_device_get_devnode(dev);
+ path = udev_device_get_devpath(dev);
+ if (path && strstr(path, "virtual/block/loop")) {
+ pb_log("SKIP: %s: ignored (path=%s)\n", name, path);
+ return 0;
+ }
+
+ if (path && strstr(path, "virtual/block/ram")) {
+ device_handler_add_ramdisk(udev->handler, node);
+ return 0;
+ }
+
+ cdrom = node && !!udev_device_get_property_value(dev, "ID_CDROM");
+ if (cdrom) {
+ /* CDROMs require a little initialisation, to get
+ * petitboot-compatible tray behaviour */
+ cdrom_init(node);
+ if (!cdrom_media_present(node)) {
+ pb_log("SKIP: %s: no media present\n", name);
+ return 0;
+ }
+ }
+
+ /* If our environment's udev can recognise them explictly skip any
+ * device mapper devices we encounter */
+ const char *devname = udev_device_get_property_value(dev, "DM_NAME");
+ if (devname) {
+ pb_log("SKIP: dm-device %s\n", devname);
+ return 0;
+ }
+
+ type = udev_device_get_property_value(dev, "ID_FS_TYPE");
+ if (!type) {
+ pb_log("SKIP: %s: no ID_FS_TYPE property\n", name);
+ return 0;
+ }
+
+ /* We may see multipath devices; they'll have the same uuid as an
+ * existing device, so only parse the first. */
+ uuid = udev_device_get_property_value(dev, "ID_FS_UUID");
+ if (uuid) {
+ ddev = device_lookup_by_uuid(udev->handler, uuid);
+ if (ddev) {
+ pb_log("SKIP: %s UUID [%s] already present (as %s)\n",
+ name, uuid, ddev->device->id);
+ return 0;
+ }
+ }