+sub setcolor
+{
+ my $linemask = shift;
+ my $line = shift;
+ if ($linemask == $masks->{TRACE}) {
+ if(leaving($line)){
+ print color("yellow on_black");
+ } else {
+ print color("green on_black");
+ }
+ }
+ if ($linemask == $masks->{DLMTRACE}) {
+ print color("magenta on_black");
+ }
+ if ($linemask == $masks->{DLM}) {
+ print color("magenta on_black");
+ }
+ if ($linemask == $masks->{DENTRY}) {
+ print color("red on_black");
+ }
+}
+
+sub study_lock
+{
+ $_ = shift;
+ my $rc;
+
+ $rc = /completion callback handler START ns: (.*) lock: (.*) lrc: (.*) mode/;
+ if ($rc) {
+ $completion_callbacks{$1}->{$2} = $3;
+# print color("white");
+# print "---CP CB START: $1 $2 $3\n";
+# print color("reset");
+ }
+ $rc = /callback handler finished.* ns: (.*) lock: (.*) lrc: (.*) mode/;
+ if ($rc) {
+# print color("white");
+# print "---CP CB END: $1 $2 $3 deleting $completion_callbacks{$1}->{$2}\n";
+# print color("reset");
+ delete $completion_callbacks{$1}->{$2};
+ }
+
+ if ($rc) {
+ $rc = /client blocking AST callback handler START ns: (.*) lock: (.*) lrc: (.*) mode/;
+ $blocking_callbacks{$1}->{$2} = $3;
+# print color("white");
+# print "---BL CB START: $1 $2\n";
+# print color("reset");
+ }
+ $rc = /client blocking callback handler END ns: (.*) lock: (.*) lrc: (.*) mode/;
+ if ($rc) {
+# print color("white");
+# print "---BL CB END: $1 $2 $3 deleting $blocking_callbacks{$1}->{$2}\n";
+# print color("reset");
+ delete $blocking_callbacks{$1}->{$2};
+ }
+
+ $rc = /ldlm_lock_addref.*ns: (.*) lock: (.*) lrc: (.*) mode/;
+# print color("white");
+# print "------>addref ns: $1 lock: $2 lrc: $3\n" if ($rc);
+# print color("reset");
+ $locks{$1}->{$2} = {$3} if ($rc);
+ $rc = /ldlm_lock_decref.*ns: (.*) lock: (.*) lrc: (.*) mode/;
+# print color("white");
+# print "------>decref ns: $1 lock: $2 lrc: $3\n" if ($rc);
+# print color("reset");
+ $locks{$1}->{$2} = {$3} if ($rc);
+}
+
+sub hanging_locks
+{
+ my $found;
+ my $ns;
+
+ foreach (keys %completion_callbacks) {
+ $ns = $_;
+ $found = 0;
+ foreach (keys %{$completion_callbacks{$ns}}) {
+ if (!$found) {
+ print "Unfinished completions in ns $ns: \n";
+ $found =1;
+ }
+ print " lock: $_ lrc: $completion_callbacks{$ns}->{$_}\n";
+ }
+ }
+ foreach (keys %blocking_callbacks) {
+ $ns = $_;
+ $found = 0;
+ foreach (keys %{$blocking_callbacks{$ns}}) {
+ if (!$found) {
+ print "Unfinished blocking in ns $ns: \n";
+ $found =1;
+ }
+ printf(" lock: $_ lrc: %s\n", $blocking_callbacks{$ns}->{$_});
+ }
+ }
+
+}
+
+sub study_intent
+{
+ $_ = shift;
+ my $rc;
+
+ $rc = /D_IT UP dentry (.*) fsdata/;
+ delete $it{$1} if ($rc);
+ $rc = /D_IT DOWN dentry (.*) fsdata/;
+ $it{$1} = "yes" if ($rc);
+}
+
+sub unmatched_intents {
+ my $found;
+ foreach (keys %it) {
+ if (!$found) {
+ print "Unmatched intents: \n";
+ $found =1;
+ }
+ print " $_\n";
+ }
+}
+
+sub usage
+{
+ print "Usage : llanalyze LOGFILE\n";
+ exit;
+}
+
+if ($ARGV[0]) {
+ if(!open(LOG, "<$ARGV[0]")){
+ print "Cannot open $ARGV[0]\n";
+ exit;
+ }
+} else {
+ usage();
+}
+$width = 0;
+if ($ARGV[1]) {
+ $width = $ARGV[1];
+}
+
+print "nodlm $nodlm, nonet $nonet, trace $trace\n";
+print "pid: $pid, dlm_ns: $dlm_ns\n";
+print "extract_start: $extract_start\n";
+print "extract_end: $extract_end\n";
+while (<LOG>) {
+ if ($extract_start && $extract_start ne "LLANAYZE_FOUND") {
+ next if (index($_, $extract_start, 0) == -1);
+ $extract_start = "LLANAYZE_FOUND";
+ }
+
+ if ($extract_end) {
+ next if ($extract_end eq "LLANAYZE_FOUND");
+ if (index($_, $extract_end, 0) != -1) {
+ $extract_end = "LLANAYZE_FOUND";
+ }
+ }
+