1 2use strict; 3use warnings; 4use POSIX; 5use Test::More tests => 19; 6use Fcntl qw(:DEFAULT :seek); 7 8use constant BLK => 512; 9use constant BLKS_PER_MB => 2048; 10 11my $unit; 12END { system "mdconfig -du$unit" if defined $unit }; 13 14sub fsck_md { 15 my ($is_clean, $md); 16 17 $md = shift; 18 19 chomp(my @fsck_output = `fsck_ffs -Ffy ${md}a`); 20 $is_clean = WIFEXITED($?) && 21 (WEXITSTATUS($?) == 0 || WEXITSTATUS($?) == 7); 22 ok($is_clean, "checking ${md}a's filesystem"); 23 if ($is_clean) { 24 diag "filesystem reported clean"; 25 } else { 26 diag "filesystem not reported clean: " . join("\n", @fsck_output); 27 } 28} 29 30sub setsize { 31 my ($partszMB, $unitszMB) = @_; 32 33 open my $fd, "|-", "bsdlabel -R md$unit /dev/stdin" or die; 34 print $fd "a: ", ($partszMB * BLKS_PER_MB), " 0 4.2BSD 1024 8192\n"; 35 print $fd "c: ", ($unitszMB * BLKS_PER_MB), " 0 unused 0 0\n"; 36 close $fd; 37} 38 39sub fill { 40 my ($start, $size, $content) = @_; 41 42 my $content512 = $content x (int(512 / length $content) + 1); 43 substr($content512, 512) = ""; 44 sysopen my $fd, "/dev/md$unit", O_RDWR or die "/dev/md$unit: $!"; 45 seek($fd, $start * BLK, SEEK_SET); 46 while ($size) { 47 syswrite($fd, $content512) == 512 or die "write: $!"; 48 $size--; 49 } 50} 51 52SKIP: { 53 skip "Cannot test without UID 0", 19 if $<; 54 55 chomp(my $md = `mdconfig -s40m`); 56 like($md, qr/^md\d+$/, "Created $md with size 40m") or die; 57 $unit = substr $md, 2; 58 59 for my $type (1..2) { 60 61 initialise: { 62 ok(setsize(10, 40), "Sized ${md}a to 10m"); 63 system "newfs -O $type -U ${md}a >/dev/null"; 64 is($?, 0, "Initialised the filesystem on ${md}a as UFS$type"); 65 66 fsck_md($md); 67 } 68 69 extend20_zeroed: { 70 ok(setsize(20, 40), "Sized ${md}a to 20m"); 71 diag "Filling the extent with zeros"; 72 fill(10 * BLKS_PER_MB, 10 * BLKS_PER_MB, chr(0)); 73 my $out = `growfs -y ${md}a`; 74 is($?, 0, "Extended the filesystem on ${md}a") or print $out; 75 76 my ($unallocated) = $out =~ m{\d+ sectors cannot be allocated}; 77 fill(30 * BLKS_PER_MB - $unallocated, $unallocated, chr(0)) 78 if $unallocated; 79 80 fsck_md($md); 81 } 82 83 extend30_garbaged: { 84 ok(setsize(30, 40), "Sized ${md}a to 30m"); 85 diag "Filling the extent with garbage"; 86 fill(20 * BLKS_PER_MB, 10 * BLKS_PER_MB, chr(0xaa) . chr(0x55)); 87 my $out = `growfs -y ${md}a`; 88 is($?, 0, "Extended the filesystem on ${md}a") or print $out; 89 90 my ($unallocated) = $out =~ m{\d+ sectors cannot be allocated}; 91 fill(30 * BLKS_PER_MB - $unallocated, $unallocated, chr(0)) 92 if $unallocated; 93 94 fsck_md($md); 95 } 96 } 97 98 system "mdconfig -du$unit"; 99 undef $unit; 100} 101