diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2022-07-01 09:38:09 +0200 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2022-07-01 12:10:28 +0200 |
| commit | 0483c71cc5aeb3b69f6deb154fe12c0b2e6dc17f (patch) | |
| tree | 6e6d54505a3e9828a328d7057ca9904054cd2311 /gnu/services | |
| parent | 4636640de8ecd9e3702bca75c9ce0649ac5d4979 (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.scm | 51 |
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 |
