X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fqa%2Fworkunits%2Frbd%2Fimage_read.sh;fp=src%2Fceph%2Fqa%2Fworkunits%2Frbd%2Fimage_read.sh;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=907ce869bc44a863a55f46e940a434c190b4bc27;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/qa/workunits/rbd/image_read.sh b/src/ceph/qa/workunits/rbd/image_read.sh deleted file mode 100755 index 907ce86..0000000 --- a/src/ceph/qa/workunits/rbd/image_read.sh +++ /dev/null @@ -1,677 +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 -# April 10, 2013 - -################################################################ - -# The purpose of this test is to validate that data read from a -# mapped rbd image is what it's expected to be. -# -# By default it creates an image and fills it with some data. It -# then reads back the data at a series of offsets known to cover -# various situations (such as reading the beginning, end, or the -# entirety of an object, or doing a read that spans multiple -# objects), and stashes the results in a set of local files. -# -# It also creates and maps a snapshot of the original image after -# it's been filled, and reads back the same ranges of data from the -# snapshot. It then compares the data read back with what was read -# back from the original image, verifying they match. -# -# Clone functionality is tested as well, in which case a clone is -# made of the snapshot, and the same ranges of data are again read -# and compared with the original. In addition, a snapshot of that -# clone is created, and a clone of *that* snapshot is put through -# the same set of tests. (Clone testing can be optionally skipped.) - -################################################################ - -# Default parameter values. Environment variables, if set, will -# supercede these defaults. Such variables have names that begin -# with "IMAGE_READ_", for e.g. use IMAGE_READ_PAGE_SIZE=65536 -# to use 65536 as the page size. - -DEFAULT_VERBOSE=true -DEFAULT_TEST_CLONES=true -DEFAULT_LOCAL_FILES=false -DEFAULT_FORMAT=2 -DEFAULT_DOUBLE_ORDER=true -DEFAULT_HALF_ORDER=false -DEFAULT_PAGE_SIZE=4096 -DEFAULT_OBJECT_ORDER=22 -MIN_OBJECT_ORDER=12 # technically 9, but the rbd CLI enforces 12 -MAX_OBJECT_ORDER=32 - -PROGNAME=$(basename $0) - -ORIGINAL=original-$$ -SNAP1=snap1-$$ -CLONE1=clone1-$$ -SNAP2=snap2-$$ -CLONE2=clone2-$$ - -function err() { - if [ $# -gt 0 ]; then - echo "${PROGNAME}: $@" >&2 - fi - exit 2 -} - -function usage() { - if [ $# -gt 0 ]; then - echo "" >&2 - echo "${PROGNAME}: $@" >&2 - fi - echo "" >&2 - echo "Usage: ${PROGNAME} []" >&2 - echo "" >&2 - echo "options are:" >&2 - echo " -o object_order" >&2 - echo " must be ${MIN_OBJECT_ORDER}..${MAX_OBJECT_ORDER}" >&2 - echo " -p page_size (in bytes)" >&2 - echo " note: there must be at least 4 pages per object" >&2 - echo " -1" >&2 - echo " test using format 1 rbd images (default)" >&2 - echo " -2" >&2 - echo " test using format 2 rbd images" >&2 - echo " -c" >&2 - echo " also test rbd clone images (implies format 2)" >&2 - echo " -d" >&2 - echo " clone object order double its parent's (format 2)" >&2 - echo " -h" >&2 - echo " clone object order half of its parent's (format 2)" >&2 - echo " -l" >&2 - echo " use local files rather than rbd images" >&2 - echo " -v" >&2 - echo " disable reporting of what's going on" >&2 - echo "" >&2 - exit 1 -} - -function verbose() { - [ "${VERBOSE}" = true ] && echo "$@" - true # Don't let the verbose test spoil our return value -} - -function quiet() { - "$@" 2> /dev/null -} - -function boolean_toggle() { - [ $# -eq 1 ] || exit 99 - test "$1" = "true" && echo false || echo true -} - -function parseargs() { - local opts="o:p:12clv" - local lopts="order:,page_size:,local,clone,verbose" - local parsed - local clone_order_msg - - # use values from environment if available - VERBOSE="${IMAGE_READ_VERBOSE:-${DEFAULT_VERBOSE}}" - TEST_CLONES="${IMAGE_READ_TEST_CLONES:-${DEFAULT_TEST_CLONES}}" - LOCAL_FILES="${IMAGE_READ_LOCAL_FILES:-${DEFAULT_LOCAL_FILES}}" - DOUBLE_ORDER="${IMAGE_READ_DOUBLE_ORDER:-${DEFAULT_DOUBLE_ORDER}}" - HALF_ORDER="${IMAGE_READ_HALF_ORDER:-${DEFAULT_HALF_ORDER}}" - FORMAT="${IMAGE_READ_FORMAT:-${DEFAULT_FORMAT}}" - PAGE_SIZE="${IMAGE_READ_PAGE_SIZE:-${DEFAULT_PAGE_SIZE}}" - OBJECT_ORDER="${IMAGE_READ_OBJECT_ORDER:-${DEFAULT_OBJECT_ORDER}}" - - parsed=$(getopt -o "${opts}" -l "${lopts}" -n "${PROGNAME}" -- "$@") || - usage - eval set -- "${parsed}" - while true; do - case "$1" in - -v|--verbose) - VERBOSE=$(boolean_toggle "${VERBOSE}");; - -c|--clone) - TEST_CLONES=$(boolean_toggle "${TEST_CLONES}");; - -d|--double) - DOUBLE_ORDER=$(boolean_toggle "${DOUBLE_ORDER}");; - -h|--half) - HALF_ORDER=$(boolean_toggle "${HALF_ORDER}");; - -l|--local) - LOCAL_FILES=$(boolean_toggle "${LOCAL_FILES}");; - -1|-2) - FORMAT="${1:1}";; - -p|--page_size) - PAGE_SIZE="$2"; shift;; - -o|--order) - OBJECT_ORDER="$2"; shift;; - --) - shift; break;; - *) - err "getopt internal error" - esac - shift - done - [ $# -gt 0 ] && usage "excess arguments ($*)" - - if [ "${TEST_CLONES}" = true ]; then - # If we're using different object orders for clones, - # make sure the limits are updated accordingly. If - # both "half" and "double" are specified, just - # ignore them both. - if [ "${DOUBLE_ORDER}" = true ]; then - if [ "${HALF_ORDER}" = true ]; then - DOUBLE_ORDER=false - HALF_ORDER=false - else - ((MAX_OBJECT_ORDER -= 2)) - fi - elif [ "${HALF_ORDER}" = true ]; then - ((MIN_OBJECT_ORDER += 2)) - fi - fi - - [ "${OBJECT_ORDER}" -lt "${MIN_OBJECT_ORDER}" ] && - usage "object order (${OBJECT_ORDER}) must be" \ - "at least ${MIN_OBJECT_ORDER}" - [ "${OBJECT_ORDER}" -gt "${MAX_OBJECT_ORDER}" ] && - usage "object order (${OBJECT_ORDER}) must be" \ - "at most ${MAX_OBJECT_ORDER}" - - if [ "${TEST_CLONES}" = true ]; then - if [ "${DOUBLE_ORDER}" = true ]; then - ((CLONE1_ORDER = OBJECT_ORDER + 1)) - ((CLONE2_ORDER = OBJECT_ORDER + 2)) - clone_order_msg="double" - elif [ "${HALF_ORDER}" = true ]; then - ((CLONE1_ORDER = OBJECT_ORDER - 1)) - ((CLONE2_ORDER = OBJECT_ORDER - 2)) - clone_order_msg="half of" - else - CLONE1_ORDER="${OBJECT_ORDER}" - CLONE2_ORDER="${OBJECT_ORDER}" - clone_order_msg="the same as" - fi - fi - - [ "${TEST_CLONES}" != true ] || FORMAT=2 - - OBJECT_SIZE=$(echo "2 ^ ${OBJECT_ORDER}" | bc) - OBJECT_PAGES=$(echo "${OBJECT_SIZE} / ${PAGE_SIZE}" | bc) - IMAGE_SIZE=$((2 * 16 * OBJECT_SIZE / (1024 * 1024))) - [ "${IMAGE_SIZE}" -lt 1 ] && IMAGE_SIZE=1 - IMAGE_OBJECTS=$((IMAGE_SIZE * (1024 * 1024) / OBJECT_SIZE)) - - [ "${OBJECT_PAGES}" -lt 4 ] && - usage "object size (${OBJECT_SIZE}) must be" \ - "at least 4 * page size (${PAGE_SIZE})" - - echo "parameters for this run:" - echo " format ${FORMAT} images will be tested" - echo " object order is ${OBJECT_ORDER}, so" \ - "objects are ${OBJECT_SIZE} bytes" - echo " page size is ${PAGE_SIZE} bytes, so" \ - "there are are ${OBJECT_PAGES} pages in an object" - echo " derived image size is ${IMAGE_SIZE} MB, so" \ - "there are ${IMAGE_OBJECTS} objects in an image" - if [ "${TEST_CLONES}" = true ]; then - echo " clone functionality will be tested" - echo " object size for a clone will be ${clone_order_msg}" - echo " the object size of its parent image" - fi - - true # Don't let the clones test spoil our return value -} - -function image_dev_path() { - [ $# -eq 1 ] || exit 99 - local image_name="$1" - - if [ "${LOCAL_FILES}" = true ]; then - echo "${TEMP}/${image_name}" - return - fi - - echo "/dev/rbd/rbd/${image_name}" -} - -function out_data_dir() { - [ $# -lt 2 ] || exit 99 - local out_data="${TEMP}/data" - local image_name - - if [ $# -eq 1 ]; then - image_name="$1" - echo "${out_data}/${image_name}" - else - echo "${out_data}" - fi -} - -function setup() { - verbose "===== setting up =====" - TEMP=$(mktemp -d /tmp/rbd_image_read.XXXXX) - mkdir -p $(out_data_dir) - - # create and fill the original image with some data - create_image "${ORIGINAL}" - map_image "${ORIGINAL}" - fill_original - - # create a snapshot of the original - create_image_snap "${ORIGINAL}" "${SNAP1}" - map_image_snap "${ORIGINAL}" "${SNAP1}" - - if [ "${TEST_CLONES}" = true ]; then - # create a clone of the original snapshot - create_snap_clone "${ORIGINAL}" "${SNAP1}" \ - "${CLONE1}" "${CLONE1_ORDER}" - map_image "${CLONE1}" - - # create a snapshot of that clone - create_image_snap "${CLONE1}" "${SNAP2}" - map_image_snap "${CLONE1}" "${SNAP2}" - - # create a clone of that clone's snapshot - create_snap_clone "${CLONE1}" "${SNAP2}" \ - "${CLONE2}" "${CLONE2_ORDER}" - map_image "${CLONE2}" - fi -} - -function teardown() { - verbose "===== cleaning up =====" - if [ "${TEST_CLONES}" = true ]; then - unmap_image "${CLONE2}" || true - destroy_snap_clone "${CLONE1}" "${SNAP2}" "${CLONE2}" || true - - unmap_image_snap "${CLONE1}" "${SNAP2}" || true - destroy_image_snap "${CLONE1}" "${SNAP2}" || true - - unmap_image "${CLONE1}" || true - destroy_snap_clone "${ORIGINAL}" "${SNAP1}" "${CLONE1}" || true - fi - unmap_image_snap "${ORIGINAL}" "${SNAP1}" || true - destroy_image_snap "${ORIGINAL}" "${SNAP1}" || true - unmap_image "${ORIGINAL}" || true - destroy_image "${ORIGINAL}" || true - - rm -rf $(out_data_dir) - rmdir "${TEMP}" -} - -function create_image() { - [ $# -eq 1 ] || exit 99 - local image_name="$1" - local image_path - local bytes - - verbose "creating image \"${image_name}\"" - if [ "${LOCAL_FILES}" = true ]; then - image_path=$(image_dev_path "${image_name}") - bytes=$(echo "${IMAGE_SIZE} * 1024 * 1024 - 1" | bc) - quiet dd if=/dev/zero bs=1 count=1 seek="${bytes}" \ - of="${image_path}" - return - fi - - rbd create "${image_name}" --image-format "${FORMAT}" \ - --size "${IMAGE_SIZE}" --order "${OBJECT_ORDER}" \ - --image-shared -} - -function destroy_image() { - [ $# -eq 1 ] || exit 99 - local image_name="$1" - local image_path - - verbose "destroying image \"${image_name}\"" - if [ "${LOCAL_FILES}" = true ]; then - image_path=$(image_dev_path "${image_name}") - rm -f "${image_path}" - return - fi - - rbd rm "${image_name}" -} - -function map_image() { - [ $# -eq 1 ] || exit 99 - local image_name="$1" # can be image@snap too - - if [ "${LOCAL_FILES}" = true ]; then - return - fi - - sudo rbd map "${image_name}" -} - -function unmap_image() { - [ $# -eq 1 ] || exit 99 - local image_name="$1" # can be image@snap too - local image_path - - if [ "${LOCAL_FILES}" = true ]; then - return - fi - image_path=$(image_dev_path "${image_name}") - - if [ -e "${image_path}" ]; then - sudo rbd unmap "${image_path}" - fi -} - -function map_image_snap() { - [ $# -eq 2 ] || exit 99 - local image_name="$1" - local snap_name="$2" - local image_snap - - if [ "${LOCAL_FILES}" = true ]; then - return - fi - - image_snap="${image_name}@${snap_name}" - map_image "${image_snap}" -} - -function unmap_image_snap() { - [ $# -eq 2 ] || exit 99 - local image_name="$1" - local snap_name="$2" - local image_snap - - if [ "${LOCAL_FILES}" = true ]; then - return - fi - - image_snap="${image_name}@${snap_name}" - unmap_image "${image_snap}" -} - -function create_image_snap() { - [ $# -eq 2 ] || exit 99 - local image_name="$1" - local snap_name="$2" - local image_snap="${image_name}@${snap_name}" - local image_path - local snap_path - - verbose "creating snapshot \"${snap_name}\"" \ - "of image \"${image_name}\"" - if [ "${LOCAL_FILES}" = true ]; then - image_path=$(image_dev_path "${image_name}") - snap_path=$(image_dev_path "${image_snap}") - - cp "${image_path}" "${snap_path}" - return - fi - - rbd snap create "${image_snap}" -} - -function destroy_image_snap() { - [ $# -eq 2 ] || exit 99 - local image_name="$1" - local snap_name="$2" - local image_snap="${image_name}@${snap_name}" - local snap_path - - verbose "destroying snapshot \"${snap_name}\"" \ - "of image \"${image_name}\"" - if [ "${LOCAL_FILES}" = true ]; then - snap_path=$(image_dev_path "${image_snap}") - rm -rf "${snap_path}" - return - fi - - rbd snap rm "${image_snap}" -} - -function create_snap_clone() { - [ $# -eq 4 ] || exit 99 - local image_name="$1" - local snap_name="$2" - local clone_name="$3" - local clone_order="$4" - local image_snap="${image_name}@${snap_name}" - local snap_path - local clone_path - - verbose "creating clone image \"${clone_name}\"" \ - "of image snapshot \"${image_name}@${snap_name}\"" - if [ "${LOCAL_FILES}" = true ]; then - snap_path=$(image_dev_path "${image_name}@${snap_name}") - clone_path=$(image_dev_path "${clone_name}") - - cp "${snap_path}" "${clone_path}" - return - fi - - rbd snap protect "${image_snap}" - rbd clone --order "${clone_order}" --image-shared \ - "${image_snap}" "${clone_name}" -} - -function destroy_snap_clone() { - [ $# -eq 3 ] || exit 99 - local image_name="$1" - local snap_name="$2" - local clone_name="$3" - local image_snap="${image_name}@${snap_name}" - local clone_path - - verbose "destroying clone image \"${clone_name}\"" - if [ "${LOCAL_FILES}" = true ]; then - clone_path=$(image_dev_path "${clone_name}") - - rm -rf "${clone_path}" - return - fi - - rbd rm "${clone_name}" - rbd snap unprotect "${image_snap}" -} - -# function that produces "random" data with which to fill the image -function source_data() { - while quiet dd if=/bin/bash skip=$(($$ % 199)) bs="${PAGE_SIZE}"; do - : # Just do the dd - done -} - -function fill_original() { - local image_path=$(image_dev_path "${ORIGINAL}") - - verbose "filling original image" - # Fill 16 objects worth of "random" data - source_data | - quiet dd bs="${PAGE_SIZE}" count=$((16 * OBJECT_PAGES)) \ - of="${image_path}" -} - -function do_read() { - [ $# -eq 3 -o $# -eq 4 ] || exit 99 - local image_name="$1" - local offset="$2" - local length="$3" - [ "${length}" -gt 0 ] || err "do_read: length must be non-zero" - local image_path=$(image_dev_path "${image_name}") - local out_data=$(out_data_dir "${image_name}") - local range=$(printf "%06u~%04u" "${offset}" "${length}") - local out_file - - [ $# -eq 4 ] && offset=$((offset + 16 * OBJECT_PAGES)) - - verbose "reading \"${image_name}\" pages ${range}" - - out_file="${out_data}/pages_${range}" - - quiet dd bs="${PAGE_SIZE}" skip="${offset}" count="${length}" \ - if="${image_path}" of="${out_file}" -} - -function one_pass() { - [ $# -eq 1 -o $# -eq 2 ] || exit 99 - local image_name="$1" - local extended - [ $# -eq 2 ] && extended="true" - local offset - local length - - offset=0 - - # +-----------+-----------+--- - # |X:X:X...X:X| : : ... : | : - # +-----------+-----------+--- - length="${OBJECT_PAGES}" - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+--- - # : |X: : ... : | : - # ---+-----------+--- - length=1 - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+--- - # : | :X: ... : | : - # ---+-----------+--- - length=1 - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+--- - # : | : :X...X: | : - # ---+-----------+--- - length=$((OBJECT_PAGES - 3)) - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+--- - # : | : : ... :X| : - # ---+-----------+--- - length=1 - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+--- - # : |X:X:X...X:X| : - # ---+-----------+--- - length="${OBJECT_PAGES}" - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - offset=$((offset + 1)) # skip 1 - - # ---+-----------+--- - # : | :X:X...X:X| : - # ---+-----------+--- - length=$((OBJECT_PAGES - 1)) - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+-----------+--- - # : |X:X:X...X:X|X: : ... : | : - # ---+-----------+-----------+--- - length=$((OBJECT_PAGES + 1)) - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+-----------+--- - # : | :X:X...X:X|X: : ... : | : - # ---+-----------+-----------+--- - length="${OBJECT_PAGES}" - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+-----------+--- - # : | :X:X...X:X|X:X: ... : | : - # ---+-----------+-----------+--- - length=$((OBJECT_PAGES + 1)) - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # ---+-----------+-----------+--- - # : | : :X...X:X|X:X:X...X:X| : - # ---+-----------+-----------+--- - length=$((2 * OBJECT_PAGES + 2)) - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - offset=$((offset + 1)) # skip 1 - - # ---+-----------+-----------+----- - # : | :X:X...X:X|X:X:X...X:X|X: : - # ---+-----------+-----------+----- - length=$((2 * OBJECT_PAGES)) - do_read "${image_name}" "${offset}" "${length}" ${extended} - offset=$((offset + length)) - - # --+-----------+-----------+-------- - # : | :X:X...X:X|X:X:X...X:X|X:X: : - # --+-----------+-----------+-------- - length=2049 - length=$((2 * OBJECT_PAGES + 1)) - do_read "${image_name}" "${offset}" "${length}" ${extended} - # offset=$((offset + length)) -} - -function run_using() { - [ $# -eq 1 ] || exit 99 - local image_name="$1" - local out_data=$(out_data_dir "${image_name}") - - verbose "===== running using \"${image_name}\" =====" - mkdir -p "${out_data}" - one_pass "${image_name}" - one_pass "${image_name}" extended -} - -function compare() { - [ $# -eq 1 ] || exit 99 - local image_name="$1" - local out_data=$(out_data_dir "${image_name}") - local original=$(out_data_dir "${ORIGINAL}") - - verbose "===== comparing \"${image_name}\" =====" - for i in $(ls "${original}"); do - verbose compare "\"${image_name}\" \"${i}\"" - cmp "${original}/${i}" "${out_data}/${i}" - done - [ "${image_name}" = "${ORIGINAL}" ] || rm -rf "${out_data}" -} - -function doit() { - [ $# -eq 1 ] || exit 99 - local image_name="$1" - - run_using "${image_name}" - compare "${image_name}" -} - -########## Start - -parseargs "$@" - -trap teardown EXIT HUP INT -setup - -run_using "${ORIGINAL}" -doit "${ORIGINAL}@${SNAP1}" -if [ "${TEST_CLONES}" = true ]; then - doit "${CLONE1}" - doit "${CLONE1}@${SNAP2}" - doit "${CLONE2}" -fi -rm -rf $(out_data_dir "${ORIGINAL}") - -echo "Success!" - -exit 0