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