Debugging modprobe in dracut

| categories: fedora

Related to bisection, I've been working on some custom packaging of the kernel. This has basically involved hacking away at the existing kernel.spec file until I get something that's usable and does what I want. My latest attempt finally resulted in an rpm that installs without errors. Exciting! When I went to test boot though I dropped into the dracut shell. journalctl showed me the error:

device-mapper: table: 253:0: crypt: unknown target type

Googling told me that this meant the dm-crypt kernel module was not found. Yet in the dracut shell I could see the module where I expected it to be. I tried running modprobe manually:

dracut:/# modprobe dm-crypt
dracut:/# echo $?
dracut:/# modprobe -v dm-crypt
dracut:/# modprobe -v sdfsdfsdfsdfds

Typically, I would expect modprobe to give some kind of message like modprobe: FATAL: Module sdfsdfsd not found. so the fact that it was giving me nothing was baffling. Nothing in journalctl either. strace is a useful tool for these types of problems except it isn't included by default in dracut. This was fixed with an update of the initrd outside of dracut:

# cp /boot/initramfs-<kversion>.img /boot/initramfs-backup.img <kversion>
# dracut --force --install 'strace' /boot/initramfs-<kversion>.img

Now the usual strace -o out modprobe dm-crypt gave me the answer I was looking for: As part of my hacking I changed the name of the folder where the modules are stored. By default, modprobe looks for the modules in /lib/modules/uname -r . Apparently if it can't find any of the usual modules.* files at that location it just dies silently with no output whatsoever. How useful. But if I pass the correct -S flag to modprobe I get the expected output about modules not loading. Arguably, this behavior is all described in the man page for modprobe but I still needed a more obvious hint to figure it out.

For more fun about why this went wrong, unknown target type is the error message from dm_get_target_type in dm_table_add_target. dm_get_target_type checks if the module is availble, if not it calls load_module -> request_module -> __request_module -> call_modprobe which does about what you think it does. This means that anything which relies on passing -S isn't going to work out of the box for dm-crypt or any other kernel subsystem which calls request_module

Back to some brainstorming for me.