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