Bug#1023476: runit: Improve default-syslog check
On Wed, 23 Nov 2022 18:42:19 +0100 Andras Korn wrote: > How about you make default-syslog/check use socklog-check or > unixclient if they are available, and fall back to the current > heuristics if not? Something like this: > > #!/bin/sh > > # note: only socklog exists as runit service in Debian right now > > socklog-check && exit 0 > > unixclient /dev/log /bin/true 2>&1 | grep -q '^connect: Protocol > wrong type for socket' && exit 0 > > fuser /dev/log >/dev/null 2>/dev/null && exit 0 > > for service in rsyslog socklog socklog-unix syslog-ng busybox-syslogd > inetutils-syslogd ; do sv u $service && sv check $service && exit 0 > done > > exit 1 > > If socklog-check and unixclient aren't installed, those commands will > just fail and the script will fall back to the next attempt. > > The only way I can see this being worse than the current solution is > if searching PATH for executables is pathologically slow (e.g. due to > an NFS outage maybe). Maybe I will include socklog-check in the future; for now I'm going to apply your suggestion and close this bug. Thanks for your contribution. Lorenzo > > > This bug can probably renamed as "default-syslog: useless inside a > > container", right ? > > I don't think so; that wouldn't be accurate. It's only useless if the > syslog daemon and the check script run in different namespaces; if > they run in the same container, it works, and it also fails if check > runs on the host and it's the syslog daemon that's in the container > (this should be rare though). > > I'd call it "default-syslog: check for running syslogd not robust" or > something. >
Bug#1023476: runit: Improve default-syslog check
On Wed, Nov 16, 2022 at 02:03:14PM +0100, Lorenzo wrote: > > > lsof /dev/log >/dev/null || exit 1 > > > > I think > > > > fuser /dev/log >/dev/null 2>/dev/null || exit 1 > > > > is more efficient, but there is a problem with both approaches: the process > > that is listening on /dev/null may be invisible to us, because it may be > > running in a different namespace. > > Thanks for the above: I didn't thought about using this service inside a > container (when the logger is outside) and I agree it's a nice to have > extension (assuming that you mean listening on /dev/log, otherwise I fail to > understand what you are talking about) Yes, sorry, my brain hit a bad sector there. /dev/log of course. > > The only way to reliably determine whether there is a Unix server listening > > on the /dev/log socket is to try to connect to the socket. > > > > One approach I can think of is to use > > > > unixclient /dev/log /bin/true 2>&1 | grep -q '^connect: Protocol wrong type > > for socket' || exit 1 > > > > This creates a SOCK_STREAM socket and tries to connect it to /dev/log, > > which will fail with EPROTOTYPE if there is a listening server (which will > > use SOCK_DGRAM) and with ECONNREFUSED if not. > > > > Using unixclient would introduce a semi-esoteric dependency on ucspi-unix, > > but it's a tiny package which is a good match for the runit ecosystem > > anyway, so maybe it's acceptable. > > > > A more mainstream but much more heavyweight approach would be to use > > socat(1) or netcat-openbsd with the -U option. > > > > Alternatively, socklog provides its own socklog-check, which does exactly > > what is necessary, but the whole point of trying to detect whether *any* > > syslog daemon is running is to avoid having to install a particular one > > like socklog, so we probably shouldn't use it. > > > > OTOH, it's such a tiny program, and so unlikely to require changes ever, > > you might even ship (a copy of) it as part of the runit package. > > I'm ok with ucspi-unix or socklog-check, but this can happen only after the > bookworm release. How about you make default-syslog/check use socklog-check or unixclient if they are available, and fall back to the current heuristics if not? Something like this: #!/bin/sh # note: only socklog exists as runit service in Debian right now socklog-check && exit 0 unixclient /dev/log /bin/true 2>&1 | grep -q '^connect: Protocol wrong type for socket' && exit 0 fuser /dev/log >/dev/null 2>/dev/null && exit 0 for service in rsyslog socklog socklog-unix syslog-ng busybox-syslogd inetutils-syslogd ; do sv u $service && sv check $service && exit 0 done exit 1 If socklog-check and unixclient aren't installed, those commands will just fail and the script will fall back to the next attempt. The only way I can see this being worse than the current solution is if searching PATH for executables is pathologically slow (e.g. due to an NFS outage maybe). > This bug can probably renamed as "default-syslog: useless inside a > container", right ? I don't think so; that wouldn't be accurate. It's only useless if the syslog daemon and the check script run in different namespaces; if they run in the same container, it works, and it also fails if check runs on the host and it's the syslog daemon that's in the container (this should be rare though). I'd call it "default-syslog: check for running syslogd not robust" or something. András -- Desk: A very large wastebasket with drawers.
Bug#1023476: runit: Improve default-syslog check
Hi, On Mon, 7 Nov 2022 09:39:18 +0100 Andras Korn wrote: > Hi, > > > the check could be just something like > > > > lsof /dev/log >/dev/null || exit 1 > > I think > > fuser /dev/log >/dev/null 2>/dev/null || exit 1 > > is more efficient, but there is a problem with both approaches: the > process that is listening on /dev/null may be invisible to us, > because it may be running in a different namespace. Thanks for the above: I didn't thought about using this service inside a container (when the logger is outside) and I agree it's a nice to have extension (assuming that you mean listening on /dev/log, otherwise I fail to understand what you are talking about) > > The only way to reliably determine whether there is a Unix server > listening on the /dev/log socket is to try to connect to the socket. > > One approach I can think of is to use > > unixclient /dev/log /bin/true 2>&1 | grep -q '^connect: Protocol > wrong type for socket' || exit 1 > > This creates a SOCK_STREAM socket and tries to connect it to > /dev/log, which will fail with EPROTOTYPE if there is a listening > server (which will use SOCK_DGRAM) and with ECONNREFUSED if not. > > Using unixclient would introduce a semi-esoteric dependency on > ucspi-unix, but it's a tiny package which is a good match for the > runit ecosystem anyway, so maybe it's acceptable. > > A more mainstream but much more heavyweight approach would be to use > socat(1) or netcat-openbsd with the -U option. > > Alternatively, socklog provides its own socklog-check, which does > exactly what is necessary, but the whole point of trying to detect > whether *any* syslog daemon is running is to avoid having to install > a particular one like socklog, so we probably shouldn't use it. > > OTOH, it's such a tiny program, and so unlikely to require changes > ever, you might even ship (a copy of) it as part of the runit package. > I'm ok with ucspi-unix or socklog-check, but this can happen only after the bookworm release. A dependency on ucspi-unix would make runit uninstallable on several architectures ( where ucspi-unix fails to build because of missing dietlibc , see https://buildd.debian.org/status/package.php?p=ucspi-unix ). To ship a copy of socklog-check (maybe also tryto can be useful) I need to build it with runit source, I think it's feasible but I need to play with those old style makefile, it takes time. For now I'm going to use fuser and keep the old code as fallback: it will be an improvement for users that have psmisc installed, and no regression for others. This bug can probably renamed as "default-syslog: useless inside a container", right ? Lorenzo
Bug#1023476: runit: Improve default-syslog check
Hi, > the check could be just something like > > lsof /dev/log >/dev/null || exit 1 I think fuser /dev/log >/dev/null 2>/dev/null || exit 1 is more efficient, but there is a problem with both approaches: the process that is listening on /dev/null may be invisible to us, because it may be running in a different namespace. The only way to reliably determine whether there is a Unix server listening on the /dev/log socket is to try to connect to the socket. One approach I can think of is to use unixclient /dev/log /bin/true 2>&1 | grep -q '^connect: Protocol wrong type for socket' || exit 1 This creates a SOCK_STREAM socket and tries to connect it to /dev/log, which will fail with EPROTOTYPE if there is a listening server (which will use SOCK_DGRAM) and with ECONNREFUSED if not. Using unixclient would introduce a semi-esoteric dependency on ucspi-unix, but it's a tiny package which is a good match for the runit ecosystem anyway, so maybe it's acceptable. A more mainstream but much more heavyweight approach would be to use socat(1) or netcat-openbsd with the -U option. Alternatively, socklog provides its own socklog-check, which does exactly what is necessary, but the whole point of trying to detect whether *any* syslog daemon is running is to avoid having to install a particular one like socklog, so we probably shouldn't use it. OTOH, it's such a tiny program, and so unlikely to require changes ever, you might even ship (a copy of) it as part of the runit package. András -- I break into song if I can't find the key.
Bug#1023476: runit: Improve default-syslog check
Package: runit Version: 2.1.2-50 Severity: normal X-Debbugs-Cc: plore...@disroot.org >From #1022837 > 2. a default-syslog service is created by something, and all it does on my > systems is sleep indefinitely (I use socklog as my syslogd, but have > my own service directory for that as well, and its name is just > "socklog", so the magic "check" script won't pick it up -- and > neither will it pick up a syslogd that is not managed by runit. Maybe > just try to see if something is listening on /dev/log in "check"?). the check could be just something like lsof /dev/log >/dev/null || exit 1 -- System Information: Debian Release: bookworm/sid APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') merged-usr: no Architecture: amd64 (x86_64) Kernel: Linux 5.7.0-1-amd64 (SMP w/4 CPU threads) Kernel taint flags: TAINT_FIRMWARE_WORKAROUND, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US:en Shell: /bin/sh linked to /bin/dash Init: runit (via /run/runit.stopit) LSM: AppArmor: enabled Versions of packages runit depends on: ii libc6 2.36-4 ii runit-helper2.15.0 ii sysuser-helper 1.3.7+really1.4.1 Versions of packages runit recommends: ii runit-init 2.1.2-50 Versions of packages runit suggests: ii socklog 2.1.0+repack-4+b1 pn zsh -- Configuration Files: /etc/default/runit changed [not included] /etc/runit/ctrlaltdel changed [not included] /etc/runit/runsvdir/single/sulogin/run [Errno 2] No such file or directory: '/etc/runit/runsvdir/single/sulogin/run' -- no debconf information