fsync-check/check-fsync-write.pl

54 lines
1.5 KiB
Perl

#!/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;