[PATCH RFC] nvmetcli: execute shell commands as arguments

Maurizio Lombardi mlombard at redhat.com
Tue Jan 21 07:59:32 PST 2025


Hello,

A few days ago I was trying to create a target with
tens of subsystems and I found out that, AFACT, there
is no straightforward way to do that with nvmetcli.

It's iSCSI counterpart, targetcli, accepts shell commands
as arguments and althought it's terribly slow, a similar
feature for nvmetcli would allow the user to create simple
scripts like the following one:

nvmetcli ports/ create portid=1
nvmetcli ports/1/ set addr adrfam=ipv4 traddr=10.8.2.212 trtype=tcp trsvcid=4420

for i in $(seq 1 100); do
    nvmetcli subsystems/ create nqn=test-nqn$i
    nvmetcli subsystems/test-nqn$i/ set attr allow_any_host=1
    nvmetcli subsystems/test-nqn$i/namespaces create nsid=1
    nvmetcli subsystems/test-nqn$i/namespaces/1 set device path=/root/storage$i.img
    nvmetcli ports/1/subsystems/ create test-nqn$i
    nvmetcli subsystems/test-nqn$i/namespaces/1 enable
done

Should there be any interest, I can submit a formal patch.

Signed-off-by: Maurizio Lombardi <mlombard at redhat.com>
---
 nvmetcli | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/nvmetcli b/nvmetcli
index d949891..044b24c 100755
--- a/nvmetcli
+++ b/nvmetcli
@@ -666,7 +666,8 @@ def usage():
     print("syntax: %s save [file_to_save_to]" % sys.argv[0])
     print("        %s restore [file_to_restore_from]" % sys.argv[0])
     print("        %s clear" % sys.argv[0])
-    print("        %s ls" % sys.argv[0])
+    print("        %s --help  (Print this information)" % sys.argv[0])
+    print("        %s <CMD>   (Run shell command and exit)" % sys.argv[0])
     sys.exit(-1)
 
 
@@ -703,14 +704,14 @@ def clear(unused):
     nvme.Root().clear_existing()
 
 
-def ls(unused):
+def execute_cmd(cmd):
     shell = configshell.shell.ConfigShell('~/.nvmetcli')
     UIRootNode(shell)
-    shell.run_cmdline("ls")
+    shell.run_cmdline(cmd)
     sys.exit(0)
 
 
-funcs = dict(save=save, restore=restore, clear=clear, ls=ls)
+funcs = dict(save=save, restore=restore, clear=clear)
 
 
 def main():
@@ -718,23 +719,23 @@ def main():
         print("%s: must run as root." % sys.argv[0], file=sys.stderr)
         sys.exit(-1)
 
-    if len(sys.argv) > 3:
-        usage()
-
-    if len(sys.argv) == 2 or len(sys.argv) == 3:
+    if len(sys.argv) > 1:
         if sys.argv[1] == "--help":
             usage()
 
-        if sys.argv[1] not in funcs.keys():
-            usage()
+        if sys.argv[1] in funcs.keys():
+            if len(sys.argv) > 3:
+                usage()
+            if len(sys.argv) == 3:
+                savefile = sys.argv[2]
+            else:
+                savefile = None
 
-        if len(sys.argv) == 3:
-            savefile = sys.argv[2]
+            funcs[sys.argv[1]](savefile)
+            return
         else:
-            savefile = None
-
-        funcs[sys.argv[1]](savefile)
-        return
+            concat_args = ' '.join(sys.argv[1:])
+            execute_cmd(concat_args)
 
     try:
         shell = configshell.shell.ConfigShell('~/.nvmetcli')
-- 
2.43.5




More information about the Linux-nvme mailing list