diff options
Diffstat (limited to 'package/aufs2-util/src/aubrsync')
-rwxr-xr-x | package/aufs2-util/src/aubrsync | 304 |
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" |