searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

QEMU Guest Agent浅析

2023-10-23 02:08:26
661
0

一、概述

    QEMU Guest Agent是运行在虚拟机内部的一个守护程序(qemu-guest-agent.service),用它来辅助Hypervisor实现对Guest 虚拟机的管理。

    通过QEMU Guest Agent可以实现在宿主机对VM发送指令进行管理,例如:查看VM内IP地址、CPU、内存信息等。这种通信不依赖网络,而是通过virtio-serial的方式使用virtio传递消息,对虚拟机和主机的网络设置没有任何要求,且效率更高,类似于VMware Tools。

二、QGA部署

1.通过libvirt启动虚拟机,在XML中增加channel配置

    <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/org.qemu.guest_agent.0.101a01fe-ee02-1de3-2922-9718b417332d.sock'/>
      <target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
      <alias name='channel0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>

其中,path为virtio通道在主机本地的映射节点文件,宿主机可以基于此socket文件,通过unix sock实现与虚拟机的通信

2.启动vm,并在vm中安装并启动qemu-ga,linux和windows均支持qemu-ga

linux:

yum install qemu-guest-agent
setenforce 0 
systemctl restart qemu-guest-agent.service

 

3.查看vm内qemu-ga进程

[root@VM-170 network-scripts]# systemctl status qemu-guest-agent
● qemu-guest-agent.service - QEMU Guest Agent
     Loaded: loaded (/usr/lib/systemd/system/qemu-guest-agent.service; enabled;>
     Active: active (running) since Thu 2022-12-29 17:20:21 CST; 4 days ago
   Main PID: 837 (qemu-ga)
      Tasks: 2 (limit: 4369)
     Memory: 1.0M
        CPU: 2ms
     CGroup: /system.slice/qemu-guest-agent.service
             └─ 837 /usr/bin/qemu-ga --method=virtio-serial --path=/dev/virtio->

Dec 29 17:20:21 localhost systemd[1]: Started qemu-guest-agent.service - QEMU G>
// service配置
[root@VM-170 network-scripts]# cat /usr/lib/systemd/system/qemu-guest-agent.service 
[Unit]
Description=QEMU Guest Agent
BindsTo=dev-virtiox2dports-org.qemu.guest_agent.0.device
After=dev-virtiox2dports-org.qemu.guest_agent.0.device
IgnoreOnIsolate=True

[Service]
UMask=0077
EnvironmentFile=/etc/sysconfig/qemu-ga
ExecStart=/usr/bin/qemu-ga 
  --method=virtio-serial 
  --path=/dev/virtio-ports/org.qemu.guest_agent.0 
  --blacklist=${BLACKLIST_RPC} 
  -F${FSFREEZE_HOOK_PATHNAME}
Restart=always
RestartSec=0

[Install]
WantedBy=dev-virtiox2dports-org.qemu.guest_agent.0.device

在/dev/virtio-ports目录下会生成串口设备

[root@VM-170 network-scripts]# ll /dev/virtio-ports/
total 0
lrwxrwxrwx 1 root root 11 Dec 29 17:20 org.qemu.guest_agent.0 -> ../vport2p1
[root@VM-170 network-scripts]# ll /dev/vport2p1 
crw------- 1 root root 238, 1 Dec 29 17:20 /dev/vport2p1

qemu-ga服务配置文件/etc/sysconfig/qemu-ga

[root@VM-170 network-scripts]# cat /etc/sysconfig/qemu-ga 
# This is a systemd environment file, not a shell script.
# It provides settings for "/lib/systemd/system/qemu-guest-agent.service".

# Comma-separated blacklist of RPCs to disable, or empty list to enable all.
#
# You can get the list of RPC commands using "qemu-ga --blacklist='?'".
# There should be no spaces between commas and commands in the blacklist.
# 禁用指定的指令
#BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status

# Fsfreeze hook script specification.
#
# FSFREEZE_HOOK_PATHNAME=/dev/null           : disables the feature.
#
# FSFREEZE_HOOK_PATHNAME=/path/to/executable : enables the feature with the
# specified binary or shell script.
#
# FSFREEZE_HOOK_PATHNAME=                    : enables the feature with the
# default value (invoke "qemu-ga --help" to interrogate).
FSFREEZE_HOOK_PATHNAME=/etc/qemu-ga/fsfreeze-hook

ubuntu init.d方式

root@vm-993:~# cat /etc/init.d/qemu-guest-agent 
#! /bin/sh
### BEGIN INIT INFO
# Provides:          qemu-guest-agent
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: QEMU Guest Agent startup script
# Description:       Start the QEMU Guest Agent if we're running
#                    in a QEMU virtual machine
### END INIT INFO

# Author: Michael Tokarev <mjt@tls.msk.ru>

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="QEMU Guest Agent"
NAME=qemu-ga
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$NAME.pid

# config
DAEMON_ARGS=""
# default transport
TRANSPORT=virtio-serial:/dev/virtio-ports/org.qemu.guest_agent.0

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/qemu-guest-agent ] && . /etc/default/qemu-guest-agent

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that checks whenever system has necessary environment
# It also splits $TRANSPORT into $method and $path
#
do_check_transport() {
	method=${TRANSPORT%%:*}; path=${TRANSPORT#*:}
	case "$method" in
	    virtio-serial | isa-serial)
		if [ ! -e "$path" ]; then
		    log_warning_msg "$NAME: transport endpoint not found, not starting"
		    return 1
		fi
		;;
	esac
}

#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started
	start-stop-daemon -Sq -p $PIDFILE -x $DAEMON --test > /dev/null 
		|| return 1
	start-stop-daemon -Sq -p $PIDFILE -x $DAEMON -- --daemonize 
		$DAEMON_ARGS -m "$method" -p "$path" 
		|| return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
	start-stop-daemon -Kq --retry=TERM/30/KILL/5 -p $PIDFILE --name $NAME
}

case "$1" in
  start)
	do_check_transport || exit 0
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" $NAME
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" $NAME
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  status)
	status_of_proc "$DAEMON" $NAME && exit 0 || exit $?
	;;
  restart|force-reload)	# we do not support reload
	do_check_transport || exit 0
	log_daemon_msg "Restarting $DESC" $NAME
	do_stop
	case "$?" in
	  0|1)
		do_start
		case "$?" in
			0) log_end_msg 0 ;;
			1) log_end_msg 1 ;; # Old process is still running
			*) log_end_msg 1 ;; # Failed to start
		esac
		;;
	  *)
		# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
  *)
	echo "Usage: /etc/init.d/qemu-guest-agent {start|stop|status|restart|force-reload}" >&2
	exit 3
	;;
esac

:

4.如果串口name为org.qemu.guest_agent.0,可以通过virsh qemu-agent-command方式通信,QGA为了数据安全性,大部分命令采用异步、base64加密传输

$ virsh qemu-agent-command 101a01fe-ee02-1de3-2922-9718b417332d '{"execute": "guest-exec", "arguments": {"path": "/bin/sh",  "capture-output": true, "arg": ["-c", "ip a"]}}'
{"return":{"pid":11510}}

$ virsh qemu-agent-command 101a01fe-ee02-1de3-2922-9718b417332d '{"execute": "guest-exec-status", "arguments": {"pid": '11510'}}'
{"return":{"exitcode":0,"out-data":"MTogbG86IDxMT09QQkFDSyxVUCxMT1dFUl9VUD4gbXR1IDY1NTM2IHFkaXNjIG5vcXVldWUgc3RhdGUgVU5LTk9XTiBncm91cCBkZWZhdWx0IHFsZW4gMTAwMAogICAgbGluay9sb29wYmFjayAwMDowMDowMDowMDowMDowMCBicmQgMDA6MDA6MDA6MDA6MDA6MDAKICAgIGluZXQgMTI3LjAuMC4xLzggc2NvcGUgaG9zdCBsbwogICAgICAgdmFsaWRfbGZ0IGZvcmV2ZXIgcHJlZmVycmVkX2xmdCBmb3JldmVyCiAgICBpbmV0NiA6OjEvMTI4IHNjb3BlIGhvc3QgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIKMjogZXRoMDogPEJST0FEQ0FTVCxNVUxUSUNBU1QsVVAsTE9XRVJfVVA+IG10dSAxNTAwIHFkaXNjIGZxX2NvZGVsIHN0YXRlIFVQIGdyb3VwIGRlZmF1bHQgcWxlbiAxMDAwCiAgICBsaW5rL2V0aGVyIGZhOjE2OjNlOjE4OmM5OjExIGJyZCBmZjpmZjpmZjpmZjpmZjpmZgogICAgYWx0bmFtZSBlbnAwczMKICAgIGFsdG5hbWUgZW5zMwogICAgaW5ldCAxMC4xMDAuMTAuNzYvMjQgYnJkIDEwLjEwMC4xMC4yNTUgc2NvcGUgZ2xvYmFsIGR5bmFtaWMgbm9wcmVmaXhyb3V0ZSBldGgwCiAgICAgICB2YWxpZF9sZnQgMzE0OTM2Mzcyc2VjIHByZWZlcnJlZF9sZnQgMzE0OTM2Mzcyc2VjCiAgICBpbmV0NiAxMDA6MToxN2U6ZDgwMDphMDY2OjQyZTY6NThkMjphMjAyLzEyOCBzY29wZSBnbG9iYWwgZHluYW1pYyBub3ByZWZpeHJvdXRlIAogICAgICAgdmFsaWRfbGZ0IDMxNDkzNjY4NXNlYyBwcmVmZXJyZWRfbGZ0IDMxNDkzNjM4NXNlYwogICAgaW5ldDYgZmU4MDo6ZGQyNDo0Y2UzOmIzOWI6ZWZkYi82NCBzY29wZSBsaW5rIG5vcHJlZml4cm91dGUgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIKMzogZXRoMTogPEJST0FEQ0FTVCxNVUxUSUNBU1QsVVAsTE9XRVJfVVA+IG10dSAxNTAwIHFkaXNjIGZxX2NvZGVsIHN0YXRlIFVQIGdyb3VwIGRlZmF1bHQgcWxlbiAxMDAwCiAgICBsaW5rL2V0aGVyIGZhOjE2OjNlOjlmOmRjOjAwIGJyZCBmZjpmZjpmZjpmZjpmZjpmZgogICAgYWx0bmFtZSBlbnAwczQKICAgIGFsdG5hbWUgZW5zNAogICAgaW5ldCAxMC4yMDAuMTAuMTEvMjQgYnJkIDEwLjIwMC4xMC4yNTUgc2NvcGUgZ2xvYmFsIGR5bmFtaWMgbm9wcmVmaXhyb3V0ZSBldGgxCiAgICAgICB2YWxpZF9sZnQgMzE0OTM2Mzczc2VjIHByZWZlcnJlZF9sZnQgMzE0OTM2Mzczc2VjCiAgICBpbmV0NiAxMDA6MToxNTQ6MjEwMDpkODM3OjgwY2Q6Nzc0OTo1ZDI2LzEyOCBzY29wZSBnbG9iYWwgZHluYW1pYyBub3ByZWZpeHJvdXRlIAogICAgICAgdmFsaWRfbGZ0IDMxNDkzNjY4NHNlYyBwcmVmZXJyZWRfbGZ0IDMxNDkzNjM4NHNlYwogICAgaW5ldDYgZmU4MDo6YTRlNzo5MzljOjY3ZTg6MTE3Ni82NCBzY29wZSBsaW5rIG5vcHJlZml4cm91dGUgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIK","exited":true}}

$ echo MTogbG86IDxMT09QQkFDSyxVUCxMT1dFUl9VUD4gbXR1IDY1NTM2IHFkaXNjIG5vcXVldWUgc3RhdGUgVU5LTk9XTiBncm91cCBkZWZhdWx0IHFsZW4gMTAwMAogICAgbGluay9sb29wYmFjayAwMDowMDowMDowMDowMDowMCBicmQgMDA6MDA6MDA6MDA6MDA6MDAKICAgIGluZXQgMTI3LjAuMC4xLzggc2NvcGUgaG9zdCBsbwogICAgICAgdmFsaWRfbGZ0IGZvcmV2ZXIgcHJlZmVycmVkX2xmdCBmb3JldmVyCiAgICBpbmV0NiA6OjEvMTI4IHNjb3BlIGhvc3QgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIKMjogZXRoMDogPEJST0FEQ0FTVCxNVUxUSUNBU1QsVVAsTE9XRVJfVVA+IG10dSAxNTAwIHFkaXNjIGZxX2NvZGVsIHN0YXRlIFVQIGdyb3VwIGRlZmF1bHQgcWxlbiAxMDAwCiAgICBsaW5rL2V0aGVyIGZhOjE2OjNlOjE4OmM5OjExIGJyZCBmZjpmZjpmZjpmZjpmZjpmZgogICAgYWx0bmFtZSBlbnAwczMKICAgIGFsdG5hbWUgZW5zMwogICAgaW5ldCAxMC4xMDAuMTAuNzYvMjQgYnJkIDEwLjEwMC4xMC4yNTUgc2NvcGUgZ2xvYmFsIGR5bmFtaWMgbm9wcmVmaXhyb3V0ZSBldGgwCiAgICAgICB2YWxpZF9sZnQgMzE0OTM2Mzcyc2VjIHByZWZlcnJlZF9sZnQgMzE0OTM2Mzcyc2VjCiAgICBpbmV0NiAxMDA6MToxN2U6ZDgwMDphMDY2OjQyZTY6NThkMjphMjAyLzEyOCBzY29wZSBnbG9iYWwgZHluYW1pYyBub3ByZWZpeHJvdXRlIAogICAgICAgdmFsaWRfbGZ0IDMxNDkzNjY4NXNlYyBwcmVmZXJyZWRfbGZ0IDMxNDkzNjM4NXNlYwogICAgaW5ldDYgZmU4MDo6ZGQyNDo0Y2UzOmIzOWI6ZWZkYi82NCBzY29wZSBsaW5rIG5vcHJlZml4cm91dGUgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIKMzogZXRoMTogPEJST0FEQ0FTVCxNVUxUSUNBU1QsVVAsTE9XRVJfVVA+IG10dSAxNTAwIHFkaXNjIGZxX2NvZGVsIHN0YXRlIFVQIGdyb3VwIGRlZmF1bHQgcWxlbiAxMDAwCiAgICBsaW5rL2V0aGVyIGZhOjE2OjNlOjlmOmRjOjAwIGJyZCBmZjpmZjpmZjpmZjpmZjpmZgogICAgYWx0bmFtZSBlbnAwczQKICAgIGFsdG5hbWUgZW5zNAogICAgaW5ldCAxMC4yMDAuMTAuMTEvMjQgYnJkIDEwLjIwMC4xMC4yNTUgc2NvcGUgZ2xvYmFsIGR5bmFtaWMgbm9wcmVmaXhyb3V0ZSBldGgxCiAgICAgICB2YWxpZF9sZnQgMzE0OTM2Mzczc2VjIHByZWZlcnJlZF9sZnQgMzE0OTM2Mzczc2VjCiAgICBpbmV0NiAxMDA6MToxNTQ6MjEwMDpkODM3OjgwY2Q6Nzc0OTo1ZDI2LzEyOCBzY29wZSBnbG9iYWwgZHluYW1pYyBub3ByZWZpeHJvdXRlIAogICAgICAgdmFsaWRfbGZ0IDMxNDkzNjY4NHNlYyBwcmVmZXJyZWRfbGZ0IDMxNDkzNjM4NHNlYwogICAgaW5ldDYgZmU4MDo6YTRlNzo5MzljOjY3ZTg6MTE3Ni82NCBzY29wZSBsaW5rIG5vcHJlZml4cm91dGUgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIK | base64 -d
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether fa:16:3e:18:c9:11 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    altname ens3
    inet 10.100.10.76/24 brd 10.100.10.255 scope global dynamic noprefixroute eth0
       valid_lft 314936372sec preferred_lft 314936372sec
    inet6 100:1:17e:d800:a066:42e6:58d2:a202/128 scope global dynamic noprefixroute 
       valid_lft 314936685sec preferred_lft 314936385sec
    inet6 fe80::dd24:4ce3:b39b:efdb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether fa:16:3e:9f:dc:00 brd ff:ff:ff:ff:ff:ff
    altname enp0s4
    altname ens4
    inet 10.200.10.11/24 brd 10.200.10.255 scope global dynamic noprefixroute eth1
       valid_lft 314936373sec preferred_lft 314936373sec
    inet6 100:1:154:2100:d837:80cd:7749:5d26/128 scope global dynamic noprefixroute 
       valid_lft 314936684sec preferred_lft 314936384sec
    inet6 fe80::a4e7:939c:67e8:1176/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

5.如果串口name不是org.qemu.guest.agent.0,则可以通过socat指定socket的方式与vm通信

$ socat unix-connect:/var/lib/libvirt/qemu/org.qemu.guest_agent.0.101a01fe-ee02-1de3-2922-9718b417332d.sock readline
0条评论
0 / 1000
b****n
2文章数
0粉丝数
b****n
2 文章 | 0 粉丝
b****n
2文章数
0粉丝数
b****n
2 文章 | 0 粉丝
原创

QEMU Guest Agent浅析

2023-10-23 02:08:26
661
0

一、概述

    QEMU Guest Agent是运行在虚拟机内部的一个守护程序(qemu-guest-agent.service),用它来辅助Hypervisor实现对Guest 虚拟机的管理。

    通过QEMU Guest Agent可以实现在宿主机对VM发送指令进行管理,例如:查看VM内IP地址、CPU、内存信息等。这种通信不依赖网络,而是通过virtio-serial的方式使用virtio传递消息,对虚拟机和主机的网络设置没有任何要求,且效率更高,类似于VMware Tools。

二、QGA部署

1.通过libvirt启动虚拟机,在XML中增加channel配置

    <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/org.qemu.guest_agent.0.101a01fe-ee02-1de3-2922-9718b417332d.sock'/>
      <target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
      <alias name='channel0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>

其中,path为virtio通道在主机本地的映射节点文件,宿主机可以基于此socket文件,通过unix sock实现与虚拟机的通信

2.启动vm,并在vm中安装并启动qemu-ga,linux和windows均支持qemu-ga

linux:

yum install qemu-guest-agent
setenforce 0 
systemctl restart qemu-guest-agent.service

 

3.查看vm内qemu-ga进程

[root@VM-170 network-scripts]# systemctl status qemu-guest-agent
● qemu-guest-agent.service - QEMU Guest Agent
     Loaded: loaded (/usr/lib/systemd/system/qemu-guest-agent.service; enabled;>
     Active: active (running) since Thu 2022-12-29 17:20:21 CST; 4 days ago
   Main PID: 837 (qemu-ga)
      Tasks: 2 (limit: 4369)
     Memory: 1.0M
        CPU: 2ms
     CGroup: /system.slice/qemu-guest-agent.service
             └─ 837 /usr/bin/qemu-ga --method=virtio-serial --path=/dev/virtio->

Dec 29 17:20:21 localhost systemd[1]: Started qemu-guest-agent.service - QEMU G>
// service配置
[root@VM-170 network-scripts]# cat /usr/lib/systemd/system/qemu-guest-agent.service 
[Unit]
Description=QEMU Guest Agent
BindsTo=dev-virtiox2dports-org.qemu.guest_agent.0.device
After=dev-virtiox2dports-org.qemu.guest_agent.0.device
IgnoreOnIsolate=True

[Service]
UMask=0077
EnvironmentFile=/etc/sysconfig/qemu-ga
ExecStart=/usr/bin/qemu-ga 
  --method=virtio-serial 
  --path=/dev/virtio-ports/org.qemu.guest_agent.0 
  --blacklist=${BLACKLIST_RPC} 
  -F${FSFREEZE_HOOK_PATHNAME}
Restart=always
RestartSec=0

[Install]
WantedBy=dev-virtiox2dports-org.qemu.guest_agent.0.device

在/dev/virtio-ports目录下会生成串口设备

[root@VM-170 network-scripts]# ll /dev/virtio-ports/
total 0
lrwxrwxrwx 1 root root 11 Dec 29 17:20 org.qemu.guest_agent.0 -> ../vport2p1
[root@VM-170 network-scripts]# ll /dev/vport2p1 
crw------- 1 root root 238, 1 Dec 29 17:20 /dev/vport2p1

qemu-ga服务配置文件/etc/sysconfig/qemu-ga

[root@VM-170 network-scripts]# cat /etc/sysconfig/qemu-ga 
# This is a systemd environment file, not a shell script.
# It provides settings for "/lib/systemd/system/qemu-guest-agent.service".

# Comma-separated blacklist of RPCs to disable, or empty list to enable all.
#
# You can get the list of RPC commands using "qemu-ga --blacklist='?'".
# There should be no spaces between commas and commands in the blacklist.
# 禁用指定的指令
#BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status

# Fsfreeze hook script specification.
#
# FSFREEZE_HOOK_PATHNAME=/dev/null           : disables the feature.
#
# FSFREEZE_HOOK_PATHNAME=/path/to/executable : enables the feature with the
# specified binary or shell script.
#
# FSFREEZE_HOOK_PATHNAME=                    : enables the feature with the
# default value (invoke "qemu-ga --help" to interrogate).
FSFREEZE_HOOK_PATHNAME=/etc/qemu-ga/fsfreeze-hook

ubuntu init.d方式

root@vm-993:~# cat /etc/init.d/qemu-guest-agent 
#! /bin/sh
### BEGIN INIT INFO
# Provides:          qemu-guest-agent
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: QEMU Guest Agent startup script
# Description:       Start the QEMU Guest Agent if we're running
#                    in a QEMU virtual machine
### END INIT INFO

# Author: Michael Tokarev <mjt@tls.msk.ru>

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="QEMU Guest Agent"
NAME=qemu-ga
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$NAME.pid

# config
DAEMON_ARGS=""
# default transport
TRANSPORT=virtio-serial:/dev/virtio-ports/org.qemu.guest_agent.0

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/qemu-guest-agent ] && . /etc/default/qemu-guest-agent

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that checks whenever system has necessary environment
# It also splits $TRANSPORT into $method and $path
#
do_check_transport() {
	method=${TRANSPORT%%:*}; path=${TRANSPORT#*:}
	case "$method" in
	    virtio-serial | isa-serial)
		if [ ! -e "$path" ]; then
		    log_warning_msg "$NAME: transport endpoint not found, not starting"
		    return 1
		fi
		;;
	esac
}

#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started
	start-stop-daemon -Sq -p $PIDFILE -x $DAEMON --test > /dev/null 
		|| return 1
	start-stop-daemon -Sq -p $PIDFILE -x $DAEMON -- --daemonize 
		$DAEMON_ARGS -m "$method" -p "$path" 
		|| return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
	start-stop-daemon -Kq --retry=TERM/30/KILL/5 -p $PIDFILE --name $NAME
}

case "$1" in
  start)
	do_check_transport || exit 0
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" $NAME
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" $NAME
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  status)
	status_of_proc "$DAEMON" $NAME && exit 0 || exit $?
	;;
  restart|force-reload)	# we do not support reload
	do_check_transport || exit 0
	log_daemon_msg "Restarting $DESC" $NAME
	do_stop
	case "$?" in
	  0|1)
		do_start
		case "$?" in
			0) log_end_msg 0 ;;
			1) log_end_msg 1 ;; # Old process is still running
			*) log_end_msg 1 ;; # Failed to start
		esac
		;;
	  *)
		# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
  *)
	echo "Usage: /etc/init.d/qemu-guest-agent {start|stop|status|restart|force-reload}" >&2
	exit 3
	;;
esac

:

4.如果串口name为org.qemu.guest_agent.0,可以通过virsh qemu-agent-command方式通信,QGA为了数据安全性,大部分命令采用异步、base64加密传输

$ virsh qemu-agent-command 101a01fe-ee02-1de3-2922-9718b417332d '{"execute": "guest-exec", "arguments": {"path": "/bin/sh",  "capture-output": true, "arg": ["-c", "ip a"]}}'
{"return":{"pid":11510}}

$ virsh qemu-agent-command 101a01fe-ee02-1de3-2922-9718b417332d '{"execute": "guest-exec-status", "arguments": {"pid": '11510'}}'
{"return":{"exitcode":0,"out-data":"MTogbG86IDxMT09QQkFDSyxVUCxMT1dFUl9VUD4gbXR1IDY1NTM2IHFkaXNjIG5vcXVldWUgc3RhdGUgVU5LTk9XTiBncm91cCBkZWZhdWx0IHFsZW4gMTAwMAogICAgbGluay9sb29wYmFjayAwMDowMDowMDowMDowMDowMCBicmQgMDA6MDA6MDA6MDA6MDA6MDAKICAgIGluZXQgMTI3LjAuMC4xLzggc2NvcGUgaG9zdCBsbwogICAgICAgdmFsaWRfbGZ0IGZvcmV2ZXIgcHJlZmVycmVkX2xmdCBmb3JldmVyCiAgICBpbmV0NiA6OjEvMTI4IHNjb3BlIGhvc3QgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIKMjogZXRoMDogPEJST0FEQ0FTVCxNVUxUSUNBU1QsVVAsTE9XRVJfVVA+IG10dSAxNTAwIHFkaXNjIGZxX2NvZGVsIHN0YXRlIFVQIGdyb3VwIGRlZmF1bHQgcWxlbiAxMDAwCiAgICBsaW5rL2V0aGVyIGZhOjE2OjNlOjE4OmM5OjExIGJyZCBmZjpmZjpmZjpmZjpmZjpmZgogICAgYWx0bmFtZSBlbnAwczMKICAgIGFsdG5hbWUgZW5zMwogICAgaW5ldCAxMC4xMDAuMTAuNzYvMjQgYnJkIDEwLjEwMC4xMC4yNTUgc2NvcGUgZ2xvYmFsIGR5bmFtaWMgbm9wcmVmaXhyb3V0ZSBldGgwCiAgICAgICB2YWxpZF9sZnQgMzE0OTM2Mzcyc2VjIHByZWZlcnJlZF9sZnQgMzE0OTM2Mzcyc2VjCiAgICBpbmV0NiAxMDA6MToxN2U6ZDgwMDphMDY2OjQyZTY6NThkMjphMjAyLzEyOCBzY29wZSBnbG9iYWwgZHluYW1pYyBub3ByZWZpeHJvdXRlIAogICAgICAgdmFsaWRfbGZ0IDMxNDkzNjY4NXNlYyBwcmVmZXJyZWRfbGZ0IDMxNDkzNjM4NXNlYwogICAgaW5ldDYgZmU4MDo6ZGQyNDo0Y2UzOmIzOWI6ZWZkYi82NCBzY29wZSBsaW5rIG5vcHJlZml4cm91dGUgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIKMzogZXRoMTogPEJST0FEQ0FTVCxNVUxUSUNBU1QsVVAsTE9XRVJfVVA+IG10dSAxNTAwIHFkaXNjIGZxX2NvZGVsIHN0YXRlIFVQIGdyb3VwIGRlZmF1bHQgcWxlbiAxMDAwCiAgICBsaW5rL2V0aGVyIGZhOjE2OjNlOjlmOmRjOjAwIGJyZCBmZjpmZjpmZjpmZjpmZjpmZgogICAgYWx0bmFtZSBlbnAwczQKICAgIGFsdG5hbWUgZW5zNAogICAgaW5ldCAxMC4yMDAuMTAuMTEvMjQgYnJkIDEwLjIwMC4xMC4yNTUgc2NvcGUgZ2xvYmFsIGR5bmFtaWMgbm9wcmVmaXhyb3V0ZSBldGgxCiAgICAgICB2YWxpZF9sZnQgMzE0OTM2Mzczc2VjIHByZWZlcnJlZF9sZnQgMzE0OTM2Mzczc2VjCiAgICBpbmV0NiAxMDA6MToxNTQ6MjEwMDpkODM3OjgwY2Q6Nzc0OTo1ZDI2LzEyOCBzY29wZSBnbG9iYWwgZHluYW1pYyBub3ByZWZpeHJvdXRlIAogICAgICAgdmFsaWRfbGZ0IDMxNDkzNjY4NHNlYyBwcmVmZXJyZWRfbGZ0IDMxNDkzNjM4NHNlYwogICAgaW5ldDYgZmU4MDo6YTRlNzo5MzljOjY3ZTg6MTE3Ni82NCBzY29wZSBsaW5rIG5vcHJlZml4cm91dGUgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIK","exited":true}}

$ echo MTogbG86IDxMT09QQkFDSyxVUCxMT1dFUl9VUD4gbXR1IDY1NTM2IHFkaXNjIG5vcXVldWUgc3RhdGUgVU5LTk9XTiBncm91cCBkZWZhdWx0IHFsZW4gMTAwMAogICAgbGluay9sb29wYmFjayAwMDowMDowMDowMDowMDowMCBicmQgMDA6MDA6MDA6MDA6MDA6MDAKICAgIGluZXQgMTI3LjAuMC4xLzggc2NvcGUgaG9zdCBsbwogICAgICAgdmFsaWRfbGZ0IGZvcmV2ZXIgcHJlZmVycmVkX2xmdCBmb3JldmVyCiAgICBpbmV0NiA6OjEvMTI4IHNjb3BlIGhvc3QgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIKMjogZXRoMDogPEJST0FEQ0FTVCxNVUxUSUNBU1QsVVAsTE9XRVJfVVA+IG10dSAxNTAwIHFkaXNjIGZxX2NvZGVsIHN0YXRlIFVQIGdyb3VwIGRlZmF1bHQgcWxlbiAxMDAwCiAgICBsaW5rL2V0aGVyIGZhOjE2OjNlOjE4OmM5OjExIGJyZCBmZjpmZjpmZjpmZjpmZjpmZgogICAgYWx0bmFtZSBlbnAwczMKICAgIGFsdG5hbWUgZW5zMwogICAgaW5ldCAxMC4xMDAuMTAuNzYvMjQgYnJkIDEwLjEwMC4xMC4yNTUgc2NvcGUgZ2xvYmFsIGR5bmFtaWMgbm9wcmVmaXhyb3V0ZSBldGgwCiAgICAgICB2YWxpZF9sZnQgMzE0OTM2Mzcyc2VjIHByZWZlcnJlZF9sZnQgMzE0OTM2Mzcyc2VjCiAgICBpbmV0NiAxMDA6MToxN2U6ZDgwMDphMDY2OjQyZTY6NThkMjphMjAyLzEyOCBzY29wZSBnbG9iYWwgZHluYW1pYyBub3ByZWZpeHJvdXRlIAogICAgICAgdmFsaWRfbGZ0IDMxNDkzNjY4NXNlYyBwcmVmZXJyZWRfbGZ0IDMxNDkzNjM4NXNlYwogICAgaW5ldDYgZmU4MDo6ZGQyNDo0Y2UzOmIzOWI6ZWZkYi82NCBzY29wZSBsaW5rIG5vcHJlZml4cm91dGUgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIKMzogZXRoMTogPEJST0FEQ0FTVCxNVUxUSUNBU1QsVVAsTE9XRVJfVVA+IG10dSAxNTAwIHFkaXNjIGZxX2NvZGVsIHN0YXRlIFVQIGdyb3VwIGRlZmF1bHQgcWxlbiAxMDAwCiAgICBsaW5rL2V0aGVyIGZhOjE2OjNlOjlmOmRjOjAwIGJyZCBmZjpmZjpmZjpmZjpmZjpmZgogICAgYWx0bmFtZSBlbnAwczQKICAgIGFsdG5hbWUgZW5zNAogICAgaW5ldCAxMC4yMDAuMTAuMTEvMjQgYnJkIDEwLjIwMC4xMC4yNTUgc2NvcGUgZ2xvYmFsIGR5bmFtaWMgbm9wcmVmaXhyb3V0ZSBldGgxCiAgICAgICB2YWxpZF9sZnQgMzE0OTM2Mzczc2VjIHByZWZlcnJlZF9sZnQgMzE0OTM2Mzczc2VjCiAgICBpbmV0NiAxMDA6MToxNTQ6MjEwMDpkODM3OjgwY2Q6Nzc0OTo1ZDI2LzEyOCBzY29wZSBnbG9iYWwgZHluYW1pYyBub3ByZWZpeHJvdXRlIAogICAgICAgdmFsaWRfbGZ0IDMxNDkzNjY4NHNlYyBwcmVmZXJyZWRfbGZ0IDMxNDkzNjM4NHNlYwogICAgaW5ldDYgZmU4MDo6YTRlNzo5MzljOjY3ZTg6MTE3Ni82NCBzY29wZSBsaW5rIG5vcHJlZml4cm91dGUgCiAgICAgICB2YWxpZF9sZnQgZm9yZXZlciBwcmVmZXJyZWRfbGZ0IGZvcmV2ZXIK | base64 -d
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether fa:16:3e:18:c9:11 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    altname ens3
    inet 10.100.10.76/24 brd 10.100.10.255 scope global dynamic noprefixroute eth0
       valid_lft 314936372sec preferred_lft 314936372sec
    inet6 100:1:17e:d800:a066:42e6:58d2:a202/128 scope global dynamic noprefixroute 
       valid_lft 314936685sec preferred_lft 314936385sec
    inet6 fe80::dd24:4ce3:b39b:efdb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether fa:16:3e:9f:dc:00 brd ff:ff:ff:ff:ff:ff
    altname enp0s4
    altname ens4
    inet 10.200.10.11/24 brd 10.200.10.255 scope global dynamic noprefixroute eth1
       valid_lft 314936373sec preferred_lft 314936373sec
    inet6 100:1:154:2100:d837:80cd:7749:5d26/128 scope global dynamic noprefixroute 
       valid_lft 314936684sec preferred_lft 314936384sec
    inet6 fe80::a4e7:939c:67e8:1176/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

5.如果串口name不是org.qemu.guest.agent.0,则可以通过socat指定socket的方式与vm通信

$ socat unix-connect:/var/lib/libvirt/qemu/org.qemu.guest_agent.0.101a01fe-ee02-1de3-2922-9718b417332d.sock readline
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0