如何修复 'invalid argument' 的 ioctl 请求以阻止设备
how to fix 'invalid argument' for ioctl requests to block device
我正在编写一个小的 c 程序来制作磁带状态并通过
查找请求
ioctl(int fd, long int request, &io_buf)
但经过试验和大量错误后,ioctl returning -1
errno 消息 "Invalid Argument"
我正在 Linux 和 运行 我的程序作为 sudo。我要向其发出请求的设备是一个光驱,通过 SCSI 连接。我已经通过将请求(分别为 MTIOCGET
或 MTIOCTOP
)传递给 ioctl
来尝试磁带状态和查找请求。
磁带状态函数的代码片段,其中 fd 是设备的文件描述符 return 由 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;
}
不是无效的参数错误消息和 -1 的 return,我希望 ioctl 和相应的结构实例 mtgetbuf 和 mtopbuf 成功 return 来填充它们的成员与设备提供的数据。
即带有 MTIOCGET
请求的成功 ioctl()
命令将 return 到 mtgetbuf mt_type 成员中 MT_ISSCSI1
、MT_ISSCSI2
或 MT_ISUNKNOWN
(我不认为这是其他供应商特定设备的任何其他定义值)。
注意:我知道 linux/mtio.h
头文件,我尝试用它代替 sys/mtio.h
,但结果是一样的。
我最近使用 SCSI 通用 Linux 驱动程序 (SG) 成功地向块设备发出了请求。三个头文件(如下)提供了操作码、用于从设备传递和检索数据的结构,以及其他信息。
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 设备通信的信息字体。 link 提供给它 here. It explains in detail various commands that can be issued, how to package the commands by creating an instance of the sg_io_hdr_t structure, as well as a programming example 发送一个 SCSI INQUIRY 命令,其中 returns 设备的基本供应商信息。还有用于错误处理和理解不成功的 SCSI 请求的状态和感知代码。
2) Seagate 的 SCSI 命令参考手册有时有助于理解 SCSI 命令中 bytes/bits 的结构。通常,操作码占据第一个字节,其余字节为零。本参考手册中的操作码是在上述三个头文件之间定义的。
我已经能够发送成功的 INQUIRY 和 GET_SG_VERSION_NUMBER 请求,而且很可能已经能够发送 SEEK(6)、READ_CAPACITY(10) 和 REZERO_UNIT 命令。我说最有可能是因为没有返回 -1/errno 值,也没有信息被传回感知缓冲区,这表明 warnings/errors(SCSI、主机适配器或驱动程序状态代码)。
希望这能回答 OP 的问题。
我正在编写一个小的 c 程序来制作磁带状态并通过
查找请求 ioctl(int fd, long int request, &io_buf)
但经过试验和大量错误后,ioctl returning -1
errno 消息 "Invalid Argument"
我正在 Linux 和 运行 我的程序作为 sudo。我要向其发出请求的设备是一个光驱,通过 SCSI 连接。我已经通过将请求(分别为 MTIOCGET
或 MTIOCTOP
)传递给 ioctl
来尝试磁带状态和查找请求。
磁带状态函数的代码片段,其中 fd 是设备的文件描述符 return 由 open() 编辑,mtgetbuf 是来自 sys/mtio.h
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;
}
不是无效的参数错误消息和 -1 的 return,我希望 ioctl 和相应的结构实例 mtgetbuf 和 mtopbuf 成功 return 来填充它们的成员与设备提供的数据。
即带有 MTIOCGET
请求的成功 ioctl()
命令将 return 到 mtgetbuf mt_type 成员中 MT_ISSCSI1
、MT_ISSCSI2
或 MT_ISUNKNOWN
(我不认为这是其他供应商特定设备的任何其他定义值)。
注意:我知道 linux/mtio.h
头文件,我尝试用它代替 sys/mtio.h
,但结果是一样的。
我最近使用 SCSI 通用 Linux 驱动程序 (SG) 成功地向块设备发出了请求。三个头文件(如下)提供了操作码、用于从设备传递和检索数据的结构,以及其他信息。
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 设备通信的信息字体。 link 提供给它 here. It explains in detail various commands that can be issued, how to package the commands by creating an instance of the sg_io_hdr_t structure, as well as a programming example 发送一个 SCSI INQUIRY 命令,其中 returns 设备的基本供应商信息。还有用于错误处理和理解不成功的 SCSI 请求的状态和感知代码。
2) Seagate 的 SCSI 命令参考手册有时有助于理解 SCSI 命令中 bytes/bits 的结构。通常,操作码占据第一个字节,其余字节为零。本参考手册中的操作码是在上述三个头文件之间定义的。
我已经能够发送成功的 INQUIRY 和 GET_SG_VERSION_NUMBER 请求,而且很可能已经能够发送 SEEK(6)、READ_CAPACITY(10) 和 REZERO_UNIT 命令。我说最有可能是因为没有返回 -1/errno 值,也没有信息被传回感知缓冲区,这表明 warnings/errors(SCSI、主机适配器或驱动程序状态代码)。
希望这能回答 OP 的问题。