Project

General

Profile

Bug #57396 » issue.sh

Josef Johansson, 12/21/2022 04:05 PM

 
#!/usr/bin/env bash
set -e

. $(dirname $0)/../../standalone/ceph-helpers.sh

function list_tests()
{
echo "AVAILABLE TESTS"
for i in $TESTS; do
echo " $i"
done
}

function usage()
{
echo "usage: $0 [-h|-l|-t <testname> [-t <testname>...] [--lttng <testname>...] [--no-cleanup]]"
}

function ncommits()
{
local image="$1"
out="$(rbd journal inspect --image ${image} --verbose |& awk \
'/entries inspected/ {print $1}')"
if [ -z "$out" ]; then
out='0'
fi

printf '%d' "$out"
}

function zero_ncommits()
{
local i=0
local image="$1"
while [ "$(ncommits ${image})" -ne 0 ]; do
i="$((i + 1))"
if [ "$i" -gt 45 ]; then
printf 'journal is not commited\n'
rbd journal inspect --image ${image} --verbose
exit 1
fi

sleep 1
done
}

function wait_for_new_journal()
{
local old="$1"
local image="$2"
local new="$(rbd journal status --image ${image})"
local i=0
while [ "$old" == "$new" ]; do
i="$((i + 1))"
new="$(rbd journal status --image ${image})"
if [ "$i" -ge 30 ]; then
return 1
fi
sleep 1
done

printf 'debug: %s\n' "$new" >&2
printf '%s' "$new"
return 0
}

test_rbd_journal_discard_replay()
{
if ! rados lspools |& grep -q '^rbd$'; then
ceph osd pool create rbd
fi
image=testrbdjournaldiscard

rbd create --image-feature exclusive-lock --image-feature journaling \
--size 128 ${image}
local journal=$(rbd info ${image} --format=xml 2> /dev/null |
$XMLSTARLET sel -t -v "//image/journal")
test -n "${journal}"

zero_ncommits ${image}

if ! status="$(wait_for_new_journal ' ' ${image})"; then
printf 'timeout\n'
exit 1
fi

rbd journal info ${journal}
rbd journal info --journal ${journal}
rbd journal info --image ${image}

rbd journal status ${journal}

local count=1
local bs=4096
local status=""

rbd-replay replay-${image}.bin

zero_ncommits ${image}

if ! status="$(wait_for_new_journal "$status" ${image})"; then
printf 'timeout\n'
exit 1
fi
}

# modprobe nbd (on host)
# mknod /dev/nbd0 b 43 0 (in docker)
lttng_rbd_journal_discard()
{
if ! rados lspools |& grep -q '^rbd$'; then
ceph osd pool create rbd
fi
image=testrbdjournaldiscard
device=/dev/nbd0
lttng create -o ${image} ${image}
lttng_destroy()
{
lttng destroy
}
trap lttng_destroy EXIT

lttng enable-event -u 'librbd:*'
lttng add-context -u -t pthread_id

rbd create --image-feature exclusive-lock --image-feature journaling \
--size 128 ${image}
local journal=$(rbd info ${image} --format=xml 2> /dev/null |
$XMLSTARLET sel -t -v "//image/journal")
test -n "${journal}"

zero_ncommits ${image}

if ! status="$(wait_for_new_journal ' ' ${image})"; then
printf 'timeout\n'
exit 1
fi

rbd journal info ${journal}
rbd journal info --journal ${journal}
rbd journal info --image ${image}

rbd journal status ${journal}

(
cat ceph.conf
printf '\n[global]\n'
printf '\t%s\n' \
'rbd discard granularity bytes = 4096' \
'rbd cache = false' \
'rbd_tracing = true'
) > ceph-tracing.conf
rbd-nbd --conf ceph-tracing.conf -d --device ${device} map ${image} &
rbdpid=$!
unmap()
{
set -x
rbd-nbd -d --device ${device} unmap ${image}
rm ceph-tracing.conf
rbd remove ${image}
lttng_destroy
}
trap unmap EXIT

local arg=""
if lsblk --help | grep -q noempty; then
arg=" --noempty "
fi
set +e
while true; do
if ! kill -0 ${rbdpid}; then
printf 'rbd-nbd died in the background\n'
exit 1
fi
lsblk ${arg} ${device} > /dev/null 2>&1
ret="$?"
if [ "$ret" -eq '32' ]; then
sleep 0.5
continue
elif [ "$ret" -ne '0' ]; then
printf 'died waiting for %s to appear (%d)\n' "${device}" "${ret}"
exit 1
else
break
fi
sleep 0.5
done
set -e

lttng start
lttng_stop()
{
lttng stop
rm replay-${image}.bin
rbd-replay-prep ${image}/ust/uid/*/* replay-${image}.bin
unmap
}
trap lttng_stop EXIT

mkfs.ext4 ${device}
t="$(mktemp -d)"
mount ${device} -o discard "$t"
unmount()
{
umount ${device}
rmdir ${t}
lttng_stop
}
trap unmount EXIT

local count=1
local bs=4096
local status=""

dd if=/dev/random "of=$t/random" bs=${bs} count=1 oflag=sync

zero_ncommits ${image}

if ! status="$(wait_for_new_journal "$status" ${image})"; then
printf 'timeout\n'
exit 1
fi

rm "$t/random"
sync "$t"

zero_ncommits ${image}

if ! status="$(wait_for_new_journal "$status" ${image})"; then
printf 'timeout\n'
exit 1
fi

fstrim "$t"

zero_ncommits ${image}

if ! status="$(wait_for_new_journal "$status" ${image})"; then
printf 'timeout\n'
exit 1
fi

dd if=/dev/random "of=$t/random2" bs=${bs} count=1 oflag=sync

zero_ncommits ${image}

if ! status="$(wait_for_new_journal "$status" ${image})"; then
printf 'timeout\n'
exit 1
fi

dd if=/dev/random "of=$t/random3" bs=${bs} count=1 oflag=sync

zero_ncommits ${image}

if ! status="$(wait_for_new_journal "$status" ${image})"; then
printf 'timeout\n'
exit 1
fi
}

TESTS+=" rbd_journal_discard_replay"

#
# "main" follows
#

tests_to_run=()

cleanup=true

while [[ $# -gt 0 ]]; do
opt=$1

case "$opt" in
"-l")
do_list=1
;;
"--no-cleanup")
cleanup=false
;;
"--lttng")
shift
if [[ -z "$1" ]]; then
echo "missing argument to '--lttng'"
usage
exit 1
fi
lttng_to_run+=" $1"
;;
"-t")
shift
if [[ -z "$1" ]]; then
echo "missing argument to '-t'"
usage
exit 1
fi
tests_to_run+=" $1"
;;
"-h")
usage
exit 0
;;
esac
shift
done

if [[ $do_list -eq 1 ]]; then
list_tests
exit 0
fi

TMPDIR=/tmp/rbd_journal$$
mkdir $TMPDIR
if $cleanup; then
trap "rm -fr $TMPDIR" 0
fi

if test -z "$lttng_to_run"; then
lttng_to_run=""
fi

if test -z "$tests_to_run"; then
tests_to_run=""
fi

for i in $lttng_to_run; do
set -x
lttng_${i}
set +x
done

for i in $tests_to_run; do
set -x
test_${i}
set +x
done

echo OK
(2-2/2)