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