#!/usr/bin/perl
+use lib '..';
+
use strict;
use warnings;
+
use Data::Dumper qw(Dumper);
use PVE::Storage;
use PVE::Cluster;
my $storagename = "zfstank99";
my $subvol = 'regressiontest';
+my $mountpoint = "${subvol}_mnt";
#volsize in GB
my $volsize = 1;
my $basesnap = '@__base__';
my $tests = {};
-#create zfs suvol for testing
-
+#create zfs subvol for testing
my $pool = undef;
my $zpath = undef;
my $cfg = undef;
my $scfg = undef;
my $count = 0;
-my $testnum = 18;
+my $testnum = 19;
+my $end_test = $testnum;
+my $start_test = 1;
+
+if (@ARGV == 2) {
+ $end_test = $ARGV[1];
+ $start_test = $ARGV[0];
+} elsif (@ARGV == 1) {
+ $start_test = $ARGV[0];
+ $end_test = $ARGV[0];
+}
+
+my $test19 = sub {
+
+ print "\nrun test19 \"path\"\n";
+
+ my @res;
+ my $fail = 0;
+ eval {
+ @res = PVE::Storage::path($cfg, "$storagename:$vmdisk");
+ if ($res[0] ne "\/dev\/zvol\/regressiontest\/$vmdisk") {
+ $count++;
+ $fail = 1;
+ warn "Test 19 a: path is not correct: expected \'\/dev\/zvol\/regressiontest\/$vmdisk'\ get \'$res[0]\'";
+ }
+ if ($res[1] ne "102") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 a: owner is not correct: expected \'102\' get \'$res[1]\'";
+ }
+ if ($res[2] ne "images") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 a: owner is not correct: expected \'images\' get \'$res[2]\'";
+ }
+ };
+ if ( $@ ) {
+ $count++;
+ warn "Test 19 a: $@";
+ }
+
+ @res = undef;
+ $fail = 0;
+ eval {
+ @res = PVE::Storage::path($cfg, "$storagename:$vmbase");
+ if ($res[0] ne "\/dev\/zvol\/regressiontest\/$vmbase") {
+ $count++;
+ $fail = 1;
+ warn "Test 19 b: path is not correct: expected \'\/dev\/zvol\/regressiontest\/$vmbase'\ get \'$res[0]\'";
+ }
+ if ($res[1] ne "100") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 b: owner is not correct: expected \'100\' get \'$res[1]\'";
+ }
+ if ($res[2] ne "images") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 b: owner is not correct: expected \'images\' get \'$res[2]\'";
+ }
+ };
+ if ( $@ ) {
+ $count++;
+ warn "Test 19 b: $@";
+ }
+
+ @res = undef;
+ $fail = 0;
+ eval {
+ @res = PVE::Storage::path($cfg, "$storagename:$vmbase\/$vmlinked");
+ if ($res[0] ne "\/dev\/zvol\/regressiontest\/$vmlinked") {
+ $count++;
+ $fail = 1;
+ warn "Test 19 c: path is not correct: expected \'\/dev\/zvol\/regressiontest\/$vmlinked'\ get \'$res[0]\'";
+ }
+ if ($res[1] ne "101") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 c: owner is not correct: expected \'101\' get \'$res[1]\'";
+ }
+ if ($res[2] ne "images") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 c: owner is not correct: expected \'images\' get \'$res[2]\'";
+ }
+ };
+ if ( $@ ) {
+ $count++;
+ warn "Test 19 c: $@";
+ }
+
+ @res = undef;
+ $fail = 0;
+ eval {
+ @res = PVE::Storage::path($cfg, "$storagename:$ctdisk");
+ if ($res[0] ne "\/$mountpoint\/$ctdisk") {
+ $count++;
+ $fail = 1;
+ warn "Test 19 d: path is not correct: expected \'\/$mountpoint\/$ctdisk'\ get \'$res[0]\'";
+ }
+ if ($res[1] ne "202") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 d: owner is not correct: expected \'202\' get \'$res[1]\'";
+ }
+ if ($res[2] ne "images") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 d: owner is not correct: expected \'images\' get \'$res[2]\'";
+ }
+ };
+ if ( $@ ) {
+ $count++;
+ warn "Test 19 d: $@";
+ }
+
+ @res = undef;
+ $fail = 0;
+ eval {
+ @res = PVE::Storage::path($cfg, "$storagename:$ctbase");
+ if ($res[0] ne "\/$mountpoint\/$ctbase") {
+ $count++;
+ $fail = 1;
+ warn "Test 19 e: path is not correct: expected \'\/$mountpoint\/$ctbase'\ get \'$res[0]\'";
+ }
+ if ($res[1] ne "200") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 e: owner is not correct: expected \'200\' get \'$res[1]\'";
+ }
+ if ($res[2] ne "images") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 e: owner is not correct: expected \'images\' get \'$res[2]\'";
+ }
+ };
+ if ( $@ ) {
+ $count++;
+ warn "Test 19 e: $@";
+ }
+
+ @res = undef;
+ $fail = 0;
+ eval {
+ @res = PVE::Storage::path($cfg, "$storagename:$ctbase\/$ctlinked");
+ if ($res[0] ne "\/$mountpoint\/$ctlinked") {
+ $count++;
+ $fail = 1;
+ warn "Test 19 f: path is not correct: expected \'\/$mountpoint\/$ctlinked'\ get \'$res[0]\'";
+ }
+ if ($res[1] ne "201") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 f: owner is not correct: expected \'201\' get \'$res[1]\'";
+ }
+ if ($res[2] ne "images") {
+ if (!$fail) {
+ $count++;
+ $fail = 1;
+ }
+ warn "Test 19 f: owner is not correct: expected \'images\' get \'$res[2]\'";
+ }
+ };
+ if ( $@ ) {
+ $count++;
+ warn "Test 19 f: $@";
+ }
+};
+$tests->{19} = $test19;
my $test18 = sub {
- print "\nrun test17 \"scan_zfs\"\n";
+ print "\nrun test18 \"scan_zfs\"\n";
my $res;
eval {
eval {
PVE::Storage::activate_storage($cfg, $storagename);
+ PVE::Storage::deactivate_storage($cfg, $storagename);
};
if ($@) {
$count++;
eval {
my $tmp_volid = PVE::Storage::vdisk_alloc($cfg, $storagename, "112", "raw", undef ,1024 * 1024);
- if ($tmp_volid ne "$storagename:vm-112-disk-1") {
+ if ($tmp_volid ne "$storagename:vm-112-disk-0") {
die "volname:$tmp_volid don't match\n";
}
eval {
- run_command("zfs get -H volsize $zpath\/vm-112-disk-1", outfunc =>
+ run_command("zfs get -H volsize $zpath\/vm-112-disk-0", outfunc =>
sub { my $tmp = shift;
- if ($tmp !~ m/^$zpath\/vm-112-disk-1.*volsize.*1G.*$/) {
+ if ($tmp !~ m/^$zpath\/vm-112-disk-0.*volsize.*1G.*$/) {
die "size don't match\n";
}
});
eval {
my $tmp_volid = PVE::Storage::vdisk_alloc($cfg, $storagename, "112", "raw", undef ,2048 * 1024);
- if ($tmp_volid ne "$storagename:vm-112-disk-2") {
+ if ($tmp_volid ne "$storagename:vm-112-disk-1") {
die "volname:$tmp_volid don't match\n";
}
eval {
- run_command("zfs get -H volsize $zpath\/vm-112-disk-2", outfunc =>
+ run_command("zfs get -H volsize $zpath\/vm-112-disk-1", outfunc =>
sub { my $tmp = shift;
- if ($tmp !~ m/^$zpath\/vm-112-disk-2.*volsize.*2G.*$/) {
+ if ($tmp !~ m/^$zpath\/vm-112-disk-1.*volsize.*2G.*$/) {
die "size don't match\n";
}
});
eval {
my $tmp_volid = PVE::Storage::vdisk_alloc($cfg, $storagename, "113", "subvol", undef ,1024 * 1024);
- if ($tmp_volid ne "$storagename:subvol-113-disk-1") {
+ if ($tmp_volid ne "$storagename:subvol-113-disk-0") {
die "volname:$tmp_volid don't match\n";
}
eval {
- run_command("zfs get -H refquota $zpath\/subvol-113-disk-1", outfunc =>
+ run_command("zfs get -H refquota $zpath\/subvol-113-disk-0", outfunc =>
sub { my $tmp = shift;
- if ($tmp !~ m/^$zpath\/subvol-113-disk-1.*refquota.*1G.*$/) {
+ if ($tmp !~ m/^$zpath\/subvol-113-disk-0.*refquota.*1G.*$/) {
die "size don't match\n";
}
});
eval {
my $tmp_volid = PVE::Storage::vdisk_alloc($cfg, $storagename, "113", "subvol", undef ,2048 * 1024);
- if ($tmp_volid ne "$storagename:subvol-113-disk-2") {
+ if ($tmp_volid ne "$storagename:subvol-113-disk-1") {
die "volname:$tmp_volid don't match\n";
}
eval {
- run_command("zfs get -H refquota $zpath\/subvol-113-disk-2", outfunc =>
+ run_command("zfs get -H refquota $zpath\/subvol-113-disk-1", outfunc =>
sub { my $tmp = shift;
- if ($tmp !~ m/^$zpath\/subvol-113-disk-2.*refquota.*G.*$/) {
+ if ($tmp !~ m/^$zpath\/subvol-113-disk-1.*refquota.*G.*$/) {
die "size don't match\n";
}
});
}
eval {
- if ("$storagename:$vmbase\/vm-110-disk-1" ne
+ if ("$storagename:$vmbase\/vm-110-disk-0" ne
PVE::Storage::vdisk_clone($cfg, "$storagename:$vmbase", 110, '__base__')){
$count++;
warn "Test11 b";
}
- run_command("zfs list -H -o volsize $zpath\/vm-110-disk-1", outfunc => sub {
+ run_command("zfs list -H -o volsize $zpath\/vm-110-disk-0", outfunc => sub {
my $line = shift;
chomp($line);
}
eval {
- if ( "$storagename:$ctbase\/subvol-210-disk-1" ne
+ if ( "$storagename:$ctbase\/subvol-210-disk-0" ne
PVE::Storage::vdisk_clone($cfg, "$storagename:$ctbase", 210, '__base__')){
$count++;
warn "Test11 e";
}
- run_command("zfs list -H -o refquota $zpath\/subvol-210-disk-1", outfunc => sub {
+ run_command("zfs list -H -o refquota $zpath\/subvol-210-disk-0", outfunc => sub {
my $line = shift;
chomp($line);
print "\nrun test10 \"volume_is_base\"\n";
eval {
- if (1 == PVE::Storage::volume_is_base($cfg, "$storagename:$vmdisk")) {
+ if (1 == volume_is_base($cfg, "$storagename:$vmdisk")) {
$count++;
warn "Test10 a: is no base";
}
}
eval {
- if (0 == PVE::Storage::volume_is_base($cfg, "$storagename:$vmbase")) {
+ if (0 == volume_is_base($cfg, "$storagename:$vmbase")) {
$count++;
warn "Test10 b: is base";
}
}
eval {
- if (1 == PVE::Storage::volume_is_base($cfg, "$storagename:$vmbase\/$vmlinked")) {
+ if (1 == volume_is_base($cfg, "$storagename:$vmbase\/$vmlinked")) {
$count++;
warn "Test10 c: is no base";
}
}
eval {
- if (1 == PVE::Storage::volume_is_base($cfg, "$storagename:$ctdisk")) {
+ if (1 == volume_is_base($cfg, "$storagename:$ctdisk")) {
$count++;
warn "Test10 d: is no base";
}
}
eval {
- if (0 == PVE::Storage::volume_is_base($cfg, "$storagename:$ctbase")) {
+ if (0 == volume_is_base($cfg, "$storagename:$ctbase")) {
$count++;
warn "Test10 e: is base";
}
}
eval {
- if (1 == PVE::Storage::volume_is_base($cfg, "$storagename:$ctbase\/$ctlinked")) {
+ if (1 == volume_is_base($cfg, "$storagename:$ctbase\/$ctlinked")) {
$count++;
warn "Test10 f: is no base";
}
my $test9 =sub {
- print "\nrun test9 \"parse_volname\"\n";
+ print "\nrun test9 \"parse_volume_id\"\n";
eval {
my ($store, $disk) = PVE::Storage::parse_volume_id("$storagename:$vmdisk");
my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = PVE::Storage::parse_volname($cfg, "$storagename:$vmdisk");
if ($vtype ne 'images' || $vmid ne '102' || $name ne $vmdisk ||
- defined($basename) || defined($basevmid) || defined($isBase) ||
+ defined($basename) || defined($basevmid) || $isBase ||
$format ne 'raw') {
$count++;
warn "Test8 a: parsing wrong";
my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = PVE::Storage::parse_volname($cfg, "$storagename:$vmbase");
if ($vtype ne 'images' || $vmid ne '100' || $name ne $vmbase ||
- defined($basename) || defined($basevmid) || $isBase ne 'base' ||
+ defined($basename) || defined($basevmid) || !$isBase ||
$format ne 'raw') {
$count++;
warn "Test8 b: parsing wrong";
my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = PVE::Storage::parse_volname($cfg, "$storagename:$vmbase\/$vmlinked");
if ($vtype ne 'images' || $name ne $vmlinked || $vmid ne '101' ||
- $basename ne $vmbase || $basevmid ne '100' || defined($isBase) ||
+ $basename ne $vmbase || $basevmid ne '100' || $isBase ||
$format ne 'raw') {
$count++;
warn "Test8 c: parsing wrong";
my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = PVE::Storage::parse_volname($cfg, "$storagename:$ctdisk");
if ($vtype ne 'images' || $vmid ne '202' || $name ne $ctdisk ||
- defined($basename) || defined($basevmid) || defined($isBase) ||
+ defined($basename) || defined($basevmid) || $isBase ||
$format ne 'subvol') {
$count++;
warn "Test8 d: parsing wrong";
eval {
my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = PVE::Storage::parse_volname($cfg, "$storagename:$ctbase");
if ($vtype ne 'images' || $vmid ne '200' || $name ne $ctbase ||
- defined($basename) || defined($basevmid) || $isBase ne 'basevol' ||
+ defined($basename) || defined($basevmid) || !$isBase ||
$format ne 'subvol') {
$count++;
warn "Test8 e: parsing wrong";
my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = PVE::Storage::parse_volname($cfg, "$storagename:$ctbase\/$ctlinked");
if ($vtype ne 'images' || $name ne $ctlinked || $vmid ne '201' ||
- $basename ne $ctbase || $basevmid ne '200' || defined($isBase) ||
+ $basename ne $ctbase || $basevmid ne '200' || $isBase ||
$format ne 'subvol') {
$count++;
warn "Test8 f: parsing wrong";
};
eval {
+ PVE::Storage::activate_volumes($cfg, ["$storagename:$vmdisk"]);
run_command("sgdisk --randomize-guids \/dev\/zvol\/$zpath\/$vmdisk", outfunc => $parse_guid);
run_command("sgdisk -p \/dev\/zvol\/$zpath\/$vmdisk", outfunc => $parse_guid);
run_command("sgdisk --randomize-guids \/dev\/zvol\/$zpath\/$vmdisk", outfunc => $parse_guid);
eval {
PVE::Storage::volume_snapshot_rollback($cfg, "$storagename:$vmdisk", 'snap1');
+ PVE::Storage::activate_volumes($cfg, ["$storagename:$vmdisk"]);
$tmp_guid = undef;
run_command("sgdisk -p \/dev\/zvol\/$zpath\/$vmdisk", outfunc => $parse_guid);
if ($old_guid ne $tmp_guid) {
$tmp_guid = undef;
eval {
+ PVE::Storage::activate_volumes($cfg, ["$storagename:$vmbase"]);
run_command("sgdisk --randomize-guids \/dev\/zvol\/$zpath\/$vmbase", outfunc => $parse_guid);
run_command("sgdisk -p \/dev\/zvol\/$zpath\/$vmbase", outfunc => $parse_guid);
run_command("sgdisk --randomize-guids \/dev\/zvol\/$zpath\/$vmbase", outfunc => $parse_guid);
eval {
PVE::Storage::volume_snapshot_rollback($cfg, "$storagename:$vmbase", 'snap1');
+ PVE::Storage::activate_volumes($cfg, ["$storagename:$vmbase"]);
$tmp_guid = undef;
run_command("sgdisk -p \/dev\/zvol\/$zpath\/$vmbase", outfunc => $parse_guid);
if ($old_guid ne $tmp_guid) {
$tmp_guid = undef;
eval {
+ PVE::Storage::activate_volumes($cfg, ["$storagename:$vmbase/$vmlinked"]);
run_command("sgdisk --randomize-guids \/dev\/zvol\/$zpath\/$vmlinked", outfunc => $parse_guid);
run_command("sgdisk -p \/dev\/zvol\/$zpath\/$vmlinked", outfunc => $parse_guid);
run_command("sgdisk --randomize-guids \/dev\/zvol\/$zpath\/$vmlinked", outfunc => $parse_guid);
eval {
PVE::Storage::volume_snapshot_rollback($cfg, "$storagename:$vmbase\/$vmlinked", 'snap1');
+ PVE::Storage::activate_volumes($cfg, ["$storagename:$vmbase/$vmlinked"]);
$tmp_guid = undef;
run_command("sgdisk -p \/dev\/zvol\/$zpath\/$vmlinked", outfunc => $parse_guid);
if ($old_guid ne $tmp_guid) {
eval {
PVE::Storage::volume_snapshot($cfg, "$storagename:$ctdisk", 'snap1');
- run_command("touch \/$zpath\/$ctdisk\/test.txt", outfunc => $parse_guid);
+ run_command("touch \/$mountpoint\/$ctdisk\/test.txt", outfunc => $parse_guid);
eval {
PVE::Storage::volume_snapshot_rollback($cfg, "$storagename:$ctdisk", 'snap1');
eval {
- run_command("ls \/$zpath\/$ctdisk\/test.txt", errofunc => sub {});
+ run_command("ls \/$mountpoint\/$ctdisk\/test.txt", errofunc => sub {});
};
if (!$@) {
$count++;
eval {
PVE::Storage::volume_snapshot($cfg, "$storagename:$ctbase", 'snap1');
- run_command("touch \/$zpath\/$ctbase\/test.txt", outfunc => $parse_guid);
+ run_command("touch \/$mountpoint\/$ctbase\/test.txt", outfunc => $parse_guid);
eval {
PVE::Storage::volume_snapshot_rollback($cfg, "$storagename:$ctbase", 'snap1');
eval {
- run_command("ls \/$zpath\/$ctbase\/test.txt", errofunc => sub {});
+ run_command("ls \/$mountpoint\/$ctbase\/test.txt", errofunc => sub {});
};
if (!$@) {
$count++;
eval {
PVE::Storage::volume_snapshot($cfg, "$storagename:$ctbase/$ctlinked", 'snap1');
- run_command("touch \/$zpath\/$ctlinked\/test.txt", outfunc => $parse_guid);
+ run_command("touch \/$mountpoint\/$ctlinked\/test.txt", outfunc => $parse_guid);
eval {
PVE::Storage::volume_snapshot_rollback($cfg, "$storagename:$ctbase/$ctlinked", 'snap1');
eval {
$count++;
warn "Test5 f: $@";
}
- print "######Ignore Output if no Test5 g: is includet######\n";
+ print "######Ignore Output if no Test5 g: is included######\n";
eval{
PVE::Storage::volume_snapshot_delete($cfg, "$storagename:$vmbase", '__base__');
eval{
$count++;
warn "Test5 PVE g: snapshot __base__ can be erased";
}
- print "######End Ignroe#######\n";
+ print "######End Ignore#######\n";
};
$tests->{5} = $test5;
$tests->{1} = $test1;
sub setup_zfs {
-
- my $tmp = undef;
-
#create VM zvol
print "create zvol $vmdisk\n" if $verbose;
run_command("zfs create -V${volsize}G $zpath\/$vmdisk");
print "create subvol $ctdisk\n" if $verbose;
run_command("zfs create -o refquota=${volsize}G $zpath\/$ctdisk");
- print "create subvol $vmbase\n" if $verbose;
+ print "create subvol $ctbase\n" if $verbose;
run_command("zfs create -o refquota=${volsize}G $zpath\/$ctbase");
run_command("zfs snapshot $zpath\/$ctbase$basesnap");
- print "create linked clone $vmlinked\n" if $verbose;
+ print "create linked clone $ctlinked\n" if $verbose;
run_command("zfs clone $zpath\/$ctbase$basesnap $zpath\/$ctlinked -o refquota=${volsize}G");
+
+ my $vollist = [
+ "$storagename:$vmdisk",
+ "$storagename:$vmbase",
+ "$storagename:$vmbase/$vmlinked",
+ "$storagename:$ctdisk",
+ "$storagename:$ctbase",
+ "$storagename:$ctbase/$ctlinked",
+ ];
+
+ PVE::Storage::activate_volumes($cfg, $vollist);
}
sub cleanup_zfs {
print "destroy $pool\/$subvol\n" if $verbose;
- run_command("zfs destroy $zpath -r");
+ eval { run_command("zfs destroy $zpath -r"); };
+ if ($@) {
+ print "cleanup failed: $@\nretrying once\n" if $verbose;
+ eval { run_command("zfs destroy $zpath -r"); };
+ if ($@) {
+ clean_up_zpool();
+ setup_zpool();
+ }
+ }
}
sub setup_zpool {
+ unlink 'zpool.img';
eval {
- run_command("dd if=/dev/zero of=zpool.img bs=1M count=8000 ");
+ run_command("truncate -s 8G zpool.img");
};
if ($@) {
clean_up_zpool();
}
my $pwd = cwd();
eval {
- run_command("zpool create $subvol $pwd\/zpool.img");
+ run_command("zpool create -m \/$mountpoint $subvol $pwd\/zpool.img");
};
if ($@) {
clean_up_zpool();
sub clean_up_zpool {
eval {
- run_command("zpool destroy $subvol");
+ run_command("zpool destroy -f $subvol");
};
if ($@) {
warn $@;}
unlink 'zpool.img';
}
+sub volume_is_base {
+ my ($cfg, $volid) = @_;
+
+ my (undef, undef, undef, undef, undef, $isBase, undef) = PVE::Storage::parse_volname($cfg, $volid);
+
+ return $isBase;
+}
+
+if ($> != 0) { #EUID
+ warn "not root, skipping zfs tests\n";
+ exit 0;
+}
+
+eval { run_command("zpool status"); };
+if ($@) {
+ warn "zpool status failed, not running tests: $@\n";
+ exit 0;
+}
+
setup_zpool();
my $time = time;
'rootdir' => 1
},
'pool' => $subvol,
+ 'mountpoint' => "\/$mountpoint",
'type' => 'zfspool'
},
},
$zpath = $subvol;
-for (my $i = 1; $i <= $testnum; $i++) {
+for (my $i = $start_test; $i <= $end_test; $i++) {
setup_zfs();
eval {
$tests->{$i}();
};
- warn $@ if $@;
+ if (my $err = $@) {
+ warn $err;
+ $count++;
+ }
cleanup_zfs();
}
print "Stop tests for ZFSPoolPlugin\n";
print "$count tests failed\n";
print "Time: ${time}s\n";
+
+exit -1 if $count > 0;