fix(build): image checks cannot pass on a stale stick; mkartemis refuses bad numbers and reads its format back
Review of the stick's increment 3 (a4221d8b..c416c805), on Captain Bob's word: - check_images.sh deletes both images before building and makes each build a check: a failed build left last run's lithos-pc.img in place, and every stick check passed against it. - mkartemis takes --first-lba and --sectors as plain decimal numbers only: "abc", "-2", "2048x" and the like formatted at LBA 0, over the GPT. - mkartemis --format reopens the image read-only and reads the volume back: blk_commit_format ignores its own write errors, so a header that never landed was reported formatted. The header is read from the disk and judged as attach judges it (magic, version 2, BAM size); blk_get_volume_meta gives the in-memory geometry of a blank disk, magic included, so --check no longer relies on it either. check_images.sh keeps each case as a check (40, PASS). stick_boot and datastick on amd64/aarch64/riscv64 PASS on the rebuilt tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c416c805cb
commit
195b7feb07
+63
-17
@@ -115,6 +115,55 @@ static int usage(void)
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* A sector count: decimal digits only, the whole string, no overflow. */
|
||||
static int parse_count(const char *s, unsigned long long *out)
|
||||
{
|
||||
char *end;
|
||||
if (*s < '0' || *s > '9') return -1;
|
||||
errno = 0;
|
||||
*out = strtoull(s, &end, 10);
|
||||
return (errno != 0 || *end != '\0') ? -1 : 0;
|
||||
}
|
||||
|
||||
/* Put the partition into the block subsystem: its first LBN and user blocks. */
|
||||
static int attach(blkio_dev_t *dev, uint32_t *start_lbn, uint32_t *count)
|
||||
{
|
||||
if (blk_subsys_init(g_ram, sizeof(g_ram)) != BLK_OK || blk_subsys_attach_device(dev) != BLK_OK ||
|
||||
blk_get_device_range(dev, start_lbn, count) != BLK_OK) {
|
||||
fprintf(stderr, "mkartemis: the block subsystem would not take the partition\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The partition holds an STFR v2 volume and a good Artemis signature. The
|
||||
* header is read from the disk itself and judged as attach judges it
|
||||
* (block_subsystem.c blk_format_or_load_disk): blk_get_volume_meta would give
|
||||
* the geometry computed in memory for a blank disk, magic and all. */
|
||||
static int check_volume(blkio_dev_t *dev, uint32_t *count, artemis_sig_t *sig)
|
||||
{
|
||||
static uint8_t hdr[BLK_DEVICE_SECTOR];
|
||||
blk_volume_meta_t meta;
|
||||
artemis_sig_result_t src;
|
||||
uint32_t i;
|
||||
uint32_t start_lbn;
|
||||
int rc = -1;
|
||||
|
||||
if (attach(dev, &start_lbn, count) != 0) return -1;
|
||||
for (i = 0; i < BLK_DEVICE_SECTOR / BLKIO_FORTH_BLOCK_SIZE; i++)
|
||||
if (blkio_read(dev, i, hdr + i * BLKIO_FORTH_BLOCK_SIZE) != BLKIO_OK) memset(hdr, 0, sizeof(hdr));
|
||||
memset(&meta, 0, sizeof(meta));
|
||||
memcpy(&meta, hdr, sizeof(meta) < sizeof(hdr) ? sizeof(meta) : sizeof(hdr));
|
||||
if (meta.magic != 0x53544652u || meta.version != 2u || meta.bam_devblocks == 0u)
|
||||
fprintf(stderr, "mkartemis: no STFR v2 volume header\n");
|
||||
else if ((src = artemis_sig_check(dev, sig)) != ARTEMIS_SIG_OK)
|
||||
fprintf(stderr, "mkartemis: the Artemis signature does not check out (%d)\n", (int)src);
|
||||
else
|
||||
rc = 0;
|
||||
blk_subsys_shutdown();
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *mode, *img;
|
||||
@@ -132,8 +181,10 @@ int main(int argc, char **argv)
|
||||
if (strcmp(mode, "--format") == 0) format = 1;
|
||||
else if (strcmp(mode, "--check") == 0) format = 0;
|
||||
else return usage();
|
||||
first_lba = strtoull(argv[4], NULL, 10);
|
||||
sectors = strtoull(argv[6], NULL, 10);
|
||||
if (parse_count(argv[4], &first_lba) != 0 || parse_count(argv[6], §ors) != 0) {
|
||||
fprintf(stderr, "mkartemis: --first-lba and --sectors take a number of sectors\n");
|
||||
return 1;
|
||||
}
|
||||
if (first_lba % 2u != 0u || sectors % 2u != 0u || sectors == 0u || sectors / 2u > 0xFFFFFFFFull) {
|
||||
fprintf(stderr, "mkartemis: the partition must start and end on a 1 KiB block (even LBA and sector count)\n");
|
||||
return 1;
|
||||
@@ -150,13 +201,8 @@ int main(int argc, char **argv)
|
||||
if (blkio_open(&dev, &g_range_vt, ¶ms) != BLKIO_OK) { fprintf(stderr, "mkartemis: cannot open the range\n"); return 1; }
|
||||
|
||||
sf_time_init();
|
||||
if (blk_subsys_init(g_ram, sizeof(g_ram)) != BLK_OK || blk_subsys_attach_device(&dev) != BLK_OK ||
|
||||
blk_get_device_range(&dev, &start_lbn, &count) != BLK_OK) {
|
||||
fprintf(stderr, "mkartemis: the block subsystem would not take the partition\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (format) {
|
||||
if (attach(&dev, &start_lbn, &count) != 0) return 1;
|
||||
if (artemis_sig_check(&dev, &sig) != ARTEMIS_SIG_BLANK) {
|
||||
fprintf(stderr, "mkartemis: the partition is not blank -- not formatted\n");
|
||||
return 1;
|
||||
@@ -164,20 +210,20 @@ int main(int argc, char **argv)
|
||||
if (blk_subsys_confirm_format(start_lbn) != BLK_OK) { fprintf(stderr, "mkartemis: format failed\n"); return 1; }
|
||||
blk_subsys_shutdown();
|
||||
if (artemis_sig_genesis_stamp(&dev) != 0) { fprintf(stderr, "mkartemis: the signature stamp failed\n"); return 1; }
|
||||
printf("mkartemis: formatted %u blocks, STFR v2, signature stamped\n", r.blocks);
|
||||
} else {
|
||||
blk_volume_meta_t meta;
|
||||
artemis_sig_result_t src;
|
||||
if (blk_get_volume_meta(&meta) != BLK_OK || meta.magic != 0x53544652u || meta.version != 2u) {
|
||||
fprintf(stderr, "mkartemis: no STFR v2 volume header\n");
|
||||
/* blk_commit_format does not report a failed write: read the volume back, read-only */
|
||||
close(r.fd);
|
||||
r.fd = open(img, O_RDONLY);
|
||||
r.read_only = 1;
|
||||
if (r.fd < 0 || check_volume(&dev, &count, &sig) != 0) {
|
||||
fprintf(stderr, "mkartemis: the format did not read back -- the partition is not usable\n");
|
||||
return 1;
|
||||
}
|
||||
src = artemis_sig_check(&dev, &sig);
|
||||
if (src != ARTEMIS_SIG_OK) { fprintf(stderr, "mkartemis: the Artemis signature does not check out (%d)\n", (int)src); return 1; }
|
||||
printf("mkartemis: formatted %u blocks, STFR v2, signature stamped, read back ok\n", r.blocks);
|
||||
} else {
|
||||
if (check_volume(&dev, &count, &sig) != 0) return 1;
|
||||
printf("mkartemis: STFR v2, %u user blocks, signature ok, disk_uuid ", count);
|
||||
for (i = 0; i < 16; i++) printf("%02x", sig.disk_uuid[i]);
|
||||
printf("\n");
|
||||
blk_subsys_shutdown();
|
||||
}
|
||||
close(r.fd);
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user