Skip to content

Conversation

killeik
Copy link

@killeik killeik commented Sep 2, 2025

Resolves: #105

  • Creates btrfs subvolume for swap file, to not break snapshots
  • Creates swap file with size of ram
  • Adds swap file to /etc/fstab to mount swap file on boot
  • Adds resume module via HOOKS+=(resume) in /etc/mkinitcpio.conf.d/omarchy_resume.conf
  • Adds Hibernate option to Power menu

I'd love to get some feedback 😄

@killeik killeik mentioned this pull request Sep 2, 2025
@nielpattin
Copy link

Not sure about install step, but I can confirm that the hibernate work like it should be.
I'm also on Nvidia which most the problem come from and doesn't have any issue. Hope this get merge soon because I have to create a copy of Omarchy menu just to test it out or just run systemctl hibernate in terminal, but I prefer it under Suspend like this.

@nielpattin
Copy link

@killeik ok, I got some problem with the hyprlock crash(not related), so I tried to reinstall and the first thing I do is to run the hibernate.sh command to test.
Run systemctl hibernate like usual.
But when power on, it brings me to the Omarchy Bootloader screen. So I'm not sure what wrong.

Boot up to the linux only open a new fresh just like when reboot, others app open or the last state doesn't return.

1756978924210

@killeik
Copy link
Author

killeik commented Sep 4, 2025

@nielpattin

it brings me to the Omarchy Bootloader screen

It's okay. The boot sequence from hibernation starts like a fresh boot. It should decrypt the disk and start the kernel. Later on, however, it finds a RAM dump on the disk and loads that instead of loading fresh.

Boot up to the linux only open a new fresh just like when reboot, others app open or the last state doesn't return.

Let's debug
I need output of that one (putted them in one command, to not make you Ctrl+C/Ctrl+V all the way :D )

bash -c 'set -x ;
swapon ;
free -h ;
sudo btrfs subvolume show /swap ;
sudo btrfs inspect-internal map-swapfile /swap/swapfile ;
cat /sys/power/resume_offset ;
cat /sys/power/resume ;
cat /etc/fstab ;
cat /etc/mkinitcpio.conf.d/omarchy_resume.conf ;'

And kernel logs after hibernation (they are not so small, so send them as file, maybe)
sudo dmesg -TH

For convenience, you can send them to me in DM in Discord, I'm @killeik on omarchy server

@killeik
Copy link
Author

killeik commented Sep 4, 2025

After some debugging in DM, it was discovered that there was a magical Nvidia, for which the standard mode of operation on Linux is to torment the user.
Other than that, everything worked fine.

@brennandunn
Copy link

I've tested this on my Framework laptop / AMD Ryzen and it works great 👍 Thanks!

@dhh dhh requested a review from ryanrhughes September 7, 2025 19:02
@dhh dhh added this to the 3.0 milestone Sep 14, 2025
@dhh
Copy link
Member

dhh commented Sep 16, 2025

Need to update for current branch, make the Hibernate option conditional on the swap being available, and add a migration with a gum confirm something like "Use XX GB on drive to make hibernate available?".

@dhh dhh removed this from the 3.0 milestone Sep 17, 2025
@woopstar
Copy link

Need to update for current branch, make the Hibernate option conditional on the swap being available, and add a migration with a gum confirm something like "Use XX GB on drive to make hibernate available?".

While you add it. Also make a check if swap is already configured. I have an encrypted swap on my machine so hibernation.sh would break my machine with custom partitions / swap / encryption.

@killeik
Copy link
Author

killeik commented Sep 18, 2025

My apologies. I updated my fork branch to the current active branch, accidentally deleting the changes I had added, and GitHub automatically closed the pull request because the branches started to match.

By the way, I added migration and made the hibernation option in omarchy-menu optional.

@killeik killeik reopened this Sep 18, 2025
@killeik killeik marked this pull request as draft September 18, 2025 14:49
@killeik
Copy link
Author

killeik commented Sep 19, 2025

Tested conditional hibernation in power menu, and migration - everything works correctly.

The only pitfall is that if the user manually created a swap and didn't enable the resume hook, the boot sequence will not resume from the saved hibernation image and will start fresh.

I found a way to check if the hooks are enabled on the current initramfs with limine:
lsinitcpio /boot/EFI/Linux/*.efi | grep 'hooks/resume'
However, I'm unsure if it will work on GRUB and other systems.

@killeik killeik marked this pull request as ready for review September 19, 2025 16:34
@woopstar
Copy link

Did you try the PR? I tried multiple PR in my own fork, and the menu does not work. I suspect this PR might break the omarchy menu system

@killeik
Copy link
Author

killeik commented Sep 20, 2025

Did you try the PR? I tried multiple PR in my own fork, and the menu does not work. I suspect this PR might break the omarchy menu system

I've tested this PR on both of my computers and it works correctly.
I actually don't have any ideas how it can break menu, because my change for it is very simple. So can you please give more info what's going on in your fork?

@woopstar
Copy link

I've tested this PR on both of my computers and it works correctly.
I actually don't have any ideas how it can break menu, because my change for it is very simple. So can you please give more info what's going on in your fork?

https://github.com/woopstar/omarchy/commits/master/

I will check tomorrow which PR that broke the app launcher then :)

@woopstar
Copy link

It was #1661 that broke the menu. I tested this. Works as it should. But it shows the lock menu that "hangs" while it waits for hibernation to be ready. Should we consider showing something else if possible? Would it be possible to have it say "Entering hibernation" instead of showing the lock screen, which you cannot type or do anything in?

@killeik
Copy link
Author

killeik commented Sep 22, 2025

It was #1661 that broke the menu. I tested this. Works as it should.

Thank you!

But it shows the lock menu that "hangs" while it waits for hibernation to be ready. Should we consider showing something else if possible? Would it be possible to have it say "Entering hibernation" instead of showing the lock screen, which you cannot type or do anything in?

Neither hybridle, which invokes the lock screen before sleep or hibernation, nor hyprlock, which works as a lock screen, has any difference between sleep and hibernation. Therefore, it's not possible at this level.

However, systemd has different targets: suspend.target, hibernate.target, hybrid-sleep.target, and suspend-then-hibernate.target.
Technically, we could write a service that runs before hibernate.target and changes the hyprlock configuration to display something like "Hibernating, wait" and then changes it back after hibernation. However, it feels like a bad hack, changing user-space config on every hibernation is kinda crazy.

To do that the normal way, we would probably need to create an issue in Hyprildle/Hyprlock.

@woopstar
Copy link

However, systemd has different targets: suspend.target, hibernate.target, hybrid-sleep.target, and suspend-then-hibernate.target.
Technically, we could write a service that runs before hibernate.target and changes the hyprlock configuration to display something like "Hibernating, wait" and then changes it back after hibernation. However, it feels like a bad hack, changing user-space config on every hibernation is kinda crazy.

Yeah, let's not walk down that road. But I can confirm the PR works as expected :)

@DominicBoettger
Copy link

DominicBoettger commented Sep 22, 2025

I am thinking about moving to OMARCHY from my customized ARCH and i think this was the script I used to enable the Swap. I used a swap file instead of a volume (i think the subvolume is the better approach). I drop my config / code as it may be helpful.
I am using hibernate when closing the lid.
I checked the issues for hibernate as this is an important feature for me.

#!/bin/sh
# check if su or root
if [ "$(id -u)" != "0" ]; then
  echo "This script must be run as root" 1>&2
  exit 1
fi
# check if btrfs
if [ ! -d /sys/fs/btrfs ]; then
  echo "This script is only for btrfs filesystems" 1>&2
  exit 1
fi
# check if swapfile exists if not create it with 96GB
if [ ! -f /swap/swapfile ]; then
  echo "Creating swapfile with 96GB"
  fallocate -l 96G /swap/swapfile
  chmod 600 /swap/swapfile
  mkswap /swap/swapfile
  swapon /swap/swapfile
fi

cd /tmp
# :: btrfs_map_physical :: #
wget https://raw.githubusercontent.com/osandov/osandov-linux/master/scripts/btrfs_map_physical.c
gcc -O2 -o btrfs_map_physical btrfs_map_physical.c

# :: edit grub :: #
offset=$(./btrfs_map_physical /swap/swapfile)
offset_arr=($(echo ${offset}))
offset_pagesize=($(getconf PAGESIZE))
offset=$((offset_arr[25] / offset_pagesize))
btrfsroot=`findmnt / -no UUID`

echo "btrfsroot=$btrfsroot"
echo "offset=$offset"

# create a backup of /etc/default/grub
cp /etc/default/grub /etc/default/grub.bak

# edit /etc/default/grub
sed -i "s#loglevel=3#resume=/dev/mapper/root loglevel=3#" /etc/default/grub
sed -i "s/loglevel=3/resume_offset=$offset loglevelbtrfs property set \/swap\/swapfile compression none=3/" /etc/default/grub

My /etc/systemd/logind.conf

[Login]
#NAutoVTs=6
#ReserveVT=6
#KillUserProcesses=no
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
#UserStopDelaySec=10
#SleepOperation=suspend-then-hibernate suspend
HandlePowerKey=lock
#HandlePowerKeyLongPress=ignore
#HandleRebootKey=reboot
#HandleRebootKeyLongPress=poweroff
#HandleSuspendKey=suspend
#HandleSuspendKeyLongPress=hibernate
#HandleHibernateKey=hibernate
#HandleHibernateKeyLongPress=ignore
HandleLidSwitch=suspend-then-hibernate
HandleLidSwitchExternalPower=suspend-then-hibernate
#HandleLidSwitchDocked=ignore
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
#RebootKeyIgnoreInhibited=no
#HoldoffTimeoutSec=30s
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RuntimeDirectoryInodesMax=
#RemoveIPC=yes
#InhibitorsMax=8192
#SessionsMax=8192
#StopIdleSessionSec=infinity

@woopstar
Copy link

@killeik I've been thinking if this should also enable the suspend-then-hibernate support.

$ cat /etc/systemd/sleep.conf.d/omarchy.conf
[Sleep]
HibernateDelaySec=60min
AllowSuspendThenHibernate=yes
$ cat /etc/systemd/logind.conf.d/omarchy.conf
[Login]
HandleLidSwitch=suspend-then-hibernate
HandleLidSwitchExternalPower=suspend-then-hibernate
HandleLidSwitchDocked=suspend-then-hibernate

Unsure if we also must:

systemctl enable systemd-suspend-then-hibernate.service

References:
https://man.archlinux.org/man/systemd-sleep.conf.5
https://man.archlinux.org/man/logind.conf.5.en

@killeik
Copy link
Author

killeik commented Sep 24, 2025

If we want to do something like this, I suggest using sleep instead of straight-forward suspend-then-hibernate for HandleLidSwitch:

sleep
Put the system to sleep, through suspend, hibernate, hybrid-sleep, or suspend-then-hibernate. The sleep operation to use is automatically selected by systemd-logind.service(8). By default, suspend-then-hibernate is used, and falls back to suspend and then hibernate if not supported. Refer to SleepOperation= setting in logind.conf(5) for more details. This command is asynchronous, and will return after the sleep operation is successfully enqueued. It will not wait for the sleep/resume cycle to complete.

Added in version 256.

It will work if the system has or does not have hibernation mode.

I'm also not sure if we really want to change HibernateDelaySec.

Setting the AllowSuspendThenHibernate=yes may actually break users without hibernation.
This flag, as I understand it, is intended to turn off the features, not to enable them.
Systemd doesn't need any changes to the configuration to find system support for hibernation.

And the systemd-suspend-then-hibernate.service - it's not a daemon. It's a one-shot command to start the suspend-then-hibernate sequence.

Note that systemd-suspend.service, systemd-hibernate.service, systemd-hybrid-sleep.service, and systemd-suspend-then-hibernate.service should never be executed directly. Instead, trigger system sleep with a command such as systemctl suspend or systemctl hibernate.

But I'm not sure if it's a good idea to talk about these improvements in this PR. My idea was just to add support for hibernation.

@yovko
Copy link

yovko commented Sep 28, 2025

There is an easier way to find resume=UUID=<UUID> and resume_offset cmdline parameters:

findmnt -no UUID -T /swap/swapfile
btrfs inspect-internal map-swapfile -r /swap/swapfile

And I add resume=UUID=<UUID> resume_offset=<the-number-from-inspect-internal> at the end of my cmdline in my limine.conf file. But I'm on my custom Arch Linux setup. Not sure about Omarchy

https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate#Acquire_swap_file_offset

@DominicBoettger

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants