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.

This commit is contained in:
Ken Pettit 2015-11-28 09:05:05 -06:00 committed by Gregory Nutt
parent 92b1eb36c8
commit d82b8a2e23
5 changed files with 190 additions and 1 deletions

View File

@ -1474,3 +1474,7 @@
* 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).

View File

@ -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

View File

@ -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

View File

@ -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 <dev-path>] | [[-m <minor>] [-o <offset>] [-e <erase-size>] [-s <sect-size>] [-r] <file-path>]" },
# endif
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0
# ifndef CONFIG_NSH_DISABLE_LS
{ "ls", cmd_ls, 1, 5, "[-lRs] <dir-path>" },

View File

@ -61,6 +61,10 @@
# ifdef CONFIG_FS_SMARTFS
# include <apps/fsutils/mksmartfs.h>
# endif
# ifdef CONFIG_SMART_DEV_LOOP
# include <sys/ioctl.h>
# include <nuttx/fs/smart.h>
# endif
# ifdef CONFIG_NFS
# include <sys/socket.h>
# include <netinet/in.h>
@ -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 <loop-device>
* losmart [-m minor-number] [-o <offset>] [-e erasesize] [-s sectsize] [-r] <filename>
*
* 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
****************************************************************************/