如何找出SCSI设备(说/ etc / sda)是否通过ioctl调用或其他磁盘?

如何通过ioctl调用或其他方式找出SCSI设备(比如/ dev / sda)是否是磁盘? 我已经尝试了以下,但ioctl调用失败。 我的/ dev / sda是​​一个USB闪存盘。

 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <scsi/scsi.h> #include <scsi/sg.h> #include <sys/ioctl.h> int main(int argc, char** argv) { char *dev = "/dev/sda"; struct sg_scsi_id m_id; int rc; int fd; fd = open(dev, O_RDONLY | O_NONBLOCK); if (fd < 0) { perror(dev); } memset(&m_id, 0, sizeof (m_id)); rc = ioctl(fd, SG_GET_SCSI_ID, &m_id); if (rc < 0) { close(fd); printf("FAIL: ioctl SG_GET_SCSI_ID, rc=%d, errno=%d\n", rc, errno); } else { if (m_id.scsi_type == TYPE_DISK || m_id.scsi_type == 14) { printf("OK: is disk\n"); } else { printf("OK: is NOT disk\n"); } } close(fd); return (EXIT_SUCCESS); } // result is: FAIL: ioctl SG_GET_SCSI_ID, rc=-1, errno=22 

我已经使用SG_IO解决了这个SG_IO并根据INQUIRY命令 (字段:外围设备类型)的规范直接解释二进制数据,并根据SCSI外围设备类型解释它们(如果每个设备类型是00h或0Eh )

 int is_disk_sd(char *dev) { unsigned char sense[32]; struct sg_io_hdr io_hdr; char scsi_data[SCSI_LEN]; struct hd_geometry geo; // request for "standard inquiry data" unsigned char inq_cmd[] = {INQUIRY, 0, 0, 0, SCSI_LEN, 0}; int fd; fd = open(dev, O_RDONLY | O_NONBLOCK); if (fd < 0) { perror(dev); } memset(&io_hdr, 0, sizeof (io_hdr)); io_hdr.interface_id = 'S'; io_hdr.cmdp = inq_cmd; io_hdr.cmd_len = sizeof (inq_cmd); io_hdr.dxferp = scsi_data; io_hdr.dxfer_len = sizeof (scsi_data); io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; io_hdr.sbp = sense; io_hdr.mx_sb_len = sizeof (sense); io_hdr.timeout = 5000; if (ioctl(fd, SG_IO, &io_hdr) < 0) { close(fd); return 0; } else { close(fd); if (scsi_data[1] & 0x80) { return 0; // support is removable } if ((scsi_data[0] & 0x1f) || ((scsi_data[0] & 0x1f) != 0xe)) { // 0 or 14 (00h or 0Eh) return 0; // not direct access neither simplified direct access device } return 1; } } 

也许你可以从/ sys / bus / scsi / devices / * / filesystem中获得有用的信息。

HDIO_GET_IDENTITY在磁盘上似乎适用于我,但不适用于闪存驱动器。 我认为这是hdparm -i使用的。