3 # Copyright (C) 2014 Red Hat <contact@redhat.com>
5 # Author: Loic Dachary <loic@dachary.org>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU Library Public License as published by
9 # the Free Software Foundation; either version 2, or (at your option)
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Library Public License for more details.
17 source $
(dirname $0)/..
/detect-build-env-vars.sh
18 source $CEPH_ROOT/qa
/workunits
/ceph-helpers.sh
20 # Test development and debugging
21 # Set to "yes" in order to ignore diff errors and save results to update test
24 # Ignore the epoch and filter out the attr '_' value because it has date information and won't match
25 jqfilter
='.inconsistents | (.[].shards[].attrs[] | select(.name == "_") | .value) |= "----Stripped-by-test----"'
26 sortkeys
='import json; import sys ; JSON=sys.stdin.read() ; ud = json.loads(JSON) ; print json.dumps(ud, sort_keys=True, indent=2)'
28 # Remove items are not consistent across runs, the pg interval and client
29 sedfilter
='s/\([ ]*\"\(selected_\)*object_info\":.*head[(]\)[^[:space:]]* [^[:space:]]* \(.*\)/\1\3/'
35 export CEPH_MON
="127.0.0.1:7107" # git grep '\<7107\>' : there must be only one
37 CEPH_ARGS
+="--fsid=$(uuidgen) --auth-supported=none "
38 CEPH_ARGS
+="--mon-host=$CEPH_MON "
40 local funcs
=${@:-$(set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p')}
41 for func
in $funcs ; do
42 $func $dir ||
return 1
46 function add_something
() {
49 local obj
=${3:-SOMETHING}
50 local scrub
=${4:-noscrub}
52 if [ "$scrub" = "noscrub" ];
54 ceph osd
set noscrub ||
return 1
55 ceph osd
set nodeep-scrub ||
return 1
57 ceph osd
unset noscrub ||
return 1
58 ceph osd
unset nodeep-scrub ||
return 1
62 echo $payload > $dir/ORIGINAL
63 rados
--pool $poolname put
$obj $dir/ORIGINAL ||
return 1
67 # Corrupt one copy of a replicated pool
69 function TEST_corrupt_and_repair_replicated
() {
73 setup
$dir ||
return 1
74 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
75 run_mgr
$dir x ||
return 1
76 run_osd
$dir 0 ||
return 1
77 run_osd
$dir 1 ||
return 1
78 wait_for_clean ||
return 1
80 add_something
$dir $poolname ||
return 1
81 corrupt_and_repair_one
$dir $poolname $
(get_not_primary
$poolname SOMETHING
) ||
return 1
82 # Reproduces http://tracker.ceph.com/issues/8914
83 corrupt_and_repair_one
$dir $poolname $
(get_primary
$poolname SOMETHING
) ||
return 1
85 teardown
$dir ||
return 1
88 function corrupt_and_repair_two
() {
95 # 1) remove the corresponding file from the OSDs
98 run_in_background pids objectstore_tool
$dir $first SOMETHING remove
99 run_in_background pids objectstore_tool
$dir $second SOMETHING remove
102 if [ $return_code -ne 0 ]; then return $return_code; fi
107 local pg
=$
(get_pg
$poolname SOMETHING
)
110 # 3) The files must be back
113 run_in_background pids objectstore_tool
$dir $first SOMETHING list-attrs
114 run_in_background pids objectstore_tool
$dir $second SOMETHING list-attrs
117 if [ $return_code -ne 0 ]; then return $return_code; fi
119 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
120 diff $dir/ORIGINAL
$dir/COPY ||
return 1
125 # 2) remove the corresponding file from a designated OSD
127 # 4) check that the file has been restored in the designated OSD
129 function corrupt_and_repair_one
() {
135 # 1) remove the corresponding file from the OSD
137 objectstore_tool
$dir $osd SOMETHING remove ||
return 1
141 local pg
=$
(get_pg
$poolname SOMETHING
)
144 # 3) The file must be back
146 objectstore_tool
$dir $osd SOMETHING list-attrs ||
return 1
147 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
148 diff $dir/ORIGINAL
$dir/COPY ||
return 1
151 function corrupt_and_repair_erasure_coded
() {
155 add_something
$dir $poolname ||
return 1
157 local primary
=$
(get_primary
$poolname SOMETHING
)
158 local -a osds
=($
(get_osds
$poolname SOMETHING |
sed -e "s/$primary//"))
159 local not_primary_first
=${osds[0]}
160 local not_primary_second
=${osds[1]}
162 # Reproduces http://tracker.ceph.com/issues/10017
163 corrupt_and_repair_one
$dir $poolname $primary ||
return 1
164 # Reproduces http://tracker.ceph.com/issues/10409
165 corrupt_and_repair_one
$dir $poolname $not_primary_first ||
return 1
166 corrupt_and_repair_two
$dir $poolname $not_primary_first $not_primary_second ||
return 1
167 corrupt_and_repair_two
$dir $poolname $primary $not_primary_first ||
return 1
171 function create_ec_pool
() {
173 local allow_overwrites
=$2
175 ceph osd erasure-code-profile
set myprofile ruleset-failure-domain
=osd
$3 $4 $5 $6 $7 ||
return 1
177 ceph osd pool create
"$poolname" 1 1 erasure myprofile ||
return 1
179 if [ "$allow_overwrites" = "true" ]; then
180 ceph osd pool
set "$poolname" allow_ec_overwrites true ||
return 1
183 wait_for_clean ||
return 1
187 function auto_repair_erasure_coded
() {
189 local allow_overwrites
=$2
190 local poolname
=ecpool
192 # Launch a cluster with 5 seconds scrub interval
193 setup
$dir ||
return 1
194 run_mon
$dir a ||
return 1
195 run_mgr
$dir x ||
return 1
196 local ceph_osd_args
="--osd-scrub-auto-repair=true \
197 --osd-deep-scrub-interval=5 \
198 --osd-scrub-max-interval=5 \
199 --osd-scrub-min-interval=5 \
200 --osd-scrub-interval-randomize-ratio=0"
201 for id
in $
(seq 0 2) ; do
202 if [ "$allow_overwrites" = "true" ]; then
203 run_osd_bluestore
$dir $id $ceph_osd_args ||
return 1
205 run_osd
$dir $id $ceph_osd_args ||
return 1
208 wait_for_clean ||
return 1
211 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 ||
return 1
215 echo $payload > $dir/ORIGINAL
216 rados
--pool $poolname put SOMETHING
$dir/ORIGINAL ||
return 1
218 # Remove the object from one shard physically
219 # Restarted osd get $ceph_osd_args passed
220 objectstore_tool
$dir $
(get_not_primary
$poolname SOMETHING
) SOMETHING remove ||
return 1
221 # Wait for auto repair
222 local pgid
=$
(get_pg
$poolname SOMETHING
)
223 wait_for_scrub
$pgid "$(get_last_scrub_stamp $pgid)"
224 wait_for_clean ||
return 1
225 # Verify - the file should be back
226 # Restarted osd get $ceph_osd_args passed
227 objectstore_tool
$dir $
(get_not_primary
$poolname SOMETHING
) SOMETHING list-attrs ||
return 1
228 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
229 diff $dir/ORIGINAL
$dir/COPY ||
return 1
232 teardown
$dir ||
return 1
235 function TEST_auto_repair_erasure_coded_appends
() {
236 auto_repair_erasure_coded
$1 false
239 function TEST_auto_repair_erasure_coded_overwrites
() {
240 auto_repair_erasure_coded
$1 true
243 function corrupt_and_repair_jerasure
() {
245 local allow_overwrites
=$2
246 local poolname
=ecpool
248 setup
$dir ||
return 1
249 run_mon
$dir a ||
return 1
250 run_mgr
$dir x ||
return 1
251 for id
in $
(seq 0 3) ; do
252 if [ "$allow_overwrites" = "true" ]; then
253 run_osd_bluestore
$dir $id ||
return 1
255 run_osd
$dir $id ||
return 1
258 wait_for_clean ||
return 1
260 create_ec_pool
$poolname $allow_overwrites k
=2 m
=2 ||
return 1
261 corrupt_and_repair_erasure_coded
$dir $poolname ||
return 1
263 teardown
$dir ||
return 1
266 function TEST_corrupt_and_repair_jerasure_appends
() {
267 corrupt_and_repair_jerasure
$1
270 function TEST_corrupt_and_repair_jerasure_overwrites
() {
271 corrupt_and_repair_jerasure
$1 true
274 function corrupt_and_repair_lrc
() {
276 local allow_overwrites
=$2
277 local poolname
=ecpool
279 setup
$dir ||
return 1
280 run_mon
$dir a ||
return 1
281 run_mgr
$dir x ||
return 1
282 for id
in $
(seq 0 9) ; do
283 if [ "$allow_overwrites" = "true" ]; then
284 run_osd_bluestore
$dir $id ||
return 1
286 run_osd
$dir $id ||
return 1
289 wait_for_clean ||
return 1
291 create_ec_pool
$poolname $allow_overwrites k
=4 m
=2 l
=3 plugin
=lrc ||
return 1
292 corrupt_and_repair_erasure_coded
$dir $poolname ||
return 1
294 teardown
$dir ||
return 1
297 function TEST_corrupt_and_repair_lrc_appends
() {
298 corrupt_and_repair_jerasure
$1
301 function TEST_corrupt_and_repair_lrc_overwrites
() {
302 corrupt_and_repair_jerasure
$1 true
305 function unfound_erasure_coded
() {
307 local allow_overwrites
=$2
308 local poolname
=ecpool
311 setup
$dir ||
return 1
312 run_mon
$dir a ||
return 1
313 run_mgr
$dir x ||
return 1
314 for id
in $
(seq 0 3) ; do
315 if [ "$allow_overwrites" = "true" ]; then
316 run_osd_bluestore
$dir $id ||
return 1
318 run_osd
$dir $id ||
return 1
321 wait_for_clean ||
return 1
323 create_ec_pool
$poolname $allow_overwrites k
=2 m
=2 ||
return 1
325 add_something
$dir $poolname ||
return 1
327 local primary
=$
(get_primary
$poolname SOMETHING
)
328 local -a osds
=($
(get_osds
$poolname SOMETHING |
sed -e "s/$primary//"))
329 local not_primary_first
=${osds[0]}
330 local not_primary_second
=${osds[1]}
331 local not_primary_third
=${osds[2]}
334 # 1) remove the corresponding file from the OSDs
337 run_in_background pids objectstore_tool
$dir $not_primary_first SOMETHING remove
338 run_in_background pids objectstore_tool
$dir $not_primary_second SOMETHING remove
339 run_in_background pids objectstore_tool
$dir $not_primary_third SOMETHING remove
342 if [ $return_code -ne 0 ]; then return $return_code; fi
347 local pg
=$
(get_pg
$poolname SOMETHING
)
352 # it may take a bit to appear due to mon/mgr asynchrony
353 for f
in `seq 1 60`; do
354 ceph
-s |
grep "1/1 unfound" && break
357 ceph
-s|
grep "4 osds: 4 up, 4 in" ||
return 1
358 ceph
-s|
grep "1/1 unfound" ||
return 1
360 teardown
$dir ||
return 1
363 function TEST_unfound_erasure_coded_appends
() {
364 unfound_erasure_coded
$1
367 function TEST_unfound_erasure_coded_overwrites
() {
368 unfound_erasure_coded
$1 true
372 # list_missing for EC pool
374 function list_missing_erasure_coded
() {
376 local allow_overwrites
=$2
377 local poolname
=ecpool
379 setup
$dir ||
return 1
380 run_mon
$dir a ||
return 1
381 run_mgr
$dir x ||
return 1
382 for id
in $
(seq 0 2) ; do
383 if [ "$allow_overwrites" = "true" ]; then
384 run_osd_bluestore
$dir $id ||
return 1
386 run_osd
$dir $id ||
return 1
389 wait_for_clean ||
return 1
391 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 ||
return 1
393 # Put an object and remove the two shards (including primary)
394 add_something
$dir $poolname MOBJ0 ||
return 1
395 local -a osds0
=($
(get_osds
$poolname MOBJ0
))
397 # Put another object and remove two shards (excluding primary)
398 add_something
$dir $poolname MOBJ1 ||
return 1
399 local -a osds1
=($
(get_osds
$poolname MOBJ1
))
401 # Stop all osd daemons
402 for id
in $
(seq 0 2) ; do
403 kill_daemons
$dir TERM osd.
$id >&2 < /dev
/null ||
return 1
407 ceph-objectstore-tool
--data-path $dir/$id \
408 MOBJ0 remove ||
return 1
410 ceph-objectstore-tool
--data-path $dir/$id \
411 MOBJ0 remove ||
return 1
414 ceph-objectstore-tool
--data-path $dir/$id \
415 MOBJ1 remove ||
return 1
417 ceph-objectstore-tool
--data-path $dir/$id \
418 MOBJ1 remove ||
return 1
420 for id
in $
(seq 0 2) ; do
421 activate_osd
$dir $id >&2 ||
return 1
423 wait_for_clean ||
return 1
425 # Get get - both objects should in the same PG
426 local pg
=$
(get_pg
$poolname MOBJ0
)
428 # Repair the PG, which triggers the recovering,
429 # and should mark the object as unfound
432 for i
in $
(seq 0 120) ; do
433 [ $i -lt 60 ] ||
return 1
434 matches
=$
(ceph pg
$pg list_missing |
egrep "MOBJ0|MOBJ1" |
wc -l)
435 [ $matches -eq 2 ] && break
438 teardown
$dir ||
return 1
441 function TEST_list_missing_erasure_coded_appends
() {
442 list_missing_erasure_coded
$1 false
445 function TEST_list_missing_erasure_coded_overwrites
() {
446 list_missing_erasure_coded
$1 true
450 # Corrupt one copy of a replicated pool
452 function TEST_corrupt_scrub_replicated
() {
454 local poolname
=csr_pool
457 setup
$dir ||
return 1
458 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
459 run_mgr
$dir x ||
return 1
460 run_osd
$dir 0 ||
return 1
461 run_osd
$dir 1 ||
return 1
462 wait_for_clean ||
return 1
464 ceph osd pool create
$poolname 1 1 ||
return 1
465 wait_for_clean ||
return 1
467 for i
in $
(seq 1 $total_objs) ; do
469 add_something
$dir $poolname $objname ||
return 1
471 rados
--pool $poolname setomapheader
$objname hdr-
$objname ||
return 1
472 rados
--pool $poolname setomapval
$objname key-
$objname val-
$objname ||
return 1
475 local pg
=$
(get_pg
$poolname ROBJ0
)
477 # Compute an old omap digest and save oi
478 CEPH_ARGS
='' ceph daemon
$dir//ceph-osd
.0.asok \
479 config
set osd_deep_scrub_update_digest_min_age
0
480 CEPH_ARGS
='' ceph daemon
$dir//ceph-osd
.1.asok \
481 config
set osd_deep_scrub_update_digest_min_age
0
484 for i
in $
(seq 1 $total_objs) ; do
487 # Alternate corruption between osd.0 and osd.1
488 local osd
=$
(expr $i % 2)
492 # Size (deep scrub data_digest too)
493 local payload
=UVWXYZZZ
494 echo $payload > $dir/CORRUPT
495 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
499 # digest (deep scrub only)
501 echo $payload > $dir/CORRUPT
502 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
507 objectstore_tool
$dir $osd $objname remove ||
return 1
511 # Modify omap value (deep scrub only)
512 objectstore_tool
$dir $osd $objname set-omap key-
$objname $dir/CORRUPT ||
return 1
516 # Delete omap key (deep scrub only)
517 objectstore_tool
$dir $osd $objname rm-omap key-
$objname ||
return 1
521 # Add extra omap key (deep scrub only)
522 echo extra
> $dir/extra-val
523 objectstore_tool
$dir $osd $objname set-omap key2-
$objname $dir/extra-val ||
return 1
528 # Modify omap header (deep scrub only)
529 echo -n newheader
> $dir/hdr
530 objectstore_tool
$dir $osd $objname set-omaphdr
$dir/hdr ||
return 1
535 rados
--pool $poolname setxattr
$objname key1-
$objname val1-
$objname ||
return 1
536 rados
--pool $poolname setxattr
$objname key2-
$objname val2-
$objname ||
return 1
539 echo -n bad-val
> $dir/bad-val
540 objectstore_tool
$dir $osd $objname set-attr _key1-
$objname $dir/bad-val ||
return 1
541 objectstore_tool
$dir $osd $objname rm-attr _key2-
$objname ||
return 1
542 echo -n val3-
$objname > $dir/newval
543 objectstore_tool
$dir $osd $objname set-attr _key3-
$objname $dir/newval ||
return 1
544 rm $dir/bad-val
$dir/newval
548 objectstore_tool
$dir $osd $objname get-attr _
> $dir/robj9-oi
549 echo -n D
> $dir/change
550 rados
--pool $poolname put
$objname $dir/change
551 objectstore_tool
$dir $osd $objname set-attr _
$dir/robj9-oi
552 rm $dir/oi
$dir/change
555 # ROBJ10 must be handled after digests are re-computed by a deep scrub below
556 # ROBJ11 must be handled with config change before deep scrub
557 # ROBJ12 must be handled with config change before scrubs
558 # ROBJ13 must be handled before scrubs
561 echo -n bad-val
> $dir/bad-val
562 objectstore_tool
$dir 0 $objname set-attr _
$dir/bad-val ||
return 1
563 objectstore_tool
$dir 1 $objname rm-attr _ ||
return 1
568 objectstore_tool
$dir $osd $objname rm-attr _ ||
return 1
573 local pg
=$
(get_pg
$poolname ROBJ0
)
575 set_config osd
0 filestore_debug_inject_read_err true ||
return 1
576 set_config osd
1 filestore_debug_inject_read_err true ||
return 1
577 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.1.asok \
578 injectdataerr
$poolname ROBJ11 ||
return 1
579 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.0.asok \
580 injectmdataerr
$poolname ROBJ12 ||
return 1
581 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.0.asok \
582 injectmdataerr
$poolname ROBJ13 ||
return 1
583 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.1.asok \
584 injectdataerr
$poolname ROBJ13 ||
return 1
588 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
590 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
592 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
594 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
595 # Get epoch for repair-get requests
596 epoch
=$
(jq .epoch
$dir/json
)
598 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
616 "selected_object_info": "2:ce3f1d6a:::ROBJ1:head(47'54 osd.0.0:53 dirty|omap|data_digest|omap_digest s 7 uv 3 dd 2ddbf8f5 od f5fba2c6 alloc_hint [0 0 0])",
617 "union_shard_errors": [
645 "selected_object_info": "2:bc819597:::ROBJ12:head(47'52 osd.0.0:51 dirty|omap|data_digest|omap_digest s 7 uv 36 dd 2ddbf8f5 od 67f306a alloc_hint [0 0 0])",
646 "union_shard_errors": [
672 "selected_object_info": "2:d60617f9:::ROBJ13:head(47'55 osd.0.0:54 dirty|omap|data_digest|omap_digest s 7 uv 39 dd 2ddbf8f5 od 6441854d alloc_hint [0 0 0])",
673 "union_shard_errors": [
702 "union_shard_errors": [
726 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
738 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
749 "selected_object_info": "2:30259878:::ROBJ15:head(47'46 osd.0.0:45 dirty|omap|data_digest|omap_digest s 7 uv 45 dd 2ddbf8f5 od 2d2a4d6e alloc_hint [0 0 0])",
750 "union_shard_errors": [
778 "selected_object_info": "2:f2a5b2a4:::ROBJ3:head(47'57 osd.0.0:56 dirty|omap|data_digest|omap_digest s 7 uv 9 dd 2ddbf8f5 od b35dfd alloc_hint [0 0 0])",
779 "union_shard_errors": [
803 "name": "_key1-ROBJ8"
807 "value": "val3-ROBJ8",
808 "name": "_key3-ROBJ8"
812 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
829 "value": "val1-ROBJ8",
830 "name": "_key1-ROBJ8"
834 "value": "val2-ROBJ8",
835 "name": "_key2-ROBJ8"
839 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
848 "selected_object_info": "2:86586531:::ROBJ8:head(82'62 client.4351.0:1 dirty|omap|data_digest|omap_digest s 7 uv 62 dd 2ddbf8f5 od d6be81dc alloc_hint [0 0 0])",
849 "union_shard_errors": [],
851 "attr_value_mismatch",
873 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
877 "object_info": "2:ffdb2004:::ROBJ9:head(102'63 client.4433.0:1 dirty|omap|data_digest|omap_digest s 1 uv 63 dd 2b63260d od 2eecc539 alloc_hint [0 0 0])",
891 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
895 "object_info": "2:ffdb2004:::ROBJ9:head(47'60 osd.0.0:59 dirty|omap|data_digest|omap_digest s 7 uv 27 dd 2ddbf8f5 od 2eecc539 alloc_hint [0 0 0])",
901 "selected_object_info": "2:ffdb2004:::ROBJ9:head(102'63 client.4433.0:1 dirty|omap|data_digest|omap_digest s 1 uv 63 dd 2b63260d od 2eecc539 alloc_hint [0 0 0])",
902 "union_shard_errors": [],
904 "object_info_inconsistency",
905 "attr_value_mismatch"
920 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
921 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
922 if test $getjson = "yes"
924 jq
'.' $dir/json
> save1.json
927 if which jsonschema
> /dev
/null
;
929 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
933 # Change data and size again because digest was recomputed
934 echo -n ZZZ
> $dir/change
935 rados
--pool $poolname put
$objname $dir/change
936 # Set one to an even older value
937 objectstore_tool
$dir 0 $objname set-attr _
$dir/robj9-oi
938 rm $dir/oi
$dir/change
941 objectstore_tool
$dir 1 $objname get-attr _
> $dir/oi
942 rados
--pool $poolname setomapval
$objname key2-
$objname val2-
$objname
943 objectstore_tool
$dir 0 $objname set-attr _
$dir/oi
944 objectstore_tool
$dir 1 $objname set-attr _
$dir/oi
947 set_config osd
0 filestore_debug_inject_read_err true ||
return 1
948 set_config osd
1 filestore_debug_inject_read_err true ||
return 1
949 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.1.asok \
950 injectdataerr
$poolname ROBJ11 ||
return 1
951 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.0.asok \
952 injectmdataerr
$poolname ROBJ12 ||
return 1
953 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.0.asok \
954 injectmdataerr
$poolname ROBJ13 ||
return 1
955 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.1.asok \
956 injectdataerr
$poolname ROBJ13 ||
return 1
959 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
961 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
963 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
965 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
966 # Get epoch for repair-get requests
967 epoch
=$
(jq .epoch
$dir/json
)
969 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
975 "data_digest": "0x2ddbf8f5",
976 "omap_digest": "0xf5fba2c6",
982 "data_digest": "0x2d4a11c2",
983 "omap_digest": "0xf5fba2c6",
986 "data_digest_mismatch_oi",
992 "selected_object_info": "2:ce3f1d6a:::ROBJ1:head(47'54 osd.0.0:53 dirty|omap|data_digest|omap_digest s 7 uv 3 dd 2ddbf8f5 od f5fba2c6 alloc_hint [0 0 0])",
993 "union_shard_errors": [
994 "data_digest_mismatch_oi",
998 "data_digest_mismatch",
1012 "data_digest": "0x2ddbf8f5",
1013 "omap_digest": "0xa8dd5adc",
1016 "omap_digest_mismatch_oi"
1021 "data_digest": "0x2ddbf8f5",
1022 "omap_digest": "0xa8dd5adc",
1025 "omap_digest_mismatch_oi"
1030 "selected_object_info": "2:b1f19cbd:::ROBJ10:head(47'51 osd.0.0:50 dirty|omap|data_digest|omap_digest s 7 uv 30 dd 2ddbf8f5 od c2025a24 alloc_hint [0 0 0])",
1031 "union_shard_errors": [
1032 "omap_digest_mismatch_oi"
1046 "data_digest": "0x2ddbf8f5",
1047 "omap_digest": "0xa03cef03",
1060 "selected_object_info": "2:87abbf36:::ROBJ11:head(47'48 osd.0.0:47 dirty|omap|data_digest|omap_digest s 7 uv 33 dd 2ddbf8f5 od a03cef03 alloc_hint [0 0 0])",
1061 "union_shard_errors": [
1082 "data_digest": "0x2ddbf8f5",
1083 "omap_digest": "0x067f306a",
1089 "selected_object_info": "2:bc819597:::ROBJ12:head(47'52 osd.0.0:51 dirty|omap|data_digest|omap_digest s 7 uv 36 dd 2ddbf8f5 od 67f306a alloc_hint [0 0 0])",
1090 "union_shard_errors": [
1118 "union_shard_errors": [
1134 "data_digest": "0x2ddbf8f5",
1135 "omap_digest": "0x4f14f849",
1143 "data_digest": "0x2ddbf8f5",
1144 "omap_digest": "0x4f14f849",
1152 "union_shard_errors": [
1176 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1180 "data_digest": "0x2ddbf8f5",
1181 "omap_digest": "0x2d2a4d6e",
1190 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1194 "data_digest": "0x2ddbf8f5",
1195 "omap_digest": "0x2d2a4d6e",
1203 "selected_object_info": "2:30259878:::ROBJ15:head(47'46 osd.0.0:45 dirty|omap|data_digest|omap_digest s 7 uv 45 dd 2ddbf8f5 od 2d2a4d6e alloc_hint [0 0 0])",
1204 "union_shard_errors": [
1208 "attr_name_mismatch"
1221 "data_digest": "0x578a4830",
1222 "omap_digest": "0xf8e11918",
1225 "data_digest_mismatch_oi"
1230 "data_digest": "0x2ddbf8f5",
1231 "omap_digest": "0xf8e11918",
1237 "selected_object_info": "2:e97ce31e:::ROBJ2:head(47'56 osd.0.0:55 dirty|omap|data_digest|omap_digest s 7 uv 6 dd 2ddbf8f5 od f8e11918 alloc_hint [0 0 0])",
1238 "union_shard_errors": [
1239 "data_digest_mismatch_oi"
1242 "data_digest_mismatch"
1255 "data_digest": "0x2ddbf8f5",
1256 "omap_digest": "0x00b35dfd",
1268 "selected_object_info": "2:f2a5b2a4:::ROBJ3:head(47'57 osd.0.0:56 dirty|omap|data_digest|omap_digest s 7 uv 9 dd 2ddbf8f5 od b35dfd alloc_hint [0 0 0])",
1269 "union_shard_errors": [
1284 "data_digest": "0x2ddbf8f5",
1285 "omap_digest": "0xd7178dfe",
1288 "omap_digest_mismatch_oi"
1293 "data_digest": "0x2ddbf8f5",
1294 "omap_digest": "0xe2d46ea4",
1300 "selected_object_info": "2:f4981d31:::ROBJ4:head(47'58 osd.0.0:57 dirty|omap|data_digest|omap_digest s 7 uv 12 dd 2ddbf8f5 od e2d46ea4 alloc_hint [0 0 0])",
1301 "union_shard_errors": [
1302 "omap_digest_mismatch_oi"
1305 "omap_digest_mismatch"
1318 "data_digest": "0x2ddbf8f5",
1319 "omap_digest": "0x1a862a41",
1325 "data_digest": "0x2ddbf8f5",
1326 "omap_digest": "0x06cac8f6",
1329 "omap_digest_mismatch_oi"
1334 "selected_object_info": "2:f4bfd4d1:::ROBJ5:head(47'59 osd.0.0:58 dirty|omap|data_digest|omap_digest s 7 uv 15 dd 2ddbf8f5 od 1a862a41 alloc_hint [0 0 0])",
1335 "union_shard_errors": [
1336 "omap_digest_mismatch_oi"
1339 "omap_digest_mismatch"
1352 "data_digest": "0x2ddbf8f5",
1353 "omap_digest": "0x689ee887",
1356 "omap_digest_mismatch_oi"
1361 "data_digest": "0x2ddbf8f5",
1362 "omap_digest": "0x179c919f",
1368 "selected_object_info": "2:a53c12e8:::ROBJ6:head(47'50 osd.0.0:49 dirty|omap|data_digest|omap_digest s 7 uv 18 dd 2ddbf8f5 od 179c919f alloc_hint [0 0 0])",
1369 "union_shard_errors": [
1370 "omap_digest_mismatch_oi"
1373 "omap_digest_mismatch"
1386 "data_digest": "0x2ddbf8f5",
1387 "omap_digest": "0xefced57a",
1393 "data_digest": "0x2ddbf8f5",
1394 "omap_digest": "0x6a73cc07",
1397 "omap_digest_mismatch_oi"
1402 "selected_object_info": "2:8b55fa4b:::ROBJ7:head(47'49 osd.0.0:48 dirty|omap|data_digest|omap_digest s 7 uv 21 dd 2ddbf8f5 od efced57a alloc_hint [0 0 0])",
1403 "union_shard_errors": [
1404 "omap_digest_mismatch_oi"
1407 "omap_digest_mismatch"
1429 "name": "_key1-ROBJ8"
1433 "value": "val3-ROBJ8",
1434 "name": "_key3-ROBJ8"
1438 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1442 "data_digest": "0x2ddbf8f5",
1443 "omap_digest": "0xd6be81dc",
1457 "value": "val1-ROBJ8",
1458 "name": "_key1-ROBJ8"
1462 "value": "val2-ROBJ8",
1463 "name": "_key2-ROBJ8"
1467 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1471 "data_digest": "0x2ddbf8f5",
1472 "omap_digest": "0xd6be81dc",
1478 "selected_object_info": "2:86586531:::ROBJ8:head(82'62 client.4351.0:1 dirty|omap|data_digest|omap_digest s 7 uv 62 dd 2ddbf8f5 od d6be81dc alloc_hint [0 0 0])",
1479 "union_shard_errors": [],
1481 "attr_value_mismatch",
1482 "attr_name_mismatch"
1503 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1507 "object_info": "2:ffdb2004:::ROBJ9:head(47'60 osd.0.0:59 dirty|omap|data_digest|omap_digest s 7 uv 27 dd 2ddbf8f5 od 2eecc539 alloc_hint [0 0 0])",
1508 "data_digest": "0x1f26fb26",
1509 "omap_digest": "0x2eecc539",
1523 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1527 "object_info": "2:ffdb2004:::ROBJ9:head(122'64 client.4532.0:1 dirty|omap|data_digest|omap_digest s 3 uv 64 dd 1f26fb26 od 2eecc539 alloc_hint [0 0 0])",
1528 "data_digest": "0x1f26fb26",
1529 "omap_digest": "0x2eecc539",
1535 "selected_object_info": "2:ffdb2004:::ROBJ9:head(122'64 client.4532.0:1 dirty|omap|data_digest|omap_digest s 3 uv 64 dd 1f26fb26 od 2eecc539 alloc_hint [0 0 0])",
1536 "union_shard_errors": [],
1538 "object_info_inconsistency",
1539 "attr_value_mismatch"
1554 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
1555 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
1556 if test $getjson = "yes"
1558 jq
'.' $dir/json
> save2.json
1561 if which jsonschema
> /dev
/null
;
1563 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
1566 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
1567 teardown
$dir ||
return 1
1572 # Test scrub errors for an erasure coded pool
1574 function corrupt_scrub_erasure
() {
1576 local allow_overwrites
=$2
1577 local poolname
=ecpool
1580 setup
$dir ||
return 1
1581 run_mon
$dir a ||
return 1
1582 run_mgr
$dir x ||
return 1
1583 for id
in $
(seq 0 2) ; do
1584 if [ "$allow_overwrites" = "true" ]; then
1585 run_osd_bluestore
$dir $id ||
return 1
1587 run_osd
$dir $id ||
return 1
1590 wait_for_clean ||
return 1
1592 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 stripe_unit
=2K
--force ||
return 1
1594 for i
in $
(seq 1 $total_objs) ; do
1596 add_something
$dir $poolname $objname ||
return 1
1598 local osd
=$
(expr $i % 2)
1602 # Size (deep scrub data_digest too)
1603 local payload
=UVWXYZZZ
1604 echo $payload > $dir/CORRUPT
1605 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1610 dd if=/dev
/urandom of
=$dir/CORRUPT bs
=2048 count
=1
1611 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1616 objectstore_tool
$dir $osd $objname remove ||
return 1
1620 rados
--pool $poolname setxattr
$objname key1-
$objname val1-
$objname ||
return 1
1621 rados
--pool $poolname setxattr
$objname key2-
$objname val2-
$objname ||
return 1
1624 echo -n bad-val
> $dir/bad-val
1625 objectstore_tool
$dir $osd $objname set-attr _key1-
$objname $dir/bad-val ||
return 1
1626 objectstore_tool
$dir $osd $objname rm-attr _key2-
$objname ||
return 1
1627 echo -n val3-
$objname > $dir/newval
1628 objectstore_tool
$dir $osd $objname set-attr _key3-
$objname $dir/newval ||
return 1
1629 rm $dir/bad-val
$dir/newval
1634 dd if=/dev
/urandom of
=$dir/CORRUPT bs
=2048 count
=2
1635 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1641 local pg
=$
(get_pg
$poolname EOBJ0
)
1645 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
1647 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
1649 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
1651 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
1652 # Get epoch for repair-get requests
1653 epoch
=$
(jq .epoch
$dir/json
)
1655 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
1681 "selected_object_info": "2:9175b684:::EOBJ1:head(21'1 client.4179.0:1 dirty|data_digest|omap_digest s 7 uv 1 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
1682 "union_shard_errors": [
1718 "selected_object_info": "2:b197b25d:::EOBJ3:head(37'3 client.4251.0:1 dirty|data_digest|omap_digest s 7 uv 3 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
1719 "union_shard_errors": [
1743 "name": "_key1-EOBJ4"
1747 "value": "val3-EOBJ4",
1748 "name": "_key3-EOBJ4"
1752 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1757 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1775 "value": "val1-EOBJ4",
1776 "name": "_key1-EOBJ4"
1780 "value": "val2-EOBJ4",
1781 "name": "_key2-EOBJ4"
1785 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1790 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1808 "value": "val1-EOBJ4",
1809 "name": "_key1-EOBJ4"
1813 "value": "val2-EOBJ4",
1814 "name": "_key2-EOBJ4"
1818 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1823 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1833 "selected_object_info": "2:5e723e06:::EOBJ4:head(45'6 client.4289.0:1 dirty|data_digest|omap_digest s 7 uv 6 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
1834 "union_shard_errors": [],
1836 "attr_value_mismatch",
1837 "attr_name_mismatch"
1870 "selected_object_info": "2:8549dfb5:::EOBJ5:head(65'7 client.4441.0:1 dirty|data_digest|omap_digest s 7 uv 7 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
1871 "union_shard_errors": [
1890 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
1891 diff -y $termwidth $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
1892 if test $getjson = "yes"
1894 jq
'.' $dir/json
> save3.json
1897 if which jsonschema
> /dev
/null
;
1899 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
1904 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
1906 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
1908 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
1910 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
1911 # Get epoch for repair-get requests
1912 epoch
=$
(jq .epoch
$dir/json
)
1914 if [ "$allow_overwrites" = "true" ]
1916 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
1922 "data_digest": "0x00000000",
1923 "omap_digest": "0xffffffff",
1939 "data_digest": "0x00000000",
1940 "omap_digest": "0xffffffff",
1947 "selected_object_info": "2:9175b684:::EOBJ1:head(27'1 client.4155.0:1 dirty|data_digest|omap_digest s 7 uv 1 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
1948 "union_shard_errors": [
1966 "data_digest": "0x00000000",
1967 "omap_digest": "0xffffffff",
1981 "data_digest": "0x00000000",
1982 "omap_digest": "0xffffffff",
1989 "selected_object_info": "2:b197b25d:::EOBJ3:head(41'3 client.4199.0:1 dirty|data_digest|omap_digest s 7 uv 3 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
1990 "union_shard_errors": [
2014 "name": "_key1-EOBJ4"
2018 "value": "val3-EOBJ4",
2019 "name": "_key3-EOBJ4"
2023 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2028 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2032 "data_digest": "0x00000000",
2033 "omap_digest": "0xffffffff",
2048 "value": "val1-EOBJ4",
2049 "name": "_key1-EOBJ4"
2053 "value": "val2-EOBJ4",
2054 "name": "_key2-EOBJ4"
2058 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2063 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2067 "data_digest": "0x00000000",
2068 "omap_digest": "0xffffffff",
2083 "value": "val1-EOBJ4",
2084 "name": "_key1-EOBJ4"
2088 "value": "val2-EOBJ4",
2089 "name": "_key2-EOBJ4"
2093 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2098 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2102 "data_digest": "0x00000000",
2103 "omap_digest": "0xffffffff",
2110 "selected_object_info": "2:5e723e06:::EOBJ4:head(48'6 client.4223.0:1 dirty|data_digest|omap_digest s 7 uv 6 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
2111 "union_shard_errors": [],
2113 "attr_value_mismatch",
2114 "attr_name_mismatch"
2127 "data_digest": "0x00000000",
2128 "omap_digest": "0xffffffff",
2135 "data_digest": "0x00000000",
2136 "omap_digest": "0xffffffff",
2145 "data_digest": "0x00000000",
2146 "omap_digest": "0xffffffff",
2153 "selected_object_info": "2:8549dfb5:::EOBJ5:head(65'7 client.4288.0:1 dirty|data_digest|omap_digest s 7 uv 7 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
2154 "union_shard_errors": [
2175 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
2181 "data_digest": "0x04cfa72f",
2182 "omap_digest": "0xffffffff",
2198 "data_digest": "0x04cfa72f",
2199 "omap_digest": "0xffffffff",
2206 "selected_object_info": "2:9175b684:::EOBJ1:head(21'1 client.4179.0:1 dirty|data_digest|omap_digest s 7 uv 1 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
2207 "union_shard_errors": [
2233 "data_digest": "0x04cfa72f",
2234 "omap_digest": "0xffffffff",
2241 "data_digest": "0x04cfa72f",
2242 "omap_digest": "0xffffffff",
2249 "selected_object_info": "2:9babd184:::EOBJ2:head(29'2 client.4217.0:1 dirty|data_digest|omap_digest s 7 uv 2 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
2250 "union_shard_errors": [
2265 "data_digest": "0x04cfa72f",
2266 "omap_digest": "0xffffffff",
2280 "data_digest": "0x04cfa72f",
2281 "omap_digest": "0xffffffff",
2288 "selected_object_info": "2:b197b25d:::EOBJ3:head(37'3 client.4251.0:1 dirty|data_digest|omap_digest s 7 uv 3 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
2289 "union_shard_errors": [
2313 "name": "_key1-EOBJ4"
2317 "value": "val3-EOBJ4",
2318 "name": "_key3-EOBJ4"
2322 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2327 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2331 "data_digest": "0x04cfa72f",
2332 "omap_digest": "0xffffffff",
2347 "value": "val1-EOBJ4",
2348 "name": "_key1-EOBJ4"
2352 "value": "val2-EOBJ4",
2353 "name": "_key2-EOBJ4"
2357 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2362 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2366 "data_digest": "0x04cfa72f",
2367 "omap_digest": "0xffffffff",
2382 "value": "val1-EOBJ4",
2383 "name": "_key1-EOBJ4"
2387 "value": "val2-EOBJ4",
2388 "name": "_key2-EOBJ4"
2392 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2397 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2401 "data_digest": "0x04cfa72f",
2402 "omap_digest": "0xffffffff",
2409 "selected_object_info": "2:5e723e06:::EOBJ4:head(45'6 client.4289.0:1 dirty|data_digest|omap_digest s 7 uv 6 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
2410 "union_shard_errors": [],
2412 "attr_value_mismatch",
2413 "attr_name_mismatch"
2426 "data_digest": "0x04cfa72f",
2427 "omap_digest": "0xffffffff",
2443 "data_digest": "0x04cfa72f",
2444 "omap_digest": "0xffffffff",
2451 "selected_object_info": "2:8549dfb5:::EOBJ5:head(65'7 client.4441.0:1 dirty|data_digest|omap_digest s 7 uv 7 dd 2ddbf8f5 od ffffffff alloc_hint [0 0 0])",
2452 "union_shard_errors": [
2474 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
2475 diff -y $termwidth $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
2476 if test $getjson = "yes"
2478 if [ "$allow_overwrites" = "true" ]
2484 jq
'.' $dir/json
> save
${num}.json
2487 if which jsonschema
> /dev
/null
;
2489 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
2492 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
2493 teardown
$dir ||
return 1
2496 function TEST_corrupt_scrub_erasure_appends
() {
2497 corrupt_scrub_erasure
$1 false
2500 function TEST_corrupt_scrub_erasure_overwrites
() {
2501 corrupt_scrub_erasure
$1 true
2505 # Test to make sure that a periodic scrub won't cause deep-scrub info to be lost
2507 function TEST_periodic_scrub_replicated
() {
2509 local poolname
=psr_pool
2512 setup
$dir ||
return 1
2513 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
2514 run_mgr
$dir x ||
return 1
2515 local ceph_osd_args
="--osd-scrub-interval-randomize-ratio=0 --osd-deep-scrub-randomize-ratio=0"
2516 run_osd
$dir 0 $ceph_osd_args ||
return 1
2517 run_osd
$dir 1 $ceph_osd_args ||
return 1
2518 wait_for_clean ||
return 1
2520 ceph osd pool create
$poolname 1 1 ||
return 1
2521 wait_for_clean ||
return 1
2524 add_something
$dir $poolname $objname scrub ||
return 1
2525 local primary
=$
(get_primary
$poolname $objname)
2526 local pg
=$
(get_pg
$poolname $objname)
2528 # Add deep-scrub only error
2529 local payload
=UVWXYZ
2530 echo $payload > $dir/CORRUPT
2531 # Uses $ceph_osd_args for osd restart
2532 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
2534 # No scrub information available, so expect failure
2536 ! rados list-inconsistent-obj
$pg | jq
'.' ||
return 1
2539 pg_deep_scrub
$pg ||
return 1
2541 # Make sure bad object found
2542 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2544 local last_scrub
=$
(get_last_scrub_stamp
$pg)
2545 # Fake a schedule scrub
2546 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd.
${primary}.asok \
2547 trigger_scrub
$pg ||
return 1
2548 # Wait for schedule regular scrub
2549 wait_for_scrub
$pg "$last_scrub"
2551 # It needed to be upgraded
2552 grep -q "Deep scrub errors, upgrading scrub to deep-scrub" $dir/osd.
${primary}.log ||
return 1
2554 # Bad object still known
2555 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2557 # Can't upgrade with this set
2558 ceph osd
set nodeep-scrub
2560 # Fake a schedule scrub
2561 local last_scrub
=$
(get_last_scrub_stamp
$pg)
2562 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd.
${primary}.asok \
2563 trigger_scrub
$pg ||
return 1
2564 # Wait for schedule regular scrub
2565 # to notice scrub and skip it
2567 for i
in $
(seq 14 -1 0)
2570 ! grep -q "Regular scrub skipped due to deep-scrub errors and nodeep-scrub set" $dir/osd.
${primary}.log ||
{ found
=true
; break; }
2571 echo Time left
: $i seconds
2573 test $found = "true" ||
return 1
2575 # Bad object still known
2576 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2578 # Request a regular scrub and it will be done
2579 local scrub_backoff_ratio
=$
(get_config osd
${primary} osd_scrub_backoff_ratio
)
2580 set_config osd
${primary} osd_scrub_backoff_ratio
0
2583 set_config osd
${primary} osd_scrub_backoff_ratio
$scrub_backoff_ratio
2584 grep -q "Regular scrub request, losing deep-scrub details" $dir/osd.
${primary}.log ||
return 1
2586 # deep-scrub error is no longer present
2587 rados list-inconsistent-obj
$pg | jq
'.' |
grep -qv $objname ||
return 1
2591 main osd-scrub-repair
"$@"
2594 # compile-command: "cd ../.. ; make -j4 && \
2595 # test/osd/osd-scrub-repair.sh # TEST_corrupt_and_repair_replicated"