]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/hibernate-resume/hibernate-resume-generator.c
Merge pull request #8575 from keszybz/non-absolute-paths
[thirdparty/systemd.git] / src / hibernate-resume / hibernate-resume-generator.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2014 Ivan Shapovalov
6 ***/
7
8 #include <errno.h>
9 #include <stdio.h>
10
11 #include "alloc-util.h"
12 #include "fstab-util.h"
13 #include "log.h"
14 #include "mkdir.h"
15 #include "proc-cmdline.h"
16 #include "special.h"
17 #include "string-util.h"
18 #include "unit-name.h"
19 #include "util.h"
20
21 static const char *arg_dest = "/tmp";
22 static char *arg_resume_device = NULL;
23
24 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
25
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)
34 return log_oom();
35
36 free(arg_resume_device);
37 arg_resume_device = s;
38 }
39
40 return 0;
41 }
42
43 static int process_resume(void) {
44 _cleanup_free_ char *name = NULL, *lnk = NULL;
45 int r;
46
47 if (!arg_resume_device)
48 return 0;
49
50 r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_device, ".service", &name);
51 if (r < 0)
52 return log_error_errno(r, "Failed to generate unit name: %m");
53
54 lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name);
55 if (!lnk)
56 return log_oom();
57
58 mkdir_parents_label(lnk, 0755);
59 if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-hibernate-resume@.service", lnk) < 0)
60 return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
61
62 return 0;
63 }
64
65 int main(int argc, char *argv[]) {
66 int r = 0;
67
68 if (argc > 1 && argc != 4) {
69 log_error("This program takes three or no arguments.");
70 return EXIT_FAILURE;
71 }
72
73 if (argc > 1)
74 arg_dest = argv[1];
75
76 log_set_prohibit_ipc(true);
77 log_set_target(LOG_TARGET_AUTO);
78 log_parse_environment();
79 log_open();
80
81 umask(0022);
82
83 /* Don't even consider resuming outside of initramfs. */
84 if (!in_initrd())
85 return EXIT_SUCCESS;
86
87 r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
88 if (r < 0)
89 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
90
91 r = process_resume();
92 free(arg_resume_device);
93
94 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
95 }