]> arthur.barton.de Git - bup.git/commitdiff
Change -x/--xdev/--one-filesystem to include the mount point itself.
authorRob Browning <rlb@defaultvalue.org>
Tue, 24 Dec 2013 02:10:49 +0000 (20:10 -0600)
committerRob Browning <rlb@defaultvalue.org>
Sat, 25 Jan 2014 21:49:13 +0000 (15:49 -0600)
Match rsync, tar, etc., and add and use t/cleanup-mounts-under to
clean up all temporary mounts under t/mnt and t/tmp.

Thanks to Karl Kiniger <karl.kiniger@med.ge.com> for the report.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Karl Kiniger <karl.kiniger@med.ge.com>
Documentation/bup-drecurse.md
Documentation/bup-index.md
Documentation/bup-meta.md
Makefile
lib/bup/drecurse.py
t/cleanup-mounts-under [new file with mode: 0755]
t/test-xdev.sh [new file with mode: 0755]

index 46920257d329db7f95d7f100b11163bf485afc5e..2a36362713c605c4e6b49dd9a9b3e8a9035116ae 100644 (file)
@@ -30,7 +30,8 @@ come after its children, making this easy.
 # OPTIONS
 
 -x, \--xdev, \--one-file-system
-:   don't cross filesystem boundaries.
+:   don't cross filesystem boundaries -- though as with tar and rsync,
+    the mount points themselves will still be reported.
 
 -q, \--quiet
 :   don't print filenames as they are encountered.  Useful
index a5404448c8b321fbe8055f56e6d49715fd17e673..003548f53871346f8b45f846441d883d508ad1e0 100644 (file)
@@ -121,9 +121,10 @@ does, due to the accommodations described above.
     format to the `-l` option to `ls`(1).
 
 -x, \--xdev, \--one-file-system
-:   don't cross filesystem boundaries when recursing
-    through the filesystem.  Only applicable if you're
-    using `-u`.
+:   don't cross filesystem boundaries when recursing through the
+    filesystem -- though as with tar and rsync, the mount points
+    themselves will still be indexed.  Only applicable if you're using
+    `-u`.
     
 \--fake-valid
 :   mark specified filenames as up-to-date even if they
index 00096ddea16485a5ffd9660e7159cdd3ff26abe8..c8d1d3769ed6e0ce4c33d49f1fc3eee6020a0e03 100644 (file)
@@ -80,6 +80,10 @@ is restored.
 -R, \--recurse
 :   Recursively descend into subdirectories during `--create`.
 
+\--xdev, \--one-file-system
+:   don't cross filesystem boundaries -- though as with tar and rsync,
+    the mount points themselves will still be handled.
+
 \--numeric-ids
 :   Apply numeric IDs (user, group, etc.) rather than names during
     `--extract` or `--finish-extract`.
index 2835005b2218fcd2441a507c125d7331531d5a7b..34f227a1eaf0355873c54db9e202418c96a28aab 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -102,6 +102,7 @@ runtests-cmdline: all
        TMPDIR="$(test_tmp)" t/test-save-restore-excludes.sh
        TMPDIR="$(test_tmp)" t/test-save-strip-graft.sh
        TMPDIR="$(test_tmp)" t/test-import-rdiff-backup.sh
+       TMPDIR="$(test_tmp)" t/test-xdev.sh
        TMPDIR="$(test_tmp)" t/test.sh
 
 stupid:
@@ -172,8 +173,9 @@ clean: Documentation/clean config/clean
                bup bup-* cmd/bup-* lib/bup/_version.py randomgen memtest \
                out[12] out2[tc] tags[12] tags2[tc] \
                testfs.img lib/bup/t/testfs.img
-       umount t/mnt/* || true
+       if test -e t/mnt; then t/cleanup-mounts-under t/mnt; fi
        if test -e t/mnt; then rm -r t/mnt; fi
+       if test -e t/tmp; then t/cleanup-mounts-under t/tmp; fi
         # FIXME: migrate these to t/mnt/
        if test -e bupmeta.tmp/testfs; \
          then umount bupmeta.tmp/testfs || true; fi
index 694c403594d1aec45c6979629c20314fd4c948ea..6be7fa2ff38f8ff7bd6de1d87e9536372c9448fe 100644 (file)
@@ -61,25 +61,25 @@ def _recursive_dirlist(prepend, xdev, bup_dir=None,
         if exclude_rxs and should_rx_exclude_path(path, exclude_rxs):
             continue
         if name.endswith('/'):
-            if xdev != None and pst.st_dev != xdev:
-                debug1('Skipping %r: different filesystem.\n' % (prepend+name))
-                continue
             if bup_dir != None:
-                if os.path.normpath(prepend+name) == bup_dir:
+                if os.path.normpath(path) == bup_dir:
                     debug1('Skipping BUP_DIR.\n')
                     continue
-            try:
-                OsFile(name).fchdir()
-            except OSError, e:
-                add_error('%s: %s' % (prepend, e))
+            if xdev != None and pst.st_dev != xdev:
+                debug1('Skipping contents of %r: different filesystem.\n' % path)
             else:
-                for i in _recursive_dirlist(prepend=prepend+name, xdev=xdev,
-                                            bup_dir=bup_dir,
-                                            excluded_paths=excluded_paths,
-                                            exclude_rxs=exclude_rxs):
-                    yield i
-                os.chdir('..')
-        yield (prepend + name, pst)
+                try:
+                    OsFile(name).fchdir()
+                except OSError, e:
+                    add_error('%s: %s' % (prepend, e))
+                else:
+                    for i in _recursive_dirlist(prepend=prepend+name, xdev=xdev,
+                                                bup_dir=bup_dir,
+                                                excluded_paths=excluded_paths,
+                                                exclude_rxs=exclude_rxs):
+                        yield i
+                    os.chdir('..')
+        yield (path, pst)
 
 
 def recursive_dirlist(paths, xdev, bup_dir=None, excluded_paths=None,
diff --git a/t/cleanup-mounts-under b/t/cleanup-mounts-under
new file mode 100755 (executable)
index 0000000..6d5cb87
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+
+import os.path, re, subprocess, sys
+
+def mntent_unescape(x):
+    def replacement(m):
+        unescapes = {
+            "\\\\" : "\\",
+            "\\011" : "\t",
+            "\\012" : "\n",
+            "\\040" : " "
+        }
+        return unescapes.get(m.group(0))
+    return re.sub(r'(\\\\|\\011|\\012|\\040)', replacement, x)
+
+targets = sys.argv[1:]
+exit_status = 0
+for target in targets:
+    if not os.path.isdir(target):
+        print >> sys.stderr, target, 'is not a directory'
+        exit_status = 1
+        continue
+    top = os.path.realpath(target)
+    proc_mounts = open('/proc/mounts', 'r')
+    for line in proc_mounts:
+        _, point, _ = line.split(' ', 2)
+        point = mntent_unescape(point)
+        if top == point or os.path.commonprefix((top + '/', point)) == top + '/':
+            if subprocess.call(['umount', point]) != 0:
+                exit_status = 1
+
+sys.exit(exit_status)
diff --git a/t/test-xdev.sh b/t/test-xdev.sh
new file mode 100755 (executable)
index 0000000..18530f6
--- /dev/null
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+. ./wvtest-bup.sh
+
+set -o pipefail
+
+if [ $(t/root-status) != root ]; then
+    echo 'Not root: skipping xdev tests.'
+    exit 0 # FIXME: add WVSKIP.
+fi
+
+# These tests are only likely to work under Linux for now
+# (patches welcome).
+if ! [[ $(uname) =~ Linux ]]; then
+    echo 'Not Linux: skipping xdev tests.'
+    exit 0 # FIXME: add WVSKIP.
+fi
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS bup init
+WVPASS pushd "$tmpdir"
+
+WVSTART 'drecurse'
+
+WVPASS dd if=/dev/zero of=testfs.img bs=1M count=32
+WVPASS mkfs -F testfs.img # Don't care what type.
+WVPASS mkdir -p src/mnt/{a,b,c}
+WVPASS mount -o loop testfs.img src/mnt
+WVPASS mkdir -p src/mnt/x
+WVPASS touch src/1 src/mnt/2 src/mnt/x/3
+
+WVPASSEQ "$(bup drecurse src | grep -vF lost+found)" "src/mnt/x/3
+src/mnt/x/
+src/mnt/2
+src/mnt/
+src/1
+src/"
+
+WVPASSEQ "$(bup drecurse -x src)" "src/mnt/
+src/1
+src/"
+
+WVSTART 'index/save/restore'
+
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS mkdir src-restore
+WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+WVPASS test -d src-restore/src
+WVPASS "$top/t/compare-trees" -c src/ src-restore/src/
+
+WVPASS rm -r "$BUP_DIR" src-restore
+WVPASS bup init
+WVPASS bup index -x src
+WVPASS bup save -n src src
+WVPASS mkdir src-restore
+WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+WVPASS test -d src-restore/src
+WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | sort)" ".
+./1
+./mnt"
+
+WVPASS popd
+WVPASS umount "$tmpdir/src/mnt"
+WVPASS rm -r "$tmpdir"