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 if [ `uname` = FreeBSD
]; then
21 # erasure coding overwrites are only tested on Bluestore
22 # erasure coding on filestore is unsafe
23 # http://docs.ceph.com/docs/master/rados/operations/erasure-code/#erasure-coding-with-overwrites
24 use_ec_overwrite
=false
29 # Test development and debugging
30 # Set to "yes" in order to ignore diff errors and save results to update test
33 # Ignore the epoch and filter out the attr '_' value because it has date information and won't match
34 jqfilter
='.inconsistents | (.[].shards[].attrs[]? | select(.name == "_") | .value) |= "----Stripped-by-test----"'
35 sortkeys
='import json; import sys ; JSON=sys.stdin.read() ; ud = json.loads(JSON) ; print json.dumps(ud, sort_keys=True, indent=2)'
37 # Remove items are not consistent across runs, the pg interval and client
38 sedfilter
='s/\([ ]*\"\(selected_\)*object_info\":.*head[(]\)[^[:space:]]* [^[:space:]]* \(.*\)/\1\3/'
44 export CEPH_MON
="127.0.0.1:7107" # git grep '\<7107\>' : there must be only one
46 CEPH_ARGS
+="--fsid=$(uuidgen) --auth-supported=none "
47 CEPH_ARGS
+="--mon-host=$CEPH_MON "
49 local funcs
=${@:-$(set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p')}
50 for func
in $funcs ; do
51 $func $dir ||
return 1
55 function add_something
() {
58 local obj
=${3:-SOMETHING}
59 local scrub
=${4:-noscrub}
61 if [ "$scrub" = "noscrub" ];
63 ceph osd
set noscrub ||
return 1
64 ceph osd
set nodeep-scrub ||
return 1
66 ceph osd
unset noscrub ||
return 1
67 ceph osd
unset nodeep-scrub ||
return 1
71 echo $payload > $dir/ORIGINAL
72 rados
--pool $poolname put
$obj $dir/ORIGINAL ||
return 1
76 # Corrupt one copy of a replicated pool
78 function TEST_corrupt_and_repair_replicated
() {
82 setup
$dir ||
return 1
83 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
84 run_mgr
$dir x ||
return 1
85 run_osd
$dir 0 ||
return 1
86 run_osd
$dir 1 ||
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 wait_for_clean ||
return 1
220 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 ||
return 1
224 echo $payload > $dir/ORIGINAL
225 rados
--pool $poolname put SOMETHING
$dir/ORIGINAL ||
return 1
227 # Remove the object from one shard physically
228 # Restarted osd get $ceph_osd_args passed
229 objectstore_tool
$dir $
(get_not_primary
$poolname SOMETHING
) SOMETHING remove ||
return 1
230 # Wait for auto repair
231 local pgid
=$
(get_pg
$poolname SOMETHING
)
232 wait_for_scrub
$pgid "$(get_last_scrub_stamp $pgid)"
233 wait_for_clean ||
return 1
234 # Verify - the file should be back
235 # Restarted osd get $ceph_osd_args passed
236 objectstore_tool
$dir $
(get_not_primary
$poolname SOMETHING
) SOMETHING list-attrs ||
return 1
237 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
238 diff $dir/ORIGINAL
$dir/COPY ||
return 1
241 teardown
$dir ||
return 1
244 function TEST_auto_repair_erasure_coded_appends
() {
245 auto_repair_erasure_coded
$1 false
248 function TEST_auto_repair_erasure_coded_overwrites
() {
249 if [ "$use_ec_overwrite" = "true" ]; then
250 auto_repair_erasure_coded
$1 true
254 function corrupt_and_repair_jerasure
() {
256 local allow_overwrites
=$2
257 local poolname
=ecpool
259 setup
$dir ||
return 1
260 run_mon
$dir a ||
return 1
261 run_mgr
$dir x ||
return 1
262 for id
in $
(seq 0 3) ; do
263 if [ "$allow_overwrites" = "true" ]; then
264 run_osd_bluestore
$dir $id ||
return 1
266 run_osd
$dir $id ||
return 1
269 wait_for_clean ||
return 1
271 create_ec_pool
$poolname $allow_overwrites k
=2 m
=2 ||
return 1
272 corrupt_and_repair_erasure_coded
$dir $poolname ||
return 1
274 teardown
$dir ||
return 1
277 function TEST_corrupt_and_repair_jerasure_appends
() {
278 corrupt_and_repair_jerasure
$1
281 function TEST_corrupt_and_repair_jerasure_overwrites
() {
282 if [ "$use_ec_overwrite" = "true" ]; then
283 corrupt_and_repair_jerasure
$1 true
287 function corrupt_and_repair_lrc
() {
289 local allow_overwrites
=$2
290 local poolname
=ecpool
292 setup
$dir ||
return 1
293 run_mon
$dir a ||
return 1
294 run_mgr
$dir x ||
return 1
295 for id
in $
(seq 0 9) ; do
296 if [ "$allow_overwrites" = "true" ]; then
297 run_osd_bluestore
$dir $id ||
return 1
299 run_osd
$dir $id ||
return 1
302 wait_for_clean ||
return 1
304 create_ec_pool
$poolname $allow_overwrites k
=4 m
=2 l
=3 plugin
=lrc ||
return 1
305 corrupt_and_repair_erasure_coded
$dir $poolname ||
return 1
307 teardown
$dir ||
return 1
310 function TEST_corrupt_and_repair_lrc_appends
() {
311 corrupt_and_repair_jerasure
$1
314 function TEST_corrupt_and_repair_lrc_overwrites
() {
315 if [ "$use_ec_overwrite" = "true" ]; then
316 corrupt_and_repair_jerasure
$1 true
320 function unfound_erasure_coded
() {
322 local allow_overwrites
=$2
323 local poolname
=ecpool
326 setup
$dir ||
return 1
327 run_mon
$dir a ||
return 1
328 run_mgr
$dir x ||
return 1
329 for id
in $
(seq 0 3) ; do
330 if [ "$allow_overwrites" = "true" ]; then
331 run_osd_bluestore
$dir $id ||
return 1
333 run_osd
$dir $id ||
return 1
336 wait_for_clean ||
return 1
338 create_ec_pool
$poolname $allow_overwrites k
=2 m
=2 ||
return 1
340 add_something
$dir $poolname ||
return 1
342 local primary
=$
(get_primary
$poolname SOMETHING
)
343 local -a osds
=($
(get_osds
$poolname SOMETHING |
sed -e "s/$primary//"))
344 local not_primary_first
=${osds[0]}
345 local not_primary_second
=${osds[1]}
346 local not_primary_third
=${osds[2]}
349 # 1) remove the corresponding file from the OSDs
352 run_in_background pids objectstore_tool
$dir $not_primary_first SOMETHING remove
353 run_in_background pids objectstore_tool
$dir $not_primary_second SOMETHING remove
354 run_in_background pids objectstore_tool
$dir $not_primary_third SOMETHING remove
357 if [ $return_code -ne 0 ]; then return $return_code; fi
362 local pg
=$
(get_pg
$poolname SOMETHING
)
367 # it may take a bit to appear due to mon/mgr asynchrony
368 for f
in `seq 1 60`; do
369 ceph
-s |
grep "1/1 unfound" && break
372 ceph
-s|
grep "4 osds: 4 up, 4 in" ||
return 1
373 ceph
-s|
grep "1/1 unfound" ||
return 1
375 teardown
$dir ||
return 1
378 function TEST_unfound_erasure_coded_appends
() {
379 unfound_erasure_coded
$1
382 function TEST_unfound_erasure_coded_overwrites
() {
383 if [ "$use_ec_overwrite" = "true" ]; then
384 unfound_erasure_coded
$1 true
389 # list_missing for EC pool
391 function list_missing_erasure_coded
() {
393 local allow_overwrites
=$2
394 local poolname
=ecpool
396 setup
$dir ||
return 1
397 run_mon
$dir a ||
return 1
398 run_mgr
$dir x ||
return 1
399 for id
in $
(seq 0 2) ; do
400 if [ "$allow_overwrites" = "true" ]; then
401 run_osd_bluestore
$dir $id ||
return 1
403 run_osd
$dir $id ||
return 1
406 wait_for_clean ||
return 1
408 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 ||
return 1
410 # Put an object and remove the two shards (including primary)
411 add_something
$dir $poolname MOBJ0 ||
return 1
412 local -a osds0
=($
(get_osds
$poolname MOBJ0
))
414 # Put another object and remove two shards (excluding primary)
415 add_something
$dir $poolname MOBJ1 ||
return 1
416 local -a osds1
=($
(get_osds
$poolname MOBJ1
))
418 # Stop all osd daemons
419 for id
in $
(seq 0 2) ; do
420 kill_daemons
$dir TERM osd.
$id >&2 < /dev
/null ||
return 1
424 ceph-objectstore-tool
--data-path $dir/$id \
425 MOBJ0 remove ||
return 1
427 ceph-objectstore-tool
--data-path $dir/$id \
428 MOBJ0 remove ||
return 1
431 ceph-objectstore-tool
--data-path $dir/$id \
432 MOBJ1 remove ||
return 1
434 ceph-objectstore-tool
--data-path $dir/$id \
435 MOBJ1 remove ||
return 1
437 for id
in $
(seq 0 2) ; do
438 activate_osd
$dir $id >&2 ||
return 1
440 wait_for_clean ||
return 1
442 # Get get - both objects should in the same PG
443 local pg
=$
(get_pg
$poolname MOBJ0
)
445 # Repair the PG, which triggers the recovering,
446 # and should mark the object as unfound
449 for i
in $
(seq 0 120) ; do
450 [ $i -lt 60 ] ||
return 1
451 matches
=$
(ceph pg
$pg list_missing |
egrep "MOBJ0|MOBJ1" |
wc -l)
452 [ $matches -eq 2 ] && break
455 teardown
$dir ||
return 1
458 function TEST_list_missing_erasure_coded_appends
() {
459 list_missing_erasure_coded
$1 false
462 function TEST_list_missing_erasure_coded_overwrites
() {
463 if [ "$use_ec_overwrite" = "true" ]; then
464 list_missing_erasure_coded
$1 true
469 # Corrupt one copy of a replicated pool
471 function TEST_corrupt_scrub_replicated
() {
473 local poolname
=csr_pool
476 setup
$dir ||
return 1
477 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
478 run_mgr
$dir x ||
return 1
479 run_osd
$dir 0 ||
return 1
480 run_osd
$dir 1 ||
return 1
481 wait_for_clean ||
return 1
483 ceph osd pool create
$poolname 1 1 ||
return 1
484 wait_for_clean ||
return 1
486 for i
in $
(seq 1 $total_objs) ; do
488 add_something
$dir $poolname $objname ||
return 1
490 rados
--pool $poolname setomapheader
$objname hdr-
$objname ||
return 1
491 rados
--pool $poolname setomapval
$objname key-
$objname val-
$objname ||
return 1
494 local pg
=$
(get_pg
$poolname ROBJ0
)
496 # Compute an old omap digest and save oi
497 CEPH_ARGS
='' ceph daemon
$dir//ceph-osd
.0.asok \
498 config
set osd_deep_scrub_update_digest_min_age
0
499 CEPH_ARGS
='' ceph daemon
$dir//ceph-osd
.1.asok \
500 config
set osd_deep_scrub_update_digest_min_age
0
503 for i
in $
(seq 1 $total_objs) ; do
506 # Alternate corruption between osd.0 and osd.1
507 local osd
=$
(expr $i % 2)
511 # Size (deep scrub data_digest too)
512 local payload
=UVWXYZZZ
513 echo $payload > $dir/CORRUPT
514 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
518 # digest (deep scrub only)
520 echo $payload > $dir/CORRUPT
521 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
526 objectstore_tool
$dir $osd $objname remove ||
return 1
530 # Modify omap value (deep scrub only)
531 objectstore_tool
$dir $osd $objname set-omap key-
$objname $dir/CORRUPT ||
return 1
535 # Delete omap key (deep scrub only)
536 objectstore_tool
$dir $osd $objname rm-omap key-
$objname ||
return 1
540 # Add extra omap key (deep scrub only)
541 echo extra
> $dir/extra-val
542 objectstore_tool
$dir $osd $objname set-omap key2-
$objname $dir/extra-val ||
return 1
547 # Modify omap header (deep scrub only)
548 echo -n newheader
> $dir/hdr
549 objectstore_tool
$dir $osd $objname set-omaphdr
$dir/hdr ||
return 1
554 rados
--pool $poolname setxattr
$objname key1-
$objname val1-
$objname ||
return 1
555 rados
--pool $poolname setxattr
$objname key2-
$objname val2-
$objname ||
return 1
558 echo -n bad-val
> $dir/bad-val
559 objectstore_tool
$dir $osd $objname set-attr _key1-
$objname $dir/bad-val ||
return 1
560 objectstore_tool
$dir $osd $objname rm-attr _key2-
$objname ||
return 1
561 echo -n val3-
$objname > $dir/newval
562 objectstore_tool
$dir $osd $objname set-attr _key3-
$objname $dir/newval ||
return 1
563 rm $dir/bad-val
$dir/newval
567 objectstore_tool
$dir $osd $objname get-attr _
> $dir/robj9-oi
568 echo -n D
> $dir/change
569 rados
--pool $poolname put
$objname $dir/change
570 objectstore_tool
$dir $osd $objname set-attr _
$dir/robj9-oi
571 rm $dir/oi
$dir/change
574 # ROBJ10 must be handled after digests are re-computed by a deep scrub below
575 # ROBJ11 must be handled with config change before deep scrub
576 # ROBJ12 must be handled with config change before scrubs
577 # ROBJ13 must be handled before scrubs
580 echo -n bad-val
> $dir/bad-val
581 objectstore_tool
$dir 0 $objname set-attr _
$dir/bad-val ||
return 1
582 objectstore_tool
$dir 1 $objname rm-attr _ ||
return 1
587 objectstore_tool
$dir $osd $objname rm-attr _ ||
return 1
592 local pg
=$
(get_pg
$poolname ROBJ0
)
594 set_config osd
0 filestore_debug_inject_read_err true ||
return 1
595 set_config osd
1 filestore_debug_inject_read_err true ||
return 1
596 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.1.asok \
597 injectdataerr
$poolname ROBJ11 ||
return 1
598 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.0.asok \
599 injectmdataerr
$poolname ROBJ12 ||
return 1
600 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.0.asok \
601 injectmdataerr
$poolname ROBJ13 ||
return 1
602 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.1.asok \
603 injectdataerr
$poolname ROBJ13 ||
return 1
607 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
609 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
611 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
613 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
614 # Get epoch for repair-get requests
615 epoch
=$
(jq .epoch
$dir/json
)
617 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
635 "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])",
636 "union_shard_errors": [
664 "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])",
665 "union_shard_errors": [
691 "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])",
692 "union_shard_errors": [
721 "union_shard_errors": [
745 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
757 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
768 "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])",
769 "union_shard_errors": [
797 "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])",
798 "union_shard_errors": [
822 "name": "_key1-ROBJ8"
826 "value": "val3-ROBJ8",
827 "name": "_key3-ROBJ8"
831 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
848 "value": "val1-ROBJ8",
849 "name": "_key1-ROBJ8"
853 "value": "val2-ROBJ8",
854 "name": "_key2-ROBJ8"
858 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
867 "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])",
868 "union_shard_errors": [],
870 "attr_value_mismatch",
892 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
896 "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])",
910 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
914 "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])",
920 "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])",
921 "union_shard_errors": [],
923 "object_info_inconsistency",
924 "attr_value_mismatch"
939 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
940 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
941 if test $getjson = "yes"
943 jq
'.' $dir/json
> save1.json
946 if which jsonschema
> /dev
/null
;
948 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
952 # Change data and size again because digest was recomputed
953 echo -n ZZZ
> $dir/change
954 rados
--pool $poolname put
$objname $dir/change
955 # Set one to an even older value
956 objectstore_tool
$dir 0 $objname set-attr _
$dir/robj9-oi
957 rm $dir/oi
$dir/change
960 objectstore_tool
$dir 1 $objname get-attr _
> $dir/oi
961 rados
--pool $poolname setomapval
$objname key2-
$objname val2-
$objname
962 objectstore_tool
$dir 0 $objname set-attr _
$dir/oi
963 objectstore_tool
$dir 1 $objname set-attr _
$dir/oi
966 set_config osd
0 filestore_debug_inject_read_err true ||
return 1
967 set_config osd
1 filestore_debug_inject_read_err true ||
return 1
968 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.1.asok \
969 injectdataerr
$poolname ROBJ11 ||
return 1
970 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.0.asok \
971 injectmdataerr
$poolname ROBJ12 ||
return 1
972 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.0.asok \
973 injectmdataerr
$poolname ROBJ13 ||
return 1
974 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd
.1.asok \
975 injectdataerr
$poolname ROBJ13 ||
return 1
978 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
980 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
982 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
984 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
985 # Get epoch for repair-get requests
986 epoch
=$
(jq .epoch
$dir/json
)
988 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
994 "data_digest": "0x2ddbf8f5",
995 "omap_digest": "0xf5fba2c6",
1001 "data_digest": "0x2d4a11c2",
1002 "omap_digest": "0xf5fba2c6",
1005 "data_digest_mismatch_oi",
1011 "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])",
1012 "union_shard_errors": [
1013 "data_digest_mismatch_oi",
1017 "data_digest_mismatch",
1031 "data_digest": "0x2ddbf8f5",
1032 "omap_digest": "0xa8dd5adc",
1035 "omap_digest_mismatch_oi"
1040 "data_digest": "0x2ddbf8f5",
1041 "omap_digest": "0xa8dd5adc",
1044 "omap_digest_mismatch_oi"
1049 "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])",
1050 "union_shard_errors": [
1051 "omap_digest_mismatch_oi"
1065 "data_digest": "0x2ddbf8f5",
1066 "omap_digest": "0xa03cef03",
1079 "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])",
1080 "union_shard_errors": [
1101 "data_digest": "0x2ddbf8f5",
1102 "omap_digest": "0x067f306a",
1108 "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])",
1109 "union_shard_errors": [
1137 "union_shard_errors": [
1153 "data_digest": "0x2ddbf8f5",
1154 "omap_digest": "0x4f14f849",
1162 "data_digest": "0x2ddbf8f5",
1163 "omap_digest": "0x4f14f849",
1171 "union_shard_errors": [
1195 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1199 "data_digest": "0x2ddbf8f5",
1200 "omap_digest": "0x2d2a4d6e",
1209 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1213 "data_digest": "0x2ddbf8f5",
1214 "omap_digest": "0x2d2a4d6e",
1222 "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])",
1223 "union_shard_errors": [
1227 "attr_name_mismatch"
1240 "data_digest": "0x578a4830",
1241 "omap_digest": "0xf8e11918",
1244 "data_digest_mismatch_oi"
1249 "data_digest": "0x2ddbf8f5",
1250 "omap_digest": "0xf8e11918",
1256 "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])",
1257 "union_shard_errors": [
1258 "data_digest_mismatch_oi"
1261 "data_digest_mismatch"
1274 "data_digest": "0x2ddbf8f5",
1275 "omap_digest": "0x00b35dfd",
1287 "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])",
1288 "union_shard_errors": [
1303 "data_digest": "0x2ddbf8f5",
1304 "omap_digest": "0xd7178dfe",
1307 "omap_digest_mismatch_oi"
1312 "data_digest": "0x2ddbf8f5",
1313 "omap_digest": "0xe2d46ea4",
1319 "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])",
1320 "union_shard_errors": [
1321 "omap_digest_mismatch_oi"
1324 "omap_digest_mismatch"
1337 "data_digest": "0x2ddbf8f5",
1338 "omap_digest": "0x1a862a41",
1344 "data_digest": "0x2ddbf8f5",
1345 "omap_digest": "0x06cac8f6",
1348 "omap_digest_mismatch_oi"
1353 "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])",
1354 "union_shard_errors": [
1355 "omap_digest_mismatch_oi"
1358 "omap_digest_mismatch"
1371 "data_digest": "0x2ddbf8f5",
1372 "omap_digest": "0x689ee887",
1375 "omap_digest_mismatch_oi"
1380 "data_digest": "0x2ddbf8f5",
1381 "omap_digest": "0x179c919f",
1387 "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])",
1388 "union_shard_errors": [
1389 "omap_digest_mismatch_oi"
1392 "omap_digest_mismatch"
1405 "data_digest": "0x2ddbf8f5",
1406 "omap_digest": "0xefced57a",
1412 "data_digest": "0x2ddbf8f5",
1413 "omap_digest": "0x6a73cc07",
1416 "omap_digest_mismatch_oi"
1421 "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])",
1422 "union_shard_errors": [
1423 "omap_digest_mismatch_oi"
1426 "omap_digest_mismatch"
1448 "name": "_key1-ROBJ8"
1452 "value": "val3-ROBJ8",
1453 "name": "_key3-ROBJ8"
1457 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1461 "data_digest": "0x2ddbf8f5",
1462 "omap_digest": "0xd6be81dc",
1476 "value": "val1-ROBJ8",
1477 "name": "_key1-ROBJ8"
1481 "value": "val2-ROBJ8",
1482 "name": "_key2-ROBJ8"
1486 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1490 "data_digest": "0x2ddbf8f5",
1491 "omap_digest": "0xd6be81dc",
1497 "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])",
1498 "union_shard_errors": [],
1500 "attr_value_mismatch",
1501 "attr_name_mismatch"
1522 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1526 "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])",
1527 "data_digest": "0x1f26fb26",
1528 "omap_digest": "0x2eecc539",
1542 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1546 "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])",
1547 "data_digest": "0x1f26fb26",
1548 "omap_digest": "0x2eecc539",
1554 "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])",
1555 "union_shard_errors": [],
1557 "object_info_inconsistency",
1558 "attr_value_mismatch"
1573 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
1574 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
1575 if test $getjson = "yes"
1577 jq
'.' $dir/json
> save2.json
1580 if which jsonschema
> /dev
/null
;
1582 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
1585 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
1586 teardown
$dir ||
return 1
1591 # Test scrub errors for an erasure coded pool
1593 function corrupt_scrub_erasure
() {
1595 local allow_overwrites
=$2
1596 local poolname
=ecpool
1599 setup
$dir ||
return 1
1600 run_mon
$dir a ||
return 1
1601 run_mgr
$dir x ||
return 1
1602 for id
in $
(seq 0 2) ; do
1603 if [ "$allow_overwrites" = "true" ]; then
1604 run_osd_bluestore
$dir $id ||
return 1
1606 run_osd
$dir $id ||
return 1
1609 wait_for_clean ||
return 1
1611 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 stripe_unit
=2K
--force ||
return 1
1613 for i
in $
(seq 1 $total_objs) ; do
1615 add_something
$dir $poolname $objname ||
return 1
1617 local osd
=$
(expr $i % 2)
1621 # Size (deep scrub data_digest too)
1622 local payload
=UVWXYZZZ
1623 echo $payload > $dir/CORRUPT
1624 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1629 dd if=/dev
/urandom of
=$dir/CORRUPT bs
=2048 count
=1
1630 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1635 objectstore_tool
$dir $osd $objname remove ||
return 1
1639 rados
--pool $poolname setxattr
$objname key1-
$objname val1-
$objname ||
return 1
1640 rados
--pool $poolname setxattr
$objname key2-
$objname val2-
$objname ||
return 1
1643 echo -n bad-val
> $dir/bad-val
1644 objectstore_tool
$dir $osd $objname set-attr _key1-
$objname $dir/bad-val ||
return 1
1645 objectstore_tool
$dir $osd $objname rm-attr _key2-
$objname ||
return 1
1646 echo -n val3-
$objname > $dir/newval
1647 objectstore_tool
$dir $osd $objname set-attr _key3-
$objname $dir/newval ||
return 1
1648 rm $dir/bad-val
$dir/newval
1653 dd if=/dev
/urandom of
=$dir/CORRUPT bs
=2048 count
=2
1654 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
1660 local pg
=$
(get_pg
$poolname EOBJ0
)
1664 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
1666 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
1668 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
1670 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
1671 # Get epoch for repair-get requests
1672 epoch
=$
(jq .epoch
$dir/json
)
1674 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
1700 "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])",
1701 "union_shard_errors": [
1737 "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])",
1738 "union_shard_errors": [
1762 "name": "_key1-EOBJ4"
1766 "value": "val3-EOBJ4",
1767 "name": "_key3-EOBJ4"
1771 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1776 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1798 "value": "val1-EOBJ4",
1799 "name": "_key1-EOBJ4"
1803 "value": "val2-EOBJ4",
1804 "name": "_key2-EOBJ4"
1808 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1813 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1831 "value": "val1-EOBJ4",
1832 "name": "_key1-EOBJ4"
1836 "value": "val2-EOBJ4",
1837 "name": "_key2-EOBJ4"
1841 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
1846 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
1852 "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])",
1853 "union_shard_errors": [],
1855 "attr_value_mismatch",
1856 "attr_name_mismatch"
1889 "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])",
1890 "union_shard_errors": [
1909 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
1910 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
1911 if test $getjson = "yes"
1913 jq
'.' $dir/json
> save3.json
1916 if which jsonschema
> /dev
/null
;
1918 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
1923 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
1925 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
1927 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
1929 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
1930 # Get epoch for repair-get requests
1931 epoch
=$
(jq .epoch
$dir/json
)
1933 if [ "$allow_overwrites" = "true" ]
1935 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
1941 "data_digest": "0x00000000",
1942 "omap_digest": "0xffffffff",
1958 "data_digest": "0x00000000",
1959 "omap_digest": "0xffffffff",
1966 "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])",
1967 "union_shard_errors": [
1985 "data_digest": "0x00000000",
1986 "omap_digest": "0xffffffff",
2000 "data_digest": "0x00000000",
2001 "omap_digest": "0xffffffff",
2008 "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])",
2009 "union_shard_errors": [
2033 "name": "_key1-EOBJ4"
2037 "value": "val3-EOBJ4",
2038 "name": "_key3-EOBJ4"
2042 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2047 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2051 "data_digest": "0x00000000",
2052 "omap_digest": "0xffffffff",
2067 "value": "val1-EOBJ4",
2068 "name": "_key1-EOBJ4"
2072 "value": "val2-EOBJ4",
2073 "name": "_key2-EOBJ4"
2077 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2082 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2086 "data_digest": "0x00000000",
2087 "omap_digest": "0xffffffff",
2102 "value": "val1-EOBJ4",
2103 "name": "_key1-EOBJ4"
2107 "value": "val2-EOBJ4",
2108 "name": "_key2-EOBJ4"
2112 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2117 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2121 "data_digest": "0x00000000",
2122 "omap_digest": "0xffffffff",
2129 "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])",
2130 "union_shard_errors": [],
2132 "attr_value_mismatch",
2133 "attr_name_mismatch"
2146 "data_digest": "0x00000000",
2147 "omap_digest": "0xffffffff",
2154 "data_digest": "0x00000000",
2155 "omap_digest": "0xffffffff",
2164 "data_digest": "0x00000000",
2165 "omap_digest": "0xffffffff",
2172 "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])",
2173 "union_shard_errors": [
2194 jq
"$jqfilter" << EOF | python -c "$sortkeys" | sed -e "$sedfilter" > $dir/checkcsjson
2200 "data_digest": "0x04cfa72f",
2201 "omap_digest": "0xffffffff",
2217 "data_digest": "0x04cfa72f",
2218 "omap_digest": "0xffffffff",
2225 "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])",
2226 "union_shard_errors": [
2252 "data_digest": "0x04cfa72f",
2253 "omap_digest": "0xffffffff",
2260 "data_digest": "0x04cfa72f",
2261 "omap_digest": "0xffffffff",
2268 "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])",
2269 "union_shard_errors": [
2284 "data_digest": "0x04cfa72f",
2285 "omap_digest": "0xffffffff",
2299 "data_digest": "0x04cfa72f",
2300 "omap_digest": "0xffffffff",
2307 "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])",
2308 "union_shard_errors": [
2332 "name": "_key1-EOBJ4"
2336 "value": "val3-EOBJ4",
2337 "name": "_key3-EOBJ4"
2341 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2346 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2350 "data_digest": "0x04cfa72f",
2351 "omap_digest": "0xffffffff",
2362 "omap_digest": "0xffffffff",
2363 "data_digest": "0x04cfa72f",
2372 "value": "val1-EOBJ4",
2373 "name": "_key1-EOBJ4"
2377 "value": "val2-EOBJ4",
2378 "name": "_key2-EOBJ4"
2382 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2387 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2397 "omap_digest": "0xffffffff",
2398 "data_digest": "0x04cfa72f",
2407 "value": "val1-EOBJ4",
2408 "name": "_key1-EOBJ4"
2412 "value": "val2-EOBJ4",
2413 "name": "_key2-EOBJ4"
2417 "value": "AQEYAAAAAAgAAAAAAAADAAAAL6fPBLB8dlsvp88E",
2422 "value": "AwIdAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
2428 "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])",
2429 "union_shard_errors": [],
2431 "attr_value_mismatch",
2432 "attr_name_mismatch"
2445 "data_digest": "0x04cfa72f",
2446 "omap_digest": "0xffffffff",
2462 "data_digest": "0x04cfa72f",
2463 "omap_digest": "0xffffffff",
2470 "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])",
2471 "union_shard_errors": [
2493 jq
"$jqfilter" $dir/json | python
-c "$sortkeys" |
sed -e "$sedfilter" > $dir/csjson
2494 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
2495 if test $getjson = "yes"
2497 if [ "$allow_overwrites" = "true" ]
2503 jq
'.' $dir/json
> save
${num}.json
2506 if which jsonschema
> /dev
/null
;
2508 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
2511 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
2512 teardown
$dir ||
return 1
2515 function TEST_corrupt_scrub_erasure_appends
() {
2516 corrupt_scrub_erasure
$1 false
2519 function TEST_corrupt_scrub_erasure_overwrites
() {
2520 if [ "$use_ec_overwrite" = "true" ]; then
2521 corrupt_scrub_erasure
$1 true
2526 # Test to make sure that a periodic scrub won't cause deep-scrub info to be lost
2528 function TEST_periodic_scrub_replicated
() {
2530 local poolname
=psr_pool
2533 setup
$dir ||
return 1
2534 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
2535 run_mgr
$dir x ||
return 1
2536 local ceph_osd_args
="--osd-scrub-interval-randomize-ratio=0 --osd-deep-scrub-randomize-ratio=0"
2537 run_osd
$dir 0 $ceph_osd_args ||
return 1
2538 run_osd
$dir 1 $ceph_osd_args ||
return 1
2539 wait_for_clean ||
return 1
2541 ceph osd pool create
$poolname 1 1 ||
return 1
2542 wait_for_clean ||
return 1
2545 add_something
$dir $poolname $objname scrub ||
return 1
2546 local primary
=$
(get_primary
$poolname $objname)
2547 local pg
=$
(get_pg
$poolname $objname)
2549 # Add deep-scrub only error
2550 local payload
=UVWXYZ
2551 echo $payload > $dir/CORRUPT
2552 # Uses $ceph_osd_args for osd restart
2553 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
2555 # No scrub information available, so expect failure
2557 ! rados list-inconsistent-obj
$pg | jq
'.' ||
return 1
2560 pg_deep_scrub
$pg ||
return 1
2562 # Make sure bad object found
2563 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2565 local last_scrub
=$
(get_last_scrub_stamp
$pg)
2566 # Fake a schedule scrub
2567 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd.
${primary}.asok \
2568 trigger_scrub
$pg ||
return 1
2569 # Wait for schedule regular scrub
2570 wait_for_scrub
$pg "$last_scrub"
2572 # It needed to be upgraded
2573 grep -q "Deep scrub errors, upgrading scrub to deep-scrub" $dir/osd.
${primary}.log ||
return 1
2575 # Bad object still known
2576 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2578 # Can't upgrade with this set
2579 ceph osd
set nodeep-scrub
2580 # Let map change propagate to OSDs
2583 # Fake a schedule scrub
2584 local last_scrub
=$
(get_last_scrub_stamp
$pg)
2585 CEPH_ARGS
='' ceph
--admin-daemon $dir/ceph-osd.
${primary}.asok \
2586 trigger_scrub
$pg ||
return 1
2587 # Wait for schedule regular scrub
2588 # to notice scrub and skip it
2590 for i
in $
(seq 14 -1 0)
2593 ! grep -q "Regular scrub skipped due to deep-scrub errors and nodeep-scrub set" $dir/osd.
${primary}.log ||
{ found
=true
; break; }
2594 echo Time left
: $i seconds
2596 test $found = "true" ||
return 1
2598 # Bad object still known
2599 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
2601 # Request a regular scrub and it will be done
2602 local scrub_backoff_ratio
=$
(get_config osd
${primary} osd_scrub_backoff_ratio
)
2603 set_config osd
${primary} osd_scrub_backoff_ratio
0
2606 set_config osd
${primary} osd_scrub_backoff_ratio
$scrub_backoff_ratio
2607 grep -q "Regular scrub request, losing deep-scrub details" $dir/osd.
${primary}.log ||
return 1
2609 # deep-scrub error is no longer present
2610 rados list-inconsistent-obj
$pg | jq
'.' |
grep -qv $objname ||
return 1
2614 main osd-scrub-repair
"$@"
2617 # compile-command: "cd ../.. ; make -j4 && \
2618 # test/osd/osd-scrub-repair.sh # TEST_corrupt_and_repair_replicated"