From d82b8a2e23743568777b8679c202bf422ef8003b Mon Sep 17 00:00:00 2001 From: Ken Pettit Date: Sat, 28 Nov 2015 09:05:05 -0600 Subject: [PATCH] apps/nshlib: Add a new NSH losmart command. losmart setups up a loop device for the smart MTD driver similar to losetup but with different syntax. From Ket Petit. --- ChangeLog.txt | 6 +- nshlib/Kconfig | 5 ++ nshlib/nsh.h | 3 + nshlib/nsh_command.c | 6 ++ nshlib/nsh_fscmds.c | 171 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 190 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 0073df8f4..2c99b9adb 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1471,6 +1471,10 @@ network statistics. A consequence of this is that you cannot view this network information if the procfs is not enabled and mounted at /proc (2015-11-27). - * apps/nshlib: Remove all references to internal OS interface + * apps/nshlib: Remove all references to internal OS interface netdev_foreach(). Logic in ifconfig, ifup, and ifown now use the procfs file system to examine networking status. (2015-11-27). + * apps/nshlib: Add a new NSH losmart command. losmart setups up + a loop device for the smart MTD driver similar to losetup but + with different syntax. From Ket Petit (2015-11-28). + diff --git a/nshlib/Kconfig b/nshlib/Kconfig index eb8a760d3..59cb27dc6 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -262,6 +262,11 @@ config NSH_DISABLE_LOSETUP default y if DEFAULT_SMALL default n if !DEFAULT_SMALL +config NSH_DISABLE_LOSMART + bool "Disable losmart" + default y if DEFAULT_SMALL + default n if !DEFAULT_SMALL + config NSH_DISABLE_LS bool "Disable ls" default n diff --git a/nshlib/nsh.h b/nshlib/nsh.h index e164ee78c..b100d8872 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -974,6 +974,9 @@ void nsh_usbtrace(void); # if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP) int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); # endif +# if defined(CONFIG_SMART_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSMART) + int cmd_losmart(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +# endif # ifndef CONFIG_NSH_DISABLE_MKFIFO int cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); # endif diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index c23049974..b1077b70e 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -248,6 +248,12 @@ static const struct cmdmap_s g_cmdmap[] = # endif #endif +#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) +# if defined(CONFIG_SMART_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSMART) + { "losmart", cmd_losmart, 2, 11, "[-d ] | [[-m ] [-o ] [-e ] [-s ] [-r] ]" }, +# endif +#endif + #if CONFIG_NFILE_DESCRIPTORS > 0 # ifndef CONFIG_NSH_DISABLE_LS { "ls", cmd_ls, 1, 5, "[-lRs] " }, diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index b72adba8a..b19d35ba2 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -61,6 +61,10 @@ # ifdef CONFIG_FS_SMARTFS # include # endif +# ifdef CONFIG_SMART_DEV_LOOP +# include +# include +# endif # ifdef CONFIG_NFS # include # include @@ -783,6 +787,173 @@ errout_with_paths: #endif #endif +/**************************************************************************** + * Name: cmd_losmart + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT) +# if defined(CONFIG_SMART_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSMART) +int cmd_losmart(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + FAR char *loopdev = NULL; + FAR char *filepath = NULL; + struct smart_losetup_s setup; + bool teardown = false; + bool readonly = false; + int minor = -1; + int erasesize = -1; + int sectsize = -1; + off_t offset = 0; + bool badarg = false; + int ret = ERROR; + int option; + int fd; + + /* Get the losetup options: Two forms are supported: + * + * losmart -d + * losmart [-m minor-number] [-o ] [-e erasesize] [-s sectsize] [-r] + * + * NOTE that the -o and -r options are accepted with the -d option, but + * will be ignored. + */ + + while ((option = getopt(argc, argv, "d:e:m:o:rs:")) != ERROR) + { + switch (option) + { + case 'd': + loopdev = nsh_getfullpath(vtbl, optarg); + teardown = true; + break; + + case 'e': + erasesize = atoi(optarg); + break; + + case 'm': + minor = atoi(optarg); + break; + + case 'o': + offset = atoi(optarg); + break; + + case 'r': + readonly = true; + break; + + case 's': + sectsize = atoi(optarg); + break; + + case '?': + default: + nsh_output(vtbl, g_fmtarginvalid, argv[0]); + badarg = true; + break; + } + } + + /* If a bad argument was encountered, then return without processing the command */ + + if (badarg) + { + goto errout_with_paths; + } + + /* If this is not a tear down operation, then additional command line + * parameters are required. + */ + + if (!teardown) + { + /* There must be two arguments on the command line after the options */ + + if (optind < argc) + { + filepath = nsh_getfullpath(vtbl, argv[optind]); + optind++; + } + else + { + nsh_output(vtbl, g_fmtargrequired, argv[0]); + goto errout_with_paths; + } + } + + /* There should be nothing else on the command line */ + + if (optind < argc) + { + nsh_output(vtbl, g_fmttoomanyargs, argv[0]); + goto errout_with_paths; + } + + /* Open the loop device */ + + fd = open("/dev/smart", O_RDONLY); + if (fd < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO); + goto errout_with_paths; + } + + /* Perform the teardown operation */ + + if (teardown) + { + /* Tear down the loop device. */ + + ret = ioctl(fd, SMART_LOOPIOC_TEARDOWN, (unsigned long)((uintptr_t) loopdev)); + if (ret < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "ioctl", NSH_ERRNO); + goto errout_with_fd; + } + } + else + { + /* Set up the loop device */ + + setup.minor = minor; /* The loop block device to be created */ + setup.filename = filepath; /* The file or character device to use */ + setup.sectsize = sectsize; /* The sector size to use with the block device */ + setup.erasesize = erasesize; /* The sector size to use with the block device */ + setup.offset = offset; /* An offset that may be applied to the device */ + setup.readonly = readonly; /* True: Read access will be supported only */ + + ret = ioctl(fd, SMART_LOOPIOC_SETUP, (unsigned long)((uintptr_t)&setup)); + if (ret < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "ioctl", NSH_ERRNO); + goto errout_with_fd; + } + } + + ret = OK; + + /* Free resources */ + +errout_with_fd: + (void)close(fd); + +errout_with_paths: + if (loopdev) + { + free(loopdev); + } + + if (filepath) + { + free(filepath); + } + + return ret; +} +#endif +#endif + /**************************************************************************** * Name: cmd_ls ****************************************************************************/