guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

51/52: DRAFT daemon: Create wrapper for mount (2).


From: guix-commits
Subject: 51/52: DRAFT daemon: Create wrapper for mount (2).
Date: Thu, 9 Apr 2020 13:29:15 -0400 (EDT)

janneke pushed a commit to branch wip-hurd-vm
in repository guix.

commit 1089ff45a77c35b9f52482d573912691b9fc94da
Author: Manolis Ragkousis <address@hidden>
AuthorDate: Thu Jul 28 16:23:25 2016 +0300

    DRAFT daemon: Create wrapper for mount (2).
    
    TODO: (Ask Manolis to) upsteam libhurdutil patch.
    
    * nix/libstore/build.cc: Use nixMount, nixUmount2 instead of mount, mount2.
    * nix/libstore/local-store.cc: Likewise.
    * nix/libutil/calls.{hh,cc}: New file.
    * nix/local.mk: Add them.
    * config-daemon.ac: Check for libhurdutil availability.
---
 config-daemon.ac      |  13 ++++++
 nix/libstore/build.cc |  24 ++++-------
 nix/libutil/calls.cc  | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++
 nix/libutil/calls.hh  | 103 ++++++++++++++++++++++++++++++++++++++++++++++
 nix/local.mk          |   4 +-
 5 files changed, 240 insertions(+), 16 deletions(-)

diff --git a/config-daemon.ac b/config-daemon.ac
index 50ead35..99e3b37 100644
--- a/config-daemon.ac
+++ b/config-daemon.ac
@@ -56,8 +56,18 @@ if test "x$guix_build_daemon" = "xyes"; then
       ;;
   esac
 
+  case "$guix_system" in
+    i586-gnu)
+      HURD_LDFLAGS="-lfshelp -lhurdutil"
+      ;;
+    *)
+      HURD_LDFLAGS=""
+      ;;
+  esac
+
   AC_SUBST([LIBGCRYPT_CFLAGS])
   AC_SUBST([LIBGCRYPT_LIBS])
+  AC_SUBST([HURD_LDFLAGS])
 
   save_CFLAGS="$CFLAGS"
   save_LDFLAGS="$LDFLAGS"
@@ -116,6 +126,9 @@ if test "x$guix_build_daemon" = "xyes"; then
   dnl to do i686-linux builds on x86_64-linux machines.
   AC_CHECK_HEADERS([sys/personality.h])
 
+  dnl Check for <hurd/libhurdutil.h> for settrans support on GNU/Hurd.
+  AC_CHECK_HEADERS([hurd/hurdutil.h])
+
   dnl Determine the appropriate default list of substitute URLs (GnuTLS
   dnl is required so we can default to 'https'.)
   guix_substitute_urls="https://ci.guix.gnu.org";
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index 29266f1..14024b4 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -9,6 +9,7 @@
 #include "archive.hh"
 #include "affinity.hh"
 #include "builtins.hh"
+#include "calls.hh"
 
 #include <map>
 #include <sstream>
@@ -41,9 +42,6 @@
 #if HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
-#if HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
 #if HAVE_SYS_SYSCALL_H
 #include <sys/syscall.h>
 #endif
@@ -52,13 +50,9 @@
 #endif
 
 
-#define CHROOT_ENABLED HAVE_CHROOT && HAVE_SYS_MOUNT_H && defined(MS_BIND) && 
defined(MS_PRIVATE)
+#define CHROOT_ENABLED HAVE_CHROOT && defined(HANE_NIX_MOUNT) && 
defined(MS_BIND) && defined(MS_PRIVATE)
 #define CLONE_ENABLED defined(CLONE_NEWNS)
 
-#if defined(SYS_pivot_root)
-#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, 
new_root,put_old))
-#endif
-
 #if CHROOT_ENABLED
 #include <sys/socket.h>
 #include <sys/ioctl.h>
@@ -2092,13 +2086,13 @@ void DerivationGoal::runChild()
                outside of the namespace.  Making a subtree private is
                local to the namespace, though, so setting MS_PRIVATE
                does not affect the outside world. */
-            if (mount(0, "/", 0, MS_REC|MS_PRIVATE, 0) == -1) {
+            if (nixMount(0, "/", 0, MS_REC|MS_PRIVATE, 0) == -1) {
                 throw SysError("unable to make ‘/’ private mount");
             }
 
             /* Bind-mount chroot directory to itself, to treat it as a
                different filesystem from /, as needed for pivot_root. */
-            if (mount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, 
MS_BIND, 0) == -1)
+            if (nixMount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, 
MS_BIND, 0) == -1)
                 throw SysError(format("unable to bind mount ‘%1%’") % 
chrootRootDir);
 
             /* Set up a nearly empty /dev, unless the user asked to
@@ -2152,19 +2146,19 @@ void DerivationGoal::runChild()
                     createDirs(dirOf(target));
                     writeFile(target, "");
                 }
-                if (mount(source.c_str(), target.c_str(), "", MS_BIND, 0) == 
-1)
+                if (nixMount(source.c_str(), target.c_str(), "", MS_BIND, 0) 
== -1)
                     throw SysError(format("bind mount from `%1%' to `%2%' 
failed") % source % target);
             }
 
             /* Bind a new instance of procfs on /proc to reflect our
                private PID namespace. */
             createDirs(chrootRootDir + "/proc");
-            if (mount("none", (chrootRootDir + "/proc").c_str(), "proc", 0, 0) 
== -1)
+            if (nixMount("none", (chrootRootDir + "/proc").c_str(), "proc", 0, 
0) == -1)
                 throw SysError("mounting /proc");
 
             /* Mount a new tmpfs on /dev/shm to ensure that whatever
                the builder puts in /dev/shm is cleaned up automatically. */
-            if (pathExists("/dev/shm") && mount("none", (chrootRootDir + 
"/dev/shm").c_str(), "tmpfs", 0, 0) == -1)
+            if (pathExists("/dev/shm") && nixMount("none", (chrootRootDir + 
"/dev/shm").c_str(), "tmpfs", 0, 0) == -1)
                 throw SysError("mounting /dev/shm");
 
             /* Mount a new devpts on /dev/pts.  Note that this
@@ -2175,7 +2169,7 @@ void DerivationGoal::runChild()
                 !pathExists(chrootRootDir + "/dev/ptmx")
                 && dirsInChroot.find("/dev/pts") == dirsInChroot.end())
             {
-                if (mount("none", (chrootRootDir + "/dev/pts").c_str(), 
"devpts", 0, "newinstance,mode=0620") == -1)
+                if (nixMount("none", (chrootRootDir + "/dev/pts").c_str(), 
"devpts", 0, "newinstance,mode=0620") == -1)
                     throw SysError("mounting /dev/pts");
                 createSymlink("/dev/pts/ptmx", chrootRootDir + "/dev/ptmx");
 
@@ -2197,7 +2191,7 @@ void DerivationGoal::runChild()
             if (chroot(".") == -1)
                 throw SysError(format("cannot change root directory to '%1%'") 
% chrootRootDir);
 
-            if (umount2("real-root", MNT_DETACH) == -1)
+            if (nixUmount2("real-root", MNT_DETACH) == -1)
                 throw SysError("cannot unmount real root filesystem");
 
             if (rmdir("real-root") == -1)
diff --git a/nix/libutil/calls.cc b/nix/libutil/calls.cc
new file mode 100644
index 0000000..0beb406
--- /dev/null
+++ b/nix/libutil/calls.cc
@@ -0,0 +1,112 @@
+#include "config.h"
+
+#include "calls.hh"
+
+#include <iostream>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <sstream>
+#include <cstring>
+
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <argz.h>
+
+#if __GNU__
+#include <hurd/hurdutil.h>
+#endif
+
+namespace nix {
+
+int nixMount(const char *source, const char *target,
+  const char *filesystemtype, unsigned long mountflags,
+  const void *data)
+{
+#if HAVE_SYS_MOUNT_H
+    return mount(source, target, filesystemtype, mountflags, data);
+#elif __GNU__
+    struct settrans_context *context;
+    int err;
+
+    settrans_context_create(&context);
+
+    context->node_name = strdup(target);
+
+    if (filesystemtype == 0){
+        argz_add(&context->argz, &context->argz_len, "hurd/ext2fs");
+        argz_add(&context->argz, &context->argz_len, source);
+    }
+
+    if ((mountflags & MS_PRIVATE) == MS_PRIVATE){
+
+    }
+
+    if ((mountflags & MS_BIND) == MS_BIND){
+        argz_add(&context->argz, &context->argz_len, "hurd/firmlink");
+        argz_add(&context->argz, &context->argz_len, source);
+    }
+
+    context->active = 1;
+
+    err = settrans(context);
+    if (err){
+        settrans_context_cleanup(context);
+        return -1;
+    }
+
+    settrans_context_cleanup(context);
+
+    return 0;
+#else
+    throw SysError("No Mount available on the system");
+#endif
+}
+
+int nixUmount2(const char *target, int flags)
+{
+#if HAVE_SYS_MOUNT_H
+    return umount2(target, flags);
+#elif __GNU__
+    struct settrans_context *context;
+    int err;
+
+    settrans_context_create(&context);
+
+    context->node_name = strdup(target);
+    context->kill_active = 1;
+
+    if ((flags & MNT_FORCE) == MNT_FORCE){
+        context->goaway_flags |= FSYS_GOAWAY_FORCE;
+    }
+
+    if ((flags & MNT_DETACH) == MNT_DETACH){
+
+    }
+
+    err = settrans(context);
+    if (err){
+        settrans_context_cleanup(context);
+        return -1;
+    }
+
+    settrans_context_cleanup(context);
+
+    return 0;
+#else
+    throw SysError("No Umount available on the system");
+#endif
+}
+
+int pivot_root(const char *new_root, const char *put_old)
+{
+#if defined(SYS_pivot_root)
+    return syscall(SYS_pivot_root, new_root,put_old);
+#else
+    return ENOSYS;
+#endif
+}
+
+}
diff --git a/nix/libutil/calls.hh b/nix/libutil/calls.hh
new file mode 100644
index 0000000..bec4440
--- /dev/null
+++ b/nix/libutil/calls.hh
@@ -0,0 +1,103 @@
+#pragma once
+
+#include "types.hh"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <signal.h>
+#include <functional>
+
+#include <cstdio>
+
+#if HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#elif __GNU__
+#include <hurd/hurdutil.h>
+/* These are the fs-independent mount-flags: up to 16 flags are
+   supported  */
+enum
+{
+  MS_RDONLY = 1,               /* Mount read-only.  */
+#define MS_RDONLY      MS_RDONLY
+  MS_NOSUID = 2,               /* Ignore suid and sgid bits.  */
+#define MS_NOSUID      MS_NOSUID
+  MS_NODEV = 4,                        /* Disallow access to device special 
files.  */
+#define MS_NODEV       MS_NODEV
+  MS_NOEXEC = 8,               /* Disallow program execution.  */
+#define MS_NOEXEC      MS_NOEXEC
+  MS_SYNCHRONOUS = 16,         /* Writes are synced at once.  */
+#define MS_SYNCHRONOUS MS_SYNCHRONOUS
+  MS_REMOUNT = 32,             /* Alter flags of a mounted FS.  */
+#define MS_REMOUNT     MS_REMOUNT
+  MS_MANDLOCK = 64,            /* Allow mandatory locks on an FS.  */
+#define MS_MANDLOCK    MS_MANDLOCK
+  MS_DIRSYNC = 128,            /* Directory modifications are synchronous.  */
+#define MS_DIRSYNC     MS_DIRSYNC
+  MS_NOATIME = 1024,           /* Do not update access times.  */
+#define MS_NOATIME     MS_NOATIME
+  MS_NODIRATIME = 2048,                /* Do not update directory access 
times.  */
+#define MS_NODIRATIME  MS_NODIRATIME
+  MS_BIND = 4096,              /* Bind directory at different place.  */
+#define MS_BIND                MS_BIND
+  MS_MOVE = 8192,
+#define MS_MOVE                MS_MOVE
+  MS_REC = 16384,
+#define MS_REC         MS_REC
+  MS_SILENT = 32768,
+#define MS_SILENT      MS_SILENT
+  MS_POSIXACL = 1 << 16,       /* VFS does not apply the umask.  */
+#define MS_POSIXACL    MS_POSIXACL
+  MS_UNBINDABLE = 1 << 17,     /* Change to unbindable.  */
+#define MS_UNBINDABLE  MS_UNBINDABLE
+  MS_PRIVATE = 1 << 18,                /* Change to private.  */
+#define MS_PRIVATE     MS_PRIVATE
+  MS_SLAVE = 1 << 19,          /* Change to slave.  */
+#define MS_SLAVE       MS_SLAVE
+  MS_SHARED = 1 << 20,         /* Change to shared.  */
+#define MS_SHARED      MS_SHARED
+  MS_RELATIME = 1 << 21,       /* Update atime relative to mtime/ctime.  */
+#define MS_RELATIME    MS_RELATIME
+  MS_KERNMOUNT = 1 << 22,      /* This is a kern_mount call.  */
+#define MS_KERNMOUNT   MS_KERNMOUNT
+  MS_I_VERSION =  1 << 23,     /* Update inode I_version field.  */
+#define MS_I_VERSION   MS_I_VERSION
+  MS_STRICTATIME = 1 << 24,    /* Always perform atime updates.  */
+#define MS_STRICTATIME MS_STRICTATIME
+  MS_ACTIVE = 1 << 30,
+#define MS_ACTIVE      MS_ACTIVE
+  MS_NOUSER = 1 << 31
+#define MS_NOUSER      MS_NOUSER
+};
+
+/* Possible value for FLAGS parameter of `umount2'.  */
+enum
+  {
+    MNT_FORCE = 1,             /* Force unmounting.  */
+#define MNT_FORCE MNT_FORCE
+    MNT_DETACH = 2,            /* Just detach from the tree.  */
+#define MNT_DETACH MNT_DETACH
+    MNT_EXPIRE = 4,            /* Mark for expiry.  */
+#define MNT_EXPIRE MNT_EXPIRE
+    UMOUNT_NOFOLLOW = 8                /* Don't follow symlink on umount.  */
+#define UMOUNT_NOFOLLOW UMOUNT_NOFOLLOW
+  };
+
+#define HAVE_HURD_MOUNT_H 1
+#endif
+
+#if HAVE_SYS_MOUNT_H || HAVE_HURD_MOUNT_H
+#define HANE_NIX_MOUNT
+#endif
+
+namespace nix {
+
+int nixMount(const char *source, const char *target,
+  const char *filesystemtype, unsigned long mountflags,
+  const void *data);
+
+int nixUmount2(const char *target, int flags);
+
+int pivot_root(const char *new_root, const char *put_old);
+}
diff --git a/nix/local.mk b/nix/local.mk
index a64bdd2..84c7cf9 100644
--- a/nix/local.mk
+++ b/nix/local.mk
@@ -53,6 +53,7 @@ libformat_a_CPPFLAGS =                                \
 libutil_a_SOURCES =                            \
   %D%/libutil/archive.cc                       \
   %D%/libutil/affinity.cc                      \
+  %D%/libutil/calls.cc                         \
   %D%/libutil/serialise.cc                     \
   %D%/libutil/util.cc                          \
   %D%/libutil/hash.cc                          \
@@ -66,6 +67,7 @@ libutil_headers =                             \
   %D%/libutil/archive.hh                       \
   %D%/libutil/types.hh                         \
   %D%/libutil/gcrypt-hash.hh                   \
+  %D%/libutil/calls.hh                         \
   %D%/libutil/md5.h                            \
   %D%/libutil/sha1.h                           \
   %D%/libutil/sha256.h                         \
@@ -129,7 +131,7 @@ guix_daemon_CPPFLAGS =                              \
 
 guix_daemon_LDADD =                            \
   libstore.a libutil.a libformat.a -lz         \
-  $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS)
+  $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(HURD_LDFLAGS)
 
 guix_daemon_headers =                          \
   %D%/nix-daemon/shared.hh



reply via email to

[Prev in Thread] Current Thread [Next in Thread]