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