📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
| 818行目: | 818行目: | ||
シャットダウンを実行する時、ホストOSがロックアップすることが知られている。<br> | シャットダウンを実行する時、ホストOSがロックアップすることが知られている。<br> | ||
<br> | <br> | ||
===== 方法 1 ===== | |||
これを回避する方法は、libvirtフックスクリプトとsystemdユニットを使用して、<br> | これを回避する方法は、libvirtフックスクリプトとsystemdユニットを使用して、<br> | ||
ゲストOSの実行中にホストOSがスリープ状態になることを防ぐ。<br> | ゲストOSの実行中にホストOSがスリープ状態になることを防ぐ。<br> | ||
| 867行目: | 868行目: | ||
上記で作成したデーモンを停止する。<br> | 上記で作成したデーモンを停止する。<br> | ||
sudo systemctl stop libvirt-nosleep.service | sudo systemctl stop libvirt-nosleep.service | ||
<br> | |||
ゲストOSを起動して、スリープが抑制されているかどうかを確認する。<br> | |||
systemd-inhibit --list | |||
<br> | |||
===== 方法 2 ===== | |||
同様に、libvirtフックスクリプトとシェルスクリプトを使用して、ゲストOSの実行中にホストOSがスリープ状態になることを防ぐ方法もある。<br> | |||
<br> | |||
libvirtフックから呼び出す場合、仮想マシンが起動する瞬間に呼び出されるため、確実に仮想マシンが起動し終わるまで待機することが可能である。<br> | |||
sudo vi /usr/local/bin/libvirt-inhibit-sleep.sh | |||
<br> | |||
<syntaxhighlight lang="sh"> | |||
# /usr/local/bin/libvirt-inhibit-sleep.shファイル | |||
#!/bin/bash | |||
# KVMドメインの実行中にスリープを抑制するスクリプト(フック用) | |||
# 引数として仮想マシン名を受け取る | |||
DOMAIN="$1" | |||
# 引数が指定されていない場合はエラー | |||
if [ -z "$DOMAIN" ]; then | |||
echo "Error: No domain name specified" >&2 | |||
exit 1 | |||
fi | |||
# ログファイルの設定(デバッグ用) | |||
LOG_FILE="/var/log/libvirt/hooks/nosleep-${DOMAIN}.log" | |||
mkdir -p /var/log/libvirt/hooks | |||
# ログ関数 | |||
log_message() { | |||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" | |||
} | |||
log_message "Sleep inhibit started for domain: $DOMAIN" | |||
# 仮想マシンが完全に起動するまで少し待機 | |||
# フックはVMの起動処理の初期段階で呼ばれるため | |||
sleep 5 | |||
# 指定されたドメインが存在するか確認 | |||
if ! virsh dominfo "$DOMAIN" &>/dev/null; then | |||
log_message "Error: Domain '$DOMAIN' does not exist" | |||
exit 1 | |||
fi | |||
# スリープを抑制しながら、ドメインの状態を監視 | |||
# ドメインが停止したら、このコマンド全体が終了する | |||
log_message "Starting systemd-inhibit for domain: $DOMAIN" | |||
systemd-inhibit --what=sleep \ | |||
--why="Libvirt domain $DOMAIN is running" \ | |||
--who="libvirt-hook" \ | |||
--mode=block \ | |||
/bin/bash -c " | |||
while virsh domstate '$DOMAIN' 2>/dev/null | grep -q 'running'; do | |||
sleep 60 | |||
done | |||
" | |||
log_message "Domain '$DOMAIN' has stopped, releasing sleep inhibit" | |||
exit 0 | |||
</syntaxhighlight> | |||
<br> | |||
このシェルスクリプトに実行権限を付加する。<br> | |||
sudo chmod u+x /usr/local/bin/libvirt-inhibit-sleep.sh | |||
<br> | |||
次に、libvirtフックスクリプトを作成する。<br> | |||
libvirtフックスクリプトは、libvirtは仮想マシンの状態が変わるたびに、このスクリプトを呼び出す。<br> | |||
その時、仮想マシンの名前、何が起きたか (start, stopped等)、それがbegin (開始) なのか end (終了) なのかという情報を引数として渡す。<br> | |||
libvirtフックスクリプトは、「仮想マシンが起動を開始した」というイベント (started / begin) を検知すると、libvirt-inhibit-sleep.shをバックグラウンドで起動する。<br> | |||
<br> | |||
フックスクリプト自体は短時間で終了する必要があるため、nohupコマンドを使用する。<br> | |||
スリープ抑制は長時間実行され続ける必要があるため、バックグラウンドプロセスとして独立させる。<br> | |||
<br> | |||
sudo vi /etc/libvirt/hooks/qemu | |||
<br> | |||
<syntaxhighlight lang="sh"> | |||
# /etc/libvirt/hooks/qemuファイル | |||
#!/bin/bash | |||
# Libvirt QEMU hook script | |||
# 仮想マシンの起動・停止時にスリープ抑制を制御する | |||
# このスクリプトは以下の引数で呼ばれます: | |||
# $1 = 仮想マシン名(guest name) | |||
# $2 = 動作(operation): start, stopped, など | |||
# $3 = サブ動作(sub-operation): begin, end | |||
# $4 = 追加引数(あれば) | |||
GUEST_NAME="$1" | |||
OPERATION="$2" | |||
SUB_OPERATION="$3" | |||
# ログファイルの設定 | |||
HOOK_LOG="/var/log/libvirt/hooks/qemu-hook.log" | |||
mkdir -p /var/log/libvirt/hooks | |||
# ログ関数 | |||
log_message() { | |||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $GUEST_NAME - $OPERATION/$SUB_OPERATION - $1" >> "$HOOK_LOG" | |||
} | |||
log_message "Hook called" | |||
# 仮想マシンが起動した時 | |||
if [ "$OPERATION" = "started" ] && [ "$SUB_OPERATION" = "begin" ]; then | |||
log_message "VM starting, launching sleep inhibit script" | |||
# スリープ抑制スクリプトをバックグラウンドで実行 | |||
# nohupを使用して、このフックスクリプトが終了しても継続実行させる | |||
nohup /usr/local/bin/libvirt-inhibit-sleep.sh "$GUEST_NAME" >> /var/log/libvirt/hooks/nosleep-${GUEST_NAME}.log 2>&1 & | |||
# プロセスIDをファイルに保存(将来的な管理用) | |||
echo $! > "/var/run/libvirt-nosleep-${GUEST_NAME}.pid" | |||
log_message "Sleep inhibit script launched with PID: $!" | |||
fi | |||
# 仮想マシンが停止した時 | |||
# スリープ抑制スクリプトは自動的に終了するはずだが、念のため確認 | |||
if [ "$OPERATION" = "stopped" ] && [ "$SUB_OPERATION" = "end" ]; then | |||
log_message "VM stopped" | |||
# PIDファイルが存在すれば削除 | |||
if [ -f "/var/run/libvirt-nosleep-${GUEST_NAME}.pid" ]; then | |||
rm -f "/var/run/libvirt-nosleep-${GUEST_NAME}.pid" | |||
log_message "Cleaned up PID file" | |||
fi | |||
fi | |||
exit 0 | |||
</syntaxhighlight> | |||
<br> | |||
ログファイルを配置するディレクトリを作成する。<br> | |||
sudo mkdir -p /var/log/libvirt/hooks | |||
<br> | |||
ゲストOSを起動して、スリープが抑制されているかどうかを確認する。<br> | |||
systemd-inhibit --list | |||
<br><br> | <br><br> | ||