1 # Dracut Developer Guidelines
3 Please make sure to follow our [Contribution Guidelines](CONTRIBUTING.md).
7 Currently dracut lives on github.com.
9 * https://github.com/dracutdevs/dracut.git
11 Pull requests should be filed preferably on github nowadays.
15 It is recommended, that you install a plugin for your editor, which reads in `.editorconfig`.
16 Additionally `emacs` and `vim` config files are provided for convenience.
18 To reformat C files use `astyle`:
20 $ astyle --options=.astylerc <FILE>
23 For convenience there is also a Makefile `indent-c` target `make indent-c`.
25 To reformat shell files use `shfmt`:
29 $ wget "https://github.com/mvdan/sh/releases/download/v${shfmt_version}/shfmt_v${shfmt_version}_linux_amd64" -O shfmt
37 $ GO111MODULE=on go get mvdan.cc/sh/v3/cmd/shfmt
38 $ $GOPATH/bin/shfmt -w -s .
41 or if `shfmt` is already in your `PATH`, use `make indent`.
43 Some IDEs already have support for shfmt.
45 For convenience the `make indent` Makefile target also calls shfmt, if it is in `$PATH`.
49 Commit messages should answer these questions:
51 * What?: a short summary of what you changed in the subject line.
52 * Why?: what the intended outcome of the change is (arguably the most important piece of information that should go into a message).
53 * How?: if multiple approaches for achieving your goal were available, you also want to explain why you chose the used implementation strategy.
54 Note that you should not explain how your change achieves your goal in your commit message.
55 That should be obvious from the code itself.
56 If you cannot achieve that clarity with the used programming language, use comments within the code instead.
58 The commit message is primarily the place for documenting the why.
60 Commit message titles should follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
62 Format is `<type>[optional scope]: <description>`, where `type` is one of:
66 * perf: A code change that improves performance
67 * refactor: A code change that neither fixes a bug nor adds a feature
68 * style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
69 * test: Adding missing tests or correcting existing tests
70 * docs: Documentation only changes
71 * revert: Reverts a previous commit
72 * chore: Other changes that don't modify src or test files
73 * build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
74 * ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
76 `scope` should be the module name (without numbers) or:
78 * cli: for the dracut command line interface
79 * rt: for the dracut initramfs runtime logic
80 * functions: for general purpose dracut functions
82 Commit messages are checked with [Commisery](https://github.com/tomtom-international/commisery).
86 Some general rules for writing modules:
88 * Use one of the inst family of functions to actually install files
89 on to the initramfs. They handle mangling the pathnames and (for binaries,
90 scripts, and kernel modules) installing dependencies as appropriate so
92 * Scripts that end up on the initramfs should be POSIX compliant. dracut
93 will try to use /bin/dash as /bin/sh for the initramfs if it is available,
94 so you should install it on your system -- dash aims for strict POSIX
95 compliance to the extent possible.
96 * Hooks MUST be POSIX compliant -- they are sourced by the init script,
97 and having a bashism break your user's ability to boot really sucks.
98 * Generator modules should have a two digit numeric prefix -- they run in
99 ascending sort order. Anything in the 90-99 range is stuff that dracut
100 relies on, so try not to break those hooks.
101 * Hooks must have a .sh extension.
102 * Generator modules are described in more detail later on.
103 * We have some breakpoints for debugging your hooks. If you pass 'rdbreak'
104 as a kernel parameter, the initramfs will drop to a shell just before
105 switching to a new root. You can pass 'rdbreak=hookpoint', and the initramfs
106 will break just before hooks in that hookpoint run.
108 Also, there is an attempt to keep things as distribution-agnostic as
109 possible. Every distribution has their own tool here and it's not
110 something which is really interesting to have separate across them.
111 So contributions to help decrease the distro-dependencies are welcome.
113 Most of the functionality that dracut implements are actually implemented
114 by dracut modules. dracut modules live in modules.d, and have the following
118 dracut_install_dir/modules.d/
122 <other files as needed by the hook>
125 `00modname`: The name of the module prefixed by a two-digit numeric sort code.
126 The numeric code must be present and in the range of 00 - 99.
127 Modules with lower numbers are installed first. This is important
128 because the dracut install functions (which install files onto
129 the initrd) refuse to overwrite already installed files. This makes
130 it easy for an earlier module to override the functionality of a
131 later module, so that you can have a distro or system specific
132 module override or modify the functionality of a generic module
133 without having to patch the more generic module.
136 dracut sources this script to install the functionality that a
137 module implements onto the initrd. For the most part, this amounts
138 to copying files from the host system onto the initrd in a controlled
142 This function of module-setup.sh is called to install all
143 non-kernel files. dracut supplies several install functions that are
144 specialized for different file types. Browse through dracut-functions
145 fore more details. dracut also provides a $moddir variable if you
146 need to install a file from the module directory, such as an initrd
147 hook, a udev rule, or a specialized executable.
150 This function of module-setup.sh is called to install all
151 kernel related files.
155 dracut calls this function to check and see if a module can be installed
158 When called without options, check should check to make sure that
159 any files it needs to install into the initrd from the host system
160 are present. It should exit with a 0 if they are, and a 1 if they are
163 When called with $hostonly set, it should perform the same check
164 that it would without it set, and it should also check to see if the
165 functionality the module implements is being used on the host system.
166 For example, if this module handles installing support for LUKS
167 encrypted volumes, it should return 0 if all the tools to handle
168 encrpted volumes are available and the host system has the root
169 partition on an encrypted volume, 1 otherwise.
172 This function should output a list of dracut modules
173 that it relies upon. An example would be the nfs and iscsi modules,
174 which rely on the network module to detect and configure network
177 Any other files in the module will not be touched by dracut directly.
179 You are encouraged to provide a README that describes what the module is for.
184 init has the following hook points to inject scripts:
186 `/lib/dracut/hooks/cmdline/*.sh`
187 scripts for command line parsing
189 `/lib/dracut/hooks/pre-udev/*.sh`
190 scripts to run before udev is started
192 `/lib/dracut/hooks/pre-trigger/*.sh`
193 scripts to run before the main udev trigger is pulled
195 `/lib/dracut/hooks/initqueue/*.sh`
196 runs in parallel to the udev trigger
197 Udev events can add scripts here with /sbin/initqueue.
198 If /sbin/initqueue is called with the "--onetime" option, the script
199 will be removed after it was run.
200 If /lib/dracut/hooks/initqueue/work is created and udev >= 143 then
201 this loop can process the jobs in parallel to the udevtrigger.
202 If the udev queue is empty and no root device is found or no root
203 filesystem was mounted, the user will be dropped to a shell after
205 Scripts can remove themselves from the initqueue by "rm $job".
207 `/lib/dracut/hooks/pre-mount/*.sh`
208 scripts to run before the root filesystem is mounted
209 Network filesystems like NFS that do not use device files are an
210 exception. Root can be mounted already at this point.
212 `/lib/dracut/hooks/mount/*.sh`
213 scripts to mount the root filesystem
214 If the udev queue is empty and no root device is found or no root
215 filesystem was mounted, the user will be dropped to a shell after
218 `/lib/dracut/hooks/pre-pivot/*.sh`
219 scripts to run before latter initramfs cleanups
221 `/lib/dracut/hooks/cleanup/*.sh`
222 scripts to run before the real init is executed and the initramfs
224 All processes started before should be killed here.
229 ### Rootless in a container with podman
233 $ podman pull [CONTAINER]
234 $ podman run --rm -it \
235 --cap-add=SYS_PTRACE --user 0 \
236 -v /dev:/dev -v ./:/dracut:z \
241 # make -j $(getconf _NPROCESSORS_ONLN)
243 # make V=1 SKIP="16 60 61" clean check
246 with `[CONTAINER]` being one of the
247 [github `dracutdevs` containers](https://github.com/orgs/dracutdevs/packages),
248 e.g. `ghcr.io/dracutdevs/fedora:latest`.
252 For the testsuite to pass, you will have to install at least the software packages
253 mentioned in the `test/container` Dockerfiles.
256 $ sudo make clean check
261 $ sudo make V=1 clean check
266 $ sudo make TESTS="01 20 40" clean check
268 only runs the 01, 20 and 40 tests.
270 debug a specific test case:
273 $ sudo make clean setup run
275 ... change some kernel parameters in `test.sh` ...
279 to run the test without doing the setup.