ホストをシャットダウンするときに、KVM 仮想マシンを正常にシャットダウンするにはどうすればよいですか?

ホストをシャットダウンするときに、KVM 仮想マシンを正常にシャットダウンするにはどうすればよいですか?

この疑問をはっきりさせるここから

私は Arch Linux を実行しており、システムとともに頻繁に VM を実行しています。実際、ほとんどの場合です。

私の目標は、次のような動作を生み出すことです。

  • シャットダウン/電源オフ/再起動/停止信号がシステムに送信されます
  • 仮想マシンを正常にシャットダウンする以外のアクションはありません
  • X 秒後に VM が正常にシャットダウンされた場合は、ホスト システムのシャットダウンも続行します。
  • そうでない場合は、別のコマンドを実行します

何から始めればいいのかさえ分からないので、何に取り組むべきか良いアイデアを教えてください。カーネルへの呼び出しを調べることができると思います。

お知らせ下さい。


現在のコード

現時点では、これらのスクリプトを使用してKVM仮想マシンを正常にシャットダウンしていますが、うまくいきます。ただし、ユーザーがシャットダウンまたはリブート彼のシェルを使用します。他のケースでは機能しません。

これらのエイリアス:

alias sudocheck="/bin/bash /home/damiano/.script/sudocheck"
alias sudo="sudocheck "

この機能をトリガーするもの:

#!/bin/bash

# This script checks for what is being passed to sudo.
# If the command passed is poweroff or reboot, it
# launches a custom script instead, that also looks
# fur currently running virtual machines and shuts them.

sudocheck() {
    if [ $1 == "poweroff" ] || [ $1 == "reboot" ]; then
        eval "sudo /home/damiano/.script/graceful $@"
    else
        eval "sudo $@"
    fi
}
sudocheck $@

必要に応じてこのスクリプトを起動します。

#!/bin/bash
i=0
e=0
## if virsh finds VMs running
virsh -c qemu:///system list | awk '{ print $3}' | \
if grep running > /dev/null ; then
    virsh -c qemu:///system list --all | grep running | awk '{print "-c qemu:///system shutdown "$2}' | \
## shuts them dow gracefully
    xargs -L1 virsh
## wait 30 seconds for them to go down
    until (( i >= 30 || e == 1 )) ; do
## check every second for their status
        virsh -c qemu:///system list --all | awk '{ print $3}' | \
        if grep -E '(running|shutdown)' > /dev/null ; then
## keep waiting if still running
            if (( i <= 30 )) ; then
                sleep 1 && let i++ && echo $i
            else
                e=1 && notify-send 'Shutdown has been canceled' 'Please check the status of your virtual machines: seems like even though a stop signal has been sent, some are still running.' --urgency=critical
            fi
        else
## if no machine is running anymore, original power command can be executed
            e=1 && eval $@
        fi
    done
fi

システムユニット

VM の実行を管理するために、次のドラフトも作成しました。

[メールアドレス]

[Unit]
Description=This service manages the execution of the %i virtual machine
Documentation=https://libvirt.org/manpages/virsh.html

[Service]
ExecStartPre=virsh -c qemu:///system
ExecStart=virsh start %i
ExecStop=virsh -c qemu:///system
ExecStop=virsh shutdown %i 
TimeoutStopSec=30
KillMode=none

[Install]
WantedBy=multi-user.target

しかし、どうすればデスクトップ環境をシャットダウンせずにそのままにしておくようにシステムに指示できるでしょうかそれまでVM は正常にシャットダウンされましたか? システムが VM をシャットダウンできない場合は、DE 内でシャットダウンしたいからです。コンピューターがすべてのサービスを停止し、強制的にシャットダウンするまでハングしたままになるのは避けたいのです。

答え1

VM を制御する奇妙な方法です。良い方法は、VM の自動起動と停止に systemd を使用することです。例:

システム[メールアドレス]

[Unit]
Description=QEMU virtual machine

[Service]
Environment="type=system-x86_64" "haltcmd=kill -INT $MAINPID"
EnvironmentFile=/etc/conf.d/qemu.d/%i
ExecStart=/usr/bin/qemu-${type} -name %i -nographic $args
ExecStop=/bin/sh -c ${haltcmd}
TimeoutStopSec=30
KillMode=none

[Install]
WantedBy=multi-user.target

...そしてもちろん、VM を実行するための構成:

1. qemu.d のファイル

type="system-x86_64"

args="-enable-kvm -m 512 -hda /dev/vg0/vm1 -net nic,macaddr=DE:AD:BE:EF:E0:00 \
 -net tap,ifname=tap0 -serial telnet:localhost:7000,server,nowait,nodelay \
 -monitor telnet:localhost:7100,server,nowait,nodelay -vnc :0"

haltcmd="echo 'system_powerdown' | nc localhost 7100" # or netcat/ncat

# You can use other ways to shut down your VM correctly
#haltcmd="ssh powermanager@vm1 sudo poweroff"

...そして別の VM 構成:

: := : 1 行目

args="-enable-kvm -m 512 -hda /srv/kvm/vm2.img -net nic,macaddr=DE:AD:BE:EF:E0:01 \
 -net tap,ifname=tap1 -serial telnet:localhost:7001,server,nowait,nodelay \
 -monitor telnet:localhost:7101,server,nowait,nodelay -vnc :1"

haltcmd="echo 'system_powerdown' | nc localhost 7101"

その他。ArchWikiの貢献者に感謝しますこの記事について

答え2

元の投稿によるドラフトと @Oxyd の回答は、各仮想マシンを個別に制御する必要がある場合に役立ちます。

ただし、シャットダウン/起動したい場合はすべてのVM前述の通り、libvirtゲストを使用することもできます。Libvirt ドキュメント

  • ファイルを編集する/etc/conf.d/libvirt-guestsか、/etc/sysconfig/libvirt-guestsCentOSの場合は設定しON_SHUTDOWN=shutdownSHUTDOWN_TIMEOUT=0
  • libvirt-guestsたとえば、サービスを有効にする必要もあると思いますsystemctl enable libvirt-guestssystemctl start libvirt-guests

関連情報