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 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
| #include <sys/mount.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <mntent.h> #include <fnmatch.h>
/** * 批量卸载条目结构 */ typedef struct { char mountpoint[256]; char filesystem[32]; char device[256]; int selected_for_unmount; int unmount_result; char result_message[128]; } batch_unmount_entry_t;
/** * 批量卸载管理器结构 */ typedef struct { batch_unmount_entry_t entries[64]; int entry_count; int selected_count; int successful_count; int failed_count; } batch_unmount_manager_t;
/** * 初始化批量卸载管理器 */ void init_batch_unmount_manager(batch_unmount_manager_t *manager) { memset(manager, 0, sizeof(batch_unmount_manager_t)); printf("批量卸载管理器初始化完成\n"); }
/** * 从/proc/mounts加载挂载信息 */ int load_mount_entries(batch_unmount_manager_t *manager) { FILE *fp = setmntent("/proc/mounts", "r"); if (!fp) { printf("无法读取挂载信息: %s\n", strerror(errno)); return -1; } struct mntent *mnt; int count = 0; printf("加载挂载信息:\n"); while ((mnt = getmntent(fp)) != NULL && count < 64) { // 过滤系统挂载点 if (strncmp(mnt->mnt_dir, "/proc", 5) == 0 || strncmp(mnt->mnt_dir, "/sys", 4) == 0 || strncmp(mnt->mnt_dir, "/dev", 4) == 0) { continue; // 跳过系统挂载点 } batch_unmount_entry_t *entry = &manager->entries[count]; strncpy(entry->mountpoint, mnt->mnt_dir, sizeof(entry->mountpoint) - 1); entry->mountpoint[sizeof(entry->mountpoint) - 1] = '\0'; strncpy(entry->filesystem, mnt->mnt_type, sizeof(entry->filesystem) - 1); entry->filesystem[sizeof(entry->filesystem) - 1] = '\0'; strncpy(entry->device, mnt->mnt_fsname, sizeof(entry->device) - 1); entry->device[sizeof(entry->device) - 1] = '\0'; entry->selected_for_unmount = 0; entry->unmount_result = 0; entry->result_message[0] = '\0'; printf(" %s (%s on %s)\n", entry->mountpoint, entry->filesystem, entry->device); count++; } endmntent(fp); manager->entry_count = count; printf("共加载 %d 个挂载点\n", count); return 0; }
/** * 根据模式选择挂载点 */ int select_mountpoints_by_pattern(batch_unmount_manager_t *manager, const char *pattern) { int selected = 0; printf("根据模式选择挂载点: %s\n", pattern); for (int i = 0; i < manager->entry_count; i++) { batch_unmount_entry_t *entry = &manager->entries[i]; if (fnmatch(pattern, entry->mountpoint, 0) == 0) { entry->selected_for_unmount = 1; selected++; printf(" 选中: %s\n", entry->mountpoint); } } manager->selected_count = selected; printf("共选中 %d 个挂载点\n", selected); return selected; }
/** * 执行批量卸载 */ int execute_batch_unmount(batch_unmount_manager_t *manager, int flags) { printf("=== 执行批量卸载 ===\n"); printf("卸载标志: 0x%x\n", flags); printf("选中挂载点数量: %d\n", manager->selected_count); manager->successful_count = 0; manager->failed_count = 0; for (int i = 0; i < manager->entry_count; i++) { batch_unmount_entry_t *entry = &manager->entries[i]; if (!entry->selected_for_unmount) { continue; } printf("\n卸载 %s:\n", entry->mountpoint); // 执行卸载 int result = umount2(entry->mountpoint, flags); entry->unmount_result = result; if (result == 0) { printf(" ✓ 卸载成功\n"); manager->successful_count++; strncpy(entry->result_message, "成功", sizeof(entry->result_message) - 1); } else { printf(" ✗ 卸载失败: %s\n", strerror(errno)); manager->failed_count++; strncpy(entry->result_message, strerror(errno), sizeof(entry->result_message) - 1); entry->result_message[sizeof(entry->result_message) - 1] = '\0'; } } printf("\n=== 批量卸载结果 ===\n"); printf("成功: %d\n", manager->successful_count); printf("失败: %d\n", manager->failed_count); printf("总计: %d\n", manager->successful_count + manager->failed_count); // 显示详细结果 printf("\n详细结果:\n"); for (int i = 0; i < manager->entry_count; i++) { batch_unmount_entry_t *entry = &manager->entries[i]; if (entry->selected_for_unmount) { printf(" %s: %s (%s)\n", entry->mountpoint, entry->unmount_result == 0 ? "✓" : "✗", entry->result_message); } } return (manager->failed_count == 0) ? 0 : -1; }
/** * 显示批量卸载摘要 */ void show_batch_unmount_summary(const batch_unmount_manager_t *manager) { printf("=== 批量卸载摘要 ===\n"); printf("总挂载点数: %d\n", manager->entry_count); printf("选中卸载数: %d\n", manager->selected_count); printf("成功卸载数: %d\n", manager->successful_count); printf("失败卸载数: %d\n", manager->failed_count); printf("成功率: %.1f%%\n", manager->selected_count > 0 ? (double)manager->successful_count / manager->selected_count * 100 : 0); if (manager->failed_count > 0) { printf("\n失败详情:\n"); for (int i = 0; i < manager->entry_count; i++) { const batch_unmount_entry_t *entry = &manager->entries[i]; if (entry->selected_for_unmount && entry->unmount_result != 0) { printf(" %s: %s\n", entry->mountpoint, entry->result_message); } } } }
/** * 演示批量卸载管理器 */ int demo_batch_unmount_manager() { batch_unmount_manager_t manager; printf("=== 批量卸载管理器演示 ===\n"); // 初始化管理器 printf("1. 初始化批量卸载管理器:\n"); init_batch_unmount_manager(&manager); // 加载挂载信息 printf("\n2. 加载挂载信息:\n"); if (load_mount_entries(&manager) != 0) { printf("加载挂载信息失败\n"); return -1; } // 显示可用的卸载选项 printf("\n3. 可用挂载点:\n"); for (int i = 0; i < manager.entry_count && i < 10; i++) { const batch_unmount_entry_t *entry = &manager.entries[i]; printf(" %d. %s (%s)\n", i + 1, entry->mountpoint, entry->filesystem); } if (manager.entry_count > 10) { printf(" ... (还有 %d 个挂载点)\n", manager.entry_count - 10); } // 演示模式匹配选择 printf("\n4. 模式匹配选择演示:\n"); // 选择/tmp目录下的挂载点 select_mountpoints_by_pattern(&manager, "/tmp/*"); // 选择/media目录下的挂载点 select_mountpoints_by_pattern(&manager, "/media/*"); // 选择所有ext4文件系统 printf("\n根据文件系统类型选择:\n"); int ext4_selected = 0; for (int i = 0; i < manager.entry_count; i++) { batch_unmount_entry_t *entry = &manager.entries[i]; if (strcmp(entry->filesystem, "ext4") == 0) { entry->selected_for_unmount = 1; ext4_selected++; printf(" 选中ext4文件系统: %s\n", entry->mountpoint); } } printf("共选中 %d 个ext4文件系统\n", ext4_selected); // 显示选中结果 printf("\n5. 选中挂载点列表:\n"); for (int i = 0; i < manager.entry_count; i++) { const batch_unmount_entry_t *entry = &manager.entries[i]; if (entry->selected_for_unmount) { printf(" %s (%s on %s)\n", entry->mountpoint, entry->filesystem, entry->device); } } // 演示不同卸载模式 printf("\n6. 不同卸载模式演示:\n"); // 模式1:普通卸载 printf("模式1:普通卸载\n"); printf("注意:实际演示中跳过真实卸载操作以避免影响系统\n"); // 模式2:强制卸载 printf("\n模式2:强制卸载\n"); printf("卸载标志: MNT_FORCE (0x%x)\n", MNT_FORCE); // 模式3:延迟卸载 printf("\n模式3:延迟卸载\n"); printf("卸载标志: MNT_DETACH (0x%x)\n", MNT_DETACH); // 模式4:过期卸载 printf("\n模式4:过期卸载\n"); printf("卸载标志: MNT_EXPIRE (0x%x)\n", MNT_EXPIRE); // 显示批量卸载策略 printf("\n=== 批量卸载策略 ===\n"); printf("1. 选择策略:\n"); printf(" ✓ 支持通配符模式匹配\n"); printf(" ✓ 支持文件系统类型筛选\n"); printf(" ✓ 支持设备类型筛选\n"); printf(" ✓ 支持交互式选择\n"); printf("\n2. 卸载策略:\n"); printf(" ✓ 优先尝试普通卸载\n"); printf(" ✓ 失败后尝试强制卸载\n"); printf(" ✓ 最后考虑延迟卸载\n"); printf(" ✓ 支持批量重试机制\n"); printf("\n3. 错误处理:\n"); printf(" ✓ 详细记录每个卸载操作结果\n"); printf(" ✓ 提供失败原因分析\n"); printf(" ✓ 支持部分成功处理\n"); printf(" ✓ 生成卸载报告\n"); printf("\n4. 安全考虑:\n"); printf(" ✓ 避免卸载系统关键挂载点\n"); printf(" ✓ 检查挂载点使用状态\n"); printf(" ✓ 提供确认机制\n"); printf(" ✓ 支持回滚操作\n"); return 0; }
int main() { return demo_batch_unmount_manager(); }
|