Bug 4198 - 2_a3: runlevel returns "unknown" in runlevel3
Summary: 2_a3: runlevel returns "unknown" in runlevel3
Status: RESOLVED WONTFIX
Alias: None
Product: Mageia
Classification: Unclassified
Component: RPM Packages (show other bugs)
Version: Cauldron
Hardware: x86_64 Linux
Priority: Normal normal
Target Milestone: ---
Assignee: Mageia Bug Squad
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 4199
Blocks: 2120
  Show dependency treegraph
 
Reported: 2012-01-20 04:53 CET by Bit Twister
Modified: 2012-04-02 10:08 CEST (History)
3 users (show)

See Also:
Source RPM: systemd-40-3.mga2.src.rpm
CVE:
Status comment:


Attachments

Description Bit Twister 2012-01-20 04:53:25 CET
Description of problem:
runlevel returns "unknown" in runlevel3 instead of N 3

Version-Release number of selected component (if applicable):


How reproducible: Always


Steps to Reproduce:
1. Clean install of Mageia-2-alpha3-x86_64-DVD.iso
2. apply updates, set system to boot at runlevel3
3. /sbin/runlevel
Comment 1 Bit Twister 2012-01-20 05:27:19 CET
This problem is caused by bug 4199.

Once systemd have completed, runlevel returns N 3 as it should in my setup.

Any scrpts using /etc/init.d/functions and depending on /sbin/runlevel results will be in for a surprise.
Manuel Hiebel 2012-01-20 12:28:23 CET

Blocks: (none) => 2120
Depends on: (none) => 4199

Comment 2 Bit Twister 2012-01-27 08:18:52 CET
Resolution, yet another clean install alpha3, apply updates, reboot.

Status: NEW => RESOLVED
Resolution: (none) => FIXED

Comment 3 Bit Twister 2012-01-31 10:36:14 CET
Reopened because runlevel does not return valid results until initrd completes.
Any service using runlevel results will be making bad decisions. 

Some background conversation can be seen in bug 4339.

Resolution: FIXED => (none)
Status: RESOLVED => REOPENED

Comment 4 D Morgan 2012-02-11 03:37:13 CET
what about this bug with systemd 40 ?

CC: (none) => dmorganec

Bit Twister 2012-02-24 07:43:53 CET

Source RPM: systemd-38-8.mga2.src.rpm => systemd-40-3.mga2.src.rpm

Comment 5 Colin Guthrie 2012-03-25 03:11:07 CEST
I'm not sure what you mean bu "until initrd completes"... systemd is started when the initrd is complete, so I'm a little confused as to what you are meaning here.

I'm interested to know at exactly which point in time you thing everything is OK?

I'd suggest it's when /lib/systemd/systemd-update-utmp is run (which updates /var/run/utmp which contains runlevel information).

Perhaps systemd needs to run this at startup as well as via systemd-update-utmp-runlevel.service and systemd-update-utmp-shutdown.service.

How many initscripts actually use runlevel just now anyway? I'd have thought that any scripts using this would be somewhat broken by design anyway. Runlevels are a mechanism to adjust what's running. It's basically a profile system, allowing you to define different runlevels for different setups. No initscript should really depend on this.

The only place I can see (in my installed system) is the initsplash() function, but I cannot see anywhere (with a quick search) that this is called.

CC: (none) => mageia

Comment 6 Bit Twister 2012-03-25 04:24:27 CEST
(In reply to comment #5)

> I'm interested to know at exactly which point in time you thing everything is
> OK?

Hmmm, As far as this bug is concerned, it's OK when runlevel returns a valid value other than unknown. A cups or named.service failure should not cause /sbin/runlevel to return unknown.

> I'd suggest it's when /lib/systemd/systemd-update-utmp is run (which updates
> /var/run/utmp which contains runlevel information).

No idea/clue, but earliest that it can be reasonably be set is better than where it is set at this time.
 
> How many initscripts actually use runlevel just now anyway?

More than one.
/bin/grep -i \$runlevel /etc/init.d/* | grep if

For starters, probably more on systems not running systemd not to mention
any user written scripts depending on it.

Have not looked at how /etc/init.d/sshd and /etc/init.d/network have loaded
their $runlevel or $RUNLEVEL variables.

> Of course that assumes I'd have thought
> that any scripts using this would be somewhat broken by design anyway.
> Runlevels are a mechanism to adjust what's running. It's basically a profile
> system, allowing you to define different runlevels for different setups. No
> initscript should really depend on this.

Maybe sshd and network are broke.

Above grep command would seem a few scripts still want to know the runlevel.
I agree I did not look to see how they set the $runlevel variable.

> The only place I can see (in my installed system) is the initsplash() function,
> but I cannot see anywhere (with a quick search) that this is called.

I can agree with your search for the bin/runlevel command on current install.

This `/sbin/runlevel bug bit me again when I retested bug 4339 using named.service.

/sbin/runlevel continued to return unknown until systemd finally decided this is as good as it gets and /sbin/runlevel finally retuned N 3.

Just a FYI.
My xroot user script uses it to decide to do a xterm -e "sudo su - root" or a
xterm -e "ssh root" depending on runlevel because of xauth problems in a gui runlevel verses a non-gui runlevel.

Any late systemd service timing out, should not impact /sbin/runlevel's results.
Comment 7 Colin Guthrie 2012-03-25 12:33:30 CEST
Yeah, I think I mostly agree here.


I'm also not sure how sshd etc. get their variables. I kinda assumed it would be a different mechanism. Perhaps it's supplied by init (tho' a quick check of the code doesn't reveal much)? Might have to try booting with sysvinit to check and see what values these variables get. It's not set from rc.sysinit as far as I can tell. To be honest, I'm not convinced it's working :D

Anyway, aside from that, as utmp contains data about the previous and current runlevel, I guess it should contain 0 as the previous runlevel and X as the current... but at what point does X = 1 and X = 3 and X = 5? Is it when all services at that runlevel are reached or is it immediately after switching levels. e.g. should a boot to a graphical.target actually say 5 pretty much from the very start of the boot process?

I'll try and get advice from upstream here.

Thanks very much for all your bugs btw. Your dedication here is invaluable :)
Comment 8 Dave Hodgins 2012-03-25 18:45:08 CEST
(In reply to comment #7)
> Anyway, aside from that, as utmp contains data about the previous and current
> runlevel, I guess it should contain 0 as the previous runlevel and X as the
> current... but at what point does X = 1 and X = 3 and X = 5? Is it when all
> services at that runlevel are reached or is it immediately after switching

When using sysvinit, /etc/inittab causes init to run /etc/rc.d/rc.sysinit,
then /etc/rc.d/rc, passing it the new run level.  The script /etc/rc.d/rc
updates the runlevel, then calls the start or kill scripts in
/etc/rc.d/rc$runlevel.d.

There's more to it then that obviously, but the point is that the runlevel
is normally set after rc.sysinit runs, but before any other init scripts
are run.

CC: (none) => davidwhodgins

Comment 9 Colin Guthrie 2012-04-01 23:47:03 CEST
OK, so I had a conversation about this with upstream.

Firstly using a $RUNLEVEL or $runlevel env var is to be considered broken. Env vars stick around may get out of date or become invalid later. Their very nature means that it's seen only as a snapshot and should not be used to make decisions etc.

The same is more or less true for calling /sbin/runlevel. There is no real valid state until the target is reached.

Basically both uses within legacy initscripts is pretty much guarenteed to be invalid and should be phased out. Fedora have already done this (which should be in our initscripts), but I guess we have a few separate initscripts still using this.

With regards to the specific scripts mentioned here:
 sshd: Masked by a native systemd unit.
 network: Only used on shutdown to run netfs which is masked under systemd so not wanted anyway.
 functions:initsplash(): Seems not to be called.

So I'd say no immediate danger/fallout from this. I'd be tempted to therefore close as wontfix and suggest that any individual initscripts needing this should have bugs opened against them to get native systemd units or have the use of $runlevel var use factored out.
Comment 10 Bit Twister 2012-04-02 00:45:00 CEST
(In reply to comment #9)
> OK, so I had a conversation about this with upstream.
> 
> Firstly using a $RUNLEVEL or $runlevel env var is to be considered broken. 

I can agree since $RUNLEVEL is invalid because /etc/rc.d/rc exports runlevel

> vars stick around may get out of date or become invalid later.

Could not agree more. /etc/rc.d/rc's export of runlevel previous were only valid during system boot.

> Their very nature means that it's seen only as a snapshot and should not be
>  used to make decisions etc.
> The same is more or less true for calling /sbin/runlevel. There is no real
> valid state until the target is reached.

Hmmm, that brings us back to the problem at hand. I say "until the target is reached" is a bit late for any init script wanting to make decisions on what level the system is booting.

> So I'd say no immediate danger/fallout from this.

I can agree with that. scripts using $RUNLEVEL should be using $runlevel if /etc/rc.d/rc is their runlevel dependency.

> I'd be tempted to therefore
> close as wontfix and suggest that any individual initscripts needing this
> should have bugs opened against them to get native systemd units or have the
> use of $runlevel var use factored out.

I have no problem with "$runlevel var use factored out" as long as /sbin/runlevel can return what runlevel was set on the boot command line by a user or what the system default runlevel is.  :)

Seems weird to me that system is booting at system default or whatever the sys admin has added to the kernel boot arguments and /sbin/runlevel is not going to get that information until systemd has timed out on all failed services.

This is a change in operation of /sbin/runlevel as I infer from /etc/rc.d/rc exporting current and previous levels.

I believe the errata document will need to warn users about /sbin/runlevel's new "feature"  :(

You may chose whatever resolution you like. I'll kludge my code to guess runlevel based on what /etc/systemd/system/default.target is linked to and open a bug against the problem I was using runlevel to work around.
Comment 11 Colin Guthrie 2012-04-02 01:17:26 CEST
(In reply to comment #10)
> > Their very nature means that it's seen only as a snapshot and should not be
> >  used to make decisions etc.
> > The same is more or less true for calling /sbin/runlevel. There is no real
> > valid state until the target is reached.
> 
> Hmmm, that brings us back to the problem at hand. I say "until the target is
> reached" is a bit late for any init script wanting to make decisions on what
> level the system is booting.

But this should be handled differently by design. e.g. if a single initscript make decisions based on $runlevel (or /sbin/runlevel), then it should be implemented instead as two systemd units that add WantedBy= Install directives that refer to different targets (e.g. one of multi-user.target and one for graphical.target), but also conflict with each other. This way the right one is used under systemd when it's isolating or switching to a given target.

> > I'd be tempted to therefore
> > close as wontfix and suggest that any individual initscripts needing this
> > should have bugs opened against them to get native systemd units or have the
> > use of $runlevel var use factored out.
> 
> I have no problem with "$runlevel var use factored out" as long as
> /sbin/runlevel can return what runlevel was set on the boot command line by a
> user or what the system default runlevel is.  :)

Well, I still reckon /sbin/runlevel use should be phased out too. I can't see any specific need for this on my current system and I'd be very surprised if any other initscript we ship genuinely needs this.

> Seems weird to me that system is booting at system default or whatever the sys
> admin has added to the kernel boot arguments and /sbin/runlevel is not going to
> get that information until systemd has timed out on all failed services.

> This is a change in operation of /sbin/runlevel as I infer from /etc/rc.d/rc
> exporting current and previous levels.

To be honest, I can see your point but I can also see the upstream point too (that the old behaviour didn't really work/make sense). I also think this is something that really doesn't matter in the long run due to runlevels being phased out and it's current, minimal usage.

That said, please do feel free to discuss it upstream on the systemd ML. I'll be sure to see the mail and can offer some degree of support albeit from my pragmatic standpoint!

> I believe the errata document will need to warn users about /sbin/runlevel's
> new "feature"  :(

Sure, I think we can put it in the release notes or whatever, but I seriously doubt any major kind of fallout from this difference.

> You may chose whatever resolution you like. I'll kludge my code to guess
> runlevel based on what /etc/systemd/system/default.target is linked to and open
> a bug against the problem I was using runlevel to work around.

Out of curiosity, what is the problem? Also as well as checking default.target you should also check kernel command line arguments (both for a single number or for systemd.target arguments)


I'll leave this open until I know the problem (I'm prepared to be proved wrong!).
Comment 12 Bit Twister 2012-04-02 02:46:41 CEST
(In reply to comment #11)

> 
> But this should be handled differently by design. e.g. if a single initscript
> make decisions based on $runlevel (or /sbin/runlevel), then it should be
> implemented instead as two systemd units that add WantedBy= Install directives
> that refer to different targets (e.g. one of multi-user.target and one for
> graphical.target), but also conflict with each other. This way the right one is
> used under systemd when it's isolating or switching to a given target.

ROFLMAO. Create scripts for each runlevel and units to keep each from stepping on each other during boot rather than one unit and script deciding based on runlevel.  Makes perfect sense to me alright. :-D


> Well, I still reckon /sbin/runlevel use should be phased out too. I can't see
> any specific need for this on my current system and I'd be very surprised if
> any other initscript we ship genuinely needs this.

AH So, users should not use tools/features not in initscripts shipped by Mageia. 8-)


> To be honest, I can see your point 

Thank you. Was beginning to wonder if I was wasting our time. 

> but I can also see the upstream point too
> (that the old behaviour didn't really work/make sense).

/sbin/runlevel did work, $RUNLEVEL vars was broke. Coder looked at
man runlevel and inferred that was the var to use without checking what /etc/rc.d/rc actually provided. 


> I also think this is something that really doesn't matter in the long run
> due to runlevels being phased out and it's current, minimal usage.

Heheh, runlevels are still there, just a lot of systemd hand waving with different implementation and nomenclature.


> That said, please do feel free to discuss it upstream on the systemd ML. I'll
> be sure to see the mail and can offer some degree of support albeit from my
> pragmatic standpoint!

No, you have made your point, indicated you see mine. I recognize systemd operation and can see how upstream is tightly focused in systemd implementation.

It will be RedHat's customers using /sbin/runlevel who will have to push this problem. I have used it for years. I'll manage.
 
> Sure, I think we can put it in the release notes or whatever, but I seriously
> doubt any major kind of fallout from this difference.

I believe you are right. Watching bugzilla users, your power users will be able to work around the problem. The rest of the users do not use the feature.
 

> Out of curiosity, what is the problem? 
Search for xterm in this bug.

> Also as well as checking default.target you should also check kernel command
> line arguments (both for a single number or for systemd.target arguments)

Or linux, single, before or after vga-xxx, .......   :-(

> I'll leave this open until I know the problem (I'm prepared to be proved
> wrong!).

In my stupid opinion, /sbin/runlevel should reflect what systemd has decided to use to boot the system.  :)

Again, You may chose whatever resolution you like.
Comment 13 Dave Hodgins 2012-04-02 03:00:18 CEST
What I use to (in a script that mounts my encrypted data
filesystem) to determine whether to use a gui or ncurses
based dialog, instead of the run level, ...

PinEntryPgm=pinentry-qt
[ -z "$DISPLAY" ] && PinEntryPgm=pinentry-curses
Comment 14 Colin Guthrie 2012-04-02 10:08:29 CEST
@Bit Twister: You may laugh at the suggestion but I was being perfectly serious.
systemd units are not initscripts with random flow. They are little bits of config. If one that we provide doesn't do what a sysadmin wants, he is perfectly free to copy it to /etc/systemd/system/ and go to town on it, hacking it to fit his needs.

In actual fact the scheme I mentioned above is exactly how the console login on tty1 is achieved in multi-user.target where as under graphical.target it's used for X11. The prefdm.service unit has a Conflicts directive for getty@tty1.service thus preventing it from running when in graphical.target.

If you wanted to use runlevels programatically in a native systemd unit otherwise, you'd have to write a wrapper script that does this inspection.

So all in all I think this is a valid suggestion still.

In fact Dave's use of it highlights the issue perfectly and why it doesn't work. He used runelevel to indicate which tool to use. If used during boot under the old scheme, it would have incorrectly determined that the current runlevel was 5 when in actual fact it had only just booted and X had not yet started. Now this may never have been a practical problem for Dave but it does highlight the temporal nature of using runlevels like this (of course the approach also has other problems, such as SSHing in remotely to the machine to do the work (you'd want a curses interface then even if the machine is running X) or the user had switched to a text console.



But to level with you completely, I feel I need to spend my time on more critical issues than this one. If you produce a patch or convince someone upstream to do so, and it is accepted upstream, I'll be happy to include it in our packages as a cherry picked patch. So essentially, if it really irks you enough, fix it and I'll help as best I can, but I won't be able to do the work myself! The code is actually quite simple (having looked at it recently) so it should just be a matter of providing a new argument to systemd-update-wtmp (e.g. a "booting" argument) and do some kind of interpretation of the dbus return info from querying default.target to find out which runelevel you're aiming at! I hope you think this is a fair response! Sorry!

Resolution: (none) => WONTFIX
Status: REOPENED => RESOLVED


Note You need to log in before you can comment on or make changes to this bug.