Package: guix;
Reported by: burban <at> opopop.net
Date: Wed, 11 Jun 2025 14:55:02 UTC
Severity: normal
Done: Ludovic Courtès <ludo <at> gnu.org>
Message #11 received at 78757 <at> debbugs.gnu.org (full text, mbox):
From: burban <at> opopop.net To: Ludovic Courtès <ludo <at> gnu.org> Cc: 78757 <at> debbugs.gnu.org Subject: Re: bug#78757: shepherd: dangling file descriptor to /dev/console Date: Sat, 14 Jun 2025 20:22:11 +0000
Hello, Ludovic Courtès <ludo <at> gnu.org> writes: > Hi burban, > > burban--- via Bug reports for GNU Guix <bug-guix <at> gnu.org> writes: > >> All shepherd children have an open file descriptor to /dev/console, >> probably because of the use of dup2 (and not dup3) in system.scm. > > I checked the /proc/PID/fd directory of several of my system services on > Guix System (nscd, guix-publish, ntpd, upower-daemon) and I don’t see > any file descriptor pointing to /dev/console, with version 1.0.5. > > You said you’re on Debian; which version of the Shepherd is it? Bookworm with my own shepherd package (1.0.0) and also Trixie with the official shepherd package (1.0.3). Without the CLOEXEC forcing below, I get this: # lsof |grep shepherd |grep /dev/console shepherd 1 root 0u CHR 5,1 0t0 12 /dev/console shepherd 1 root 1u CHR 5,1 0t0 12 /dev/console shepherd 1 root 2u CHR 5,1 0t0 12 /dev/console shepherd 1 root 19w CHR 5,1 0t0 12 /dev/console shepherd 1 183 shepherd root 0u CHR 5,1 0t0 12 /dev/console shepherd 1 183 shepherd root 1u CHR 5,1 0t0 12 /dev/console shepherd 1 183 shepherd root 2u CHR 5,1 0t0 12 /dev/console shepherd 1 183 shepherd root 19w CHR 5,1 0t0 12 /dev/console shepherd 1 251476 shepherd root 0u CHR 5,1 0t0 12 /dev/console shepherd 1 251476 shepherd root 1u CHR 5,1 0t0 12 /dev/console shepherd 1 251476 shepherd root 2u CHR 5,1 0t0 12 /dev/console shepherd 1 251476 shepherd root 19w CHR 5,1 0t0 12 /dev/console and fd 19 is duplicated for a lot of the children: # lsof |grep 19w systemd-u 211 root 19w CHR 5,1 0t0 12 /dev/console getty 853 root 19w CHR 5,1 0t0 12 /dev/console getty 856 root 19w CHR 5,1 0t0 12 /dev/console getty 859 root 19w CHR 5,1 0t0 12 /dev/console radvd 894 radvd 19w CHR 5,1 0t0 12 /dev/console radvd 895 root 19w CHR 5,1 0t0 12 /dev/console exim4 1001 Debian-exim 19w CHR 5,1 0t0 12 /dev/console ntpd 1003 ntpsec 19w CHR 5,1 0t0 12 /dev/console fwknopd 1005 root 19w CHR 5,1 0t0 12 /dev/console dbus-daem 1006 messagebus 19w CHR 5,1 0t0 12 /dev/console openvpn 1416 root 19w CHR 5,1 0t0 12 /dev/console apache2 160524 root 19w CHR 5,1 0t0 12 /dev/console php-fpm8. 160561 root 19w CHR 5,1 0t0 12 /dev/console php-fpm8. 160562 www-data 19w CHR 5,1 0t0 12 /dev/console php-fpm8. 160563 www-data 19w CHR 5,1 0t0 12 /dev/console unbound 199459 unbound 19w CHR 5,1 0t0 12 /dev/console postgres 214913 postgres 19w CHR 5,1 0t0 12 /dev/console cron 230165 root 19w CHR 5,1 0t0 12 /dev/console apache2 281804 www-data 19w CHR 5,1 0t0 12 /dev/console apache2 281804 281805 apache2 www-data 19w CHR 5,1 0t0 12 /dev/console And here the boot log when forcing CLOEXEC: 2025-06-13T11:32:51.657288+02:00 tanis [ 8.21 ] shepherd[1]: fcntl error for port #<output:soft-port 7f4045fb2980> 2025-06-13T11:32:51.657312+02:00 tanis [ 8.21 ] shepherd[1]: FD_CLOEXEC flag set on port #<output: file /dev/console> (fd: 2) 2025-06-13T11:32:51.657336+02:00 tanis [ 8.21 ] shepherd[1]: FD_CLOEXEC flag set on port #<output: file /dev/console> (fd: 1) 2025-06-13T11:32:51.657359+02:00 tanis [ 8.22 ] shepherd[1]: fcntl error for port #<output: #{write pipe}# 24> 2025-06-13T11:32:51.657383+02:00 tanis [ 8.22 ] shepherd[1]: FD_CLOEXEC flag set on port #<output: /proc/self/fd/1 /dev/console> (fd: 19) 2025-06-13T11:32:51.657408+02:00 tanis [ 8.22 ] shepherd[1]: fcntl error for port #<output: #{write pipe}# 24> 2025-06-13T11:32:51.657432+02:00 tanis [ 8.22 ] shepherd[1]: FD_CLOEXEC flag set on port #<input: file /dev/console> (fd: 0) 2025-06-13T11:32:51.657456+02:00 tanis [ 8.234859] shepherd[1]: GNU Shepherd 1.0.3 (Guile 3.0.10, x86_64-pc-linux-gnu) 2025-06-13T11:32:51.657480+02:00 tanis [ 8.234924] shepherd[1]: Starting service root... 2025-06-13T11:32:51.657503+02:00 tanis [ 8.235127] shepherd[1]: Service root started. > I also don’t see any ‘dup2’ call in ‘system.scm’; this takes place > rather in ‘service.scm’. Oops, yes of course. >> The pb. disapears if I force that flag with that code before I define >> my services (context: shepherd used as init system on Debian): >> (port-for-each (lambda (x) >> (catch #t >> (lambda () >> (when (= (fcntl x F_GETFD) 0) >> (fcntl x F_SETFD FD_CLOEXEC) >> (format #t "FD_CLOEXEC flag set on port ~a (fd: ~a)\n" x (port->fdes x)))) >> (lambda (keys . args) (format #t "fcntl error for port ~a\n" x))) >> )) > > ‘shepherd’ marks all previously-opened FDs as O_CLOEXEC upfront—see > ‘mark-as-close-on-exec’ in ‘shepherd.scm’. Those opened later are > opened with O_CLOEXEC, except for user code that explicitly omits the > O_CLOEXEC flag. Hmmm.... I have at one point (before the above (port-for-each ...) (define *s* (open-output-file "/proc/self/fd/1")) to have an early log output to (on ordinary PC) /dev/tty1. But maybe /dev/tty1 is a synonym for /dev/console. Let's test that: (fileno *s*) returns 19 indeed! Now all I have to do is (fcntl *s* F_SETFD FD_CLOEXEC) after creating *s*. So you can close that ticket. > > Thanks, > Ludo’. Regards. -- Bernard
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.