forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
5.8 KiB
260 lines
5.8 KiB
#!/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]*' |
|
} |
|
|
|
event_is_enabled() { # enable-file |
|
test -f $1 & grep -q "1" $1 |
|
} |
|
|
|
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 |
|
|
|
if [ $GROUP_ENABLED -eq 0 ] && event_is_enabled $evdir/enable; then |
|
emit_kv $PREFIX.event.$group.$event.enable |
|
fi |
|
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 |
|
ALL_ENABLED=0 |
|
if event_is_enabled $INSTANCE/events/enable; then |
|
emit_kv $PREFIX.event.enable |
|
ALL_ENABLED=1 |
|
fi |
|
for group in `ls $INSTANCE/events/` ; do |
|
[ ! -d $INSTANCE/events/$group ] && continue |
|
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 |
|
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 |
|
val=`cat $INSTANCE/tracing_on` |
|
if [ "$val" = "0" ]; then |
|
emit_kv $PREFIX.tracing_on = 0 |
|
fi |
|
|
|
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
|
|
|