Home | History | Annotate | Line # | Download | only in tools
lvcreate.c revision 1.1.1.2
      1      1.1  haad /*	$NetBSD: lvcreate.c,v 1.1.1.2 2009/12/02 00:25:50 haad 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 "lv_alloc.h"
     20      1.1  haad 
     21      1.1  haad #include <fcntl.h>
     22      1.1  haad 
     23  1.1.1.2  haad struct lvcreate_cmdline_params {
     24      1.1  haad 	percent_t percent;
     25  1.1.1.2  haad 	uint64_t size;
     26      1.1  haad 	char **pvs;
     27  1.1.1.2  haad 	int pv_count;
     28      1.1  haad };
     29      1.1  haad 
     30      1.1  haad static int _lvcreate_name_params(struct lvcreate_params *lp,
     31      1.1  haad 				 struct cmd_context *cmd,
     32      1.1  haad 				 int *pargc, char ***pargv)
     33      1.1  haad {
     34      1.1  haad 	int argc = *pargc;
     35      1.1  haad 	char **argv = *pargv, *ptr;
     36      1.1  haad 	char *vg_name;
     37      1.1  haad 
     38  1.1.1.2  haad 	lp->lv_name = arg_str_value(cmd, name_ARG, NULL);
     39      1.1  haad 
     40  1.1.1.2  haad 	if (lp->snapshot && !arg_count(cmd, virtualsize_ARG)) {
     41      1.1  haad 		if (!argc) {
     42  1.1.1.2  haad 			log_error("Please specify a logical volume to act as "
     43  1.1.1.2  haad 				  "the snapshot origin.");
     44      1.1  haad 			return 0;
     45      1.1  haad 		}
     46      1.1  haad 
     47      1.1  haad 		lp->origin = argv[0];
     48      1.1  haad 		(*pargv)++, (*pargc)--;
     49      1.1  haad 		if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) {
     50  1.1.1.2  haad 			log_error("The origin name should include the "
     51  1.1.1.2  haad 				  "volume group.");
     52      1.1  haad 			return 0;
     53      1.1  haad 		}
     54      1.1  haad 
     55      1.1  haad 		/* Strip the volume group from the origin */
     56      1.1  haad 		if ((ptr = strrchr(lp->origin, (int) '/')))
     57      1.1  haad 			lp->origin = ptr + 1;
     58      1.1  haad 
     59      1.1  haad 	} else {
     60      1.1  haad 		/*
     61      1.1  haad 		 * If VG not on command line, try -n arg and then
     62      1.1  haad 		 * environment.
     63      1.1  haad 		 */
     64      1.1  haad 		if (!argc) {
     65      1.1  haad 			if (!(lp->vg_name = extract_vgname(cmd, lp->lv_name))) {
     66  1.1.1.2  haad 				log_error("Please provide a volume group name");
     67      1.1  haad 				return 0;
     68      1.1  haad 			}
     69      1.1  haad 
     70      1.1  haad 		} else {
     71      1.1  haad 			vg_name = skip_dev_dir(cmd, argv[0], NULL);
     72      1.1  haad 			if (strrchr(vg_name, '/')) {
     73      1.1  haad 				log_error("Volume group name expected "
     74      1.1  haad 					  "(no slash)");
     75      1.1  haad 				return 0;
     76      1.1  haad 			}
     77      1.1  haad 
     78      1.1  haad 			/*
     79      1.1  haad 			 * Ensure lv_name doesn't contain a
     80      1.1  haad 			 * different VG.
     81      1.1  haad 			 */
     82      1.1  haad 			if (lp->lv_name && strchr(lp->lv_name, '/')) {
     83      1.1  haad 				if (!(lp->vg_name =
     84      1.1  haad 				      extract_vgname(cmd, lp->lv_name)))
     85      1.1  haad 					return 0;
     86      1.1  haad 
     87      1.1  haad 				if (strcmp(lp->vg_name, vg_name)) {
     88      1.1  haad 					log_error("Inconsistent volume group "
     89      1.1  haad 						  "names "
     90      1.1  haad 						  "given: \"%s\" and \"%s\"",
     91      1.1  haad 						  lp->vg_name, vg_name);
     92      1.1  haad 					return 0;
     93      1.1  haad 				}
     94      1.1  haad 			}
     95      1.1  haad 
     96      1.1  haad 			lp->vg_name = vg_name;
     97      1.1  haad 			(*pargv)++, (*pargc)--;
     98      1.1  haad 		}
     99      1.1  haad 	}
    100      1.1  haad 
    101      1.1  haad 	if (!validate_name(lp->vg_name)) {
    102      1.1  haad 		log_error("Volume group name %s has invalid characters",
    103      1.1  haad 			  lp->vg_name);
    104      1.1  haad 		return 0;
    105      1.1  haad 	}
    106      1.1  haad 
    107      1.1  haad 	if (lp->lv_name) {
    108      1.1  haad 		if ((ptr = strrchr(lp->lv_name, '/')))
    109      1.1  haad 			lp->lv_name = ptr + 1;
    110      1.1  haad 
    111      1.1  haad 		if (!apply_lvname_restrictions(lp->lv_name))
    112      1.1  haad 			return_0;
    113      1.1  haad 
    114      1.1  haad 		if (!validate_name(lp->lv_name)) {
    115      1.1  haad 			log_error("Logical volume name \"%s\" is invalid",
    116      1.1  haad 				  lp->lv_name);
    117      1.1  haad 			return 0;
    118      1.1  haad 		}
    119      1.1  haad 	}
    120      1.1  haad 
    121      1.1  haad 	return 1;
    122      1.1  haad }
    123      1.1  haad 
    124  1.1.1.2  haad /*
    125  1.1.1.2  haad  * Update extents parameters based on other parameters which affect the size
    126  1.1.1.2  haad  * calcuation.
    127  1.1.1.2  haad  * NOTE: We must do this here because of the percent_t typedef and because we
    128  1.1.1.2  haad  * need the vg.
    129  1.1.1.2  haad  */
    130  1.1.1.2  haad static int _update_extents_params(struct volume_group *vg,
    131  1.1.1.2  haad 				  struct lvcreate_params *lp,
    132  1.1.1.2  haad 				  struct lvcreate_cmdline_params *lcp)
    133  1.1.1.2  haad {
    134  1.1.1.2  haad 	uint32_t pv_extent_count;
    135  1.1.1.2  haad 
    136  1.1.1.2  haad 	if (lcp->size &&
    137  1.1.1.2  haad 	    !(lp->extents = extents_from_size(vg->cmd, lcp->size,
    138  1.1.1.2  haad 					       vg->extent_size)))
    139  1.1.1.2  haad 		return_0;
    140  1.1.1.2  haad 
    141  1.1.1.2  haad 	if (lp->voriginsize &&
    142  1.1.1.2  haad 	    !(lp->voriginextents = extents_from_size(vg->cmd, lp->voriginsize,
    143  1.1.1.2  haad 						      vg->extent_size)))
    144  1.1.1.2  haad 		return_0;
    145  1.1.1.2  haad 
    146  1.1.1.2  haad 	/*
    147  1.1.1.2  haad 	 * Create the pv list before we parse lcp->percent - might be
    148  1.1.1.2  haad 	 * PERCENT_PVSs
    149  1.1.1.2  haad 	 */
    150  1.1.1.2  haad 	if (lcp->pv_count) {
    151  1.1.1.2  haad 		if (!(lp->pvh = create_pv_list(vg->cmd->mem, vg,
    152  1.1.1.2  haad 					   lcp->pv_count, lcp->pvs, 1)))
    153  1.1.1.2  haad 			return_0;
    154  1.1.1.2  haad 	} else
    155  1.1.1.2  haad 		lp->pvh = &vg->pvs;
    156  1.1.1.2  haad 
    157  1.1.1.2  haad 	switch(lcp->percent) {
    158  1.1.1.2  haad 		case PERCENT_VG:
    159  1.1.1.2  haad 			lp->extents = lp->extents * vg->extent_count / 100;
    160  1.1.1.2  haad 			break;
    161  1.1.1.2  haad 		case PERCENT_FREE:
    162  1.1.1.2  haad 			lp->extents = lp->extents * vg->free_count / 100;
    163  1.1.1.2  haad 			break;
    164  1.1.1.2  haad 		case PERCENT_PVS:
    165  1.1.1.2  haad 			if (!lcp->pv_count)
    166  1.1.1.2  haad 				lp->extents = lp->extents * vg->extent_count / 100;
    167  1.1.1.2  haad 			else {
    168  1.1.1.2  haad 				pv_extent_count = pv_list_extents_free(lp->pvh);
    169  1.1.1.2  haad 				lp->extents = lp->extents * pv_extent_count / 100;
    170  1.1.1.2  haad 			}
    171  1.1.1.2  haad 			break;
    172  1.1.1.2  haad 		case PERCENT_LV:
    173  1.1.1.2  haad 			log_error("Please express size as %%VG, %%PVS, or "
    174  1.1.1.2  haad 				  "%%FREE.");
    175  1.1.1.2  haad 			return 0;
    176  1.1.1.2  haad 		case PERCENT_NONE:
    177  1.1.1.2  haad 			break;
    178  1.1.1.2  haad 	}
    179  1.1.1.2  haad 	return 1;
    180  1.1.1.2  haad }
    181  1.1.1.2  haad 
    182      1.1  haad static int _read_size_params(struct lvcreate_params *lp,
    183  1.1.1.2  haad 			     struct lvcreate_cmdline_params *lcp,
    184      1.1  haad 			     struct cmd_context *cmd)
    185      1.1  haad {
    186      1.1  haad 	if (arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG) != 1) {
    187      1.1  haad 		log_error("Please specify either size or extents (not both)");
    188      1.1  haad 		return 0;
    189      1.1  haad 	}
    190      1.1  haad 
    191      1.1  haad 	if (arg_count(cmd, extents_ARG)) {
    192      1.1  haad 		if (arg_sign_value(cmd, extents_ARG, 0) == SIGN_MINUS) {
    193      1.1  haad 			log_error("Negative number of extents is invalid");
    194      1.1  haad 			return 0;
    195      1.1  haad 		}
    196      1.1  haad 		lp->extents = arg_uint_value(cmd, extents_ARG, 0);
    197  1.1.1.2  haad 		lcp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
    198      1.1  haad 	}
    199      1.1  haad 
    200      1.1  haad 	/* Size returned in kilobyte units; held in sectors */
    201      1.1  haad 	if (arg_count(cmd, size_ARG)) {
    202      1.1  haad 		if (arg_sign_value(cmd, size_ARG, 0) == SIGN_MINUS) {
    203      1.1  haad 			log_error("Negative size is invalid");
    204      1.1  haad 			return 0;
    205      1.1  haad 		}
    206  1.1.1.2  haad 		lcp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0));
    207  1.1.1.2  haad 		lcp->percent = PERCENT_NONE;
    208  1.1.1.2  haad 	}
    209  1.1.1.2  haad 
    210  1.1.1.2  haad 	/* Size returned in kilobyte units; held in sectors */
    211  1.1.1.2  haad 	if (arg_count(cmd, virtualsize_ARG)) {
    212  1.1.1.2  haad 		if (arg_sign_value(cmd, virtualsize_ARG, 0) == SIGN_MINUS) {
    213  1.1.1.2  haad 			log_error("Negative virtual origin size is invalid");
    214  1.1.1.2  haad 			return 0;
    215  1.1.1.2  haad 		}
    216  1.1.1.2  haad 		lp->voriginsize = arg_uint64_value(cmd, virtualsize_ARG,
    217  1.1.1.2  haad 						   UINT64_C(0));
    218  1.1.1.2  haad 		if (!lp->voriginsize) {
    219  1.1.1.2  haad 			log_error("Virtual origin size may not be zero");
    220  1.1.1.2  haad 			return 0;
    221  1.1.1.2  haad 		}
    222      1.1  haad 	}
    223      1.1  haad 
    224      1.1  haad 	return 1;
    225      1.1  haad }
    226      1.1  haad 
    227      1.1  haad /*
    228      1.1  haad  * Generic stripe parameter checks.
    229      1.1  haad  * FIXME: Should eventually be moved into lvm library.
    230      1.1  haad  */
    231      1.1  haad static int _validate_stripe_params(struct cmd_context *cmd,
    232      1.1  haad 				   struct lvcreate_params *lp)
    233      1.1  haad {
    234      1.1  haad 	if (lp->stripes == 1 && lp->stripe_size) {
    235      1.1  haad 		log_print("Ignoring stripesize argument with single stripe");
    236      1.1  haad 		lp->stripe_size = 0;
    237      1.1  haad 	}
    238      1.1  haad 
    239      1.1  haad 	if (lp->stripes > 1 && !lp->stripe_size) {
    240      1.1  haad 		lp->stripe_size = find_config_tree_int(cmd,
    241      1.1  haad 						  "metadata/stripesize",
    242      1.1  haad 						  DEFAULT_STRIPESIZE) * 2;
    243      1.1  haad 		log_print("Using default stripesize %s",
    244      1.1  haad 			  display_size(cmd, (uint64_t) lp->stripe_size));
    245      1.1  haad 	}
    246      1.1  haad 
    247      1.1  haad 	if (lp->stripes < 1 || lp->stripes > MAX_STRIPES) {
    248      1.1  haad 		log_error("Number of stripes (%d) must be between %d and %d",
    249      1.1  haad 			  lp->stripes, 1, MAX_STRIPES);
    250      1.1  haad 		return 0;
    251      1.1  haad 	}
    252      1.1  haad 
    253      1.1  haad 	/* MAX size check is in _lvcreate */
    254      1.1  haad 	if (lp->stripes > 1 && (lp->stripe_size < STRIPE_SIZE_MIN ||
    255      1.1  haad 				lp->stripe_size & (lp->stripe_size - 1))) {
    256      1.1  haad 		log_error("Invalid stripe size %s",
    257      1.1  haad 			  display_size(cmd, (uint64_t) lp->stripe_size));
    258      1.1  haad 		return 0;
    259      1.1  haad 	}
    260      1.1  haad 
    261      1.1  haad 	return 1;
    262      1.1  haad }
    263      1.1  haad 
    264      1.1  haad /* The stripe size is limited by the size of a uint32_t, but since the
    265      1.1  haad  * value given by the user is doubled, and the final result must be a
    266      1.1  haad  * power of 2, we must divide UINT_MAX by four and add 1 (to round it
    267      1.1  haad  * up to the power of 2) */
    268      1.1  haad static int _read_stripe_params(struct lvcreate_params *lp,
    269      1.1  haad 			       struct cmd_context *cmd)
    270      1.1  haad {
    271      1.1  haad 	if (arg_count(cmd, stripesize_ARG)) {
    272      1.1  haad 		if (arg_sign_value(cmd, stripesize_ARG, 0) == SIGN_MINUS) {
    273      1.1  haad 			log_error("Negative stripesize is invalid");
    274      1.1  haad 			return 0;
    275      1.1  haad 		}
    276      1.1  haad 		/* Check to make sure we won't overflow lp->stripe_size */
    277      1.1  haad 		if(arg_uint_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT * 2) {
    278      1.1  haad 			log_error("Stripe size cannot be larger than %s",
    279      1.1  haad 				  display_size(cmd, (uint64_t) STRIPE_SIZE_LIMIT));
    280      1.1  haad 			return 0;
    281      1.1  haad 		}
    282      1.1  haad 		lp->stripe_size = arg_uint_value(cmd, stripesize_ARG, 0);
    283      1.1  haad 	}
    284      1.1  haad 
    285      1.1  haad 
    286      1.1  haad 	if (!_validate_stripe_params(cmd, lp))
    287      1.1  haad 		return 0;
    288      1.1  haad 
    289      1.1  haad 	return 1;
    290      1.1  haad }
    291      1.1  haad 
    292      1.1  haad /*
    293      1.1  haad  * Generic mirror parameter checks.
    294      1.1  haad  * FIXME: Should eventually be moved into lvm library.
    295      1.1  haad  */
    296      1.1  haad static int _validate_mirror_params(const struct cmd_context *cmd __attribute((unused)),
    297      1.1  haad 				   const struct lvcreate_params *lp)
    298      1.1  haad {
    299      1.1  haad 	int pagesize = lvm_getpagesize();
    300      1.1  haad 
    301      1.1  haad 	if (lp->region_size & (lp->region_size - 1)) {
    302      1.1  haad 		log_error("Region size (%" PRIu32 ") must be a power of 2",
    303      1.1  haad 			  lp->region_size);
    304      1.1  haad 		return 0;
    305      1.1  haad 	}
    306      1.1  haad 
    307      1.1  haad 	if (lp->region_size % (pagesize >> SECTOR_SHIFT)) {
    308      1.1  haad 		log_error("Region size (%" PRIu32 ") must be a multiple of "
    309      1.1  haad 			  "machine memory page size (%d)",
    310      1.1  haad 			  lp->region_size, pagesize >> SECTOR_SHIFT);
    311      1.1  haad 		return 0;
    312      1.1  haad 	}
    313      1.1  haad 
    314      1.1  haad 	if (!lp->region_size) {
    315      1.1  haad 		log_error("Non-zero region size must be supplied.");
    316      1.1  haad 		return 0;
    317      1.1  haad 	}
    318      1.1  haad 
    319      1.1  haad 	return 1;
    320      1.1  haad }
    321      1.1  haad 
    322      1.1  haad static int _read_mirror_params(struct lvcreate_params *lp,
    323      1.1  haad 			       struct cmd_context *cmd)
    324      1.1  haad {
    325      1.1  haad 	int region_size;
    326      1.1  haad 	const char *mirrorlog;
    327      1.1  haad 
    328      1.1  haad 	if (arg_count(cmd, corelog_ARG))
    329      1.1  haad 		lp->corelog = 1;
    330      1.1  haad 
    331      1.1  haad 	mirrorlog = arg_str_value(cmd, mirrorlog_ARG,
    332      1.1  haad 				  lp->corelog ? "core" : DEFAULT_MIRRORLOG);
    333      1.1  haad 
    334      1.1  haad 	if (!strcmp("disk", mirrorlog)) {
    335      1.1  haad 		if (lp->corelog) {
    336      1.1  haad 			log_error("--mirrorlog disk and --corelog "
    337      1.1  haad 				  "are incompatible");
    338      1.1  haad 			return 0;
    339      1.1  haad 		}
    340      1.1  haad 		lp->corelog = 0;
    341      1.1  haad 	} else if (!strcmp("core", mirrorlog))
    342      1.1  haad 		lp->corelog = 1;
    343      1.1  haad 	else {
    344      1.1  haad 		log_error("Unknown mirrorlog type: %s", mirrorlog);
    345      1.1  haad 		return 0;
    346      1.1  haad 	}
    347      1.1  haad 
    348      1.1  haad 	log_verbose("Setting logging type to %s", mirrorlog);
    349      1.1  haad 
    350  1.1.1.2  haad 	lp->nosync = arg_is_set(cmd, nosync_ARG);
    351      1.1  haad 
    352      1.1  haad 	if (arg_count(cmd, regionsize_ARG)) {
    353      1.1  haad 		if (arg_sign_value(cmd, regionsize_ARG, 0) == SIGN_MINUS) {
    354      1.1  haad 			log_error("Negative regionsize is invalid");
    355      1.1  haad 			return 0;
    356      1.1  haad 		}
    357      1.1  haad 		lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
    358      1.1  haad 	} else {
    359      1.1  haad 		region_size = 2 * find_config_tree_int(cmd,
    360      1.1  haad 					"activation/mirror_region_size",
    361      1.1  haad 					DEFAULT_MIRROR_REGION_SIZE);
    362      1.1  haad 		if (region_size < 0) {
    363      1.1  haad 			log_error("Negative regionsize in configuration file "
    364      1.1  haad 				  "is invalid");
    365      1.1  haad 			return 0;
    366      1.1  haad 		}
    367      1.1  haad 		lp->region_size = region_size;
    368      1.1  haad 	}
    369      1.1  haad 
    370      1.1  haad 	if (!_validate_mirror_params(cmd, lp))
    371      1.1  haad 		return 0;
    372      1.1  haad 
    373      1.1  haad 	return 1;
    374      1.1  haad }
    375      1.1  haad 
    376  1.1.1.2  haad static int _lvcreate_params(struct lvcreate_params *lp,
    377  1.1.1.2  haad 			    struct lvcreate_cmdline_params *lcp,
    378  1.1.1.2  haad 			    struct cmd_context *cmd,
    379      1.1  haad 			    int argc, char **argv)
    380      1.1  haad {
    381      1.1  haad 	int contiguous;
    382      1.1  haad 	unsigned pagesize;
    383      1.1  haad 
    384      1.1  haad 	memset(lp, 0, sizeof(*lp));
    385  1.1.1.2  haad 	memset(lcp, 0, sizeof(*lcp));
    386      1.1  haad 
    387      1.1  haad 	/*
    388      1.1  haad 	 * Check selected options are compatible and determine segtype
    389      1.1  haad 	 */
    390      1.1  haad 	lp->segtype = (const struct segment_type *)
    391      1.1  haad 	    arg_ptr_value(cmd, type_ARG,
    392      1.1  haad 			  get_segtype_from_string(cmd, "striped"));
    393      1.1  haad 
    394      1.1  haad 	lp->stripes = arg_uint_value(cmd, stripes_ARG, 1);
    395      1.1  haad 	if (arg_count(cmd, stripes_ARG) && lp->stripes == 1)
    396      1.1  haad 		log_print("Redundant stripes argument: default is 1");
    397      1.1  haad 
    398  1.1.1.2  haad 	if (arg_count(cmd, snapshot_ARG) || seg_is_snapshot(lp) ||
    399  1.1.1.2  haad 	    arg_count(cmd, virtualsize_ARG))
    400      1.1  haad 		lp->snapshot = 1;
    401      1.1  haad 
    402      1.1  haad 	lp->mirrors = 1;
    403      1.1  haad 
    404      1.1  haad 	/* Default to 2 mirrored areas if --type mirror */
    405      1.1  haad 	if (seg_is_mirrored(lp))
    406      1.1  haad 		lp->mirrors = 2;
    407      1.1  haad 
    408      1.1  haad 	if (arg_count(cmd, mirrors_ARG)) {
    409      1.1  haad 		lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
    410      1.1  haad 		if (lp->mirrors == 1)
    411      1.1  haad 			log_print("Redundant mirrors argument: default is 0");
    412      1.1  haad 		if (arg_sign_value(cmd, mirrors_ARG, 0) == SIGN_MINUS) {
    413      1.1  haad 			log_error("Mirrors argument may not be negative");
    414      1.1  haad 			return 0;
    415      1.1  haad 		}
    416      1.1  haad 	}
    417      1.1  haad 
    418      1.1  haad 	if (lp->snapshot) {
    419      1.1  haad 		if (arg_count(cmd, zero_ARG)) {
    420      1.1  haad 			log_error("-Z is incompatible with snapshots");
    421      1.1  haad 			return 0;
    422      1.1  haad 		}
    423      1.1  haad 		if (arg_sign_value(cmd, chunksize_ARG, 0) == SIGN_MINUS) {
    424      1.1  haad 			log_error("Negative chunk size is invalid");
    425      1.1  haad 			return 0;
    426      1.1  haad 		}
    427      1.1  haad 		lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
    428      1.1  haad 		if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
    429      1.1  haad 		    (lp->chunk_size & (lp->chunk_size - 1))) {
    430      1.1  haad 			log_error("Chunk size must be a power of 2 in the "
    431      1.1  haad 				  "range 4K to 512K");
    432      1.1  haad 			return 0;
    433      1.1  haad 		}
    434      1.1  haad 		log_verbose("Setting chunksize to %d sectors.", lp->chunk_size);
    435      1.1  haad 
    436      1.1  haad 		if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
    437      1.1  haad 			return_0;
    438      1.1  haad 	} else {
    439      1.1  haad 		if (arg_count(cmd, chunksize_ARG)) {
    440      1.1  haad 			log_error("-c is only available with snapshots");
    441      1.1  haad 			return 0;
    442      1.1  haad 		}
    443      1.1  haad 	}
    444      1.1  haad 
    445      1.1  haad 	if (lp->mirrors > 1) {
    446      1.1  haad 		if (lp->snapshot) {
    447      1.1  haad 			log_error("mirrors and snapshots are currently "
    448      1.1  haad 				  "incompatible");
    449      1.1  haad 			return 0;
    450      1.1  haad 		}
    451      1.1  haad 
    452      1.1  haad 		if (lp->stripes > 1) {
    453      1.1  haad 			log_error("mirrors and stripes are currently "
    454      1.1  haad 				  "incompatible");
    455      1.1  haad 			return 0;
    456      1.1  haad 		}
    457      1.1  haad 
    458      1.1  haad 		if (!(lp->segtype = get_segtype_from_string(cmd, "striped")))
    459      1.1  haad 			return_0;
    460      1.1  haad 	} else {
    461      1.1  haad 		if (arg_count(cmd, corelog_ARG)) {
    462      1.1  haad 			log_error("--corelog is only available with mirrors");
    463      1.1  haad 			return 0;
    464      1.1  haad 		}
    465      1.1  haad 
    466      1.1  haad 		if (arg_count(cmd, nosync_ARG)) {
    467      1.1  haad 			log_error("--nosync is only available with mirrors");
    468      1.1  haad 			return 0;
    469      1.1  haad 		}
    470      1.1  haad 	}
    471      1.1  haad 
    472      1.1  haad 	if (activation() && lp->segtype->ops->target_present &&
    473  1.1.1.2  haad 	    !lp->segtype->ops->target_present(cmd, NULL, NULL)) {
    474      1.1  haad 		log_error("%s: Required device-mapper target(s) not "
    475      1.1  haad 			  "detected in your kernel", lp->segtype->name);
    476      1.1  haad 		return 0;
    477      1.1  haad 	}
    478      1.1  haad 
    479      1.1  haad 	if (!_lvcreate_name_params(lp, cmd, &argc, &argv) ||
    480  1.1.1.2  haad 	    !_read_size_params(lp, lcp, cmd) ||
    481      1.1  haad 	    !_read_stripe_params(lp, cmd) ||
    482      1.1  haad 	    !_read_mirror_params(lp, cmd))
    483      1.1  haad 		return_0;
    484      1.1  haad 
    485      1.1  haad 	/*
    486      1.1  haad 	 * Should we zero the lv.
    487      1.1  haad 	 */
    488      1.1  haad 	lp->zero = strcmp(arg_str_value(cmd, zero_ARG,
    489      1.1  haad 		(lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n");
    490      1.1  haad 
    491      1.1  haad 	/*
    492      1.1  haad 	 * Alloc policy
    493      1.1  haad 	 */
    494      1.1  haad 	contiguous = strcmp(arg_str_value(cmd, contiguous_ARG, "n"), "n");
    495      1.1  haad 
    496      1.1  haad 	lp->alloc = contiguous ? ALLOC_CONTIGUOUS : ALLOC_INHERIT;
    497      1.1  haad 
    498      1.1  haad 	lp->alloc = arg_uint_value(cmd, alloc_ARG, lp->alloc);
    499      1.1  haad 
    500      1.1  haad 	if (contiguous && (lp->alloc != ALLOC_CONTIGUOUS)) {
    501      1.1  haad 		log_error("Conflicting contiguous and alloc arguments");
    502      1.1  haad 		return 0;
    503      1.1  haad 	}
    504      1.1  haad 
    505      1.1  haad 	/*
    506      1.1  haad 	 * Read ahead.
    507      1.1  haad 	 */
    508      1.1  haad 	lp->read_ahead = arg_uint_value(cmd, readahead_ARG, DM_READ_AHEAD_NONE);
    509      1.1  haad 	pagesize = lvm_getpagesize() >> SECTOR_SHIFT;
    510      1.1  haad 	if (lp->read_ahead != DM_READ_AHEAD_AUTO &&
    511      1.1  haad 	    lp->read_ahead != DM_READ_AHEAD_NONE &&
    512      1.1  haad 	    lp->read_ahead % pagesize) {
    513  1.1.1.2  haad 		if (lp->read_ahead < pagesize)
    514  1.1.1.2  haad 			lp->read_ahead = pagesize;
    515  1.1.1.2  haad 		else
    516  1.1.1.2  haad 			lp->read_ahead = (lp->read_ahead / pagesize) * pagesize;
    517  1.1.1.2  haad 		log_warn("WARNING: Overriding readahead to %u sectors, a multiple "
    518  1.1.1.2  haad 			    "of %uK page size.", lp->read_ahead, pagesize >> 1);
    519      1.1  haad 	}
    520      1.1  haad 
    521      1.1  haad 	/*
    522      1.1  haad 	 * Permissions.
    523      1.1  haad 	 */
    524  1.1.1.2  haad 	lp->permission = arg_uint_value(cmd, permission_ARG,
    525  1.1.1.2  haad 					LVM_READ | LVM_WRITE);
    526      1.1  haad 
    527      1.1  haad 	/* Must not zero read only volume */
    528      1.1  haad 	if (!(lp->permission & LVM_WRITE))
    529      1.1  haad 		lp->zero = 0;
    530      1.1  haad 
    531      1.1  haad 	lp->minor = arg_int_value(cmd, minor_ARG, -1);
    532      1.1  haad 	lp->major = arg_int_value(cmd, major_ARG, -1);
    533      1.1  haad 
    534      1.1  haad 	/* Persistent minor */
    535      1.1  haad 	if (arg_count(cmd, persistent_ARG)) {
    536      1.1  haad 		if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "y")) {
    537      1.1  haad 			if (lp->minor == -1) {
    538      1.1  haad 				log_error("Please specify minor number with "
    539      1.1  haad 					  "--minor when using -My");
    540      1.1  haad 				return 0;
    541      1.1  haad 			}
    542      1.1  haad 			if (lp->major == -1) {
    543      1.1  haad 				log_error("Please specify major number with "
    544      1.1  haad 					  "--major when using -My");
    545      1.1  haad 				return 0;
    546      1.1  haad 			}
    547      1.1  haad 		} else {
    548      1.1  haad 			if ((lp->minor != -1) || (lp->major != -1)) {
    549      1.1  haad 				log_error("--major and --minor incompatible "
    550      1.1  haad 					  "with -Mn");
    551      1.1  haad 				return 0;
    552      1.1  haad 			}
    553      1.1  haad 		}
    554      1.1  haad 	} else if (arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) {
    555      1.1  haad 		log_error("--major and --minor require -My");
    556      1.1  haad 		return 0;
    557      1.1  haad 	}
    558      1.1  haad 
    559  1.1.1.2  haad 	lp->tag = arg_str_value(cmd, addtag_ARG, NULL);
    560      1.1  haad 
    561  1.1.1.2  haad 	lcp->pv_count = argc;
    562  1.1.1.2  haad 	lcp->pvs = argv;
    563      1.1  haad 
    564      1.1  haad 	return 1;
    565      1.1  haad }
    566      1.1  haad 
    567      1.1  haad int lvcreate(struct cmd_context *cmd, int argc, char **argv)
    568      1.1  haad {
    569      1.1  haad 	int r = ECMD_PROCESSED;
    570      1.1  haad 	struct lvcreate_params lp;
    571  1.1.1.2  haad 	struct lvcreate_cmdline_params lcp;
    572      1.1  haad 	struct volume_group *vg;
    573      1.1  haad 
    574      1.1  haad 	memset(&lp, 0, sizeof(lp));
    575      1.1  haad 
    576  1.1.1.2  haad 	if (!_lvcreate_params(&lp, &lcp, cmd, argc, argv))
    577      1.1  haad 		return EINVALID_CMD_LINE;
    578      1.1  haad 
    579      1.1  haad 	log_verbose("Finding volume group \"%s\"", lp.vg_name);
    580  1.1.1.2  haad 	vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0);
    581  1.1.1.2  haad 	if (vg_read_error(vg)) {
    582  1.1.1.2  haad 		vg_release(vg);
    583  1.1.1.2  haad 		stack;
    584      1.1  haad 		return ECMD_FAILED;
    585  1.1.1.2  haad 	}
    586      1.1  haad 
    587  1.1.1.2  haad 	if (!_update_extents_params(vg, &lp, &lcp)) {
    588      1.1  haad 		r = ECMD_FAILED;
    589  1.1.1.2  haad 		goto_out;
    590  1.1.1.2  haad 	}
    591      1.1  haad 
    592  1.1.1.2  haad 	if (!lv_create_single(vg, &lp)) {
    593  1.1.1.2  haad 		stack;
    594  1.1.1.2  haad 		r = ECMD_FAILED;
    595  1.1.1.2  haad 	}
    596  1.1.1.2  haad out:
    597  1.1.1.2  haad 	unlock_and_release_vg(cmd, vg, lp.vg_name);
    598      1.1  haad 	return r;
    599      1.1  haad }
    600