]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/hibernate-resume/hibernate-resume-generator.c
hibernate-resume: add resumeflags= kernel option
[thirdparty/systemd.git] / src / hibernate-resume / hibernate-resume-generator.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
d2c68822 2
d2c68822 3#include <errno.h>
07630cea 4#include <stdio.h>
ca78ad1d 5#include <unistd.h>
d2c68822 6
b5efdb8a 7#include "alloc-util.h"
6550203e 8#include "fstab-util.h"
afe44c8f 9#include "generator.h"
d2c68822 10#include "log.h"
77182cc6 11#include "main-func.h"
d2c68822 12#include "mkdir.h"
4e731273 13#include "proc-cmdline.h"
07630cea
LP
14#include "special.h"
15#include "string-util.h"
d2c68822
IS
16#include "unit-name.h"
17
18static const char *arg_dest = "/tmp";
1d84ad94 19static char *arg_resume_device = NULL;
8b6805a2 20static char *arg_resume_options = NULL;
70e843fe 21static char *arg_root_options = NULL;
e83419d0 22static bool arg_noresume = false;
d2c68822 23
77182cc6 24STATIC_DESTRUCTOR_REGISTER(arg_resume_device, freep);
8b6805a2 25STATIC_DESTRUCTOR_REGISTER(arg_resume_options, freep);
70e843fe 26STATIC_DESTRUCTOR_REGISTER(arg_root_options, freep);
77182cc6 27
96287a49 28static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
7410616c 29
1d84ad94
LP
30 if (streq(key, "resume")) {
31 char *s;
32
33 if (proc_cmdline_value_missing(key, value))
34 return 0;
35
36 s = fstab_node_to_udev_node(value);
37 if (!s)
d2c68822 38 return log_oom();
1d84ad94 39
e83419d0
ZJS
40 free_and_replace(arg_resume_device, s);
41
8b6805a2
JR
42 } else if (streq(key, "resumeflags")) {
43
44 if (proc_cmdline_value_missing(key, value))
45 return 0;
46
47 if (!strextend_with_separator(&arg_resume_options, ",", value, NULL))
48 return log_oom();
49
70e843fe
JR
50 } else if (streq(key, "rootflags")) {
51
52 if (proc_cmdline_value_missing(key, value))
53 return 0;
54
55 if (!strextend_with_separator(&arg_root_options, ",", value, NULL))
56 return log_oom();
57
e83419d0
ZJS
58 } else if (streq(key, "noresume")) {
59 if (value) {
60 log_warning("\"noresume\" kernel command line switch specified with an argument, ignoring.");
61 return 0;
62 }
63
64 arg_noresume = true;
d2c68822
IS
65 }
66
67 return 0;
68}
69
70static int process_resume(void) {
71 _cleanup_free_ char *name = NULL, *lnk = NULL;
8b6805a2 72 const char *opts;
7410616c 73 int r;
d2c68822 74
1d84ad94 75 if (!arg_resume_device)
b5884878
LP
76 return 0;
77
1d84ad94 78 r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_device, ".service", &name);
7410616c
LP
79 if (r < 0)
80 return log_error_errno(r, "Failed to generate unit name: %m");
d2c68822 81
605405c6 82 lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name);
d2c68822
IS
83 if (!lnk)
84 return log_oom();
85
86 mkdir_parents_label(lnk, 0755);
4a62c710
MS
87 if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-hibernate-resume@.service", lnk) < 0)
88 return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
d2c68822 89
8b6805a2
JR
90 if (arg_resume_options)
91 opts = arg_resume_options;
92 else
93 opts = arg_root_options;
94
95 r = generator_write_timeouts(arg_dest, arg_resume_device, arg_resume_device, opts, NULL);
70e843fe
JR
96 if (r < 0)
97 return r;
98
d2c68822
IS
99 return 0;
100}
101
77182cc6 102static int run(int argc, char *argv[]) {
d2c68822
IS
103 int r = 0;
104
afe44c8f 105 log_setup_generator();
a79858bf 106
baaa35ad
ZJS
107 if (argc > 1 && argc != 4)
108 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
109 "This program takes three or no arguments.");
d2c68822
IS
110
111 if (argc > 1)
112 arg_dest = argv[1];
113
d2c68822 114 /* Don't even consider resuming outside of initramfs. */
a79858bf
ZJS
115 if (!in_initrd()) {
116 log_debug("Not running in an initrd, quitting.");
77182cc6 117 return 0;
a79858bf 118 }
d2c68822 119
1d84ad94 120 r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
b5884878 121 if (r < 0)
da927ba9 122 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
d2c68822 123
e83419d0
ZJS
124 if (arg_noresume) {
125 log_notice("Found \"noresume\" on the kernel command line, quitting.");
77182cc6 126 return 0;
e83419d0
ZJS
127 }
128
77182cc6 129 return process_resume();
d2c68822 130}
77182cc6
YW
131
132DEFINE_MAIN_FUNCTION(run);