Example #1
0
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;
}
Example #2
0
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 parse_fstab(bool initrd) {
        _cleanup_endmntent_ FILE *f = NULL;
        const char *fstab_path;
        struct mntent *me;
        int r = 0;

        fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab";
        f = setmntent(fstab_path, "re");
        if (!f) {
                if (errno == ENOENT)
                        return 0;

                log_error_errno(errno, "Failed to open %s: %m", fstab_path);
                return -errno;
        }

        while ((me = getmntent(f))) {
                _cleanup_free_ char *where = NULL, *what = NULL;
                bool noauto, nofail;
                int k;

                if (initrd && !mount_in_initrd(me))
                        continue;

                what = fstab_node_to_udev_node(me->mnt_fsname);
                if (!what)
                        return log_oom();

                if (is_device_path(what) && path_is_read_only_fs("sys") > 0) {
                        log_info("Running in a container, ignoring fstab device entry for %s.", what);
                        continue;
                }

                where = initrd ? strappend("/sysroot/", me->mnt_dir) : strdup(me->mnt_dir);
                if (!where)
                        return log_oom();

                if (is_path(where))
                        path_kill_slashes(where);

                noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
                nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
                log_debug("Found entry what=%s where=%s type=%s nofail=%s noauto=%s",
                          what, where, me->mnt_type,
                          yes_no(noauto), yes_no(nofail));

                if (streq(me->mnt_type, "swap"))
                        k = add_swap(what, me, noauto, nofail);
                else {
                        bool automount;
                        const char *post;

                        automount = fstab_test_option(me->mnt_opts,
                                                      "comment=systemd.automount\0"
                                                      "x-systemd.automount\0");
                        if (initrd)
                                post = SPECIAL_INITRD_FS_TARGET;
                        else if (mount_in_initrd(me))
                                post = SPECIAL_INITRD_ROOT_FS_TARGET;
                        else if (mount_is_network(me))
                                post = SPECIAL_REMOTE_FS_TARGET;
                        else
                                post = SPECIAL_LOCAL_FS_TARGET;

                        k = add_mount(what,
                                      where,
                                      me->mnt_type,
                                      me->mnt_opts,
                                      me->mnt_passno,
                                      noauto,
                                      nofail,
                                      automount,
                                      post,
                                      fstab_path);
                }

                if (k < 0)
                        r = k;
        }

        return r;
}
Example #4
0
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;
}