如何修复ioctl请求的“无效参数”以阻止设备

时间:2019-09-13 16:33:52

标签: 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_ISSCSI1MT_ISSCSI2MT_ISUNKNOWN的值(我不会相信它是其他特定于供应商的设备的其他定义值。

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

1 个答案:

答案 0 :(得分:0)

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

SCSI SG头文件:

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

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

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

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

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

希望这能回答OP的问题。