#!/bin/bash # SPDX-License-Identifier: BSD-3-Clause # # fetch_from_guest.sh - copy a file out of a running Open-IOV guest. # # The guest agent is used to start a netcat transfer from the guest to the # host (QEMU user networking: the host is 10.0.2.2), which is much faster and # more robust than pushing tens of megabytes through the agent in base64 # chunks. # # Usage: scripts/fetch_from_guest.sh [guest-bind-ip] # e.g. scripts/fetch_from_guest.sh \ # /usr/lib/x86_64-linux-gnu/libcuda.so.570.144 set -e HERE="$(cd "$(dirname "$0")" && pwd)" RUN="$(cd "$HERE/.." && pwd)/run" VMEXEC="$HERE/../../../scripts/vgpu_vm.py" PORT="${PORT:-47311}" GUEST_PATH="${1:?usage: $0 [guest-bind-ip]}" HOST_IP="${2:-10.0.2.2}" OUT="$RUN/$(basename "$GUEST_PATH")" mkdir -p "$RUN" # Guest-side md5 for verification GUEST_MD5=$("$VMEXEC" exec "md5sum '$GUEST_PATH'" 2>/dev/null | awk '{print $1}') [ -n "$GUEST_MD5" ] || { echo "cannot stat $GUEST_PATH in guest"; exit 1; } echo "[*] guest md5: $GUEST_MD5" echo "[*] listening on :$PORT -> $OUT" rm -f "$OUT" nc -l "$PORT" > "$OUT" & NCPID=$! sleep 1 "$VMEXEC" exec "setsid sh -c 'nc $HOST_IP $PORT < $GUEST_PATH' >/dev/null 2>&1 &" >/dev/null 2>&1 || true # Wait for the transfer to settle (size stable for two checks) prev=0 for _ in $(seq 1 60); do sleep 2 cur=$(stat -c%s "$OUT" 2>/dev/null || echo 0) [ "$cur" -gt 0 ] && [ "$cur" = "$prev" ] && break prev=$cur done wait $NCPID 2>/dev/null || true HOST_MD5=$(md5sum "$OUT" | awk '{print $1}') echo "[*] host md5: $HOST_MD5" if [ "$GUEST_MD5" != "$HOST_MD5" ]; then echo "[FAIL] md5 mismatch" exit 1 fi echo "[ok] $OUT ($(stat -c%s "$OUT") bytes)"