You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:52:02