fix: MINT-ZUSE says the stick was erased when it was (#168)

failed() printed "MINT-ZUSE: failed -- nothing changed" on every failure
after YES, though by then gpt_write_one() had rewritten the stick's partition
table and the identity partition's first blocks had been zeroed.

gpt_write_one() now tells the two apart: GPT_EIO when its first write failed
(nothing written), GPT_PART when a later write or flush failed (the disk is
changed). MINT-ZUSE keeps "failed -- nothing changed" for GPT_EIO only, and
says "failed -- the stick was erased; Zuse not minted" for every failure
after the table is written. The marker is still written last.

Tested first, seen to fail: qemu_session.py mint_part_fail (writes fail only
at the identity partition's first sector, LBA 2048) -- "nothing changed",
logs/20261112-122132. After: mint_part_fail PASS; mint_fail (every write
fails) still "nothing changed", PASS; replace (the success path) PASS. Their
logs here. FABRIC-3 XLVIII.20.

Captain Bob, 2026-11-12: "start #168".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
This commit is contained in:
Claude
2026-11-12 12:41:36 +00:00
parent 7e30b4525e
commit 54311be18a
21 changed files with 102 additions and 19 deletions
+4 -2
View File
@@ -352,14 +352,16 @@ int gpt_write_one(blkio_dev_t *disk, const uint8_t type[16], uint64_t part_secto
* partition not yet written -- a used stick's old table included */
{
static const uint8_t zero[GPT_SECTOR];
if (put_sectors(disk, 0u, zero, 1u) != 0 || disk->vt->flush(disk) != BLKIO_OK) return GPT_EIO;
if (put_sectors(disk, 0u, zero, 1u) != 0) return GPT_EIO; /* nothing written yet */
if (disk->vt->flush(disk) != BLKIO_OK) return GPT_PART; /* the MBR may be gone */
}
/* from here the disk is changed: any failure says so (#168) */
if (put_sectors(disk, alt - GPT_ENT_SECTORS, g_gpt_new_entries, GPT_ENT_SECTORS) != 0 ||
put_sectors(disk, alt, bak, 1u) != 0 ||
put_sectors(disk, 2u, g_gpt_new_entries, GPT_ENT_SECTORS) != 0 ||
put_sectors(disk, 1u, hdr, 1u) != 0 || disk->vt->flush(disk) != BLKIO_OK ||
put_sectors(disk, 0u, mbr, 1u) != 0 || disk->vt->flush(disk) != BLKIO_OK)
return GPT_EIO;
return GPT_PART;
return GPT_OK;
}
+20 -9
View File
@@ -11,7 +11,9 @@
* fresh Zuse minted into it, read back -- and only then the real key written
* into the genesis marker on the system stick's Artemis. Any failure before
* the marker leaves the marker as it was: the old Zuse stick, if there is
* one, still works.
* one, still works. A failure says what happened to the stick (#168): "nothing
* changed" only while nothing has been written to it; once its partition table
* is written, "the stick was erased".
*/
#include "starkernel/v4/sk_v4_mint.h"
#include "starkernel/v4/sk_v4_identity.h"
@@ -65,13 +67,20 @@ static int read_answer(char *buf, int max)
}
}
static int failed(void)
static int failed(void) /* nothing has been written to the stick */
{
console_println("MINT-ZUSE: failed -- nothing changed");
sk_v4_identity_release_offered();
return -1;
}
static int erased(void) /* its old partition table is gone (#168) */
{
console_println("MINT-ZUSE: failed -- the stick was erased; Zuse not minted");
sk_v4_identity_release_offered();
return -1;
}
int sk_v4_mint_zuse(void)
{
static blkio_dev_t part;
@@ -115,27 +124,29 @@ int sk_v4_mint_zuse(void)
sk_v4_identity_release_offered();
return -1;
}
if (rc != GPT_OK || gpt_read(raw, parts, 4u, &n) != GPT_OK) return failed();
if (rc == GPT_EIO) return failed(); /* its first write failed: nothing written */
if (rc != GPT_OK) return erased();
if (gpt_read(raw, parts, 4u, &n) != GPT_OK) return erased();
pi = gpt_find(parts, n, gpt_type_starship_identity);
if (pi < 0 || gpt_part_open(&part, &part_state, raw, &parts[pi]) != BLKIO_OK) return failed();
if (pi < 0 || gpt_part_open(&part, &part_state, raw, &parts[pi]) != BLKIO_OK) return erased();
/* nothing of the stick's old bytes may read as an identity */
for (i = 0; i < MINT_ZERO_FBLOCKS; i++)
if (blkio_write(&part, i, zero) != BLKIO_OK) return failed();
if (blkio_write(&part, i, zero) != BLKIO_OK) return erased();
/* Zuse, minted, then read back from the stick */
if (capsule_zuse_boot_genesis_mint(&part, seed, pub) != 0) return failed();
if (capsule_zuse_boot_genesis_mint(&part, seed, pub) != 0) return erased();
sig_rc = homeblocks_sig_check(&part, HOMEBLOCKS_SIG_START_FBLOCK, &sig);
if (capsule_zuse_boot_check_key(&part, sig_rc, &sig, pub, rseed, rpub) != ZUSE_DRIVE_HERS ||
memcmp(rseed, seed, 32) != 0)
return failed();
return erased();
/* only now the marker: the proxy kept, the real Zuse named */
m = *sk_v4_identity_marker();
if (!m.present) return failed();
if (!m.present) return erased();
memcpy(m.real, pub, 32);
m.has_real = 1;
if (sk_v4_marker_write(&m) != 0) return failed();
if (sk_v4_marker_write(&m) != 0) return erased();
sk_v4_identity_set_marker(&m);
memset(seed, 0, sizeof seed);
memset(rseed, 0, sizeof rseed);