static int add_mount( const char *id, const char *what, const char *where, const char *fstype, bool rw, const char *options, const char *description, const char *post) { _cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL; _cleanup_fclose_ FILE *f = NULL; int r; assert(id); assert(what); assert(where); assert(description); log_debug("Adding %s: %s %s", where, what, strna(fstype)); if (streq_ptr(fstype, "crypto_LUKS")) { r = add_cryptsetup(id, what, rw, &crypto_what); if (r < 0) return r; what = crypto_what; fstype = NULL; } r = unit_name_from_path(where, ".mount", &unit); if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); p = strjoin(arg_dest, "/", unit, NULL); if (!p) return log_oom(); f = fopen(p, "wxe"); if (!f) return log_error_errno(errno, "Failed to create unit file %s: %m", unit); fprintf(f, "# Automatically generated by systemd-gpt-auto-generator\n\n" "[Unit]\n" "Description=%s\n" "Documentation=man:systemd-gpt-auto-generator(8)\n", description); if (post) fprintf(f, "Before=%s\n", post); r = generator_write_fsck_deps(f, arg_dest, what, where, fstype); if (r < 0) return r; fprintf(f, "\n" "[Mount]\n" "What=%s\n" "Where=%s\n", what, where); if (fstype) fprintf(f, "Type=%s\n", fstype); if (options) fprintf(f, "Options=%s,%s\n", options, rw ? "rw" : "ro"); else fprintf(f, "Options=%s\n", rw ? "rw" : "ro"); r = fflush_and_check(f); if (r < 0) return log_error_errno(r, "Failed to write unit file %s: %m", p); if (post) { lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL); if (!lnk) return log_oom(); mkdir_parents_label(lnk, 0755); if (symlink(p, lnk) < 0) return log_error_errno(errno, "Failed to create symlink %s: %m", lnk); } return 0; }
static int add_mount( const char *what, const char *where, const char *fstype, const char *opts, int passno, bool noauto, bool nofail, bool automount, const char *post, const char *source) { _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL, *automount_name = NULL, *automount_unit = NULL, *filtered = NULL; _cleanup_fclose_ FILE *f = NULL; int r; assert(what); assert(where); assert(opts); assert(source); if (streq_ptr(fstype, "autofs")) return 0; if (!is_path(where)) { log_warning("Mount point %s is not a valid path, ignoring.", where); return 0; } if (mount_point_is_api(where) || mount_point_ignore(where)) return 0; if (path_equal(where, "/")) { /* The root disk is not an option */ automount = false; noauto = false; nofail = false; } name = unit_name_from_path(where, ".mount"); if (!name) return log_oom(); unit = strjoin(arg_dest, "/", name, NULL); if (!unit) return log_oom(); f = fopen(unit, "wxe"); if (!f) { if (errno == EEXIST) log_error("Failed to create mount unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit); else log_error_errno(errno, "Failed to create unit file %s: %m", unit); return -errno; } fprintf(f, "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=%s\n" "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n", source); if (post && !noauto && !nofail && !automount) fprintf(f, "Before=%s\n", post); if (passno != 0) { r = generator_write_fsck_deps(f, arg_dest, what, where, fstype); if (r < 0) return r; } fprintf(f, "\n" "[Mount]\n" "What=%s\n" "Where=%s\n", what, where); if (!isempty(fstype) && !streq(fstype, "auto")) fprintf(f, "Type=%s\n", fstype); r = generator_write_timeouts(arg_dest, what, where, opts, &filtered); if (r < 0) return r; if (!isempty(filtered) && !streq(filtered, "defaults")) fprintf(f, "Options=%s\n", filtered); fflush(f); if (ferror(f)) return log_error_errno(errno, "Failed to write unit file %s: %m", unit); if (!noauto && post) { lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL); if (!lnk) return log_oom(); mkdir_parents_label(lnk, 0755); if (symlink(unit, lnk) < 0) return log_error_errno(errno, "Failed to create symlink %s: %m", lnk); } if (automount) { automount_name = unit_name_from_path(where, ".automount"); if (!automount_name) return log_oom(); automount_unit = strjoin(arg_dest, "/", automount_name, NULL); if (!automount_unit) return log_oom(); fclose(f); f = fopen(automount_unit, "wxe"); if (!f) return log_error_errno(errno, "Failed to create unit file %s: %m", automount_unit); fprintf(f, "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=%s\n" "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n", source); if (post) fprintf(f, "Before=%s\n", post); fprintf(f, "[Automount]\n" "Where=%s\n", where); fflush(f); if (ferror(f)) return log_error_errno(errno, "Failed to write unit file %s: %m", automount_unit); free(lnk); lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL); if (!lnk) return log_oom(); mkdir_parents_label(lnk, 0755); if (symlink(automount_unit, lnk) < 0) return log_error_errno(errno, "Failed to create symlink %s: %m", lnk); } return 0; }
int main(int argc, char *argv[]) { _cleanup_free_ char *what = NULL; _cleanup_fclose_ FILE *f = NULL; int r = EXIT_SUCCESS; sd_id128_t id; char *name; if (argc > 1 && argc != 4) { log_error("This program takes three or no arguments."); return EXIT_FAILURE; } if (argc > 1) arg_dest = argv[3]; log_set_target(LOG_TARGET_SAFE); log_parse_environment(); log_open(); umask(0022); if (in_initrd()) { log_debug("In initrd, exiting."); return EXIT_SUCCESS; } if (detect_container(NULL) > 0) { log_debug("In a container, exiting."); return EXIT_SUCCESS; } if (!is_efi_boot()) { log_debug("Not an EFI boot, exiting."); return EXIT_SUCCESS; } if (path_is_mount_point("/boot", true) <= 0 && dir_is_empty("/boot") <= 0) { log_debug("/boot already populated, exiting."); return EXIT_SUCCESS; } r = efi_loader_get_device_part_uuid(&id); if (r == -ENOENT) { log_debug("EFI loader partition unknown, exiting."); return EXIT_SUCCESS; } else if (r < 0) { log_error_errno(r, "Failed to read ESP partition UUID: %m"); return EXIT_FAILURE; } name = strjoina(arg_dest, "/boot.mount"); f = fopen(name, "wxe"); if (!f) { log_error_errno(errno, "Failed to create mount unit file %s: %m", name); return EXIT_FAILURE; } r = asprintf(&what, "/dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", SD_ID128_FORMAT_VAL(id)); if (r < 0) { log_oom(); return EXIT_FAILURE; } fprintf(f, "# Automatially generated by systemd-efi-boot-generator\n\n" "[Unit]\n" "Description=EFI System Partition\n" "Documentation=man:systemd-efi-boot-generator(8)\n"); r = generator_write_fsck_deps(f, arg_dest, what, "/boot", "vfat"); if (r < 0) return EXIT_FAILURE; fprintf(f, "\n" "[Mount]\n" "What=%s\n" "Where=/boot\n" "Type=vfat\n" "Options=umask=0077,noauto\n", what); fflush(f); if (ferror(f)) { log_error_errno(errno, "Failed to write mount unit file: %m"); return EXIT_FAILURE; } name = strjoina(arg_dest, "/boot.automount"); fclose(f); f = fopen(name, "wxe"); if (!f) { log_error_errno(errno, "Failed to create automount unit file %s: %m", name); return EXIT_FAILURE; } fputs("# Automatially generated by systemd-efi-boot-generator\n\n" "[Unit]\n" "Description=EFI System Partition Automount\n\n" "[Automount]\n" "Where=/boot\n", f); fflush(f); if (ferror(f)) { log_error_errno(errno, "Failed to write automount unit file: %m"); return EXIT_FAILURE; } name = strjoina(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/boot.automount"); mkdir_parents(name, 0755); if (symlink("../boot.automount", name) < 0) { log_error_errno(errno, "Failed to create symlink %s: %m", name); return EXIT_FAILURE; } return EXIT_SUCCESS; }