activation: Set the right owner for home directories.
[jackhill/guix/guix.git] / gnu / system / file-systems.scm
CommitLineData
c5df1839 1;;; GNU Guix --- Functional package management for GNU
38434419 2;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
c5df1839
LC
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 system file-systems)
575b4b09 20 #:use-module (ice-9 match)
c5df1839 21 #:use-module (guix records)
3392ce5d 22 #:use-module (guix store)
f8865db6
LC
23 #:use-module ((gnu build file-systems)
24 #:select (string->uuid uuid->string))
25 #:re-export (string->uuid
26 uuid->string)
c5df1839
LC
27 #:export (<file-system>
28 file-system
29 file-system?
30 file-system-device
d4c87617 31 file-system-title
c5df1839
LC
32 file-system-mount-point
33 file-system-type
34 file-system-needed-for-boot?
35 file-system-flags
36 file-system-options
be21979d 37 file-system-mount?
4e469051
LC
38 file-system-check?
39 file-system-create-mount-point?
e51710d1 40 file-system-dependencies
c5df1839 41
575b4b09 42 file-system->spec
5970e8e2 43 spec->file-system
d77a0bd6 44 specification->file-system-mapping
661a1d79 45 uuid
575b4b09 46
c5df1839 47 %fuse-control-file-system
a69576ea 48 %binary-format-file-system
705f8b68
MW
49 %shared-memory-file-system
50 %pseudo-terminal-file-system
3c185b24 51 %tty-gid
3392ce5d 52 %immutable-store
727636aa 53 %control-groups
14454f0b 54 %elogind-file-systems
a69576ea 55
5dae0186 56 %base-file-systems
c829bc80 57 %container-file-systems
5dae0186 58
9110c2e9
DT
59 <file-system-mapping>
60 file-system-mapping
61 file-system-mapping?
62 file-system-mapping-source
63 file-system-mapping-target
64 file-system-mapping-writable?
65
d2a5e698
LC
66 file-system-mapping->bind-mount
67
9110c2e9 68 %store-mapping))
c5df1839
LC
69
70;;; Commentary:
71;;;
72;;; Declaring file systems to be mounted.
73;;;
74;;; Code:
75
76;; File system declaration.
77(define-record-type* <file-system> file-system
78 make-file-system
79 file-system?
80 (device file-system-device) ; string
d4c87617
LC
81 (title file-system-title ; 'device | 'label | 'uuid
82 (default 'device))
c5df1839
LC
83 (mount-point file-system-mount-point) ; string
84 (type file-system-type) ; string
85 (flags file-system-flags ; list of symbols
86 (default '()))
87 (options file-system-options ; string or #f
88 (default #f))
be21979d
LC
89 (mount? file-system-mount? ; Boolean
90 (default #t))
4d6b879c 91 (needed-for-boot? %file-system-needed-for-boot? ; Boolean
c5df1839
LC
92 (default #f))
93 (check? file-system-check? ; Boolean
4e469051
LC
94 (default #t))
95 (create-mount-point? file-system-create-mount-point? ; Boolean
e51710d1 96 (default #f))
e502bf89
LC
97 (dependencies file-system-dependencies ; list of <file-system>
98 (default '()))) ; or <mapped-device>
c5df1839 99
38434419
LC
100(define %not-slash
101 (char-set-complement (char-set #\/)))
102
103(define (file-prefix? file1 file2)
104 "Return #t if FILE1 denotes the name of a file that is a parent of FILE2,
105where both FILE1 and FILE2 are absolute file name. For example:
106
107 (file-prefix? \"/gnu\" \"/gnu/store\")
108 => #t
109
110 (file-prefix? \"/gn\" \"/gnu/store\")
111 => #f
112"
113 (and (string-prefix? "/" file1)
114 (string-prefix? "/" file2)
115 (let loop ((file1 (string-tokenize file1 %not-slash))
116 (file2 (string-tokenize file2 %not-slash)))
117 (match file1
118 (()
119 #t)
120 ((head1 tail1 ...)
121 (match file2
122 ((head2 tail2 ...)
123 (and (string=? head1 head2) (loop tail1 tail2)))
124 (()
125 #f)))))))
126
127(define (file-system-needed-for-boot? fs)
128 "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the
129store--e.g., if FS is the root file system."
4d6b879c 130 (or (%file-system-needed-for-boot? fs)
38434419
LC
131 (and (file-prefix? (file-system-mount-point fs) (%store-prefix))
132 (not (memq 'bind-mount (file-system-flags fs))))))
4d6b879c 133
575b4b09
DT
134(define (file-system->spec fs)
135 "Return a list corresponding to file-system FS that can be passed to the
136initrd code."
137 (match fs
be21979d 138 (($ <file-system> device title mount-point type flags options _ _ check?)
575b4b09
DT
139 (list device title mount-point type flags options check?))))
140
5970e8e2
LC
141(define (spec->file-system sexp)
142 "Deserialize SEXP, a list, to the corresponding <file-system> object."
143 (match sexp
144 ((device title mount-point type flags options check?)
145 (file-system
146 (device device) (title title)
147 (mount-point mount-point) (type type)
148 (flags flags) (options options)
149 (check? check?)))))
150
d77a0bd6
LC
151(define (specification->file-system-mapping spec writable?)
152 "Read the SPEC and return the corresponding <file-system-mapping>. SPEC is
153a string of the form \"SOURCE\" or \"SOURCE=TARGET\". The former specifies
154that SOURCE from the host should be mounted at SOURCE in the other system.
155The latter format specifies that SOURCE from the host should be mounted at
156TARGET in the other system."
157 (let ((index (string-index spec #\=)))
158 (if index
159 (file-system-mapping
160 (source (substring spec 0 index))
161 (target (substring spec (+ 1 index)))
162 (writable? writable?))
163 (file-system-mapping
164 (source spec)
165 (target spec)
166 (writable? writable?)))))
167
661a1d79
LC
168(define-syntax uuid
169 (lambda (s)
170 "Return the bytevector corresponding to the given UUID representation."
171 (syntax-case s ()
172 ((_ str)
173 (string? (syntax->datum #'str))
174 ;; A literal string: do the conversion at expansion time.
1cab9e81
LC
175 (let ((bv (string->uuid (syntax->datum #'str))))
176 (unless bv
177 (syntax-violation 'uuid "invalid UUID" s))
178 (datum->syntax #'str bv)))
661a1d79
LC
179 ((_ str)
180 #'(string->uuid str)))))
181
182\f
183;;;
184;;; Common file systems.
185;;;
186
c5df1839
LC
187(define %fuse-control-file-system
188 ;; Control file system for Linux' file systems in user-space (FUSE).
189 (file-system
190 (device "fusectl")
191 (mount-point "/sys/fs/fuse/connections")
192 (type "fusectl")
193 (check? #f)))
194
195(define %binary-format-file-system
196 ;; Support for arbitrary executable binary format.
197 (file-system
198 (device "binfmt_misc")
199 (mount-point "/proc/sys/fs/binfmt_misc")
200 (type "binfmt_misc")
201 (check? #f)))
202
7f239fd3
LC
203(define %tty-gid
204 ;; ID of the 'tty' group. Allocate it statically to make it easy to refer
205 ;; to it from here and from the 'tty' group definitions.
c8fa3426 206 996)
7f239fd3
LC
207
208(define %pseudo-terminal-file-system
209 ;; The pseudo-terminal file system. It needs to be mounted so that
210 ;; statfs(2) returns DEVPTS_SUPER_MAGIC like libc's getpt(3) expects (and
211 ;; thus openpty(3) and its users, such as xterm.)
212 (file-system
213 (device "none")
214 (mount-point "/dev/pts")
215 (type "devpts")
216 (check? #f)
217 (needed-for-boot? #f)
218 (create-mount-point? #t)
219 (options (string-append "gid=" (number->string %tty-gid) ",mode=620"))))
a69576ea 220
db17ae5c
LC
221(define %shared-memory-file-system
222 ;; Shared memory.
223 (file-system
224 (device "tmpfs")
225 (mount-point "/dev/shm")
226 (type "tmpfs")
227 (check? #f)
228 (flags '(no-suid no-dev))
229 (options "size=50%") ;TODO: make size configurable
230 (create-mount-point? #t)))
231
3392ce5d
LC
232(define %immutable-store
233 ;; Read-only store to avoid users or daemons accidentally modifying it.
234 ;; 'guix-daemon' has provisions to remount it read-write in its own name
235 ;; space.
236 (file-system
237 (device (%store-prefix))
238 (mount-point (%store-prefix))
239 (type "none")
240 (check? #f)
241 (flags '(read-only bind-mount))))
242
727636aa 243(define %control-groups
b78cad85
LC
244 (let ((parent (file-system
245 (device "cgroup")
246 (mount-point "/sys/fs/cgroup")
247 (type "tmpfs")
248 (check? #f))))
249 (cons parent
250 (map (lambda (subsystem)
251 (file-system
252 (device "cgroup")
253 (mount-point (string-append "/sys/fs/cgroup/" subsystem))
254 (type "cgroup")
255 (check? #f)
256 (options subsystem)
257 (create-mount-point? #t)
258
259 ;; This must be mounted after, and unmounted before the
260 ;; parent directory.
261 (dependencies (list parent))))
262 '("cpuset" "cpu" "cpuacct" "memory" "devices" "freezer"
263 "blkio" "perf_event" "hugetlb")))))
727636aa 264
14454f0b
MW
265(define %elogind-file-systems
266 ;; We don't use systemd, but these file systems are needed for elogind,
267 ;; which was extracted from systemd.
268 (list (file-system
269 (device "none")
270 (mount-point "/run/systemd")
271 (type "tmpfs")
272 (check? #f)
273 (flags '(no-suid no-dev no-exec))
274 (options "mode=0755")
275 (create-mount-point? #t))
276 (file-system
277 (device "none")
278 (mount-point "/run/user")
279 (type "tmpfs")
280 (check? #f)
281 (flags '(no-suid no-dev no-exec))
282 (options "mode=0755")
a7e50a2a
AW
283 (create-mount-point? #t))
284 ;; Elogind uses cgroups to organize processes, allowing it to map PIDs
285 ;; to sessions. Elogind's cgroup hierarchy isn't associated with any
286 ;; resource controller ("subsystem").
287 (file-system
288 (device "cgroup")
289 (mount-point "/sys/fs/cgroup/elogind")
290 (type "cgroup")
291 (check? #f)
292 (options "none,name=elogind")
293 (create-mount-point? #t)
294 (dependencies (list (car %control-groups))))))
14454f0b 295
a69576ea
LC
296(define %base-file-systems
297 ;; List of basic file systems to be mounted. Note that /proc and /sys are
298 ;; currently mounted by the initrd.
cc0e575a 299 (append (list %pseudo-terminal-file-system
727636aa
DT
300 %shared-memory-file-system
301 %immutable-store)
302 %control-groups))
a69576ea 303
c829bc80
DT
304;; File systems for Linux containers differ from %base-file-systems in that
305;; they impose additional restrictions such as no-exec or need different
306;; options to function properly.
307;;
308;; The file system flags and options conform to the libcontainer
309;; specification:
310;; https://github.com/docker/libcontainer/blob/master/SPEC.md#filesystem
311(define %container-file-systems
312 (list
b57ec5f6 313 ;; Pseudo-terminal file system.
c829bc80
DT
314 (file-system
315 (device "none")
316 (mount-point "/dev/pts")
317 (type "devpts")
318 (flags '(no-exec no-suid))
319 (needed-for-boot? #t)
320 (create-mount-point? #t)
321 (check? #f)
322 (options "newinstance,ptmxmode=0666,mode=620"))
323 ;; Shared memory file system.
324 (file-system
325 (device "tmpfs")
326 (mount-point "/dev/shm")
327 (type "tmpfs")
328 (flags '(no-exec no-suid no-dev))
329 (options "mode=1777,size=65536k")
330 (needed-for-boot? #t)
331 (create-mount-point? #t)
332 (check? #f))
333 ;; Message queue file system.
334 (file-system
335 (device "mqueue")
336 (mount-point "/dev/mqueue")
337 (type "mqueue")
338 (flags '(no-exec no-suid no-dev))
339 (needed-for-boot? #t)
340 (create-mount-point? #t)
341 (check? #f))))
342
9110c2e9
DT
343\f
344;;;
345;;; Shared file systems, for VMs/containers.
346;;;
347
348;; Mapping of host file system SOURCE to mount point TARGET in the guest.
349(define-record-type* <file-system-mapping> file-system-mapping
350 make-file-system-mapping
351 file-system-mapping?
352 (source file-system-mapping-source) ;string
353 (target file-system-mapping-target) ;string
354 (writable? file-system-mapping-writable? ;Boolean
355 (default #f)))
356
d2a5e698
LC
357(define (file-system-mapping->bind-mount mapping)
358 "Return a file system that realizes MAPPING, a <file-system-mapping>, using
359a bind mount."
360 (match mapping
361 (($ <file-system-mapping> source target writable?)
362 (file-system
363 (mount-point target)
364 (device source)
365 (type "none")
366 (flags (if writable?
367 '(bind-mount)
368 '(bind-mount read-only)))
369 (check? #f)
370 (create-mount-point? #t)))))
371
9110c2e9
DT
372(define %store-mapping
373 ;; Mapping of the host's store into the guest.
374 (file-system-mapping
375 (source (%store-prefix))
376 (target (%store-prefix))
377 (writable? #f)))
378
c5df1839 379;;; file-systems.scm ends here