Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

install: 'w' now ALWAYS wipes the target disk (not just merges into ESP)

Previous behavior: auto_install_to_hd's per-partition loop scanned p1..p16
for an existing FAT32, mounted the first one it found (e.g. Fedora's
/boot/efi at p1), and copied our boot tree alongside the existing
filesystem. If the ESP was too small, it reformatted JUST that partition
and left p2/p3/etc. (Fedora root, home, swap) intact.

User pressed 'w' expecting "wipe + install AC native OS"; what they got
was "merge AC bootloader into existing Fedora install." Install reported
"complete" and even worked from boot manager standpoint, but Fedora was
still on disk taking 90% of capacity.

Fix:
- The blank-disk pre-pass now runs UNCONDITIONALLY when targeting any
internal disk: force-unmount everything → dd zero first 16 MiB →
sfdisk single GPT ESP spanning the whole disk → kernel partition
reread → wait for p1. Whatever was on the disk is gone.
- Confirmation screen warning changed from "this will overwrite EFI
boot!" (misleading — implies only the ESP) to "ERASES ALL DATA on
internal disk" (truthful).
- TTS prompt updated to match.

Boot-time `w` is still gated behind the y/n confirm + only fires when
booted from removable media, so accidental triggering is unlikely. But
the data-loss warning is now what it actually does.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+36 -29
+36 -29
fedac/native/src/ac-native.c
··· 1193 1193 if (rem == 1) continue; // removable = USB 1194 1194 } 1195 1195 1196 - // Blank-disk pre-pass: if the parent disk node exists but it has 1197 - // ZERO partitions (truly blank — fresh SSD the user just plugged 1198 - // in), the per-partition loop below would skip it silently. Run 1199 - // sfdisk first to lay down a single GPT ESP, then fall through to 1200 - // the normal install path which will format + populate p1. 1196 + // Wipe-and-install pre-pass: ALWAYS repartition the candidate 1197 + // disk before installing (was: only blank disks). Boot-time `w` 1198 + // is meant to install fresh AC Native OS; if the user pressed it 1199 + // they expect Fedora / whatever was there to be REPLACED, not 1200 + // dual-booted. Previous behavior found existing ESPs (e.g. 1201 + // Fedora's /boot/efi) and added our boot tree alongside, leaving 1202 + // the rest of the disk intact — install reported "complete" but 1203 + // didn't actually wipe. 1204 + // 1205 + // Order: zero first 16 MiB → sfdisk single GPT ESP spanning the 1206 + // disk → kernel reread → wait for p1 to materialize → fall through 1207 + // to the per-partition loop, which will now find p1 (newly created, 1208 + // no fs yet) and use the rescue-mkfs path on pass 1 to format + 1209 + // populate it. 1201 1210 { 1202 1211 char parent_path[32]; 1203 1212 snprintf(parent_path, sizeof(parent_path), "/dev/%s", blk); ··· 1206 1215 snprintf(first_part, sizeof(first_part), "/dev/%sp1", blk); 1207 1216 else 1208 1217 snprintf(first_part, sizeof(first_part), "/dev/%s1", blk); 1209 - int parent_exists = (access(parent_path, F_OK) == 0); 1210 - int has_any_part = 0; 1211 - if (parent_exists) { 1212 - for (int p = 1; p <= 16 && !has_any_part; p++) { 1213 - char dp[32]; 1214 - if (blk[0] == 'n' || strncmp(blk, "mmcblk", 6) == 0) 1215 - snprintf(dp, sizeof(dp), "/dev/%sp%d", blk, p); 1216 - else 1217 - snprintf(dp, sizeof(dp), "/dev/%s%d", blk, p); 1218 - if (access(dp, F_OK) == 0) has_any_part = 1; 1219 - } 1220 - } 1221 - if (parent_exists && !has_any_part) { 1222 - ac_log("[install] %s is blank (no partitions) — running sfdisk\n", parent_path); 1223 - // Wipe first 16 MiB so any leftover signatures don't confuse sfdisk. 1218 + if (access(parent_path, F_OK) == 0) { 1219 + ac_log("[install] WIPE+INSTALL on %s (was: %s) — running sfdisk\n", 1220 + parent_path, 1221 + (access(first_part, F_OK) == 0) ? "had partitions, all replaced" : "blank disk"); 1222 + // Force-unmount everything on the target disk before we 1223 + // touch its partition table. Without this, the kernel 1224 + // would block sfdisk with EBUSY for the in-use partitions. 1225 + force_unmount_disk(blk, "/tmp/install-debug.log"); 1226 + sync(); 1227 + usleep(200000); 1228 + // Wipe first 16 MiB so any leftover GPT/MBR/FS signatures 1229 + // don't confuse sfdisk or the firmware on next boot. 1224 1230 char wcmd[256]; 1225 1231 snprintf(wcmd, sizeof(wcmd), 1226 1232 "dd if=/dev/zero of=%s bs=1M count=16 conv=fsync 2>&1 | head -3", ··· 1233 1239 "sfdisk --force --no-reread %s 2>&1", 1234 1240 parent_path); 1235 1241 int srrc = system(rcmd); 1236 - ac_log("[install] sfdisk on blank %s rc=%d\n", parent_path, srrc); 1242 + ac_log("[install] sfdisk on %s rc=%d\n", parent_path, srrc); 1237 1243 sync(); 1238 1244 usleep(500000); 1239 1245 blkrrpart_with_retry(parent_path, "/tmp/install-debug.log"); ··· 1242 1248 if (access(first_part, F_OK) == 0) break; 1243 1249 usleep(100000); 1244 1250 } 1245 - ac_log("[install] blank-disk: %s exists=%d after sfdisk\n", 1251 + ac_log("[install] wipe+install: %s exists=%d after sfdisk\n", 1246 1252 first_part, access(first_part, F_OK) == 0); 1247 - // Fall through — the per-partition loop below will now find 1248 - // p1 and the rescue-mkfs path will format it on pass 1. 1249 1253 } 1250 1254 } 1251 1255 ··· 2045 2049 struct timespec anim_time; 2046 2050 clock_gettime(CLOCK_MONOTONIC, &anim_time); 2047 2051 2048 - if (tts) tts_speak(tts, "install to disk? press Y for yes, N for no"); 2052 + if (tts) tts_speak(tts, "wipe and install AC native OS? this erases all data on the disk. press Y for yes, N for no"); 2049 2053 play_install_prompt_beep(audio); 2050 2054 2051 2055 for (;;) { ··· 2055 2059 uint8_t fg = is_dark ? 220 : 0; 2056 2060 graph_ink(graph, (ACColor){fg, fg, fg, 255}); 2057 2061 2058 - int tw = font_measure_matrix("install to disk?", 2); 2059 - font_draw_matrix(graph, "install to disk?", 2062 + int tw = font_measure_matrix("wipe + install?", 2); 2063 + font_draw_matrix(graph, "wipe + install?", 2060 2064 (screen->width - tw) / 2, screen->height / 2 - 24, 2); 2061 2065 2062 - // Warning text 2066 + // Warning text — be explicit. The previous warning said "overwrite 2067 + // EFI boot" which suggested only the ESP would change; the 2068 + // operation actually wipes the entire disk now (sfdisk single ESP 2069 + // spanning everything → kills Fedora root, swap, etc.). 2063 2070 graph_ink(graph, (ACColor){220, 80, 80, 255}); 2064 - const char *warn = "this will overwrite EFI boot!"; 2071 + const char *warn = "ERASES ALL DATA on internal disk"; 2065 2072 int ww = font_measure_matrix(warn, 1); 2066 2073 font_draw_matrix(graph, warn, (screen->width - ww) / 2, 2067 2074 screen->height / 2 + 2, 1);