linux-initrd: Remove now obsolete #:guile-modules-in-chroot? parameter.
[jackhill/guix/guix.git] / gnu / services / base.scm
CommitLineData
db4fdc04
LC
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (gnu services base)
185f6691
LC
20 #:use-module ((guix store)
21 #:select (%store-prefix))
db4fdc04 22 #:use-module (gnu services)
4a3b3b07 23 #:use-module (gnu services networking)
db4fdc04
LC
24 #:use-module (gnu system shadow) ; 'user-account', etc.
25 #:use-module (gnu system linux) ; 'pam-service', etc.
26 #:use-module (gnu packages admin)
151a2c07 27 #:use-module ((gnu packages linux)
8a7330fd 28 #:select (eudev kbd e2fsprogs lvm2 fuse alsa-utils))
db4fdc04 29 #:use-module ((gnu packages base)
bdb36958 30 #:select (canonical-package glibc))
db4fdc04 31 #:use-module (gnu packages package-management)
e2f4b305 32 #:use-module ((gnu build file-systems)
2c071ce9 33 #:select (mount-flags->bit-mask))
b5f4e686 34 #:use-module (guix gexp)
db4fdc04
LC
35 #:use-module (guix monads)
36 #:use-module (srfi srfi-1)
37 #:use-module (srfi srfi-26)
38 #:use-module (ice-9 format)
a00dd9fb 39 #:export (root-file-system-service
023f391c 40 file-system-service
5dae0186 41 device-mapping-service
2a13d05e 42 swap-service
a00dd9fb
LC
43 user-processes-service
44 host-name-service
62ca0fdf 45 console-font-service
151a2c07 46 udev-service
db4fdc04
LC
47 mingetty-service
48 nscd-service
49 syslog-service
8b198abe
LC
50 guix-service
51 %base-services))
db4fdc04
LC
52
53;;; Commentary:
54;;;
55;;; Base system services---i.e., services that 99% of the users will want to
56;;; use.
57;;;
58;;; Code:
59
a00dd9fb
LC
60(define (root-file-system-service)
61 "Return a service whose sole purpose is to re-mount read-only the root file
62system upon shutdown (aka. cleanly \"umounting\" root.)
63
64This service must be the root of the service dependency graph so that its
65'stop' action is invoked when dmd is the only process left."
a00dd9fb
LC
66 (with-monad %store-monad
67 (return
68 (service
69 (documentation "Take care of the root file system.")
70 (provision '(root-file-system))
71 (start #~(const #t))
72 (stop #~(lambda _
73 ;; Return #f if successfully stopped.
23ed63a1 74 (sync)
a00dd9fb
LC
75
76 (call-with-blocked-asyncs
77 (lambda ()
78 (let ((null (%make-void-port "w")))
79 ;; Close 'dmd.log'.
80 (display "closing log\n")
81 ;; XXX: Ideally we'd use 'stop-logging', but that one
82 ;; doesn't actually close the port as of dmd 0.1.
83 (close-port (@@ (dmd comm) log-output-port))
84 (set! (@@ (dmd comm) log-output-port) null)
85
86 ;; Redirect the default output ports..
87 (set-current-output-port null)
88 (set-current-error-port null)
89
90 ;; Close /dev/console.
91 (for-each close-fdes '(0 1 2))
92
23ed63a1 93 ;; At this point, there are no open files left, so the
a00dd9fb 94 ;; root file system can be re-mounted read-only.
23ed63a1
LC
95 (mount #f "/" #f
96 (logior MS_REMOUNT MS_RDONLY)
97 #:update-mtab? #f)
98
99 #f)))))
a00dd9fb
LC
100 (respawn? #f)))))
101
023f391c 102(define* (file-system-service device target type
2c071ce9 103 #:key (flags '()) (check? #t)
5dae0186
LC
104 create-mount-point? options (title 'any)
105 (requirements '()))
023f391c 106 "Return a service that mounts DEVICE on TARGET as a file system TYPE with
d4c87617
LC
107OPTIONS. TITLE is a symbol specifying what kind of name DEVICE is: 'label for
108a partition label, 'device for a device file name, or 'any. When CHECK? is
4e469051 109true, check the file system before mounting it. When CREATE-MOUNT-POINT? is
2c071ce9 110true, create TARGET if it does not exist yet. FLAGS is a list of symbols,
5dae0186
LC
111such as 'read-only' etc. Optionally, REQUIREMENTS may be a list of service
112names such as device-mapping services."
023f391c
LC
113 (with-monad %store-monad
114 (return
115 (service
116 (provision (list (symbol-append 'file-system- (string->symbol target))))
5dae0186 117 (requirement `(root-file-system ,@requirements))
023f391c
LC
118 (documentation "Check, mount, and unmount the given file system.")
119 (start #~(lambda args
d4c87617 120 (let ((device (canonicalize-device-spec #$device '#$title)))
4e469051
LC
121 #$(if create-mount-point?
122 #~(mkdir-p #$target)
123 #~#t)
d4c87617 124 #$(if check?
1b09031f
LC
125 #~(begin
126 ;; Make sure fsck.ext2 & co. can be found.
127 (setenv "PATH"
128 (string-append
129 #$e2fsprogs "/sbin:"
130 "/run/current-system/profile/sbin:"
131 (getenv "PATH")))
132 (check-file-system device #$type))
d4c87617 133 #~#t)
2c071ce9
LC
134 (mount device #$target #$type
135 #$(mount-flags->bit-mask flags)
136 #$options))
023f391c
LC
137 #t))
138 (stop #~(lambda args
139 ;; Normally there are no processes left at this point, so
140 ;; TARGET can be safely unmounted.
6a3f4c74
LC
141
142 ;; Make sure PID 1 doesn't keep TARGET busy.
143 (chdir "/")
144
023f391c
LC
145 (umount #$target)
146 #f))))))
147
7d57cfd3
LC
148(define %do-not-kill-file
149 ;; Name of the file listing PIDs of processes that must survive when halting
150 ;; the system. Typical example is user-space file systems.
151 "/etc/dmd/do-not-kill")
152
023f391c 153(define* (user-processes-service requirements #:key (grace-delay 2))
a00dd9fb
LC
154 "Return the service that is responsible for terminating all the processes so
155that the root file system can be re-mounted read-only, just before
156rebooting/halting. Processes still running GRACE-DELAY seconds after SIGTERM
157has been sent are terminated with SIGKILL.
158
023f391c
LC
159The returned service will depend on 'root-file-system' and on all the services
160listed in REQUIREMENTS.
161
a00dd9fb
LC
162All the services that spawn processes must depend on this one so that they are
163stopped before 'kill' is called."
164 (with-monad %store-monad
165 (return (service
166 (documentation "When stopped, terminate all user processes.")
167 (provision '(user-processes))
023f391c 168 (requirement (cons 'root-file-system requirements))
a00dd9fb
LC
169 (start #~(const #t))
170 (stop #~(lambda _
7d57cfd3
LC
171 (define (kill-except omit signal)
172 ;; Kill all the processes with SIGNAL except those
173 ;; listed in OMIT and the current process.
174 (let ((omit (cons (getpid) omit)))
175 (for-each (lambda (pid)
176 (unless (memv pid omit)
177 (false-if-exception
178 (kill pid signal))))
179 (processes))))
180
181 (define omitted-pids
182 ;; List of PIDs that must not be killed.
183 (if (file-exists? #$%do-not-kill-file)
184 (map string->number
185 (call-with-input-file #$%do-not-kill-file
186 (compose string-tokenize
187 (@ (ice-9 rdelim) read-string))))
188 '()))
189
d656c14e
LC
190 (define lset= (@ (srfi srfi-1) lset=))
191
a00dd9fb
LC
192 ;; When this happens, all the processes have been
193 ;; killed, including 'deco', so DMD-OUTPUT-PORT and
194 ;; thus CURRENT-OUTPUT-PORT are dangling.
195 (call-with-output-file "/dev/console"
196 (lambda (port)
197 (display "sending all processes the TERM signal\n"
198 port)))
199
7d57cfd3
LC
200 (if (null? omitted-pids)
201 (begin
202 ;; Easy: terminate all of them.
203 (kill -1 SIGTERM)
204 (sleep #$grace-delay)
205 (kill -1 SIGKILL))
206 (begin
207 ;; Kill them all except OMITTED-PIDS. XXX: We
208 ;; would like to (kill -1 SIGSTOP) to get a fixed
209 ;; list of processes, like 'killall5' does, but
210 ;; that seems unreliable.
211 (kill-except omitted-pids SIGTERM)
212 (sleep #$grace-delay)
213 (kill-except omitted-pids SIGKILL)
214 (delete-file #$%do-not-kill-file)))
a00dd9fb 215
d656c14e
LC
216 (let wait ()
217 (let ((pids (processes)))
218 (unless (lset= = pids (cons 1 omitted-pids))
219 (format #t "waiting for process termination\
220 (processes left: ~s)~%"
221 pids)
222 (sleep 2)
223 (wait))))
224
a00dd9fb
LC
225 (display "all processes have been terminated\n")
226 #f))
227 (respawn? #f)))))
228
db4fdc04 229(define (host-name-service name)
51da7ca0 230 "Return a service that sets the host name to @var{name}."
db4fdc04
LC
231 (with-monad %store-monad
232 (return (service
233 (documentation "Initialize the machine's host name.")
234 (provision '(host-name))
b5f4e686
LC
235 (start #~(lambda _
236 (sethostname #$name)))
db4fdc04
LC
237 (respawn? #f)))))
238
62ca0fdf
LC
239(define (unicode-start tty)
240 "Return a gexp to start Unicode support on @var{tty}."
241
242 ;; We have to run 'unicode_start' in a pipe so that when it invokes the
243 ;; 'tty' command, that command returns TTY.
244 #~(begin
245 (let ((pid (primitive-fork)))
246 (case pid
247 ((0)
248 (close-fdes 0)
249 (dup2 (open-fdes #$tty O_RDONLY) 0)
250 (close-fdes 1)
251 (dup2 (open-fdes #$tty O_WRONLY) 1)
252 (execl (string-append #$kbd "/bin/unicode_start")
253 "unicode_start"))
254 (else
255 (zero? (cdr (waitpid pid))))))))
256
257(define* (console-font-service tty #:optional (font "LatGrkCyr-8x16"))
258 "Return a service that sets up Unicode support in @var{tty} and loads
259@var{font} for that tty (fonts are per virtual console in Linux.)"
260 ;; Note: 'LatGrkCyr-8x16' has the advantage of providing three common
261 ;; scripts as well as glyphs for em dash, quotation marks, and other Unicode
262 ;; codepoints notably found in the UTF-8 manual.
263 (let ((device (string-append "/dev/" tty)))
264 (with-monad %store-monad
265 (return (service
266 (documentation "Load a Unicode console font.")
267 (provision (list (symbol-append 'console-font-
268 (string->symbol tty))))
269
270 ;; Start after mingetty has been started on TTY, otherwise the
271 ;; settings are ignored.
272 (requirement (list (symbol-append 'term-
273 (string->symbol tty))))
274
275 (start #~(lambda _
276 (and #$(unicode-start device)
277 (zero?
278 (system* (string-append #$kbd "/bin/setfont")
279 "-C" #$device #$font)))))
280 (stop #~(const #t))
281 (respawn? #f))))))
282
db4fdc04
LC
283(define* (mingetty-service tty
284 #:key
285 (motd (text-file "motd" "Welcome.\n"))
52322163
LC
286 auto-login
287 login-program
288 login-pause?
51da7ca0
LC
289
290 ;; Allow empty passwords by default so that
291 ;; first-time users can log in when the 'root'
292 ;; account has just been created.
db4fdc04 293 (allow-empty-passwords? #t))
52322163
LC
294 "Return a service to run mingetty on @var{tty}.
295
296When @var{allow-empty-passwords?} is true, allow empty log-in password. When
297@var{auto-login} is true, it must be a user name under which to log-in
298automatically. @var{login-pause?} can be set to @code{#t} in conjunction with
299@var{auto-login}, in which case the user will have to press a key before the
300login shell is launched.
301
302When true, @var{login-program} is a gexp or a monadic gexp denoting the name
303of the log-in program (the default is the @code{login} program from the Shadow
304tool suite.)
305
306@var{motd} is a monadic value containing a text file to use as
51da7ca0 307the ``message of the day''."
52322163
LC
308 (mlet %store-monad ((motd motd)
309 (login-program (cond ((gexp? login-program)
310 (return login-program))
311 ((not login-program)
312 (return #f))
313 (else
314 login-program))))
db4fdc04
LC
315 (return
316 (service
317 (documentation (string-append "Run mingetty on " tty "."))
318 (provision (list (symbol-append 'term- (string->symbol tty))))
319
320 ;; Since the login prompt shows the host name, wait for the 'host-name'
321 ;; service to be done.
a00dd9fb 322 (requirement '(user-processes host-name))
db4fdc04 323
b5f4e686 324 (start #~(make-forkexec-constructor
1c6b445b
LC
325 (list (string-append #$mingetty "/sbin/mingetty")
326 "--noclear" #$tty
327 #$@(if auto-login
328 #~("--autologin" #$auto-login)
329 #~())
330 #$@(if login-program
331 #~("--loginprog" #$login-program)
332 #~())
333 #$@(if login-pause?
334 #~("--loginpause")
335 #~()))))
b5f4e686 336 (stop #~(make-kill-destructor))
db4fdc04
LC
337
338 (pam-services
339 ;; Let 'login' be known to PAM. All the mingetty services will have
340 ;; that PAM service, but that's fine because they're all identical and
341 ;; duplicates are removed.
342 (list (unix-pam-service "login"
343 #:allow-empty-passwords? allow-empty-passwords?
344 #:motd motd)))))))
345
bdb36958 346(define* (nscd-service #:key (glibc (canonical-package glibc)))
db4fdc04 347 "Return a service that runs libc's name service cache daemon (nscd)."
b5f4e686 348 (with-monad %store-monad
db4fdc04
LC
349 (return (service
350 (documentation "Run libc's name service cache daemon (nscd).")
351 (provision '(nscd))
a00dd9fb 352 (requirement '(user-processes))
4b2615e1
LC
353
354 (activate #~(begin
355 (use-modules (guix build utils))
356 (mkdir-p "/var/run/nscd")))
357
1c6b445b
LC
358 (start #~(make-forkexec-constructor
359 (list (string-append #$glibc "/sbin/nscd")
360 "-f" "/dev/null" "--foreground")))
b5f4e686 361 (stop #~(make-kill-destructor))
db4fdc04 362
b5f4e686 363 (respawn? #f)))))
db4fdc04
LC
364
365(define (syslog-service)
51da7ca0 366 "Return a service that runs @code{syslogd} with reasonable default settings."
db4fdc04
LC
367
368 ;; Snippet adapted from the GNU inetutils manual.
369 (define contents "
1f3fc60d 370 # Log all error messages, authentication messages of
db4fdc04
LC
371 # level notice or higher and anything of level err or
372 # higher to the console.
373 # Don't log private authentication messages!
6a191274 374 *.alert;auth.notice;authpriv.none /dev/console
db4fdc04
LC
375
376 # Log anything (except mail) of level info or higher.
377 # Don't log private authentication messages!
378 *.info;mail.none;authpriv.none /var/log/messages
379
380 # Same, in a different place.
381 *.info;mail.none;authpriv.none /dev/tty12
382
383 # The authpriv file has restricted access.
384 authpriv.* /var/log/secure
385
386 # Log all the mail messages in one place.
387 mail.* /var/log/maillog
388")
389
390 (mlet %store-monad
b5f4e686 391 ((syslog.conf (text-file "syslog.conf" contents)))
db4fdc04
LC
392 (return
393 (service
394 (documentation "Run the syslog daemon (syslogd).")
395 (provision '(syslogd))
a00dd9fb 396 (requirement '(user-processes))
b5f4e686 397 (start
1c6b445b
LC
398 #~(make-forkexec-constructor
399 (list (string-append #$inetutils "/libexec/syslogd")
400 "--no-detach" "--rcfile" #$syslog.conf)))
b5f4e686 401 (stop #~(make-kill-destructor))))))
db4fdc04
LC
402
403(define* (guix-build-accounts count #:key
ab6a279a 404 (group "guixbuild")
db4fdc04 405 (first-uid 30001)
db4fdc04
LC
406 (shadow shadow))
407 "Return a list of COUNT user accounts for Guix build users, with UIDs
408starting at FIRST-UID, and under GID."
409 (with-monad %store-monad
410 (return (unfold (cut > <> count)
411 (lambda (n)
412 (user-account
413 (name (format #f "guixbuilder~2,'0d" n))
459dd9ea 414 (system? #t)
db4fdc04 415 (uid (+ first-uid n -1))
ab6a279a 416 (group group)
3d116a70
LC
417
418 ;; guix-daemon expects GROUP to be listed as a
419 ;; supplementary group too:
420 ;; <http://lists.gnu.org/archive/html/bug-guix/2013-01/msg00239.html>.
421 (supplementary-groups (list group))
422
db4fdc04
LC
423 (comment (format #f "Guix Build User ~2d" n))
424 (home-directory "/var/empty")
b5f4e686 425 (shell #~(string-append #$shadow "/sbin/nologin"))))
db4fdc04
LC
426 1+
427 1))))
428
2c5c696c
LC
429(define (hydra-key-authorization guix)
430 "Return a gexp with code to register the hydra.gnu.org public key with
431GUIX."
432 #~(unless (file-exists? "/etc/guix/acl")
433 (let ((pid (primitive-fork)))
434 (case pid
435 ((0)
436 (let* ((key (string-append #$guix
437 "/share/guix/hydra.gnu.org.pub"))
438 (port (open-file key "r0b")))
439 (format #t "registering public key '~a'...~%" key)
440 (close-port (current-input-port))
2c5c696c
LC
441 (dup port 0)
442 (execl (string-append #$guix "/bin/guix")
443 "guix" "archive" "--authorize")
444 (exit 1)))
445 (else
446 (let ((status (cdr (waitpid pid))))
447 (unless (zero? status)
448 (format (current-error-port) "warning: \
449failed to register hydra.gnu.org public key: ~a~%" status))))))))
450
db4fdc04 451(define* (guix-service #:key (guix guix) (builder-group "guixbuild")
c11a6eb1
LC
452 (build-accounts 10) authorize-hydra-key?
453 (use-substitutes? #t)
454 (extra-options '()))
51da7ca0
LC
455 "Return a service that runs the build daemon from @var{guix}, and has
456@var{build-accounts} user accounts available under @var{builder-group}.
2c5c696c 457
51da7ca0
LC
458When @var{authorize-hydra-key?} is true, the @code{hydra.gnu.org} public key
459provided by @var{guix} is authorized upon activation, meaning that substitutes
c11a6eb1
LC
460from @code{hydra.gnu.org} are used by default.
461
462If @var{use-substitutes?} is false, the daemon is run with
463@option{--no-substitutes} (@pxref{Invoking guix-daemon,
464@option{--no-substitutes}}).
465
466Finally, @var{extra-options} is a list of additional command-line options
467passed to @command{guix-daemon}."
185f6691 468 (define activate
e97c5be9
LC
469 ;; Assume that the store has BUILDER-GROUP as its group. We could
470 ;; otherwise call 'chown' here, but the problem is that on a COW unionfs,
471 ;; chown leads to an entire copy of the tree, which is a bad idea.
185f6691 472
e97c5be9
LC
473 ;; Optionally authorize hydra.gnu.org's key.
474 (and authorize-hydra-key?
475 (hydra-key-authorization guix)))
185f6691 476
b5f4e686 477 (mlet %store-monad ((accounts (guix-build-accounts build-accounts
ab6a279a 478 #:group builder-group)))
db4fdc04
LC
479 (return (service
480 (provision '(guix-daemon))
a00dd9fb 481 (requirement '(user-processes))
b5f4e686 482 (start
1c6b445b
LC
483 #~(make-forkexec-constructor
484 (list (string-append #$guix "/bin/guix-daemon")
c11a6eb1
LC
485 "--build-users-group" #$builder-group
486 #$@(if use-substitutes?
487 '()
488 '("--no-substitutes"))
489 #$@extra-options)))
b5f4e686 490 (stop #~(make-kill-destructor))
db4fdc04
LC
491 (user-accounts accounts)
492 (user-groups (list (user-group
493 (name builder-group)
41717509 494 (system? #t)
e97c5be9
LC
495
496 ;; Use a fixed GID so that we can create the
497 ;; store with the right owner.
498 (id 30000))))
185f6691 499 (activate activate)))))
db4fdc04 500
ecd06ca9
LC
501(define (udev-rules-union packages)
502 "Return the union of the @code{lib/udev/rules.d} directories found in each
503item of @var{packages}."
504 (define build
505 #~(begin
506 (use-modules (guix build union)
507 (guix build utils)
508 (srfi srfi-1)
509 (srfi srfi-26))
510
511 (define %standard-locations
512 '("/lib/udev/rules.d" "/libexec/udev/rules.d"))
513
514 (define (rules-sub-directory directory)
515 ;; Return the sub-directory of DIRECTORY containing udev rules, or
516 ;; #f if none was found.
517 (find directory-exists?
518 (map (cut string-append directory <>) %standard-locations)))
519
520 (mkdir-p (string-append #$output "/lib/udev"))
521 (union-build (string-append #$output "/lib/udev/rules.d")
522 (filter-map rules-sub-directory '#$packages))))
523
524 (gexp->derivation "udev-rules" build
525 #:modules '((guix build union)
526 (guix build utils))
527 #:local-build? #t))
528
8a7330fd 529(define* (udev-service #:key (udev eudev) (rules '()))
ecd06ca9
LC
530 "Run @var{udev}, which populates the @file{/dev} directory dynamically. Get
531extra rules from the packages listed in @var{rules}."
532 (mlet* %store-monad ((rules (udev-rules-union (cons udev rules)))
533 (udev.conf (text-file* "udev.conf"
534 "udev_rules=\"" rules
535 "/lib/udev/rules.d\"\n")))
151a2c07
LC
536 (return (service
537 (provision '(udev))
a69576ea
LC
538
539 ;; Udev needs /dev to be a 'devtmpfs' mount so that new device
540 ;; nodes can be added: see
541 ;; <http://www.linuxfromscratch.org/lfs/view/development/chapter07/udev.html>.
7f239fd3 542 (requirement '(root-file-system))
a69576ea
LC
543
544 (documentation "Populate the /dev directory, dynamically.")
151a2c07 545 (start #~(lambda ()
66a99a06
LC
546 (define find
547 (@ (srfi srfi-1) find))
548
1c6b445b 549 (define udevd
66a99a06
LC
550 ;; Choose the right 'udevd'.
551 (find file-exists?
552 (map (lambda (suffix)
553 (string-append #$udev suffix))
554 '("/libexec/udev/udevd" ;udev
555 "/sbin/udevd")))) ;eudev
1c6b445b 556
ed09bb11
LC
557 (define (wait-for-udevd)
558 ;; Wait until someone's listening on udevd's control
559 ;; socket.
560 (let ((sock (socket AF_UNIX SOCK_SEQPACKET 0)))
561 (let try ()
562 (catch 'system-error
563 (lambda ()
564 (connect sock PF_UNIX "/run/udev/control")
565 (close-port sock))
566 (lambda args
567 (format #t "waiting for udevd...~%")
568 (usleep 500000)
569 (try))))))
570
081c5b2d
LC
571 ;; Allow udev to find the modules.
572 (setenv "LINUX_MODULE_DIRECTORY"
573 "/run/booted-system/kernel/lib/modules")
574
66a99a06 575 ;; The first one is for udev, the second one for eudev.
ecd06ca9 576 (setenv "UDEV_CONFIG_FILE" #$udev.conf)
66a99a06 577 (setenv "EUDEV_RULES_DIRECTORY" #$rules)
ecd06ca9 578
151a2c07
LC
579 (let ((pid (primitive-fork)))
580 (case pid
581 ((0)
1c6b445b 582 (exec-command (list udevd)))
151a2c07 583 (else
ed09bb11
LC
584 ;; Wait until udevd is up and running. This
585 ;; appears to be needed so that the events
586 ;; triggered below are actually handled.
587 (wait-for-udevd)
588
589 ;; Trigger device node creation.
590 (system* (string-append #$udev "/bin/udevadm")
591 "trigger" "--action=add")
592
081c5b2d
LC
593 ;; Wait for things to settle down.
594 (system* (string-append #$udev "/bin/udevadm")
595 "settle")
151a2c07 596 pid)))))
66d5d8c0
LC
597 (stop #~(make-kill-destructor))
598
599 ;; When halting the system, 'udev' is actually killed by
600 ;; 'user-processes', i.e., before its own 'stop' method was
601 ;; called. Thus, make sure it is not respawned.
602 (respawn? #f)))))
151a2c07 603
722554a3 604(define (device-mapping-service target open close)
5dae0186 605 "Return a service that maps device @var{target}, a string such as
722554a3
LC
606@code{\"home\"} (meaning @code{/dev/mapper/home}). Evaluate @var{open}, a
607gexp, to open it, and evaluate @var{close} to close it."
5dae0186
LC
608 (with-monad %store-monad
609 (return (service
610 (provision (list (symbol-append 'device-mapping-
611 (string->symbol target))))
612 (requirement '(udev))
613 (documentation "Map a device node using Linux's device mapper.")
722554a3
LC
614 (start #~(lambda () #$open))
615 (stop #~(lambda _ (not #$close)))
5dae0186
LC
616 (respawn? #f)))))
617
2a13d05e
LC
618(define (swap-service device)
619 "Return a service that uses @var{device} as a swap device."
620 (define requirement
621 (if (string-prefix? "/dev/mapper/" device)
622 (list (symbol-append 'device-mapping-
623 (string->symbol (basename device))))
624 '()))
625
626 (with-monad %store-monad
627 (return (service
628 (provision (list (symbol-append 'swap- (string->symbol device))))
629 (requirement `(udev ,@requirement))
630 (documentation "Enable the given swap device.")
631 (start #~(lambda ()
632 (swapon #$device)
633 #t))
634 (stop #~(lambda _
635 (swapoff #$device)
636 #f))
637 (respawn? #f)))))
638
8b198abe
LC
639(define %base-services
640 ;; Convenience variable holding the basic services.
641 (let ((motd (text-file "motd" "
642This is the GNU operating system, welcome!\n\n")))
62ca0fdf
LC
643 (list (console-font-service "tty1")
644 (console-font-service "tty2")
645 (console-font-service "tty3")
646 (console-font-service "tty4")
647 (console-font-service "tty5")
648 (console-font-service "tty6")
649
650 (mingetty-service "tty1" #:motd motd)
8b198abe
LC
651 (mingetty-service "tty2" #:motd motd)
652 (mingetty-service "tty3" #:motd motd)
653 (mingetty-service "tty4" #:motd motd)
654 (mingetty-service "tty5" #:motd motd)
655 (mingetty-service "tty6" #:motd motd)
4a3b3b07
LC
656 (static-networking-service "lo" "127.0.0.1"
657 #:provision '(loopback))
8b198abe
LC
658 (syslog-service)
659 (guix-service)
151a2c07 660 (nscd-service)
ecd06ca9 661
52bd5734
LC
662 ;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
663 ;; used, so enable them by default. The FUSE and ALSA rules are
664 ;; less critical, but handy.
665 (udev-service #:rules (list lvm2 fuse alsa-utils)))))
8b198abe 666
db4fdc04 667;;; base.scm ends here