From 81f4813c294760b1d074e65e29a307f6911649af Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Thu, 10 Aug 2006 14:11:03 +0000 Subject: [PATCH] Add --table argument to dmsetup for a one-line table. Abort if errors are found during cmdline option processing. --- WHATS_NEW_DM | 2 + man/dmsetup.8.in | 19 ++++---- tools/dmsetup.c | 114 +++++++++++++++++++++++++++++------------------ 3 files changed, 84 insertions(+), 51 deletions(-) diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index cc297b63b..db9d6110e 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,7 @@ Version 1.02.09 - ============================== + Add --table argument to dmsetup for a one-line table. + Abort if errors are found during cmdline option processing. Add lockfs indicator to debug output. Version 1.02.08 - 17 July 2006 diff --git a/man/dmsetup.8.in b/man/dmsetup.8.in index 42d452a92..e518b5004 100644 --- a/man/dmsetup.8.in +++ b/man/dmsetup.8.in @@ -4,7 +4,7 @@ dmsetup \- low level logical volume management .SH SYNOPSIS .ad l .B dmsetup create -.I device_name [-u uuid] [--notable] [table_file] +.I device_name [-u uuid] [--notable | --table | table_file] .br .B dmsetup remove .I [-f|--force] device_name @@ -19,13 +19,13 @@ dmsetup \- low level logical volume management .I device_name .br .B dmsetup load -.I device_name [table_file] +.I device_name [--table
| table_file] .br .B dmsetup clear .I device_name .br .B dmsetup reload -.I device_name [table_file] +.I device_name [--table
| table_file] .br .B dmsetup rename .I device_name new_name @@ -101,6 +101,9 @@ Specify which fields to display. Only \fB-o\ name\fP is supported. .IP \fB-r|--readonly .br Set the table being loaded read-only. +.IP \fB--table\
+.br +Specify a one-line table directly on the command line. .IP \fB-u|--uuid .br Specify the uuid. @@ -112,10 +115,10 @@ Produce additional output. Display the library and kernel driver version. .SH COMMANDS .IP \fBcreate -.I device_name [-u uuid] [--notable] [table_file] +.I device_name [-u uuid] [--notable | --table
| table_file] .br Creates a device with the given name. -If table_file is supplied, the table is loaded and made live. +If table_file or
is supplied, the table is loaded and made live. Otherwise a table is read from standard input unless --notable is used. The optional uuid can be used in place of device_name in subsequent dmsetup commands. @@ -160,10 +163,10 @@ device/nodevice; active, open, rw, uuid. Others specify how the tree is displayed: ascii, utf, vt100; compact, inverted, notrunc. .IP \fBload|reload -.I device_name [table_file] +.I device_name [--table
| table_file] .br -Loads table_file into the inactive table slot for device_name. -If table_file is not supplied, reads a table from standard input. +Loads
or table_file into the inactive table slot for device_name. +If neither is supplied, reads a table from standard input. .IP \fBmknodes .I [device_name] .br diff --git a/tools/dmsetup.c b/tools/dmsetup.c index 1b8d82837..d9dab9d54 100644 --- a/tools/dmsetup.c +++ b/tools/dmsetup.c @@ -98,6 +98,7 @@ enum { NOOPENCOUNT_ARG, NOTABLE_ARG, OPTIONS_ARG, + TABLE_ARG, TARGET_ARG, TREE_ARG, UID_ARG, @@ -112,6 +113,7 @@ static int _values[NUM_SWITCHES]; static int _num_devices; static char *_uuid; static char *_fields; +static char *_table; static char *_target; static char *_command; static struct dm_tree *_dtree; @@ -119,17 +121,55 @@ static struct dm_tree *_dtree; /* * Commands */ +static int _parse_line(struct dm_task *dmt, char *buffer, const char *file, + int line) +{ + char ttype[LINE_SIZE], *ptr, *comment; + unsigned long long start, size; + int n; + + /* trim trailing space */ + for (ptr = buffer + strlen(buffer) - 1; ptr >= buffer; ptr--) + if (!isspace((int) *ptr)) + break; + ptr++; + *ptr = '\0'; + + /* trim leading space */ + for (ptr = buffer; *ptr && isspace((int) *ptr); ptr++) + ; + + if (!*ptr || *ptr == '#') + return 1; + + if (sscanf(ptr, "%llu %llu %s %n", + &start, &size, ttype, &n) < 3) { + err("Invalid format on line %d of table %s", line, file); + return 0; + } + + ptr += n; + if ((comment = strchr(ptr, (int) '#'))) + *comment = '\0'; + + if (!dm_task_add_target(dmt, start, size, ttype, ptr)) + return 0; + + return 1; +} + static int _parse_file(struct dm_task *dmt, const char *file) { char *buffer = NULL; size_t buffer_size = 0; - char ttype[LINE_SIZE], *ptr, *comment; FILE *fp; - unsigned long long start, size; - int r = 0, n, line = 0; + int r = 0, line = 0; + + /* one-line table on cmdline */ + if (_table) + return _parse_line(dmt, _table, "", ++line); /* OK for empty stdin */ - if (file) { if (!(fp = fopen(file, "r"))) { err("Couldn't open '%s' for reading", file); @@ -145,38 +185,13 @@ static int _parse_file(struct dm_task *dmt, const char *file) return 0; } - while (fgets(buffer, (int) buffer_size, fp)) { + while (fgets(buffer, (int) buffer_size, fp)) #else - while (getline(&buffer, &buffer_size, fp) > 0) { + while (getline(&buffer, &buffer_size, fp) > 0) #endif - line++; - - /* trim trailing space */ - for (ptr = buffer + strlen(buffer) - 1; ptr >= buffer; ptr--) - if (!isspace((int) *ptr)) - break; - ptr++; - *ptr = '\0'; - - /* trim leading space */ - for (ptr = buffer; *ptr && isspace((int) *ptr); ptr++) ; - - if (!*ptr || *ptr == '#') - continue; - - if (sscanf(ptr, "%llu %llu %s %n", - &start, &size, ttype, &n) < 3) { - err("%s:%d Invalid format", file, line); + if (!_parse_line(dmt, buffer, file ? : "on stdin", ++line)) goto out; - } - ptr += n; - if ((comment = strchr(ptr, (int) '#'))) - *comment = '\0'; - - if (!dm_task_add_target(dmt, start, size, ttype, ptr)) - goto out; - } r = 1; out: @@ -725,23 +740,23 @@ static int _error_device(int argc __attribute((unused)), char **argv __attribute size = _get_device_size(name); - if (!(dmt = dm_task_create(DM_DEVICE_RELOAD))) - return 0; + if (!(dmt = dm_task_create(DM_DEVICE_RELOAD))) + return 0; if (!_set_task_device(dmt, name, 0)) goto err; - if (!dm_task_add_target(dmt, 0, size, "error", "")) + if (!dm_task_add_target(dmt, 0, size, "error", "")) goto err; - if (_switches[READ_ONLY] && !dm_task_set_ro(dmt)) - goto err; + if (_switches[READ_ONLY] && !dm_task_set_ro(dmt)) + goto err; - if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt)) - goto err; + if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt)) + goto err; - if (!dm_task_run(dmt)) - goto err; + if (!dm_task_run(dmt)) + goto err; if (!_simple(DM_DEVICE_RESUME, name, 0, 0)) { _simple(DM_DEVICE_CLEAR, name, 0, 0); @@ -1472,7 +1487,8 @@ struct command { static struct command _commands[] = { {"create", " [-j|--major -m|--minor ]\n" "\t [-U|--uid ] [-G|--gid ] [-M|--mode ]\n" - "\t [-u|uuid ] [--notable] []", + "\t [-u|uuid ]" + "\t [--notable | --table
| ]", 1, 2, _create}, {"remove", "[-f|--force] ", 0, 1, _remove}, {"remove_all", "[-f|--force]", 0, 0, _remove_all}, @@ -1611,6 +1627,7 @@ static int _process_switches(int *argc, char ***argv) {"noopencount", 0, &ind, NOOPENCOUNT_ARG}, {"notable", 0, &ind, NOTABLE_ARG}, {"options", 1, &ind, OPTIONS_ARG}, + {"table", 1, &ind, TABLE_ARG}, {"target", 1, &ind, TARGET_ARG}, {"tree", 0, &ind, TREE_ARG}, {"uid", 1, &ind, UID_ARG}, @@ -1667,6 +1684,8 @@ static int _process_switches(int *argc, char ***argv) optind = OPTIND_INIT; while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCfGj:m:Mno:ru:Uv", long_options, NULL)) != -1) { + if (ind == -1 || ind == ':' || ind == '?') + return 0; if (c == 'c' || c == 'C' || ind == COLS_ARG) _switches[COLS_ARG]++; if (c == 'f' || ind == FORCE_ARG) @@ -1720,6 +1739,10 @@ static int _process_switches(int *argc, char ***argv) _switches[NOLOCKFS_ARG]++; if ((ind == NOOPENCOUNT_ARG)) _switches[NOOPENCOUNT_ARG]++; + if ((ind == TABLE_ARG)) { + _switches[TABLE_ARG]++; + _table = optarg; + } if ((ind == TREE_ARG)) _switches[TREE_ARG]++; if ((ind == VERSION_ARG)) @@ -1745,6 +1768,11 @@ static int _process_switches(int *argc, char ***argv) if (_switches[TREE_ARG] && !_process_tree_options(_fields)) return 0; + if (_switches[TABLE_ARG] && _switches[NOTABLE_ARG]) { + fprintf(stderr, "--table and --notable are incompatible.\n"); + return 0; + } + *argv += optind; *argc -= optind; return 1; @@ -1755,7 +1783,7 @@ int main(int argc, char **argv) struct command *c; int r = 1; - (void) setlocale(LC_ALL, ""); + (void) setlocale(LC_ALL, ""); if (!_process_switches(&argc, &argv)) { fprintf(stderr, "Couldn't process command line.\n");