145 lines
4.9 KiB
Perl
Executable File
145 lines
4.9 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
use strict;
|
|
use warnings;
|
|
use Digest::MD5 "md5_base64";
|
|
use POSIX;
|
|
|
|
open (my $drand, "<", "/dev/urandom");
|
|
my $clobber;
|
|
read($drand, $clobber, 10240000);
|
|
close($drand);
|
|
my $clobsum = md5_base64($clobber);
|
|
my %color = (
|
|
"red" => "\e[0;31m",
|
|
"green" => "\e[0;32m",
|
|
"reset" => "\e[0m"
|
|
);
|
|
my @failed = ();
|
|
my $term = POSIX::Termios->new;
|
|
|
|
sub anykey {
|
|
print shift;
|
|
my $key;
|
|
my $oldflag = $term->getlflag;
|
|
$term->setlflag(ICANON);
|
|
system "stty", '-icanon', 'eol', "\001"; #ISNT POSIX compliant
|
|
$key = getc(STDIN);
|
|
$term->setlflag($oldflag);
|
|
system "stty", 'icanon', 'eol', "^@";
|
|
return $key
|
|
}
|
|
|
|
sub warning {
|
|
print shift;
|
|
return 0;
|
|
}
|
|
|
|
sub getdisks {
|
|
my $devices = `find /dev/sd*`;
|
|
my %listhash = ();
|
|
foreach(split("\n",$devices)) {
|
|
my $devicepath = $_;
|
|
my $serial = `udevadm info --query=all --name=$_ | grep SERIAL_SHORT | sed -e 's/^.*=//'`;
|
|
chomp( $serial );
|
|
if ( $serial ) {
|
|
print $devicepath."\t".$serial."\n";
|
|
$listhash{$_}{"path"} = $devicepath;
|
|
$listhash{$_}{"serial"} = $serial;
|
|
} else { next; }
|
|
}
|
|
return %listhash;
|
|
}
|
|
|
|
sub wipethemdrives {
|
|
my $diskid = shift;
|
|
my $disks = shift;
|
|
print $disks->{$diskid}{"path"}." - Serial:".$disks->{$diskid}{"serial"}." is being wiped...\n";
|
|
open(my $diskw, ">", $disks{$diskid}{"path"}) or return warning("could not open ".$disks{$diskid}{"path"});
|
|
# open(my $diskw, ">", "./test") or warning("could not open "."./test");
|
|
print $diskw $clobber;
|
|
close($diskw);
|
|
system("sync");
|
|
print "Wipe attempt complete, checking...\n";
|
|
open(my $diskr, "<", $disks{$diskid}{"path"}) or return warning("could not open ".$disks{$diskid}{"path"});
|
|
# open(my $diskr, "<", "./test") or warning("could not open "."./test");
|
|
my $diskdata;
|
|
read($diskr, $diskdata, 10240000);
|
|
my $disksum = md5_base64($diskdata);
|
|
close($diskr);
|
|
print "Disk Checksum: ".$disksum."\n";
|
|
if ($disksum eq $clobsum) {
|
|
print "Checksum ".$color{"green"}."PASSED!!!".$color{"reset"}."\n";
|
|
print $disks->{$diskid}{"path"}." is clean.\n";
|
|
return 1;
|
|
} else {
|
|
print "Wipe Checksum: ".$clobsum."\n";
|
|
print "Checksum ".$color{"red"}."FAILED!!!".$color{"reset"}."\n";
|
|
print $disks->{$diskid}{"path"}." did not take, it could be bad.\n";
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
sub smartcheck {
|
|
# Do our smart disk thing...
|
|
my $diskid = shift;
|
|
my $disks = shift;
|
|
print "Checking S.M.A.R.T. variables...\n";
|
|
print 'smartctl '.$disks->{$diskid}{"path"}.' -A -f hex,id | grep "^0x"'."\n";
|
|
(my $smartcommand = `smartctl $disks->{$diskid}{"path"} -A -f hex,id | grep "^0x"`) or (print $!."\ncould not check smart data, skipping\n" and return 1);
|
|
for (split("\n",$smartcommand)) {
|
|
my @smartdata = split(/\s+/,$_);
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"id"} = $smartdata[0];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"name"} = $smartdata[1];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"flag"} = $smartdata[2];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"value"} = $smartdata[3];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"worst"} = $smartdata[4];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"thresh"} = $smartdata[5];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"type"} = $smartdata[6];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"updated"} = $smartdata[7];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"when_failed"} = $smartdata[8];
|
|
$disks->{$diskid}{"smart"}{$smartdata[0]}{"raw_value"} = $smartdata[9];
|
|
}
|
|
close( $smartcommand );
|
|
for my $smartentry (keys %{$disks->{$diskid}{"smart"}}) {
|
|
if ($disks->{$diskid}{"smart"}{$smartentry}{"id"} =~ /0x05|0x07|0xc4|0xc5|0xc6|0xc7/) {
|
|
print $disks->{$diskid}{"smart"}{$smartentry}{"id"}." ".$disks->{$diskid}{"smart"}{$smartentry}{"name"}."\t".$disks->{$diskid}{"smart"}{$smartentry}{"raw_value"}."\t";
|
|
if ($disks->{$diskid}{"smart"}{$smartentry}{"raw_value"} =~ /0|0\/0/) {
|
|
print $color{"green"}."Passed".$color{"reset"}."\n";
|
|
}else { print $color{"red"}."Failed".$color{"reset"}."\n"; return 0}
|
|
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
while () {
|
|
my %disks = getdisks();
|
|
my $batchcount = keys %disks;
|
|
print "About to wipe ".$batchcount." drives with the following serial numbers:\n";
|
|
foreach my $diskid (keys %disks) {
|
|
print $disks{$diskid}{"serial"}."\n";
|
|
}
|
|
anykey("Hit any key to continue...\n");
|
|
foreach my $diskid (keys %disks) {
|
|
print "\e[J";
|
|
print "="x33;
|
|
printf '[ %-10s ]', $diskid;
|
|
print "="x33;
|
|
print "\n";
|
|
$disks{$diskid}{"wipe"} = wipethemdrives($diskid,\%disks);
|
|
if ($disks{$diskid}{"wipe"} == 1) {
|
|
$disks{$diskid}{"smartpass"} = smartcheck($diskid,\%disks);
|
|
if ($disks{$diskid}{"smartpass"} == 1) {
|
|
print "Smart looks good.\n";
|
|
} else { push(@failed, $disks{$diskid}{"serial"}); }
|
|
} else { push(@failed, $disks{$diskid}{"serial"}); }
|
|
print "="x80;
|
|
print "\n"x5;
|
|
}
|
|
print "The folowing drives did not wipe successfully,\nThey may need another attempt or they may be bad.\n";
|
|
print join("\n",@failed);
|
|
@failed = ();
|
|
print "\nWipe complete, insert more drives.\n";
|
|
anykey("Hit any key when ready to continue...\n");
|
|
}
|