#!/usr/bin/perl

use IO::File;

my $insync = 0;
my %times;
my %packets;
my %calls;
$| = 1;

my $lf = new IO::File(">>/tmp/vldb_timeouts.log");
$lf->autoflush();

open(IF, "strace -s 4096 -p `ps -efw | grep bip_stream| grep -v grep | awk '{print \$2}'` -xx -ttt 2>&1 |");
while (<IF>){
    my $store;
    next unless /(read\(|write\()(\d+)/;
    if (!$insync){
	# We're looking for a read
	next unless $1 =~ /read/;
	next unless /\s+=\s+4$/;
	print;
	$insync = 1;
	$store = $_;
    }
    # Typical layout is:
    #  read length, read packet, send length, send packet
    #    or
    #  read length, read packet, send length, send id, send packet
    if ($insync){
	if (!defined($store)){
	    $store = <IF>;
	}
	my $pack = <IF>;
	my $sl = <IF>;
	my $sp = <IF>;
	my $sid;
	if ($sp =~ /\s+=\s+4$/){
	    # Case #2
	    $sid = $sp;
	    $sp = <IF>;
	}
	if ($sid){
	    # Handle case #2
	    $sp =~ /\"(\\x[^\"]*)\"/;
	    my $idp = $1;
	    $idp =~ s/\\x//g;
	    my $rpcheader = substr($idp, 0, 6 * 8);
	    my $rpcargs = substr($idp, 6 * 8);
	    my ($id, $u1, $u2, $u3, $u4, $u5) = unpack('NNNNNN', pack('H*', $rpcheader));
	    if (1 == 0){
		printf("sp = $sp\n");
		printf("idp = $idp\n");
		printf("Id is %x\n", $id);
	    }
	    my $msg = "";
	    if (exists($calls{$id})){
		if ($calls{$id} == 1){
		    my ($result, $context, $vfsid, $al, $dbladeid) = unpack('NNNNn', pack('H*', $rpcargs));
		    $msg = "root lookup response: $vfsid, $dbladeid\n";
		} elsif ($calls{$id} == 2){
		    my ($result, $context, $vserver, $al, $dbladeid, $er) = unpack('NNNNnn', pack('H*', $rpcargs));
		    $msg =  "vfsid lookup response: $vserver, $dbladeid, $er\n";
		} elsif ($calls{$id} == 3){
		    my ($result, $context, $vserver, $vfsid, $al, $dbladeid) = unpack('NNNNNn', pack('H*', $rpcargs));
		    $msg = "Mount lookup response: $vserver, $vfsid, $dbladeid\n";
		}
		print $msg;
		delete $calls{$id};
	    }
	    if (exists($times{$id})){
		$store =~ /^(\d+\.\d+)/;
		my $delta = $1 - $times{$id};
		if ($delta > 1.0){
		    printf("\n" . (scalar localtime) . " $id - Delta is %.5f : $1 $times{$id}, %d\n", $delta, scalar keys %times);
		    printf($lf (scalar localtime) . " $id - Delta is %.5f : $1 $times{$id}, %d\n", $delta, scalar keys %times);
		    printf($lf "Response is $msg");
		    open(OF, ">/tmp/bip_stream.packets");
		    foreach my $key (keys %packets){
			print OF "$key - $packets{$key}\n";
		    }
		    close(OF);
		} else {
                    print "-" . scalar keys %times;
                }
		delete $times{$id};
		delete $packets{$id};
	    } else {
		$packets{$id} = $pack;
	    }
	} else {
	    # Handle case #1
	    $pack =~ /\"(\\x[^\"]*)\"/;
	    my $data = $1;
	    $data =~ s/\\x//g;
	    my $rpcheader = substr($data, 0, 11 * 8);
	    my $rpcargs = substr($data, 11 * 8);
	    my ($u1, $id, $u2, $u3, $rpcprog, $rpcvers, $rpccall, $u7, $u8, $u9, $u10) = unpack('NNNNNNNNNNN', pack('H*', $rpcheader));
#	    printf("Id is %x\n", $id);
	    if ($rpcprog == 536871424){
		if ($rpccall == 2){
		    my ($f1, $f2) = unpack('NN', pack('H*', $rpcargs));
		    print "Root lookup of $f1\n";
		    $calls{$id} = 1;
		} elsif ($rpccall == 3){
		    my ($f1, $f2) = unpack('NN', pack('H*', $rpcargs));
		    print "vfsid lookup of $f1\n";
		    $calls{$id} = 2;
		} elsif ($rpccall == 4){
		    my ($f1, $f2, $mp) = unpack('NNa*', pack('H*', $rpcargs));
		    print "mount lookup of $mp\n";
		    $calls{$id} = 3;
		} elsif ($rpccall == 25){
		    my ($f1) = unpack('n', pack('H*', $rpcargs));
		    printf("export ruleset lookup of %d\n", $f1);
		} else {
		    print "Unhandled RPC call $rpcall\n";
		    printf "u1 = $u1\n";
		    printf "u2 = $u2\n";
		    printf "u3 = $u3\n";
		    printf "rpcprog = $rpcprog\n";
		    printf "rpcvers = $rpcvers\n";
		    printf "rpccall = $rpccall\n";
		    printf "u7 = $u7\n";
		    printf "u8 = $u8\n";
		    printf "u9 = $u9\n";
		    printf "u10 = $u10\n";
		    printf "f1 = $f1\n";
		    printf "f2 = $f2\n";
		    printf "id = $id\n";
		}
	    } elsif ($rpcprog == 536872194){
		print "CIFS auth request\n";
	    } else {
#		print "Unhandled rpc program $rpcprog\n";
	    }

	    $store =~ /^(\d+\.\d+)/;
	    $times{$id} = $1;
	    $packets{$id} = $pack;
	}
    }
}
