From 576beaa671c735b99745ee8fa9741d635ad952b9 Mon Sep 17 00:00:00 2001
From: Steffen Winterfeldt <wfeldt@opensuse.org>
Date: Thu, 29 Mar 2018 14:56:21 +0200
Subject: [PATCH 21/39] ensure udev device links are unique (bsc #1084700)

It sometimes happens that udev generates the same by-* links for different
devices. Mainly in strange virtualized environments.

This patch ensures that the udev symlinks libhd gathers point to the correct
kernel device (only one of the duplicates can, obviously).
---
 src/hd/hd.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/src/hd/hd.c b/src/hd/hd.c
index 528ef40..5321050 100644
--- a/src/hd/hd.c
+++ b/src/hd/hd.c
@@ -5634,6 +5634,7 @@ void read_udevinfo(hd_data_t *hd_data)
   str_list_t *sl, *udevinfo;
   hd_udevinfo_t **uip, *ui;
   char *s = NULL, buf[256];
+  struct stat sbuf;
 
   udevinfo = read_file("| " PROG_UDEVADM " info -e 2>/dev/null", 0, 0);
   if(!udevinfo) udevinfo = read_file("| " PROG_UDEVINFO " -e 2>/dev/null", 0, 0);
@@ -5675,6 +5676,33 @@ void read_udevinfo(hd_data_t *hd_data)
 
   s = free_mem(s);
 
+  /*
+   * It sometimes happens that udev generates the same link for different
+   * kernel devices. To catch this we check here that udev device symlinks
+   * actually point to the kernel device name.
+   *
+   * If it does not match the link is replaced by the kernel device name.
+   */
+  for(ui = hd_data->udevinfo; ui; ui = ui->next) {
+    if(!ui->name || stat(ui->name, &sbuf)) continue;
+
+    for(sl = ui->links; sl; sl = sl->next) {
+      char *real_path = realpath(sl->str, NULL);
+
+      if(real_path) {
+        if(strcmp(real_path, ui->name)) {
+          ADD2LOG(
+            "udev link %s points to %s (expected %s) - removed\n",
+            sl->str, real_path, ui->name
+          );
+          str_printf(&sl->str, 0, "%s", ui->name);
+        }
+
+        free(real_path);
+      }
+    }
+  }
+
   for(ui = hd_data->udevinfo; ui; ui = ui->next) {
     ADD2LOG("%s\n", ui->sysfs);
     if(ui->name) ADD2LOG("  name: %s\n", ui->name);
-- 
2.7.4

