1#!/usr/local/bin/bash
2
3ulimit -c unlimited
4
5#####################################################################
6## Lyrics:
7##
8## The goal of that script is to clean data leftovers, run away fuser
9## processes, and report if here is any problem
10##
11## That script has one parameter :
12##
13##      config_name : it will try to find configuration file
14##                    cfg/config_name.cfg ( optional )
15##                    default config name is 'standard'
16##
17#####################################################################
18
19##  Where we are, who we are?
20##
21SCR_DIR=`dirname $0`
22SCR_DIR=`cd $SCR_DIR; pwd`
23
24SCR_NAME=`basename $0`
25SCR_SNAME=`basename $0 .sh`
26
27##  Loading common things to live
28##
29CMN_SCR="$SCR_DIR/remote_fuser_common.sh"
30if [ ! -f "$CMN_SCR" ]
31then
32    echo "ERROR: Can not stat script '$CMN_SCR' ... exiting"
33    exit 1
34fi
35
36. $CMN_SCR
37
38#####################################################################
39##
40## Simple setup : directory
41##
42## TEST_DIR ---/ USER ---/ HOST ---/ PID ---/ cache_dir /
43##                 |-/ logs           |-/ mount_point /
44##                 |-/ bin            |-/ tmp_dir /
45##                 |-/ depot          |-/ status_file
46##
47## depot - directory with test binaries, just a history
48## bin - test binaries in work
49## status_file - says a lot ... but heart-bot
50##
51## It is checking USER/HOST directory for PID and clean unused.
52## If there is a process which is unable to kill, it will be reported
53## to MAIL_LIST from config file
54##
55#####################################################################
56
57##  Config file
58##
59CFG_DIR=$SCR_DIR/cfg
60if [ ! -d "$CFG_DIR" ]
61then
62    _err_exit "Can not stat directory '$CFG_DIR'"
63fi
64
65####
66##  Here the usage and Arguments processing
67#
68CFG_NAME_DEF="standard"
69CFG_NAME=$CFG_NAME_DEF
70
71usage ( )
72{
73    cat >&2 <<EOF
74
75This script will remove unused test data for remote_fuser utility. 
76
77Syntax is :
78
79    $SCR_NAME [ config_name ]
80
81Where :
82
83         config_name - name of config to use. 
84                       String. Optional. Default "$CFG_NAME_DEF"
85
86EOF
87}
88
89case $# in
90    0)
91        ;;
92    1)
93        CFG_NAME=$1
94        ;;
95    *)
96        usage
97        _err_exit Invalid parameters
98        ;;
99esac
100
101##  Checking arguments
102##
103CFG_FILE=$CFG_DIR/${CFG_NAME}.cfg
104if [ ! -f "$CFG_FILE" ]
105then
106    _err_exit "Can not stat config file with name '$CFG_NAME'"
107fi
108
109####
110##  Loading fonfig file
111#
112. $CFG_FILE
113if [ $? -ne 0 ]
114then
115    _err_exit "Can not load config file '$CFG_NAME'"
116fi
117
118####
119##  Checking config file data and prepareing environment
120#
121if [ -z "$TEST_DIR" ]
122then
123    _err_exit "Config does not have definition for variable TEST_DIR"
124fi
125
126if [ ! -d "$TEST_DIR" ]
127then
128    _err_exit "Can not stat directory '$TEST_DIR'"
129fi
130
131###
132### Prefixes U_(ser), H_(ost), P_(rocess), F_(inal) - is what we use
133###
134
135_assign_create_dir ()
136{
137    if [ $# -ne 2 ]
138    then
139        _err_exit "_assign_create_dir(): requires two arguments"
140    fi
141
142    DVAL=$1
143    if [ ! -d "$DVAL" ]
144    then
145        _msg "Creating directory '$DVAL'"
146        _exec mkdir $DVAL
147        _exec chmod ugoa+rwx $DVAL
148    fi
149
150    DVAL=`cd $DVAL; pwd`
151
152    eval "$2=$DVAL"
153}
154
155###
156## There are logs, bin and depot on user level of test direcotry
157#
158_assign_create_dir $TEST_DIR/$DAS_USER U_TEST_DIR
159_assign_create_dir $U_TEST_DIR/$DAS_HOST H_TEST_DIR
160
161_assign_create_dir $U_TEST_DIR/log   F_LOG_DIR
162
163F_VALID="cache mount status.file temp"
164U_VALID="bin depot log"
165
166##  Here we are logging and execing
167##
168F_TIME_STAMP=`date +%Y-%m-%d_%H-%M-%S`
169F_LOG_FILE=$F_LOG_DIR/${SCR_SNAME}.log.${DAS_CTX}.${F_TIME_STAMP}
170echo Log file: $F_LOG_FILE
171
172exec >$F_LOG_FILE 2>&1
173
174## One more time for log file
175##
176_print_env $@
177
178####
179### OLD LOGS
180##
181#
182_bump
183_msg OLD LOGS
184
185##  Here we are clearing old logs
186##
187DAYS_KEEP_LOG=10
188
189SEC_IN_DAY=$(( 60 * 60 * 24 ))
190NOW_DAY=$(( `date +%s` / $SEC_IN_DAY ))
191
192check_remove ()
193{
194    F2R=$1
195
196    if [ -n "$F2R" ]
197    then
198        FILE_DAY=$(( `stat --print="%X" $F2R` / $SEC_IN_DAY ))
199        DALT=$(( $NOW_DAY - $FILE_DAY ))
200        if [ $DAYS_KEEP_LOG -le $DALT ]
201        then
202            _msg Log file is $DALT days old, removing \'$F2R\'
203            rm -f $F2R
204            if [ $? -ne 0 ]
205            then
206                _wrn Can not remove file \'$F2R\'
207            fi
208        fi
209    fi
210}
211
212clear_old_logs ()
213{
214    _msg Cleaning old logs ...
215
216    for i in `ls $F_LOG_DIR 2>/dev/null`
217    do
218        check_remove $F_LOG_DIR/$i
219    done
220}
221
222clear_old_logs
223
224_msg OLD LOGS DONE
225
226####
227### OLD FUSES
228##
229#
230_bump
231_msg OLD FUSES
232
233_remove_dir ()
234{
235    D2R=$1
236
237    if [ -d "$D2R" ]
238    then
239        _exec_plain rm -rf $D2R
240        if [ $? -ne 0 ]
241        then
242            _msg Failed to remove directory $D2R
243            sleep 3
244            _exec_plain rm -rf $D2R
245            if [ $? -ne 0 ]
246            then
247                INVALID_FUSES[${#INVALID_FUSES[*]}]="CAN NOT REMOVE: $D2R"
248            fi
249        fi
250    fi
251}
252
253_clean_data_for_pid ()
254{
255    DPD=$1
256
257    _msg "<=================================>"
258    _msg Cleaning data for PID = $DPD
259
260    F_TEST_DIR=$H_TEST_DIR/$DPD
261
262    ## First we are trying to read data from status file
263    ##
264
265    unset F_PID
266    unset F_MNT
267    ST_FL=$F_TEST_DIR/status.file
268    if [ -f $ST_FL ]
269    then
270        _load_fuser_params $ST_FL F_PID F_MNT
271    else
272        F_MNT=$F_TEST_DIR/mount
273    fi
274
275    if [ -n "$F_PID" ]
276    then
277        _shutdown_fuser $F_PID $F_MNT
278        if [ $? -ne 0 ]
279        then
280            ## Failed to shutdown
281            INVALID_FUSES[${#INVALID_FUSES[*]}]="STIL RUN: PID=$F_PID MPOINT=$F_MNT"
282        else
283            _remove_dir $F_TEST_DIR
284        fi
285    else
286        _check_dir_mounted $F_MNT
287        if [ $? -eq 0 ]
288        then
289            /bin/fusermount -u $F_MNT
290
291            _check_dir_mounted $F_MNT
292            if [ $? -eq 0 ]
293            then
294                INVALID_FUSES[${#INVALID_FUSES[*]}]="STIL RUN: MPOINT=$F_MNT"
295            else
296                _remove_dir $F_TEST_DIR
297            fi
298        else
299            _remove_dir $F_TEST_DIR
300        fi
301    fi
302}
303
304_clean_test_data ()
305{
306    DPD=$1
307
308    ps -p $DPD > /dev/null 2>&1
309    if [ $? -eq 0 ]
310    then
311        _msg Process with PID = $DPD is still running
312        return
313    fi
314
315    _clean_data_for_pid $DPD
316}
317
318for i in ` ls $H_TEST_DIR 2>/dev/null `
319do
320    _clean_test_data $i
321done
322
323####
324### SANITY CHECK
325##
326#
327_bump
328_msg SANITY CHECK
329
330_check_sanity ()
331{
332    N2C=$1
333
334    for i in $U_VALID
335    do
336        if [ "$i" == "$N2C" ]
337        then
338            return 0
339        fi
340    done
341
342    /usr/bin/nslookup $N2C >/dev/null 2>&1
343    if [ $? -eq 0 ]
344    then
345        return 0
346    fi
347
348    return 1
349}
350
351_check_sanity_remove ()
352{
353    SDR=$1
354
355    ENT=$U_TEST_DIR/$SDR
356
357    _check_sanity $SDR
358    if [ $? -eq 0 ]
359    then
360        _msg LEGIT: $ENT
361    else
362        _msg REMOVING: $ENT
363        _exec_plain rm -rf $ENT
364        if [ $? -ne 0 ]
365        then
366            _msg Failed to remove $ENT
367            sleep 3
368            _msg Another attempt to remove $ENT
369            _exec_plain rm -rf $ENT
370            if [ $? -ne 0 ]
371            then
372                INVALID_FUSES[${#INVALID_FUSES[*]}]="CAN NOT REMOVE: $ENT"
373            fi
374        fi
375    fi
376}
377
378for i in ` ls $U_TEST_DIR 2>/dev/null `
379do
380    _check_sanity_remove $i
381done
382
383####
384### REPORTING EXITING
385##
386#
387_bump
388_msg CLEANING COMPLETED
389
390PQT=${#INVALID_FUSES[*]}
391
392_msg FOUND $PQT PROBLEMS
393
394if [ $PQT -ne 0 ]
395then
396    CNT=0
397    while [ $CNT -lt $PQT ]
398    do
399        CNT=$(( $CNT + 1 ))
400        _msg "  $CNT: ${INVALID_FUSES[$CNT]}"
401    done
402fi
403
404_msg BYE ...
405