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

临时ext3镜像文件挂载后fs4::available_space返回值与预期不符

问题描述

我用Rust编写了一段代码,通过dd命令创建大小为100*1000字节的临时镜像文件,将其格式化为ext3文件系统并挂载到指定目录。但使用fs4::available_space获取该挂载目录的可用空间时,返回值与预期的100000字节不匹配,执行代码后断言失败。相关代码、输出及依赖配置如下:

代码实现

use std::process::Command;

const TMP_DIR: &str = "/tmp/memory_check_test/";

fn init() {
    let _ = Command::new("dd")
    .args(["if=/dev/zero", "of=mem_check_file", "bs=1000", "count=100"])
    .output()
    .expect("failed to create empty file");

    let _ = Command::new("mkfs.ext3")
    .arg("mem_check_file")
    .output()
    .expect("failed to format mem_check_file with ext3 filesystem");

    let _ = Command::new("mkdir")
    .arg("-p")
    .arg(TMP_DIR)
    .output()
    .expect(&format!("failed to create directory {}", TMP_DIR));

    let _ = Command::new("mount")
    .arg("-o")
    .args(["loop", "mem_check_file", TMP_DIR])
    .output()
    .expect(&format!("failed to mount file to {} directory", TMP_DIR));

    let _ = Command::new("chmod")
    .arg("-R")
    .args(["777", TMP_DIR])
    .output()
    .expect(&format!("failed to change permissions for {} directory", TMP_DIR));
}

fn teardown() {
    let _ = Command::new("umount")
    .arg(TMP_DIR)
    .output()
    .expect(&format!("failed to unmount {} directory", TMP_DIR));

    let _ = Command::new("rmdir")
    .arg(TMP_DIR)
    .output()
    .expect(&format!("failed to remove {} directory", TMP_DIR));

    let _ = Command::new("rm")
    .arg("mem_check_file")
    .output()
    .expect("failed to remove mem_check_file");
}

fn main() {
    init();
    let available_space = fs4::available_space(TMP_DIR).expect("Failed to retrieve available memory space");
    println!("{}", available_space);
    teardown();
    assert_eq!(available_space, 100000);
}

运行输出

thread 'main' panicked at src/main.rs:57:5:
assertion `left == right` failed
  left: 100000
 right: 839506960384
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Cargo.toml配置

[package]
name = "mem_check"
version = "0.1.0"
edition = "2024"

[dependencies]
fs4 = "0.13.1"

问题分析与解决

核心原因

  1. 挂载操作未实际成功:代码仅检查命令是否能执行,未验证命令的退出状态码。大概率mount命令执行失败(比如权限不足、镜像过小无法挂载),导致fs4::available_space读取的是/tmp所在系统分区的可用空间,而非挂载的镜像文件。
  2. ext3文件系统元数据开销:即使挂载成功,ext3需要预留空间存储超级块、inode等元数据,100KB的小镜像中,元数据占比极高,实际可用空间远小于100000字节。
  3. 权限不足:mkfs.ext3和mount通常需要root权限,普通用户执行会直接失败。

修复方案

1. 严格校验命令执行结果

所有系统命令执行后必须检查退出状态,确保操作真的完成。以mount为例,修改代码如下(其他命令同理):

let output = Command::new("mount")
    .arg("-o")
    .args(["loop", "mem_check_file", TMP_DIR])
    .output()
    .expect(&format!("failed to run mount command for {}", TMP_DIR));

assert!(output.status.success(), "mount failed: {}", String::from_utf8_lossy(&output.stderr));

这样挂载失败时会直接打印错误信息,快速定位问题。

2. 调整镜像大小与预期值

ext3有最小空间要求,过小的镜像(100KB)无法正常格式化和挂载。建议创建更大的镜像(比如10MB):

// 修改dd命令参数
.args(["if=/dev/zero", "of=mem_check_file", "bs=1M", "count=10"])

挂载后用df -B1 /tmp/memory_check_test/查看实际可用字节数,再将断言的预期值替换为该实际数值。

3. 以root权限运行代码

执行mkfs.ext3和mount需要root权限,运行代码时加上sudo:

sudo cargo run

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:13:14