From bc072c78f6c91bf4e97c205ea56fdef86ab10850 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Thu, 28 Jun 2018 19:20:32 +0300 Subject: [PATCH] Initial commit (with hardcode) --- check-fsync-read.pl | 49 ++++++++++++++++++++++++++++++++++++++++ check-fsync-write.pl | 53 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 check-fsync-read.pl create mode 100644 check-fsync-write.pl diff --git a/check-fsync-read.pl b/check-fsync-read.pl new file mode 100644 index 0000000..9e1042e --- /dev/null +++ b/check-fsync-read.pl @@ -0,0 +1,49 @@ +#!/usr/bin/perl + +use strict; +use File::Sync qw(fsync); +use Fcntl qw(:DEFAULT O_ASYNC O_DIRECT); + +my $device = $ARGV[0]; +my $logfn = $ARGV[1]; +if (!$logfn) +{ + print "USAGE: perl r20.pl DEVICE LOGFILE\n"; + exit; +} + +my $last = {}; +my $logfd; +open $logfd, $logfn or die $!; +my $i = 0; +while (my $s = <$logfd>) +{ + $s =~ s/[\x0d\x0a]+$//; + my ($pos, $hex) = split / /, $s, 2; + $last->{$pos} = $i++; +} + +my $fd; +sysopen $fd, $device, O_RDONLY or die $!; +my $buffer = " " x 4096; +my $fact; +$i = 0; +seek $logfd, 0, 0 or die $!; +while (my $s = <$logfd>) +{ + $s =~ s/[\x0d\x0a]+$//; + my ($pos, $hex) = split / /, $s, 2; + next if $last->{$pos} != $i; # only check last overwrite + $hex = pack("H*", $hex); + substr($buffer, 0, 4096, ($hex x 512)); + sysseek($fd, $pos*4096, 0) or die $!; + sysread($fd, $fact, 4096) or die $!; + if ($fact ne $buffer) + { + print "Mismatch at offset $pos*4096 (line $i): ".unpack("H*", substr($fact, 0, 8))." vs ".unpack("H*", $hex)."\n"; + } + $i++; +} +close $fd; + +close $logfd; diff --git a/check-fsync-write.pl b/check-fsync-write.pl new file mode 100644 index 0000000..92730f7 --- /dev/null +++ b/check-fsync-write.pl @@ -0,0 +1,53 @@ +#!/usr/bin/perl +# Idea: +# - run `nc -l 6777 > logfile.txt` on your machine +# - run `perl check-fsync-write.pl` on tested machine +# - pull power plug out from tested machine (do not press RESET! pull the plug out!) +# - power it back on +# - copy logfile.txt to tested machine +# - run `perl check-fsync-read.pl /dev/sdX logfile.txt` and check the output + +use strict; +use Socket qw(PF_INET SOCK_STREAM pack_sockaddr_in inet_aton); +use File::Sync qw(fsync); +use Fcntl qw(:DEFAULT O_ASYNC O_DIRECT); + +# Parameters +my $diskpath = "/dev/sdf"; # device +my $disksize = 499896320/8; # (device size / 4096) +my $ip = '172.29.1.109'; # logger machine IP +my $port = 6777; # logger machine port + +# Code +my $bufsize = 4096; +my $align = 512; +my $buffer = ' ' x ($align+$bufsize); +my $off = unpack("J", pack "p", $buffer) % $align; +$off = $align - $off if $off; + +my $socket; +socket $socket, PF_INET, SOCK_STREAM, 0 or die $!; +connect $socket, pack_sockaddr_in($port, inet_aton($ip)) or die $!; + +my $randfd; +open $randfd, "/dev/urandom" or die $!; + +my $fd; +sysopen $fd, $diskpath, O_WRONLY|O_DIRECT, 0666 or die $!; +while (1) +{ + my $pos; + my $number; + read $randfd, $pos, 4 or die $!; + read $randfd, $number, 8 or die $!; + substr($buffer, $off, 4096, $number x 512); + $pos = int(1.0 * ($disksize-1) * (unpack("V", $pos) & 0x7fffffff) / 0x7fffffff); + sysseek($fd, $pos*4096, 0) or die $!; + syswrite($fd, $buffer, 4096, $off) or die $!; + fsync($fd); + my $s = "$pos ".unpack("H*", $number)."\x0d\x0a"; + syswrite($socket, $s, length $s) or die $!; +} +close $fd; + +close $randfd;