Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/omarchy-hibernation-available
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ SWAPSIZE=$(( 1024 * ${SWAPSIZE_KB:-0} ))

HIBERNATION_IMAGE_SIZE=$(cat /sys/power/image_size)

if (( SWAPSIZE > HIBERNATION_IMAGE_SIZE )) && [[ -f /etc/mkinitcpio.conf.d/omarchy_resume.conf ]]; then
if (( SWAPSIZE > HIBERNATION_IMAGE_SIZE )) && grep -q "resume" /etc/mkinitcpio.conf.d/omarchy_hooks.conf 2>/dev/null; then
exit 0
else
exit 1
Expand Down
11 changes: 7 additions & 4 deletions bin/omarchy-hibernation-remove
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
# omarchy:summary=Remove hibernation setup including swap and boot resume settings
# omarchy:requires-sudo=true

MKINITCPIO_CONF="/etc/mkinitcpio.conf.d/omarchy_resume.conf"
HOOKS_CONF="/etc/mkinitcpio.conf.d/omarchy_hooks.conf"

# Check if hibernation is configured
if [[ ! -f $MKINITCPIO_CONF ]] || ! grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
if [[ ! -f $HOOKS_CONF ]] || ! grep -q "resume" "$HOOKS_CONF"; then
echo "Hibernation is not set up"
exit 0
fi
Expand Down Expand Up @@ -48,10 +48,13 @@ fi
echo "Removing suspend-then-hibernate configuration"
sudo rm -f /etc/systemd/logind.conf.d/lid.conf
sudo rm -f /etc/systemd/sleep.conf.d/hibernate.conf
sudo rm -f /etc/systemd/system/systemd-logind.service.d/hibernate.conf
sudo rm -f /etc/systemd/system/systemd-hibernate.service.d/bypass.conf

# Remove mkinitcpio resume hook
echo "Removing resume hook"
sudo rm "$MKINITCPIO_CONF"
echo "Removing resume hook from $HOOKS_CONF"
sudo sed -i 's/resume //' "$HOOKS_CONF"
sudo rm -f /etc/mkinitcpio.conf.d/omarchy_resume.conf

echo "Regenerating initramfs..."
sudo limine-mkinitcpio
Expand Down
44 changes: 35 additions & 9 deletions bin/omarchy-hibernation-setup
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ if ! $NO_REBUILD && ! command -v limine-mkinitcpio &>/dev/null; then
exit 0
fi

MKINITCPIO_CONF="/etc/mkinitcpio.conf.d/omarchy_resume.conf"
HOOKS_CONF="/etc/mkinitcpio.conf.d/omarchy_hooks.conf"
SWAP_FILE="/swap/swapfile"
RESUME_DROP_IN="/etc/limine-entry-tool.d/resume.conf"

# Check if hibernation is already configured
if [[ -f $MKINITCPIO_CONF ]] && grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
if [[ -f $HOOKS_CONF ]] && grep -q "resume" "$HOOKS_CONF"; then
# Fix empty resume_offset if btrfs map-swapfile failed during initial setup
if [[ -f $RESUME_DROP_IN ]] && grep -q 'resume_offset="$' "$RESUME_DROP_IN" && [[ -f $SWAP_FILE ]]; then
RESUME_OFFSET=$(sudo btrfs inspect-internal map-swapfile -r "$SWAP_FILE" 2>/dev/null)
Expand Down Expand Up @@ -82,28 +82,54 @@ if ! swapon --show | grep -q "$SWAP_FILE"; then
sudo swapon -p 0 "$SWAP_FILE"
fi

# Add resume hook to mkinitcpio
sudo mkdir -p /etc/mkinitcpio.conf.d
echo "Adding resume hook to $MKINITCPIO_CONF"
echo "HOOKS+=(resume)" | sudo tee "$MKINITCPIO_CONF" >/dev/null
# Add resume hook to mkinitcpio — must come before filesystems so the kernel
# can restore the hibernation image before root is mounted read-write.
if [[ -f $HOOKS_CONF ]] && ! grep -q "resume" "$HOOKS_CONF"; then
echo "Inserting resume hook before filesystems in $HOOKS_CONF"
sudo sed -i 's/\bfilesystems\b/resume filesystems/' "$HOOKS_CONF"
fi
# Remove legacy append-style config that put resume in the wrong position
sudo rm -f /etc/mkinitcpio.conf.d/omarchy_resume.conf

# Ensure keyboard backlight doesn't prevent sleep
sudo cp -p "$OMARCHY_PATH/default/systemd/system-sleep/keyboard-backlight" /usr/lib/systemd/system-sleep/

# Resolve resume device and offset
sudo swapon -p 0 "$SWAP_FILE" 2>/dev/null
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
RESUME_OFFSET=$(sudo btrfs inspect-internal map-swapfile -r "$SWAP_FILE")

# Add resume= kernel parameters so the initramfs resume hook knows where to find the
# hibernation image. Without these, resume happens late (after GPU drivers load) and fails.
if [[ ! -f $RESUME_DROP_IN ]]; then
echo "Adding resume kernel parameters"
sudo swapon -p 0 "$SWAP_FILE" 2>/dev/null
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
RESUME_OFFSET=$(sudo btrfs inspect-internal map-swapfile -r "$SWAP_FILE")
if [[ -n $RESUME_OFFSET ]]; then
sudo mkdir -p /etc/limine-entry-tool.d
echo "KERNEL_CMDLINE[default]+=\" resume=$RESUME_DEVICE resume_offset=$RESUME_OFFSET\"" | sudo tee "$RESUME_DROP_IN" >/dev/null
sudo tee -a /etc/default/limine < "$RESUME_DROP_IN" >/dev/null
else
echo "Warning: Could not determine resume offset for $SWAP_FILE" >&2
fi
elif [[ -n $RESUME_OFFSET ]] && ! grep -q "resume_offset=$RESUME_OFFSET" "$RESUME_DROP_IN"; then
echo "Updating stale resume_offset in $RESUME_DROP_IN"
sudo sed -i "s/resume_offset=[0-9]*/resume_offset=$RESUME_OFFSET/" "$RESUME_DROP_IN"
sudo sed -i "s/resume_offset=[0-9]*/resume_offset=$RESUME_OFFSET/" /etc/default/limine
fi

# Work around systemd not being able to resolve btrfs swapfiles on dm-crypt
# as valid hibernation devices (see https://github.com/systemd/systemd/issues/30083)
LOGIND_DROP_IN="/etc/systemd/system/systemd-logind.service.d/hibernate.conf"
if [[ ! -f $LOGIND_DROP_IN ]]; then
echo "Adding systemd-logind hibernation bypass"
sudo mkdir -p /etc/systemd/system/systemd-logind.service.d
printf '[Service]\nEnvironment="SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"\n' | sudo tee "$LOGIND_DROP_IN" >/dev/null
fi

HIBERNATE_DROP_IN="/etc/systemd/system/systemd-hibernate.service.d/bypass.conf"
if [[ ! -f $HIBERNATE_DROP_IN ]]; then
echo "Adding systemd-hibernate bypass"
sudo mkdir -p /etc/systemd/system/systemd-hibernate.service.d
printf '[Service]\nEnvironment="SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"\n' | sudo tee "$HIBERNATE_DROP_IN" >/dev/null
fi

# Use ACPI alarm for RTC wakeup on s2idle systems (needed for suspend-then-hibernate)
Expand Down
44 changes: 44 additions & 0 deletions migrations/1778497305.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
echo "Fix hibernation on btrfs swapfiles with dm-crypt (systemd 256+)"

HOOKS_CONF="/etc/mkinitcpio.conf.d/omarchy_hooks.conf"
LEGACY_RESUME_CONF="/etc/mkinitcpio.conf.d/omarchy_resume.conf"
SWAP_FILE="/swap/swapfile"
RESUME_DROP_IN="/etc/limine-entry-tool.d/resume.conf"

# Only apply if hibernation is configured
if ! grep -q "resume" "$HOOKS_CONF" 2>/dev/null && [[ ! -f $LEGACY_RESUME_CONF ]]; then
exit 0
fi

# Move resume hook from appended position (after fsck) to before filesystems,
# so the kernel can restore the hibernation image before root is mounted rw.
if [[ -f $HOOKS_CONF ]] && ! grep -q "resume" "$HOOKS_CONF"; then
sudo sed -i 's/\bfilesystems\b/resume filesystems/' "$HOOKS_CONF"
fi
sudo rm -f "$LEGACY_RESUME_CONF"

Comment thread
Cliffback marked this conversation as resolved.
# Add systemd bypass drop-ins for btrfs swapfile on dm-crypt
# (see https://github.com/systemd/systemd/issues/30083)
LOGIND_DROP_IN="/etc/systemd/system/systemd-logind.service.d/hibernate.conf"
if [[ ! -f $LOGIND_DROP_IN ]]; then
sudo mkdir -p /etc/systemd/system/systemd-logind.service.d
printf '[Service]\nEnvironment="SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"\n' | sudo tee "$LOGIND_DROP_IN" >/dev/null
fi

HIBERNATE_DROP_IN="/etc/systemd/system/systemd-hibernate.service.d/bypass.conf"
if [[ ! -f $HIBERNATE_DROP_IN ]]; then
sudo mkdir -p /etc/systemd/system/systemd-hibernate.service.d
printf '[Service]\nEnvironment="SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"\n' | sudo tee "$HIBERNATE_DROP_IN" >/dev/null
fi

Comment thread
Cliffback marked this conversation as resolved.
# Fix stale resume_offset if swapfile was recreated at a different physical location
if [[ -f $RESUME_DROP_IN ]] && [[ -f $SWAP_FILE ]]; then
RESUME_OFFSET=$(sudo btrfs inspect-internal map-swapfile -r "$SWAP_FILE" 2>/dev/null)
if [[ -n $RESUME_OFFSET ]] && ! grep -q "resume_offset=$RESUME_OFFSET" "$RESUME_DROP_IN"; then
sudo sed -i "s/resume_offset=[0-9]*/resume_offset=$RESUME_OFFSET/" "$RESUME_DROP_IN"
sudo sed -i "s/resume_offset=[0-9]*/resume_offset=$RESUME_OFFSET/" /etc/default/limine
sudo limine-mkinitcpio
fi
fi

omarchy-state set reboot-required
Loading