summaryrefslogtreecommitdiff
path: root/src/pmlogger/pmlogmv.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmlogger/pmlogmv.sh')
-rwxr-xr-xsrc/pmlogger/pmlogmv.sh261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/pmlogger/pmlogmv.sh b/src/pmlogger/pmlogmv.sh
new file mode 100755
index 0000000..7a07098
--- /dev/null
+++ b/src/pmlogger/pmlogmv.sh
@@ -0,0 +1,261 @@
+#!/bin/sh
+#
+# Copyright (c) 1997,2003 Silicon Graphics, Inc. All Rights Reserved.
+# Copyright (c) 2013-2014 Red Hat.
+# Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# Move (rename) a PCP archive.
+#
+# Operation is atomic across the multiple files of a PCP archive
+#
+
+. $PCP_DIR/etc/pcp.env
+
+status=1
+tmp=`mktemp -d /tmp/pcp.XXXXXXXXX` || exit 1
+trap "rm -rf $tmp; exit \$status" 0
+trap "_cleanup; rm -rf $tmp; exit \$status" 1 2 3 15
+prog=`basename $0`
+
+cat > $tmp/usage << EOF
+# Usage: [options] oldname newname
+
+Options:
+ -N, --showme perform a dry run, showing what would be done
+ -V, --verbose increase diagnostic verbosity
+ --help
+EOF
+
+_usage()
+{
+ pmgetopt --progname=$prog --config=$tmp/usage --usage
+ exit 1
+}
+
+verbose=false
+showme=false
+LN=ln
+RM=rm
+RMF="rm -f"
+
+ARGS=`pmgetopt --progname=$prog --config=$tmp/usage -- "$@"`
+[ $? != 0 ] && exit 1
+
+eval set -- "$ARGS"
+while [ $# -gt 0 ]
+do
+ case "$1"
+ in
+ -N) # show me
+ showme=true
+ LN='echo >&2 + ln'
+ RM='echo >&2 + rm'
+ RMF='echo >&2 + rm -f'
+ ;;
+ -V) # verbose
+ verbose=true
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -\?)
+ _usage
+ # NOTREACHED
+ ;;
+ esac
+ shift
+done
+
+if [ $# -ne 2 ]
+then
+ _usage
+ # NOTREACHED
+fi
+
+if [ -f "$1" ]
+then
+ # oldname is an existing file, strip the expected PCP suffix
+ #
+ case "$1"
+ in
+ *[0-9])
+ old=`echo "$1" | sed -e 's/\.[0-9][0-9]*$//'`
+ ;;
+ *.index|*.meta)
+ old=`echo "$1" | sed -e 's/\.[a-z][a-z]*$//'`
+ ;;
+ *)
+ echo >&2 "$prog: Error: oldname argument ($1) is not a PCP archive"
+ exit
+ ;;
+ esac
+else
+ old="$1"
+fi
+new="$2"
+
+_cleanup()
+{
+ if [ -f $tmp/old ]
+ then
+ for f in `cat $tmp/old`
+ do
+ if [ ! -f "$f" ]
+ then
+ part=`echo "$f" | sed -e 's/.*\.\([^.][^.]*\)$/\1/'`
+ if [ ! -f "$new.$part" ]
+ then
+ echo >&2 "$prog: Fatal: $f and $new.$part lost"
+ ls -l "$old"* "$new"*
+ rm -f $tmp/old
+ return
+ fi
+ $verbose && echo >&2 "cleanup: recover $f from $new.$part"
+ if eval $LN "$new.$part" "$f"
+ then
+ :
+ else
+ echo >&2 "$prog: Fatal: ln $new.$part $f failed!"
+ ls -l "$old"* "$new"*
+ rm -f $tmp/old
+ return
+ fi
+ fi
+ done
+ fi
+ if [ -f $tmp/new ]
+ then
+ for f in `cat $tmp/new`
+ do
+ $verbose && echo >&2 "cleanup: remove $f"
+ eval $RMF "$f"
+ done
+ rm -f $tmp/new
+ fi
+ exit
+}
+
+# get oldnames inventory check required files are present
+#
+ls "$old".* 2>&1 | egrep '\.(index|meta|[0-9][0-9]*)$' >$tmp/old
+if [ -s $tmp/old ]
+then
+ # $old may be an ambiguous suffix, e.g. 20140417.00 (with more than
+ # one .HH archives) ... pick the suffixes and make sure there are
+ # no duplicates
+ #
+ touch $tmp/ok
+ sed <$tmp/old \
+ -e 's/.*\.index$/index/' \
+ -e 's/.*\.meta$/meta/' \
+ -e 's/.*\.\([0-9][0-9]*\)$/\1/' \
+ | sort \
+ | uniq -c \
+ | while read c x
+ do
+ case $c
+ in
+ 1)
+ ;;
+ *)
+ echo >&2 "$prog: Error: oldname argument ($old) is a prefix for multiple PCP archive files:"
+ grep "\\.$x\$" $tmp/old | sed -e 's/^/ /' >&2
+ rm -f $tmp/ok
+ ;;
+ esac
+ done
+ [ -f $tmp/ok ] || exit
+else
+ echo >&2 "$prog: Error: cannot find any files for the input archive ($old)"
+ exit
+fi
+if grep -q '.[0-9][0-9]*$' $tmp/old
+then
+ :
+else
+ echo >&2 "$prog: Error: cannot find any data files for the input archive ($old)"
+ ls -l "$old"*
+ exit
+fi
+if grep -q '.meta$' $tmp/old
+then
+ :
+else
+ echo >&2 "$prog: Error: cannot find .metadata file for the input archive ($old)"
+ ls -l "$old"*
+ exit
+fi
+
+# (hard) link oldnames and newnames
+#
+for f in `cat $tmp/old`
+do
+ if [ ! -f "$f" ]
+ then
+ echo >&2 "$prog: Error: ln-pass: input file vanished: $f"
+ ls -l "$old"* "$new"*
+ _cleanup
+ # NOTREACHED
+ fi
+ part=`echo "$f" | sed -e 's/.*\.\([^.][^.]*\)$/\1/'`
+ if [ -f "$new.$part" ]
+ then
+ echo >&2 "$prog: Error: ln-pass: output file already exists: $new.$part"
+ ls -l "$old"* "$new"*
+ _cleanup
+ # NOTREACHED
+ fi
+ $verbose && echo >&2 "link $f -> $new.$part"
+ echo "$new.$part" >>$tmp/new
+ if eval $LN "$f" "$new.$part"
+ then
+ :
+ else
+ echo >&2 "$prog: Error: ln $f $new.$part failed!"
+ ls -l "$old"* "$new"*
+ _cleanup
+ # NOTREACHED
+ fi
+done
+
+# unlink oldnames provided link count is 2
+#
+for f in `cat $tmp/old`
+do
+ if [ ! -f "$f" ]
+ then
+ echo >&2 "$prog: Error: rm-pass: input file vanished: $f"
+ ls -l "$old"* "$new"*
+ _cleanup
+ # NOTREACHED
+ fi
+ links=`stat $f | sed -n -e '/Links:/s/.*Links:[ ]*\([0-9][0-9]*\).*/\1/p'`
+ xpect=2
+ $showme && xpect=1
+ if [ -z "$links" -o "$links" != $xpect ]
+ then
+ echo >&2 "$prog: Error: rm-pass: link count "$links" (not $xpect): $f"
+ ls -l "$old"* "$new"*
+ _cleanup
+ fi
+ $verbose && echo >&2 "remove $f"
+ if eval $RM "$f"
+ then
+ :
+ else
+ echo >&2 "$prog: Warning: rm $f failed!"
+ fi
+done
+
+status=0