ceph/qa/workunits/rbd/cli_generic.sh

1717 lines
60 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
set -ex
. $(dirname $0)/../../standalone/ceph-helpers.sh
export RBD_FORCE_ALLOW_V1=1
# make sure rbd pool is EMPTY.. this is a test script!!
rbd ls | wc -l | grep -v '^0$' && echo "nonempty rbd pool, aborting! run this script on an empty test cluster only." && exit 1
IMGS="testimg1 testimg2 testimg3 testimg4 testimg5 testimg6 testimg-diff1 testimg-diff2 testimg-diff3 foo foo2 bar bar2 test1 test2 test3 test4 clone2"
expect_fail() {
"$@" && return 1 || return 0
}
tiered=0
if ceph osd dump | grep ^pool | grep "'rbd'" | grep tier; then
tiered=1
fi
remove_images() {
for img in $IMGS
do
(rbd snap purge $img || true) >/dev/null 2>&1
(rbd rm $img || true) >/dev/null 2>&1
done
}
test_others() {
echo "testing import, export, resize, and snapshots..."
TMP_FILES="/tmp/img1 /tmp/img1.new /tmp/img2 /tmp/img2.new /tmp/img3 /tmp/img3.new /tmp/img-diff1.new /tmp/img-diff2.new /tmp/img-diff3.new /tmp/img1.snap1 /tmp/img1.snap1 /tmp/img-diff1.snap1"
remove_images
rm -f $TMP_FILES
# create an image
dd if=/bin/sh of=/tmp/img1 bs=1k count=1 seek=10
dd if=/bin/dd of=/tmp/img1 bs=1k count=10 seek=100
dd if=/bin/rm of=/tmp/img1 bs=1k count=100 seek=1000
dd if=/bin/ls of=/tmp/img1 bs=1k seek=10000
dd if=/bin/ln of=/tmp/img1 bs=1k seek=100000
# import, snapshot
rbd import $RBD_CREATE_ARGS /tmp/img1 testimg1
rbd resize testimg1 --size=256 --allow-shrink
rbd export testimg1 /tmp/img2
rbd snap create testimg1 --snap=snap1
rbd resize testimg1 --size=128 && exit 1 || true # shrink should fail
rbd resize testimg1 --size=128 --allow-shrink
rbd export testimg1 /tmp/img3
# info
rbd info testimg1 | grep 'size 128 MiB'
rbd info --snap=snap1 testimg1 | grep 'size 256 MiB'
# export-diff
rm -rf /tmp/diff-testimg1-1 /tmp/diff-testimg1-2
rbd export-diff testimg1 --snap=snap1 /tmp/diff-testimg1-1
rbd export-diff testimg1 --from-snap=snap1 /tmp/diff-testimg1-2
# import-diff
rbd create $RBD_CREATE_ARGS --size=1 testimg-diff1
rbd import-diff --sparse-size 8K /tmp/diff-testimg1-1 testimg-diff1
rbd import-diff --sparse-size 8K /tmp/diff-testimg1-2 testimg-diff1
# info
rbd info testimg1 | grep 'size 128 MiB'
rbd info --snap=snap1 testimg1 | grep 'size 256 MiB'
rbd info testimg-diff1 | grep 'size 128 MiB'
rbd info --snap=snap1 testimg-diff1 | grep 'size 256 MiB'
# make copies
rbd copy testimg1 --snap=snap1 testimg2
rbd copy testimg1 testimg3
rbd copy testimg-diff1 --sparse-size 768K --snap=snap1 testimg-diff2
rbd copy testimg-diff1 --sparse-size 768K testimg-diff3
# verify the result
rbd info testimg2 | grep 'size 256 MiB'
rbd info testimg3 | grep 'size 128 MiB'
rbd info testimg-diff2 | grep 'size 256 MiB'
rbd info testimg-diff3 | grep 'size 128 MiB'
# deep copies
rbd deep copy testimg1 testimg4
rbd deep copy testimg1 --snap=snap1 testimg5
rbd info testimg4 | grep 'size 128 MiB'
rbd info testimg5 | grep 'size 256 MiB'
rbd snap ls testimg4 | grep -v 'SNAPID' | wc -l | grep 1
rbd snap ls testimg4 | grep '.*snap1.*'
rbd export testimg1 /tmp/img1.new
rbd export testimg2 /tmp/img2.new
rbd export testimg3 /tmp/img3.new
rbd export testimg-diff1 /tmp/img-diff1.new
rbd export testimg-diff2 /tmp/img-diff2.new
rbd export testimg-diff3 /tmp/img-diff3.new
cmp /tmp/img2 /tmp/img2.new
cmp /tmp/img3 /tmp/img3.new
cmp /tmp/img2 /tmp/img-diff2.new
cmp /tmp/img3 /tmp/img-diff3.new
# rollback
rbd snap rollback --snap=snap1 testimg1
rbd snap rollback --snap=snap1 testimg-diff1
rbd info testimg1 | grep 'size 256 MiB'
rbd info testimg-diff1 | grep 'size 256 MiB'
rbd export testimg1 /tmp/img1.snap1
rbd export testimg-diff1 /tmp/img-diff1.snap1
cmp /tmp/img2 /tmp/img1.snap1
cmp /tmp/img2 /tmp/img-diff1.snap1
# test create, copy of zero-length images
rbd rm testimg2
rbd rm testimg3
rbd create testimg2 -s 0
rbd cp testimg2 testimg3
rbd deep cp testimg2 testimg6
# remove snapshots
rbd snap rm --snap=snap1 testimg1
rbd snap rm --snap=snap1 testimg-diff1
rbd info --snap=snap1 testimg1 2>&1 | grep 'error setting snapshot context: (2) No such file or directory'
rbd info --snap=snap1 testimg-diff1 2>&1 | grep 'error setting snapshot context: (2) No such file or directory'
# sparsify
rbd sparsify testimg1
remove_images
rm -f $TMP_FILES
}
test_rename() {
echo "testing rename..."
remove_images
rbd create --image-format 1 -s 1 foo
rbd create --image-format 2 -s 1 bar
rbd rename foo foo2
rbd rename foo2 bar 2>&1 | grep exists
rbd rename bar bar2
rbd rename bar2 foo2 2>&1 | grep exists
ceph osd pool create rbd2 8
rbd pool init rbd2
rbd create -p rbd2 -s 1 foo
rbd rename rbd2/foo rbd2/bar
rbd -p rbd2 ls | grep bar
rbd rename rbd2/bar foo
rbd rename --pool rbd2 foo bar
! rbd rename rbd2/bar --dest-pool rbd foo
rbd rename --pool rbd2 bar --dest-pool rbd2 foo
rbd -p rbd2 ls | grep foo
ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it
remove_images
}
test_ls() {
echo "testing ls..."
remove_images
rbd create --image-format 1 -s 1 test1
rbd create --image-format 1 -s 1 test2
rbd ls | grep test1
rbd ls | grep test2
rbd ls | wc -l | grep 2
# look for fields in output of ls -l without worrying about space
rbd ls -l | grep 'test1.*1 MiB.*1'
rbd ls -l | grep 'test2.*1 MiB.*1'
rbd rm test1
rbd rm test2
rbd create --image-format 2 -s 1 test1
rbd create --image-format 2 -s 1 test2
rbd ls | grep test1
rbd ls | grep test2
rbd ls | wc -l | grep 2
rbd ls -l | grep 'test1.*1 MiB.*2'
rbd ls -l | grep 'test2.*1 MiB.*2'
rbd rm test1
rbd rm test2
rbd create --image-format 2 -s 1 test1
rbd create --image-format 1 -s 1 test2
rbd ls | grep test1
rbd ls | grep test2
rbd ls | wc -l | grep 2
rbd ls -l | grep 'test1.*1 MiB.*2'
rbd ls -l | grep 'test2.*1 MiB.*1'
remove_images
# test that many images can be shown by ls
for i in $(seq -w 00 99); do
rbd create image.$i -s 1
done
rbd ls | wc -l | grep 100
rbd ls -l | grep image | wc -l | grep 100
for i in $(seq -w 00 99); do
rbd rm image.$i
done
for i in $(seq -w 00 99); do
rbd create image.$i --image-format 2 -s 1
done
rbd ls | wc -l | grep 100
rbd ls -l | grep image | wc -l | grep 100
for i in $(seq -w 00 99); do
rbd rm image.$i
done
}
test_remove() {
echo "testing remove..."
remove_images
rbd remove "NOT_EXIST" && exit 1 || true # remove should fail
rbd create --image-format 1 -s 1 test1
rbd rm test1
rbd ls | wc -l | grep "^0$"
rbd create --image-format 2 -s 1 test2
rbd rm test2
rbd ls | wc -l | grep "^0$"
# check that remove succeeds even if it's
# interrupted partway through. simulate this
# by removing some objects manually.
# remove with header missing (old format)
rbd create --image-format 1 -s 1 test1
rados rm -p rbd test1.rbd
rbd rm test1
rbd ls | wc -l | grep "^0$"
if [ $tiered -eq 0 ]; then
# remove with header missing
rbd create --image-format 2 -s 1 test2
HEADER=$(rados -p rbd ls | grep '^rbd_header')
rados -p rbd rm $HEADER
rbd rm test2
rbd ls | wc -l | grep "^0$"
# remove with id missing
rbd create --image-format 2 -s 1 test2
rados -p rbd rm rbd_id.test2
rbd rm test2
rbd ls | wc -l | grep "^0$"
# remove with header and id missing
rbd create --image-format 2 -s 1 test2
HEADER=$(rados -p rbd ls | grep '^rbd_header')
rados -p rbd rm $HEADER
rados -p rbd rm rbd_id.test2
rbd rm test2
rbd ls | wc -l | grep "^0$"
fi
# remove with rbd_children object missing (and, by extension,
# with child not mentioned in rbd_children)
rbd create --image-format 2 -s 1 test2
rbd snap create test2@snap
rbd snap protect test2@snap
rbd clone test2@snap clone --rbd-default-clone-format 1
rados -p rbd rm rbd_children
rbd rm clone
rbd ls | grep clone | wc -l | grep '^0$'
rbd snap unprotect test2@snap
rbd snap rm test2@snap
rbd rm test2
}
test_locking() {
echo "testing locking..."
remove_images
rbd create $RBD_CREATE_ARGS -s 1 test1
rbd lock list test1 | wc -l | grep '^0$'
rbd lock add test1 id
rbd lock list test1 | grep ' 1 '
LOCKER=$(rbd lock list test1 | tail -n 1 | awk '{print $1;}')
rbd lock remove test1 id $LOCKER
rbd lock list test1 | wc -l | grep '^0$'
rbd lock add test1 id --shared tag
rbd lock list test1 | grep ' 1 '
rbd lock add test1 id --shared tag
rbd lock list test1 | grep ' 2 '
rbd lock add test1 id2 --shared tag
rbd lock list test1 | grep ' 3 '
rbd lock list test1 | tail -n 1 | awk '{print $2, $1;}' | xargs rbd lock remove test1
if rbd info test1 | grep -qE "features:.*exclusive"
then
# new locking functionality requires all locks to be released
while [ -n "$(rbd lock list test1)" ]
do
rbd lock list test1 | tail -n 1 | awk '{print $2, $1;}' | xargs rbd lock remove test1
done
fi
rbd rm test1
}
test_pool_image_args() {
echo "testing pool and image args..."
remove_images
ceph osd pool delete test test --yes-i-really-really-mean-it || true
ceph osd pool create test 32
rbd pool init test
truncate -s 1 /tmp/empty /tmp/empty@snap
rbd ls | wc -l | grep 0
rbd create -s 1 test1
rbd ls | grep -q test1
rbd import --image test2 /tmp/empty
rbd ls | grep -q test2
rbd --dest test3 import /tmp/empty
rbd ls | grep -q test3
rbd import /tmp/empty foo
rbd ls | grep -q foo
# should fail due to "destination snapname specified"
rbd import --dest test/empty@snap /tmp/empty && exit 1 || true
rbd import /tmp/empty test/empty@snap && exit 1 || true
rbd import --image test/empty@snap /tmp/empty && exit 1 || true
rbd import /tmp/empty@snap && exit 1 || true
rbd ls test | wc -l | grep 0
rbd import /tmp/empty test/test1
rbd ls test | grep -q test1
rbd -p test import /tmp/empty test2
rbd ls test | grep -q test2
rbd --image test3 -p test import /tmp/empty
rbd ls test | grep -q test3
rbd --image test4 -p test import /tmp/empty
rbd ls test | grep -q test4
rbd --dest test5 -p test import /tmp/empty
rbd ls test | grep -q test5
rbd --dest test6 --dest-pool test import /tmp/empty
rbd ls test | grep -q test6
rbd --image test7 --dest-pool test import /tmp/empty
rbd ls test | grep -q test7
rbd --image test/test8 import /tmp/empty
rbd ls test | grep -q test8
rbd --dest test/test9 import /tmp/empty
rbd ls test | grep -q test9
rbd import --pool test /tmp/empty
rbd ls test | grep -q empty
# copy with no explicit pool goes to pool rbd
rbd copy test/test9 test10
rbd ls test | grep -qv test10
rbd ls | grep -q test10
rbd copy test/test9 test/test10
rbd ls test | grep -q test10
rbd copy --pool test test10 --dest-pool test test11
rbd ls test | grep -q test11
rbd copy --dest-pool rbd --pool test test11 test12
rbd ls | grep test12
rbd ls test | grep -qv test12
rm -f /tmp/empty /tmp/empty@snap
ceph osd pool delete test test --yes-i-really-really-mean-it
for f in foo test1 test10 test12 test2 test3 ; do
rbd rm $f
done
}
test_clone() {
echo "testing clone..."
remove_images
rbd create test1 $RBD_CREATE_ARGS -s 1
rbd snap create test1@s1
rbd snap protect test1@s1
ceph osd pool create rbd2 8
rbd pool init rbd2
rbd clone test1@s1 rbd2/clone
rbd -p rbd2 ls | grep clone
rbd -p rbd2 ls -l | grep clone | grep test1@s1
rbd ls | grep -v clone
rbd flatten rbd2/clone
rbd snap create rbd2/clone@s1
rbd snap protect rbd2/clone@s1
rbd clone rbd2/clone@s1 clone2
rbd ls | grep clone2
rbd ls -l | grep clone2 | grep rbd2/clone@s1
rbd -p rbd2 ls | grep -v clone2
rbd rm clone2
rbd snap unprotect rbd2/clone@s1
rbd snap rm rbd2/clone@s1
rbd rm rbd2/clone
rbd snap unprotect test1@s1
rbd snap rm test1@s1
rbd rm test1
ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it
}
test_trash() {
echo "testing trash..."
remove_images
rbd create $RBD_CREATE_ARGS -s 1 test1
rbd create $RBD_CREATE_ARGS -s 1 test2
rbd ls | grep test1
rbd ls | grep test2
rbd ls | wc -l | grep 2
rbd ls -l | grep 'test1.*2.*'
rbd ls -l | grep 'test2.*2.*'
rbd trash mv test1
rbd ls | grep test2
rbd ls | wc -l | grep 1
rbd ls -l | grep 'test2.*2.*'
rbd trash ls | grep test1
rbd trash ls | wc -l | grep 1
rbd trash ls -l | grep 'test1.*USER.*'
rbd trash ls -l | grep -v 'protected until'
ID=`rbd trash ls | cut -d ' ' -f 1`
rbd trash rm $ID
rbd trash mv test2
ID=`rbd trash ls | cut -d ' ' -f 1`
rbd info --image-id $ID | grep "rbd image 'test2'"
rbd children --image-id $ID | wc -l | grep 0
rbd trash restore $ID
rbd ls | grep test2
rbd ls | wc -l | grep 1
rbd ls -l | grep 'test2.*2.*'
rbd trash mv test2 --expires-at "3600 sec"
rbd trash ls | grep test2
rbd trash ls | wc -l | grep 1
rbd trash ls -l | grep 'test2.*USER.*protected until'
rbd trash rm $ID 2>&1 | grep 'Deferment time has not expired'
rbd trash rm --image-id $ID --force
rbd create $RBD_CREATE_ARGS -s 1 test1
rbd snap create test1@snap1
rbd snap protect test1@snap1
rbd clone test1@snap1 clone
rbd trash mv test1
rbd trash ls | grep test1
rbd trash ls | wc -l | grep 1
rbd trash ls -l | grep 'test1.*USER.*'
rbd trash ls -l | grep -v 'protected until'
ID=`rbd trash ls | cut -d ' ' -f 1`
rbd snap ls --image-id $ID | grep -v 'SNAPID' | wc -l | grep 1
rbd snap ls --image-id $ID | grep '.*snap1.*'
rbd children --image-id $ID | wc -l | grep 1
rbd children --image-id $ID | grep 'clone'
rbd rm clone
rbd snap unprotect --image-id $ID --snap snap1
rbd snap rm --image-id $ID --snap snap1
rbd snap ls --image-id $ID | grep -v 'SNAPID' | wc -l | grep 0
rbd trash restore $ID
rbd snap create test1@snap1
rbd snap create test1@snap2
rbd snap ls --image-id $ID | grep -v 'SNAPID' | wc -l | grep 2
rbd snap purge --image-id $ID
rbd snap ls --image-id $ID | grep -v 'SNAPID' | wc -l | grep 0
rbd rm --rbd_move_to_trash_on_remove=true --rbd_move_to_trash_on_remove_expire_seconds=3600 test1
rbd trash ls | grep test1
rbd trash ls | wc -l | grep 1
rbd trash ls -l | grep 'test1.*USER.*protected until'
rbd trash rm $ID 2>&1 | grep 'Deferment time has not expired'
rbd trash rm --image-id $ID --force
remove_images
}
test_purge() {
echo "testing trash purge..."
remove_images
rbd trash ls | wc -l | grep 0
rbd trash purge
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd create $RBD_CREATE_ARGS --size 256 testimg2
rbd trash mv testimg1
rbd trash mv testimg2
rbd trash ls | wc -l | grep 2
rbd trash purge
rbd trash ls | wc -l | grep 0
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd create $RBD_CREATE_ARGS --size 256 testimg2
rbd trash mv testimg1 --expires-at "1 hour"
rbd trash mv testimg2 --expires-at "3 hours"
rbd trash ls | wc -l | grep 2
rbd trash purge
rbd trash ls | wc -l | grep 2
rbd trash purge --expired-before "now + 2 hours"
rbd trash ls | wc -l | grep 1
rbd trash ls | grep testimg2
rbd trash purge --expired-before "now + 4 hours"
rbd trash ls | wc -l | grep 0
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd snap create testimg1@snap # pin testimg1
rbd create $RBD_CREATE_ARGS --size 256 testimg2
rbd create $RBD_CREATE_ARGS --size 256 testimg3
rbd trash mv testimg1
rbd trash mv testimg2
rbd trash mv testimg3
rbd trash ls | wc -l | grep 3
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 1
rbd trash ls | grep testimg1
ID=$(rbd trash ls | awk '{ print $1 }')
rbd snap purge --image-id $ID
rbd trash purge
rbd trash ls | wc -l | grep 0
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd create $RBD_CREATE_ARGS --size 256 testimg2
rbd snap create testimg2@snap # pin testimg2
rbd create $RBD_CREATE_ARGS --size 256 testimg3
rbd trash mv testimg1
rbd trash mv testimg2
rbd trash mv testimg3
rbd trash ls | wc -l | grep 3
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 1
rbd trash ls | grep testimg2
ID=$(rbd trash ls | awk '{ print $1 }')
rbd snap purge --image-id $ID
rbd trash purge
rbd trash ls | wc -l | grep 0
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd create $RBD_CREATE_ARGS --size 256 testimg2
rbd create $RBD_CREATE_ARGS --size 256 testimg3
rbd snap create testimg3@snap # pin testimg3
rbd trash mv testimg1
rbd trash mv testimg2
rbd trash mv testimg3
rbd trash ls | wc -l | grep 3
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 1
rbd trash ls | grep testimg3
ID=$(rbd trash ls | awk '{ print $1 }')
rbd snap purge --image-id $ID
rbd trash purge
rbd trash ls | wc -l | grep 0
# test purging a clone with a chain of parents
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd snap create testimg1@snap
rbd clone --rbd-default-clone-format=2 testimg1@snap testimg2
rbd snap rm testimg1@snap
rbd create $RBD_CREATE_ARGS --size 256 testimg3
rbd snap create testimg2@snap
rbd clone --rbd-default-clone-format=2 testimg2@snap testimg4
rbd clone --rbd-default-clone-format=2 testimg2@snap testimg5
rbd snap rm testimg2@snap
rbd snap create testimg4@snap
rbd clone --rbd-default-clone-format=2 testimg4@snap testimg6
rbd snap rm testimg4@snap
rbd trash mv testimg1
rbd trash mv testimg2
rbd trash mv testimg3
rbd trash mv testimg4
rbd trash ls | wc -l | grep 4
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 3
rbd trash ls | grep testimg1
rbd trash ls | grep testimg2
rbd trash ls | grep testimg4
rbd trash mv testimg6
rbd trash ls | wc -l | grep 4
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 2
rbd trash ls | grep testimg1
rbd trash ls | grep testimg2
rbd trash mv testimg5
rbd trash ls | wc -l | grep 3
rbd trash purge
rbd trash ls | wc -l | grep 0
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd snap create testimg1@snap
rbd clone --rbd-default-clone-format=2 testimg1@snap testimg2
rbd snap rm testimg1@snap
rbd create $RBD_CREATE_ARGS --size 256 testimg3
rbd snap create testimg3@snap # pin testimg3
rbd snap create testimg2@snap
rbd clone --rbd-default-clone-format=2 testimg2@snap testimg4
rbd clone --rbd-default-clone-format=2 testimg2@snap testimg5
rbd snap rm testimg2@snap
rbd snap create testimg4@snap
rbd clone --rbd-default-clone-format=2 testimg4@snap testimg6
rbd snap rm testimg4@snap
rbd trash mv testimg1
rbd trash mv testimg2
rbd trash mv testimg3
rbd trash mv testimg4
rbd trash ls | wc -l | grep 4
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 4
rbd trash mv testimg6
rbd trash ls | wc -l | grep 5
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 3
rbd trash ls | grep testimg1
rbd trash ls | grep testimg2
rbd trash ls | grep testimg3
rbd trash mv testimg5
rbd trash ls | wc -l | grep 4
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 1
rbd trash ls | grep testimg3
ID=$(rbd trash ls | awk '{ print $1 }')
rbd snap purge --image-id $ID
rbd trash purge
rbd trash ls | wc -l | grep 0
# test purging a clone with a chain of auto-delete parents
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd snap create testimg1@snap
rbd clone --rbd-default-clone-format=2 testimg1@snap testimg2
rbd snap rm testimg1@snap
rbd create $RBD_CREATE_ARGS --size 256 testimg3
rbd snap create testimg2@snap
rbd clone --rbd-default-clone-format=2 testimg2@snap testimg4
rbd clone --rbd-default-clone-format=2 testimg2@snap testimg5
rbd snap rm testimg2@snap
rbd snap create testimg4@snap
rbd clone --rbd-default-clone-format=2 testimg4@snap testimg6
rbd snap rm testimg4@snap
rbd rm --rbd_move_parent_to_trash_on_remove=true testimg1
rbd rm --rbd_move_parent_to_trash_on_remove=true testimg2
rbd trash mv testimg3
rbd rm --rbd_move_parent_to_trash_on_remove=true testimg4
rbd trash ls | wc -l | grep 4
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 3
rbd trash ls | grep testimg1
rbd trash ls | grep testimg2
rbd trash ls | grep testimg4
rbd trash mv testimg6
rbd trash ls | wc -l | grep 4
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 2
rbd trash ls | grep testimg1
rbd trash ls | grep testimg2
rbd trash mv testimg5
rbd trash ls | wc -l | grep 3
rbd trash purge
rbd trash ls | wc -l | grep 0
rbd create $RBD_CREATE_ARGS --size 256 testimg1
rbd snap create testimg1@snap
rbd clone --rbd-default-clone-format=2 testimg1@snap testimg2
rbd snap rm testimg1@snap
rbd create $RBD_CREATE_ARGS --size 256 testimg3
rbd snap create testimg3@snap # pin testimg3
rbd snap create testimg2@snap
rbd clone --rbd-default-clone-format=2 testimg2@snap testimg4
rbd clone --rbd-default-clone-format=2 testimg2@snap testimg5
rbd snap rm testimg2@snap
rbd snap create testimg4@snap
rbd clone --rbd-default-clone-format=2 testimg4@snap testimg6
rbd snap rm testimg4@snap
rbd rm --rbd_move_parent_to_trash_on_remove=true testimg1
rbd rm --rbd_move_parent_to_trash_on_remove=true testimg2
rbd trash mv testimg3
rbd rm --rbd_move_parent_to_trash_on_remove=true testimg4
rbd trash ls | wc -l | grep 4
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 4
rbd trash mv testimg6
rbd trash ls | wc -l | grep 5
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 3
rbd trash ls | grep testimg1
rbd trash ls | grep testimg2
rbd trash ls | grep testimg3
rbd trash mv testimg5
rbd trash ls | wc -l | grep 4
rbd trash purge 2>&1 | grep 'some expired images could not be removed'
rbd trash ls | wc -l | grep 1
rbd trash ls | grep testimg3
ID=$(rbd trash ls | awk '{ print $1 }')
rbd snap purge --image-id $ID
rbd trash purge
rbd trash ls | wc -l | grep 0
}
test_deep_copy_clone() {
echo "testing deep copy clone..."
remove_images
rbd create testimg1 $RBD_CREATE_ARGS --size 256
rbd snap create testimg1 --snap=snap1
rbd snap protect testimg1@snap1
rbd clone testimg1@snap1 testimg2
rbd snap create testimg2@snap2
rbd deep copy testimg2 testimg3
rbd info testimg3 | grep 'size 256 MiB'
rbd info testimg3 | grep 'parent: rbd/testimg1@snap1'
rbd snap ls testimg3 | grep -v 'SNAPID' | wc -l | grep 1
rbd snap ls testimg3 | grep '.*snap2.*'
rbd info testimg2 | grep 'features:.*deep-flatten' || rbd snap rm testimg2@snap2
rbd info testimg3 | grep 'features:.*deep-flatten' || rbd snap rm testimg3@snap2
rbd flatten testimg2
rbd flatten testimg3
rbd snap unprotect testimg1@snap1
rbd snap purge testimg2
rbd snap purge testimg3
rbd rm testimg2
rbd rm testimg3
rbd snap protect testimg1@snap1
rbd clone testimg1@snap1 testimg2
rbd snap create testimg2@snap2
rbd deep copy --flatten testimg2 testimg3
rbd info testimg3 | grep 'size 256 MiB'
rbd info testimg3 | grep -v 'parent:'
rbd snap ls testimg3 | grep -v 'SNAPID' | wc -l | grep 1
rbd snap ls testimg3 | grep '.*snap2.*'
rbd info testimg2 | grep 'features:.*deep-flatten' || rbd snap rm testimg2@snap2
rbd flatten testimg2
rbd snap unprotect testimg1@snap1
remove_images
}
test_clone_v2() {
echo "testing clone v2..."
remove_images
rbd create $RBD_CREATE_ARGS -s 1 test1
rbd snap create test1@1
rbd clone --rbd-default-clone-format=1 test1@1 test2 && exit 1 || true
rbd clone --rbd-default-clone-format=2 test1@1 test2
rbd clone --rbd-default-clone-format=2 test1@1 test3
rbd snap protect test1@1
rbd clone --rbd-default-clone-format=1 test1@1 test4
rbd children test1@1 | sort | tr '\n' ' ' | grep -E "test2.*test3.*test4"
rbd children --descendants test1 | sort | tr '\n' ' ' | grep -E "test2.*test3.*test4"
rbd remove test4
rbd snap unprotect test1@1
rbd snap remove test1@1
rbd snap list --all test1 | grep -E "trash \(1\) *$"
rbd snap create test1@2
rbd rm test1 2>&1 | grep 'image has snapshots'
rbd snap rm test1@2
rbd rm test1 2>&1 | grep 'linked clones'
rbd rm test3
rbd rm test1 2>&1 | grep 'linked clones'
rbd flatten test2
rbd snap list --all test1 | wc -l | grep '^0$'
rbd rm test1
rbd rm test2
rbd create $RBD_CREATE_ARGS -s 1 test1
rbd snap create test1@1
rbd snap create test1@2
rbd clone test1@1 test2 --rbd-default-clone-format 2
rbd clone test1@2 test3 --rbd-default-clone-format 2
rbd snap rm test1@1
rbd snap rm test1@2
expect_fail rbd rm test1
rbd rm test1 --rbd-move-parent-to-trash-on-remove=true
rbd trash ls -a | grep test1
rbd rm test2
rbd trash ls -a | grep test1
rbd rm test3
rbd trash ls -a | expect_fail grep test1
}
test_thick_provision() {
echo "testing thick provision..."
remove_images
# Try to create small and large thick-pro image and
# check actual size. (64M and 4G)
# Small thick-pro image test
rbd create $RBD_CREATE_ARGS --thick-provision -s 64M test1
count=0
ret=""
while [ $count -lt 10 ]
do
rbd du|grep test1|tr -s " "|cut -d " " -f 4-5|grep '^64 MiB' && ret=$?
if [ "$ret" = "0" ]
then
break;
fi
count=`expr $count + 1`
sleep 2
done
rbd du
if [ "$ret" != "0" ]
then
exit 1
fi
rbd rm test1
rbd ls | grep test1 | wc -l | grep '^0$'
# Large thick-pro image test
rbd create $RBD_CREATE_ARGS --thick-provision -s 4G test1
count=0
ret=""
while [ $count -lt 10 ]
do
rbd du|grep test1|tr -s " "|cut -d " " -f 4-5|grep '^4 GiB' && ret=$?
if [ "$ret" = "0" ]
then
break;
fi
count=`expr $count + 1`
sleep 2
done
rbd du
if [ "$ret" != "0" ]
then
exit 1
fi
rbd rm test1
rbd ls | grep test1 | wc -l | grep '^0$'
}
test_namespace() {
echo "testing namespace..."
remove_images
rbd namespace ls | wc -l | grep '^0$'
rbd namespace create rbd/test1
rbd namespace create --pool rbd --namespace test2
rbd namespace create --namespace test3
expect_fail rbd namespace create rbd/test3
rbd namespace list | grep 'test' | wc -l | grep '^3$'
expect_fail rbd namespace remove --pool rbd missing
rbd create $RBD_CREATE_ARGS --size 1G rbd/test1/image1
# default test1 ns to test2 ns clone
rbd bench --io-type write --io-pattern rand --io-total 32M --io-size 4K rbd/test1/image1
rbd snap create rbd/test1/image1@1
rbd clone --rbd-default-clone-format 2 rbd/test1/image1@1 rbd/test2/image1
rbd snap rm rbd/test1/image1@1
cmp <(rbd export rbd/test1/image1 -) <(rbd export rbd/test2/image1 -)
rbd rm rbd/test2/image1
# default ns to test1 ns clone
rbd create $RBD_CREATE_ARGS --size 1G rbd/image2
rbd bench --io-type write --io-pattern rand --io-total 32M --io-size 4K rbd/image2
rbd snap create rbd/image2@1
rbd clone --rbd-default-clone-format 2 rbd/image2@1 rbd/test2/image2
rbd snap rm rbd/image2@1
cmp <(rbd export rbd/image2 -) <(rbd export rbd/test2/image2 -)
expect_fail rbd rm rbd/image2
rbd rm rbd/test2/image2
rbd rm rbd/image2
# v1 clones are supported within the same namespace
rbd create $RBD_CREATE_ARGS --size 1G rbd/test1/image3
rbd snap create rbd/test1/image3@1
rbd snap protect rbd/test1/image3@1
rbd clone --rbd-default-clone-format 1 rbd/test1/image3@1 rbd/test1/image4
rbd rm rbd/test1/image4
rbd snap unprotect rbd/test1/image3@1
rbd snap rm rbd/test1/image3@1
rbd rm rbd/test1/image3
rbd create $RBD_CREATE_ARGS --size 1G --namespace test1 image2
expect_fail rbd namespace remove rbd/test1
rbd group create rbd/test1/group1
rbd group image add rbd/test1/group1 rbd/test1/image1
rbd group rm rbd/test1/group1
rbd trash move rbd/test1/image1
ID=`rbd trash --namespace test1 ls | cut -d ' ' -f 1`
rbd trash rm rbd/test1/${ID}
rbd remove rbd/test1/image2
rbd namespace remove --pool rbd --namespace test1
rbd namespace remove --namespace test3
rbd namespace list | grep 'test' | wc -l | grep '^1$'
rbd namespace remove rbd/test2
}
get_migration_state() {
local image=$1
rbd --format xml status $image |
$XMLSTARLET sel -t -v '//status/migration/state'
}
test_migration() {
echo "testing migration..."
remove_images
ceph osd pool create rbd2 8
rbd pool init rbd2
# Convert to new format
rbd create --image-format 1 -s 128M test1
rbd info test1 | grep 'format: 1'
rbd migration prepare test1 --image-format 2
test "$(get_migration_state test1)" = prepared
rbd info test1 | grep 'format: 2'
rbd rm test1 && exit 1 || true
rbd migration execute test1
test "$(get_migration_state test1)" = executed
rbd migration commit test1
get_migration_state test1 && exit 1 || true
# Enable layering (and some other features)
rbd info test1 | grep 'features: .*layering' && exit 1 || true
rbd migration prepare test1 --image-feature \
layering,exclusive-lock,object-map,fast-diff,deep-flatten
rbd info test1 | grep 'features: .*layering'
rbd migration execute test1
rbd migration commit test1
# Migration to other pool
rbd migration prepare test1 rbd2/test1
test "$(get_migration_state rbd2/test1)" = prepared
rbd ls | wc -l | grep '^0$'
rbd -p rbd2 ls | grep test1
rbd migration execute test1
test "$(get_migration_state rbd2/test1)" = executed
rbd rm rbd2/test1 && exit 1 || true
rbd migration commit test1
# Migration to other namespace
rbd namespace create rbd2/ns1
rbd namespace create rbd2/ns2
rbd migration prepare rbd2/test1 rbd2/ns1/test1
test "$(get_migration_state rbd2/ns1/test1)" = prepared
rbd migration execute rbd2/test1
test "$(get_migration_state rbd2/ns1/test1)" = executed
rbd migration commit rbd2/test1
rbd migration prepare rbd2/ns1/test1 rbd2/ns2/test1
rbd migration execute rbd2/ns2/test1
rbd migration commit rbd2/ns2/test1
# Enable data pool
rbd create -s 128M test1
rbd migration prepare test1 --data-pool rbd2
rbd info test1 | grep 'data_pool: rbd2'
rbd migration execute test1
rbd migration commit test1
# testing trash
rbd migration prepare test1
expect_fail rbd trash mv test1
ID=`rbd trash ls -a | cut -d ' ' -f 1`
expect_fail rbd trash rm $ID
expect_fail rbd trash restore $ID
rbd migration abort test1
# Migrate parent
rbd remove test1
dd if=/dev/urandom bs=1M count=1 | rbd --image-format 2 import - test1
md5sum=$(rbd export test1 - | md5sum)
rbd snap create test1@snap1
rbd snap protect test1@snap1
rbd snap create test1@snap2
rbd clone test1@snap1 clone_v1 --rbd_default_clone_format=1
rbd clone test1@snap2 clone_v2 --rbd_default_clone_format=2
rbd info clone_v1 | fgrep 'parent: rbd/test1@snap1'
rbd info clone_v2 | fgrep 'parent: rbd/test1@snap2'
rbd info clone_v2 |grep 'op_features: clone-child'
test "$(rbd export clone_v1 - | md5sum)" = "${md5sum}"
test "$(rbd export clone_v2 - | md5sum)" = "${md5sum}"
test "$(rbd children test1@snap1)" = "rbd/clone_v1"
test "$(rbd children test1@snap2)" = "rbd/clone_v2"
rbd migration prepare test1 rbd2/test2
rbd info clone_v1 | fgrep 'parent: rbd2/test2@snap1'
rbd info clone_v2 | fgrep 'parent: rbd2/test2@snap2'
rbd info clone_v2 | fgrep 'op_features: clone-child'
test "$(rbd children rbd2/test2@snap1)" = "rbd/clone_v1"
test "$(rbd children rbd2/test2@snap2)" = "rbd/clone_v2"
rbd migration execute test1
expect_fail rbd migration commit test1
rbd migration commit test1 --force
test "$(rbd export clone_v1 - | md5sum)" = "${md5sum}"
test "$(rbd export clone_v2 - | md5sum)" = "${md5sum}"
rbd migration prepare rbd2/test2 test1
rbd info clone_v1 | fgrep 'parent: rbd/test1@snap1'
rbd info clone_v2 | fgrep 'parent: rbd/test1@snap2'
rbd info clone_v2 | fgrep 'op_features: clone-child'
test "$(rbd children test1@snap1)" = "rbd/clone_v1"
test "$(rbd children test1@snap2)" = "rbd/clone_v2"
rbd migration execute test1
expect_fail rbd migration commit test1
rbd migration commit test1 --force
test "$(rbd export clone_v1 - | md5sum)" = "${md5sum}"
test "$(rbd export clone_v2 - | md5sum)" = "${md5sum}"
rbd remove clone_v1
rbd remove clone_v2
rbd snap unprotect test1@snap1
rbd snap purge test1
rbd rm test1
for format in 1 2; do
# Abort migration after successful prepare
rbd create -s 128M --image-format ${format} test2
rbd migration prepare test2 --data-pool rbd2
rbd bench --io-type write --io-size 1024 --io-total 1024 test2
rbd migration abort test2
rbd bench --io-type write --io-size 1024 --io-total 1024 test2
rbd rm test2
# Abort migration after successful execute
rbd create -s 128M --image-format ${format} test2
rbd migration prepare test2 --data-pool rbd2
rbd bench --io-type write --io-size 1024 --io-total 1024 test2
rbd migration execute test2
rbd migration abort test2
rbd bench --io-type write --io-size 1024 --io-total 1024 test2
rbd rm test2
# Migration is automatically aborted if prepare failed
rbd create -s 128M --image-format ${format} test2
rbd migration prepare test2 --data-pool INVALID_DATA_POOL && exit 1 || true
rbd bench --io-type write --io-size 1024 --io-total 1024 test2
rbd rm test2
# Abort migration to other pool
rbd create -s 128M --image-format ${format} test2
rbd migration prepare test2 rbd2/test2
rbd bench --io-type write --io-size 1024 --io-total 1024 rbd2/test2
rbd migration abort test2
rbd bench --io-type write --io-size 1024 --io-total 1024 test2
rbd rm test2
# The same but abort using destination image
rbd create -s 128M --image-format ${format} test2
rbd migration prepare test2 rbd2/test2
rbd migration abort rbd2/test2
rbd bench --io-type write --io-size 1024 --io-total 1024 test2
rbd rm test2
test $format = 1 && continue
# Abort migration to other namespace
rbd create -s 128M --image-format ${format} test2
rbd migration prepare test2 rbd2/ns1/test3
rbd bench --io-type write --io-size 1024 --io-total 1024 rbd2/ns1/test3
rbd migration abort test2
rbd bench --io-type write --io-size 1024 --io-total 1024 test2
rbd rm test2
done
remove_images
ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it
}
test_config() {
echo "testing config..."
remove_images
expect_fail rbd config global set osd rbd_cache true
expect_fail rbd config global set global debug_ms 10
expect_fail rbd config global set global rbd_UNKNOWN false
expect_fail rbd config global set global rbd_cache INVALID
rbd config global set global rbd_cache false
rbd config global set client rbd_cache true
rbd config global set client.123 rbd_cache false
rbd config global get global rbd_cache | grep '^false$'
rbd config global get client rbd_cache | grep '^true$'
rbd config global get client.123 rbd_cache | grep '^false$'
expect_fail rbd config global get client.UNKNOWN rbd_cache
rbd config global list global | grep '^rbd_cache * false * global *$'
rbd config global list client | grep '^rbd_cache * true * client *$'
rbd config global list client.123 | grep '^rbd_cache * false * client.123 *$'
rbd config global list client.UNKNOWN | grep '^rbd_cache * true * client *$'
rbd config global rm client rbd_cache
expect_fail rbd config global get client rbd_cache
rbd config global list client | grep '^rbd_cache * false * global *$'
rbd config global rm client.123 rbd_cache
rbd config global rm global rbd_cache
rbd config pool set rbd rbd_cache true
rbd config pool list rbd | grep '^rbd_cache * true * pool *$'
rbd config pool get rbd rbd_cache | grep '^true$'
rbd create $RBD_CREATE_ARGS -s 1 test1
rbd config image list rbd/test1 | grep '^rbd_cache * true * pool *$'
rbd config image set rbd/test1 rbd_cache false
rbd config image list rbd/test1 | grep '^rbd_cache * false * image *$'
rbd config image get rbd/test1 rbd_cache | grep '^false$'
rbd config image remove rbd/test1 rbd_cache
expect_fail rbd config image get rbd/test1 rbd_cache
rbd config image list rbd/test1 | grep '^rbd_cache * true * pool *$'
rbd config pool remove rbd rbd_cache
expect_fail rbd config pool get rbd rbd_cache
rbd config pool list rbd | grep '^rbd_cache * true * config *$'
rbd rm test1
}
test_trash_purge_schedule() {
echo "testing trash purge schedule..."
remove_images
ceph osd pool create rbd2 8
rbd pool init rbd2
rbd namespace create rbd2/ns1
test "$(ceph rbd trash purge schedule list)" = "{}"
ceph rbd trash purge schedule status | fgrep '"scheduled": []'
expect_fail rbd trash purge schedule ls
test "$(rbd trash purge schedule ls -R --format json)" = "[]"
rbd trash purge schedule add -p rbd 1d 01:30
rbd trash purge schedule ls -p rbd | grep 'every 1d starting at 01:30'
expect_fail rbd trash purge schedule ls
rbd trash purge schedule ls -R | grep 'every 1d starting at 01:30'
rbd trash purge schedule ls -R -p rbd | grep 'every 1d starting at 01:30'
expect_fail rbd trash purge schedule ls -p rbd2
test "$(rbd trash purge schedule ls -p rbd2 -R --format json)" = "[]"
rbd trash purge schedule add -p rbd2/ns1 2d
test "$(rbd trash purge schedule ls -p rbd2 -R --format json)" != "[]"
rbd trash purge schedule ls -p rbd2 -R | grep 'rbd2 *ns1 *every 2d'
rbd trash purge schedule rm -p rbd2/ns1
test "$(rbd trash purge schedule ls -p rbd2 -R --format json)" = "[]"
for i in `seq 12`; do
test "$(rbd trash purge schedule status --format xml |
$XMLSTARLET sel -t -v '//scheduled/item/pool')" = 'rbd' && break
sleep 10
done
rbd trash purge schedule status
test "$(rbd trash purge schedule status --format xml |
$XMLSTARLET sel -t -v '//scheduled/item/pool')" = 'rbd'
test "$(rbd trash purge schedule status -p rbd --format xml |
$XMLSTARLET sel -t -v '//scheduled/item/pool')" = 'rbd'
rbd trash purge schedule add 2d 00:17
rbd trash purge schedule ls | grep 'every 2d starting at 00:17'
rbd trash purge schedule ls -R | grep 'every 2d starting at 00:17'
expect_fail rbd trash purge schedule ls -p rbd2
rbd trash purge schedule ls -p rbd2 -R | grep 'every 2d starting at 00:17'
rbd trash purge schedule ls -p rbd2/ns1 -R | grep 'every 2d starting at 00:17'
test "$(rbd trash purge schedule ls -R -p rbd2/ns1 --format xml |
$XMLSTARLET sel -t -v '//schedules/schedule/pool')" = "-"
test "$(rbd trash purge schedule ls -R -p rbd2/ns1 --format xml |
$XMLSTARLET sel -t -v '//schedules/schedule/namespace')" = "-"
test "$(rbd trash purge schedule ls -R -p rbd2/ns1 --format xml |
$XMLSTARLET sel -t -v '//schedules/schedule/items/item/start_time')" = "00:17:00"
for i in `seq 12`; do
rbd trash purge schedule status --format xml |
$XMLSTARLET sel -t -v '//scheduled/item/pool' | grep 'rbd2' && break
sleep 10
done
rbd trash purge schedule status
rbd trash purge schedule status --format xml |
$XMLSTARLET sel -t -v '//scheduled/item/pool' | grep 'rbd2'
echo $(rbd trash purge schedule status --format xml |
$XMLSTARLET sel -t -v '//scheduled/item/pool') | grep 'rbd rbd2 rbd2'
test "$(rbd trash purge schedule status -p rbd --format xml |
$XMLSTARLET sel -t -v '//scheduled/item/pool')" = 'rbd'
test "$(echo $(rbd trash purge schedule status -p rbd2 --format xml |
$XMLSTARLET sel -t -v '//scheduled/item/pool'))" = 'rbd2 rbd2'
test "$(echo $(rbd trash purge schedule ls -R --format xml |
$XMLSTARLET sel -t -v '//schedules/schedule/items'))" = "2d00:17:00 1d01:30:00"
rbd trash purge schedule add 1d
rbd trash purge schedule ls | grep 'every 2d starting at 00:17'
rbd trash purge schedule ls | grep 'every 1d'
rbd trash purge schedule ls -R --format xml |
$XMLSTARLET sel -t -v '//schedules/schedule/items' | grep '2d00:17'
rbd trash purge schedule rm 1d
rbd trash purge schedule ls | grep 'every 2d starting at 00:17'
rbd trash purge schedule rm 2d 00:17
expect_fail rbd trash purge schedule ls
for p in rbd2 rbd2/ns1; do
rbd create $RBD_CREATE_ARGS -s 1 rbd2/ns1/test1
rbd trash mv rbd2/ns1/test1
rbd trash ls rbd2/ns1 | wc -l | grep '^1$'
rbd trash purge schedule add -p $p 1m
rbd trash purge schedule list -p rbd2 -R | grep 'every 1m'
rbd trash purge schedule list -p rbd2/ns1 -R | grep 'every 1m'
for i in `seq 12`; do
rbd trash ls rbd2/ns1 | wc -l | grep '^1$' || break
sleep 10
done
rbd trash ls rbd2/ns1 | wc -l | grep '^0$'
# repeat with kicked in schedule, see https://tracker.ceph.com/issues/53915
rbd trash purge schedule list -p rbd2 -R | grep 'every 1m'
rbd trash purge schedule list -p rbd2/ns1 -R | grep 'every 1m'
rbd trash purge schedule status | grep 'rbd2 *ns1'
rbd trash purge schedule status -p rbd2 | grep 'rbd2 *ns1'
rbd trash purge schedule status -p rbd2/ns1 | grep 'rbd2 *ns1'
rbd trash purge schedule rm -p $p 1m
done
# Negative tests
rbd trash purge schedule add 2m
expect_fail rbd trash purge schedule add -p rbd dummy
expect_fail rbd trash purge schedule add dummy
expect_fail rbd trash purge schedule remove -p rbd dummy
expect_fail rbd trash purge schedule remove dummy
rbd trash purge schedule ls -p rbd | grep 'every 1d starting at 01:30'
rbd trash purge schedule ls | grep 'every 2m'
rbd trash purge schedule remove -p rbd 1d 01:30
rbd trash purge schedule remove 2m
test "$(rbd trash purge schedule ls -R --format json)" = "[]"
remove_images
ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it
}
test_trash_purge_schedule_recovery() {
echo "testing recovery of trash_purge_schedule handler after module's RADOS client is blocklisted..."
remove_images
ceph osd pool create rbd3 8
rbd pool init rbd3
rbd namespace create rbd3/ns1
rbd trash purge schedule add -p rbd3/ns1 2d
rbd trash purge schedule ls -p rbd3 -R | grep 'rbd3 *ns1 *every 2d'
# Fetch and blocklist the rbd_support module's RADOS client
CLIENT_ADDR=$(ceph mgr dump | jq .active_clients[] |
jq 'select(.name == "rbd_support")' |
jq -r '[.addrvec[0].addr, "/", .addrvec[0].nonce|tostring] | add')
ceph osd blocklist add $CLIENT_ADDR
# Check that you can add a trash purge schedule after a few retries
expect_fail rbd trash purge schedule add -p rbd3 10m
sleep 10
for i in `seq 24`; do
rbd trash purge schedule add -p rbd3 10m && break
sleep 10
done
rbd trash purge schedule ls -p rbd3 -R | grep 'every 10m'
# Verify that the schedule present before client blocklisting is preserved
rbd trash purge schedule ls -p rbd3 -R | grep 'rbd3 *ns1 *every 2d'
rbd trash purge schedule remove -p rbd3 10m
rbd trash purge schedule remove -p rbd3/ns1 2d
rbd trash purge schedule ls -p rbd3 -R | expect_fail grep 'every 10m'
rbd trash purge schedule ls -p rbd3 -R | expect_fail grep 'rbd3 *ns1 *every 2d'
ceph osd pool rm rbd3 rbd3 --yes-i-really-really-mean-it
}
test_mirror_snapshot_schedule() {
echo "testing mirror snapshot schedule..."
remove_images
ceph osd pool create rbd2 8
rbd pool init rbd2
rbd namespace create rbd2/ns1
rbd mirror pool enable rbd2 image
rbd mirror pool enable rbd2/ns1 image
rbd mirror pool peer add rbd2 cluster1
test "$(ceph rbd mirror snapshot schedule list)" = "{}"
ceph rbd mirror snapshot schedule status | fgrep '"scheduled_images": []'
expect_fail rbd mirror snapshot schedule ls
test "$(rbd mirror snapshot schedule ls -R --format json)" = "[]"
rbd create $RBD_CREATE_ARGS -s 1 rbd2/ns1/test1
test "$(rbd mirror image status rbd2/ns1/test1 |
grep -c mirror.primary)" = '0'
rbd mirror image enable rbd2/ns1/test1 snapshot
test "$(rbd mirror image status rbd2/ns1/test1 |
grep -c mirror.primary)" = '1'
rbd mirror snapshot schedule add -p rbd2/ns1 --image test1 1m
expect_fail rbd mirror snapshot schedule ls
rbd mirror snapshot schedule ls -R | grep 'rbd2 *ns1 *test1 *every 1m'
expect_fail rbd mirror snapshot schedule ls -p rbd2
rbd mirror snapshot schedule ls -p rbd2 -R | grep 'rbd2 *ns1 *test1 *every 1m'
expect_fail rbd mirror snapshot schedule ls -p rbd2/ns1
rbd mirror snapshot schedule ls -p rbd2/ns1 -R | grep 'rbd2 *ns1 *test1 *every 1m'
test "$(rbd mirror snapshot schedule ls -p rbd2/ns1 --image test1)" = 'every 1m'
for i in `seq 12`; do
test "$(rbd mirror image status rbd2/ns1/test1 |
grep -c mirror.primary)" -gt '1' && break
sleep 10
done
test "$(rbd mirror image status rbd2/ns1/test1 |
grep -c mirror.primary)" -gt '1'
# repeat with kicked in schedule, see https://tracker.ceph.com/issues/53915
expect_fail rbd mirror snapshot schedule ls
rbd mirror snapshot schedule ls -R | grep 'rbd2 *ns1 *test1 *every 1m'
expect_fail rbd mirror snapshot schedule ls -p rbd2
rbd mirror snapshot schedule ls -p rbd2 -R | grep 'rbd2 *ns1 *test1 *every 1m'
expect_fail rbd mirror snapshot schedule ls -p rbd2/ns1
rbd mirror snapshot schedule ls -p rbd2/ns1 -R | grep 'rbd2 *ns1 *test1 *every 1m'
test "$(rbd mirror snapshot schedule ls -p rbd2/ns1 --image test1)" = 'every 1m'
rbd mirror snapshot schedule status
test "$(rbd mirror snapshot schedule status --format xml |
$XMLSTARLET sel -t -v '//scheduled_images/image/image')" = 'rbd2/ns1/test1'
test "$(rbd mirror snapshot schedule status -p rbd2 --format xml |
$XMLSTARLET sel -t -v '//scheduled_images/image/image')" = 'rbd2/ns1/test1'
test "$(rbd mirror snapshot schedule status -p rbd2/ns1 --format xml |
$XMLSTARLET sel -t -v '//scheduled_images/image/image')" = 'rbd2/ns1/test1'
test "$(rbd mirror snapshot schedule status -p rbd2/ns1 --image test1 --format xml |
$XMLSTARLET sel -t -v '//scheduled_images/image/image')" = 'rbd2/ns1/test1'
mgr/rbd_support: always rescan image mirror snapshots on refresh Establishing a watch on rbd_mirroring object and skipping rescanning image mirror snapshots on periodic refresh unless rbd_mirroring object gets notified in the interim is flawed. rbd_mirroring object is notified when mirroring is enabled or disabled on some image (including when the image is removed), but it is not notified when images are promoted or demoted. However, load_pool_images() discards images that are not primary at the time of the scan. If the image is promoted later, no snapshots are created even if the schedule is in place. This happens regardless of whether the schedule is added before or after the promotion. This effectively reverts commit 69259c8d3722 ("mgr/rbd_support: make mirror_snapshot_schedule rescan only updated pools"). An alternative fix could be to stop discarding non-primary images (i.e. drop if not info['primary']: continue check added in commit d39eb283c5ce ("mgr/rbd_support: mirror snapshot schedule should skip non-primary images")), but that would clutter the queue and therefore "rbd mirror snapshot schedule status" output with bogus entries. Performing a rescan roughly every 60 seconds should be manageable: currently it amounts to a single mirror_image_status_list request, followed by mirror_image_get, get_snapcontext and snapshot_get requests for each snapshot-based mirroring enabled image and concluded by a single dir_list request. Among these, per-image get_snapcontext and snapshot_get requests are necessary for determining primaryness. Fixes: https://tracker.ceph.com/issues/53914 Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2022-06-19 10:12:01 +00:00
rbd mirror image demote rbd2/ns1/test1
for i in `seq 12`; do
rbd mirror snapshot schedule status | grep 'rbd2/ns1/test1' || break
sleep 10
done
rbd mirror snapshot schedule status | expect_fail grep 'rbd2/ns1/test1'
rbd mirror image promote rbd2/ns1/test1
for i in `seq 12`; do
rbd mirror snapshot schedule status | grep 'rbd2/ns1/test1' && break
sleep 10
done
rbd mirror snapshot schedule status | grep 'rbd2/ns1/test1'
rbd mirror snapshot schedule add 1h 00:15
test "$(rbd mirror snapshot schedule ls)" = 'every 1h starting at 00:15:00'
rbd mirror snapshot schedule ls -R | grep 'every 1h starting at 00:15:00'
rbd mirror snapshot schedule ls -R | grep 'rbd2 *ns1 *test1 *every 1m'
expect_fail rbd mirror snapshot schedule ls -p rbd2
rbd mirror snapshot schedule ls -p rbd2 -R | grep 'every 1h starting at 00:15:00'
rbd mirror snapshot schedule ls -p rbd2 -R | grep 'rbd2 *ns1 *test1 *every 1m'
expect_fail rbd mirror snapshot schedule ls -p rbd2/ns1
rbd mirror snapshot schedule ls -p rbd2/ns1 -R | grep 'every 1h starting at 00:15:00'
rbd mirror snapshot schedule ls -p rbd2/ns1 -R | grep 'rbd2 *ns1 *test1 *every 1m'
test "$(rbd mirror snapshot schedule ls -p rbd2/ns1 --image test1)" = 'every 1m'
# Negative tests
expect_fail rbd mirror snapshot schedule add dummy
expect_fail rbd mirror snapshot schedule add -p rbd2/ns1 --image test1 dummy
expect_fail rbd mirror snapshot schedule remove dummy
expect_fail rbd mirror snapshot schedule remove -p rbd2/ns1 --image test1 dummy
test "$(rbd mirror snapshot schedule ls)" = 'every 1h starting at 00:15:00'
test "$(rbd mirror snapshot schedule ls -p rbd2/ns1 --image test1)" = 'every 1m'
rbd rm rbd2/ns1/test1
for i in `seq 12`; do
rbd mirror snapshot schedule status | grep 'rbd2/ns1/test1' || break
sleep 10
done
mgr/rbd_support: always rescan image mirror snapshots on refresh Establishing a watch on rbd_mirroring object and skipping rescanning image mirror snapshots on periodic refresh unless rbd_mirroring object gets notified in the interim is flawed. rbd_mirroring object is notified when mirroring is enabled or disabled on some image (including when the image is removed), but it is not notified when images are promoted or demoted. However, load_pool_images() discards images that are not primary at the time of the scan. If the image is promoted later, no snapshots are created even if the schedule is in place. This happens regardless of whether the schedule is added before or after the promotion. This effectively reverts commit 69259c8d3722 ("mgr/rbd_support: make mirror_snapshot_schedule rescan only updated pools"). An alternative fix could be to stop discarding non-primary images (i.e. drop if not info['primary']: continue check added in commit d39eb283c5ce ("mgr/rbd_support: mirror snapshot schedule should skip non-primary images")), but that would clutter the queue and therefore "rbd mirror snapshot schedule status" output with bogus entries. Performing a rescan roughly every 60 seconds should be manageable: currently it amounts to a single mirror_image_status_list request, followed by mirror_image_get, get_snapcontext and snapshot_get requests for each snapshot-based mirroring enabled image and concluded by a single dir_list request. Among these, per-image get_snapcontext and snapshot_get requests are necessary for determining primaryness. Fixes: https://tracker.ceph.com/issues/53914 Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2022-06-19 10:12:01 +00:00
rbd mirror snapshot schedule status | expect_fail grep 'rbd2/ns1/test1'
rbd mirror snapshot schedule remove
test "$(rbd mirror snapshot schedule ls -R --format json)" = "[]"
remove_images
ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it
}
test_mirror_snapshot_schedule_recovery() {
echo "testing recovery of mirror snapshot scheduler after module's RADOS client is blocklisted..."
remove_images
ceph osd pool create rbd3 8
rbd pool init rbd3
rbd namespace create rbd3/ns1
rbd mirror pool enable rbd3 image
rbd mirror pool enable rbd3/ns1 image
rbd mirror pool peer add rbd3 cluster1
rbd create $RBD_CREATE_ARGS -s 1 rbd3/ns1/test1
rbd mirror image enable rbd3/ns1/test1 snapshot
test "$(rbd mirror image status rbd3/ns1/test1 |
grep -c mirror.primary)" = '1'
rbd mirror snapshot schedule add -p rbd3/ns1 --image test1 1m
test "$(rbd mirror snapshot schedule ls -p rbd3/ns1 --image test1)" = 'every 1m'
# Fetch and blocklist rbd_support module's RADOS client
CLIENT_ADDR=$(ceph mgr dump | jq .active_clients[] |
jq 'select(.name == "rbd_support")' |
jq -r '[.addrvec[0].addr, "/", .addrvec[0].nonce|tostring] | add')
ceph osd blocklist add $CLIENT_ADDR
# Check that you can add a mirror snapshot schedule after a few retries
expect_fail rbd mirror snapshot schedule add -p rbd3/ns1 --image test1 2m
sleep 10
for i in `seq 24`; do
rbd mirror snapshot schedule add -p rbd3/ns1 --image test1 2m && break
sleep 10
done
rbd mirror snapshot schedule ls -p rbd3/ns1 --image test1 | grep 'every 2m'
# Verify that the schedule present before client blocklisting is preserved
rbd mirror snapshot schedule ls -p rbd3/ns1 --image test1 | grep 'every 1m'
rbd mirror snapshot schedule rm -p rbd3/ns1 --image test1 2m
rbd mirror snapshot schedule rm -p rbd3/ns1 --image test1 1m
rbd mirror snapshot schedule ls -p rbd3/ns1 --image test1 | expect_fail grep 'every 2m'
rbd mirror snapshot schedule ls -p rbd3/ns1 --image test1 | expect_fail grep 'every 1m'
rbd snap purge rbd3/ns1/test1
rbd rm rbd3/ns1/test1
ceph osd pool rm rbd3 rbd3 --yes-i-really-really-mean-it
}
test_perf_image_iostat() {
echo "testing perf image iostat..."
remove_images
ceph osd pool create rbd1 8
rbd pool init rbd1
rbd namespace create rbd1/ns
ceph osd pool create rbd2 8
rbd pool init rbd2
rbd namespace create rbd2/ns
IMAGE_SPECS=("test1" "rbd1/test2" "rbd1/ns/test3" "rbd2/test4" "rbd2/ns/test5")
for spec in "${IMAGE_SPECS[@]}"; do
# ensure all images are created without a separate data pool
# as we filter iostat by specific pool specs below
rbd create $RBD_CREATE_ARGS --size 10G --rbd-default-data-pool '' $spec
done
BENCH_PIDS=()
for spec in "${IMAGE_SPECS[@]}"; do
rbd bench --io-type write --io-pattern rand --io-total 10G --io-threads 1 \
--rbd-cache false $spec >/dev/null 2>&1 &
BENCH_PIDS+=($!)
done
# test specifying pool spec via spec syntax
test "$(rbd perf image iostat --format json rbd1 |
jq -r 'map(.image) | sort | join(" ")')" = 'test2'
test "$(rbd perf image iostat --format json rbd1/ns |
jq -r 'map(.image) | sort | join(" ")')" = 'test3'
test "$(rbd perf image iostat --format json --rbd-default-pool rbd1 /ns |
jq -r 'map(.image) | sort | join(" ")')" = 'test3'
# test specifying pool spec via options
test "$(rbd perf image iostat --format json --pool rbd2 |
jq -r 'map(.image) | sort | join(" ")')" = 'test4'
test "$(rbd perf image iostat --format json --pool rbd2 --namespace ns |
jq -r 'map(.image) | sort | join(" ")')" = 'test5'
test "$(rbd perf image iostat --format json --rbd-default-pool rbd2 --namespace ns |
jq -r 'map(.image) | sort | join(" ")')" = 'test5'
# test omitting pool spec (-> GLOBAL_POOL_KEY)
test "$(rbd perf image iostat --format json |
jq -r 'map(.image) | sort | join(" ")')" = 'test1 test2 test3 test4 test5'
for pid in "${BENCH_PIDS[@]}"; do
kill $pid
done
wait
remove_images
ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it
ceph osd pool rm rbd1 rbd1 --yes-i-really-really-mean-it
}
test_perf_image_iostat_recovery() {
echo "testing recovery of perf handler after module's RADOS client is blocklisted..."
remove_images
ceph osd pool create rbd3 8
rbd pool init rbd3
rbd namespace create rbd3/ns
IMAGE_SPECS=("rbd3/test1" "rbd3/ns/test2")
for spec in "${IMAGE_SPECS[@]}"; do
# ensure all images are created without a separate data pool
# as we filter iostat by specific pool specs below
rbd create $RBD_CREATE_ARGS --size 10G --rbd-default-data-pool '' $spec
done
BENCH_PIDS=()
for spec in "${IMAGE_SPECS[@]}"; do
rbd bench --io-type write --io-pattern rand --io-total 10G --io-threads 1 \
--rbd-cache false $spec >/dev/null 2>&1 &
BENCH_PIDS+=($!)
done
test "$(rbd perf image iostat --format json rbd3 |
jq -r 'map(.image) | sort | join(" ")')" = 'test1'
# Fetch and blocklist the rbd_support module's RADOS client
CLIENT_ADDR=$(ceph mgr dump | jq .active_clients[] |
jq 'select(.name == "rbd_support")' |
jq -r '[.addrvec[0].addr, "/", .addrvec[0].nonce|tostring] | add')
ceph osd blocklist add $CLIENT_ADDR
expect_fail rbd perf image iostat --format json rbd3/ns
sleep 10
for i in `seq 24`; do
test "$(rbd perf image iostat --format json rbd3/ns |
jq -r 'map(.image) | sort | join(" ")')" = 'test2' && break
sleep 10
done
for pid in "${BENCH_PIDS[@]}"; do
kill $pid
done
wait
remove_images
ceph osd pool rm rbd3 rbd3 --yes-i-really-really-mean-it
}
test_mirror_pool_peer_bootstrap_create() {
echo "testing mirror pool peer bootstrap create..."
remove_images
ceph osd pool create rbd1 8
rbd pool init rbd1
rbd mirror pool enable rbd1 image
ceph osd pool create rbd2 8
rbd pool init rbd2
rbd mirror pool enable rbd2 pool
readarray -t MON_ADDRS < <(ceph mon dump |
sed -n 's/^[0-9]: \(.*\) mon\.[a-z]$/\1/p')
# check that all monitors make it to the token even if only one
# valid monitor is specified
BAD_MON_ADDR="1.2.3.4:6789"
MON_HOST="${MON_ADDRS[0]},$BAD_MON_ADDR"
TOKEN="$(rbd mirror pool peer bootstrap create \
--mon-host "$MON_HOST" rbd1 | base64 -d)"
TOKEN_FSID="$(jq -r '.fsid' <<< "$TOKEN")"
TOKEN_CLIENT_ID="$(jq -r '.client_id' <<< "$TOKEN")"
TOKEN_KEY="$(jq -r '.key' <<< "$TOKEN")"
TOKEN_MON_HOST="$(jq -r '.mon_host' <<< "$TOKEN")"
test "$TOKEN_FSID" = "$(ceph fsid)"
test "$TOKEN_KEY" = "$(ceph auth get-key client.$TOKEN_CLIENT_ID)"
for addr in "${MON_ADDRS[@]}"; do
fgrep "$addr" <<< "$TOKEN_MON_HOST"
done
expect_fail fgrep "$BAD_MON_ADDR" <<< "$TOKEN_MON_HOST"
# check that the token does not change, including across pools
test "$(rbd mirror pool peer bootstrap create \
--mon-host "$MON_HOST" rbd1 | base64 -d)" = "$TOKEN"
test "$(rbd mirror pool peer bootstrap create \
rbd1 | base64 -d)" = "$TOKEN"
test "$(rbd mirror pool peer bootstrap create \
--mon-host "$MON_HOST" rbd2 | base64 -d)" = "$TOKEN"
test "$(rbd mirror pool peer bootstrap create \
rbd2 | base64 -d)" = "$TOKEN"
ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it
ceph osd pool rm rbd1 rbd1 --yes-i-really-really-mean-it
}
test_tasks_removed_pool() {
echo "testing removing pool under running tasks..."
remove_images
ceph osd pool create rbd2 8
rbd pool init rbd2
rbd create $RBD_CREATE_ARGS --size 1G foo
rbd snap create foo@snap
rbd snap protect foo@snap
rbd clone foo@snap bar
rbd create $RBD_CREATE_ARGS --size 1G rbd2/dummy
rbd bench --io-type write --io-pattern seq --io-size 1M --io-total 1G rbd2/dummy
rbd snap create rbd2/dummy@snap
rbd snap protect rbd2/dummy@snap
for i in {1..5}; do
rbd clone rbd2/dummy@snap rbd2/dummy$i
done
# queue flattens on a few dummy images and remove that pool
test "$(ceph rbd task list)" = "[]"
for i in {1..5}; do
ceph rbd task add flatten rbd2/dummy$i
done
ceph osd pool delete rbd2 rbd2 --yes-i-really-really-mean-it
test "$(ceph rbd task list)" != "[]"
# queue flatten on another image and check that it completes
rbd info bar | grep 'parent: '
expect_fail rbd snap unprotect foo@snap
ceph rbd task add flatten bar
for i in {1..12}; do
rbd info bar | grep 'parent: ' || break
sleep 10
done
rbd info bar | expect_fail grep 'parent: '
rbd snap unprotect foo@snap
# check that flattens disrupted by pool removal are cleaned up
for i in {1..12}; do
test "$(ceph rbd task list)" = "[]" && break
sleep 10
done
test "$(ceph rbd task list)" = "[]"
remove_images
}
test_tasks_recovery() {
echo "testing task handler recovery after module's RADOS client is blocklisted..."
remove_images
ceph osd pool create rbd2 8
rbd pool init rbd2
rbd create $RBD_CREATE_ARGS --size 1G rbd2/img1
rbd bench --io-type write --io-pattern seq --io-size 1M --io-total 1G rbd2/img1
rbd snap create rbd2/img1@snap
rbd snap protect rbd2/img1@snap
rbd clone rbd2/img1@snap rbd2/clone1
# Fetch and blocklist rbd_support module's RADOS client
CLIENT_ADDR=$(ceph mgr dump | jq .active_clients[] |
jq 'select(.name == "rbd_support")' |
jq -r '[.addrvec[0].addr, "/", .addrvec[0].nonce|tostring] | add')
ceph osd blocklist add $CLIENT_ADDR
expect_fail ceph rbd task add flatten rbd2/clone1
sleep 10
for i in `seq 24`; do
ceph rbd task add flatten rbd2/clone1 && break
sleep 10
done
test "$(ceph rbd task list)" != "[]"
for i in {1..12}; do
rbd info rbd2/clone1 | grep 'parent: ' || break
sleep 10
done
rbd info rbd2/clone1 | expect_fail grep 'parent: '
rbd snap unprotect rbd2/img1@snap
test "$(ceph rbd task list)" = "[]"
ceph osd pool rm rbd2 rbd2 --yes-i-really-really-mean-it
}
test_pool_image_args
test_rename
test_ls
test_remove
test_migration
test_config
RBD_CREATE_ARGS=""
test_others
test_locking
test_thick_provision
RBD_CREATE_ARGS="--image-format 2"
test_others
test_locking
test_clone
test_trash
test_purge
test_deep_copy_clone
test_clone_v2
test_thick_provision
test_namespace
test_trash_purge_schedule
test_trash_purge_schedule_recovery
test_mirror_snapshot_schedule
test_mirror_snapshot_schedule_recovery
test_perf_image_iostat
test_perf_image_iostat_recovery
test_mirror_pool_peer_bootstrap_create
test_tasks_removed_pool
test_tasks_recovery
echo OK