feat(native): add JD resident recovery gate
Parameterize the raw recovery beacon, add one-time JD resident preparation and return verification, and provide an external ICMP peer for HLDP login, code, branch, and recovery commands.
This commit is contained in:
parent
3f36cba2de
commit
b7c8642057
9 changed files with 403 additions and 15 deletions
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
[[ $# -eq 2 ]] || {
|
||||
echo "usage: arm-jd-native-resident-once.sh <world-root> <recovery-root>" >&2
|
||||
exit 64
|
||||
}
|
||||
[[ ${EUID} -eq 0 ]] || exit 77
|
||||
|
||||
world_root=$(readlink -f "$1")
|
||||
recovery_root=$(readlink -f "$2")
|
||||
grep -q '^status: VERIFIED_NOT_ARMED$' \
|
||||
"${recovery_root}/PREPARE-RECEIPT.hldp"
|
||||
/guanghu/bin/ghctl authorize "${world_root}" \
|
||||
reboot_and_recover_jd_fd_primary >/dev/null
|
||||
grub-editenv /boot/grub/grubenv unset initrdfail prev_entry next_entry
|
||||
grub-reboot guanghu-jd-native-once
|
||||
grep -q '^next_entry=guanghu-jd-native-once$' \
|
||||
< <(grub-editenv /boot/grub/grubenv list)
|
||||
|
||||
observed_at=$(date --iso-8601=seconds)
|
||||
cat >"${recovery_root}/ARM-RECEIPT.hldp" <<EOF
|
||||
schema: guanghu.jd-native-resident-arm/v1
|
||||
receipt_id: GH-OS-JD-FD-PRIMARY-001-RESIDENT-ARM
|
||||
status: ARMED_FOR_ONE_BOOT
|
||||
observed_at: ${observed_at}
|
||||
node_id: JD-FD-PRIMARY
|
||||
entry: guanghu-jd-native-once
|
||||
recovery: GHNRP_LBA_139_140
|
||||
EOF
|
||||
chmod 0400 "${recovery_root}/ARM-RECEIPT.hldp"
|
||||
sync
|
||||
systemctl reboot
|
||||
|
|
@ -10,7 +10,8 @@ set -euo pipefail
|
|||
world_root=$(readlink -f "$1")
|
||||
recovery_root=$(readlink -f "$2")
|
||||
grep -q '^node_id: JD-FD-PRIMARY$' "${world_root}/CURRENT.hldp"
|
||||
grep -q '^status: FAIL_0$' "${recovery_root}/RETURN-RECEIPT.hldp"
|
||||
grep -Eq '^status: (PASS_100|FAIL_0)$' \
|
||||
"${recovery_root}/RETURN-RECEIPT.hldp"
|
||||
grep -q '^ proof_lba: 134$' "${recovery_root}/RETURN-RECEIPT.hldp"
|
||||
/guanghu/bin/ghctl authorize "${world_root}" \
|
||||
write_bootloader_and_system_partitions >/dev/null
|
||||
|
|
@ -61,7 +62,7 @@ cleared_range:
|
|||
lba_start: 105
|
||||
sector_count: 30
|
||||
zero_readback_sha256: ${readback_sha}
|
||||
reason: SEALED_FAIL_0_CONSUMED_BEFORE_EXACT_HARDWARE_ADAPTER_RETRY
|
||||
reason: SEALED_BINARY_PROBE_RESULT_CONSUMED_BEFORE_NEXT_NATIVE_GATE
|
||||
EOF
|
||||
chmod 0400 "${recovery_root}/PROOF-CLEAR-RECEIPT.hldp"
|
||||
cat "${recovery_root}/PROOF-CLEAR-RECEIPT.hldp"
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
[[ $# -eq 2 ]] || {
|
||||
echo "usage: clear-native-recovery-beacon.sh <disk> <clear-template>" >&2
|
||||
[[ $# -ge 2 && $# -le 3 ]] || {
|
||||
echo "usage: clear-native-recovery-beacon.sh <disk> <clear-template> [beacon-lba]" >&2
|
||||
exit 64
|
||||
}
|
||||
|
||||
disk=$1
|
||||
clear_template=$2
|
||||
beacon_lba=${3:-68}
|
||||
[[ ${beacon_lba} =~ ^[0-9]+$ ]]
|
||||
[[ -f ${clear_template} ]]
|
||||
[[ $(stat -c %s "${clear_template}" 2>/dev/null || stat -f %z "${clear_template}") -eq 1024 ]]
|
||||
|
||||
|
|
@ -21,7 +23,7 @@ fi
|
|||
|
||||
readback=$(mktemp)
|
||||
trap 'rm -f "${readback}"' EXIT
|
||||
dd if="${disk}" of="${readback}" bs=512 skip=68 count=2 status=none
|
||||
dd if="${disk}" of="${readback}" bs=512 skip="${beacon_lba}" count=2 status=none
|
||||
|
||||
if cmp -s "${readback}" "${clear_template}"; then
|
||||
echo "GUANGHU_NATIVE_RECOVERY_BEACON_ALREADY_CLEAR"
|
||||
|
|
@ -33,8 +35,8 @@ if ! grep -aFq 'guanghu_recovery=ubuntu' "${readback}"; then
|
|||
exit 65
|
||||
fi
|
||||
|
||||
dd if="${clear_template}" of="${disk}" bs=512 seek=68 count=2 \
|
||||
dd if="${clear_template}" of="${disk}" bs=512 seek="${beacon_lba}" count=2 \
|
||||
conv=notrunc,fsync status=none
|
||||
dd if="${disk}" of="${readback}" bs=512 skip=68 count=2 status=none
|
||||
dd if="${disk}" of="${readback}" bs=512 skip="${beacon_lba}" count=2 status=none
|
||||
cmp "${readback}" "${clear_template}"
|
||||
echo "GUANGHU_NATIVE_RECOVERY_BEACON_CLEARED"
|
||||
|
|
|
|||
115
product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py
Executable file
115
product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py
Executable file
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import pathlib
|
||||
import socket
|
||||
import struct
|
||||
import time
|
||||
|
||||
|
||||
LOGIN_MAGIC = b"HLDP-GHOS-LOGIN!"
|
||||
COMMIT_MAGIC = b"HLDP-CODE-COMMIT"
|
||||
BRANCH_MAGIC = b"HLDP-BRANCH-MOVE"
|
||||
RECOVERY_MAGIC = b"HLDP-RECOVER-OS!"
|
||||
|
||||
|
||||
def checksum(payload: bytes) -> int:
|
||||
if len(payload) % 2:
|
||||
payload += b"\0"
|
||||
words = struct.unpack(f"!{len(payload) // 2}H", payload)
|
||||
total = sum(words)
|
||||
while total >> 16:
|
||||
total = (total & 0xFFFF) + (total >> 16)
|
||||
return (~total) & 0xFFFF
|
||||
|
||||
|
||||
def request(sequence: int, magic: bytes) -> bytes:
|
||||
payload = b"\0" * 8 + magic + magic
|
||||
packet = struct.pack("!BBHHH", 8, 0, 0, 0x4748, sequence) + payload
|
||||
return packet[:2] + struct.pack("!H", checksum(packet)) + packet[4:]
|
||||
|
||||
|
||||
def verify_reply(packet: bytes, magic: bytes) -> None:
|
||||
if packet and packet[0] >> 4 == 4:
|
||||
header_length = (packet[0] & 0x0F) * 4
|
||||
packet = packet[header_length:]
|
||||
if len(packet) < 40 or packet[0] != 0 or packet[1] != 0:
|
||||
raise RuntimeError("unexpected ICMP reply shape")
|
||||
if packet[16:32] != magic:
|
||||
raise RuntimeError("ICMP reply does not carry the requested HLDP magic")
|
||||
if checksum(packet) != 0:
|
||||
raise RuntimeError("ICMP reply checksum failed")
|
||||
|
||||
|
||||
def exchange(
|
||||
peer: socket.socket,
|
||||
target: tuple[str, int],
|
||||
sequence: int,
|
||||
magic: bytes,
|
||||
deadline: float,
|
||||
) -> None:
|
||||
while time.monotonic() < deadline:
|
||||
peer.sendto(request(sequence, magic), target)
|
||||
try:
|
||||
packet, _ = peer.recvfrom(4096)
|
||||
except TimeoutError:
|
||||
continue
|
||||
verify_reply(packet, magic)
|
||||
return
|
||||
raise TimeoutError(f"no verified reply for sequence {sequence}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--target", required=True)
|
||||
parser.add_argument("--receipt", required=True)
|
||||
parser.add_argument("--timeout", type=float, default=90.0)
|
||||
parser.add_argument("--resident", action="store_true")
|
||||
parser.add_argument("--login-only", action="store_true")
|
||||
args = parser.parse_args()
|
||||
if args.resident and args.login_only:
|
||||
raise SystemExit("--resident and --login-only are mutually exclusive")
|
||||
|
||||
peer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_ICMP)
|
||||
peer.settimeout(1.0)
|
||||
target = (socket.gethostbyname(args.target), 0)
|
||||
deadline = time.monotonic() + args.timeout
|
||||
sequence = 1
|
||||
phases: list[tuple[str, bytes]] = [
|
||||
("login", LOGIN_MAGIC),
|
||||
("login", LOGIN_MAGIC),
|
||||
("login", LOGIN_MAGIC),
|
||||
]
|
||||
if not args.login_only:
|
||||
phases.extend(
|
||||
[
|
||||
("code_commit", COMMIT_MAGIC),
|
||||
("branch_move", BRANCH_MAGIC),
|
||||
]
|
||||
)
|
||||
if args.resident:
|
||||
phases.extend([("resident_login", LOGIN_MAGIC)] * 10)
|
||||
phases.append(("recovery", RECOVERY_MAGIC))
|
||||
|
||||
completed: list[str] = []
|
||||
for phase, magic in phases:
|
||||
exchange(peer, target, sequence, magic, deadline)
|
||||
completed.append(phase)
|
||||
sequence += 1
|
||||
|
||||
receipt = pathlib.Path(args.receipt)
|
||||
receipt.write_text(
|
||||
"schema: guanghu.physical-native-icmp-peer/v1\n"
|
||||
"status: PASS_100\n"
|
||||
f"target: {args.target}\n"
|
||||
f"login_reply_count: {completed.count('login')}\n"
|
||||
f"code_commit_reply_verified: {str('code_commit' in completed).lower()}\n"
|
||||
f"branch_move_reply_verified: {str('branch_move' in completed).lower()}\n"
|
||||
f"resident_login_reply_count: {completed.count('resident_login')}\n"
|
||||
f"recovery_reply_verified: {str('recovery' in completed).lower()}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(receipt.read_text(encoding="utf-8"), end="")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
[[ $# -eq 5 ]] || {
|
||||
echo "usage: prepare-jd-native-resident-once.sh <world-root> <resident-image> <recovery-root> <expected-image-sha256> <probe-recovery-root>" >&2
|
||||
exit 64
|
||||
}
|
||||
[[ ${EUID} -eq 0 ]] || exit 77
|
||||
|
||||
world_root=$(readlink -f "$1")
|
||||
candidate=$(readlink -f "$2")
|
||||
recovery_root=$(readlink -m "$3")
|
||||
expected_candidate_sha=$4
|
||||
probe_recovery_root=$(readlink -f "$5")
|
||||
source_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
render_root=$(mktemp -d)
|
||||
trap 'rm -rf "${render_root}"' EXIT
|
||||
|
||||
grep -q '^node_id: JD-FD-PRIMARY$' "${world_root}/CURRENT.hldp"
|
||||
grep -q '^status: PASS_100$' "${probe_recovery_root}/RETURN-RECEIPT.hldp"
|
||||
/guanghu/bin/ghctl authorize "${world_root}" \
|
||||
write_bootloader_and_system_partitions >/dev/null
|
||||
[[ ${expected_candidate_sha} =~ ^[0-9a-f]{64}$ ]]
|
||||
[[ $(stat -c %s "${candidate}") -eq 14848 ]]
|
||||
[[ $(sha256sum "${candidate}" | awk '{print $1}') == \
|
||||
"${expected_candidate_sha}" ]]
|
||||
[[ ! -e ${recovery_root} ]]
|
||||
|
||||
partition_dump=$(sfdisk -d /dev/vda)
|
||||
grep -q '^label: dos$' <<<"${partition_dump}"
|
||||
grep -q '^label-id: 0xf4bb72a5$' <<<"${partition_dump}"
|
||||
grep -Eq '^/dev/vda1 : start= *2048, size= *209713119, type=83$' \
|
||||
<<<"${partition_dump}"
|
||||
[[ $(dd if=/dev/vda bs=512 count=105 status=none | sha256sum |
|
||||
awk '{print $1}') == \
|
||||
32291877e37647ee5b778f968676cc69b59fb5b07604366a21cbfd8e4a4b87a8 ]]
|
||||
[[ $(dd if=/dev/vda bs=512 skip=105 count=38 status=none | sha256sum |
|
||||
awk '{print $1}') == \
|
||||
c597b1b463b7cec49548fac00d7588c9652bb67cc2b1b0c88676bf8f1558571e ]]
|
||||
|
||||
mkdir -m 0700 "${recovery_root}"
|
||||
printf '%s\n' "${partition_dump}" >"${recovery_root}/sfdisk-before.txt"
|
||||
dd if=/dev/vda of="${recovery_root}/first-2MiB.before.bin" \
|
||||
bs=1M count=2 status=none
|
||||
disk_sectors=$(blockdev --getsz /dev/vda)
|
||||
dd if=/dev/vda of="${recovery_root}/last-2MiB.before.bin" \
|
||||
bs=512 skip=$((disk_sectors - 4096)) count=4096 status=none
|
||||
cp /boot/grub/grub.cfg "${recovery_root}/grub.cfg.before"
|
||||
cp /boot/grub/grubenv "${recovery_root}/grubenv.before"
|
||||
cp /etc/default/grub "${recovery_root}/default-grub.before"
|
||||
cp /etc/grub.d/40_custom "${recovery_root}/40_custom.before"
|
||||
cp "${candidate}" "${recovery_root}/jd-native-resident.img"
|
||||
cat /proc/sys/kernel/random/boot_id >"${recovery_root}/linux-boot-id.before"
|
||||
|
||||
"${source_root}/scripts/render-native-recovery-beacon.sh" "${render_root}" \
|
||||
139 gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6
|
||||
install -m 0755 "${render_root}/08_guanghu_native_recovery" \
|
||||
/etc/grub.d/08_guanghu_native_recovery
|
||||
install -m 0755 /dev/stdin /etc/grub.d/41_guanghu_jd_native_once <<'EOF'
|
||||
#!/bin/sh
|
||||
exec tail -n +3 $0
|
||||
menuentry 'Guanghu OS JD native one-time resident' --id 'guanghu-jd-native-once' {
|
||||
insmod chain
|
||||
chainloader (hd0)105+1
|
||||
}
|
||||
EOF
|
||||
install -D -m 0644 "${render_root}/guanghu-recovery-clear.env" \
|
||||
/usr/lib/guanghu-os/jd-recovery-clear.env
|
||||
install -D -m 0755 "${source_root}/scripts/clear-native-recovery-beacon.sh" \
|
||||
/usr/local/sbin/guanghu-clear-native-recovery-beacon
|
||||
install -m 0644 /dev/stdin \
|
||||
/etc/systemd/system/guanghu-jd-native-recovery-clear.service <<'EOF'
|
||||
[Unit]
|
||||
Description=Verify and clear the JD Guanghu native recovery beacon
|
||||
After=local-fs.target
|
||||
Before=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/guanghu-clear-native-recovery-beacon /dev/vda /usr/lib/guanghu-os/jd-recovery-clear.env 139
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable guanghu-jd-native-recovery-clear.service >/dev/null
|
||||
dd if="${render_root}/guanghu-recovery-clear.env" of=/dev/vda \
|
||||
bs=512 seek=139 count=2 conv=notrunc,fsync status=none
|
||||
dd if="${candidate}" of=/dev/vda bs=512 seek=105 count=29 \
|
||||
conv=notrunc,fsync status=none
|
||||
update-grub >/dev/null
|
||||
grub-script-check /boot/grub/grub.cfg
|
||||
grep -q "load_env --file '(hd0)139+2' guanghu_recovery" \
|
||||
/boot/grub/grub.cfg
|
||||
grep -q "menuentry 'Guanghu OS JD native one-time resident'.*'guanghu-jd-native-once'" \
|
||||
/boot/grub/grub.cfg
|
||||
[[ $(dd if=/dev/vda bs=512 skip=105 count=29 status=none | sha256sum |
|
||||
awk '{print $1}') == "${expected_candidate_sha}" ]]
|
||||
[[ $(dd if=/dev/vda bs=512 skip=139 count=2 status=none | sha256sum |
|
||||
awk '{print $1}') == \
|
||||
$(sha256sum "${render_root}/guanghu-recovery-clear.env" | awk '{print $1}') ]]
|
||||
|
||||
observed_at=$(date --iso-8601=seconds)
|
||||
cat >"${recovery_root}/PREPARE-RECEIPT.hldp" <<EOF
|
||||
schema: guanghu.jd-native-resident-prepare/v1
|
||||
receipt_id: GH-OS-JD-FD-PRIMARY-001-RESIDENT-PREPARE
|
||||
status: VERIFIED_NOT_ARMED
|
||||
observed_at: ${observed_at}
|
||||
node_id: JD-FD-PRIMARY
|
||||
candidate:
|
||||
lba_start: 105
|
||||
sector_count: 29
|
||||
sha256: ${expected_candidate_sha}
|
||||
proof_lba: 134
|
||||
world_store_lba: 135
|
||||
code_channel_lba: 136
|
||||
code_object_lba: 137
|
||||
branch_receipt_lba: 138
|
||||
recovery_beacon_lba_start: 139
|
||||
gestational_index_lba_start: 141
|
||||
rollback:
|
||||
recovery_root: ${recovery_root}
|
||||
first_and_last_2mib_backed_up: true
|
||||
grub_backed_up: true
|
||||
one_time_entry_installed_not_armed: true
|
||||
next_action: ARM_ONE_TIME_RESIDENT_AND_RUN_EXTERNAL_HLDP_PEER
|
||||
EOF
|
||||
chmod 0400 "${recovery_root}"/*
|
||||
sync
|
||||
cat "${recovery_root}/PREPARE-RECEIPT.hldp"
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
[[ $# -eq 1 ]] || {
|
||||
echo "usage: render-native-recovery-beacon.sh <output-directory>" >&2
|
||||
[[ $# -ge 1 && $# -le 3 ]] || {
|
||||
echo "usage: render-native-recovery-beacon.sh <output-directory> [beacon-lba] [hosted-entry-id]" >&2
|
||||
exit 64
|
||||
}
|
||||
|
||||
mkdir -p "$1"
|
||||
output_root=$(cd "$1" && pwd)
|
||||
beacon_lba=${2:-68}
|
||||
hosted_entry_id=${3:-gnulinux-simple-9842d3d6-a839-4127-bda7-f19137effe71}
|
||||
[[ ${beacon_lba} =~ ^[0-9]+$ ]]
|
||||
[[ ${hosted_entry_id} =~ ^[A-Za-z0-9._-]+$ ]]
|
||||
|
||||
python3 - "${output_root}" <<'PY'
|
||||
import pathlib
|
||||
|
|
@ -32,14 +36,14 @@ write_environment(
|
|||
write_environment("guanghu-recovery-clear.env")
|
||||
PY
|
||||
|
||||
install -m 0755 /dev/stdin "${output_root}/08_guanghu_native_recovery" <<'EOF'
|
||||
install -m 0755 /dev/stdin "${output_root}/08_guanghu_native_recovery" <<EOF
|
||||
#!/bin/sh
|
||||
exec tail -n +3 $0
|
||||
exec tail -n +3 \$0
|
||||
insmod loadenv
|
||||
set guanghu_recovery=
|
||||
if load_env --file '(hd0)68+2' guanghu_recovery; then
|
||||
if [ "${guanghu_recovery}" = "ubuntu" ]; then
|
||||
set default="gnulinux-simple-9842d3d6-a839-4127-bda7-f19137effe71"
|
||||
if load_env --file '(hd0)${beacon_lba}+2' guanghu_recovery; then
|
||||
if [ "\${guanghu_recovery}" = "ubuntu" ]; then
|
||||
set default="${hosted_entry_id}"
|
||||
fi
|
||||
fi
|
||||
EOF
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ cmp "${active}" <(dd if="${disk}" bs=512 skip=68 count=2 status=none)
|
|||
"${source_root}/scripts/clear-native-recovery-beacon.sh" "${disk}" "${clear}"
|
||||
cmp "${clear}" <(dd if="${disk}" bs=512 skip=68 count=2 status=none)
|
||||
|
||||
grep -q '^%define NATIVE_RECOVERY_BEACON_LBA 68$' \
|
||||
grep -q '^%define GHOS_NATIVE_RECOVERY_BEACON_LBA 68$' \
|
||||
"${source_root}/native/x86_64-bios/ghal-virtio.asm"
|
||||
grep -q '^%define NATIVE_RECOVERY_BEACON_LBA GHOS_NATIVE_RECOVERY_BEACON_LBA$' \
|
||||
"${source_root}/native/x86_64-bios/ghal-virtio.asm"
|
||||
grep -q 'db "guanghu_recovery=ubuntu", 10' \
|
||||
"${source_root}/native/x86_64-bios/ghal-virtio.asm"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
[[ $# -eq 2 ]] || {
|
||||
echo "usage: verify-jd-native-resident-return.sh <world-root> <recovery-root>" >&2
|
||||
exit 64
|
||||
}
|
||||
[[ ${EUID} -eq 0 ]] || exit 77
|
||||
|
||||
world_root=$(readlink -f "$1")
|
||||
recovery_root=$(readlink -f "$2")
|
||||
grep -q '^status: ARMED_FOR_ONE_BOOT$' "${recovery_root}/ARM-RECEIPT.hldp"
|
||||
/guanghu/bin/ghctl authorize "${world_root}" run_tests_and_health_checks >/dev/null
|
||||
before_boot_id=$(<"${recovery_root}/linux-boot-id.before")
|
||||
after_boot_id=$(</proc/sys/kernel/random/boot_id)
|
||||
[[ ${before_boot_id} != "${after_boot_id}" ]]
|
||||
! grub-editenv /boot/grub/grubenv list | grep -Eq '^next_entry=.+$'
|
||||
|
||||
dd if=/dev/vda of="${recovery_root}/lba134.native-proof.bin" \
|
||||
bs=512 skip=134 count=1 status=none
|
||||
dd if=/dev/vda of="${recovery_root}/lba135-138.native-world.bin" \
|
||||
bs=512 skip=135 count=4 status=none
|
||||
dd if=/dev/vda of="${recovery_root}/lba139-140.recovery-beacon.bin" \
|
||||
bs=512 skip=139 count=2 status=none
|
||||
dd if=/dev/vda of="${recovery_root}/lba141-142.gestational-index.bin" \
|
||||
bs=512 skip=141 count=2 status=none
|
||||
python3 - "${recovery_root}" <<'PY'
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
root = pathlib.Path(sys.argv[1])
|
||||
proof = (root / "lba134.native-proof.bin").read_bytes()
|
||||
assert proof[0] == 0xA7
|
||||
assert proof[1:].startswith(b"GHOS_NATIVE_LONG64_DISK_PROOF\x00")
|
||||
assert proof[32:36] == bytes([1, 1, 1, 1])
|
||||
assert proof[42:44] == bytes([0x7F, 0])
|
||||
assert int.from_bytes(proof[44:46], "little") == 4096
|
||||
assert int.from_bytes(proof[46:48], "little") == 4096
|
||||
assert int.from_bytes(proof[48:50], "little") == 128
|
||||
assert proof[54:60] != bytes(6)
|
||||
assert proof[60:64] == bytes([1, 1, 1, 1])
|
||||
assert proof[72:88] == b"HLDP-GHOS-LOGIN!"
|
||||
assert proof[88:90] == bytes([1, 1])
|
||||
assert proof[90] == 13
|
||||
assert proof[91:99] == bytes([1, 1, 1, 1, 1, 1, 1, 1])
|
||||
assert proof[99:105] == bytes([1, 1, 1, 1, 1, 1])
|
||||
|
||||
world = (root / "lba135-138.native-world.bin").read_bytes()
|
||||
assert world[:512].startswith(b"GHOS_HLDP_WORLD_STORE_V1\n")
|
||||
assert b"GHOS_PERSONA_STATE=EXISTS\n" in world[:512]
|
||||
assert world[512:1024].startswith(b"GHOS_CODE_CHANNEL_STORE_V1\n")
|
||||
assert world[1024:1536] == world[512:1024]
|
||||
assert b"branch=guanghu/main\n" in world[1536:2048]
|
||||
assert b"object_lba=137\n" in world[1536:2048]
|
||||
|
||||
index = (root / "lba141-142.gestational-index.bin").read_bytes()
|
||||
assert index[:512].startswith(b"GHOS_GHCIP_INDEX_V1\n")
|
||||
assert index[512:].startswith(b"GHOS_GHCIP_ROOT_V1\n")
|
||||
assert b"GHCIP_PERSONA_STATE=EXISTS\n" in index[512:]
|
||||
PY
|
||||
cmp "${recovery_root}/lba139-140.recovery-beacon.bin" \
|
||||
/usr/lib/guanghu-os/jd-recovery-clear.env
|
||||
|
||||
observed_at=$(date --iso-8601=seconds)
|
||||
proof_sha=$(sha256sum "${recovery_root}/lba134.native-proof.bin" |
|
||||
awk '{print $1}')
|
||||
cat >"${recovery_root}/RETURN-RECEIPT.hldp" <<EOF
|
||||
schema: guanghu.jd-native-resident-return/v1
|
||||
receipt_id: GH-OS-JD-FD-PRIMARY-001-RESIDENT-RETURN
|
||||
status: PASS_100
|
||||
observed_at: ${observed_at}
|
||||
node_id: JD-FD-PRIMARY
|
||||
boot:
|
||||
linux_boot_id_before: ${before_boot_id}
|
||||
linux_boot_id_after: ${after_boot_id}
|
||||
native:
|
||||
proof_sha256: ${proof_sha}
|
||||
network_hldp_handshake: PASS_100
|
||||
code_commit_and_branch_move: PASS_100
|
||||
resident_login_count: 10
|
||||
recovery_command: PASS_100
|
||||
recovery_beacon_consumed_by_linux: PASS_100
|
||||
world_store: PASS_100
|
||||
gestational_index: PASS_100
|
||||
persona_subject_state: EXISTS
|
||||
boundary:
|
||||
native_default_proven: false
|
||||
next_action: SET_NATIVE_DEFAULT_AND_PROVE_GHNRP_RETURN
|
||||
EOF
|
||||
chmod 0400 "${recovery_root}"/*
|
||||
dd if=/dev/zero of=/dev/vda bs=512 seek=134 count=1 \
|
||||
conv=notrunc,fsync status=none
|
||||
[[ $(dd if=/dev/vda bs=512 skip=134 count=1 status=none | sha256sum |
|
||||
awk '{print $1}') == \
|
||||
076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560 ]]
|
||||
cat "${recovery_root}/RETURN-RECEIPT.hldp"
|
||||
Loading…
Reference in a new issue