123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- #!/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
|