3 # remove_changelog: emergency remove changelog files from server.
5 # This is emergency tool to cleanup changelogs in server if changelog
6 # records cannot be removed by regular means, e.g. due to llog corruptions
8 # Tool goes through changelog_catalog and removes all plain llogs listed
9 # then removes changelog_catalog itself and changelog_users
10 # Script accept single parameter which is mount point of server FS mounted
11 # locally, script accepts also --dry-run option to emulate files removal
13 # Steps to cleanup problematic llogs:
15 # 1. mount MDT filesystem locally on server as ldiskfs mount
16 # 2. run script first in dry-run mode to make sure it parses llogs as needed:
17 # # bash remove_changelog -n <ldiskfs_mount>
18 # 3. save all llogs for analysis:
19 # # bash remove_changelog -n -z /tmp/llogs_saved <ldiskfs_mount>
20 # 4. check that /tmp/llogs_saved.tar.gz exists and has all llogs inside:
21 # # ls -ali /tmp/llogs_saved.tar.gz
22 # # tar -tf /tmp/llog_saved.tar.gz
23 # 5. finally run script to delete all llogs:
24 # # bash remove_changelog <ldiskfs_mount>
26 # For better llogs compression xz can be used as well, pass it to the script
27 # via GZIP env variable:
28 # # GZIP=xz bash remove_changelog -n -z /tmp/llogs_saved <ldiskfs_mount>
29 # Archive name will ends with .xz in that case instead of .gz
36 LLOG_READER=${LLOG_READER:-llog_reader}
41 usage: remove_changelog [--dry-run|-n] [--help|-h] [--quiet|-q]
42 [--zip}-z] <archive> <localmount>
43 --help|-h show this usage message
44 --dry-run|-n only print the names of files to be removed
45 --quiet|-q run quietly (don't print filenames or status)
46 --zip|-z <name_prefix>
47 save all llogs into compressed tar archive with given
48 name prefix using gzip by default. Other compression
49 tools can be used via GZIP env variable.
51 The 'localmount' argument should be an ldiskfs mounted MDT device mountpoint.
54 remove_changelog /mnt/mdt0
55 remove_changelog --dry-run /mnt/mdt0
56 remove_changelog -z /tmp/llogs /mnt/mdt0
65 # Examine any long options and arguments
70 -n|--dry-run) OPT_DRYRUN=true;;
72 -z|--zip) OPT_ARCH="$2.tar"; shift;;
74 [ -d "$arg" ] && OPT_MOUNT="$arg";;
80 local mntpoint=$OPT_MOUNT
81 local catalog=${mntpoint}/changelog_catalog
82 local users=${mntpoint}/changelog_users
85 if [[ -z $(df -t ldiskfs $mntpoint 2>/dev/null) ]] ; then
86 echo "$PROG: '$mntpoint' is not ldiskfs mount."
91 $ECHO "Dry run was requested, no changes will be applied"
94 $ECHO "Scan changelog_catalog at '$mntpoint':"
95 if [[ ! -f $catalog ]] ; then
96 echo "$PROG: $catalog doesn't exist already."
98 if [[ ! $(which $LLOG_READER 2>/dev/null) ]] ; then
99 echo "$PROG: $LLOG_READER is missing."
102 [[ -z $arch ]] || tar -cf $arch $catalog 2>/dev/null
103 if (( $(stat -c %s $catalog) >= 8192 )) ; then
104 while read -r path ; do
106 tar -rf $arch ${mntpoint}/$path 2>/dev/null
107 $ECHO "rm ${mntpoint}/$path"
108 $OPT_DRYRUN || rm -f ${mntpoint}/$path
109 done < <($LLOG_READER $catalog |
110 awk -F "path=" '/path=/ { print $2 }')
112 echo "$PROG: $catalog is too small."
115 $OPT_DRYRUN || > $catalog
118 if [[ -f $users ]] ; then
119 [[ -z $arch ]] || tar -rf $arch $users 2>/dev/null
121 $OPT_DRYRUN || > $users
123 echo "$PROG: $user doesn't exist."
125 if [[ "$arch" ]] ; then
127 $ECHO "llog archive was created by $GZIP"
131 if [ -z $OPT_MOUNT ] ; then
132 echo "Mount is not specified, exiting"