Proxmox Backup Auto-Shutdown
Today I’m trying to reduce the power consumption of my Proxmox Backup Server. The HP Microserver is great for what I need, but it’s kinda loud and I’m working on optimizing my power bill. The homelab is the largest single consumer of electricity aside from the air conditioning in the summer, so it’s something I’m looking at heavily.
Anyway, I thought I could do this purely with systemd sleep / suspend initially. Systemd can set up the system RTC to wake the system from suspend or hibernate at a specific time, and it’s easy to configure this by setting up a timer unit which is allowed to wake the system to happen. Of course, this requires the system to be able to suspend or hibernate.
I tried doing S3 speep (normal suspend to RAM) and found that the Microserver doesn’t support this. I then didn’t have enough space on my 16G boot disk (microSD card) for a swap partition to hibernate to, and don’t want to mess with the partition tables on my zfs drives to add one there, so hibernate is out too. This leaves me with actually fully shutting the system down and booting back up in the future. Downside to this is the RTC won’t wake it back up, I need to have another system send a Wake on LAN magic packet. No big deal, I just need to make sure I send it early enough that the backups aren’t scheduled to start until after the server is fully booted.
Video⌗
Here’s the video if you want to listen to me say all of these things:
Wake On LAN⌗
I found the MACs of all of my interfaces. In this case, I’m using eno1, so I am using 70:10:6f:3e:d1:f8
. You will of course need to find your own MAC address. This is also the hardware MAC, not the virtual MAC if you’re using a bond. I then installed the simple wakeonlan
utility with apt install wakeonlan
. It’s installed in /usr/bin
so I can call it directly from the systemd service unit.
Service Unit to Wake On LAN⌗
This just calls wakeonlan with the MAC address. Don’t enable the service, but you can systemctl start wakebigstor
to bootup the server if you want. I put the file in /etc/systemd/system/wakebigstor.service
. Bigstor is the name of the backup server.
[Unit]
Description=Wake up Bigstor
[Service]
Type=oneshot
ExecStart=/usr/bin/wakeonlan 70:10:6f:3e:d1:f8
[Install]
WantedBy=default.target
Timer Unit to call Service Unit⌗
Systemd timers are separate units from services, so here’s the timer unit that triggers the service unit at 19:05 local time daily. I put this one in /etc/systemd/system/wakebigstor.timer
and enabled and started it (systemctl enable --now wakebigstor.timer
). Again, don’t enable the service, just the timer.
[Unit]
Description=Wakeup Bigstor
RefuseManualStart=no
RefuseManualStop=no
[Timer]
#Run at 19:05 (7pm local time)
OnCalendar=*-*-* 19:05:00
Unit=wakebigstor.service
[Install]
WantedBy=timers.target
Autoshutdown⌗
This is 3 parts - a systemd timer that runs 5 hours after we start the server, to attempt shutdown (this gives clients 5 hours to start their backups), a systemd service unit that calls a bash script, and a bash script that waits until there are no more tasks running in proxmox-backup-manager.
Bash Script⌗
This script calls proxmox-backup-manager repeatedly. Hopefully you can understand my bash scripting. I put this file in /usr/local/bin/autoshutdown
. Don’t forget to chmod +x
it since it’s executable.
#!/bin/bash
#Count of times we have queried and there are tasks running
count=0
#Number of no-task intervals before we shutdown
max=10
#Interval in seconds
interval=5
#Continue until we shutdown
while true; do
#Check if we should shutdown until we see not
if [[ $(proxmox-backup-manager task list) ]]; then
#Continue to wait
count=0
else
#There are no tasks running, so increment counter
count=$((count + 1))
echo "No tasks running, time until shutdown is $(((max - count) * interval)) seconds"
#If we reached the max count, then shutdown
if ((count >= max)); then
echo "Time to shutdown!"
shutdown now
fi
fi
#Delay by interval to next check
sleep "$interval"
done
echo "Exiting"
Service Unit⌗
And the service unit that calls autoshutdown goes in /etc/systemd/system/autoshutdown.service
:
[Unit]
Description=Shutdown when there are no tasks left
[Service]
ExecStart=/usr/local/bin/autoshutdown
[Install]
WantedBy=default.target
Timer Unit⌗
And it also has a timer, /etc/systemd/system/autoshutdown.timer
:
[Unit]
Description=Shutdown
RefuseManualStart=no
RefuseManualStop=no
[Timer]
#Run at 22:00 local time
OnCalendar=*-*-* 22:00:00
Unit=autoshutdown.service
[Install]
WantedBy=timers.target
When you are done, don’t forget to run systemctl daemon-reload
and systemctl enable --now autoshutdown.timer
(but not the service unit, just the timer).
Mount Root FS noatime⌗
To reduce writes to the SD card, I mounted the root fs with noatime
. The line in my /etc/fstab
now looks like this:
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/sdh1 during installation
UUID=b58dfd0c-b6dc-4e44-a9b8-22ba3a5540d8 / ext4 errors=remount-ro,noatime 0 1
Move Logs to Datastore Disks⌗
Logs are stored in /var/log/proxmox-backup
and a subdirectory for tasks
can grow qutite significantly, with my larger file backups taking hundreds of MB for a log. This is not great for my root SD card, so I want to move them to zfs. I’m going to keep the api
logs on root.
The zfs fs is already mounted at /mnt/datastore/backup
(the datastore is named backup
), so I created a zfs dataset backup/logs
. I then rsync copied the logs into it rsync -r -v /var/log/proxmox-backup/tasks /mnt/datastore/backup/logs/
, deleted the original rm -rf /var/log/proxmox-backup/tasks
and symlinked it back back ln -s /mnt/datastore/backup/logs/tasks /var/log/proxmox-backup/tasks
. I then needed to fix permissions to user/group backup:backup
with chown backup:backup -R /mnt/datastore/backup/logs
and chown backup:backup /var/log/proxmox-backup/tasks
. After this, task logs were working correctly and backups were happy again.
Increase ZFS ARC Limit⌗
Since the system exists primarily to store the data in ZFS and has no large workload otherwise, I increased the ARC max from 50% of system RAM (Default) to 75%, in my case 12GB. I did this by first calculating the number of bytes in 12GB (12884901888) and storing this in a new file /etc/modprobe.d/zfs.conf
with the following contents:
options zfs zfs_arc_max=12884901888
This applies on the next boot.