diff options
author | David Disseldorp <ddiss@samba.org> | 2016-12-06 13:03:27 +0100 |
---|---|---|
committer | Amitay Isaacs <amitay@samba.org> | 2016-12-09 07:59:33 +0100 |
commit | f5536ce1f6ab4e0764e4e806fb0fca5c43051f86 (patch) | |
tree | dc3adbba1366295ef157230302661c85fa37faaa /ctdb/utils | |
parent | 8aba284fc493815592de77847c6a990866a7afce (diff) | |
download | samba-f5536ce1f6ab4e0764e4e806fb0fca5c43051f86.tar.gz |
ctdb: add test script for ctdb_mutex_ceph_rados_helper
This standalone test script performs the following:
- using ctdb_mutex_ceph_rados_helper, take a lock on the Ceph RADOS
object a CLUSTER/$POOL/$OBJECT using the Ceph keyring for $USER
+ confirm that lock is obtained, via ctdb_mutex_ceph_rados_helper "0"
output
- check RADOS object lock state, using the "rados lock info" command
- attempt to obtain the lock again, using ctdb_mutex_ceph_rados_helper
+ confirm that the lock is not successfully taken
- tell the first locker to drop the lock and exit, via SIGTERM
- once the first locker has exited, attempt to get the lock again
+ confirm that this attempt succeeds
Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Autobuild-User(master): Amitay Isaacs <amitay@samba.org>
Autobuild-Date(master): Fri Dec 9 07:59:33 CET 2016 on sn-devel-144
Diffstat (limited to 'ctdb/utils')
-rwxr-xr-x | ctdb/utils/ceph/test_ceph_rados_reclock.sh | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/ctdb/utils/ceph/test_ceph_rados_reclock.sh b/ctdb/utils/ceph/test_ceph_rados_reclock.sh new file mode 100755 index 00000000000..1adacf6a27c --- /dev/null +++ b/ctdb/utils/ceph/test_ceph_rados_reclock.sh @@ -0,0 +1,151 @@ +#!/bin/bash +# standalone test for ctdb_mutex_ceph_rados_helper +# +# Copyright (C) David Disseldorp 2016 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +# XXX The following parameters may require configuration: +CLUSTER="ceph" # Name of the Ceph cluster under test +USER="client.admin" # Ceph user - a keyring must exist +POOL="rbd" # RADOS pool - must exist +OBJECT="ctdb_reclock" # RADOS object: target for lock requests + +# test procedure: +# - using ctdb_mutex_ceph_rados_helper, take a lock on the Ceph RADOS object at +# CLUSTER/$POOL/$OBJECT using the Ceph keyring for $USER +# + confirm that lock is obtained, via ctdb_mutex_ceph_rados_helper "0" output +# - check RADOS object lock state, using the "rados lock info" command +# - attempt to obtain the lock again, using ctdb_mutex_ceph_rados_helper +# + confirm that the lock is not successfully taken ("1" output=contention) +# - tell the first locker to drop the lock and exit, via SIGTERM +# - once the first locker has exited, attempt to get the lock again +# + confirm that this attempt succeeds + +function _fail() { + echo "FAILED: $*" + exit 1 +} + +# this test requires the Ceph "rados" binary, and "jq" json parser +which jq > /dev/null || exit 1 +which rados > /dev/null || exit 1 +which ctdb_mutex_ceph_rados_helper || exit 1 + +TMP_DIR="$(mktemp --directory)" || exit 1 +rados -p "$POOL" rm "$OBJECT" + +(ctdb_mutex_ceph_rados_helper "$CLUSTER" "$USER" "$POOL" "$OBJECT" \ + > ${TMP_DIR}/first) & +locker_pid=$! + +# TODO wait for ctdb_mutex_ceph_rados_helper to write one byte to stdout, +# indicating lock acquisition success/failure +sleep 1 + +first_out=$(cat ${TMP_DIR}/first) +[ "$first_out" == "0" ] \ + || _fail "expected lock acquisition (0), but got $first_out" + +rados -p "$POOL" lock info "$OBJECT" ctdb_reclock_mutex \ + > ${TMP_DIR}/lock_state_first + +# echo "with lock: `cat ${TMP_DIR}/lock_state_first`" + +LOCK_NAME="$(jq -r '.name' ${TMP_DIR}/lock_state_first)" +[ "$LOCK_NAME" == "ctdb_reclock_mutex" ] \ + || _fail "unexpected lock name: $LOCK_NAME" +LOCK_TYPE="$(jq -r '.type' ${TMP_DIR}/lock_state_first)" +[ "$LOCK_TYPE" == "exclusive" ] \ + || _fail "unexpected lock type: $LOCK_TYPE" + +LOCK_COUNT="$(jq -r '.lockers | length' ${TMP_DIR}/lock_state_first)" +[ $LOCK_COUNT -eq 1 ] || _fail "expected 1 lock in rados state, got $LOCK_COUNT" +LOCKER_COOKIE="$(jq -r '.lockers[0].cookie' ${TMP_DIR}/lock_state_first)" +[ "$LOCKER_COOKIE" == "ctdb_reclock_mutex" ] \ + || _fail "unexpected locker cookie: $LOCKER_COOKIE" +LOCKER_DESC="$(jq -r '.lockers[0].description' ${TMP_DIR}/lock_state_first)" +[ "$LOCKER_DESC" == "CTDB recovery lock" ] \ + || _fail "unexpected locker description: $LOCKER_DESC" + +# second attempt while first is still holding the lock - expect failure +ctdb_mutex_ceph_rados_helper "$CLUSTER" "$USER" "$POOL" "$OBJECT" \ + > ${TMP_DIR}/second +second_out=$(cat ${TMP_DIR}/second) +[ "$second_out" == "1" ] \ + || _fail "expected lock contention (1), but got $second_out" + +# confirm lock state didn't change +rados -p "$POOL" lock info "$OBJECT" ctdb_reclock_mutex \ + > ${TMP_DIR}/lock_state_second + +diff ${TMP_DIR}/lock_state_first ${TMP_DIR}/lock_state_second \ + || _fail "unexpected lock state change" + +# tell first locker to drop the lock and terminate +kill $locker_pid || exit 1 + +wait $locker_pid &> /dev/null + +rados -p "$POOL" lock info "$OBJECT" ctdb_reclock_mutex \ + > ${TMP_DIR}/lock_state_third +# echo "without lock: `cat ${TMP_DIR}/lock_state_third`" + +LOCK_NAME="$(jq -r '.name' ${TMP_DIR}/lock_state_third)" +[ "$LOCK_NAME" == "ctdb_reclock_mutex" ] \ + || _fail "unexpected lock name: $LOCK_NAME" +LOCK_TYPE="$(jq -r '.type' ${TMP_DIR}/lock_state_third)" +[ "$LOCK_TYPE" == "exclusive" ] \ + || _fail "unexpected lock type: $LOCK_TYPE" + +LOCK_COUNT="$(jq -r '.lockers | length' ${TMP_DIR}/lock_state_third)" +[ $LOCK_COUNT -eq 0 ] \ + || _fail "didn\'t expect any locks in rados state, got $LOCK_COUNT" + +exec >${TMP_DIR}/third -- ctdb_mutex_ceph_rados_helper "$CLUSTER" "$USER" "$POOL" "$OBJECT" & +locker_pid=$! + +sleep 1 + +rados -p "$POOL" lock info "$OBJECT" ctdb_reclock_mutex \ + > ${TMP_DIR}/lock_state_fourth +# echo "with lock again: `cat ${TMP_DIR}/lock_state_fourth`" + +LOCK_NAME="$(jq -r '.name' ${TMP_DIR}/lock_state_fourth)" +[ "$LOCK_NAME" == "ctdb_reclock_mutex" ] \ + || _fail "unexpected lock name: $LOCK_NAME" +LOCK_TYPE="$(jq -r '.type' ${TMP_DIR}/lock_state_fourth)" +[ "$LOCK_TYPE" == "exclusive" ] \ + || _fail "unexpected lock type: $LOCK_TYPE" + +LOCK_COUNT="$(jq -r '.lockers | length' ${TMP_DIR}/lock_state_fourth)" +[ $LOCK_COUNT -eq 1 ] || _fail "expected 1 lock in rados state, got $LOCK_COUNT" +LOCKER_COOKIE="$(jq -r '.lockers[0].cookie' ${TMP_DIR}/lock_state_fourth)" +[ "$LOCKER_COOKIE" == "ctdb_reclock_mutex" ] \ + || _fail "unexpected locker cookie: $LOCKER_COOKIE" +LOCKER_DESC="$(jq -r '.lockers[0].description' ${TMP_DIR}/lock_state_fourth)" +[ "$LOCKER_DESC" == "CTDB recovery lock" ] \ + || _fail "unexpected locker description: $LOCKER_DESC" + +kill $locker_pid || exit 1 +wait $locker_pid &> /dev/null + +third_out=$(cat ${TMP_DIR}/third) +[ "$third_out" == "0" ] \ + || _fail "expected lock acquisition (0), but got $third_out" + +rm ${TMP_DIR}/* +rmdir $TMP_DIR + +echo "$0: all tests passed" |