2017-07-20 22:26:42 +00:00
#!/usr/bin/env bash
2015-10-29 04:34:44 +00:00
#
# Copyright (C) 2015 Red Hat <contact@redhat.com>
#
# Author: David Zafman <dzafman@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library Public License for more details.
#
2017-07-21 02:54:48 +00:00
source $CEPH_ROOT /qa/standalone/ceph-helpers.sh
2015-10-29 04:34:44 +00:00
2018-04-04 23:04:41 +00:00
# Test development and debugging
# Set to "yes" in order to ignore diff errors and save results to update test
getjson = "no"
2015-10-29 04:34:44 +00:00
function run( ) {
local dir = $1
shift
export CEPH_MON = "127.0.0.1:7121" # git grep '\<7121\>' : there must be only one
export CEPH_ARGS
CEPH_ARGS += " --fsid= $( uuidgen) --auth-supported=none "
CEPH_ARGS += " --mon-host= $CEPH_MON "
local funcs = ${ @ :- $( set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p' ) }
for func in $funcs ; do
2018-03-20 23:07:49 +00:00
setup $dir || return 1
2015-10-29 04:34:44 +00:00
$func $dir || return 1
2018-03-20 23:07:49 +00:00
teardown $dir || return 1
2015-10-29 04:34:44 +00:00
done
}
function TEST_scrub_snaps( ) {
local dir = $1
local poolname = test
2018-03-20 23:07:49 +00:00
local OBJS = 15
local OSDS = 1
2015-10-29 04:34:44 +00:00
TESTDATA = " testdata. $$ "
2018-03-20 23:07:49 +00:00
run_mon $dir a --osd_pool_default_size= $OSDS || return 1
2017-03-06 23:47:11 +00:00
run_mgr $dir x || return 1
2018-03-20 23:07:49 +00:00
for osd in $( seq 0 $( expr $OSDS - 1) )
do
run_osd $dir $osd || return 1
done
2015-09-30 02:57:43 +00:00
2015-10-29 04:34:44 +00:00
# Create a pool with a single pg
2017-07-31 23:17:16 +00:00
create_pool $poolname 1 1
wait_for_clean || return 1
2015-10-29 04:34:44 +00:00
poolid = $( ceph osd dump | grep "^pool.*[']test[']" | awk '{ print $2 }' )
2015-09-30 02:57:43 +00:00
2015-10-29 04:34:44 +00:00
dd if = /dev/urandom of = $TESTDATA bs = 1032 count = 1
2018-03-20 23:07:49 +00:00
for i in ` seq 1 $OBJS `
2015-09-30 02:57:43 +00:00
do
2015-10-29 04:34:44 +00:00
rados -p $poolname put obj${ i } $TESTDATA
done
2018-03-20 23:07:49 +00:00
local primary = $( get_primary $poolname obj1)
2015-10-29 04:34:44 +00:00
SNAP = 1
rados -p $poolname mksnap snap${ SNAP }
dd if = /dev/urandom of = $TESTDATA bs = 256 count = ${ SNAP }
rados -p $poolname put obj1 $TESTDATA
rados -p $poolname put obj5 $TESTDATA
rados -p $poolname put obj3 $TESTDATA
for i in ` seq 6 14`
do rados -p $poolname put obj${ i } $TESTDATA
done
SNAP = 2
rados -p $poolname mksnap snap${ SNAP }
dd if = /dev/urandom of = $TESTDATA bs = 256 count = ${ SNAP }
rados -p $poolname put obj5 $TESTDATA
SNAP = 3
rados -p $poolname mksnap snap${ SNAP }
dd if = /dev/urandom of = $TESTDATA bs = 256 count = ${ SNAP }
rados -p $poolname put obj3 $TESTDATA
SNAP = 4
rados -p $poolname mksnap snap${ SNAP }
dd if = /dev/urandom of = $TESTDATA bs = 256 count = ${ SNAP }
rados -p $poolname put obj5 $TESTDATA
rados -p $poolname put obj2 $TESTDATA
SNAP = 5
rados -p $poolname mksnap snap${ SNAP }
SNAP = 6
rados -p $poolname mksnap snap${ SNAP }
dd if = /dev/urandom of = $TESTDATA bs = 256 count = ${ SNAP }
rados -p $poolname put obj5 $TESTDATA
SNAP = 7
rados -p $poolname mksnap snap${ SNAP }
rados -p $poolname rm obj4
rados -p $poolname rm obj2
2015-12-10 07:36:33 +00:00
kill_daemons $dir TERM osd || return 1
2015-10-29 04:34:44 +00:00
2018-03-20 23:07:49 +00:00
# Don't need to use ceph_objectstore_tool() function because osd stopped
2015-10-29 04:34:44 +00:00
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj1) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " --force remove
2015-10-29 04:34:44 +00:00
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --op list obj5 | grep \" snapid\" :2) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " remove
2015-10-29 04:34:44 +00:00
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --op list obj5 | grep \" snapid\" :1) "
2015-10-29 04:34:44 +00:00
OBJ5SAVE = " $JSON "
2018-03-20 23:07:49 +00:00
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " remove
2015-10-29 04:34:44 +00:00
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --op list obj5 | grep \" snapid\" :4) "
2015-10-29 04:34:44 +00:00
dd if = /dev/urandom of = $TESTDATA bs = 256 count = 18
2018-03-20 23:07:49 +00:00
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " set-bytes $TESTDATA
2015-10-29 04:34:44 +00:00
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj3) "
2015-10-29 04:34:44 +00:00
dd if = /dev/urandom of = $TESTDATA bs = 256 count = 15
2018-03-20 23:07:49 +00:00
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " set-bytes $TESTDATA
2015-10-29 04:34:44 +00:00
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --op list obj4 | grep \" snapid\" :7) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " remove
2015-10-29 04:34:44 +00:00
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj2) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " rm-attr snapset
2015-10-29 04:34:44 +00:00
# Create a clone which isn't in snapset and doesn't have object info
JSON = " $( echo " $OBJ5SAVE " | sed s/snapid\" :1/snapid\" :7/) "
dd if = /dev/urandom of = $TESTDATA bs = 256 count = 7
2018-03-20 23:07:49 +00:00
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " set-bytes $TESTDATA
2015-10-29 04:34:44 +00:00
rm -f $TESTDATA
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj6) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj7) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset corrupt
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj8) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset seq
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj9) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset clone_size
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj10) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset clone_overlap
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj11) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset clones
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj12) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset head
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj13) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset snaps
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj14) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " clear-snapset size
2015-10-29 04:34:44 +00:00
2016-08-24 17:21:38 +00:00
echo "garbage" > $dir /bad
2018-03-20 23:07:49 +00:00
JSON = " $( ceph-objectstore-tool --data-path $dir /${ primary } --head --op list obj15) "
ceph-objectstore-tool --data-path $dir /${ primary } " $JSON " set-attr snapset $dir /bad
2016-08-24 17:21:38 +00:00
rm -f $dir /bad
2018-03-20 23:07:49 +00:00
for osd in $( seq 0 $( expr $OSDS - 1) )
do
run_osd $dir $osd || return 1
done
2015-10-29 04:34:44 +00:00
2015-11-25 12:19:54 +00:00
local pgid = " ${ poolid } .0 "
2015-12-08 12:54:58 +00:00
if ! pg_scrub " $pgid " ; then
cat $dir /osd.0.log
return 1
fi
2015-11-25 12:19:54 +00:00
grep 'log_channel' $dir /osd.0.log
2015-10-29 04:34:44 +00:00
2016-05-03 19:10:38 +00:00
rados list-inconsistent-pg $poolname > $dir /json || return 1
# Check pg count
test $( jq '. | length' $dir /json) = "1" || return 1
# Check pgid
test $( jq -r '.[0]' $dir /json) = $pgid || return 1
rados list-inconsistent-snapset $pgid > $dir /json || return 1
2016-07-03 06:11:10 +00:00
local jqfilter = '.inconsistents'
local sortkeys = 'import json; import sys ; JSON=sys.stdin.read() ; ud = json.loads(JSON) ; print json.dumps(ud, sort_keys=True, indent=2)'
jq " $jqfilter " << EOF | python -c " $sortkeys " > $dir /checkcsjson
{
"inconsistents" : [
{
"errors" : [
"headless"
] ,
"snap" : 1,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj1"
} ,
{
"errors" : [
"size_mismatch"
] ,
"snap" : 1,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj10"
} ,
{
"errors" : [
"headless"
] ,
"snap" : 1,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj11"
} ,
{
"errors" : [
"size_mismatch"
] ,
"snap" : 1,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj14"
} ,
{
"errors" : [
"headless"
] ,
"snap" : 1,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj6"
} ,
{
"errors" : [
"headless"
] ,
"snap" : 1,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj7"
} ,
{
"errors" : [
"size_mismatch"
] ,
"snap" : 1,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj9"
} ,
{
"errors" : [
"headless"
] ,
"snap" : 4,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj2"
} ,
{
"errors" : [
"size_mismatch"
] ,
"snap" : 4,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj5"
} ,
{
"errors" : [
"headless"
] ,
"snap" : 7,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj2"
} ,
{
"errors" : [
2018-03-16 00:09:43 +00:00
"info_missing" ,
2016-07-03 06:11:10 +00:00
"headless"
] ,
"snap" : 7,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj5"
} ,
{
"extra clones" : [
1
] ,
"errors" : [
"extra_clones"
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj11"
} ,
2016-08-24 17:21:38 +00:00
{
"errors" : [
2018-03-15 21:29:54 +00:00
"snapset_corrupted"
2016-08-24 17:21:38 +00:00
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj15"
} ,
2017-02-28 00:57:26 +00:00
{
"extra clones" : [
7,
4
] ,
"errors" : [
2018-03-15 21:29:54 +00:00
"snapset_missing" ,
2017-02-28 00:57:26 +00:00
"extra_clones"
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj2"
} ,
2016-07-03 06:11:10 +00:00
{
"errors" : [
"size_mismatch"
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj3"
} ,
2017-02-28 00:57:26 +00:00
{
"missing" : [
7
] ,
"errors" : [
"clone_missing"
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj4"
} ,
2016-07-03 06:11:10 +00:00
{
"missing" : [
2,
1
] ,
"extra clones" : [
7
] ,
"errors" : [
"extra_clones" ,
"clone_missing"
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj5"
} ,
{
"extra clones" : [
1
] ,
"errors" : [
"extra_clones"
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj6"
} ,
{
"extra clones" : [
1
] ,
"errors" : [
"extra_clones"
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj7"
} ,
{
"errors" : [
2018-04-04 22:58:57 +00:00
"snapset_error"
2016-07-03 06:11:10 +00:00
] ,
"snap" : "head" ,
"locator" : "" ,
"nspace" : "" ,
"name" : "obj8"
}
] ,
"epoch" : 20
}
2016-05-03 19:10:38 +00:00
EOF
2016-07-03 06:11:10 +00:00
jq " $jqfilter " $dir /json | python -c " $sortkeys " > $dir /csjson
2018-04-04 23:04:41 +00:00
diff ${ DIFFCOLOPTS } $dir /checkcsjson $dir /csjson || test $getjson = "yes" || return 1
if test $getjson = "yes"
then
jq '.' $dir /json > save1.json
fi
2016-05-03 19:10:38 +00:00
2016-08-30 19:11:44 +00:00
if which jsonschema > /dev/null;
then
jsonschema -i $dir /json $CEPH_ROOT /doc/rados/command/list-inconsistent-snap.json || return 1
fi
2015-10-29 04:34:44 +00:00
for i in ` seq 1 7`
do
rados -p $poolname rmsnap snap$i
2015-09-30 02:57:43 +00:00
done
2015-10-29 04:34:44 +00:00
ERRORS = 0
pidfile = $( find $dir 2>/dev/null | grep $name_prefix '[^/]*\.pid' )
pid = $( cat $pidfile )
if ! kill -0 $pid
2015-09-30 02:57:43 +00:00
then
2015-10-29 04:34:44 +00:00
echo "OSD crash occurred"
tail -100 $dir /osd.0.log
2015-09-30 02:57:43 +00:00
ERRORS = $( expr $ERRORS + 1)
fi
2015-10-29 04:34:44 +00:00
kill_daemons $dir || return 1
declare -a err_strings
2016-01-05 20:00:12 +00:00
err_strings[ 0] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*::obj10:.* is missing in clone_overlap"
err_strings[ 1] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*::obj5:7 no '_' attr"
err_strings[ 2] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*::obj5:7 is an unexpected clone"
err_strings[ 3] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*::obj5:4 on disk size [(]4608[)] does not match object info size [(]512[)] adjusted for ondisk to [(]512[)]"
err_strings[ 4] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj5:head expected clone .*:::obj5:2"
err_strings[ 5] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj5:head expected clone .*:::obj5:1"
err_strings[ 6] = "log_channel[(]cluster[)] log [[]INF[]] : scrub [0-9]*[.]0 .*:::obj5:head 2 missing clone[(]s[)]"
2017-09-22 21:49:19 +00:00
err_strings[ 7] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj8:head snaps.seq not set"
err_strings[ 8] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj7:1 is an unexpected clone"
err_strings[ 9] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj3:head on disk size [(]3840[)] does not match object info size [(]768[)] adjusted for ondisk to [(]768[)]"
err_strings[ 10] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj6:1 is an unexpected clone"
err_strings[ 11] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj2:head no 'snapset' attr"
err_strings[ 12] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj2:7 clone ignored due to missing snapset"
err_strings[ 13] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj2:4 clone ignored due to missing snapset"
err_strings[ 14] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj4:head expected clone .*:::obj4:7"
err_strings[ 15] = "log_channel[(]cluster[)] log [[]INF[]] : scrub [0-9]*[.]0 .*:::obj4:head 1 missing clone[(]s[)]"
err_strings[ 16] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj1:1 is an unexpected clone"
err_strings[ 17] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj9:1 is missing in clone_size"
err_strings[ 18] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj11:1 is an unexpected clone"
err_strings[ 19] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj14:1 size 1032 != clone_size 1033"
err_strings[ 20] = "log_channel[(]cluster[)] log [[]ERR[]] : [0-9]*[.]0 scrub 20 errors"
err_strings[ 21] = "log_channel[(]cluster[)] log [[]ERR[]] : scrub [0-9]*[.]0 .*:::obj15:head can't decode 'snapset' attr buffer"
2015-10-29 04:34:44 +00:00
2017-08-15 21:46:40 +00:00
for err_string in " ${ err_strings [@] } "
2015-10-29 04:34:44 +00:00
do
2018-03-20 23:07:49 +00:00
if ! grep " $err_string " $dir /osd.${ primary } .log > /dev/null;
2015-10-29 04:34:44 +00:00
then
2017-08-15 21:46:40 +00:00
echo " Missing log message ' $err_string ' "
2015-10-29 04:34:44 +00:00
ERRORS = $( expr $ERRORS + 1)
fi
done
if [ $ERRORS != "0" ] ;
then
echo " TEST FAILED WITH $ERRORS ERRORS "
return 1
fi
echo "TEST PASSED"
return 0
}
main osd-scrub-snaps " $@ "
2015-09-30 02:57:43 +00:00
2015-10-29 04:34:44 +00:00
# Local Variables:
# compile-command: "cd ../.. ; make -j4 && \
# test/osd/osd-scrub-snaps.sh"