Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

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

fix(native): skip repartition when ESP already large enough

On ThinkPad, sfdisk successfully wrote a 1GB GPT partition on the first
install attempt, but mkfs failed with EBUSY. Every subsequent boot, the
kernel loads the correct 1GB partition table but the code repartitions
again (hitting the same EBUSY). Now we check the partition size via
BLKGETSIZE64 first — if it's already large enough, we skip sfdisk
entirely and go straight to unmount + BLKFLSBUF + mkfs.

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

+92
+92
fedac/native/src/ac-native.c
··· 1206 1206 (long)((install_bytes + (1048576 - 1)) / 1048576), free_mb, devpath); 1207 1207 if (install_bytes > 0 && free_bytes < install_bytes + 10LL * 1048576LL) { 1208 1208 ac_log("[install] NOT ENOUGH SPACE — need %ldMB, have %ldMB\n", need_mb, free_mb); 1209 + // Check the PARTITION SIZE (not free space). If a previous 1210 + // sfdisk already expanded it to 1024MB but mkfs failed, the 1211 + // partition is big enough — we just need to unmount + reformat, 1212 + // no repartitioning needed (which avoids the EBUSY nightmare). 1213 + long long part_size_bytes = 0; 1214 + { 1215 + int pfd = open(devpath, O_RDONLY | O_CLOEXEC); 1216 + if (pfd >= 0) { 1217 + unsigned long long sz = 0; 1218 + if (ioctl(pfd, BLKGETSIZE64, &sz) == 0) 1219 + part_size_bytes = (long long)sz; 1220 + close(pfd); 1221 + } 1222 + } 1223 + long part_mb = (long)(part_size_bytes / 1048576LL); 1224 + ac_log("[install] partition %s size=%ldMB (need %ldMB)\n", devpath, part_mb, need_mb); 1225 + 1226 + if (part_mb >= need_mb) { 1227 + // Partition already large enough — just unmount + reformat 1228 + ac_log("[install] partition big enough, skip repartition → direct reformat\n"); 1229 + umount("/tmp/hd"); 1230 + umount2("/tmp/hd", MNT_DETACH); 1231 + // Unmount all mounts on this disk 1232 + char parent_blk_tmp[32] = ""; 1233 + { 1234 + const char *d = devpath + 5; 1235 + strncpy(parent_blk_tmp, d, sizeof(parent_blk_tmp) - 1); 1236 + char *pp = strstr(parent_blk_tmp, "p"); 1237 + if (pp && pp > parent_blk_tmp && *(pp-1) >= '0' && *(pp-1) <= '9' && *(pp+1) >= '1' && *(pp+1) <= '9') 1238 + *pp = 0; 1239 + else { 1240 + int len = strlen(parent_blk_tmp); 1241 + while (len > 0 && parent_blk_tmp[len-1] >= '0' && parent_blk_tmp[len-1] <= '9') len--; 1242 + parent_blk_tmp[len] = 0; 1243 + } 1244 + } 1245 + const char *DLOG = "/tmp/install-debug.log"; 1246 + FILE *__dl = fopen(DLOG, "w"); 1247 + if (__dl) { fprintf(__dl, "=== direct-reformat (no repartition) ===\n"); fclose(__dl); } 1248 + force_unmount_disk(parent_blk_tmp, DLOG); 1249 + sync(); 1250 + // Flush block device cache 1251 + { 1252 + int pfd = open(devpath, O_RDONLY | O_CLOEXEC); 1253 + if (pfd >= 0) { ioctl(pfd, BLKFLSBUF); close(pfd); } 1254 + char dd[64]; 1255 + snprintf(dd, sizeof(dd), "/dev/%s", parent_blk_tmp); 1256 + int dfd = open(dd, O_RDONLY | O_CLOEXEC); 1257 + if (dfd >= 0) { ioctl(dfd, BLKFLSBUF); close(dfd); } 1258 + } 1259 + system("echo 3 > /proc/sys/vm/drop_caches 2>/dev/null || true"); 1260 + sync(); 1261 + usleep(2000000); 1262 + // Format directly 1263 + char rcmd[512]; 1264 + const char *MKFS_ERR = "/tmp/mkfs-err.log"; 1265 + int mkfs_exit = -1; 1266 + for (int mkfs_try = 1; mkfs_try <= 5 && mkfs_exit != 0; mkfs_try++) { 1267 + if (mkfs_try > 1) { 1268 + int pfd = open(devpath, O_RDONLY | O_CLOEXEC); 1269 + if (pfd >= 0) { ioctl(pfd, BLKFLSBUF); close(pfd); } 1270 + system("echo 3 > /proc/sys/vm/drop_caches 2>/dev/null || true"); 1271 + sync(); 1272 + usleep(3000000); 1273 + } 1274 + snprintf(rcmd, sizeof(rcmd), 1275 + "echo '--- mkfs attempt %d ---' >> %s; " 1276 + "(mkfs.vfat -F 32 -n AC-NATIVE %s > %s 2>&1; rc=$?; " 1277 + "cat %s >> %s; exit $rc)", 1278 + mkfs_try, DLOG, devpath, MKFS_ERR, MKFS_ERR, DLOG); 1279 + int rrc = system(rcmd); 1280 + mkfs_exit = WIFEXITED(rrc) ? WEXITSTATUS(rrc) : -1; 1281 + ac_log("[install] direct mkfs rc=%d attempt=%d\n", rrc, mkfs_try); 1282 + FILE *mf = fopen(MKFS_ERR, "r"); 1283 + if (mf) { 1284 + char line[512]; 1285 + while (fgets(line, sizeof(line), mf)) { 1286 + size_t len = strlen(line); 1287 + if (len > 0 && line[len-1] == '\n') line[len-1] = '\0'; 1288 + ac_log("[mkfs/%d] %s\n", mkfs_try, line); 1289 + } 1290 + fclose(mf); 1291 + } 1292 + } 1293 + if (mkfs_exit == 0) { 1294 + ac_log("[install] direct reformat succeeded\n"); 1295 + goto install_copy_phase; 1296 + } 1297 + ac_log("[install] direct reformat failed, falling through to repartition\n"); 1298 + } 1299 + 1209 1300 // Repartition: expand ESP to 1024MB 1210 1301 char parent_blk[32] = ""; 1211 1302 // Extract parent device: /dev/nvme0n1p1 → nvme0n1, /dev/sda1 → sda ··· 1475 1566 } 1476 1567 usleep(500000); 1477 1568 // Remount and retry 1569 + install_copy_phase: 1478 1570 if (mount(devpath, "/tmp/hd", "vfat", 0, NULL) != 0) { 1479 1571 ac_log("[install] remount failed after repartition\n"); 1480 1572 snprintf(install_fail_reason, sizeof(install_fail_reason),