【问题标题】:How can I determine filesystem type (name) with Linux API for C?如何使用 Linux API for C 确定文件系统类型(名称)?
【发布时间】:2018-01-18 10:37:09
【问题描述】:

我需要一个 C 字符串,其中包含 fs 名称。 有很多命令可以在终端中打印 fs 名称,但我找不到在 C/C++ 代码中获取它的简单方法。

【问题讨论】:

标签: c++ c linux system-calls


【解决方案1】:

你解析/proc/mounts

如果您使用过 stat() 系列函数之一,并且有一个数字形式的文件系统标识符 (st_dev),您只需 stat()/proc/mounts 中列出的每个挂载点的挂载目录(附加/./ 到每个挂载点,这样你就可以统计挂载的目录,而不是其父文件系统中的挂载点),直到你看到一个匹配的。使用该条目(行),您可以获得内核看到的文件系统的类型。

请记住,Linux 系统中的/proc//sys/ 不在磁盘上,但它们是内核公开某些细节的适当接口。当前挂载的文件系统(/proc/mounts)就是其中之一。

中,使用fopen()getline()fclose()free()strtok()sscanf() 或您自己的分行函数非常简单。请记住,作为内核接口,/proc//sys/ 中的文件内容永远不会本地化;它们总是在默认的 C/POSIX 语言环境中。

【讨论】:

    【解决方案2】:

    Linux C API 有 statfs()(受 BSD 启发,对于其他 unix 等操作系统,请查看 stat from coreutils)。

    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/vfs.h>
    
    // https://github.com/linux-test-project/ltp/tree/master/include/tst_fs.h
    /* man 2 statfs or kernel-source/include/linux/magic.h */
    #define TST_BTRFS_MAGIC    0x9123683E
    #define TST_NFS_MAGIC      0x6969
    #define TST_RAMFS_MAGIC    0x858458f6
    #define TST_TMPFS_MAGIC    0x01021994
    #define TST_V9FS_MAGIC     0x01021997
    #define TST_XFS_MAGIC      0x58465342
    #define TST_EXT2_OLD_MAGIC 0xEF51
    /* ext2, ext3, ext4 have the same magic number */
    #define TST_EXT234_MAGIC   0xEF53
    #define TST_MINIX_MAGIC    0x137F
    #define TST_MINIX_MAGIC2   0x138F
    #define TST_MINIX2_MAGIC   0x2468
    #define TST_MINIX2_MAGIC2  0x2478
    #define TST_MINIX3_MAGIC   0x4D5A
    #define TST_UDF_MAGIC      0x15013346
    #define TST_SYSV2_MAGIC    0x012FF7B6
    #define TST_SYSV4_MAGIC    0x012FF7B5
    #define TST_UFS_MAGIC      0x00011954
    #define TST_UFS2_MAGIC     0x19540119
    #define TST_F2FS_MAGIC     0xF2F52010
    #define TST_NILFS_MAGIC    0x3434
    #define TST_EXOFS_MAGIC    0x5DF5
    #define TST_OVERLAYFS_MAGIC 0x794c7630
    #define TST_FUSE_MAGIC     0x65735546
    
    // https://github.com/linux-test-project/ltp/tree/master/lib/tst_fs_type.c
    const char *tst_fs_type_name(long f_type)
    {
        switch (f_type) {
        case TST_TMPFS_MAGIC:
            return "tmpfs";
        case TST_NFS_MAGIC:
            return "nfs";
        case TST_V9FS_MAGIC:
            return "9p";
        case TST_RAMFS_MAGIC:
            return "ramfs";
        case TST_BTRFS_MAGIC:
            return "btrfs";
        case TST_XFS_MAGIC:
            return "xfs";
        case TST_EXT2_OLD_MAGIC:
            return "ext2";
        case TST_EXT234_MAGIC:
            return "ext2/ext3/ext4";
        case TST_MINIX_MAGIC:
        case TST_MINIX_MAGIC2:
        case TST_MINIX2_MAGIC:
        case TST_MINIX2_MAGIC2:
        case TST_MINIX3_MAGIC:
            return "minix";
        case TST_UDF_MAGIC:
            return "udf";
        case TST_SYSV2_MAGIC:
        case TST_SYSV4_MAGIC:
            return "sysv";
        case TST_UFS_MAGIC:
        case TST_UFS2_MAGIC:
            return "ufs";
        case TST_F2FS_MAGIC:
            return "f2fs";
        case TST_NILFS_MAGIC:
            return "nilfs";
        case TST_EXOFS_MAGIC:
            return "exofs";
        case TST_OVERLAYFS_MAGIC:
            return "overlayfs";
        case TST_FUSE_MAGIC:
            return "fuse";
        default:
            return "unknown";
        }
    }
    
    void print_filesystem(const char* path)
    {
        if (path == NULL)
            return;
    
        struct statfs s;
    
        if (statfs(path, &s)) {
            fprintf(stderr, "statfs(%s) failed: %s\n", path, strerror(errno));
            return;
        }
    
        printf("'%s' filesystem: %s\n", path, tst_fs_type_name(s.f_type));
    }
    
    int main(int argc, char *argv[]) {
        print_filesystem("/");
        print_filesystem("/tmp");
    
        return 0;
    }
    

    例子:

    $ gcc -Wall filesystem.c -o filesystem && ./filesystem
    '/' filesystem: ext2/ext3/ext4
    '/tmp' filesystem: tmpfs
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 2017-03-08
      • 2018-11-12
      • 1970-01-01
      • 1970-01-01
      • 2014-06-08
      • 2015-05-28
      相关资源
      最近更新 更多