QEMU 串行标准输出在 archlinux 客户机上发散
Posted
技术标签:
【中文标题】QEMU 串行标准输出在 archlinux 客户机上发散【英文标题】:QEMU serial std output diverges on archlinux guest 【发布时间】:2021-11-03 06:20:13 【问题描述】:我正在尝试在 QEMU 中引导一些新下载的 ISO 的安装自动化。我创建了一个干净的 img 来安装并启动 QEMU,如下所示:
$ qemu-img create -f qcow2 out/main.img 15G
$ qemu-system-x86_64
-m 8G \
-serial stdio \
-cdrom out/linux.iso \
-drive file=out/main.img,if=virtio \
-netdev user,id=net0 \
-device e1000,netdev=net0
我可以看到 Arch 启动了。起初,显示器和终端是同步的,但在 GRUB 启动屏幕之后它们很快就不同了。
我不确定我缺少什么才能让它工作。我见过有人建议将-append "root=/dev/sda console=ttyS0"
添加到您的 QEMU 参数中,但是(据我所知)虽然它需要您从 ISO 中提取内核和 initram(这应该很容易安装和复制/粘贴正确的文件),但它也希望您已经在/dev/sda
上安装了系统(这是我试图引导的)。
此时我不知道接下来要搜索什么,如何在当前终端中获取完整的终端会话,而不仅仅是在我的显示器中?
【问题讨论】:
这是一个 archlinux 问题,而不是 QEMU 问题,我认为——如果你知道它们,你可能想要添加一些相关标签。您需要了解如何让 archlinux 安装程序在串行端口上运行(如果您在真实硬件上运行安装程序,这将与您执行此操作的方式相同)。 【参考方案1】:在这种情况下,就像@Peter Maydell 评论的那样;这不是 QEMU 问题。 QEMU 正在做它应该做的事情,但 Arch 必须被告知使用串行控制台作为其主要通信方式。
如何做到这一点的两个示例
通过控制台bash
pipe_dir="$(mktemp -d)"
mkfifo "$pipe_dir/pipe.in" "$pipe_dir/pipe.out"
function cleanup
rm -rfv "$pipe_dir"
trap cleanup EXIT
qemu-system-x86_64 \
-m 8G \
-display none \
-serial stdio \
-drive file=./out/linux.iso,index=0,media=cdrom \
-drive file=./out/main.img,if=virtio &
sleep 2s
printf "\t" > "$pipe_dir/pipe.in"
sleep 2s
printf " console=ttyS0,115200" > "$pipe_dir/pipe.in"
sleep 2s
echo > "$pipe_dir/pipe.in"
# Whatever other interactions you want go here...
wait
期望通过控制台
set timeout -1
spawn qemu-system-x86_64 \
-m 8G \
-display none \
-serial stdio \
-drive file=./out/linux.iso,index=0,media=cdrom \
-drive file=./out/main.img,if=virtio
sleep 1
send \t
sleep 1
send " console=ttyS0,115200"
sleep 1
send \n
理论上这应该没问题,但实际上我仍然难以与控制台交互并发送字符以正确登录。我敢肯定,我可能有更多的用户错误。
一个更好的解决方案(再次与 Arch 而不是专门针对 QEMU 的上下文相关)是使用包含我的 SSH 公钥的 cloud-init 脚本。与 VM 的交互稳定、可靠且易于重现。
bash 与 cloud-init/ssh
$ touch ./out/meta-data
$ cat > ./out/user-data <<EOF
#cloud-config
users:
- name: root
ssh_authorized_keys:
- $(cat $HOME/.ssh/id_ed25519.pub)
EOF
$ xorriso -as genisoimage -output ./out/cloud-init.iso \
-volid CIDATA -joliet -rock ./out/meta-data ./out/user-data
$ qemu-system-x86_64 \
-m 8G \
-drive file=./out/linux.iso,index=0,media=cdrom \
-drive file=./out/cloud-init.iso,index=1,media=cdrom \
-drive file=./out/main.img,if=virtio \
-net user,hostfwd=tcp::10022-:22 \
-net nic &
$ function qemu-ssh
ssh -q -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o "UserKnownHostsFile /dev/null" -p 10022 root@localhost $@
$ printf 'Waiting for SSH to go live (this will take a while)...'
$ until qemu-ssh exit; do
printf '.'
done
# This convenience function starts an interactive
# session when supplied with no additional arguments
# but your automation can go here
$ qemu-ssh
【讨论】:
以上是关于QEMU 串行标准输出在 archlinux 客户机上发散的主要内容,如果未能解决你的问题,请参考以下文章