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 $CEPH_ROOT/qa
/standalone
/ceph-helpers.sh
19 if [ `uname` = FreeBSD
]; then
20 # erasure coding overwrites are only tested on Bluestore
21 # erasure coding on filestore is unsafe
22 # http://docs.ceph.com/docs/master/rados/operations/erasure-code/#erasure-coding-with-overwrites
23 use_ec_overwrite
=false
28 # Test development and debugging
29 # Set to "yes" in order to ignore diff errors and save results to update test
32 # Ignore the epoch and filter out the attr '_' value because it has date information and won't match
33 jqfilter
='.inconsistents | (.[].shards[].attrs[]? | select(.name == "_") | .value) |= "----Stripped-by-test----"'
34 sortkeys
='import json; import sys ; JSON=sys.stdin.read() ; ud = json.loads(JSON) ; print json.dumps(ud, sort_keys=True, indent=2)'
36 # Remove items are not consistent across runs, the pg interval and client
37 sedfilter
='s/\([ ]*\"\(selected_\)*object_info\":.*head[(]\)[^[:space:]]* [^[:space:]]* \(.*\)/\1\3/'
43 export CEPH_MON
="127.0.0.1:7107" # git grep '\<7107\>' : there must be only one
45 CEPH_ARGS
+="--fsid=$(uuidgen) --auth-supported=none "
46 CEPH_ARGS
+="--mon-host=$CEPH_MON "
48 local funcs
=${@:-$(set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p')}
49 for func
in $funcs ; do
50 $func $dir ||
return 1
54 function add_something
() {
57 local obj
=${3:-SOMETHING}
58 local scrub
=${4:-noscrub}
60 if [ "$scrub" = "noscrub" ];
62 ceph osd
set noscrub ||
return 1
63 ceph osd
set nodeep-scrub ||
return 1
65 ceph osd
unset noscrub ||
return 1
66 ceph osd
unset nodeep-scrub ||
return 1
70 echo $payload > $dir/ORIGINAL
71 rados
--pool $poolname put
$obj $dir/ORIGINAL ||
return 1
75 # Corrupt one copy of a replicated pool
77 function TEST_corrupt_and_repair_replicated
() {
81 setup
$dir ||
return 1
82 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
83 run_mgr
$dir x ||
return 1
84 run_osd
$dir 0 ||
return 1
85 run_osd
$dir 1 ||
return 1
86 create_rbd_pool ||
return 1
87 wait_for_clean ||
return 1
89 add_something
$dir $poolname ||
return 1
90 corrupt_and_repair_one
$dir $poolname $
(get_not_primary
$poolname SOMETHING
) ||
return 1
91 # Reproduces http://tracker.ceph.com/issues/8914
92 corrupt_and_repair_one
$dir $poolname $
(get_primary
$poolname SOMETHING
) ||
return 1
94 teardown
$dir ||
return 1
97 function corrupt_and_repair_two
() {
104 # 1) remove the corresponding file from the OSDs
107 run_in_background pids objectstore_tool
$dir $first SOMETHING remove
108 run_in_background pids objectstore_tool
$dir $second SOMETHING remove
111 if [ $return_code -ne 0 ]; then return $return_code; fi
116 local pg
=$
(get_pg
$poolname SOMETHING
)
119 # 3) The files must be back
122 run_in_background pids objectstore_tool
$dir $first SOMETHING list-attrs
123 run_in_background pids objectstore_tool
$dir $second SOMETHING list-attrs
126 if [ $return_code -ne 0 ]; then return $return_code; fi
128 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
129 diff $dir/ORIGINAL
$dir/COPY ||
return 1
134 # 2) remove the corresponding file from a designated OSD
136 # 4) check that the file has been restored in the designated OSD
138 function corrupt_and_repair_one
() {
144 # 1) remove the corresponding file from the OSD
146 objectstore_tool
$dir $osd SOMETHING remove ||
return 1
150 local pg
=$
(get_pg
$poolname SOMETHING
)
153 # 3) The file must be back
155 objectstore_tool
$dir $osd SOMETHING list-attrs ||
return 1
156 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
157 diff $dir/ORIGINAL
$dir/COPY ||
return 1
160 function corrupt_and_repair_erasure_coded
() {
164 add_something
$dir $poolname ||
return 1
166 local primary
=$
(get_primary
$poolname SOMETHING
)
167 local -a osds
=($
(get_osds
$poolname SOMETHING |
sed -e "s/$primary//"))
168 local not_primary_first
=${osds[0]}
169 local not_primary_second
=${osds[1]}
171 # Reproduces http://tracker.ceph.com/issues/10017
172 corrupt_and_repair_one
$dir $poolname $primary ||
return 1
173 # Reproduces http://tracker.ceph.com/issues/10409
174 corrupt_and_repair_one
$dir $poolname $not_primary_first ||
return 1
175 corrupt_and_repair_two
$dir $poolname $not_primary_first $not_primary_second ||
return 1
176 corrupt_and_repair_two
$dir $poolname $primary $not_primary_first ||
return 1
180 function create_ec_pool
() {
182 local allow_overwrites
=$2
184 ceph osd erasure-code-profile
set myprofile crush-failure-domain
=osd
$3 $4 $5 $6 $7 ||
return 1
186 ceph osd pool create
"$poolname" 1 1 erasure myprofile ||
return 1
188 if [ "$allow_overwrites" = "true" ]; then
189 ceph osd pool
set "$poolname" allow_ec_overwrites true ||
return 1
192 wait_for_clean ||
return 1
196 function auto_repair_erasure_coded
() {
198 local allow_overwrites
=$2
199 local poolname
=ecpool
201 # Launch a cluster with 5 seconds scrub interval
202 setup
$dir ||
return 1
203 run_mon
$dir a ||
return 1
204 run_mgr
$dir x ||
return 1
205 local ceph_osd_args
="--osd-scrub-auto-repair=true \
206 --osd-deep-scrub-interval=5 \
207 --osd-scrub-max-interval=5 \
208 --osd-scrub-min-interval=5 \
209 --osd-scrub-interval-randomize-ratio=0"
210 for id
in $
(seq 0 2) ; do
211 if [ "$allow_overwrites" = "true" ]; then
212 run_osd_bluestore
$dir $id $ceph_osd_args ||
return 1
214 run_osd
$dir $id $ceph_osd_args ||
return 1
217 create_rbd_pool ||
return 1
218 wait_for_clean ||
return 1
221 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 ||
return 1
225 echo $payload > $dir/ORIGINAL
226 rados
--pool $poolname put SOMETHING
$dir/ORIGINAL ||
return 1
228 # Remove the object from one shard physically
229 # Restarted osd get $ceph_osd_args passed
230 objectstore_tool
$dir $
(get_not_primary
$poolname SOMETHING
) SOMETHING remove ||
return 1
231 # Wait for auto repair
232 local pgid
=$
(get_pg
$poolname SOMETHING
)
233 wait_for_scrub
$pgid "$(get_last_scrub_stamp $pgid)"
234 wait_for_clean ||
return 1
235 # Verify - the file should be back
236 # Restarted osd get $ceph_osd_args passed
237 objectstore_tool
$dir $
(get_not_primary
$poolname SOMETHING
) SOMETHING list-attrs ||
return 1
238 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
239 diff $dir/ORIGINAL
$dir/COPY ||
return 1
242 teardown
$dir ||
return 1
245 function TEST_auto_repair_erasure_coded_appends
() {
246 auto_repair_erasure_coded
$1 false
249 function TEST_auto_repair_erasure_coded_overwrites
() {
250 if [ "$use_ec_overwrite" = "true" ]; then
251 auto_repair_erasure_coded
$1 true
255 function corrupt_and_repair_jerasure
() {
257 local allow_overwrites
=$2
258 local poolname
=ecpool
260 setup
$dir ||
return 1
261 run_mon
$dir a ||
return 1
262 run_mgr
$dir x ||
return 1
263 for id
in $
(seq 0 3) ; do
264 if [ "$allow_overwrites" = "true" ]; then
265 run_osd_bluestore
$dir $id ||
return 1
267 run_osd
$dir $id ||
return 1
270 create_rbd_pool ||
return 1
271 wait_for_clean ||
return 1
273 create_ec_pool
$poolname $allow_overwrites k
=2 m
=2 ||
return 1
274 corrupt_and_repair_erasure_coded
$dir $poolname ||
return 1
276 teardown
$dir ||
return 1
279 function TEST_corrupt_and_repair_jerasure_appends
() {
280 corrupt_and_repair_jerasure
$1
283 function TEST_corrupt_and_repair_jerasure_overwrites
() {
284 if [ "$use_ec_overwrite" = "true" ]; then
285 corrupt_and_repair_jerasure
$1 true
289 function corrupt_and_repair_lrc
() {
291 local allow_overwrites
=$2
292 local poolname
=ecpool
294 setup
$dir ||
return 1
295 run_mon
$dir a ||
return 1
296 run_mgr
$dir x ||
return 1
297 for id
in $
(seq 0 9) ; do
298 if [ "$allow_overwrites" = "true" ]; then
299 run_osd_bluestore
$dir $id ||
return 1
301 run_osd
$dir $id ||
return 1
304 create_rbd_pool ||
return 1
305 wait_for_clean ||
return 1
307 create_ec_pool
$poolname $allow_overwrites k
=4 m
=2 l
=3 plugin
=lrc ||
return 1
308 corrupt_and_repair_erasure_coded
$dir $poolname ||
return 1
310 teardown
$dir ||
return 1
313 function TEST_corrupt_and_repair_lrc_appends
() {
314 corrupt_and_repair_jerasure
$1
317 function TEST_corrupt_and_repair_lrc_overwrites
() {
318 if [ "$use_ec_overwrite" = "true" ]; then
319 corrupt_and_repair_jerasure
$1 true
323 function unfound_erasure_coded
() {
325 local allow_overwrites
=$2
326 local poolname
=ecpool
329 setup
$dir ||
return 1
330 run_mon
$dir a ||
return 1
331 run_mgr
$dir x ||
return 1
332 for id
in $
(seq 0 3) ; do
333 if [ "$allow_overwrites" = "true" ]; then
334 run_osd_bluestore
$dir $id ||
return 1
336 run_osd
$dir $id ||
return 1
339 create_rbd_pool ||
return 1
340 wait_for_clean ||
return 1
342 create_ec_pool
$poolname $allow_overwrites k
=2 m
=2 ||
return 1
344 add_something
$dir $poolname ||
return 1
346 local primary
=$
(get_primary
$poolname SOMETHING
)
347 local -a osds
=($
(get_osds
$poolname SOMETHING |
sed -e "s/$primary//"))
348 local not_primary_first
=${osds[0]}
349 local not_primary_second
=${osds[1]}
350 local not_primary_third
=${osds[2]}
353 # 1) remove the corresponding file from the OSDs
356 run_in_background pids objectstore_tool
$dir $not_primary_first SOMETHING remove
357 run_in_background pids objectstore_tool
$dir $not_primary_second SOMETHING remove
358 run_in_background pids objectstore_tool
$dir $not_primary_third SOMETHING remove
361 if [ $return_code -ne 0 ]; then return $return_code; fi
366 local pg
=$
(get_pg
$poolname SOMETHING
)
371 # it may take a bit to appear due to mon/mgr asynchrony
372 for f
in `seq 1 60`; do
373 ceph
-s |
grep "1/1 unfound" && break
376 ceph
-s|
grep "4 osds: 4 up, 4 in" ||
return 1
377 ceph
-s|
grep "1/1 unfound" ||
return 1
379 teardown
$dir ||
return 1
382 function TEST_unfound_erasure_coded_appends
() {
383 unfound_erasure_coded
$1
386 function TEST_unfound_erasure_coded_overwrites
() {
387 if [ "$use_ec_overwrite" = "true" ]; then
388 unfound_erasure_coded
$1 true
393 # list_missing for EC pool
395 function list_missing_erasure_coded
() {
397 local allow_overwrites
=$2
398 local poolname
=ecpool
400 setup
$dir ||
return 1
401 run_mon
$dir a ||
return 1
402 run_mgr
$dir x ||
return 1
403 for id
in $
(seq 0 2) ; do
404 if [ "$allow_overwrites" = "true" ]; then
405 run_osd_bluestore
$dir $id ||
return 1
407 run_osd
$dir $id ||
return 1
410 create_rbd_pool ||
return 1
411 wait_for_clean ||
return 1
413 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 ||
return 1
415 # Put an object and remove the two shards (including primary)
416 add_something
$dir $poolname MOBJ0 ||
return 1
417 local -a osds0
=($
(get_osds
$poolname MOBJ0
))
419 # Put another object and remove two shards (excluding primary)
420 add_something
$dir $poolname MOBJ1 ||
return 1
421 local -a osds1
=($
(get_osds
$poolname MOBJ1
))
423 # Stop all osd daemons
424 for id
in $
(seq 0 2) ; do
425 kill_daemons
$dir TERM osd.
$id >&2 < /dev
/null ||
return 1
429 ceph-objectstore-tool
--data-path $dir/$id \
430 MOBJ0 remove ||
return 1
432 ceph-objectstore-tool
--data-path $dir/$id \
433 MOBJ0 remove ||
return 1
436 ceph-objectstore-tool
--data-path $dir/$id \
437 MOBJ1 remove ||
return 1
439 ceph-objectstore-tool
--data-path $dir/$id \
440 MOBJ1 remove ||
return 1
442 for id
in $
(seq 0 2) ; do
443 activate_osd
$dir $id >&2 ||
return 1
445 create_rbd_pool ||
return 1
446 wait_for_clean ||
return 1
448 # Get get - both objects should in the same PG
449 local pg
=$
(get_pg
$poolname MOBJ0
)
451 # Repair the PG, which triggers the recovering,
452 # and should mark the object as unfound
455 for i
in $
(seq 0 120) ; do
456 [ $i -lt 60 ] ||
return 1
457 matches
=$
(ceph pg
$pg list_missing |
egrep "MOBJ0|MOBJ1" |
wc -l)
458 [ $matches -eq 2 ] && break
461 teardown
$dir ||
return 1
464 function TEST_list_missing_erasure_coded_appends
() {
465 list_missing_erasure_coded
$1 false
468 function TEST_list_missing_erasure_coded_overwrites
() {
469 if [ "$use_ec_overwrite" = "true" ]; then
470 list_missing_erasure_coded
$1 true
475 # Corrupt one copy of a replicated pool
477 function TEST_corrupt_scrub_replicated
() {
479 local poolname
=csr_pool
482 setup
$dir ||
return 1
483 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
484 run_mgr
$dir x ||
return 1
485 run_osd
$dir 0 ||
return 1
486 run_osd
$dir 1 ||
return 1
487 create_rbd_pool ||
return 1
488 wait_for_clean ||
return 1
490 ceph osd pool create foo
1 ||
return 1
491 ceph osd pool create
$poolname 1 1 ||
return 1
492 wait_for_clean ||
return 1
494 for i
in $
(seq 1 $total_objs) ; do
496 add_something
$dir $poolname $objname ||
return 1
498 rados
--pool $poolname setomapheader
$objname hdr-
$objname ||
return 1
499 rados
--pool $poolname setomapval
$objname key-
$objname val-
$objname ||
return 1
502 local pg
=$
(get_pg
$poolname ROBJ0
)
504 # Compute an old omap digest and save oi
505 CEPH_ARGS
='' ceph daemon $
(get_asok_path osd
.0) \
506 config
set osd_deep_scrub_update_digest_min_age
0
507 CEPH_ARGS
='' ceph daemon $
(get_asok_path osd
.1) \
508 config
set osd_deep_scrub_update_digest_min_age
0
511 for i
in $
(seq 1 $total_objs) ; do
514 # Alternate corruption between osd.0 and osd.1
515 local osd
=$
(expr $i % 2)
519 # Size (deep scrub data_digest too)
520 local payload
=UVWXYZZZ
521 echo $payload > $dir/CORRUPT
522 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
526 # digest (deep scrub only)
528 echo $payload > $dir/CORRUPT
529 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
534 objectstore_tool
$dir $osd $objname remove ||
return 1
538 # Modify omap value (deep scrub only)
539 objectstore_tool
$dir $osd $objname set-omap key-
$objname $dir/CORRUPT ||
return 1
543 # Delete omap key (deep scrub only)
544 objectstore_tool
$dir $osd $objname rm-omap key-
$objname ||
return 1
548 # Add extra omap key (deep scrub only)
549 echo extra
> $dir/extra-val
550 objectstore_tool
$dir $osd $objname set-omap key2-
$objname $dir/extra-val ||
return 1
555 # Modify omap header (deep scrub only)
556 echo -n newheader
> $dir/hdr
557 objectstore_tool
$dir $osd $objname set-omaphdr
$dir/hdr ||
return 1
562 rados
--pool $poolname setxattr
$objname key1-
$objname val1-
$objname ||
return 1
563 rados
--pool $poolname setxattr
$objname key2-
$objname val2-
$objname ||
return 1
566 echo -n bad-val
> $dir/bad-val
567 objectstore_tool
$dir $osd $objname set-attr _key1-
$objname $dir/bad-val ||
return 1
568 objectstore_tool
$dir $osd $objname rm-attr _key2-
$objname ||
return 1
569 echo -n val3-
$objname > $dir/newval
570 objectstore_tool
$dir $osd $objname set-attr _key3-
$objname $dir/newval ||
return 1
571 rm $dir/bad-val
$dir/newval
575 objectstore_tool
$dir $osd $objname get-attr _
> $dir/robj9-oi
576 echo -n D
> $dir/change
577 rados
--pool $poolname put
$objname $dir/change
578 objectstore_tool
$dir $osd $objname set-attr _
$dir/robj9-oi
579 rm $dir/oi
$dir/change
582 # ROBJ10 must be handled after digests are re-computed by a deep scrub below
583 # ROBJ11 must be handled with config change before deep scrub
584 # ROBJ12 must be handled with config change before scrubs
585 # ROBJ13 must be handled before scrubs
588 echo -n bad-val
> $dir/bad-val
589 objectstore_tool
$dir 0 $objname set-attr _
$dir/bad-val ||
return 1
590 objectstore_tool
$dir 1 $objname rm-attr _ ||
return 1
595 objectstore_tool
$dir $osd $objname rm-attr _ ||
return 1
600 local pg
=$
(get_pg
$poolname ROBJ0
)
602 set_config osd
0 filestore_debug_inject_read_err true ||
return 1
603 set_config osd
1 filestore_debug_inject_read_err true ||
return 1
604 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd
.1) \
605 injectdataerr
$poolname ROBJ11 ||
return 1
606 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd
.0) \
607 injectmdataerr
$poolname ROBJ12 ||
return 1
608 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd
.0) \
609 injectmdataerr
$poolname ROBJ13 ||
return 1
610 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd
.1) \
611 injectdataerr
$poolname ROBJ13 ||
return 1
615 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
617 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
619 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
621 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
622 # Get epoch for repair-get requests
623 epoch
=$
(jq .epoch
$dir/json
)
625 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
643 "selected_object_info": "3: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])",
644 "union_shard_errors": [
672 "selected_object_info": "3: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])",
673 "union_shard_errors": [
699 "selected_object_info": "3: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])",
700 "union_shard_errors": [
729 "union_shard_errors": [
753 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
765 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
776 "selected_object_info": "3: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])",
777 "union_shard_errors": [
805 "selected_object_info": "3: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])",
806 "union_shard_errors": [
830 "name": "_key1-ROBJ8"
834 "value": "val3-ROBJ8",
835 "name": "_key3-ROBJ8"
839 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
856 "value": "val1-ROBJ8",
857 "name": "_key1-ROBJ8"
861 "value": "val2-ROBJ8",
862 "name": "_key2-ROBJ8"
866 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
875 "selected_object_info": "3: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])",
876 "union_shard_errors": [],
878 "attr_value_mismatch",
900 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
904 "object_info": "3: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])",
918 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
922 "object_info": "3: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])",
928 "selected_object_info": "3: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])",
929 "union_shard_errors": [],
931 "object_info_inconsistency",
932 "attr_value_mismatch"
947 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
948 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
949 if test $getjson = "yes"
951 jq
'.' $dir/json
> save1.json
954 if which jsonschema
> /dev
/null
;
956 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
960 # Change data and size again because digest was recomputed
961 echo -n ZZZ
> $dir/change
962 rados
--pool $poolname put
$objname $dir/change
963 # Set one to an even older value
964 objectstore_tool
$dir 0 $objname set-attr _
$dir/robj9-oi
965 rm $dir/oi
$dir/change
968 objectstore_tool
$dir 1 $objname get-attr _
> $dir/oi
969 rados
--pool $poolname setomapval
$objname key2-
$objname val2-
$objname
970 objectstore_tool
$dir 0 $objname set-attr _
$dir/oi
971 objectstore_tool
$dir 1 $objname set-attr _
$dir/oi
974 set_config osd
0 filestore_debug_inject_read_err true ||
return 1
975 set_config osd
1 filestore_debug_inject_read_err true ||
return 1
976 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd
.1) \
977 injectdataerr
$poolname ROBJ11 ||
return 1
978 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd
.0) \
979 injectmdataerr
$poolname ROBJ12 ||
return 1
980 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd
.0) \
981 injectmdataerr
$poolname ROBJ13 ||
return 1
982 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd
.1) \
983 injectdataerr
$poolname ROBJ13 ||
return 1
986 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
988 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
990 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
992 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
993 # Get epoch for repair-get requests
994 epoch
=$
(jq .epoch
$dir/json
)
996 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
1002 "data_digest": "0x2ddbf8f5",
1003 "omap_digest": "0xf5fba2c6",
1009 "data_digest": "0x2d4a11c2",
1010 "omap_digest": "0xf5fba2c6",
1013 "data_digest_mismatch_oi",
1019 "selected_object_info": "3: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])",
1020 "union_shard_errors": [
1021 "data_digest_mismatch_oi",
1025 "data_digest_mismatch",
1039 "data_digest": "0x2ddbf8f5",
1040 "omap_digest": "0xa8dd5adc",
1043 "omap_digest_mismatch_oi"
1048 "data_digest": "0x2ddbf8f5",
1049 "omap_digest": "0xa8dd5adc",
1052 "omap_digest_mismatch_oi"
1057 "selected_object_info": "3: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])",
1058 "union_shard_errors": [
1059 "omap_digest_mismatch_oi"
1073 "data_digest": "0x2ddbf8f5",
1074 "omap_digest": "0xa03cef03",
1087 "selected_object_info": "3: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])",
1088 "union_shard_errors": [
1109 "data_digest": "0x2ddbf8f5",
1110 "omap_digest": "0x067f306a",
1116 "selected_object_info": "3: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])",
1117 "union_shard_errors": [
1145 "union_shard_errors": [
1161 "data_digest": "0x2ddbf8f5",
1162 "omap_digest": "0x4f14f849",
1170 "data_digest": "0x2ddbf8f5",
1171 "omap_digest": "0x4f14f849",
1179 "union_shard_errors": [
1203 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1207 "data_digest": "0x2ddbf8f5",
1208 "omap_digest": "0x2d2a4d6e",
1217 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1221 "data_digest": "0x2ddbf8f5",
1222 "omap_digest": "0x2d2a4d6e",
1230 "selected_object_info": "3: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])",
1231 "union_shard_errors": [
1235 "attr_name_mismatch"
1248 "data_digest": "0x578a4830",
1249 "omap_digest": "0xf8e11918",
1252 "data_digest_mismatch_oi"
1257 "data_digest": "0x2ddbf8f5",
1258 "omap_digest": "0xf8e11918",
1264 "selected_object_info": "3: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])",
1265 "union_shard_errors": [
1266 "data_digest_mismatch_oi"
1269 "data_digest_mismatch"
1282 "data_digest": "0x2ddbf8f5",
1283 "omap_digest": "0x00b35dfd",
1295 "selected_object_info": "3: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])",
1296 "union_shard_errors": [
1311 "data_digest": "0x2ddbf8f5",
1312 "omap_digest": "0xd7178dfe",
1315 "omap_digest_mismatch_oi"
1320 "data_digest": "0x2ddbf8f5",
1321 "omap_digest": "0xe2d46ea4",
1327 "selected_object_info": "3: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])",
1328 "union_shard_errors": [
1329 "omap_digest_mismatch_oi"
1332 "omap_digest_mismatch"
1345 "data_digest": "0x2ddbf8f5",
1346 "omap_digest": "0x1a862a41",
1352 "data_digest": "0x2ddbf8f5",
1353 "omap_digest": "0x06cac8f6",
1356 "omap_digest_mismatch_oi"
1361 "selected_object_info": "3: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])",
1362 "union_shard_errors": [
1363 "omap_digest_mismatch_oi"
1366 "omap_digest_mismatch"
1379 "data_digest": "0x2ddbf8f5",
1380 "omap_digest": "0x689ee887",
1383 "omap_digest_mismatch_oi"
1388 "data_digest": "0x2ddbf8f5",
1389 "omap_digest": "0x179c919f",
1395 "selected_object_info": "3: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])",
1396 "union_shard_errors": [
1397 "omap_digest_mismatch_oi"
1400 "omap_digest_mismatch"
1413 "data_digest": "0x2ddbf8f5",
1414 "omap_digest": "0xefced57a",
1420 "data_digest": "0x2ddbf8f5",
1421 "omap_digest": "0x6a73cc07",
1424 "omap_digest_mismatch_oi"
1429 "selected_object_info": "3: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])",
1430 "union_shard_errors": [
1431 "omap_digest_mismatch_oi"
1434 "omap_digest_mismatch"
1456 "name": "_key1-ROBJ8"
1460 "value": "val3-ROBJ8",
1461 "name": "_key3-ROBJ8"
1465 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1469 "data_digest": "0x2ddbf8f5",
1470 "omap_digest": "0xd6be81dc",
1484 "value": "val1-ROBJ8",
1485 "name": "_key1-ROBJ8"
1489 "value": "val2-ROBJ8",
1490 "name": "_key2-ROBJ8"
1494 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1498 "data_digest": "0x2ddbf8f5",
1499 "omap_digest": "0xd6be81dc",
1505 "selected_object_info": "3: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])",
1506 "union_shard_errors": [],
1508 "attr_value_mismatch",
1509 "attr_name_mismatch"
1530 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1534 "object_info": "3: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])",
1535 "data_digest": "0x1f26fb26",
1536 "omap_digest": "0x2eecc539",
1550 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1554 "object_info": "3: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])",
1555 "data_digest": "0x1f26fb26",
1556 "omap_digest": "0x2eecc539",
1562 "selected_object_info": "3: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])",
1563 "union_shard_errors": [],
1565 "object_info_inconsistency",
1566 "attr_value_mismatch"
1581 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
1582 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
1583 if test $getjson = "yes"
1585 jq
'.' $dir/json
> save2.json
1588 if which jsonschema
> /dev
/null
;
1590 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
1593 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
1594 teardown
$dir ||
return 1
1599 # Test scrub errors for an erasure coded pool
1601 function corrupt_scrub_erasure
() {
1603 local allow_overwrites
=$2
1604 local poolname
=ecpool
1607 setup
$dir ||
return 1
1608 run_mon
$dir a ||
return 1
1609 run_mgr
$dir x ||
return 1
1610 for id
in $
(seq 0 2) ; do
1611 if [ "$allow_overwrites" = "true" ]; then
1612 run_osd_bluestore
$dir $id ||
return 1
1614 run_osd
$dir $id ||
return 1
1617 create_rbd_pool ||
return 1
1618 ceph osd pool create foo
1
1620 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 stripe_unit
=2K
--force ||
return 1
1621 wait_for_clean ||
return 1
1623 for i
in $
(seq 1 $total_objs) ; do
1625 add_something
$dir $poolname $objname ||
return 1
1627 local osd
=$
(expr $i % 2)
1631 # Size (deep scrub data_digest too)
1632 local payload
=UVWXYZZZ
1633 echo $payload > $dir/CORRUPT
1634 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1639 dd if=/dev
/urandom of
=$dir/CORRUPT bs
=2048 count
=1
1640 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1645 objectstore_tool
$dir $osd $objname remove ||
return 1
1649 rados
--pool $poolname setxattr
$objname key1-
$objname val1-
$objname ||
return 1
1650 rados
--pool $poolname setxattr
$objname key2-
$objname val2-
$objname ||
return 1
1653 echo -n bad-val
> $dir/bad-val
1654 objectstore_tool
$dir $osd $objname set-attr _key1-
$objname $dir/bad-val ||
return 1
1655 objectstore_tool
$dir $osd $objname rm-attr _key2-
$objname ||
return 1
1656 echo -n val3-
$objname > $dir/newval
1657 objectstore_tool
$dir $osd $objname set-attr _key3-
$objname $dir/newval ||
return 1
1658 rm $dir/bad-val
$dir/newval
1663 dd if=/dev
/urandom of
=$dir/CORRUPT bs
=2048 count
=2
1664 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1670 local pg
=$
(get_pg
$poolname EOBJ0
)
1674 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
1676 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
1678 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
1680 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
1681 # Get epoch for repair-get requests
1682 epoch
=$
(jq .epoch
$dir/json
)
1684 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
1710 "selected_object_info": "3: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])",
1711 "union_shard_errors": [
1747 "selected_object_info": "3: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])",
1748 "union_shard_errors": [
1772 "name": "_key1-EOBJ4"
1776 "value": "val3-EOBJ4",
1777 "name": "_key3-EOBJ4"
1781 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1786 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1808 "value": "val1-EOBJ4",
1809 "name": "_key1-EOBJ4"
1813 "value": "val2-EOBJ4",
1814 "name": "_key2-EOBJ4"
1818 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1823 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1841 "value": "val1-EOBJ4",
1842 "name": "_key1-EOBJ4"
1846 "value": "val2-EOBJ4",
1847 "name": "_key2-EOBJ4"
1851 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1856 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1862 "selected_object_info": "3: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])",
1863 "union_shard_errors": [],
1865 "attr_value_mismatch",
1866 "attr_name_mismatch"
1899 "selected_object_info": "3: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])",
1900 "union_shard_errors": [
1919 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
1920 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
1921 if test $getjson = "yes"
1923 jq
'.' $dir/json
> save3.json
1926 if which jsonschema
> /dev
/null
;
1928 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
1933 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
1935 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
1937 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
1939 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
1940 # Get epoch for repair-get requests
1941 epoch
=$
(jq .epoch
$dir/json
)
1943 if [ "$allow_overwrites" = "true" ]
1945 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
1951 "data_digest": "0x00000000",
1952 "omap_digest": "0xffffffff",
1968 "data_digest": "0x00000000",
1969 "omap_digest": "0xffffffff",
1976 "selected_object_info": "3: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])",
1977 "union_shard_errors": [
1995 "data_digest": "0x00000000",
1996 "omap_digest": "0xffffffff",
2010 "data_digest": "0x00000000",
2011 "omap_digest": "0xffffffff",
2018 "selected_object_info": "3: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])",
2019 "union_shard_errors": [
2043 "name": "_key1-EOBJ4"
2047 "value": "val3-EOBJ4",
2048 "name": "_key3-EOBJ4"
2052 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2057 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2061 "data_digest": "0x00000000",
2062 "omap_digest": "0xffffffff",
2077 "value": "val1-EOBJ4",
2078 "name": "_key1-EOBJ4"
2082 "value": "val2-EOBJ4",
2083 "name": "_key2-EOBJ4"
2087 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2092 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2096 "data_digest": "0x00000000",
2097 "omap_digest": "0xffffffff",
2112 "value": "val1-EOBJ4",
2113 "name": "_key1-EOBJ4"
2117 "value": "val2-EOBJ4",
2118 "name": "_key2-EOBJ4"
2122 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2127 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2131 "data_digest": "0x00000000",
2132 "omap_digest": "0xffffffff",
2139 "selected_object_info": "3: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])",
2140 "union_shard_errors": [],
2142 "attr_value_mismatch",
2143 "attr_name_mismatch"
2156 "data_digest": "0x00000000",
2157 "omap_digest": "0xffffffff",
2164 "data_digest": "0x00000000",
2165 "omap_digest": "0xffffffff",
2174 "data_digest": "0x00000000",
2175 "omap_digest": "0xffffffff",
2182 "selected_object_info": "3: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])",
2183 "union_shard_errors": [
2204 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
2210 "data_digest": "0x04cfa72f",
2211 "omap_digest": "0xffffffff",
2227 "data_digest": "0x04cfa72f",
2228 "omap_digest": "0xffffffff",
2235 "selected_object_info": "3: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])",
2236 "union_shard_errors": [
2262 "data_digest": "0x04cfa72f",
2263 "omap_digest": "0xffffffff",
2270 "data_digest": "0x04cfa72f",
2271 "omap_digest": "0xffffffff",
2278 "selected_object_info": "3: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])",
2279 "union_shard_errors": [
2294 "data_digest": "0x04cfa72f",
2295 "omap_digest": "0xffffffff",
2309 "data_digest": "0x04cfa72f",
2310 "omap_digest": "0xffffffff",
2317 "selected_object_info": "3: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])",
2318 "union_shard_errors": [
2342 "name": "_key1-EOBJ4"
2346 "value": "val3-EOBJ4",
2347 "name": "_key3-EOBJ4"
2351 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2356 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2360 "data_digest": "0x04cfa72f",
2361 "omap_digest": "0xffffffff",
2372 "omap_digest": "0xffffffff",
2373 "data_digest": "0x04cfa72f",
2382 "value": "val1-EOBJ4",
2383 "name": "_key1-EOBJ4"
2387 "value": "val2-EOBJ4",
2388 "name": "_key2-EOBJ4"
2392 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2397 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2407 "omap_digest": "0xffffffff",
2408 "data_digest": "0x04cfa72f",
2417 "value": "val1-EOBJ4",
2418 "name": "_key1-EOBJ4"
2422 "value": "val2-EOBJ4",
2423 "name": "_key2-EOBJ4"
2427 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2432 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2438 "selected_object_info": "3: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])",
2439 "union_shard_errors": [],
2441 "attr_value_mismatch",
2442 "attr_name_mismatch"
2455 "data_digest": "0x04cfa72f",
2456 "omap_digest": "0xffffffff",
2472 "data_digest": "0x04cfa72f",
2473 "omap_digest": "0xffffffff",
2480 "selected_object_info": "3: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])",
2481 "union_shard_errors": [
2503 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
2504 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
2505 if test $getjson = "yes"
2507 if [ "$allow_overwrites" = "true" ]
2513 jq
'.' $dir/json
> save
${num}.json
2516 if which jsonschema
> /dev
/null
;
2518 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
2521 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
2522 teardown
$dir ||
return 1
2525 function TEST_corrupt_scrub_erasure_appends
() {
2526 corrupt_scrub_erasure
$1 false
2529 function TEST_corrupt_scrub_erasure_overwrites
() {
2530 if [ "$use_ec_overwrite" = "true" ]; then
2531 corrupt_scrub_erasure
$1 true
2536 # Test to make sure that a periodic scrub won't cause deep-scrub info to be lost
2538 function TEST_periodic_scrub_replicated
() {
2540 local poolname
=psr_pool
2543 setup
$dir ||
return 1
2544 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
2545 run_mgr
$dir x ||
return 1
2546 local ceph_osd_args
="--osd-scrub-interval-randomize-ratio=0 --osd-deep-scrub-randomize-ratio=0"
2547 run_osd
$dir 0 $ceph_osd_args ||
return 1
2548 run_osd
$dir 1 $ceph_osd_args ||
return 1
2549 create_rbd_pool ||
return 1
2550 wait_for_clean ||
return 1
2552 ceph osd pool create
$poolname 1 1 ||
return 1
2553 wait_for_clean ||
return 1
2556 add_something
$dir $poolname $objname scrub ||
return 1
2557 local primary
=$
(get_primary
$poolname $objname)
2558 local pg
=$
(get_pg
$poolname $objname)
2560 # Add deep-scrub only error
2561 local payload
=UVWXYZ
2562 echo $payload > $dir/CORRUPT
2563 # Uses $ceph_osd_args for osd restart
2564 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
2566 # No scrub information available, so expect failure
2568 ! rados list-inconsistent-obj
$pg | jq
'.' ||
return 1
2571 pg_deep_scrub
$pg ||
return 1
2573 # Make sure bad object found
2574 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2576 local last_scrub
=$
(get_last_scrub_stamp
$pg)
2577 # Fake a schedule scrub
2578 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd.
${primary}) \
2579 trigger_scrub
$pg ||
return 1
2580 # Wait for schedule regular scrub
2581 wait_for_scrub
$pg "$last_scrub"
2583 # It needed to be upgraded
2584 grep -q "Deep scrub errors, upgrading scrub to deep-scrub" $dir/osd.
${primary}.log ||
return 1
2586 # Bad object still known
2587 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2589 # Can't upgrade with this set
2590 ceph osd
set nodeep-scrub
2591 # Let map change propagate to OSDs
2594 # Fake a schedule scrub
2595 local last_scrub
=$
(get_last_scrub_stamp
$pg)
2596 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd.
${primary}) \
2597 trigger_scrub
$pg ||
return 1
2598 # Wait for schedule regular scrub
2599 # to notice scrub and skip it
2601 for i
in $
(seq 14 -1 0)
2604 ! grep -q "Regular scrub skipped due to deep-scrub errors and nodeep-scrub set" $dir/osd.
${primary}.log ||
{ found
=true
; break; }
2605 echo Time left
: $i seconds
2607 test $found = "true" ||
return 1
2609 # Bad object still known
2610 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2612 # Request a regular scrub and it will be done
2613 local scrub_backoff_ratio
=$
(get_config osd
${primary} osd_scrub_backoff_ratio
)
2614 set_config osd
${primary} osd_scrub_backoff_ratio
0
2617 set_config osd
${primary} osd_scrub_backoff_ratio
$scrub_backoff_ratio
2618 grep -q "Regular scrub request, deep-scrub details will be lost" $dir/osd.
${primary}.log ||
return 1
2620 # deep-scrub error is no longer present
2621 rados list-inconsistent-obj
$pg | jq
'.' |
grep -qv $objname ||
return 1
2625 main osd-scrub-repair
"$@"
2628 # compile-command: "cd ../.. ; make -j4 && \
2629 # test/osd/osd-scrub-repair.sh # TEST_corrupt_and_repair_replicated"