使用接口statfs
函数接口:
int statfs(const charpath, struct statfsbuf);
参数:
path: 位于需要查询信息的文件系统的文件路径
buf: statfs结构体类型的指针变量,用于存储文件系统的相关信息
statfs 结构体:
struct statfs{
long f_type; //文件系统的类型
long f_bsize; //经优化后的传输块的大小
long f_blocks; //文件系统数据块总数
long f_bfree; //可用块数
long f_bavail; //普通用户能够获得的块数
long f_files; //文件结点总数
long f_ffree; //可用文件结点数
fisd_t f_fsid; //文件系统标识
long f_namelen; //文件名的最大长度
}
Tips:
f_bfree VS f_bavail 区别:
f_bfree 是 硬盘所有剩余空间
f_bavail 是 非root用户剩余空间, 一般ext3文件系统会给root留5%的独享空间
zabbix 源码:
static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *free,
zbx_uint64_t *used, double *pfree, double *pused, char **error)
{
#ifdef HAVE_SYS_STATVFS_H
# define ZBX_STATFS statvfs
# define ZBX_BSIZE f_frsize
#else
# define ZBX_STATFS statfs
# define ZBX_BSIZE f_bsize
#endif
struct ZBX_STATFS s;
if (NULL == fs || '\0' == *fs)
{
*error = zbx_strdup(NULL, "Filesystem name cannot be empty.");
zabbix_log(LOG_LEVEL_DEBUG,"%s failed with error: %s",__func__, *error);
return SYSINFO_RET_FAIL;
}
if (0 != ZBX_STATFS(fs, &s))
{
*error = zbx_dsprintf(NULL, "Cannot obtain filesystem information: %s", zbx_strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG,"%s failed with error: %s",__func__, *error);
return SYSINFO_RET_FAIL;
}
/* Available space could be negative (top bit set) if we hit disk space */
/* reserved for non-privileged users. Treat it as 0. */
if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail))
s.f_bavail = 0;
//磁盘整体空间字节数, f_blocks * f_bsize
if (NULL != total)
*total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE;
// 用户级空闲空间的大小, f_bavail * f_bsize
if (NULL != free)
*free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE;
//已使用空间大小: (f_blocks - f_bfree)* f_bsize
if (NULL != used)
*used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE;
//可用百分比
if (NULL != pfree)
{
if (0 != s.f_blocks - s.f_bfree + s.f_bavail)
*pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail);
else
*pfree = 0;
}
//已用百分比
if (NULL != pused)
{
if (0 != s.f_blocks - s.f_bfree + s.f_bavail)
*pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail);
else
*pused = 0;
}
return SYSINFO_RET_OK;
}
Linux平台下使用 df -h / 验证磁盘实际使用情况
需要注意的是, df 命令获得的是整数百分比,没有小数,使用的是进一法,而不是四舍五入法。