Rust无依赖项目调用ioctl BLKRRPART返回Bad Address(os error 14)
解决Rust调用ioctl BLKRRPART返回Bad address的问题
问题根源
你手动定义的BLKRRPART值错误。Linux的ioctl请求码并非简单的十六进制数,而是通过_IO宏生成,包含方向、类型、编号和参数大小四个结构字段。你直接写的0x00001269不符合_IO(0x12,95)的展开规则,这是导致"Bad address"错误的核心原因。
解决方案
1. 正确计算BLKRRPART请求码
根据Linux内核的_IO宏定义,_IO(0x12,95)展开后的正确值为0x0000125F(计算逻辑:(0 << 30) | (0 << 16) | (0x12 << 8) | 95,其中0代表无方向、无参数大小,0x12是类型码,95是请求编号)。
2. 修正代码并确保权限
以下是修正后的完整代码,同时确保以读写模式打开磁盘设备(BLKRRPART需要写权限):
use std::fs::{File, OpenOptions}; use std::os::unix::io::{AsRawFd, RawFd}; use std::io; #[derive(Debug)] enum SpamErrors { IOErrors(String), } impl From<io::Error> for SpamErrors { fn from(err: io::Error) -> Self { SpamErrors::IOErrors(err.to_string()) } } // 正确的BLKRRPART请求码,对应Linux内核的_IO(0x12, 95) const BLKRRPART: u64 = 0x0000125F; extern "C" { fn ioctl(fd: RawFd, request: u64) -> i32; } pub fn refresh_partition_table(drive_path: &str) -> Result<(), SpamErrors> { // 必须以读写模式打开磁盘设备,只读权限无法执行BLKRRPART let dr = OpenOptions::new() .read(true) .write(true) .open(drive_path)?; let fd: RawFd = dr.as_raw_fd(); let syscall = unsafe { ioctl(fd, BLKRRPART) }; if syscall == -1 { return Err(io::Error::last_os_error().into()); } Ok(()) }
补充说明
- 不需要传递空指针:BLKRRPART是无参数的ioctl请求,调用时只需传入文件描述符和请求码即可。
- 权限注意事项:执行该操作需要root权限,否则会返回权限不足的错误。
内容的提问来源于stack exchange,提问作者MarkAssPandi
相关产品推荐
相关产品推荐

