On Thu, Aug 06, 2015 at 05:14:28PM +0200, Laurent Bercot wrote: > On 06/08/2015 16:31, Isaac Dunham wrote: > >If differences in environment can cause problems, it's a problem with > >design. A program that changes what it does just due to differences > >between the init environment and a login environment is going to be > >hard to debug. > > There are tons of those, and you can't fix them all. Stupid example: > less. Behaves differently when its stdout is a terminal and when it's > not. > The only way to ensure reproducible behaviour for a program, no matter > what it is, is to start it in a reproducible environment.
Which, fortunately, is pretty easy to do: I wrote an environment sanitizer yesterday, because I was curious how easily solved that is. Usage is cautenv [-c DIR] [-u] [-x] COMMAND [COMMAND_ARGS...] and it cleans the environment (saving some user variables if -u is specified and DISPLAY/XAUTH if -x is specified), closes all fds above 2, changes directory to DIR ("/" if that's not specified, and calls execvp(argv[optind], argv+optind). It comes out at 123 lines, and could probably be made shorter. If one wants to use this in an init script, just change the shebang to #!/path/to/cautenv /bin/sh and you know that there are no extra variables or fds. > >It took me ... less than a minute to find "pgrep -F". > >That solves the problem of stale pidfiles. > > Do you think so? See for yourself: > https://gitlab.com/procps-ng/procps/blob/master/pgrep.c > > It just reads the pid in the pidfile, and does its matching with > the read pid. Unless you also give other options to narrow the match, > it will have the exact same problem. I meant "the -F option that pgrep has solves the problem of stale pidfiles". I assumed that the reader would know to use that in addition to the standard options, for which I apologize. > Now, of course, you can give the executable name, and add even more > guards to make sure you don't find the wrong process. At the end of > the day, you wrote a nice and complex pgrep command line, you're > *almost* 100% sure that it will nail your process and only yours, > and you just scanned /proc to send a goddamn signal to a daemon. If someone finds "pgrep -F /var/run/$PIDFILE -x $NAME" complex, I don't expect that they'd be competent to write any init script, nor even a systemd unit. And the only way that could be wrong is if: -you have a stale pidfile AND -that stale pidfile happens to contain the same PID as a running process AND -that running process has the same executable name as the process that created the pidfile, while being distinct. I will acknowledge that whoever implemented -F did so in a lame way. What I'd assumed that it did, because it's the right thing to do, is make "-F $PIDFILE" check /proc/<pid>/* to determine if there's a match where <pid> is strictly any pid specified in $PIDFILE. But this could be solved, if one did a little refactoring. > I'd rather type "s6-svc -d /run/service/my-daemon" and kill my > process with absolute certainty, using 10 or 20 times fewer system > calls than pgrep and a small fraction of the CPU time. Fair enough. Thanks, Isaac Dunham _______________________________________________ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng