aboutsummaryrefslogtreecommitdiff
path: root/gnu/services/base.scm
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/base.scm
parent2fe4ceee18f8687de8520d28dbfefc7bc3a7e084 (diff)
downloadgnu-guix-a43aca973eb867bee632d521c49fd620904e0d1a.tar
gnu-guix-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/base.scm')
-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))
;;;