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 95 event_is_enabled() { # enable-file 96 test -f $1 && grep -q "1" $1 96 test -f $1 && grep -q "1" $1 97 } 97 } 98 98 99 per_event_options() { # event-dir 99 per_event_options() { # event-dir 100 evdir=$1 100 evdir=$1 101 # Check the special event which has no 101 # Check the special event which has no filter and no trigger 102 [ ! -f $evdir/filter ] && return 102 [ ! -f $evdir/filter ] && return 103 103 104 if grep -q "^hist:" $evdir/trigger; th 104 if grep -q "^hist:" $evdir/trigger; then 105 # hist action can refer the un 105 # hist action can refer the undefined variables 106 __vars=`defined_vars $evdir` 106 __vars=`defined_vars $evdir` 107 for v in `referred_vars $evdir 107 for v in `referred_vars $evdir`; do 108 if echo $DEFINED_VARS 108 if echo $DEFINED_VARS $__vars | grep -vqw ${v#$}; then 109 # $v is not de 109 # $v is not defined yet, defer it 110 UNRESOLVED_EVE 110 UNRESOLVED_EVENTS="$UNRESOLVED_EVENTS $evdir" 111 return; 111 return; 112 fi 112 fi 113 done 113 done 114 DEFINED_VARS="$DEFINED_VARS "` 114 DEFINED_VARS="$DEFINED_VARS "`defined_vars $evdir` 115 fi 115 fi 116 grep -v "^#" $evdir/trigger | while re 116 grep -v "^#" $evdir/trigger | while read action active; do 117 emit_kv $PREFIX.event.$group.$ 117 emit_kv $PREFIX.event.$group.$event.actions += \'$action\' 118 done 118 done 119 119 120 if [ $GROUP_ENABLED -eq 0 ] && event_i 120 if [ $GROUP_ENABLED -eq 0 ] && event_is_enabled $evdir/enable; then 121 emit_kv $PREFIX.event.$group.$ 121 emit_kv $PREFIX.event.$group.$event.enable 122 fi 122 fi 123 val=`cat $evdir/filter` 123 val=`cat $evdir/filter` 124 if [ "$val" != "none" ]; then 124 if [ "$val" != "none" ]; then 125 emit_kv $PREFIX.event.$group.$ 125 emit_kv $PREFIX.event.$group.$event.filter = "$val" 126 fi 126 fi 127 } 127 } 128 128 129 retry_unresolved() { 129 retry_unresolved() { 130 unresolved=$UNRESOLVED_EVENTS 130 unresolved=$UNRESOLVED_EVENTS 131 UNRESOLVED_EVENTS= 131 UNRESOLVED_EVENTS= 132 for evdir in $unresolved; do 132 for evdir in $unresolved; do 133 event=${evdir##*/} 133 event=${evdir##*/} 134 group=${evdir%/*}; group=${gro 134 group=${evdir%/*}; group=${group##*/} 135 per_event_options $evdir 135 per_event_options $evdir 136 done 136 done 137 } 137 } 138 138 139 event_options() { 139 event_options() { 140 # PREFIX and INSTANCE must be set 140 # PREFIX and INSTANCE must be set 141 if [ $PREFIX = "ftrace" ]; then 141 if [ $PREFIX = "ftrace" ]; then 142 # define the dynamic events 142 # define the dynamic events 143 kprobe_event_options 143 kprobe_event_options 144 synth_event_options 144 synth_event_options 145 fi 145 fi 146 ALL_ENABLED=0 146 ALL_ENABLED=0 147 if event_is_enabled $INSTANCE/events/e 147 if event_is_enabled $INSTANCE/events/enable; then 148 emit_kv $PREFIX.event.enable 148 emit_kv $PREFIX.event.enable 149 ALL_ENABLED=1 149 ALL_ENABLED=1 150 fi 150 fi 151 for group in `ls $INSTANCE/events/` ; 151 for group in `ls $INSTANCE/events/` ; do 152 [ ! -d $INSTANCE/events/$group 152 [ ! -d $INSTANCE/events/$group ] && continue 153 GROUP_ENABLED=$ALL_ENABLED 153 GROUP_ENABLED=$ALL_ENABLED 154 if [ $ALL_ENABLED -eq 0 ] && \ 154 if [ $ALL_ENABLED -eq 0 ] && \ 155 event_is_enabled $INSTANCE/ 155 event_is_enabled $INSTANCE/events/$group/enable ;then 156 emit_kv $PREFIX.event. 156 emit_kv $PREFIX.event.$group.enable 157 GROUP_ENABLED=1 157 GROUP_ENABLED=1 158 fi 158 fi 159 for event in `ls $INSTANCE/eve 159 for event in `ls $INSTANCE/events/$group/` ;do 160 [ ! -d $INSTANCE/event 160 [ ! -d $INSTANCE/events/$group/$event ] && continue 161 per_event_options $INS 161 per_event_options $INSTANCE/events/$group/$event 162 done 162 done 163 done 163 done 164 retry=0 164 retry=0 165 while [ $retry -lt 3 ]; do 165 while [ $retry -lt 3 ]; do 166 retry_unresolved 166 retry_unresolved 167 retry=$((retry + 1)) 167 retry=$((retry + 1)) 168 done 168 done 169 if [ "$UNRESOLVED_EVENTS" ]; then 169 if [ "$UNRESOLVED_EVENTS" ]; then 170 cat 1>&2 << EOF 170 cat 1>&2 << EOF 171 ! ERROR: hist triggers in $UNRESOLVED_EVENTS u 171 ! ERROR: hist triggers in $UNRESOLVED_EVENTS use some undefined variables. 172 EOF 172 EOF 173 fi 173 fi 174 } 174 } 175 175 176 is_default_trace_option() { # option 176 is_default_trace_option() { # option 177 grep -qw $1 << EOF 177 grep -qw $1 << EOF 178 print-parent 178 print-parent 179 nosym-offset 179 nosym-offset 180 nosym-addr 180 nosym-addr 181 noverbose 181 noverbose 182 noraw 182 noraw 183 nohex 183 nohex 184 nobin 184 nobin 185 noblock 185 noblock 186 trace_printk 186 trace_printk 187 annotate 187 annotate 188 nouserstacktrace 188 nouserstacktrace 189 nosym-userobj 189 nosym-userobj 190 noprintk-msg-only 190 noprintk-msg-only 191 context-info 191 context-info 192 nolatency-format 192 nolatency-format 193 record-cmd 193 record-cmd 194 norecord-tgid 194 norecord-tgid 195 overwrite 195 overwrite 196 nodisable_on_free 196 nodisable_on_free 197 irq-info 197 irq-info 198 markers 198 markers 199 noevent-fork 199 noevent-fork 200 nopause-on-trace 200 nopause-on-trace 201 function-trace 201 function-trace 202 nofunction-fork 202 nofunction-fork 203 nodisplay-graph 203 nodisplay-graph 204 nostacktrace 204 nostacktrace 205 notest_nop_accept 205 notest_nop_accept 206 notest_nop_refuse 206 notest_nop_refuse 207 EOF 207 EOF 208 } 208 } 209 209 210 instance_options() { # [instance-name] 210 instance_options() { # [instance-name] 211 if [ $# -eq 0 ]; then 211 if [ $# -eq 0 ]; then 212 PREFIX="ftrace" 212 PREFIX="ftrace" 213 INSTANCE=$TRACEFS 213 INSTANCE=$TRACEFS 214 else 214 else 215 PREFIX="ftrace.instance.$1" 215 PREFIX="ftrace.instance.$1" 216 INSTANCE=$TRACEFS/instances/$1 216 INSTANCE=$TRACEFS/instances/$1 217 fi 217 fi 218 val= 218 val= 219 for i in `cat $INSTANCE/trace_options` 219 for i in `cat $INSTANCE/trace_options`; do 220 is_default_trace_option $i && 220 is_default_trace_option $i && continue 221 val="$val, $i" 221 val="$val, $i" 222 done 222 done 223 [ "$val" ] && emit_kv $PREFIX.options 223 [ "$val" ] && emit_kv $PREFIX.options = "${val#,}" 224 val="local" 224 val="local" 225 for i in `cat $INSTANCE/trace_clock` ; 225 for i in `cat $INSTANCE/trace_clock` ; do 226 [ "${i#*]}" ] && continue 226 [ "${i#*]}" ] && continue 227 i=${i%]}; val=${i#[} 227 i=${i%]}; val=${i#[} 228 done 228 done 229 [ $val != "local" ] && emit_kv $PREFIX 229 [ $val != "local" ] && emit_kv $PREFIX.trace_clock = $val 230 val=`cat $INSTANCE/buffer_size_kb` 230 val=`cat $INSTANCE/buffer_size_kb` 231 if echo $val | grep -vq "expanded" ; t 231 if echo $val | grep -vq "expanded" ; then 232 emit_kv $PREFIX.buffer_size = 232 emit_kv $PREFIX.buffer_size = $val"KB" 233 fi 233 fi 234 if grep -q "is allocated" $INSTANCE/sn 234 if grep -q "is allocated" $INSTANCE/snapshot ; then 235 emit_kv $PREFIX.alloc_snapshot 235 emit_kv $PREFIX.alloc_snapshot 236 fi 236 fi 237 val=`cat $INSTANCE/tracing_cpumask` 237 val=`cat $INSTANCE/tracing_cpumask` 238 if [ `echo $val | sed -e s/f//g`x != x 238 if [ `echo $val | sed -e s/f//g`x != x ]; then 239 emit_kv $PREFIX.cpumask = $val 239 emit_kv $PREFIX.cpumask = $val 240 fi 240 fi 241 val=`cat $INSTANCE/tracing_on` 241 val=`cat $INSTANCE/tracing_on` 242 if [ "$val" = "0" ]; then 242 if [ "$val" = "0" ]; then 243 emit_kv $PREFIX.tracing_on = 0 243 emit_kv $PREFIX.tracing_on = 0 244 fi 244 fi 245 245 246 val=`cat $INSTANCE/current_tracer` 246 val=`cat $INSTANCE/current_tracer` 247 [ $val != nop ] && emit_kv $PREFIX.tra 247 [ $val != nop ] && emit_kv $PREFIX.tracer = $val 248 if grep -qv "^#" $INSTANCE/set_ftrace_ 248 if grep -qv "^#" $INSTANCE/set_ftrace_filter $INSTANCE/set_ftrace_notrace; then 249 cat 1>&2 << EOF 249 cat 1>&2 << EOF 250 # WARN: kernel.ftrace.filters and kernel.ftrac 250 # WARN: kernel.ftrace.filters and kernel.ftrace.notrace are not supported, since the wild card expression was expanded and lost from memory. 251 EOF 251 EOF 252 fi 252 fi 253 event_options 253 event_options 254 } 254 } 255 255 256 global_options 256 global_options 257 instance_options 257 instance_options 258 for i in `ls $TRACEFS/instances` ; do 258 for i in `ls $TRACEFS/instances` ; do 259 instance_options $i 259 instance_options $i 260 done 260 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.