如何设置 QEMU 输出到控制台并使用 Shell 脚本自动化

如何设置 QEMU 输出到控制台并使用 Shell 脚本自动化

原文:How to Setup QEMU Output to Console and Automate Using Shell Script

Preface

While struggling to automate QEMU guest (communicate and control with the shell scripts), I faced with a lot of incomplete, partially working solutions around the internet. Now I’ve got a pretty decent collection of working recipes to tune up a QEMU guest, so I decided to organize all that stuff here, and it could be definitely useful for anyone else. Each scenario has been tested on the binaries, links on which I put below in the annex: Binaries used in examples, so you could check it out on your own.

Contents

  1. Input/output to the host terminal
  2. Early boot messages in the host terminal
  3. Input/output through a named pipe (file)
  4. Automate QEMU guest using expect tool
  5. Automate QEMU guest using ssh
  6. Binaries used in examples

  7. Input/output to the host terminal

-serial stdio

qemu-system-x86_64 -serial stdio wheezy.qcow2

如何设置 QEMU 输出到控制台并使用 Shell 脚本自动化

-serial stdio redirects the virtual serial port to the host’s terminal input/output. You will see a welcome string after a successful boot.

-nographic

qemu-system-x86_64 -nographic wheezy.qcow2

如何设置 QEMU 输出到控制台并使用 Shell 脚本自动化

-nographic does the same as “-serial stdio” and also hides a QEMU’s graphical window.

Cautions:

  1. You will not see any early boot logs in the host’s console. To get them, see Early boot messages in the host terminal below.

  2. To exit the guest system without GUI, using stdio redirected to the terminal, login as a root (user: root , password: root ) and shutdown the system (wait after that for a while):

Guest
shutdown -h now
  1. Early boot messages in the host terminal

console=ttyS0

If you want to see early boot logs, you should pass console=ttyS0 parameter to a Linux kernel command line:

qemu-system-x86_64 -nographic -kernel vmlinuz -hda wheezy.img -append "root=/dev/sda console=ttyS0"

or

qemu-system-x86_64 -serial stdio -kernel vmlinuz -hda wheezy.img -append "root=/dev/sda console=ttyS0"

or

qemu-system-x86_64 -serial stdio wheezy.qcow2
 # 1. Wait for a GRUB menu to show.

 # 2. Press e.

 # 3. Find the line starting with "linux".

 # 4. Add "console=ttyS0".

  • qemu-system-x86_64 -serial stdio -kernel vmlinuz -hda wheezy.img -append “root=/dev/sda console=ttyS0”*:

    如何设置 QEMU 输出到控制台并使用 Shell 脚本自动化
  • -serial stdio or -nographic redirects input/output to the current terminal.

  • -append “root=/dev/sda console=ttyS0”: console=ttyS0 forces the guest kernel to send output to the first UART serial port ttyS0, which is redirected to the host by the -serial stdio option, and root=/dev/sda points the kernel to use a /dev/sda device to load the wheezy.img.

Other options:

  • -kernel vmlinuz loads the kernel from the local “./vmlinuz” file.

  • -hda wheezy.img is a raw image which is suitable for booting with vmlinuz binary (wheezy.qcow2 won’t be recognized in the block device).

  • Input/output through a named pipe (file)

Create a named pipe

mkfifo /tmp/guest.in /tmp/guest.out

Start QEMU

qemu-system-x86_64 -serial pipe:/tmp/guest -kernel vmlinuz -hda wheezy.img -append "root=/dev/sda console=ttyS0"

-serial pipe:/tmp/guest redirects a guest’s output to a /tmp/guest.out and allows to send input from host to guest via /tmp/guest.in.

Take an output from the guest

cat /tmp/guest.out

Send a command to the guest

When login screen appears, send a login string:

printf "root\n" > /tmp/guest.in

Wait until some string

Wait until SSH Daemon starts.

while read line; do
  echo "${line}"
  if [[ ${line} == *"Secure Shell server: sshd"* ]]; then
    break;
  fi
done < /tmp/quest.out
  1. Automate QEMU guest using expect tool

Install “expect” tool

sudo apt install expect

Create an expect script

example.exp:

#!/usr/bin/expect -f

Wait enough (forever) until a long-time boot
set timeout -1

Start the guest VM
spawn qemu-system-x86_64 -serial stdio wheezy.qcow2

expect "login: "
send "root\n"

expect "Password: "
send "root\n"

expect "# "
send "shutdown -h now"

Original script is found there:https://stacoverflow.com/questions/314613/qemu-guest-automation, but be careful, symbol of quotes ” (which is not a “) in the original stackoverflow answer cannot be recognized by the expect utility (send "root\n").

Execute “expect” script

chmod +x example.exp
./example.exp
  1. Automate QEMU guest using ssh

Set up port forwarding

qemu-system-x86_64 -netdev user,id=net0,hostfwd=tcp::10022-:22 -device e1000,netdev=net0 wheezy.qcow2

Connect via ssh

ssh root@localhost -p 10022 'uptime; ls; echo Test;'
  • To apply server’s public key automatically use
-o "StrictHostKeyChecking no"

:

ssh root@localhost -p 10022 -o "StrictHostKeyChecking no" 'uptime; ls; echo Test;'

Troubleshooting

  1. QEMU guest has to be able to recognize a network card device (NIC, Network Interface Card):
-netdev user,id=net0 -device e1000,netdev=net0

.

Without port forwarding
qemu-system-x86_64 -netdev user,id=net0 -device e1000,netdev=net0 wheezy.qcow2
  1. Boot and check that the new interface has appeared on the guest system:
Guest
ifconfig -a

Linux kernel on the guest must support a network card emulated by QEMU. In the opposite case the guest won’t get a new Ethernet interface. After booting you should find “eth0” (running broadcast device, not loopback) on the guest. It depends solely on the guest Linux kernel and on the kernel modules.

  1. Check the
10022

port on the host:

Host
netstat -tanp | grep 10022
   tcp  0  0 0.0.0.0:10022   0.0.0.0:*  LISTEN  16589/qemu-system-x
  1. Check the
22

port on the guest:

Guest
netstat -tanp | grep 22
    tcp  0  0 0.0.0.0:22      0.0.0.0:*  LISTEN  2430/sshd
  1. You can forward telnet port
23

and verify the connection:

qemu-system-x86_64 -netdev user,id=net0,hostfwd=tcp::10023-:23 -device e1000,netdev=net0 wheezy.qcow2
  1. Guest (server):
Guest
nc -v -l -p 23
    Listening on [0.0.0.0] (family 0, port 23)
  1. Host (client):
Host
echo asdf | nc localhost 10023

Establish passwordless login via ssh

  1. Generate host SSH keys:
Host
ssh-keygen -b 2048 -t rsa -q -N "" -f ./qemukey
  1. Set up a public key to the guest as a trusted (authorized) key.

  2. Via

ssh-copy-id
+ You need a root with password. You the guest root is passwordless, go to the guest system and set up the password:
Guest
sudo passwd
+ Send the generated public key:
Host
ssh-copy-id -p 10022 -i ~/.ssh/qemukey root@localhost
+ Reset the password in the guest system:
Guest
sudo passwd -l root
  1. Manually
    • Send a public key via
scp

:

Host
scp -P 10022 ./qemukey.pub root@localhost:/root/.ssh/
+ Login to the guest and set up new authorized key:
Guest
cat /root/.ssh/qemukey.pub >> /root/.ssh/authorized_keys
/etc/init.d/ssh restart
+ Or mount device locally, put the public key to the .ssh directory, and concatenate to authorized_keys.
  1. Fix the
/etc/ssh/sshd_config

on the guest:

PasswordAuthentication no
PermitRootLogin without-password
  1. Restart SSH daemon on the guest:
Guest
/etc/init.d/ssh restart
  1. Connect via ssh:
Host
ssh root@localhost -p 10022 -i ./qemukey

Viola! You don’t need the password and you can automate the remote QEMU guest.

Binaries used in the examples

  1. wheezy.qcow2 (i386) bootable Debian “Wheezy” image a QEMU copy-on-write format. Login/password: “root”/”root”, and “user”/”user”.
wget https://people.debian.org/~aurel32/qemu/i386/debian_wheezy_i386_standard.qcow2 -O wheezy.qcow2
  1. wheezy.img (i386) non-bootable Debian “Wheezy” image (without kernel) to use with own kernel (-kernel vmlinuz ).
wget https://storage.googleapis.com/syzkaller/wheezy.img
  1. vmlinuz (i386) compressed bootable Linux kernel. Options:
  2. Build from the scratch: Build Android Kernel and Run on QEMU with Minimal Environment: Step by Step.

  3. Download from Ubuntu repository ( WARNING! Port forwarding will NOT work):

wget http://security.ubuntu.com/ubuntu/pool/main/l/linux-signed-azure/linux-image-4.15.0-1036-azure_4.15.0-1036.38~14.04.2_amd64.deb
ar x linux-image-4.15.0-1036-azure_4.15.0-1036.38~14.04.2_amd64.deb
tar xf data.tar.xz ./boot/vmlinuz-4.15.0-1036-azure
cp ./boot/vmlinuz-4.15.0-1036-azure ./vmlinuz
  1. You can try your host’s linux kernel passing one to the QEMU guest ( WARNING! You could have problems either with port forwarding, or with a block device):

bash
sudo cp /boot/vmlinuz-$(uname -r) ./
WARNING! Ubuntu’s vmlinuz doesn’t contain drivers for QEMU emulated network card devices (NIC). Debian’s vmlinuz doesn’t have prebuilt drivers to load a raw image from /dev/sda device.

Original: https://www.cnblogs.com/schips/p/15489856.html
Author: schips
Title: 如何设置 QEMU 输出到控制台并使用 Shell 脚本自动化

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529530/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [20220302]oracle如何定位使用library cache mutex 2.txt

    [20220302]oracle如何定位使用library cache mutex 2.txt –//这个问题实际上困扰我很久,我开始以为library cache b…

    Linux 2023年6月13日
    074
  • Linux ARMv7中断向量表搬移(2)【转】

    经历过kernel的汇编阶段,进入C语言start_kernel后对中断向量表的位置进行搬移,搬移函数是early_trap_init。 early_trap_init函数的调用流…

    Linux 2023年6月8日
    099
  • 操作系统之虚拟内存总结

    前言 操作系统为每个进程提供了一个假象:它拥有属于自己的大量的私有内存,可以有巨大的连续地址空间放入自己的代码和数据。用户程序中访问的地址都是虚拟地址,需要经过操作系统和硬件的协同…

    Linux 2023年6月7日
    0133
  • shell脚本echo打印错位

    问题描述 在脚本中使用curl命令请求Jenkins的API获取job的编号,随后将编号和其他字符串拼接后,使用echo命令打印出来,但打印后字符串错位了。 脚本大致如下: num…

    Linux 2023年6月8日
    0108
  • SQLI-LABS(Less-1)

    Less-1(GET-Error-Single quotes-String) 打开Less-1页面,可以看到页面中间有一句 Please input the ID as param…

    Linux 2023年6月6日
    078
  • K8s-二进制安装

    K8S-二进制安装使用 1.IP总规划 服务类型 ip地址 组件 k8s-master01 etcd集群节点1 192.168.80.20 kube-apiserver、kube-…

    Linux 2023年6月13日
    093
  • Jenkins中HTML报告无法正常显示问题解决

    自动化结果生成了HTML报告,但是在Jenkins中打开报告却显示空白,打开控制台,可以看到该报错 参考https://www.jenkins.io/doc/book/securi…

    Linux 2023年6月6日
    0101
  • 如何在 pyqt 中实现桌面歌词

    前言 酷狗、网抑云和 QQ 音乐都有桌面歌词功能,这篇博客也将使用 pyqt 实现桌面歌词功能,效果如下图所示: 代码实现 桌面歌词部件 LyricWidget 在 paintEv…

    Linux 2023年6月7日
    098
  • Redis 经验谈

    新浪作为全世界最大的Redis用户,在开发和运维方面有非常多的经验。本文作者来自新浪,希望能为业界提供一些亲身经历,让大家少走弯路。 使用初衷 从2010年上半年起,我们就开始尝试…

    Linux 2023年5月28日
    086
  • UWP 在XAML设计器中使用设计时数据

    1. 功能解释 有些布局没有数据很难进行可视化。 在本文档中,我们将审查从事桌面项目的开发人员可在 XAML 设计器中模拟数据的一种方法。 此方法是使用现有可忽略的”d…

    Linux 2023年6月13日
    088
  • @EnableFeignClients注解源码解析

    转载请注明出处: @EnableFeignClients 注解定义的源码 这个注解通过@Import注解导入一个配置类FeignClientsRegistrar.class ;Fe…

    Linux 2023年6月14日
    091
  • 容器的监控和日志管理

    一、Docker监控工具和使用 1、Docker自带的监控命令 监控容器最简单的方法是使用Docker自带的监控命令:docker ps、docker top、docker sta…

    Linux 2023年6月8日
    087
  • FusionAccess桌面云安装(windows AD方法)

    创建FusionAccess虚拟机 选择自定义 默认兼容 选择稍后安装操作系统 选择Linux SUSE Linux 名字位置自己选择 选择最少4个处理器 选择最少8G内存 选择仅…

    Linux 2023年6月8日
    0103
  • 正则表达

    常用表达式 单字符:. : 除换行以外所有字符[] :[aoe] [a-w] 匹配集合中任意一个字符\d :数字 [0-9]\D : 非数字\w :数字、字母、下划线、中文\W :…

    Linux 2023年6月13日
    075
  • ceph存储集群搭建以及介绍

    转载至https://blog.csdn.net/weixin_44989941/article/details/123370410 Original: https://www.c…

    Linux 2023年6月14日
    086
  • 工程课Linux第一节笔记

    上课笔记 文件系统结构 /根目录 /bin/ 存放系统命令,普通用户与root都可以执行 /etc/ 配置文件保存位置 /lib/ 系统调用的函数库保存位置 /var/ 目录用于存…

    Linux 2023年6月6日
    070
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球