ftrace2bconf.sh 5.8 KB

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