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