Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */ 2 : : 3 : : #include <errno.h> 4 : : #include <sys/stat.h> 5 : : #include <unistd.h> 6 : : 7 : : #include "efivars.h" 8 : : #include "generator.h" 9 : : #include "log.h" 10 : : #include "mkdir.h" 11 : : #include "special.h" 12 : : #include "string-util.h" 13 : : #include "util.h" 14 : : #include "virt.h" 15 : : 16 : : /* This generator pulls systemd-bless-boot.service into the initial transaction if the "LoaderBootCountPath" EFI 17 : : * variable is set, i.e. the system boots up with boot counting in effect, which means we should mark the boot as 18 : : * "good" if we manage to boot up far enough. */ 19 : : 20 : : static const char *arg_dest = "/tmp"; 21 : : 22 : 0 : int main(int argc, char *argv[]) { 23 : : const char *p; 24 : : 25 : 0 : log_setup_generator(); 26 : : 27 [ # # # # ]: 0 : if (argc > 1 && argc != 4) { 28 [ # # ]: 0 : log_error("This program takes three or no arguments."); 29 : 0 : return EXIT_FAILURE; 30 : : } 31 : : 32 [ # # ]: 0 : if (argc > 1) 33 : 0 : arg_dest = argv[2]; 34 : : 35 [ # # ]: 0 : if (in_initrd() > 0) { 36 [ # # ]: 0 : log_debug("Skipping generator, running in the initrd."); 37 : 0 : return EXIT_SUCCESS; 38 : : } 39 : : 40 [ # # ]: 0 : if (detect_container() > 0) { 41 [ # # ]: 0 : log_debug("Skipping generator, running in a container."); 42 : 0 : return EXIT_SUCCESS; 43 : : } 44 : : 45 [ # # ]: 0 : if (!is_efi_boot()) { 46 [ # # ]: 0 : log_debug("Skipping generator, not an EFI boot."); 47 : 0 : return EXIT_SUCCESS; 48 : : } 49 : : 50 [ # # ]: 0 : if (access("/sys/firmware/efi/efivars/LoaderBootCountPath-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f", F_OK) < 0) { 51 : : 52 [ # # ]: 0 : if (errno == ENOENT) { 53 [ # # ]: 0 : log_debug_errno(errno, "Skipping generator, not booted with boot counting in effect."); 54 : 0 : return EXIT_SUCCESS; 55 : : } 56 : : 57 [ # # ]: 0 : log_error_errno(errno, "Failed to check if LoaderBootCountPath EFI variable exists: %m"); 58 : 0 : return EXIT_FAILURE; 59 : : } 60 : : 61 : : /* We pull this in from basic.target so that it ends up in all "regular" boot ups, but not in rescue.target or 62 : : * even emergency.target. */ 63 [ # # # # : 0 : p = strjoina(arg_dest, "/" SPECIAL_BASIC_TARGET ".wants/systemd-bless-boot.service"); # # # # # # # # ] 64 : 0 : (void) mkdir_parents(p, 0755); 65 [ # # ]: 0 : if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-bless-boot.service", p) < 0) { 66 [ # # ]: 0 : log_error_errno(errno, "Failed to create symlink '%s': %m", p); 67 : 0 : return EXIT_FAILURE; 68 : : } 69 : : 70 : 0 : return EXIT_SUCCESS; 71 : : }