]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/hibernate-resume/hibernate-resume-generator.c
Add $SYSTEMD_IN_INITRD=yes|no override for debugging
[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"
d2c68822 8#include "log.h"
d2c68822 9#include "mkdir.h"
4e731273 10#include "proc-cmdline.h"
07630cea
LP
11#include "special.h"
12#include "string-util.h"
d2c68822 13#include "unit-name.h"
07630cea 14#include "util.h"
d2c68822
IS
15
16static const char *arg_dest = "/tmp";
1d84ad94 17static char *arg_resume_device = NULL;
d2c68822 18
96287a49 19static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
7410616c 20
1d84ad94
LP
21 if (streq(key, "resume")) {
22 char *s;
23
24 if (proc_cmdline_value_missing(key, value))
25 return 0;
26
27 s = fstab_node_to_udev_node(value);
28 if (!s)
d2c68822 29 return log_oom();
1d84ad94
LP
30
31 free(arg_resume_device);
32 arg_resume_device = s;
d2c68822
IS
33 }
34
35 return 0;
36}
37
38static int process_resume(void) {
39 _cleanup_free_ char *name = NULL, *lnk = NULL;
7410616c 40 int r;
d2c68822 41
1d84ad94 42 if (!arg_resume_device)
b5884878
LP
43 return 0;
44
1d84ad94 45 r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_device, ".service", &name);
7410616c
LP
46 if (r < 0)
47 return log_error_errno(r, "Failed to generate unit name: %m");
d2c68822 48
605405c6 49 lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name);
d2c68822
IS
50 if (!lnk)
51 return log_oom();
52
53 mkdir_parents_label(lnk, 0755);
4a62c710
MS
54 if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-hibernate-resume@.service", lnk) < 0)
55 return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
d2c68822
IS
56
57 return 0;
58}
59
60int main(int argc, char *argv[]) {
61 int r = 0;
62
63 if (argc > 1 && argc != 4) {
64 log_error("This program takes three or no arguments.");
65 return EXIT_FAILURE;
66 }
67
68 if (argc > 1)
69 arg_dest = argv[1];
70
6c347d50
LP
71 log_set_prohibit_ipc(true);
72 log_set_target(LOG_TARGET_AUTO);
d2c68822
IS
73 log_parse_environment();
74 log_open();
75
76 umask(0022);
77
78 /* Don't even consider resuming outside of initramfs. */
79 if (!in_initrd())
80 return EXIT_SUCCESS;
81
1d84ad94 82 r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
b5884878 83 if (r < 0)
da927ba9 84 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
d2c68822 85
b5884878 86 r = process_resume();
1d84ad94 87 free(arg_resume_device);
d2c68822
IS
88
89 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
90}