aboutsummaryrefslogtreecommitdiffstats
path: root/tools/tests/mce-test/lib/xen-mceinj-tool.sh
blob: 1d25d2a2bc3eba21c668fbe75ead940b84ba51c6 (plain)
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
#!/bin/bash
#
# Software injection based test cases: test cases are triggered via
# mce-inject tool.
# Copyright (c) 2010, Intel Corporation
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version
# 2 as published by the Free Software Foundation.
# 
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
#
# Author: Xudong Hao <xudong.hao@intel.com>
#

. $ROOT/config/setup.conf

#Guest Image Preparation
hvm_image_prepare()
{
    local image=$1
    local tmpdir=`mktemp -d`
    local tmpfile=`mktemp`
    local offset=`kpartx -l $image | awk '{print $NF*512}'`
    mount -oloop,offset=$offset $image $tmpdir && echo "mount image to $tmpdir"
    local g_grub=$tmpdir/boot/grub/grub.conf
    if [ $? -ne 0 ]; then
        show "  Mount image failed!"
        return 1
    fi

    if ! grep FLAG_CONSOLE $g_grub; then
        sed -e '/kernel/s/$/ console=ttyS0,115200,8n1 console=tty0/g' \
            $g_grub > $tmpfile
        mv -f $tmpfile $g_grub
        rm -f $tmpfile
        echo "
#### FLAG_CONSOLE #### " >> $g_grub
    fi
    umount $tmpdir
    rm -fr $tmpdir

    return 0
}

create_hvm_guest()
{
    local image=$1
    local originconfig="/etc/xen/xmexample.hvm"
    local TF=`mktemp`
    local case_dir=$ROOT/results/$this_case
    local config=$case_dir/guest_config
    [ -d $case_dir ] || mkdir $case_dir
    [ -f $logfile ] || touch $logfile
    local File=`echo $image|sed "s/\//\\\\\\\\\\//g"`
    local g_name="`basename $image`_`date +%H%M%S`"

    hvm_image_prepare $image

    while getopts ":u:m:" Option
    do
        case $Option in
            u ) vcpus=$OPTARG;;
            m ) memory=$OPTARG;;
            e ) bridge_name=$OPTARG;;
            * ) ;;
        esac
    done

    cp $originconfig $config -f

    if [ -z $image ]; then
        show "Image file $image does not exist, Please input one valid file"
        return 1
    fi

    sed -e "/^disk/s/file:.*,\(hda\)/file:${File},\1/" $config \
          | sed -e "/^disk/s/phy:.*,\(hda\)/file:${File},\1/" >$TF
    mv -f $TF $config

    [ -z $memory ] || sed -i "/^memory/s/^.*$/memory = $memory/" $config
    [ -z $vcpus ] || sed -i "1,/^#vcpus/s/^#vcpus.*$/vcpus=$vcpus/;1d" $config
    sed -i "/^vif/s/vif/#vif/" $config
    sed -i "/^name/s/^.*$/name = \"$g_name\"/" $config

    string1=$(ls /dev/pts | sort)
    xm cr $config
    [ $? -eq 0 ] && domid=`xm list $g_name | tail -n1 | awk '{print $2}'`
    if [ -z $domid ]; then
        show "  Guest can not boot up"
        return 1
    fi
    
    sleep 10

    string2=$(ls /dev/pts | sort)

    get_guest_klog
    sleep 40

    return 0
}

get_guest_klog()
{
    local case_dir=$ROOT/results/$this_case
    gklog=$case_dir/gklog
    [ -d $case_dir ] || mkdir $case_dir
    [ -f $gklog ] || touch $gklog
    for fo in $string2; do
        echo $string1 | grep $fo -wq
        [ $? -eq 1 ] && num=$fo
    done
    cat /dev/pts/$num > $gklog &
}

mce_inject_trigger()
{
    local errtype=$1
    local append=""
    while getopts ":d:u:p:" Option
    do
        case $Option in
            d ) domid=$OPTARG;;
            u ) cpu=$OPTARG;;
            p ) pageaddr=$OPTARG;;
            * ) ;;
        esac
    done

    [ -z $domid ] || append=$append" -d $domid"
    [ -z $cpu ] || append=$append" -c $cpu"
    [ -z $pageaddr ] || append=$append" -p $pageaddr"

    [ -f $ROOT/tools/xen-mceinj ]
    if [ $? -eq 0 ]; then
        xm dmesg -c
        $ROOT/tools/xen-mceinj -t $errtype $append
        if [ $? -ne 0 ]; then
            show "  Failed: Maybe the memory addr is out of range. \
                      Please check whether used xen-mceinj tool correctlly"
            return 1
        fi
    else
        show "  Failed: please compile xen-mce inject tool firstly"
        return 1
    fi
    return 0
}

xen_verify()
{
    local case_dir=$ROOT/results/$this_case
    local xenlog=$case_dir/xenlog
    [ -d $case_dir ] || mkdir $case_dir
    [ -f $xenlog ] || touch $xenlog
    xm dmesg > $xenlog
    grep "Error is successfully recovered" $xenlog > /dev/null
    if [ $? -eq 0 ]; then
        show "  Passed: Xen handle this MCE error successfully"
    else
        show "  Failed: Xen does not handle MCE error correctly !!"
        return 1
    fi
    return 0
}

guest_verify()
{
    grep "kernel page recovery" $gklog > /dev/null
    if [ $? -eq 0 ]; then
        show "  Passed: Guest recive MCE error and solved correctly"
    else
        show "  Failed: Guest fail to solve MCE error"
        return 1
    fi
    return 0
}

mcelog_verify()
{
    local err_type=$1
    local ret=0
    local case_dir=$ROOT/results/$this_case
    local mcelog=$case_dir/mcelog
    [ -d $case_dir ] || mkdir $case_dir
    [ -f $mcelog ] || touch $mcelog
    mcelog > $mcelog
    if [ -z $mcelog ]; then
        show "  Failed: MCELOG does not catch anything"
        return 1
    else
        if [ $err_type -eq 0 ]; then
            grep "MEMORY CONTROLLER MS_CHANNELunspecified_ERR" $mcelog \
                > /dev/null
            ret=$?
        elif [ $err_type -eq 1 ]; then
            grep "Generic CACHE Level-2 Eviction Error" $mcelog > /dev/null
            ret=$?
        elif [ $err_type -eq 2 ]; then
            grep "Data CACHE Level-2 Data-Read Error" $mcelog > /dev/null
            ret=$?
        fi

        if [ $ret -eq 0 ]; then
            show "  Passed: MCElog catch a correct error"
        else 
            show "  Failed: MCE log catch a incorrect error !!"
            return 1
        fi
    fi

    return 0
}

function des_guest()
{
    xm des $domid    
}

function clean_env()
{
    [ -d $ROOT/results ] || mkdir $ROOT/results
    # clean logs and results of last test for this case
    rm -fr $ROOT/results/$this_case/*
}

function show()
{
    local case_dir=$ROOT/results/$this_case
    local logfile=$case_dir/testlog
    [ -d $case_dir ] || mkdir $case_dir
    [ -f $logfile ] || touch $logfile
    echo -e $* | tee -a $logfile > /dev/null
}

function gen_result()
{
    local ret=$1
    local case_dir=$ROOT/results/$this_case
    local result=$case_dir/result
    [ -d $case_dir ] || mkdir $case_dir
    [ -f $result ] || touch $result
    
    if [ $ret -eq 0 ]; then
        echo "PASSED" > $result
    elif [ $ret -eq 1 ]; then
        echo "FAILED" > $result
        echo "   Please check testlog for details!!! " >> $result
    else
        echo "NORESULT" > $result
        echo "   Please check testlog for details!!! " >> $result
    fi
}