You are not logged in.

#1 2014-05-09 20:29:50

Rexilion
Member
Registered: 2013-12-23
Posts: 784

[HOWTO] Systemd scripts to handle resume from disk

EDIT: I noticed that the resume scripts in dracut add the resume device to a custom udev script. Once the specified swap device comes up, udev will actually run the resume command. I guess this is to prevent other stuff from touching anything below /sysroot. This is still racy. However, I did notice that the configuration outlined does not prevent fsck from touching the root device. I can see the mkfs.btrfs being called when resuming from disk. This is potentially very dangerous. I guess this is the downside of an event based initrd -> many more possible race conditions. However, I don't see why adding udev rules would circumvent this.

EDIT2: It seems that all fsck utility's are designed not to touch the fs unless the user says it should. So I think we should be okay, especially since dracut does the same.

Since lvm2 broke my initrd + custom build script, I'm using a systemd based initrd. This works around the issue, but does not have support for the /hooks in the initrd created by mkinitcpio. Here, I will present my custom scripts to make resume from disk work. They have not been tailored to use the kernel commandline, so you have to modify the file to point to the swap partition containing the resume signature.

First, we are adding some debug utility's to our init. Furthermore, we are placing back some important utility's that used to be provided by the base hook in mkinitcpio.

Create /etc/initcpio/install/systemd-plus:

#!/bin/bash

build() {
	# basic utility's
	local applet
	add_binary /usr/lib/initcpio/busybox /bin/busybox
	for applet in $(/usr/lib/initcpio/busybox --list); do
		add_symlink "/usr/bin/$applet" busybox
	done

	# emergency target login
	add_binary sulogin
	add_file /etc/shadow
	add_file /etc/passwd

	# useful for debug
	add_binary journalctl
}

Above script will add the basic utility's as explained before. Furthermore, it will add the required files to allow you to login with your root password in case initrd fails to start. Many .service files in this part of bootup set the target to emergency.target in case they fail to launch or run. This target requires the sulogin binary and related files. Otherwise the system will just hang. Now, you will get a login prompt and be able to 'look around'. I added journalctl for convenience.

Create /etc/initcpio/install/sd-resume:

#!/bin/bash

build() {
	add_runscript
	add_file /usr/lib/initcpio/init_functions /init_functions

	add_file /etc/initcpio/systemd/sd-resume.service
	add_symlink /usr/lib/systemd/system/initrd.target.wants/sd-resume.service /etc/initcpio/systemd/sd-resume.service
}

I'm trying to reuse the init_functions provided by the base hook. They are useful and well tested. However, they require care now that the environment in which they are executed has changed. More on this later.

The last two lines include and hook up our resume script into the systemd start procedure. Creating the symlink is equivalent of adding a 'WantedBy=initrd.target' to sd-resume.service. Initrd.target is the default.target in the initrd. There is also sysinit.target and basic.target.

Create /etc/initcpio/hooks/sd-resume:

#!/bin/sh

export udevd_running=1
source /init_functions

poll_device /dev/main/swap
echo $(mountpoint -x /dev/main/swap) > /sys/power/resume

exit 0

This is the actual resume script. This script needs to be edited to your particular situation. Replace both occurrences of /dev/main/swap with your active swap partition.

We have to set udevd_running for the poll_device function to work. This is a safeguard to only start polling when udev is running. Otherwise waiting is futile. However, nothing is setting this env var since we only reuse parts of the bash styled scripts.

Finally, create the directory /etc/initcpio/systemd and create /etc/initcpio/systemd/sd-resume.service

[Unit]
Description=Resume from disk
Before=initrd-root-fs.target sysroot.mount

DefaultDependencies=no
ConditionPathIsReadWrite=/sys

[Service]
Type=oneshot
ExecStart=/bin/sh /hooks/sd-resume

This file will hook up our custom sd-resume script into the systemd start procedure. I have carefully designed it to start before root is mounted or even touched (fsck'ed).

DefaultDependencies allows the service to be run before basic.target is started. This allows sd-resume to start earlier.
ConditionPathIsReadWrite is to ensure that /sys is there once this service is started. I have no idea when /sys is mounted. I expect that systemd does this before any .service or .unit file is started.

My hooks array in mkinitcpio.conf looks like this:

HOOKS="systemd systemd-plus autodetect modconf sd-lvm2 block filesystems sd-resume keyboard fsck"

Now rebuild your initrd and you should have basic support for resume in your systemd based initrd!

EDIT: Some grammar fixes.

Last edited by Rexilion (2014-05-17 09:26:22)


fs/super.c : "Self-destruct in 5 seconds.  Have a nice day...\n",

Offline

#2 2014-05-17 00:44:37

gehidore
IRC Op
From: Near the pine trees
Registered: 2012-11-09
Posts: 35

Re: [HOWTO] Systemd scripts to handle resume from disk

Works perfectly for me! Thank you for this!


Windows get broken, penguins rarely get sucked into jet engines.

Offline

#3 2014-05-17 03:18:05

WonderWoofy
Member
From: Los Gatos, CA
Registered: 2012-05-19
Posts: 8,414

Re: [HOWTO] Systemd scripts to handle resume from disk

Maybe you should ask about adding this functionality to mkinitcpio?  I think that asking on [arch-projects] would at least give you some feedback and possible cleanup from the guys working on mkinitcpio.

Offline

#4 2014-05-17 09:24:44

Rexilion
Member
Registered: 2013-12-23
Posts: 784

Re: [HOWTO] Systemd scripts to handle resume from disk

WonderWoofy wrote:

Maybe you should ask about adding this functionality to mkinitcpio?  I think that asking on [arch-projects] would at least give you some feedback and possible cleanup from the guys working on mkinitcpio.

There are two problems with this approach:

  • It ignores the kernel commandline resume= parameter. Which would be nice and not hard to add btw.

  • Implementing only resume would be wasteful. It's probably better to hook the existing modules through generic systemd .service files. Dracut does this (and that is where I verified my .service file). Furthermore, we need to port the base module to sd-base suitable for systemd.

  • Finally, it seems that systemd in initrd is a rather young project. For example, the initrd does not contain sulogin. Which is really required if something goes wrong during the initrd startup phase.

gehidore wrote:

Works perfectly for me! Thank you for this!

That is great! The main reason I posted this is because I believe that resume from disk is one of the big main features holding many people back from using a systemd based initrd.


fs/super.c : "Self-destruct in 5 seconds.  Have a nice day...\n",

Offline

#5 2014-05-17 09:27:16

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,426
Website

Re: [HOWTO] Systemd scripts to handle resume from disk

Moving to Community Contributions...


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#6 2014-05-17 19:41:10

WonderWoofy
Member
From: Los Gatos, CA
Registered: 2012-05-19
Posts: 8,414

Re: [HOWTO] Systemd scripts to handle resume from disk

Rexilion wrote:
WonderWoofy wrote:

Maybe you should ask about adding this functionality to mkinitcpio?  I think that asking on [arch-projects] would at least give you some feedback and possible cleanup from the guys working on mkinitcpio.

There are two problems with this approach:
<snip>

Yeah, that is why I was suggesting to ask about this on that mailing list.  It would likely not be accepted as is, but you could get feedback and assistance in possibly making it "right" (or as right as it can be atm).

Offline

#7 2014-07-12 01:51:14

CharlesAtum
Member
Registered: 2013-01-15
Posts: 2

Re: [HOWTO] Systemd scripts to handle resume from disk

I spent a lot of time today trying to implement a sd-resume hook and, during some Google searches, I found this thread.
I was mostly basing my work on what the other sd-* hooks (including their services) and the resume hook do, but I got from here the idea to use "ConditionPathIsReadWrite=/sys" and that I would need to use poll_device (eventually workarounded by using a small part of the implementation).
I also used some code I saw on dracut and on a random bash init (olpc-init.txt) I found on google, because I basically don't know anything about bash. (Seriously, I took me hours to figure out how to extract the resume device from /proc/cmdline, and most of the time was used for figuring how to extract any specific thing from it.)

Anyway, I got a working sd-resume hook and submitted it to AUR if anybody wanna test it: https://aur.archlinux.org/packages/mkinitcpio-sd-resume
If you have any problems with it check the output of "journalctl -b -u systemd-resume-setup.service"
Also, I'm almost sure it will only work with partitions, but you can try with other things if you want.

Offline

#8 2014-11-19 11:50:19

farc
Member
Registered: 2014-03-05
Posts: 17

Re: [HOWTO] Systemd scripts to handle resume from disk

Hey guys,
with systemd 217 there is now resume helper:

http://lists.freedesktop.org/archives/systemd-devel/2014-October/024662.html wrote:

        * A helper binary and a service have been added which can be
          used to resume from hibernation in the initramfs. A
          generator will parse the resume= option on the kernel
          command-line to trigger resume.

Did someone already test this?

@CharlesAtum:
why did you delete your sd-resume hook?

From what I gather from the wiki we still need a systemd resume hook for mkinitpio, no?

Last edited by farc (2014-11-19 11:55:46)

Offline

#9 2014-11-19 13:20:25

CharlesAtum
Member
Registered: 2013-01-15
Posts: 2

Re: [HOWTO] Systemd scripts to handle resume from disk

farc wrote:

Hey guys,
with systemd 217 there is now resume helper:

http://lists.freedesktop.org/archives/systemd-devel/2014-October/024662.html wrote:

        * A helper binary and a service have been added which can be
          used to resume from hibernation in the initramfs. A
          generator will parse the resume= option on the kernel
          command-line to trigger resume.

Did someone already test this?

Yes, and it works great.

farc wrote:

@CharlesAtum:
why did you delete your sd-resume hook?

Because the implementation now in systemd is much better than what I would be able to achieve with a shell script having basically no shell scripting knowledge.

farc wrote:

From what I gather from the wiki we still need a systemd resume hook for mkinitpio, no?

No, we just need the systemd hook now. The problem is that nobody got around to updating the wiki.

Offline

#10 2014-11-19 23:36:05

farc
Member
Registered: 2014-03-05
Posts: 17

Re: [HOWTO] Systemd scripts to handle resume from disk

CharlesAtum wrote:

No, we just need the systemd hook now. The problem is that nobody got around to updating the wiki.

Aha, can you post your setup? Where do I set the systemd hook?
TY!

Offline

Board footer

Powered by FluxBB