Package: cron
Version: 3.0pl1-106
Severity: minor
Tags: patch
As has been mentioned in other bugreports (#485452, #535227), the
use of lockfile-progs by /etc/cron.daily/standard introduces an
unnecessary dependency on a low-Priority package, pulling it in by
default on every Debian install, even though you could get the same
functionality more easily via coreutils these days.
I attach three different sh scripts:
* flockdemo - which just shows how it works;
* standard.daily - a minimal modification of the cronjob;
* rewrite - a thoroughgoing reimplementation.
That third one is just there because I couldn't help myself - it has
extra features such as recognising ext4, but it deliberately changes
more or less every line and probably isn't suitable for use.
I also attach a patch that covers the minimal-change version plus
corresponding edits to the control file, removing the unnecessary
"Recommends: lockfile-progs" and the corresponding paragraph of the
package description. It should also fix bugs #179629 and #478967,
though not bug #333837.
Further comments on the standard cronjobs:
------------------------------------------
First, "/etc/cron.monthly/standard" has been empty for most of a
decade. Now would be a good time to get rid of it.
Second, the names of these cronjobs contravene a "should" in Debian
Policy 9.5, where it defines the namespace for these files:
# If a package wants to install a job that has to be executed via
# cron, it should place a file with the name of the package in one
# or more of the following directories:
Even anacron, which can't use plain "anacron", gets as close as it
can with "0anacron". So the one remaining standard cronjob should
be named "/etc/cron.daily/cron", leaving the namespace clear in case
a package ever turns up named "standard".
Third, I agree with bug #473711: it's pointless to have every single
Debian machine spinning up every single hard disk to check the
status of lost+found directories every single day. Corrupted file
systems don't surreptitiously fsck themselves - doing the check more
often than once per boot is only going to be useful if the sysadmin
performs crucial system rescue procedures without paying attention,
and if you're going to assume that, you need to do a lot more kinds
of check! IMHO this task should belong to initscripts; if that's
too much trouble it could at least be factored out into a script
(something like "/sbin/chklost+found") so that it can be called both
@reboot and @daily.
--
JBR
Ankh kak! (Ancient Egyptian blessing)
#!/bin/sh
FLOCK=~/lock # or whatever; not somewhere world-writable
umask 066 # don't let anyone else get a read-lock
: > $FLOCK # always recreate it in case it's on a tmpfs
exec < $FLOCK # use STDIN, don't interfere with output
if ! flock -n 0; then
echo 'Failed to acquire lock'
exit 1
fi
echo 'Running - now launch another to demonstrate collisions'
sleep 5
echo 'Finished' # $FLOCK automatically released
#!/bin/sh
# /etc/cron.daily/standard: standard daily maintenance script
# Written by Ian A. Murdock <imurd...@gnu.ai.mit.edu>
# Modified by Ian Jackson <ijack...@nyx.cs.du.edu>
# Modified by Steve Greenland <stev...@debian.org>
# Start in the root filesystem, make SElinux happy
cd /
bak=/var/backups
LOCKFILE=/var/lock/cron.daily
#
# Avoid running more than one at a time
#
umask 066
: > $LOCKFILE
exec < $LOCKFILE
if ! flock -n 0; then
cat <<EOF
Unable to run /etc/cron.daily/standard because lockfile $LOCKFILE
acquisition failed. This probably means that the previous day's
instance is still running. Please check and correct if necessary.
EOF
exit 1
fi
umask 022
#
# Backup key system files
#
if cd $bak ; then
cmp -s passwd.bak /etc/passwd || (cp -p /etc/passwd passwd.bak &&
chmod 600 passwd.bak)
cmp -s group.bak /etc/group || (cp -p /etc/group group.bak &&
chmod 600 group.bak)
if [ -f /etc/shadow ] ; then
cmp -s shadow.bak /etc/shadow || (cp -p /etc/shadow shadow.bak &&
chmod 600 shadow.bak)
fi
if [ -f /etc/gshadow ] ; then
cmp -s gshadow.bak /etc/gshadow || (cp -p /etc/gshadow gshadow.bak &&
chmod 600 gshadow.bak)
fi
fi
if cd $bak ; then
if ! cmp -s dpkg.status.0 /var/lib/dpkg/status ; then
cp -p /var/lib/dpkg/status dpkg.status
savelog -c 7 dpkg.status >/dev/null
fi
fi
#
# Check to see if any files are in lost+found directories and warn admin
#
# Get a list of the (potential) ext2, ext3 and xfs l+f directories
# Discard errors, for systems not using any of these.
df -P --type=ext2 --type=ext3 --type=xfs 2>/dev/null |
awk '/\/dev\// { print }' | sed -e 's/ [[:space:]]*/ /g' |
while read mount block used avail perc mp; do
[ "$mp" = "/" ] && mp=""
echo "$mp/lost+found"
done |
while read lfdir; do
# In each directory, look for files
if [ -d "$lfdir" ] ; then
more_lost_found=`ls -1 "$lfdir" | grep -v 'lost+found$' | sed 's/^/
/'`
if [ -n "$more_lost_found" ] ; then
lost_found="$lost_found
$lfdir:
$more_lost_found"
# NOTE: above weird line breaks in string are intentional!
fi
else
no_lost_found="$no_lost_found
$lfdir"
fi
done
# NOTE: This might need to be configurable if systems abound
# w/o lost+found out there to prevent giving out this warning
# every day.
if [ -n "$lost_found" ]; then
cat << EOF
Files were found in lost+found directories. This is probably
the result of a crash or bad shutdown, or possibly of a disk
problem. These files may contain important information. You
should examine them, and move them out of lost+found or delete
them if they are not important.
The following files were found:
$lost_found
EOF
fi
if [ -n "$no_lost_found" ]; then
cat << EOF
Some local filesystems do not have lost+found directories. This
means that these filesystems will not be able to recover
lost files when the filesystem is checked after a crash.
Consider creating a lost+found directory with mklost+found(8).
The following lost+found directories were not available:
$no_lost_found
EOF
fi
#!/bin/sh
#--------------------------------------------------------------------#
# Preparation
cd / # to keep SElinux happy
. /etc/default/cron # for NO_* variables
#--------------------------------------------------------------------#
# Prevent overlapping runs
FLOCK=/var/lock/cron
if ! test "$NO_FLOCK" # maybe you've got Lenny coreutils
then umask 066 # (only affects the following line)
: > $FLOCK
exec < $FLOCK
if ! flock -n 0
then echo "
Acquisition of lockfile $FLOCK failed - cronjob aborting.
This probably means that the previous instance is still running.
Please check and correct if necessary.
"
exit 1
fi
fi
#--------------------------------------------------------------------#
# Back up key system files
if test "$NO_BACKUPS" # if every MB of space is precious
then :
elif cd /var/backups
then for FILE in passwd group shadow gshadow
do test -f "/etc/$FILE" || continue
cmp -s $FILE.bak /etc/$FILE && continue
cp -p /etc/$FILE $FILE.bak || continue
chmod 0600 $FILE.bak
done
for FILE in /var/lib/dpkg/status
do cmp -s $FILE dpkg.status.0 && continue
cp -p $FILE dpkg.status || continue
savelog -m 644 -c 7 dpkg.status >&-
done
fi
#--------------------------------------------------------------------#
# Check lost+found directories
test "$NO_CHECK_LF" && exit 0 # advisable on e.g. all-JFS systems
LF=lost+found # vary to debug!
NEWLINE='
'
exec < /etc/mtab
while read DEV MP FS
do case $DEV in
/dev/*) ;;
*) continue ;;
esac
case $FS in
ext*|xfs) ;;
*) continue ;;
esac
test "$MP" = '/' && MP=''
if ! test -d "$MP/$LF"
then MISSING="$MISSING$NEWLINE $MP/$LF"
elif cd "$MP/$LF" 2>&-
then for NAME in *
do test "$NAME" = '*' && continue
LIST="$LIST$NEWLINE $NAME"
done
test "$LIST" || continue
CONTENTS="$CONTENTS$NEWLINE $MP/$LF:$LIST"
else echo "Can't access $MP/$LF"
fi
done
#--------------------------------------------------------------------#
# Report findings if any
if test "$MISSING"
then echo "
Some local file systems lack a $LF directory. This means if the
file system is damaged and needs to be repaired, fsck will not have
anywhere to put stray files for recovery. You should consider creating
a $LF directory with mk$LF(8).
The following $LF directories were not available:
$MISSING"
fi
if test "$CONTENTS"
then echo "
Items were found in $LF directories. This is probably the result
of a crash or bad shutdown, or possibly of a disk problem. You should
examine them to see if they contain important information, and either
retrieve them from $LF or delete them.
The following items were found:
$CONTENTS"
fi
#--------------------------------------------------------------------#
# The End
exit 0
#--------------------------------------------------------------------#
diff -ru cron-3.0pl1.pristine/debian/control cron-3.0pl1/debian/control
--- cron-3.0pl1.pristine/debian/control 2009-06-30 18:58:02.000000000 +0100
+++ cron-3.0pl1/debian/control 2009-07-11 21:58:27.000000000 +0100
@@ -9,7 +9,7 @@
Package: cron
Architecture: any
Depends: ${shlibs:Depends}, debianutils (>=1.7), adduser, lsb-base (>= 3.0-10)
-Recommends: exim4 | postfix | mail-transport-agent, lockfile-progs
+Recommends: exim4 | postfix | mail-transport-agent
Suggests: anacron (>=2.0-1), logrotate, checksecurity
Conflicts: suidmanager (<< 0.50), lockfile-progs (<< 0.1.7)
Provides:
@@ -31,7 +31,3 @@
maintenance tasks, such as ensuring creating copying key system files.
Additional maintenance tasks are available on external packages, such as
'checksecurity'
- .
- The lockfile-progs package is recommended as it will prevent
- /etc/cron.daily/standard from running multiple
- times if something gets jammed.
diff -ru cron-3.0pl1.pristine/debian/standard.daily cron-3.0pl1/debian/standard.daily
--- cron-3.0pl1.pristine/debian/standard.daily 2009-06-30 18:58:02.000000000 +0100
+++ cron-3.0pl1/debian/standard.daily 2009-07-13 11:51:34.000000000 +0100
@@ -8,15 +8,15 @@
cd /
bak=/var/backups
LOCKFILE=/var/lock/cron.daily
-umask 022
#
# Avoid running more than one at a time
#
-if [ -x /usr/bin/lockfile-create ] ; then
- lockfile-create $LOCKFILE
- if [ $? -ne 0 ] ; then
+umask 066
+: > $LOCKFILE
+exec < $LOCKFILE
+if ! flock -n 0; then
cat <<EOF
Unable to run /etc/cron.daily/standard because lockfile $LOCKFILE
@@ -24,13 +24,9 @@
instance is still running. Please check and correct if necessary.
EOF
- exit 1
- fi
-
- # Keep lockfile fresh
- lockfile-touch $LOCKFILE &
- LOCKTOUCHPID="$!"
+ exit 1
fi
+umask 022
#
# Backup key system files
@@ -112,11 +108,3 @@
$no_lost_found
EOF
fi
-
-#
-# Clean up lockfile
-#
-if [ -x /usr/bin/lockfile-create ] ; then
- kill $LOCKTOUCHPID
- lockfile-remove $LOCKFILE
-fi