]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fstab-generator: port to libmount parser
authorMike Yuan <me@yhndnzj.com>
Sat, 6 Sep 2025 15:16:14 +0000 (17:16 +0200)
committerMike Yuan <me@yhndnzj.com>
Thu, 18 Sep 2025 18:25:14 +0000 (20:25 +0200)
src/fstab-generator/fstab-generator.c
src/fstab-generator/meson.build

index 14a53cd572587e420059d07dbd4e3d6059f3755f..1b68689bf9daa81759ea04e295d5f0113a3e48d0 100644 (file)
 #include "generator.h"
 #include "in-addr-util.h"
 #include "initrd-util.h"
+#include "libmount-util.h"
 #include "log.h"
 #include "main-func.h"
 #include "mount-setup.h"
-#include "mount-util.h"
 #include "mountpoint-util.h"
 #include "parse-util.h"
 #include "path-util.h"
@@ -1025,9 +1025,9 @@ static int parse_fstab_one(
 }
 
 static int parse_fstab(bool prefix_sysroot) {
-        _cleanup_endmntent_ FILE *f = NULL;
+        _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+        _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
         const char *fstab;
-        struct mntent *me;
         int r, ret = 0;
 
         if (prefix_sysroot)
@@ -1039,27 +1039,31 @@ static int parse_fstab(bool prefix_sysroot) {
 
         log_debug("Parsing %s...", fstab);
 
-        f = setmntent(fstab, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
+        r = libmount_parse_full(fstab, /* source = */ NULL, &table, &iter);
+        if (r == -ENOENT)
+                return 0;
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse '%s': %m", fstab);
 
-                return log_error_errno(errno, "Failed to open %s: %m", fstab);
-        }
+        for (;;) {
+                struct libmnt_fs *fs;
+
+                r = mnt_table_next_fs(table, iter, &fs);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to get next entry from '%s': %m", fstab);
+                if (r > 0) /* EOF */
+                        return ret;
 
-        while ((me = getmntent(f))) {
                 r = parse_fstab_one(fstab,
-                                    me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno,
+                                    mnt_fs_get_source(fs), mnt_fs_get_target(fs),
+                                    mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
                                     prefix_sysroot,
                                     /* accept_root = */ false,
                                     /* use_swap_enabled = */ true);
-                if (r < 0 && ret >= 0)
-                        ret = r;
                 if (arg_sysroot_check && r > 0)
                         return true;  /* We found a mount or swap that would be started… */
+                RET_GATHER(ret, r);
         }
-
-        return ret;
 }
 
 static int mount_source_is_nfsroot(const char *what) {
@@ -1414,15 +1418,15 @@ static int add_mounts_from_cmdline(void) {
 
 static int add_mounts_from_creds(bool prefix_sysroot) {
         _cleanup_free_ void *b = NULL;
-        struct mntent *me;
         size_t bs;
-        int r;
+        const char *cred;
+        int r, ret = 0;
 
         assert(in_initrd() || !prefix_sysroot);
 
-        r = read_credential_with_decryption(
-                        in_initrd() && !prefix_sysroot ? "fstab.extra.initrd" : "fstab.extra",
-                        &b, &bs);
+        cred = in_initrd() && !prefix_sysroot ? "fstab.extra.initrd" : "fstab.extra";
+
+        r = read_credential_with_decryption(cred, &b, &bs);
         if (r <= 0)
                 return r;
 
@@ -1431,20 +1435,29 @@ static int add_mounts_from_creds(bool prefix_sysroot) {
         if (!f)
                 return log_oom();
 
-        r = 0;
+        _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+        _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
 
-        while ((me = getmntent(f)))
-                RET_GATHER(r, parse_fstab_one("/run/credentials",
-                                              me->mnt_fsname,
-                                              me->mnt_dir,
-                                              me->mnt_type,
-                                              me->mnt_opts,
-                                              me->mnt_passno,
-                                              /* prefix_sysroot = */ prefix_sysroot,
-                                              /* accept_root = */ true,
-                                              /* use_swap_enabled = */ true));
+        r = libmount_parse_full(cred, f, &table, &iter);
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse credential '%s' (as fstab): %m", cred);
 
-        return r;
+        for (;;) {
+                struct libmnt_fs *fs;
+
+                r = mnt_table_next_fs(table, iter, &fs);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to get next fstab entry from credential '%s': %m", cred);
+                if (r > 0) /* EOF */
+                        return ret;
+
+                RET_GATHER(ret, parse_fstab_one("/run/credentials",
+                                                mnt_fs_get_source(fs), mnt_fs_get_target(fs),
+                                                mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
+                                                prefix_sysroot,
+                                                /* accept_root = */ true,
+                                                /* use_swap_enabled = */ true));
+        }
 }
 
 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
index fb492158fc3b5a47a370ad4090357570a26f6b94..fb5dccdd41b391a000c2d9f1a99108403475c2af 100644 (file)
@@ -4,6 +4,7 @@ executables += [
         generator_template + {
                 'name' : 'systemd-fstab-generator',
                 'sources' : files('fstab-generator.c'),
+                'dependencies' : libmount,
         },
 ]