Gentoo Archives: gentoo-commits

From: "Mike Frysinger (vapier)" <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in sys-process/cronbase/files: run-crons-0.3.7
Date: Fri, 24 Jul 2015 05:45:06
Message-Id: 20150724054503.B7F37BF@oystercatcher.gentoo.org
1 vapier 15/07/24 05:45:03
2
3 Added: run-crons-0.3.7
4 Log:
5 Split global lock up into one lock per /etc/cron.xxx dir #157547 by Radoslaw Stachowiak.
6
7 (Portage version: 2.2.20/cvs/Linux x86_64, signed Manifest commit with key D2E96200)
8
9 Revision Changes Path
10 1.1 sys-process/cronbase/files/run-crons-0.3.7
11
12 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-process/cronbase/files/run-crons-0.3.7?rev=1.1&view=markup
13 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-process/cronbase/files/run-crons-0.3.7?rev=1.1&content-type=text/plain
14
15 Index: run-crons-0.3.7
16 ===================================================================
17 #!/bin/sh
18 #
19 # $Header: /var/cvsroot/gentoo-x86/sys-process/cronbase/files/run-crons-0.3.7,v 1.1 2015/07/24 05:45:03 vapier Exp $
20 #
21 # 12 Oct 2008; Thilo Bangert <bangert@g.o> run-crons:
22 # ignore emacs backup files (bug #237200)
23 # include logging patch (bug #140869)
24 #
25 # 08 Mar 2005; Aaron Walker <ka0ttic@g.o> run-crons:
26 # Ignore the error messages from find caused by race conditions, since
27 # we could care less about the error as long as the file has been removed.
28 # See bug 8506.
29 #
30 # 06 May 2004; Aron Griffis <agriffis@g.o> run-crons:
31 # Make the locking actually work. The old code was racy.
32 # Thanks to Mathias Gumz in bug 45155 for some cleanups.
33 #
34 # 23 Jun 2002; Jon Nelson <jnelson@g.o> run-crons:
35 # fixed a race condition, where cron jobs and run-crons wanted to
36 # delete touch files
37 #
38 # 20 Apr 2002; Thilo Bangert <bangert@g.o> run-crons:
39 # moved lastrun directory to /var/spool/cron/lastrun
40 #
41 # Author: Achim Gottinger <achim@g.o>
42 #
43 # Mostly copied from SuSE
44 #
45 # this script looks into /etc/cron.[hourly|daily|weekly|monthly]
46 # for scripts to be executed. The info about last run is stored in
47 # /var/spool/cron/lastrun
48
49 LOCKDIR="/var/run/lock"
50 CRONSPOOLDIR="/var/spool/cron"
51 LASTRUNDIR="${CRONSPOOLDIR}/lastrun"
52 # This is the legacy lockfile that we need to clean up.
53 GLOBAL_LOCKFILE="${LASTRUNDIR}/lock"
54
55 # Usage: log <level> <args to logger>
56 # Log a message via syslog.
57 log() {
58 local level="$1"
59 shift
60 logger -i -p "cron.${level}" -t run-crons "$@"
61 }
62
63 # Usage: grab_lock <class>
64 # Grab the lock for <class> to make sure we are the only instance.
65 grab_lock() {
66 local i cronpid cmdline1 cmdline2
67 local lockfile
68
69 # Free whatever previous lock (if any) we held.
70 free_lock
71
72 # For the legacy global lock, don't try to create a full path.
73 case $1 in
74 /*) lockfile=$1 ;;
75 *) lockfile="${LOCKDIR}/cron.$1" ;;
76 esac
77
78 # Try twice to lock, otherwise give up.
79 i=0
80 while [ $(( i += 1 )) -le 2 ] ; do
81 # Normally we should be able to grab the lock and get out of here fast.
82 if ln -sn $$ "${lockfile}" 2>/dev/null ; then
83 break
84 fi
85
86 # Locking failed, so check for a running process.
87 # Handle both old- and new-style locking.
88 # Delete the cat logic when GLOBAL_LOCKFILE is purged.
89 # Note: Does not handle PID namespaces ...
90 if ! cronpid=$(readlink "${lockfile}" 2>/dev/null) ; then
91 if ! cronpid=$(cat "${lockfile}" 2>/dev/null) ; then
92 # The lockfile disappeared? Try the whole thing again ...
93 continue
94 fi
95 fi
96
97 # This is better than kill -0 because we can verify that it's really
98 # another run-crons process.
99 cmdline1=$(cat "/proc/${cronpid}/cmdline" 2>/dev/null) || :
100 cmdline2=$(cat /proc/$$/cmdline)
101 if [ "${cmdline1}" = "${cmdline2}" ] ; then
102 # Whoa, another run-crons is really running.
103 return 1
104 fi
105
106 # The lockfile is pointing to a dead process so break it.
107 # TODO: This is still racy if we're running more than one run-crons.
108 rm -f "${lockfile}"
109 done
110
111 # Check to make sure locking was successful.
112 if [ ! -L "${lockfile}" ] ; then
113 echo "Can't create or read existing ${lockfile}, giving up"
114 exit 1
115 fi
116
117 # Set the lock file for free_lock to clean up.
118 _LOCKFILE="${lockfile}"
119
120 return 0
121 }
122 # Prevent random env vars from messing with us.
123 _LOCKFILE=
124 # Set a trap to release the lockfile when we're finished.
125 trap 'free_lock' EXIT HUP INT QUIT TERM
126
127 # Usage: free_lock
128 # Release the lock that we last grabbed. This does not nest!
129 free_lock() {
130 if [ -n "${_LOCKFILE}" ] ; then
131 rm -f "${_LOCKFILE}"
132 # Only break the lock once.
133 _LOCKFILE=
134 fi
135 }
136
137
138 EXIT_STATUS=0
139
140 # Grab the legacy global lock to smoothly handle upgrades.
141 # We should drop this after like Dec 2016.
142 if [ -L "${GLOBAL_LOCKFILE}" -o -f "${GLOBAL_LOCKFILE}" ] ; then
143 if ! grab_lock "${GLOBAL_LOCKFILE}" ; then
144 # An old process is still running -- abort.
145 exit 0
146 fi
147 # Now release the lock since we no longer care about it.
148 free_lock
149 fi
150
151 for BASE in hourly daily weekly monthly ; do
152 CRONDIR=/etc/cron.${BASE}
153
154 test -d $CRONDIR || continue
155
156 # Grab the lock for this specific dir.
157 if ! grab_lock "${BASE}" ; then
158 # Someone else is processing this dir, so skip it.
159 continue
160 fi
161
162 # Blow away stale states for this particular dir.
163 lastrunfile="${LASTRUNDIR}/cron.${BASE}"
164 if [ -e "${lastrunfile}" ] ; then
165 case $BASE in
166 hourly)
167 #>= 1 hour, 5 min -=> +65 min
168 TIME="-cmin +65" ;;
169 daily)
170 #>= 1 day, 5 min -=> +1445 min
171 TIME="-cmin +1445" ;;
172 weekly)
173 #>= 1 week, 5 min -=> +10085 min
174 TIME="-cmin +10085" ;;
175 monthly)
176 #>= 31 days, 5 min -=> +44645 min
177 TIME="-cmin +44645" ;;
178 esac
179
180 find "${LASTRUNDIR}/" -name cron.$BASE $TIME -exec rm {} \; 2>/dev/null || :
181 fi
182
183 # if there is no state file, make one, then run the scripts.
184 if [ ! -e "${lastrunfile}" ] ; then
185 touch "${lastrunfile}"
186
187 set +e
188 for SCRIPT in $CRONDIR/* ; do
189 if [ -x "${SCRIPT}" ] && [ ! -d "${SCRIPT}" ] ; then
190 # Filter out files people do not expect to be executed.
191 case ${SCRIPT} in
192 .*|*~) continue ;;
193 esac
194
195 log info "($(whoami)) CMD (${SCRIPT})"
196 $SCRIPT
197 ret=$?
198 if [ ${ret} -ne 0 ] ; then
199 log err "CMD (${SCRIPT}) failed with exit status ${ret}"
200 EXIT_STATUS=1
201 fi
202 fi
203 done
204 fi
205 done
206
207 # Clean out bogus state files with future times.
208 touch "${LASTRUNDIR}"
209 find "${LASTRUNDIR}/" -newer "${LASTRUNDIR}" -exec /bin/rm -f {} \; 2>/dev/null || :
210
211 exit ${EXIT_STATUS}