Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */ 2 : : 3 : : #include <errno.h> 4 : : #include <unistd.h> 5 : : 6 : : #include "fs-util.h" 7 : : #include "generator.h" 8 : : #include "log.h" 9 : : #include "proc-cmdline.h" 10 : : #include "special.h" 11 : : #include "string-util.h" 12 : : #include "util.h" 13 : : 14 : : /* 15 : : * Implements the logic described in systemd.offline-updates(7). 16 : : */ 17 : : 18 : : static const char *arg_dest = NULL; 19 : : 20 : 0 : static int generate_symlink(void) { 21 : 0 : const char *p = NULL; 22 : : 23 [ # # ]: 0 : if (laccess("/system-update", F_OK) < 0) { 24 [ # # ]: 0 : if (errno == ENOENT) 25 : 0 : return 0; 26 : : 27 [ # # ]: 0 : log_error_errno(errno, "Failed to check for system update: %m"); 28 : 0 : return -EINVAL; 29 : : } 30 : : 31 [ # # # # : 0 : p = strjoina(arg_dest, "/" SPECIAL_DEFAULT_TARGET); # # # # # # # # ] 32 [ # # ]: 0 : if (symlink(SYSTEM_DATA_UNIT_PATH "/system-update.target", p) < 0) 33 [ # # ]: 0 : return log_error_errno(errno, "Failed to create symlink %s: %m", p); 34 : : 35 : 0 : return 1; 36 : : } 37 : : 38 : 0 : static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { 39 [ # # ]: 0 : 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 [ # # # # ]: 0 : if (streq(key, "systemd.unit") && !proc_cmdline_value_missing(key, value)) 47 [ # # ]: 0 : log_warning("Offline system update overridden by kernel command line systemd.unit= setting"); 48 [ # # # # ]: 0 : else if (!value && runlevel_to_target(key)) 49 [ # # ]: 0 : log_warning("Offline system update overridden by runlevel \"%s\" on the kernel command line", key); 50 : : 51 : 0 : return 0; 52 : : } 53 : : 54 : 0 : static int run(const char *dest, const char *dest_early, const char *dest_late) { 55 : : int r; 56 : : 57 [ # # ]: 0 : assert_se(arg_dest = dest_early); 58 : : 59 : 0 : r = generate_symlink(); 60 [ # # ]: 0 : if (r <= 0) 61 : 0 : return r; 62 : : 63 : : /* We parse the command line only to emit warnings. */ 64 : 0 : r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0); 65 [ # # ]: 0 : if (r < 0) 66 [ # # ]: 0 : log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); 67 : : 68 : 0 : return 0; 69 : : } 70 : : 71 [ # # # # : 0 : DEFINE_MAIN_GENERATOR_FUNCTION(run); # # # # # # # # ]