]> git.ipfire.org Git - people/ms/pakfire.git/blobdiff - src/libpakfire/mount.c
mount: Remove the legacy logger
[people/ms/pakfire.git] / src / libpakfire / mount.c
index ec9537a60b1698e244a77096c2632c596e483efe..a364baf0c701172f79a79ac066d0af12cf2c34fd 100644 (file)
 #include <sys/sysmacros.h>
 #include <sys/types.h>
 
-// libmount
-#include <libmount/libmount.h>
-
 #include <pakfire/arch.h>
 #include <pakfire/logging.h>
 #include <pakfire/pakfire.h>
+#include <pakfire/parse.h>
 #include <pakfire/path.h>
 #include <pakfire/mount.h>
 #include <pakfire/string.h>
 #include <pakfire/util.h>
 
 static const struct pakfire_mountpoint {
+       pakfire_mntns_t ns;
        const char* source;
        const char* target;
        const char* fstype;
@@ -45,59 +44,178 @@ static const struct pakfire_mountpoint {
        const char* options;
 } mountpoints[] = {
        // Mount a new instance of /proc
-       { "pakfire_proc",        "proc",               "proc",
-               MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL, },
+       {
+               PAKFIRE_MNTNS_INNER|PAKFIRE_MNTNS_OUTER,
+               "pakfire_proc",
+               "proc",
+               "proc",
+               MS_NOSUID|MS_NOEXEC|MS_NODEV,
+               NULL,
+       },
+
+       /*
+               XXX it is kind of problematic to mount /proc twice as a process inside the
+               jail can umount /proc and will then see the host's /proc.
+       */
 
        // Make /proc/sys read-only (except /proc/sys/net)
-       { "/proc/sys",           "proc/sys",           "bind",   MS_BIND|MS_REC, NULL, },
-       { "/proc/sys/net",       "proc/sys/net",       "bind",   MS_BIND|MS_REC, NULL, },
-       { "/proc/sys",           "proc/sys",           "bind",
-               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL, },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/sys",
+               "proc/sys",
+               "bind",
+               MS_BIND|MS_REC,
+               NULL,
+       },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/sys/net",
+               "proc/sys/net",
+               "bind",
+               MS_BIND|MS_REC,
+               NULL,
+       },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/sys",
+               "proc/sys",
+               "bind",
+               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
+               NULL,
+       },
 
        // Deny write access to /proc/sysrq-trigger (can be used to restart the host)
-       { "/proc/sysrq-trigger", "proc/sysrq-trigger", "bind",   MS_BIND|MS_REC, NULL, },
-       { "/proc/sysrq-trigger", "proc/sysrq-trigger", "bind",
-               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL, },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/sysrq-trigger",
+               "proc/sysrq-trigger",
+               "bind",
+               MS_BIND|MS_REC,
+               NULL,
+       },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/sysrq-trigger",
+               "proc/sysrq-trigger",
+               "bind",
+               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
+               NULL,
+       },
 
        // Make /proc/irq read-only
-       { "/proc/irq",           "proc/irq",           "bind",   MS_BIND|MS_REC, NULL, },
-       { "/proc/irq",           "proc/irq",           "bind",
-               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL, },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/irq",
+               "proc/irq",
+               "bind",
+               MS_BIND|MS_REC,
+               NULL,
+       },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/irq",
+               "proc/irq",
+               "bind",
+               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
+               NULL,
+       },
 
        // Make /proc/bus read-only
-       { "/proc/bus",           "proc/bus",           "bind",   MS_BIND|MS_REC, NULL, },
-       { "/proc/bus",           "proc/bus",           "bind",
-               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL, },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/bus",
+               "proc/bus",
+               "bind",
+               MS_BIND|MS_REC,
+               NULL,
+       },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "/proc/bus",
+               "proc/bus",
+               "bind",
+               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
+               NULL,
+       },
 
        // Bind-Mount /sys ready-only
-       { "/sys",                "sys",                "bind",   MS_BIND|MS_REC, NULL, },
-       { "/sys",                "sys",                "bind",
-               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL, },
+       {
+               PAKFIRE_MNTNS_OUTER,
+               "/sys",
+               "sys",
+               "bind",
+               MS_BIND|MS_REC,
+               NULL,
+       },
+       {
+               PAKFIRE_MNTNS_OUTER,
+               "/sys",
+               "sys",
+               "bind",
+               MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
+               NULL,
+       },
 
        // Create a new /dev
-       { "pakfire_dev",         "dev",                "tmpfs",  MS_NOSUID|MS_NOEXEC,
-               "mode=0755,size=4m,nr_inodes=64k", },
-       { "pakfire_dev_pts",     "dev/pts",            "devpts", MS_NOSUID|MS_NOEXEC,
-               "newinstance,ptmxmode=0666,mode=620", },
+       {
+               PAKFIRE_MNTNS_OUTER,
+               "pakfire_dev",
+               "dev",
+               "tmpfs",
+               MS_NOSUID|MS_NOEXEC,
+               "mode=0755,size=4m,nr_inodes=64k",
+       },
+       {
+               PAKFIRE_MNTNS_OUTER,
+               "pakfire_dev_pts",
+               "dev/pts",
+               "devpts",
+               MS_NOSUID|MS_NOEXEC,
+               "newinstance,ptmxmode=0666,mode=620",
+       },
 
        // Create a new /dev/shm
-       { "pakfire_dev_shm",     "dev/shm",            "tmpfs",
-               MS_NOSUID|MS_NODEV|MS_STRICTATIME, "mode=1777,size=1024m", },
+       {
+               PAKFIRE_MNTNS_OUTER,
+               "pakfire_dev_shm",
+               "dev/shm",
+               "tmpfs",
+               MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+               "mode=1777,size=1024m",
+       },
 
        // Mount /dev/mqueue
-       { "mqueue",               "dev/mqueue",        "mqueue",
-               MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL },
+       {
+               PAKFIRE_MNTNS_INNER,
+               "mqueue",
+               "dev/mqueue",
+               "mqueue",
+               MS_NOSUID|MS_NOEXEC|MS_NODEV,
+               NULL,
+       },
 
        // Create a new /run
-       { "pakfire_run",          "run",               "tmpfs",  MS_NOSUID|MS_NOEXEC|MS_NODEV,
-               "mode=755,size=256m,nr_inodes=1k", },
+       {
+               PAKFIRE_MNTNS_OUTER,
+               "pakfire_run",
+               "run",
+               "tmpfs",
+               MS_NOSUID|MS_NOEXEC|MS_NODEV,
+               "mode=755,size=256m,nr_inodes=1k",
+       },
 
        // Create a new /tmp
-       { "pakfire_tmp",          "tmp",               "tmpfs",
-               MS_NOSUID|MS_NODEV|MS_STRICTATIME, "mode=1777,size=4096m", },
+       {
+               PAKFIRE_MNTNS_OUTER,
+               "pakfire_tmp",
+               "tmp",
+               "tmpfs",
+               MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+               "mode=1777,size=4096m",
+       },
 
        // The end
-       { NULL },
+       {},
 };
 
 static const struct pakfire_devnode {
@@ -114,7 +232,6 @@ static const struct pakfire_devnode {
        { "/dev/urandom",   1,  9, S_IFCHR|S_IRUSR|S_IRGRP|S_IROTH, 0 },
        { "/dev/kmsg",      1, 11, S_IFCHR|S_IRUSR|S_IRGRP|S_IROTH, 0 },
        { "/dev/tty",       5,  0, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, 0 },
-       { "/dev/console",   5,  1, S_IFCHR|S_IRUSR|S_IWUSR, 0 },
        { "/dev/rtc0",    252,  0, S_IFCHR|S_IRUSR|S_IWUSR, 0 },
 
        // Loop Devices
@@ -144,12 +261,12 @@ static const struct pakfire_symlink {
        { NULL },
 };
 
-int pakfire_mount_change_propagation(struct pakfire* pakfire, int propagation, const char* path) {
-       DEBUG(pakfire, "Changing mount propagation on %s\n", path);
+int pakfire_mount_change_propagation(struct pakfire_ctx* ctx, const char* path, int propagation) {
+       CTX_DEBUG(ctx, "Changing mount propagation on %s\n", path);
 
        int r = mount(NULL, path, NULL, propagation|MS_REC, NULL);
        if (r)
-               ERROR(pakfire, "Failed to change mount propagation on %s: %m\n", path);
+               CTX_ERROR(ctx, "Failed to change mount propagation on %s: %m\n", path);
 
        return r;
 }
@@ -159,7 +276,8 @@ static int pakfire_mount_is_mountpoint(struct pakfire* pakfire, const char* path
        return 1;
 }
 
-int pakfire_mount_make_mounpoint(struct pakfire* pakfire, const char* path) {
+int pakfire_mount_make_mounpoint(struct pakfire_ctx* ctx, struct pakfire* pakfire,
+               const char* path) {
        int r;
 
        // Check if path already is a mountpoint
@@ -174,86 +292,22 @@ int pakfire_mount_make_mounpoint(struct pakfire* pakfire, const char* path) {
                        break;
 
                default:
-                       ERROR(pakfire, "Could not determine whether %s is a mountpoint: %m\n", path);
+                       CTX_ERROR(ctx, "Could not determine whether %s is a mountpoint: %m\n", path);
                        return r;
        }
 
        // Bind-mount to self
        r = mount(path, path, NULL, MS_BIND|MS_REC, NULL);
        if (r) {
-               ERROR(pakfire, "Could not make %s a mountpoint: %m\n", path);
+               CTX_ERROR(ctx, "Could not make %s a mountpoint: %m\n", path);
                return r;
        }
 
        return 0;
 }
 
-/*
-       Easy way to iterate through all mountpoints
-*/
-static int pakfire_mount_foreach(struct pakfire* pakfire, int direction,
-               int (*callback)(struct pakfire* pakfire, struct libmnt_fs* fs, const void* data),
-               const void* data) {
-       const char* root = pakfire_get_path(pakfire);
-       int r = 0;
-
-       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");
-               goto ERROR;
-       }
-
-       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(target, root))
-                       continue;
-
-               // Call the callback for each relevant mountpoint
-               r = callback(pakfire, fs, data);
-               if (r)
-                       break;
-       }
-
-ERROR:
-       // Tidy up
-       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 libmnt_fs* fs, const void* data) {
-       const char* path = (const char*)data;
-
-       return mnt_fs_streq_target(fs, path);
-}
-
-int pakfire_is_mountpoint(struct pakfire* pakfire, const char* path) {
-       return pakfire_mount_foreach(pakfire, MNT_ITER_FORWARD,
-               __pakfire_is_mountpoint, path);
-}
-
-static int pakfire_mount(struct pakfire* pakfire, const char* source, const char* target,
-               const char* fstype, unsigned long mflags, const void* data) {
+static int pakfire_mount(struct pakfire_ctx* ctx, struct pakfire* pakfire, const char* source,
+               const char* target, const char* fstype, unsigned long mflags, const void* data) {
        const char* options = (const char*)data;
 
        // Check for some basic inputs
@@ -262,43 +316,38 @@ static int pakfire_mount(struct pakfire* pakfire, const char* source, const char
                return 1;
        }
 
-       DEBUG(pakfire, "Mounting %s from %s (%s - %s)\n", target, source, fstype, options);
+       CTX_DEBUG(ctx, "Mounting %s from %s (%s - %s)\n", target, source, fstype, options);
 
        // Perform mount()
        int r = mount(source, target, fstype, mflags, data);
        if (r) {
-               ERROR(pakfire, "Could not mount %s: %m\n", target);
+               CTX_ERROR(ctx, "Could not mount %s: %m\n", target);
        }
 
        return r;
 }
 
-static int __pakfire_mount_print(struct pakfire* pakfire,
-               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)
-       );
+static int __pakfire_mount_list(char* line, size_t length, void* data) {
+       struct pakfire_ctx* ctx = data;
+
+       // Send the line to the logger
+       CTX_DEBUG(ctx, "  %.*s", (int)length, line);
 
        return 0;
 }
 
-int pakfire_mount_list(struct pakfire* pakfire) {
-       DEBUG(pakfire, "Mountpoints:\n");
+int pakfire_mount_list(struct pakfire_ctx* ctx) {
+       CTX_DEBUG(ctx, "Mountpoints:\n");
 
-       return pakfire_mount_foreach(pakfire, MNT_ITER_FORWARD,
-               __pakfire_mount_print, NULL);
+       return pakfire_parse_file("/proc/self/mounts", __pakfire_mount_list, ctx);
 }
 
-static int pakfire_populate_dev(struct pakfire* pakfire, int flags) {
+int pakfire_populate_dev(struct pakfire_ctx* ctx, struct pakfire* pakfire, int flags) {
        char path[PATH_MAX];
 
        // Create device nodes
        for (const struct pakfire_devnode* devnode = devnodes; devnode->path; devnode++) {
-               DEBUG(pakfire, "Creating device node %s\n", devnode->path);
+               CTX_DEBUG(ctx, "Creating device node %s\n", devnode->path);
 
                // Check if flags match
                if (devnode->flags && !(flags & devnode->flags))
@@ -323,26 +372,26 @@ static int pakfire_populate_dev(struct pakfire* pakfire, int flags) {
                        goto MOUNT;
 
                // Otherwise log an error and end
-               ERROR(pakfire, "Could not create %s: %m\n", devnode->path);
+               CTX_ERROR(ctx, "Could not create %s: %m\n", devnode->path);
                return r;
 
 MOUNT:
                // Create an empty file
                r = pakfire_touch(path, 0444);
                if (r) {
-                       ERROR(pakfire, "Could not create %s: %m\n", path);
+                       CTX_ERROR(ctx, "Could not create %s: %m\n", path);
                        return r;
                }
 
                // Create a bind-mount over the file
-               r = pakfire_mount(pakfire, devnode->path, path, "bind", MS_BIND, NULL);
+               r = pakfire_mount(ctx, pakfire, devnode->path, path, "bind", MS_BIND, NULL);
                if (r)
                        return r;
        }
 
        // Create symlinks
        for (const struct pakfire_symlink* s = symlinks; s->target; s++) {
-               DEBUG(pakfire, "Creating symlink %s -> %s\n", s->path, s->target);
+               CTX_DEBUG(ctx, "Creating symlink %s -> %s\n", s->path, s->target);
 
                int r = pakfire_path(pakfire, path, "%s", s->path);
                if (r)
@@ -350,7 +399,7 @@ MOUNT:
 
                r = symlink(s->target, path);
                if (r) {
-                       ERROR(pakfire, "Could not create symlink %s: %m\n", s->path);
+                       CTX_ERROR(ctx, "Could not create symlink %s: %m\n", s->path);
                        return r;
                }
        }
@@ -358,7 +407,7 @@ MOUNT:
        return 0;
 }
 
-static int pakfire_mount_interpreter(struct pakfire* pakfire) {
+int pakfire_mount_interpreter(struct pakfire_ctx* ctx, struct pakfire* pakfire) {
        char target[PATH_MAX];
 
        // Fetch the target architecture
@@ -371,7 +420,7 @@ static int pakfire_mount_interpreter(struct pakfire* pakfire) {
        if (!interpreter)
                return 0;
 
-       DEBUG(pakfire, "Mounting interpreter %s for %s\n", interpreter, arch);
+       CTX_DEBUG(ctx, "Mounting interpreter %s for %s\n", interpreter, arch);
 
        // Where to mount this?
        int r = pakfire_path(pakfire, target, "%s", interpreter);
@@ -389,23 +438,29 @@ static int pakfire_mount_interpreter(struct pakfire* pakfire) {
                return 1;
        fclose(f);
 
-       r = pakfire_mount(pakfire, interpreter, target, NULL, MS_BIND|MS_RDONLY, NULL);
+       r = pakfire_mount(ctx, pakfire, interpreter, target, NULL, MS_BIND|MS_RDONLY, NULL);
        if (r)
-               ERROR(pakfire, "Could not mount interpreter %s to %s: %m\n", interpreter, target);
+               CTX_ERROR(ctx, "Could not mount interpreter %s to %s: %m\n", interpreter, target);
 
        return r;
 }
 
-int pakfire_mount_all(struct pakfire* pakfire, int flags) {
+int pakfire_mount_all(struct pakfire_ctx* ctx, struct pakfire* pakfire, pakfire_mntns_t ns, int flags) {
        char target[PATH_MAX];
        int r;
 
+       const char* root = "/";
+
        // Fetch Pakfire's root directory
-       const char* root = pakfire_get_path(pakfire);
+       if (ns == PAKFIRE_MNTNS_OUTER)
+               root = pakfire_get_path(pakfire);
 
        for (const struct pakfire_mountpoint* mp = mountpoints; mp->source; mp++) {
+               if (!(mp->ns & ns))
+                       continue;
+
                // Figure out where to mount
-               r = pakfire_path_join(target, root, mp->target);
+               r = pakfire_path_append(target, root, mp->target);
                if (r)
                        return r;
 
@@ -413,31 +468,23 @@ int pakfire_mount_all(struct pakfire* pakfire, int flags) {
                if (!pakfire_path_exists(target)) {
                        r = pakfire_mkdir(target, 0755);
                        if (r) {
-                               ERROR(pakfire, "Could not create %s: %m\n", target);
+                               CTX_ERROR(ctx, "Could not create %s: %m\n", target);
                                return r;
                        }
                }
 
                // Perform mount()
-               r = pakfire_mount(pakfire, mp->source, target, mp->fstype, mp->flags, mp->options);
+               r = pakfire_mount(ctx, pakfire, mp->source, target,
+                       mp->fstype, mp->flags, mp->options);
                if (r)
                        return r;
        }
 
-       // Populate /dev
-       r = pakfire_populate_dev(pakfire, flags);
-       if (r)
-               return r;
-
-       // Mount the interpreter (if needed)
-       r = pakfire_mount_interpreter(pakfire);
-       if (r)
-               return r;
-
        return 0;
 }
 
-int pakfire_make_ramdisk(struct pakfire* pakfire, char* path, const char* args) {
+int pakfire_make_ramdisk(struct pakfire_ctx* ctx, struct pakfire* pakfire,
+               char* path, const char* args) {
        int r;
 
        // Create a new temporary directory
@@ -446,18 +493,20 @@ int pakfire_make_ramdisk(struct pakfire* pakfire, char* path, const char* args)
                return -errno;
 
        // Mount the ramdisk
-       r = pakfire_mount(pakfire, "pakfire_ramdisk", p, "tmpfs", 0, args);
+       r = pakfire_mount(ctx, pakfire, "pakfire_ramdisk", p, "tmpfs", 0, args);
        if (r) {
-               ERROR_ERRNO(pakfire, r, "Could not mount ramdisk at %s (%s): %m\n", p, args);
+               CTX_ERROR(ctx, "Could not mount ramdisk at %s (%s): %s\n",
+                       p, args, strerror(errno));
                return r;
        }
 
-       DEBUG(pakfire, "Ramdisk mounted at %s (%s)\n", p, args);
+       CTX_DEBUG(ctx, "Ramdisk mounted at %s (%s)\n", p, args);
 
        return 0;
 }
 
-int pakfire_bind(struct pakfire* pakfire, const char* src, const char* dst, int flags) {
+int pakfire_bind(struct pakfire_ctx* ctx, struct pakfire* pakfire,
+               const char* src, const char* dst, int flags) {
        struct stat st;
        char mountpoint[PATH_MAX];
 
@@ -468,11 +517,11 @@ int pakfire_bind(struct pakfire* pakfire, const char* src, const char* dst, int
        if (r)
                return r;
 
-       DEBUG(pakfire, "Bind-mounting %s to %s\n", src, mountpoint);
+       CTX_DEBUG(ctx, "Bind-mounting %s to %s\n", src, mountpoint);
 
        r = stat(src, &st);
        if (r < 0) {
-               ERROR(pakfire, "Could not stat %s: %m\n", src);
+               CTX_ERROR(ctx, "Could not stat %s: %m\n", src);
                return 1;
        }
 
@@ -507,7 +556,7 @@ int pakfire_bind(struct pakfire* pakfire, const char* src, const char* dst, int
        // as read-only and requires us to mount the source first, and then remount it
        // again using MS_RDONLY.
        if (flags & MS_RDONLY) {
-               r = pakfire_mount(pakfire, src, mountpoint, "bind", MS_BIND|MS_REC, NULL);
+               r = pakfire_mount(ctx, pakfire, src, mountpoint, "bind", MS_BIND|MS_REC, NULL);
                if (r)
                        return r;
 
@@ -516,5 +565,5 @@ int pakfire_bind(struct pakfire* pakfire, const char* src, const char* dst, int
        }
 
        // Perform mount
-       return pakfire_mount(pakfire, src, mountpoint, "bind", flags|MS_BIND|MS_REC, NULL);
+       return pakfire_mount(ctx, pakfire, src, mountpoint, "bind", flags|MS_BIND|MS_REC, NULL);
 }