]> sourceware.org Git - lvm2.git/blob - tools/lvcreate.c
thin: tighten discard string conversions
[lvm2.git] / tools / lvcreate.c
1 /*
2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
4 *
5 * This file is part of LVM2.
6 *
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.
10 *
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
14 */
15
16 #include "tools.h"
17 #include "lv_alloc.h"
18
19 #include <fcntl.h>
20
21 struct lvcreate_cmdline_params {
22 percent_type_t percent;
23 uint64_t size;
24 char **pvs;
25 int pv_count;
26 };
27
28 static int _set_vg_name(struct lvcreate_params *lp, const char *vg_name)
29 {
30 /* Can't do anything */
31 if (!vg_name)
32 return 1;
33
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);
39 return 0;
40 }
41 lp->vg_name = vg_name;
42
43 return 1;
44 }
45
46 static int _lvcreate_name_params(struct lvcreate_params *lp,
47 struct cmd_context *cmd,
48 int *pargc, char ***pargv)
49 {
50 int argc = *pargc;
51 char **argv = *pargv, *ptr;
52 const char *vg_name;
53
54 lp->pool = arg_str_value(cmd, thinpool_ARG, NULL);
55
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)))
59 return 0;
60 /* Strip VG from pool */
61 if ((ptr = strrchr(lp->pool, (int) '/')))
62 lp->pool = ptr + 1;
63 }
64
65 lp->lv_name = arg_str_value(cmd, name_ARG, NULL);
66
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)))
70 return_0;
71
72 /* Strip VG from lv_name */
73 if ((ptr = strrchr(lp->lv_name, (int) '/')))
74 lp->lv_name = ptr + 1;
75 }
76
77 /* Need an origin? */
78 if (lp->snapshot && !arg_count(cmd, virtualsize_ARG)) {
79 /* argv[0] might be origin or vg/origin */
80 if (!argc) {
81 log_error("Please specify a logical volume to act as "
82 "the snapshot origin.");
83 return 0;
84 }
85
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)))
89 return_0;
90
91 /* Strip the volume group from the origin */
92 if ((ptr = strrchr(lp->origin, (int) '/')))
93 lp->origin = ptr + 1;
94 }
95
96 if (!lp->vg_name &&
97 !_set_vg_name(lp, extract_vgname(cmd, NULL)))
98 return_0;
99
100 if (!lp->vg_name) {
101 log_error("The origin name should include the "
102 "volume group.");
103 return 0;
104 }
105
106 (*pargv)++, (*pargc)--;
107 } else if (seg_is_thin(lp) && !lp->pool && argc) {
108 /* argv[0] might be vg or vg/Pool */
109
110 vg_name = skip_dev_dir(cmd, argv[0], NULL);
111 if (!strrchr(vg_name, '/')) {
112 if (!_set_vg_name(lp, vg_name))
113 return_0;
114 } else {
115 lp->pool = vg_name;
116 if (!_set_vg_name(lp, extract_vgname(cmd, lp->pool)))
117 return_0;
118
119 if (!lp->vg_name &&
120 !_set_vg_name(lp, extract_vgname(cmd, NULL)))
121 return_0;
122
123 if (!lp->vg_name) {
124 log_error("The pool name should include the "
125 "volume group.");
126 return 0;
127 }
128
129 /* Strip the volume group */
130 if ((ptr = strrchr(lp->pool, (int) '/')))
131 lp->pool = ptr + 1;
132 }
133
134 (*pargv)++, (*pargc)--;
135 } else {
136 /*
137 * If VG not on command line, try environment default.
138 */
139 if (!argc) {
140 if (!lp->vg_name && !(lp->vg_name = extract_vgname(cmd, NULL))) {
141 log_error("Please provide a volume group name");
142 return 0;
143 }
144 } else {
145 vg_name = skip_dev_dir(cmd, argv[0], NULL);
146 if (strrchr(vg_name, '/')) {
147 log_error("Volume group name expected "
148 "(no slash)");
149 return 0;
150 }
151
152 if (!_set_vg_name(lp, vg_name))
153 return_0;
154
155 (*pargv)++, (*pargc)--;
156 }
157 }
158
159 if (!validate_name(lp->vg_name)) {
160 log_error("Volume group name %s has invalid characters",
161 lp->vg_name);
162 return 0;
163 }
164
165 if (lp->lv_name) {
166 if (!apply_lvname_restrictions(lp->lv_name))
167 return_0;
168
169 if (!validate_name(lp->lv_name)) {
170 log_error("Logical volume name \"%s\" is invalid",
171 lp->lv_name);
172 return 0;
173 }
174 }
175
176 if (lp->pool) {
177 if (!apply_lvname_restrictions(lp->pool))
178 return_0;
179
180 if (!validate_name(lp->pool)) {
181 log_error("Logical volume name \"%s\" is invalid",
182 lp->pool);
183 return 0;
184 }
185
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);
189 return 0;
190 }
191 }
192
193 return 1;
194 }
195
196 /*
197 * Normal snapshot or thinly-provisioned snapshot?
198 */
199 static int _determine_snapshot_type(struct volume_group *vg,
200 struct lvcreate_params *lp)
201 {
202 struct lv_list *lvl;
203
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);
207 return 0;
208 }
209
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.");
213 return 0;
214 }
215
216 lp->thin = 1;
217 if (!(lp->segtype = get_segtype_from_string(vg->cmd, "thin")))
218 return_0;
219
220 lp->pool = first_seg(lvl->lv)->pool_lv->name;
221 }
222
223 return 1;
224 }
225
226 /*
227 * Update extents parameters based on other parameters which affect the size
228 * calculation.
229 * NOTE: We must do this here because of the percent_t typedef and because we
230 * need the vg.
231 */
232 static int _update_extents_params(struct volume_group *vg,
233 struct lvcreate_params *lp,
234 struct lvcreate_cmdline_params *lcp)
235 {
236 uint32_t pv_extent_count;
237 struct logical_volume *origin = NULL;
238 int changed = 0;
239 uint32_t size_rest;
240 uint32_t stripesize_extents;
241
242 if (lcp->size &&
243 !(lp->extents = extents_from_size(vg->cmd, lcp->size,
244 vg->extent_size)))
245 return_0;
246
247 if (lp->voriginsize &&
248 !(lp->voriginextents = extents_from_size(vg->cmd, lp->voriginsize,
249 vg->extent_size)))
250 return_0;
251
252 /*
253 * Create the pv list before we parse lcp->percent - might be
254 * PERCENT_PVSs
255 */
256 if (lcp->pv_count) {
257 if (!(lp->pvh = create_pv_list(vg->cmd->mem, vg,
258 lcp->pv_count, lcp->pvs, 1)))
259 return_0;
260 } else
261 lp->pvh = &vg->pvs;
262
263 switch(lcp->percent) {
264 case PERCENT_VG:
265 lp->extents = percent_of_extents(lp->extents, vg->extent_count, 0);
266 break;
267 case PERCENT_FREE:
268 lp->extents = percent_of_extents(lp->extents, vg->free_count, 0);
269 break;
270 case PERCENT_PVS:
271 if (!lcp->pv_count)
272 lp->extents = percent_of_extents(lp->extents, vg->extent_count, 0);
273 else {
274 pv_extent_count = pv_list_extents_free(lp->pvh);
275 lp->extents = percent_of_extents(lp->extents, pv_extent_count, 0);
276 }
277 break;
278 case PERCENT_LV:
279 log_error("Please express size as %%VG, %%PVS, or "
280 "%%FREE.");
281 return 0;
282 case PERCENT_ORIGIN:
283 if (lp->snapshot && lp->origin &&
284 !(origin = find_lv(vg, lp->origin))) {
285 log_error("Couldn't find origin volume '%s'.",
286 lp->origin);
287 return 0;
288 }
289 if (!origin) {
290 log_error(INTERNAL_ERROR "Couldn't find origin volume.");
291 return 0;
292 }
293 lp->extents = percent_of_extents(lp->extents, origin->le_count, 0);
294 break;
295 case PERCENT_NONE:
296 break;
297 }
298
299 if (!(stripesize_extents = lp->stripe_size / vg->extent_size))
300 stripesize_extents = 1;
301
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;
309 }
310
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)));
316
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;
324 changed++;
325 }
326 if (changed)
327 log_verbose("Changed chunksize to %u sectors.",
328 lp->chunk_size);
329 }
330 }
331
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;
340 }
341
342 log_verbose("Setting pool metadata size to %" PRIu64 " sectors.",
343 lp->poolmetadatasize);
344
345 if (!(lp->poolmetadataextents =
346 extents_from_size(vg->cmd, lp->poolmetadatasize, vg->extent_size)))
347 return_0;
348 }
349
350 return 1;
351 }
352
353 static int _read_size_params(struct lvcreate_params *lp,
354 struct lvcreate_cmdline_params *lcp,
355 struct cmd_context *cmd)
356 {
357 if (arg_count(cmd, extents_ARG) && arg_count(cmd, size_ARG)) {
358 log_error("Please specify either size or extents (not both)");
359 return 0;
360 }
361
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");
364 return 0;
365 }
366
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");
370 return 0;
371 }
372 lp->extents = arg_uint_value(cmd, extents_ARG, 0);
373 lcp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
374 }
375
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");
380 return 0;
381 }
382 lcp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0));
383 lcp->percent = PERCENT_NONE;
384 }
385
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;
389
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.");
393 return 0;
394 }
395 if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
396 log_error("Negative poolmetadatasize is invalid.");
397 return 0;
398 }
399 lp->poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, UINT64_C(0));
400 }
401
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.");
406 return 0;
407 }
408 if (arg_sign_value(cmd, virtualsize_ARG, SIGN_NONE) == SIGN_MINUS) {
409 log_error("Negative virtual origin size is invalid");
410 return 0;
411 }
412 lp->voriginsize = arg_uint64_value(cmd, virtualsize_ARG,
413 UINT64_C(0));
414 if (!lp->voriginsize) {
415 log_error("Virtual origin size may not be zero");
416 return 0;
417 }
418 } else {
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")))
421 return_0;
422
423 lp->thin = 0;
424 }
425
426 return 1;
427 }
428
429 /*
430 * Generic mirror parameter checks.
431 * FIXME: Should eventually be moved into lvm library.
432 */
433 static int _validate_mirror_params(const struct cmd_context *cmd __attribute__((unused)),
434 const struct lvcreate_params *lp)
435 {
436 int pagesize = lvm_getpagesize();
437
438 if (lp->region_size & (lp->region_size - 1)) {
439 log_error("Region size (%" PRIu32 ") must be a power of 2",
440 lp->region_size);
441 return 0;
442 }
443
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);
448 return 0;
449 }
450
451 if (!lp->region_size) {
452 log_error("Non-zero region size must be supplied.");
453 return 0;
454 }
455
456 return 1;
457 }
458
459 static int _read_mirror_params(struct lvcreate_params *lp,
460 struct cmd_context *cmd)
461 {
462 int region_size;
463 const char *mirrorlog;
464 int corelog = arg_count(cmd, corelog_ARG);
465
466 mirrorlog = arg_str_value(cmd, mirrorlog_ARG,
467 corelog ? "core" : DEFAULT_MIRRORLOG);
468
469 if (strcmp("core", mirrorlog) && corelog) {
470 log_error("Please use only one of --mirrorlog or --corelog");
471 return 0;
472 }
473
474 if (!strcmp("mirrored", mirrorlog)) {
475 lp->log_count = 2;
476 } else if (!strcmp("disk", mirrorlog)) {
477 lp->log_count = 1;
478 } else if (!strcmp("core", mirrorlog))
479 lp->log_count = 0;
480 else {
481 log_error("Unknown mirrorlog type: %s", mirrorlog);
482 return 0;
483 }
484
485 log_verbose("Setting logging type to %s", mirrorlog);
486
487 lp->nosync = arg_is_set(cmd, nosync_ARG);
488
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");
492 return 0;
493 }
494 lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
495 } else {
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 "
501 "is invalid");
502 return 0;
503 }
504 lp->region_size = region_size;
505 }
506
507 if (!_validate_mirror_params(cmd, lp))
508 return 0;
509
510 return 1;
511 }
512
513 static int _read_raid_params(struct lvcreate_params *lp,
514 struct cmd_context *cmd)
515 {
516 if (!segtype_is_raid(lp->segtype))
517 return 1;
518
519 if (arg_count(cmd, corelog_ARG) ||
520 arg_count(cmd, mirrorlog_ARG)) {
521 log_error("Log options not applicable to %s segtype",
522 lp->segtype->name);
523 return 0;
524 }
525
526 /*
527 * get_stripe_params is called before _read_raid_params
528 * and already sets:
529 * lp->stripes
530 * lp->stripe_size
531 *
532 * For RAID 4/5/6, these values must be set.
533 */
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);
538 return 0;
539 }
540
541 /*
542 * _read_mirror_params is called before _read_raid_params
543 * and already sets:
544 * lp->nosync
545 * lp->region_size
546 *
547 * But let's ensure that programmers don't reorder
548 * that by checking and warning if they aren't set.
549 */
550 if (!lp->region_size) {
551 log_error(INTERNAL_ERROR "region_size not set.");
552 return 0;
553 }
554
555 return 1;
556 }
557
558 static int _read_activation_params(struct lvcreate_params *lp, struct cmd_context *cmd,
559 struct volume_group *vg)
560 {
561 unsigned pagesize;
562
563 lp->activate = (activation_change_t)
564 arg_uint_value(cmd, activate_ARG, CHANGE_AY);
565
566 if (lp->activate == CHANGE_AN || lp->activate == CHANGE_ALN) {
567 if (lp->zero && !seg_is_thin(lp)) {
568 log_error("--activate n requires --zero n");
569 return 0;
570 }
571 } else if (lp->activate == CHANGE_AAY) {
572 if (arg_count(cmd, zero_ARG)) {
573 log_error("-Z is incompatible with --activate a");
574 return 0;
575 }
576 lp->zero = 0;
577 }
578
579 /*
580 * Read ahead.
581 */
582 lp->read_ahead = arg_uint_value(cmd, readahead_ARG,
583 cmd->default_settings.read_ahead);
584 pagesize = lvm_getpagesize() >> SECTOR_SHIFT;
585 if (lp->read_ahead != DM_READ_AHEAD_AUTO &&
586 lp->read_ahead != DM_READ_AHEAD_NONE &&
587 lp->read_ahead % pagesize) {
588 if (lp->read_ahead < pagesize)
589 lp->read_ahead = pagesize;
590 else
591 lp->read_ahead = (lp->read_ahead / pagesize) * pagesize;
592 log_warn("WARNING: Overriding readahead to %u sectors, a multiple "
593 "of %uK page size.", lp->read_ahead, pagesize >> 1);
594 }
595
596 /*
597 * Permissions.
598 */
599 lp->permission = arg_uint_value(cmd, permission_ARG,
600 LVM_READ | LVM_WRITE);
601
602 if (lp->thin && !(lp->permission & LVM_WRITE)) {
603 log_error("Read-only thin volumes are not currently supported.");
604 return 0;
605 }
606
607 /* Must not zero read only volume */
608 if (!(lp->permission & LVM_WRITE))
609 lp->zero = 0;
610
611 if (arg_count(cmd, major_ARG) > 1) {
612 log_error("Option -j/--major may not be repeated.");
613 return 0;
614 }
615
616 if (arg_count(cmd, minor_ARG) > 1) {
617 log_error("Option --minor may not be repeated.");
618 return 0;
619 }
620
621 lp->minor = arg_int_value(cmd, minor_ARG, -1);
622 lp->major = arg_int_value(cmd, major_ARG, -1);
623
624 /* Persistent minor */
625 if (arg_count(cmd, persistent_ARG)) {
626 if (lp->create_thin_pool && !lp->thin) {
627 log_error("--persistent is not permitted when creating a thin pool device.");
628 return 0;
629 }
630 if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "y")) {
631 if (lp->minor == -1) {
632 log_error("Please specify minor number with "
633 "--minor when using -My");
634 return 0;
635 }
636 if (lp->major == -1) {
637 log_error("Please specify major number with "
638 "--major when using -My");
639 return 0;
640 }
641 if (!major_minor_valid(cmd, vg->fid->fmt, lp->major, lp->minor))
642 return 0;
643 } else {
644 if ((lp->minor != -1) || (lp->major != -1)) {
645 log_error("--major and --minor incompatible "
646 "with -Mn");
647 return 0;
648 }
649 }
650 } else if (arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) {
651 log_error("--major and --minor require -My");
652 return 0;
653 }
654
655 return 1;
656 }
657
658 static int _lvcreate_params(struct lvcreate_params *lp,
659 struct lvcreate_cmdline_params *lcp,
660 struct cmd_context *cmd,
661 int argc, char **argv)
662 {
663 int contiguous;
664 struct arg_value_group_list *current_group;
665 const char *segtype_str;
666 const char *tag;
667
668 memset(lp, 0, sizeof(*lp));
669 memset(lcp, 0, sizeof(*lcp));
670 dm_list_init(&lp->tags);
671
672 /*
673 * Check selected options are compatible and determine segtype
674 */
675 // FIXME -m0 implies *striped*
676 if (arg_count(cmd, thin_ARG) && arg_count(cmd,mirrors_ARG)) {
677 log_error("--thin and --mirrors are incompatible.");
678 return 0;
679 }
680
681 // FIXME -m0 implies *striped*
682
683 /* Set default segtype */
684 if (arg_count(cmd, mirrors_ARG))
685 segtype_str = find_config_tree_str(cmd, "global/mirror_segtype_default", DEFAULT_MIRROR_SEGTYPE);
686 else if (arg_count(cmd, thin_ARG) || arg_count(cmd, thinpool_ARG))
687 segtype_str = "thin";
688 else
689 segtype_str = "striped";
690
691 segtype_str = arg_str_value(cmd, type_ARG, segtype_str);
692
693 if (!(lp->segtype = get_segtype_from_string(cmd, segtype_str)))
694 return_0;
695
696 if (seg_unknown(lp)) {
697 log_error("Unable to create LV with unknown segment type %s.", segtype_str);
698 return 0;
699 }
700
701 if (arg_count(cmd, snapshot_ARG) || seg_is_snapshot(lp) ||
702 (!seg_is_thin(lp) && arg_count(cmd, virtualsize_ARG)))
703 lp->snapshot = 1;
704
705 if (seg_is_thin_pool(lp)) {
706 if (lp->snapshot) {
707 log_error("Snapshots are incompatible with thin_pool segment_type.");
708 return 0;
709 }
710 lp->create_thin_pool = 1;
711 }
712
713 if (seg_is_thin_volume(lp))
714 lp->thin = 1;
715
716 lp->mirrors = 1;
717
718 /* Default to 2 mirrored areas if '--type mirror|raid1' */
719 if (segtype_is_mirrored(lp->segtype))
720 lp->mirrors = 2;
721
722 if (arg_count(cmd, mirrors_ARG)) {
723 lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
724 if (lp->mirrors == 1) {
725 if (segtype_is_mirrored(lp->segtype)) {
726 log_error("--mirrors must be at least 1 with segment type %s.", lp->segtype->name);
727 return 0;
728 }
729 log_print("Redundant mirrors argument: default is 0");
730 }
731 if (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS) {
732 log_error("Mirrors argument may not be negative");
733 return 0;
734 }
735 }
736
737 if (lp->snapshot && arg_count(cmd, zero_ARG)) {
738 log_error("-Z is incompatible with snapshots");
739 return 0;
740 }
741
742 if (segtype_is_mirrored(lp->segtype) || segtype_is_raid(lp->segtype)) {
743 if (lp->snapshot) {
744 log_error("mirrors and snapshots are currently "
745 "incompatible");
746 return 0;
747 }
748 } else {
749 if (arg_count(cmd, corelog_ARG)) {
750 log_error("--corelog is only available with mirrors");
751 return 0;
752 }
753
754 if (arg_count(cmd, mirrorlog_ARG)) {
755 log_error("--mirrorlog is only available with mirrors");
756 return 0;
757 }
758
759 if (arg_count(cmd, nosync_ARG)) {
760 log_error("--nosync is only available with mirrors");
761 return 0;
762 }
763 }
764
765 if (activation() && lp->segtype->ops->target_present &&
766 !lp->segtype->ops->target_present(cmd, NULL, NULL)) {
767 log_error("%s: Required device-mapper target(s) not "
768 "detected in your kernel", lp->segtype->name);
769 return 0;
770 }
771
772 if (!_lvcreate_name_params(lp, cmd, &argc, &argv) ||
773 !_read_size_params(lp, lcp, cmd) ||
774 !get_stripe_params(cmd, &lp->stripes, &lp->stripe_size) ||
775 !_read_mirror_params(lp, cmd) ||
776 !_read_raid_params(lp, cmd))
777 return_0;
778
779 if (lp->snapshot && lp->thin && arg_count(cmd, chunksize_ARG))
780 log_warn("WARNING: Ignoring --chunksize with thin snapshots.");
781 else if (lp->thin && !lp->create_thin_pool) {
782 if (arg_count(cmd, chunksize_ARG))
783 log_warn("WARNING: Ignoring --chunksize when using an existing pool.");
784 } else if (lp->snapshot || lp->create_thin_pool) {
785 if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
786 log_error("Negative chunk size is invalid");
787 return 0;
788 }
789 if (lp->snapshot) {
790 lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
791 if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
792 (lp->chunk_size & (lp->chunk_size - 1))) {
793 log_error("Chunk size must be a power of 2 in the "
794 "range 4K to 512K");
795 return 0;
796 }
797 } else {
798 lp->chunk_size = arg_uint_value(cmd, chunksize_ARG,
799 DM_THIN_MIN_DATA_BLOCK_SIZE);
800 if ((lp->chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ||
801 (lp->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE) ||
802 (lp->chunk_size & (lp->chunk_size - 1))) {
803 log_error("Chunk size must be a power of 2 in the "
804 "range %uK to %uK",
805 (DM_THIN_MIN_DATA_BLOCK_SIZE / 2),
806 (DM_THIN_MAX_DATA_BLOCK_SIZE / 2));
807 return 0;
808 }
809 }
810 log_verbose("Setting chunksize to %u sectors.", lp->chunk_size);
811
812 if (!lp->thin && lp->snapshot && !(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
813 return_0;
814 } else {
815 if (arg_count(cmd, chunksize_ARG)) {
816 log_error("-c is only available with snapshots and thin pools");
817 return 0;
818 }
819 }
820
821 /*
822 * Should we zero the lv.
823 */
824 lp->zero = strcmp(arg_str_value(cmd, zero_ARG,
825 (lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n");
826
827 if (lp->mirrors > DEFAULT_MIRROR_MAX_IMAGES) {
828 log_error("Only up to %d images in mirror supported currently.",
829 DEFAULT_MIRROR_MAX_IMAGES);
830 return 0;
831 }
832
833 /*
834 * Allocation parameters
835 */
836 contiguous = strcmp(arg_str_value(cmd, contiguous_ARG, "n"), "n");
837
838 lp->alloc = contiguous ? ALLOC_CONTIGUOUS : ALLOC_INHERIT;
839
840 lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, lp->alloc);
841
842 if (contiguous && (lp->alloc != ALLOC_CONTIGUOUS)) {
843 log_error("Conflicting contiguous and alloc arguments");
844 return 0;
845 }
846
847 dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
848 if (!grouped_arg_is_set(current_group->arg_values, addtag_ARG))
849 continue;
850
851 if (!(tag = grouped_arg_str_value(current_group->arg_values, addtag_ARG, NULL))) {
852 log_error("Failed to get tag");
853 return 0;
854 }
855
856 if (!str_list_add(cmd->mem, &lp->tags, tag)) {
857 log_error("Unable to allocate memory for tag %s", tag);
858 return 0;
859 }
860 }
861
862 lcp->pv_count = argc;
863 lcp->pvs = argv;
864
865 return 1;
866 }
867
868 static int _check_thin_parameters(struct volume_group *vg, struct lvcreate_params *lp,
869 struct lvcreate_cmdline_params *lcp)
870 {
871 struct lv_list *lvl;
872
873 if (!lp->thin && !lp->create_thin_pool) {
874 log_error("Please specify device size(s).");
875 return 0;
876 }
877
878 if (lp->thin && !lp->create_thin_pool) {
879 if (arg_count(vg->cmd, chunksize_ARG)) {
880 log_error("Only specify --chunksize when originally creating the thin pool.");
881 return 0;
882 }
883
884 if (lcp->pv_count) {
885 log_error("Only specify Physical volumes when allocating the thin pool.");
886 return 0;
887 }
888
889 if (arg_count(vg->cmd, alloc_ARG)) {
890 log_error("--alloc may only be specified when allocating the thin pool.");
891 return 0;
892 }
893
894 if (arg_count(vg->cmd, poolmetadatasize_ARG)) {
895 log_error("--poolmetadatasize may only be specified when allocating the thin pool.");
896 return 0;
897 }
898
899 if (arg_count(vg->cmd, stripesize_ARG)) {
900 log_error("--stripesize may only be specified when allocating the thin pool.");
901 return 0;
902 }
903
904 if (arg_count(vg->cmd, stripes_ARG)) {
905 log_error("--stripes may only be specified when allocating the thin pool.");
906 return 0;
907 }
908
909 if (arg_count(vg->cmd, contiguous_ARG)) {
910 log_error("--contiguous may only be specified when allocating the thin pool.");
911 return 0;
912 }
913
914 if (arg_count(vg->cmd, zero_ARG)) {
915 log_error("--zero may only be specified when allocating the thin pool.");
916 return 0;
917 }
918 }
919
920 if (lp->create_thin_pool && lp->pool) {
921 if (find_lv_in_vg(vg, lp->pool)) {
922 log_error("Pool %s already exists in Volume group %s.", lp->pool, vg->name);
923 return 0;
924 }
925 } else if (lp->pool) {
926 if (!(lvl = find_lv_in_vg(vg, lp->pool))) {
927 log_error("Pool %s not found in Volume group %s.", lp->pool, vg->name);
928 return 0;
929 }
930 if (!lv_is_thin_pool(lvl->lv)) {
931 log_error("Logical volume %s is not a thin pool.", lp->pool);
932 return 0;
933 }
934 } else if (!lp->create_thin_pool) {
935 log_error("Please specify name of existing pool.");
936 return 0;
937 }
938
939 if (!lp->thin && lp->lv_name) {
940 log_error("--name may only be given when creating a new thin Logical volume or snapshot.");
941 return 0;
942 }
943
944 if (!lp->thin) {
945 if (arg_count(vg->cmd, readahead_ARG)) {
946 log_error("--readhead may only be given when creating a new thin Logical volume or snapshot.");
947 return 0;
948 }
949 if (arg_count(vg->cmd, permission_ARG)) {
950 log_error("--permission may only be given when creating a new thin Logical volume or snapshot.");
951 return 0;
952 }
953 if (arg_count(vg->cmd, persistent_ARG)) {
954 log_error("--persistent may only be given when creating a new thin Logical volume or snapshot.");
955 return 0;
956 }
957 }
958
959 return 1;
960 }
961
962 /*
963 * Ensure the set of thin parameters extracted from the command line is consistent.
964 */
965 static int _validate_internal_thin_processing(const struct lvcreate_params *lp)
966 {
967 int r = 1;
968
969 /*
970 The final state should be one of:
971 thin create_thin_pool snapshot origin pool
972 1 1 0 0 y/n - create new pool and a thin LV in it
973 1 0 0 0 y - create new thin LV in existing pool
974 0 1 0 0 y/n - create new pool only
975 1 0 1 1 y - create thin snapshot of existing thin LV
976 */
977
978 if (!lp->create_thin_pool && !lp->pool) {
979 log_error(INTERNAL_ERROR "--thinpool not identified.");
980 r = 0;
981 }
982
983 if ((lp->snapshot && !lp->origin) || (!lp->snapshot && lp->origin)) {
984 log_error(INTERNAL_ERROR "Inconsistent snapshot and origin parameters identified.");
985 r = 0;
986 }
987
988 if (lp->snapshot && (lp->create_thin_pool || !lp->thin)) {
989 log_error(INTERNAL_ERROR "Inconsistent thin and snapshot parameters identified.");
990 r = 0;
991 }
992
993 if (!lp->thin && !lp->create_thin_pool) {
994 log_error(INTERNAL_ERROR "Failed to identify what type of thin target to use.");
995 r = 0;
996 }
997
998 if (seg_is_thin_pool(lp) && lp->thin) {
999 log_error(INTERNAL_ERROR "Thin volume cannot be created with thin pool segment type.");
1000 r = 0;
1001 }
1002
1003 return r;
1004 }
1005
1006 int lvcreate(struct cmd_context *cmd, int argc, char **argv)
1007 {
1008 int r = ECMD_PROCESSED;
1009 struct lvcreate_params lp;
1010 struct lvcreate_cmdline_params lcp;
1011 struct volume_group *vg;
1012
1013 if (!_lvcreate_params(&lp, &lcp, cmd, argc, argv))
1014 return EINVALID_CMD_LINE;
1015
1016 log_verbose("Finding volume group \"%s\"", lp.vg_name);
1017 vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0);
1018 if (vg_read_error(vg)) {
1019 release_vg(vg);
1020 stack;
1021 return ECMD_FAILED;
1022 }
1023
1024 if (lp.snapshot && lp.origin && !_determine_snapshot_type(vg, &lp)) {
1025 r = ECMD_FAILED;
1026 goto_out;
1027 }
1028
1029 if (seg_is_thin(&lp) && !_check_thin_parameters(vg, &lp, &lcp)) {
1030 r = ECMD_FAILED;
1031 goto_out;
1032 }
1033
1034 /*
1035 * Check activation parameters to support inactive thin snapshot creation
1036 * FIXME: anything else needs to be moved past _determine_snapshot_type()?
1037 */
1038 if (!_read_activation_params(&lp, cmd, vg)) {
1039 r = ECMD_FAILED;
1040 goto_out;
1041 }
1042
1043 if (!_update_extents_params(vg, &lp, &lcp)) {
1044 r = ECMD_FAILED;
1045 goto_out;
1046 }
1047
1048 if (seg_is_thin(&lp) && !_validate_internal_thin_processing(&lp)) {
1049 r = ECMD_FAILED;
1050 goto_out;
1051 }
1052
1053 if (lp.create_thin_pool)
1054 log_verbose("Making thin pool %s in VG %s using segtype %s",
1055 lp.pool ? : "with generated name", lp.vg_name, lp.segtype->name);
1056
1057 if (lp.thin)
1058 log_verbose("Making thin LV %s in pool %s in VG %s%s%s using segtype %s",
1059 lp.lv_name ? : "with generated name",
1060 lp.pool ? : "with generated name", lp.vg_name,
1061 lp.snapshot ? " as snapshot of " : "",
1062 lp.snapshot ? lp.origin : "", lp.segtype->name);
1063
1064 if (!lv_create_single(vg, &lp)) {
1065 stack;
1066 r = ECMD_FAILED;
1067 }
1068 out:
1069 unlock_and_release_vg(cmd, vg, lp.vg_name);
1070 return r;
1071 }
This page took 0.083856 seconds and 5 git commands to generate.