forked from rapido-linux/rapido
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vm.sh
executable file
·117 lines (97 loc) · 3.75 KB
/
vm.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/bin/bash
# SPDX-License-Identifier: (LGPL-2.1 OR LGPL-3.0)
# Copyright (C) SUSE LLC 2016-2022, all rights reserved.
RAPIDO_DIR="`dirname $0`"
. "${RAPIDO_DIR}/runtime.vars"
_rt_require_qemu_args
_vm_is_running() {
local vm_num=$1
local vm_pid_file="${QEMU_PID_DIR}/rapido_vm${vm_num}.pid"
[ -f $vm_pid_file ] || return
ps -p "$(head -n1 $vm_pid_file)" > /dev/null && echo "1"
}
_vm_start() {
local vm_num=$1
local vm_pid_file="${QEMU_PID_DIR}/rapido_vm${vm_num}.pid"
local netd_flag netd_mach_id i vm_tap tap_mac n f
local vm_resources=()
local vm_num_kparam="rapido.vm_num=${vm_num}"
local net_conf="${VM_NET_CONF}/vm${vm_num}"
local qemu_netdev=()
local kcmdline=(rd.systemd.unit=dracut-cmdline.service \
"console=$QEMU_KERNEL_CONSOLE" \
$QEMU_EXTRA_KERNEL_PARAMS)
[ -f "$DRACUT_OUT" ] \
|| _fail "no initramfs image at ${DRACUT_OUT}. Run \"cut_X\" script?"
# XXX could use systemd.hostname=, but it requires systemd-hostnamed
n=$(head -n1 "${net_conf}/hostname" 2>/dev/null) \
&& kcmdline+=("rapido.hostname=\"${n}\"")
_rt_qemu_resources_get "${DRACUT_OUT}" vm_resources netd_flag \
|| _fail "failed to get qemu resource parameters"
if [[ -z $netd_flag ]]; then
# this image doesn't require network access
qemu_netdev+=(-net none) # override default (-net nic -net user)
else
# networkd needs a hex unique ID (for dhcp leases, etc.)
# TODO could use value in .network config instead?
netd_mach_id="$(echo $vm_num_kparam | md5sum)" \
|| _fail "failed to generate networkd machine-id"
kcmdline+=(net.ifnames=0 "systemd.machine_id=${netd_mach_id% *}")
[ -d "$net_conf" ] \
|| _fail "$net_conf configuration missing"
n=0
for i in $(ls "$net_conf"); do
[[ $i =~ ^(.*)\.network$ ]] || continue
vm_tap="${BASH_REMATCH[1]}"
# Only attempt to add host IFF_TAP (0x02) devices as
# qemu netdevs. This allows for extra VM virtual device
# creation and configuration via net-conf.
f="$(cat /sys/class/net/${vm_tap}/tun_flags \
2>/dev/null)" || continue
(( (f & 0x2) == 0x2 )) || continue
# calculate a vNIC MAC based on the VM#
# and corresponding host tapdev name.
tap_mac=$(echo "vm${vm_num}.${vm_tap}" | md5sum | sed \
's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/b8:\1:\2:\3:\4:\5/') \
|| _fail "failed to generate vm${vm_num}.${vm_tap} MAC"
# allow guest to [match] net-conf devices based on MAC.
# XXX this could get too long for the kernel. The netd
# [match] entry could instead be appended at cut time.
kcmdline+=("rapido.mac.${vm_tap}=${tap_mac}")
# each entry is expected to match a corresponding tapdev
qemu_netdev+=(
"-device"
"virtio-net,netdev=if${n},mac=${tap_mac}"
"-netdev"
"tap,id=if${n},script=no,downscript=no,ifname=${vm_tap}"
)
((n++))
done
# warn only, as a netdev may be provided via QEMU_EXTRA_ARGS
(( n > 0 )) \
|| _warn "no valid TAP devices found in $net_conf"
fi
# rapido.conf might have specified a shared folder for qemu
if [ -n "$VIRTFS_SHARE_PATH" ]; then
vm_resources+=(-virtfs
"local,path=${VIRTFS_SHARE_PATH},mount_tag=host0,security_model=mapped,id=host0")
fi
$QEMU_BIN \
"${QEMU_ARCH_VARS[@]}" \
"${vm_resources[@]}" \
-kernel "$QEMU_KERNEL_IMG" \
-initrd "$DRACUT_OUT" \
-append "$vm_num_kparam ${kcmdline[*]}" \
-pidfile "$vm_pid_file" \
"${qemu_netdev[@]}" \
$QEMU_EXTRA_ARGS
exit $?
}
# The VMs limit is arbitrary and with the new flexible net-conf we could remove
# it completely. It's up to the user to make sure that enough tap devices have
# been created to satisfy the net-conf/vm# configuration.
for ((i = 1; i <= 100; i++)); do
[ -z "$(_vm_is_running $i)" ] && _vm_start $i
done
# _vm_start exits when done, so we only get here if none were started
_fail "Currently Rapido supports a maximum of 100 VMs"