summaryrefslogtreecommitdiff
path: root/package/aufs2-util/src/aubrsync
diff options
context:
space:
mode:
Diffstat (limited to 'package/aufs2-util/src/aubrsync')
-rwxr-xr-xpackage/aufs2-util/src/aubrsync304
1 files changed, 304 insertions, 0 deletions
diff --git a/package/aufs2-util/src/aubrsync b/package/aufs2-util/src/aubrsync
new file mode 100755
index 000000000..54adac9cb
--- /dev/null
+++ b/package/aufs2-util/src/aubrsync
@@ -0,0 +1,304 @@
+#!/bin/sh
+
+# Copyright (C) 2005-2009 Junjiro Okajima
+#
+# This program, aufs 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#
+# The development of this script is sponcered by ASUSTek Computer Inc.
+# Kindly they agreed that I keep my aufs work as free software as it has
+# been.
+#
+
+set -eu
+#set -x
+
+me=$(basename $0)
+EEcho() # str
+{
+ echo ${me}: $@ 1>&2
+}
+
+f=/sbin/mount.aufs
+test ! -x $f && EEcho $f is not installed && exit 1
+
+# special handling for backward compatibility.
+#
+# aufs in the donated eeepc is aufs1 20080211 without CONFIG_AUFS_COMPAT.
+# /etc/default/aufs was introduced in aufs1 20080922.
+# shwh/noshwh was introduced in aufs1 20080310 with CONFIG_AUFS_SHWH.
+# noshwh became always available regardless CONFIG_AUFS_SHWH in aufs1 20081117.
+
+noshwh=1
+AUFS_VERSION=20080211
+f=/etc/default/aufs
+if [ -s $f ]
+then
+ . $f
+else
+ echo ${me}: warning, broken $f, assuming aufs is $AUFS_VERSION
+ f=/usr/lib/aufs.shlib
+ test ! -s $f && EEcho $f is not installed && exit 1
+ . $f
+
+ case $AUFS_VERSION in
+ 200*) # aufs1
+ test $AUFS_VERSION -lt 20081117 && noshwh=0
+ ;;
+ esac
+ AUFS_SUPER_MAGIC=1635083891
+ AUFS_SUPER_MAGIC_HEX=0x61756673
+ AUFS_WH_PFX=.wh.
+ AUFS_WH_PFX2=.wh..wh.
+ AUFS_WH_DIROPQ=.wh..wh..opq
+fi
+
+########################################
+
+_Rsync="rsync --exclude=lost+found"
+Rsync="$_Rsync -aHSx --devices --specials --delete-before"
+Copy="$Rsync"
+Move="$Copy"
+RsyncWh="$_Rsync -ptgoHx"
+
+FindForRm() # rw
+{
+ echo "find \"$1\" -xdev -depth \(
+ \( ! -type d
+ \( -name $AUFS_WH_DIROPQ
+ -o ! -name ${AUFS_WH_PFX2}\* \) \)
+ -o \( -type d
+ ! -name ${AUFS_WH_PFX2}\*
+ ! -wholename \"$1\"
+ ! -wholename \"$1/lost+found\" \)
+ \) -print0"
+}
+
+MoveWh() # rw ro+wh
+{
+ cd "$1"
+ find . -xdev -name ${AUFS_WH_PFX}\* ! -name ${AUFS_WH_PFX2}\* \
+ -printf '%P\n' |
+ while read wh
+ do
+ f=$(echo "$wh" | sed -e '
+ s/^'${AUFS_WH_PFX}'//
+ t
+ s:/'${AUFS_WH_PFX}':/:
+ ')
+ test -e "$dst/$f" || echo "$wh"
+ done |
+ # -v
+ $RsyncWh --files-from=- ./ "$2"
+ cd "$OLDPWD"
+}
+
+copy()
+{
+ $Copy $@ "$mntpnt"/ "$dst"
+}
+
+_move()
+{
+ set +x
+ test $hinotify -ne 1 && echo ${me}: warning, -i is not specified
+ src_is_nfs=0
+ test $(stat -f -c %T "$src") = nfs && src_is_nfs=1
+ set $quiet
+
+ $Move $@ &&
+ eval $(FindForRm "$src") |
+ {
+ if [ $src_is_nfs -eq 1 ]
+ then
+ mount -o remount "$mntpnt"
+ mount -o remount "$src"
+ fi
+ xargs -r0 rm -fr #-v
+ }
+}
+
+move()
+{
+ _move $@ "$mntpnt"/ "$dst"
+}
+
+move_with_wh()
+{
+ {
+ set +x
+ MoveWh "$src" "$dst"
+ set $quiet
+ } &&
+ move --exclude=${AUFS_WH_PFX}\*
+}
+
+# backward compatibility
+move_w()
+{
+ move_with_wh $@
+}
+
+Usage()
+{
+ t=$(FindForRm src_branch | sed -e '
+ s/"//g
+ $b
+ s/$/ \\/')
+
+ cat <<- EOF
+ $me Options move | move_with_wh | copy \\
+ mntpnt src_branch dst_branch [ options for rsync ]
+
+ generic form:
+ $me [ -w | --wh ] [ -i | --inotify ] Options \\
+ mntpnt cmd [ parameters for cmd ]
+
+ Options:
+ [ -n | --dry_run ]
+ [ -q | --quiet ]
+
+ The dst_branch must be mounted as writable.
+ During the operation, the mntpnt is set readonly.
+ If you are opening a file for writing on the writable branch,
+ you need to close the file before invoking this script.
+ The -w or --wh option requires CONFIG_AUFS_SHWH enabled.
+ The -i or --inotify option requires CONFIG_AUFS_HINOTIFY enabled.
+
+ 'copy' is a shortcut for
+ $me mntpnt \\
+ $Copy mntpnt/ dst_branch
+ 'move' is a shortcut for
+ $me mntpnt \\
+ "$Move \\
+ mntpnt/ dst_branch && \\
+ $t |\\
+ xargs -r0 rm -fr"
+ Note: in most cases, you will need '-i' option, and
+ find(1) is invoked by $me only when rsync(1)
+ succeded.
+ 'move_with_wh' is a simple variation of 'move' which moves
+ whiteouts separately before the actual 'move'.
+
+ If you execute this script under linux-2.6.24 or earlier, the
+ kernel may produce a harmless warning "inotify.c:NNN
+ set_dentry_child_flags()". The message was already removed in
+ linux-2.6.25.
+
+ examples:
+ - Copy and reflect all the modification (modifed files, newly
+ created and removed ones) in the upper branch to the lower
+ branch. This operation is for aufs which has only 2 branches,
+ and mainly for a system shutdown script.
+ All files on the upper branch remain.
+
+ $ sudo $me copy /your/aufs /your/upper_branch /your/lower_branch
+
+ - Like above (2 branches), move and reflect all modifications
+ from upper to lower. Almost all files on the upper branch will
+ be removed. You can still use this aufs after the
+ operation. But the inode number may be changed. If your
+ application which depends upon the inode number was running at
+ that time, it may not work correctly.
+
+ $ sudo $me move /your/aufs /your/upper_branch /your/lower_branch
+ EOF
+
+# - Like above (2 branches), generate a new middle layer like a
+# snapshot including whiteouts and make the upper_branch almost
+# empty, but untouch the lower_branch.
+#
+# $ img=/hda1/a.ext2
+# $ dd if=/dev/zero of=\$img bs=4k count=1k
+# $ mkfs -t ext2 -F \$img
+# $ sudo mount -o rw,loop \$img /your/new_branch
+# $ sudo mount -o remount,ins:1:/your/new_branch=ro+wh /your/aufs
+# $ sudo $me _move /your/aufs /your/upper_branch /your/lower_branch \\
+# "--remove-source-files \\
+# --exclude=$AUFS_WH_BASE \\
+# --exclude=$AUFS_WH_PLINKDIR \\
+# --exclude=$AUFS_WH_TMPDIR \\
+# /your/upper_branch/ /your/new_branch; \\
+# mount -o remount,ro /your/new_branch"
+# EOF
+}
+
+########################################
+
+wh=0
+hinotify=0
+quiet=-x
+dry_run=
+cmd=
+cmd_opts=
+for i
+do
+ case $i in
+ -w|--wh) wh=1;;
+ -i|--inotify) hinotify=1;;
+ -n|--dry_run) dry_run=echo;;
+ -q|--quiet) quiet=+x;;
+ -h|--help) Usage; exit 0;;
+ --) shift; break;;
+ *) break;;
+ esac
+ shift
+done
+
+test $# -lt 2 && Usage 1>&2 && exit 1
+case "$1" in
+_move|move|copy|move_w|move_with_wh)
+ test $# -lt 4 && Usage 1>&2 && exit 1
+ cmd=$1
+ SetDir mntpnt "$2"
+ SetDir src "$3"
+ SetDir dst "$4"
+ shift 4
+ wh=0
+ ;;
+*)
+ SetDir mntpnt "$1"
+ cmd="$2"
+ shift 2
+ ;;
+esac
+cmd_opts="$@"
+
+case $(stat -f -c %T "$mntpnt") in
+aufs|UNKNOWN*${AUFS_SUPER_MAGIC_HEX}*) ;;
+*)
+ EEcho "$mntpnt" is not aufs
+ exit 1
+ ;;
+esac
+
+cur_opts=$(MntOpts "$mntpnt")
+test ! "$cur_opts" &&
+EEcho bad /proc/mounts or "$mntpnt" is not mounted &&
+exit 1
+cur_opts="udba=reval,noshwh,$cur_opts"
+test $noshwh -eq 0 && cur_opts=$(echo $cur_opts | sed -e 's/,noshwh//')
+
+# force flushing the pusedo-links
+tmp_opts="remount,ro,udba=reval,noshwh"
+test $noshwh -eq 0 && tmp_opts=$(echo $tmp_opts | sed -e 's/,noshwh//')
+test $wh -eq 1 && tmp_opts="$tmp_opts,shwh"
+test $hinotify -eq 1 && tmp_opts="$tmp_opts,udba=inotify"
+
+# here we go
+trap "$dry_run mount -o remount,$cur_opts \"$mntpnt\"" EXIT
+set $quiet
+$dry_run mount -o $tmp_opts "$mntpnt"
+eval "$dry_run $cmd $cmd_opts"