]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
d360705f LP |
2 | |
3 | #include <errno.h> | |
4 | #include <unistd.h> | |
5 | ||
f4f15635 | 6 | #include "fs-util.h" |
afe44c8f | 7 | #include "generator.h" |
d360705f | 8 | #include "log.h" |
1cec251c | 9 | #include "proc-cmdline.h" |
075dafd2 | 10 | #include "special.h" |
07630cea | 11 | #include "string-util.h" |
d360705f | 12 | #include "util.h" |
d360705f | 13 | |
399c5f96 | 14 | /* |
075dafd2 | 15 | * Implements the logic described in systemd.offline-updates(7). |
399c5f96 LP |
16 | */ |
17 | ||
bd020018 | 18 | static const char *arg_dest = NULL; |
d360705f LP |
19 | |
20 | static int generate_symlink(void) { | |
9194c8e4 | 21 | const char *p = NULL; |
d360705f | 22 | |
6b321a79 | 23 | if (laccess("/system-update", F_OK) < 0) { |
d360705f LP |
24 | if (errno == ENOENT) |
25 | return 0; | |
26 | ||
56f64d95 | 27 | log_error_errno(errno, "Failed to check for system update: %m"); |
d360705f LP |
28 | return -EINVAL; |
29 | } | |
30 | ||
075dafd2 | 31 | p = strjoina(arg_dest, "/" SPECIAL_DEFAULT_TARGET); |
4a62c710 MS |
32 | if (symlink(SYSTEM_DATA_UNIT_PATH "/system-update.target", p) < 0) |
33 | return log_error_errno(errno, "Failed to create symlink %s: %m", p); | |
d360705f | 34 | |
1cec251c ZJS |
35 | return 1; |
36 | } | |
37 | ||
38 | static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { | |
39 | assert(key); | |
40 | ||
41 | /* Check if a run level is specified on the kernel command line. The | |
42 | * command line has higher priority than any on-disk configuration, so | |
43 | * it'll make any symlink we create moot. | |
44 | */ | |
45 | ||
46 | if (streq(key, "systemd.unit") && !proc_cmdline_value_missing(key, value)) | |
3fe91079 | 47 | log_warning("Offline system update overridden by kernel command line systemd.unit= setting"); |
1cec251c | 48 | else if (!value && runlevel_to_target(key)) |
3fe91079 | 49 | log_warning("Offline system update overridden by runlevel \"%s\" on the kernel command line", key); |
1cec251c | 50 | |
d360705f LP |
51 | return 0; |
52 | } | |
53 | ||
bd020018 ZJS |
54 | static int run(const char *dest, const char *dest_early, const char *dest_late) { |
55 | int r; | |
d360705f | 56 | |
bd020018 | 57 | assert_se(arg_dest = dest_early); |
d360705f | 58 | |
d360705f | 59 | r = generate_symlink(); |
bd020018 ZJS |
60 | if (r < 0) |
61 | return r; | |
d360705f | 62 | |
bd020018 ZJS |
63 | r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0); |
64 | if (r < 0) | |
65 | log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); | |
1cec251c | 66 | |
bd020018 | 67 | return 0; |
d360705f | 68 | } |
bd020018 ZJS |
69 | |
70 | DEFINE_MAIN_GENERATOR_FUNCTION(run); |