dracut
dracut copied to clipboard
dracut-shutdown.service lacks DRACUT_SYSTEMD=1 environment variable
Describe the bug
dracut-shutdown.service lacks DRACUT_SYSTEMD=1 environment variable
Distribution used
Debian but easily seen in dracut upstream source code: https://github.com/dracutdevs/dracut/blob/master/modules.d/98dracut-systemd/dracut-shutdown.service#L11
Dracut version latest git
Init system systemd
To Reproduce Write a shutdown hook and check for DRACUT_SYSTEMD variable existence.
Expected behavior DRACUT_SYSTEMD=1 environment variable should be set during
Additional context
dracut-lib.sh looks at the DRACUT_SYSTEMD environment variable. For example, the info and warn functions of dracut-lib.sh require a properly set DRACUT_SYSTEMD.
All other dracut systemd units in https://github.com/dracutdevs/dracut/blob/master/modules.d/98dracut-systemd/ are setting the DRACUT_SYSTEMD environment variable too.
This is wrong, dracut-initramfs-restore does not need the DRACUT_SYSTEMD env var, it does not run within the initramfs, but after switching to root, so no calls to any function defined in dracut-lib.sh.
Indeed.
However, the bug remains. During shutdown.sh (dracut shutdown module and any shutdown hook) the DRACUT_SYSTEMD=1 environment variable is missing.
Seems like this is actually a systemd bug? systemd's system-shutdown
https://github.com/systemd/systemd/blob/main/src/shutdown/shutdown.c
should set the DRACUT_SYSTEMD=1 environment variable because that runs /run/initramfs/shutdown?
Indeed.
However, the bug remains. During
shutdown.sh(dracutshutdownmodule and anyshutdownhook) theDRACUT_SYSTEMD=1environment variable is missing.
Right, now I see the problem.
Seems like this is actually a systemd bug? systemd's system-shutdown
https://github.com/systemd/systemd/blob/main/src/shutdown/shutdown.c
should set the
DRACUT_SYSTEMD=1environment variable because that runs/run/initramfs/shutdown?
This is not a systemd bug, systemd is not going to export any environment variable unrelated to systemd...
You can try this patch and give some feedback. If it works, update your PR with it.
diff --git a/modules.d/99shutdown/shutdown.sh b/modules.d/99shutdown/shutdown.sh
index 73550ba9..6b1e526b 100755
--- a/modules.d/99shutdown/shutdown.sh
+++ b/modules.d/99shutdown/shutdown.sh
@@ -17,6 +17,9 @@ ACTION="$1"
export TERM=linux
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
+if [ -e /oldroot/etc/machine-id ]; then
+ export DRACUT_SYSTEMD=1
+fi
. /lib/dracut-lib.sh
if [ "$(stat -c '%T' -f /)" = "tmpfs" ]; then
@dtardon WDYT?
Seems like this is actually a systemd bug? systemd's system-shutdown https://github.com/systemd/systemd/blob/main/src/shutdown/shutdown.c should set the
DRACUT_SYSTEMD=1environment variable because that runs/run/initramfs/shutdown?This is not a systemd bug, systemd is not going to export any environment variable unrelated to systemd...
Why do you think so? This whole /run/initramfs/shutdown already is unrelated to systemd, yet they do it...
Seems like this is actually a systemd bug? systemd's system-shutdown https://github.com/systemd/systemd/blob/main/src/shutdown/shutdown.c should set the
DRACUT_SYSTEMD=1environment variable because that runs/run/initramfs/shutdown?This is not a systemd bug, systemd is not going to export any environment variable unrelated to systemd...
Why do you think so? This whole
/run/initramfs/shutdownalready is unrelated to systemd, yet they do it...
Yes, 8-year old code added by Harald, good old days. So, do you really think that nowadays systemd is willing to add to its code an export of a dracut-specific-only variable? then other initrd generators will start asking for their specific needs also.
Yes, 8-year old code added by Harald, good old days. So, do you really think that nowadays systemd is willing to add to its code an export of a dracut-specific-only variable?
Why don't you ask them instead of guessing?
That aside, the main point is if it even makes any sense to export DRACUT_SYSTEMD in exitrd. At boot, it signifies that initrd is is started with systemd (instead of the traditional init.sh script), which means daemons should be started using units, logs should go to journal, etc. But this does not hold for exitd. systemd is not running anymore. systemd-journald is not running anymore (which AFAIK means error messages would be lost, because nothing reads /dev/kmsg). IOW, DRACUT_SYSTEMD=1 would only tell us is that the system was running systemd. But I can't see any meaningful use of that knowledge, so what's the point?
Thank you for your consideration!
@aafeijoo-suse
Yes, 8-year old code added by Harald, good old days. So, do you really think that nowadays systemd is willing to add to its code an export of a dracut-specific-only variable?
I wouldn't worry just yet. My interpretation is that systemd is quite fond of dracut, because quote https://systemd.io/INITRD_INTERFACE/
Oh, and one last question before closing: instead of implementing these features in your own distro’s initrd, may I suggest just using Dracut instead? It’s all already implemented there!
@aafeijoo-suse
then other initrd generators will start asking for their specific needs also.
Then systemd could accommodate the request in a generic way. They already have a generic term for this as in above link "initrd Interface of systemd". Instead of DRACUT_SYSTEMD, systemd might set a variable such SYSTEMD_EXITRD or so.
IOW,
DRACUT_SYSTEMD=1would only tell us is that the system was running systemd. But I can't see any meaningful use of that knowledge, so what's the point?
dracut-lib.sh looks at the DRACUT_SYSTEMD environment variable. For example, the info and warn functions of dracut-lib.sh require a properly set DRACUT_SYSTEMD. Otherwise, the info and warn function do not work as expected, as they usually do.
https://github.com/zfsonlinux/dracut/blob/master/modules.d/99base/dracut-lib.sh
if [ -z "$DRACUT_SYSTEMD" ]; then
warn() {
check_quiet
echo "<28>dracut Warning: $*" > /dev/kmsg
echo "dracut Warning: $*" >&2
}
info() {
check_quiet
echo "<30>dracut: $*" > /dev/kmsg
[ "$DRACUT_QUIET" != "yes" ] && \
echo "dracut: $*"
}
else
warn() {
echo "Warning: $*" >&2
}
info() {
echo "$*"
}
fi
dracut-lib.sh looks at the DRACUT_SYSTEMD environment variable. For example, the info and warn functions of dracut-lib.sh require a properly set DRACUT_SYSTEMD. Otherwise, the info and warn function do not work as expected, as they usually do.
Why wouldn't they work? What's the exact problem there?
No output visible in console during shutdown. Because they don't write to kmsg.
No output visible in console during shutdown. Because they don't write to kmsg.
They do, if DRACUT_SYSTEMD is unset. You pasted the code here yourself...
Indeed. I was wrong. It's no about kmsg. It's about stdout vs stderr.
For a systemd enabled system...
- At boot: User gets the
if [ -z "$DRACUT_SYSTEMD" ]; thenpart of the if condition becauseDRACUT_SYSTEMDis set as expected.check_quietruns and might conditionallyexport DRACUT_QUIET. - During exitrd: Since
DRACUT_SYSTEMDis unset, the user gets theelsepart of the condition.check_quietwon't be executed.
stdout vs stderr:
- If
DRACUT_SYSTEMDis unset:infowill runecho "dracut: $*" >&2 || :(stderr) - If
DRACUT_SYSTEMDis set:infowill runecho "$*"(stdout)
That is inconsistent. But it's not about a formality but difference in console / serial console output that I experienced.
- At boot:
infois written unconditional. There are no missinginfolevel messages in console or serial console. - During exitrd:
infomessages are missing in serial console output because now it's conditional ofDRACUT_QUIET.
In other words, shorter...
Since info and warn do different things depending on environment variable DRACUT_SYSTEMD being unset versus set. This results in different info / warn behavior during boot versus exitrd. Therefore for consistency, DRACUT_SYSTEMD should always be set on systemd enabled systems in both, during initrd and exitrd.
Or more generically worded: info / warn should have the same behavior during inird as well as during exitrd.
During shutdown.sh and its modules...
dracut now (while using quiet kernel parameter) (but without rd.info kernel parameter):
- Is environment variable
DRACUT_SYSTEMD=1available fromshutdown.shand its modules? No. info()shown in tty console: nowarn()shown in tty console: yesinfo()shown in serial console: nowarn()shown in serial console: yesecho "some-message" > /dev/kmsgshown in tty console: yesecho "some-message" > /dev/kmsgshown in serial console: yes
@aafeijoo-suse https://github.com/dracutdevs/dracut/issues/1862#issuecomment-1185613687
You can try this patch and give some feedback. If it works, update your PR with it.
Thank you for your patch suggestion! Tested it...
dracut with patch suggestion (quiet) (without rd.info):
- Is environment variable
DRACUT_SYSTEMD=1available fromshutdown.shand its modules? Yes. info()shown in tty console: nowarn()shown in tty console: noinfo()shown in serial console: yeswarn()shown in serial console: yesecho "some-message" > /dev/kmsgshown in tty console: yesecho "some-message" > /dev/kmsgshown in serial console: yes
I am not sure why that is but seems actually setting environment variable DRACUT_SYSTEMD=1 does not improve tty console output.
- without
quiet:info()andwarn()is shown in tty console and in serial console - with
quiet: onlywarn()is shown in tty console and in serial console - with
quietandrd.info:info()andwarn()is shown in tty console and in serial console
Seems to work all as intended according to dracut manpage on rd.info.
In conclusion, probably user error.
- If I want
info()to be shown in tty console, I have to either remove thequietkernel parameter or addrd.infoas kernel parameter. - If I want to force writing to tty console and serial console, dracut has no
force_info(), if I need that during development/debugging, I can useecho "some-message" > /dev/kmsg. - I should have experimented with something easier first. Dracut module output using
info()during initrd, not exitrd which might be quite harder.
One could argue that the DRACUT_SYSTEMD=1 set vs unset is still an inconsistency but that would just have a formality impact for now. Perhaps not a perfectly clean, perfectly understood implementation, might break something depending on that environment variable in the future, but not an actual functionality impact. Not sure about that.
So unless someone (still) believes there might be an issue here, the pull request and this issue can be closed.