X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fqa%2Fworkunits%2Frbd%2Fconcurrent.sh;fp=src%2Fceph%2Fqa%2Fworkunits%2Frbd%2Fconcurrent.sh;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=e2fb7974724ba7e0371167e74ea8127549fad470;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/qa/workunits/rbd/concurrent.sh b/src/ceph/qa/workunits/rbd/concurrent.sh deleted file mode 100755 index e2fb797..0000000 --- a/src/ceph/qa/workunits/rbd/concurrent.sh +++ /dev/null @@ -1,375 +0,0 @@ -#!/bin/bash -e - -# Copyright (C) 2013 Inktank Storage, Inc. -# -# This is free software; see the source for copying conditions. -# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. -# -# This 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 version 2. - -# Alex Elder -# January 29, 2013 - -################################################################ - -# The purpose of this test is to exercise paths through the rbd -# code, making sure no bad pointer references or invalid reference -# count operations occur in the face of concurrent activity. -# -# Each pass of the test creates an rbd image, maps it, and writes -# some data into the image. It also reads some data from all of the -# other images that exist at the time the pass executes. Finally, -# the image is unmapped and removed. The image removal completes in -# the background. -# -# An iteration of the test consists of performing some number of -# passes, initating each pass as a background job, and finally -# sleeping for a variable delay. The delay is initially a specified -# value, but each iteration shortens that proportionally, such that -# the last iteration will not delay at all. -# -# The result exercises concurrent creates and deletes of rbd images, -# writes to new images, reads from both written and unwritten image -# data (including reads concurrent with writes), and attempts to -# unmap images being read. - -# Usage: concurrent [-i ] [-c ] [-d ] -# -# Exit status: -# 0: success -# 1: usage error -# 2: other runtime error -# 99: argument count error (programming error) -# 100: getopt error (internal error) - -################################################################ - -set -x - -# Default flag values; RBD_CONCURRENT_ITER names are intended -# to be used in yaml scripts to pass in alternate values, e.g.: -# env: -# RBD_CONCURRENT_ITER: 20 -# RBD_CONCURRENT_COUNT: 5 -# RBD_CONCURRENT_DELAY: 3 -ITER_DEFAULT=${RBD_CONCURRENT_ITER:-100} -COUNT_DEFAULT=${RBD_CONCURRENT_COUNT:-5} -DELAY_DEFAULT=${RBD_CONCURRENT_DELAY:-5} # seconds - -CEPH_SECRET_FILE=${CEPH_SECRET_FILE:-} -CEPH_ID=${CEPH_ID:-admin} -SECRET_ARGS="" -if [ "${CEPH_SECRET_FILE}" ]; then - SECRET_ARGS="--secret $CEPH_SECRET_FILE" -fi - -################################################################ - -function setup() { - ID_MAX_DIR=$(mktemp -d /tmp/image_max_id.XXXXX) - ID_COUNT_DIR=$(mktemp -d /tmp/image_ids.XXXXXX) - NAMES_DIR=$(mktemp -d /tmp/image_names.XXXXXX) - SOURCE_DATA=$(mktemp /tmp/source_data.XXXXXX) - - # Use urandom to generate SOURCE_DATA - dd if=/dev/urandom of=${SOURCE_DATA} bs=2048 count=66 \ - >/dev/null 2>&1 - - # List of rbd id's *not* created by this script - export INITIAL_RBD_IDS=$(ls /sys/bus/rbd/devices) - - # Set up some environment for normal teuthology test setup. - # This really should not be necessary but I found it was. - - export CEPH_ARGS=" --name client.0" -} - -function cleanup() { - [ ! "${ID_MAX_DIR}" ] && return - local id - local image - - # Unmap mapped devices - for id in $(rbd_ids); do - image=$(cat "/sys/bus/rbd/devices/${id}/name") - rbd_unmap_image "${id}" - rbd_destroy_image "${image}" - done - # Get any leftover images - for image in $(rbd ls 2>/dev/null); do - rbd_destroy_image "${image}" - done - wait - sync - rm -f "${SOURCE_DATA}" - [ -d "${NAMES_DIR}" ] && rmdir "${NAMES_DIR}" - echo "Max concurrent rbd image count was $(get_max "${ID_COUNT_DIR}")" - rm -rf "${ID_COUNT_DIR}" - echo "Max rbd image id was $(get_max "${ID_MAX_DIR}")" - rm -rf "${ID_MAX_DIR}" -} - -function get_max() { - [ $# -eq 1 ] || exit 99 - local dir="$1" - - ls -U "${dir}" | sort -n | tail -1 -} - -trap cleanup HUP INT QUIT - -# print a usage message and quit -# -# if a message is supplied, print that first, and then exit -# with non-zero status -function usage() { - if [ $# -gt 0 ]; then - echo "" >&2 - echo "$@" >&2 - fi - - echo "" >&2 - echo "Usage: ${PROGNAME} " >&2 - echo "" >&2 - echo " options:" >&2 - echo " -h or --help" >&2 - echo " show this message" >&2 - echo " -i or --iterations" >&2 - echo " iteration count (1 or more)" >&2 - echo " -c or --count" >&2 - echo " images created per iteration (1 or more)" >&2 - echo " -d or --delay" >&2 - echo " maximum delay between iterations" >&2 - echo "" >&2 - echo " defaults:" >&2 - echo " iterations: ${ITER_DEFAULT}" - echo " count: ${COUNT_DEFAULT}" - echo " delay: ${DELAY_DEFAULT} (seconds)" - echo "" >&2 - - [ $# -gt 0 ] && exit 1 - - exit 0 # This is used for a --help -} - -# parse command line arguments -function parseargs() { - ITER="${ITER_DEFAULT}" - COUNT="${COUNT_DEFAULT}" - DELAY="${DELAY_DEFAULT}" - - # Short option flags - SHORT_OPTS="" - SHORT_OPTS="${SHORT_OPTS},h" - SHORT_OPTS="${SHORT_OPTS},i:" - SHORT_OPTS="${SHORT_OPTS},c:" - SHORT_OPTS="${SHORT_OPTS},d:" - - # Short option flags - LONG_OPTS="" - LONG_OPTS="${LONG_OPTS},help" - LONG_OPTS="${LONG_OPTS},iterations:" - LONG_OPTS="${LONG_OPTS},count:" - LONG_OPTS="${LONG_OPTS},delay:" - - TEMP=$(getopt --name "${PROGNAME}" \ - --options "${SHORT_OPTS}" \ - --longoptions "${LONG_OPTS}" \ - -- "$@") - eval set -- "$TEMP" - - while [ "$1" != "--" ]; do - case "$1" in - -h|--help) - usage - ;; - -i|--iterations) - ITER="$2" - [ "${ITER}" -lt 1 ] && - usage "bad iterations value" - shift - ;; - -c|--count) - COUNT="$2" - [ "${COUNT}" -lt 1 ] && - usage "bad count value" - shift - ;; - -d|--delay) - DELAY="$2" - shift - ;; - *) - exit 100 # Internal error - ;; - esac - shift - done - shift -} - -function rbd_ids() { - [ $# -eq 0 ] || exit 99 - local ids - local i - - [ -d /sys/bus/rbd ] || return - ids=" $(echo $(ls /sys/bus/rbd/devices)) " - for i in ${INITIAL_RBD_IDS}; do - ids=${ids/ ${i} / } - done - echo ${ids} -} - -function update_maxes() { - local ids="$@" - local last_id - # These aren't 100% safe against concurrent updates but it - # should be pretty close - count=$(echo ${ids} | wc -w) - touch "${ID_COUNT_DIR}/${count}" - last_id=${ids% } - last_id=${last_id##* } - touch "${ID_MAX_DIR}/${last_id}" -} - -function rbd_create_image() { - [ $# -eq 0 ] || exit 99 - local image=$(basename $(mktemp "${NAMES_DIR}/image.XXXXXX")) - - rbd create "${image}" --size=1024 - echo "${image}" -} - -function rbd_image_id() { - [ $# -eq 1 ] || exit 99 - local image="$1" - - grep -l "${image}" /sys/bus/rbd/devices/*/name 2>/dev/null | - cut -d / -f 6 -} - -function rbd_map_image() { - [ $# -eq 1 ] || exit 99 - local image="$1" - local id - - sudo rbd map "${image}" --user "${CEPH_ID}" ${SECRET_ARGS} \ - > /dev/null 2>&1 - - id=$(rbd_image_id "${image}") - echo "${id}" -} - -function rbd_write_image() { - [ $# -eq 1 ] || exit 99 - local id="$1" - - # Offset and size here are meant to ensure beginning and end - # cross both (4K or 64K) page and (4MB) rbd object boundaries. - # It assumes the SOURCE_DATA file has size 66 * 2048 bytes - dd if="${SOURCE_DATA}" of="/dev/rbd${id}" bs=2048 seek=2015 \ - > /dev/null 2>&1 -} - -# All starting and ending offsets here are selected so they are not -# aligned on a (4 KB or 64 KB) page boundary -function rbd_read_image() { - [ $# -eq 1 ] || exit 99 - local id="$1" - - # First read starting and ending at an offset before any - # written data. The osd zero-fills data read from an - # existing rbd object, but before any previously-written - # data. - dd if="/dev/rbd${id}" of=/dev/null bs=2048 count=34 skip=3 \ - > /dev/null 2>&1 - # Next read starting at an offset before any written data, - # but ending at an offset that includes data that's been - # written. The osd zero-fills unwritten data at the - # beginning of a read. - dd if="/dev/rbd${id}" of=/dev/null bs=2048 count=34 skip=1983 \ - > /dev/null 2>&1 - # Read the data at offset 2015 * 2048 bytes (where it was - # written) and make sure it matches the original data. - cmp --quiet "${SOURCE_DATA}" "/dev/rbd${id}" 0 4126720 || - echo "MISMATCH!!!" - # Now read starting within the pre-written data, but ending - # beyond it. The rbd client zero-fills the unwritten - # portion at the end of a read. - dd if="/dev/rbd${id}" of=/dev/null bs=2048 count=34 skip=2079 \ - > /dev/null 2>&1 - # Now read starting from an unwritten range within a written - # rbd object. The rbd client zero-fills this. - dd if="/dev/rbd${id}" of=/dev/null bs=2048 count=34 skip=2115 \ - > /dev/null 2>&1 - # Finally read from an unwritten region which would reside - # in a different (non-existent) osd object. The osd client - # zero-fills unwritten data when the target object doesn't - # exist. - dd if="/dev/rbd${id}" of=/dev/null bs=2048 count=34 skip=4098 \ - > /dev/null 2>&1 -} - -function rbd_unmap_image() { - [ $# -eq 1 ] || exit 99 - local id="$1" - - sudo rbd unmap "/dev/rbd${id}" -} - -function rbd_destroy_image() { - [ $# -eq 1 ] || exit 99 - local image="$1" - - # Don't wait for it to complete, to increase concurrency - rbd rm "${image}" >/dev/null 2>&1 & - rm -f "${NAMES_DIR}/${image}" -} - -function one_pass() { - [ $# -eq 0 ] || exit 99 - local image - local id - local ids - local i - - image=$(rbd_create_image) - id=$(rbd_map_image "${image}") - ids=$(rbd_ids) - update_maxes "${ids}" - for i in ${rbd_ids}; do - if [ "${i}" -eq "${id}" ]; then - rbd_write_image "${i}" - else - rbd_read_image "${i}" - fi - done - rbd_unmap_image "${id}" - rbd_destroy_image "${image}" -} - -################################################################ - -parseargs "$@" - -setup - -for iter in $(seq 1 "${ITER}"); do - for count in $(seq 1 "${COUNT}"); do - one_pass & - done - # Sleep longer at first, overlap iterations more later. - # Use awk to get sub-second granularity (see sleep(1)). - sleep $(echo "${DELAY}" "${iter}" "${ITER}" | - awk '{ printf("%.2f\n", $1 - $1 * $2 / $3);}') - -done -wait - -cleanup - -exit 0