getmntent_r接口示例程序地址:https://github.com/Rtoax/test/tree/master/c/glibc/mntent

statfs 接口示例程序地址​​​​​​​:https://github.com/Rtoax/test/tree/master/c/glibc/sys/statfs

本文所有代码地址:GitHub地址:https://github.com/Rtoax/test/tree/master/fs-filesystem/fs_occupy

目录

背景介绍

相关接口

文件系统接口

struct mntent

getmntent_r

文件系统状态接口

struct statfs

statfs

C语言实现

接口设计

struct fs_occupy_info

fs_info_ops_fn

fs_storage_occupy

源代码地址

fs_occupy.c

fs_occupy.h

test.c

运行结果

编译运行

df指令查询结果对比


背景介绍


Linux系统C语言遍历系统文件系统,并查询其磁盘使用率(有效磁盘)

相关接口


文件系统接口


struct mntent

#include <mntent.h>struct mntent {char *mnt_fsname;   /* name of mounted file system */char *mnt_dir;      /* file system path prefix */char *mnt_type;     /* mount type (see mntent.h) */char *mnt_opts;     /* mount options (see mntent.h) */int   mnt_freq;     /* dump frequency in days */int   mnt_passno;   /* pass number on parallel fsck */
};

getmntent_r

getmntent_r是线程安全的。

getmntent_r接口示例程序地址:https://github.com/Rtoax/test/tree/master/c/glibc/mntent

/* GNU extension */
#include <mntent.h>//The  reentrant getmntent_r() function is similar to getmntent(),
//but stores the struct mount in the provided *mntbuf and stores the strings
//pointed to by the entries in that struct in the provided array buf of size buflen.
struct mntent *getmntent_r(FILE *fp, struct mntent *mntbuf,char *buf, int buflen);

文件系统状态接口


struct statfs

#if __WORDSIZE == 32          /* System word size */
# define __SWORD_TYPE           int
#else /* __WORDSIZE == 64 */
# define __SWORD_TYPE         long int
#endifstruct statfs {__SWORD_TYPE f_type;    /* type of file system (see below) */__SWORD_TYPE f_bsize;   /* optimal transfer block size */fsblkcnt_t   f_blocks;  /* total data blocks in file system */fsblkcnt_t   f_bfree;   /* free blocks in fs */fsblkcnt_t   f_bavail;  /* free blocks available tounprivileged user */fsfilcnt_t   f_files;   /* total file nodes in file system */fsfilcnt_t   f_ffree;   /* free file nodes in fs */fsid_t       f_fsid;    /* file system id */__SWORD_TYPE f_namelen; /* maximum length of filenames */__SWORD_TYPE f_frsize;  /* fragment size (since Linux 2.6) */__SWORD_TYPE f_spare[5];
};

系统定义的文件系统类型

//File system types:
//
#define   ADFS_SUPER_MAGIC      0xadf5
#define   AFFS_SUPER_MAGIC      0xADFF
#define   BEFS_SUPER_MAGIC      0x42465331
#define   BFS_MAGIC             0x1BADFACE
#define   CIFS_MAGIC_NUMBER     0xFF534D42
#define   CODA_SUPER_MAGIC      0x73757245
#define   COH_SUPER_MAGIC       0x012FF7B7
#define   CRAMFS_MAGIC          0x28cd3d45
#define   DEVFS_SUPER_MAGIC     0x1373
#define   EFS_SUPER_MAGIC       0x00414A53
#define   EXT_SUPER_MAGIC       0x137D
#define   EXT2_OLD_SUPER_MAGIC  0xEF51
#define   EXT2_SUPER_MAGIC      0xEF53
#define   EXT3_SUPER_MAGIC      0xEF53
#define   EXT4_SUPER_MAGIC      0xEF53
#define   HFS_SUPER_MAGIC       0x4244
#define   HPFS_SUPER_MAGIC      0xF995E849
#define   HUGETLBFS_MAGIC       0x958458f6
#define   ISOFS_SUPER_MAGIC     0x9660
#define   JFFS2_SUPER_MAGIC     0x72b6
#define   JFS_SUPER_MAGIC       0x3153464a
#define   MINIX_SUPER_MAGIC     0x137F /* orig. minix */
#define   MINIX_SUPER_MAGIC2    0x138F /* 30 char minix */
#define   MINIX2_SUPER_MAGIC    0x2468 /* minix V2 */
#define   MINIX2_SUPER_MAGIC2   0x2478 /* minix V2, 30 char names */
#define   MSDOS_SUPER_MAGIC     0x4d44
#define   NCP_SUPER_MAGIC       0x564c
#define   NFS_SUPER_MAGIC       0x6969
#define   NTFS_SB_MAGIC         0x5346544e
#define   OPENPROM_SUPER_MAGIC  0x9fa1
#define   PROC_SUPER_MAGIC      0x9fa0
#define   QNX4_SUPER_MAGIC      0x002f
#define   REISERFS_SUPER_MAGIC  0x52654973
#define   ROMFS_MAGIC           0x7275
#define   SMB_SUPER_MAGIC       0x517B
#define   SYSV2_SUPER_MAGIC     0x012FF7B6
#define   SYSV4_SUPER_MAGIC     0x012FF7B5
#define   TMPFS_MAGIC           0x01021994
#define   UDF_SUPER_MAGIC       0x15013346
#define   UFS_MAGIC             0x00011954
#define   USBDEVICE_SUPER_MAGIC 0x9fa2
#define   VXFS_SUPER_MAGIC      0xa501FCF5
#define   XENIX_SUPER_MAGIC     0x012FF7B4
#define   XFS_SUPER_MAGIC       0x58465342
#define   _XIAFS_SUPER_MAGIC    0x012FD16D

statfs

statfs 接口示例程序地址​​​​​​​:https://github.com/Rtoax/test/tree/master/c/glibc/sys/statfs

int statfs (const char *__file, struct statfs *__buf);

C语言实现


接口设计

struct fs_occupy_info

struct fs_occupy_info {char fs_name[64];   /* name of mounted file system */char fs_mnt_dir[128];      /* file system path prefix */char fs_type[64];     /* mount type (see mntent.h) */unsigned long int totalMB;unsigned long int freeMB;struct {int integer;int decimal;}occupy;
};

fs_info_ops_fn

/***  fs_info_ops_fn - 有效文件系统使用率查询回调函数*  *  info - 参见 struct fs_occupy_info */
typedef void (*fs_info_ops_fn)(const struct fs_occupy_info *info);

fs_storage_occupy

/** *  fs_storage_occupy - 查询有效文件系统使用率*      *   该接口会轮询调用 display 有效文件系统个数次,每次将 struct fs_occupy_info 结构*  传递给 fs_info_ops_fn 回调函数。*/
void fs_storage_occupy(fs_info_ops_fn display);

源代码地址

GitHub地址:https://github.com/Rtoax/test/tree/master/fs-filesystem/fs_occupy

fs_occupy.c

/***  fs_occupy - 遍历系统文件系统,并查询其磁盘使用率(有效磁盘)*  *  日期:2020年10月15日*  作者:荣涛*/
#include <stdio.h>
#include <stdlib.h>
#include <mntent.h>
#include <pthread.h>
#include <assert.h>
#include <malloc.h>
#include <string.h>
#include <sys/statfs.h>#include "list.h"
#include "fs_occupy.h"#ifndef weak_alias
#define weak_alias(name, aliasname) extern typeof (name) aliasname __attribute__ ((weak, alias(#name)))
#endif/* 文件系统列表 */
struct crypto_fs_system {struct fs_occupy_info occupy_info;struct list_head list;
};/* 为了线程安全 */
static pthread_rwlock_t fs_rwlock = PTHREAD_RWLOCK_INITIALIZER;
static LIST_HEAD(fs_list);/*多文件系统链表头  *//* 返回0,有效的文件系统,可以统计出使用率返回其他,无效的文件系统,不可以统计使用率
*/
static int calculate_fs_occupy_nonlock(struct fs_occupy_info *info)
{struct statfs diskInfo;memset(&diskInfo, 0, sizeof(struct statfs));/* 获取文件系统属性 */statfs(info->fs_mnt_dir, &diskInfo);/* 获取参数,计算总MB数 */unsigned long long totalBlocks = diskInfo.f_bsize;unsigned long long totalSize = totalBlocks * diskInfo.f_blocks;size_t mbTotalsize = totalSize>>20;info->totalMB = mbTotalsize;//    printf(">>>>>>>>> %-15s %ld\t%ld\t\n",
//                info->fs_mnt_dir,
//                diskInfo.f_blocks,      /* total data blocks in file system */
//                diskInfo.f_bfree        /* free blocks in fs */
//            );/* 检测参数有效性 */if(mbTotalsize <= 0) return -1;/* 计算参数 */unsigned long long freeDisk = diskInfo.f_bfree*totalBlocks;size_t mbFreedisk = freeDisk>>20;info->freeMB = mbFreedisk;/* 检测参数有效性 */if(mbFreedisk <= 0) return -1;/* 计算使用率 */double occupy = (mbTotalsize-mbFreedisk)*1.0/mbTotalsize;int occupy_integer = (int) (occupy*100.0);int occupy_decimal = (int) (occupy*100000.0) - occupy_integer*100;if(occupy_integer < 0) return -1;if(occupy_decimal < 0) return -1;info->occupy.integer = occupy_integer;info->occupy.decimal = occupy_decimal;return 0;
}/* 从系统中获取 */
static void fs_list_alloc_nonlock()
{struct mntent *ent, mntbuf;FILE *aFile;aFile = setmntent("/proc/mounts", "r"); assert(aFile != NULL);char buf[512] = {0};while (NULL != (ent = getmntent_r(aFile, &mntbuf, buf, 512))) {struct crypto_fs_system *fs = malloc(sizeof(struct crypto_fs_system));assert(fs != NULL);memset(fs, 0, sizeof(struct crypto_fs_system));/* 这里需要拷贝新实例 */strcpy(fs->occupy_info.fs_name, ent->mnt_fsname);strcpy(fs->occupy_info.fs_type, ent->mnt_type);strcpy(fs->occupy_info.fs_mnt_dir, ent->mnt_dir);/* 计算使用率 */int ret = calculate_fs_occupy_nonlock(&fs->occupy_info);if(ret == 0) {list_add_tail(&fs->list, &fs_list);} else {free(fs);}}endmntent(aFile);
}/* 释放链表 */
static void fs_list_free_nonlock()
{struct crypto_fs_system *ifs = NULL, *next_fs = NULL;list_for_each_entry_safe(ifs, next_fs, &fs_list, list) {if(ifs) {list_del(&ifs->list);free(ifs);}}
}
/* 初始化/创建/填充链表 */
static void fs_list_init_safe()
{volatile static int load_already = 0;/* 线程锁 */pthread_rwlock_wrlock(&fs_rwlock);load_already += 1;  if(load_already == 1) {fs_list_alloc_nonlock();}if(load_already == 3) {load_already = 1;fs_list_free_nonlock();fs_list_alloc_nonlock();}pthread_rwlock_unlock(&fs_rwlock);
}/* 轮询链表 */
static void for_each_fs_nonlock(fs_info_ops_fn display)
{   if(list_empty_careful(&fs_list)) {return ;}struct crypto_fs_system *ifs = NULL, *next_fs = NULL;list_for_each_entry_safe(ifs, next_fs, &fs_list, list) {if(ifs) {struct fs_occupy_info *info = &ifs->occupy_info;if(display) display(info);}}
}/* 轮询链表,线程安全 */
static void for_each_fs_safe(fs_info_ops_fn display)
{pthread_rwlock_rdlock(&fs_rwlock);for_each_fs_nonlock(display);pthread_rwlock_unlock(&fs_rwlock);
}/** *  __fs_storage_occupy - 查询有效文件系统使用率*      *   该接口会轮询调用 display 有效文件系统个数次,每次将 struct fs_occupy_info 结构*  传递给 fs_info_ops_fn 回调函数。*/
static void __fs_storage_occupy(fs_info_ops_fn display)
{if(!display) return ;fs_list_init_safe();for_each_fs_safe(display);
}
weak_alias(__fs_storage_occupy, fs_storage_occupy);

fs_occupy.h

/***  fs_occupy - 遍历系统文件系统,并查询其磁盘使用率(有效磁盘)*  *  日期:2020年10月15日*  作者:荣涛*/
#ifndef __FS_OCCUPY_H
#define __FS_OCCUPY_H 1#include <stdio.h>/***  struct fs_occupy_info - 文件系统使用率查询信息结构*  *  fs_name - 文件系统名称,例如 /dev/mapper/centos-root*  fs_mnt_dir - 文件系统挂载点*              # df  *              文件系统                     1K-块       已用       可用      已用% 挂载点*              /dev/mapper/centos-root  36678148 35066696  1611452   96%   /**  fs_type - 文件系统类型 xfs ext4 rootfs 等*  *  *  occupy  occupy.integer  使用率的正数部分*          occupy.decimal  使用率的小数部分*          例如: 使用率为 20.234 %时:*                  occupy.integer=20*                  occupy.decimal=234*/
struct fs_occupy_info {char fs_name[64];   /* name of mounted file system */char fs_mnt_dir[128];      /* file system path prefix */char fs_type[64];     /* mount type (see mntent.h) */unsigned long int totalMB;unsigned long int freeMB;struct {int integer;int decimal;}occupy;
};/***  fs_info_ops_fn - 有效文件系统使用率查询回调函数*  *  info - 参见 struct fs_occupy_info */
typedef void (*fs_info_ops_fn)(const struct fs_occupy_info *info);/** *  fs_storage_occupy - 查询有效文件系统使用率*      *   该接口会轮询调用 display 有效文件系统个数次,每次将 struct fs_occupy_info 结构*  传递给 fs_info_ops_fn 回调函数。*/
void fs_storage_occupy(fs_info_ops_fn display);#endif /*<__FS_OCCUPY_H>*/

test.c

#include <stdio.h>#include "fs_occupy.h"void fs_display(const struct fs_occupy_info *info)
{printf("%-25s %-10s %-16s %ldMb/%ldMb  %3d.%2d%%\n", info->fs_name, info->fs_type, info->fs_mnt_dir,info->freeMB,info->totalMB,info->occupy.integer,info->occupy.decimal);
}int main(void)
{printf("\n-------------------------------------\n");fs_storage_occupy(fs_display);
}

运行结果


编译运行

[root@localhost fs_occupy]# make
gcc fs_occupy.c test.c -o test.out -pthread
[root@localhost fs_occupy]# ./test.out -------------------------------------
rootfs                    rootfs     /                1573Mb/35818Mb   95.86108%
devtmpfs                  devtmpfs   /dev             3875Mb/3875Mb    0. 0%
tmpfs                     tmpfs      /dev/shm         3891Mb/3891Mb    0. 0%
tmpfs                     tmpfs      /run             3410Mb/3891Mb   12.11161%
tmpfs                     tmpfs      /sys/fs/cgroup   3891Mb/3891Mb    0. 0%
/dev/mapper/centos-root   xfs        /                1573Mb/35818Mb   95.86108%
/dev/vda1                 xfs        /boot            641Mb/1014Mb   36.33185%
/dev/vdb                  ext4       /work            66404Mb/100664Mb   34.30634%
tmpfs                     tmpfs      /run/user/42     778Mb/778Mb    0. 0%
tmpfs                     tmpfs      /run/user/1002   778Mb/778Mb    0. 0%

df指令查询结果对比

[root@localhost fs_occupy]# df
文件系统                    1K-块     已用     可用 已用% 挂载点
/dev/mapper/centos-root  36678148 35066860  1611288   96% /
devtmpfs                  3968696        0  3968696    0% /dev
tmpfs                     3985092       88  3985004    1% /dev/shm
tmpfs                     3985092   492648  3492444   13% /run
tmpfs                     3985092        0  3985092    0% /sys/fs/cgroup
/dev/vda1                 1038336   381768   656568   37% /boot
/dev/vdb                103080888 35082384 62739240   36% /work
tmpfs                      797020       12   797008    1% /run/user/42
tmpfs                      797020        0   797020    0% /run/user/1002

可以看出本文结果精确度更高

Linux系统C语言遍历系统文件系统,并查询其磁盘使用率(有效磁盘)相关推荐

  1. c语言的学生理系统,C语言学习系统的教程

    完美者(wmzhe.com)网站以软件下载为基础,改版后的网站对功能性板块进行扩充,以期能够解决用户在软件使用过程中遇见的所有问题.网站新增了"软件百科"."锦囊妙技&q ...

  2. Linux系统查看CPU使用率、内存使用率、磁盘使用率、磁盘大小

    一.查看CPU使用率 1.top命令 在linux的系统维护中,可能需要经常查看cpu使用率,分析系统整体的运行情况.常用的查看CPU使用率命令为top命令. top命令是Linux下常用的性能分析工 ...

  3. c语言飞机订餐系统,C语言订餐系统.doc

    C语言订餐系统 课 程 设 计 说 明 书 课程名称:C语言程序设计 设计题目:电话订餐信息处理 院 系:计算机科学与信息工程学院 姓名学号: 专业班级: 指导教师: 课 程 设 计 任 务 书 设计 ...

  4. c语言报表系统,C语言考试系统程序设计报告.doc

    C语言考试系统程序设计报告 <程序设计基础> 课程设计报告 考试系统 指导教师:任姚鹏 班 级:计科系1204班 学生姓名:丁晓荟 加雪梅 姚乐 张进 吕亚斌 完成日期:2013.11.2 ...

  5. Linux下C语言的系统头文件

    Linux菜鸟初看Linux下编程的糗事. 前段时间琢磨着接触一下Linux下的C语言编程,就找了本书看.看到很多文件操作的程序要包含"sys/stat.h". 写程序前,我想先找 ...

  6. linux vim go语言,CentOS7系统基于Vim8搭建Go语言开发环境

    主要是在vim中通过vundle来安装vim-go插件.gocode插件,支持代码高亮.代码提示以及语法检查等功能 安装Golang 1.11.2 curl -Lo golang.tar.gz htt ...

  7. linux 使用 C 语言获得系统 MAC 地址

    2019独角兽企业重金招聘Python工程师标准>>> //google 到的 测试有效 #include <stdio.h> #include <sys/ioct ...

  8. 城市公交查询系统c语言,Android的城市公交查询系统

    随着国家大力发展公共交通,越来越多的人选择公交出行,如何才能快速准确地获得出行信息也成为了关注的问题.正在被大家使用的GPS和GIS等手段已经非常成熟,其中最主要的三大功能:站点查询,线路查询,公交换 ...

  9. linux 系统 Shell语言 基础

    linux 系统 Shell语言 基础 第一章 Shell 编程 1 . 概述 ​ Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Sh ...

最新文章

  1. excel数据透视表列名更改
  2. mysql gbk支持_mysql如何支持gbk编码
  3. C语言:内存的分配与管理
  4. code vs 集成tfs_关于编译器和集成开发环境,一文给你讲明白!
  5. 你一定要了解的NB-IoT !
  6. 描写火车站场景_关于描写火车站的句子
  7. python 爬虫是什么_“python爬虫“是什么呢?
  8. 递归列出文件下的文件信息,迭代器
  9. python十大实例_Python练习实例100例(从简入难)96-100
  10. unity怪物攻击玩家减血_怪物猎人发布15周年 — 回顾历代封面怪之三大传奇怪物...
  11. Rust 创始人谈 Rust 2019 和未来:社区应限制成长速度
  12. 常用计算机故障的判断方法有哪些,常用汽车故障基本诊断方法
  13. 查看显卡型号命令_ubuntu查看显卡型号方法有哪些
  14. 不同音乐格式之谜(wav,flac,ape,wv,tak,ogg,aac)
  15. 若菜光个人小档案(dambolo)
  16. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true
  17. How to install VIB on VMware ESXi
  18. Delphi对象克隆技术
  19. Java 关于java.util.LinkedHashMap cannot be cast to 实体类问题答案
  20. 【HTML+CSS】字体字号行高

热门文章

  1. java关键字:volatile
  2. Spring框架----Spring的IOC
  3. POJ 2762Going from u to v or from v to u?(强联通 + 缩点 + 拓扑排序)
  4. Python3 移动文件——合集
  5. css3-background clip 和background origin
  6. Spring-Security (学习记录二)--修改为自己的登录页面
  7. 黑马程序员—————— 随机访问流
  8. Ubuntu下 VirtualBox的卸载和升级 (转载)
  9. loadrunner 脚本优化-事务时间简介
  10. havlenapetr ffmpeg的移植