summaryrefslogtreecommitdiff
path: root/src/qemu.sh
blob: 0300c7165b8b44406e704d5704761a6f9dc694ce (plain)
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
118
119
120
121
122
123
124
125
126
127
128
129
#!/bin/sh

. samizdat-paths.sh

case "$(id -u)" in
  0) sudo= ;;
  *) sudo=sudo ;;
esac

iso=${samizdat_iso_dir}/samizdat.iso
disk=${samizdat_iso_dir}/samizdat.disk.img
layered=${samizdat_iso_dir}/${iso%.iso}.layered.iso

[ -f "$layered" ] && iso=$layered

[ "$1" ] && iso=$1

[ "$NO_NET" ] || USE_NET=y

NET='tap,ifname=tap0,script=no,downscript=no'

[ "$SLOW_BOOT" ] || QEMU_LOADS_LINUX=y

# To use qemu built-in pxe boot server:
# NET='user,tftp=isolinux,bootfile=/pxelinux.0'

nbd_filename=samizdat.btrfs
[ "$NBD_FILENAME" ] && nbd_filename=$NBD_FILENAME

initrd=${samizdat_isolinux_dir}/linux/initrd.img
kernel=${samizdat_isolinux_dir}/linux/vmlinuz
kcmdline_CDROM='boot=samizdat components quiet'
kcmdline_CDROM_NET="${kcmdline_CDROM} nbdroot=,${nbd_filename}, nbddev=/dev/nbd0 ip=dhcp"
kcmdline_NET="${kcmdline_CDROM_NET} netkeys"

find_mac()
{
  start_mac=$1
  for mac in $(ip link show | grep link/ether | (read _ mac _; echo $mac | tr : -)); do
    if [ "${mac%??}" = "${start_mac%??}" ]; then
      prefix=${mac%??}
      suffix=$(printf %x $(( 0x${mac##*-} + 1 )))
      MAC=${prefix}${suffix}
      return
    fi
  done
  MAC=$start_mac
}
find_mac 52-54-00-12-34-56

kcmdline_BOOTIF="BOOTIF=01-$MAC"

set --
if [ "$USE_ISO" ]; then
    set -- "$@" -cdrom "$iso"
    if [ "$QEMU_LOADS_LINUX" ]; then
        set -- "$@" -initrd "$initrd" -kernel "$kernel"
        if [ "$NO_NET" ]; then
            set -- "$@" -append "$kcmdline_CDROM"
        else
            set -- "$@" -append "$kcmdline_CDROM_NET"
        fi
    else
        set -- "$@" -boot d
    fi
else
    if [ "$QEMU_LOADS_LINUX" ]; then
        set -- "$@" -initrd "$initrd" -kernel "$kernel" -append "$kcmdline_NET $kcmdline_BOOTIF"
    else
        set -- "$@" -boot n
    fi
fi

case $(arch) in
    x86_64) qemu=qemu-system-x86_64 ;;
    *) qemu=qemu-system-i386 ;;
esac

try_fallocate()
{
    for size in "$@"; do
        fallocate -l "$size" "$disk"~tmp || continue
        mv "$disk"~tmp "$disk"
        return
    done
    false
}

if [ ! -e "$disk" ]; then
    try_fallocate 16GB 8GB 4GB 2GB 1GB ||
        echo "Warning: no virtual disk (could not create $disk)" >&2
fi

if grep -q '^flags.*\<vmx\>' /proc/cpuinfo; then
    kvm='-enable-kvm -cpu host'
    read nested < /sys/module/kvm_intel/parameters/nested
    if [ "$nested" != Y ]; then
        printf '%s\n' \
               'Warning: nested KVM is not available' \
               'Try "make install-nested-kvm"'
    fi
else
    >&2 printf '%s\n' \
        '' \
        'Warning: kernel virtual machine extensions (KVM) not available.' \
        'The VM will be intolerably slow.' \
        'If your hardware supports KVM, you need to enable it in the BIOS.' \
        '' \
        'If you are trying to run qemu in a virtual machine, you need to append' \
        'the kvm-(intel|amd) module parameter "nested=1" on the _host_ machine.' \
        'Use "make install-nested-kvm" to do so.' \
        ''
    kvm=
fi

mem_total=$(grep MemTotal /proc/meminfo | (read _ kb _; echo $((kb / 1024))))
use_mem=640
if [ "$mem_total" -le $((use_mem * 2)) ]; then
  use_mem=$((mem_total / 2))
fi

set -x
$sudo ${qemu} ${kvm} -smp 2 -m ${use_mem} -k en-us \
     -vga qxl \
     -net nic,model=virtio,macaddr=$MAC \
     ${USE_NET:+ -net "$NET"} \
     -rtc base=localtime \
     -drive index=0,media=disk,format=raw,file="$disk" \
     "$@"