Mario

Looking at your patches and the preceding discussion on #89050 and
having wrapped a cold towel round my head, I have a few comments.

As of kernel 4.17,
<https://elixir.bootlin.com/linux/v4.17/source/Documentation/power/swsusp.txt>
documents the use of /sys/power/resume_offset to set the offset block,
and this is the first version that does actually include the required
code in hibernate.c (static ssize_t resume_offset_store(...) line 1070).
But that is not the same as the offset parameter sent by /bin/resume.

Therefore ...

In all cases, the initramfs can only know that it should invoke a resume
through the resume kernel parameter. The local-premount/resume script is
needed to do this. It has to canonicalise the resume kernel parameter
value and pass it via the /sys/power/resume maj:min API. The resume code
can use the resume_offset kernel parameter if provided.

For kernels before 4.17, the only way to get resume_offset into the
resume process is via the kernel command line, either manually or via a
function in /etc/default/grub as below invoked during update-grub:

Get_Resume()
{
    local sname stype junk roff res

    swapon --show --noheadings --raw | head -1 | {
        read sname stype junk
        if  [ "$stype" = "file" ]; then
            res=`df "$sname" | awk 'END {print $1}'`
            type swap-offset>/dev/null && # from suspend-utils|uswsusp
               roff=`swap-offset "$sname" |
                     awk '/resume offset =/ {print $4;exit}'`
            [ -z "$roff" ] &&
               roff=`filefrag -v "$sname" |
                     awk '{if ($1=="0:") {print
                           substr($4,1,length($4)-2);exit}}'`
            sname=$res
        fi
        # now [ "$stype" = "device" ]
        res=`lsblk -o PARTUUID --noheadings "$sname"`
        [ -n "$res" ] && res="resume=PARTUUID=$res"
        [ -n "$res" ] && [ "$roff" -ge 0 ] &&
            res="$res resume_offset=$roff"
        echo $res;
    }
}

GRUB_CMDLINE_LINUX="`Get_Resume`"

I tested a swapfile resume with 4.4 using the echo
maj:min:offset>/sys/power/resume API and believed that it worked, but
the kernel must have been reading offset from the grub command-line.

Whereas for 4.17 and later, you can save the resume device and
resume_offset into a conf file for initramfs-tools from a hook run from
update-initramfs (which has to happen once for each installed kernel),
so long as you replace/update /bin/resume to use the new API. These
values override any kernel command-line parameters. The resume_offset
parameter remains the default value if the /sys/power/resume_offset API
is not used.

I can't really see why that's any better than the update-grub approach.

There needs to be some global initramfs storage that can be mounted when
initiating hibernate/hybrid-sleep and then again by the initramfs when
booting. I really have no idea if that's possible.

As to the scripts ...

        hooks/resume
<https://salsa.debian.org/superm1-guest/initramfs-tools/commit/f74423c610bd3b9ee9baf97d42bfa0219bfb4826>

1       line 59
For filefrag, e2fsprogs has to be installed. Is it a dependency of other
file systems?

Should the check on resume_offset be the same as in l63?

2       global
If this is going to work with a resume_offset, /sys/power/resume_offset
has to be writable. There should be a test "[ -w
/sys/power/resume_offset ]" somewhere before writing resume_offset (>0)
to the conf file and error if not.


        scripts/local-premount/resume
<https://salsa.debian.org/superm1-guest/initramfs-tools/commit/a39f61e48eca03e264a7235ee984db76e8c10aa9#8609b9b67b65b1556d2a51cfeacee8a080c15af6>

Mostly issues with the unpatched source!

1       line 18
Test -e /sys/power/resume should be -w /sys/power/resume.

2       line 29
Test [ -x /bin/plymouth ] but then call plymouth instead of
/bin/plymouth - is PATH sure to begin /bin:...? Instead:

if type plymouth >/dev/null && plymouth --ping; then

3       line 30
Why not tell the whole truth:

plymouth message --text="Resuming from $resume ${resume_offset:+at
offset $resume_offset}"

4       line 34
The test is redundant. Replace if ... fi by line 35.

There could be a test that resume_offset is an unsigned long number, as
in your hooks/resume:63, but then you'd need to handle the error case
where resume_offset is set and invalid.

5       lines 35ff
/bin/resume
<https://github.com/mirror/busybox/blob/master/klibc-utils/resume.c> is
no help. It doesn't do what's needed if the resume_offset has been
provided from within the initramfs, since it only writes to
/sys/power/resume using the never actually implemented maj:min:offset API.

You can do the right thing in the script itself per
<https://bugs.launchpad.net/ubuntu/+source/initramfs-tools/+bug/983805>
and avoid possible confusion with uswsusp's resume binary. This is a
modified script to handle the 4.17+ API.

resume() # resume_device [resume_offset]
{
    local majmin x

    majmin=
    # Get the major and minor numbers for the resume device
    x=$(stat -L -c '0x%t 0x%T' "$1") && majmin=$(printf '%d:%d' $x)

    [ -n "$majmin" ] && [ "${majmin%:*}" != "0" ] ||
        # No device (could not stat device) or not a real device
        return 99;

    [ ! "$2" -ge 0 ] || printf "$2" > /sys/power/resume_offset &&
        printf "$majmin" > /sys/power/resume

    return $?
}


Hope that helps.
/df

-- 
London SW6
UK

Reply via email to