2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
9 * of the GNU Lesser General Public License v.2.1.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 struct lvcreate_cmdline_params
{
22 percent_type_t percent
;
28 static int _set_vg_name(struct lvcreate_params
*lp
, const char *vg_name
)
30 /* Can't do anything */
34 /* If VG name already known, ensure this 2nd copy is identical */
35 if (lp
->vg_name
&& strcmp(lp
->vg_name
, vg_name
)) {
36 log_error("Inconsistent volume group names "
37 "given: \"%s\" and \"%s\"",
38 lp
->vg_name
, vg_name
);
41 lp
->vg_name
= vg_name
;
46 static int _lvcreate_name_params(struct lvcreate_params
*lp
,
47 struct cmd_context
*cmd
,
48 int *pargc
, char ***pargv
)
51 char **argv
= *pargv
, *ptr
;
54 lp
->pool
= arg_str_value(cmd
, thinpool_ARG
, NULL
);
56 /* If --thinpool contains VG name, extract it. */
57 if (lp
->pool
&& strchr(lp
->pool
, '/')) {
58 if (!(lp
->vg_name
= extract_vgname(cmd
, lp
->pool
)))
60 /* Strip VG from pool */
61 if ((ptr
= strrchr(lp
->pool
, (int) '/')))
65 lp
->lv_name
= arg_str_value(cmd
, name_ARG
, NULL
);
67 /* If --name contains VG name, extract it. */
68 if (lp
->lv_name
&& strchr(lp
->lv_name
, '/')) {
69 if (!_set_vg_name(lp
, extract_vgname(cmd
, lp
->lv_name
)))
72 /* Strip VG from lv_name */
73 if ((ptr
= strrchr(lp
->lv_name
, (int) '/')))
74 lp
->lv_name
= ptr
+ 1;
78 if (lp
->snapshot
&& !arg_count(cmd
, virtualsize_ARG
)) {
79 /* argv[0] might be origin or vg/origin */
81 log_error("Please specify a logical volume to act as "
82 "the snapshot origin.");
86 lp
->origin
= skip_dev_dir(cmd
, argv
[0], NULL
);
87 if (strrchr(lp
->origin
, '/')) {
88 if (!_set_vg_name(lp
, extract_vgname(cmd
, lp
->origin
)))
91 /* Strip the volume group from the origin */
92 if ((ptr
= strrchr(lp
->origin
, (int) '/')))
97 !_set_vg_name(lp
, extract_vgname(cmd
, NULL
)))
101 log_error("The origin name should include the "
106 (*pargv
)++, (*pargc
)--;
107 } else if (seg_is_thin(lp
) && !lp
->pool
&& argc
) {
108 /* argv[0] might be vg or vg/Pool */
110 vg_name
= skip_dev_dir(cmd
, argv
[0], NULL
);
111 if (!strrchr(vg_name
, '/')) {
112 if (!_set_vg_name(lp
, vg_name
))
116 if (!_set_vg_name(lp
, extract_vgname(cmd
, lp
->pool
)))
120 !_set_vg_name(lp
, extract_vgname(cmd
, NULL
)))
124 log_error("The pool name should include the "
129 /* Strip the volume group */
130 if ((ptr
= strrchr(lp
->pool
, (int) '/')))
134 (*pargv
)++, (*pargc
)--;
137 * If VG not on command line, try environment default.
140 if (!lp
->vg_name
&& !(lp
->vg_name
= extract_vgname(cmd
, NULL
))) {
141 log_error("Please provide a volume group name");
145 vg_name
= skip_dev_dir(cmd
, argv
[0], NULL
);
146 if (strrchr(vg_name
, '/')) {
147 log_error("Volume group name expected "
152 if (!_set_vg_name(lp
, vg_name
))
155 (*pargv
)++, (*pargc
)--;
159 if (!validate_name(lp
->vg_name
)) {
160 log_error("Volume group name %s has invalid characters",
166 if (!apply_lvname_restrictions(lp
->lv_name
))
169 if (!validate_name(lp
->lv_name
)) {
170 log_error("Logical volume name \"%s\" is invalid",
177 if (!apply_lvname_restrictions(lp
->pool
))
180 if (!validate_name(lp
->pool
)) {
181 log_error("Logical volume name \"%s\" is invalid",
186 if (lp
->lv_name
&& !strcmp(lp
->lv_name
, lp
->pool
)) {
187 log_error("Logical volume name %s and pool name %s must be different.",
188 lp
->lv_name
, lp
->pool
);
197 * Normal snapshot or thinly-provisioned snapshot?
199 static int _determine_snapshot_type(struct volume_group
*vg
,
200 struct lvcreate_params
*lp
)
204 if (!(lvl
= find_lv_in_vg(vg
, lp
->origin
))) {
205 log_error("Snapshot origin LV %s not found in Volume group %s.",
206 lp
->origin
, vg
->name
);
210 if (!arg_count(vg
->cmd
, extents_ARG
) && !arg_count(vg
->cmd
, size_ARG
)) {
211 if (!lv_is_thin_volume(lvl
->lv
)) {
212 log_error("Please specify either size or extents with snapshots.");
217 if (!(lp
->segtype
= get_segtype_from_string(vg
->cmd
, "thin")))
220 lp
->pool
= first_seg(lvl
->lv
)->pool_lv
->name
;
227 * Update extents parameters based on other parameters which affect the size
229 * NOTE: We must do this here because of the percent_t typedef and because we
232 static int _update_extents_params(struct volume_group
*vg
,
233 struct lvcreate_params
*lp
,
234 struct lvcreate_cmdline_params
*lcp
)
236 uint32_t pv_extent_count
;
237 struct logical_volume
*origin
= NULL
;
240 uint32_t stripesize_extents
;
243 !(lp
->extents
= extents_from_size(vg
->cmd
, lcp
->size
,
247 if (lp
->voriginsize
&&
248 !(lp
->voriginextents
= extents_from_size(vg
->cmd
, lp
->voriginsize
,
253 * Create the pv list before we parse lcp->percent - might be
257 if (!(lp
->pvh
= create_pv_list(vg
->cmd
->mem
, vg
,
258 lcp
->pv_count
, lcp
->pvs
, 1)))
263 switch(lcp
->percent
) {
265 lp
->extents
= percent_of_extents(lp
->extents
, vg
->extent_count
, 0);
268 lp
->extents
= percent_of_extents(lp
->extents
, vg
->free_count
, 0);
272 lp
->extents
= percent_of_extents(lp
->extents
, vg
->extent_count
, 0);
274 pv_extent_count
= pv_list_extents_free(lp
->pvh
);
275 lp
->extents
= percent_of_extents(lp
->extents
, pv_extent_count
, 0);
279 log_error("Please express size as %%VG, %%PVS, or "
283 if (lp
->snapshot
&& lp
->origin
&&
284 !(origin
= find_lv(vg
, lp
->origin
))) {
285 log_error("Couldn't find origin volume '%s'.",
290 log_error(INTERNAL_ERROR
"Couldn't find origin volume.");
293 lp
->extents
= percent_of_extents(lp
->extents
, origin
->le_count
, 0);
299 if (!(stripesize_extents
= lp
->stripe_size
/ vg
->extent_size
))
300 stripesize_extents
= 1;
302 if ((lcp
->percent
!= PERCENT_NONE
) && lp
->stripes
&&
303 (size_rest
= lp
->extents
% (lp
->stripes
* stripesize_extents
)) &&
304 (vg
->free_count
< lp
->extents
- size_rest
+ (lp
->stripes
* stripesize_extents
))) {
305 log_print("Rounding size (%d extents) down to stripe boundary "
306 "size (%d extents)", lp
->extents
,
307 lp
->extents
- size_rest
);
308 lp
->extents
= lp
->extents
- size_rest
;
311 if (lp
->create_thin_pool
) {
312 if (!arg_count(vg
->cmd
, poolmetadatasize_ARG
)) {
313 /* Defaults to nr_pool_blocks * 64b */
314 lp
->poolmetadatasize
= (uint64_t) lp
->extents
* vg
->extent_size
/
315 (uint64_t) (lp
->chunk_size
* (SECTOR_SIZE
/ UINT64_C(64)));
317 /* Check if we could eventually use bigger chunk size */
318 if (!arg_count(vg
->cmd
, chunksize_ARG
)) {
319 while ((lp
->poolmetadatasize
>
320 (DEFAULT_THIN_POOL_OPTIMAL_SIZE
/ SECTOR_SIZE
)) &&
321 (lp
->chunk_size
< DM_THIN_MAX_DATA_BLOCK_SIZE
)) {
322 lp
->chunk_size
<<= 1;
323 lp
->poolmetadatasize
>>= 1;
327 log_verbose("Changed chunksize to %u sectors.",
332 if (lp
->poolmetadatasize
> (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE
)) {
333 if (arg_count(vg
->cmd
, poolmetadatasize_ARG
))
334 log_warn("WARNING: Maximum supported pool metadata size is 16GB.");
335 lp
->poolmetadatasize
= 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE
;
336 } else if (lp
->poolmetadatasize
< (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE
)) {
337 if (arg_count(vg
->cmd
, poolmetadatasize_ARG
))
338 log_warn("WARNING: Minimum supported pool metadata size is 2M.");
339 lp
->poolmetadatasize
= 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE
;
342 log_verbose("Setting pool metadata size to %" PRIu64
" sectors.",
343 lp
->poolmetadatasize
);
345 if (!(lp
->poolmetadataextents
=
346 extents_from_size(vg
->cmd
, lp
->poolmetadatasize
, vg
->extent_size
)))
353 static int _read_size_params(struct lvcreate_params
*lp
,
354 struct lvcreate_cmdline_params
*lcp
,
355 struct cmd_context
*cmd
)
357 if (arg_count(cmd
, extents_ARG
) && arg_count(cmd
, size_ARG
)) {
358 log_error("Please specify either size or extents (not both)");
362 if (!lp
->thin
&& !lp
->snapshot
&& !arg_count(cmd
, extents_ARG
) && !arg_count(cmd
, size_ARG
)) {
363 log_error("Please specify either size or extents");
367 if (arg_count(cmd
, extents_ARG
)) {
368 if (arg_sign_value(cmd
, extents_ARG
, SIGN_NONE
) == SIGN_MINUS
) {
369 log_error("Negative number of extents is invalid");
372 lp
->extents
= arg_uint_value(cmd
, extents_ARG
, 0);
373 lcp
->percent
= arg_percent_value(cmd
, extents_ARG
, PERCENT_NONE
);
376 /* Size returned in kilobyte units; held in sectors */
377 if (arg_count(cmd
, size_ARG
)) {
378 if (arg_sign_value(cmd
, size_ARG
, SIGN_NONE
) == SIGN_MINUS
) {
379 log_error("Negative size is invalid");
382 lcp
->size
= arg_uint64_value(cmd
, size_ARG
, UINT64_C(0));
383 lcp
->percent
= PERCENT_NONE
;
386 /* If size/extents given with thin, then we are creating a thin pool */
387 if (lp
->thin
&& (arg_count(cmd
, size_ARG
) || arg_count(cmd
, extents_ARG
)))
388 lp
->create_thin_pool
= 1;
390 if (arg_count(cmd
, poolmetadatasize_ARG
)) {
391 if (!seg_is_thin(lp
)) {
392 log_error("--poolmetadatasize may only be specified when allocating the thin pool.");
395 if (arg_sign_value(cmd
, poolmetadatasize_ARG
, SIGN_NONE
) == SIGN_MINUS
) {
396 log_error("Negative poolmetadatasize is invalid.");
399 lp
->poolmetadatasize
= arg_uint64_value(cmd
, poolmetadatasize_ARG
, UINT64_C(0));
402 /* Size returned in kilobyte units; held in sectors */
403 if (arg_count(cmd
, virtualsize_ARG
)) {
404 if (seg_is_thin_pool(lp
)) {
405 log_error("Virtual size in incompatible with thin_pool segment type.");
408 if (arg_sign_value(cmd
, virtualsize_ARG
, SIGN_NONE
) == SIGN_MINUS
) {
409 log_error("Negative virtual origin size is invalid");
412 lp
->voriginsize
= arg_uint64_value(cmd
, virtualsize_ARG
,
414 if (!lp
->voriginsize
) {
415 log_error("Virtual origin size may not be zero");
419 /* No virtual size given, so no thin LV to create. */
420 if (seg_is_thin_volume(lp
) && !(lp
->segtype
= get_segtype_from_string(cmd
, "thin-pool")))
430 * Generic mirror parameter checks.
431 * FIXME: Should eventually be moved into lvm library.
433 static int _validate_mirror_params(const struct cmd_context
*cmd
__attribute__((unused
)),
434 const struct lvcreate_params
*lp
)
436 int pagesize
= lvm_getpagesize();
438 if (lp
->region_size
& (lp
->region_size
- 1)) {
439 log_error("Region size (%" PRIu32
") must be a power of 2",
444 if (lp
->region_size
% (pagesize
>> SECTOR_SHIFT
)) {
445 log_error("Region size (%" PRIu32
") must be a multiple of "
446 "machine memory page size (%d)",
447 lp
->region_size
, pagesize
>> SECTOR_SHIFT
);
451 if (!lp
->region_size
) {
452 log_error("Non-zero region size must be supplied.");
459 static int _read_mirror_params(struct lvcreate_params
*lp
,
460 struct cmd_context
*cmd
)
463 const char *mirrorlog
;
464 int corelog
= arg_count(cmd
, corelog_ARG
);
466 mirrorlog
= arg_str_value(cmd
, mirrorlog_ARG
,
467 corelog
? "core" : DEFAULT_MIRRORLOG
);
469 if (strcmp("core", mirrorlog
) && corelog
) {
470 log_error("Please use only one of --mirrorlog or --corelog");
474 if (!strcmp("mirrored", mirrorlog
)) {
476 } else if (!strcmp("disk", mirrorlog
)) {
478 } else if (!strcmp("core", mirrorlog
))
481 log_error("Unknown mirrorlog type: %s", mirrorlog
);
485 log_verbose("Setting logging type to %s", mirrorlog
);
487 lp
->nosync
= arg_is_set(cmd
, nosync_ARG
);
489 if (arg_count(cmd
, regionsize_ARG
)) {
490 if (arg_sign_value(cmd
, regionsize_ARG
, SIGN_NONE
) == SIGN_MINUS
) {
491 log_error("Negative regionsize is invalid");
494 lp
->region_size
= arg_uint_value(cmd
, regionsize_ARG
, 0);
496 region_size
= 2 * find_config_tree_int(cmd
,
497 "activation/mirror_region_size",
498 DEFAULT_MIRROR_REGION_SIZE
);
499 if (region_size
< 0) {
500 log_error("Negative regionsize in configuration file "
504 lp
->region_size
= region_size
;
507 if (!_validate_mirror_params(cmd
, lp
))
513 static int _read_raid_params(struct lvcreate_params
*lp
,
514 struct cmd_context
*cmd
)
516 if (!segtype_is_raid(lp
->segtype
))
519 if (arg_count(cmd
, corelog_ARG
) ||
520 arg_count(cmd
, mirrorlog_ARG
)) {
521 log_error("Log options not applicable to %s segtype",
527 * get_stripe_params is called before _read_raid_params
532 * For RAID 4/5/6, these values must be set.
534 if (!segtype_is_mirrored(lp
->segtype
) &&
535 (lp
->stripes
<= lp
->segtype
->parity_devs
)) {
536 log_error("Number of stripes must be at least %d for %s",
537 lp
->segtype
->parity_devs
+ 1, lp
->segtype
->name
);
542 * _read_mirror_params is called before _read_raid_params
547 * But let's ensure that programmers don't reorder
548 * that by checking and warning if they aren't set.
550 if (!lp
->region_size
) {
551 log_error(INTERNAL_ERROR
"region_size not set.");
558 static int _read_activation_params(struct lvcreate_params
*lp
, struct cmd_context
*cmd
)
562 lp
->activate
= (activation_change_t
)
563 arg_uint_value(cmd
, available_ARG
, CHANGE_AY
);
565 if (lp
->activate
== CHANGE_AN
|| lp
->activate
== CHANGE_ALN
) {
566 if (lp
->zero
&& !seg_is_thin(lp
)) {
567 log_error("--available n requires --zero n");
575 lp
->read_ahead
= arg_uint_value(cmd
, readahead_ARG
,
576 cmd
->default_settings
.read_ahead
);
577 pagesize
= lvm_getpagesize() >> SECTOR_SHIFT
;
578 if (lp
->read_ahead
!= DM_READ_AHEAD_AUTO
&&
579 lp
->read_ahead
!= DM_READ_AHEAD_NONE
&&
580 lp
->read_ahead
% pagesize
) {
581 if (lp
->read_ahead
< pagesize
)
582 lp
->read_ahead
= pagesize
;
584 lp
->read_ahead
= (lp
->read_ahead
/ pagesize
) * pagesize
;
585 log_warn("WARNING: Overriding readahead to %u sectors, a multiple "
586 "of %uK page size.", lp
->read_ahead
, pagesize
>> 1);
592 lp
->permission
= arg_uint_value(cmd
, permission_ARG
,
593 LVM_READ
| LVM_WRITE
);
595 if (lp
->thin
&& !(lp
->permission
& LVM_WRITE
)) {
596 log_error("Read-only thin volumes are not currently supported.");
600 /* Must not zero read only volume */
601 if (!(lp
->permission
& LVM_WRITE
))
604 if (arg_count(cmd
, major_ARG
) > 1) {
605 log_error("Option -j/--major may not be repeated.");
609 if (arg_count(cmd
, minor_ARG
) > 1) {
610 log_error("Option --minor may not be repeated.");
614 lp
->minor
= arg_int_value(cmd
, minor_ARG
, -1);
615 lp
->major
= arg_int_value(cmd
, major_ARG
, -1);
617 /* Persistent minor */
618 if (arg_count(cmd
, persistent_ARG
)) {
619 if (lp
->create_thin_pool
&& !lp
->thin
) {
620 log_error("--persistent is not permitted when creating a thin pool device.");
623 if (!strcmp(arg_str_value(cmd
, persistent_ARG
, "n"), "y")) {
624 if (lp
->minor
== -1) {
625 log_error("Please specify minor number with "
626 "--minor when using -My");
629 if (lp
->major
== -1) {
630 log_error("Please specify major number with "
631 "--major when using -My");
635 if ((lp
->minor
!= -1) || (lp
->major
!= -1)) {
636 log_error("--major and --minor incompatible "
641 } else if (arg_count(cmd
, minor_ARG
) || arg_count(cmd
, major_ARG
)) {
642 log_error("--major and --minor require -My");
649 static int _lvcreate_params(struct lvcreate_params
*lp
,
650 struct lvcreate_cmdline_params
*lcp
,
651 struct cmd_context
*cmd
,
652 int argc
, char **argv
)
655 struct arg_value_group_list
*current_group
;
656 const char *segtype_str
;
659 memset(lp
, 0, sizeof(*lp
));
660 memset(lcp
, 0, sizeof(*lcp
));
661 dm_list_init(&lp
->tags
);
664 * Check selected options are compatible and determine segtype
666 // FIXME -m0 implies *striped*
667 if (arg_count(cmd
, thin_ARG
) && arg_count(cmd
,mirrors_ARG
)) {
668 log_error("--thin and --mirrors are incompatible.");
672 // FIXME -m0 implies *striped*
674 /* Set default segtype */
675 if (arg_count(cmd
, mirrors_ARG
))
676 segtype_str
= find_config_tree_str(cmd
, "global/mirror_segtype_default", DEFAULT_MIRROR_SEGTYPE
);
677 else if (arg_count(cmd
, thin_ARG
) || arg_count(cmd
, thinpool_ARG
))
678 segtype_str
= "thin";
680 segtype_str
= "striped";
682 segtype_str
= arg_str_value(cmd
, type_ARG
, segtype_str
);
684 if (!(lp
->segtype
= get_segtype_from_string(cmd
, segtype_str
)))
687 if (seg_unknown(lp
)) {
688 log_error("Unable to create LV with unknown segment type %s.", segtype_str
);
692 if (arg_count(cmd
, snapshot_ARG
) || seg_is_snapshot(lp
) ||
693 (!seg_is_thin(lp
) && arg_count(cmd
, virtualsize_ARG
)))
696 if (seg_is_thin_pool(lp
)) {
698 log_error("Snapshots are incompatible with thin_pool segment_type.");
701 lp
->create_thin_pool
= 1;
704 if (seg_is_thin_volume(lp
))
709 /* Default to 2 mirrored areas if '--type mirror|raid1' */
710 if (segtype_is_mirrored(lp
->segtype
))
713 if (arg_count(cmd
, mirrors_ARG
)) {
714 lp
->mirrors
= arg_uint_value(cmd
, mirrors_ARG
, 0) + 1;
715 if (lp
->mirrors
== 1) {
716 if (segtype_is_mirrored(lp
->segtype
)) {
717 log_error("--mirrors must be at least 1 with segment type %s.", lp
->segtype
->name
);
720 log_print("Redundant mirrors argument: default is 0");
722 if (arg_sign_value(cmd
, mirrors_ARG
, SIGN_NONE
) == SIGN_MINUS
) {
723 log_error("Mirrors argument may not be negative");
728 if (lp
->snapshot
&& arg_count(cmd
, zero_ARG
)) {
729 log_error("-Z is incompatible with snapshots");
733 if (segtype_is_mirrored(lp
->segtype
) || segtype_is_raid(lp
->segtype
)) {
735 log_error("mirrors and snapshots are currently "
740 if (arg_count(cmd
, corelog_ARG
)) {
741 log_error("--corelog is only available with mirrors");
745 if (arg_count(cmd
, mirrorlog_ARG
)) {
746 log_error("--mirrorlog is only available with mirrors");
750 if (arg_count(cmd
, nosync_ARG
)) {
751 log_error("--nosync is only available with mirrors");
756 if (activation() && lp
->segtype
->ops
->target_present
&&
757 !lp
->segtype
->ops
->target_present(cmd
, NULL
, NULL
)) {
758 log_error("%s: Required device-mapper target(s) not "
759 "detected in your kernel", lp
->segtype
->name
);
763 if (!_lvcreate_name_params(lp
, cmd
, &argc
, &argv
) ||
764 !_read_size_params(lp
, lcp
, cmd
) ||
765 !get_stripe_params(cmd
, &lp
->stripes
, &lp
->stripe_size
) ||
766 !_read_mirror_params(lp
, cmd
) ||
767 !_read_raid_params(lp
, cmd
))
770 if (lp
->snapshot
&& lp
->thin
&& arg_count(cmd
, chunksize_ARG
))
771 log_warn("WARNING: Ignoring --chunksize with thin snapshots.");
772 else if (lp
->thin
&& !lp
->create_thin_pool
) {
773 if (arg_count(cmd
, chunksize_ARG
))
774 log_warn("WARNING: Ignoring --chunksize when using an existing pool.");
775 } else if (lp
->snapshot
|| lp
->create_thin_pool
) {
776 if (arg_sign_value(cmd
, chunksize_ARG
, SIGN_NONE
) == SIGN_MINUS
) {
777 log_error("Negative chunk size is invalid");
781 lp
->chunk_size
= arg_uint_value(cmd
, chunksize_ARG
, 8);
782 if (lp
->chunk_size
< 8 || lp
->chunk_size
> 1024 ||
783 (lp
->chunk_size
& (lp
->chunk_size
- 1))) {
784 log_error("Chunk size must be a power of 2 in the "
789 lp
->chunk_size
= arg_uint_value(cmd
, chunksize_ARG
,
790 DM_THIN_MIN_DATA_BLOCK_SIZE
);
791 if ((lp
->chunk_size
< DM_THIN_MIN_DATA_BLOCK_SIZE
) ||
792 (lp
->chunk_size
> DM_THIN_MAX_DATA_BLOCK_SIZE
) ||
793 (lp
->chunk_size
& (lp
->chunk_size
- 1))) {
794 log_error("Chunk size must be a power of 2 in the "
796 (DM_THIN_MIN_DATA_BLOCK_SIZE
/ 2),
797 (DM_THIN_MAX_DATA_BLOCK_SIZE
/ 2));
801 log_verbose("Setting chunksize to %u sectors.", lp
->chunk_size
);
803 if (!lp
->thin
&& lp
->snapshot
&& !(lp
->segtype
= get_segtype_from_string(cmd
, "snapshot")))
806 if (arg_count(cmd
, chunksize_ARG
)) {
807 log_error("-c is only available with snapshots and thin pools");
813 * Should we zero the lv.
815 lp
->zero
= strcmp(arg_str_value(cmd
, zero_ARG
,
816 (lp
->segtype
->flags
& SEG_CANNOT_BE_ZEROED
) ? "n" : "y"), "n");
818 if (lp
->mirrors
> DEFAULT_MIRROR_MAX_IMAGES
) {
819 log_error("Only up to %d images in mirror supported currently.",
820 DEFAULT_MIRROR_MAX_IMAGES
);
825 * Allocation parameters
827 contiguous
= strcmp(arg_str_value(cmd
, contiguous_ARG
, "n"), "n");
829 lp
->alloc
= contiguous
? ALLOC_CONTIGUOUS
: ALLOC_INHERIT
;
831 lp
->alloc
= (alloc_policy_t
) arg_uint_value(cmd
, alloc_ARG
, lp
->alloc
);
833 if (contiguous
&& (lp
->alloc
!= ALLOC_CONTIGUOUS
)) {
834 log_error("Conflicting contiguous and alloc arguments");
838 dm_list_iterate_items(current_group
, &cmd
->arg_value_groups
) {
839 if (!grouped_arg_is_set(current_group
->arg_values
, addtag_ARG
))
842 if (!(tag
= grouped_arg_str_value(current_group
->arg_values
, addtag_ARG
, NULL
))) {
843 log_error("Failed to get tag");
847 if (!str_list_add(cmd
->mem
, &lp
->tags
, tag
)) {
848 log_error("Unable to allocate memory for tag %s", tag
);
853 lcp
->pv_count
= argc
;
859 static int _check_thin_parameters(struct volume_group
*vg
, struct lvcreate_params
*lp
,
860 struct lvcreate_cmdline_params
*lcp
)
864 if (!lp
->thin
&& !lp
->create_thin_pool
) {
865 log_error("Please specify device size(s).");
869 if (lp
->thin
&& !lp
->create_thin_pool
) {
870 if (arg_count(vg
->cmd
, chunksize_ARG
)) {
871 log_error("Only specify --chunksize when originally creating the thin pool.");
876 log_error("Only specify Physical volumes when allocating the thin pool.");
880 if (arg_count(vg
->cmd
, alloc_ARG
)) {
881 log_error("--alloc may only be specified when allocating the thin pool.");
885 if (arg_count(vg
->cmd
, poolmetadatasize_ARG
)) {
886 log_error("--poolmetadatasize may only be specified when allocating the thin pool.");
890 if (arg_count(vg
->cmd
, stripesize_ARG
)) {
891 log_error("--stripesize may only be specified when allocating the thin pool.");
895 if (arg_count(vg
->cmd
, stripes_ARG
)) {
896 log_error("--stripes may only be specified when allocating the thin pool.");
900 if (arg_count(vg
->cmd
, contiguous_ARG
)) {
901 log_error("--contiguous may only be specified when allocating the thin pool.");
905 if (arg_count(vg
->cmd
, zero_ARG
)) {
906 log_error("--zero may only be specified when allocating the thin pool.");
911 if (lp
->create_thin_pool
&& lp
->pool
) {
912 if (find_lv_in_vg(vg
, lp
->pool
)) {
913 log_error("Pool %s already exists in Volume group %s.", lp
->pool
, vg
->name
);
916 } else if (lp
->pool
) {
917 if (!(lvl
= find_lv_in_vg(vg
, lp
->pool
))) {
918 log_error("Pool %s not found in Volume group %s.", lp
->pool
, vg
->name
);
921 if (!lv_is_thin_pool(lvl
->lv
)) {
922 log_error("Logical volume %s is not a thin pool.", lp
->pool
);
925 } else if (!lp
->create_thin_pool
) {
926 log_error("Please specify name of existing pool.");
930 if (!lp
->thin
&& lp
->lv_name
) {
931 log_error("--name may only be given when creating a new thin Logical volume or snapshot.");
936 if (arg_count(vg
->cmd
, readahead_ARG
)) {
937 log_error("--readhead may only be given when creating a new thin Logical volume or snapshot.");
940 if (arg_count(vg
->cmd
, permission_ARG
)) {
941 log_error("--permission may only be given when creating a new thin Logical volume or snapshot.");
944 if (arg_count(vg
->cmd
, persistent_ARG
)) {
945 log_error("--persistent may only be given when creating a new thin Logical volume or snapshot.");
954 * Ensure the set of thin parameters extracted from the command line is consistent.
956 static int _validate_internal_thin_processing(const struct lvcreate_params
*lp
)
961 The final state should be one of:
962 thin create_thin_pool snapshot origin pool
963 1 1 0 0 y/n - create new pool and a thin LV in it
964 1 0 0 0 y - create new thin LV in existing pool
965 0 1 0 0 y/n - create new pool only
966 1 0 1 1 y - create thin snapshot of existing thin LV
969 if (!lp
->create_thin_pool
&& !lp
->pool
) {
970 log_error(INTERNAL_ERROR
"--thinpool not identified.");
974 if ((lp
->snapshot
&& !lp
->origin
) || (!lp
->snapshot
&& lp
->origin
)) {
975 log_error(INTERNAL_ERROR
"Inconsistent snapshot and origin parameters identified.");
979 if (lp
->snapshot
&& (lp
->create_thin_pool
|| !lp
->thin
)) {
980 log_error(INTERNAL_ERROR
"Inconsistent thin and snapshot parameters identified.");
984 if (!lp
->thin
&& !lp
->create_thin_pool
) {
985 log_error(INTERNAL_ERROR
"Failed to identify what type of thin target to use.");
989 if (seg_is_thin_pool(lp
) && lp
->thin
) {
990 log_error(INTERNAL_ERROR
"Thin volume cannot be created with thin pool segment type.");
997 int lvcreate(struct cmd_context
*cmd
, int argc
, char **argv
)
999 int r
= ECMD_PROCESSED
;
1000 struct lvcreate_params lp
;
1001 struct lvcreate_cmdline_params lcp
;
1002 struct volume_group
*vg
;
1004 if (!_lvcreate_params(&lp
, &lcp
, cmd
, argc
, argv
))
1005 return EINVALID_CMD_LINE
;
1007 log_verbose("Finding volume group \"%s\"", lp
.vg_name
);
1008 vg
= vg_read_for_update(cmd
, lp
.vg_name
, NULL
, 0);
1009 if (vg_read_error(vg
)) {
1015 if (lp
.snapshot
&& lp
.origin
&& !_determine_snapshot_type(vg
, &lp
)) {
1020 if (seg_is_thin(&lp
) && !_check_thin_parameters(vg
, &lp
, &lcp
)) {
1026 * Check activation parameters to support inactive thin snapshot creation
1027 * FIXME: anything else needs to be moved past _determine_snapshot_type()?
1029 if (!_read_activation_params(&lp
, cmd
)) {
1034 if (!_update_extents_params(vg
, &lp
, &lcp
)) {
1039 if (seg_is_thin(&lp
) && !_validate_internal_thin_processing(&lp
)) {
1044 if (lp
.create_thin_pool
)
1045 log_verbose("Making thin pool %s in VG %s using segtype %s",
1046 lp
.pool
? : "with generated name", lp
.vg_name
, lp
.segtype
->name
);
1049 log_verbose("Making thin LV %s in pool %s in VG %s%s%s using segtype %s",
1050 lp
.lv_name
? : "with generated name",
1051 lp
.pool
? : "with generated name", lp
.vg_name
,
1052 lp
.snapshot
? " as snapshot of " : "",
1053 lp
.snapshot
? lp
.origin
: "", lp
.segtype
->name
);
1055 if (!lv_create_single(vg
, &lp
)) {
1060 unlock_and_release_vg(cmd
, vg
, lp
.vg_name
);