1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013-2016, 2018-2022 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
4 ;;; Copyright © 2018 Carlo Zancanaro <carlo@zancanaro.id.au>
5 ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
6 ;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
8 ;;; This file is part of GNU Guix.
10 ;;; GNU Guix is free software; you can redistribute it and/or modify it
11 ;;; under the terms of the GNU General Public License as published by
12 ;;; the Free Software Foundation; either version 3 of the License, or (at
13 ;;; your option) any later version.
15 ;;; GNU Guix is distributed in the hope that it will be useful, but
16 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;;; GNU General Public License for more details.
20 ;;; You should have received a copy of the GNU General Public License
21 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
23 (define-module (gnu services shepherd)
24 #:use-module (guix ui)
25 #:use-module (guix sets)
26 #:use-module (guix gexp)
27 #:use-module (guix store)
28 #:use-module (guix records)
29 #:use-module (guix packages)
30 #:use-module (guix derivations) ;imported-modules, etc.
31 #:use-module (guix utils)
32 #:use-module (gnu services)
33 #:use-module (gnu services herd)
34 #:use-module (gnu packages admin)
35 #:use-module (ice-9 match)
36 #:use-module (ice-9 vlist)
37 #:use-module (srfi srfi-1)
38 #:use-module (srfi srfi-26)
39 #:use-module (srfi srfi-34)
40 #:use-module (srfi srfi-35)
41 #:export (shepherd-configuration
42 shepherd-configuration?
43 shepherd-configuration-shepherd
44 shepherd-configuration-services
46 shepherd-root-service-type
47 %shepherd-root-service
52 shepherd-service-documentation
53 shepherd-service-provision
54 shepherd-service-canonical-name
55 shepherd-service-requirement
56 shepherd-service-one-shot?
57 shepherd-service-respawn?
58 shepherd-service-start
60 shepherd-service-auto-start?
61 shepherd-service-modules
66 shepherd-action-documentation
67 shepherd-action-procedure
73 shepherd-service-lookup-procedure
74 shepherd-service-back-edges
75 shepherd-service-upgrade
77 user-processes-service-type
83 ;;; Instantiating system services as a shepherd configuration file.
88 (define-record-type* <shepherd-configuration>
89 shepherd-configuration make-shepherd-configuration
90 shepherd-configuration?
91 (shepherd shepherd-configuration-shepherd
92 (default shepherd-0.9)) ; file-like
93 (services shepherd-configuration-services
94 (default '()))) ; list of <shepherd-service>
96 (define (shepherd-boot-gexp config)
97 "Return a gexp starting the shepherd service."
98 (let ((shepherd (shepherd-configuration-shepherd config))
99 (services (shepherd-configuration-services config)))
101 ;; Keep track of the booted system.
102 (false-if-exception (delete-file "/run/booted-system"))
104 ;; Make /run/booted-system, an indirect GC root, point to the store item
105 ;; /run/current-system points to. Use 'canonicalize-path' rather than
106 ;; 'readlink' to make sure we get the store item.
107 (symlink (canonicalize-path "/run/current-system")
108 "/run/booted-system")
110 ;; Close any remaining open file descriptors to be on the safe
111 ;; side. This must be the very last thing we do, because
112 ;; Guile has internal FDs such as 'sleep_pipe' that need to be
116 (false-if-exception (close-fdes fd))
120 (execl #$(file-append shepherd "/bin/shepherd")
121 "shepherd" "--config"
122 #$(shepherd-configuration-file services shepherd)))))
124 (define shepherd-packages
125 (compose list shepherd-configuration-shepherd))
127 (define shepherd-root-service-type
129 (name 'shepherd-root)
130 ;; Extending the root shepherd service (aka. PID 1) happens by
131 ;; concatenating the list of services provided by the extensions.
132 (compose concatenate)
133 (extend (lambda (config extra-services)
134 (shepherd-configuration
136 (services (append (shepherd-configuration-services config)
138 (extensions (list (service-extension boot-service-type
140 (service-extension profile-service-type
142 (default-value (shepherd-configuration))
144 "Run the GNU Shepherd as PID 1---i.e., the operating system's first
145 process. The Shepherd takes care of managing services such as daemons by
146 ensuring they are started and stopped in the right order.")))
148 (define %shepherd-root-service
149 ;; The root shepherd service, aka. PID 1. Its parameter is a
150 ;; <shepherd-configuration>.
151 (service shepherd-root-service-type))
153 (define-syntax shepherd-service-type
154 (syntax-rules (description)
155 "Return a <service-type> denoting a simple shepherd service--i.e., the type
156 for a service that extends SHEPHERD-ROOT-SERVICE-TYPE and nothing else. When
157 DEFAULT is given, use it as the service's default value."
158 ((_ service-name proc default (description text))
162 (list (service-extension shepherd-root-service-type
163 (compose list proc))))
164 (default-value default)
166 ((_ service-name proc (description text))
170 (list (service-extension shepherd-root-service-type
171 (compose list proc))))
172 (description text)))))
174 (define %default-imported-modules
175 ;; Default set of modules imported for a service's consumption.
177 (guix build syscalls)))
179 (define %default-modules
180 ;; Default set of modules visible in a service's file.
183 ((guix build utils) #:hide (delete))
184 (guix build syscalls)))
186 (define-record-type* <shepherd-service>
187 shepherd-service make-shepherd-service
189 (documentation shepherd-service-documentation ;string
190 (default "[No documentation.]"))
191 (provision shepherd-service-provision) ;list of symbols
192 (requirement shepherd-service-requirement ;list of symbols
194 (one-shot? shepherd-service-one-shot? ;Boolean
196 (respawn? shepherd-service-respawn? ;Boolean
198 (start shepherd-service-start) ;g-expression (procedure)
199 (stop shepherd-service-stop ;g-expression (procedure)
200 (default #~(const #f)))
201 (actions shepherd-service-actions ;list of <shepherd-action>
203 (auto-start? shepherd-service-auto-start? ;Boolean
205 (modules shepherd-service-modules ;list of module names
206 (default %default-modules)))
208 (define-record-type* <shepherd-action>
209 shepherd-action make-shepherd-action
211 (name shepherd-action-name) ;symbol
212 (procedure shepherd-action-procedure) ;gexp
213 (documentation shepherd-action-documentation)) ;string
215 (define (shepherd-service-canonical-name service)
216 "Return the 'canonical name' of SERVICE."
217 (first (shepherd-service-provision service)))
219 (define (assert-valid-graph services)
220 "Raise an error if SERVICES does not define a valid shepherd service graph,
221 for instance if a service requires a nonexistent service, or if more than one
222 service uses a given name.
224 These are constraints that shepherd's 'register-service' verifies but we'd
225 better verify them here statically than wait until PID 1 halts with an
228 ;; The set of provisions (symbols). Bail out if a symbol is given more
230 (fold (lambda (service set)
231 (define (assert-unique symbol)
232 (when (set-contains? set symbol)
236 (format #f (G_ "service '~a' provided more than once")
239 (for-each assert-unique (shepherd-service-provision service))
240 (fold set-insert set (shepherd-service-provision service)))
244 (define (assert-satisfied-requirements service)
245 ;; Bail out if the requirements of SERVICE aren't satisfied.
246 (for-each (lambda (requirement)
247 (unless (set-contains? provisions requirement)
251 (format #f (G_ "service '~a' requires '~a', \
252 which is not provided by any service")
253 (match (shepherd-service-provision service)
257 (shepherd-service-requirement service)))
259 (for-each assert-satisfied-requirements services))
261 (define %store-characters
262 ;; Valid store characters; see 'checkStoreName' in the daemon.
264 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-._?="))
266 (define (shepherd-service-file-name service)
267 "Return the file name where the initialization code for SERVICE is to be
269 (let ((provisions (string-join (map symbol->string
270 (shepherd-service-provision service)))))
271 (string-append "shepherd-"
272 (string-map (lambda (chr)
273 (if (char-set-contains? %store-characters chr)
279 (define (shepherd-service-file service)
280 "Return a file defining SERVICE."
281 (scheme-file (shepherd-service-file-name service)
282 (with-imported-modules %default-imported-modules
284 (use-modules #$@(shepherd-service-modules service))
287 #:docstring '#$(shepherd-service-documentation service)
288 #:provides '#$(shepherd-service-provision service)
289 #:requires '#$(shepherd-service-requirement service)
291 ;; The 'one-shot?' slot is new in Shepherd 0.6.0.
292 ;; Older versions ignore it.
293 #:one-shot? '#$(shepherd-service-one-shot? service)
295 #:respawn? '#$(shepherd-service-respawn? service)
296 #:start #$(shepherd-service-start service)
297 #:stop #$(shepherd-service-stop service)
300 #$@(map (match-lambda
301 (($ <shepherd-action> name proc doc)
302 #~(#$name #$doc #$proc)))
303 (shepherd-service-actions service))))))))
305 (define (scm->go file shepherd)
306 "Compile FILE, which contains code to be loaded by shepherd's config file,
307 and return the resulting '.go' file. SHEPHERD is used as shepherd package."
310 (match (lookup-package-input shepherd "guile-fibers")
312 (fibers (list fibers)))))
314 (let-system (system target)
315 (with-extensions shepherd&co
316 (computed-file (string-append (basename (scheme-file-name file) ".scm")
319 (use-modules (system base compile)
320 (system base target))
322 ;; Do the same as the Shepherd's 'load-in-user-module'.
323 (let ((env (make-fresh-user-module)))
324 (module-use! env (resolve-interface '(oop goops)))
325 (module-use! env (resolve-interface '(shepherd service)))
326 (with-target #$(or target #~%host-type)
328 (compile-file #$file #:output-file #$output
331 ;; It's faster to build locally than to download.
332 #:options '(#:local-build? #t
333 #:substitutable? #f)))))
335 (define (shepherd-configuration-file services shepherd)
336 "Return the shepherd configuration file for SERVICES. SHEPHERD is used
337 as shepherd package."
338 (assert-valid-graph services)
340 (let ((files (map shepherd-service-file services))
341 (scm->go (cute scm->go <> shepherd)))
344 (use-modules (srfi srfi-34)
345 (system repl error-handling))
347 (define (call-with-file file flags proc)
351 (set! port (open file flags)))
358 ;; There's code run from shepherd that uses 'call-with-input-file' &
359 ;; co.--e.g., the 'urandom-seed' service. Starting from Shepherd
360 ;; 0.9.2, users need to make sure not to leak non-close-on-exec file
361 ;; descriptors to child processes. To address that, replace the
362 ;; standard bindings with O_CLOEXEC variants.
363 (set! call-with-input-file
365 (call-with-file file (logior O_RDONLY O_CLOEXEC)
367 (set! call-with-output-file
369 (call-with-file file (logior O_WRONLY O_CREAT O_CLOEXEC)
372 ;; Specify the default environment visible to all the services.
373 ;; Without this statement, all the environment variables of PID 1
374 ;; are inherited by child services.
375 (default-environment-variables
376 '("PATH=/run/current-system/profile/bin"))
378 ;; Booting off a DVD, especially on a slow machine, can make
379 ;; everything slow. Thus, increase the timeout compared to the
380 ;; default 5s in the Shepherd 0.7.0. See
381 ;; <https://bugs.gnu.org/40572>.
382 (default-pid-file-timeout 30)
384 ;; Arrange to spawn a REPL if something goes wrong. This is better
385 ;; than a kernel panic.
386 (call-with-error-handling
388 (apply register-services
389 (parameterize ((current-warning-port
390 (%make-void-port "w")))
391 (map load-compiled '#$(map scm->go files))))))
393 (format #t "starting services...~%")
394 (let ((services-to-start
395 '#$(append-map shepherd-service-provision
396 (filter shepherd-service-auto-start?
398 (if (defined? 'start-in-the-background)
399 (start-in-the-background services-to-start)
400 (for-each (lambda (service) ;pre-0.9.0 compatibility
401 (guard (c ((service-error? c)
402 (format (current-error-port)
403 "failed to start service '~a'~%"
408 ;; Hang up stdin. At this point, we assume that 'start' methods
409 ;; that required user interaction on the console (e.g.,
410 ;; 'cryptsetup open' invocations, post-fsck emergency REPL) have
411 ;; completed. User interaction becomes impossible after this
412 ;; call; this avoids situations where services wrongfully lead
413 ;; PID 1 to read from stdin (the console), which users may not
414 ;; have access to (see <https://bugs.gnu.org/23697>).
415 (redirect-port (open "/dev/null" (logior O_RDONLY O_CLOEXEC))
416 (current-input-port)))))
418 (scheme-file "shepherd.conf" config)))
420 (define* (shepherd-service-lookup-procedure services
423 shepherd-service-provision))
424 "Return a procedure that, when passed a symbol, return the item among
425 SERVICES that provides this symbol. PROVISION must be a one-argument
426 procedure that takes a service and returns the list of symbols it provides."
427 (let ((services (fold (lambda (service result)
428 (fold (cut vhash-consq <> service <>)
430 (provision service)))
434 (match (vhash-assq name services)
435 ((_ . service) service)
438 (define* (shepherd-service-back-edges services
440 (provision shepherd-service-provision)
441 (requirement shepherd-service-requirement))
442 "Return a procedure that, when given a <shepherd-service> from SERVICES,
443 returns the list of <shepherd-service> that depend on it.
445 Use PROVISION and REQUIREMENT as one-argument procedures that return the
446 symbols provided/required by a service."
447 (define provision->service
448 (shepherd-service-lookup-procedure services provision))
451 (fold (lambda (service edges)
452 (fold (lambda (requirement edges)
453 (vhash-consq (provision->service requirement) service
456 (requirement service)))
461 (vhash-foldq* cons '() service edges)))
463 (define (shepherd-service-upgrade live target)
464 "Return two values: the subset of LIVE (a list of <live-service>) that needs
465 to be unloaded, and the subset of TARGET (a list of <shepherd-service>) that
466 need to be restarted to complete their upgrade."
467 (define (essential? service)
468 (memq (first (live-service-provision service))
471 (define lookup-target
472 (shepherd-service-lookup-procedure target
473 shepherd-service-provision))
476 (shepherd-service-lookup-procedure live
477 live-service-provision))
479 (define (running? service)
480 (and=> (lookup-live (shepherd-service-canonical-name service))
481 live-service-running))
483 (define live-service-dependents
484 (shepherd-service-back-edges live
485 #:provision live-service-provision
486 #:requirement live-service-requirement))
488 (define (obsolete? service)
489 (match (lookup-target (first (live-service-provision service)))
490 (#f (every obsolete? (live-service-dependents service)))
494 ;; Restart services that are currently running.
495 (filter running? target))
498 ;; Unload services that are no longer required. Essential services must
499 ;; be kept and transient services such as inetd child services should be
500 ;; kept as well--they'll vanish eventually.
501 (remove (lambda (live)
502 (or (essential? live)
503 (live-service-transient? live)))
504 (filter obsolete? live)))
506 (values to-unload to-restart))
513 (define %do-not-kill-file
514 ;; Name of the file listing PIDs of processes that must survive when halting
515 ;; the system. Typical example is user-space file systems.
516 "/etc/shepherd/do-not-kill")
518 (define (user-processes-shepherd-service requirements)
519 "Return the 'user-processes' Shepherd service with dependencies on
520 REQUIREMENTS (a list of service names).
522 This is a synchronization point used to make sure user processes and daemons
523 get started only after crucial initial services have been started---file
524 system mounts, etc. This is similar to the 'sysvinit' target in systemd."
526 ;; Delay after sending SIGTERM and before sending SIGKILL.
529 (list (shepherd-service
530 (documentation "When stopped, terminate all user processes.")
531 (provision '(user-processes))
532 (requirement requirements)
535 (define (kill-except omit signal)
536 ;; Kill all the processes with SIGNAL except those listed
537 ;; in OMIT and the current process.
538 (let ((omit (cons (getpid) omit)))
539 (for-each (lambda (pid)
540 (unless (memv pid omit)
546 ;; List of PIDs that must not be killed.
547 (if (file-exists? #$%do-not-kill-file)
549 (call-with-input-file #$%do-not-kill-file
550 (compose string-tokenize
551 (@ (ice-9 rdelim) read-string))))
555 (car (gettimeofday)))
558 ;; Really sleep N seconds.
559 ;; Work around <http://bugs.gnu.org/19581>.
561 (let loop ((elapsed 0))
563 (sleep (- n elapsed))
564 (loop (- (now) start)))))
566 (define lset= (@ (srfi srfi-1) lset=))
568 (display "sending all processes the TERM signal\n")
570 (if (null? omitted-pids)
572 ;; Easy: terminate all of them.
574 (sleep* #$grace-delay)
577 ;; Kill them all except OMITTED-PIDS. XXX: We would
578 ;; like to (kill -1 SIGSTOP) to get a fixed list of
579 ;; processes, like 'killall5' does, but that seems
581 (kill-except omitted-pids SIGTERM)
582 (sleep* #$grace-delay)
583 (kill-except omitted-pids SIGKILL)
584 (delete-file #$%do-not-kill-file)))
587 ;; Reap children, if any, so that we don't end up with
588 ;; zombies and enter an infinite loop.
589 (let reap-children ()
592 (waitpid WAIT_ANY (if (null? omitted-pids)
596 (when (and (pair? result)
597 (not (zero? (car result))))
600 (let ((pids (processes)))
601 (unless (lset= = pids (cons 1 omitted-pids))
602 (format #t "waiting for process termination\
603 (processes left: ~s)~%"
608 (display "all processes have been terminated\n")
612 (define user-processes-service-type
614 (name 'user-processes)
615 (extensions (list (service-extension shepherd-root-service-type
616 user-processes-shepherd-service)))
617 (compose concatenate)
620 ;; The value is the list of Shepherd services 'user-processes' depends on.
621 ;; Extensions can add new services to this list.
624 (description "The @code{user-processes} service is responsible for
625 terminating all the processes so that the root file system can be re-mounted
626 read-only, just before rebooting/halting. Processes still running after a few
627 seconds after @code{SIGTERM} has been sent are terminated with
630 ;;; shepherd.scm ends here