C 不带df-i的Inode使用

C 不带df-i的Inode使用,c,linux,bash,inode,C,Linux,Bash,Inode,我想自动化一个远程进程,以了解我的一台机器是否耗尽了inode(由于配置不好而经常发生的事情…)。遗憾的是,它运行在轻量级linux上,df命令上没有-i选项,因此该选项不可用。我做了一些研究,我遇到了一些方法来找到索引节点最多和类似的文件夹,但我不想这样 我需要一种方法(在C或bash中)来知道我的系统总共有多少个inode,并且当前是可用的 对于每个挂载的文件系统(通过提供指向所述挂载文件系统上的任何文件或目录的路径来指定),函数会报告您要查找的内容 如果系统安装了GNU coreutils

我想自动化一个远程进程,以了解我的一台机器是否耗尽了inode(由于配置不好而经常发生的事情…)。遗憾的是,它运行在轻量级linux上,df命令上没有-i选项,因此该选项不可用。我做了一些研究,我遇到了一些方法来找到索引节点最多和类似的文件夹,但我不想这样


我需要一种方法(在C或bash中)来知道我的系统总共有多少个inode,并且当前是可用的

对于每个挂载的文件系统(通过提供指向所述挂载文件系统上的任何文件或目录的路径来指定),函数会报告您要查找的内容

如果系统安装了GNU coreutils,那么它有一个名为
stat
的小实用程序。对于文件系统上文件或目录的每个路径

stat -c '%d %c' -f /path
报告可用索引节点的数量和索引节点的总数,每个给定路径一行。如果系统使用busybox,则

busybox stat -c '%d %c' -f /path
做同样的事情

如果您需要对输出进行更多的控制,或者出于某种原因上述两项都不适合您,您可以轻松编写自己的实用程序来报告摘要: 下面是一个示例,inode stats.c

#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    dev_t       device[argc];
    int         devices = 0;
    uint64_t    total_inodes = 0;
    uint64_t    avail_inodes = 0; /* Free to normal users */
    uint64_t    free_inodes = 0;  /* Free to superuser */
    int         arg, i;

    if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
        printf("\n");
        printf("Usage: %s [ -h | --help ]\n", argv[0]);
        printf("       %s mountpoint [ mountpoint ... ]\n", argv[0]);
        printf("\n");
        printf("This program will report the percentage of inodes in use,\n");
        printf("the number free inodes available for normal users,\n");
        printf("the number of free inodes available for root,\n");
        printf("and the total number of inodes,\n");
        printf("in the filesystems referred to the supplied paths.\n");
        printf("\n");
        printf("Each mount is only counted once, even if multiple paths\n");
        printf("to the same mount are given as parameters.\n");
        printf("\n");
        return EXIT_SUCCESS;
    }

    for (arg = 1; arg < argc; arg++) {
        struct stat     info;
        struct statvfs  vfsinfo;

        if (stat(argv[arg], &info) == -1) {
            fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
            continue;
        }
        if (statvfs(argv[arg], &vfsinfo) == -1) {
            fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
            continue;
        }

        /* Check if device already seen. */
        for (i = 0; i < devices; i++)
            if (info.st_dev == device[i])
                break;
        if (i < devices)
            continue;

        /* Add to known devices. */
        device[devices++] = info.st_dev;

        /* Add to inode counters. */
        total_inodes += (uint64_t)vfsinfo.f_files;
        avail_inodes += (uint64_t)vfsinfo.f_favail;
        free_inodes  += (uint64_t)vfsinfo.f_ffree;
    }

    if (total_inodes < 0) {
        fprintf(stderr, "No inodes!\n");
        return EXIT_FAILURE;
    }

    /* Print result. */
    printf("%.3f%% - %" PRIu64 " free (%" PRIu64 " for root) out of %" PRIu64 " inodes.\n",
           100.0 - 100.0 * (double)avail_inodes / (double)total_inodes,
           avail_inodes, free_inodes, total_inodes);
    return EXIT_SUCCESS;
}
可选择使用安装,例如:

gcc -Wall -O2 inode-stats.c -o inode-stats
sudo install -o root -g root -m 0755 inode-stats /usr/bin
并运行它,为您感兴趣的挂载(挂载文件系统)中的任何目录或文件提供路径。比如说,

inode-stats / /usr /var /home
该程序非常聪明,即使您提供了指向其中目录/文件的多条路径,也只需计算一次装载量——这与GNU coreutils'或busybox
stat
不同


您可以简单地更改输出报告格式,并轻松地添加其他统计信息(如可用磁盘空间,使用
(uint64_t)vfsinfo.f_bavail*(uint64_t)vfsinfo.f_bsize
了解普通用户可用的磁盘空间量,以及
(uint64_t)vfsinfo.f_块*(uint64_t)vfsinfo.f_frsize了解每个文件系统的总大小)

如果系统安装了GNU coreutils,那么它有一个名为
stat
的小实用程序。对于文件系统上文件或目录的每个路径

stat -c '%d %c' -f /path
报告可用索引节点的数量和索引节点的总数,每个给定路径一行。如果系统使用busybox,则

busybox stat -c '%d %c' -f /path
做同样的事情

如果您需要对输出进行更多的控制,或者出于某种原因上述两项都不适合您,您可以轻松编写自己的实用程序来报告摘要: 下面是一个示例,inode stats.c

#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    dev_t       device[argc];
    int         devices = 0;
    uint64_t    total_inodes = 0;
    uint64_t    avail_inodes = 0; /* Free to normal users */
    uint64_t    free_inodes = 0;  /* Free to superuser */
    int         arg, i;

    if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
        printf("\n");
        printf("Usage: %s [ -h | --help ]\n", argv[0]);
        printf("       %s mountpoint [ mountpoint ... ]\n", argv[0]);
        printf("\n");
        printf("This program will report the percentage of inodes in use,\n");
        printf("the number free inodes available for normal users,\n");
        printf("the number of free inodes available for root,\n");
        printf("and the total number of inodes,\n");
        printf("in the filesystems referred to the supplied paths.\n");
        printf("\n");
        printf("Each mount is only counted once, even if multiple paths\n");
        printf("to the same mount are given as parameters.\n");
        printf("\n");
        return EXIT_SUCCESS;
    }

    for (arg = 1; arg < argc; arg++) {
        struct stat     info;
        struct statvfs  vfsinfo;

        if (stat(argv[arg], &info) == -1) {
            fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
            continue;
        }
        if (statvfs(argv[arg], &vfsinfo) == -1) {
            fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
            continue;
        }

        /* Check if device already seen. */
        for (i = 0; i < devices; i++)
            if (info.st_dev == device[i])
                break;
        if (i < devices)
            continue;

        /* Add to known devices. */
        device[devices++] = info.st_dev;

        /* Add to inode counters. */
        total_inodes += (uint64_t)vfsinfo.f_files;
        avail_inodes += (uint64_t)vfsinfo.f_favail;
        free_inodes  += (uint64_t)vfsinfo.f_ffree;
    }

    if (total_inodes < 0) {
        fprintf(stderr, "No inodes!\n");
        return EXIT_FAILURE;
    }

    /* Print result. */
    printf("%.3f%% - %" PRIu64 " free (%" PRIu64 " for root) out of %" PRIu64 " inodes.\n",
           100.0 - 100.0 * (double)avail_inodes / (double)total_inodes,
           avail_inodes, free_inodes, total_inodes);
    return EXIT_SUCCESS;
}
可选择使用安装,例如:

gcc -Wall -O2 inode-stats.c -o inode-stats
sudo install -o root -g root -m 0755 inode-stats /usr/bin
并运行它,为您感兴趣的挂载(挂载文件系统)中的任何目录或文件提供路径。比如说,

inode-stats / /usr /var /home
该程序非常聪明,即使您提供了指向其中目录/文件的多条路径,也只需计算一次装载量——这与GNU coreutils'或busybox
stat
不同


您可以简单地更改输出报告格式,并轻松地添加其他统计信息(如可用磁盘空间,使用
(uint64_t)vfsinfo.f_bavail*(uint64_t)vfsinfo.f_bsize
了解普通用户可用的磁盘空间量,以及
(uint64_t)vfsinfo.f_块*(uint64_t)vfsinfo.f_frsize了解每个文件系统的总大小).

至于
C
源代码,您可以参加
df.C
的一部分,它是开源的。至于
bash
解决方案,请看另一个问题,您可以使用Perl还是Python?我有Perl,但没有python。我来看看这个解决方案。对于
C
源代码,您可以使用开源的
df.C
的一部分。至于
bash
解决方案,请看另一个问题,您可以使用Perl还是Python?我有Perl,但没有python。我来看看这个解决方案。不管是stat还是busybox stat都不适合我。我将尝试C解决方案,稍后报告。@J63:请这样做;目前,我只能在x86-64系统上测试它。您还应该能够以正常的方式将它交叉编译到您的目标系统中。我将它编译到我的目标系统中,它运行得很好。非常感谢=)stat和busybox stat都不适合我。我将尝试C解决方案,稍后报告。@J63:请这样做;目前,我只能在x86-64系统上测试它。您还应该能够以正常的方式将它交叉编译到您的目标系统中。我将它编译到我的目标系统中,它运行得很好。非常感谢=)