]> git.ipfire.org Git - people/ms/pakfire.git/blobdiff - src/libpakfire/mount.c
mount: Make changing mount operation not dependant on pakfire
[people/ms/pakfire.git] / src / libpakfire / mount.c
index c08a1214eab6710ba13132d4691b327aa0b6a039..494c25852921b3dd166f6ccc91933449586a508d 100644 (file)
@@ -32,6 +32,7 @@
 #include <pakfire/arch.h>
 #include <pakfire/logging.h>
 #include <pakfire/pakfire.h>
+#include <pakfire/path.h>
 #include <pakfire/mount.h>
 #include <pakfire/string.h>
 #include <pakfire/util.h>
@@ -104,16 +105,29 @@ static const struct pakfire_devnode {
        int major;
        int minor;
        mode_t mode;
+       int flags;
 } devnodes[] = {
-       { "/dev/null",      1,  3, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, },
-       { "/dev/zero",      1,  5, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, },
-       { "/dev/full",      1,  7, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, },
-       { "/dev/random",    1,  8, S_IFCHR|S_IRUSR|S_IRGRP|S_IROTH, },
-       { "/dev/urandom",   1,  9, S_IFCHR|S_IRUSR|S_IRGRP|S_IROTH, },
-       { "/dev/kmsg",      1, 11, S_IFCHR|S_IRUSR|S_IRGRP|S_IROTH, },
-       { "/dev/tty",       5,  0, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, },
-       { "/dev/console",   5,  1, S_IFCHR|S_IRUSR|S_IWUSR, },
-       { "/dev/rtc0",    252,  0, S_IFCHR|S_IRUSR|S_IWUSR, },
+       { "/dev/null",      1,  3, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, 0 },
+       { "/dev/zero",      1,  5, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, 0 },
+       { "/dev/full",      1,  7, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH, 0 },
+       { "/dev/random",    1,  8, S_IFCHR|S_IRUSR|S_IRGRP|S_IROTH, 0 },
+       { "/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
+       { "/dev/loop-control", 10, 237, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+       { "/dev/loop0",         7,   0, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+       { "/dev/loop1",         7,   1, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+       { "/dev/loop2",         7,   2, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+       { "/dev/loop3",         7,   3, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+       { "/dev/loop4",         7,   4, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+       { "/dev/loop5",         7,   5, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+       { "/dev/loop6",         7,   6, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+       { "/dev/loop7",         7,   7, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, PAKFIRE_MOUNT_LOOP_DEVICES },
+
        { NULL },
 };
 
@@ -130,6 +144,50 @@ static const struct pakfire_symlink {
        { NULL },
 };
 
+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)
+               CTX_ERROR(ctx, "Failed to change mount propagation on %s: %m\n", path);
+
+       return r;
+}
+
+static int pakfire_mount_is_mountpoint(struct pakfire* pakfire, const char* path) {
+       // XXX THIS STILL NEEDS TO BE IMPLEMENTED
+       return 1;
+}
+
+int pakfire_mount_make_mounpoint(struct pakfire* pakfire, const char* path) {
+       int r;
+
+       // Check if path already is a mountpoint
+       r = pakfire_mount_is_mountpoint(pakfire, path);
+       switch (r) {
+               // Already is a mountpoint
+               case 0:
+                       return 0;
+
+               // Is not a mountpoint
+               case 1:
+                       break;
+
+               default:
+                       ERROR(pakfire, "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);
+               return r;
+       }
+
+       return 0;
+}
+
 /*
        Easy way to iterate through all mountpoints
 */
@@ -235,13 +293,17 @@ int pakfire_mount_list(struct pakfire* pakfire) {
                __pakfire_mount_print, NULL);
 }
 
-static int pakfire_populate_dev(struct pakfire* pakfire) {
+static int pakfire_populate_dev(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);
 
+               // Check if flags match
+               if (devnode->flags && !(flags & devnode->flags))
+                       continue;
+
                int r = pakfire_path(pakfire, path, "%s", devnode->path);
                if (r)
                        return r;
@@ -300,7 +362,7 @@ static int pakfire_mount_interpreter(struct pakfire* pakfire) {
        char target[PATH_MAX];
 
        // Fetch the target architecture
-       const char* arch = pakfire_get_arch(pakfire);
+       const char* arch = pakfire_get_effective_arch(pakfire);
 
        // Can we emulate this architecture?
        char* interpreter = pakfire_arch_find_interpreter(arch);
@@ -334,7 +396,7 @@ static int pakfire_mount_interpreter(struct pakfire* pakfire) {
        return r;
 }
 
-int pakfire_mount_all(struct pakfire* pakfire) {
+int pakfire_mount_all(struct pakfire* pakfire, int flags) {
        char target[PATH_MAX];
        int r;
 
@@ -343,7 +405,7 @@ int pakfire_mount_all(struct pakfire* pakfire) {
 
        for (const struct pakfire_mountpoint* mp = mountpoints; mp->source; mp++) {
                // 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;
 
@@ -363,7 +425,7 @@ int pakfire_mount_all(struct pakfire* pakfire) {
        }
 
        // Populate /dev
-       r = pakfire_populate_dev(pakfire);
+       r = pakfire_populate_dev(pakfire, flags);
        if (r)
                return r;
 
@@ -375,6 +437,26 @@ int pakfire_mount_all(struct pakfire* pakfire) {
        return 0;
 }
 
+int pakfire_make_ramdisk(struct pakfire* pakfire, char* path, const char* args) {
+       int r;
+
+       // Create a new temporary directory
+       char* p = pakfire_mkdtemp(path);
+       if (!p)
+               return -errno;
+
+       // Mount the ramdisk
+       r = pakfire_mount(pakfire, "pakfire_ramdisk", p, "tmpfs", 0, args);
+       if (r) {
+               ERROR_ERRNO(pakfire, r, "Could not mount ramdisk at %s (%s): %m\n", p, args);
+               return r;
+       }
+
+       DEBUG(pakfire, "Ramdisk mounted at %s (%s)\n", p, args);
+
+       return 0;
+}
+
 int pakfire_bind(struct pakfire* pakfire, const char* src, const char* dst, int flags) {
        struct stat st;
        char mountpoint[PATH_MAX];
@@ -425,7 +507,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, NULL, MS_BIND|MS_REC, NULL);
+               r = pakfire_mount(pakfire, src, mountpoint, "bind", MS_BIND|MS_REC, NULL);
                if (r)
                        return r;
 
@@ -434,5 +516,5 @@ int pakfire_bind(struct pakfire* pakfire, const char* src, const char* dst, int
        }
 
        // Perform mount
-       return pakfire_mount(pakfire, src, mountpoint, NULL, flags|MS_BIND|MS_REC, NULL);
+       return pakfire_mount(pakfire, src, mountpoint, "bind", flags|MS_BIND|MS_REC, NULL);
 }