2020-08-10 17:35:21 +09:00
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
usage( ) {
echo "Dump boot-time tracing bootconfig from ftrace"
echo " Usage: $0 [--debug] [ > BOOTCONFIG-FILE] "
exit 1
}
DEBUG =
while [ x" $1 " != x ] ; do
case " $1 " in
"--debug" )
DEBUG = $1 ; ;
-*)
usage
; ;
esac
shift 1
done
if [ x" $DEBUG " != x ] ; then
set -x
fi
TRACEFS = ` grep -m 1 -w tracefs /proc/mounts | cut -f 2 -d " " `
if [ -z " $TRACEFS " ] ; then
if ! grep -wq debugfs /proc/mounts; then
echo "Error: No tracefs/debugfs was mounted."
exit 1
fi
TRACEFS = ` grep -m 1 -w debugfs /proc/mounts | cut -f 2 -d " " ` /tracing
if [ ! -d $TRACEFS ] ; then
echo "Error: ftrace is not enabled on this kernel." 1>& 2
exit 1
fi
fi
######## main #########
set -e
emit_kv( ) { # key =|+= value
echo " $@ "
}
global_options( ) {
val = ` cat $TRACEFS /max_graph_depth`
[ $val != 0 ] && emit_kv kernel.fgraph_max_depth = $val
if grep -qv "^#" $TRACEFS /set_graph_function $TRACEFS /set_graph_notrace ; then
cat 1>& 2 << EOF
# WARN: kernel.fgraph_filters and kernel.fgraph_notrace are not supported, since the wild card expression was expanded and lost from memory.
EOF
fi
}
kprobe_event_options( ) {
cat $TRACEFS /kprobe_events | while read p args; do
case $p in
r*)
cat 1>& 2 << EOF
# WARN: A return probe found but it is not supported by bootconfig. Skip it.
EOF
continue ; ;
esac
p = ${ p #* : }
event = ${ p #*/ }
group = ${ p %/* }
if [ $group != "kprobes" ] ; then
cat 1>& 2 << EOF
# WARN: kprobes group name $group is changed to "kprobes" for bootconfig.
EOF
fi
emit_kv $PREFIX .event.kprobes.$event .probes += $args
done
}
synth_event_options( ) {
cat $TRACEFS /synthetic_events | while read event fields; do
emit_kv $PREFIX .event.synthetic.$event .fields = ` echo $fields | sed "s/;/,/g" `
done
}
# Variables resolver
DEFINED_VARS =
UNRESOLVED_EVENTS =
defined_vars( ) { # event-dir
grep "^hist" $1 /trigger | grep -o ':[a-zA-Z0-9]*='
}
referred_vars( ) {
grep "^hist" $1 /trigger | grep -o '$[a-zA-Z0-9]*'
}
2021-08-10 11:08:14 +09:00
event_is_enabled( ) { # enable-file
test -f $1 & grep -q "1" $1
}
2020-08-10 17:35:21 +09:00
per_event_options( ) { # event-dir
evdir = $1
# Check the special event which has no filter and no trigger
[ ! -f $evdir /filter ] && return
if grep -q "^hist:" $evdir /trigger; then
# hist action can refer the undefined variables
__vars = ` defined_vars $evdir `
for v in ` referred_vars $evdir ` ; do
if echo $DEFINED_VARS $__vars | grep -vqw ${ v # $} ; then
# $v is not defined yet, defer it
UNRESOLVED_EVENTS = " $UNRESOLVED_EVENTS $evdir "
return ;
fi
done
DEFINED_VARS = " $DEFINED_VARS " ` defined_vars $evdir `
fi
grep -v "^#" $evdir /trigger | while read action active; do
emit_kv $PREFIX .event.$group .$event .actions += \' $action \'
done
2021-08-10 11:08:14 +09:00
if [ $GROUP_ENABLED -eq 0 ] && event_is_enabled $evdir /enable; then
emit_kv $PREFIX .event.$group .$event .enable
fi
2020-08-10 17:35:21 +09:00
val = ` cat $evdir /filter`
if [ " $val " != "none" ] ; then
emit_kv $PREFIX .event.$group .$event .filter = " $val "
fi
}
retry_unresolved( ) {
unresolved = $UNRESOLVED_EVENTS
UNRESOLVED_EVENTS =
for evdir in $unresolved ; do
event = ${ evdir ##*/ }
group = ${ evdir %/* } ; group = ${ group ##*/ }
per_event_options $evdir
done
}
event_options( ) {
# PREFIX and INSTANCE must be set
if [ $PREFIX = "ftrace" ] ; then
# define the dynamic events
kprobe_event_options
synth_event_options
fi
2021-08-10 11:08:14 +09:00
ALL_ENABLED = 0
if event_is_enabled $INSTANCE /events/enable; then
emit_kv $PREFIX .event.enable
ALL_ENABLED = 1
fi
2020-08-10 17:35:21 +09:00
for group in ` ls $INSTANCE /events/` ; do
[ ! -d $INSTANCE /events/$group ] && continue
2021-08-10 11:08:14 +09:00
GROUP_ENABLED = $ALL_ENABLED
if [ $ALL_ENABLED -eq 0 ] && \
event_is_enabled $INSTANCE /events/$group /enable ; then
emit_kv $PREFIX .event.$group .enable
GROUP_ENABLED = 1
fi
2020-08-10 17:35:21 +09:00
for event in ` ls $INSTANCE /events/$group /` ; do
[ ! -d $INSTANCE /events/$group /$event ] && continue
per_event_options $INSTANCE /events/$group /$event
done
done
retry = 0
while [ $retry -lt 3 ] ; do
retry_unresolved
retry = $(( retry + 1 ))
done
if [ " $UNRESOLVED_EVENTS " ] ; then
cat 1>& 2 << EOF
! ERROR: hist triggers in $UNRESOLVED_EVENTS use some undefined variables.
EOF
fi
}
is_default_trace_option( ) { # option
grep -qw $1 << EOF
print-parent
nosym-offset
nosym-addr
noverbose
noraw
nohex
nobin
noblock
trace_printk
annotate
nouserstacktrace
nosym-userobj
noprintk-msg-only
context-info
nolatency-format
record-cmd
norecord-tgid
overwrite
nodisable_on_free
irq-info
markers
noevent-fork
nopause-on-trace
function -trace
nofunction-fork
nodisplay-graph
nostacktrace
notest_nop_accept
notest_nop_refuse
EOF
}
instance_options( ) { # [instance-name]
if [ $# -eq 0 ] ; then
PREFIX = "ftrace"
INSTANCE = $TRACEFS
else
PREFIX = " ftrace.instance. $1 "
INSTANCE = $TRACEFS /instances/$1
fi
val =
for i in ` cat $INSTANCE /trace_options` ; do
is_default_trace_option $i && continue
val = " $val , $i "
done
[ " $val " ] && emit_kv $PREFIX .options = " ${ val #, } "
val = "local"
for i in ` cat $INSTANCE /trace_clock` ; do
[ " ${ i #*] } " ] && continue
i = ${ i %] } ; val = ${ i #[ }
done
[ $val != "local" ] && emit_kv $PREFIX .trace_clock = $val
val = ` cat $INSTANCE /buffer_size_kb`
if echo $val | grep -vq "expanded" ; then
emit_kv $PREFIX .buffer_size = $val "KB"
fi
if grep -q "is allocated" $INSTANCE /snapshot ; then
emit_kv $PREFIX .alloc_snapshot
fi
val = ` cat $INSTANCE /tracing_cpumask`
if [ ` echo $val | sed -e s/f//g` x != x ] ; then
emit_kv $PREFIX .cpumask = $val
fi
2020-12-09 14:27:44 +09:00
val = ` cat $INSTANCE /tracing_on`
2021-09-05 00:54:31 +09:00
if [ " $val " = "0" ] ; then
emit_kv $PREFIX .tracing_on = 0
2020-12-09 14:27:44 +09:00
fi
2020-08-10 17:35:21 +09:00
val = ` cat $INSTANCE /current_tracer`
[ $val != nop ] && emit_kv $PREFIX .tracer = $val
if grep -qv "^#" $INSTANCE /set_ftrace_filter $INSTANCE /set_ftrace_notrace; then
cat 1>& 2 << EOF
# WARN: kernel.ftrace.filters and kernel.ftrace.notrace are not supported, since the wild card expression was expanded and lost from memory.
EOF
fi
event_options
}
global_options
instance_options
for i in ` ls $TRACEFS /instances` ; do
instance_options $i
done