Skip to content

Instantly share code, notes, and snippets.

@Roliga
Created April 14, 2020 12:00
Show Gist options
  • Select an option

  • Save Roliga/928cd44440f4df74e796e4e1315034bf to your computer and use it in GitHub Desktop.

Select an option

Save Roliga/928cd44440f4df74e796e4e1315034bf to your computer and use it in GitHub Desktop.
Hibernate libvirt VM on host shutdown/sleep.
#!/bin/bash
#
# Usage: hibernate-vm NAME
#
# Hibernates the VM specified in NAME and waits for it to finish shutting down
#
if virsh dompmsuspend "$1" disk; then
echo "Waiting for domain to finish shutting down.." >&2
while ! [ "$(virsh domstate "$1")" == 'shut off' ]; do
sleep 1
done
echo "Domain finished shutting down" >&2
fi
[Unit]
Description=Hibernate VM %I when host shuts down
Requires=virt-guest-shutdown.target
After=libvirt-guests.service
After=libvirtd.service
After=virt-guest-shutdown.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStop=/usr/local/bin/hibernate-vm %i
[Install]
WantedBy=multi-user.target
[Unit]
Description=Hibernate VM %I when host goes to sleep
Before=sleep.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/hibernate-vm %i
[Install]
WantedBy=sleep.target
@Roliga

Roliga commented Apr 14, 2020 •

Copy link
Copy Markdown
Author

The .service files go in /etc/systemd/system/, and hibernate-vm goes in /usr/local/bin/. Make sure to chmod 755 it.

The sleep service can be enabled with systemctl enable hibernate-vm-sleep@SOME_VM.service.

The shutdown service should always be active while your system is on, so enable it with systemctl enable --now hibernate-vm-shutdown@SOME_VM.service for it to work right away.

@wujinjun-MC

Copy link
Copy Markdown

Suggestion: add "managedsave" support, because I don't want to setup hibernation in the guest VM.

#!/bin/bash

#
# Usage: hibernate-vm NAME
#
# Hibernates the VM specified in NAME and waits for it to finish shutting down
#

domname="$1"

if virsh managedsave "$domname"; then
    echo "Waiting for domain to finish saving states to disk.." >&2
    while ! [ "$(virsh domstate "$domname")" == 'saved' ]; do
        sleep 1
    done
    echo "Domain finished saving states to disk" >&2
fi
# If failed (e.g. VFIO migration not supported caused by GPU-passthroughing), fallback to domain powermanagement - hibernate (requires swap partition/file setup in guest)
elif virsh dompmsuspend "$domname" disk; then
    echo "Waiting for domain to finish shutting down.." >&2
    while ! [ "$(virsh domstate "$domname")" == 'shut off' ]; do
        sleep 1
    done
    echo "Domain finished shutting down" >&2
fi
# DO NOT add "virsh suspend" as it isn't persist after shutting down

virsh dompmsuspend <domain name> disk requires corresponding domain to enable S4 state.

virsh edit: ensure <suspend-to-disk enabled='yes'/> in <pm>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment