目录
一、实现原理
在Linux系统中,操作系统屏蔽了用户直接访问系统内核,提供了LKM机制间接在内核空间工作,在LKM机制中一个重要的组成部分就是proc伪文件系统,它为用户提供了动态操作Linux内核信息的接口。linux各个磁盘数据信息通过df命令进行访问获取,例如(本文在win10-VMware下安装的centos7虚拟机测试命令):
[py@pyfree disk_info_test]$ df
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/mapper/cl-root 17811456 8651408 9160048 49% /
devtmpfs 917796 0 917796 0% /dev
tmpfs 933644 84 933560 1% /dev/shm
tmpfs 933644 9160 924484 1% /run
tmpfs 933644 0 933644 0% /sys/fs/cgroup
/dev/sda1 1038336 176556 861780 18% /boot
.host:/ 962138108 850708448 111429660 89% /mnt/hgfs
tmpfs 186732 16 186716 1% /run/user/42
tmpfs 186732 0 186732 0% /run/user/1000
[py@pyfree disk_info_test]$
c/c++读取磁盘数据信息,就是打开“df”命令管道文件句柄,识别该文件内容格式及字段描述,从中读取到需要的数据信息。
二、代码实现
工程设计
disk_info_test
bin
src
disk.h
disk.cpp
main.cpp
Makefile
disk.h,定义磁盘项信息结构体,通过popen打开“df”命令管道文件句柄获取各个磁盘项目数据信息
#ifndef _DISK_INFO_H_
#define _DISK_INFO_H_
/**********************************************************************************
*Copyright 2020-09-28, pyfree
*
*File Name : disk.h
*File Mark :
*Summary :
*
*Current Version : 1.00
*Author : pyfree
*FinishDate :
*
*Replace Version :
*Author :
*FinishDate :
***********************************************************************************/
#include <inttypes.h>
#include <vector>
typedef struct {
char diskName[64];
uint32_t diskTotal;
uint32_t diskUse;
uint32_t diskUsePer;
}DiskItem;
typedef struct {
DiskItem allItem;
std::vector<DiskItem> items;
}DiskInfo;
int GetDiskInfo(DiskInfo *diskPtr);
#endif //_DISK_INFO_H_
disk.cpp
#include "disk.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#define CMD "df -P -l -x iso9660 -x iso9600 | awk \'{if(NR!=1 && NF==6) print $2\" \"$3\" \"$6 }\'"
int GetDiskInfo(DiskInfo *diskPtr)
{
FILE *fp = popen(CMD, "r");
if(fp == NULL) {
return -1;
}
diskPtr->allItem = {0};
memcpy(diskPtr->allItem.diskName, "total", 6);
DiskItem item = {0};
while( fscanf(fp, "%" PRIu64" %" PRIu64" %s", &item.diskTotal, &item.diskUse, item.diskName) == 3) {
item.diskUsePer = ceil(item.diskUse*100.0/item.diskTotal);
diskPtr->items.push_back(item);
//
diskPtr->allItem.diskTotal += item.diskTotal;
diskPtr->allItem.diskUse += item.diskUse;
if(item.diskUsePer > diskPtr->allItem.diskUsePer){
diskPtr->allItem.diskUsePer = item.diskUsePer;
}
}
pclose(fp);
return 0;
}
main.cpp,按需读取磁盘数据并打印输出显示
#include "disk.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
DiskInfo disk_;
GetDiskInfo(&disk_);
printf("%s: %" PRIu32" %" PRIu32" %" PRIu32"%\n",
disk_.allItem.diskName, disk_.allItem.diskTotal,
disk_.allItem.diskUse, disk_.allItem.diskUsePer);
for(int i=0; i<disk_.items.size(); i++)
{
printf("%s: %" PRIu32" %" PRIu32" %" PRIu32"%\n",
disk_.items.at(i).diskName, disk_.items.at(i).diskTotal,
disk_.items.at(i).diskUse, disk_.items.at(i).diskUsePer);
}
return 0;
}
三、编译
Makefile
#/bin/sh
CX= g++
BIN := ./bin
TARGET := disk_test.bin
FLAGS := -std=c++11
#-static
SRCDIR := ./src
#INCLUDES
INCLUDEDIR := -I"$(SRCDIR)"
source := $(wildcard $(SRCDIR)/*.cpp)
$(TARGET) :
$(CX) $(FLAGS) $(INCLUDEDIR) $(source) -o $(BIN)/$(TARGET)
clean:
rm $(BIN)/$(TARGET)
编译及输出结果(cd disk_info_test && make && ./bin/disk_test.bin):
[py@pyfree disk_info_test]$ make
g++ -std=c++11 -I"./src" ./src/disk.cpp ./src/main.cpp -o ./bin/disk_test.bin
[py@pyfree disk_info_test]$ ./bin/disk_test.bin
total: 22941984 8837724 49%
/: 17811456 8651908 49%
/dev: 917796 0 0%
/dev/shm: 933644 84 1%
/run: 933644 9160 1%
/sys/fs/cgroup: 933644 0 0%
/boot: 1038336 176556 18%
/run/user/42: 186732 16 1%
/run/user/1000: 186732 0 0%
[py@pyfree disk_info_test]$