Posted at

Linuxで簡単dfコマンド

dfコマンドはstatfs()を使って作るだけ。statvfs()でもいいけど.

setmntent(),endmntent() は中身は fopen()/fclose() だから使わないくても/etc/mtab直接みてもいいかな。

human-readableオプションや、excludeオプションなど、高機能な部分をなくした骨子はこんな感じでしょうか。


df.c

#include <mntent.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <unistd.h>

typedef struct _df_t {
struct mntent* mnt;
struct statfs* fs;
} DfData;

int get_mount_record(FILE* mtab, DfData* df)
{
df->mnt = getmntent(mtab);
if (df->mnt) {
if (df->mnt->mnt_dir == NULL) return 0;
if (statfs(df->mnt->mnt_dir, df->fs) != 0) return 0;
return 1;
}
return 0;
}

#define DF_KILO_RECORD_FMT "%-25s %10lu %10lu %10lu %4s %-10s\n"

void print_kilobyte(DfData* df) {
size_t total_size = df->fs->f_blocks * df->fs->f_bsize / 1024;
size_t avail_size = df->fs->f_bavail * df->fs->f_bsize / 1024;
size_t used_size = total_size - avail_size;
char percent[4] = {0};
if (df->fs->f_blocks == 0)
snprintf(percent, sizeof(percent), "-");
else
snprintf(percent, sizeof(percent), "%lu%%", (100 * used_size / total_size));

printf(DF_KILO_RECORD_FMT, df->mnt->mnt_fsname, total_size, used_size, avail_size, percent, df->mnt->mnt_dir);
return;
}

void show_kilobyte(FILE* mtab) {
DfData* df = (DfData*)malloc(sizeof(DfData));
df->fs = (struct statfs *)malloc(sizeof(struct statfs));

while(get_mount_record(mtab, df))
print_kilobyte(df);

free(df->fs);
free(df);
return;
}

int main(void)
{
FILE* mtab = setmntent(_PATH_MOUNTED, "r");
show_kilobyte(mtab);
endmntent(mtab);
exit(0);
}


実行結果。

$ gcc -Wall -Wextra -O2 df.o -o df

$ ./df
rootfs 30909700 19431160 11478540 62% /
sysfs 0 0 0 - /sys
proc 0 0 0 - /proc
devtmpfs 2441664 0 2441664 0% /dev
securityfs 0 0 0 - /sys/kernel/security
tmpfs 2325352 0 2325352 0% /dev/shm
devpts 0 0 0 - /dev/pts
tmpfs 2325352 8676 2316676 0% /run
tmpfs 2325352 0 2325352 0% /sys/fs/cgroup
cgroup 0 0 0 - /sys/fs/cgroup/systemd
pstore 0 0 0 - /sys/fs/pstore
cgroup 0 0 0 - /sys/fs/cgroup/cpuset
cgroup 0 0 0 - /sys/fs/cgroup/pids
cgroup 0 0 0 - /sys/fs/cgroup/net_cls,net_prio
cgroup 0 0 0 - /sys/fs/cgroup/blkio
cgroup 0 0 0 - /sys/fs/cgroup/perf_event
cgroup 0 0 0 - /sys/fs/cgroup/devices
cgroup 0 0 0 - /sys/fs/cgroup/freezer
cgroup 0 0 0 - /sys/fs/cgroup/hugetlb
cgroup 0 0 0 - /sys/fs/cgroup/cpu,cpuacct
cgroup 0 0 0 - /sys/fs/cgroup/memory
configfs 0 0 0 - /sys/kernel/config
/dev/mapper/centos-root 30909700 19431160 11478540 62% /
systemd-1 0 0 0 - /proc/sys/fs/binfmt_misc
mqueue 0 0 0 - /dev/mqueue
hugetlbfs 0 0 0 - /dev/hugepages
debugfs 0 0 0 - /sys/kernel/debug
binfmt_misc 0 0 0 - /proc/sys/fs/binfmt_misc
nfsd 0 0 0 - /proc/fs/nfsd
/dev/xvda1 508588 296336 212252 58% /boot
sunrpc 0 0 0 - /var/lib/nfs/rpc_pipefs
none 0 0 0 - /proc/xen
tmpfs 465072 0 465072 0% /run/user/1000