1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
| #include <sys/swap.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <getopt.h>
/** * 交换空间条目结构 */ typedef struct { char path[256]; long size_kb; long used_kb; int priority; char type[32]; } swap_entry_t;
/** * 解析交换空间信息 */ int parse_swap_info(swap_entry_t *entries, int max_entries) { FILE *fp; char line[512]; int count = 0; fp = fopen("/proc/swaps", "r"); if (!fp) { return -1; } // 跳过标题行 fgets(line, sizeof(line), fp); while (fgets(line, sizeof(line), fp) && count < max_entries) { char *token; char *saveptr; int field = 0; token = strtok_r(line, " \t\n", &saveptr); while (token && field < 5) { switch (field) { case 0: // Filename strncpy(entries[count].path, token, sizeof(entries[count].path) - 1); entries[count].path[sizeof(entries[count].path) - 1] = '\0'; break; case 1: // Type strncpy(entries[count].type, token, sizeof(entries[count].type) - 1); entries[count].type[sizeof(entries[count].type) - 1] = '\0'; break; case 2: // Size entries[count].size_kb = atol(token); break; case 3: // Used entries[count].used_kb = atol(token); break; case 4: // Priority entries[count].priority = atoi(token); break; } token = strtok_r(NULL, " \t\n", &saveptr); field++; } if (field >= 4) { count++; } } fclose(fp); return count; }
/** * 显示详细的交换空间信息 */ void show_detailed_swap_info() { swap_entry_t entries[32]; int count = parse_swap_info(entries, 32); printf("=== 详细交换空间信息 ===\n"); if (count <= 0) { printf("没有活动的交换空间\n"); return; } printf("%-20s %-10s %-12s %-12s %-10s %-8s\n", "路径", "类型", "大小(MB)", "已用(MB)", "可用(MB)", "优先级"); printf("%-20s %-10s %-12s %-12s %-10s %-8s\n", "----", "----", "--------", "--------", "--------", "------"); long total_size = 0, total_used = 0; for (int i = 0; i < count; i++) { double size_mb = entries[i].size_kb / 1024.0; double used_mb = entries[i].used_kb / 1024.0; double free_mb = (entries[i].size_kb - entries[i].used_kb) / 1024.0; printf("%-20s %-10s %-12.1f %-12.1f %-10.1f %-8d\n", entries[i].path, entries[i].type, size_mb, used_mb, free_mb, entries[i].priority); total_size += entries[i].size_kb; total_used += entries[i].used_kb; } printf("\n总计:\n"); printf(" 总大小: %.1f MB\n", total_size / 1024.0); printf(" 已使用: %.1f MB\n", total_used / 1024.0); printf(" 可用: %.1f MB\n", (total_size - total_used) / 1024.0); printf(" 使用率: %.1f%%\n", total_size > 0 ? (total_used * 100.0 / total_size) : 0.0); }
/** * 交换空间管理工具 */ int demo_swap_management_tool() { const char *test_swap_file = "/tmp/swap_management_test"; uid_t uid = getuid(); printf("=== 交换空间管理工具演示 ===\n"); // 权限检查 printf("权限检查:\n"); printf(" 当前用户ID: %d\n", uid); if (uid == 0) { printf(" ✓ 具有root权限\n"); } else { printf(" ✗ 没有root权限,部分功能将受限\n"); } // 显示当前交换空间状态 printf("\n1. 当前交换空间状态:\n"); show_detailed_swap_info(); // 如果有root权限,演示创建和管理交换文件 if (uid == 0) { printf("\n2. 创建测试交换文件:\n"); // 创建小的交换文件用于测试 int fd = open(test_swap_file, O_CREAT | O_WRONLY | O_TRUNC, 0600); if (fd != -1) { // 设置文件大小为32MB if (ftruncate(fd, 32 * 1024 * 1024) == 0) { close(fd); // 创建交换空间 char cmd[256]; snprintf(cmd, sizeof(cmd), "mkswap %s >/dev/null 2>&1", test_swap_file); if (system(cmd) == 0) { printf(" ✓ 创建交换文件成功: %s\n", test_swap_file); // 启用交换文件 printf("3. 启用交换文件:\n"); int result = swapon(test_swap_file, 0); if (result == 0) { printf(" ✓ 交换文件启用成功\n"); show_detailed_swap_info(); // 禁用交换文件 printf("\n4. 禁用交换文件:\n"); result = swapoff(test_swap_file); if (result == 0) { printf(" ✓ 交换文件禁用成功\n"); } else { printf(" ✗ 交换文件禁用失败: %s\n", strerror(errno)); } } else { printf(" ✗ 交换文件启用失败: %s\n", strerror(errno)); } } else { printf(" ✗ 初始化交换空间失败\n"); } } else { perror(" 设置文件大小失败"); close(fd); } // 清理测试文件 unlink(test_swap_file); } else { perror(" 创建交换文件失败"); } } // 显示交换空间管理建议 printf("\n=== 交换空间管理建议 ===\n"); printf("1. 交换空间大小:\n"); printf(" - 物理内存 < 2GB: 交换空间 = 物理内存 × 2\n"); printf(" - 物理内存 2-8GB: 交换空间 = 物理内存\n"); printf(" - 物理内存 > 8GB: 交换空间 = 4-8GB\n"); printf("\n2. 交换空间类型:\n"); printf(" - 交换分区: 性能更好,推荐用于生产环境\n"); printf(" - 交换文件: 灵活性更好,便于管理\n"); printf("\n3. 优先级设置:\n"); printf(" - 高速设备设置高优先级\n"); printf(" - SSD交换空间优先级高于HDD\n"); printf("\n4. 监控和维护:\n"); printf(" - 定期检查交换空间使用情况\n"); printf(" - 避免交换空间使用率过高\n"); printf(" - 及时清理不需要的交换文件\n"); return 0; }
int main() { return demo_swap_management_tool(); }
|