1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00

Add dmsetup ls --exec.

This commit is contained in:
Alasdair Kergon 2005-05-16 20:46:46 +00:00
parent d6da172a2a
commit 332286072e
3 changed files with 127 additions and 31 deletions

View File

@ -2,6 +2,7 @@ Version 1.01.02 -
============================= =============================
Call dm_lib_exit() and dm_lib_release() automatically now. Call dm_lib_exit() and dm_lib_release() automatically now.
Add --target <target_type> filter to dmsetup table/status/ls. Add --target <target_type> filter to dmsetup table/status/ls.
Add --exec <command> to dmsetup ls.
Fix dmsetup getopt_long usage. Fix dmsetup getopt_long usage.
Version 1.01.01 - 29 Mar 2005 Version 1.01.01 - 29 Mar 2005

View File

@ -29,7 +29,7 @@ dmsetup \- low level logical volume management
.B dmsetup rename .B dmsetup rename
.I device_name new_name .I device_name new_name
.br .br
.B dmsetup ls [--target target_type] .B dmsetup ls [--target target_type] [--exec command]
.br .br
.B dmsetup info .B dmsetup info
.I [device_name] .I [device_name]
@ -146,9 +146,11 @@ Outputs some brief information about the device in the form:
UUID UUID
.IP \fBls .IP \fBls
.I [--target target_type] .I [--target target_type]
.I [--exec command]
.br .br
List device names. Optionally only list devices that have at least List device names. Optionally only list devices that have at least
one target of the specified type. one target of the specified type. Optionally execute a command for
each device. The device name is appended to the supplied command.
.IP \fBload|reload .IP \fBload|reload
.I device_name [table_file] .I device_name [table_file]
.br .br

View File

@ -13,6 +13,9 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include "libdevmapper.h" #include "libdevmapper.h"
#include "log.h" #include "log.h"
@ -24,6 +27,9 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <libgen.h> #include <libgen.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/param.h>
#ifdef HAVE_GETOPTLONG #ifdef HAVE_GETOPTLONG
# include <getopt.h> # include <getopt.h>
@ -38,6 +44,15 @@ extern char *optarg;
# define OPTIND_INIT 1 # define OPTIND_INIT 1
#endif #endif
#ifndef TEMP_FAILURE_RETRY
# define TEMP_FAILURE_RETRY(expression) \
(__extension__ \
({ long int __result; \
do __result = (long int) (expression); \
while (__result == -1L && errno == EINTR); \
__result; }))
#endif
#ifdef linux #ifdef linux
# include "kdev_t.h" # include "kdev_t.h"
#else #else
@ -47,6 +62,7 @@ extern char *optarg;
#endif #endif
#define LINE_SIZE 1024 #define LINE_SIZE 1024
#define ARGS_MAX 256
#define err(msg, x...) fprintf(stderr, msg "\n", ##x) #define err(msg, x...) fprintf(stderr, msg "\n", ##x)
@ -56,6 +72,7 @@ extern char *optarg;
enum { enum {
READ_ONLY = 0, READ_ONLY = 0,
COLS_ARG, COLS_ARG,
EXEC_ARG,
MAJOR_ARG, MAJOR_ARG,
MINOR_ARG, MINOR_ARG,
NOHEADINGS_ARG, NOHEADINGS_ARG,
@ -74,6 +91,7 @@ static int _values[NUM_SWITCHES];
static char *_uuid; static char *_uuid;
static char *_fields; static char *_fields;
static char *_target; static char *_target;
static char *_command;
/* /*
* Commands * Commands
@ -608,6 +626,94 @@ static void _display_dev(struct dm_task *dmt, char *name)
printf("%s\t(%u, %u)\n", name, info.major, info.minor); printf("%s\t(%u, %u)\n", name, info.major, info.minor);
} }
static int _mknodes_single(char *name)
{
struct dm_task *dmt;
int r = 0;
if (!(dmt = dm_task_create(DM_DEVICE_MKNODES)))
return 0;
if (!_set_task_device(dmt, name, 1))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
r = 1;
out:
dm_task_destroy(dmt);
return r;
}
static int _mknodes(int argc, char **argv, void *data)
{
return _mknodes_single(argc > 1 ? argv[1] : NULL);
}
static int _exec_command(char *name)
{
int n;
static char path[PATH_MAX];
static char *args[ARGS_MAX + 1];
static int argc = 0;
char *c;
pid_t pid;
if (argc < 0)
return 0;
if (!_mknodes_single(name))
return 0;
n = snprintf(path, sizeof(path), "%s/%s", dm_dir(), name);
if (n < 0 || n > sizeof(path) - 1)
return 0;
if (!argc) {
c = _command;
while (argc < ARGS_MAX) {
while (*c && isspace(*c))
c++;
if (!*c)
break;
args[argc++] = c;
while (*c && !isspace(*c))
c++;
if (*c)
*c++ = '\0';
}
if (!argc) {
argc = -1;
return 0;
}
if (argc == ARGS_MAX) {
err("Too many args to --exec\n");
argc = -1;
return 0;
}
args[argc++] = path;
args[argc] = NULL;
}
if (!(pid = fork())) {
execvp(args[0], args);
exit(127);
} else if (pid < (pid_t) 0)
return 0;
TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0));
return 1;
}
static int _status(int argc, char **argv, void *data) static int _status(int argc, char **argv, void *data)
{ {
int r = 0; int r = 0;
@ -660,9 +766,12 @@ static int _status(int argc, char **argv, void *data)
strcmp(target_type, _target)) strcmp(target_type, _target))
continue; continue;
if (ls_only) { if (ls_only) {
_display_dev(dmt, name); if (!_switches[EXEC_ARG] || !_command ||
_switches[VERBOSE_ARG])
_display_dev(dmt, name);
next = NULL; next = NULL;
} else { } else if (!_switches[EXEC_ARG] || !_command ||
_switches[VERBOSE_ARG]) {
if (!matched && _switches[VERBOSE_ARG]) if (!matched && _switches[VERBOSE_ARG])
_display_info(dmt); _display_info(dmt);
if (data && !_switches[VERBOSE_ARG]) if (data && !_switches[VERBOSE_ARG])
@ -679,12 +788,14 @@ static int _status(int argc, char **argv, void *data)
if (data && _switches[VERBOSE_ARG] && matched && !ls_only) if (data && _switches[VERBOSE_ARG] && matched && !ls_only)
printf("\n"); printf("\n");
if (matched && _switches[EXEC_ARG] && _command && !_exec_command(name))
goto out;
r = 1; r = 1;
out: out:
dm_task_destroy(dmt); dm_task_destroy(dmt);
return r; return r;
} }
/* Show target names and their version numbers */ /* Show target names and their version numbers */
@ -721,30 +832,6 @@ static int _targets(int argc, char **argv, void *data)
} }
static int _mknodes(int argc, char **argv, void *data)
{
struct dm_task *dmt;
int r = 0;
if (!(dmt = dm_task_create(DM_DEVICE_MKNODES)))
return 0;
if (!_set_task_device(dmt, argc > 1 ? argv[1] : NULL, 1))
goto out;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
r = 1;
out:
dm_task_destroy(dmt);
return r;
}
static int _info(int argc, char **argv, void *data) static int _info(int argc, char **argv, void *data)
{ {
int r = 0; int r = 0;
@ -859,7 +946,8 @@ static int _display_name(int argc, char **argv, void *data)
static int _ls(int argc, char **argv, void *data) static int _ls(int argc, char **argv, void *data)
{ {
if (_switches[TARGET_ARG] && _target) if ((_switches[TARGET_ARG] && _target) ||
(_switches[EXEC_ARG] && _command))
return _status(argc, argv, data); return _status(argc, argv, data);
else else
return _process_all(argc, argv, _display_name); return _process_all(argc, argv, _display_name);
@ -891,7 +979,7 @@ static struct command _commands[] = {
{"reload", "<device> [<table_file>]", 0, 2, _load}, {"reload", "<device> [<table_file>]", 0, 2, _load},
{"rename", "<device> <new_name>", 1, 2, _rename}, {"rename", "<device> <new_name>", 1, 2, _rename},
{"message", "<device> <sector> <message>", 2, -1, _message}, {"message", "<device> <sector> <message>", 2, -1, _message},
{"ls", "[--target <target_type>]", 0, 0, _ls}, {"ls", "[--target <target_type>] [--exec <command>]", 0, 0, _ls},
{"info", "[<device>]", 0, 1, _info}, {"info", "[<device>]", 0, 1, _info},
{"deps", "[<device>]", 0, 1, _deps}, {"deps", "[<device>]", 0, 1, _deps},
{"status", "[<device>] [--target <target_type>]", 0, 1, _status}, {"status", "[<device>] [--target <target_type>]", 0, 1, _status},
@ -939,6 +1027,7 @@ static int _process_switches(int *argc, char ***argv)
static struct option long_options[] = { static struct option long_options[] = {
{"readonly", 0, &ind, READ_ONLY}, {"readonly", 0, &ind, READ_ONLY},
{"columns", 0, &ind, COLS_ARG}, {"columns", 0, &ind, COLS_ARG},
{"exec", 1, &ind, EXEC_ARG},
{"major", 1, &ind, MAJOR_ARG}, {"major", 1, &ind, MAJOR_ARG},
{"minor", 1, &ind, MINOR_ARG}, {"minor", 1, &ind, MINOR_ARG},
{"noheadings", 0, &ind, NOHEADINGS_ARG}, {"noheadings", 0, &ind, NOHEADINGS_ARG},
@ -1023,6 +1112,10 @@ static int _process_switches(int *argc, char ***argv)
_switches[UUID_ARG]++; _switches[UUID_ARG]++;
_uuid = optarg; _uuid = optarg;
} }
if ((ind == EXEC_ARG)) {
_switches[EXEC_ARG]++;
_command = optarg;
}
if ((ind == TARGET_ARG)) { if ((ind == TARGET_ARG)) {
_switches[TARGET_ARG]++; _switches[TARGET_ARG]++;
_target = optarg; _target = optarg;