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