]>
Commit | Line | Data |
---|---|---|
d89dffa9 AM |
1 | #!/bin/bash |
2 | ||
3 | SYSFS= | |
4 | ||
5 | prerequisite() | |
6 | { | |
7 | msg="skip all tests:" | |
8 | ||
9 | if [ $UID != 0 ]; then | |
10 | echo $msg must be run as root >&2 | |
11 | exit 0 | |
12 | fi | |
13 | ||
14 | SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` | |
15 | ||
16 | if [ ! -d "$SYSFS" ]; then | |
17 | echo $msg sysfs is not mounted >&2 | |
18 | exit 0 | |
19 | fi | |
20 | ||
21 | if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then | |
22 | echo $msg memory hotplug is not supported >&2 | |
23 | exit 0 | |
24 | fi | |
fae61a87 PHL |
25 | |
26 | if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then | |
27 | echo $msg no hot-pluggable memory >&2 | |
28 | exit 0 | |
29 | fi | |
d89dffa9 AM |
30 | } |
31 | ||
32 | # | |
33 | # list all hot-pluggable memory | |
34 | # | |
35 | hotpluggable_memory() | |
36 | { | |
37 | local state=${1:-.\*} | |
38 | ||
39 | for memory in $SYSFS/devices/system/memory/memory*; do | |
40 | if grep -q 1 $memory/removable && | |
41 | grep -q $state $memory/state; then | |
42 | echo ${memory##/*/memory} | |
43 | fi | |
44 | done | |
45 | } | |
46 | ||
a54726dd | 47 | hotpluggable_offline_memory() |
d89dffa9 AM |
48 | { |
49 | hotpluggable_memory offline | |
50 | } | |
51 | ||
52 | hotpluggable_online_memory() | |
53 | { | |
54 | hotpluggable_memory online | |
55 | } | |
56 | ||
57 | memory_is_online() | |
58 | { | |
59 | grep -q online $SYSFS/devices/system/memory/memory$1/state | |
60 | } | |
61 | ||
62 | memory_is_offline() | |
63 | { | |
64 | grep -q offline $SYSFS/devices/system/memory/memory$1/state | |
65 | } | |
66 | ||
67 | online_memory() | |
68 | { | |
69 | echo online > $SYSFS/devices/system/memory/memory$1/state | |
70 | } | |
71 | ||
72 | offline_memory() | |
73 | { | |
74 | echo offline > $SYSFS/devices/system/memory/memory$1/state | |
75 | } | |
76 | ||
77 | online_memory_expect_success() | |
78 | { | |
79 | local memory=$1 | |
80 | ||
81 | if ! online_memory $memory; then | |
82 | echo $FUNCNAME $memory: unexpected fail >&2 | |
3e49bbb0 | 83 | return 1 |
d89dffa9 AM |
84 | elif ! memory_is_online $memory; then |
85 | echo $FUNCNAME $memory: unexpected offline >&2 | |
3e49bbb0 | 86 | return 1 |
d89dffa9 | 87 | fi |
3e49bbb0 | 88 | return 0 |
d89dffa9 AM |
89 | } |
90 | ||
91 | online_memory_expect_fail() | |
92 | { | |
93 | local memory=$1 | |
94 | ||
95 | if online_memory $memory 2> /dev/null; then | |
96 | echo $FUNCNAME $memory: unexpected success >&2 | |
3e49bbb0 | 97 | return 1 |
d89dffa9 AM |
98 | elif ! memory_is_offline $memory; then |
99 | echo $FUNCNAME $memory: unexpected online >&2 | |
3e49bbb0 | 100 | return 1 |
d89dffa9 | 101 | fi |
3e49bbb0 | 102 | return 0 |
d89dffa9 AM |
103 | } |
104 | ||
105 | offline_memory_expect_success() | |
106 | { | |
107 | local memory=$1 | |
108 | ||
109 | if ! offline_memory $memory; then | |
110 | echo $FUNCNAME $memory: unexpected fail >&2 | |
3e49bbb0 | 111 | return 1 |
d89dffa9 AM |
112 | elif ! memory_is_offline $memory; then |
113 | echo $FUNCNAME $memory: unexpected offline >&2 | |
3e49bbb0 | 114 | return 1 |
d89dffa9 | 115 | fi |
3e49bbb0 | 116 | return 0 |
d89dffa9 AM |
117 | } |
118 | ||
119 | offline_memory_expect_fail() | |
120 | { | |
121 | local memory=$1 | |
122 | ||
123 | if offline_memory $memory 2> /dev/null; then | |
124 | echo $FUNCNAME $memory: unexpected success >&2 | |
3e49bbb0 | 125 | return 1 |
d89dffa9 AM |
126 | elif ! memory_is_online $memory; then |
127 | echo $FUNCNAME $memory: unexpected offline >&2 | |
3e49bbb0 | 128 | return 1 |
d89dffa9 | 129 | fi |
3e49bbb0 | 130 | return 0 |
d89dffa9 AM |
131 | } |
132 | ||
133 | error=-12 | |
134 | priority=0 | |
135 | ratio=10 | |
3e49bbb0 | 136 | retval=0 |
d89dffa9 AM |
137 | |
138 | while getopts e:hp:r: opt; do | |
139 | case $opt in | |
140 | e) | |
141 | error=$OPTARG | |
142 | ;; | |
143 | h) | |
144 | echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]" | |
145 | exit | |
146 | ;; | |
147 | p) | |
148 | priority=$OPTARG | |
149 | ;; | |
150 | r) | |
151 | ratio=$OPTARG | |
3b476858 PHL |
152 | if [ "$ratio" -gt 100 ] || [ "$ratio" -lt 0 ]; then |
153 | echo "The percentage should be an integer within 0~100 range" | |
154 | exit 1 | |
155 | fi | |
d89dffa9 AM |
156 | ;; |
157 | esac | |
158 | done | |
159 | ||
160 | if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then | |
161 | echo "error code must be -4095 <= errno < 0" >&2 | |
162 | exit 1 | |
163 | fi | |
164 | ||
165 | prerequisite | |
166 | ||
ddddda9b | 167 | echo "Test scope: $ratio% hotplug memory" |
ddddda9b | 168 | |
d89dffa9 AM |
169 | # |
170 | # Online all hot-pluggable memory | |
171 | # | |
3e49bbb0 PHL |
172 | hotpluggable_num=`hotpluggable_offline_memory | wc -l` |
173 | echo -e "\t online all hot-pluggable memory in offline state:" | |
174 | if [ "$hotpluggable_num" -gt 0 ]; then | |
175 | for memory in `hotpluggable_offline_memory`; do | |
176 | echo "offline->online memory$memory" | |
177 | if ! online_memory_expect_success $memory; then | |
178 | retval=1 | |
179 | fi | |
180 | done | |
181 | else | |
182 | echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state" | |
183 | fi | |
d89dffa9 AM |
184 | |
185 | # | |
186 | # Offline $ratio percent of hot-pluggable memory | |
187 | # | |
3e49bbb0 PHL |
188 | hotpluggable_num=`hotpluggable_online_memory | wc -l` |
189 | target=`echo "a=$hotpluggable_num*$ratio; if ( a%100 ) a/100+1 else a/100" | bc` | |
190 | echo -e "\t offline $ratio% hot-pluggable memory in online state" | |
191 | echo -e "\t trying to offline $target out of $hotpluggable_num memory block(s):" | |
d89dffa9 | 192 | for memory in `hotpluggable_online_memory`; do |
3e49bbb0 PHL |
193 | if [ "$target" -gt 0 ]; then |
194 | echo "online->offline memory$memory" | |
195 | if offline_memory_expect_success $memory; then | |
196 | target=$(($target - 1)) | |
197 | fi | |
d89dffa9 AM |
198 | fi |
199 | done | |
3e49bbb0 PHL |
200 | if [ "$target" -gt 0 ]; then |
201 | retval=1 | |
202 | echo -e "\t\t FAILED - unable to offline some memory blocks, device busy?" | |
203 | fi | |
d89dffa9 AM |
204 | |
205 | # | |
206 | # Online all hot-pluggable memory again | |
207 | # | |
3e49bbb0 PHL |
208 | hotpluggable_num=`hotpluggable_offline_memory | wc -l` |
209 | echo -e "\t online all hot-pluggable memory in offline state:" | |
210 | if [ "$hotpluggable_num" -gt 0 ]; then | |
211 | for memory in `hotpluggable_offline_memory`; do | |
212 | echo "offline->online memory$memory" | |
213 | if ! online_memory_expect_success $memory; then | |
214 | retval=1 | |
215 | fi | |
216 | done | |
217 | else | |
218 | echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state" | |
219 | fi | |
d89dffa9 AM |
220 | |
221 | # | |
222 | # Test with memory notifier error injection | |
223 | # | |
224 | ||
225 | DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` | |
226 | NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory | |
227 | ||
228 | prerequisite_extra() | |
229 | { | |
230 | msg="skip extra tests:" | |
231 | ||
232 | /sbin/modprobe -q -r memory-notifier-error-inject | |
233 | /sbin/modprobe -q memory-notifier-error-inject priority=$priority | |
234 | ||
235 | if [ ! -d "$DEBUGFS" ]; then | |
236 | echo $msg debugfs is not mounted >&2 | |
3e49bbb0 | 237 | exit $retval |
d89dffa9 AM |
238 | fi |
239 | ||
240 | if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then | |
241 | echo $msg memory-notifier-error-inject module is not available >&2 | |
3e49bbb0 | 242 | exit $retval |
d89dffa9 AM |
243 | fi |
244 | } | |
245 | ||
e977f5e5 | 246 | echo -e "\t Test with memory notifier error injection" |
d89dffa9 AM |
247 | prerequisite_extra |
248 | ||
249 | # | |
250 | # Offline $ratio percent of hot-pluggable memory | |
251 | # | |
252 | echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error | |
253 | for memory in `hotpluggable_online_memory`; do | |
254 | if [ $((RANDOM % 100)) -lt $ratio ]; then | |
255 | offline_memory_expect_success $memory | |
256 | fi | |
257 | done | |
258 | ||
259 | # | |
260 | # Test memory hot-add error handling (offline => online) | |
261 | # | |
262 | echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error | |
a54726dd | 263 | for memory in `hotpluggable_offline_memory`; do |
d89dffa9 AM |
264 | online_memory_expect_fail $memory |
265 | done | |
266 | ||
267 | # | |
268 | # Online all hot-pluggable memory | |
269 | # | |
270 | echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error | |
a54726dd | 271 | for memory in `hotpluggable_offline_memory`; do |
d89dffa9 AM |
272 | online_memory_expect_success $memory |
273 | done | |
274 | ||
275 | # | |
276 | # Test memory hot-remove error handling (online => offline) | |
277 | # | |
278 | echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error | |
279 | for memory in `hotpluggable_online_memory`; do | |
280 | offline_memory_expect_fail $memory | |
281 | done | |
282 | ||
283 | echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error | |
284 | /sbin/modprobe -q -r memory-notifier-error-inject | |
3e49bbb0 PHL |
285 | |
286 | exit $retval |