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