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