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 # Filter out mtime and local_mtime dates, version, prior_version and last_reqid (client) from any object_info.
33 jqfilter
='def walk(f):
35 | if type == "object" then
37 ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
38 elif type == "array" then map( walk(f) ) | f
41 walk(if type == "object" then del(.mtime) else . end)
42 | walk(if type == "object" then del(.local_mtime) else . end)
43 | walk(if type == "object" then del(.last_reqid) else . end)
44 | walk(if type == "object" then del(.version) else . end)
45 | walk(if type == "object" then del(.prior_version) else . end)
46 | walk(if type == "object" then del(.redirect_target) else . end)
47 | walk(if type == "object" then del(.legacy_snaps) else . end)'
49 sortkeys
='import json; import sys ; JSON=sys.stdin.read() ; ud = json.loads(JSON) ; print json.dumps(ud, sort_keys=True, indent=2)'
55 export CEPH_MON
="127.0.0.1:7107" # git grep '\<7107\>' : there must be only one
57 CEPH_ARGS
+="--fsid=$(uuidgen) --auth-supported=none "
58 CEPH_ARGS
+="--mon-host=$CEPH_MON "
59 CEPH_ARGS
+="--osd-skip-data-digest=false "
61 local funcs
=${@:-$(set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p')}
62 for func
in $funcs ; do
63 $func $dir ||
return 1
67 function add_something
() {
70 local obj
=${3:-SOMETHING}
71 local scrub
=${4:-noscrub}
73 if [ "$scrub" = "noscrub" ];
75 ceph osd
set noscrub ||
return 1
76 ceph osd
set nodeep-scrub ||
return 1
78 ceph osd
unset noscrub ||
return 1
79 ceph osd
unset nodeep-scrub ||
return 1
83 echo $payload > $dir/ORIGINAL
84 rados
--pool $poolname put
$obj $dir/ORIGINAL ||
return 1
88 # Corrupt one copy of a replicated pool
90 function TEST_corrupt_and_repair_replicated
() {
94 setup
$dir ||
return 1
95 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
96 run_mgr
$dir x ||
return 1
97 run_osd
$dir 0 ||
return 1
98 run_osd
$dir 1 ||
return 1
99 create_rbd_pool ||
return 1
100 wait_for_clean ||
return 1
102 add_something
$dir $poolname ||
return 1
103 corrupt_and_repair_one
$dir $poolname $
(get_not_primary
$poolname SOMETHING
) ||
return 1
104 # Reproduces http://tracker.ceph.com/issues/8914
105 corrupt_and_repair_one
$dir $poolname $
(get_primary
$poolname SOMETHING
) ||
return 1
107 teardown
$dir ||
return 1
110 function corrupt_and_repair_two
() {
117 # 1) remove the corresponding file from the OSDs
120 run_in_background pids objectstore_tool
$dir $first SOMETHING remove
121 run_in_background pids objectstore_tool
$dir $second SOMETHING remove
124 if [ $return_code -ne 0 ]; then return $return_code; fi
129 local pg
=$
(get_pg
$poolname SOMETHING
)
132 # 3) The files must be back
135 run_in_background pids objectstore_tool
$dir $first SOMETHING list-attrs
136 run_in_background pids objectstore_tool
$dir $second SOMETHING list-attrs
139 if [ $return_code -ne 0 ]; then return $return_code; fi
141 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
142 diff $dir/ORIGINAL
$dir/COPY ||
return 1
147 # 2) remove the corresponding file from a designated OSD
149 # 4) check that the file has been restored in the designated OSD
151 function corrupt_and_repair_one
() {
157 # 1) remove the corresponding file from the OSD
159 objectstore_tool
$dir $osd SOMETHING remove ||
return 1
163 local pg
=$
(get_pg
$poolname SOMETHING
)
166 # 3) The file must be back
168 objectstore_tool
$dir $osd SOMETHING list-attrs ||
return 1
169 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
170 diff $dir/ORIGINAL
$dir/COPY ||
return 1
173 function corrupt_and_repair_erasure_coded
() {
177 add_something
$dir $poolname ||
return 1
179 local primary
=$
(get_primary
$poolname SOMETHING
)
180 local -a osds
=($
(get_osds
$poolname SOMETHING |
sed -e "s/$primary//"))
181 local not_primary_first
=${osds[0]}
182 local not_primary_second
=${osds[1]}
184 # Reproduces http://tracker.ceph.com/issues/10017
185 corrupt_and_repair_one
$dir $poolname $primary ||
return 1
186 # Reproduces http://tracker.ceph.com/issues/10409
187 corrupt_and_repair_one
$dir $poolname $not_primary_first ||
return 1
188 corrupt_and_repair_two
$dir $poolname $not_primary_first $not_primary_second ||
return 1
189 corrupt_and_repair_two
$dir $poolname $primary $not_primary_first ||
return 1
193 function create_ec_pool
() {
195 local allow_overwrites
=$2
197 ceph osd erasure-code-profile
set myprofile crush-failure-domain
=osd
$3 $4 $5 $6 $7 ||
return 1
199 create_pool
"$poolname" 1 1 erasure myprofile ||
return 1
201 if [ "$allow_overwrites" = "true" ]; then
202 ceph osd pool
set "$poolname" allow_ec_overwrites true ||
return 1
205 wait_for_clean ||
return 1
209 function auto_repair_erasure_coded
() {
211 local allow_overwrites
=$2
212 local poolname
=ecpool
214 # Launch a cluster with 5 seconds scrub interval
215 setup
$dir ||
return 1
216 run_mon
$dir a ||
return 1
217 run_mgr
$dir x ||
return 1
218 local ceph_osd_args
="--osd-scrub-auto-repair=true \
219 --osd-deep-scrub-interval=5 \
220 --osd-scrub-max-interval=5 \
221 --osd-scrub-min-interval=5 \
222 --osd-scrub-interval-randomize-ratio=0"
223 for id
in $
(seq 0 2) ; do
224 if [ "$allow_overwrites" = "true" ]; then
225 run_osd_bluestore
$dir $id $ceph_osd_args ||
return 1
227 run_osd
$dir $id $ceph_osd_args ||
return 1
230 create_rbd_pool ||
return 1
231 wait_for_clean ||
return 1
234 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 ||
return 1
238 echo $payload > $dir/ORIGINAL
239 rados
--pool $poolname put SOMETHING
$dir/ORIGINAL ||
return 1
241 # Remove the object from one shard physically
242 # Restarted osd get $ceph_osd_args passed
243 objectstore_tool
$dir $
(get_not_primary
$poolname SOMETHING
) SOMETHING remove ||
return 1
244 # Wait for auto repair
245 local pgid
=$
(get_pg
$poolname SOMETHING
)
246 wait_for_scrub
$pgid "$(get_last_scrub_stamp $pgid)"
247 wait_for_clean ||
return 1
248 # Verify - the file should be back
249 # Restarted osd get $ceph_osd_args passed
250 objectstore_tool
$dir $
(get_not_primary
$poolname SOMETHING
) SOMETHING list-attrs ||
return 1
251 rados
--pool $poolname get SOMETHING
$dir/COPY ||
return 1
252 diff $dir/ORIGINAL
$dir/COPY ||
return 1
255 teardown
$dir ||
return 1
258 function TEST_auto_repair_erasure_coded_appends
() {
259 auto_repair_erasure_coded
$1 false
262 function TEST_auto_repair_erasure_coded_overwrites
() {
263 if [ "$use_ec_overwrite" = "true" ]; then
264 auto_repair_erasure_coded
$1 true
268 function corrupt_and_repair_jerasure
() {
270 local allow_overwrites
=$2
271 local poolname
=ecpool
273 setup
$dir ||
return 1
274 run_mon
$dir a ||
return 1
275 run_mgr
$dir x ||
return 1
276 for id
in $
(seq 0 3) ; do
277 if [ "$allow_overwrites" = "true" ]; then
278 run_osd_bluestore
$dir $id ||
return 1
280 run_osd
$dir $id ||
return 1
283 create_rbd_pool ||
return 1
284 wait_for_clean ||
return 1
286 create_ec_pool
$poolname $allow_overwrites k
=2 m
=2 ||
return 1
287 corrupt_and_repair_erasure_coded
$dir $poolname ||
return 1
289 teardown
$dir ||
return 1
292 function TEST_corrupt_and_repair_jerasure_appends
() {
293 corrupt_and_repair_jerasure
$1
296 function TEST_corrupt_and_repair_jerasure_overwrites
() {
297 if [ "$use_ec_overwrite" = "true" ]; then
298 corrupt_and_repair_jerasure
$1 true
302 function corrupt_and_repair_lrc
() {
304 local allow_overwrites
=$2
305 local poolname
=ecpool
307 setup
$dir ||
return 1
308 run_mon
$dir a ||
return 1
309 run_mgr
$dir x ||
return 1
310 for id
in $
(seq 0 9) ; do
311 if [ "$allow_overwrites" = "true" ]; then
312 run_osd_bluestore
$dir $id ||
return 1
314 run_osd
$dir $id ||
return 1
317 create_rbd_pool ||
return 1
318 wait_for_clean ||
return 1
320 create_ec_pool
$poolname $allow_overwrites k
=4 m
=2 l
=3 plugin
=lrc ||
return 1
321 corrupt_and_repair_erasure_coded
$dir $poolname ||
return 1
323 teardown
$dir ||
return 1
326 function TEST_corrupt_and_repair_lrc_appends
() {
327 corrupt_and_repair_jerasure
$1
330 function TEST_corrupt_and_repair_lrc_overwrites
() {
331 if [ "$use_ec_overwrite" = "true" ]; then
332 corrupt_and_repair_jerasure
$1 true
336 function unfound_erasure_coded
() {
338 local allow_overwrites
=$2
339 local poolname
=ecpool
342 setup
$dir ||
return 1
343 run_mon
$dir a ||
return 1
344 run_mgr
$dir x ||
return 1
345 for id
in $
(seq 0 3) ; do
346 if [ "$allow_overwrites" = "true" ]; then
347 run_osd_bluestore
$dir $id ||
return 1
349 run_osd
$dir $id ||
return 1
352 create_rbd_pool ||
return 1
353 wait_for_clean ||
return 1
355 create_ec_pool
$poolname $allow_overwrites k
=2 m
=2 ||
return 1
357 add_something
$dir $poolname ||
return 1
359 local primary
=$
(get_primary
$poolname SOMETHING
)
360 local -a osds
=($
(get_osds
$poolname SOMETHING |
sed -e "s/$primary//"))
361 local not_primary_first
=${osds[0]}
362 local not_primary_second
=${osds[1]}
363 local not_primary_third
=${osds[2]}
366 # 1) remove the corresponding file from the OSDs
369 run_in_background pids objectstore_tool
$dir $not_primary_first SOMETHING remove
370 run_in_background pids objectstore_tool
$dir $not_primary_second SOMETHING remove
371 run_in_background pids objectstore_tool
$dir $not_primary_third SOMETHING remove
374 if [ $return_code -ne 0 ]; then return $return_code; fi
379 local pg
=$
(get_pg
$poolname SOMETHING
)
384 # it may take a bit to appear due to mon/mgr asynchrony
385 for f
in `seq 1 60`; do
386 ceph
-s |
grep "1/1 objects unfound" && break
389 ceph
-s|
grep "4 osds: 4 up, 4 in" ||
return 1
390 ceph
-s|
grep "1/1 objects unfound" ||
return 1
392 teardown
$dir ||
return 1
395 function TEST_unfound_erasure_coded_appends
() {
396 unfound_erasure_coded
$1
399 function TEST_unfound_erasure_coded_overwrites
() {
400 if [ "$use_ec_overwrite" = "true" ]; then
401 unfound_erasure_coded
$1 true
406 # list_missing for EC pool
408 function list_missing_erasure_coded
() {
410 local allow_overwrites
=$2
411 local poolname
=ecpool
413 setup
$dir ||
return 1
414 run_mon
$dir a ||
return 1
415 run_mgr
$dir x ||
return 1
416 for id
in $
(seq 0 2) ; do
417 if [ "$allow_overwrites" = "true" ]; then
418 run_osd_bluestore
$dir $id ||
return 1
420 run_osd
$dir $id ||
return 1
423 create_rbd_pool ||
return 1
424 wait_for_clean ||
return 1
426 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 ||
return 1
428 # Put an object and remove the two shards (including primary)
429 add_something
$dir $poolname MOBJ0 ||
return 1
430 local -a osds0
=($
(get_osds
$poolname MOBJ0
))
432 # Put another object and remove two shards (excluding primary)
433 add_something
$dir $poolname MOBJ1 ||
return 1
434 local -a osds1
=($
(get_osds
$poolname MOBJ1
))
436 # Stop all osd daemons
437 for id
in $
(seq 0 2) ; do
438 kill_daemons
$dir TERM osd.
$id >&2 < /dev
/null ||
return 1
442 ceph-objectstore-tool
--data-path $dir/$id \
443 MOBJ0 remove ||
return 1
445 ceph-objectstore-tool
--data-path $dir/$id \
446 MOBJ0 remove ||
return 1
449 ceph-objectstore-tool
--data-path $dir/$id \
450 MOBJ1 remove ||
return 1
452 ceph-objectstore-tool
--data-path $dir/$id \
453 MOBJ1 remove ||
return 1
455 for id
in $
(seq 0 2) ; do
456 activate_osd
$dir $id >&2 ||
return 1
458 create_rbd_pool ||
return 1
459 wait_for_clean ||
return 1
461 # Get get - both objects should in the same PG
462 local pg
=$
(get_pg
$poolname MOBJ0
)
464 # Repair the PG, which triggers the recovering,
465 # and should mark the object as unfound
468 for i
in $
(seq 0 120) ; do
469 [ $i -lt 60 ] ||
return 1
470 matches
=$
(ceph pg
$pg list_missing |
egrep "MOBJ0|MOBJ1" |
wc -l)
471 [ $matches -eq 2 ] && break
474 teardown
$dir ||
return 1
477 function TEST_list_missing_erasure_coded_appends
() {
478 list_missing_erasure_coded
$1 false
481 function TEST_list_missing_erasure_coded_overwrites
() {
482 if [ "$use_ec_overwrite" = "true" ]; then
483 list_missing_erasure_coded
$1 true
488 # Corrupt one copy of a replicated pool
490 function TEST_corrupt_scrub_replicated
() {
492 local poolname
=csr_pool
495 setup
$dir ||
return 1
496 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
497 run_mgr
$dir x ||
return 1
498 run_osd
$dir 0 ||
return 1
499 run_osd
$dir 1 ||
return 1
500 create_rbd_pool ||
return 1
501 wait_for_clean ||
return 1
503 create_pool foo
1 ||
return 1
504 create_pool
$poolname 1 1 ||
return 1
505 wait_for_clean ||
return 1
507 for i
in $
(seq 1 $total_objs) ; do
509 add_something
$dir $poolname $objname ||
return 1
511 rados
--pool $poolname setomapheader
$objname hdr-
$objname ||
return 1
512 rados
--pool $poolname setomapval
$objname key-
$objname val-
$objname ||
return 1
515 local pg
=$
(get_pg
$poolname ROBJ0
)
517 # Compute an old omap digest and save oi
518 CEPH_ARGS
='' ceph daemon $
(get_asok_path osd
.0) \
519 config
set osd_deep_scrub_update_digest_min_age
0
520 CEPH_ARGS
='' ceph daemon $
(get_asok_path osd
.1) \
521 config
set osd_deep_scrub_update_digest_min_age
0
524 for i
in $
(seq 1 $total_objs) ; do
527 # Alternate corruption between osd.0 and osd.1
528 local osd
=$
(expr $i % 2)
532 # Size (deep scrub data_digest too)
533 local payload
=UVWXYZZZ
534 echo $payload > $dir/CORRUPT
535 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
539 # digest (deep scrub only)
541 echo $payload > $dir/CORRUPT
542 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
547 objectstore_tool
$dir $osd $objname remove ||
return 1
551 # Modify omap value (deep scrub only)
552 objectstore_tool
$dir $osd $objname set-omap key-
$objname $dir/CORRUPT ||
return 1
556 # Delete omap key (deep scrub only)
557 objectstore_tool
$dir $osd $objname rm-omap key-
$objname ||
return 1
561 # Add extra omap key (deep scrub only)
562 echo extra
> $dir/extra-val
563 objectstore_tool
$dir $osd $objname set-omap key2-
$objname $dir/extra-val ||
return 1
568 # Modify omap header (deep scrub only)
569 echo -n newheader
> $dir/hdr
570 objectstore_tool
$dir $osd $objname set-omaphdr
$dir/hdr ||
return 1
575 rados
--pool $poolname setxattr
$objname key1-
$objname val1-
$objname ||
return 1
576 rados
--pool $poolname setxattr
$objname key2-
$objname val2-
$objname ||
return 1
579 echo -n bad-val
> $dir/bad-val
580 objectstore_tool
$dir $osd $objname set-attr _key1-
$objname $dir/bad-val ||
return 1
581 objectstore_tool
$dir $osd $objname rm-attr _key2-
$objname ||
return 1
582 echo -n val3-
$objname > $dir/newval
583 objectstore_tool
$dir $osd $objname set-attr _key3-
$objname $dir/newval ||
return 1
584 rm $dir/bad-val
$dir/newval
588 objectstore_tool
$dir $osd $objname get-attr _
> $dir/robj9-oi
589 echo -n D
> $dir/change
590 rados
--pool $poolname put
$objname $dir/change
591 objectstore_tool
$dir $osd $objname set-attr _
$dir/robj9-oi
592 rm $dir/oi
$dir/change
595 # ROBJ10 must be handled after digests are re-computed by a deep scrub below
596 # ROBJ11 must be handled with config change before deep scrub
597 # ROBJ12 must be handled with config change before scrubs
598 # ROBJ13 must be handled before scrubs
601 echo -n bad-val
> $dir/bad-val
602 objectstore_tool
$dir 0 $objname set-attr _
$dir/bad-val ||
return 1
603 objectstore_tool
$dir 1 $objname rm-attr _ ||
return 1
608 objectstore_tool
$dir $osd $objname rm-attr _ ||
return 1
612 objectstore_tool
$dir 0 $objname rm-attr snapset ||
return 1
613 echo -n bad-val
> $dir/bad-val
614 objectstore_tool
$dir 1 $objname set-attr snapset
$dir/bad-val ||
return 1
619 local pg
=$
(get_pg
$poolname ROBJ0
)
621 inject_eio rep data
$poolname ROBJ11
$dir 0 ||
return 1 # shard 0 of [1, 0], osd.1
622 inject_eio rep mdata
$poolname ROBJ12
$dir 1 ||
return 1 # shard 1 of [1, 0], osd.0
623 inject_eio rep mdata
$poolname ROBJ13
$dir 1 ||
return 1 # shard 1 of [1, 0], osd.0
624 inject_eio rep data
$poolname ROBJ13
$dir 0 ||
return 1 # shard 0 of [1, 0], osd.1
628 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
630 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
632 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
634 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
635 # Get epoch for repair-get requests
636 epoch
=$
(jq .epoch
$dir/json
)
638 jq
"$jqfilter" << EOF | jq '.inconsistents' | python -c "$sortkeys" > $dir/checkcsjson
661 "prior_version": "21'3",
662 "last_reqid": "osd.1.0:57",
676 "data_digest": "0x2ddbf8f5",
677 "omap_digest": "0xf5fba2c6",
678 "expected_object_size": 0,
679 "expected_write_size": 0,
680 "alloc_hint_flags": 0,
688 "size_mismatch_info",
689 "obj_size_info_mismatch"
695 "selected_object_info": {
706 "prior_version": "21'3",
707 "last_reqid": "osd.1.0:57",
710 "mtime": "2018-04-05 14:33:19.804040",
711 "local_mtime": "2018-04-05 14:33:19.804839",
721 "data_digest": "0x2ddbf8f5",
722 "omap_digest": "0xf5fba2c6",
723 "expected_object_size": 0,
724 "expected_write_size": 0,
725 "alloc_hint_flags": 0,
731 "union_shard_errors": [
732 "size_mismatch_info",
733 "obj_size_info_mismatch"
762 "selected_object_info": {
773 "prior_version": "43'36",
774 "last_reqid": "osd.1.0:55",
788 "data_digest": "0x2ddbf8f5",
789 "omap_digest": "0x067f306a",
790 "expected_object_size": 0,
791 "expected_write_size": 0,
792 "alloc_hint_flags": 0,
798 "union_shard_errors": [
826 "selected_object_info": {
837 "prior_version": "45'39",
838 "last_reqid": "osd.1.0:58",
852 "data_digest": "0x2ddbf8f5",
853 "omap_digest": "0x6441854d",
854 "expected_object_size": 0,
855 "expected_write_size": 0,
856 "alloc_hint_flags": 0,
862 "union_shard_errors": [
877 "object_info": "bad-val",
894 "union_shard_errors": [
921 "prior_version": "49'45",
922 "last_reqid": "osd.1.0:48",
925 "mtime": "2018-04-05 14:33:29.498969",
926 "local_mtime": "2018-04-05 14:33:29.499890",
936 "data_digest": "0x2ddbf8f5",
937 "omap_digest": "0x2d2a4d6e",
938 "expected_object_size": 0,
939 "expected_write_size": 0,
940 "alloc_hint_flags": 0,
960 "selected_object_info": {
971 "prior_version": "49'45",
972 "last_reqid": "osd.1.0:48",
986 "data_digest": "0x2ddbf8f5",
987 "omap_digest": "0x2d2a4d6e",
988 "expected_object_size": 0,
989 "expected_write_size": 0,
990 "alloc_hint_flags": 0,
996 "union_shard_errors": [
1032 "snapset": "bad-val",
1036 "union_shard_errors": [
1057 "selected_object_info": {
1068 "prior_version": "25'9",
1069 "last_reqid": "osd.1.0:60",
1083 "data_digest": "0x2ddbf8f5",
1084 "omap_digest": "0x00b35dfd",
1085 "expected_object_size": 0,
1086 "expected_write_size": 0,
1087 "alloc_hint_flags": 0,
1093 "union_shard_errors": [
1112 "name": "key1-ROBJ8"
1116 "value": "val2-ROBJ8",
1117 "name": "key2-ROBJ8"
1129 "value": "val1-ROBJ8",
1130 "name": "key1-ROBJ8"
1134 "value": "val3-ROBJ8",
1135 "name": "key3-ROBJ8"
1144 "selected_object_info": {
1155 "prior_version": "79'65",
1156 "last_reqid": "client.4554.0:1",
1170 "data_digest": "0x2ddbf8f5",
1171 "omap_digest": "0xd6be81dc",
1172 "expected_object_size": 0,
1173 "expected_write_size": 0,
1174 "alloc_hint_flags": 0,
1180 "union_shard_errors": [],
1182 "attr_value_mismatch",
1183 "attr_name_mismatch"
1207 "prior_version": "51'64",
1208 "last_reqid": "client.4649.0:1",
1222 "data_digest": "0x2b63260d",
1223 "omap_digest": "0x2eecc539",
1224 "expected_object_size": 0,
1225 "expected_write_size": 0,
1226 "alloc_hint_flags": 0,
1249 "prior_version": "37'27",
1250 "last_reqid": "osd.1.0:63",
1253 "mtime": "2018-04-05 14:33:25.352485",
1254 "local_mtime": "2018-04-05 14:33:25.353746",
1264 "data_digest": "0x2ddbf8f5",
1265 "omap_digest": "0x2eecc539",
1266 "expected_object_size": 0,
1267 "expected_write_size": 0,
1268 "alloc_hint_flags": 0,
1276 "obj_size_info_mismatch"
1282 "selected_object_info": {
1293 "prior_version": "51'64",
1294 "last_reqid": "client.4649.0:1",
1308 "data_digest": "0x2b63260d",
1309 "omap_digest": "0x2eecc539",
1310 "expected_object_size": 0,
1311 "expected_write_size": 0,
1312 "alloc_hint_flags": 0,
1318 "union_shard_errors": [
1319 "obj_size_info_mismatch"
1322 "object_info_inconsistency"
1337 jq
"$jqfilter" $dir/json | jq
'.inconsistents' | python
-c "$sortkeys" > $dir/csjson
1338 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
1339 if test $getjson = "yes"
1341 jq
'.' $dir/json
> save1.json
1344 if test "$LOCALRUN" = "yes" && which jsonschema
> /dev
/null
;
1346 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
1350 # Change data and size again because digest was recomputed
1351 echo -n ZZZ
> $dir/change
1352 rados
--pool $poolname put
$objname $dir/change
1353 # Set one to an even older value
1354 objectstore_tool
$dir 0 $objname set-attr _
$dir/robj9-oi
1355 rm $dir/oi
$dir/change
1358 objectstore_tool
$dir 1 $objname get-attr _
> $dir/oi
1359 rados
--pool $poolname setomapval
$objname key2-
$objname val2-
$objname
1360 objectstore_tool
$dir 0 $objname set-attr _
$dir/oi
1361 objectstore_tool
$dir 1 $objname set-attr _
$dir/oi
1364 inject_eio rep data
$poolname ROBJ11
$dir 0 ||
return 1 # shard 0 of [1, 0], osd.1
1365 inject_eio rep mdata
$poolname ROBJ12
$dir 1 ||
return 1 # shard 1 of [1, 0], osd.0
1366 inject_eio rep mdata
$poolname ROBJ13
$dir 1 ||
return 1 # shard 1 of [1, 0], osd.0
1367 inject_eio rep data
$poolname ROBJ13
$dir 0 ||
return 1 # shard 0 of [1, 0], osd.1
1370 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
1372 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
1374 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
1376 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
1377 # Get epoch for repair-get requests
1378 epoch
=$
(jq .epoch
$dir/json
)
1380 jq
"$jqfilter" << EOF | jq '.inconsistents' | python -c "$sortkeys" > $dir/checkcsjson
1386 "data_digest": "0x2ddbf8f5",
1387 "omap_digest": "0xf5fba2c6",
1405 "prior_version": "21'3",
1406 "last_reqid": "osd.1.0:57",
1409 "mtime": "2018-04-05 14:33:19.804040",
1410 "local_mtime": "2018-04-05 14:33:19.804839",
1420 "data_digest": "0x2ddbf8f5",
1421 "omap_digest": "0xf5fba2c6",
1422 "expected_object_size": 0,
1423 "expected_write_size": 0,
1424 "alloc_hint_flags": 0,
1430 "data_digest": "0x2d4a11c2",
1431 "omap_digest": "0xf5fba2c6",
1434 "data_digest_mismatch_info",
1435 "size_mismatch_info",
1436 "obj_size_info_mismatch"
1442 "selected_object_info": {
1453 "prior_version": "21'3",
1454 "last_reqid": "osd.1.0:57",
1457 "mtime": "2018-04-05 14:33:19.804040",
1458 "local_mtime": "2018-04-05 14:33:19.804839",
1468 "data_digest": "0x2ddbf8f5",
1469 "omap_digest": "0xf5fba2c6",
1470 "expected_object_size": 0,
1471 "expected_write_size": 0,
1472 "alloc_hint_flags": 0,
1478 "union_shard_errors": [
1479 "data_digest_mismatch_info",
1480 "size_mismatch_info",
1481 "obj_size_info_mismatch"
1484 "data_digest_mismatch",
1498 "data_digest": "0x2ddbf8f5",
1499 "omap_digest": "0xa8dd5adc",
1502 "omap_digest_mismatch_info"
1508 "data_digest": "0x2ddbf8f5",
1509 "omap_digest": "0xa8dd5adc",
1512 "omap_digest_mismatch_info"
1518 "selected_object_info": {
1519 "alloc_hint_flags": 0,
1520 "data_digest": "0x2ddbf8f5",
1521 "expected_object_size": 0,
1522 "expected_write_size": 0,
1529 "last_reqid": "osd.0.0:50",
1530 "local_mtime": "2018-04-05 14:33:26.762368",
1535 "mtime": "2018-04-05 14:33:26.762368",
1545 "omap_digest": "0xc2025a24",
1546 "prior_version": "41'33",
1554 "union_shard_errors": [
1555 "omap_digest_mismatch_info"
1569 "data_digest": "0x2ddbf8f5",
1570 "omap_digest": "0xa03cef03",
1585 "selected_object_info": {
1596 "prior_version": "41'33",
1597 "last_reqid": "osd.1.0:51",
1600 "mtime": "2018-04-05 14:33:26.761286",
1601 "local_mtime": "2018-04-05 14:33:26.762368",
1611 "data_digest": "0x2ddbf8f5",
1612 "omap_digest": "0xa03cef03",
1613 "expected_object_size": 0,
1614 "expected_write_size": 0,
1615 "alloc_hint_flags": 0,
1621 "union_shard_errors": [
1643 "data_digest": "0x2ddbf8f5",
1644 "omap_digest": "0x067f306a",
1651 "selected_object_info": {
1662 "prior_version": "43'36",
1663 "last_reqid": "osd.1.0:55",
1666 "mtime": "2018-04-05 14:33:27.460958",
1667 "local_mtime": "2018-04-05 14:33:27.462109",
1677 "data_digest": "0x2ddbf8f5",
1678 "omap_digest": "0x067f306a",
1679 "expected_object_size": 0,
1680 "expected_write_size": 0,
1681 "alloc_hint_flags": 0,
1687 "union_shard_errors": [
1717 "union_shard_errors": [
1733 "object_info": "bad-val",
1734 "data_digest": "0x2ddbf8f5",
1735 "omap_digest": "0x4f14f849",
1744 "data_digest": "0x2ddbf8f5",
1745 "omap_digest": "0x4f14f849",
1754 "union_shard_errors": [
1781 "prior_version": "49'45",
1782 "last_reqid": "osd.1.0:48",
1785 "mtime": "2018-04-05 14:33:29.498969",
1786 "local_mtime": "2018-04-05 14:33:29.499890",
1796 "data_digest": "0x2ddbf8f5",
1797 "omap_digest": "0x2d2a4d6e",
1798 "expected_object_size": 0,
1799 "expected_write_size": 0,
1800 "alloc_hint_flags": 0,
1806 "data_digest": "0x2ddbf8f5",
1807 "omap_digest": "0x2d2a4d6e",
1814 "data_digest": "0x2ddbf8f5",
1815 "omap_digest": "0x2d2a4d6e",
1824 "selected_object_info": {
1835 "prior_version": "49'45",
1836 "last_reqid": "osd.1.0:48",
1839 "mtime": "2018-04-05 14:33:29.498969",
1840 "local_mtime": "2018-04-05 14:33:29.499890",
1850 "data_digest": "0x2ddbf8f5",
1851 "omap_digest": "0x2d2a4d6e",
1852 "expected_object_size": 0,
1853 "expected_write_size": 0,
1854 "alloc_hint_flags": 0,
1860 "union_shard_errors": [
1883 "data_digest": "0x2ddbf8f5",
1887 "omap_digest": "0x8b699207",
1893 "snapset": "bad-val",
1894 "data_digest": "0x2ddbf8f5",
1898 "omap_digest": "0x8b699207",
1904 "union_shard_errors": [
1912 "data_digest": "0x578a4830",
1913 "omap_digest": "0xf8e11918",
1916 "data_digest_mismatch_info"
1922 "data_digest": "0x2ddbf8f5",
1923 "omap_digest": "0xf8e11918",
1930 "selected_object_info": {
1941 "prior_version": "23'6",
1942 "last_reqid": "osd.1.0:59",
1945 "mtime": "2018-04-05 14:33:20.498756",
1946 "local_mtime": "2018-04-05 14:33:20.499704",
1956 "data_digest": "0x2ddbf8f5",
1957 "omap_digest": "0xf8e11918",
1958 "expected_object_size": 0,
1959 "expected_write_size": 0,
1960 "alloc_hint_flags": 0,
1966 "union_shard_errors": [
1967 "data_digest_mismatch_info"
1970 "data_digest_mismatch"
1983 "data_digest": "0x2ddbf8f5",
1984 "omap_digest": "0x00b35dfd",
1998 "selected_object_info": {
2009 "prior_version": "25'9",
2010 "last_reqid": "osd.1.0:60",
2013 "mtime": "2018-04-05 14:33:21.189382",
2014 "local_mtime": "2018-04-05 14:33:21.190446",
2024 "data_digest": "0x2ddbf8f5",
2025 "omap_digest": "0x00b35dfd",
2026 "expected_object_size": 0,
2027 "expected_write_size": 0,
2028 "alloc_hint_flags": 0,
2034 "union_shard_errors": [
2049 "data_digest": "0x2ddbf8f5",
2050 "omap_digest": "0xd7178dfe",
2053 "omap_digest_mismatch_info"
2059 "data_digest": "0x2ddbf8f5",
2060 "omap_digest": "0xe2d46ea4",
2067 "selected_object_info": {
2078 "prior_version": "27'12",
2079 "last_reqid": "osd.1.0:61",
2082 "mtime": "2018-04-05 14:33:21.862313",
2083 "local_mtime": "2018-04-05 14:33:21.863261",
2093 "data_digest": "0x2ddbf8f5",
2094 "omap_digest": "0xe2d46ea4",
2095 "expected_object_size": 0,
2096 "expected_write_size": 0,
2097 "alloc_hint_flags": 0,
2103 "union_shard_errors": [
2104 "omap_digest_mismatch_info"
2107 "omap_digest_mismatch"
2120 "data_digest": "0x2ddbf8f5",
2121 "omap_digest": "0x1a862a41",
2128 "data_digest": "0x2ddbf8f5",
2129 "omap_digest": "0x06cac8f6",
2132 "omap_digest_mismatch_info"
2138 "selected_object_info": {
2149 "prior_version": "29'15",
2150 "last_reqid": "osd.1.0:62",
2153 "mtime": "2018-04-05 14:33:22.589300",
2154 "local_mtime": "2018-04-05 14:33:22.590376",
2164 "data_digest": "0x2ddbf8f5",
2165 "omap_digest": "0x1a862a41",
2166 "expected_object_size": 0,
2167 "expected_write_size": 0,
2168 "alloc_hint_flags": 0,
2174 "union_shard_errors": [
2175 "omap_digest_mismatch_info"
2178 "omap_digest_mismatch"
2191 "data_digest": "0x2ddbf8f5",
2192 "omap_digest": "0x689ee887",
2195 "omap_digest_mismatch_info"
2201 "data_digest": "0x2ddbf8f5",
2202 "omap_digest": "0x179c919f",
2209 "selected_object_info": {
2220 "prior_version": "31'18",
2221 "last_reqid": "osd.1.0:53",
2224 "mtime": "2018-04-05 14:33:23.289188",
2225 "local_mtime": "2018-04-05 14:33:23.290130",
2235 "data_digest": "0x2ddbf8f5",
2236 "omap_digest": "0x179c919f",
2237 "expected_object_size": 0,
2238 "expected_write_size": 0,
2239 "alloc_hint_flags": 0,
2245 "union_shard_errors": [
2246 "omap_digest_mismatch_info"
2249 "omap_digest_mismatch"
2262 "data_digest": "0x2ddbf8f5",
2263 "omap_digest": "0xefced57a",
2270 "data_digest": "0x2ddbf8f5",
2271 "omap_digest": "0x6a73cc07",
2274 "omap_digest_mismatch_info"
2280 "selected_object_info": {
2291 "prior_version": "33'21",
2292 "last_reqid": "osd.1.0:52",
2295 "mtime": "2018-04-05 14:33:23.979658",
2296 "local_mtime": "2018-04-05 14:33:23.980731",
2306 "data_digest": "0x2ddbf8f5",
2307 "omap_digest": "0xefced57a",
2308 "expected_object_size": 0,
2309 "expected_write_size": 0,
2310 "alloc_hint_flags": 0,
2316 "union_shard_errors": [
2317 "omap_digest_mismatch_info"
2320 "omap_digest_mismatch"
2337 "name": "key1-ROBJ8"
2341 "value": "val2-ROBJ8",
2342 "name": "key2-ROBJ8"
2345 "data_digest": "0x2ddbf8f5",
2346 "omap_digest": "0xd6be81dc",
2356 "value": "val1-ROBJ8",
2357 "name": "key1-ROBJ8"
2361 "value": "val3-ROBJ8",
2362 "name": "key3-ROBJ8"
2365 "data_digest": "0x2ddbf8f5",
2366 "omap_digest": "0xd6be81dc",
2373 "selected_object_info": {
2384 "prior_version": "79'65",
2385 "last_reqid": "client.4554.0:1",
2388 "mtime": "2018-04-05 14:34:05.598688",
2389 "local_mtime": "2018-04-05 14:34:05.599698",
2399 "data_digest": "0x2ddbf8f5",
2400 "omap_digest": "0xd6be81dc",
2401 "expected_object_size": 0,
2402 "expected_write_size": 0,
2403 "alloc_hint_flags": 0,
2409 "union_shard_errors": [],
2411 "attr_value_mismatch",
2412 "attr_name_mismatch"
2436 "prior_version": "37'27",
2437 "last_reqid": "osd.1.0:63",
2440 "mtime": "2018-04-05 14:33:25.352485",
2441 "local_mtime": "2018-04-05 14:33:25.353746",
2451 "data_digest": "0x2ddbf8f5",
2452 "omap_digest": "0x2eecc539",
2453 "expected_object_size": 0,
2454 "expected_write_size": 0,
2455 "alloc_hint_flags": 0,
2461 "data_digest": "0x1f26fb26",
2462 "omap_digest": "0x2eecc539",
2465 "obj_size_info_mismatch"
2481 "version": "119'68",
2482 "prior_version": "51'64",
2483 "last_reqid": "client.4834.0:1",
2486 "mtime": "2018-04-05 14:35:01.500659",
2487 "local_mtime": "2018-04-05 14:35:01.502117",
2497 "data_digest": "0x1f26fb26",
2498 "omap_digest": "0x2eecc539",
2499 "expected_object_size": 0,
2500 "expected_write_size": 0,
2501 "alloc_hint_flags": 0,
2507 "data_digest": "0x1f26fb26",
2508 "omap_digest": "0x2eecc539",
2515 "selected_object_info": {
2525 "version": "119'68",
2526 "prior_version": "51'64",
2527 "last_reqid": "client.4834.0:1",
2530 "mtime": "2018-04-05 14:35:01.500659",
2531 "local_mtime": "2018-04-05 14:35:01.502117",
2541 "data_digest": "0x1f26fb26",
2542 "omap_digest": "0x2eecc539",
2543 "expected_object_size": 0,
2544 "expected_write_size": 0,
2545 "alloc_hint_flags": 0,
2551 "union_shard_errors": [
2552 "obj_size_info_mismatch"
2555 "object_info_inconsistency"
2570 jq
"$jqfilter" $dir/json | jq
'.inconsistents' | python
-c "$sortkeys" > $dir/csjson
2571 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
2572 if test $getjson = "yes"
2574 jq
'.' $dir/json
> save2.json
2577 if test "$LOCALRUN" = "yes" && which jsonschema
> /dev
/null
;
2579 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
2582 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
2583 teardown
$dir ||
return 1
2588 # Test scrub errors for an erasure coded pool
2590 function corrupt_scrub_erasure
() {
2592 local allow_overwrites
=$2
2593 local poolname
=ecpool
2596 setup
$dir ||
return 1
2597 run_mon
$dir a ||
return 1
2598 run_mgr
$dir x ||
return 1
2599 for id
in $
(seq 0 2) ; do
2600 if [ "$allow_overwrites" = "true" ]; then
2601 run_osd_bluestore
$dir $id ||
return 1
2603 run_osd
$dir $id ||
return 1
2606 create_rbd_pool ||
return 1
2609 create_ec_pool
$poolname $allow_overwrites k
=2 m
=1 stripe_unit
=2K
--force ||
return 1
2610 wait_for_clean ||
return 1
2612 for i
in $
(seq 1 $total_objs) ; do
2614 add_something
$dir $poolname $objname ||
return 1
2616 local osd
=$
(expr $i % 2)
2620 # Size (deep scrub data_digest too)
2621 local payload
=UVWXYZZZ
2622 echo $payload > $dir/CORRUPT
2623 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
2628 dd if=/dev
/urandom of
=$dir/CORRUPT bs
=2048 count
=1
2629 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
2634 objectstore_tool
$dir $osd $objname remove ||
return 1
2638 rados
--pool $poolname setxattr
$objname key1-
$objname val1-
$objname ||
return 1
2639 rados
--pool $poolname setxattr
$objname key2-
$objname val2-
$objname ||
return 1
2642 echo -n bad-val
> $dir/bad-val
2643 objectstore_tool
$dir $osd $objname set-attr _key1-
$objname $dir/bad-val ||
return 1
2644 objectstore_tool
$dir $osd $objname rm-attr _key2-
$objname ||
return 1
2645 echo -n val3-
$objname > $dir/newval
2646 objectstore_tool
$dir $osd $objname set-attr _key3-
$objname $dir/newval ||
return 1
2647 rm $dir/bad-val
$dir/newval
2652 dd if=/dev
/urandom of
=$dir/CORRUPT bs
=2048 count
=2
2653 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
2657 objectstore_tool
$dir 0 $objname rm-attr hinfo_key ||
return 1
2658 echo -n bad-val
> $dir/bad-val
2659 objectstore_tool
$dir 1 $objname set-attr hinfo_key
$dir/bad-val ||
return 1
2663 local payload
=MAKETHISDIFFERENTFROMOTHEROBJECTS
2664 echo $payload > $dir/DIFFERENT
2665 rados
--pool $poolname put
$objname $dir/DIFFERENT ||
return 1
2667 # Get hinfo_key from EOBJ1
2668 objectstore_tool
$dir 0 EOBJ1 get-attr hinfo_key
> $dir/hinfo
2669 objectstore_tool
$dir 0 $objname set-attr hinfo_key
$dir/hinfo ||
return 1
2676 local pg
=$
(get_pg
$poolname EOBJ0
)
2680 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
2682 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
2684 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
2686 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
2687 # Get epoch for repair-get requests
2688 epoch
=$
(jq .epoch
$dir/json
)
2690 jq
"$jqfilter" << EOF | jq '.inconsistents' | python -c "$sortkeys" > $dir/checkcsjson
2714 "prior_version": "0'0",
2715 "last_reqid": "client.4184.0:1",
2727 "data_digest": "0x2ddbf8f5",
2728 "omap_digest": "0xffffffff",
2729 "expected_object_size": 0,
2730 "expected_write_size": 0,
2731 "alloc_hint_flags": 0,
2740 "size_mismatch_info",
2741 "obj_size_info_mismatch"
2754 "selected_object_info": {
2765 "prior_version": "0'0",
2766 "last_reqid": "client.4184.0:1",
2778 "data_digest": "0x2ddbf8f5",
2779 "omap_digest": "0xffffffff",
2780 "expected_object_size": 0,
2781 "expected_write_size": 0,
2782 "alloc_hint_flags": 0,
2788 "union_shard_errors": [
2789 "size_mismatch_info",
2790 "obj_size_info_mismatch"
2828 "selected_object_info": {
2839 "prior_version": "0'0",
2840 "last_reqid": "client.4252.0:1",
2852 "data_digest": "0x2ddbf8f5",
2853 "omap_digest": "0xffffffff",
2854 "expected_object_size": 0,
2855 "expected_write_size": 0,
2856 "alloc_hint_flags": 0,
2862 "union_shard_errors": [
2881 "name": "key1-EOBJ4"
2885 "value": "val2-EOBJ4",
2886 "name": "key2-EOBJ4"
2904 "value": "val1-EOBJ4",
2905 "name": "key1-EOBJ4"
2909 "value": "val2-EOBJ4",
2910 "name": "key2-EOBJ4"
2923 "value": "val1-EOBJ4",
2924 "name": "key1-EOBJ4"
2928 "value": "val3-EOBJ4",
2929 "name": "key3-EOBJ4"
2934 "selected_object_info": {
2945 "prior_version": "45'5",
2946 "last_reqid": "client.4294.0:1",
2958 "data_digest": "0x2ddbf8f5",
2959 "omap_digest": "0xffffffff",
2960 "expected_object_size": 0,
2961 "expected_write_size": 0,
2962 "alloc_hint_flags": 0,
2968 "union_shard_errors": [],
2970 "attr_value_mismatch",
2971 "attr_name_mismatch"
3002 "prior_version": "0'0",
3003 "last_reqid": "client.4382.0:1",
3015 "data_digest": "0x2ddbf8f5",
3016 "omap_digest": "0xffffffff",
3017 "expected_object_size": 0,
3018 "expected_write_size": 0,
3019 "alloc_hint_flags": 0,
3028 "size_mismatch_info",
3029 "obj_size_info_mismatch"
3042 "selected_object_info": {
3053 "prior_version": "0'0",
3054 "last_reqid": "client.4382.0:1",
3066 "data_digest": "0x2ddbf8f5",
3067 "omap_digest": "0xffffffff",
3068 "expected_object_size": 0,
3069 "expected_write_size": 0,
3070 "alloc_hint_flags": 0,
3076 "union_shard_errors": [
3077 "size_mismatch_info",
3078 "obj_size_info_mismatch"
3100 "selected_object_info": {
3111 "prior_version": "0'0",
3112 "last_reqid": "client.4418.0:1",
3124 "data_digest": "0x2ddbf8f5",
3125 "omap_digest": "0xffffffff",
3126 "expected_object_size": 0,
3127 "expected_write_size": 0,
3128 "alloc_hint_flags": 0,
3151 "hashinfo": "bad-val",
3161 "cumulative_shard_hashes": [
3175 "total_chunk_size": 2048
3179 "union_shard_errors": [
3186 "hinfo_inconsistency"
3195 "selected_object_info": {
3206 "prior_version": "75'9",
3207 "last_reqid": "client.4482.0:1",
3219 "data_digest": "0x136e4e27",
3220 "omap_digest": "0xffffffff",
3221 "expected_object_size": 0,
3222 "expected_write_size": 0,
3223 "alloc_hint_flags": 0,
3232 "cumulative_shard_hashes": [
3246 "total_chunk_size": 2048
3256 "cumulative_shard_hashes": [
3270 "total_chunk_size": 2048
3280 "cumulative_shard_hashes": [
3294 "total_chunk_size": 2048
3303 "union_shard_errors": []
3310 jq
"$jqfilter" $dir/json | jq
'.inconsistents' | python
-c "$sortkeys" > $dir/csjson
3311 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
3312 if test $getjson = "yes"
3314 jq
'.' $dir/json
> save3.json
3317 if test "$LOCALRUN" = "yes" && which jsonschema
> /dev
/null
;
3319 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
3324 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
3326 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
3328 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
3330 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
3331 # Get epoch for repair-get requests
3332 epoch
=$
(jq .epoch
$dir/json
)
3334 if [ "$allow_overwrites" = "true" ]
3336 jq
"$jqfilter" << EOF | jq '.inconsistents' | python -c "$sortkeys" > $dir/checkcsjson
3342 "data_digest": "0x00000000",
3343 "omap_digest": "0xffffffff",
3362 "prior_version": "0'0",
3363 "last_reqid": "client.4184.0:1",
3366 "mtime": "2018-04-05 14:31:33.837147",
3367 "local_mtime": "2018-04-05 14:31:33.840763",
3375 "data_digest": "0x2ddbf8f5",
3376 "omap_digest": "0xffffffff",
3377 "expected_object_size": 0,
3378 "expected_write_size": 0,
3379 "alloc_hint_flags": 0,
3389 "size_mismatch_info",
3390 "obj_size_info_mismatch"
3396 "data_digest": "0x00000000",
3397 "omap_digest": "0xffffffff",
3405 "selected_object_info": {
3416 "prior_version": "0'0",
3417 "last_reqid": "client.4184.0:1",
3420 "mtime": "2018-04-05 14:31:33.837147",
3421 "local_mtime": "2018-04-05 14:31:33.840763",
3429 "data_digest": "0x2ddbf8f5",
3430 "omap_digest": "0xffffffff",
3431 "expected_object_size": 0,
3432 "expected_write_size": 0,
3433 "alloc_hint_flags": 0,
3439 "union_shard_errors": [
3441 "size_mismatch_info",
3442 "obj_size_info_mismatch"
3458 "data_digest": "0x00000000",
3459 "omap_digest": "0xffffffff",
3475 "data_digest": "0x00000000",
3476 "omap_digest": "0xffffffff",
3484 "selected_object_info": {
3495 "prior_version": "0'0",
3496 "last_reqid": "client.4252.0:1",
3499 "mtime": "2018-04-05 14:31:46.841145",
3500 "local_mtime": "2018-04-05 14:31:46.844996",
3508 "data_digest": "0x2ddbf8f5",
3509 "omap_digest": "0xffffffff",
3510 "expected_object_size": 0,
3511 "expected_write_size": 0,
3512 "alloc_hint_flags": 0,
3518 "union_shard_errors": [
3537 "name": "key1-EOBJ4"
3541 "value": "val2-EOBJ4",
3542 "name": "key2-EOBJ4"
3545 "data_digest": "0x00000000",
3546 "omap_digest": "0xffffffff",
3557 "value": "val1-EOBJ4",
3558 "name": "key1-EOBJ4"
3562 "value": "val2-EOBJ4",
3563 "name": "key2-EOBJ4"
3566 "data_digest": "0x00000000",
3567 "omap_digest": "0xffffffff",
3578 "value": "val1-EOBJ4",
3579 "name": "key1-EOBJ4"
3583 "value": "val3-EOBJ4",
3584 "name": "key3-EOBJ4"
3587 "data_digest": "0x00000000",
3588 "omap_digest": "0xffffffff",
3596 "selected_object_info": {
3607 "prior_version": "45'5",
3608 "last_reqid": "client.4294.0:1",
3611 "mtime": "2018-04-05 14:31:54.663622",
3612 "local_mtime": "2018-04-05 14:31:54.664527",
3620 "data_digest": "0x2ddbf8f5",
3621 "omap_digest": "0xffffffff",
3622 "expected_object_size": 0,
3623 "expected_write_size": 0,
3624 "alloc_hint_flags": 0,
3630 "union_shard_errors": [],
3632 "attr_value_mismatch",
3633 "attr_name_mismatch"
3646 "data_digest": "0x00000000",
3647 "omap_digest": "0xffffffff",
3655 "data_digest": "0x00000000",
3656 "omap_digest": "0xffffffff",
3668 "prior_version": "0'0",
3669 "last_reqid": "client.4382.0:1",
3672 "mtime": "2018-04-05 14:32:12.929161",
3673 "local_mtime": "2018-04-05 14:32:12.934707",
3681 "data_digest": "0x2ddbf8f5",
3682 "omap_digest": "0xffffffff",
3683 "expected_object_size": 0,
3684 "expected_write_size": 0,
3685 "alloc_hint_flags": 0,
3693 "size_mismatch_info",
3694 "obj_size_info_mismatch"
3701 "data_digest": "0x00000000",
3702 "omap_digest": "0xffffffff",
3710 "selected_object_info": {
3721 "prior_version": "0'0",
3722 "last_reqid": "client.4382.0:1",
3725 "mtime": "2018-04-05 14:32:12.929161",
3726 "local_mtime": "2018-04-05 14:32:12.934707",
3734 "data_digest": "0x2ddbf8f5",
3735 "omap_digest": "0xffffffff",
3736 "expected_object_size": 0,
3737 "expected_write_size": 0,
3738 "alloc_hint_flags": 0,
3744 "union_shard_errors": [
3745 "size_mismatch_info",
3746 "obj_size_info_mismatch"
3768 "union_shard_errors": [
3773 "selected_object_info": {
3784 "prior_version": "0'0",
3785 "last_reqid": "client.4418.0:1",
3788 "mtime": "2018-04-05 14:32:20.634116",
3789 "local_mtime": "2018-04-05 14:32:20.637999",
3797 "data_digest": "0x2ddbf8f5",
3798 "omap_digest": "0xffffffff",
3799 "expected_object_size": 0,
3800 "expected_write_size": 0,
3801 "alloc_hint_flags": 0,
3827 "hashinfo": "bad-val"
3835 "omap_digest": "0xffffffff",
3836 "data_digest": "0x00000000",
3838 "cumulative_shard_hashes": [
3852 "total_chunk_size": 2048
3866 "hinfo_inconsistency"
3868 "union_shard_errors": [],
3869 "selected_object_info": {
3880 "prior_version": "75'9",
3881 "last_reqid": "client.4482.0:1",
3884 "mtime": "2018-04-05 14:32:33.058782",
3885 "local_mtime": "2018-04-05 14:32:33.059679",
3893 "data_digest": "0x136e4e27",
3894 "omap_digest": "0xffffffff",
3895 "expected_object_size": 0,
3896 "expected_write_size": 0,
3897 "alloc_hint_flags": 0,
3910 "omap_digest": "0xffffffff",
3911 "data_digest": "0x00000000",
3913 "cumulative_shard_hashes": [
3927 "total_chunk_size": 2048
3936 "omap_digest": "0xffffffff",
3937 "data_digest": "0x00000000",
3939 "cumulative_shard_hashes": [
3953 "total_chunk_size": 2048
3962 "omap_digest": "0xffffffff",
3963 "data_digest": "0x00000000",
3965 "cumulative_shard_hashes": [
3979 "total_chunk_size": 2048
3991 jq
"$jqfilter" << EOF | jq '.inconsistents' | python -c "$sortkeys" > $dir/checkcsjson
3997 "data_digest": "0x04cfa72f",
3998 "omap_digest": "0xffffffff",
4017 "prior_version": "0'0",
4018 "last_reqid": "client.4192.0:1",
4021 "mtime": "2018-04-05 14:30:10.688009",
4022 "local_mtime": "2018-04-05 14:30:10.691774",
4030 "data_digest": "0x2ddbf8f5",
4031 "omap_digest": "0xffffffff",
4032 "expected_object_size": 0,
4033 "expected_write_size": 0,
4034 "alloc_hint_flags": 0,
4044 "size_mismatch_info",
4045 "obj_size_info_mismatch"
4051 "data_digest": "0x04cfa72f",
4052 "omap_digest": "0xffffffff",
4060 "selected_object_info": {
4071 "prior_version": "0'0",
4072 "last_reqid": "client.4192.0:1",
4075 "mtime": "2018-04-05 14:30:10.688009",
4076 "local_mtime": "2018-04-05 14:30:10.691774",
4084 "data_digest": "0x2ddbf8f5",
4085 "omap_digest": "0xffffffff",
4086 "expected_object_size": 0,
4087 "expected_write_size": 0,
4088 "alloc_hint_flags": 0,
4094 "union_shard_errors": [
4096 "size_mismatch_info",
4097 "obj_size_info_mismatch"
4122 "data_digest": "0x04cfa72f",
4123 "omap_digest": "0xffffffff",
4131 "data_digest": "0x04cfa72f",
4132 "omap_digest": "0xffffffff",
4140 "selected_object_info": {
4151 "prior_version": "0'0",
4152 "last_reqid": "client.4224.0:1",
4155 "mtime": "2018-04-05 14:30:14.152945",
4156 "local_mtime": "2018-04-05 14:30:14.154014",
4164 "data_digest": "0x2ddbf8f5",
4165 "omap_digest": "0xffffffff",
4166 "expected_object_size": 0,
4167 "expected_write_size": 0,
4168 "alloc_hint_flags": 0,
4174 "union_shard_errors": [
4189 "data_digest": "0x04cfa72f",
4190 "omap_digest": "0xffffffff",
4206 "data_digest": "0x04cfa72f",
4207 "omap_digest": "0xffffffff",
4215 "selected_object_info": {
4226 "prior_version": "0'0",
4227 "last_reqid": "client.4258.0:1",
4230 "mtime": "2018-04-05 14:30:18.875544",
4231 "local_mtime": "2018-04-05 14:30:18.880153",
4239 "data_digest": "0x2ddbf8f5",
4240 "omap_digest": "0xffffffff",
4241 "expected_object_size": 0,
4242 "expected_write_size": 0,
4243 "alloc_hint_flags": 0,
4249 "union_shard_errors": [
4268 "name": "key1-EOBJ4"
4272 "value": "val2-EOBJ4",
4273 "name": "key2-EOBJ4"
4276 "data_digest": "0x04cfa72f",
4277 "omap_digest": "0xffffffff",
4290 "omap_digest": "0xffffffff",
4291 "data_digest": "0x04cfa72f",
4295 "value": "val1-EOBJ4",
4296 "name": "key1-EOBJ4"
4300 "value": "val2-EOBJ4",
4301 "name": "key2-EOBJ4"
4311 "omap_digest": "0xffffffff",
4312 "data_digest": "0x04cfa72f",
4316 "value": "val1-EOBJ4",
4317 "name": "key1-EOBJ4"
4321 "value": "val3-EOBJ4",
4322 "name": "key3-EOBJ4"
4327 "selected_object_info": {
4338 "prior_version": "45'5",
4339 "last_reqid": "client.4296.0:1",
4342 "mtime": "2018-04-05 14:30:22.271983",
4343 "local_mtime": "2018-04-05 14:30:22.272840",
4351 "data_digest": "0x2ddbf8f5",
4352 "omap_digest": "0xffffffff",
4353 "expected_object_size": 0,
4354 "expected_write_size": 0,
4355 "alloc_hint_flags": 0,
4361 "union_shard_errors": [],
4363 "attr_value_mismatch",
4364 "attr_name_mismatch"
4377 "data_digest": "0x04cfa72f",
4378 "omap_digest": "0xffffffff",
4397 "prior_version": "0'0",
4398 "last_reqid": "client.4384.0:1",
4401 "mtime": "2018-04-05 14:30:35.162395",
4402 "local_mtime": "2018-04-05 14:30:35.166390",
4410 "data_digest": "0x2ddbf8f5",
4411 "omap_digest": "0xffffffff",
4412 "expected_object_size": 0,
4413 "expected_write_size": 0,
4414 "alloc_hint_flags": 0,
4423 "size_mismatch_info",
4425 "obj_size_info_mismatch"
4431 "data_digest": "0x04cfa72f",
4432 "omap_digest": "0xffffffff",
4440 "selected_object_info": {
4451 "prior_version": "0'0",
4452 "last_reqid": "client.4384.0:1",
4455 "mtime": "2018-04-05 14:30:35.162395",
4456 "local_mtime": "2018-04-05 14:30:35.166390",
4464 "data_digest": "0x2ddbf8f5",
4465 "omap_digest": "0xffffffff",
4466 "expected_object_size": 0,
4467 "expected_write_size": 0,
4468 "alloc_hint_flags": 0,
4474 "union_shard_errors": [
4475 "size_mismatch_info",
4477 "obj_size_info_mismatch"
4499 "union_shard_errors": [
4504 "selected_object_info": {
4515 "prior_version": "0'0",
4516 "last_reqid": "client.4420.0:1",
4519 "mtime": "2018-04-05 14:30:40.914673",
4520 "local_mtime": "2018-04-05 14:30:40.917705",
4528 "data_digest": "0x2ddbf8f5",
4529 "omap_digest": "0xffffffff",
4530 "expected_object_size": 0,
4531 "expected_write_size": 0,
4532 "alloc_hint_flags": 0,
4558 "hashinfo": "bad-val"
4566 "omap_digest": "0xffffffff",
4567 "data_digest": "0x04cfa72f",
4569 "cumulative_shard_hashes": [
4583 "total_chunk_size": 2048
4597 "hinfo_inconsistency"
4599 "union_shard_errors": [
4602 "selected_object_info": {
4613 "prior_version": "75'9",
4614 "last_reqid": "client.4486.0:1",
4617 "mtime": "2018-04-05 14:30:50.995009",
4618 "local_mtime": "2018-04-05 14:30:50.996112",
4626 "data_digest": "0x136e4e27",
4627 "omap_digest": "0xffffffff",
4628 "expected_object_size": 0,
4629 "expected_write_size": 0,
4630 "alloc_hint_flags": 0,
4646 "cumulative_shard_hashes": [
4660 "total_chunk_size": 2048
4669 "omap_digest": "0xffffffff",
4670 "data_digest": "0x5b7455a8",
4672 "cumulative_shard_hashes": [
4686 "total_chunk_size": 2048
4695 "omap_digest": "0xffffffff",
4696 "data_digest": "0x5b7455a8",
4698 "cumulative_shard_hashes": [
4712 "total_chunk_size": 2048
4724 jq
"$jqfilter" $dir/json | jq
'.inconsistents' | python
-c "$sortkeys" > $dir/csjson
4725 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
4726 if test $getjson = "yes"
4728 if [ "$allow_overwrites" = "true" ]
4734 jq
'.' $dir/json
> save
${num}.json
4737 if test "$LOCALRUN" = "yes" && which jsonschema
> /dev
/null
;
4739 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
4742 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
4743 teardown
$dir ||
return 1
4746 function TEST_corrupt_scrub_erasure_appends
() {
4747 corrupt_scrub_erasure
$1 false
4750 function TEST_corrupt_scrub_erasure_overwrites
() {
4751 if [ "$use_ec_overwrite" = "true" ]; then
4752 corrupt_scrub_erasure
$1 true
4757 # Test to make sure that a periodic scrub won't cause deep-scrub info to be lost
4759 function TEST_periodic_scrub_replicated
() {
4761 local poolname
=psr_pool
4764 setup
$dir ||
return 1
4765 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
4766 run_mgr
$dir x ||
return 1
4767 local ceph_osd_args
="--osd-scrub-interval-randomize-ratio=0 --osd-deep-scrub-randomize-ratio=0 "
4768 ceph_osd_args
+="--osd_scrub_backoff_ratio=0"
4769 run_osd
$dir 0 $ceph_osd_args ||
return 1
4770 run_osd
$dir 1 $ceph_osd_args ||
return 1
4771 create_rbd_pool ||
return 1
4772 wait_for_clean ||
return 1
4774 create_pool
$poolname 1 1 ||
return 1
4775 wait_for_clean ||
return 1
4778 add_something
$dir $poolname $objname scrub ||
return 1
4779 local primary
=$
(get_primary
$poolname $objname)
4780 local pg
=$
(get_pg
$poolname $objname)
4782 # Add deep-scrub only error
4783 local payload
=UVWXYZ
4784 echo $payload > $dir/CORRUPT
4785 # Uses $ceph_osd_args for osd restart
4786 objectstore_tool
$dir $osd $objname set-bytes
$dir/CORRUPT ||
return 1
4788 # No scrub information available, so expect failure
4790 ! rados list-inconsistent-obj
$pg | jq
'.' ||
return 1
4793 pg_deep_scrub
$pg ||
return 1
4795 # Make sure bad object found
4796 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
4799 local last_scrub
=$
(get_last_scrub_stamp
$pg)
4800 # Fake a schedule scrub
4801 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd.
${primary}) \
4802 trigger_scrub
$pg ||
return 1
4803 # Wait for schedule regular scrub
4804 wait_for_scrub
$pg "$last_scrub"
4806 # It needed to be upgraded
4807 grep -q "Deep scrub errors, upgrading scrub to deep-scrub" $dir/osd.
${primary}.log ||
return 1
4809 # Bad object still known
4810 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
4812 # Can't upgrade with this set
4813 ceph osd
set nodeep-scrub
4814 # Let map change propagate to OSDs
4818 # Fake a schedule scrub
4819 CEPH_ARGS
='' ceph
--admin-daemon $
(get_asok_path osd.
${primary}) \
4820 trigger_scrub
$pg ||
return 1
4821 # Wait for schedule regular scrub
4822 # to notice scrub and skip it
4824 for i
in $
(seq 14 -1 0)
4827 ! grep -q "Regular scrub skipped due to deep-scrub errors and nodeep-scrub set" $dir/osd.
${primary}.log ||
{ found
=true
; break; }
4828 echo Time left
: $i seconds
4830 test $found = "true" ||
return 1
4832 # Bad object still known
4833 rados list-inconsistent-obj
$pg | jq
'.' |
grep -q $objname ||
return 1
4836 # Request a regular scrub and it will be done
4838 grep -q "Regular scrub request, deep-scrub details will be lost" $dir/osd.
${primary}.log ||
return 1
4840 # deep-scrub error is no longer present
4841 rados list-inconsistent-obj
$pg | jq
'.' |
grep -qv $objname ||
return 1
4845 # Corrupt snapset in replicated pool
4847 function TEST_corrupt_snapset_scrub_rep
() {
4849 local poolname
=csr_pool
4852 setup
$dir ||
return 1
4853 run_mon
$dir a
--osd_pool_default_size=2 ||
return 1
4854 run_mgr
$dir x ||
return 1
4855 run_osd
$dir 0 ||
return 1
4856 run_osd
$dir 1 ||
return 1
4857 create_rbd_pool ||
return 1
4858 wait_for_clean ||
return 1
4860 create_pool foo
1 ||
return 1
4861 create_pool
$poolname 1 1 ||
return 1
4862 wait_for_clean ||
return 1
4864 for i
in $
(seq 1 $total_objs) ; do
4866 add_something
$dir $poolname $objname ||
return 1
4868 rados
--pool $poolname setomapheader
$objname hdr-
$objname ||
return 1
4869 rados
--pool $poolname setomapval
$objname key-
$objname val-
$objname ||
return 1
4872 local pg
=$
(get_pg
$poolname ROBJ0
)
4874 for i
in $
(seq 1 $total_objs) ; do
4877 # Alternate corruption between osd.0 and osd.1
4878 local osd
=$
(expr $i % 2)
4880 rados
-p $poolname mksnap snap1
4881 echo -n head_of_snapshot_data
> $dir/change
4885 rados
--pool $poolname put
$objname $dir/change
4886 objectstore_tool
$dir $osd --head $objname clear-snapset corrupt ||
return 1
4890 rados
--pool $poolname put
$objname $dir/change
4891 objectstore_tool
$dir $osd --head $objname clear-snapset corrupt ||
return 1
4900 rados list-inconsistent-pg
$poolname > $dir/json ||
return 1
4902 test $
(jq
'. | length' $dir/json
) = "1" ||
return 1
4904 test $
(jq
-r '.[0]' $dir/json
) = $pg ||
return 1
4906 rados list-inconsistent-obj
$pg > $dir/json ||
return 1
4908 jq
"$jqfilter" << EOF | jq '.inconsistents' | python -c "$sortkeys" > $dir/checkcsjson
4921 "snapset_inconsistency"
4923 "union_shard_errors": [],
4924 "selected_object_info": {
4935 "prior_version": "21'3",
4936 "last_reqid": "client.4195.0:1",
4939 "mtime": "2018-04-05 14:35:43.286117",
4940 "local_mtime": "2018-04-05 14:35:43.288990",
4949 "data_digest": "0x53acb008",
4950 "omap_digest": "0xffffffff",
4951 "expected_object_size": 0,
4952 "expected_write_size": 0,
4953 "alloc_hint_flags": 0,
5010 "snapset_inconsistency"
5012 "union_shard_errors": [],
5013 "selected_object_info": {
5024 "prior_version": "23'6",
5025 "last_reqid": "client.4223.0:1",
5028 "mtime": "2018-04-05 14:35:48.326856",
5029 "local_mtime": "2018-04-05 14:35:48.328097",
5038 "data_digest": "0x53acb008",
5039 "omap_digest": "0xffffffff",
5040 "expected_object_size": 0,
5041 "expected_write_size": 0,
5042 "alloc_hint_flags": 0,
5094 jq
"$jqfilter" $dir/json | jq
'.inconsistents' | python
-c "$sortkeys" > $dir/csjson
5095 diff ${DIFFCOLOPTS} $dir/checkcsjson
$dir/csjson ||
test $getjson = "yes" ||
return 1
5096 if test $getjson = "yes"
5098 jq
'.' $dir/json
> save6.json
5101 if test "$LOCALRUN" = "yes" && which jsonschema
> /dev
/null
;
5103 jsonschema
-i $dir/json
$CEPH_ROOT/doc
/rados
/command
/list-inconsistent-obj.json ||
return 1
5106 rados rmpool
$poolname $poolname --yes-i-really-really-mean-it
5107 teardown
$dir ||
return 1
5110 main osd-scrub-repair
"$@"
5113 # compile-command: "cd build ; make -j4 && \
5114 # ../qa/run-standalone.sh osd-scrub-repair.sh"