§H.12 steps 5-6: pin Hera/Hermes/Artemis in generic capsule-birth admission
capsule_birth.c's generic admission block now registers a session for every born VM (session_register) and pins it (session_set_pinned) when the birthing capsule is Hera/Hermes/Artemis. Bug found and fixed via a temporary probe (written, run, captured, reverted): the fleet-foundation name check first used an exact-match comparison against "Hermes"/"Artemis", but capsule_name is actually "hermes:init.4th"/"artemis:init.4th" (the real namespace:filename convention) -- the check silently never matched, both would-be-pinned VMs stayed unpinned. Fixed with a new vm_name_prefix_eq_nocase() helper matching everything before a literal ':'. Probe confirmed pinned=0 before the fix, pinned=1 after, on all relevant VMs. Session.parent is hardcoded to vm_uuid_hera() for now (every birth through this path is Hera-initiated today); step 7 generalizes this to the actual birthing VM's own id. Verified 3-arch boot to ok> (amd64/aarch64/riscv64) on the final, probe-free code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
67793ea4a1
commit
09998af999
@@ -34,6 +34,7 @@
|
||||
#include "starkernel/kmalloc.h"
|
||||
#include "starkernel/console.h"
|
||||
#include "starkernel/vm/stadium.h" /* item 4.1a -- stadium_grant_quota() */
|
||||
#include "starkernel/session.h" /* session_register()/session_set_pinned() -- FABRIC-3.md §H.12 step 5 */
|
||||
#include "vm.h"
|
||||
#include "platform_alloc.h"
|
||||
/* No LOG_LINE_MAX include-order constraint anymore: vm.h's own
|
||||
@@ -259,6 +260,21 @@ static int vm_name_eq_nocase(const char *a, const char *b) {
|
||||
return *a == *b;
|
||||
}
|
||||
|
||||
/* Case-insensitive ASCII prefix match up to (and not including) a literal
|
||||
* ':' in `str`, or the whole of `str` if it has no ':' -- capsule names use
|
||||
* a "namespace:filename" convention (e.g. "hermes:init.4th"), confirmed
|
||||
* live via a temporary probe (§H.12 step 6) rather than assumed: bare
|
||||
* vm_name_eq_nocase(capsule_name, "Hermes") never matched. `prefix` has no
|
||||
* ':' of its own. */
|
||||
static int vm_name_prefix_eq_nocase(const char *str, const char *prefix) {
|
||||
while (*str && *str != ':' && *prefix) {
|
||||
if (vm_to_lower(*str) != vm_to_lower(*prefix)) return 0;
|
||||
str++; prefix++;
|
||||
}
|
||||
if (*prefix) return 0; /* prefix longer than str's namespace segment */
|
||||
return (*str == '\0' || *str == ':');
|
||||
}
|
||||
|
||||
int capsule_vm_find_by_name_nocase(const char *name, VMRegistryEntry *out) {
|
||||
vm_node_t *node;
|
||||
if (!name || !out) return -1;
|
||||
@@ -572,22 +588,41 @@ CapsuleRunResult capsule_birth_baby(
|
||||
|
||||
/* FABRIC-3.md SS B, VM-COOL: admit this VM as a patron of its own
|
||||
* quota -- identity 0 (same convention stadium_birth_hera() uses for
|
||||
* "patron zero"), heat 0 (no reservoir cost), unpinned (unlike Hera --
|
||||
* there is no unpin primitive, and pinning here would make the
|
||||
* explicit KILL-time eviction below unreachable without adding one).
|
||||
* Unpinned means unrelated quota pressure on this VM's own words/
|
||||
* blocks could naturally evict this cell before KILL ever runs; that
|
||||
* is tolerated, not a bug -- nothing wires COOL's dispatch body to
|
||||
* kill anything, so the only visible effect is entry->stadium_
|
||||
* patron_cell going stale, which the KILL-time eviction below already
|
||||
* tolerates (stadium_evict() simply refuses if it's already gone).
|
||||
* "patron zero"), heat 0 (no reservoir cost). Admitted unpinned here
|
||||
* regardless of which VM this is -- pinning (when it applies) happens
|
||||
* through session_set_pinned() below, after admission, same
|
||||
* unpinned-then-pin ordering §H.12 step 4 already established for
|
||||
* Hera (stadium_admit() has no admission-time-special pin handling,
|
||||
* just copies the candidate header, so this ordering is safe).
|
||||
*
|
||||
* FABRIC-3.md §H.12 step 5: fleet-foundation VMs (Hera/Hermes/Artemis)
|
||||
* are pinned -- permanent, exempt from COOL, per §H.1's decision.
|
||||
* Ordinary/user VMs stay unpinned, matching the original comment's own
|
||||
* reasoning here (unrelated quota pressure can naturally evict this
|
||||
* cell before an explicit KILL runs; tolerated, not a bug -- nothing
|
||||
* wires COOL's dispatch body to kill anything, so the only visible
|
||||
* effect is entry->stadium_patron_cell going stale, which the
|
||||
* KILL-time eviction below already tolerates). The original comment's
|
||||
* "there is no unpin primitive" concern no longer applies to Hera
|
||||
* herself (session_set_pinned() now provides one, §H.12 step 3) but
|
||||
* still correctly describes why ordinary VMs -- which DO get killed --
|
||||
* must stay unpinned: nothing here ever un-pins a killed ordinary VM,
|
||||
* so it must never have been pinned to begin with.
|
||||
*
|
||||
* Soft failure, same as stadium_grant_quota() above -- a refused
|
||||
* admission leaves stadium_patron_cell at STADIUM_CELL_NONE, and
|
||||
* nothing downstream depends on it succeeding. */
|
||||
* nothing downstream depends on it succeeding. session_register()/
|
||||
* session_set_pinned() failures are soft-fail the same way (logged,
|
||||
* non-fatal) -- same reasoning §H.12 step 4 already established for
|
||||
* Hera. */
|
||||
{
|
||||
StadiumPatronHeader vm_patron;
|
||||
uint8_t *raw = (uint8_t *)&vm_patron;
|
||||
size_t i;
|
||||
int is_fleet_foundation =
|
||||
vm_name_prefix_eq_nocase(capsule_name, "Hera") ||
|
||||
vm_name_prefix_eq_nocase(capsule_name, "Hermes") ||
|
||||
vm_name_prefix_eq_nocase(capsule_name, "Artemis");
|
||||
|
||||
for (i = 0; i < sizeof(vm_patron); i++) raw[i] = 0;
|
||||
vm_patron.identity = 0;
|
||||
@@ -600,6 +635,14 @@ CapsuleRunResult capsule_birth_baby(
|
||||
vm_patron.behaviour = (uint8_t)STADIUM_BEHAVIOUR_COOL;
|
||||
|
||||
entry->stadium_patron_cell = stadium_admit(vm_id, &vm_patron);
|
||||
|
||||
if (entry->stadium_patron_cell != STADIUM_CELL_NONE) {
|
||||
Session *s = session_register(vm_id, vm_uuid_hera(), capsule_name);
|
||||
if (s) {
|
||||
s->stadium_cell = entry->stadium_patron_cell;
|
||||
if (is_fleet_foundation) session_set_pinned(vm_id, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t *payload = capsule_get_payload(cap, arena);
|
||||
|
||||
Reference in New Issue
Block a user