]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
mount: Use libmount to iterate over any mountpoints
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 24 May 2022 14:45:28 +0000 (14:45 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 24 May 2022 14:45:28 +0000 (14:45 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/mount.c

index e8885cc5ec8657e33602199c0b77fa352a493e12..d7e1e0e8dac2233b7b5bc9d7d90e932dd2ba04ba 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <errno.h>
 #include <linux/limits.h>
-#include <mntent.h>
 #include <stddef.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
@@ -81,55 +80,71 @@ static const struct pakfire_mountpoint {
 /*
        Easy way to iterate through all mountpoints
 */
-static int pakfire_mount_foreach(struct pakfire* pakfire,
-               int (*callback)(struct pakfire* pakfire, struct mntent* mnt, const void* data),
+static int pakfire_mount_foreach(struct pakfire* pakfire, int direction,
+               int (*callback)(struct pakfire* pakfire, struct libmnt_fs* fs, const void* data),
                const char* option, const void* data) {
        const char* root = pakfire_get_path(pakfire);
        int r = 1;
 
-       FILE* f = setmntent("/proc/mounts", "r");
-       if (!f) {
+       struct libmnt_iter* iterator = NULL;
+       struct libmnt_table* tab = NULL;
+       struct libmnt_fs* fs = NULL;
+
+       // Create an iterator
+       iterator = mnt_new_iter(direction);
+       if (!iterator) {
+               ERROR(pakfire, "Could not setup iterator: %m\n");
+               goto ERROR;
+       }
+
+       // Read /proc/mounts
+       tab = mnt_new_table_from_file("/proc/mounts");
+       if (!tab) {
                ERROR(pakfire, "Could not open /proc/mounts: %m\n");
-               return r;
+               goto ERROR;
        }
 
-       for (;;) {
-               struct mntent* mnt = getmntent(f);
-               if (!mnt)
-                       break;
+       while (mnt_table_next_fs(tab, iterator, &fs) == 0) {
+               const char* target = mnt_fs_get_target(fs);
 
                // Ignore any mointpoints that don't belong to us
-               if (!pakfire_string_startswith(mnt->mnt_dir, root))
+               if (!pakfire_string_startswith(target, root))
                        continue;
 
                // Filter by option
                if (option) {
-                       if (hasmntopt(mnt, option))
+                       if (!mnt_fs_match_options(fs, option))
                                continue;
                }
 
                // Call the callback for each relevant mountpoint
-               r = callback(pakfire, mnt, data);
+               r = callback(pakfire, fs, data);
                if (r)
                        break;
        }
 
+ERROR:
        // Tidy up
-       endmntent(f);
+       if (fs)
+               mnt_unref_fs(fs);
+       if (tab)
+               mnt_unref_table(tab);
+       if (iterator)
+               mnt_free_iter(iterator);
 
        return r;
 }
 
 static int __pakfire_is_mountpoint(struct pakfire* pakfire,
-               struct mntent* mnt, const void* data) {
+               struct libmnt_fs* fs, const void* data) {
        const char* path = (const char*)data;
 
-       // Return if path matches
-       return (strcmp(mnt->mnt_dir, path) == 0);
+       return mnt_fs_streq_target(fs, path);
 }
 
 int pakfire_is_mountpoint(struct pakfire* pakfire, const char* path) {
-       return pakfire_mount_foreach(pakfire, __pakfire_is_mountpoint, NULL, path);
+       return pakfire_mount_foreach(pakfire, MNT_ITER_FORWARD,
+               __pakfire_is_mountpoint, NULL, path);
 }
 
 int pakfire_mount(struct pakfire* pakfire, const char* source, const char* target,
@@ -245,27 +260,23 @@ RETRY:
 }
 
 static int __pakfire_mount_print(struct pakfire* pakfire,
-               struct mntent* mnt, const void* data) {
-       //DEBUG(pakfire,
-       printf(
-               "%s %s %s %s %d %d\n",
-               mnt->mnt_fsname,
-               mnt->mnt_dir,
-               mnt->mnt_type,
-               mnt->mnt_opts,
-               mnt->mnt_freq,
-               mnt->mnt_passno
+               struct libmnt_fs* fs, const void* data) {
+       DEBUG(pakfire,
+               "  %s %s %s %s\n",
+               mnt_fs_get_source(fs),
+               mnt_fs_get_target(fs),
+               mnt_fs_get_fstype(fs),
+               mnt_fs_get_fs_options(fs)
        );
 
        return 0;
 }
 
 static int pakfire_mount_list(struct pakfire* pakfire) {
-       return 0;
-
        DEBUG(pakfire, "Current mountpoints:\n");
 
-       return pakfire_mount_foreach(pakfire, __pakfire_mount_print, NULL, NULL);
+       return pakfire_mount_foreach(pakfire, MNT_ITER_FORWARD,
+               __pakfire_mount_print, NULL, NULL);
 }
 
 int pakfire_mount_all(struct pakfire* pakfire, const enum pakfire_mount_flags mount_flags) {
@@ -335,8 +346,12 @@ RETRY:
 }
 
 static int __pakfire_umount(struct pakfire* pakfire,
-               struct mntent* mnt, const void* data) {
-       return pakfire_umount(pakfire, mnt->mnt_dir, 0);
+               struct libmnt_fs* fs, const void* data) {
+       const char* target = mnt_fs_get_target(fs);
+       if (!target)
+               return 1;
+
+       return pakfire_umount(pakfire, target, 0);
 }
 
 /*
@@ -346,5 +361,6 @@ int pakfire_umount_all(struct pakfire* pakfire, const char* option) {
        // List everything that is mounted
        pakfire_mount_list(pakfire);
 
-       return pakfire_mount_foreach(pakfire, __pakfire_umount, option, NULL);
+       return pakfire_mount_foreach(pakfire, MNT_ITER_BACKWARD,
+               __pakfire_umount, option, NULL);
 }