system: Add btrfs file system support.

* gnu/build/file-systems.scm (%btrfs-endianness, btrfs-superblock?,
  read-btrfs-superblock, btrfs-superblock-uuid,
  btrfs-superblock-volume-name, check-btrfs-file-system): New variables.
  (%paritition-label-readers, %partition-uuid-readers): Add btrfs
  readers.
* gnu/system/linux-initrd.scm (linux-modules): Add btrfs modules when a
  btrfs file-system is used.
* gnu/tests/install.scm (%btrfs-root-os %btrfs-root-os-source,
  %btrfs-root-installation-script, %test-btrfs-root-os): New system
  test.
* doc/guix.texi: Adjust accordingly.

Fixes <http://bugs.gnu.org/19280>.
This commit is contained in:
David Craven 2016-11-30 19:30:12 +01:00
parent f3e44f5cd0
commit b1a505baf6
No known key found for this signature in database
GPG Key ID: C5E051C79C0BECDB
4 changed files with 129 additions and 6 deletions

View File

@ -6919,9 +6919,9 @@ cfdisk
Once you are done partitioning the target hard disk drive, you have to Once you are done partitioning the target hard disk drive, you have to
create a file system on the relevant partition(s)@footnote{Currently create a file system on the relevant partition(s)@footnote{Currently
GuixSD pretty much assumes an ext4 file system. In particular, code GuixSD only supports ext4 and btrfs file systems. In particular, code
that reads partition UUIDs and labels only works with ext4. This will that reads partition UUIDs and labels only works for these file system
be fixed in the future.}. types.}.
Preferably, assign partitions a label so that you can easily and Preferably, assign partitions a label so that you can easily and
reliably refer to them in @code{file-system} declarations (@pxref{File reliably refer to them in @code{file-system} declarations (@pxref{File

View File

@ -144,6 +144,43 @@ if DEVICE does not contain an ext2 file system."
(2 'reboot-required) (2 'reboot-required)
(_ 'fatal-error))) (_ 'fatal-error)))
;;;
;;; Btrfs file systems.
;;;
;; <https://btrfs.wiki.kernel.org/index.php/On-disk_Format#Superblock>.
(define-syntax %btrfs-endianness
;; Endianness of btrfs file systems.
(identifier-syntax (endianness little)))
(define (btrfs-superblock? sblock)
"Return #t when SBLOCK is a btrfs superblock."
(bytevector=? (sub-bytevector sblock 64 8)
(string->utf8 "_BHRfS_M")))
(define (read-btrfs-superblock device)
"Return the raw contents of DEVICE's btrfs superblock as a bytevector, or #f
if DEVICE does not contain a btrfs file system."
(read-superblock device 65536 4096 btrfs-superblock?))
(define (btrfs-superblock-uuid sblock)
"Return the UUID of a btrfs superblock SBLOCK as a 16-byte bytevector."
(sub-bytevector sblock 32 16))
(define (btrfs-superblock-volume-name sblock)
"Return the volume name of SBLOCK as a string of at most 256 characters, or
#f if SBLOCK has no volume name."
(null-terminated-latin1->string (sub-bytevector sblock 299 256)))
(define (check-btrfs-file-system device)
"Return the health of a btrfs file system on DEVICE."
(match (status:exit-val
(system* "btrfs" "device" "scan"))
(0 'pass)
(_ 'fatal-error)))
;;; ;;;
;;; LUKS encrypted devices. ;;; LUKS encrypted devices.
@ -257,11 +294,15 @@ partition field reader that returned a value."
(define %partition-label-readers (define %partition-label-readers
(list (partition-field-reader read-ext2-superblock (list (partition-field-reader read-ext2-superblock
ext2-superblock-volume-name))) ext2-superblock-volume-name)
(partition-field-reader read-btrfs-superblock
btrfs-superblock-volume-name)))
(define %partition-uuid-readers (define %partition-uuid-readers
(list (partition-field-reader read-ext2-superblock (list (partition-field-reader read-ext2-superblock
ext2-superblock-uuid))) ext2-superblock-uuid)
(partition-field-reader read-btrfs-superblock
btrfs-superblock-uuid)))
(define read-partition-label (define read-partition-label
(cut read-partition-field <> %partition-label-readers)) (cut read-partition-field <> %partition-label-readers))
@ -428,6 +469,7 @@ the following:
(define check-procedure (define check-procedure
(cond (cond
((string-prefix? "ext" type) check-ext2-file-system) ((string-prefix? "ext" type) check-ext2-file-system)
((string-prefix? "btrfs" type) check-btrfs-file-system)
(else #f))) (else #f)))
(if check-procedure (if check-procedure

View File

@ -197,6 +197,9 @@ loaded at boot time in the order in which they appear."
,@(if (find (file-system-type-predicate "vfat") file-systems) ,@(if (find (file-system-type-predicate "vfat") file-systems)
'("nls_iso8859-1") '("nls_iso8859-1")
'()) '())
,@(if (find (file-system-type-predicate "btrfs") file-systems)
'("btrfs")
'())
,@(if volatile-root? ,@(if volatile-root?
'("fuse") '("fuse")
'()) '())
@ -214,6 +217,9 @@ loaded at boot time in the order in which they appear."
file-systems) file-systems)
(list fatfsck/static) (list fatfsck/static)
'()) '())
,@(if (find (file-system-type-predicate "btrfs") file-systems)
(list btrfs-progs/static)
'())
,@(if volatile-root? ,@(if volatile-root?
(list unionfs-fuse/static) (list unionfs-fuse/static)
'()))) '())))

View File

@ -36,7 +36,8 @@
#:export (%test-installed-os #:export (%test-installed-os
%test-separate-store-os %test-separate-store-os
%test-raid-root-os %test-raid-root-os
%test-encrypted-os)) %test-encrypted-os
%test-btrfs-root-os))
;;; Commentary: ;;; Commentary:
;;; ;;;
@ -518,4 +519,78 @@ build (current-guix) and then store a couple of full system images.")
(run-basic-test %encrypted-root-os command "encrypted-root-os" (run-basic-test %encrypted-root-os command "encrypted-root-os"
#:initialization enter-luks-passphrase))))) #:initialization enter-luks-passphrase)))))
;;;
;;; Btrfs root file system.
;;;
(define-os-with-source (%btrfs-root-os %btrfs-root-os-source)
;; The OS we want to install.
(use-modules (gnu) (gnu tests) (srfi srfi-1))
(operating-system
(host-name "liberigilo")
(timezone "Europe/Paris")
(locale "en_US.UTF-8")
(bootloader (grub-configuration (device "/dev/vdb")))
(kernel-arguments '("console=ttyS0"))
(file-systems (cons (file-system
(device "my-root")
(title 'label)
(mount-point "/")
(type "btrfs"))
%base-file-systems))
(users (cons (user-account
(name "charlie")
(group "users")
(home-directory "/home/charlie")
(supplementary-groups '("wheel" "audio" "video")))
%base-user-accounts))
(services (cons (service marionette-service-type
(marionette-configuration
(imported-modules '((gnu services herd)
(guix combinators)))))
%base-services))))
(define %btrfs-root-installation-script
;; Shell script of a simple installation.
"\
. /etc/profile
set -e -x
guix --version
export GUIX_BUILD_OPTIONS=--no-grafts
ls -l /run/current-system/gc-roots
parted --script /dev/vdb mklabel gpt \\
mkpart primary ext2 1M 3M \\
mkpart primary ext2 3M 1G \\
set 1 boot on \\
set 1 bios_grub on
mkfs.btrfs -L my-root /dev/vdb2
mount /dev/vdb2 /mnt
btrfs subvolume create /mnt/home
herd start cow-store /mnt
mkdir /mnt/etc
cp /etc/target-config.scm /mnt/etc/config.scm
guix system build /mnt/etc/config.scm
guix system init /mnt/etc/config.scm /mnt --no-substitutes
sync
reboot\n")
(define %test-btrfs-root-os
(system-test
(name "btrfs-root-os")
(description
"Test basic functionality of an OS installed like one would do by hand.
This test is expensive in terms of CPU and storage usage since we need to
build (current-guix) and then store a couple of full system images.")
(value
(mlet* %store-monad ((image (run-install %btrfs-root-os
%btrfs-root-os-source
#:script
%btrfs-root-installation-script))
(command (qemu-command/writable-image image)))
(run-basic-test %btrfs-root-os command "btrfs-root-os")))))
;;; install.scm ends here ;;; install.scm ends here