[systemd-devel] [RFC] [PATCH 2/3] resume: add a tool to write a device node's major:minor to /sys/power/resume.

Thomas H.P. Andersen phomes at gmail.com
Sun Aug 24 04:34:04 PDT 2014


On Sat, Aug 23, 2014 at 2:47 PM, Ivan Shapovalov <intelfx100 at gmail.com> wrote:
> This can be used to initiate a resume from hibernation by path to a swap
> device containing the hibernation image.
>
> The respective templated unit is also added. It is instantiated using
> path to the desired resume device.
> ---
>  Makefile-man.am                  |  9 +++++
>  Makefile.am                      | 28 ++++++++++++--
>  man/systemd-resume at .service.xml  | 81 +++++++++++++++++++++++++++++++++++++++
>  src/resume/Makefile              |  1 +
>  src/resume/resume.c              | 82 ++++++++++++++++++++++++++++++++++++++++
>  units/systemd-resume at .service.in | 23 +++++++++++
>  6 files changed, 220 insertions(+), 4 deletions(-)
>  create mode 100644 man/systemd-resume at .service.xml
>  create mode 120000 src/resume/Makefile
>  create mode 100644 src/resume/resume.c
>  create mode 100644 units/systemd-resume at .service.in
>
> diff --git a/Makefile-man.am b/Makefile-man.am
> index 5c289dd..00daae2 100644
> --- a/Makefile-man.am
> +++ b/Makefile-man.am
> @@ -76,6 +76,8 @@ MANPAGES += \
>         man/systemd-nspawn.1 \
>         man/systemd-path.1 \
>         man/systemd-remount-fs.service.8 \
> +       man/systemd-resume-generator.8 \
> +       man/systemd-resume at .service.8 \
>         man/systemd-run.1 \
>         man/systemd-shutdownd.service.8 \
>         man/systemd-sleep.conf.5 \
> @@ -206,6 +208,7 @@ MANPAGES_ALIAS += \
>         man/systemd-poweroff.service.8 \
>         man/systemd-reboot.service.8 \
>         man/systemd-remount-fs.8 \
> +       man/systemd-resume.8 \
>         man/systemd-shutdown.8 \
>         man/systemd-shutdownd.8 \
>         man/systemd-shutdownd.socket.8 \
> @@ -311,6 +314,7 @@ man/systemd-kexec.service.8: man/systemd-halt.service.8
>  man/systemd-poweroff.service.8: man/systemd-halt.service.8
>  man/systemd-reboot.service.8: man/systemd-halt.service.8
>  man/systemd-remount-fs.8: man/systemd-remount-fs.service.8
> +man/systemd-resume.8: man/systemd-resume at .service.8
>  man/systemd-shutdown.8: man/systemd-halt.service.8
>  man/systemd-shutdownd.8: man/systemd-shutdownd.service.8
>  man/systemd-shutdownd.socket.8: man/systemd-shutdownd.service.8
> @@ -592,6 +596,9 @@ man/systemd-reboot.service.html: man/systemd-halt.service.html
>  man/systemd-remount-fs.html: man/systemd-remount-fs.service.html
>         $(html-alias)
>
> +man/systemd-resume.html: man/systemd-resume at .service.html
> +       $(html-alias)
> +
>  man/systemd-shutdown.html: man/systemd-halt.service.html
>         $(html-alias)
>
> @@ -1626,6 +1633,8 @@ EXTRA_DIST += \
>         man/systemd-readahead-replay.service.xml \
>         man/systemd-remount-fs.service.xml \
>         man/systemd-resolved.service.xml \
> +       man/systemd-resume-generator.xml \
> +       man/systemd-resume at .service.xml \
>         man/systemd-rfkill at .service.xml \
>         man/systemd-run.xml \
>         man/systemd-shutdownd.service.xml \
> diff --git a/Makefile.am b/Makefile.am
> index e238cde..820d082 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -371,13 +371,15 @@ rootlibexec_PROGRAMS = \
>         systemd-sleep \
>         systemd-bus-proxyd \
>         systemd-socket-proxyd \
> -       systemd-update-done
> +       systemd-update-done \
> +       systemd-resume
>
>  systemgenerator_PROGRAMS = \
>         systemd-getty-generator \
>         systemd-fstab-generator \
>         systemd-system-update-generator \
> -       systemd-debug-generator
> +       systemd-debug-generator \
> +       systemd-resume-generator
>
>  dist_bashcompletion_DATA = \
>         shell-completion/bash/busctl \
> @@ -509,7 +511,8 @@ nodist_systemunit_DATA = \
>         units/initrd-udevadm-cleanup-db.service \
>         units/initrd-switch-root.service \
>         units/systemd-nspawn at .service \
> -       units/systemd-update-done.service
> +       units/systemd-update-done.service \
> +       units/systemd-resume at .service
>
>  dist_userunit_DATA = \
>         units/user/basic.target \
> @@ -556,7 +559,8 @@ EXTRA_DIST += \
>         units/initrd-udevadm-cleanup-db.service.in \
>         units/initrd-switch-root.service.in \
>         units/systemd-nspawn at .service.in \
> -       units/systemd-update-done.service.in
> +       units/systemd-update-done.service.in \
> +       units/systemd-resume at .service.in
>
>  CLEANFILES += \
>         units/console-shell.service.m4 \
> @@ -1930,6 +1934,14 @@ systemd_delta_LDADD = \
>         libsystemd-shared.la
>
>  # ------------------------------------------------------------------------------
> +systemd_resume_SOURCES = \
> +       src/resume/resume.c
> +
> +systemd_resume_LDADD = \
> +       libsystemd-internal.la \
> +       libsystemd-shared.la
> +
> +# ------------------------------------------------------------------------------
>  systemd_getty_generator_SOURCES = \
>         src/getty-generator/getty-generator.c
>
> @@ -1962,6 +1974,14 @@ systemd_system_update_generator_LDADD = \
>         libsystemd-label.la \
>         libsystemd-shared.la
>
> +# ------------------------------------------------------------------------------
> +systemd_resume_generator_SOURCES = \
> +       src/resume-generator/resume-generator.c
> +
> +systemd_resume_generator_LDADD = \
> +       libsystemd-label.la \
> +       libsystemd-shared.la
> +
>  if ENABLE_EFI
>  # ------------------------------------------------------------------------------
>  systemgenerator_PROGRAMS +=  \
> diff --git a/man/systemd-resume at .service.xml b/man/systemd-resume at .service.xml
> new file mode 100644
> index 0000000..b7d28fb
> --- /dev/null
> +++ b/man/systemd-resume at .service.xml
> @@ -0,0 +1,81 @@
> +<?xml version="1.0"?>
> +<!--*-nxml-*-->
> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
> +<!--
> +  This file is part of systemd.
> +
> +  Copyright 2014 Ivan Shapovalov
> +
> +  systemd is free software; you can redistribute it and/or modify it
> +  under the terms of the GNU Lesser General Public License as published by
> +  the Free Software Foundation; either version 2.1 of the License, or
> +  (at your option) any later version.
> +
> +  systemd is distributed in the hope that it will be useful, but
> +  WITHOUT ANY WARRANTY; without even the implied warranty of
> +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +  Lesser General Public License for more details.
> +
> +  You should have received a copy of the GNU Lesser General Public License
> +  along with systemd; If not, see <http://www.gnu.org/licenses/>.
> +-->
> +<refentry id="systemd-resume at .service">
> +
> +        <refentryinfo>
> +                <title>systemd-resume at .service</title>
> +                <productname>systemd</productname>
> +
> +                <authorgroup>
> +                        <author>
> +                                <contrib>Developer</contrib>
> +                                <firstname>Ivan</firstname>
> +                                <surname>Shapovalov</surname>
> +                                <email>intelfx100 at gmail.com</email>
> +                        </author>
> +                </authorgroup>
> +        </refentryinfo>
> +
> +        <refmeta>
> +                <refentrytitle>systemd-resume at .service</refentrytitle>
> +                <manvolnum>8</manvolnum>
> +        </refmeta>
> +
> +        <refnamediv>
> +                <refname>systemd-resume at .service</refname>
> +                <refname>systemd-resume</refname>
> +                <refpurpose>Resume from hibernation</refpurpose>
> +        </refnamediv>
> +
> +        <refsynopsisdiv>
> +                <para><filename>systemd-resume at .service</filename></para>
> +                <para><filename>/usr/lib/systemd/systemd-resume</filename></para>
> +        </refsynopsisdiv>
> +
> +        <refsect1>
> +                <title>Description</title>
> +
> +                <para><filename>systemd-resume at .service</filename> is a
> +                service that initiates hibernation resume from a device
> +                containing the resume image. It is instantiated for each
> +                device that is configured for resuming from.</para>
> +
> +                <para><filename>systemd-resume</filename> only supports
> +                the in-kernel hibernation implementation, known as swsusp.
> +                Internally, it works by writing the major:minor of specified
> +                device node to <filename>/sys/power/resume</filename>.</para>
> +
> +                <para>Failing to initiate a resume is not an error condition.
> +                It may mean that there was no resume image (e. g. if the
> +                system has been simply powered off and not hibernated). In
> +                such case, the boot is ordinarily continued.</para>
> +        </refsect1>
> +
> +        <refsect1>
> +                <title>See Also</title>
> +                <para>
> +                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
> +                        <citerefentry><refentrytitle>systemd-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
> +                </para>
> +        </refsect1>
> +
> +</refentry>
> diff --git a/src/resume/Makefile b/src/resume/Makefile
> new file mode 120000
> index 0000000..d0b0e8e
> --- /dev/null
> +++ b/src/resume/Makefile
> @@ -0,0 +1 @@
> +../Makefile
> \ No newline at end of file
> diff --git a/src/resume/resume.c b/src/resume/resume.c
> new file mode 100644
> index 0000000..9bda8ff
> --- /dev/null
> +++ b/src/resume/resume.c
> @@ -0,0 +1,82 @@
> +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
> +
> +/***
> +  This file is part of systemd.
> +
> +  Copyright 2014 Ivan Shapovalov
> +
> +  systemd is free software; you can redistribute it and/or modify it
> +  under the terms of the GNU Lesser General Public License as published by
> +  the Free Software Foundation; either version 2.1 of the License, or
> +  (at your option) any later version.
> +
> +  systemd is distributed in the hope that it will be useful, but
> +  WITHOUT ANY WARRANTY; without even the implied warranty of
> +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +  Lesser General Public License for more details.
> +
> +  You should have received a copy of the GNU Lesser General Public License
> +  along with systemd; If not, see <http://www.gnu.org/licenses/>.
> +***/
> +
> +#include <stdio.h>
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +
> +#include "log.h"
> +#include "util.h"
> +#include "fileio.h"
> +
> +int main(int argc, char *argv[]) {
> +        struct stat st;
> +        const char *device, *major_minor;

major_minor should not be const and you could use the cleanup
attribute to free it automatically. The program will exit soon after
but still. Something like:

_cleanup_free_ char *major_minor = NULL;

> +        int r;
> +
> +        if (argc != 2) {
> +                log_error("This program expects one argument.");
> +                return EXIT_FAILURE;
> +        }
> +
> +        log_set_target(LOG_TARGET_AUTO);
> +        log_parse_environment();
> +        log_open();
> +
> +        umask(0022);
> +
> +        device = argv[1];
> +
> +        if (stat(device, &st) < 0) {
> +                log_error("Failed to stat '%s': %m", device);
> +                return EXIT_FAILURE;
> +        }
> +
> +        if (!S_ISBLK(st.st_mode)) {
> +                log_error("Resume device '%s' is not a block device.", device);
> +                return EXIT_FAILURE;
> +        }
> +
> +        if (asprintf(&major_minor, "%d:%d", major(st.st_rdev), minor(st.st_rdev)) < 0) {
> +                log_oom();
> +                return EXIT_FAILURE;
> +        }
> +
> +        r = write_string_file("/sys/power/resume", major_minor);
> +        if (r < 0) {
> +                log_error("Failed to write '%s' to /sys/power/resume: %s",
> +                          major_minor, strerror(-r));
> +                return EXIT_FAILURE;
> +        }
> +
> +        /*
> +         * The write above shall not return.
> +         *
> +         * However, failed resume is a normal condition (may mean that there is
> +         * no hibernation image).
> +         */
> +
> +        log_notice("Failed to resume from device '%s' (%d:%d).",
> +                   device, major(st.st_rdev), minor(st.st_rdev));
> +        return EXIT_SUCCESS;
> +}
> diff --git a/units/systemd-resume at .service.in b/units/systemd-resume at .service.in
> new file mode 100644
> index 0000000..f760f16
> --- /dev/null
> +++ b/units/systemd-resume at .service.in
> @@ -0,0 +1,23 @@
> +#  This file is part of systemd.
> +#
> +#  systemd is free software; you can redistribute it and/or modify it
> +#  under the terms of the GNU Lesser General Public License as published by
> +#  the Free Software Foundation; either version 2.1 of the License, or
> +#  (at your option) any later version.
> +
> +[Unit]
> +Description=Resume from hibernation using device %f
> +Documentation=man:systemd-resume at .service(8)
> +DefaultDependencies=no
> +Conflicts=shutdown.target
> +BindsTo=%i.device
> +Wants=local-fs-pre.target
> +After=%i.device systemd-udevd.service
> +Before=local-fs-pre.target systemd-remount-fs.service systemd-fsck-root.service usr.mount shutdown.target
> +ConditionPathIsReadWrite=|!/
> +ConditionPathExists=|/etc/initrd-release
> +
> +[Service]
> +Type=oneshot
> +RemainAfterExit=yes
> +ExecStart=@rootlibexecdir@/systemd-resume %f
> --
> 2.1.0
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel


More information about the systemd-devel mailing list