4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU Lesser General Public License v.2.1.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 struct lvcreate_cmdline_params
{
30 static int _lvcreate_name_params(struct lvcreate_params
*lp
,
31 struct cmd_context
*cmd
,
32 int *pargc
, char ***pargv
)
35 char **argv
= *pargv
, *ptr
;
38 lp
->lv_name
= arg_str_value(cmd
, name_ARG
, NULL
);
40 if (lp
->snapshot
&& !arg_count(cmd
, virtualsize_ARG
)) {
42 log_error("Please specify a logical volume to act as "
43 "the snapshot origin.");
48 (*pargv
)++, (*pargc
)--;
49 if (!(lp
->vg_name
= extract_vgname(cmd
, lp
->origin
))) {
50 log_error("The origin name should include the "
55 /* Strip the volume group from the origin */
56 if ((ptr
= strrchr(lp
->origin
, (int) '/')))
61 * If VG not on command line, try -n arg and then
65 if (!(lp
->vg_name
= extract_vgname(cmd
, lp
->lv_name
))) {
66 log_error("Please provide a volume group name");
71 vg_name
= skip_dev_dir(cmd
, argv
[0], NULL
);
72 if (strrchr(vg_name
, '/')) {
73 log_error("Volume group name expected "
79 * Ensure lv_name doesn't contain a
82 if (lp
->lv_name
&& strchr(lp
->lv_name
, '/')) {
84 extract_vgname(cmd
, lp
->lv_name
)))
87 if (strcmp(lp
->vg_name
, vg_name
)) {
88 log_error("Inconsistent volume group "
90 "given: \"%s\" and \"%s\"",
91 lp
->vg_name
, vg_name
);
96 lp
->vg_name
= vg_name
;
97 (*pargv
)++, (*pargc
)--;
101 if (!validate_name(lp
->vg_name
)) {
102 log_error("Volume group name %s has invalid characters",
108 if ((ptr
= strrchr(lp
->lv_name
, '/')))
109 lp
->lv_name
= ptr
+ 1;
111 if (!apply_lvname_restrictions(lp
->lv_name
))
114 if (!validate_name(lp
->lv_name
)) {
115 log_error("Logical volume name \"%s\" is invalid",
125 * Update extents parameters based on other parameters which affect the size
127 * NOTE: We must do this here because of the percent_t typedef and because we
130 static int _update_extents_params(struct volume_group
*vg
,
131 struct lvcreate_params
*lp
,
132 struct lvcreate_cmdline_params
*lcp
)
134 uint32_t pv_extent_count
;
137 !(lp
->extents
= extents_from_size(vg
->cmd
, lcp
->size
,
141 if (lp
->voriginsize
&&
142 !(lp
->voriginextents
= extents_from_size(vg
->cmd
, lp
->voriginsize
,
147 * Create the pv list before we parse lcp->percent - might be
151 if (!(lp
->pvh
= create_pv_list(vg
->cmd
->mem
, vg
,
152 lcp
->pv_count
, lcp
->pvs
, 1)))
157 switch(lcp
->percent
) {
159 lp
->extents
= lp
->extents
* vg
->extent_count
/ 100;
162 lp
->extents
= lp
->extents
* vg
->free_count
/ 100;
166 lp
->extents
= lp
->extents
* vg
->extent_count
/ 100;
168 pv_extent_count
= pv_list_extents_free(lp
->pvh
);
169 lp
->extents
= lp
->extents
* pv_extent_count
/ 100;
173 log_error("Please express size as %%VG, %%PVS, or "
182 static int _read_size_params(struct lvcreate_params
*lp
,
183 struct lvcreate_cmdline_params
*lcp
,
184 struct cmd_context
*cmd
)
186 if (arg_count(cmd
, extents_ARG
) + arg_count(cmd
, size_ARG
) != 1) {
187 log_error("Please specify either size or extents (not both)");
191 if (arg_count(cmd
, extents_ARG
)) {
192 if (arg_sign_value(cmd
, extents_ARG
, 0) == SIGN_MINUS
) {
193 log_error("Negative number of extents is invalid");
196 lp
->extents
= arg_uint_value(cmd
, extents_ARG
, 0);
197 lcp
->percent
= arg_percent_value(cmd
, extents_ARG
, PERCENT_NONE
);
200 /* Size returned in kilobyte units; held in sectors */
201 if (arg_count(cmd
, size_ARG
)) {
202 if (arg_sign_value(cmd
, size_ARG
, 0) == SIGN_MINUS
) {
203 log_error("Negative size is invalid");
206 lcp
->size
= arg_uint64_value(cmd
, size_ARG
, UINT64_C(0));
207 lcp
->percent
= PERCENT_NONE
;
210 /* Size returned in kilobyte units; held in sectors */
211 if (arg_count(cmd
, virtualsize_ARG
)) {
212 if (arg_sign_value(cmd
, virtualsize_ARG
, 0) == SIGN_MINUS
) {
213 log_error("Negative virtual origin size is invalid");
216 lp
->voriginsize
= arg_uint64_value(cmd
, virtualsize_ARG
,
218 if (!lp
->voriginsize
) {
219 log_error("Virtual origin size may not be zero");
228 * Generic stripe parameter checks.
229 * FIXME: Should eventually be moved into lvm library.
231 static int _validate_stripe_params(struct cmd_context
*cmd
,
232 struct lvcreate_params
*lp
)
234 if (lp
->stripes
== 1 && lp
->stripe_size
) {
235 log_print("Ignoring stripesize argument with single stripe");
239 if (lp
->stripes
> 1 && !lp
->stripe_size
) {
240 lp
->stripe_size
= find_config_tree_int(cmd
,
241 "metadata/stripesize",
242 DEFAULT_STRIPESIZE
) * 2;
243 log_print("Using default stripesize %s",
244 display_size(cmd
, (uint64_t) lp
->stripe_size
));
247 if (lp
->stripes
< 1 || lp
->stripes
> MAX_STRIPES
) {
248 log_error("Number of stripes (%d) must be between %d and %d",
249 lp
->stripes
, 1, MAX_STRIPES
);
253 /* MAX size check is in _lvcreate */
254 if (lp
->stripes
> 1 && (lp
->stripe_size
< STRIPE_SIZE_MIN
||
255 lp
->stripe_size
& (lp
->stripe_size
- 1))) {
256 log_error("Invalid stripe size %s",
257 display_size(cmd
, (uint64_t) lp
->stripe_size
));
264 /* The stripe size is limited by the size of a uint32_t, but since the
265 * value given by the user is doubled, and the final result must be a
266 * power of 2, we must divide UINT_MAX by four and add 1 (to round it
267 * up to the power of 2) */
268 static int _read_stripe_params(struct lvcreate_params
*lp
,
269 struct cmd_context
*cmd
)
271 if (arg_count(cmd
, stripesize_ARG
)) {
272 if (arg_sign_value(cmd
, stripesize_ARG
, 0) == SIGN_MINUS
) {
273 log_error("Negative stripesize is invalid");
276 /* Check to make sure we won't overflow lp->stripe_size */
277 if(arg_uint_value(cmd
, stripesize_ARG
, 0) > STRIPE_SIZE_LIMIT
* 2) {
278 log_error("Stripe size cannot be larger than %s",
279 display_size(cmd
, (uint64_t) STRIPE_SIZE_LIMIT
));
282 lp
->stripe_size
= arg_uint_value(cmd
, stripesize_ARG
, 0);
286 if (!_validate_stripe_params(cmd
, lp
))
293 * Generic mirror parameter checks.
294 * FIXME: Should eventually be moved into lvm library.
296 static int _validate_mirror_params(const struct cmd_context
*cmd
__attribute((unused
)),
297 const struct lvcreate_params
*lp
)
299 int pagesize
= lvm_getpagesize();
301 if (lp
->region_size
& (lp
->region_size
- 1)) {
302 log_error("Region size (%" PRIu32
") must be a power of 2",
307 if (lp
->region_size
% (pagesize
>> SECTOR_SHIFT
)) {
308 log_error("Region size (%" PRIu32
") must be a multiple of "
309 "machine memory page size (%d)",
310 lp
->region_size
, pagesize
>> SECTOR_SHIFT
);
314 if (!lp
->region_size
) {
315 log_error("Non-zero region size must be supplied.");
322 static int _read_mirror_params(struct lvcreate_params
*lp
,
323 struct cmd_context
*cmd
)
326 const char *mirrorlog
;
328 if (arg_count(cmd
, corelog_ARG
))
331 mirrorlog
= arg_str_value(cmd
, mirrorlog_ARG
,
332 lp
->corelog
? "core" : DEFAULT_MIRRORLOG
);
334 if (!strcmp("disk", mirrorlog
)) {
336 log_error("--mirrorlog disk and --corelog "
341 } else if (!strcmp("core", mirrorlog
))
344 log_error("Unknown mirrorlog type: %s", mirrorlog
);
348 log_verbose("Setting logging type to %s", mirrorlog
);
350 lp
->nosync
= arg_is_set(cmd
, nosync_ARG
);
352 if (arg_count(cmd
, regionsize_ARG
)) {
353 if (arg_sign_value(cmd
, regionsize_ARG
, 0) == SIGN_MINUS
) {
354 log_error("Negative regionsize is invalid");
357 lp
->region_size
= arg_uint_value(cmd
, regionsize_ARG
, 0);
359 region_size
= 2 * find_config_tree_int(cmd
,
360 "activation/mirror_region_size",
361 DEFAULT_MIRROR_REGION_SIZE
);
362 if (region_size
< 0) {
363 log_error("Negative regionsize in configuration file "
367 lp
->region_size
= region_size
;
370 if (!_validate_mirror_params(cmd
, lp
))
376 static int _lvcreate_params(struct lvcreate_params
*lp
,
377 struct lvcreate_cmdline_params
*lcp
,
378 struct cmd_context
*cmd
,
379 int argc
, char **argv
)
384 memset(lp
, 0, sizeof(*lp
));
385 memset(lcp
, 0, sizeof(*lcp
));
388 * Check selected options are compatible and determine segtype
390 lp
->segtype
= (const struct segment_type
*)
391 arg_ptr_value(cmd
, type_ARG
,
392 get_segtype_from_string(cmd
, "striped"));
394 lp
->stripes
= arg_uint_value(cmd
, stripes_ARG
, 1);
395 if (arg_count(cmd
, stripes_ARG
) && lp
->stripes
== 1)
396 log_print("Redundant stripes argument: default is 1");
398 if (arg_count(cmd
, snapshot_ARG
) || seg_is_snapshot(lp
) ||
399 arg_count(cmd
, virtualsize_ARG
))
404 /* Default to 2 mirrored areas if --type mirror */
405 if (seg_is_mirrored(lp
))
408 if (arg_count(cmd
, mirrors_ARG
)) {
409 lp
->mirrors
= arg_uint_value(cmd
, mirrors_ARG
, 0) + 1;
410 if (lp
->mirrors
== 1)
411 log_print("Redundant mirrors argument: default is 0");
412 if (arg_sign_value(cmd
, mirrors_ARG
, 0) == SIGN_MINUS
) {
413 log_error("Mirrors argument may not be negative");
419 if (arg_count(cmd
, zero_ARG
)) {
420 log_error("-Z is incompatible with snapshots");
423 if (arg_sign_value(cmd
, chunksize_ARG
, 0) == SIGN_MINUS
) {
424 log_error("Negative chunk size is invalid");
427 lp
->chunk_size
= arg_uint_value(cmd
, chunksize_ARG
, 8);
428 if (lp
->chunk_size
< 8 || lp
->chunk_size
> 1024 ||
429 (lp
->chunk_size
& (lp
->chunk_size
- 1))) {
430 log_error("Chunk size must be a power of 2 in the "
434 log_verbose("Setting chunksize to %d sectors.", lp
->chunk_size
);
436 if (!(lp
->segtype
= get_segtype_from_string(cmd
, "snapshot")))
439 if (arg_count(cmd
, chunksize_ARG
)) {
440 log_error("-c is only available with snapshots");
445 if (lp
->mirrors
> 1) {
447 log_error("mirrors and snapshots are currently "
452 if (lp
->stripes
> 1) {
453 log_error("mirrors and stripes are currently "
458 if (!(lp
->segtype
= get_segtype_from_string(cmd
, "striped")))
461 if (arg_count(cmd
, corelog_ARG
)) {
462 log_error("--corelog is only available with mirrors");
466 if (arg_count(cmd
, nosync_ARG
)) {
467 log_error("--nosync is only available with mirrors");
472 if (activation() && lp
->segtype
->ops
->target_present
&&
473 !lp
->segtype
->ops
->target_present(cmd
, NULL
, NULL
)) {
474 log_error("%s: Required device-mapper target(s) not "
475 "detected in your kernel", lp
->segtype
->name
);
479 if (!_lvcreate_name_params(lp
, cmd
, &argc
, &argv
) ||
480 !_read_size_params(lp
, lcp
, cmd
) ||
481 !_read_stripe_params(lp
, cmd
) ||
482 !_read_mirror_params(lp
, cmd
))
486 * Should we zero the lv.
488 lp
->zero
= strcmp(arg_str_value(cmd
, zero_ARG
,
489 (lp
->segtype
->flags
& SEG_CANNOT_BE_ZEROED
) ? "n" : "y"), "n");
494 contiguous
= strcmp(arg_str_value(cmd
, contiguous_ARG
, "n"), "n");
496 lp
->alloc
= contiguous
? ALLOC_CONTIGUOUS
: ALLOC_INHERIT
;
498 lp
->alloc
= arg_uint_value(cmd
, alloc_ARG
, lp
->alloc
);
500 if (contiguous
&& (lp
->alloc
!= ALLOC_CONTIGUOUS
)) {
501 log_error("Conflicting contiguous and alloc arguments");
508 lp
->read_ahead
= arg_uint_value(cmd
, readahead_ARG
, DM_READ_AHEAD_NONE
);
509 pagesize
= lvm_getpagesize() >> SECTOR_SHIFT
;
510 if (lp
->read_ahead
!= DM_READ_AHEAD_AUTO
&&
511 lp
->read_ahead
!= DM_READ_AHEAD_NONE
&&
512 lp
->read_ahead
% pagesize
) {
513 if (lp
->read_ahead
< pagesize
)
514 lp
->read_ahead
= pagesize
;
516 lp
->read_ahead
= (lp
->read_ahead
/ pagesize
) * pagesize
;
517 log_warn("WARNING: Overriding readahead to %u sectors, a multiple "
518 "of %uK page size.", lp
->read_ahead
, pagesize
>> 1);
524 lp
->permission
= arg_uint_value(cmd
, permission_ARG
,
525 LVM_READ
| LVM_WRITE
);
527 /* Must not zero read only volume */
528 if (!(lp
->permission
& LVM_WRITE
))
531 lp
->minor
= arg_int_value(cmd
, minor_ARG
, -1);
532 lp
->major
= arg_int_value(cmd
, major_ARG
, -1);
534 /* Persistent minor */
535 if (arg_count(cmd
, persistent_ARG
)) {
536 if (!strcmp(arg_str_value(cmd
, persistent_ARG
, "n"), "y")) {
537 if (lp
->minor
== -1) {
538 log_error("Please specify minor number with "
539 "--minor when using -My");
542 if (lp
->major
== -1) {
543 log_error("Please specify major number with "
544 "--major when using -My");
548 if ((lp
->minor
!= -1) || (lp
->major
!= -1)) {
549 log_error("--major and --minor incompatible "
554 } else if (arg_count(cmd
, minor_ARG
) || arg_count(cmd
, major_ARG
)) {
555 log_error("--major and --minor require -My");
559 lp
->tag
= arg_str_value(cmd
, addtag_ARG
, NULL
);
561 lcp
->pv_count
= argc
;
567 int lvcreate(struct cmd_context
*cmd
, int argc
, char **argv
)
569 int r
= ECMD_PROCESSED
;
570 struct lvcreate_params lp
;
571 struct lvcreate_cmdline_params lcp
;
572 struct volume_group
*vg
;
574 memset(&lp
, 0, sizeof(lp
));
576 if (!_lvcreate_params(&lp
, &lcp
, cmd
, argc
, argv
))
577 return EINVALID_CMD_LINE
;
579 log_verbose("Finding volume group \"%s\"", lp
.vg_name
);
580 vg
= vg_read_for_update(cmd
, lp
.vg_name
, NULL
, 0);
581 if (vg_read_error(vg
)) {
587 if (!_update_extents_params(vg
, &lp
, &lcp
)) {
592 if (!lv_create_single(vg
, &lp
)) {
597 unlock_and_release_vg(cmd
, vg
, lp
.vg_name
);