Ubuntu上如何获取分区的可用空间

最近工作需要获取指定磁盘分区的可用空间,在这里记录一下。


网上找的资料一般用的是statvfs获取的,不过这种方案有缺陷,这里先简单介绍一下。

1. 使用statvfs获取

函数原型和入参介绍如下:

cpp 复制代码
int statvfs(const char *path, struct statvfs *buf);
// path:文件系统上的目录,磁盘目录不行,需要传对应磁盘的挂载点
// buf:引用传递的入参,包含查询的结果

statvfs结构体介绍如下:

cpp 复制代码
struct statvfs {
    unsigned long f_bsize;       // 用于执行I/O操作的首选块大小
    unsigned long f_frsize;      // 实际用于计算文件系统容量的块大小
    fsblkcnt_t   f_blocks;      // 文件系统中的总块数
    fsblkcnt_t   f_bfree;       // 空闲块的总数(包括保留给超级用户的块)
    fsblkcnt_t   f_bavail;      // 非超级用户可用的空闲块
    fsfilcnt_t   f_files;       // 文件系统能够创建的最大文件节点(inode)数
    fsfilcnt_t   f_ffree;       // 当前空闲的文件节点数(包括给超级用户的)
    fsfilcnt_t   f_favail;      // 非超级用户可用的自由节点
    unsigned long f_flag;       // 文件系统的挂载标志
    unsigned long f_namemax;    // 最大文件名长度
    // ... 其他成员
};

因此:

空闲空间大小 = f_frsize(块大小)× f_bavail(空闲块数)

代码如下:

cpp 复制代码
float get_partition_available_space(const char* partition) {
    // 1. 首先获取分区的挂载点
    char* mount_point = get_mount_point(partition);
    if (!mount_point) {
        printf("Partition %s is not mounted\n", partition);
        return -1;
    }

    // 2. 使用挂载点获取空间信息
    struct statvfs vfs;
    float available_space = -1;
    
    if (statvfs(mount_point, &vfs) == 0) {
        unsigned long long available = vfs.f_bavail * vfs.f_frsize;
        available_space = available / (1024.0 * 1024.0); // 转换为 MiB
    }

    free(mount_point);
    return available_space;
}

这个办法有一个缺点,就是只能获取挂载的磁盘分区,不挂载的无法获取。

2. 获取未挂载的磁盘可用容量

目前尝试过df等指令,以及libparted库,都无法获取。

临时的解决方案是把未挂载的磁盘挂起来,查看可用容量,查完之后再卸载。

代码如下:

cpp 复制代码
float get_unmounted_partition_space(const char* partition) {
    // 创建临时挂载点
    const char* temp_mount = "/tmp/temp_mount";
    if (mkdir(temp_mount, 0755) != 0 && errno != EEXIST) {
        perror("mkdir");
        return -1;
    }
    
    // 临时挂载
    char cmd[256];
    snprintf(cmd, sizeof(cmd), "mount %s %s", partition, temp_mount);
    if (system(cmd) != 0) {
        rmdir(temp_mount);
        return -1;
    }
    
    // 获取空间信息
    struct statvfs vfs;
    float available_space = -1;
    
    if (statvfs(temp_mount, &vfs) == 0) {
        unsigned long long available = vfs.f_bavail * vfs.f_frsize;
        available_space = available / (1024.0 * 1024.0); // 转换为 MiB
    }
    
    // 清理
    snprintf(cmd, sizeof(cmd), "umount %s", temp_mount);
    system(cmd);
    rmdir(temp_mount);
    
    return available_space;
}

这份代码执行需要root权限,因为涉及到挂载和卸载。

相关推荐
liulilittle3 分钟前
C++ 无锁编程:单停多发送场景高性能方案
服务器·开发语言·c++·高性能·无锁·原子
m0_738120729 分钟前
渗透基础知识ctfshow——Web应用安全与防护(第一章)
服务器·前端·javascript·安全·web安全·网络安全
亚空间仓鼠11 分钟前
OpenEuler系统常用服务(四)
linux·运维·服务器·网络
郝学胜-神的一滴29 分钟前
Socket实战:从单端聊天到多用户连接的实现秘籍
服务器·开发语言·python·网络协议·pycharm
MichealChen01050837 分钟前
Influxdb-cluster使用docker部署
运维·docker·容器
昪彧翀忞39 分钟前
dhcp小实验
linux·服务器·网络
bukeyiwanshui1 小时前
20260407系统间复制文档
linux
wqfhenanxc1 小时前
AirFlow安装和使用
运维
阿凤211 小时前
nginx部署如何配置ssl证书
运维·nginx·ssl
23.1 小时前
【Linux】grep -F 及 双横线--的妙用
linux·命令模式