> You aren't allowed to do very much between vfork() and exec(). > Basically just sort out the child's fd table. > And I suspect that needs to only look at on-stack data. > > Having the child execute first is only an optimisation. > The child can fault on paged-out memory (even its stack) which > would allow the parent to run.
Yes. Definitely! :) And per man page 'On some implementations, vfork() is equivalent to fork().' race conditions between parent and children is possible too, depends on implementation. https://linux.die.net/man/3/vfork https://man7.org/linux/man-pages/man2/vfork.2.html A possible approach is: let crond parent prepare the DGRAM socket fd connecting to /dev/log, avoid been delayed connecting until the first message is logged by vfork() children. This patch add LOG_NDELAY to openlog(), let parent open the DGRAM socket connecting to '/dev/log' immediately (if success). Upcoming vfork() children would get the same static var 'LogFile', just using it and not modifying it, because it is all setup ready by parent. For example, after applied this patch, crond parent pid=23384 will prepared the DGRAM socket fd connecting to '/dev/log', then vfork() children. # grep -rE "^vfork|^sock.*DGRAM" 20231208_05.log.23384 socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 3 connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 110) = 0 vfork() = 28336 vfork() = 2392 vfork() = 6124 ... <cut too long dummy> ... And vfork() children would just use fd=3 for logging. # grep -rE "^vfork|^sock.*DGRAM|connect.*log|sendto" 20231208_05.log.28336 sendto(3, "<75>Dec 8 15:38:01 crond[28336]: can't change directory to '/share/ho"..., 81, MSG_NOSIGNAL, NULL, 0) = 81 # grep -rE "^vfork|^sock.*DGRAM|connect.*log|sendto" 20231208_05.log.2392 sendto(3, "<75>Dec 8 15:39:00 crond[2392]: can't change directory to '/share/hom"..., 80, MSG_NOSIGNAL, NULL, 0) = 80 # grep -rE "^vfork|^sock.*DGRAM|connect.*log|sendto" 20231208_05.log.6124 sendto(3, "<75>Dec 8 15:40:00 crond[6124]: can't change directory to '/share/hom"..., 80, MSG_NOSIGNAL, NULL, 0) = 80 Note that '/dev/log' should be ready by syslogd or syslog-ng before crond. After poking around the mailing list found an old thread: inetd fd leak? http://lists.busybox.net/pipermail/busybox/2009-September/070195.html https://git.busybox.net/busybox/commit/?id=cfc216345e18081cba9ac3ed0464abf5d7f40cea It looks like inetd has a similar case in old days, and the solution is add LOG_NDELAY into openlog(). Hope this patch could be applied into git :) -- Regards, Jones Syue | 薛懷宗 QNAP Systems, Inc. _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
