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 95per_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 123retry_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 133event_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. 155EOF 156 fi 157} 158 159is_default_trace_option() { # option 160grep -qw $1 << EOF 161print-parent 162nosym-offset 163nosym-addr 164noverbose 165noraw 166nohex 167nobin 168noblock 169trace_printk 170annotate 171nouserstacktrace 172nosym-userobj 173noprintk-msg-only 174context-info 175nolatency-format 176record-cmd 177norecord-tgid 178overwrite 179nodisable_on_free 180irq-info 181markers 182noevent-fork 183nopause-on-trace 184function-trace 185nofunction-fork 186nodisplay-graph 187nostacktrace 188notest_nop_accept 189notest_nop_refuse 190EOF 191} 192 193instance_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. 235EOF 236 fi 237 event_options 238} 239 240global_options 241instance_options 242for i in `ls $TRACEFS/instances` ; do 243 instance_options $i 244done 245