mirror of
				https://git.proxmox.com/git/pve-manager
				synced 2025-11-04 11:37:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			302 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			302 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/perl -w
 | 
						|
 | 
						|
use strict;
 | 
						|
use File::Sync;
 | 
						|
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
 | 
						|
use Net::DNS::Resolver;
 | 
						|
 | 
						|
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 = <TMP>) {
 | 
						|
	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";
 | 
						|
 
 | 
						|
	    print TMP $data;
 | 
						|
 | 
						|
	    File::Sync::fsync (\*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";
 | 
						|
 | 
						|
    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";
 | 
						|
 | 
						|
	$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";
 | 
						|
 | 
						|
 
 | 
						|
    for (;;) {
 | 
						|
 | 
						|
	my $c = sysread (ROOTHD, $readbuf, 2 * 1024 *1024);
 | 
						|
	die "read failed" 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);
 | 
						|
 | 
						|
__END__
 | 
						|
 | 
						|
=head1 NAME
 | 
						|
                                          
 | 
						|
pveperf - the Proxmox benchmark
 | 
						|
 | 
						|
=head1 SYNOPSIS
 | 
						|
 | 
						|
pveperf [PATH]
 | 
						|
 | 
						|
=head1 DESCRIPTION
 | 
						|
 | 
						|
Tries to gather some CPU/Hardisk performance data on the hardisk
 | 
						|
mounted at PATH (/ is used as default) 
 | 
						|
 | 
						|
* CPU BOGOMIPS: bogomips sum of all CPUs
 | 
						|
 | 
						|
* REGEX/SECOND: regular expressions per second (perl performance test), should be above 300000
 | 
						|
 | 
						|
* HD SIZE: harddisk size
 | 
						|
 | 
						|
* BUFFERED READS: simple HD read test. Modern HDs should reach 
 | 
						|
at least 40 MB/sec
 | 
						|
 | 
						|
* AVERAGE SEEK TIME: tests average seek time. Fast SCSI HDs reach values < 8 milliseconds. Common IDE/SATA disks get values from 15 to 20 ms.
 | 
						|
 | 
						|
* FSYNCS/SECOND: value should be greater than 200 (you should 
 | 
						|
enable 'write back' cache mode on you RAID controller - needs a battery 
 | 
						|
backed cache (BBWC)).
 | 
						|
 | 
						|
* DNS EXT: average time to resolve an external DNS name
 | 
						|
 | 
						|
* DNS INT: average time to resolve a local DNS name
 |