summaryrefslogtreecommitdiff
path: root/gnu/services
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2022-07-01 09:38:09 +0200
committerLudovic Courtès <ludo@gnu.org>2022-07-01 12:10:28 +0200
commit0483c71cc5aeb3b69f6deb154fe12c0b2e6dc17f (patch)
tree6e6d54505a3e9828a328d7057ca9904054cd2311 /gnu/services
parent4636640de8ecd9e3702bca75c9ce0649ac5d4979 (diff)
services: root-file-system: Cleanly unmount upon shutdown.
Fixes <https://issues.guix.gnu.org/56209>. Reported by angry rectangle <angryrectangle@cock.li>. * gnu/packages/admin.scm (shepherd-0.9)[modules, snippet]: New fields. * gnu/services/base.scm (%root-file-system-shepherd-service): In 'stop' method, remove 'call-with-blocked-asyncs'. When 'mount' throws to 'system-error, call (@ (fibers) sleep) and try again. * gnu/tests/base.scm (run-root-unmount-test): New procedure. (%test-root-unmount): New variable.
Diffstat (limited to 'gnu/services')
-rw-r--r--gnu/services/base.scm51
1 files changed, 30 insertions, 21 deletions
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 75a0cf69d76..27eae75c46c 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -300,27 +300,36 @@ system objects.")))
300 ;; Return #f if successfully stopped. 300 ;; Return #f if successfully stopped.
301 (sync) 301 (sync)
302 302
303 (call-with-blocked-asyncs 303 (let ((null (%make-void-port "w")))
304 (lambda () 304 ;; Close 'shepherd.log'.
305 (let ((null (%make-void-port "w"))) 305 (display "closing log\n")
306 ;; Close 'shepherd.log'. 306 ((@ (shepherd comm) stop-logging))
307 (display "closing log\n") 307
308 ((@ (shepherd comm) stop-logging)) 308 ;; Redirect the default output ports..
309 309 (set-current-output-port null)
310 ;; Redirect the default output ports.. 310 (set-current-error-port null)
311 (set-current-output-port null) 311
312 (set-current-error-port null) 312 ;; Close /dev/console.
313 313 (for-each close-fdes '(0 1 2))
314 ;; Close /dev/console. 314
315 (for-each close-fdes '(0 1 2)) 315 ;; At this point, there should be no open files left so the
316 316 ;; root file system can be re-mounted read-only.
317 ;; At this point, there are no open files left, so the 317 (let loop ((n 10))
318 ;; root file system can be re-mounted read-only. 318 (unless (catch 'system-error
319 (mount #f "/" #f 319 (lambda ()
320 (logior MS_REMOUNT MS_RDONLY) 320 (mount #f "/" #f
321 #:update-mtab? #f) 321 (logior MS_REMOUNT MS_RDONLY)
322 322 #:update-mtab? #f)
323 #f))))) 323 #t)
324 (const #f))
325 (unless (zero? n)
326 ;; Yield to the other fibers. That gives logging fibers
327 ;; an opportunity to close log files so the 'mount' call
328 ;; doesn't fail with EBUSY.
329 ((@ (fibers) sleep) 1)
330 (loop (- n 1)))))
331
332 #f)))
324 (respawn? #f))) 333 (respawn? #f)))
325 334
326(define root-file-system-service-type 335(define root-file-system-service-type