forked from gnu-user/Tapper-autoreport
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathbash-test-utils
executable file
·1841 lines (1587 loc) · 53 KB
/
bash-test-utils
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
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#! /bin/bash
# ====================================================================
#
# bash-test-utils
# ----------------
#
# This is the "bash-test-utils" bash utility -- a bash include file
# to turn your bash script into a test suite.
#
# It also allows your bash script to be used with the "prove" command,
# a tool to run test scripts that produce TAP output (Test Anything
# Protocol).
#
# It was derived from "Tapper-autoreport" by simply dropping all
# Tapper specific features like: file upload, Tapper testrun context
# detection, and special parameter handling.
#
# It provides facilities to test Linux kernel in Xen/KVM contexts (in
# host and guest) and was polished to work with x86, x86_64, and ARM.
#
# It is licensed under a 2-clause BSD license. See the LICENSE file.
#
# ====================================================================
# ==================== Utility functions =============================
# constants
_SUCCESS=0
_FAILURE=1
declare -A program_package_mapping_ALinux
declare -A program_package_mapping_Debian
run_hook () {
_hook=${1:-UNDEFINED}
_TA_INC="bash-test-utils.hooks/$TESTUTIL_HOOKS/$_hook"
if [ -e "$_TA_INC" ] ; then . $_TA_INC ; fi
}
# gets vendor "AMD" or "Intel" from /proc/cpuinfo
get_vendor () {
vendor=$(echo $(grep vendor_id /proc/cpuinfo |head -1|cut -d: -f2|sed -e "s/Genuine\|Authentic//"))
echo $vendor
}
# checks for vendor "Intel" in /proc/cpuinfo
vendor_intel () {
grep -Eq 'vendor_id.*:.*Intel' /proc/cpuinfo
}
# checks for vendor "AMD" in /proc/cpuinfo
vendor_amd () {
grep -Eq 'vendor_id.*:.*AMD' /proc/cpuinfo
}
# stops testscript if not matching required cpu vendor
require_vendor_intel () {
if vendor_intel
then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok 0 "require_vendor_intel" ; fi
return $_SUCCESS
else
explanation="${1:-vendor does not match Intel}"
autoreport_skip_all "$explanation"
fi
}
# stops testscript if not matching required cpu vendor
require_vendor_amd () {
if vendor_amd
then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok 0 "require_vendor_amd" ; fi
return $_SUCCESS
else
explanation="${1:-vendor does not match AMD}"
autoreport_skip_all "$explanation"
fi
}
# Checks for ARM cpu
arm_cpu () {
grep -Eqi 'Processor.*:.*ARM' /proc/cpuinfo
}
# outputs cpu stepping from /proc/cpuinfo
get_cpu_stepping () {
echo $(echo $(grep "^stepping" /proc/cpuinfo |head -1|cut -d: -f2))
}
# outputs cpu model from /proc/cpuinfo
get_cpu_model () {
echo $(echo $(grep "^model[^ ]" /proc/cpuinfo |head -1|cut -d: -f2))
}
# outputs cpu model from /proc/cpuinfo
get_cpu_model_hex () {
echo "0x"$(get_hex_from_int $(get_cpu_model))
}
# checks cpu model from /proc/cpuinfo against a minimum model
cpu_model_min () {
min=${1:-0}
mod=$(get_cpu_model)
[ $(($mod)) -ge $(($min)) ]
}
# checks cpu model from /proc/cpuinfo against a maximum model
cpu_model_max () {
max=${1:-0x999}
mod=$(get_cpu_model)
[ $(($mod)) -le $(($max)) ]
}
# outputs cpu family from /proc/cpuinfo
# since all testsuites using hex values, return value in hex format
get_cpu_family () {
echo $(echo $(grep "^cpu family" /proc/cpuinfo |head -1|cut -d: -f2))
}
get_cpu_family_hex () {
echo "0x"$(get_hex_from_int $(get_cpu_family))
}
# checks cpu family from /proc/cpuinfo against a minimum family
cpu_family_min () {
min=${1:-0}
fam=$(get_cpu_family)
[ $(($fam)) -ge $(($min)) ]
}
# checks cpu family from /proc/cpuinfo against a maximum family
cpu_family_max () {
max=${1:-0x999}
fam=$(get_cpu_family)
[ $(($fam)) -le $(($max)) ]
}
is_amd_family_range () {
min="${1:-0}"
max="${2:-$min}"
if vendor_amd && cpu_family_min "$min" && cpu_family_max "$max" ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
# stops testscript if not matching required cpu family from
# /proc/cpuinfo of a minimum/maximum range
require_amd_family_range () {
min="${1:-0}"
max="${2:-$min}"
if is_amd_family_range "$min" "$max" ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok 0 "require_amd_family_range $min $max" ; fi
return $_SUCCESS
else
vendor=$(get_vendor);
fam=$(printf "0x%x" $(get_cpu_family));
explanation="${3:-Family $vendor/$fam does not match AMD/$min..$max}"
autoreport_skip_all "$explanation"
fi
}
# Checks all nodes for NB devices with one of the supplied PCI device ids
# Note: Call it separately for different PCI device functions
has_amd_nb_function_id () {
devids=${@:-"0xffffffff"}
for devid in $devids; do
devid=$(printf '0x%x' $devid)
nbdevs="/sys/bus/pci/devices/0000:00:1[89abcdef].*"
[ $(ls $nbdevs 2>/dev/null | wc -l) -gt 0 ] || continue
f0devs="/sys/bus/pci/devices/0000:00:1[89abcdef].0/vendor"
northbridges=$(ls $f0devs 2>/dev/null | wc -l)
devices=0
for nbdev in $nbdevs; do
vendor=$(cat $nbdev/vendor 2>/dev/null)
if [ "$vendor" != "0x1022" ]; then
return $_FAILURE
fi
device=$(cat $nbdev/device 2>/dev/null)
if [ "$device" = "$devid" ]; then
let devices++
fi
done
if [ $devices -gt 0 -a $devices -eq $northbridges ]; then
return $_SUCCESS
fi
done
return $_FAILURE
}
# Stops if no NB devices with one of supplied PCI device ids exist on all nodes
# Note: Call it separately for different PCI device functions
require_amd_nb_function_id () {
devids=${@:-"0xffffffff"}
if has_amd_nb_function_id "$devids"; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_amd_nb_function_id" ; fi
else
autoreport_skip_all "No supported AMD northbridge function devices"
fi
}
get_number_cpus () {
(getconf _NPROCESSORS_ONLN || grep -ci "^bogomips" /proc/cpuinfo || echo -1) 2>/dev/null
}
# check sysfs whether cpu has L3 cache
has_l3cache () {
if [ -d /sys/devices/system/cpu/cpu0/cache/index3 ] ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
# stops testscript if cpu does not have L3 cache
require_l3cache () {
explanation="${1:-No L3 cache}"
if has_l3cache ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_l3cache" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# check x86_64
is_x86_64 () {
if uname -m | grep -q x86_64 ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
# stops testscript if is not x86_64
require_x86_64 () {
explanation="${1:-No x86_64}"
if is_x86_64 ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_x86_64" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# scan all PCI devices for one with XenSource's PCI-ID
has_xen_pci_device () {
# try lspci (not in PATH if not root)
_ta_xen_LSPCI=$(which lspci 2> /dev/null) || _ta_xen_LSPCI=/sbin/lspci
if [ -x "$_ta_xen_LSPCI" ]
then
$_ta_xen_LSPCI -n | grep -q " 5853:"
return $?
else
# directly query sysfs and check for XenSource's PCI-ID
if [ -r /sys/bus/pci/devices/0000:00:00.0/vendor ] ; then
cat /sys/bus/pci/devices/*/vendor | grep -q 0x5853
return $?
else
return $_FAILURE
fi
fi
}
# checks the PCI hostbridge's vendor and optionally device ID
# usage: check_hostbridge 0x1022 (for checking for AMD northbridge)
# check_hostbridge 0x8086 0x1237 (for QEMU host bridge)
check_hostbridge() (
LSPCI=$(which lspci 2> /dev/null) || LSPCI=/sbin/lspci
if [ -x "$LSPCI" ]
then
lspciout=$($LSPCI -s 0:0.0 -n | cut -d: -f3- | tr -d \ )
vendor="0x$(echo $lspciout | cut -d: -f1)"
device="0x$(echo $lspciout | cut -d: -f2)"
else
vendor=$(cat /sys/bus/pci/devices/0000:00:00.0/vendor)
device=$(cat /sys/bus/pci/devices/0000:00:00.0/device)
fi
[ "$vendor" = "$1" ] || return $_FAILURE
[ -z "$2" ] && return $_SUCCESS
[ "$device" = "$2" ]
return $?
)
# checks whether the Xen hypervisor is running
# this returns 0 if we are a Dom0 or PV DomU or HVM DomU
is_running_under_xen_hv () {
if [ -r /sys/hypervisor/type ] ; then
[ $(cat /sys/hypervisor/type) = "xen" ]
return $?
fi
[ -r /proc/xen/capabilities ] && return $_SUCCESS
# Linux denies registering XenFS if not running under Xen
if has_kernel_config CONFIG_XENFS ; then
grep -q xenfs /proc/filesystems
return $?
fi
# TODO: do older kernels support this? At least RHEL5 does
has_cpufeature hypervisor || return $_FAILURE
_ta_e820prov=$(dmesg | sed -e 's/^\[.*\] *//' | grep -A1 "^BIOS-provided physical RAM map:" | tail -1 | cut -d: -f1)
[ -n "$_ta_820prov" ] && [ "$_ta_e820prov" = "Xen" ] && return $_SUCCESS
dmesg | grep -q "Booting paravirtualized kernel on Xen" && return $_SUCCESS
return $_FAILURE
}
# check if we are in a Xen host
# it is a bit tricky to differentiate Dom0 and (PV-)DomU
is_running_in_xen_dom0 () {
# this is a definite way to check for Dom0, but not always available, since
# XENFS could not be mounted
if [ -r /proc/xen/capabilities ] ; then
grep -q control_d /proc/xen/capabilities
return $?
fi
# this should sort out most of the other possibilities
is_running_under_xen_hv || return $_FAILURE
# we need to sort out only Dom0 vs. DomU from now on
# an ATI or AMD northbridge means Dom0
if check_hostbridge 0x1002 || check_hostbridge 0x1022 ; then
return $_SUCCESS
fi
# a QEMU northbridge cannot be Dom0
check_hostbridge 0x8086 0x1237 && return $_FAILURE
# out of clues, but we are probably not Dom0 at this point anymore
return $_FAILURE
}
# check if we are in a KVM host
is_running_in_kvm_host () {
[ -e /dev/kvm ]
}
# check if we have KVM guests running
has_kvm_guests () {
counter=$(lsmod |grep '^kvm_'|awk '{print $3}')
if [ $counter -gt 0 ] ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
get_xen_tool () {
which xl 2> /dev/null || which xm 2> /dev/null
}
get_number_xen_guests () {
XL=$(get_xen_tool) || return $_FAILURE
res=$($XL list | wc -l)
if [ -n "$res" -a "$res" -ge 2 ] ; then
echo "$((res-2))"
return $_SUCCESS
else
echo "0"
return $_FAILURE
fi
}
# check if we are in a Xen guest
# Note:
# In Xen the dom0 reports the same 'hypervisor' flag and CPUID entry
# as in domU therefore the CPUID check is not enough, but dmidecode
# and lspci show different devices inside a domU.
is_running_in_xen_guest () {
is_running_under_xen_hv || return $_FAILURE
has_xen_pci_device && return $_SUCCESS
check_hostbridge 0x8086 0x1237 && return $_SUCCESS
# try dmidecode
if dmidecode > /dev/null 2>&1 ; then
_dmi_chassis=$(dmidecode -s chassis-manufacturer)
# dmidecode does not output anything in PV Xen
if [ -n "$_dmi_chassis" ] ; then
echo "$_dmi_chassis" | grep -q Xen
return $?
fi
fi
# last resort: check for Xen Dom0
is_running_in_xen_dom0 && return $_FAILURE
# there are no PCI device by default in PV guests
_nr_pci_devices=$(ls /sys/bus/pci/devices | wc -l)
[ "$_nr_pci_devices" -eq 0 ] && return $_SUCCESS
# no more clues at this point, assume we are some kind of DomU
return $_SUCCESS
}
# check if we are in a KVM guest
# Note:
# In KVM the hypervisor CPUID check is relieable and we can first
# narrow it against being not a Xen guest. After that the devices
# are less significant in KVM so here we then check for the CPUID.
is_running_in_kvm_guest () {
is_running_in_xen_guest && return $_FAILURE
has_cpufeature hypervisor || return $_FAILURE
# try to load the cpuid module if not already done
[ -c /dev/cpu/0/cpuid ] || modprobe cpuid > /dev/null 2>&1
if [ -c /dev/cpu/0/cpuid ] ; then
virtvendor=$(dd if=/dev/cpu/0/cpuid bs=16 skip=67108864 count=1 2> /dev/null)
[ "$virtvendor" = "KVMKVMKVM" ]
return $?
fi
return 1
}
# check if we are in a virtualized guest (Xen or KVM)
is_running_in_virtualized_guest () {
is_running_in_xen_guest || is_running_in_kvm_guest
return $?
}
# stops testscript if we aren't a Xen guest
require_running_in_xen_guest () {
explanation="${1:-Needs to run in Xen guest}"
if is_running_in_xen_guest ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_xen_guest" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# stops testscript if we aren't a Xen dom0
require_running_in_xen_dom0 () {
explanation="${1:-Needs to run in Xen dom0}"
if is_running_in_xen_dom0 ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_xen_dom0" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# stops testscript if we aren't a KVM guest
require_running_in_kvm_guest () {
explanation="${1:-Needs to run in KVM guest}"
if is_running_in_kvm_guest ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_kvm_guest" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# stops testscript if we aren't a KVM host
require_running_in_kvm_host () {
explanation="${1:-Needs to run in KVM host}"
if is_running_in_kvm_host ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_kvm_host" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# stops testscript if we aren't a virtualized guest
require_running_in_virtualized_guest () {
explanation="${1:-Needs to run in virtualized guest}"
if is_running_in_virtualized_guest ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_running_in_virtualized_guest" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# checks for a feature flag in /proc/cpuinfo
has_cpufeature () {
_ta_feature="${1:-UNKNOWNFEATURE}"
if cat /proc/cpuinfo | grep -E '^flags\W*:' | head -1 | sed -e 's/^flags\W*://' | grep -q "\<${_ta_feature}\>" 2>&1 ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
# stops testscript if a feature flag is not found in /proc/cpuinfo
require_cpufeature () {
_ta2_feature="${1:-UNKNOWNFEATURE}"
explanation="${2:-Missing cpufeature $_ta2_feature}"
if has_cpufeature "$_ta2_feature" ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_cpufeature $_ta2_feature" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# checks for a config in /proc/config.gz or /boot/config/$(uname -r)
has_kernel_config () {
_ta3_feature="${1:-UNKNOWNFEATURE}"
CONFIG=$(get_first_file "/proc/config.gz" "/boot/config-$(uname -r)")
if [ -z "$CONFIG" ] ; then
return $_FAILURE
fi
if echo $CONFIG | grep -q '\.gz' ; then
gzip -cd "$CONFIG" | grep -q "^${_ta3_feature}=."
else
grep -q "^${_ta3_feature}=." "$CONFIG"
fi
}
# stops testscript if a feature flag is not found in /proc/cpuinfo
require_kernel_config () {
_ta4_feature="${1:-UNKNOWNFEATURE}"
explanation="${2:-Missing kernel config $_ta4_feature}"
if has_kernel_config "$_ta4_feature" ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_kernel_config $_ta4_feature" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# Enable CPU frequency scaling and set sane defaults
# - Makes sure the appropriate cpufreq driver is loaded
# - Enables ondemand governor on all cores
# - Sets the boost state, on=1 (default), off=0
enable_cpufreq () {
booststate="$1"
[ "$booststate" != "0" ] && booststate=1
# Load cpufreq driver module
for module in acpi-cpufreq powernow-k8; do
[ -d /sys/devices/system/cpu/cpu0/cpufreq ] && break
modprobe $module 2>/dev/null
done
if [ ! -d /sys/devices/system/cpu/cpu0/cpufreq ]; then
echo "failed to load cpufreq driver"
return $_FAILURE
fi
# Load ondemand governor module and set ondemand governor
if ! grep -q ondemand /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors; then
modprobe cpufreq-ondemand 2>/dev/null
fi
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo ondemand > $cpu 2>/dev/null
if [ "$(cat $cpu)" != "ondemand" ]; then
echo "failed to set ondemand governor"
return $_FAILURE
fi
done
# Set requested boost state
if ! has_cpufeature cpb; then
return $_SUCCESS
elif [ -f /sys/devices/system/cpu/cpufreq/boost ]; then
interfaces="/sys/devices/system/cpu/cpufreq/boost"
elif [ $(ls /sys/devices/system/cpu/cpu*/cpufreq/cpb 2>/dev/null | wc -l) -gt 0 ]; then
interfaces="/sys/devices/system/cpu/cpu*/cpufreq/cpb"
elif grep -q " show_cpb\| show_global_boost" /proc/kallsyms; then
echo "failed to find sysfs boost state interface"
return $_FAILURE
elif [ $booststate -eq 0 ]; then
echo "cpufreq driver doesn't provide sysfs boost state interface"
return $_FAILURE
else
return $_SUCCESS
fi
for interface in $interfaces; do
echo $booststate > $interface 2>/dev/null
if [ "$(cat $interface)" != "$booststate" ]; then
echo "failed to set requested boost state"
return $_FAILURE
fi
done
return $_SUCCESS
}
require_cpufreq_enabled () {
explanation="${1:-CPUFreq not available}"
reason=$(enable_cpufreq 1)
if [ $? -eq $_SUCCESS ] ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_cpufreq_enabled" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation ($reason)"
fi
}
require_cpb_disabled () {
explanation="${1:-Failed to disable Core Boosting}"
reason=$(enable_cpufreq 0)
if [ $? -eq $_SUCCESS ] ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_cpufreq_enabled" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation ($reason)"
fi
}
request_cpufreq_enabled () {
todo="# TODO $(enable_cpufreq 1)" && todo=""
ok $? "request_cpufreq_enabled $todo"
[ -n "$todo" ] && return $_FAILURE
return $_SUCCESS
}
request_cpb_disabled () {
todo="# TODO $(enable_cpufreq 0)" && todo=""
ok $? "request_cpb_disabled $todo"
[ -n "$todo" ] && return $_FAILURE
return $_SUCCESS
}
# disables core performance boosting for reproducable and well scaling
# benchmarks. Tries hard to learn the actual state and to really disable
# it. Diagnostic messages will be print to stdout, the return value
# describes the success: 0=CPB is disabled, 1=CPB is (probably) still enabled.
# possible usage (failed disabling is non-fatal, but report it):
# todostem="# TODO "
# expl=$(disable_cpb) && todostem=""
# ok $? "disable CPB $todostem$expl"
# or a fatal version ending the script:
# expl=$(disable_cpb)
# require_ok $? "disable CPB"
# or: just try to disable it, but don't care if we fail
# disable_cpb > /dev/null
disable_cpb () {
# check whether the CPB sysfs knob is there
if [ ! -r /sys/devices/system/cpu/cpu0/cpufreq/cpb ] ; then
is_running_in_virtualized_guest && _cpbhint=" (running virtualized)"
# if the CPU does not support boosting, we dont care
if ! has_cpufeature cpb ; then
echo "# CPU has no CPB support$_cpbhint"
return 0
fi
# is the powernow_k8 driver loaded?
if ! grep -q " powernowk8_init" /proc/kallsyms; then
# if not, try to load it
if ! _modprobe_res=$(modprobe powernow_k8 2>&1) ; then
echo "# modprobe powernow_k8: $_modprobe_res"
return 1
fi
fi
# does this version of powernow_k8 support CPB?
if ! grep -q " show_cpb" /proc/kallsyms ; then
echo "# powernow_k8 loaded, but no CPB support"
return 1
fi
fi
# now check for the sysfs knob again (we may have loaded the driver)
if [ ! -r /sys/devices/system/cpu/cpu0/cpufreq/cpb ] ; then
echo "# no sysfs knob for disabling CPB, probably still active"
return 1
fi
# if the knob is there and it reads 0, everything is fine
if [ $(cat /sys/devices/system/cpu/cpu0/cpufreq/cpb) = "0" ] ; then
echo "# CPB already disabled"
return 0
fi
# try to disable CPB on all cores and count the number of failures
failures=0
for cpb in /sys/devices/system/cpu/cpu*/cpufreq/cpb; do
echo 0 2> /dev/null > $cpb || let failures++
done
# no failures means everything is fine
if [ "$failures" = 0 ] ; then
echo "# CPB successfully disabled"
return 0
fi
# don't give up so quickly, try to explore dmesg for the right message
if $(dmesg | grep -q "Core Boosting .*abled") ; then
# there was at least one messages, check the last one
if dmesg | grep -q "Core Boosting .*abled" | tail -1 | grep -q "Core Boosting disabled" ; then
# the last message says its disabled, believe this
echo "# CPB disabling failed, but probably disabled before"
return 0
else
# the last message says its enabled, we failed eventually
echo "# CPB disabling failed (no permissions), CPB active"
return 1
fi
fi
# we have no real clue at this point, but assume the worst
echo "# CPB disabling failed, probably still active"
return 1
}
# checks whether the cpbdisable file exists in sysfs
has_cpbdisable () {
# This file's existence is not the best check.
# It also exists on non-cpb systems.
if [ -e /sys/devices/system/cpu/cpu0/cpufreq/cpb ] ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
# stops testscript if the cpbdisable file does not exist in sysfs
require_cpbdisable () {
explanation="${1:-No CPB disable}"
if has_cpbdisable ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_cpbdisable" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# checks whether the module is ther
has_module () {
module="${1:-UNKNOWNMODULE}"
if lsmod | grep -q "^$module\b" ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
# stops testscript if the cpbdisable file does not exist in sysfs
require_module () {
module="${1:-UNKNOWNMODULE}"
explanation="${2:-No module $module disable}"
if has_module "$module"; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_module" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# checks whether the program is available
has_program () {
_has_program_program="${1:-UNKNOWNPROGRAM}"
if which "$_has_program_program" > /dev/null 2>&1 ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
get_distro () {
if grep -q "Amazon Linux" /etc/issue ; then
echo ALinux
elif grep -q "Ubuntu" /etc/issue ; then
echo Ubuntu
elif grep -q "Debian" /etc/issue ; then
echo Debian
fi
}
get_pkg_for_program () {
_BTU_program="$1"
_BTU_distro=$(get_distro)
# Mapping of programs to RPM/DEB packages if pkg differs from program name
declare -A default_program_package_mapping_ALinux
declare -A default_program_package_mapping_Debian
default_program_package_mapping_ALinux=( ["g++"]="gcc-c++" )
default_program_package_mapping_Debian=( ["g++"]="g++" )
_BTU_pkg=""
if [ "xDebian" == "x$_BTU_distro" -o "xUbuntu" == "x$_BTU_distro" ] ; then
_BTU_pkg="${program_package_mapping_Debian[$_BTU_program]:-${default_program_package_mapping_Debian[$_BTU_program]}}"
elif [ "xALinux" == "x$_BTU_distro" ] ; then
_BTU_pkg="${program_package_mapping_ALinux[$_BTU_program]:-${default_program_package_mapping_ALinux[$_BTU_program]}}"
fi
if [ -z "$_BTU_pkg" ] ; then
_BTU_pkg="$_BTU_program"
fi
echo "$_BTU_pkg"
}
# installs program (assume deb/rpm packagename == program name)
install_program () {
_install_program_program="$1"
if [ -z "$_install_program_program" ] ; then
diag "install_program: no program name provided"
return
fi
if ! has_program "$program" ; then
_install_program_pkg=$(get_pkg_for_program $_install_program_program)
print_and_diag "INSTALLING program: $_install_program_program (package '$_install_program_pkg') ..."
if has_program "aptitude" ; then
sudo aptitude update
sudo aptitude -y install "$_install_program_pkg"
elif has_program "yum" ; then
sudo yum -y update
sudo yum -y install "$_install_program_pkg"
else
print_and_diag "Neither 'aptitude' nor 'yum' available."
fi
fi
}
# stops testscript if program not available
require_program () {
program="${1:-UNKNOWNPROGRAM}"
explanation="${2:-Missing program $program}"
if has_program "$program" ; then
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# checks whether the file is available
has_file () {
file="${1:-UNKNOWNFILE}"
explanation="${2:-Missing file $file}"
if [ -e "$file" ] ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
# stops testscript if file not available
require_file () {
file="${1:-UNKNOWNFILE}"
explanation="${2:-Missing file $file}"
if has_file "$file" ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_file $file" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# get environment variable
get_env () {
_ltu_get_env_name="${1:-}"
explanation="${2:-No environment variable $_ltu_get_env_name}"
echo "${!_ltu_get_env_name}"
return
}
# return whether environment variable is set to expected value
has_env () {
_ltu_require_env_name="${1:-}"
_ltu_require_env_expected_value="${2:-}"
_ltu_require_env_actual_value="${!_ltu_require_env_name}"
if [ "x$_ltu_require_env_actual_value" = "x$_ltu_require_env_expected_value" ] ; then
return $_SUCCESS
else
return $_FAILURE
fi
}
# stops testscript if environment variable does not equal a particular value
require_env_eq () {
_ltu_require_env_name="${1:-}"
_ltu_require_env_expected_value="${2:-}"
_ltu_require_env_actual_value="${!_ltu_require_env_name}"
explanation="require environment variable $_ltu_require_env_name = '$_ltu_require_env_expected_value' (actual value: '$_ltu_require_env_actual_value')"
if has_env "$_ltu_require_env_name" "$_ltu_require_env_expected_value" ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then
ok $_SUCCESS "$explanation"
fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# stops testscript if environment variable equals a particular value
require_env_not_eq () {
_ltu_require_env_name="${1:-}"
_ltu_require_env_expected_value="${2:-}"
_ltu_require_env_actual_value="${!_ltu_require_env_name}"
explanation="require environment variable $_ltu_require_env_name != '$_ltu_require_env_expected_value' (actual value: '$_ltu_require_env_actual_value')"
if ! has_env "$_ltu_require_env_name" "$_ltu_require_env_expected_value" ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then
ok $_SUCCESS "$explanation"
fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
# checks whether the script's criticality is in allowed range
has_crit_level () {
_ta_crit_level="${1:-5}"
_ta_crit_level_allowed="${CRITICALITY:-0}"
if [ $_ta_crit_level -le $_ta_crit_level_allowed ] ; then
return $_SUCCESS;
else
return $_FAILURE
fi
}
# stops testscript if script's criticality is not in allowed range
require_crit_level () {
_ta_crit_level="${1:-5}"
_ta_crit_level_allowed="${CRITICALITY:-0}"
explanation="${2:-Too high criticality level: $_ta_crit_level (CRITICALITY=$_ta_crit_level_allowed)}"
if has_crit_level $_ta_crit_level ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "criticality level $_ta_crit_level (CRITICALITY=$_ta_crit_level_allowed)" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
require_root () {
explanation="${1:-Need to run as root}"
ID=$(id|cut -d" " -f1|cut -d= -f2|cut -d\( -f1)
if [ "x$ID" == "x0" ] ; then
if [ "x1" = "x$REQUIRES_GENERATE_TAP" ] ; then ok $_SUCCESS "require_root" ; fi
return $_SUCCESS
else
autoreport_skip_all "$explanation"
fi
}
get_largest_partition () {
echo $(df |grep -v -i available | awk '{print $4, $1, $6}'| sort -t" " -k 1 -n|tail -1|cut -d" " -f3)
}
get_largest_user_tempdir () {
_BTU_LARGESTPARTITION=$(get_largest_partition)
_BTU_TEMP=${_BTU_LARGESTPARTITION:-${TEMP:-/tmp}}
_BTU_LARGETEMP=$(mktemp -q -d --tmpdir=$_BTU_TEMP)
if [ ! -w "$_BTU_LARGETEMP" ] ; then
_BTU_LARGETEMP=$(sudo mktemp -q -d --tmpdir=$_BTU_TEMP)
sudo chown $USER "$_BTU_LARGETEMP"
fi
echo "$_BTU_LARGETEMP"
}
get_first_file () {
for i in $(seq 1 $#) ; do
file=${!i}
if [ -r "$file" ] ; then
echo "$file"
return
fi
done
}
# checks whether MSRs could be read from userspace
# will try to load the appropriate kernel module if not already done
# will return an error if the file is not readable (not root)
has_msr_access() (
cpu=${1:-0}
if [ ! -e /dev/cpu/$cpu/msr ] ; then
has_program modprobe || return 1
modprobe msr || return 1
fi
[ -r /dev/cpu/$cpu/msr ]
)
# reads a MSR via the /dev/cpu/<n>/msr device
# expects the MSR number (in hex) as the first parameter and optionally the
# CPU number from which to read as the second argument (defaults to 0)
# outputs a 16 char hex value (lower case letters) to stdout
# returns 0 on success, 1 for an invalid MSR and 2 for permission issues
read_msr() (
cpu=${2:-0}
if has_program rdmsr ; then
rdmsr -x -0 -p $cpu "$1" 2> /dev/null
return $?
fi
[ -r /dev/cpu/$cpu/msr ] || return 2