3

During a long time, I used

echo disk > /sys/power/state

In order to hibernate to/dev/sda10and I was using the initrd of my Debian distribution to resume.

But recently, I switched to a raid array that require me to use a completely custom initramfs (I had to build it from scratch because attempt to modify existing initrd didn’t worked) in order to set‑up the raid array before mounting the root partition.

There’s 2 way to resume : either the kernel can read directly the swap filesystem with theresume=kernel parameter (and it will resume before starting init) ; or it needs some user space (for example loading modules) in order to be able to access the swap partition.

So what is the user space command in order to resume from /dev/mapper/isw_qfyzrvbsusf_Volume0p9 ?

user2284570
  • 1,799
  • 7
  • 35
  • 62

2 Answers2

8

The short answer is /sys/power/resume

Much longer answer, because that by itself won't do much if any good. Most distros recommend initiating a resume from the init / PID 1 process (early user space). However, the instructions will almost invariably inform you to add a kernel cmd line argument to your boot loader with the resume target. The reason for this is in almost every case that the initramfs build tool (dracut / mkinitcpio / initramfs-tools) is itself triggered by that argument in the configuration.

Based on your example and distro I'm assuming you are using the low level kernel interface for suspend (swsusp). There are a number of other utilities that can be used to start the suspend process; all of them are fundamentally wrappers around the first item, swusp.

  • swusp - low level kernel interface; user space interface is through sysfs
  • uswswp - low level userspace software suspend wrapper - provides s2disk, s2ram utilities (not actively maintained)
  • pm-utils - high level scripts to configure the process
  • systemd-suspend - on systemd systems a suspend target is available which will initiate the suspend operation via the kernel interface.

Resume Configuration

An oversimplified outline of the boot sequence in linux with using an initramfs image is:

[BIOS] ==> [Boot Loader] ==>[Kernel on temp rootfs - initramfs] ==> [Kernel on rootfs - drives]

There is a small window at the end of the initramfs stage where the resume can occur; after the kernel has started PID 1 (systemd or init), loaded the drivers for the raid, but before mounting the actual drives.

I've provided an example of a typical resume configuration. This assumes that the resume path you provided is a swap partition; and not a 'normal' partition containing a swap file. A swap file requires additional configuration. The systemd method is different - it uses a udev rule based on resume.target which triggers the resume process. It's worth looking into if the more traditional bootloader / initramfs image approach doesn't work. This is a direct corelary to the way that an init based system would do it; but a bit trickier to manually insert your own script and get the inter-dependencies / relative timing correct.

The bottom line is that the point in time at which the resume is triggered is immediately prior to when the kernel mounts the 'real' hard drives. So if the kernel can mount the entire fs, it also has all of the capability and information required to mount just the swap partition.

Make sure that your swap partition is mounted via fstab; the dracut initramfs tool specifically looks for it and does not include the resume module if the swap partition is not there.

configure bootloader

Assuming that you are using grub2, you need to append resume=/dev/mapper/isw_qfyzrvbsusf_Volume0p9 to the GRUB_CMDLINE_LINUX_DEFAULT field in /etc/default/grub Update your grub image, usually with command: sudo grub2-mkconfig -o /boot/grub2/grub.cfg

rebuild initramfs

You need to rebuild the initramfs image with the resume capability (as well as the raid modifications you've already made). Debian provides both dracut and initramfs-tools to generate initramfs. It must be regenerated with the resume module. With dracut, add the command line argument --add resume. With update-initramfs, add the entry resume=/dev/mapper/isw_qfyzrvbsusf_Volume0p9 to the config file /etc/initramfs-tools/conf.d/resume

That should be it; assuming I made some correct assumptions about your configuration.

Edit; assuming you can time it correctly, you can echo the major / minor device number of the swap partition to /sys/power/resume from an init script to trigger the resume. Your initramfs (or initd) image needs to have resume support in it, or that sysfs item and the capability it represents won't exist. See https://bugs.launchpad.net/ubuntu/+source/initramfs-tools/+bug/983805

Argonauts
  • 4,410
  • 19
  • 23
  • `rebuild initramfs`. **Did you really read my question ?** I can’t use the anything from the initramfs supplied distro, since in order to set up my raid array **I need to maintain a custom initrd from scratch manually** *(I can’t use any script from my distribution)*. So what needs to be written on`/sys/power/resume` ? – user2284570 May 22 '16 at 12:00
  • It has to be done from initramfs. You said you customized it, presumably using a utility, in which case you can do so again - this time with resume support. – Argonauts May 22 '16 at 13:47
  • I didn’t used any utility *(remember an initrd is just a compressed ᴄᴘɪᴏ archive containing a light rootfs)*. I really created the rootfs of initrd from scratch. It means writing all the start‑up shell scripts and choosing each files and folder it should contains one by one. **So my question is about what’s behind the scripts used by linux distributions for resuming** *(aka resume support included in initrd)*. – user2284570 May 22 '16 at 14:17
  • You stated that you were using initrd and then switched to an initramfs based boot - they are not equivalent. So which is it? What version of debian are you using? Are you using systemd? The initrd image needs to have resume built into it regardless of how you generated it. The majority of that image is a kernel binary, and it needs to be generated with resume support; no scripting will provide that capability if the initial boot kernel does not provide that capability (exposed via sysfs). – Argonauts May 22 '16 at 14:32
  • Again, there’s no such thing like resume support *(since I write`/init`manually from scratch)*. What I’m having is`/sys being mounted` before the root partition and every entries of`/sys/power/`.so what would be the minimal shell script that would trigger the resume. Otherwise yes, /sysfs/ is fully availaible in my custom initramfs. and in fact I use darban. but systemd or sysv init is irrelevant here since mounting the root partition shouldn’t be done. The real solution is to add`echo -n "$major:$minor" > /sys/power/resume`along [this](http://stackoverflow.com/a/29347598/2284570) in`/init`. – user2284570 May 22 '16 at 14:55
  • I provided the link in the answer to a method to do this. You need to do be careful to do this at the right point in the boot sequence. As far as systemd or init being irrelevent, your init script can't be called until PID 1 has been launched; which apparently in your case is init, not systemd. – Argonauts May 22 '16 at 15:14
  • `can't be called until PID 1 has been launched`nonsense. The first program on an initrd has ᴘɪᴅ 1 *(`/init`systemd or not)*. Or rather, the first user space binary executed by the kernel has always ᴘɪᴅ 1. You don’t mount any filesystems from the hard drive. – user2284570 May 22 '16 at 15:18
  • Hope this info helped in some way. You seem to be calling my answer nonsense and then agreeing with it. Odd reaction. – Argonauts May 22 '16 at 15:21
  • The comment is nonsense. and without proper reformatting I’ll write the answer myself next week‑end. It sounds like you’re misunderstanding several things about initrd/initramfs. – user2284570 May 22 '16 at 15:37
  • The point of the comment is that what you are using for PID 1 plays a role in what you can use it for. You could use ls as PID 1, but it offers little helpful capability in that context. As you may or may not know, all other processes, including the shell your scripts are being called in are children of PID 1, and this necessitates PID 1 having been launched prior to your script executing, which is just the way it works, nonsense or otherwise. In general, if you are looking for specific answers to your questions, provide specific details - especially when they are requested. – Argonauts May 22 '16 at 16:07
  • I my case`/init`is a shell script, so`/sys/power/resume`would be written by pid 1 *(echo is a built‑in shell command)*. – user2284570 May 22 '16 at 16:18
  • Ok, I didn’t needed much explanations. But what is required to be done in order to achieve what I need. So I posted my own answer which seems to be clearer. – user2284570 May 26 '16 at 22:41
2

The file is/sys/power/resume.

In order to trigger the resume, the major of the device followed by the minor, must be written to that file. So the following command can achieve it :

echo `stat -c %t /dev/mapper/isw_*_Volume0p9`\:`stat -c %T /dev/mapper/isw_*_Volume0p9` > /sys/power/resume
user2284570
  • 1,799
  • 7
  • 35
  • 62
  • 1
    You can also do `echo /dev/mapper/isw_*_Volume0p9 > /sys/power/resume` and the kernel will automatically determine the right major/minor device numbers. – Hitechcomputergeek Jun 04 '17 at 03:59