1 #!/bin/bash
2 #
3 # Software injection based test cases: test cases are triggered via
4 # mce-inject tool.
5 # Copyright (c) 2010, Intel Corporation
6 #
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License version
9 # 2 as published by the Free Software Foundation.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; If not, see <http://www.gnu.org/licenses/>.
18 #
19 # Author: Xudong Hao <xudong.hao@intel.com>
20 #
21 
22 . $ROOT/config/setup.conf
23 
24 #Guest Image Preparation
25 hvm_image_prepare()
26 {
27     local image=$1
28     local tmpdir=`mktemp -d`
29     local tmpfile=`mktemp`
30     local offset=`kpartx -l $image | awk '{print $NF*512}'`
31     mount -oloop,offset=$offset $image $tmpdir && echo "mount image to $tmpdir"
32     local g_grub=$tmpdir/boot/grub/grub.conf
33     if [ $? -ne 0 ]; then
34         show "  Mount image failed!"
35         return 1
36     fi
37 
38     if ! grep FLAG_CONSOLE $g_grub; then
39         sed -e '/kernel/s/$/ console=ttyS0,115200,8n1 console=tty0/g' \
40             $g_grub > $tmpfile
41         mv -f $tmpfile $g_grub
42         rm -f $tmpfile
43         echo "
44 #### FLAG_CONSOLE #### " >> $g_grub
45     fi
46     umount $tmpdir
47     rm -fr $tmpdir
48 
49     return 0
50 }
51 
52 create_hvm_guest()
53 {
54     local image=$1
55     local originconfig="/etc/xen/xmexample.hvm"
56     local TF=`mktemp`
57     local case_dir=$ROOT/results/$this_case
58     local config=$case_dir/guest_config
59     [ -d $case_dir ] || mkdir $case_dir
60     [ -f $logfile ] || touch $logfile
61     local File=`echo $image|sed "s/\//\\\\\\\\\\//g"`
62     local g_name="`basename $image`_`date +%H%M%S`"
63 
64     hvm_image_prepare $image
65 
66     while getopts ":u:m:" Option
67     do
68         case $Option in
69             u ) vcpus=$OPTARG;;
70             m ) memory=$OPTARG;;
71             e ) bridge_name=$OPTARG;;
72             * ) ;;
73         esac
74     done
75 
76     cp $originconfig $config -f
77 
78     if [ -z $image ]; then
79         show "Image file $image does not exist, Please input one valid file"
80         return 1
81     fi
82 
83     sed -e "/^disk/s/file:.*,\(hda\)/file:${File},\1/" $config \
84           | sed -e "/^disk/s/phy:.*,\(hda\)/file:${File},\1/" >$TF
85     mv -f $TF $config
86 
87     [ -z $memory ] || sed -i "/^memory/s/^.*$/memory = $memory/" $config
88     [ -z $vcpus ] || sed -i "1,/^#vcpus/s/^#vcpus.*$/vcpus=$vcpus/;1d" $config
89     sed -i "/^vif/s/vif/#vif/" $config
90     sed -i "/^name/s/^.*$/name = \"$g_name\"/" $config
91 
92     string1=$(ls /dev/pts | sort)
93     xm cr $config
94     [ $? -eq 0 ] && domid=`xm list $g_name | tail -n1 | awk '{print $2}'`
95     if [ -z $domid ]; then
96         show "  Guest can not boot up"
97         return 1
98     fi
99 
100     sleep 10
101 
102     string2=$(ls /dev/pts | sort)
103 
104     get_guest_klog
105     sleep 40
106 
107     return 0
108 }
109 
110 get_guest_klog()
111 {
112     local case_dir=$ROOT/results/$this_case
113     gklog=$case_dir/gklog
114     [ -d $case_dir ] || mkdir $case_dir
115     [ -f $gklog ] || touch $gklog
116     for fo in $string2; do
117         echo $string1 | grep $fo -wq
118         [ $? -eq 1 ] && num=$fo
119     done
120     cat /dev/pts/$num > $gklog &
121 }
122 
123 mce_inject_trigger()
124 {
125     local errtype=$1
126     local append=""
127     while getopts ":d:u:p:" Option
128     do
129         case $Option in
130             d ) domid=$OPTARG;;
131             u ) cpu=$OPTARG;;
132             p ) pageaddr=$OPTARG;;
133             * ) ;;
134         esac
135     done
136 
137     [ -z $domid ] || append=$append" -d $domid"
138     [ -z $cpu ] || append=$append" -c $cpu"
139     [ -z $pageaddr ] || append=$append" -p $pageaddr"
140 
141     [ -f $ROOT/tools/xen-mceinj ]
142     if [ $? -eq 0 ]; then
143         xm dmesg -c
144         $ROOT/tools/xen-mceinj -t $errtype $append
145         if [ $? -ne 0 ]; then
146             show "  Failed: Maybe the memory addr is out of range. \
147                       Please check whether used xen-mceinj tool correctlly"
148             return 1
149         fi
150     else
151         show "  Failed: please compile xen-mce inject tool firstly"
152         return 1
153     fi
154     return 0
155 }
156 
157 xen_verify()
158 {
159     local case_dir=$ROOT/results/$this_case
160     local xenlog=$case_dir/xenlog
161     [ -d $case_dir ] || mkdir $case_dir
162     [ -f $xenlog ] || touch $xenlog
163     xm dmesg > $xenlog
164     grep "Error is successfully recovered" $xenlog > /dev/null
165     if [ $? -eq 0 ]; then
166         show "  Passed: Xen handle this MCE error successfully"
167     else
168         show "  Failed: Xen does not handle MCE error correctly !!"
169         return 1
170     fi
171     return 0
172 }
173 
174 guest_verify()
175 {
176     grep "kernel page recovery" $gklog > /dev/null
177     if [ $? -eq 0 ]; then
178         show "  Passed: Guest recive MCE error and solved correctly"
179     else
180         show "  Failed: Guest fail to solve MCE error"
181         return 1
182     fi
183     return 0
184 }
185 
186 mcelog_verify()
187 {
188     local err_type=$1
189     local ret=0
190     local case_dir=$ROOT/results/$this_case
191     local mcelog=$case_dir/mcelog
192     [ -d $case_dir ] || mkdir $case_dir
193     [ -f $mcelog ] || touch $mcelog
194     mcelog > $mcelog
195     if [ -z $mcelog ]; then
196         show "  Failed: MCELOG does not catch anything"
197         return 1
198     else
199         if [ $err_type -eq 0 ]; then
200             grep "MEMORY CONTROLLER MS_CHANNELunspecified_ERR" $mcelog \
201                 > /dev/null
202             ret=$?
203         elif [ $err_type -eq 1 ]; then
204             grep "Generic CACHE Level-2 Eviction Error" $mcelog > /dev/null
205             ret=$?
206         elif [ $err_type -eq 2 ]; then
207             grep "Data CACHE Level-2 Data-Read Error" $mcelog > /dev/null
208             ret=$?
209         fi
210 
211         if [ $ret -eq 0 ]; then
212             show "  Passed: MCElog catch a correct error"
213         else
214             show "  Failed: MCE log catch a incorrect error !!"
215             return 1
216         fi
217     fi
218 
219     return 0
220 }
221 
222 function des_guest()
223 {
224     xm des $domid
225 }
226 
227 function clean_env()
228 {
229     [ -d $ROOT/results ] || mkdir $ROOT/results
230     # clean logs and results of last test for this case
231     rm -fr $ROOT/results/$this_case/*
232 }
233 
234 function show()
235 {
236     local case_dir=$ROOT/results/$this_case
237     local logfile=$case_dir/testlog
238     [ -d $case_dir ] || mkdir $case_dir
239     [ -f $logfile ] || touch $logfile
240     echo -e $* | tee -a $logfile > /dev/null
241 }
242 
243 function gen_result()
244 {
245     local ret=$1
246     local case_dir=$ROOT/results/$this_case
247     local result=$case_dir/result
248     [ -d $case_dir ] || mkdir $case_dir
249     [ -f $result ] || touch $result
250 
251     if [ $ret -eq 0 ]; then
252         echo "PASSED" > $result
253     elif [ $ret -eq 1 ]; then
254         echo "FAILED" > $result
255         echo "   Please check testlog for details!!! " >> $result
256     else
257         echo "NORESULT" > $result
258         echo "   Please check testlog for details!!! " >> $result
259     fi
260 }
261