summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-05-04 22:24:47 +0200
committerLudovic Courtès <ludo@gnu.org>2014-05-04 22:24:47 +0200
commit1d4628329d37c5e5857c70f3720b941e4bbcfcd2 (patch)
treedc9d7be259d18567ee50c6ff45191486737b0b54
parent2d49f8452215ab6e898589cd757d02fc1f1fc930 (diff)
downloadguix-1d4628329d37c5e5857c70f3720b941e4bbcfcd2.tar.gz
linux-initrd: Improve root file system switching.
* guix/build/linux-initrd.scm (move-essential-file-systems,
  switch-root): New procedures.
  (MS_MOVE): New variable.
  (boot-system): Remove 'mount-essential-file-systems' call for ROOT.
  Use 'switch-root' instead of chdir + chroot.
-rw-r--r--guix/build/linux-initrd.scm24
1 files changed, 20 insertions, 4 deletions
diff --git a/guix/build/linux-initrd.scm b/guix/build/linux-initrd.scm
index b2cbcae7d8..b133550bca 100644
--- a/guix/build/linux-initrd.scm
+++ b/guix/build/linux-initrd.scm
@@ -62,6 +62,15 @@
     (mkdir (scope "sys")))
   (mount "none" (scope "sys") "sysfs"))
 
+(define (move-essential-file-systems root)
+  "Move currently mounted essential file systems to ROOT."
+  (for-each (lambda (dir)
+              (let ((target (string-append root dir)))
+                (unless (file-exists? target)
+                  (mkdir target))
+                (mount dir target "" MS_MOVE)))
+            '("/proc" "/sys")))
+
 (define (linux-command-line)
   "Return the Linux kernel command line as a list of strings."
   (string-tokenize
@@ -172,6 +181,7 @@ networking values.)  Return #t if INTERFACE is up, #f otherwise."
 ;; Linux mount flags, from libc's <sys/mount.h>.
 (define MS_RDONLY 1)
 (define MS_BIND 4096)
+(define MS_MOVE 8192)
 
 (define (bind-mount source target)
   "Bind-mount SOURCE at TARGET."
@@ -271,6 +281,15 @@ run a file system check."
                   (string->pointer options)
                   %null-pointer))))))
 
+(define (switch-root root)
+  "Switch to ROOT as the root file system, in a way similar to what
+util-linux' switch_root(8) does."
+  (move-essential-file-systems root)
+  (chdir root)
+  ;; TODO: Delete files from the old root.
+  (mount root "/" "" MS_MOVE)
+  (chroot "."))
+
 (define* (boot-system #:key
                       (linux-modules '())
                       qemu-guest-networking?
@@ -351,8 +370,6 @@ to it are lost."
                                 #:volatile-root? volatile-root?)
         (mount "none" "/root" "tmpfs"))
 
-    (mount-essential-file-systems #:root "/root")
-
     (unless (file-exists? "/root/dev")
       (mkdir "/root/dev")
       (make-essential-device-nodes #:root "/root"))
@@ -377,8 +394,7 @@ to it are lost."
     (if to-load
         (begin
           (format #t "loading '~a'...\n" to-load)
-          (chdir "/root")
-          (chroot "/root")
+          (switch-root "/root")
 
           ;; Obviously this has to be done each time we boot.  Do it from here
           ;; so that statfs(2) returns DEVPTS_SUPER_MAGIC like libc's getpt(3)