summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Stakenvicius <axs@gentoo.org>2013-01-25 12:20:48 -0500
committerAnthony G. Basile <blueness@gentoo.org>2013-01-28 17:42:47 -0500
commiteb256defbed7f66cd6e3073f6bff3e167ec3d6f2 (patch)
tree2695c132bb59856f42c59fad3f4959f9dc282fba /src
parente34b05dc4c5c8b48cbc0428b29344f7634b3b4a5 (diff)
Handle scsi Hyper-V devices properly
Hyper-V has an abstract bus, which gets renumbered on guest startup. So instead of the bus numbers we should be using the device GUIDs, which can be retrieved from the 'device_id' sysfs attribute. systemd commit a24d03b8ee2ca62cd1273e27cf4e79ddcc0fbb1c Author: Hannes Reinecke <hare@suse.de> Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
Diffstat (limited to 'src')
-rw-r--r--src/udev/udev-builtin-path_id.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index bfdedc0989..c2c9161c94 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -302,6 +302,42 @@ out:
return hostdev;
}
+static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char **path) {
+ struct udev_device *hostdev;
+ struct udev_device *vmbusdev;
+ const char *guid_str;
+ char *lun = NULL;
+ char guid[38];
+ size_t i, k;
+
+ hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
+ if (!hostdev)
+ return NULL;
+
+ vmbusdev = udev_device_get_parent(hostdev);
+ if (!vmbusdev)
+ return NULL;
+
+ guid_str = udev_device_get_sysattr_value(vmbusdev, "device_id");
+ if (!guid_str)
+ return NULL;
+
+ if (strlen(guid_str) < 37 || guid_str[0] != '{' || guid_str[36] != '}')
+ return NULL;
+
+ for (i = 1, k = 0; i < 36; i++) {
+ if (guid_str[i] == '-')
+ continue;
+ guid[k++] = guid_str[i];
+ }
+ guid[k] = '\0';
+
+ format_lun_number(parent, &lun);
+ path_prepend(path, "vmbus-%s-%s", guid, lun);
+ free(lun);
+ return parent;
+}
+
static struct udev_device *handle_scsi(struct udev_device *parent, char **path)
{
const char *devtype;
@@ -351,6 +387,11 @@ static struct udev_device *handle_scsi(struct udev_device *parent, char **path)
goto out;
}
+ if (strstr(name, "/vmbus_") != NULL) {
+ parent = handle_scsi_hyperv(parent, path);
+ goto out;
+ }
+
parent = handle_scsi_default(parent, path);
out:
return parent;