summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-28 10:01:43 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-28 10:01:43 -0400
commit701346522d9e152049ec6a4fdb99448937803e60 (patch)
tree025435fede392668ef34ef06b11ea36208b3d2dd /tools/guest-diag
parent595e023abff7d5f7e25ad1afd0907989115df541 (diff)
downloadopen-iov-701346522d9e152049ec6a4fdb99448937803e60.tar.gz
open-iov-701346522d9e152049ec6a4fdb99448937803e60.zip
tools: r18 GPU animation + QGA guest-file fetch - forwarded kernels must fit ONE 4 KB code page (SESSION 150)
Diffstat (limited to 'tools/guest-diag')
-rwxr-xr-xtools/guest-diag/qga_fetch.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/tools/guest-diag/qga_fetch.py b/tools/guest-diag/qga_fetch.py
new file mode 100755
index 0000000..5a940fc
--- /dev/null
+++ b/tools/guest-diag/qga_fetch.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+# Fetch a file from the guest via the QEMU guest agent protocol
+# (/tmp/qemu-guest-agent.sock, the virtio-serial QGA chardev - the same
+# socket vgpu_vm.py exec uses). Usage: qga_fetch.py <guest_path> <host_path> [chunk]
+import base64
+import json
+import socket
+import sys
+
+GUEST = sys.argv[1]
+HOST = sys.argv[2]
+CHUNK = int(sys.argv[3]) if len(sys.argv) > 3 else 1 << 20
+SOCK = "/tmp/qemu-guest-agent.sock"
+
+
+def recv_line(s):
+ buf = b""
+ while b"\n" not in buf:
+ chunk = s.recv(65536)
+ if not chunk:
+ break
+ buf += chunk
+ return buf.split(b"\n", 1)[0]
+
+
+def cmd(s, obj):
+ s.sendall((json.dumps(obj) + "\r\n").encode())
+ line = recv_line(s)
+ return json.loads(line)
+
+
+s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+s.settimeout(30.0)
+s.connect(SOCK)
+r = cmd(s, {"execute": "guest-file-open",
+ "arguments": {"path": GUEST, "mode": "r"}})
+h = r["return"]
+print(f"handle={h}")
+total = 0
+with open(HOST, "wb") as out:
+ while True:
+ r = cmd(s, {"execute": "guest-file-read",
+ "arguments": {"handle": h, "count": CHUNK}})
+ d = r["return"]
+ buf = base64.b64decode(d.get("buf-b64", ""))
+ if buf:
+ out.write(buf)
+ total += len(buf)
+ print(f"\r{total}", end="", flush=True)
+ if d.get("eof"):
+ break
+cmd(s, {"execute": "guest-file-close", "arguments": {"handle": h}})
+print(f"\nFETCHED {total} bytes -> {HOST}")