]> sourceware.org Git - lvm2.git/commitdiff
When there are device name aliases, choose the "nicest" to display.
authorAlasdair Kergon <agk@redhat.com>
Fri, 3 Jan 2003 21:11:23 +0000 (21:11 +0000)
committerAlasdair Kergon <agk@redhat.com>
Fri, 3 Jan 2003 21:11:23 +0000 (21:11 +0000)
lib/device/dev-cache.c

index 5232ed256d56f0a27d98c9c2212ccf679891cb24..6e2b463a8c86cd689d5b4f938b852d5cf371a117 100644 (file)
@@ -65,9 +65,72 @@ static struct device *_create_dev(dev_t d)
        return dev;
 }
 
+/* Return 1 if we prefer path1 else return 0 */
+static int _compare_paths(const char *path0, const char *path1)
+{
+       int slash0 = 0, slash1 = 0;
+       const char *p;
+       char p0[PATH_MAX], p1[PATH_MAX];
+       char *s0, *s1;
+       struct stat stat0, stat1;
+
+       /* Return the path with fewer slashes */
+       for (p = path0; p++; p = (const char *) strchr(p, '/'))
+               slash0++;
+
+       for (p = path1; p++; p = (const char *) strchr(p, '/'))
+               slash1++;
+
+       if (slash0 < slash1)
+               return 0;
+       if (slash1 < slash0)
+               return 1;
+
+       strncpy(p0, path0, PATH_MAX);
+       strncpy(p1, path1, PATH_MAX);
+       s0 = &p0[0] + 1;
+       s1 = &p1[0] + 1;
+
+       /* We prefer symlinks - they exist for a reason!
+        * So we prefer a shorter path before the first symlink in the name.
+        * FIXME Configuration option to invert this? */
+       while (s0) {
+               s0 = strchr(s0, '/');
+               s1 = strchr(s1, '/');
+               if (s0) {
+                       *s0 = '\0';
+                       *s1 = '\0';
+               }
+               if (lstat(p0, &stat0)) {
+                       log_sys_error("lstat", p0);
+                       return 1;
+               }
+               if (lstat(p1, &stat1)) {
+                       log_sys_error("lstat", p1);
+                       return 0;
+               }
+               if (S_ISLNK(stat0.st_mode) && !S_ISLNK(stat1.st_mode))
+                       return 0;
+               if (!S_ISLNK(stat0.st_mode) && S_ISLNK(stat1.st_mode))
+                       return 1;
+               if (s0) {
+                       *s0++ = '/';
+                       *s1++ = '/';
+               }
+       }
+
+       /* ASCII comparison */
+       if (strcmp(path0, path1) < 0)
+               return 0;
+       else
+               return 1;
+}
+
 static int _add_alias(struct device *dev, const char *path)
 {
        struct str_list *sl = _alloc(sizeof(*sl));
+       const char *oldpath;
+       int prefer_old = 1;
 
        if (!sl) {
                stack;
@@ -79,7 +142,16 @@ static int _add_alias(struct device *dev, const char *path)
                return 0;
        }
 
-       list_add(&dev->aliases, &sl->list);
+       if (!list_empty(&dev->aliases)) {
+               oldpath = list_item(dev->aliases.n, struct str_list)->str;
+               prefer_old = _compare_paths(path, oldpath);
+       }
+
+       if (prefer_old)
+               list_add(&dev->aliases, &sl->list);
+       else
+               list_add_h(&dev->aliases, &sl->list);
+
        return 1;
 }
 
This page took 0.039538 seconds and 5 git commands to generate.