]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/hibernate-resume/hibernate-resume-generator.c
tree-wide: drop copyright headers from frequent contributors
[thirdparty/systemd.git] / src / hibernate-resume / hibernate-resume-generator.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <stdio.h>
5
6 #include "alloc-util.h"
7 #include "fstab-util.h"
8 #include "log.h"
9 #include "mkdir.h"
10 #include "proc-cmdline.h"
11 #include "special.h"
12 #include "string-util.h"
13 #include "unit-name.h"
14 #include "util.h"
15
16 static const char *arg_dest = "/tmp";
17 static char *arg_resume_device = NULL;
18
19 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
20
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)
29 return log_oom();
30
31 free(arg_resume_device);
32 arg_resume_device = s;
33 }
34
35 return 0;
36 }
37
38 static int process_resume(void) {
39 _cleanup_free_ char *name = NULL, *lnk = NULL;
40 int r;
41
42 if (!arg_resume_device)
43 return 0;
44
45 r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_device, ".service", &name);
46 if (r < 0)
47 return log_error_errno(r, "Failed to generate unit name: %m");
48
49 lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name);
50 if (!lnk)
51 return log_oom();
52
53 mkdir_parents_label(lnk, 0755);
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);
56
57 return 0;
58 }
59
60 int 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
71 log_set_prohibit_ipc(true);
72 log_set_target(LOG_TARGET_AUTO);
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
82 r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
83 if (r < 0)
84 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
85
86 r = process_resume();
87 free(arg_resume_device);
88
89 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
90 }