]> git.ipfire.org Git - thirdparty/dracut.git/blame - HACKING.md
fix: shellcheck for dracut.sh
[thirdparty/dracut.git] / HACKING.md
CommitLineData
1ed4b9f1
HH
1# Dracut Developer Guidelines
2
3## git
4
5Currently dracut lives on github.com and kernel.org.
6
7* https://github.com/dracutdevs/dracut.git
8* https://git.kernel.org/pub/scm/boot/dracut/dracut.git
9
10Pull requests should be filed preferably on github nowadays.
11
12### Commit Messages
13
14Commit messages should answer these questions:
15
16* What?: a short summary of what you changed in the subject line.
17* Why?: what the intended outcome of the change is (arguably the most important piece of information that should go into a message).
18* How?: if multiple approaches for achieving your goal were available, you also want to explain why you chose the used implementation strategy.
19 Note that you should not explain how your change achieves your goal in your commit message.
20 That should be obvious from the code itself.
21 If you cannot achieve that clarity with the used programming language, use comments within the code instead.
22
23The commit message is primarily the place for documenting the why.
24
25Commit message titles should follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
26
27Format is `<type>[optional scope]: <description>`, where `type` is one of:
28
29* fix: A bug fix
30* feat: A new feature
31* perf: A code change that improves performance
32* refactor: A code change that neither fixes a bug nor adds a feature
33* style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
34* test: Adding missing tests or correcting existing tests
35* docs: Documentation only changes
36* revert: Reverts a previous commit
37* chore: Other changes that don't modify src or test files
38* build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
39* ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
40
41`scope` should be the module name (without numbers) or:
42
43* cli: for the dracut command line interface
44* rt: for the dracut initramfs runtime logic
45* functions: for general purpose dracut functions
46
47Commit messages are checked with [Commisery](https://github.com/tomtom-international/commisery).
48
49## Writing modules
50
51Some general rules for writing modules:
52
53* Use one of the inst family of functions to actually install files
54 on to the initramfs. They handle mangling the pathnames and (for binaries,
55 scripts, and kernel modules) installing dependencies as appropriate so
56 you do not have to.
57* Scripts that end up on the initramfs should be POSIX compliant. dracut
58 will try to use /bin/dash as /bin/sh for the initramfs if it is available,
59 so you should install it on your system -- dash aims for strict POSIX
60 compliance to the extent possible.
61* Hooks MUST be POSIX compliant -- they are sourced by the init script,
62 and having a bashism break your user's ability to boot really sucks.
63* Generator modules should have a two digit numeric prefix -- they run in
64 ascending sort order. Anything in the 90-99 range is stuff that dracut
65 relies on, so try not to break those hooks.
66* Hooks must have a .sh extension.
67* Generator modules are described in more detail later on.
68* We have some breakpoints for debugging your hooks. If you pass 'rdbreak'
69 as a kernel parameter, the initramfs will drop to a shell just before
70 switching to a new root. You can pass 'rdbreak=hookpoint', and the initramfs
71 will break just before hooks in that hookpoint run.
72
73Also, there is an attempt to keep things as distribution-agnostic as
74possible. Every distribution has their own tool here and it's not
75something which is really interesting to have separate across them.
76So contributions to help decrease the distro-dependencies are welcome.
77
78Most of the functionality that dracut implements are actually implemented
79by dracut modules. dracut modules live in modules.d, and have the following
80structure:
81
82```
83dracut_install_dir/modules.d/
84 00modname/
85 module-setup.sh
86 check
87 <other files as needed by the hook>
88```
89
90`00modname`: The name of the module prefixed by a two-digit numeric sort code.
91 The numeric code must be present and in the range of 00 - 99.
92 Modules with lower numbers are installed first. This is important
93 because the dracut install functions (which install files onto
94 the initrd) refuse to overwrite already installed files. This makes
95 it easy for an earlier module to override the functionality of a
96 later module, so that you can have a distro or system specific
97 module override or modify the functionality of a generic module
98 without having to patch the more generic module.
99
100`module-setup.sh`:
101 dracut sources this script to install the functionality that a
102 module implements onto the initrd. For the most part, this amounts
103 to copying files from the host system onto the initrd in a controlled
104 manner.
105
106`install()`:
107 This function of module-setup.sh is called to install all
108 non-kernel files. dracut supplies several install functions that are
109 specialized for different file types. Browse through dracut-functions
110 fore more details. dracut also provides a $moddir variable if you
111 need to install a file from the module directory, such as an initrd
112 hook, a udev rule, or a specialized executable.
113
114`installkernel()`:
115 This function of module-setup.sh is called to install all
116 kernel related files.
117
118
119`check()`:
120 dracut calls this function to check and see if a module can be installed
121 on the initrd.
122
123 When called without options, check should check to make sure that
124 any files it needs to install into the initrd from the host system
125 are present. It should exit with a 0 if they are, and a 1 if they are
126 not.
127
128 When called with $hostonly set, it should perform the same check
129 that it would without it set, and it should also check to see if the
130 functionality the module implements is being used on the host system.
131 For example, if this module handles installing support for LUKS
132 encrypted volumes, it should return 0 if all the tools to handle
133 encrpted volumes are available and the host system has the root
134 partition on an encrypted volume, 1 otherwise.
135
136`depends()`:
137 This function should output a list of dracut modules
138 that it relies upon. An example would be the nfs and iscsi modules,
139 which rely on the network module to detect and configure network
140 interfaces.
141
142Any other files in the module will not be touched by dracut directly.
143
144You are encouraged to provide a README that describes what the module is for.
145
146
147### Hooks
148
149init has the following hook points to inject scripts:
150
151`/lib/dracut/hooks/cmdline/*.sh`
152 scripts for command line parsing
153
154`/lib/dracut/hooks/pre-udev/*.sh`
155 scripts to run before udev is started
156
157`/lib/dracut/hooks/pre-trigger/*.sh`
158 scripts to run before the main udev trigger is pulled
159
160`/lib/dracut/hooks/initqueue/*.sh`
161 runs in parallel to the udev trigger
162 Udev events can add scripts here with /sbin/initqueue.
163 If /sbin/initqueue is called with the "--onetime" option, the script
164 will be removed after it was run.
165 If /lib/dracut/hooks/initqueue/work is created and udev >= 143 then
166 this loop can process the jobs in parallel to the udevtrigger.
167 If the udev queue is empty and no root device is found or no root
168 filesystem was mounted, the user will be dropped to a shell after
169 a timeout.
170 Scripts can remove themselves from the initqueue by "rm $job".
171
172`/lib/dracut/hooks/pre-mount/*.sh`
173 scripts to run before the root filesystem is mounted
174 Network filesystems like NFS that do not use device files are an
175 exception. Root can be mounted already at this point.
176
177`/lib/dracut/hooks/mount/*.sh`
178 scripts to mount the root filesystem
179 If the udev queue is empty and no root device is found or no root
180 filesystem was mounted, the user will be dropped to a shell after
181 a timeout.
182
183`/lib/dracut/hooks/pre-pivot/*.sh`
184 scripts to run before latter initramfs cleanups
185
186`/lib/dracut/hooks/cleanup/*.sh`
187 scripts to run before the real init is executed and the initramfs
188 disappears
189 All processes started before should be killed here.
190
191
192## Testsuite
193
194For the testsuite to work, you will have to install at least the following software packages:
195```
196dash \
197asciidoc \
198mdadm \
199lvm2 \
200dmraid \
201cryptsetup \
202nfs-utils \
203nbd \
204dhcp-server \
205scsi-target-utils \
206iscsi-initiator-utils \
207strace \
208syslinux \
209python-imgcreate \
210genisoimage \
211btrfs-progs \
212kmod-devel \
213gcc \
214bzip2 \
215xz \
216tar \
217wget \
218rpm-build \
219${NULL}
220```
221
222How to run the testsuite:
223
224```
225$ sudo make clean check
226```
227
228in verbose mode:
229```
230$ sudo make V=1 clean check
231```
232
233only specific test:
234```
235$ sudo make TESTS="01 20 40" clean check
236```
237only runs the 01, 20 and 40 tests.
238
239debug a specific test case:
240```
241$ cd TEST-01-BASIC
242$ sudo make clean setup run
243```
244... change some kernel parameters ...
245```
246$ sudo make run
247```
248to run the test without doing the setup