]> git.ipfire.org Git - thirdparty/systemd.git/blame - 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
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
d2c68822
IS
2/***
3 This file is part of systemd.
4
5 Copyright 2014 Ivan Shapovalov
d2c68822
IS
6***/
7
d2c68822 8#include <errno.h>
07630cea 9#include <stdio.h>
d2c68822 10
b5efdb8a 11#include "alloc-util.h"
6550203e 12#include "fstab-util.h"
d2c68822 13#include "log.h"
d2c68822 14#include "mkdir.h"
4e731273 15#include "proc-cmdline.h"
07630cea
LP
16#include "special.h"
17#include "string-util.h"
d2c68822 18#include "unit-name.h"
07630cea 19#include "util.h"
d2c68822
IS
20
21static const char *arg_dest = "/tmp";
1d84ad94 22static char *arg_resume_device = NULL;
d2c68822 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
LP
35
36 free(arg_resume_device);
37 arg_resume_device = s;
d2c68822
IS
38 }
39
40 return 0;
41}
42
43static int process_resume(void) {
44 _cleanup_free_ char *name = NULL, *lnk = NULL;
7410616c 45 int r;
d2c68822 46
1d84ad94 47 if (!arg_resume_device)
b5884878
LP
48 return 0;
49
1d84ad94 50 r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_device, ".service", &name);
7410616c
LP
51 if (r < 0)
52 return log_error_errno(r, "Failed to generate unit name: %m");
d2c68822 53
605405c6 54 lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name);
d2c68822
IS
55 if (!lnk)
56 return log_oom();
57
58 mkdir_parents_label(lnk, 0755);
4a62c710
MS
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);
d2c68822
IS
61
62 return 0;
63}
64
65int 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
6c347d50
LP
76 log_set_prohibit_ipc(true);
77 log_set_target(LOG_TARGET_AUTO);
d2c68822
IS
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
1d84ad94 87 r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
b5884878 88 if (r < 0)
da927ba9 89 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
d2c68822 90
b5884878 91 r = process_resume();
1d84ad94 92 free(arg_resume_device);
d2c68822
IS
93
94 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
95}