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