Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dracut-shutdown.service lacks DRACUT_SYSTEMD=1 environment variable #1862

Open
adrelanos opened this issue Jul 2, 2022 · 15 comments
Open

dracut-shutdown.service lacks DRACUT_SYSTEMD=1 environment variable #1862

adrelanos opened this issue Jul 2, 2022 · 15 comments
Labels
bug Our bugs shutdown Issues related to the shutdown module

Comments

@adrelanos
Copy link

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.

@aafeijoo-suse
Copy link
Member

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.

@adrelanos
Copy link
Author

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?

@aafeijoo-suse
Copy link
Member

Indeed.

However, the bug remains. During shutdown.sh (dracut shutdown module and any shutdown hook) the DRACUT_SYSTEMD=1 environment 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=1 environment 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...

@aafeijoo-suse
Copy link
Member

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

@pvalena
Copy link
Contributor

pvalena commented Jul 26, 2022

@dtardon WDYT?

@dtardon
Copy link
Contributor

dtardon commented Jul 27, 2022

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?

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...

@aafeijoo-suse
Copy link
Member

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?

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...

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.

@dtardon
Copy link
Contributor

dtardon commented Jul 27, 2022

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?

@dtardon
Copy link
Contributor

dtardon commented Jul 27, 2022

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?

@adrelanos
Copy link
Author

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=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?

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

@dtardon
Copy link
Contributor

dtardon commented Jul 27, 2022

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?

@adrelanos
Copy link
Author

No output visible in console during shutdown. Because they don't write to kmsg.

@dtardon
Copy link
Contributor

dtardon commented Jul 28, 2022

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...

@adrelanos
Copy link
Author

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" ]; then part of the if condition because DRACUT_SYSTEMD is set as expected. check_quiet runs and might conditionally export DRACUT_QUIET.
  • During exitrd: Since DRACUT_SYSTEMD is unset, the user gets the else part of the condition. check_quiet won't be executed.

stdout vs stderr:

  • If DRACUT_SYSTEMD is unset: info will run echo "dracut: $*" >&2 || : (stderr)
  • If DRACUT_SYSTEMD is set: info will run echo "$*" (stdout)

That is inconsistent. But it's not about a formality but difference in console / serial console output that I experienced.

  • At boot: info is written unconditional. There are no missing info level messages in console or serial console.
  • During exitrd: info messages are missing in serial console output because now it's conditional of DRACUT_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.

@adrelanos
Copy link
Author

During shutdown.sh and its modules...


dracut now (while using quiet kernel parameter) (but without rd.info kernel parameter):

  • Is environment variable DRACUT_SYSTEMD=1 available from shutdown.sh and its modules? No.
  • info() shown in tty console: no
  • warn() shown in tty console: yes
  • info() shown in serial console: no
  • warn() shown in serial console: yes
  • echo "some-message" > /dev/kmsg shown in tty console: yes
  • echo "some-message" > /dev/kmsg shown in serial console: yes

@aafeijoo-suse #1862 (comment)

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=1 available from shutdown.sh and its modules? Yes.
  • info() shown in tty console: no
  • warn() shown in tty console: no
  • info() shown in serial console: yes
  • warn() shown in serial console: yes
  • echo "some-message" > /dev/kmsg shown in tty console: yes
  • echo "some-message" > /dev/kmsg shown 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() and warn() is shown in tty console and in serial console
  • with quiet: only warn() is shown in tty console and in serial console
  • with quiet and rd.info: info() and warn() 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 the quiet kernel parameter or add rd.info as 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 use echo "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.

@LaszloGombos LaszloGombos added the shutdown Issues related to the shutdown module label Mar 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Our bugs shutdown Issues related to the shutdown module
Projects
None yet
5 participants