From: Keith Busch Date: Tue, 7 Jun 2016 18:35:08 +0000 (-0600) Subject: Make lnvm sub-commands an extension X-Git-Tag: v0.8~16 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=98ce5b06094180d50d28ae4b415097ec00f906b6;p=users%2Fsagi%2Fnvme-cli.git Make lnvm sub-commands an extension We want to keep the nvme top level commands strictly to spec. Anything outside the spec can go in an extension. Signed-off-by: Keith Busch --- diff --git a/Makefile b/Makefile index 841cc08b..47d35597 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,8 @@ override CFLAGS += -DNVME_VERSION='"$(NVME_VERSION)"' NVME_DPKG_VERSION=1~`lsb_release -sc` OBJS := argconfig.o suffix.o parser.o nvme-print.o nvme-ioctl.o \ - nvme-lightnvm.o fabrics.o json.o plugin.o intel-nvme.o + nvme-lightnvm.o fabrics.o json.o plugin.o intel-nvme.o \ + lnvm-nvme.o nvme: nvme.c nvme.h $(OBJS) NVME-VERSION-FILE $(CC) $(CPPFLAGS) $(CFLAGS) nvme.c $(LDFLAGS) -o $(NVME) $(OBJS) diff --git a/lnvm-nvme.c b/lnvm-nvme.c new file mode 100644 index 00000000..975d07de --- /dev/null +++ b/lnvm-nvme.c @@ -0,0 +1,336 @@ +#include +#include + +#include "nvme.h" +#include "nvme-print.h" +#include "nvme-ioctl.h" +#include "plugin.h" + +#include "nvme-lightnvm.h" + +#include "argconfig.h" +#include "suffix.h" + +#define CREATE_CMD +#include "lnvm-nvme.h" + +static struct plugin lnvm_nvme = { + .name = "lnvm", + .desc = "LightNVM specific extensions", + .commands = commands, +}; + +static void init() __attribute__((constructor)); +static void init() +{ + register_extension(&lnvm_nvme); +} + +static int lnvm_init(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Initialize LightNVM device. A LightNVM/Open-Channel SSD"\ + " must have a media manager associated before it can "\ + " be exposed to the user. The default is to initialize" + " the general media manager on top of the device.\n\n" + "Example:" + " lnvm-init -d nvme0n1"; + const char *devname = "identifier of desired device. e.g. nvme0n1."; + const char *mmtype = "media manager to initialize on top of device. Default: gennvm."; + + struct config + { + char *devname; + char *mmtype; + }; + + struct config cfg = { + .devname = "", + .mmtype = "gennvm", + }; + + const struct argconfig_commandline_options command_line_options[] = { + {"device-name", 'd', "DEVICE", CFG_STRING, &cfg.devname, required_argument, devname}, + {"mediamgr-name", 'm', "MM", CFG_STRING, &cfg.mmtype, no_argument, mmtype}, + {0} + }; + + argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); + + return lnvm_do_init(cfg.devname, cfg.mmtype); +} + +static int lnvm_list(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "List all devices registered with LightNVM."; + + const struct argconfig_commandline_options command_line_options[] = { + {0} + }; + + argconfig_parse(argc, argv, desc, command_line_options, NULL, 0); + + return lnvm_do_list_devices(); +} + +static int lnvm_info(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Show general information and registered target types with LightNVM"; + + const struct argconfig_commandline_options command_line_options[] = { + {0} + }; + + argconfig_parse(argc, argv, desc, command_line_options, NULL, 0); + + return lnvm_do_info(); +} + +static int lnvm_id_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Send an Identify Geometry command to the "\ + "given LightNVM device, returns properties of the specified"\ + "namespace in either human-readable or binary format."; + const char *force = "Return this namespace, even if not supported"; + const char *raw_binary = "show infos in binary format"; + const char *human_readable = "show infos in readable format"; + const char *namespace_id = "identifier of desired namespace. default: 1"; + unsigned int fd, flags = 0; + + struct config { + __u32 namespace_id; + int raw_binary; + int human_readable; + int force; + }; + + struct config cfg = { + .namespace_id = 1, + }; + + const struct argconfig_commandline_options command_line_options[] = { + {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace_id}, + {"force", 'f', "FLAG", CFG_NONE, &cfg.force, no_argument, force}, + {"raw-binary", 'b', "FLAG", CFG_NONE, &cfg.raw_binary, no_argument, raw_binary}, + {"human-readable", 'H', "FLAG", CFG_NONE, &cfg.human_readable, no_argument, human_readable}, + {0} + }; + + fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); + + if (cfg.human_readable) + flags |= HUMAN; + else if (cfg.raw_binary) + flags |= RAW; + + return lnvm_do_id_ns(fd, cfg.namespace_id, flags); +} + + +static int lnvm_create_tgt(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Instantiate a target on top of a LightNVM enabled device."; + const char *devname = "identifier of desired device. e.g. nvme0n1."; + const char *tgtname = "target name of the device to initialize. e.g. target0."; + const char *tgttype = "identifier of target type. e.g. pblk."; + const char *lun_begin = "Define begin of luns to use for target."; + const char *lun_end = "Define set of luns to use for target."; + + struct config + { + char *devname; + char *tgtname; + char *tgttype; + int lun_begin; + int lun_end; + }; + + struct config cfg = { + .devname = "", + .tgtname = "", + .tgttype = "", + .lun_begin = 0, + .lun_end = 0, + }; + + const struct argconfig_commandline_options command_line_options[] = { + {"device-name", 'd', "DEVICE", CFG_STRING, &cfg.devname, required_argument, devname}, + {"target-name", 'n', "TARGET", CFG_STRING, &cfg.tgtname, required_argument, tgtname}, + {"target-type", 't', "TARGETTYPE", CFG_STRING, &cfg.tgttype, required_argument, tgttype}, + {"lun-begin", 'b', "NUM", CFG_POSITIVE, &cfg.tgttype, no_argument, lun_begin}, + {"lun-end", 'e', "NUM", CFG_POSITIVE, &cfg.tgttype, no_argument, lun_end}, + {0} + }; + + argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); + + if (!strlen(cfg.devname)) { + fprintf(stderr, "device name missing %d\n", (int)strlen(cfg.devname)); + return -EINVAL; + } + if (!strlen(cfg.tgtname)) { + fprintf(stderr, "target name missing\n"); + return -EINVAL; + } + if (!strlen(cfg.tgttype)) { + fprintf(stderr, "target type missing\n"); + return -EINVAL; + } + + return lnvm_do_create_tgt(cfg.devname, cfg.tgtname, cfg.tgttype, cfg.lun_begin, cfg.lun_end); +} + +static int lnvm_remove_tgt(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Remove an initialized LightNVM target."; + const char *tgtname = "target name of the device to initialize. e.g. target0."; + + struct config + { + char *tgtname; + }; + + struct config cfg = { + .tgtname = "", + }; + + const struct argconfig_commandline_options command_line_options[] = { + {"target-name", 'n', "TARGET", CFG_STRING, &cfg.tgtname, required_argument, tgtname}, + {0} + }; + + argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); + + if (!strlen(cfg.tgtname)) { + fprintf(stderr, "target name missing\n"); + return -EINVAL; + } + + return lnvm_do_remove_tgt(cfg.tgtname); +} + +static int lnvm_factory_init(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Factory initialize a LightNVM enabled device."; + const char *devname = "identifier of desired device. e.g. nvme0n1."; + const char *erase_only_marked = "only erase marked blocks. default: all blocks."; + const char *host_marks = "remove host side blocks list. default: keep."; + const char *bb_marks = "remove grown bad blocks list. default: keep"; + + struct config + { + char *devname; + int erase_only_marked; + int clear_host_marks; + int clear_bb_marks; + }; + + struct config cfg = { + .devname = "", + }; + + const struct argconfig_commandline_options command_line_options[] = { + {"device-name", 'd', "DEVICE", CFG_STRING, &cfg.devname, required_argument, devname}, + {"erase-only-marked", 'e', "", CFG_NONE, &cfg.erase_only_marked, no_argument, erase_only_marked}, + {"clear-host-side-blks", 's', "", CFG_NONE, &cfg.clear_host_marks, no_argument, host_marks}, + {"clear-bb-blks", 'b', "", CFG_NONE, &cfg.clear_bb_marks, no_argument, bb_marks}, + {0} + }; + + argconfig_parse(argc, argv, desc, command_line_options, &cfg, + sizeof(cfg)); + + return lnvm_do_factory_init(cfg.devname, cfg.erase_only_marked, + cfg.clear_host_marks, cfg.clear_bb_marks); +} + +static int lnvm_get_bbtbl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Receive bad block table from a LightNVM compatible"\ + " device."; + const char *namespace = "(optional) desired namespace"; + const char *ch = "channel identifier"; + const char *lun = "lun identifier (within a channel)"; + const char *raw_binary = "show infos in binary format"; + unsigned int fd, flags = 0; + + struct config + { + __u32 namespace_id; + __u16 lunid; + __u16 chid; + int raw_binary; + }; + + struct config cfg = { + .namespace_id = 1, + .lunid = 0, + .chid = 0, + }; + + const struct argconfig_commandline_options command_line_options[] = { + {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace}, + {"channel-id", 'c', "", CFG_SHORT, &cfg.chid, required_argument, ch}, + {"lun-id", 'l', "", CFG_SHORT, &cfg.lunid, required_argument, lun}, + {"raw-binary", 'b', "FLAG", CFG_NONE, &cfg.raw_binary, no_argument, raw_binary}, + {0} + }; + + fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); + + if (cfg.raw_binary) + flags |= RAW; + + return lnvm_do_get_bbtbl(fd, cfg.namespace_id, cfg.lunid, cfg.chid, + flags); +} + +static int lnvm_set_bbtbl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Update bad block table on a LightNVM compatible"\ + " device."; + const char *namespace = "(optional) desired namespace"; + const char *ch = "channel identifier"; + const char *lun = "lun identifier (within a channel)"; + const char *pln = "plane identifier (within a lun)"; + const char *blk = "block identifier (within a plane)"; + const char *value = "value to update the specific block to."; + int fd; + + struct config + { + __u32 namespace_id; + __u16 lunid; + __u16 chid; + __u16 plnid; + __u16 blkid; + __u16 value; + }; + + struct config cfg = { + .namespace_id = 1, + .lunid = 0, + .chid = 0, + .plnid = 0, + .blkid = 0, + .value = 0, + }; + + const struct argconfig_commandline_options command_line_options[] = { + {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace}, + {"channel-id", 'c', "NUM", CFG_SHORT, &cfg.chid, required_argument, ch}, + {"lun-id", 'l', "NUM", CFG_SHORT, &cfg.lunid, required_argument, lun}, + {"plane-id", 'p', "NUM", CFG_SHORT, &cfg.plnid, required_argument, pln}, + {"block-id", 'b', "NUM", CFG_SHORT, &cfg.blkid, required_argument, blk}, + {"value", 'v', "NUM", CFG_SHORT, &cfg.value, required_argument, value}, + {0} + }; + + fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); + + printf("Updating: Ch.: %u LUN: %u Plane: %u Block: %u -> %u\n", + cfg.chid, cfg.lunid, cfg.plnid, cfg.blkid, cfg.value); + + return lnvm_do_set_bbtbl(fd, cfg.namespace_id, + cfg.chid, cfg.lunid, cfg.plnid, cfg.blkid, + cfg.value); +} diff --git a/lnvm-nvme.h b/lnvm-nvme.h new file mode 100644 index 00000000..65e7180c --- /dev/null +++ b/lnvm-nvme.h @@ -0,0 +1,24 @@ + +#undef CMD_INC_FILE +#define CMD_INC_FILE lnvm-nvme + +#if !defined(LNVM_NVME) || defined(CMD_HEADER_MULTI_READ) +#define LNVM_NVME + +#include "cmd.h" + +COMMAND_LIST( + ENTRY("list", "List available LightNVM devices", lnvm_list) + ENTRY("info", "List general information and available target engines", lnvm_info) + ENTRY("id-ns", "List geometry for LightNVM device", lnvm_id_ns) + ENTRY("init", "Initialize media manager on LightNVM device", lnvm_init) + ENTRY("create", "Create target on top of a LightNVM device", lnvm_create_tgt) + ENTRY("remove", "Remove target from device", lnvm_remove_tgt) + ENTRY("factory", "Reset device to factory state", lnvm_factory_init) + ENTRY("diag-bbtbl", "Diagnose bad block table", lnvm_get_bbtbl) + ENTRY("diag-set-bbtbl", "Update bad block table", lnvm_set_bbtbl) +); + +#endif + +#include "define_cmd.h" diff --git a/nvme-builtin.h b/nvme-builtin.h index d8dc8989..dc314cbb 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -45,15 +45,6 @@ COMMAND_LIST( ENTRY("reset", "Resets the controller", reset) ENTRY("subsystem-reset", "Resets the controller", subsystem_reset) ENTRY("show-regs", "Shows the controller registers. Requires admin character device", show_registers) - ENTRY("lnvm-list", "List available LightNVM devices", lnvm_list) - ENTRY("lnvm-info", "List general information and available target engines", lnvm_info) - ENTRY("lnvm-id-ns", "List geometry for LightNVM device", lnvm_id_ns) - ENTRY("lnvm-init", "Initialize media manager on LightNVM device", lnvm_init) - ENTRY("lnvm-create", "Create target on top of a LightNVM device", lnvm_create_tgt) - ENTRY("lnvm-remove", "Remove target from device", lnvm_remove_tgt) - ENTRY("lnvm-factory", "Reset device to factory state", lnvm_factory_init) - ENTRY("lnvm-diag-bbtbl", "Diagnose bad block table", lnvm_get_bbtbl) - ENTRY("lnvm-diag-set-bbtbl", "Update bad block table", lnvm_set_bbtbl) ENTRY("discover", "Discover NVMeoF subsystems", discover_cmd) ENTRY("connect-all", "Discover and Connect to NVMeoF subsystems", connect_all_cmd) ENTRY("connect", "Connect to NVMeoF subsystem", connect_cmd) diff --git a/nvme.c b/nvme.c index 5313755f..cfeac844 100644 --- a/nvme.c +++ b/nvme.c @@ -2562,314 +2562,6 @@ static int admin_passthru(int argc, char **argv, struct command *cmd, struct plu return passthru(argc, argv, NVME_IOCTL_ADMIN_CMD, desc, cmd); } -static int lnvm_init(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "Initialize LightNVM device. A LightNVM/Open-Channel SSD"\ - " must have a media manager associated before it can "\ - " be exposed to the user. The default is to initialize" - " the general media manager on top of the device.\n\n" - "Example:" - " lnvm-init -d nvme0n1"; - const char *devname = "identifier of desired device. e.g. nvme0n1."; - const char *mmtype = "media manager to initialize on top of device. Default: gennvm."; - - struct config - { - char *devname; - char *mmtype; - }; - - struct config cfg = { - .devname = "", - .mmtype = "gennvm", - }; - - const struct argconfig_commandline_options command_line_options[] = { - {"device-name", 'd', "DEVICE", CFG_STRING, &cfg.devname, required_argument, devname}, - {"mediamgr-name", 'm', "MM", CFG_STRING, &cfg.mmtype, no_argument, mmtype}, - {0} - }; - - argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); - - return lnvm_do_init(cfg.devname, cfg.mmtype); -} - -static int lnvm_list(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "List all devices registered with LightNVM."; - - const struct argconfig_commandline_options command_line_options[] = { - {0} - }; - - argconfig_parse(argc, argv, desc, command_line_options, NULL, 0); - - return lnvm_do_list_devices(); -} - -static int lnvm_info(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "Show general information and registered target types with LightNVM"; - - const struct argconfig_commandline_options command_line_options[] = { - {0} - }; - - argconfig_parse(argc, argv, desc, command_line_options, NULL, 0); - - return lnvm_do_info(); -} - -static int lnvm_id_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "Send an Identify Geometry command to the "\ - "given LightNVM device, returns properties of the specified"\ - "namespace in either human-readable or binary format."; - const char *force = "Return this namespace, even if not supported"; - const char *raw_binary = "show infos in binary format"; - const char *human_readable = "show infos in readable format"; - const char *namespace_id = "identifier of desired namespace. default: 1"; - unsigned int flags = 0; - - struct config { - __u32 namespace_id; - int raw_binary; - int human_readable; - int force; - }; - - struct config cfg = { - .namespace_id = 1, - }; - - const struct argconfig_commandline_options command_line_options[] = { - {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace_id}, - {"force", 'f', "FLAG", CFG_NONE, &cfg.force, no_argument, force}, - {"raw-binary", 'b', "FLAG", CFG_NONE, &cfg.raw_binary, no_argument, raw_binary}, - {"human-readable", 'H', "FLAG", CFG_NONE, &cfg.human_readable, no_argument, human_readable}, - {0} - }; - - parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); - - if (cfg.human_readable) - flags |= HUMAN; - else if (cfg.raw_binary) - flags |= RAW; - - return lnvm_do_id_ns(fd, cfg.namespace_id, flags); -} - - -static int lnvm_create_tgt(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "Instantiate a target on top of a LightNVM enabled device."; - const char *devname = "identifier of desired device. e.g. nvme0n1."; - const char *tgtname = "target name of the device to initialize. e.g. target0."; - const char *tgttype = "identifier of target type. e.g. pblk."; - const char *lun_begin = "Define begin of luns to use for target."; - const char *lun_end = "Define set of luns to use for target."; - - struct config - { - char *devname; - char *tgtname; - char *tgttype; - int lun_begin; - int lun_end; - }; - - struct config cfg = { - .devname = "", - .tgtname = "", - .tgttype = "", - .lun_begin = 0, - .lun_end = 0, - }; - - const struct argconfig_commandline_options command_line_options[] = { - {"device-name", 'd', "DEVICE", CFG_STRING, &cfg.devname, required_argument, devname}, - {"target-name", 'n', "TARGET", CFG_STRING, &cfg.tgtname, required_argument, tgtname}, - {"target-type", 't', "TARGETTYPE", CFG_STRING, &cfg.tgttype, required_argument, tgttype}, - {"lun-begin", 'b', "NUM", CFG_POSITIVE, &cfg.tgttype, no_argument, lun_begin}, - {"lun-end", 'e', "NUM", CFG_POSITIVE, &cfg.tgttype, no_argument, lun_end}, - {0} - }; - - argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); - - if (!strlen(cfg.devname)) { - fprintf(stderr, "device name missing %d\n", (int)strlen(cfg.devname)); - return -EINVAL; - } - if (!strlen(cfg.tgtname)) { - fprintf(stderr, "target name missing\n"); - return -EINVAL; - } - if (!strlen(cfg.tgttype)) { - fprintf(stderr, "target type missing\n"); - return -EINVAL; - } - - return lnvm_do_create_tgt(cfg.devname, cfg.tgtname, cfg.tgttype, cfg.lun_begin, cfg.lun_end); -} - -static int lnvm_remove_tgt(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "Remove an initialized LightNVM target."; - const char *tgtname = "target name of the device to initialize. e.g. target0."; - - struct config - { - char *tgtname; - }; - - struct config cfg = { - .tgtname = "", - }; - - const struct argconfig_commandline_options command_line_options[] = { - {"target-name", 'n', "TARGET", CFG_STRING, &cfg.tgtname, required_argument, tgtname}, - {0} - }; - - argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); - - if (!strlen(cfg.tgtname)) { - fprintf(stderr, "target name missing\n"); - return -EINVAL; - } - - return lnvm_do_remove_tgt(cfg.tgtname); -} - -static int lnvm_factory_init(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "Factory initialize a LightNVM enabled device."; - const char *devname = "identifier of desired device. e.g. nvme0n1."; - const char *erase_only_marked = "only erase marked blocks. default: all blocks."; - const char *host_marks = "remove host side blocks list. default: keep."; - const char *bb_marks = "remove grown bad blocks list. default: keep"; - - struct config - { - char *devname; - int erase_only_marked; - int clear_host_marks; - int clear_bb_marks; - }; - - struct config cfg = { - .devname = "", - }; - - const struct argconfig_commandline_options command_line_options[] = { - {"device-name", 'd', "DEVICE", CFG_STRING, &cfg.devname, required_argument, devname}, - {"erase-only-marked", 'e', "", CFG_NONE, &cfg.erase_only_marked, no_argument, erase_only_marked}, - {"clear-host-side-blks", 's', "", CFG_NONE, &cfg.clear_host_marks, no_argument, host_marks}, - {"clear-bb-blks", 'b', "", CFG_NONE, &cfg.clear_bb_marks, no_argument, bb_marks}, - {0} - }; - - argconfig_parse(argc, argv, desc, command_line_options, &cfg, - sizeof(cfg)); - - return lnvm_do_factory_init(cfg.devname, cfg.erase_only_marked, - cfg.clear_host_marks, cfg.clear_bb_marks); -} - -static int lnvm_get_bbtbl(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "Receive bad block table from a LightNVM compatible"\ - " device."; - const char *namespace = "(optional) desired namespace"; - const char *ch = "channel identifier"; - const char *lun = "lun identifier (within a channel)"; - const char *raw_binary = "show infos in binary format"; - unsigned int flags = 0; - - struct config - { - __u32 namespace_id; - __u16 lunid; - __u16 chid; - int raw_binary; - }; - - struct config cfg = { - .namespace_id = 1, - .lunid = 0, - .chid = 0, - }; - - const struct argconfig_commandline_options command_line_options[] = { - {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace}, - {"channel-id", 'c', "", CFG_SHORT, &cfg.chid, required_argument, ch}, - {"lun-id", 'l', "", CFG_SHORT, &cfg.lunid, required_argument, lun}, - {"raw-binary", 'b', "FLAG", CFG_NONE, &cfg.raw_binary, no_argument, raw_binary}, - {0} - }; - - parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); - - if (cfg.raw_binary) - flags |= RAW; - - return lnvm_do_get_bbtbl(fd, cfg.namespace_id, cfg.lunid, cfg.chid, - flags); -} - -static int lnvm_set_bbtbl(int argc, char **argv, struct command *cmd, struct plugin *plugin) -{ - const char *desc = "Update bad block table on a LightNVM compatible"\ - " device."; - const char *namespace = "(optional) desired namespace"; - const char *ch = "channel identifier"; - const char *lun = "lun identifier (within a channel)"; - const char *pln = "plane identifier (within a lun)"; - const char *blk = "block identifier (within a plane)"; - const char *value = "value to update the specific block to."; - - struct config - { - __u32 namespace_id; - __u16 lunid; - __u16 chid; - __u16 plnid; - __u16 blkid; - __u16 value; - }; - - struct config cfg = { - .namespace_id = 1, - .lunid = 0, - .chid = 0, - .plnid = 0, - .blkid = 0, - .value = 0, - }; - - const struct argconfig_commandline_options command_line_options[] = { - {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace}, - {"channel-id", 'c', "NUM", CFG_SHORT, &cfg.chid, required_argument, ch}, - {"lun-id", 'l', "NUM", CFG_SHORT, &cfg.lunid, required_argument, lun}, - {"plane-id", 'p', "NUM", CFG_SHORT, &cfg.plnid, required_argument, pln}, - {"block-id", 'b', "NUM", CFG_SHORT, &cfg.blkid, required_argument, blk}, - {"value", 'v', "NUM", CFG_SHORT, &cfg.value, required_argument, value}, - {0} - }; - - parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); - - printf("Updating: Ch.: %u LUN: %u Plane: %u Block: %u -> %u\n", - cfg.chid, cfg.lunid, cfg.plnid, cfg.blkid, cfg.value); - - return lnvm_do_set_bbtbl(fd, cfg.namespace_id, - cfg.chid, cfg.lunid, cfg.plnid, cfg.blkid, - cfg.value); -} - static int discover_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) { const char *desc = "Send command to discovery service.";