1 #!/usr/bin/bash
   2 
   3 enabler="spa_import"
   4 functions_list_file="functions_list.txt"
   5 
   6 if [ ! -z "$1" ]; then
   7         enabler="$1"
   8 fi
   9 
  10 if [ ! -z "$2" ]; then
  11         functions_list_file="$2"
  12 fi
  13 
  14 build_probe_list()
  15 {
  16         provider="fbt"
  17         module="zfs"
  18         probe="entry"
  19 
  20         list_file="$1"
  21         if [ ! -z "$2" ]; then
  22                 probe="$2"
  23         fi
  24         if [ ! -z "$3" ]; then
  25                 module="$3"
  26         fi
  27         if [ ! -z "$4" ]; then
  28                 provider="$4"
  29         fi
  30 
  31         functions=( $(cat ${list_file}) )
  32         pos=$(( ${#functions[*]} - 1 ))
  33         last=${functions[$pos]}
  34         
  35         for func in "${functions[@]}"; do
  36                 echo -n "${provider}:${module}:${func}:${probe}"
  37                 if [[ ${func} == ${last} ]]; then
  38                         echo
  39                 else
  40                         echo ","
  41                 fi
  42         done
  43 }
  44 
  45 entry_probe_list=$(build_probe_list ${functions_list_file})
  46 return_probe_list=$(build_probe_list ${functions_list_file} "return")
  47 
  48 cat<<EOF 
  49 #!/usr/sbin/dtrace -s
  50 fbt:zfs:${enabler}:entry
  51 {
  52         self->ts[probefunc] = timestamp;
  53         self->trace = 1;
  54         printf("%Y\n", self->ts[probefunc]);
  55 }
  56 
  57 fbt:zfs:${enabler}:return
  58 /self->trace && self->ts[probefunc]/
  59 {
  60         this->ts = timestamp - self->ts[probefunc];
  61         self->ts[probefunc] = 0;
  62         self->trace = 0;
  63         printf("%Y\n", timestamp);
  64         printf("%s took %lu.%09lu seconds\n", stringof(probefunc),
  65             this->ts / 1000000000, this->ts % 1000000000);
  66 }
  67 
  68 ${entry_probe_list}
  69 /self->trace && (self->rec_count[probefunc] == 0)/
  70 {
  71         self->ts[probefunc] = timestamp;
  72         ++self->rec_count[probefunc];
  73         printf("%Y\n", self->ts[probefunc]);
  74 }
  75 
  76 ${entry_probe_list}
  77 /self->trace && (self->rec_count[probefunc] > 0) && self->ts[probefunc]/
  78 {
  79         ++self->rec_count[probefunc];
  80 }
  81 
  82 ${return_probe_list}
  83 /self->trace && (self->rec_count[probefunc] <= 2) && self->ts[probefunc]/
  84 {
  85         this->ts = timestamp - self->ts[probefunc];
  86         self->ts[probefunc] = 0;
  87         self->rec_count[probefunc] = 0;
  88         printf("%Y\n", timestamp);
  89         printf("%s took %lu.%09lu seconds\n", stringof(probefunc),
  90             this->ts / 1000000000, this->ts % 1000000000);
  91 }
  92 
  93 ${return_probe_list}
  94 /self->trace && (self->rec_count[probefunc] > 2) && self->ts[probefunc]/
  95 {
  96         --self->rec_count[probefunc];
  97 }
  98 
  99 EOF