【问题标题】:Inode usage without df -i没有 df -i 的 inode 使用
【发布时间】:2017-07-28 16:30:52
【问题描述】:

我想自动化远程进程以了解我的机器是否用尽 inode(由于配置错误而经常发生这种情况......)。遗憾的是,它在 df 命令上没有 -i 选项的轻量级 Linux 上运行,因此该选项不可用。我已经进行了一些研究,并且遇到了一些方法来查找具有最多 inode 和类似内容的文件夹,但我不希望那样。

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

【问题讨论】:

标签: c linux bash inode


【解决方案1】:

statvfs() 函数会针对每个已挂载的文件系统(通过提供所述已挂载文件系统上的任何文件或目录的路径来指定)报告您所寻找的内容。

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

stat -c '%d %c' -f /path

报告空闲 inode 的数量和 inode 的总数,每个给定的路径一行。如果系统使用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_blocks * (uint64_t)vfsinfo.f_frsize 表示每个文件系统的总大小)。

【讨论】:

  • stat 或busybox stat 都不适合我。我将尝试该 C 解决方案并稍后报告。
  • @J63:请做;我现在只能在 x86-64 系统上测试它。您还应该能够以正常方式将其交叉编译到您的目标系统。
  • 我将它编译到我的目标系统,它运行良好。非常感谢=)
猜你喜欢
  • 1970-01-01
  • 2017-05-06
  • 2010-09-25
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
相关资源
最近更新 更多