Bug#563260: /etc/cron.daily/htdig generates lock-related error message
Zaar Hai wrote:
> htdig seems to be installed as part of KDE. I've never changed any
> htdig configs. However, each morning, I have this email from cron
> in my box:
>
> /etc/cron.daily/htdig:
> /etc/cron.daily/htdig: line 26: 10138 Terminated lockfile-touch /var/run/htdig.cron
I am also seeing this problem. I have been ignoring it for a bit but
then finally decided to look into it. The problem only exists on
systems where /bin/sh is linked to bash, which are a very many
systems. Bash always prints the status of killed processes when those
processes are killed with any signal other than SIGINT or SIGPIPE.
This is arguably a bug in bash. But it seems unlikely to be fixed.
Here is a reference.
http://lists.gnu.org/archive/html/bug-bash/2006-09/msg00073.html
Alternate Archive: http://www.mail-archive.com/bug-bash@gnu.org/msg02013.html
I can see in /etc/cron.daily/htdig that someone was trying to supress
this error by redirecting the output of the 'kill' to /dev/null.
kill "${BADGER}" >/dev/null 2>&1
The redirection of the kill error output is incorrect. It is not the
kill process that is emitting the terminated message. It is the shell
interpreter that is running the script that is monitoring the
background status of the previous lockfile-touch command that is
emitting the message. In order to have the shell avoid the message it
is necessary to redirect the output of the running shell to /dev/null
and then kill the background job.
exec 2>/dev/null
kill "${BADGER}"
If that is at the end of the script then that is good enough. Let it
fall off the end of the script. If there are more commands to be run
however then saving and restoring stderr may be more correct. But it
is a lot of lines of code for little benefit.
if [ -n "$BASH_VERSION" ]; then
exec 3>&2
exec 2>/dev/null
fi
kill "${BADGER}"
wait
if [ -n "$BASH_VERSION" ]; then
exec 2>&3
exec 3>&-
fi
lockfile-remove $HOME/tmp/foo
Therefore I suggest using the other solution. Instead of killing with
the default SIGTERM kill with an explicit SIGINT. Bash will not
produce a status message about processes killed with either SIGINT or
SIGPIPE. SIGINT is a reasonable signal to use. It greatly simplifies
the script error handling.
kill -s INT "${BADGER}"
lockfile-remove /var/run/htdig.cron
That is much the simpler way!
Also the unconditional creation of the lockfile even when it isn't
needed isn't optimal. Currently the script creates a lockfile first.
Then it checks to see if it should run. If so it calls rundig. Then
it removes the lockfile and exits. But by default run_rundig is false
and so nothing is ever run unless it is configured to do so but
regardless the lockfile is unnecessarily created.
Here is a patch that corrects the terminated message bug reported here
and also orders the actions differently so that no lockfile is
attempted if not needed. I would actually like to do more but the
script is so small I couldn't bring myself to completely rewriting it.
Bob
--- htdig.original 2010-11-30 14:55:27.000000000 -0700
+++ htdig 2010-11-30 15:35:08.000000000 -0700
@@ -4,23 +4,27 @@
exit 0
fi
-if ! lockfile-create /var/run/htdig.cron; then
- # Another htdig indexing cronjob is already running
- exit 0
-fi
-
-lockfile-touch /var/run/htdig.cron &
-# Save the PID of the lockfile-touch process
-BADGER="$!"
-
if [ -r /etc/default/htdig ]; then
if [ -f /usr/bin/rundig ]; then
RUN=$(awk '/^run_rundig/ {print $3}' /etc/default/htdig)
if [ "$RUN" = "true" ]; then
+
+ if ! lockfile-create /var/run/htdig.cron; then
+ # Another htdig indexing cronjob is already running
+ exit 0
+ fi
+
+ lockfile-touch /var/run/htdig.cron &
+ # Save the PID of the lockfile-touch process
+ BADGER=$!
+
/usr/bin/rundig -a -s
+
+ kill -s INT "${BADGER}"
+ lockfile-remove /var/run/htdig.cron
+
fi
fi
fi
-kill "${BADGER}" >/dev/null 2>&1
-lockfile-remove /var/run/htdig.cron
+exit 0
#!/bin/sh
if ! `which lockfile-create >/dev/null 2>&1` || [ ! -x /usr/bin/rundig ]; then
exit 0
fi
if [ -r /etc/default/htdig ]; then
if [ -f /usr/bin/rundig ]; then
RUN=$(awk '/^run_rundig/ {print $3}' /etc/default/htdig)
if [ "$RUN" = "true" ]; then
if ! lockfile-create /var/run/htdig.cron; then
# Another htdig indexing cronjob is already running
exit 0
fi
lockfile-touch /var/run/htdig.cron &
# Save the PID of the lockfile-touch process
BADGER=$!
/usr/bin/rundig -a -s
kill -s INT "${BADGER}"
lockfile-remove /var/run/htdig.cron
fi
fi
fi
exit 0
Reply to: