Please read this before reporting a bug:
https://wiki.archlinux.org/title/Bug_reporting_guidelines
Do NOT report bugs when a package is just outdated, or it is in the AUR. Use the 'flag out of date' link on the package page, or the Mailing List.
REPEAT: Do NOT report bugs for outdated packages!
https://wiki.archlinux.org/title/Bug_reporting_guidelines
Do NOT report bugs when a package is just outdated, or it is in the AUR. Use the 'flag out of date' link on the package page, or the Mailing List.
REPEAT: Do NOT report bugs for outdated packages!
FS#34757 - [ypbind-mt] systemd starts autofs before ypbind has bound to a server.
Attached to Project:
Arch Linux
Opened by Brian BIdulock (bidulock) - Friday, 12 April 2013, 23:32 GMT
Last edited by Dave Reisner (falconindy) - Friday, 08 August 2014, 13:32 GMT
Opened by Brian BIdulock (bidulock) - Friday, 12 April 2013, 23:32 GMT
Last edited by Dave Reisner (falconindy) - Friday, 08 August 2014, 13:32 GMT
|
DetailsDescription:
Although the 1.37 calls sd_notify() it does so in the main thread just before it exits. When the parent exists, systemd figures that ypbind has finished starting and goes about starting autofs (which depends on ypbind). The problem is that systemd is so freaking fast that autofs performs nss-switch table lookups before ypbind has bound to a server and autofs fails to load nis maps and proceeds assuming there are none. When autofs is mounting home directories from nis maps, it fails to start them and must be manually restarted. This is probably an upstream problem, but it causes problems. I placed a startup script called ypwait and executed it as an ExecPre in autofs.service. The script simply peforms ypwhich until it gets a result (and sleeps for a whole darn second otherwise) to stall autofs startup until ypbind has finished binding to an NIS server. Ultimately, ypbind-mt should not call sd_notify() until it has successfully bound to an NIS server and the ypbind.service should have Notify=always. I would work up a patch, but ypbind-mt is the worst ratsnest I have seen in a while. Any advice you could give? Additional info: * package version(s) 1.37 (all really) Steps to reproduce: |
This task depends upon
Closed by Dave Reisner (falconindy)
Friday, 08 August 2014, 13:32 GMT
Reason for closing: Fixed
Additional comments about closing: Current ypbind-mt 1.37.1-5 works quite fine.
Friday, 08 August 2014, 13:32 GMT
Reason for closing: Fixed
Additional comments about closing: Current ypbind-mt 1.37.1-5 works quite fine.
Well, let me test it thouroughly first. Back in a moment...
Please just fix sd_notify support in ypbind and offer it upstream. It's trivial to do.
If you prefer:
ExecStartPost=/bin/sh -c "while ! /usr/bin/ypwhich; do sleep 1; done"
"If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well."
That it does work is, frankly, a bug in bash.
$ dash -c 'for ((i=0; i<5; i++)); do echo $i; done'
dash: 1: Syntax error: Bad for loop variable
You would be better off invoking bash if you're going to use bash syntax. Better yet, just fix the problem at the source rather than hacking around it.
sd_notify(3): READY=1 tells the init system that daemon startup is finished. This is only used by systemd if the service definition has Type=notify set.
systemd.service(5): Behavior of notify is similar to simple, however, it is expected that the daemon sends a notification message via sd_notify(3) or an equivalent call when it finished starting up. (Note this is non-forking.)
ypbind(8): -debug: starts ypbind in debug mode. ypbind will not put itself into the background, and error messages and debug output are written to standard error.
So, unless you want your logs/journal filled with ypbind debugging messages, it is necessary to set Type=forking.
systemd.service(5): If set to forking it is expected that the process configured with ExecStart= will call fork() as part of its start-up. The parent process is expected to exit when start-up is complete and all communication channels set up.
That is what ypbind does, forks() and main exits once the communications channels have started up. It also calls sd_notify(3) so that you can run it with Type=notify in debug mode under systemd.
So it seems upstream ypbind is behaving quite properly.
So unless we at least put ExecStartPost=/usr/bin/sleep 5, logins and autofs mounts will proceed and fail routinely on boot.
log_action_begin_msg "binding to YP server"
for i in 1 2 3 4 5 6 7 8 9 10
do
sleep 1
log_action_cont_msg "."
if [ "`ypwhich 2>/dev/null`" != "" ]
then
echo -n " done] "
bound="yes"
break
fi
done
ExecStartPost= is precisely the replacement for this kind of thing. They obviously don't know about the return code.
ExecStartPost=/bin/sh -c "for i in 1 2 3 4 5; do ! ypwhich >/dev/null || break; sleep 1; done"
Is that better?
I'm reading this as:
1) In forking mode: ypbind-mt isn't actually ready to do work when main exits in forking mode. If it was actually ready, the sleep loop wouldn't be required.
2) In notify mode: upstream forces you to run in debug mode, but this works "properly" and doesn't need the sleep loop hack. Forcing debug logging on the user for a more preferable mode of operation under systemd seems like broken behavior.
How is this not an upstream problem?
> Is that better?
Syntactically, sure. 'ypwhich >/dev/null && break' would be a little more readable, but it's still a filthy hack.
The sleep loop has been done in sysvinit ypbind/nis scripts since time immemorial (well, 15 years). I have sysvinit scripts going back to redhat 7.3 that do this. redhat, mageia, mandriva, mandrake, suse, opensuse, fedora, debian, ubuntu, ... everybody but Arch.
I attach the ypbind initscript from RedHat 7.3 from Aug 13, 2001, current debian squeeze, and fedora 18's *.service file and supporting script. See?
You're completely missing/ignoring my point. *WHY* is this needed? You claim the daemon behaves properly -- it signals to systemd (either by sd_notify or by main exiting) that it's setup all its sockets and is ready to handle requests. Why then do you need to wait even further before it's capable of handling requests?
It has always been the init system's responsibility to determine the dependencies between services. If there is a bug in upstream, its systemd not ypbind. It has facilities for major subsystems but seems to have forgotten about name services.