new package aufs2-util
[openadk.git] / package / aufs2-util / src / aubrsync
blob54adac9cb27edc87bbc45ce3a61192dfb1d5d5c2
1 #!/bin/sh
3 # Copyright (C) 2005-2009 Junjiro Okajima
5 # This program, aufs is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 # The development of this script is sponcered by ASUSTek Computer Inc.
21 # Kindly they agreed that I keep my aufs work as free software as it has
22 # been.
25 set -eu
26 #set -x
28 me=$(basename $0)
29 EEcho() # str
31 echo ${me}: $@ 1>&2
34 f=/sbin/mount.aufs
35 test ! -x $f && EEcho $f is not installed && exit 1
37 # special handling for backward compatibility.
39 # aufs in the donated eeepc is aufs1 20080211 without CONFIG_AUFS_COMPAT.
40 # /etc/default/aufs was introduced in aufs1 20080922.
41 # shwh/noshwh was introduced in aufs1 20080310 with CONFIG_AUFS_SHWH.
42 # noshwh became always available regardless CONFIG_AUFS_SHWH in aufs1 20081117.
44 noshwh=1
45 AUFS_VERSION=20080211
46 f=/etc/default/aufs
47 if [ -s $f ]
48 then
49 . $f
50 else
51 echo ${me}: warning, broken $f, assuming aufs is $AUFS_VERSION
52 f=/usr/lib/aufs.shlib
53 test ! -s $f && EEcho $f is not installed && exit 1
54 . $f
56 case $AUFS_VERSION in
57 200*) # aufs1
58 test $AUFS_VERSION -lt 20081117 && noshwh=0
60 esac
61 AUFS_SUPER_MAGIC=1635083891
62 AUFS_SUPER_MAGIC_HEX=0x61756673
63 AUFS_WH_PFX=.wh.
64 AUFS_WH_PFX2=.wh..wh.
65 AUFS_WH_DIROPQ=.wh..wh..opq
68 ########################################
70 _Rsync="rsync --exclude=lost+found"
71 Rsync="$_Rsync -aHSx --devices --specials --delete-before"
72 Copy="$Rsync"
73 Move="$Copy"
74 RsyncWh="$_Rsync -ptgoHx"
76 FindForRm() # rw
78 echo "find \"$1\" -xdev -depth \(
79 \( ! -type d
80 \( -name $AUFS_WH_DIROPQ
81 -o ! -name ${AUFS_WH_PFX2}\* \) \)
82 -o \( -type d
83 ! -name ${AUFS_WH_PFX2}\*
84 ! -wholename \"$1\"
85 ! -wholename \"$1/lost+found\" \)
86 \) -print0"
89 MoveWh() # rw ro+wh
91 cd "$1"
92 find . -xdev -name ${AUFS_WH_PFX}\* ! -name ${AUFS_WH_PFX2}\* \
93 -printf '%P\n' |
94 while read wh
96 f=$(echo "$wh" | sed -e '
97 s/^'${AUFS_WH_PFX}'//
99 s:/'${AUFS_WH_PFX}':/:
101 test -e "$dst/$f" || echo "$wh"
102 done |
103 # -v
104 $RsyncWh --files-from=- ./ "$2"
105 cd "$OLDPWD"
108 copy()
110 $Copy $@ "$mntpnt"/ "$dst"
113 _move()
115 set +x
116 test $hinotify -ne 1 && echo ${me}: warning, -i is not specified
117 src_is_nfs=0
118 test $(stat -f -c %T "$src") = nfs && src_is_nfs=1
119 set $quiet
121 $Move $@ &&
122 eval $(FindForRm "$src") |
124 if [ $src_is_nfs -eq 1 ]
125 then
126 mount -o remount "$mntpnt"
127 mount -o remount "$src"
129 xargs -r0 rm -fr #-v
133 move()
135 _move $@ "$mntpnt"/ "$dst"
138 move_with_wh()
141 set +x
142 MoveWh "$src" "$dst"
143 set $quiet
144 } &&
145 move --exclude=${AUFS_WH_PFX}\*
148 # backward compatibility
149 move_w()
151 move_with_wh $@
154 Usage()
156 t=$(FindForRm src_branch | sed -e '
157 s/"//g
159 s/$/ \\/')
161 cat <<- EOF
162 $me Options move | move_with_wh | copy \\
163 mntpnt src_branch dst_branch [ options for rsync ]
165 generic form:
166 $me [ -w | --wh ] [ -i | --inotify ] Options \\
167 mntpnt cmd [ parameters for cmd ]
169 Options:
170 [ -n | --dry_run ]
171 [ -q | --quiet ]
173 The dst_branch must be mounted as writable.
174 During the operation, the mntpnt is set readonly.
175 If you are opening a file for writing on the writable branch,
176 you need to close the file before invoking this script.
177 The -w or --wh option requires CONFIG_AUFS_SHWH enabled.
178 The -i or --inotify option requires CONFIG_AUFS_HINOTIFY enabled.
180 'copy' is a shortcut for
181 $me mntpnt \\
182 $Copy mntpnt/ dst_branch
183 'move' is a shortcut for
184 $me mntpnt \\
185 "$Move \\
186 mntpnt/ dst_branch && \\
187 $t |\\
188 xargs -r0 rm -fr"
189 Note: in most cases, you will need '-i' option, and
190 find(1) is invoked by $me only when rsync(1)
191 succeded.
192 'move_with_wh' is a simple variation of 'move' which moves
193 whiteouts separately before the actual 'move'.
195 If you execute this script under linux-2.6.24 or earlier, the
196 kernel may produce a harmless warning "inotify.c:NNN
197 set_dentry_child_flags()". The message was already removed in
198 linux-2.6.25.
200 examples:
201 - Copy and reflect all the modification (modifed files, newly
202 created and removed ones) in the upper branch to the lower
203 branch. This operation is for aufs which has only 2 branches,
204 and mainly for a system shutdown script.
205 All files on the upper branch remain.
207 $ sudo $me copy /your/aufs /your/upper_branch /your/lower_branch
209 - Like above (2 branches), move and reflect all modifications
210 from upper to lower. Almost all files on the upper branch will
211 be removed. You can still use this aufs after the
212 operation. But the inode number may be changed. If your
213 application which depends upon the inode number was running at
214 that time, it may not work correctly.
216 $ sudo $me move /your/aufs /your/upper_branch /your/lower_branch
219 # - Like above (2 branches), generate a new middle layer like a
220 # snapshot including whiteouts and make the upper_branch almost
221 # empty, but untouch the lower_branch.
223 # $ img=/hda1/a.ext2
224 # $ dd if=/dev/zero of=\$img bs=4k count=1k
225 # $ mkfs -t ext2 -F \$img
226 # $ sudo mount -o rw,loop \$img /your/new_branch
227 # $ sudo mount -o remount,ins:1:/your/new_branch=ro+wh /your/aufs
228 # $ sudo $me _move /your/aufs /your/upper_branch /your/lower_branch \\
229 # "--remove-source-files \\
230 # --exclude=$AUFS_WH_BASE \\
231 # --exclude=$AUFS_WH_PLINKDIR \\
232 # --exclude=$AUFS_WH_TMPDIR \\
233 # /your/upper_branch/ /your/new_branch; \\
234 # mount -o remount,ro /your/new_branch"
235 # EOF
238 ########################################
240 wh=0
241 hinotify=0
242 quiet=-x
243 dry_run=
244 cmd=
245 cmd_opts=
246 for i
248 case $i in
249 -w|--wh) wh=1;;
250 -i|--inotify) hinotify=1;;
251 -n|--dry_run) dry_run=echo;;
252 -q|--quiet) quiet=+x;;
253 -h|--help) Usage; exit 0;;
254 --) shift; break;;
255 *) break;;
256 esac
257 shift
258 done
260 test $# -lt 2 && Usage 1>&2 && exit 1
261 case "$1" in
262 _move|move|copy|move_w|move_with_wh)
263 test $# -lt 4 && Usage 1>&2 && exit 1
264 cmd=$1
265 SetDir mntpnt "$2"
266 SetDir src "$3"
267 SetDir dst "$4"
268 shift 4
269 wh=0
272 SetDir mntpnt "$1"
273 cmd="$2"
274 shift 2
276 esac
277 cmd_opts="$@"
279 case $(stat -f -c %T "$mntpnt") in
280 aufs|UNKNOWN*${AUFS_SUPER_MAGIC_HEX}*) ;;
282 EEcho "$mntpnt" is not aufs
283 exit 1
285 esac
287 cur_opts=$(MntOpts "$mntpnt")
288 test ! "$cur_opts" &&
289 EEcho bad /proc/mounts or "$mntpnt" is not mounted &&
290 exit 1
291 cur_opts="udba=reval,noshwh,$cur_opts"
292 test $noshwh -eq 0 && cur_opts=$(echo $cur_opts | sed -e 's/,noshwh//')
294 # force flushing the pusedo-links
295 tmp_opts="remount,ro,udba=reval,noshwh"
296 test $noshwh -eq 0 && tmp_opts=$(echo $tmp_opts | sed -e 's/,noshwh//')
297 test $wh -eq 1 && tmp_opts="$tmp_opts,shwh"
298 test $hinotify -eq 1 && tmp_opts="$tmp_opts,udba=inotify"
300 # here we go
301 trap "$dry_run mount -o remount,$cur_opts \"$mntpnt\"" EXIT
302 set $quiet
303 $dry_run mount -o $tmp_opts "$mntpnt"
304 eval "$dry_run $cmd $cmd_opts"