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