File: common.bcc

package info (click to toggle)
pcp 6.3.8-1
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 235,180 kB
  • sloc: ansic: 1,253,622; sh: 173,998; xml: 160,490; cpp: 83,331; python: 20,482; perl: 18,302; yacc: 6,886; makefile: 2,955; lex: 2,862; fortran: 60; java: 52
file content (416 lines) | stat: -rw-r--r-- 11,083 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
#
# Common shell routines for testing pmdabcc
#
# Copyright (c) 2018 Andreas Gerstmayr.
# Copyright (c) 2019 Red Hat.
#

# get standard environment, filters and checks
. ./common.python

_pmdabcc_check()
{
    $python -c "from pcp import pmda" >/dev/null 2>&1
    [ $? -eq 0 ] || _notrun "python pcp pmda module not installed"

    $python -c "import bcc" >/dev/null 2>&1
    [ $? -eq 0 ] || _notrun "python bcc module not installed"

    # Most bcc PMDA modules load pcpbcc.python which in turn loads
    # __version__ from the Python BCC library.
    # Older versions of the Python BCC library do not contain the
    # __version__ symbol.
    #
    $python -c "from bcc import __version__" >/dev/null 2>&1
    [ $? -eq 0 ] || _notrun "python bcc module 0.5.0+ with __version__ is required"

    [ -f $PCP_PMDAS_DIR/bcc/pmdabcc.python ] || _notrun "bcc PMDA not installed"

    [ -d /lib/modules/$(uname -r) ] || _notrun "kernel headers for kernel $(uname -r) not found"

    if $sudo [ ! -d /sys/kernel/debug/kprobes ]
    then
	# on vm13 x86_64  MX 23.4 (Libretto) circa Dec 2024 debugfs
	# was mysteriously not mounted ... try to fix that
	#
	if $sudo mount -t debugfs none /sys/kernel/debug
	then
	    :
	else
	    _notrun "cannot mount debugfs"
	fi
    fi
}

_pmdabcc_require_kernel_version()
{
    uname -r | awk -F. -v __major=$1 -v __minor=$2 '$1 < __major || ($1 == __major && $2 < __minor) {exit 1}' || \
    _notrun "this test requires kernel $1.$2+"
}

_pmdabcc_install_filter()
{
    # ignore warnings because PMDA might not be ready yet
    # and therefore it has no values
    sed \
    -e "s/.*pmdabcc.* Info/Info/g" \
    -e "s/Tracing PID.*/Tracing PID./g" \
    -e "s/[0-9]\+ warnings, //" \
    -e "s/[0-9]\+ metrics and [0-9]\+ values/X metrics and X values/g" \
    #end
}

_pmdabcc_install()
{
    cat > $tmp.config

    # start from known starting points
    cd $PCP_PMDAS_DIR/bcc
    $sudo ./Remove >/dev/null 2>&1

    echo "pmdabcc config:" >> $here/$seq.full
    cat $tmp.config >> $here/$seq.full

    [ -f $PCP_PMDAS_DIR/bcc/bcc.conf ] && \
    $sudo cp $PCP_PMDAS_DIR/bcc/bcc.conf $PCP_PMDAS_DIR/bcc/bcc.conf.$seq
    $sudo cp $tmp.config $PCP_PMDAS_DIR/bcc/bcc.conf

    echo
    echo "=== bcc agent installation ==="
    $sudo ./Install </dev/null >$tmp.out 2>&1
    cat $tmp.out | _filter_pmda_install | _pmdabcc_install_filter

    echo
    cd $here
}

_pmdabcc_wait_for_metric()
{
    # Wait for the PMDA to compile the bcc modules and become ready, 60s max
    __canwait=60
    __i=0
    while [ $__i -lt $__canwait ]
    do
	grep -q 'Failed to compile BPF text' $PCP_LOG_DIR/pmcd/bcc.log
	if [ $? -eq 0 ]; then
	    echo BPF compilation error, test failed
	    exit
	fi

	grep -q 'Ready to process requests' $PCP_LOG_DIR/pmcd/bcc.log && break
	sleep 1
	__i=`expr $__i + 1`
    done
    sed -n '/Error:/,$p' $PCP_LOG_DIR/pmcd/bcc.log
    if [ $__i -eq $__canwait ]; then
        echo PMDA was not ready in $__canwait seconds, test failed
        exit
    fi
    echo "=== _pmdabcc_wait_for_metric: after $__i secs, metrics should be available ===" >>$here/$seq.full
    # "should" be available, but now wait up to 20 seconds for values
    # to be seen ...
    #
    __canwait=20
    __i=1
    while [ $__i -le $__canwait ]
    do
	touch $tmp.ok
	pmprobe bcc \
	| while read __metric __numval __foo
	do
	    if [ "$__numval" -eq -12389 ]
	    then
		# PM_ERR_AGAIN ... this is expected (apparently)
		#
		:
	    elif [ "$__numval" -lt 0 ]
	    then
		rm -f $tmp.ok
		if [ $__i -eq $__canwait ]
		then
		    # still bad on last iteration ... report
		    #
		    echo "_pmdabcc_wait_for_metric: Botch: bcc PMDA ready but metric $__metric returns numval $__numval (`pmerr $__numval`)"
		fi
	    fi
	done
	if [ -f $tmp.ok ]
	then
	    # goodness
	    #
	    echo "=== _pmdabcc_wait_for_metric: after another $__i secs, values are available ===" >>$here/$seq.full
	    pminfo -f bcc >>$here/$seq.full
	    return 0
	fi
	sleep 1
	__i=`expr $__i + 1`
    done

    # badness ...
    #
    pminfo -f bcc
    echo "Here's the PMDA log ..."
    cat $PCP_LOG_DIR/pmcd/bcc.log

    return 0
}

_pmdabcc_wait_for_value()
{
    __value_regex=${2:-'.*'}

    sed -n '/Error:/,$p' $PCP_LOG_DIR/pmcd/bcc.log
    for __i in `seq 1 30`; do pminfo -f $1 | grep -q -P 'inst .* value '$__value_regex && break; sleep 1; done
    if [ $__i -ge 30 ]; then
        echo Could not get a single value matching $__value_regex
        echo Current values:
        pminfo -f $1
        exit
    fi
}

_pmdabcc_remove()
{
    cd $PCP_PMDAS_DIR/bcc

    echo
    echo "=== remove bcc agent ==="
    $sudo ./Remove >$tmp.out 2>&1
    _filter_pmda_remove <$tmp.out \
    | sed \
	-e '/ Info: /d' \
    # end
    cd $here
}

_pmdabcc_cleanup()
{
    cat $PCP_LOG_DIR/pmcd/bcc.log >> $here/$seq.full
    if [ -f $PCP_PMDAS_DIR/bcc/bcc.conf.$seq ]; then
        $sudo cp $PCP_PMDAS_DIR/bcc/bcc.conf.$seq $PCP_PMDAS_DIR/bcc/bcc.conf
        $sudo rm $PCP_PMDAS_DIR/bcc/bcc.conf.$seq
    else
        $sudo rm -f $PCP_PMDAS_DIR/bcc/bcc.conf
    fi
    # note: _restore_auto_restart pmcd done in _cleanup_pmda()
    _cleanup_pmda bcc

    rm -f $tmp.*
}

_java_check()
{
    __machine=`uname -m`
    case "$__machine"
    in
        x86_64)
            __java_machine=amd64
            ;;
        *)
            __java_machine="$__machine"
            ;;
    esac

    __java_version=`java -version 2>&1 | awk '/version/ { print $3 }'`
    __java_version=`echo $__java_version | tr -d '"' | sed -e 's,_.*,,'`
    __java_major=`echo $__java_version   | sed -e 's,\..*,,g'`
    echo "\$__java_machine=$__java_machine" >>$here/$seq.full
    echo "\$__java_version=$__java_version" >>$here/$seq.full
    echo "\$__java_major=$__java_major" >>$here/$seq.full

    __jvm_path=""
    for __path in \
	/etc/alternatives/jre/lib/server \
	/etc/alternatives/jre/lib/$__java_machine/server \
	/usr/lib/jvm/java-${__java_major}-openjdk-$__java_machine/lib/server \
	/usr/lib/jvm/java-${__java_version}-openjdk/jre/lib/$__java_machine/server \
	/usr/lib/jvm/java-${__java_major}-openjdk-$__java_machine/jre/lib/$__java_machine/server \
	/usr/lib/jvm/jre/lib/server \
	/usr/lib/jvm/jre-openjdk/lib/server \
	/usr/lib/jvm/jre-${__java_major}/lib/server \
	/usr/lib/jvm/jre-${__java_major}-openjdk/lib/server
    do
        [ -f "$__path/libjvm.$DSO_SUFFIX" ] || continue
	__jvm_path="$__path/libjvm.$DSO_SUFFIX"
	echo "trying \$__jvm_path=$__jvm_path for USDT probes" >>$here/$seq.full
	for __tplistcmd in /usr/share/bcc/tools/tplist tplist-bpfcc tplist
	do
	    which $__tplistcmd >/dev/null 2>&1 && \
		__probes=$($__tplistcmd -l $__jvm_path 2>/dev/null \
		           | grep thread \
			   | tee -a $here/$seq.full \
			   | grep thread__start)
	    if [ -n "$__probes" ]
	    then
		echo "success with \$__jvm_path=$__jvm_path" >>$here/$seq.full
		return 0
	    fi
	done
    done
    [ -z "$__jvm_path" ] && _notrun "no libjvm.$DSO_SUFFIX not found"
    _notrun "No Java USDT probes available in any libjvm.$DSO_SUFFIX"
}

_python_probe_check()
{
    $python -c 'import time;time.sleep(5)' > /dev/null 2>&1 &
    __pypid=$!
    __probes=
    for __tplistcmd in /usr/share/bcc/tools/tplist tplist-bpfcc tplist
    do
        which $__tplistcmd >/dev/null 2>&1 && \
            __probes=$($__tplistcmd -p $__pypid 2>/dev/null | grep function__entry)
        [ -n "$__probes" ] && return 0
    done
    _notrun "No Python USDT probes available"
}

_mount_filesystem()
{
    __fs=$1
    __image=$tmp.loop.$__fs.img
    __mountpoint=$tmp.mount.$__fs

    truncate -s 350M $__image
    echo y | mkfs.$__fs $__image >>$here/$seq.full 2>&1
    mkdir -p $__mountpoint
    $sudo mount -t $__fs $__image $__mountpoint
    $sudo chown $(id -u):$(id -g) $__mountpoint
}

_unmount_filesystem()
{
    __fs=$1
    __mountpoint=$tmp.mount.$__fs

    $sudo umount $__mountpoint
    rm -r $__mountpoint
}

_value_filter_any()
{
    awk '/value .+/ {print "OK"; exit}'
}

_value_filter_nonzero()
{
    awk '/value [1-9][0-9]*/ {print "OK"; exit}'
}

_value_filter_exact()
{
    grep "value $1" > /dev/null && echo OK
}

_value_filter_regex()
{
    grep -P 'value '$1 > /dev/null && echo OK
}

# openSUSE 15.0 bcc-0.5.0-lp150.9.2 is carrying a patch to backport bcc
# upstream commit c0ca99a2 but not a subsequent fix made in upstream
# commit d1a83c1b so bcc on openSUSE 15.0 is broken on this regard.
# Problem persists in version libbcc0-0.5.0-lp151.11.5.x86_64.
_bcc_check_ArgString()
{
    if [ -f /etc/os-release ]
    then
	if grep 'openSUSE Leap' /etc/os-release >/dev/null
	then
	    case "`rpm -q libbcc0`"
	    in
		libbcc0-0.5.0-lp15[01]*)
		    # BAD
		    return 1
	    esac
	fi
    fi
    
    # OK
    return 0
}

# Usage: _pmdabcc_try_compile configfile
#
# Try to compile configfile and _notrun on failure unless
# $PCPQA_RUN_PMDABCC is set, in which case the compilation
# check is skipped.
#
_pmdabcc_try_compile()
{
    if [ -n "$PCPQA_RUN_PMDABCC" ]
    then
	# short-circuit ... this forces all the pmda.bcc tests to
	# be run and skips any compilation checks
	#
	echo "PCPQA_RUN_PMADBCC=$PCPQA_RUN_PMDABCC, skip PMDA try compile+load" >>$here/$seq.full
	return
    fi

    $sudo rm -f bcc.log
    if [ ! -f $PCP_VAR_DIR/pmdas/bcc/pmdabcc.python ]
    then
	echo "Oops: _pmdabcc_try_compile: $PCP_VAR_DIR/pmdas/bcc/pmdabcc.python not found"
    else
	$sudo $PCP_VAR_DIR/pmdas/bcc/pmdabcc.python --trycompile=$tmp.conf >>$seq.full
	if grep 'Failed to compile BPF module' bcc.log >/dev/null
	then
	    cat bcc.log >>$here/$seq.full
	    trap "rm -f $tmp.*" 0
	    _notrun "Failed to compile bcc module, see $seq.full for details"
	    # NOTREACHED
	elif grep 'Failed to load BPF program' bcc.log >/dev/null
	then
	    cat bcc.log >>$here/$seq.full
	    trap "rm -f $tmp.*" 0
	    _notrun "Failed to load bcc program, see $seq.full for details"
	    # NOTREACHED
	elif grep 'Failed to attach BPF program' bcc.log >/dev/null
	then
	    cat bcc.log >>$here/$seq.full
	    trap "rm -f $tmp.*" 0
	    _notrun "Failed to attach bcc program, see $seq.full for details"
	    # NOTREACHED
	elif grep '^LLVM ERROR:' bcc.log >/dev/null
	then
	    cat bcc.log >>$here/$seq.full
	    trap "rm -f $tmp.*" 0
	    _notrun "LLVM error, see $seq.full for details"
	    # NOTREACHED
	else
	    echo "No compile+load errors detected, but that does not guarantee all is well ..." >>$here/$seq.full
	    cat bcc.log >>$here/$seq.full
	fi
	$sudo rm -f bcc.log
    fi
}

# if we can find a tplist executable, run that to ensure the tracepoint
# "$1" is defined
#
_pmdabcc_check_tracepoint()
{
    # /usr/share/bcc/tools/tplist for RH-based distros
    # /usr/sbin/tplist-bpfcc for Debian-based distros
    #
    PATH=/usr/share/bcc/tools:/usr/sbin:$PATH
    for _exec in tplist tplist-bpfcc tplist 
    do
	exec=`which $_exec 2>/dev/null`
	if [ -x "$exec" ]
	then
	    # Bingo, we have a tplist command
	    #
	    if "$exec" | grep "^$1\$"
	    then
		return
	    else
		_notrun "tracepoint \"$1\" not known to $exec"
		# NOTREACHED
	    fi
	fi
    done

    # if no tplist, charge on and hope for the best ...
    #
}