Tizen 2.1 base
[external/device-mapper.git] / tools / lvmcmdline.c
1 /*
2  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3  * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
4  *
5  * This file is part of LVM2.
6  *
7  * This copyrighted material is made available to anyone wishing to use,
8  * modify, copy, or redistribute it subject to the terms and conditions
9  * of the GNU Lesser General Public License v.2.1.
10  *
11  * You should have received a copy of the GNU Lesser General Public License
12  * along with this program; if not, write to the Free Software Foundation,
13  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14  */
15
16 #include "tools.h"
17 #include "lvm2cmdline.h"
18 #include "label.h"
19 #include "lvm-version.h"
20
21 #include "stub.h"
22 #include "lvm2cmd.h"
23 #include "last-path-component.h"
24
25 #include <signal.h>
26 #include <syslog.h>
27 #include <libgen.h>
28 #include <sys/stat.h>
29 #include <time.h>
30 #include <sys/resource.h>
31
32 #ifdef HAVE_GETOPTLONG
33 #  include <getopt.h>
34 #  define GETOPTLONG_FN(a, b, c, d, e) getopt_long((a), (b), (c), (d), (e))
35 #  define OPTIND_INIT 0
36 #else
37 struct option {
38 };
39 extern int optind;
40 extern char *optarg;
41 #  define GETOPTLONG_FN(a, b, c, d, e) getopt((a), (b), (c))
42 #  define OPTIND_INIT 1
43 #endif
44
45 #ifdef UDEV_SYNC_SUPPORT
46 #  define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
47 #  include <libudev.h>
48 #endif
49
50 /*
51  * Table of valid switches
52  */
53 static struct arg_props _arg_props[ARG_COUNT + 1] = {
54 #define arg(a, b, c, d, e) {b, "", "--" c, d, e},
55 #include "args.h"
56 #undef arg
57 };
58
59 static struct cmdline_context _cmdline;
60
61 /* Command line args */
62 unsigned arg_count(const struct cmd_context *cmd, int a)
63 {
64         return cmd->arg_values[a].count;
65 }
66
67 unsigned grouped_arg_count(const struct arg_values *av, int a)
68 {
69         return av[a].count;
70 }
71
72 unsigned arg_is_set(const struct cmd_context *cmd, int a)
73 {
74         return arg_count(cmd, a) ? 1 : 0;
75 }
76
77 unsigned grouped_arg_is_set(const struct arg_values *av, int a)
78 {
79         return grouped_arg_count(av, a) ? 1 : 0;
80 }
81
82 const char *arg_value(struct cmd_context *cmd, int a)
83 {
84         return cmd->arg_values[a].value;
85 }
86
87 const char *arg_str_value(struct cmd_context *cmd, int a, const char *def)
88 {
89         return arg_count(cmd, a) ? cmd->arg_values[a].value : def;
90 }
91
92 const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def)
93 {
94         return grouped_arg_count(av, a) ? av[a].value : def;
95 }
96
97 int32_t arg_int_value(struct cmd_context *cmd, int a, const int32_t def)
98 {
99         return arg_count(cmd, a) ? cmd->arg_values[a].i_value : def;
100 }
101
102 uint32_t arg_uint_value(struct cmd_context *cmd, int a, const uint32_t def)
103 {
104         return arg_count(cmd, a) ? cmd->arg_values[a].ui_value : def;
105 }
106
107 int64_t arg_int64_value(struct cmd_context *cmd, int a, const int64_t def)
108 {
109         return arg_count(cmd, a) ? cmd->arg_values[a].i64_value : def;
110 }
111
112 uint64_t arg_uint64_value(struct cmd_context *cmd, int a, const uint64_t def)
113 {
114         return arg_count(cmd, a) ? cmd->arg_values[a].ui64_value : def;
115 }
116
117 /* No longer used.
118 const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def)
119 {
120         return arg_count(cmd, a) ? cmd->arg_values[a].ptr : def;
121 }
122 */
123
124 sign_t arg_sign_value(struct cmd_context *cmd, int a, const sign_t def)
125 {
126         return arg_count(cmd, a) ? cmd->arg_values[a].sign : def;
127 }
128
129 percent_type_t arg_percent_value(struct cmd_context *cmd, int a, const percent_type_t def)
130 {
131         return arg_count(cmd, a) ? cmd->arg_values[a].percent : def;
132 }
133
134 int arg_count_increment(struct cmd_context *cmd, int a)
135 {
136         return cmd->arg_values[a].count++;
137 }
138
139 int yes_no_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
140 {
141         av->sign = SIGN_NONE;
142         av->percent = PERCENT_NONE;
143
144         if (!strcmp(av->value, "y")) {
145                 av->i_value = 1;
146                 av->ui_value = 1;
147         }
148
149         else if (!strcmp(av->value, "n")) {
150                 av->i_value = 0;
151                 av->ui_value = 0;
152         }
153
154         else
155                 return 0;
156
157         return 1;
158 }
159
160 int yes_no_excl_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
161 {
162         av->sign = SIGN_NONE;
163         av->percent = PERCENT_NONE;
164
165         if (!strcmp(av->value, "e") || !strcmp(av->value, "ey") ||
166             !strcmp(av->value, "ye")) {
167                 av->i_value = CHANGE_AE;
168                 av->ui_value = CHANGE_AE;
169         }
170
171         else if (!strcmp(av->value, "y")) {
172                 av->i_value = CHANGE_AY;
173                 av->ui_value = CHANGE_AY;
174         }
175
176         else if (!strcmp(av->value, "n") || !strcmp(av->value, "en") ||
177                  !strcmp(av->value, "ne")) {
178                 av->i_value = CHANGE_AN;
179                 av->ui_value = CHANGE_AN;
180         }
181
182         else if (!strcmp(av->value, "ln") || !strcmp(av->value, "nl")) {
183                 av->i_value = CHANGE_ALN;
184                 av->ui_value = CHANGE_ALN;
185         }
186
187         else if (!strcmp(av->value, "ly") || !strcmp(av->value, "yl")) {
188                 av->i_value = CHANGE_ALY;
189                 av->ui_value = CHANGE_ALY;
190         }
191
192         else
193                 return 0;
194
195         return 1;
196 }
197
198 int metadatatype_arg(struct cmd_context *cmd, struct arg_values *av)
199 {
200         return get_format_by_name(cmd, av->value) ? 1 : 0;
201 }
202
203 static int _get_int_arg(struct arg_values *av, char **ptr)
204 {
205         char *val;
206         long v;
207
208         av->percent = PERCENT_NONE;
209
210         val = av->value;
211         switch (*val) {
212         case '+':
213                 av->sign = SIGN_PLUS;
214                 val++;
215                 break;
216         case '-':
217                 av->sign = SIGN_MINUS;
218                 val++;
219                 break;
220         default:
221                 av->sign = SIGN_NONE;
222         }
223
224         if (!isdigit(*val))
225                 return 0;
226
227         v = strtol(val, ptr, 10);
228
229         if (*ptr == val)
230                 return 0;
231
232         av->i_value = (int32_t) v;
233         av->ui_value = (uint32_t) v;
234         av->i64_value = (int64_t) v;
235         av->ui64_value = (uint64_t) v;
236
237         return 1;
238 }
239
240 /* Size stored in sectors */
241 static int _size_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av, int factor)
242 {
243         char *ptr;
244         int i;
245         static const char *suffixes = "kmgtpebs";
246         char *val;
247         double v;
248         uint64_t v_tmp, adjustment;
249
250         av->percent = PERCENT_NONE;
251
252         val = av->value;
253         switch (*val) {
254         case '+':
255                 av->sign = SIGN_PLUS;
256                 val++;
257                 break;
258         case '-':
259                 av->sign = SIGN_MINUS;
260                 val++;
261                 break;
262         default:
263                 av->sign = SIGN_NONE;
264         }
265
266         if (!isdigit(*val))
267                 return 0;
268
269         v = strtod(val, &ptr);
270
271         if (ptr == val)
272                 return 0;
273
274         if (*ptr) {
275                 for (i = strlen(suffixes) - 1; i >= 0; i--)
276                         if (suffixes[i] == tolower((int) *ptr))
277                                 break;
278
279                 if (i < 0) {
280                         return 0;
281                 } else if (i == 7) {
282                         /* sectors */
283                         v = v;
284                 } else if (i == 6) {
285                         /* bytes */
286                         v_tmp = (uint64_t) v;
287                         adjustment = v_tmp % 512;
288                         if (adjustment) {
289                                 v_tmp += (512 - adjustment);
290                                 log_error("Size is not a multiple of 512. "
291                                           "Try using %"PRIu64" or %"PRIu64".",
292                                           v_tmp - 512, v_tmp);
293                                 return 0;
294                         }
295                         v /= 512;
296                 } else {
297                         /* all other units: kmgtpe */
298                         while (i-- > 0)
299                                 v *= 1024;
300                         v *= 2;
301                 }
302         } else
303                 v *= factor;
304
305         av->i_value = (int32_t) v;
306         av->ui_value = (uint32_t) v;
307         av->i64_value = (int64_t) v;
308         av->ui64_value = (uint64_t) v;
309
310         return 1;
311 }
312
313 int size_kb_arg(struct cmd_context *cmd, struct arg_values *av)
314 {
315         return _size_arg(cmd, av, 2);
316 }
317
318 int size_mb_arg(struct cmd_context *cmd, struct arg_values *av)
319 {
320         return _size_arg(cmd, av, 2048);
321 }
322
323 int int_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
324 {
325         char *ptr;
326
327         if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS))
328                 return 0;
329
330         return 1;
331 }
332
333 int int_arg_with_sign(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
334 {
335         char *ptr;
336
337         if (!_get_int_arg(av, &ptr) || (*ptr))
338                 return 0;
339
340         return 1;
341 }
342
343 int int_arg_with_sign_and_percent(struct cmd_context *cmd __attribute__((unused)),
344                                   struct arg_values *av)
345 {
346         char *ptr;
347
348         if (!_get_int_arg(av, &ptr))
349                 return 0;
350
351         if (!*ptr)
352                 return 1;
353
354         if (*ptr++ != '%')
355                 return 0;
356
357         if (!strcasecmp(ptr, "V") || !strcasecmp(ptr, "VG"))
358                 av->percent = PERCENT_VG;
359         else if (!strcasecmp(ptr, "L") || !strcasecmp(ptr, "LV"))
360                 av->percent = PERCENT_LV;
361         else if (!strcasecmp(ptr, "P") || !strcasecmp(ptr, "PV") ||
362                  !strcasecmp(ptr, "PVS"))
363                 av->percent = PERCENT_PVS;
364         else if (!strcasecmp(ptr, "F") || !strcasecmp(ptr, "FR") ||
365                  !strcasecmp(ptr, "FREE"))
366                 av->percent = PERCENT_FREE;
367         else if (!strcasecmp(ptr, "O") || !strcasecmp(ptr, "OR") ||
368                  !strcasecmp(ptr, "ORIGIN"))
369                 av->percent = PERCENT_ORIGIN;
370         else
371                 return 0;
372
373         return 1;
374 }
375
376 int minor_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
377 {
378         char *ptr;
379
380         if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS))
381                 return 0;
382
383         if (av->i_value > 255) {
384                 log_error("Minor number outside range 0-255");
385                 return 0;
386         }
387
388         return 1;
389 }
390
391 int major_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
392 {
393         char *ptr;
394
395         if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS))
396                 return 0;
397
398         if (av->i_value > 255) {
399                 log_error("Major number outside range 0-255");
400                 return 0;
401         }
402
403         /* FIXME Also Check against /proc/devices */
404
405         return 1;
406 }
407
408 int string_arg(struct cmd_context *cmd __attribute__((unused)),
409                struct arg_values *av __attribute__((unused)))
410 {
411         return 1;
412 }
413
414 int tag_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
415 {
416         char *pos = av->value;
417
418         if (*pos == '@')
419                 pos++;
420
421         if (!validate_tag(pos))
422                 return 0;
423
424         av->value = pos;
425
426         return 1;
427 }
428
429 int permission_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
430 {
431         av->sign = SIGN_NONE;
432
433         if ((!strcmp(av->value, "rw")) || (!strcmp(av->value, "wr")))
434                 av->ui_value = LVM_READ | LVM_WRITE;
435
436         else if (!strcmp(av->value, "r"))
437                 av->ui_value = LVM_READ;
438
439         else
440                 return 0;
441
442         return 1;
443 }
444
445 int alloc_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
446 {
447         alloc_policy_t alloc;
448
449         av->sign = SIGN_NONE;
450
451         alloc = get_alloc_from_string(av->value);
452         if (alloc == ALLOC_INVALID)
453                 return 0;
454
455         av->ui_value = (uint32_t) alloc;
456
457         return 1;
458 }
459
460 int segtype_arg(struct cmd_context *cmd, struct arg_values *av)
461 {
462         return get_segtype_from_string(cmd, av->value) ? 1 : 0;
463 }
464
465 /*
466  * Positive integer, zero or "auto".
467  */
468 int readahead_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
469 {
470         if (!strcasecmp(av->value, "auto")) {
471                 av->ui_value = DM_READ_AHEAD_AUTO;
472                 return 1;
473         }
474
475         if (!strcasecmp(av->value, "none")) {
476                 av->ui_value = DM_READ_AHEAD_NONE;
477                 return 1;
478         }
479
480         if (!_size_arg(cmd, av, 1))
481                 return 0;
482
483         if (av->sign == SIGN_MINUS)
484                 return 0;
485
486         return 1;
487 }
488
489 /*
490  * Non-zero, positive integer, "all", or "unmanaged"
491  */
492 int metadatacopies_arg(struct cmd_context *cmd, struct arg_values *av)
493 {
494         if (!strncmp(cmd->command->name, "vg", 2)) {
495                 if (!strcasecmp(av->value, "all")) {
496                         av->ui_value = VGMETADATACOPIES_ALL;
497                         return 1;
498                 }
499
500                 if (!strcasecmp(av->value, "unmanaged")) {
501                         av->ui_value = VGMETADATACOPIES_UNMANAGED;
502                         return 1;
503                 }
504         }
505
506         return int_arg(cmd, av);
507 }
508
509 static void __alloc(int size)
510 {
511         if (!(_cmdline.commands = dm_realloc(_cmdline.commands, sizeof(*_cmdline.commands) * size))) {
512                 log_fatal("Couldn't allocate memory.");
513                 exit(ECMD_FAILED);
514         }
515
516         _cmdline.commands_size = size;
517 }
518
519 static void _alloc_command(void)
520 {
521         if (!_cmdline.commands_size)
522                 __alloc(32);
523
524         if (_cmdline.commands_size <= _cmdline.num_commands)
525                 __alloc(2 * _cmdline.commands_size);
526 }
527
528 static void _create_new_command(const char *name, command_fn command,
529                                 unsigned flags,
530                                 const char *desc, const char *usagestr,
531                                 int nargs, int *args)
532 {
533         struct command *nc;
534
535         _alloc_command();
536
537         nc = _cmdline.commands + _cmdline.num_commands++;
538
539         nc->name = name;
540         nc->desc = desc;
541         nc->usage = usagestr;
542         nc->fn = command;
543         nc->flags = flags;
544         nc->num_args = nargs;
545         nc->valid_args = args;
546 }
547
548 static void _register_command(const char *name, command_fn fn, const char *desc,
549                               unsigned flags, const char *usagestr, ...)
550 {
551         int nargs = 0, i;
552         int *args;
553         va_list ap;
554
555         /* count how many arguments we have */
556         va_start(ap, usagestr);
557         while (va_arg(ap, int) >= 0)
558                  nargs++;
559         va_end(ap);
560
561         /* allocate space for them */
562         if (!(args = dm_malloc(sizeof(*args) * nargs))) {
563                 log_fatal("Out of memory.");
564                 exit(ECMD_FAILED);
565         }
566
567         /* fill them in */
568         va_start(ap, usagestr);
569         for (i = 0; i < nargs; i++)
570                 args[i] = va_arg(ap, int);
571         va_end(ap);
572
573         /* enter the command in the register */
574         _create_new_command(name, fn, flags, desc, usagestr, nargs, args);
575 }
576
577 void lvm_register_commands(void)
578 {
579 #define xx(a, b, c, d...) _register_command(# a, a, b, c, ## d, \
580                                             driverloaded_ARG, \
581                                             debug_ARG, help_ARG, help2_ARG, \
582                                             version_ARG, verbose_ARG, \
583                                             quiet_ARG, config_ARG, -1);
584 #include "commands.h"
585 #undef xx
586 }
587
588 static struct command *_find_command(const char *name)
589 {
590         int i;
591         const char *base;
592
593         base = last_path_component(name);
594
595         for (i = 0; i < _cmdline.num_commands; i++) {
596                 if (!strcmp(base, _cmdline.commands[i].name))
597                         break;
598         }
599
600         if (i >= _cmdline.num_commands)
601                 return 0;
602
603         return _cmdline.commands + i;
604 }
605
606 static void _short_usage(const char *name)
607 {
608         log_error("Run `%s --help' for more information.", name);
609 }
610
611 static int _usage(const char *name)
612 {
613         struct command *com = _find_command(name);
614
615         if (!com) {
616                 log_print("%s: no such command.", name);
617                 return 0;
618         }
619
620         log_print("%s: %s\n\n%s", com->name, com->desc, com->usage);
621         return 1;
622 }
623
624 /*
625  * Sets up the short and long argument.  If there
626  * is no short argument then the index of the
627  * argument in the the_args array is set as the
628  * long opt value.  Yuck.  Of course this means we
629  * can't have more than 'a' long arguments.
630  */
631 static void _add_getopt_arg(int arg, char **ptr, struct option **o)
632 {
633         struct arg_props *a = _cmdline.arg_props + arg;
634
635         if (a->short_arg) {
636                 *(*ptr)++ = a->short_arg;
637
638                 if (a->fn)
639                         *(*ptr)++ = ':';
640         }
641 #ifdef HAVE_GETOPTLONG
642         if (*(a->long_arg + 2)) {
643                 (*o)->name = a->long_arg + 2;
644                 (*o)->has_arg = a->fn ? 1 : 0;
645                 (*o)->flag = NULL;
646                 if (a->short_arg)
647                         (*o)->val = a->short_arg;
648                 else
649                         (*o)->val = arg;
650                 (*o)++;
651         }
652 #endif
653 }
654
655 static int _find_arg(struct command *com, int opt)
656 {
657         struct arg_props *a;
658         int i, arg;
659
660         for (i = 0; i < com->num_args; i++) {
661                 arg = com->valid_args[i];
662                 a = _cmdline.arg_props + arg;
663
664                 /*
665                  * opt should equal either the
666                  * short arg, or the index into
667                  * the_args.
668                  */
669                 if ((a->short_arg && (opt == a->short_arg)) ||
670                     (!a->short_arg && (opt == arg)))
671                         return arg;
672         }
673
674         return -1;
675 }
676
677 static int _process_command_line(struct cmd_context *cmd, int *argc,
678                                  char ***argv)
679 {
680         int i, opt, arg;
681         char str[((ARG_COUNT + 1) * 2) + 1], *ptr = str;
682         struct option opts[ARG_COUNT + 1], *o = opts;
683         struct arg_props *a;
684         struct arg_values *av;
685         struct arg_value_group_list *current_group = NULL;
686
687         if (!(cmd->arg_values = dm_pool_zalloc(cmd->mem, sizeof(*cmd->arg_values) * ARG_COUNT))) {
688                 log_fatal("Unable to allocate memory for command line arguments.");
689                 return 0;
690         }
691
692         /* fill in the short and long opts */
693         for (i = 0; i < cmd->command->num_args; i++)
694                 _add_getopt_arg(cmd->command->valid_args[i], &ptr, &o);
695
696         *ptr = '\0';
697         memset(o, 0, sizeof(*o));
698
699         /* initialise getopt_long & scan for command line switches */
700         optarg = 0;
701         optind = OPTIND_INIT;
702         while ((opt = GETOPTLONG_FN(*argc, *argv, str, opts, NULL)) >= 0) {
703
704                 if (opt == '?')
705                         return 0;
706
707                 if ((arg = _find_arg(cmd->command, opt)) < 0) {
708                         log_fatal("Unrecognised option.");
709                         return 0;
710                 }
711
712                 a = _cmdline.arg_props + arg;
713
714                 av = &cmd->arg_values[arg];
715
716                 if (a->flags & ARG_GROUPABLE) {
717                         /* Start a new group of arguments the first time or if a non-countable argument is repeated. */
718                         if (!current_group || (current_group->arg_values[arg].count && !(a->flags & ARG_COUNTABLE))) {
719                                 /* FIXME Reduce size including only groupable args */
720                                 if (!(current_group = dm_pool_zalloc(cmd->mem, sizeof(struct arg_value_group_list) + sizeof(*cmd->arg_values) * ARG_COUNT))) {
721                                         log_fatal("Unable to allocate memory for command line arguments.");
722                                         return 0;
723                                 }
724
725                                 dm_list_add(&cmd->arg_value_groups, &current_group->list);
726                         }
727                         /* Maintain total argument count as well as count within each group */
728                         av->count++;
729                         av = &current_group->arg_values[arg];
730                 }
731
732                 if (av->count && !(a->flags & ARG_COUNTABLE)) {
733                         log_error("Option%s%c%s%s may not be repeated.",
734                                   a->short_arg ? " -" : "",
735                                   a->short_arg ? : ' ',
736                                   (a->short_arg && a->long_arg) ?
737                                   "/" : "", a->long_arg ? : "");
738                         return 0;
739                 }
740
741                 if (a->fn) {
742                         if (!optarg) {
743                                 log_error("Option requires argument.");
744                                 return 0;
745                         }
746
747                         av->value = optarg;
748
749                         if (!a->fn(cmd, av)) {
750                                 log_error("Invalid argument for %s: %s", a->long_arg, optarg);
751                                 return 0;
752                         }
753                 }
754
755                 av->count++;
756         }
757
758         *argc -= optind;
759         *argv += optind;
760         return 1;
761 }
762
763 static int _merge_synonym(struct cmd_context *cmd, int oldarg, int newarg)
764 {
765         const struct arg_values *old;
766         struct arg_values *new;
767
768         if (arg_count(cmd, oldarg) && arg_count(cmd, newarg)) {
769                 log_error("%s and %s are synonyms.  Please only supply one.",
770                           _cmdline.arg_props[oldarg].long_arg, _cmdline.arg_props[newarg].long_arg);
771                 return 0;
772         }
773
774         if (!arg_count(cmd, oldarg))
775                 return 1;
776
777         old = cmd->arg_values + oldarg;
778         new = cmd->arg_values + newarg;
779
780         new->count = old->count;
781         new->value = old->value;
782         new->i_value = old->i_value;
783         new->ui_value = old->ui_value;
784         new->i64_value = old->i64_value;
785         new->ui64_value = old->ui64_value;
786         new->sign = old->sign;
787
788         return 1;
789 }
790
791 int version(struct cmd_context *cmd __attribute__((unused)),
792             int argc __attribute__((unused)),
793             char **argv __attribute__((unused)))
794 {
795         char vsn[80];
796
797         log_print("LVM version:     %s", LVM_VERSION);
798         if (library_version(vsn, sizeof(vsn)))
799                 log_print("Library version: %s", vsn);
800         if (driver_version(vsn, sizeof(vsn)))
801                 log_print("Driver version:  %s", vsn);
802
803         return ECMD_PROCESSED;
804 }
805
806 static int _get_settings(struct cmd_context *cmd)
807 {
808         cmd->current_settings = cmd->default_settings;
809
810         if (arg_count(cmd, debug_ARG))
811                 cmd->current_settings.debug = _LOG_FATAL +
812                     (arg_count(cmd, debug_ARG) - 1);
813
814         if (arg_count(cmd, verbose_ARG))
815                 cmd->current_settings.verbose = arg_count(cmd, verbose_ARG);
816
817         if (arg_count(cmd, quiet_ARG)) {
818                 cmd->current_settings.debug = 0;
819                 cmd->current_settings.verbose = 0;
820         }
821
822         if (arg_count(cmd, test_ARG))
823                 cmd->current_settings.test = arg_count(cmd, test_ARG);
824
825         if (arg_count(cmd, driverloaded_ARG)) {
826                 cmd->current_settings.activation =
827                     arg_int_value(cmd, driverloaded_ARG,
828                                   cmd->default_settings.activation);
829         }
830
831         cmd->current_settings.archive = arg_int_value(cmd, autobackup_ARG, cmd->current_settings.archive);
832         cmd->current_settings.backup = arg_int_value(cmd, autobackup_ARG, cmd->current_settings.backup);
833         cmd->current_settings.cache_vgmetadata = cmd->command->flags & CACHE_VGMETADATA ? 1 : 0;
834         cmd->partial_activation = 0;
835
836         if (arg_count(cmd, partial_ARG)) {
837                 cmd->partial_activation = 1;
838                 log_print("Partial mode. Incomplete logical volumes will be processed.");
839         }
840
841         if (arg_count(cmd, ignorelockingfailure_ARG) || arg_count(cmd, sysinit_ARG))
842                 init_ignorelockingfailure(1);
843         else
844                 init_ignorelockingfailure(0);
845
846         if (arg_count(cmd, nosuffix_ARG))
847                 cmd->current_settings.suffix = 0;
848
849         if (arg_count(cmd, units_ARG))
850                 if (!(cmd->current_settings.unit_factor =
851                       units_to_bytes(arg_str_value(cmd, units_ARG, ""),
852                                      &cmd->current_settings.unit_type))) {
853                         log_error("Invalid units specification");
854                         return EINVALID_CMD_LINE;
855                 }
856
857         if (arg_count(cmd, trustcache_ARG)) {
858                 if (arg_count(cmd, all_ARG)) {
859                         log_error("--trustcache is incompatible with --all");
860                         return EINVALID_CMD_LINE;
861                 }
862                 init_trust_cache(1);
863                 log_warn("WARNING: Cache file of PVs will be trusted.  "
864                           "New devices holding PVs may get ignored.");
865         } else
866                 init_trust_cache(0);
867
868         if (arg_count(cmd, noudevsync_ARG))
869                 cmd->current_settings.udev_sync = 0;
870
871         /* Handle synonyms */
872         if (!_merge_synonym(cmd, resizable_ARG, resizeable_ARG) ||
873             !_merge_synonym(cmd, allocation_ARG, allocatable_ARG) ||
874             !_merge_synonym(cmd, allocation_ARG, resizeable_ARG) ||
875             !_merge_synonym(cmd, virtualoriginsize_ARG, virtualsize_ARG))
876                 return EINVALID_CMD_LINE;
877
878         if ((!strncmp(cmd->command->name, "pv", 2) &&
879             !_merge_synonym(cmd, metadatacopies_ARG, pvmetadatacopies_ARG)) ||
880             (!strncmp(cmd->command->name, "vg", 2) &&
881              !_merge_synonym(cmd, metadatacopies_ARG, vgmetadatacopies_ARG)))
882                 return EINVALID_CMD_LINE;
883
884         /* Zero indicates success */
885         return 0;
886 }
887
888 static int _process_common_commands(struct cmd_context *cmd)
889 {
890         if (arg_count(cmd, help_ARG) || arg_count(cmd, help2_ARG)) {
891                 _usage(cmd->command->name);
892                 return ECMD_PROCESSED;
893         }
894
895         if (arg_count(cmd, version_ARG)) {
896                 return version(cmd, 0, (char **) NULL);
897         }
898
899         /* Zero indicates it's OK to continue processing this command */
900         return 0;
901 }
902
903 static void _display_help(void)
904 {
905         int i;
906
907         log_error("Available lvm commands:");
908         log_error("Use 'lvm help <command>' for more information");
909         log_error(" ");
910
911         for (i = 0; i < _cmdline.num_commands; i++) {
912                 struct command *com = _cmdline.commands + i;
913
914                 log_error("%-16.16s%s", com->name, com->desc);
915         }
916 }
917
918 int help(struct cmd_context *cmd __attribute__((unused)), int argc, char **argv)
919 {
920         int ret = ECMD_PROCESSED;
921
922         if (!argc)
923                 _display_help();
924         else {
925                 int i;
926                 for (i = 0; i < argc; i++)
927                         if (!_usage(argv[i]))
928                                 ret = EINVALID_CMD_LINE;
929         }
930
931         return ret;
932 }
933
934 static void _apply_settings(struct cmd_context *cmd)
935 {
936         init_debug(cmd->current_settings.debug);
937         init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
938         init_test(cmd->current_settings.test);
939         init_full_scan_done(0);
940         init_mirror_in_sync(0);
941
942         init_msg_prefix(cmd->default_settings.msg_prefix);
943         init_cmd_name(cmd->default_settings.cmd_name);
944
945         archive_enable(cmd, cmd->current_settings.archive);
946         backup_enable(cmd, cmd->current_settings.backup);
947
948         set_activation(cmd->current_settings.activation);
949
950         cmd->fmt = get_format_by_name(cmd, arg_str_value(cmd, metadatatype_ARG,
951                                       cmd->current_settings.fmt_name));
952
953         cmd->handles_missing_pvs = 0;
954 }
955
956 static int _set_udev_checking(struct cmd_context *cmd)
957 {
958 #ifdef UDEV_SYNC_SUPPORT
959         struct udev *udev;
960         const char *udev_dev_dir;
961         size_t udev_dev_dir_len;
962         int dirs_diff;
963
964         if (!(udev = udev_new()) ||
965             !(udev_dev_dir = udev_get_dev_path(udev)) ||
966             !*udev_dev_dir) {
967                 log_error("Could not get udev dev path.");
968                 return 0;
969         }
970         udev_dev_dir_len = strlen(udev_dev_dir);
971
972         /* There's always a slash at the end of dev_dir. But check udev_dev_dir! */
973         if (udev_dev_dir[udev_dev_dir_len - 1] != '/')
974                 dirs_diff = strncmp(cmd->dev_dir, udev_dev_dir,
975                                     udev_dev_dir_len);
976         else
977                 dirs_diff = strcmp(cmd->dev_dir, udev_dev_dir);
978
979         if (dirs_diff) {
980                 log_debug("The path %s used for creating device nodes and "
981                           "symlinks that is set in the configuration differs "
982                           "from the path %s that is used by udev. All warnings "
983                           "about udev not working correctly while processing "
984                           "particular nodes and symlinks will be suppressed. "
985                           "These nodes and symlinks will be managed in each "
986                           "directory separately.",
987                            cmd->dev_dir, udev_dev_dir);
988                 dm_udev_set_checking(0);
989                 init_udev_checking(0);
990         }
991
992         udev_unref(udev);
993 #endif
994         return 1;
995 }
996
997 static const char *_copy_command_line(struct cmd_context *cmd, int argc, char **argv)
998 {
999         int i, space;
1000
1001         /*
1002          * Build up the complete command line, used as a
1003          * description for backups.
1004          */
1005         if (!dm_pool_begin_object(cmd->mem, 128))
1006                 goto_bad;
1007
1008         for (i = 0; i < argc; i++) {
1009                 space = strchr(argv[i], ' ') ? 1 : 0;
1010
1011                 if (space && !dm_pool_grow_object(cmd->mem, "'", 1))
1012                         goto_bad;
1013
1014                 if (!dm_pool_grow_object(cmd->mem, argv[i], strlen(argv[i])))
1015                         goto_bad;
1016
1017                 if (space && !dm_pool_grow_object(cmd->mem, "'", 1))
1018                         goto_bad;
1019
1020                 if (i < (argc - 1))
1021                         if (!dm_pool_grow_object(cmd->mem, " ", 1))
1022                                 goto_bad;
1023         }
1024
1025         /*
1026          * Terminate.
1027          */
1028         if (!dm_pool_grow_object(cmd->mem, "\0", 1))
1029                 goto_bad;
1030
1031         return dm_pool_end_object(cmd->mem);
1032
1033       bad:
1034         log_error("Couldn't copy command line.");
1035         dm_pool_abandon_object(cmd->mem);
1036         return NULL;
1037 }
1038
1039 int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
1040 {
1041         int ret = 0;
1042         int locking_type;
1043
1044         init_error_message_produced(0);
1045
1046         /* each command should start out with sigint flag cleared */
1047         sigint_clear();
1048
1049         if (!(cmd->cmd_line = _copy_command_line(cmd, argc, argv))) {
1050                 stack;
1051                 return ECMD_FAILED;
1052         }
1053
1054         log_debug("Parsing: %s", cmd->cmd_line);
1055
1056         if (!(cmd->command = _find_command(argv[0])))
1057                 return ENO_SUCH_CMD;
1058
1059         if (!_process_command_line(cmd, &argc, &argv)) {
1060                 log_error("Error during parsing of command line.");
1061                 return EINVALID_CMD_LINE;
1062         }
1063
1064         set_cmd_name(cmd->command->name);
1065
1066         if (arg_count(cmd, config_ARG))
1067                 if (override_config_tree_from_string(cmd,
1068                     arg_str_value(cmd, config_ARG, ""))) {
1069                         ret = EINVALID_CMD_LINE;
1070                         goto_out;
1071                 }
1072
1073         if (arg_count(cmd, config_ARG) || !cmd->config_valid || config_files_changed(cmd)) {
1074                 /* Reinitialise various settings inc. logging, filters */
1075                 if (!refresh_toolcontext(cmd)) {
1076                         if (cmd->cft_override) {
1077                                 destroy_config_tree(cmd->cft_override);
1078                                 cmd->cft_override = NULL;
1079                         }
1080                         log_error("Updated config file invalid. Aborting.");
1081                         return ECMD_FAILED;
1082                 }
1083         }
1084
1085         if ((ret = _get_settings(cmd)))
1086                 goto_out;
1087         _apply_settings(cmd);
1088
1089         log_debug("Processing: %s", cmd->cmd_line);
1090
1091 #ifdef O_DIRECT_SUPPORT
1092         log_debug("O_DIRECT will be used");
1093 #endif
1094
1095         if (!_set_udev_checking(cmd))
1096                 goto_out;
1097
1098         if ((ret = _process_common_commands(cmd)))
1099                 goto_out;
1100
1101         if (cmd->metadata_read_only &&
1102             !(cmd->command->flags & PERMITTED_READ_ONLY)) {
1103                 log_error("%s: Command not permitted while global/metadata_read_only "
1104                           "is set.", cmd->cmd_line);
1105                 goto out;
1106         }
1107
1108         if (arg_count(cmd, nolocking_ARG))
1109                 locking_type = 0;
1110         else
1111                 locking_type = -1;
1112
1113         if (!init_locking(locking_type, cmd, arg_count(cmd, sysinit_ARG))) {
1114                 ret = ECMD_FAILED;
1115                 goto out;
1116         }
1117
1118         ret = cmd->command->fn(cmd, argc, argv);
1119
1120         fin_locking();
1121
1122       out:
1123         if (test_mode()) {
1124                 log_verbose("Test mode: Wiping internal cache");
1125                 lvmcache_destroy(cmd, 1);
1126         }
1127
1128         if (cmd->cft_override) {
1129                 destroy_config_tree(cmd->cft_override);
1130                 cmd->cft_override = NULL;
1131                 /* Move this? */
1132                 if (!refresh_toolcontext(cmd))
1133                         stack;
1134         }
1135
1136         /* FIXME Move this? */
1137         cmd->current_settings = cmd->default_settings;
1138         _apply_settings(cmd);
1139
1140         if (ret == EINVALID_CMD_LINE && !_cmdline.interactive)
1141                 _short_usage(cmd->command->name);
1142
1143         log_debug("Completed: %s", cmd->cmd_line);
1144
1145         /*
1146          * free off any memory the command used.
1147          */
1148         dm_list_init(&cmd->arg_value_groups);
1149         dm_pool_empty(cmd->mem);
1150
1151         reset_lvm_errno(1);
1152         reset_log_duplicated();
1153
1154         return ret;
1155 }
1156
1157 int lvm_return_code(int ret)
1158 {
1159         return (ret == ECMD_PROCESSED ? 0 : ret);
1160 }
1161
1162 int lvm_split(char *str, int *argc, char **argv, int max)
1163 {
1164         char *b = str, *e;
1165         *argc = 0;
1166
1167         while (*b) {
1168                 while (*b && isspace(*b))
1169                         b++;
1170
1171                 if ((!*b) || (*b == '#'))
1172                         break;
1173
1174                 e = b;
1175                 while (*e && !isspace(*e))
1176                         e++;
1177
1178                 argv[(*argc)++] = b;
1179                 if (!*e)
1180                         break;
1181                 *e++ = '\0';
1182                 b = e;
1183                 if (*argc == max)
1184                         break;
1185         }
1186
1187         return *argc;
1188 }
1189
1190 static const char *_get_cmdline(pid_t pid)
1191 {
1192         static char _proc_cmdline[32];
1193         char buf[256];
1194         int fd, n = 0;
1195
1196         snprintf(buf, sizeof(buf), DEFAULT_PROC_DIR "/%u/cmdline", pid);
1197         /* FIXME Use generic read code. */
1198         if ((fd = open(buf, O_RDONLY)) > 0) {
1199                 if ((n = read(fd, _proc_cmdline, sizeof(_proc_cmdline) - 1)) < 0) {
1200                         log_sys_error("read", buf);
1201                         n = 0;
1202                 }
1203                 if (close(fd))
1204                         log_sys_error("close", buf);
1205         }
1206         _proc_cmdline[n] = '\0';
1207
1208         return _proc_cmdline;
1209 }
1210
1211 static const char *_get_filename(int fd)
1212 {
1213         static char filename[PATH_MAX];
1214         char buf[32];   /* Assumes short DEFAULT_PROC_DIR */
1215         int size;
1216
1217         snprintf(buf, sizeof(buf), DEFAULT_PROC_DIR "/self/fd/%u", fd);
1218
1219         if ((size = readlink(buf, filename, sizeof(filename) - 1)) == -1)
1220                 filename[0] = '\0';
1221         else
1222                 filename[size] = '\0';
1223
1224         return filename;
1225 }
1226
1227 static void _close_descriptor(int fd, unsigned suppress_warnings,
1228                               const char *command, pid_t ppid,
1229                               const char *parent_cmdline)
1230 {
1231         int r;
1232         const char *filename;
1233
1234         /* Ignore bad file descriptors */
1235         if (fcntl(fd, F_GETFD) == -1 && errno == EBADF)
1236                 return;
1237
1238         if (!suppress_warnings)
1239                 filename = _get_filename(fd);
1240
1241         r = close(fd);
1242         if (suppress_warnings)
1243                 return;
1244
1245         if (!r)
1246                 fprintf(stderr, "File descriptor %d (%s) leaked on "
1247                         "%s invocation.", fd, filename, command);
1248         else if (errno == EBADF)
1249                 return;
1250         else
1251                 fprintf(stderr, "Close failed on stray file descriptor "
1252                         "%d (%s): %s", fd, filename, strerror(errno));
1253
1254         fprintf(stderr, " Parent PID %" PRIpid_t ": %s\n", ppid, parent_cmdline);
1255 }
1256
1257 static void _close_stray_fds(const char *command)
1258 {
1259         struct rlimit rlim;
1260         int fd;
1261         unsigned suppress_warnings = 0;
1262         pid_t ppid = getppid();
1263         const char *parent_cmdline = _get_cmdline(ppid);
1264
1265         if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
1266                 fprintf(stderr, "getrlimit(RLIMIT_NOFILE) failed: %s\n",
1267                         strerror(errno));
1268                 return;
1269         }
1270
1271         if (getenv("LVM_SUPPRESS_FD_WARNINGS"))
1272                 suppress_warnings = 1;
1273
1274         for (fd = 3; fd < rlim.rlim_cur; fd++)
1275                 _close_descriptor(fd, suppress_warnings, command, ppid,
1276                                   parent_cmdline);
1277 }
1278
1279 struct cmd_context *init_lvm(void)
1280 {
1281         struct cmd_context *cmd;
1282
1283         if (!(cmd = create_toolcontext(0, NULL)))
1284                 return_NULL;
1285
1286         _cmdline.arg_props = &_arg_props[0];
1287
1288         if (stored_errno()) {
1289                 destroy_toolcontext(cmd);
1290                 return_NULL;
1291         }
1292
1293         return cmd;
1294 }
1295
1296 static void _fin_commands(void)
1297 {
1298         int i;
1299
1300         for (i = 0; i < _cmdline.num_commands; i++)
1301                 dm_free(_cmdline.commands[i].valid_args);
1302
1303         dm_free(_cmdline.commands);
1304
1305         _cmdline.commands = NULL;
1306         _cmdline.num_commands = 0;
1307         _cmdline.commands_size = 0;
1308 }
1309
1310 void lvm_fin(struct cmd_context *cmd)
1311 {
1312         _fin_commands();
1313         destroy_toolcontext(cmd);
1314 }
1315
1316 static int _run_script(struct cmd_context *cmd, int argc, char **argv)
1317 {
1318         FILE *script;
1319
1320         char buffer[CMD_LEN];
1321         int ret = 0;
1322         int magic_number = 0;
1323         char *script_file = argv[0];
1324
1325         if ((script = fopen(script_file, "r")) == NULL)
1326                 return ENO_SUCH_CMD;
1327
1328         while (fgets(buffer, sizeof(buffer), script) != NULL) {
1329                 if (!magic_number) {
1330                         if (buffer[0] == '#' && buffer[1] == '!')
1331                                 magic_number = 1;
1332                         else {
1333                                 ret = ENO_SUCH_CMD;
1334                                 break;
1335                         }
1336                 }
1337                 if ((strlen(buffer) == sizeof(buffer) - 1)
1338                     && (buffer[sizeof(buffer) - 1] - 2 != '\n')) {
1339                         buffer[50] = '\0';
1340                         log_error("Line too long (max 255) beginning: %s",
1341                                   buffer);
1342                         ret = EINVALID_CMD_LINE;
1343                         break;
1344                 }
1345                 if (lvm_split(buffer, &argc, argv, MAX_ARGS) == MAX_ARGS) {
1346                         buffer[50] = '\0';
1347                         log_error("Too many arguments: %s", buffer);
1348                         ret = EINVALID_CMD_LINE;
1349                         break;
1350                 }
1351                 if (!argc)
1352                         continue;
1353                 if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "exit"))
1354                         break;
1355                 ret = lvm_run_command(cmd, argc, argv);
1356                 if (ret != ECMD_PROCESSED) {
1357                         if (!error_message_produced()) {
1358                                 log_debug(INTERNAL_ERROR "Failed command did not use log_error");
1359                                 log_error("Command failed with status code %d.", ret);
1360                         }
1361                         break;
1362                 }
1363         }
1364
1365         if (fclose(script))
1366                 log_sys_error("fclose", script_file);
1367
1368         return ret;
1369 }
1370
1371 /*
1372  * Determine whether we should fall back and exec the equivalent LVM1 tool
1373  */
1374 static int _lvm1_fallback(struct cmd_context *cmd)
1375 {
1376         char vsn[80];
1377         int dm_present;
1378
1379         if (!find_config_tree_int(cmd, "global/fallback_to_lvm1",
1380                              DEFAULT_FALLBACK_TO_LVM1) ||
1381             strncmp(cmd->kernel_vsn, "2.4.", 4))
1382                 return 0;
1383
1384         log_suppress(1);
1385         dm_present = driver_version(vsn, sizeof(vsn));
1386         log_suppress(0);
1387
1388         if (dm_present || !lvm1_present(cmd))
1389                 return 0;
1390
1391         return 1;
1392 }
1393
1394 static void _exec_lvm1_command(char **argv)
1395 {
1396         char path[PATH_MAX];
1397
1398         if (dm_snprintf(path, sizeof(path), "%s.lvm1", argv[0]) < 0) {
1399                 log_error("Failed to create LVM1 tool pathname");
1400                 return;
1401         }
1402
1403         execvp(path, argv);
1404         log_sys_error("execvp", path);
1405 }
1406
1407 static void _nonroot_warning(void)
1408 {
1409         if (getuid() || geteuid())
1410                 log_warn("WARNING: Running as a non-root user. Functionality may be unavailable.");
1411 }
1412
1413 int lvm2_main(int argc, char **argv)
1414 {
1415         const char *base;
1416         int ret, alias = 0;
1417         struct cmd_context *cmd;
1418
1419         base = last_path_component(argv[0]);
1420         if (strcmp(base, "lvm") && strcmp(base, "lvm.static") &&
1421             strcmp(base, "initrd-lvm"))
1422                 alias = 1;
1423
1424         _close_stray_fds(base);
1425
1426         if (is_static() && strcmp(base, "lvm.static") &&
1427             path_exists(LVM_SHARED_PATH) &&
1428             !getenv("LVM_DID_EXEC")) {
1429                 setenv("LVM_DID_EXEC", base, 1);
1430                 execvp(LVM_SHARED_PATH, argv);
1431                 unsetenv("LVM_DID_EXEC");
1432         }
1433
1434         /* "version" command is simple enough so it doesn't need any complex init */
1435         if (!alias && argc > 1 && !strcmp(argv[1], "version"))
1436                 return lvm_return_code(version(NULL, argc, argv));
1437
1438         if (!(cmd = init_lvm()))
1439                 return -1;
1440
1441         cmd->argv = argv;
1442         lvm_register_commands();
1443
1444         if (_lvm1_fallback(cmd)) {
1445                 /* Attempt to run equivalent LVM1 tool instead */
1446                 if (!alias) {
1447                         argv++;
1448                         argc--;
1449                 }
1450                 if (!argc) {
1451                         log_error("Falling back to LVM1 tools, but no "
1452                                   "command specified.");
1453                         ret = ECMD_FAILED;
1454                         goto out;
1455                 }
1456                 _exec_lvm1_command(argv);
1457                 ret = ECMD_FAILED;
1458                 goto out;
1459         }
1460 #ifdef READLINE_SUPPORT
1461         if (!alias && argc == 1) {
1462                 _nonroot_warning();
1463                 ret = lvm_shell(cmd, &_cmdline);
1464                 goto out;
1465         }
1466 #endif
1467
1468         if (!alias) {
1469                 if (argc < 2) {
1470                         log_fatal("Please supply an LVM command.");
1471                         _display_help();
1472                         ret = EINVALID_CMD_LINE;
1473                         goto out;
1474                 }
1475
1476                 argc--;
1477                 argv++;
1478         }
1479
1480         _nonroot_warning();
1481         ret = lvm_run_command(cmd, argc, argv);
1482         if ((ret == ENO_SUCH_CMD) && (!alias))
1483                 ret = _run_script(cmd, argc, argv);
1484         if (ret == ENO_SUCH_CMD)
1485                 log_error("No such command.  Try 'help'.");
1486
1487         if ((ret != ECMD_PROCESSED) && !error_message_produced()) {
1488                 log_debug(INTERNAL_ERROR "Failed command did not use log_error");
1489                 log_error("Command failed with status code %d.", ret);
1490         }
1491
1492       out:
1493         lvm_fin(cmd);
1494         return lvm_return_code(ret);
1495 }