static int parse_fstab(void) { FILE *f; int r = 0; struct mntent *me; errno = 0; f = setmntent("/etc/fstab", "r"); if (!f) { if (errno == ENOENT) return 0; log_error("Failed to open /etc/fstab: %m"); return -errno; } while ((me = getmntent(f))) { char _cleanup_free_ *where = NULL, *what = NULL; int k; what = fstab_node_to_udev_node(me->mnt_fsname); where = strdup(me->mnt_dir); if (!what || !where) { r = log_oom(); goto finish; } if (is_path(where)) path_kill_slashes(where); log_debug("Found entry what=%s where=%s type=%s", what, where, me->mnt_type); if (streq(me->mnt_type, "swap")) k = add_swap(what, me); else { bool noauto, nofail, automount, isbind, isnetwork; noauto = !!hasmntopt(me, "noauto"); nofail = !!hasmntopt(me, "nofail"); automount = hasmntopt(me, "comment=systemd.automount") || hasmntopt(me, "x-systemd.automount"); isbind = mount_is_bind(me); isnetwork = mount_is_network(me); k = add_mount(what, where, me->mnt_type, me->mnt_opts, me->mnt_passno, false, noauto, nofail, automount, isbind, isnetwork, "/etc/fstab"); } if (k < 0) r = k; } finish: endmntent(f); return r; }
static int parse_fstab(const char *prefix, bool initrd) { _cleanup_free_ char *fstab_path = NULL; FILE *f; int r = 0; struct mntent *me; fstab_path = strjoin(strempty(prefix), "/etc/fstab", NULL); if (!fstab_path) return log_oom(); f = setmntent(fstab_path, "r"); if (!f) { if (errno == ENOENT) return 0; log_error("Failed to open %s/etc/fstab: %m", strempty(prefix)); return -errno; } while ((me = getmntent(f))) { _cleanup_free_ char *where = NULL, *what = NULL; int k; if (initrd && !mount_in_initrd(me)) continue; what = fstab_node_to_udev_node(me->mnt_fsname); where = strjoin(strempty(prefix), me->mnt_dir, NULL); if (!what || !where) { r = log_oom(); goto finish; } if (is_path(where)) path_kill_slashes(where); log_debug("Found entry what=%s where=%s type=%s", what, where, me->mnt_type); if (streq(me->mnt_type, "swap")) k = add_swap(what, me); else { bool noauto, nofail, automount, isbind; const char *pre, *pre2, *post, *online; noauto = !!hasmntopt(me, "noauto"); nofail = !!hasmntopt(me, "nofail"); automount = hasmntopt(me, "comment=systemd.automount") || hasmntopt(me, "x-systemd.automount"); isbind = mount_is_bind(me); if (initrd) { pre = pre2 = online = NULL; post = SPECIAL_INITRD_FS_TARGET; } else if (mount_in_initrd(me)) { pre = pre2 = online = NULL; post = SPECIAL_INITRD_ROOT_FS_TARGET; } else if (mount_is_network(me)) { pre = SPECIAL_REMOTE_FS_PRE_TARGET; pre2 = SPECIAL_NETWORK_TARGET; online = SPECIAL_NETWORK_ONLINE_TARGET; post = SPECIAL_REMOTE_FS_TARGET; } else { pre = SPECIAL_LOCAL_FS_PRE_TARGET; pre2 = online = NULL; post = SPECIAL_LOCAL_FS_TARGET; } k = add_mount(what, where, me->mnt_type, me->mnt_opts, me->mnt_passno, noauto, nofail, automount, isbind, pre, pre2, online, post, fstab_path); } if (k < 0) r = k; } finish: endmntent(f); return r; }
static int add_mount(const char *what, const char *where, struct mntent *me) { char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL, *automount_name = NULL, *automount_unit = NULL; FILE *f = NULL; bool noauto, nofail, automount, isbind, isnetwork; int r; const char *post, *pre; assert(what); assert(where); assert(me); if (streq(me->mnt_type, "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; isnetwork = mount_is_network(me); isbind = mount_is_bind(me); noauto = !!hasmntopt(me, "noauto"); nofail = !!hasmntopt(me, "nofail"); automount = hasmntopt(me, "comment=systemd.automount") || hasmntopt(me, "x-systemd.automount"); if (isnetwork) { post = SPECIAL_REMOTE_FS_TARGET; pre = SPECIAL_REMOTE_FS_PRE_TARGET; } else { post = SPECIAL_LOCAL_FS_TARGET; pre = SPECIAL_LOCAL_FS_PRE_TARGET; } name = unit_name_from_path(where, ".mount"); if (!name) { r = log_oom(); goto finish; } unit = strjoin(arg_dest, "/", name, NULL); if (!unit) { r = log_oom(); goto finish; } f = fopen(unit, "wxe"); if (!f) { r = -errno; log_error("Failed to create unit file: %m"); goto finish; } fputs("# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=/etc/fstab\n" "DefaultDependencies=no\n", f); if (!path_equal(where, "/")) fprintf(f, "After=%s\n" "Wants=%s\n" "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" "Before=" SPECIAL_UMOUNT_TARGET "\n", pre, pre); if (!noauto && !nofail && !automount) fprintf(f, "Before=%s\n", post); fprintf(f, "\n" "[Mount]\n" "What=%s\n" "Where=%s\n" "Type=%s\n" "FsckPassNo=%i\n", what, where, me->mnt_type, me->mnt_passno); if (!isempty(me->mnt_opts) && !streq(me->mnt_opts, "defaults")) fprintf(f, "Options=%s\n", me->mnt_opts); fflush(f); if (ferror(f)) { log_error("Failed to write unit file: %m"); r = -errno; goto finish; } if (!noauto) { lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL); if (!lnk) { r = log_oom(); goto finish; } mkdir_parents_label(lnk, 0755); if (symlink(unit, lnk) < 0) { log_error("Failed to create symlink: %m"); r = -errno; goto finish; } if (!isbind && !path_equal(where, "/")) { r = device_name(what, &device); if (r < 0) goto finish; if (r > 0) { free(lnk); lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL); if (!lnk) { r = log_oom(); goto finish; } mkdir_parents_label(lnk, 0755); if (symlink(unit, lnk) < 0) { log_error("Failed to create symlink: %m"); r = -errno; goto finish; } } } } if (automount && !path_equal(where, "/")) { automount_name = unit_name_from_path(where, ".automount"); if (!name) { r = log_oom(); goto finish; } automount_unit = strjoin(arg_dest, "/", automount_name, NULL); if (!automount_unit) { r = log_oom(); goto finish; } fclose(f); f = fopen(automount_unit, "wxe"); if (!f) { r = -errno; log_error("Failed to create unit file: %m"); goto finish; } fprintf(f, "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=/etc/fstab\n" "DefaultDependencies=no\n" "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" "Before=" SPECIAL_UMOUNT_TARGET " %s\n" "\n" "[Automount]\n" "Where=%s\n", post, where); fflush(f); if (ferror(f)) { log_error("Failed to write unit file: %m"); r = -errno; goto finish; } free(lnk); lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL); if (!lnk) { r = log_oom(); goto finish; } mkdir_parents_label(lnk, 0755); if (symlink(automount_unit, lnk) < 0) { log_error("Failed to create symlink: %m"); r = -errno; goto finish; } } r = 0; finish: if (f) fclose(f); free(unit); free(lnk); free(name); free(device); free(automount_name); free(automount_unit); return r; }