aboutsummaryrefslogtreecommitdiff
path: root/gnu/build/linux-initrd.scm
blob: ea7de58553ceac11c11c8df516bef81a9c6dd234 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013, 2014, 2015, 2018 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu build linux-initrd)
  #:use-module ((guix cpio) #:prefix cpio:)
  #:use-module (guix build utils)
  #:use-module (guix build store-copy)
  #:use-module (system base compile)
  #:use-module (rnrs bytevectors)
  #:use-module ((system foreign) #:select (sizeof))
  #:use-module (ice-9 ftw)
  #:export (write-cpio-archive
            build-initrd))

;;; Commentary:
;;;
;;; Tools to create Linux initial RAM disks ("initrds").  Initrds are
;;; essentially gzipped cpio archives, with a '/init' executable that the
;;; kernel runs at boot time.
;;;
;;; Code:

(define* (write-cpio-archive output directory
                             #:key
                             (compress? #t)
                             (gzip "gzip"))
  "Write a cpio archive containing DIRECTORY to file OUTPUT.  When
COMPRESS? is true, compress it using GZIP.  On success, return OUTPUT."

  ;; Note: as per `ramfs-rootfs-initramfs.txt', always add directory entries
  ;; before the files that are inside of it: "The Linux kernel cpio
  ;; extractor won't create files in a directory that doesn't exist, so the
  ;; directory entries must go before the files that go in those
  ;; directories."

  (define files
    ;; Use 'sort' so that (1) the order of files is deterministic, and (2)
    ;; directories appear before the files they contain.
    (sort (file-system-fold (const #t)                 ;enter?
                            (lambda (file stat result) ;leaf
                              (cons file result))
                            (lambda (dir stat result)  ;down
                              (if (string=? dir directory)
                                  result
                                  (cons dir result)))
                            (lambda (file stat result)
                              result)
                            (const #f)                 ;skip
                            (const #f)                 ;error
                            '()
                            directory)
          string<?))

  (call-with-output-file output
    (lambda (port)
      (cpio:write-cpio-archive files port
                               #:file->header cpio:file->cpio-header*)))

  (if compress?
      ;; Gzip insists on adding a '.gz' suffix and does nothing if the input
      ;; file already has that suffix.  Shuffle files around to placate it.
      (let* ((gz-suffix? (string-suffix? ".gz" output))
             (sans-gz    (if gz-suffix?
                             (string-drop-right output 3)
                             output)))
        (when gz-suffix?
          (rename-file output sans-gz))
        ;; Use '--no-name' so that gzip records neither a file name nor a time
        ;; stamp in its output.
        (and (zero? (system* gzip "--best" "--no-name" sans-gz))
             (begin
               (unless gz-suffix?
                 (rename-file (string-append output ".gz") output))
               output)))
      output))

(define (cache-compiled-file-name file)
  "Return the file name of the in-cache .go file for FILE, relative to the
current directory.

This is similar to what 'compiled-file-name' in (system base compile) does."
  (let loop ((file file))
    (let ((target (false-if-exception (readlink file))))
     (if target
         (loop target)
         (format #f ".cache/guile/ccache/~a-~a-~a-~a/~a"
                 (effective-version)
                 (if (eq? (native-endianness) (endianness little))
                     "LE"
                     "BE")
                 (sizeof '*)
                 (effective-version)
                 file)))))

(define (compile-to-cache file)
  "Compile FILE to the cache."
  (let ((compiled-file (cache-compiled-file-name file)))
    (mkdir-p (dirname compiled-file))
    (compile-file file
                  #:opts %auto-compilation-options
                  #:output-file compiled-file)))

(define* (build-initrd output
                       #:key
                       guile init
                       (references-graphs '())
                       (gzip "gzip"))
  "Write an initial RAM disk (initrd) to OUTPUT.  The initrd starts the script
at INIT, running GUILE.  It contains all the items referred to by
REFERENCES-GRAPHS."
  (mkdir "contents")

  ;; Copy the closures of all the items referenced in REFERENCES-GRAPHS.
  (populate-store references-graphs "contents")

  (with-directory-excursion "contents"
    ;; Make '/init'.
    (symlink init "init")

    ;; Compile it.
    (compile-to-cache "init")

    ;; Allow Guile to find out where it is (XXX).  See
    ;; 'guile-relocatable.patch'.
    (mkdir-p "proc/self")
    (symlink (string-append guile "/bin/guile") "proc/self/exe")
    (readlink "proc/self/exe")

    ;; Reset the timestamps of all the files that will make it in the initrd.
    (for-each (lambda (file)
                (unless (eq? 'symlink (stat:type (lstat file)))
                  (utime file 0 0 0 0)))
              (find-files "." ".*"))

    (write-cpio-archive output "." #:gzip gzip))

  ;; Make sure directories are writable so we can delete files.
  (for-each make-file-writable
            (find-files "contents"
                        (lambda (file stat)
                          (eq? 'directory (stat:type stat)))
                        #:directories? #t))
  (delete-file-recursively "contents"))

;;; linux-initrd.scm ends here
9f395fb'>teams: Add Mark H Weaver to the ‘mozilla’ team....* etc/teams.scm (Mark H Weaver): Add to the ‘mozilla’ team. Mark H Weaver 2024-01-30teams: go: Add golang-xyz.scm to scope....* etc/teams.scm (go): Add "gnu/packages/golang-xyz.scm". Change-Id: I580eadf52b631c6582e256a2900786b53483a466 Sharlatan Hellseher 2024-01-28teams: go: Add more related files to the scope....* etc/teams.scm (go): Add "gnu/packages/configuration-management.scm", "gnu/packages/golang-crypto.scm", "gnu/packages/golang-web.scm", "gnu/packages/syncthing.scm", "gnu/packages/terraform.scm". Sort list alphabetically. Change-Id: I56ce5bd21e487e5dbe2d84aa1d83e3239268fb71 Sharlatan Hellseher 2024-01-24teams: Remove Efraim Flashner from the science team....* etc/teams.scm (Efraim Flashner): Remove science team. Change-Id: I790fe329cde11fcb4b706b01b9aa59ad29d8c874 Efraim Flashner 2024-01-16teams: Add Wilko Meyer to kernel....* etc/teams.scm: Add Wilko Meyer. Change-Id: Ia7b85a090a4d8e81689bd137e1d12cb3708aa760 Signed-off-by: Leo Famulari <leo@famulari.name> Wilko Meyer 2024-01-14teams: Add Vivien Kraus....* etc/teams.scm.in ("Vivien Kraus"): New member. Change-Id: Iab2c9300f3e1e604fb2ee539a7eb05e7a3f54776 Signed-off-by: Liliana Marie Prikler <liliana.prikler@gmail.com> Vivien Kraus 2024-01-12teams: Add entry for Sharlatan Hellseher....* etc/teams.scm ("Sharlatan Hellseher"): New member. Change-Id: I05f1442e90799e182feb153f45191e789c05461b Sharlatan Hellseher 2024-01-05teams: Add ‘core-packages’ team....* etc/teams.scm (bootstrap): Add “gnu/packages/commencement.scm”. (core-packages): New team. (Ludovic Courtès): Add to ‘core-packages’ team. Change-Id: I25f22d436a4dc9bf4c8f577f94cc178cbaa80768 Ludovic Courtès 2023-12-22teams: mozilla: Add icecat-extension.scm and browser-extensions.scm....* etc/teams.scm (mozilla): Add "gnu/build/icecat-extension.scm" and "gnu/packages/browser-extensions.scm". Change-Id: Id59fb307256e5870b3c19f0b7c41446775a57d9e Clément Lassieur 2023-12-20teams: Add entry for Clément Lassieur....* etc/teams.scm ("Clément Lassieur"): New member. Change-Id: If6456d9496f59b0a26608ad5e55aa8fdfb8af492 Clément Lassieur 2023-11-20teams: Include golang-check.scm in the go team....* etc/teams.scm (go): Add gnu/packages/golang-check.scm to scope. Change-Id: Ifc90eb0c3fc5d716b605e7e3e100a38431498a2c Signed-off-by: Christopher Baines <mail@cbaines.net> Benjamin 2023-11-12teams: Add Ekaitz Zarraga to bootstrap and zig....* etc/teams.scm: Add Ekaitz Zarraga. Change-Id: Idda2ffbc15adc3725bcd1600988582f0d4c2766a Signed-off-by: Efraim Flashner <efraim@flashner.co.il> Ekaitz Zarraga 2023-11-12teams: Add Zig team....* etc/teams.scm (zig): New team for the zig programming language, packages and build system. Change-Id: I96f9ced1ad04b1cd9041c53aa8c86fe29014ccd1 Signed-off-by: Efraim Flashner <efraim@flashner.co.il> Ekaitz Zarraga 2023-11-01teams.scm: Add file-local variable prop line for the mode....This tells Emacs to use the scheme-mode to edit the file. * etc/teams.scm (mode): New file-local variable. Change-Id: I9a48f552e831317402673d95cf6c1de506d388b5 Maxim Cournoyer 2023-10-27teams: Add myself to audio team....Message-ID: <cfad42ecdcd190893699ef28d42b35b706729bcd.1698355699.git.gabriel@erlikon.ch> In-Reply-To: <81d0877b2cb39164563dfbf2c551f1c99aad75ed.1698355699.git.gabriel@erlikon.ch> References: <81d0877b2cb39164563dfbf2c551f1c99aad75ed.1698355699.git.gabriel@erlikon.ch> From: Gabriel Wicki <gabriel@erlikon.ch> Date: Tue, 2 May 2023 16:47:41 +0200 Subject: [PATCH 2/2] teams: Add Gabriel Wicki. * etc/teams.scm.in ("Gabriel Wicki"): New member. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> Gabriel Wicki 2023-10-27teams: Add audio team....Message-ID: <81d0877b2cb39164563dfbf2c551f1c99aad75ed.1698355699.git.gabriel@erlikon.ch> From: Gabriel Wicki <gabriel@erlikon.ch> Date: Tue, 2 May 2023 16:38:15 +0200 Subject: [PATCH 1/2] teams: Add audio team. * etc/teams.scm.in (audio): Add team. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org> Gabriel Wicki 2023-10-22teams: Adjust shebang to use 'guix repl'....This ensures the correct Guix dependencies are always available for the script. * etc/teams.scm.in: Rename to... * etc/teams.scm: ... this. Adjust shebang. * .gitignore: No longer ignore it. * configure.ac: Do not process it with AC_CONFIG_FILES. Reported-by: Clément Lassieur <clement@lassieur.org> Fixes: https://issues.guix.gnu.org/66605 Change-Id: I7a01750c6c5f0696b6c36b1e6caa9389d9e6822c Maxim Cournoyer