Debian上でQEMU実行

## 目的  
Debian上でQEMUを実行する。
（以下暫定）
  
## 開発環境  
``` bash:開発環境
master@sv-server:~$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
・・・省略
master@sv-server:~$ lscpu | grep -Ei "(vt-x|amd-v)"
Virtualization:                  VT-x
master@sv-server:~$ lsmod | grep kvm
kvm_intel             327680  0
kvm                   921600  1 kvm_intel
irqbypass              16384  1 kvm
master@sv-server:~$ lsmem | grep "Total online memory"
Total online memory:       4G
```
  
## パッケージ導入  
``` bash:パッケージ導入
sudo apt-get update
sudo apt-get install qemu-system-x86 bridge-utils
```
  
## ブリッジ接続設定  
``` bash:ブリッジ接続設定
sudo cp -p /etc/network/interfaces /etc/network/interfaces.org
sudo sed -i /etc/network/interfaces \
         -e 's/^\(iface ens160 inet\) .*$/\1 manual/' \
         -e '/^iface ens160 inet .*$/a \\nauto br0\niface br0 inet static' \
         -e '$a \\tbridge_ports ens160\n\tbridge_stp off\n#\thwaddress ether '
connmanctl services
connmanctl services ethernet_(MAC ADDR)_cable
sudo connmanctl config ethernet_(MAC ADDR)_cable --ipv4 off --ipv6 off && \
sudo mkdir -p /etc/qemu
echo "allow br0" | sudo tee -a /etc/qemu/bridge.conf > /dev/null
sudo gpasswd -a ${USER} kvm
sudo reboot
```
  
## QEMUテスト  
::: note info
予めpreseed_debian.cfgを入れたISOファイルを用意する。
ここでは[dist_remaster.sh](https://github.com/office-itou/Linux/blob/master/installer/source/dist_remaster.sh)で以下のpreseed_debian.cfgを入れたISOファイルを作成し使用した。
:::
``` bash:QEMUテスト
mkdir -p ~/work
rm -f ~/work/debian11.img
qemu-img create -f raw ~/work/debian11.img 20G
sudo qemu-system-x86_64 \
  -smbios type=0,uefi=on \
  -cpu host -smp 2 -m 2G \
  -machine type=pc,accel=kvm -M q35 \
  -boot once=d \
  -cdrom ~/mkcd/dist_remaster_net/debian-11.3.0-amd64-netinst-preseed.iso \
  -drive file=~/work/debian11.img,media=disk,format=raw \
  -nic bridge,id=br0 \
  -nographic 
```
::: note warn
* -boot <strong>once</strong>=d
onceを忘れるとDVDから起動しインストールが繰り返される
* -cdrom 
IDE接続に設定
:::
  
### preseed.cfg  
::: note info
コンソール画面でのインストールなのでpreseed_debian.cfgに以下の設定を行う。
| 項目      | 説明                           |
| --------- | ----------------------------- |
| ログイン先 | 任意（以下の例では192.168.1.1） |  
| ユーザー名 | installer                     |  
| パスワード | 任意（以下の例ではr00tme）      |  
``` bash:
d-i netcfg/get_ipaddress string 192.168.1.1
d-i anna/choose_modules string network-console
d-i network-console/password password r00tme
d-i network-console/password-again password r00tme
```
:::
  
``` bash:preseed_debian.cfg
#_preseed_V1
# *****************************************************************************
# Contents of the preconfiguration file (for debian) : x86/amd64 [lxde-desktop]
# *****************************************************************************
# == Unattended Installation ==================================================
# d-i auto-install/enable boolean false
# d-i debconf/priority select critical
# d-i debconf/priority select low
  d-i hw-detect/select_modules multiselect usb-storage
# == Localization =============================================================
  d-i localechooser/translation/warn-light boolean true
  d-i localechooser/translation/warn-severe boolean true
  d-i debian-installer/language string ja
  d-i debian-installer/country string JP
  d-i debian-installer/locale string ja_JP.UTF-8
# -- Keyboard selection. ------------------------------------------------------
  d-i console-setup/ask_detect boolean false
  d-i keyboard-configuration/xkb-keymap select jp
  d-i keyboard-configuration/layoutcode string jp
  d-i keyboard-configuration/variant select Japanese
  d-i keyboard-configuration/modelcode string pc105
# == Network configuration ====================================================
# d-i netcfg/target_network_config select Network Manager
  d-i netcfg/choose_interface select auto
# d-i netcfg/choose_interface select ens160
# -- Static network configuration. --------------------------------------------
# d-i netcfg/disable_dhcp boolean true
  d-i netcfg/disable_autoconfig boolean true
  d-i netcfg/dhcp_failed note
  d-i netcfg/dhcp_options select Configure network manually
# -- IPv4 example -------------------------------------------------------------
  d-i netcfg/get_ipaddress string 192.168.1.1
  d-i netcfg/get_netmask string 255.255.255.0
  d-i netcfg/get_gateway string 192.168.1.254
  d-i netcfg/get_nameservers string 192.168.1.254
  d-i netcfg/confirm_static boolean true
# -- IPv6 example -------------------------------------------------------------
# d-i netcfg/get_ipaddress string fc00::2
# d-i netcfg/get_netmask string ffff:ffff:ffff:ffff::
# d-i netcfg/get_gateway string fc00::1
# d-i netcfg/get_nameservers string fc00::1
# d-i netcfg/confirm_static boolean true
# -- hostname and domain names ------------------------------------------------
  d-i netcfg/get_hostname string sv-debian
  d-i netcfg/get_domain string workgroup
# d-i netcfg/hostname string somehost
# == Network console ==========================================================
  d-i anna/choose_modules string network-console
# d-i network-console/authorized_keys_url string http://10.0.0.1/openssh-key
  d-i network-console/password password r00tme
  d-i network-console/password-again password r00tme
# == Mirror settings ==========================================================
# d-i mirror/protocol string ftp
  d-i mirror/country string JP
  d-i mirror/http/hostname string deb.debian.org
  d-i mirror/http/directory string /debian
  d-i mirror/http/proxy string
  d-i mirror/http/mirror select deb.debian.org
# == Account setup ============================================================
  d-i passwd/root-login boolean false
  d-i passwd/make-user boolean true
# -- Root password, either in clear text or encrypted -------------------------
# d-i passwd/root-password password r00tme
# d-i passwd/root-password-again password r00tme
# d-i passwd/root-password-crypted password [crypt(3) hash]
# -- Normal user's password, either in clear text or encrypted ----------------
  d-i passwd/user-fullname string Master
  d-i passwd/username string master
  d-i passwd/user-password password master
  d-i passwd/user-password-again password master
# d-i passwd/user-password-crypted password [crypt(3) hash]
# -----------------------------------------------------------------------------
  d-i user-setup/allow-password-weak boolean true
  d-i user-setup/encrypt-home boolean false
# == Clock and time zone setup ================================================
  d-i clock-setup/utc boolean true
  d-i time/zone select Asia/Tokyo
# -- Controls whether to use NTP to set the clock during the install ----------
  d-i clock-setup/ntp boolean true
# -- NTP server to use. The default is almost always fine here. ---------------
  d-i clock-setup/ntp-server string ntp.nict.jp
# == Partitioning =============================================================
  d-i partman-basicfilesystems/no_swap boolean false
# d-i partman-auto/disk string /dev/nvme0n1
# d-i partman-auto/disk string /dev/nvme0n1 /dev/sda
# d-i partman-auto/disk string /dev/sda
  d-i partman-auto/init_automatically_partition select lvm
  d-i partman-auto/method string lvm
# -----------------------------------------------------------------------------
  d-i partman-md/device_remove_md boolean true
  d-i partman-lvm/device_remove_lvm boolean true
  d-i partman-lvm/device_remove_lvm_span boolean true
  d-i partman-auto/purge_lvm_from_device boolean true
  d-i partman-lvm/confirm boolean true
  d-i partman-lvm/confirm_nooverwrite boolean true
# -----------------------------------------------------------------------------
  d-i partman-auto-lvm/guided_size string max
  d-i partman-auto/choose_recipe select atomic
# -----------------------------------------------------------------------------
  d-i partman-auto-lvm/new_vg_name string system
# -----------------------------------------------------------------------------
# /dev/nvme0n1p1: 512MB: efi
#      nvme0n1p2: 512MB: /boot
#      nvme0n1p3:    -1: vg00
# /dev/sda1     :    -1: vg01
# vg00-root     :    -1: /
# vg01-home     :    -1: /home
#
# d-i partman-auto/expert_recipe string                                       \
#         boot-lvm ::                                                         \
#               512   512   512 free                                          \
#                 $iflabel{ gpt } $reusemethod{ }                             \
#                 method{ efi } format{ }                                     \
#                 device{ /dev/nvme0n1p1 }                                    \
#             .                                                               \
#               512   512   512 ext3                                          \
#                 $primary{ } $bootable{ }                                    \
#                 method{ format } format{ }                                  \
#                 use_filesystem{ } filesystem{ ext3 }                        \
#                 mountpoint{ /boot }                                         \
#                 device{ /dev/nvme0n1p2 }                                    \
#             .                                                               \
#              1024  1024    -1 ext4                                          \
#                 $primary{ }                                                 \
#                 method{ lvm } vg_name{ vg00 }                               \
#                 device{ /dev/nvme0n1p3 }                                    \
#             .                                                               \
#              1024  1024    -1 ext4                                          \
#                 $primary{ }                                                 \
#                 method{ lvm } vg_name{ vg01 }                               \
#                 device{ /dev/sda1 }                                         \
#             .                                                               \
#              1024  1024    -1 ext4                                          \
#                 $lvmok{ } in_vg{ vg00 } lv_name{ root }                     \
#                 method{ format } format{ }                                  \
#                 use_filesystem{ } filesystem{ ext4 }                        \
#                 mountpoint{ / }                                             \
#             .                                                               \
#              1024  1024    -1 ext4                                          \
#                 $lvmok{ } in_vg{ vg01 } lv_name{ home }                     \
#                 method{ format } format{ }                                  \
#                 use_filesystem{ } filesystem{ ext4 }                        \
#                 mountpoint{ /home }                                         \
#             .
# -----------------------------------------------------------------------------
# d-i partman/default_filesystem string btrfs
# -- Force UEFI booting ('BIOS compatibility' will be lost). Default: false. --
  d-i partman-efi/non_efi_system boolean true
# -- Ensure the partition table is GPT - this is required for EFI -------------
# d-i partman-partitioning/choose_label string gpt
# d-i partman-partitioning/default_label string gpt
# -- When disk encryption is enabled, skip wiping the partitions beforehand. --
# d-i partman-auto-crypto/erase_disks boolean false
# -- This makes partman automatically partition without confirmation. ---------
  d-i partman-md/confirm boolean true
  d-i partman-partitioning/confirm_write_new_label boolean true
  d-i partman/choose_partition select finish
  d-i partman/confirm boolean true
  d-i partman/confirm_nooverwrite boolean true
# -- Controlling how partitions are mounted -----------------------------------
# d-i partman/mount_style select uuid
# == Base system installation =================================================
# d-i base-installer/install-recommends boolean true
# d-i base-installer/kernel/image select linux-image-amd64
# == Apt setup ================================================================
  d-i apt-setup/non-free boolean true
  d-i apt-setup/contrib boolean true
  d-i apt-setup/use_mirror boolean true
  d-i apt-setup/services-select multiselect security, updates
  d-i apt-setup/security_host string security.debian.org
  d-i apt-setup/cdrom/set-first boolean false
  d-i apt-setup/cdrom/set-next boolean false
  d-i apt-setup/cdrom/set-failed boolean false
# d-i debian-installer/allow_unauthenticated boolean true
# == Package selection ========================================================
# d-i pkgsel/run_tasksel boolean true
# -----------------------------------------------------------------------------
  tasksel tasksel/first multiselect \
      standard, desktop, laptop, lxde-desktop, \
      ssh-server, dns-server, file-server, print-server
# -----------------------------------------------------------------------------
  d-i pkgsel/include string \
      network-manager network-manager-gnome \
      chrony clamav curl wget rsync inxi \
      build-essential indent vim bc \
      sudo tasksel whois \
      openssh-server \
      bind9 bind9utils dnsutils \
      samba smbclient cifs-utils \
      isc-dhcp-server \
      cups cups-common \
      lxde fonts-noto ibus-mozc mozc-utils-gui \
      libreoffice-help-ja libreoffice-l10n-ja \
      firefox-esr-l10n-ja thunderbird thunderbird-l10n-ja \
      minidlna
#     task-desktop task-japanese task-japanese-desktop task-laptop task-lxde-desktop task-ssh-server
#     open-vm-tools open-vm-tools-desktop
# -----------------------------------------------------------------------------
  d-i pkgsel/install-language-support boolean true
  d-i shared/default-x-display-manager select lightdm
# -- Whether to upgrade packages after debootstrap. ---------------------------
# d-i pkgsel/upgrade select none
# d-i pkgsel/upgrade select safe-upgrade
  d-i pkgsel/upgrade select full-upgrade
  d-i pkgsel/update-policy select unattended-upgrades
# -----------------------------------------------------------------------------
  d-i samba-common/dhcp boolean false
# -----------------------------------------------------------------------------
  popularity-contest popularity-contest/participate boolean false
# == Boot loader installation =================================================
  d-i grub-installer/only_debian boolean true
  d-i grub-installer/bootdev string default
  d-i grub-installer/force-efi-extra-removable boolean true
# d-i preseed/late_command string \
#     in-target --pass-stdout systemctl disable connman.service;
  d-i finish-install/reboot_in_progress note
  d-i cdrom-detect/eject boolean true
# == Preseeding other packages ================================================
# d-i debhelper debconf-utils
#   echo "#_preseed_V1" > file
#   debconf-get-selections --installer >> file
#   debconf-get-selections >> file
#   debconf-set-selections -c preseed.cfg
# == End Of File ==============================================================
```
  
## 課題  
* sudo qemu-system-x86_64…としないと実行時にエラーとなる。  
``` bash:実行時エラー
master@sv-server:~$ qemu-system-x86_64 \
・・・省略
failed to create tun device: Operation not permitted
qemu-system-x86_64: bridge helper failed
```
  
* ネットワークの設定が想定と異なる。  
``` bash:ネットワーク
master@sv-debian:~$ cat /etc/network/interfaces
・・・省略
# The primary network interface
allow-hotplug enp0s2
iface enp0s2 inet static
        address 192.168.1.1/24
        gateway 192.168.1.254
        # dns-* options are implemented by the resolvconf package, if installed
        dns-nameservers 192.168.1.254
        dns-search workgroup
master@sv-debian:~$ ip address show enp0s2
2: enp0s2: <BROADCAST,MULTICAST,DYNAMIC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
・・・省略
    inet 192.168.1.116/24 brd 192.168.1.255 scope global enp0s2
・・・省略
```
  
## おまけ
QEMUをmakeする。  
``` bash:QEMUのmake
cd /usr/src/
sudo apt-get install \
  git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build
sudo apt-get install \
  git-email \
  libaio-dev libbluetooth-dev libcapstone-dev libbrlapi-dev libbz2-dev \
  libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev \
  libibverbs-dev libncurses5-dev libnuma-dev \
  librbd-dev librdmacm-dev \
  libsasl2-dev libsdl2-dev libseccomp-dev libsnappy-dev libssh-dev \
  libvde-dev libvdeplug-dev libvte-2.91-dev libxen-dev liblzo2-dev \
  valgrind xfslibs-dev
sudo apt-get install libnfs-dev libiscsi-dev
sudo git clone https://gitlab.com/qemu-project/qemu.git
cd qemu/
sudo git submodule init
sudo git submodule update --recursive
sudo ./configure
sudo make
sudo make install
```
### 参考
* [Download QEMU - QEMU](https://www.qemu.org/download/)
* [Documentation - QEMU](https://wiki.qemu.org/Documentation)