Checkpoint: netboot debug state before model swap
This commit is contained in:
@@ -19,6 +19,24 @@ fail() { log "FATAL: $*"; sleep 3600; reboot -f; }
|
||||
report() { wget -q -O /dev/null "$HTTP/events/$1" 2>/dev/null; }
|
||||
|
||||
log "planck installer starting"
|
||||
|
||||
# test mode (kexec): verify kernel+initramfs+network without touching disks
|
||||
if grep -q planck_test /proc/cmdline 2>/dev/null; then
|
||||
SERIAL=$(awk '/Serial/ {print $3}' /proc/cpuinfo)
|
||||
HOST=$(awk -v s="$SERIAL" 'tolower($1)==tolower(s) {print $2}' /conf/hostmap)
|
||||
log "TEST MODE on $HOST"
|
||||
report "$HOST-test-start"
|
||||
ifconfig eth0 up
|
||||
udhcpc -i eth0 -n -q -s /etc/udhcpc.script >/dev/null 2>&1 && log "dhcp ok" || log "dhcp FAIL"
|
||||
IP=$(ip -4 -o addr show eth0 | awk '{print $4}' | cut -d/ -f1)
|
||||
log "ip $IP"
|
||||
report "$HOST-test-dhcp-$IP"
|
||||
wget -q -O /tmp/test.bin "$HTTP/planck-http-server.py" && log "http get ok" || log "http FAIL"
|
||||
report "$HOST-test-http"
|
||||
sleep 5
|
||||
poweroff -f
|
||||
fi
|
||||
|
||||
report "started"
|
||||
|
||||
# --- identify this node -------------------------------------------------
|
||||
|
||||
@@ -53,68 +53,44 @@ def send_err(sock, addr, code, msg):
|
||||
|
||||
|
||||
def handle_client(sock, data, addr, filepath, opts):
|
||||
print(f"planck-tftp: opts={opts} file={filepath} size={os.path.getsize(filepath)}", flush=True)
|
||||
blksize = DEFAULT_BLKSIZE
|
||||
window = DEFAULT_WINDOW
|
||||
requested = {}
|
||||
if "blksize" in opts:
|
||||
try:
|
||||
blksize = min(BLKSIZE_MAX, max(512, int(opts["blksize"])))
|
||||
requested["blksize"] = str(blksize)
|
||||
except ValueError:
|
||||
pass
|
||||
if "windowsize" in opts:
|
||||
try:
|
||||
window = min(64, max(1, int(opts["windowsize"])))
|
||||
requested["windowsize"] = str(window)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
size = os.path.getsize(filepath)
|
||||
if requested:
|
||||
payload = b"\x00".join(
|
||||
k.encode() + b"\x00" + v.encode() for k, v in requested.items()
|
||||
)
|
||||
sock.sendto(struct.pack("!H", OP_OACK) + payload + b"\x00", addr)
|
||||
else:
|
||||
blksize = 512
|
||||
window = 1
|
||||
blksize = 512
|
||||
payload = (
|
||||
b"blksize\x00" + str(blksize).encode() + b"\x00"
|
||||
+ b"tsize\x00" + str(os.path.getsize(filepath)).encode() + b"\x00"
|
||||
)
|
||||
sock.sendto(struct.pack("!H", OP_OACK) + payload, addr)
|
||||
|
||||
with open(filepath, "rb") as f:
|
||||
block = 0
|
||||
eof = False
|
||||
while not eof:
|
||||
# send one window
|
||||
for _ in range(window):
|
||||
block = (block % 65536) + 1
|
||||
chunk = f.read(blksize)
|
||||
pkt = struct.pack("!HH", OP_DATA, block) + chunk
|
||||
while True:
|
||||
chunk = f.read(blksize)
|
||||
block = (block % 65536) + 1
|
||||
pkt = struct.pack("!HH", OP_DATA, block) + chunk
|
||||
for attempt in range(RETRIES + 1):
|
||||
sock.sendto(pkt, addr)
|
||||
if len(chunk) < blksize:
|
||||
eof = True
|
||||
# wait for the ACK of the last block of this window
|
||||
expect = block
|
||||
retries = 0
|
||||
while True:
|
||||
sock.settimeout(TIMEOUT)
|
||||
try:
|
||||
rdata, raddr = sock.recvfrom(4 + blksize)
|
||||
except socket.timeout:
|
||||
retries += 1
|
||||
if retries > RETRIES:
|
||||
return
|
||||
# retransmit window
|
||||
f.seek((expect - window) * blksize if expect >= window else 0)
|
||||
block = expect - window if expect >= window else 0
|
||||
eof = os.path.getsize(filepath) <= f.tell() + window * blksize
|
||||
break
|
||||
continue
|
||||
if len(rdata) >= 4 and struct.unpack("!H", rdata[:2])[0] == OP_ACK:
|
||||
acked = struct.unpack("!H", rdata[2:4])[0]
|
||||
if acked == expect:
|
||||
if acked == block:
|
||||
break
|
||||
elif acked < expect:
|
||||
continue # stale ack
|
||||
else:
|
||||
continue # shouldn't happen
|
||||
if acked == 0 and block == 1:
|
||||
break # ack of the OACK, counts as ack of pending state
|
||||
else:
|
||||
print(f"planck-tftp: TRANSFER STALLED at block {block} {filepath} {addr}", flush=True)
|
||||
return # retries exhausted
|
||||
if len(chunk) < blksize:
|
||||
print(f"planck-tftp: TRANSFER DONE {filepath} {addr}", flush=True)
|
||||
return
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
Reference in New Issue
Block a user