]> git.proxmox.com Git - pve-container.git/commitdiff
fix and improve bindmount tests
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 3 Jun 2016 07:54:04 +0000 (09:54 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 3 Jun 2016 07:56:23 +0000 (09:56 +0200)
fixed leftover mounts after running the tests
added another testcase:
  inject symlink before mount() and restore before verify()

src/test/bindmount_test.pl

index a6052dbda33890f76de5747c6fbfe01fcf56acd5..83152e97edde54cf7a4697eb836b2623befbeda6 100755 (executable)
@@ -20,23 +20,29 @@ my $a        = "/tmpshare/a";
 my $ab       = "/tmpshare/a/b";
 my $abc      = "/tmpshare/a/b/c";
 my $sym      = "/tmpshare/sym";
 my $ab       = "/tmpshare/a/b";
 my $abc      = "/tmpshare/a/b/c";
 my $sym      = "/tmpshare/sym";
+my $tmp      = "/tmpshare/tmp";
 
 my $secret = "/secret";
 
 
 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});
     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) };
 
 # 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 {
 
 # 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) =
 
     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) {
     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);
     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 !$@;
 }
 
 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.
 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 !$@;
 # __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, 1) };
+die "injected symlink bindmount went through\n" if !$@;
+die "unexpected test error: $@\n" if $@ ne "bindmount verification failed\n";