diff options
author | Dan Williams <dan.j.williams@intel.com> | 2008-06-14 02:27:30 +0200 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2008-06-14 02:27:30 +0200 |
commit | f1665f720035ab37913a68838d3310188f3a4b08 (patch) | |
tree | 1635b0affc86320fa2f0833185c910c2bd2d34c4 /sysfs.c | |
parent | sysfs: provide a helper function for locating scsi_generic interfaces (diff) | |
download | mdadm-f1665f720035ab37913a68838d3310188f3a4b08.tar.xz mdadm-f1665f720035ab37913a68838d3310188f3a4b08.zip |
sysfs: helper routine to retrieve the scsi id
imsm records this information in its metadata
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'sysfs.c')
-rw-r--r-- | sysfs.c | 49 |
1 files changed, 49 insertions, 0 deletions
@@ -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; +} |