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