c - 如何修复 'invalid argument' 的 ioctl 请求以阻止设备

标签 c ioctl scsi

我正在编写一个小的 c 程序来制作磁带状态并通过

寻求请求
        ioctl(int fd, long int request, &io_buf) 

但在尝试和大量错误之后,ioctl 返回了 -1带有错误消息“无效参数”

我在 Linux 上运行我的程序作为 sudo。我要向其发出请求的设备是一个光驱,通过 SCSI 连接。我尝试了磁带状态并通过将请求(分别为 MTIOCGETMTIOCTOP )传递给 ioctl 来寻求请求。 .

磁带状态函数的代码片段,其中 fd 是 open() 返回的设备的文件描述符,mtgetbuf 是来自 sys/mtio.h 的 mtget 结构的实例。

       stat = ioctl(fd, MTIOCGET, &mtgetbuf);
       if (stat == -1)
       {
          perror("error on ioctl MTIOCGET request: ")
          return EXIT_FAILURE;
       }

除了mtopbuf 之外,查找磁带功能的类似代码片段是 mtop 结构的一个实例,MTSEEK 是为查找操作定义的操作码,也在 sys/mtio.h 中。

        mtopbuf.mt_op = MTSEEK;
        stat = ioctl(fd, MTIOCTOP, &mtopbuf);
        if (stat == -1)
        {
           perror("error on ioctl MTIOCGET request: ")
           return EXIT_FAILURE;
        }

我本希望 ioctl 和相应的结构实例 mtgetbuf 和 mtopbuf 成功返回,而不是无效参数错误消息和返回 -1,以让它们的成员填充设备提供的数据。

即一次成功ioctl()命令与 MTIOCGET请求将向 mtgetbuf mt_type 成员返回一个值 MT_ISSCSI1 , MT_ISSCSI2 , 或 MT_ISUNKNOWN (我不认为这是其他供应商特定设备的任何其他定义值)。

注意:我知道 linux/mtio.h头文件,我尝试用它代替 sys/mtio.h但结果是一样的。

最佳答案

我最近使用 SCSI 通用 Linux 驱动程序 (SG) 成功地向 block 设备发出了请求。三个头文件(如下)提供了操作码、用于从设备传递和检索数据的结构,以及其他信息。

SCSI SG 头文件:

        /usr/include/scsi/scsi.h
        /usr/include/scsi/scsi_ioctl.h
        /usr/include/scsi/sg.h

在线资源的组合有助于理解如何打包、发送和接收请求:

1) TLDP SCSI Generic (sg) HOW-TO 指南是关于通过 SG 驱动程序与 SCSI 设备通信的信息字体。提供了指向它的链接 here .它详细解释了可以发出的各种命令,如何通过创建 sg_io_hdr_t 结构的实例来打包命令,以及 programming example发送 SCSI INQUIRY 命令,该命令返回设备的基本供应商信息。还有用于错误处理和理解不成功的 SCSI 请求的状态和感知代码。

2) Seagate 的 SCSI 命令引用手册有时有助于理解 SCSI 命令中字节/位的结构。通常,操作码占据第一个字节,其余字节为零。本引用手册中的操作码是在上述三个头文件之间定义的。

我已经能够发送成功的 INQUIRY 和 GET_SG_VERSION_NUMBER 请求,而且很可能已经能够发送 SEEK(6)、READ_CAPACITY(10) 和 REZERO_UNIT 命令。我说最有可能是因为没有返回 -1/errno 值并且没有信息被传回感知缓冲区,这是警告/错误的指示(SCSI、主机适配器或驱动程序状态代码)。

希望这能回答 OP 的问题。

关于c - 如何修复 'invalid argument' 的 ioctl 请求以阻止设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57927360/

相关文章:

Linux:写入被分成 512K block

c++ - C/C++ 中的可移植目录/文件监视库

库达错误 C2054 : expected '(' to follow '__device__'

c - 当被测可执行文件以0退出时,为什么Valgrind的退出代码为1?

python - "Inappropriate ioctl for device"来自带有管道的 termios

java - ioctl() 与 JNI : broken file descriptor

linux - 将自定义结构类型添加到 strace

c - C 中没有 else 的三元运算符

error-handling - ASC/ASCQ 号码的 Sense Key

c++ - 如何在 Linux 下使用 C/C++ 获取 SCSI 磁盘列表?