]>
Commit | Line | Data |
---|---|---|
2b86062a MH |
1 | #!/bin/sh |
2 | # SPDX-License-Identifier: GPL-2.0-only | |
3 | ||
4 | usage() { | |
5 | echo "Dump boot-time tracing bootconfig from ftrace" | |
6 | echo "Usage: $0 [--debug] [ > BOOTCONFIG-FILE]" | |
7 | exit 1 | |
8 | } | |
9 | ||
10 | DEBUG= | |
11 | while [ x"$1" != x ]; do | |
12 | case "$1" in | |
13 | "--debug") | |
14 | DEBUG=$1;; | |
15 | -*) | |
16 | usage | |
17 | ;; | |
18 | esac | |
19 | shift 1 | |
20 | done | |
21 | ||
22 | if [ x"$DEBUG" != x ]; then | |
23 | set -x | |
24 | fi | |
25 | ||
26 | TRACEFS=`grep -m 1 -w tracefs /proc/mounts | cut -f 2 -d " "` | |
27 | if [ -z "$TRACEFS" ]; then | |
28 | if ! grep -wq debugfs /proc/mounts; then | |
29 | echo "Error: No tracefs/debugfs was mounted." | |
30 | exit 1 | |
31 | fi | |
32 | TRACEFS=`grep -m 1 -w debugfs /proc/mounts | cut -f 2 -d " "`/tracing | |
33 | if [ ! -d $TRACEFS ]; then | |
34 | echo "Error: ftrace is not enabled on this kernel." 1>&2 | |
35 | exit 1 | |
36 | fi | |
37 | fi | |
38 | ||
39 | ######## main ######### | |
40 | ||
41 | set -e | |
42 | ||
43 | emit_kv() { # key =|+= value | |
44 | echo "$@" | |
45 | } | |
46 | ||
47 | global_options() { | |
48 | val=`cat $TRACEFS/max_graph_depth` | |
49 | [ $val != 0 ] && emit_kv kernel.fgraph_max_depth = $val | |
50 | if grep -qv "^#" $TRACEFS/set_graph_function $TRACEFS/set_graph_notrace ; then | |
51 | cat 1>&2 << EOF | |
52 | # WARN: kernel.fgraph_filters and kernel.fgraph_notrace are not supported, since the wild card expression was expanded and lost from memory. | |
53 | EOF | |
54 | fi | |
55 | } | |
56 | ||
57 | kprobe_event_options() { | |
58 | cat $TRACEFS/kprobe_events | while read p args; do | |
59 | case $p in | |
60 | r*) | |
61 | cat 1>&2 << EOF | |
62 | # WARN: A return probe found but it is not supported by bootconfig. Skip it. | |
63 | EOF | |
64 | continue;; | |
65 | esac | |
66 | p=${p#*:} | |
67 | event=${p#*/} | |
68 | group=${p%/*} | |
69 | if [ $group != "kprobes" ]; then | |
70 | cat 1>&2 << EOF | |
71 | # WARN: kprobes group name $group is changed to "kprobes" for bootconfig. | |
72 | EOF | |
73 | fi | |
74 | emit_kv $PREFIX.event.kprobes.$event.probes += $args | |
75 | done | |
76 | } | |
77 | ||
78 | synth_event_options() { | |
79 | cat $TRACEFS/synthetic_events | while read event fields; do | |
80 | emit_kv $PREFIX.event.synthetic.$event.fields = `echo $fields | sed "s/;/,/g"` | |
81 | done | |
82 | } | |
83 | ||
84 | # Variables resolver | |
85 | DEFINED_VARS= | |
86 | UNRESOLVED_EVENTS= | |
87 | ||
88 | defined_vars() { # event-dir | |
89 | grep "^hist" $1/trigger | grep -o ':[a-zA-Z0-9]*=' | |
90 | } | |
91 | referred_vars() { | |
92 | grep "^hist" $1/trigger | grep -o '$[a-zA-Z0-9]*' | |
93 | } | |
94 | ||
95 | per_event_options() { # event-dir | |
96 | evdir=$1 | |
97 | # Check the special event which has no filter and no trigger | |
98 | [ ! -f $evdir/filter ] && return | |
99 | ||
100 | if grep -q "^hist:" $evdir/trigger; then | |
101 | # hist action can refer the undefined variables | |
102 | __vars=`defined_vars $evdir` | |
103 | for v in `referred_vars $evdir`; do | |
104 | if echo $DEFINED_VARS $__vars | grep -vqw ${v#$}; then | |
105 | # $v is not defined yet, defer it | |
106 | UNRESOLVED_EVENTS="$UNRESOLVED_EVENTS $evdir" | |
107 | return; | |
108 | fi | |
109 | done | |
110 | DEFINED_VARS="$DEFINED_VARS "`defined_vars $evdir` | |
111 | fi | |
112 | grep -v "^#" $evdir/trigger | while read action active; do | |
113 | emit_kv $PREFIX.event.$group.$event.actions += \'$action\' | |
114 | done | |
115 | ||
116 | # enable is not checked; this is done by set_event in the instance. | |
117 | val=`cat $evdir/filter` | |
118 | if [ "$val" != "none" ]; then | |
119 | emit_kv $PREFIX.event.$group.$event.filter = "$val" | |
120 | fi | |
121 | } | |
122 | ||
123 | retry_unresolved() { | |
124 | unresolved=$UNRESOLVED_EVENTS | |
125 | UNRESOLVED_EVENTS= | |
126 | for evdir in $unresolved; do | |
127 | event=${evdir##*/} | |
128 | group=${evdir%/*}; group=${group##*/} | |
129 | per_event_options $evdir | |
130 | done | |
131 | } | |
132 | ||
133 | event_options() { | |
134 | # PREFIX and INSTANCE must be set | |
135 | if [ $PREFIX = "ftrace" ]; then | |
136 | # define the dynamic events | |
137 | kprobe_event_options | |
138 | synth_event_options | |
139 | fi | |
140 | for group in `ls $INSTANCE/events/` ; do | |
141 | [ ! -d $INSTANCE/events/$group ] && continue | |
142 | for event in `ls $INSTANCE/events/$group/` ;do | |
143 | [ ! -d $INSTANCE/events/$group/$event ] && continue | |
144 | per_event_options $INSTANCE/events/$group/$event | |
145 | done | |
146 | done | |
147 | retry=0 | |
148 | while [ $retry -lt 3 ]; do | |
149 | retry_unresolved | |
150 | retry=$((retry + 1)) | |
151 | done | |
152 | if [ "$UNRESOLVED_EVENTS" ]; then | |
153 | cat 1>&2 << EOF | |
154 | ! ERROR: hist triggers in $UNRESOLVED_EVENTS use some undefined variables. | |
155 | EOF | |
156 | fi | |
157 | } | |
158 | ||
159 | is_default_trace_option() { # option | |
160 | grep -qw $1 << EOF | |
161 | print-parent | |
162 | nosym-offset | |
163 | nosym-addr | |
164 | noverbose | |
165 | noraw | |
166 | nohex | |
167 | nobin | |
168 | noblock | |
169 | trace_printk | |
170 | annotate | |
171 | nouserstacktrace | |
172 | nosym-userobj | |
173 | noprintk-msg-only | |
174 | context-info | |
175 | nolatency-format | |
176 | record-cmd | |
177 | norecord-tgid | |
178 | overwrite | |
179 | nodisable_on_free | |
180 | irq-info | |
181 | markers | |
182 | noevent-fork | |
183 | nopause-on-trace | |
184 | function-trace | |
185 | nofunction-fork | |
186 | nodisplay-graph | |
187 | nostacktrace | |
188 | notest_nop_accept | |
189 | notest_nop_refuse | |
190 | EOF | |
191 | } | |
192 | ||
193 | instance_options() { # [instance-name] | |
194 | if [ $# -eq 0 ]; then | |
195 | PREFIX="ftrace" | |
196 | INSTANCE=$TRACEFS | |
197 | else | |
198 | PREFIX="ftrace.instance.$1" | |
199 | INSTANCE=$TRACEFS/instances/$1 | |
200 | fi | |
201 | val= | |
202 | for i in `cat $INSTANCE/trace_options`; do | |
203 | is_default_trace_option $i && continue | |
204 | val="$val, $i" | |
205 | done | |
206 | [ "$val" ] && emit_kv $PREFIX.options = "${val#,}" | |
207 | val="local" | |
208 | for i in `cat $INSTANCE/trace_clock` ; do | |
209 | [ "${i#*]}" ] && continue | |
210 | i=${i%]}; val=${i#[} | |
211 | done | |
212 | [ $val != "local" ] && emit_kv $PREFIX.trace_clock = $val | |
213 | val=`cat $INSTANCE/buffer_size_kb` | |
214 | if echo $val | grep -vq "expanded" ; then | |
215 | emit_kv $PREFIX.buffer_size = $val"KB" | |
216 | fi | |
217 | if grep -q "is allocated" $INSTANCE/snapshot ; then | |
218 | emit_kv $PREFIX.alloc_snapshot | |
219 | fi | |
220 | val=`cat $INSTANCE/tracing_cpumask` | |
221 | if [ `echo $val | sed -e s/f//g`x != x ]; then | |
222 | emit_kv $PREFIX.cpumask = $val | |
223 | fi | |
224 | ||
225 | val= | |
226 | for i in `cat $INSTANCE/set_event`; do | |
227 | val="$val, $i" | |
228 | done | |
229 | [ "$val" ] && emit_kv $PREFIX.events = "${val#,}" | |
230 | val=`cat $INSTANCE/current_tracer` | |
231 | [ $val != nop ] && emit_kv $PREFIX.tracer = $val | |
232 | if grep -qv "^#" $INSTANCE/set_ftrace_filter $INSTANCE/set_ftrace_notrace; then | |
233 | cat 1>&2 << EOF | |
234 | # WARN: kernel.ftrace.filters and kernel.ftrace.notrace are not supported, since the wild card expression was expanded and lost from memory. | |
235 | EOF | |
236 | fi | |
237 | event_options | |
238 | } | |
239 | ||
240 | global_options | |
241 | instance_options | |
242 | for i in `ls $TRACEFS/instances` ; do | |
243 | instance_options $i | |
244 | done |