[pve-devel] [PATCH container] fix and improve bindmount tests

Wolfgang Bumiller w.bumiller at proxmox.com
Fri Jun 3 09:26:30 CEST 2016


fixed leftover mounts after running the tests
added another testcase:
  inject symlink before mount() and restore before verify()
---
 src/test/bindmount_test.pl | 66 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 47 insertions(+), 19 deletions(-)

diff --git a/src/test/bindmount_test.pl b/src/test/bindmount_test.pl
index a6052db..0d8dfd1 100755
--- a/src/test/bindmount_test.pl
+++ b/src/test/bindmount_test.pl
@@ -20,23 +20,29 @@ my $a        = "/tmpshare/a";
 my $ab       = "/tmpshare/a/b";
 my $abc      = "/tmpshare/a/b/c";
 my $sym      = "/tmpshare/sym";
+my $tmp      = "/tmpshare/tmp";
 
 my $secret = "/secret";
 
-END {
+END { cleanup(); };
+sub cleanup {
     my $ignore_error;
     File::Path::rmtree("$pwd/$rootdir", {error => \$ignore_error});
     File::Path::rmtree("$pwd/$sharedir", {error => \$ignore_error});
     File::Path::rmtree("$pwd/$secret", {error => \$ignore_error});
-};
+}
+
+sub setup {
+    # Create all the test paths...
+    PVE::LXC::walk_tree_nofollow('.', $rootdir, 1);
+    PVE::LXC::walk_tree_nofollow($rootdir, $destdir, 1);
+    PVE::LXC::walk_tree_nofollow('.', $abc, 1);
+    PVE::LXC::walk_tree_nofollow('.', $secret, 1);
+    # Create one evil symlink
+    symlink('a/b', "$pwd/$sym") or die "failed to prepare test folders: $!\n";
+}
 
-# Create all the test paths...
-PVE::LXC::walk_tree_nofollow('.', $rootdir, 1);
-PVE::LXC::walk_tree_nofollow($rootdir, $destdir, 1);
-PVE::LXC::walk_tree_nofollow('.', $abc, 1);
-PVE::LXC::walk_tree_nofollow('.', $secret, 1);
-# Create one evil symlink
-symlink('a/b', "$pwd/$sym") or die "failed to prepare test folders: $!\n";
+setup();
 
 # Test walk_tree_nofollow:
 eval { PVE::LXC::walk_tree_nofollow('.', $rootdir, 0) };
@@ -47,7 +53,7 @@ die "unexpected test error: '$@'\n" if $@ ne "symlink encountered at: .$sym\n";
 
 # Bindmount testing:
 sub bindmount {
-    my ($from, $rootdir, $destdir, $inject, $ro, $inject_write) = @_;
+    my ($from, $rootdir, $destdir, $inject, $ro, $inject_write, $restore) = @_;
 
     my ($mpath, $mpfd, $parentfd, $last);
     ($rootdir, $mpath, $mpfd, $parentfd, $last) =
@@ -56,21 +62,36 @@ sub bindmount {
     my $srcdh = PVE::LXC::__bindmount_prepare('.', $from);
 
     if ($inject) {
-        File::Path::rmtree(".$inject");
-        symlink("$pwd/$secret", ".$inject")
-            or die "failed to create symlink\n";
-        PVE::LXC::walk_tree_nofollow('.', $from, 1);
+	if ($restore) {
+	    rename(".$inject", ".$tmp")
+		or die "failed to move directory: $!\n";
+	} else {
+	    File::Path::rmtree(".$inject");
+	}
+	symlink("$pwd/$secret", ".$inject")
+	    or die "failed to create symlink\n";
+	File::Path::mkpath(".$from");
     }
-    PVE::LXC::__bindmount_do(".$from", $mpath, $inject_write ? 0 : $ro);
-
-    my $res = PVE::LXC::__bindmount_verify($srcdh, $parentfd, $last, $ro);
-
+    eval {
+	PVE::LXC::__bindmount_do(".$from", $mpath, $inject_write ? 0 : $ro);
+
+	if ($restore) {
+	    unlink(".$inject") or die "failed to restore path: $!\n";
+	    rename(".$tmp", ".$inject") or die "failed to restore path: $!\n";
+	}
+
+	PVE::LXC::__bindmount_verify($srcdh, $parentfd, $last, $ro)
+	    or die "bindmount verification failed\n";
+    };
+    my $err = $@;
     system('umount', $mpath);
+    die $err if $err;
 }
 
 bindmount($a, $rootdir, $destdir, undef, 0, 0);
 eval { bindmount($sym, $rootdir, $destdir, undef, 0, 0) };
 die "illegal symlink bindmount went through\n" if !$@;
+die "unexpected test error: $@\n" if $@ ne "symlink encountered at: .$sym\n";
 bindmount($abc, $rootdir, $destdir, undef, 0, 0);
 # Race test: Assume someone exchanged 2 equivalent bind mounts between and
 # after the bindmount_do()'s mount and remount calls.
@@ -86,4 +107,11 @@ die "unexpected test error: $@\n" if $@ ne "failed to mark bind mount read only\
 # __bindmount_do().
 eval { bindmount($abc, $rootdir, $destdir, $ab, 0, 0) };
 die "injected symlink bindmount went through\n" if !$@;
-die "unexpected test error: $@\n" if $@ ne "symlink encountered at: .$ab\n";
+die "unexpected test error: $@\n" if $@ ne "bindmount verification failed\n";
+# Restore setup:
+cleanup();
+setup();
+# Race test 2: As above but also reset the symlink back after __bindmount_do()
+eval { bindmount($abc, $rootdir, $destdir, $ab, 0, 0) };
+die "injected symlink bindmount went through\n" if !$@;
+die "unexpected test error: $@\n" if $@ ne "bindmount verification failed\n";
-- 
2.1.4




More information about the pve-devel mailing list