summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util.c')
-rw-r--r--util.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/util.c b/util.c
index bdb19f9..9327b75 100644
--- a/util.c
+++ b/util.c
@@ -1648,3 +1648,44 @@ void append_metadata_update(struct supertype *st, void *buf, int len)
unsigned int __invalid_size_argument_for_IOC = 0;
#endif
+/*
+ * Resolve from a device name, such as /dev/sdb2, to a device path, such
+ * as pci-0000:00:1f.2-scsi-1:0:0:0-part2 which can then be used to match
+ * against paths in DOMAIN lines from the config file
+ */
+char *get_devpath_from_devname(char *devname)
+{
+ char *name = strrchr(devname, '/'), *link;
+ DIR *by_path;
+ struct dirent *ent;
+ char symlink[PATH_MAX] = "/dev/disk/by-path/";
+ char *symlinkp, target[PATH_MAX];
+ int read;
+
+ if (!name++)
+ name = devname;
+ if ((by_path = opendir("/dev/disk/by-path")) == NULL) {
+ fprintf(stderr, Name ": unable to open /dev/disk/by-path, "
+ "domain lookups not possible\n");
+ return NULL;
+ }
+ symlinkp = &symlink[0] + strlen(symlink);
+ while ((ent = readdir(by_path)) != NULL) {
+ if (ent->d_type != DT_LNK)
+ continue;
+ strncpy(symlinkp, ent->d_name,
+ sizeof(symlink) - (symlinkp - &symlink[0]));
+ read = readlink(symlink, target, sizeof(target));
+ if (read < 0)
+ continue;
+ link = strrchr(target, '/');
+ if (!link++)
+ link = target;
+ if (strcmp(name, link) == 0) {
+ closedir(by_path);
+ return strdup(ent->d_name);
+ }
+ }
+ closedir(by_path);
+ return NULL;
+}