summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gnu/services/base.scm28
-rw-r--r--gnu/system.scm6
-rw-r--r--gnu/system/install.scm4
3 files changed, 36 insertions, 2 deletions
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index abf8ae99ac..0c45d54d17 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -38,6 +38,7 @@
   #:use-module (ice-9 format)
   #:export (root-file-system-service
             file-system-service
+            user-unmount-service
             device-mapping-service
             swap-service
             user-processes-service
@@ -145,6 +146,33 @@ names such as device-mapping services."
                 (umount #$target)
                 #f))))))
 
+(define (user-unmount-service known-mount-points)
+  "Return a service whose sole purpose is to unmount file systems not listed
+in KNOWN-MOUNT-POINTS when it is stopped."
+  (with-monad %store-monad
+    (return
+     (service
+      (documentation "Unmount manually-mounted file systems.")
+      (provision '(user-unmount))
+      (start #~(const #t))
+      (stop #~(lambda args
+                (define (known? mount-point)
+                  (member mount-point
+                          (cons* "/proc" "/sys"
+                                 '#$known-mount-points)))
+
+                (for-each (lambda (mount-point)
+                            (format #t "unmounting '~a'...~%" mount-point)
+                            (catch 'system-error
+                              (lambda ()
+                                (umount mount-point))
+                              (lambda args
+                                (let ((errno (system-error-errno args)))
+                                  (format #t "failed to unmount '~a': ~a~%"
+                                          mount-point (strerror errno))))))
+                          (filter (negate known?) (mount-points)))
+                #f))))))
+
 (define %do-not-kill-file
   ;; Name of the file listing PIDs of processes that must survive when halting
   ;; the system.  Typical example is user-space file systems.
diff --git a/gnu/system.scm b/gnu/system.scm
index 4140272a3c..57d71e5158 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -269,16 +269,20 @@ from the initrd."
   "Return the list of essential services for OS.  These are special services
 that implement part of what's declared in OS are responsible for low-level
 bookkeeping."
+  (define known-fs
+    (map file-system-mount-point (operating-system-file-systems os)))
+
   (mlet* %store-monad ((mappings  (device-mapping-services os))
                        (root-fs   (root-file-system-service))
                        (other-fs  (other-file-system-services os))
+                       (unmount   (user-unmount-service known-fs))
                        (swaps     (swap-services os))
                        (procs     (user-processes-service
                                    (map (compose first service-provision)
                                         other-fs)))
                        (host-name (host-name-service
                                    (operating-system-host-name os))))
-    (return (cons* host-name procs root-fs
+    (return (cons* host-name procs root-fs unmount
                    (append other-fs mappings swaps)))))
 
 (define (operating-system-services os)
diff --git a/gnu/system/install.scm b/gnu/system/install.scm
index 12470d16c9..6b3aa6cbf2 100644
--- a/gnu/system/install.scm
+++ b/gnu/system/install.scm
@@ -112,7 +112,9 @@ the given target.")
              (stop #~(lambda (target)
                        ;; Delete the temporary directory, but leave everything
                        ;; mounted as there may still be processes using it
-                       ;; since 'user-processes' doesn't depend on us.
+                       ;; since 'user-processes' doesn't depend on us.  The
+                       ;; 'user-unmount' service will unmount TARGET
+                       ;; eventually.
                        (delete-file-recursively
                         (string-append target #$%backing-directory))))))))