bdev/error: Add new bdev/error to inject errors in bdev layer.

Change-Id: I3c68cb5911b3662dbb35f551dc291d5ebdd84bf6
Signed-off-by: Cunyin Chang <cunyin.chang@intel.com>
This commit is contained in:
Cunyin Chang 2017-03-17 14:10:32 +08:00 committed by Jim Harris
parent 679e2831bd
commit 32b4ab71a2
8 changed files with 593 additions and 4 deletions

View File

@ -38,7 +38,7 @@ CFLAGS += $(ENV_CFLAGS) -I.
C_SRCS = bdev.c scsi_nvme.c
LIBNAME = bdev
DIRS-y += malloc null nvme rpc split
DIRS-y += error malloc null nvme rpc split
ifeq ($(OS),Linux)
DIRS-y += aio

41
lib/bdev/error/Makefile Normal file
View File

@ -0,0 +1,41 @@
#
# BSD LICENSE
#
# Copyright (c) Intel Corporation.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
CFLAGS += $(ENV_CFLAGS) -I$(SPDK_ROOT_DIR)/lib/bdev/
C_SRCS = vbdev_error.c vbdev_error_rpc.c
LIBNAME = vbdev_error
include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk

View File

@ -0,0 +1,285 @@
/*-
* BSD LICENSE
*
* Copyright (c) Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is a module for test purpose which will simulate error cases for bdev.
*/
#include "spdk/stdinc.h"
#include "spdk/rpc.h"
#include "spdk/conf.h"
#include "spdk/endian.h"
#include "spdk/nvme_spec.h"
#include "spdk_internal/bdev.h"
#include "spdk_internal/log.h"
#include "vbdev_error.h"
/* Context for each error bdev */
struct vbdev_error_disk {
struct spdk_bdev disk;
struct spdk_bdev *base_bdev;
TAILQ_ENTRY(vbdev_error_disk) tailq;
};
static uint32_t g_io_type_mask;
static uint32_t g_error_num;
static pthread_mutex_t g_vbdev_error_mutex = PTHREAD_MUTEX_INITIALIZER;
static TAILQ_HEAD(, vbdev_error_disk) g_vbdev_error_disks = TAILQ_HEAD_INITIALIZER(
g_vbdev_error_disks);
void
spdk_vbdev_inject_error(uint32_t io_type_mask, uint32_t error_num)
{
pthread_mutex_lock(&g_vbdev_error_mutex);
g_io_type_mask = io_type_mask;
g_error_num = error_num;
pthread_mutex_unlock(&g_vbdev_error_mutex);
}
static void
vbdev_error_task_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status,
void *cb_arg)
{
struct spdk_bdev_io *bdevio = (struct spdk_bdev_io *)cb_arg;
struct spdk_bdev_io *parent = bdevio->parent;
spdk_bdev_io_complete(parent, SPDK_BDEV_IO_STATUS_FAILED);
}
static void
vbdev_error_reset(struct vbdev_error_disk *error_disk, struct spdk_bdev_io *bdev_io)
{
/*
* pass the I/O through unmodified.
*
* However, we do need to increment the generation count for the error bdev,
* since the spdk_bdev_io_complete() path that normally updates it will not execute
* after we resubmit the I/O to the base_bdev.
*/
if (bdev_io->u.reset.type == SPDK_BDEV_RESET_HARD) {
error_disk->disk.gencnt++;
}
}
static void
vbdev_error_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
{
struct vbdev_error_disk *error_disk = bdev_io->bdev->ctxt;
uint32_t io_type_mask;
struct spdk_bdev_io *child;
switch (bdev_io->type) {
case SPDK_BDEV_IO_TYPE_READ:
case SPDK_BDEV_IO_TYPE_WRITE:
case SPDK_BDEV_IO_TYPE_UNMAP:
case SPDK_BDEV_IO_TYPE_FLUSH:
break;
case SPDK_BDEV_IO_TYPE_RESET:
vbdev_error_reset(error_disk, bdev_io);
break;
default:
SPDK_ERRLOG("Error Injection: unknown I/O type %d\n", bdev_io->type);
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
return;
}
io_type_mask = 1U << bdev_io->type;
if (g_error_num == 0 || !(g_io_type_mask & io_type_mask)) {
spdk_bdev_io_resubmit(bdev_io, error_disk->base_bdev);
return;
}
pthread_mutex_lock(&g_vbdev_error_mutex);
/* check again to make sure g_error_num has not been decremented since we checked it above */
if (g_error_num == 0) {
spdk_bdev_io_resubmit(bdev_io, error_disk->base_bdev);
} else {
g_error_num--;
child = spdk_bdev_get_child_io(bdev_io, &error_disk->disk, vbdev_error_task_complete, NULL);
child->ch = bdev_io->ch;
spdk_bdev_io_resubmit(child, error_disk->base_bdev);
}
pthread_mutex_unlock(&g_vbdev_error_mutex);
}
static void
vbdev_error_free(struct vbdev_error_disk *error_disk)
{
if (!error_disk) {
return;
}
TAILQ_REMOVE(&g_vbdev_error_disks, error_disk, tailq);
spdk_bdev_unclaim(error_disk->base_bdev);
free(error_disk);
}
static int
vbdev_error_destruct(void *ctx)
{
struct vbdev_error_disk *error_disk = ctx;
vbdev_error_free(error_disk);
return 0;
}
static bool
vbdev_error_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type)
{
struct vbdev_error_disk *error_disk = ctx;
return error_disk->base_bdev->fn_table->io_type_supported(error_disk->base_bdev,
io_type);
}
static struct spdk_io_channel *
vbdev_error_get_io_channel(void *ctx, uint32_t priority)
{
struct vbdev_error_disk *error_disk = ctx;
return error_disk->base_bdev->fn_table->get_io_channel(error_disk->base_bdev,
priority);
}
static int
vbdev_error_dump_config_json(void *ctx, struct spdk_json_write_ctx *w)
{
struct vbdev_error_disk *error_disk = ctx;
spdk_json_write_name(w, "error_disk");
spdk_json_write_object_begin(w);
spdk_json_write_name(w, "base_bdev");
spdk_json_write_string(w, error_disk->base_bdev->name);
spdk_json_write_object_end(w);
return 0;
}
static struct spdk_bdev_fn_table vbdev_error_fn_table = {
.destruct = vbdev_error_destruct,
.io_type_supported = vbdev_error_io_type_supported,
.submit_request = vbdev_error_submit_request,
.get_io_channel = vbdev_error_get_io_channel,
.dump_config_json = vbdev_error_dump_config_json,
};
int
spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
{
struct vbdev_error_disk *disk;
int rc;
if (!spdk_bdev_claim(base_bdev, NULL, NULL)) {
SPDK_ERRLOG("Error bdev %s is already claimed\n", base_bdev->name);
return -1;
}
disk = calloc(1, sizeof(*disk));
if (!disk) {
SPDK_ERRLOG("Memory allocation failure\n");
rc = -1;
goto cleanup;
}
disk->base_bdev = base_bdev;
memcpy(&disk->disk, base_bdev, sizeof(*base_bdev));
snprintf(disk->disk.name, sizeof(disk->disk.name), "EE_%s", base_bdev->name);
snprintf(disk->disk.product_name, sizeof(disk->disk.product_name), "Error Injection Disk");
disk->disk.ctxt = disk;
disk->disk.fn_table = &vbdev_error_fn_table;
spdk_bdev_register(&disk->disk);
TAILQ_INSERT_TAIL(&g_vbdev_error_disks, disk, tailq);
rc = 0;
return rc;
cleanup:
free(disk);
return rc;
}
static int
vbdev_error_init(void)
{
struct spdk_conf_section *sp;
const char *base_bdev_name;
int i;
struct spdk_bdev *base_bdev;
sp = spdk_conf_find_section(NULL, "BdevError");
if (sp == NULL) {
return 0;
}
for (i = 0; ; i++) {
if (!spdk_conf_section_get_nval(sp, "BdevError", i)) {
break;
}
base_bdev_name = spdk_conf_section_get_nmval(sp, "BdevError", i, 0);
if (!base_bdev_name) {
SPDK_ERRLOG("ErrorInjection configuration missing blockdev name\n");
return -1;
}
base_bdev = spdk_bdev_get_by_name(base_bdev_name);
if (!base_bdev) {
SPDK_ERRLOG("Could not find ErrorInjection bdev %s\n", base_bdev_name);
return -1;
}
if (spdk_vbdev_error_create(base_bdev)) {
return -1;
}
}
return 0;
}
static void
vbdev_error_fini(void)
{
struct vbdev_error_disk *error_disk, *tmp;
TAILQ_FOREACH_SAFE(error_disk, &g_vbdev_error_disks, tailq, tmp) {
vbdev_error_free(error_disk);
}
}
SPDK_VBDEV_MODULE_REGISTER(vbdev_error_init, vbdev_error_fini, NULL, NULL)

View File

@ -0,0 +1,43 @@
/*-
* BSD LICENSE
*
* Copyright (c) Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SPDK_BLOCKDEV_ERROR_H
#define SPDK_BLOCKDEV_ERROR_H
#include "spdk/stdinc.h"
#include "spdk/bdev.h"
int spdk_vbdev_error_create(struct spdk_bdev *base_bdev);
void spdk_vbdev_inject_error(uint32_t io_type_mask, uint32_t error_num);
#endif // SPDK_BLOCKDEV_ERROR_H

View File

@ -0,0 +1,178 @@
/*-
* BSD LICENSE
*
* Copyright (c) Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "spdk/stdinc.h"
#include "spdk/string.h"
#include "spdk/rpc.h"
#include "spdk/util.h"
#include "spdk_internal/log.h"
#include "vbdev_error.h"
#define ERROR_BDEV_IO_TYPE_INVALID (1U << (SPDK_BDEV_IO_TYPE_RESET + 1))
static uint32_t
spdk_rpc_error_bdev_io_type_parse(char *name)
{
if (strcmp(name, "read") == 0) {
return 1U << SPDK_BDEV_IO_TYPE_READ;
} else if (strcmp(name, "write") == 0) {
return 1U << SPDK_BDEV_IO_TYPE_WRITE;
} else if (strcmp(name, "flush") == 0) {
return 1U << SPDK_BDEV_IO_TYPE_FLUSH;
} else if (strcmp(name, "unmap") == 0) {
return 1U << SPDK_BDEV_IO_TYPE_UNMAP;
} else if (strcmp(name, "reset") == 0) {
return 1U << SPDK_BDEV_IO_TYPE_RESET;
} else if (strcmp(name, "all") == 0) {
return 0xffffffff;
} else if (strcmp(name, "clear") == 0) {
return 0;
}
return ERROR_BDEV_IO_TYPE_INVALID;
}
struct rpc_construct_error_bdev {
char *base_name;
};
static void
free_rpc_construct_error_bdev(struct rpc_construct_error_bdev *req)
{
free(req->base_name);
}
static const struct spdk_json_object_decoder rpc_construct_error_bdev_decoders[] = {
{"base_name", offsetof(struct rpc_construct_error_bdev, base_name), spdk_json_decode_string},
};
static void
spdk_rpc_construct_error_bdev(struct spdk_jsonrpc_server_conn *conn,
const struct spdk_json_val *params,
const struct spdk_json_val *id)
{
struct rpc_construct_error_bdev req = {};
struct spdk_json_write_ctx *w;
struct spdk_bdev *base_bdev;
if (spdk_json_decode_object(params, rpc_construct_error_bdev_decoders,
SPDK_COUNTOF(rpc_construct_error_bdev_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
base_bdev = spdk_bdev_get_by_name(req.base_name);
if (!base_bdev) {
SPDK_ERRLOG("Could not find ErrorInjection bdev %s\n", req.base_name);
goto invalid;
}
if (spdk_vbdev_error_create(base_bdev)) {
SPDK_ERRLOG("Could not create ErrorInjection bdev %s\n", req.base_name);
goto invalid;
}
if (id == NULL) {
free_rpc_construct_error_bdev(&req);
return;
}
w = spdk_jsonrpc_begin_result(conn, id);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(conn, w);
free_rpc_construct_error_bdev(&req);
return;
invalid:
spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
free_rpc_construct_error_bdev(&req);
}
SPDK_RPC_REGISTER("construct_error_bdev", spdk_rpc_construct_error_bdev)
struct rpc_error_information {
char *type;
uint32_t num;
};
static const struct spdk_json_object_decoder rpc_error_information_decoders[] = {
{"type", offsetof(struct rpc_error_information, type), spdk_json_decode_string},
{"num", offsetof(struct rpc_error_information, num), spdk_json_decode_uint32, true},
};
static void
free_rpc_error_information(struct rpc_error_information *p)
{
free(p->type);
}
static void
spdk_rpc_bdev_inject_error(struct spdk_jsonrpc_server_conn *conn,
const struct spdk_json_val *params,
const struct spdk_json_val *id)
{
struct rpc_error_information req = {};
struct spdk_json_write_ctx *w;
uint32_t ret;
if (spdk_json_decode_object(params, rpc_error_information_decoders,
SPDK_COUNTOF(rpc_error_information_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
ret = spdk_rpc_error_bdev_io_type_parse(req.type);
if (ret == ERROR_BDEV_IO_TYPE_INVALID) {
goto invalid;
}
spdk_vbdev_inject_error(ret, req.num);
free_rpc_error_information(&req);
if (id == NULL) {
return;
}
w = spdk_jsonrpc_begin_result(conn, id);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(conn, w);
return;
invalid:
spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
free_rpc_error_information(&req);
}
SPDK_RPC_REGISTER("bdev_inject_error", spdk_rpc_bdev_inject_error)

View File

@ -31,7 +31,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
BLOCKDEV_MODULES_LIST = bdev_malloc bdev_null bdev_nvme nvme vbdev_split
BLOCKDEV_MODULES_LIST = bdev_malloc bdev_null bdev_nvme nvme vbdev_error vbdev_split
ifeq ($(CONFIG_RDMA),y)
BLOCKDEV_MODULES_DEPS += -libverbs -lrdmacm

View File

@ -236,6 +236,13 @@ p.add_argument('rbd_name', help='rbd image name')
p.add_argument('block_size', help='rbd block size', type=int)
p.set_defaults(func=construct_rbd_bdev)
def construct_error_bdev(args):
params = {'base_name': args.base_name}
jsonrpc_call('construct_error_bdev', params)
p = subparsers.add_parser('construct_error_bdev', help='Add bdev with error injection backend')
p.add_argument('base_name', help='base bdev name')
p.set_defaults(func=construct_error_bdev)
def set_trace_flag(args):
params = {'flag': args.flag}
jsonrpc_call('set_trace_flag', params)
@ -446,6 +453,19 @@ p = subparsers.add_parser('delete_nvmf_subsystem', help='Delete a nvmf subsystem
p.add_argument('subsystem_nqn', help='subsystem nqn to be deleted. Example: nqn.2016-06.io.spdk:cnode1.')
p.set_defaults(func=delete_nvmf_subsystem)
def bdev_inject_error(args):
params = {
'type': args.type,
'num': args.num,
}
jsonrpc_call('bdev_inject_error', params)
p = subparsers.add_parser('bdev_inject_error', help='bdev inject error')
p.add_argument('type', help="""type: 'clear' 'read' 'write' 'unmap' 'flush' 'reset' 'all'""")
p.add_argument('-n', '--num', help='the number of commands you want to fail', type=int, default=1)
p.set_defaults(func=bdev_inject_error)
def kill_instance(args):
params = {'sig_name': args.sig_name}
jsonrpc_call('kill_instance', params)

View File

@ -47,14 +47,14 @@ echo "iscsi_tgt is listening. Running tests..."
$rpc_py add_portal_group 1 $TARGET_IP:$PORT
$rpc_py add_initiator_group $INITIATOR_TAG $INITIATOR_NAME $NETMASK
$rpc_py construct_error_bdev 'Malloc0'
# "1:2" ==> map PortalGroup1 to InitiatorGroup2
# "64" ==> iSCSI queue depth 64
# "1 0 0 0" ==> disable CHAP authentication
if [ -z "$NO_NVME" ]; then
$rpc_py construct_target_node Target0 Target0_alias Nvme0n1:0 1:2 64 1 0 0 0
fi
$rpc_py construct_target_node Target1 Target1_alias Malloc0:0 1:2 64 1 0 0 0
$rpc_py construct_target_node Target1 Target1_alias EE_Malloc0:0 1:2 64 1 0 0 0
sleep 1
iscsiadm -m discovery -t sendtargets -p $TARGET_IP:$PORT
@ -65,9 +65,31 @@ trap 'for new_dir in `dir -d /mnt/*dir`; do umount $new_dir; rm -rf $new_dir; do
sleep 1
$rpc_py bdev_inject_error 'all' -n 1000
devs=$(iscsiadm -m session -P 3 | grep "Attached scsi disk" | awk '{print $4}')
declare -i failcount=0
set +e
for dev in $devs; do
mkfs.ext4 -F /dev/$dev
if [ $? -eq 0 ]; then
echo "mkfs successful"
else
echo "mkfs failed"
failcount+=1
fi
done
set -e
if [ $failcount -eq 1 ]; then
echo "error injection success"
else
exit 1
fi
$rpc_py bdev_inject_error 'clear'
for dev in $devs; do
mkfs.ext4 -F /dev/$dev
mkdir -p /mnt/${dev}dir