[pve-devel] [PATCH v2 container] fix and improve bindmount tests
Wolfgang Bumiller
w.bumiller at proxmox.com
Fri Jun 3 09:54:04 CEST 2016
fixed leftover mounts after running the tests
added another testcase:
inject symlink before mount() and restore before verify()
---
changes since v2:
added missing parameter for the last testcase
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..83152e9 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, 1) };
+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