From patchwork Thu Mar 23 11:55:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 666844 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75D26C6FD1C for ; Thu, 23 Mar 2023 11:57:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231375AbjCWL5j (ORCPT ); Thu, 23 Mar 2023 07:57:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229508AbjCWL5V (ORCPT ); Thu, 23 Mar 2023 07:57:21 -0400 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 219DA3609B; Thu, 23 Mar 2023 04:56:57 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4Pj3fh1zJ9zLFXB; Thu, 23 Mar 2023 19:54:36 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21; Thu, 23 Mar 2023 19:56:53 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: , , Subject: [PATCH 1/5] scsi:scsi_debug: Add sysfs interface to manage scsi devices' error injection Date: Thu, 23 Mar 2023 19:55:57 +0800 Message-ID: <20230323115601.178494-2-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230323115601.178494-1-haowenchao2@huawei.com> References: <20230323115601.178494-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Add interface "/sys/class/scsi_device//device/error_inject/error" to manage scsi_device's error injection rules. Write it to add/remove an error injection rule, read it to get error injection rules. The interface format is line-by-line, each line is an error injection rule. Each rule contains integers separated by spaces, first three columns are fixed to "Error code", "Error count" and "SCSI command", other columns depend on error code. +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error code | | | | 0: timeout SCSI command | | | | 1: fail queuecommand, make queuecommand return | | | | specific value | | | | 2: fail command, finish command with specific status | | | | and sense date | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error Count | | | | 0: the rule would not take effect | | | | positive: the rule would always take effect | | | | negative: the rule take effect for the absolute of | | | | this value | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command this rule is for, 0xff for all command | +--------+------+-------------------------------------------------------+ | ... | xxx | Error type specific fields | +--------+------+-------------------------------------------------------+ - When multiple error injects are added to one scsi command, the one with smaller error code would take effect. - If an same error is added to one device, old one would be overwritten. - Currently, basic types are (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types (x8/x16/x32/x64) Timeout SCSI command: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x0 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error Count | | | | 0: the rule would not take effect | | | | positive: the rule would always take effect | | | | negative: the rule take effect for the absolute of | | | | this value | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command this rule is for, 0xff for all command | +--------+------+-------------------------------------------------------+ Examples: error=/sys/class/scsi_device/0:0:0:1/device/error_inject/error echo "0 -10 0x12" > $error would make the device's inquiry command timeout for 10 time. error=/sys/class/scsi_device/0:0:0:1/device/error_inject/error echo "0 1 0x12" > $error would make the device's inquiry timeout forever. Make queuecommand return specific value: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x1 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error Count | | | | 0: the rule would not take effect | | | | positive: the rule would always take effect | | | | negative: the rule take effect for the absolute of | | | | this value | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command this rule is for, 0xff for all command | +--------+------+-------------------------------------------------------+ | 4 | x32 | The return value of queuecommand we desired | +--------+------+-------------------------------------------------------+ Examples: error=/sys/class/scsi_device/0:0:0:1/device/error_inject/error echo "1 1 0x12 0x1055" > $error would make device's inquiry command return 0x1055(SCSI_MLQUEUE_HOST_BUSY) forever. Set scsi_cmd's status and sense data to specific value: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x2 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error Count | | | | 0: the rule would not take effect | | | | positive: the rule would always take effect | | | | negative: the rule take effect for the absolute of | | | | this value | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command this rule is for, 0xff for all command | +--------+------+-------------------------------------------------------+ | 4 | x8 | Host byte in scsi_cmd's status | +--------+------+-------------------------------------------------------+ | 5 | x8 | Driver byte in scsi_cmd's status | +--------+------+-------------------------------------------------------+ | 6 | x8 | Status byte in scsi_cmd's status | +--------+------+-------------------------------------------------------+ | 7 | x8 | Sense Key of scsi_cmnd | +--------+------+-------------------------------------------------------+ | 8 | x8 | ASC of scsi_cmnd | +--------+------+-------------------------------------------------------+ | 9 | x8 | ASQ of scsi_cmnd | +--------+------+-------------------------------------------------------+ Examples: error=/sys/class/scsi_device/0:0:0:1/device/error_inject/error echo "2 -10 0x88 0 0 0x2 0x3 0x11 0x0" >$error would make device's read command return with media error UNC: Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 161 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 7ed117e78bd4..8cfa19f8b034 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -280,6 +280,41 @@ struct sdeb_zone_state { /* ZBC: per zone state */ sector_t z_wp; }; +enum sdebug_err_type { + ERR_TMOUT_CMD = 0, /* make specific scsi command timeout */ + ERR_FAIL_QUEUE_CMD = 1, /* make specific scsi command's */ + /* queuecmd return failed */ + ERR_FAIL_CMD = 2, /* make specific scsi command's */ + /* queuecmd return succeed but */ + /* with errors set in scsi_cmnd */ +}; + +struct sdebug_err_inject { + int type; + struct list_head list; + int cnt; + unsigned char cmd; + + union { + /* + * For ERR_FAIL_QUEUE_CMD + */ + int queuecmd_ret; + + /* + * For ERR_FAIL_CMD + */ + struct { + unsigned char host_byte; + unsigned char driver_byte; + unsigned char status_byte; + unsigned char sense_key; + unsigned char asc; + unsigned char asq; + }; + }; +}; + struct sdebug_dev_info { struct list_head dev_list; unsigned int channel; @@ -305,6 +340,8 @@ struct sdebug_dev_info { unsigned int max_open; ktime_t create_ts; /* time since bootup that this device was created */ struct sdeb_zone_state *zstate; + + struct list_head inject_err_list; }; struct sdebug_host_info { @@ -5152,6 +5189,7 @@ static struct sdebug_dev_info *sdebug_device_create( } devip->create_ts = ktime_get_boottime(); atomic_set(&devip->stopped, (sdeb_tur_ms_to_ready > 0 ? 2 : 0)); + INIT_LIST_HEAD(&devip->inject_err_list); list_add_tail(&devip->dev_list, &sdbg_host->dev_info_list); } return devip; @@ -7553,6 +7591,128 @@ static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) return num_entries; } +static void sdebug_err_add(struct device *dev, struct sdebug_err_inject *new) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdev->hostdata; + struct sdebug_err_inject *tmp, *err; + + list_for_each_entry_safe(err, tmp, &devip->inject_err_list, list) { + if (err->type == new->type && err->cmd == new->cmd) { + sdev_printk(KERN_INFO, sdev, "Substituted %d 0x%x\n", + err->type, err->cmd); + list_del(&err->list); + kfree(err); + } + } + + list_add_tail(&new->list, &devip->inject_err_list); +} + +static ssize_t error_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int tmp, ret = 0; + struct scsi_device *sdev = to_scsi_device(dev); + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdev->hostdata; + struct sdebug_err_inject *err; + + tmp = sysfs_emit_at(buf, ret, "Type\tCount\tCommand\n"); + ret += tmp; + + list_for_each_entry(err, &devip->inject_err_list, list) { + switch (err->type) { + case ERR_TMOUT_CMD: + tmp = sysfs_emit_at(buf, ret, "%d\t%d\t0x%x\n", + err->type, err->cnt, err->cmd); + ret += tmp; + break; + + case ERR_FAIL_QUEUE_CMD: + tmp = sysfs_emit_at(buf, ret, "%d\t%d\t0x%x\t0x%x\n", + err->type, err->cnt, err->cmd, err->queuecmd_ret); + ret += tmp; + break; + + case ERR_FAIL_CMD: + tmp = sysfs_emit_at(buf, ret, + "%d\t%d\t0x%x\t0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + err->type, err->cnt, err->cmd, + err->host_byte, err->driver_byte, + err->status_byte, err->sense_key, + err->asc, err->asq); + ret += tmp; + break; + } + } + + return ret; +} +static ssize_t error_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int inject_type; + struct sdebug_err_inject *inject; + + if (sscanf(buf, "%d", &inject_type) != 1) + return -EINVAL; + + inject = kzalloc(sizeof(struct sdebug_err_inject), GFP_KERNEL); + if (!inject) + return -ENOMEM; + + switch (inject_type) { + case ERR_TMOUT_CMD: + if (sscanf(buf, "%d %d %hhx", &inject->type, &inject->cnt, + &inject->cmd) != 3) + goto out_error; + break; + + case ERR_FAIL_QUEUE_CMD: + if (sscanf(buf, "%d %d %hhx %x", &inject->type, &inject->cnt, + &inject->cmd, &inject->queuecmd_ret) != 4) + goto out_error; + break; + + case ERR_FAIL_CMD: + if (sscanf(buf, "%d %d %hhx %hhx %hhx %hhx %hhx %hhx %hhx", + &inject->type, &inject->cnt, &inject->cmd, + &inject->host_byte, &inject->driver_byte, + &inject->status_byte, &inject->sense_key, + &inject->asc, &inject->asq) != 9) + goto out_error; + break; + + default: + goto out_error; + break; + } + + sdebug_err_add(dev, inject); + + return count; + +out_error: + kfree(inject); + return -EINVAL; +} +static DEVICE_ATTR_RW(error); + +static struct attribute *sdebug_sdev_attrs[] = { + &dev_attr_error.attr, + NULL +}; + +static const struct attribute_group sdebug_sdev_attr_group = { + .name = "error_inject", + .attrs = sdebug_sdev_attrs, +}; + +const struct attribute_group *sdebug_sdev_groups[] = { + &sdebug_sdev_attr_group, + NULL +}; + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7732,6 +7892,7 @@ static struct scsi_host_template sdebug_driver_template = { .ioctl = scsi_debug_ioctl, .queuecommand = scsi_debug_queuecommand, .change_queue_depth = sdebug_change_qdepth, + .sdev_groups = sdebug_sdev_groups, .map_queues = sdebug_map_queues, .mq_poll = sdebug_blk_mq_poll, .eh_abort_handler = scsi_debug_abort, From patchwork Thu Mar 23 11:55:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 666843 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C100C6FD1D for ; Thu, 23 Mar 2023 11:57:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231516AbjCWL5n (ORCPT ); Thu, 23 Mar 2023 07:57:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231224AbjCWL5V (ORCPT ); Thu, 23 Mar 2023 07:57:21 -0400 Received: from szxga03-in.huawei.com (szxga03-in.huawei.com [45.249.212.189]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 15D0E36094; Thu, 23 Mar 2023 04:56:56 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.57]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4Pj3hv6fnNzKnDF; Thu, 23 Mar 2023 19:56:31 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21; Thu, 23 Mar 2023 19:56:54 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: , , Subject: [PATCH 2/5] scsi:scsi_debug: Define grammar to remove added error injection Date: Thu, 23 Mar 2023 19:55:58 +0800 Message-ID: <20230323115601.178494-3-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230323115601.178494-1-haowenchao2@huawei.com> References: <20230323115601.178494-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The grammar to remove error injection is a line with fixed 3 columns separated by spaces. First column is fixed to "-". It tells this is a removal operation. Second column is the error code to match. Third column is the scsi command to match. For example the following command would remove timeout injection of inquiry command. echo "- 0 0x12" > /sys/class/scsi_device/0:0:0:1/device/error_inect/error Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 8cfa19f8b034..e5ee75ce6d27 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7609,6 +7609,30 @@ static void sdebug_err_add(struct device *dev, struct sdebug_err_inject *new) list_add_tail(&new->list, &devip->inject_err_list); } +static int sdebug_err_remove(struct device *dev, const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdev->hostdata; + struct sdebug_err_inject *tmp, *err; + int type; + unsigned char cmd; + + if (sscanf(buf, "- %d %hhx", &type, &cmd) != 2) + return -EINVAL; + + list_for_each_entry_safe(err, tmp, &devip->inject_err_list, list) { + if (err->type == type && err->cmd == cmd) { + sdev_printk(KERN_INFO, sdev, "Remove %d 0x%x\n", + err->type, err->cmd); + list_del(&err->list); + kfree(err); + return count; + } + } + + return -EINVAL; +} + static ssize_t error_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -7654,6 +7678,9 @@ static ssize_t error_store(struct device *dev, struct device_attribute *attr, unsigned int inject_type; struct sdebug_err_inject *inject; + if (buf[0] == '-') + return sdebug_err_remove(dev, buf, count); + if (sscanf(buf, "%d", &inject_type) != 1) return -EINVAL; From patchwork Thu Mar 23 11:55:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 666449 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AF1FAC6FD1C for ; Thu, 23 Mar 2023 11:57:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231464AbjCWL5k (ORCPT ); Thu, 23 Mar 2023 07:57:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231209AbjCWL5V (ORCPT ); Thu, 23 Mar 2023 07:57:21 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F728360A8; Thu, 23 Mar 2023 04:56:57 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.56]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4Pj3dl0ftJzbcP4; Thu, 23 Mar 2023 19:53:47 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21; Thu, 23 Mar 2023 19:56:54 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: , , Subject: [PATCH 3/5] scsi:scsi_debug: timeout command if the error is injected Date: Thu, 23 Mar 2023 19:55:59 +0800 Message-ID: <20230323115601.178494-4-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230323115601.178494-1-haowenchao2@huawei.com> References: <20230323115601.178494-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org If a timeout error is injected, return 0 from scsi_debug_queuecommand to make the command timeout. For example, the following command would inject timeout error for inquiry(0x12) command for 10 times: error=/sys/class/scsi_device/0:0:0:1/device/error_inject/error echo "0 -10 0x12" > $error Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index e5ee75ce6d27..06a830eb2ca1 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7740,6 +7740,30 @@ const struct attribute_group *sdebug_sdev_groups[] = { NULL }; +static int sdebug_timeout_cmd(struct scsi_cmnd *cmnd) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_TMOUT_CMD && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + ret = !!err->cnt; + if (err->cnt < 0) + err->cnt++; + return ret; + } + } + + return 0; +} + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7798,6 +7822,12 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, if (NULL == devip) goto err_out; } + + if (sdebug_timeout_cmd(scp)) { + scmd_printk(KERN_INFO, scp, "timeout command 0x%x\n", opcode); + return 0; + } + if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending))) atomic_set(&sdeb_inject_pending, 1); From patchwork Thu Mar 23 11:56:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 666448 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B2CAC6FD1D for ; Thu, 23 Mar 2023 11:57:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231521AbjCWL5p (ORCPT ); Thu, 23 Mar 2023 07:57:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33246 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230025AbjCWL5W (ORCPT ); Thu, 23 Mar 2023 07:57:22 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 547AF35263; Thu, 23 Mar 2023 04:56:58 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.56]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4Pj3dl5M4XzbcQc; Thu, 23 Mar 2023 19:53:47 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21; Thu, 23 Mar 2023 19:56:55 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: , , Subject: [PATCH 4/5] scsi:scsi_debug: Return failed value if the error is injected Date: Thu, 23 Mar 2023 19:56:00 +0800 Message-ID: <20230323115601.178494-5-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230323115601.178494-1-haowenchao2@huawei.com> References: <20230323115601.178494-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org If a fail queuecommand error is injected, return the failed value defined in the rule from queuecommand. We can make any scsi command's queuecommand return the value we desired, for example make it return SCSI_MLQUEUE_HOST_BUSY. error=/sys/class/scsi_device/0:0:0:1/device/error_inject/error echo "1 1 0x12 0x1055" > $error would make all inquiry(0x12) command's queuecommand return 0x1055: Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 06a830eb2ca1..1deccf8dfc90 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7764,6 +7764,30 @@ static int sdebug_timeout_cmd(struct scsi_cmnd *cmnd) return 0; } +static int sdebug_fail_queue_cmd(struct scsi_cmnd *cmnd) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_FAIL_QUEUE_CMD && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + ret = err->cnt ? err->queuecmd_ret : 0; + if (err->cnt < 0) + err->cnt++; + return ret; + } + } + + return 0; +} + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7783,6 +7807,7 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, u8 opcode = cmd[0]; bool has_wlun_rl; bool inject_now; + int ret = 0; scsi_set_resid(scp, 0); if (sdebug_statistics) { @@ -7828,6 +7853,13 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, return 0; } + ret = sdebug_fail_queue_cmd(scp); + if (ret) { + scmd_printk(KERN_INFO, scp, "fail queue command 0x%x with 0x%x\n", + opcode, ret); + return ret; + } + if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending))) atomic_set(&sdeb_inject_pending, 1); From patchwork Thu Mar 23 11:56:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 666842 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3DABC7619A for ; Thu, 23 Mar 2023 11:57:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231152AbjCWL5r (ORCPT ); Thu, 23 Mar 2023 07:57:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33280 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231220AbjCWL5W (ORCPT ); Thu, 23 Mar 2023 07:57:22 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EBF44366A5; Thu, 23 Mar 2023 04:56:58 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.55]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4Pj3dm2qw1zbcQg; Thu, 23 Mar 2023 19:53:48 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21; Thu, 23 Mar 2023 19:56:56 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: , , Subject: [PATCH 5/5] scsi:scsi_debug: set command's result and sense data if the error is injected Date: Thu, 23 Mar 2023 19:56:01 +0800 Message-ID: <20230323115601.178494-6-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230323115601.178494-1-haowenchao2@huawei.com> References: <20230323115601.178494-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org If a fail commnd error is injected, set the command's status and sense data then finish this scsi command. For example, the following command would make read(0x88) command finished with UNC for 8 times: error=/sys/class/scsi_device/0:0:0:1/device/error_inject/error echo "2 -8 0x88 0 0 0x2 0x3 0x11 0x0" >$error Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 1deccf8dfc90..863e1a23c055 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7788,6 +7788,41 @@ static int sdebug_fail_queue_cmd(struct scsi_cmnd *cmnd) return 0; } +static int sdebug_fail_cmd(struct scsi_cmnd *cmnd, int *retval, + struct sdebug_err_inject *info) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + int result; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_FAIL_CMD && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + if (!err->cnt) + return 0; + ret = !!err->cnt; + goto out_handle; + } + } + return 0; + +out_handle: + if (err->cnt < 0) + err->cnt++; + mk_sense_buffer(cmnd, err->sense_key, err->asc, err->asq); + result = err->status_byte | err->host_byte << 16 | err->driver_byte << 24; + *info = *err; + *retval = schedule_resp(cmnd, devip, result, NULL, 0, 0); + + return ret; +} + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7808,6 +7843,7 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, bool has_wlun_rl; bool inject_now; int ret = 0; + struct sdebug_err_inject err; scsi_set_resid(scp, 0); if (sdebug_statistics) { @@ -7860,6 +7896,16 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, return ret; } + if (sdebug_fail_cmd(scp, &ret, &err)) { + scmd_printk(KERN_INFO, scp, + "fail command 0x%x with hostbyte=0x%x, " + "driverbyte=0x%x, statusbyte=0x%x, " + "sense_key=0x%x, asc=0x%x, asq=0x%x\n", + opcode, err.host_byte, err.driver_byte, + err.status_byte, err.sense_key, err.asc, err.asq); + return ret; + } + if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending))) atomic_set(&sdeb_inject_pending, 1);