forked from Manuel/meeting-assistant
diagnose native Recovery disk IPC with bounded observation
This commit is contained in:
@@ -69,7 +69,7 @@ static class NativeDiagnostic
|
||||
await PrepareSource(Path.GetFullPath(source), output, "validation", false, Option(args, "--cryptex-archive"), CancellationToken.None);
|
||||
await ValidateResourceRetention(output);
|
||||
await ValidateRecoveryPatch(output);
|
||||
Save(Path.Combine(output, "validation.json"), new { success = true, profile = "kvm-host-ventura-cryptex", helperSha256 = Hash(File.ReadAllBytes(Path.Combine("tools", "ci", "MacOsNativeDiagnostic.cs"))), udifChecksumBindingSha256 = Hash(File.ReadAllBytes(Path.Combine("tools", "ci", "macos-native-udif-checksums.py"))), baselineReadinessNormalized = true, resultNegativeCases = 6, containerNegativeCases = 11, recoveryPositiveCases = 4, recoveryNegativeCases = 12, independentFixtureCrc32Readback = true, resourceSnapshotRetention = true, cryptexArchiveVerified = true, configurationAndStagingContractsVerified = true, templateIsoDownloaded = false, activeLiluRuntimeChecked = false, sourceModified = false, dockerExecuted = false, guestExecuted = false, completedUtc = DateTimeOffset.UtcNow });
|
||||
Save(Path.Combine(output, "validation.json"), new { success = true, profile = "kvm-host-ventura-cryptex", helperSha256 = Hash(File.ReadAllBytes(Path.Combine("tools", "ci", "MacOsNativeDiagnostic.cs"))), udifChecksumBindingSha256 = Hash(File.ReadAllBytes(Path.Combine("tools", "ci", "macos-native-udif-checksums.py"))), baselineReadinessNormalized = true, readinessDiagnosticBlocksExcluded = 6, diskReadinessAttemptLimit = 2, resultNegativeCases = 6, containerNegativeCases = 11, recoveryPositiveCases = 4, recoveryNegativeCases = 12, independentFixtureCrc32Readback = true, resourceSnapshotRetention = true, cryptexArchiveVerified = true, configurationAndStagingContractsVerified = true, templateIsoDownloaded = false, activeLiluRuntimeChecked = false, sourceModified = false, dockerExecuted = false, guestExecuted = false, completedUtc = DateTimeOffset.UtcNow });
|
||||
}
|
||||
Console.WriteLine("Source patch contracts and diagnostic result validation passed; no Docker or guest execution occurred.");
|
||||
return 0;
|
||||
@@ -184,9 +184,11 @@ static class NativeDiagnostic
|
||||
static void ValidateContracts()
|
||||
{
|
||||
var readiness = File.ReadAllText(Path.Combine("tools", "ci", "macos-native-readiness.sh"));
|
||||
var baseline = ReplaceOnce(readiness, "(( ${os_version%%.*} >= 13 ))", "(( ${os_version%%.*} >= 14 ))");
|
||||
var baseline = NormalizeReadinessDiagnostics(readiness);
|
||||
baseline = ReplaceOnce(baseline, "(( ${os_version%%.*} >= 13 ))", "(( ${os_version%%.*} >= 14 ))");
|
||||
baseline = ReplaceOnce(baseline, "while (( attempt < 2 && SECONDS - readiness_start < 600 )); do", "while (( SECONDS - readiness_start < 600 )); do");
|
||||
if (Hash(Encoding.UTF8.GetBytes(baseline)) != "4d428f594dac14eff64ed87b172c81ecf85ac91da8c5460cd6ec4b1d310800c3")
|
||||
throw new InvalidOperationException("Compatibility readiness may change only the baseline's macOS minimum to 13; identity, services, disk and limits must remain identical.");
|
||||
throw new InvalidOperationException("Outside six explicit diagnostic blocks, the macOS minimum and two-attempt limit, baseline identity/service/disk gates and watchdogs must remain identical.");
|
||||
if (Hash(File.ReadAllBytes(Path.Combine("tools", "ci", "macos-native-bootstrap.sh"))) != "94f069e116fdc7685a4d233cab6fa50df9f39274386bb82157674061e74fadb5")
|
||||
throw new InvalidOperationException("Compatibility profile must preserve the baseline Apple recoveryosd wrapper.");
|
||||
if (Hash(Encoding.UTF8.GetBytes(OriginalDaemon13)) != "af9d7f6c1948079bd4384d27b6882678d6fb4e338fcf6a8be8f84fceef174ad6") throw new InvalidOperationException("macOS 13 allowlist bytes differ from the independently read comparison plist.");
|
||||
@@ -214,6 +216,24 @@ static class NativeDiagnostic
|
||||
}
|
||||
}
|
||||
|
||||
static string NormalizeReadinessDiagnostics(string source)
|
||||
{
|
||||
const string start = "# BEGIN disk IPC diagnostic\n";
|
||||
const string end = "# END disk IPC diagnostic\n";
|
||||
var blocks = 0;
|
||||
while (source.IndexOf(start, StringComparison.Ordinal) is var from && from >= 0)
|
||||
{
|
||||
var to = source.IndexOf(end, from + start.Length, StringComparison.Ordinal);
|
||||
if (to < 0 || source.IndexOf(start, from + start.Length, to - from - start.Length, StringComparison.Ordinal) >= 0)
|
||||
throw new InvalidOperationException("Readiness diagnostic blocks are unbalanced or nested.");
|
||||
source = source.Remove(from, to + end.Length - from);
|
||||
blocks++;
|
||||
}
|
||||
if (blocks != 6 || source.Contains(end, StringComparison.Ordinal))
|
||||
throw new InvalidOperationException("Readiness must contain exactly six explicit disk IPC diagnostic blocks.");
|
||||
return source;
|
||||
}
|
||||
|
||||
static async Task PrepareSource(string source, string output, string token, bool writeSource, string? cryptexArchive, CancellationToken cancellation)
|
||||
{
|
||||
Directory.CreateDirectory(output);
|
||||
|
||||
@@ -14,6 +14,9 @@ TIMER_FIFO="/tmp/native-diagnostic-$PROOF_TOKEN-$$.fifo"
|
||||
PENDING_OUTPUTS=()
|
||||
ACTIVE_COMMAND=""
|
||||
ACTIVE_TIMER=""
|
||||
# BEGIN disk IPC diagnostic
|
||||
ACTIVE_OBSERVER=""
|
||||
# END disk IPC diagnostic
|
||||
os_version=""
|
||||
architecture=""
|
||||
uid=-1
|
||||
@@ -96,8 +99,75 @@ read_scalar() {
|
||||
SCALAR="$value"
|
||||
}
|
||||
|
||||
# BEGIN disk IPC diagnostic
|
||||
# Optional observations have their own child/timer ownership. No service is
|
||||
# loaded, restarted or changed, and samples target only this probe's diskutil.
|
||||
observe_disk_query() {
|
||||
local disk_process="$1" output="$2" sample_output="$3" observation_child="" observation_timer=""
|
||||
cancel_observation() {
|
||||
trap '' TERM INT
|
||||
if [ -n "$observation_child" ]; then
|
||||
kill -TERM "$observation_child" 2>/dev/null || :
|
||||
IFS= read -r -t 2 -u 9 unused || :
|
||||
kill -KILL "$observation_child" 2>/dev/null || :
|
||||
wait "$observation_child" 2>/dev/null || :
|
||||
fi
|
||||
[ -z "$observation_timer" ] || { kill -TERM "$observation_timer" 2>/dev/null || :; wait "$observation_timer" 2>/dev/null || :; }
|
||||
printf '[disk-observation] stopped after the owned disk query\n' >> "$output"
|
||||
exit 143
|
||||
}
|
||||
observe_command() {
|
||||
local name="$1" status started=$SECONDS
|
||||
shift
|
||||
printf '\n[disk-observation-command] %s:' "$name" >> "$output"
|
||||
printf ' %s' "$@" >> "$output"
|
||||
printf '\n' >> "$output"
|
||||
"$@" >> "$output" 2>&1 &
|
||||
observation_child=$!
|
||||
(
|
||||
trap 'exit 0' TERM INT
|
||||
IFS= read -r -t 8 -u 9 unused || :
|
||||
printf '[disk-observation-timeout] %s child=%s limit=8s\n' "$name" "$observation_child" >> "$output"
|
||||
kill -TERM "$observation_child" 2>/dev/null || :
|
||||
IFS= read -r -t 2 -u 9 unused || :
|
||||
kill -KILL "$observation_child" 2>/dev/null || :
|
||||
) &
|
||||
observation_timer=$!
|
||||
wait "$observation_child"; status=$?
|
||||
kill -TERM "$observation_timer" 2>/dev/null || :
|
||||
wait "$observation_timer" 2>/dev/null || :
|
||||
printf '[disk-observation-exit] %s status=%s elapsed=%ss\n' "$name" "$status" "$((SECONDS - started))" >> "$output"
|
||||
observation_child=""; observation_timer=""
|
||||
}
|
||||
trap cancel_observation TERM INT
|
||||
printf '[disk-observation] owned-diskutil-child=%s parent-shell=%s\n' "$disk_process" "$$" >> "$output"
|
||||
observe_command processes /bin/ps -axo pid,ppid,state,comm
|
||||
if [ -x /usr/bin/sample ]; then
|
||||
if kill -0 "$disk_process" 2>/dev/null; then
|
||||
observe_command diskutil-sample /usr/bin/sample "$disk_process" 3 10 -file "$sample_output"
|
||||
else
|
||||
printf '[disk-observation-unavailable] diskutil already exited before sample\n' >> "$output"
|
||||
fi
|
||||
else
|
||||
printf '[disk-observation-unavailable] /usr/bin/sample is unavailable\n' >> "$output"
|
||||
fi
|
||||
observe_command arbitration /bin/launchctl print system/com.apple.diskarbitrationd
|
||||
observe_command management /bin/launchctl print system/com.apple.diskmanagementd
|
||||
}
|
||||
|
||||
stop_disk_observation() {
|
||||
[ -n "$ACTIVE_OBSERVER" ] || return 0
|
||||
kill -TERM "$ACTIVE_OBSERVER" 2>/dev/null || :
|
||||
wait "$ACTIVE_OBSERVER" 2>/dev/null || :
|
||||
ACTIVE_OBSERVER=""
|
||||
}
|
||||
|
||||
# END disk IPC diagnostic
|
||||
cancel_probe() {
|
||||
trap '' TERM INT
|
||||
# BEGIN disk IPC diagnostic
|
||||
stop_disk_observation
|
||||
# END disk IPC diagnostic
|
||||
if [ -n "$ACTIVE_COMMAND" ]; then
|
||||
kill -TERM "$ACTIVE_COMMAND" 2>/dev/null || :
|
||||
IFS= read -r -t 2 -u 9 unused || :
|
||||
@@ -136,6 +206,18 @@ run_command() {
|
||||
) &
|
||||
timer=$!
|
||||
ACTIVE_TIMER="$timer"
|
||||
# BEGIN disk IPC diagnostic
|
||||
if [[ "$name" == disks && "$attempt" == 1 ]]; then
|
||||
local observation_output="/tmp/native-diagnostic-disk-observation.out"
|
||||
local sample_output="/tmp/native-diagnostic-disk-sample.out"
|
||||
: > "$observation_output"
|
||||
: > "$sample_output"
|
||||
observe_disk_query "$process" "$observation_output" "$sample_output" &
|
||||
ACTIVE_OBSERVER=$!
|
||||
printf '[disk-observation-start] observer=%s owned-diskutil-child=%s\n' "$ACTIVE_OBSERVER" "$process" >&3
|
||||
PENDING_OUTPUTS+=("$observation_output" "$sample_output")
|
||||
fi
|
||||
# END disk IPC diagnostic
|
||||
wait "$process"
|
||||
exit_code=$?
|
||||
waited=$SECONDS
|
||||
@@ -143,6 +225,9 @@ run_command() {
|
||||
printf '[proof-native-wait] %s child=%s elapsed=%ss exit=%s\n' "$name" "$process" "$((waited - started))" "$exit_code" >&3
|
||||
kill -TERM "$timer" 2>/dev/null || :
|
||||
wait "$timer" 2>/dev/null || :
|
||||
# BEGIN disk IPC diagnostic
|
||||
stop_disk_observation
|
||||
# END disk IPC diagnostic
|
||||
ACTIVE_COMMAND=""; ACTIVE_TIMER=""
|
||||
printf '[proof-cleanup] %s child=%s elapsed=%ss total=%ss\n' "$name" "$process" "$((SECONDS - waited))" "$((SECONDS - started))" >&3
|
||||
printf '[proof-exit] %s\n' "$exit_code" >&3
|
||||
@@ -203,10 +288,17 @@ os_version="$SCALAR"
|
||||
(( ${os_version%%.*} >= 13 )) || fail_probe unsupported_macos_version
|
||||
flush_outputs || finish false diagnostic_log_budget_exceeded
|
||||
|
||||
# BEGIN disk IPC diagnostic
|
||||
run_command arbitration_before /bin/launchctl print system/com.apple.diskarbitrationd
|
||||
run_command management_before /bin/launchctl print system/com.apple.diskmanagementd
|
||||
run_command media_before /usr/sbin/ioreg -r -c IOMedia -l -w 0
|
||||
flush_outputs || finish false diagnostic_log_budget_exceeded
|
||||
|
||||
# END disk IPC diagnostic
|
||||
# Bound readiness independently of the host's 40-minute overall deadline.
|
||||
readiness_start=$SECONDS
|
||||
attempt=0
|
||||
while (( SECONDS - readiness_start < 600 )); do
|
||||
while (( attempt < 2 && SECONDS - readiness_start < 600 )); do
|
||||
attempt=$((attempt + 1))
|
||||
printf '\n[readiness-attempt] %s\n' "$attempt" >&3
|
||||
run_command disks /usr/sbin/diskutil list physical
|
||||
|
||||
Reference in New Issue
Block a user