From: Dan Williams Date: Sat, 14 Jun 2008 00:27:30 +0000 (-0700) Subject: sysfs: helper routine to retrieve the scsi id X-Git-Tag: mdadm-3.0-devel1~159^2~9 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=commitdiff_plain;h=f1665f720035ab37913a68838d3310188f3a4b08 sysfs: helper routine to retrieve the scsi id imsm records this information in its metadata Signed-off-by: Dan Williams --- diff --git a/mdadm.h b/mdadm.h index f29cf018..bc3d4ea0 100644 --- a/mdadm.h +++ b/mdadm.h @@ -347,7 +347,7 @@ extern int sysfs_set_array(struct mdinfo *sra, struct mdinfo *info); extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd); extern int sysfs_disk_to_sg(int fd); - +extern int sysfs_disk_to_scsi_id(int fd, __u32 *id); extern int save_stripes(int *source, unsigned long long *offsets, diff --git a/sysfs.c b/sysfs.c index 37b8b097..5f0c2127 100644 --- a/sysfs.c +++ b/sysfs.c @@ -464,3 +464,52 @@ int sysfs_disk_to_sg(int fd) return -1; } +int sysfs_disk_to_scsi_id(int fd, __u32 *id) +{ + /* from an open block device, try to retrieve it scsi_id */ + struct stat st; + char path[256]; + char *c1, *c2; + DIR *dir; + struct dirent *de; + + if (fstat(fd, &st)) + return 1; + + snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/device", + major(st.st_rdev), minor(st.st_rdev)); + + dir = opendir(path); + if (!dir) + return 1; + + de = readdir(dir); + while (de) { + if (strncmp("scsi_disk:", de->d_name, + strlen("scsi_disk:")) == 0) + break; + de = readdir(dir); + } + closedir(dir); + + if (!de) + return 1; + + c1 = strchr(de->d_name, ':'); + c1++; + c2 = strchr(c1, ':'); + *c2 = '\0'; + *id = strtol(c1, NULL, 10) << 24; /* host */ + c1 = c2 + 1; + c2 = strchr(c1, ':'); + *c2 = '\0'; + *id |= strtol(c1, NULL, 10) << 16; /* channel */ + c1 = c2 + 1; + c2 = strchr(c1, ':'); + *c2 = '\0'; + *id |= strtol(c1, NULL, 10) << 8; /* lun */ + c1 = c2 + 1; + *id |= strtol(c1, NULL, 10); /* id */ + + return 0; +}