sysfs: provide a helper function for locating scsi_generic interfaces
imsm records and validates this data in its metadata Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
c42ec1ed43
commit
90c8b70714
2
mdadm.h
2
mdadm.h
|
@ -346,7 +346,7 @@ extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
|
||||||
extern int sysfs_set_array(struct mdinfo *sra,
|
extern int sysfs_set_array(struct mdinfo *sra,
|
||||||
struct mdinfo *info);
|
struct mdinfo *info);
|
||||||
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd);
|
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd);
|
||||||
|
extern int sysfs_disk_to_sg(int fd);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -544,26 +544,19 @@ static int imsm_read_serial(int fd, char *devname,
|
||||||
__u8 serial[MAX_RAID_SERIAL_LEN])
|
__u8 serial[MAX_RAID_SERIAL_LEN])
|
||||||
{
|
{
|
||||||
unsigned char scsi_serial[255];
|
unsigned char scsi_serial[255];
|
||||||
struct stat stb;
|
|
||||||
int sg_fd;
|
int sg_fd;
|
||||||
int minor;
|
|
||||||
char sg_path[20];
|
|
||||||
int rv;
|
int rv;
|
||||||
int rsp_len;
|
int rsp_len;
|
||||||
int i, cnt;
|
int i, cnt;
|
||||||
|
|
||||||
memset(scsi_serial, 0, sizeof(scsi_serial));
|
memset(scsi_serial, 0, sizeof(scsi_serial));
|
||||||
fstat(fd, &stb);
|
|
||||||
minor = minor(stb.st_rdev);
|
|
||||||
minor /= 16;
|
|
||||||
|
|
||||||
sprintf(sg_path, "/dev/sg%d", minor);
|
sg_fd = sysfs_disk_to_sg(fd);
|
||||||
sg_fd = open(sg_path, O_RDONLY);
|
|
||||||
if (sg_fd < 0) {
|
if (sg_fd < 0) {
|
||||||
if (devname)
|
if (devname)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
Name ": Failed to open %s for %s: %s\n",
|
Name ": Failed to open sg interface for %s: %s\n",
|
||||||
sg_path, devname, strerror(errno));
|
devname, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
65
sysfs.c
65
sysfs.c
|
@ -399,3 +399,68 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd)
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sysfs_disk_to_sg(int fd)
|
||||||
|
{
|
||||||
|
/* from an open block device, try find and open its corresponding
|
||||||
|
* scsi_generic interface
|
||||||
|
*/
|
||||||
|
struct stat st;
|
||||||
|
char path[256];
|
||||||
|
char sg_path[256];
|
||||||
|
char sg_major_minor[8];
|
||||||
|
char *c;
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *de;
|
||||||
|
int major, minor, rv;
|
||||||
|
|
||||||
|
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_generic:", de->d_name,
|
||||||
|
strlen("scsi_generic:")) == 0)
|
||||||
|
break;
|
||||||
|
de = readdir(dir);
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
if (!de)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
snprintf(sg_path, sizeof(sg_path), "%s/%s/dev", path, de->d_name);
|
||||||
|
fd = open(sg_path, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
rv = read(fd, sg_major_minor, sizeof(sg_major_minor));
|
||||||
|
close(fd);
|
||||||
|
if (rv < 0)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
sg_major_minor[rv - 1] = '\0';
|
||||||
|
|
||||||
|
c = strchr(sg_major_minor, ':');
|
||||||
|
*c = '\0';
|
||||||
|
c++;
|
||||||
|
major = strtol(sg_major_minor, NULL, 10);
|
||||||
|
minor = strtol(c, NULL, 10);
|
||||||
|
snprintf(path, sizeof(path), "/dev/.tmp.md.%d:%d:%d",
|
||||||
|
(int) getpid(), major, minor);
|
||||||
|
if (mknod(path, S_IFCHR|0600, makedev(major, minor))==0) {
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
unlink(path);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue