mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
selftests: ublk: add helper for SET_PARAMS
The normal kublk add command goes through device startup. It does not tell the shell test whether a bad parameter is rejected by SET_PARAMS or later by START_DEV. Add a set_params command. It creates a temporary ublk device, sends SET_PARAMS with the command line parameters, returns the ioctl result, and deletes the device before START_DEV. Signed-off-by: Yao Sang <sangyao@kylinos.cn> Link: https://patch.msgid.link/20260814023226.354288-3-sangyao@kylinos.cn Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
2707acf185
commit
176f02a86c
|
|
@ -8,6 +8,13 @@
|
|||
#include "kublk.h"
|
||||
|
||||
#define MAX_NR_TGT_ARG 64
|
||||
#define KUBLK_PARAM_LOGICAL_BS_SHIFT 9
|
||||
#define KUBLK_PARAM_PHYSICAL_BS_SHIFT 12
|
||||
#define KUBLK_PARAM_ZONE_SECTORS 128
|
||||
#define KUBLK_PARAM_NR_ZONES 16
|
||||
#define KUBLK_PARAM_DEV_SECTORS \
|
||||
(KUBLK_PARAM_ZONE_SECTORS * KUBLK_PARAM_NR_ZONES)
|
||||
#define KUBLK_PARAM_ZONE_APPEND_SECTORS 8
|
||||
|
||||
unsigned int ublk_dbg_mask = UBLK_LOG;
|
||||
static const struct ublk_tgt_ops *tgt_ops_list[] = {
|
||||
|
|
@ -227,6 +234,55 @@ static int ublk_ctrl_get_features(struct ublk_dev *dev,
|
|||
return __ublk_ctrl_cmd(dev, &data);
|
||||
}
|
||||
|
||||
static int parse_param_types(const char *arg, __u32 *types)
|
||||
{
|
||||
char buf[128], *save = NULL, *tok;
|
||||
|
||||
if (strlen(arg) >= sizeof(buf))
|
||||
return -EINVAL;
|
||||
|
||||
strcpy(buf, arg);
|
||||
*types = 0;
|
||||
tok = strtok_r(buf, ",", &save);
|
||||
while (tok) {
|
||||
if (!strcmp(tok, "none"))
|
||||
;
|
||||
else if (!strcmp(tok, "basic"))
|
||||
*types |= UBLK_PARAM_TYPE_BASIC;
|
||||
else if (!strcmp(tok, "zoned"))
|
||||
*types |= UBLK_PARAM_TYPE_ZONED;
|
||||
else
|
||||
return -EINVAL;
|
||||
tok = strtok_r(NULL, ",", &save);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ublk_init_params_from_ctx(const struct dev_ctx *ctx,
|
||||
struct ublk_params *params)
|
||||
{
|
||||
const struct params_ctx *p = &ctx->params;
|
||||
|
||||
*params = (struct ublk_params) {
|
||||
.types = p->types,
|
||||
.basic = {
|
||||
.logical_bs_shift = p->logical_bs_shift,
|
||||
.physical_bs_shift = p->physical_bs_shift,
|
||||
.io_min_shift = p->io_min_shift,
|
||||
.io_opt_shift = p->io_opt_shift,
|
||||
.max_sectors = p->max_sectors,
|
||||
.chunk_sectors = p->chunk_sectors,
|
||||
.dev_sectors = p->dev_sectors,
|
||||
},
|
||||
.zoned = {
|
||||
.max_open_zones = p->max_open_zones,
|
||||
.max_active_zones = p->max_active_zones,
|
||||
.max_zone_append_sectors = p->max_zone_append_sectors,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static int ublk_ctrl_update_size(struct ublk_dev *dev,
|
||||
__u64 nr_sects)
|
||||
{
|
||||
|
|
@ -1772,6 +1828,51 @@ static int __cmd_dev_add(const struct dev_ctx *ctx)
|
|||
|
||||
static int __cmd_dev_list(struct dev_ctx *ctx);
|
||||
|
||||
static int cmd_dev_set_params(struct dev_ctx *ctx)
|
||||
{
|
||||
struct ublksrv_ctrl_dev_info *info;
|
||||
struct ublk_params params;
|
||||
struct ublk_dev *dev;
|
||||
__u64 features;
|
||||
int ret, del_ret;
|
||||
|
||||
dev = ublk_ctrl_init();
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
ret = ublk_ctrl_get_features(dev, &features);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (!(features & UBLK_F_CMD_IOCTL_ENCODE)) {
|
||||
ret = -ENOTSUP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
info = &dev->dev_info;
|
||||
info->dev_id = ctx->dev_id;
|
||||
info->nr_hw_queues = ctx->nr_hw_queues;
|
||||
info->queue_depth = ctx->queue_depth;
|
||||
info->io_desc_size = ctx->io_desc_size;
|
||||
info->flags = ctx->flags;
|
||||
|
||||
ret = ublk_ctrl_add_dev(dev);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ublk_init_params_from_ctx(ctx, ¶ms);
|
||||
|
||||
ret = ublk_ctrl_set_params(dev, ¶ms);
|
||||
printf("SET_PARAMS returned %d\n", ret);
|
||||
|
||||
del_ret = ublk_ctrl_del_dev(dev);
|
||||
if (del_ret < 0 && ret == 0)
|
||||
ret = del_ret;
|
||||
out:
|
||||
ublk_ctrl_deinit(dev);
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static int cmd_dev_add(struct dev_ctx *ctx)
|
||||
{
|
||||
int res;
|
||||
|
|
@ -2117,6 +2218,9 @@ static int cmd_dev_help(char *exe)
|
|||
printf("\t --safe only stop if device has no active openers\n\n");
|
||||
printf("%s list [-n dev_id] -a \n", exe);
|
||||
printf("\t -a list all devices, -n list specified device, default -a \n\n");
|
||||
printf("%s set_params [-n dev_id] [-q nr_queues] [-d depth] [-u] [--zoned]\n", exe);
|
||||
printf("\t[--param_types basic[,zoned]|none]\n");
|
||||
printf("\t issue ADD_DEV, SET_PARAMS and DEL_DEV without START_DEV\n\n");
|
||||
printf("%s features\n", exe);
|
||||
printf("%s update_size -n dev_id -s|--size size_in_bytes \n", exe);
|
||||
printf("%s quiesce -n dev_id\n", exe);
|
||||
|
|
@ -2160,6 +2264,18 @@ int main(int argc, char *argv[])
|
|||
{ "htlb", 1, NULL, 0 },
|
||||
{ "rdonly_shmem_buf", 0, NULL, 0 },
|
||||
{ "io_desc_size", 1, NULL, 0 },
|
||||
{ "zoned", 0, NULL, 0 },
|
||||
{ "param_types", 1, NULL, 0 },
|
||||
{ "logical_bs_shift", 1, NULL, 0 },
|
||||
{ "physical_bs_shift", 1, NULL, 0 },
|
||||
{ "io_min_shift", 1, NULL, 0 },
|
||||
{ "io_opt_shift", 1, NULL, 0 },
|
||||
{ "max_sectors", 1, NULL, 0 },
|
||||
{ "chunk_sectors", 1, NULL, 0 },
|
||||
{ "dev_sectors", 1, NULL, 0 },
|
||||
{ "max_zone_append_sectors", 1, NULL, 0 },
|
||||
{ "max_open_zones", 1, NULL, 0 },
|
||||
{ "max_active_zones", 1, NULL, 0 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
const struct ublk_tgt_ops *ops = NULL;
|
||||
|
|
@ -2173,6 +2289,19 @@ int main(int argc, char *argv[])
|
|||
.tgt_type = "unknown",
|
||||
.csum_type = LBMD_PI_CSUM_NONE,
|
||||
.io_desc_size = sizeof(struct ublksrv_io_desc),
|
||||
.params = {
|
||||
.types = UBLK_PARAM_TYPE_BASIC,
|
||||
.logical_bs_shift = KUBLK_PARAM_LOGICAL_BS_SHIFT,
|
||||
.physical_bs_shift = KUBLK_PARAM_PHYSICAL_BS_SHIFT,
|
||||
.io_min_shift = KUBLK_PARAM_LOGICAL_BS_SHIFT,
|
||||
.io_opt_shift = KUBLK_PARAM_PHYSICAL_BS_SHIFT,
|
||||
.max_sectors =
|
||||
UBLK_IO_MAX_BYTES >> KUBLK_PARAM_LOGICAL_BS_SHIFT,
|
||||
.chunk_sectors = KUBLK_PARAM_ZONE_SECTORS,
|
||||
.dev_sectors = KUBLK_PARAM_DEV_SECTORS,
|
||||
.max_zone_append_sectors =
|
||||
KUBLK_PARAM_ZONE_APPEND_SECTORS,
|
||||
},
|
||||
};
|
||||
int ret = -EINVAL, i;
|
||||
int tgt_argc = 1;
|
||||
|
|
@ -2288,6 +2417,34 @@ int main(int argc, char *argv[])
|
|||
ctx.flags |= UBLK_F_IO_DESC_SIZE;
|
||||
ctx.io_desc_size = strtoul(optarg, NULL, 0);
|
||||
}
|
||||
if (!strcmp(longopts[option_idx].name, "zoned"))
|
||||
ctx.flags |= UBLK_F_ZONED;
|
||||
if (!strcmp(longopts[option_idx].name, "param_types")) {
|
||||
ret = parse_param_types(optarg, &ctx.params.types);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (!strcmp(longopts[option_idx].name, "logical_bs_shift"))
|
||||
ctx.params.logical_bs_shift = strtoul(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "physical_bs_shift"))
|
||||
ctx.params.physical_bs_shift = strtoul(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "io_min_shift"))
|
||||
ctx.params.io_min_shift = strtoul(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "io_opt_shift"))
|
||||
ctx.params.io_opt_shift = strtoul(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "max_sectors"))
|
||||
ctx.params.max_sectors = strtoul(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "chunk_sectors"))
|
||||
ctx.params.chunk_sectors = strtoul(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "dev_sectors"))
|
||||
ctx.params.dev_sectors = strtoull(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "max_zone_append_sectors"))
|
||||
ctx.params.max_zone_append_sectors =
|
||||
strtoul(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "max_open_zones"))
|
||||
ctx.params.max_open_zones = strtoul(optarg, NULL, 0);
|
||||
if (!strcmp(longopts[option_idx].name, "max_active_zones"))
|
||||
ctx.params.max_active_zones = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case '?':
|
||||
/*
|
||||
|
|
@ -2377,7 +2534,9 @@ int main(int argc, char *argv[])
|
|||
ops->parse_cmd_line(&ctx, tgt_argc, tgt_argv);
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "add"))
|
||||
if (!strcmp(cmd, "set_params"))
|
||||
ret = cmd_dev_set_params(&ctx);
|
||||
else if (!strcmp(cmd, "add"))
|
||||
ret = cmd_dev_add(&ctx);
|
||||
else if (!strcmp(cmd, "recover")) {
|
||||
if (ctx.dev_id < 0) {
|
||||
|
|
|
|||
|
|
@ -63,6 +63,22 @@ struct fault_inject_ctx {
|
|||
bool die_during_fetch;
|
||||
};
|
||||
|
||||
struct params_ctx {
|
||||
__u32 types;
|
||||
|
||||
__u32 logical_bs_shift;
|
||||
__u32 physical_bs_shift;
|
||||
__u32 io_min_shift;
|
||||
__u32 io_opt_shift;
|
||||
__u32 max_sectors;
|
||||
__u32 chunk_sectors;
|
||||
__u64 dev_sectors;
|
||||
|
||||
__u32 max_open_zones;
|
||||
__u32 max_active_zones;
|
||||
__u32 max_zone_append_sectors;
|
||||
};
|
||||
|
||||
struct dev_ctx {
|
||||
char tgt_type[16];
|
||||
unsigned long flags;
|
||||
|
|
@ -99,6 +115,8 @@ struct dev_ctx {
|
|||
/* for 'update_size' command */
|
||||
unsigned long long size;
|
||||
|
||||
struct params_ctx params;
|
||||
|
||||
char *htlb_path;
|
||||
|
||||
union {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user