2024-05-23 18:12:04 +08:00
|
|
|
#include "disk.h"
|
|
|
|
|
2024-05-22 15:10:19 +08:00
|
|
|
|
|
|
|
// 获取指定路径的磁盘使用率
|
|
|
|
int get_disk_usage(const char *path, double *usage) {
|
|
|
|
struct statvfs stat;
|
|
|
|
|
|
|
|
if (statvfs(path, &stat) != 0) {
|
|
|
|
perror("statvfs failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 计算磁盘使用率
|
|
|
|
unsigned long total_blocks = stat.f_blocks;
|
|
|
|
unsigned long free_blocks = stat.f_bfree;
|
|
|
|
unsigned long used_blocks = total_blocks - free_blocks;
|
|
|
|
|
|
|
|
*usage = (double)used_blocks / total_blocks * 100;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-05-23 18:12:04 +08:00
|
|
|
|
|
|
|
|
|
|
|
// 第三方邮箱告警, 磁盘使用率
|
|
|
|
int QQ_mail_warning_Disk_Use(const char *recv_mail, const char *local_ip, const char *text, int current_length) {
|
|
|
|
|
|
|
|
int command_len = current_length + sizeof(QQMAIL_DISK_USE) + strlen(recv_mail) + strlen(local_ip) + 256;
|
|
|
|
char command[command_len];
|
|
|
|
|
|
|
|
// 生成邮件正文
|
|
|
|
char mail_text[command_len];
|
|
|
|
snprintf(mail_text, command_len, "Host:%s\n%s", local_ip, text);
|
|
|
|
|
|
|
|
// 生成命令字符串
|
|
|
|
snprintf(command, command_len, QQMAIL_DISK_USE, recv_mail, mail_text);
|
|
|
|
|
|
|
|
// 打印命令用于调试
|
|
|
|
printf("Command: %s %d\n", command, current_length);
|
|
|
|
|
|
|
|
// 执行命令
|
|
|
|
int ret = system(command);
|
|
|
|
if (ret == -1) {
|
|
|
|
perror("system command failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int disk_usage(conf *conf, char *local_ip, int threshold) {
|
2024-05-22 15:10:19 +08:00
|
|
|
FILE *mounts;
|
|
|
|
struct mntent *ent;
|
2024-05-23 18:12:04 +08:00
|
|
|
char *result;
|
|
|
|
size_t result_size = INITIAL_SIZE;
|
|
|
|
size_t current_length = 0;
|
|
|
|
|
|
|
|
result = (char *)malloc(result_size);
|
|
|
|
if (result == NULL) {
|
|
|
|
perror("内存分配失败");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
result[0] = '\0'; // 初始化为空字符串
|
2024-05-22 15:10:19 +08:00
|
|
|
|
2024-05-23 18:12:04 +08:00
|
|
|
// 打开挂载表
|
2024-05-22 15:10:19 +08:00
|
|
|
mounts = setmntent("/etc/mtab", "r");
|
|
|
|
if (mounts == NULL) {
|
2024-05-23 18:12:04 +08:00
|
|
|
perror("打开挂载表失败");
|
|
|
|
free(result);
|
2024-05-22 15:10:19 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-05-23 18:12:04 +08:00
|
|
|
// 遍历每个挂载的文件系统
|
|
|
|
while ((ent = getmntent(mounts)) != NULL) {
|
2024-05-22 15:10:19 +08:00
|
|
|
double usage = 0;
|
2024-05-23 18:12:04 +08:00
|
|
|
|
|
|
|
// 检查文件系统是否为设备
|
|
|
|
if (strstr(ent->mnt_fsname, "/dev/") != NULL) {
|
|
|
|
// 获取挂载点的磁盘使用率
|
2024-05-22 15:10:19 +08:00
|
|
|
if (get_disk_usage(ent->mnt_dir, &usage) != 0) {
|
2024-05-23 18:12:04 +08:00
|
|
|
fprintf(stderr, "获取 %s 的磁盘使用率失败\n", ent->mnt_dir);
|
2024-05-22 15:10:19 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-05-23 18:12:04 +08:00
|
|
|
// 如果使用率超过阈值则拼接字符串
|
|
|
|
if (usage > threshold) {
|
|
|
|
char buffer[BUFFER_INCREMENT];
|
|
|
|
int len = snprintf(buffer, BUFFER_INCREMENT, "挂载点:%s 使用率:%.2f%% 阀值:%d%%\n", ent->mnt_dir, usage, threshold);
|
|
|
|
|
|
|
|
// 检查缓冲区大小是否足够
|
|
|
|
if (current_length + len >= result_size) {
|
|
|
|
result_size += BUFFER_INCREMENT;
|
|
|
|
result = (char *)realloc(result, result_size);
|
|
|
|
if (result == NULL) {
|
|
|
|
perror("内存重新分配失败");
|
|
|
|
endmntent(mounts);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
strcat(result, buffer);
|
|
|
|
current_length += len;
|
2024-05-22 15:10:19 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-23 18:12:04 +08:00
|
|
|
// 发送邮件警告
|
|
|
|
if (current_length > 0) {
|
2024-05-28 11:08:55 +08:00
|
|
|
if (QQ_mail_warning_Disk_Use(conf->RECV_MAIL, local_ip, result, current_length) != 0) {
|
2024-05-23 18:12:04 +08:00
|
|
|
fprintf(stderr, "发送邮件失败\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 清理
|
|
|
|
free(result);
|
2024-05-22 15:10:19 +08:00
|
|
|
endmntent(mounts);
|
|
|
|
return 0;
|
|
|
|
}
|
2024-05-23 18:12:04 +08:00
|
|
|
|
|
|
|
|