diff options
| author | user <user@clank> | 2026-07-17 19:47:12 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-17 19:47:12 +0200 |
| commit | 6f8243ef094241d3a4175fd2deed23fe5ee946ce (patch) | |
| tree | e4d71c21979664e185a56284dde9da6de1e1286b /tools/gbhub | |
| parent | net: unbreak ping against hosts that intermittently drop ICMP (diff) | |
| download | gbos-6f8243ef094241d3a4175fd2deed23fe5ee946ce.tar.gz gbos-6f8243ef094241d3a4175fd2deed23fe5ee946ce.tar.xz gbos-6f8243ef094241d3a4175fd2deed23fe5ee946ce.zip | |
gbhub: make GB drops attributable, not spooky
Link-drop investigation fallout - every drop looked identical because
the hub discarded all the evidence:
- gb_reader logs *how* a GB left (clean eof vs the exception) with
timestamps on join/leave, for correlating against SSH/terminal events.
- Spawn mode keeps each emulator's stderr in /tmp/gbhub_<n>.err instead
of devnull - postmortems get the emulator's side of the story.
- A second gbhub exits with a clear 'already running?' message instead
of an ioctl traceback (and can't damage the live hub's NAT/socket).
Diffstat (limited to '')
| -rwxr-xr-x | tools/gbhub | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/tools/gbhub b/tools/gbhub index 3823463..85a4843 100755 --- a/tools/gbhub +++ b/tools/gbhub @@ -93,13 +93,16 @@ def route(gb, fr): def gb_reader(gb): buf, inf, esc = bytearray(), False, False while True: + why = "eof" try: chunk = gb.conn.recv(2048) - except Exception: chunk = None + except Exception as e: + chunk = None; why = "%s: %s" % (type(e).__name__, e) if not chunk: with lock: # GB left: free its address conns.pop(gb.ip, None) if gb.octet not in pool: pool.append(gb.octet); pool.sort() - sys.stderr.write("[gbhub] GB%d (10.0.0.%d) left\n" % (gb.idx, gb.octet)) + sys.stderr.write("[gbhub] %s GB%d (10.0.0.%d) left (%s)\n" + % (time.strftime("%H:%M:%S"), gb.idx, gb.octet, why)) return for c in chunk: if c == END: @@ -125,7 +128,11 @@ def tun_reader(): def net_setup(): global tun tun = os.open("/dev/net/tun", os.O_RDWR) - fcntl.ioctl(tun, 0x400454ca, struct.pack("16sH", IFACE.encode(), 0x0001|0x1000)) + try: + fcntl.ioctl(tun, 0x400454ca, struct.pack("16sH", IFACE.encode(), 0x0001|0x1000)) + except OSError as e: + sys.exit("gbhub: cannot claim %s (%s) - another gbhub is already running?\n" + " (sudo pkill -f tools/gbhub to stop it)" % (IFACE, e.strerror)) wan = subprocess.check_output("ip route show default|awk '{print $5;exit}'", shell=True).decode().strip() or "eth0" sh("ip addr add 10.0.0.1/24 dev %s" % IFACE); sh("ip link set %s mtu %d up" % (IFACE, MTU)) sh("sysctl -w net.ipv4.ip_forward=1") @@ -146,7 +153,8 @@ def register(conn): octet = pool.pop(0) gb = GB(octet, conn); conns[gb.ip] = gb threading.Thread(target=gb_reader, args=(gb,), daemon=True).start() - sys.stderr.write("[gbhub] GB%d joined -> 10.0.0.%d\n" % (gb.idx, octet)) + sys.stderr.write("[gbhub] %s GB%d joined -> 10.0.0.%d\n" + % (time.strftime("%H:%M:%S"), gb.idx, octet)) return gb def main(): @@ -176,9 +184,11 @@ def main(): for i in range(n): rom = "/tmp/gbhub_%d.gb" % i # per-GB ROM so saves don't clash shutil.copyfile(ROM, rom) + err = open("/tmp/gbhub_%d.err" % i, "ab", buffering=0) # keep emulator stderr for postmortems emus.append(subprocess.Popen([EMU, "--headless", "--uncapped", "--serial-sock", SOCK, rom], - stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=err, start_new_session=True)) + err.close() sys.stderr.write("[gbhub] %d Game Boys on 10.0.0.0/24 (10.0.0.2..%d), NAT via %s\n" % (n, 1+n, wan)) srv.settimeout(12) for i in range(n): |
