summary refs log tree commit diff
path: root/gnu/services
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2017-01-31 22:53:29 +0100
committerLudovic Courtès <ludo@gnu.org>2017-01-31 23:21:59 +0100
commita43aca973eb867bee632d521c49fd620904e0d1a (patch)
tree00804b22b8239fbc0d9359c93fd70def8b3f530d /gnu/services
parent2fe4ceee18f8687de8520d28dbfefc7bc3a7e084 (diff)
downloadguix-a43aca973eb867bee632d521c49fd620904e0d1a.tar.gz
system: Introduce 'file-systems' Shepherd service.
* gnu/services/base.scm (file-system-shepherd-services): New procedure.
(file-system-service-type): Use it as the SHEPHERD-ROOT-SERVICE-TYPE
extension.
(user-processes-service-type): Change to take a single 'grace-delay'
parameter.
(user-processes-service): Remove 'file-systems' parameter.  Pass
GRACE-DELAY as the only value for the service.
* gnu/system.scm (essential-services): Adjust accordingly.
Diffstat (limited to 'gnu/services')
-rw-r--r--gnu/services/base.scm169
1 files changed, 89 insertions, 80 deletions
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index ef4d4b723e..ecabf78429 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
 ;;; Copyright © 2015, 2016 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
@@ -313,13 +313,26 @@ FILE-SYSTEM."
                         #:select (mount-file-system))
                        ,@%default-modules)))))))
 
+(define (file-system-shepherd-services file-systems)
+  "Return the list of Shepherd services for FILE-SYSTEMS."
+  (let* ((file-systems (filter file-system-mount? file-systems)))
+    (define sink
+      (shepherd-service
+       (provision '(file-systems))
+       (requirement (cons* 'root-file-system 'user-file-systems
+                           (map file-system->shepherd-service-name
+                                file-systems)))
+       (documentation "Target for all the initially-mounted file systems")
+       (start #~(const #t))
+       (stop #~(const #f))))
+
+    (cons sink (map file-system-shepherd-service file-systems))))
+
 (define file-system-service-type
   (service-type (name 'file-systems)
                 (extensions
                  (list (service-extension shepherd-root-service-type
-                                          (lambda (file-systems)
-                                            (filter-map file-system-shepherd-service
-                                                        file-systems)))
+                                          file-system-shepherd-services)
                        (service-extension fstab-service-type
                                           identity)))
                 (compose concatenate)
@@ -366,93 +379,89 @@ in KNOWN-MOUNT-POINTS when it is stopped."
 (define user-processes-service-type
   (shepherd-service-type
    'user-processes
-   (match-lambda
-     ((requirements grace-delay)
-      (shepherd-service
-       (documentation "When stopped, terminate all user processes.")
-       (provision '(user-processes))
-       (requirement (cons* 'root-file-system 'user-file-systems
-                           (map file-system->shepherd-service-name
-                                requirements)))
-       (start #~(const #t))
-       (stop #~(lambda _
-                 (define (kill-except omit signal)
-                   ;; Kill all the processes with SIGNAL except those listed
-                   ;; in OMIT and the current process.
-                   (let ((omit (cons (getpid) omit)))
-                     (for-each (lambda (pid)
-                                 (unless (memv pid omit)
-                                   (false-if-exception
-                                    (kill pid signal))))
-                               (processes))))
-
-                 (define omitted-pids
-                   ;; List of PIDs that must not be killed.
-                   (if (file-exists? #$%do-not-kill-file)
-                       (map string->number
-                            (call-with-input-file #$%do-not-kill-file
-                              (compose string-tokenize
-                                       (@ (ice-9 rdelim) read-string))))
-                       '()))
-
-                 (define (now)
-                   (car (gettimeofday)))
-
-                 (define (sleep* n)
-                   ;; Really sleep N seconds.
-                   ;; Work around <http://bugs.gnu.org/19581>.
-                   (define start (now))
-                   (let loop ((elapsed 0))
-                     (when (> n elapsed)
-                       (sleep (- n elapsed))
-                       (loop (- (now) start)))))
-
-                 (define lset= (@ (srfi srfi-1) lset=))
-
-                 (display "sending all processes the TERM signal\n")
-
-                 (if (null? omitted-pids)
-                     (begin
-                       ;; Easy: terminate all of them.
-                       (kill -1 SIGTERM)
-                       (sleep* #$grace-delay)
-                       (kill -1 SIGKILL))
-                     (begin
-                       ;; Kill them all except OMITTED-PIDS.  XXX: We would
-                       ;; like to (kill -1 SIGSTOP) to get a fixed list of
-                       ;; processes, like 'killall5' does, but that seems
-                       ;; unreliable.
-                       (kill-except omitted-pids SIGTERM)
-                       (sleep* #$grace-delay)
-                       (kill-except omitted-pids SIGKILL)
-                       (delete-file #$%do-not-kill-file)))
-
-                 (let wait ()
-                   (let ((pids (processes)))
-                     (unless (lset= = pids (cons 1 omitted-pids))
-                       (format #t "waiting for process termination\
+   (lambda (grace-delay)
+     (shepherd-service
+      (documentation "When stopped, terminate all user processes.")
+      (provision '(user-processes))
+      (requirement '(file-systems))
+      (start #~(const #t))
+      (stop #~(lambda _
+                (define (kill-except omit signal)
+                  ;; Kill all the processes with SIGNAL except those listed
+                  ;; in OMIT and the current process.
+                  (let ((omit (cons (getpid) omit)))
+                    (for-each (lambda (pid)
+                                (unless (memv pid omit)
+                                  (false-if-exception
+                                   (kill pid signal))))
+                              (processes))))
+
+                (define omitted-pids
+                  ;; List of PIDs that must not be killed.
+                  (if (file-exists? #$%do-not-kill-file)
+                      (map string->number
+                           (call-with-input-file #$%do-not-kill-file
+                             (compose string-tokenize
+                                      (@ (ice-9 rdelim) read-string))))
+                      '()))
+
+                (define (now)
+                  (car (gettimeofday)))
+
+                (define (sleep* n)
+                  ;; Really sleep N seconds.
+                  ;; Work around <http://bugs.gnu.org/19581>.
+                  (define start (now))
+                  (let loop ((elapsed 0))
+                    (when (> n elapsed)
+                      (sleep (- n elapsed))
+                      (loop (- (now) start)))))
+
+                (define lset= (@ (srfi srfi-1) lset=))
+
+                (display "sending all processes the TERM signal\n")
+
+                (if (null? omitted-pids)
+                    (begin
+                      ;; Easy: terminate all of them.
+                      (kill -1 SIGTERM)
+                      (sleep* #$grace-delay)
+                      (kill -1 SIGKILL))
+                    (begin
+                      ;; Kill them all except OMITTED-PIDS.  XXX: We would
+                      ;; like to (kill -1 SIGSTOP) to get a fixed list of
+                      ;; processes, like 'killall5' does, but that seems
+                      ;; unreliable.
+                      (kill-except omitted-pids SIGTERM)
+                      (sleep* #$grace-delay)
+                      (kill-except omitted-pids SIGKILL)
+                      (delete-file #$%do-not-kill-file)))
+
+                (let wait ()
+                  (let ((pids (processes)))
+                    (unless (lset= = pids (cons 1 omitted-pids))
+                      (format #t "waiting for process termination\
  (processes left: ~s)~%"
-                               pids)
-                       (sleep* 2)
-                       (wait))))
+                              pids)
+                      (sleep* 2)
+                      (wait))))
 
-                 (display "all processes have been terminated\n")
-                 #f))
-       (respawn? #f))))))
+                (display "all processes have been terminated\n")
+                #f))
+      (respawn? #f)))))
 
-(define* (user-processes-service file-systems #:key (grace-delay 4))
+(define* (user-processes-service #:key (grace-delay 4))
   "Return the service that is responsible for terminating all the processes so
 that the root file system can be re-mounted read-only, just before
 rebooting/halting.  Processes still running GRACE-DELAY seconds after SIGTERM
 has been sent are terminated with SIGKILL.
 
-The returned service will depend on 'root-file-system' and on all the shepherd
-services corresponding to FILE-SYSTEMS.
+The returned service will depend on 'file-systems', meaning that it is
+considered started after all the auto-mount file systems have been mounted.
 
 All the services that spawn processes must depend on this one so that they are
 stopped before 'kill' is called."
-  (service user-processes-service-type
-           (list (filter file-system-mount? file-systems) grace-delay)))
+  (service user-processes-service-type grace-delay))
 
 
 ;;;