#!/usr/bin/perl use strict; use warnings; use Time::HiRes qw( usleep ualarm gettimeofday tv_interval ); use Net::DNS::Resolver; use PVE::Tools; if ($#ARGV >= 1) { print STDERR "usage: $0 [PATH]\n"; exit -1; } my $path = $ARGV[0] || '/'; sub drop_cache { # free pagecache,dentries,inode cache if (-f '/proc/sys/vm/drop_caches') { system ("echo 3 > /proc/sys/vm/drop_caches"); } } sub test_bogomips { my $bogomips = 0; open (TMP, "/proc/cpuinfo"); while (my $line = ) { if ($line =~ m/^bogomips\s*:\s*(\d+\.\d+)\s*$/) { $bogomips += $1; } } close (TMP); printf "CPU BOGOMIPS: %.2f\n", $bogomips; } sub test_regex { my $starttime = [gettimeofday]; my $count = 0; my $elapsed = 0; for (;; $count++) { my $str = int(rand(1000000)) . time(); if ($str =~ m/(.+)123.?123/) { } $elapsed = tv_interval ($starttime); last if $elapsed > 3; } printf "REGEX/SECOND: %d\n", $count; } sub test_fsync { my $basedir = shift; drop_cache (); my $dir = "$basedir/ptest.$$"; eval { mkdir $dir; my $data = ('A' x 4000) . "\n"; my $starttime = [gettimeofday]; my $count; my $elapsed = 0; for ($count=1;;$count++) { my $m = $count % 300; my $filename = "$dir/tf_$m.dat"; open (TMP, ">$filename") || die "open failed: $!\n"; print TMP $data; PVE::Tools::fsync(fileno(\*TMP)); close (TMP); $elapsed = tv_interval ($starttime); last if $elapsed > 3; } my $sps = $count /$elapsed; # fsync per second printf "FSYNCS/SECOND: %.2f\n", $sps; }; my $err = $@; system ("rm -rf $dir"); die $err if $err; } sub test_seektime { my ($rootdev, $hdsize) = @_; drop_cache (); open (ROOTHD, "<$rootdev") || die "unable to open HD '$rootdev': $!\n"; my $starttime = [gettimeofday]; my $count; my $elapsed = 0; my $readbuf; for ($count=1;;$count++) { my $pos = int (rand (int($hdsize/512))) * 512; sysseek (ROOTHD, $pos, 0); (sysread (ROOTHD, $readbuf, 512) == 512) || die "read failed: $!\n"; $elapsed = tv_interval ($starttime); last if $elapsed > 3; } close (ROOTHD); my $rps = $count /$elapsed; # blocks per second my $ast = (1000/$rps); printf "AVERAGE SEEK TIME: %.2f ms\n", $ast; } sub test_read { my $rootdev = shift; drop_cache (); my $starttime = [gettimeofday]; my $bytes = 0; my $elapsed = 0; my $readbuf; open (ROOTHD, "<$rootdev") || die "unable to open HD '$rootdev': $!\n"; for (;;) { my $c = sysread (ROOTHD, $readbuf, 2 * 1024 *1024); die "read failed: $!\n" if $c < 0; $bytes += $c; $elapsed = tv_interval ($starttime); last if $elapsed > 3; } close (ROOTHD); my $bps = $bytes /($elapsed * 1024 * 1024); # MB per second printf "BUFFERED READS: %.2f MB/sec\n", $bps; } sub get_address { my ($resolv, $dns) = @_; if (my $a = $resolv->send ($dns, 'A')) { foreach my $rra ($a->answer) { if ($rra->type eq 'A') { return $rra->address; } } } return undef; } sub test_dns { my %dnsargs = ( tcp_timeout => 10, udp_timeout => 10, retry => 1, retrans => 0, dnsrch => 0, defnames => 0, debug => 0, ); #$dnsargs{nameservers} = [ qw (208.67.222.222) ]; #$dnsargs{nameservers} = [ qw (127.0.0.1) ]; my $resolv = Net::DNS::Resolver->new (%dnsargs); my $starttime = [gettimeofday]; my $count; my $elapsed = 0; my $uid = time() . int(rand(1000000)); my $domain = "nonexistent$uid.com"; for ($count=1;;$count++) { my $hid = int(rand(1000000)); my $hname = "test${hid}.$domain"; get_address ($resolv, $hname); $elapsed = tv_interval ($starttime); last if ($count > 100) || ($elapsed > 3); } printf "DNS EXT: %0.2f ms\n", ($elapsed * 1000)/$count; my $resolv_conf = `cat /etc/resolv.conf`; ($domain) = $resolv_conf =~ m/^search\s+(\S+)\s*$/mg; if ($domain) { $starttime = [gettimeofday]; $elapsed = 0; for ($count=1;;$count++) { my $hid = int(rand(1000000)); my $hname = "test${hid}.$domain"; get_address ($resolv, $hname); $elapsed = tv_interval ($starttime); last if ($count > 100) || ($elapsed > 3); } printf "DNS INT: %0.2f ms (%s)\n", ($elapsed * 1000)/ $count, $domain; } } test_bogomips (); test_regex (); my $hd = `df -P '$path'`; my ($rootdev, $hdo_total, $hdo_used, $hdo_avail) = $hd =~ m/^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\S+\s+.*$/mg; if ($rootdev) { my $hdsize = $hdo_total*1024; printf "HD SIZE: %.2f GB ($rootdev)\n", ($hdsize / (1024*1024*1024)); if ($rootdev =~ m|^/dev/|) { test_read ($rootdev); test_seektime ($rootdev, $hdsize); } } test_fsync ($path) if $hdo_avail; test_dns (); exit (0);