]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
libpakfire: Move mount operations into a new file
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 24 May 2022 14:18:12 +0000 (14:18 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 24 May 2022 14:18:12 +0000 (14:18 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/libpakfire/execute.c
src/libpakfire/include/pakfire/mount.h [new file with mode: 0644]
src/libpakfire/mount.c [new file with mode: 0644]
src/libpakfire/pakfire.c

index da734ae48fc58f83f4307ee13c451cdf6db1627b..466365e1103cce349c572cef0cf766881cc0e013 100644 (file)
@@ -231,6 +231,7 @@ libpakfire_la_SOURCES = \
        src/libpakfire/key.c \
        src/libpakfire/keystore.c \
        src/libpakfire/logging.c \
+       src/libpakfire/mount.c \
        src/libpakfire/package.c \
        src/libpakfire/packager.c \
        src/libpakfire/packagelist.c \
@@ -267,6 +268,7 @@ pkginclude_HEADERS += \
        src/libpakfire/include/pakfire/key.h \
        src/libpakfire/include/pakfire/keystore.h \
        src/libpakfire/include/pakfire/logging.h \
+       src/libpakfire/include/pakfire/mount.h \
        src/libpakfire/include/pakfire/package.h \
        src/libpakfire/include/pakfire/packager.h \
        src/libpakfire/include/pakfire/packagelist.h \
index 082b04be94be537351802a85d2689928e80145c8..4279b17b9ca45d7af6b5bf0007b4d2a19c66323f 100644 (file)
@@ -44,6 +44,7 @@
 #include <pakfire/cgroup.h>
 #include <pakfire/execute.h>
 #include <pakfire/logging.h>
+#include <pakfire/mount.h>
 #include <pakfire/private.h>
 #include <pakfire/util.h>
 
@@ -560,6 +561,12 @@ static int pakfire_execute_fork(void* data) {
 
        // Change root (unless root is /)
        if (strcmp(root, "/") != 0) {
+               // Mount everything
+               r = pakfire_mount_all(pakfire, MOUNT_IN_NEW_NS);
+               if (r)
+                       return r;
+
+               // Move the old root toi here
                r = pakfire_string_format(oldroot, "%s/.oldroot.XXXXXX", root);
                if (r < 0) {
                        ERROR(pakfire, "Could not figure out where the old root directory is going: %m\n");
@@ -871,6 +878,9 @@ ERROR:
        if (env.stderr[0])
                close(env.stderr[0]);
 
+       // Umount everything
+       pakfire_umount_all(pakfire, PAKFIRE_MOUNT_OPT_NAMESPACED);
+
        // Free environment
        for (unsigned int i = 0; env.envp[i]; i++)
                free(env.envp[i]);
diff --git a/src/libpakfire/include/pakfire/mount.h b/src/libpakfire/include/pakfire/mount.h
new file mode 100644 (file)
index 0000000..2f745e0
--- /dev/null
@@ -0,0 +1,39 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2022 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifdef PAKFIRE_PRIVATE
+
+#include <sys/queue.h>
+
+#include <pakfire/pakfire.h>
+
+#define PAKFIRE_MOUNT_OPT_NAMESPACED "x-pakfire.ns" // "_pakfire_ns"
+
+enum pakfire_mount_flags {
+       MOUNT_IN_NEW_NS = (1 << 0),
+};
+
+int pakfire_mount(struct pakfire* pakfire, const char* source, const char* target,
+       const char* filesystemtype, unsigned long mountflags, const void* data);
+
+int pakfire_mount_all(struct pakfire* pakfire, const enum pakfire_mount_flags mount_flags);
+int pakfire_umount_all(struct pakfire* pakfire, const char* option);
+
+#endif /* PAKFIRE_PRIVATE */
diff --git a/src/libpakfire/mount.c b/src/libpakfire/mount.c
new file mode 100644 (file)
index 0000000..e8885cc
--- /dev/null
@@ -0,0 +1,350 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2022 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+#include <linux/limits.h>
+#include <mntent.h>
+#include <stddef.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+// libmount
+#include <libmount/libmount.h>
+
+#include <pakfire/logging.h>
+#include <pakfire/pakfire.h>
+#include <pakfire/mount.h>
+#include <pakfire/util.h>
+
+static const struct pakfire_mountpoint {
+       const char* source;
+       const char* target;
+       const char* fstype;
+       int flags;
+       const char* options;
+       enum pakfire_mount_flags mount_flags;
+} mountpoints[] = {
+       // The root filesystem is a tmpfs
+       { "pakfire_root",  "",             "tmpfs", 0, NULL, 0 },
+
+       { "pakfire_proc",  "proc",         "proc",  MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL,
+               MOUNT_IN_NEW_NS },
+
+       // Bind mount /proc/sys as read-only with the following exceptions:
+       //  * /proc/sys/net
+       { "/proc/sys",     "proc/sys",     "bind",  MS_BIND, NULL,
+               MOUNT_IN_NEW_NS },
+       { "/proc/sys/net", "proc/sys/net", "bind",  MS_BIND, NULL,
+               MOUNT_IN_NEW_NS },
+       { "/proc/sys",     "proc/sys",     "bind",  MS_BIND|MS_RDONLY|MS_REMOUNT, NULL,
+               MOUNT_IN_NEW_NS },
+
+       // Bind mount /sys as read-only
+       { "/sys",          "sys",          "bind",  MS_BIND, NULL, 0 },
+       { "/sys",          "sys",          "bind",  MS_BIND|MS_RDONLY|MS_REMOUNT, NULL, 0 },
+
+       // Create a new /dev
+       { "pakfire_dev",   "dev",          "tmpfs", MS_NOSUID|MS_NOEXEC,
+               "mode=755,size=4m,nr_inodes=64k", 0 },
+       { "/dev/pts",      "dev/pts",      "bind",  MS_BIND, NULL, 0 },
+
+       // Create a new /run
+       { "pakfire_tmpfs", "run",          "tmpfs", MS_NOSUID|MS_NOEXEC|MS_NODEV,
+               "mode=755,size=4m,nr_inodes=1k", 0 },
+
+       // Create a new /tmp
+       { "pakfire_tmpfs", "tmp",          "tmpfs", MS_NOSUID|MS_NODEV,
+               "mode=755", 0 },
+
+       // The end
+       { NULL },
+};
+
+/*
+       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),
+               const char* option, const void* data) {
+       const char* root = pakfire_get_path(pakfire);
+       int r = 1;
+
+       FILE* f = setmntent("/proc/mounts", "r");
+       if (!f) {
+               ERROR(pakfire, "Could not open /proc/mounts: %m\n");
+               return r;
+       }
+
+       for (;;) {
+               struct mntent* mnt = getmntent(f);
+               if (!mnt)
+                       break;
+
+               // Ignore any mointpoints that don't belong to us
+               if (!pakfire_string_startswith(mnt->mnt_dir, root))
+                       continue;
+
+               // Filter by option
+               if (option) {
+                       if (hasmntopt(mnt, option))
+                               continue;
+               }
+
+               // Call the callback for each relevant mountpoint
+               r = callback(pakfire, mnt, data);
+               if (r)
+                       break;
+       }
+
+       // Tidy up
+       endmntent(f);
+
+       return r;
+}
+
+static int __pakfire_is_mountpoint(struct pakfire* pakfire,
+               struct mntent* mnt, const void* data) {
+       const char* path = (const char*)data;
+
+       // Return if path matches
+       return (strcmp(mnt->mnt_dir, path) == 0);
+}
+
+int pakfire_is_mountpoint(struct pakfire* pakfire, const char* path) {
+       return pakfire_mount_foreach(pakfire, __pakfire_is_mountpoint, NULL, path);
+}
+
+int pakfire_mount(struct pakfire* pakfire, const char* source, const char* target,
+               const char* fstype, unsigned long mflags, const void* data) {
+       const char* options = (const char*)data;
+       int r;
+
+       char error[1024];
+
+       // Check for some basic inputs
+       if (!source || !target) {
+               errno = EINVAL;
+               return 1;
+       }
+
+       DEBUG(pakfire, "Mounting %s from %s (%s - %s)\n",
+               target, source, fstype, options);
+
+#ifdef PAKFIRE_DEBUG
+       // Enable debugging for libmount
+       mnt_init_debug(0xffff);
+#endif
+
+       // Allocate a new mount context
+       struct libmnt_context* ctx = mnt_new_context();
+       if (!ctx)
+               return 1;
+
+       // Disable any mount helpers
+       r = mnt_context_disable_helpers(ctx, 1);
+       if (r) {
+               ERROR(pakfire, "Could not disable mount helpers: %m\n");
+               goto ERROR;
+       }
+
+       // Set source
+       r = mnt_context_set_source(ctx, source);
+       if (r) {
+               ERROR(pakfire, "Could not set source: %m\n");
+               goto ERROR;
+       }
+
+       // Set target
+       r = mnt_context_set_target(ctx, target);
+       if (r) {
+               ERROR(pakfire, "Could not set target: %m\n");
+               goto ERROR;
+       }
+
+       // Set filesystem type
+       if (fstype) {
+               r = mnt_context_set_fstype(ctx, fstype);
+               if (r) {
+                       ERROR(pakfire, "Could not set filesystem type: %m\n");
+                       goto ERROR;
+               }
+       }
+
+       // Set mount flags
+       if (mflags) {
+               r = mnt_context_set_mflags(ctx, mflags);
+               if (r) {
+                       ERROR(pakfire, "Could not set mount flags: %m\n");
+                       goto ERROR;
+               }
+       }
+
+       // Set options
+       if (options) {
+               r = mnt_context_set_options(ctx, options);
+               if (r) {
+                       ERROR(pakfire, "Could not set mount options: %m\n");
+                       goto ERROR;
+               }
+       }
+
+       // Perform mount operation
+       r = mnt_context_mount(ctx);
+       if (r) {
+               // Fetch the error message
+               mnt_context_get_excode(ctx, r, error, sizeof(error));
+
+               ERROR(pakfire, "Mount unsuccessful: %s\n", error);
+               goto ERROR;
+       }
+
+ERROR:
+       if (ctx)
+               mnt_free_context(ctx);
+
+       return r;
+}
+
+static int pakfire_umount(struct pakfire* pakfire, const char* path, int flags) {
+       int r;
+
+       DEBUG(pakfire, "Umounting %s\n", path);
+
+RETRY:
+       // Perform umount
+       r = umount2(path, flags);
+       if (r) {
+               // Attempt a lazy umount when busy
+               if (errno == EBUSY) {
+                       flags |= MNT_DETACH;
+                       goto RETRY;
+               }
+
+               ERROR(pakfire, "Could not umount %s: %m\n", path);
+       }
+
+       return r;
+}
+
+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
+       );
+
+       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);
+}
+
+int pakfire_mount_all(struct pakfire* pakfire, const enum pakfire_mount_flags mount_flags) {
+       char target[PATH_MAX];
+       char options[PATH_MAX];
+       int r;
+
+       // Fetch Pakfire's root directory
+       const char* root = pakfire_get_path(pakfire);
+
+       // Are we being called from a new namespace?
+       const unsigned int in_new_ns = (mount_flags & MOUNT_IN_NEW_NS);
+
+       for (const struct pakfire_mountpoint* mp = mountpoints; mp->source; mp++) {
+               if (!in_new_ns && (mp->mount_flags & MOUNT_IN_NEW_NS))
+                       continue;
+
+               if (in_new_ns && !(mp->mount_flags & MOUNT_IN_NEW_NS))
+                       continue;
+
+               // Figure out where to mount
+               r = pakfire_path_join(target, root, mp->target);
+               if (r < 0)
+                       return r;
+
+               // Append namespace mount option
+               if (in_new_ns) {
+                       if (mp->options)
+                               pakfire_string_format(options, "%s,%s",
+                                       mp->options, PAKFIRE_MOUNT_OPT_NAMESPACED);
+                       else
+                               pakfire_string_set(options, PAKFIRE_MOUNT_OPT_NAMESPACED);
+               } else {
+                       if (mp->options)
+                               pakfire_string_set(options, mp->options);
+                       else
+                               pakfire_string_set(options, "");
+               }
+
+               // Create target
+               pakfire_mkdir(target, 0);
+
+RETRY:
+               // Perform mount()
+               r = pakfire_mount(pakfire, mp->source, target, mp->fstype, mp->flags, options);
+               if (r) {
+                       // If the target directory does not exist, we will create it
+                       if (errno == ENOENT) {
+                               r = pakfire_mkdir(target, S_IRUSR|S_IWUSR|S_IXUSR);
+                               if (r) {
+                                       ERROR(pakfire, "Could not create %s\n", target);
+                                       return r;
+                               }
+
+                               goto RETRY;
+                       }
+
+                       ERROR(pakfire, "Could not mount /%s: %m\n", mp->target);
+                       return r;
+               }
+       }
+
+       // List everything that is mounted
+       pakfire_mount_list(pakfire);
+
+       return 0;
+}
+
+static int __pakfire_umount(struct pakfire* pakfire,
+               struct mntent* mnt, const void* data) {
+       return pakfire_umount(pakfire, mnt->mnt_dir, 0);
+}
+
+/*
+       umounts everything that hasn't been umounted, yet
+*/
+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);
+}
index ea7bf2deb0cae0dd337120c96cd472ff10256506..378ab095f525c05ddb394678033859472481fdbf 100644 (file)
@@ -27,7 +27,6 @@
 #include <stdlib.h>
 #include <sys/file.h>
 #include <sys/mount.h>
-#include <sys/queue.h>
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
 #include <sys/types.h>
@@ -49,6 +48,7 @@
 #include <pakfire/db.h>
 #include <pakfire/keystore.h>
 #include <pakfire/logging.h>
+#include <pakfire/mount.h>
 #include <pakfire/package.h>
 #include <pakfire/packagelist.h>
 #include <pakfire/pakfire.h>
 #define LOCK_PATH PAKFIRE_PRIVATE_DIR "/.lock"
 #define CCACHE_DIR "/var/cache/ccache"
 
-struct mountpoint {
-       STAILQ_ENTRY(mountpoint) nodes;
-       char path[PATH_MAX];
-};
-
 struct pakfire {
        int nrefs;
 
@@ -104,8 +99,6 @@ struct pakfire {
 
        struct pakfire_config* config;
 
-       STAILQ_HEAD(mountpoints, mountpoint) mountpoints;
-
        struct pakfire_distro {
                char pretty_name[256];
                char name[64];
@@ -154,160 +147,6 @@ int pakfire_on_root(struct pakfire* pakfire) {
        return (strcmp(pakfire->path, "/") == 0);
 }
 
-static const struct pakfire_mountpoint {
-       const char* source;
-       const char* target;
-       const char* fstype;
-       int flags;
-       const char* options;
-} mountpoints[] = {
-       { "pakfire_root",  "",             "tmpfs", 0, NULL },
-
-       { "pakfire_proc",  "proc",         "proc",  MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL },
-
-       // Bind mount /proc/sys as read-only with the following exceptions:
-       //  * /proc/sys/net
-       { "/proc/sys",     "proc/sys",     NULL,    MS_BIND, NULL },
-       { "/proc/sys/net", "proc/sys/net", NULL,    MS_BIND, NULL },
-       { "/proc/sys",     "proc/sys",     NULL,    MS_BIND|MS_RDONLY|MS_REMOUNT, NULL },
-
-       // Bind mount /sys as read-only
-       { "/sys",          "sys",          NULL,    MS_BIND, NULL },
-       { "/sys",          "sys",          NULL,    MS_BIND|MS_RDONLY|MS_REMOUNT, NULL },
-
-       // Create a new /dev
-       { "pakfire_dev",   "dev",          "tmpfs", MS_NOSUID|MS_NOEXEC,
-               "mode=755,size=4m,nr_inodes=64k" },
-       { "/dev/pts",      "dev/pts",      NULL,    MS_BIND, NULL },
-
-       // Create a new /run
-       { "pakfire_tmpfs", "run",          "tmpfs", MS_NOSUID|MS_NOEXEC|MS_NODEV,
-               "mode=755,size=4m,nr_inodes=1k" },
-
-       // Create a new /tmp
-       { "pakfire_tmpfs", "tmp",          "tmpfs", MS_NOSUID|MS_NODEV,
-               "mode=755" },
-
-       // The end
-       { NULL },
-};
-
-static int __mount(struct pakfire* pakfire, const char* source, const char* target,
-               const char* filesystemtype, unsigned long mountflags, const void* data) {
-       int r = mount(source, target, filesystemtype, mountflags, data);
-       if (r)
-               return r;
-
-       // Skip if the mountpoint is already on the list
-       if (pakfire_is_mountpoint(pakfire, target))
-               return 0;
-
-       // If not, add the mountpoint to the list so that we can umount it later
-       struct mountpoint* mp = calloc(1, sizeof(*mp));
-       if (!mp)
-               return 1;
-
-       pakfire_string_set(mp->path, target);
-
-       STAILQ_INSERT_HEAD(&pakfire->mountpoints, mp, nodes);
-
-       return 0;
-}
-
-static int pakfire_mount(struct pakfire* pakfire) {
-       char target[PATH_MAX];
-       int r;
-
-       // Remount / as private
-       r = mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL);
-       if (r) {
-               ERROR(pakfire, "Could not re-mount / as private: %m\n");
-               return r;
-       }
-
-       for (const struct pakfire_mountpoint* mp = mountpoints; mp->source; mp++) {
-               // Skip mounting root when a directory has been passed
-               if (!*mp->target && !pakfire->mount_tmpfs)
-                       continue;
-
-               DEBUG(pakfire, "Mounting /%s\n", mp->target);
-
-               r = pakfire_path_join(target, pakfire->path, mp->target);
-               if (r < 0)
-                       return r;
-
-RETRY:
-               // Perform mount()
-               r = __mount(pakfire, mp->source, target, mp->fstype, mp->flags, mp->options);
-               if (r) {
-                       // If the target directory does not exist, we will create it
-                       if (errno == ENOENT) {
-                               r = pakfire_mkdir(target, S_IRUSR|S_IWUSR|S_IXUSR);
-                               if (r) {
-                                       ERROR(pakfire, "Could not create %s\n", target);
-                                       return r;
-                               }
-
-                               goto RETRY;
-                       }
-
-                       ERROR(pakfire, "Could not mount /%s: %m\n", mp->target);
-                       return r;
-               }
-       }
-
-       return 0;
-}
-
-static int pakfire_umount(struct pakfire* pakfire) {
-       struct mountpoint* mp;
-       int r;
-       int flags = 0;
-
-       while (!STAILQ_EMPTY(&pakfire->mountpoints)) {
-               // Take the first element from the list
-               mp = STAILQ_FIRST(&pakfire->mountpoints);
-
-               // Remove first element
-               STAILQ_REMOVE_HEAD(&pakfire->mountpoints, nodes);
-
-               DEBUG(pakfire, "Umounting %s\n", mp->path);
-
-               // Reset flags
-               flags = 0;
-
-               // Perform umount
-RETRY:
-               r = umount2(mp->path, flags);
-
-               if (r) {
-                       // Attempt a lazy umount when busy
-                       if (errno == EBUSY) {
-                               flags |= MNT_DETACH;
-                               goto RETRY;
-                       }
-
-                       ERROR(pakfire, "Could not umount %s: %m\n", mp->path);
-               }
-
-               free(mp);
-       }
-
-       return 0;
-}
-
-int pakfire_is_mountpoint(struct pakfire* pakfire, const char* path) {
-       struct mountpoint* mp;
-
-       // Check if path is on this list
-       STAILQ_FOREACH(mp, &pakfire->mountpoints, nodes) {
-               if (strcmp(mp->path, path) == 0)
-                       return 1;
-       }
-
-       return 0;
-}
-
 static const struct pakfire_devnode {
        const char* path;
        int major;
@@ -524,7 +363,7 @@ static int pakfire_mount_interpreter(struct pakfire* pakfire) {
                return 1;
        fclose(f);
 
-       r = __mount(pakfire, interpreter, target, NULL, MS_BIND|MS_RDONLY, NULL);
+       r = pakfire_mount(pakfire, interpreter, target, NULL, MS_BIND|MS_RDONLY, NULL);
        if (r)
                ERROR(pakfire, "Could not mount interpreter %s to %s: %m\n", interpreter, target);
 
@@ -557,7 +396,7 @@ static void pakfire_free(struct pakfire* pakfire) {
        pakfire_release_lock(pakfire);
 
        // umount everything
-       pakfire_umount(pakfire);
+       pakfire_umount_all(pakfire, 0);
 
        if (pakfire->destroy_on_free && *pakfire->path) {
                DEBUG(pakfire, "Destroying %s\n", pakfire->path);
@@ -996,7 +835,7 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
        }
 
        // Mount filesystems
-       r = pakfire_mount(p);
+       r = pakfire_mount_all(p, 0);
        if (r)
                goto ERROR;
 
@@ -1162,7 +1001,7 @@ PAKFIRE_EXPORT int pakfire_bind(struct pakfire* pakfire, const char* src, const
        if (r < 0)
                return 1;
 
-       DEBUG(pakfire, "Mounting %s to %s\n", src, mountpoint);
+       DEBUG(pakfire, "Bind-mounting %s to %s\n", src, mountpoint);
 
        r = stat(src, &st);
        if (r < 0) {
@@ -1198,7 +1037,7 @@ PAKFIRE_EXPORT int pakfire_bind(struct pakfire* pakfire, const char* src, const
        }
 
        // Perform mount
-       return __mount(pakfire, src, mountpoint, NULL, flags|MS_BIND, NULL);
+       return pakfire_mount(pakfire, src, mountpoint, NULL, flags|MS_BIND, NULL);
 }
 
 gpgme_ctx_t pakfire_get_gpgctx(struct pakfire* pakfire) {