]> sourceware.org Git - lvm2.git/blame - tools/lvcreate.c
pre-release
[lvm2.git] / tools / lvcreate.c
CommitLineData
642c2e96 1/*
67cdbd7e 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
9ac61d2b 3 * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
642c2e96 4 *
6606c3ae 5 * This file is part of LVM2.
642c2e96 6 *
6606c3ae
AK
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
be684599 9 * of the GNU Lesser General Public License v.2.1.
6606c3ae 10 *
be684599 11 * You should have received a copy of the GNU Lesser General Public License
6606c3ae
AK
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
642c2e96
AK
14 */
15
16#include "tools.h"
60f13f01 17#include "lv_alloc.h"
cc219483 18
fe827798 19#include <fcntl.h>
642c2e96 20
8842d526 21struct lvcreate_cmdline_params {
8191fe4f 22 percent_type_t percent;
7a0b0db1 23 uint64_t size;
e6479dff
DW
24 char **pvs;
25 int pv_count;
8842d526
DW
26};
27
9ac61d2b
AK
28static 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
8a2fc586
AK
46static int _lvcreate_name_params(struct lvcreate_params *lp,
47 struct cmd_context *cmd,
48 int *pargc, char ***pargv)
052360e9
JT
49{
50 int argc = *pargc;
51 char **argv = *pargv, *ptr;
aec21154 52 const char *vg_name;
052360e9 53
9ac61d2b
AK
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
a8fb89ad 65 lp->lv_name = arg_str_value(cmd, name_ARG, NULL);
052360e9 66
9ac61d2b
AK
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? */
154753db 78 if (lp->snapshot && !arg_count(cmd, virtualsize_ARG)) {
9ac61d2b 79 /* argv[0] might be origin or vg/origin */
052360e9 80 if (!argc) {
b8f47d5f
AK
81 log_error("Please specify a logical volume to act as "
82 "the snapshot origin.");
052360e9
JT
83 return 0;
84 }
85
9ac61d2b
AK
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
24d39aa1
ZK
96 if (!lp->vg_name &&
97 !_set_vg_name(lp, extract_vgname(cmd, NULL)))
98 return_0;
e903e37d 99
9ac61d2b 100 if (!lp->vg_name) {
b8f47d5f
AK
101 log_error("The origin name should include the "
102 "volume group.");
052360e9
JT
103 return 0;
104 }
105
9ac61d2b
AK
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;
e903e37d 118
24d39aa1
ZK
119 if (!lp->vg_name &&
120 !_set_vg_name(lp, extract_vgname(cmd, NULL)))
121 return_0;
e903e37d 122
9ac61d2b
AK
123 if (!lp->vg_name) {
124 log_error("The pool name should include the "
125 "volume group.");
126 return 0;
127 }
0eb83127 128
9ac61d2b
AK
129 /* Strip the volume group */
130 if ((ptr = strrchr(lp->pool, (int) '/')))
131 lp->pool = ptr + 1;
132 }
133
134 (*pargv)++, (*pargc)--;
052360e9
JT
135 } else {
136 /*
9ac61d2b 137 * If VG not on command line, try environment default.
052360e9
JT
138 */
139 if (!argc) {
9ac61d2b 140 if (!lp->vg_name && !(lp->vg_name = extract_vgname(cmd, NULL))) {
b8f47d5f 141 log_error("Please provide a volume group name");
052360e9
JT
142 return 0;
143 }
052360e9 144 } else {
9397354a 145 vg_name = skip_dev_dir(cmd, argv[0], NULL);
cb8920e6 146 if (strrchr(vg_name, '/')) {
fdf8038f
AK
147 log_error("Volume group name expected "
148 "(no slash)");
149 return 0;
150 }
151
9ac61d2b
AK
152 if (!_set_vg_name(lp, vg_name))
153 return_0;
052360e9 154
052360e9
JT
155 (*pargv)++, (*pargc)--;
156 }
642c2e96
AK
157 }
158
d38bf361
AK
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
b8c919b4 165 if (lp->lv_name) {
c51b9fff
AK
166 if (!apply_lvname_restrictions(lp->lv_name))
167 return_0;
5a52dca9 168
b8c919b4 169 if (!validate_name(lp->lv_name)) {
8387b473
AK
170 log_error("Logical volume name \"%s\" is invalid",
171 lp->lv_name);
b8c919b4
AK
172 return 0;
173 }
7e4867f7
AK
174 }
175
9ac61d2b
AK
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 */
199static int _determine_snapshot_type(struct volume_group *vg,
200 struct lvcreate_params *lp)
201{
202 struct lv_list *lvl;
9ac61d2b
AK
203
204 if (!(lvl = find_lv_in_vg(vg, lp->origin))) {
6e89eb9a
ZK
205 log_error("Snapshot origin LV %s not found in Volume group %s.",
206 lp->origin, vg->name);
9ac61d2b
AK
207 return 0;
208 }
209
95308c5f
ZK
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
9ac61d2b
AK
216 lp->thin = 1;
217 if (!(lp->segtype = get_segtype_from_string(vg->cmd, "thin")))
218 return_0;
219
bb6f9b10 220 lp->pool = first_seg(lvl->lv)->pool_lv->name;
9ac61d2b
AK
221 }
222
052360e9
JT
223 return 1;
224}
225
8675b317
DW
226/*
227 * Update extents parameters based on other parameters which affect the size
6e89eb9a 228 * calculation.
8675b317
DW
229 * NOTE: We must do this here because of the percent_t typedef and because we
230 * need the vg.
231 */
232static int _update_extents_params(struct volume_group *vg,
8842d526
DW
233 struct lvcreate_params *lp,
234 struct lvcreate_cmdline_params *lcp)
8675b317
DW
235{
236 uint32_t pv_extent_count;
5bc2af26 237 struct logical_volume *origin = NULL;
8675b317 238
7a0b0db1 239 if (lcp->size &&
9963d071 240 !(lp->extents = extents_from_size(vg->cmd, lcp->size,
8675b317
DW
241 vg->extent_size)))
242 return_0;
243
244 if (lp->voriginsize &&
9963d071 245 !(lp->voriginextents = extents_from_size(vg->cmd, lp->voriginsize,
8675b317
DW
246 vg->extent_size)))
247 return_0;
248
249 /*
8842d526 250 * Create the pv list before we parse lcp->percent - might be
8675b317
DW
251 * PERCENT_PVSs
252 */
e6479dff 253 if (lcp->pv_count) {
8675b317 254 if (!(lp->pvh = create_pv_list(vg->cmd->mem, vg,
e6479dff 255 lcp->pv_count, lcp->pvs, 1)))
8675b317
DW
256 return_0;
257 } else
258 lp->pvh = &vg->pvs;
259
8842d526 260 switch(lcp->percent) {
8675b317 261 case PERCENT_VG:
4fbde014 262 lp->extents = percent_of_extents(lp->extents, vg->extent_count, 0);
8675b317
DW
263 break;
264 case PERCENT_FREE:
4fbde014 265 lp->extents = percent_of_extents(lp->extents, vg->free_count, 0);
8675b317
DW
266 break;
267 case PERCENT_PVS:
ba3851fd 268 if (!lcp->pv_count)
4fbde014 269 lp->extents = percent_of_extents(lp->extents, vg->extent_count, 0);
ba3851fd
MB
270 else {
271 pv_extent_count = pv_list_extents_free(lp->pvh);
4fbde014 272 lp->extents = percent_of_extents(lp->extents, pv_extent_count, 0);
8675b317 273 }
8675b317
DW
274 break;
275 case PERCENT_LV:
276 log_error("Please express size as %%VG, %%PVS, or "
277 "%%FREE.");
278 return 0;
5bc2af26
MS
279 case PERCENT_ORIGIN:
280 if (lp->snapshot && lp->origin &&
281 !(origin = find_lv(vg, lp->origin))) {
282 log_error("Couldn't find origin volume '%s'.",
283 lp->origin);
284 return 0;
285 }
fc218865
ZK
286 if (!origin) {
287 log_error(INTERNAL_ERROR "Couldn't find origin volume.");
288 return 0;
289 }
4fbde014 290 lp->extents = percent_of_extents(lp->extents, origin->le_count, 0);
5bc2af26 291 break;
8675b317
DW
292 case PERCENT_NONE:
293 break;
294 }
b8cac455 295
79c42c66
ZK
296 if (lp->create_thin_pool) {
297 if (!arg_count(vg->cmd, poolmetadatasize_ARG))
298 /* Defaults to nr_pool_blocks * 64b */
299 lp->poolmetadatasize = (uint64_t) lp->extents * vg->extent_size /
300 (uint64_t) (lp->chunk_size * (SECTOR_SIZE / UINT64_C(64)));
301
302 if (lp->poolmetadatasize > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) {
303 if (arg_count(vg->cmd, poolmetadatasize_ARG))
304 log_warn("WARNING: Maximum supported pool metadata size is 16GB.");
305 lp->poolmetadatasize = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
306 } else if (lp->poolmetadatasize < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) {
307 if (arg_count(vg->cmd, poolmetadatasize_ARG))
308 log_warn("WARNING: Minimum supported pool metadata size is 2M.");
309 lp->poolmetadatasize = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
310 }
311
312 log_verbose("Setting pool metadata size to %" PRIu64 " sectors.",
313 lp->poolmetadatasize);
314
315 if (!(lp->poolmetadataextents =
316 extents_from_size(vg->cmd, lp->poolmetadatasize, vg->extent_size)))
317 return_0;
318 }
b8cac455 319
8675b317
DW
320 return 1;
321}
322
052360e9 323static int _read_size_params(struct lvcreate_params *lp,
8842d526 324 struct lvcreate_cmdline_params *lcp,
72b2cb61 325 struct cmd_context *cmd)
052360e9 326{
9ac61d2b 327 if (arg_count(cmd, extents_ARG) && arg_count(cmd, size_ARG)) {
1832f310 328 log_error("Please specify either size or extents (not both)");
052360e9 329 return 0;
642c2e96
AK
330 }
331
9ac61d2b
AK
332 if (!lp->thin && !lp->snapshot && !arg_count(cmd, extents_ARG) && !arg_count(cmd, size_ARG)) {
333 log_error("Please specify either size or extents");
334 return 0;
335 }
336
fdd4f3c0 337 if (arg_count(cmd, extents_ARG)) {
fbf6b89a 338 if (arg_sign_value(cmd, extents_ARG, SIGN_NONE) == SIGN_MINUS) {
fdd4f3c0
AK
339 log_error("Negative number of extents is invalid");
340 return 0;
341 }
8ef2b021 342 lp->extents = arg_uint_value(cmd, extents_ARG, 0);
8842d526 343 lcp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
fdd4f3c0 344 }
052360e9
JT
345
346 /* Size returned in kilobyte units; held in sectors */
fdd4f3c0 347 if (arg_count(cmd, size_ARG)) {
fbf6b89a 348 if (arg_sign_value(cmd, size_ARG, SIGN_NONE) == SIGN_MINUS) {
fdd4f3c0
AK
349 log_error("Negative size is invalid");
350 return 0;
351 }
7a0b0db1 352 lcp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0));
8842d526 353 lcp->percent = PERCENT_NONE;
fdd4f3c0 354 }
052360e9 355
9ac61d2b
AK
356 /* If size/extents given with thin, then we are creating a thin pool */
357 if (lp->thin && (arg_count(cmd, size_ARG) || arg_count(cmd, extents_ARG)))
358 lp->create_thin_pool = 1;
359
b8cac455
ZK
360 if (arg_count(cmd, poolmetadatasize_ARG)) {
361 if (!seg_is_thin(lp)) {
362 log_error("--poolmetadatasize may only be specified when allocating the thin pool.");
363 return 0;
364 }
fbf6b89a 365 if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
b8cac455
ZK
366 log_error("Negative poolmetadatasize is invalid.");
367 return 0;
368 }
369 lp->poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, UINT64_C(0));
370 }
371
87f42fda 372 /* Size returned in kilobyte units; held in sectors */
154753db 373 if (arg_count(cmd, virtualsize_ARG)) {
9ac61d2b
AK
374 if (seg_is_thin_pool(lp)) {
375 log_error("Virtual size in incompatible with thin_pool segment type.");
376 return 0;
377 }
fbf6b89a 378 if (arg_sign_value(cmd, virtualsize_ARG, SIGN_NONE) == SIGN_MINUS) {
87f42fda
AK
379 log_error("Negative virtual origin size is invalid");
380 return 0;
381 }
154753db 382 lp->voriginsize = arg_uint64_value(cmd, virtualsize_ARG,
87f42fda
AK
383 UINT64_C(0));
384 if (!lp->voriginsize) {
385 log_error("Virtual origin size may not be zero");
386 return 0;
387 }
9ac61d2b
AK
388 } else {
389 /* No virtual size given, so no thin LV to create. */
f582793f 390 if (seg_is_thin_volume(lp) && !(lp->segtype = get_segtype_from_string(cmd, "thin-pool")))
9ac61d2b
AK
391 return_0;
392
393 lp->thin = 0;
87f42fda
AK
394 }
395
052360e9
JT
396 return 1;
397}
398
f18ef244
DW
399/*
400 * Generic mirror parameter checks.
401 * FIXME: Should eventually be moved into lvm library.
402 */
08f1ddea 403static int _validate_mirror_params(const struct cmd_context *cmd __attribute__((unused)),
bf4f5b21 404 const struct lvcreate_params *lp)
60f13f01 405{
916490f8 406 int pagesize = lvm_getpagesize();
60f13f01
AK
407
408 if (lp->region_size & (lp->region_size - 1)) {
409 log_error("Region size (%" PRIu32 ") must be a power of 2",
410 lp->region_size);
411 return 0;
412 }
413
5c24f56b
AK
414 if (lp->region_size % (pagesize >> SECTOR_SHIFT)) {
415 log_error("Region size (%" PRIu32 ") must be a multiple of "
416 "machine memory page size (%d)",
417 lp->region_size, pagesize >> SECTOR_SHIFT);
418 return 0;
419 }
420
12ccdb25
AK
421 if (!lp->region_size) {
422 log_error("Non-zero region size must be supplied.");
423 return 0;
424 }
425
f18ef244
DW
426 return 1;
427}
428
429static int _read_mirror_params(struct lvcreate_params *lp,
cd3ae9bc 430 struct cmd_context *cmd)
f18ef244
DW
431{
432 int region_size;
433 const char *mirrorlog;
f3ac7d1b 434 int corelog = arg_count(cmd, corelog_ARG);
19583d11 435
2b849ab4 436 mirrorlog = arg_str_value(cmd, mirrorlog_ARG,
f3ac7d1b 437 corelog ? "core" : DEFAULT_MIRRORLOG);
2b849ab4 438
7a369d37
JEB
439 if (strcmp("core", mirrorlog) && corelog) {
440 log_error("Please use only one of --mirrorlog or --corelog");
441 return 0;
442 }
443
444 if (!strcmp("mirrored", mirrorlog)) {
445 lp->log_count = 2;
446 } else if (!strcmp("disk", mirrorlog)) {
77dd1c0e 447 lp->log_count = 1;
f3ac7d1b 448 } else if (!strcmp("core", mirrorlog))
77dd1c0e 449 lp->log_count = 0;
edb3374d
AK
450 else {
451 log_error("Unknown mirrorlog type: %s", mirrorlog);
452 return 0;
19583d11
JEB
453 }
454
edb3374d
AK
455 log_verbose("Setting logging type to %s", mirrorlog);
456
a8fb89ad 457 lp->nosync = arg_is_set(cmd, nosync_ARG);
f17f6814 458
f18ef244 459 if (arg_count(cmd, regionsize_ARG)) {
fbf6b89a 460 if (arg_sign_value(cmd, regionsize_ARG, SIGN_NONE) == SIGN_MINUS) {
f18ef244
DW
461 log_error("Negative regionsize is invalid");
462 return 0;
463 }
204a12e5 464 lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
f18ef244
DW
465 } else {
466 region_size = 2 * find_config_tree_int(cmd,
467 "activation/mirror_region_size",
468 DEFAULT_MIRROR_REGION_SIZE);
469 if (region_size < 0) {
470 log_error("Negative regionsize in configuration file "
471 "is invalid");
472 return 0;
473 }
474 lp->region_size = region_size;
475 }
476
477 if (!_validate_mirror_params(cmd, lp))
478 return 0;
479
60f13f01
AK
480 return 1;
481}
482
cac52ca4
JEB
483static int _read_raid_params(struct lvcreate_params *lp,
484 struct cmd_context *cmd)
485{
486 if (!segtype_is_raid(lp->segtype))
487 return 1;
488
489 if (arg_count(cmd, corelog_ARG) ||
490 arg_count(cmd, mirrorlog_ARG)) {
491 log_error("Log options not applicable to %s segtype",
492 lp->segtype->name);
493 return 0;
494 }
495
496 /*
497 * get_stripe_params is called before _read_raid_params
498 * and already sets:
499 * lp->stripes
500 * lp->stripe_size
501 *
502 * For RAID 4/5/6, these values must be set.
503 */
870762d8
JEB
504 if (!segtype_is_mirrored(lp->segtype) &&
505 (lp->stripes <= lp->segtype->parity_devs)) {
506 log_error("Number of stripes must be at least %d for %s",
507 lp->segtype->parity_devs + 1, lp->segtype->name);
cac52ca4
JEB
508 return 0;
509 }
510
511 /*
512 * _read_mirror_params is called before _read_raid_params
513 * and already sets:
514 * lp->nosync
515 * lp->region_size
516 *
517 * But let's ensure that programmers don't reorder
518 * that by checking and warning if they aren't set.
519 */
520 if (!lp->region_size) {
9ac61d2b
AK
521 log_error(INTERNAL_ERROR "region_size not set.");
522 return 0;
523 }
524
525 return 1;
526}
527
528static int _read_activation_params(struct lvcreate_params *lp, struct cmd_context *cmd)
529{
530 unsigned pagesize;
531
fbf6b89a
ZK
532 lp->activate = (activation_change_t)
533 arg_uint_value(cmd, available_ARG, CHANGE_AY);
9ac61d2b
AK
534
535 if (lp->activate == CHANGE_AN || lp->activate == CHANGE_ALN) {
536 if (lp->zero && !seg_is_thin(lp)) {
537 log_error("--available n requires --zero n");
538 return 0;
539 }
540 }
541
542 /*
543 * Read ahead.
544 */
545 lp->read_ahead = arg_uint_value(cmd, readahead_ARG,
546 cmd->default_settings.read_ahead);
547 pagesize = lvm_getpagesize() >> SECTOR_SHIFT;
548 if (lp->read_ahead != DM_READ_AHEAD_AUTO &&
549 lp->read_ahead != DM_READ_AHEAD_NONE &&
550 lp->read_ahead % pagesize) {
551 if (lp->read_ahead < pagesize)
552 lp->read_ahead = pagesize;
553 else
554 lp->read_ahead = (lp->read_ahead / pagesize) * pagesize;
555 log_warn("WARNING: Overriding readahead to %u sectors, a multiple "
556 "of %uK page size.", lp->read_ahead, pagesize >> 1);
557 }
558
559 /*
560 * Permissions.
561 */
562 lp->permission = arg_uint_value(cmd, permission_ARG,
563 LVM_READ | LVM_WRITE);
564
565 if (lp->thin && !(lp->permission & LVM_WRITE)) {
566 log_error("Read-only thin volumes are not currently supported.");
567 return 0;
568 }
569
570 /* Must not zero read only volume */
571 if (!(lp->permission & LVM_WRITE))
572 lp->zero = 0;
573
574 lp->minor = arg_int_value(cmd, minor_ARG, -1);
575 lp->major = arg_int_value(cmd, major_ARG, -1);
576
577 /* Persistent minor */
578 if (arg_count(cmd, persistent_ARG)) {
579 if (lp->create_thin_pool && !lp->thin) {
580 log_error("--persistent is not permitted when creating a thin pool device.");
581 return 0;
582 }
583 if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "y")) {
584 if (lp->minor == -1) {
585 log_error("Please specify minor number with "
586 "--minor when using -My");
587 return 0;
588 }
589 if (lp->major == -1) {
590 log_error("Please specify major number with "
591 "--major when using -My");
592 return 0;
593 }
594 } else {
595 if ((lp->minor != -1) || (lp->major != -1)) {
596 log_error("--major and --minor incompatible "
597 "with -Mn");
598 return 0;
599 }
600 }
601 } else if (arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) {
602 log_error("--major and --minor require -My");
cac52ca4
JEB
603 return 0;
604 }
605
606 return 1;
607}
608
8842d526
DW
609static int _lvcreate_params(struct lvcreate_params *lp,
610 struct lvcreate_cmdline_params *lcp,
611 struct cmd_context *cmd,
8a2fc586 612 int argc, char **argv)
052360e9 613{
a0a23eff 614 int contiguous;
f8452d8c 615 struct arg_value_group_list *current_group;
cac52ca4 616 const char *segtype_str;
f8452d8c 617 const char *tag;
a0a23eff 618
fdf8038f 619 memset(lp, 0, sizeof(*lp));
8842d526 620 memset(lcp, 0, sizeof(*lcp));
f8452d8c 621 dm_list_init(&lp->tags);
fdf8038f 622
052360e9 623 /*
1832f310 624 * Check selected options are compatible and determine segtype
052360e9 625 */
0ed2af7f 626// FIXME -m0 implies *striped*
9ac61d2b
AK
627 if (arg_count(cmd, thin_ARG) && arg_count(cmd,mirrors_ARG)) {
628 log_error("--thin and --mirrors are incompatible.");
629 return 0;
630 }
631
0ed2af7f
AK
632// FIXME -m0 implies *striped*
633
9ac61d2b 634 /* Set default segtype */
cac52ca4 635 if (arg_count(cmd, mirrors_ARG))
d8b1aa19 636 segtype_str = find_config_tree_str(cmd, "global/mirror_segtype_default", DEFAULT_MIRROR_SEGTYPE);
9ac61d2b
AK
637 else if (arg_count(cmd, thin_ARG) || arg_count(cmd, thinpool_ARG))
638 segtype_str = "thin";
639 else
640 segtype_str = "striped";
cac52ca4 641
1281a5e3
ZK
642 segtype_str = arg_str_value(cmd, type_ARG, segtype_str);
643
644 if (!(lp->segtype = get_segtype_from_string(cmd, segtype_str)))
645 return_0;
1832f310 646
ef78ebf3 647 if (seg_unknown(lp)) {
1281a5e3 648 log_error("Unable to create LV with unknown segment type %s.", segtype_str);
ef78ebf3
AK
649 return 0;
650 }
651
154753db 652 if (arg_count(cmd, snapshot_ARG) || seg_is_snapshot(lp) ||
9ac61d2b 653 (!seg_is_thin(lp) && arg_count(cmd, virtualsize_ARG)))
1832f310
AK
654 lp->snapshot = 1;
655
9ac61d2b
AK
656 if (seg_is_thin_pool(lp)) {
657 if (lp->snapshot) {
658 log_error("Snapshots are incompatible with thin_pool segment_type.");
659 return 0;
660 }
661 lp->create_thin_pool = 1;
662 }
663
664 if (seg_is_thin_volume(lp))
665 lp->thin = 1;
666
60f13f01
AK
667 lp->mirrors = 1;
668
cac52ca4 669 /* Default to 2 mirrored areas if '--type mirror|raid1' */
09c4fd3f 670 if (segtype_is_mirrored(lp->segtype))
60f13f01
AK
671 lp->mirrors = 2;
672
673 if (arg_count(cmd, mirrors_ARG)) {
674 lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
f989a555
JEB
675 if (lp->mirrors == 1) {
676 if (segtype_is_mirrored(lp->segtype)) {
0ed2af7f 677 log_error("--mirrors must be at least 1 with segment type %s.", lp->segtype->name);
f989a555
JEB
678 return 0;
679 }
60f13f01 680 log_print("Redundant mirrors argument: default is 0");
f989a555 681 }
fbf6b89a 682 if (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS) {
7424de5b
AK
683 log_error("Mirrors argument may not be negative");
684 return 0;
685 }
60f13f01
AK
686 }
687
9ac61d2b
AK
688 if (lp->snapshot && arg_count(cmd, zero_ARG)) {
689 log_error("-Z is incompatible with snapshots");
690 return 0;
fdf8038f 691 }
052360e9 692
cac52ca4 693 if (segtype_is_mirrored(lp->segtype) || segtype_is_raid(lp->segtype)) {
60f13f01
AK
694 if (lp->snapshot) {
695 log_error("mirrors and snapshots are currently "
696 "incompatible");
697 return 0;
698 }
f17f6814
AK
699 } else {
700 if (arg_count(cmd, corelog_ARG)) {
701 log_error("--corelog is only available with mirrors");
702 return 0;
703 }
de828433 704
dfafb8fb
JEB
705 if (arg_count(cmd, mirrorlog_ARG)) {
706 log_error("--mirrorlog is only available with mirrors");
707 return 0;
708 }
709
de828433
AK
710 if (arg_count(cmd, nosync_ARG)) {
711 log_error("--nosync is only available with mirrors");
712 return 0;
713 }
60f13f01
AK
714 }
715
1832f310 716 if (activation() && lp->segtype->ops->target_present &&
81680dce 717 !lp->segtype->ops->target_present(cmd, NULL, NULL)) {
1832f310
AK
718 log_error("%s: Required device-mapper target(s) not "
719 "detected in your kernel", lp->segtype->name);
720 return 0;
721 }
722
8a2fc586 723 if (!_lvcreate_name_params(lp, cmd, &argc, &argv) ||
8842d526 724 !_read_size_params(lp, lcp, cmd) ||
68176be1 725 !get_stripe_params(cmd, &lp->stripes, &lp->stripe_size) ||
cac52ca4 726 !_read_mirror_params(lp, cmd) ||
79c42c66 727 !_read_raid_params(lp, cmd))
c51b9fff 728 return_0;
d53f88d7 729
9ac61d2b
AK
730 if (lp->snapshot && lp->thin && arg_count(cmd, chunksize_ARG))
731 log_warn("WARNING: Ignoring --chunksize with thin snapshots.");
732 else if (lp->thin && !lp->create_thin_pool) {
733 if (arg_count(cmd, chunksize_ARG))
734 log_warn("WARNING: Ignoring --chunksize when using an existing pool.");
735 } else if (lp->snapshot || lp->create_thin_pool) {
fbf6b89a 736 if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
9ac61d2b
AK
737 log_error("Negative chunk size is invalid");
738 return 0;
739 }
3bc41748
ZK
740 if (lp->snapshot) {
741 lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
742 if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
743 (lp->chunk_size & (lp->chunk_size - 1))) {
744 log_error("Chunk size must be a power of 2 in the "
745 "range 4K to 512K");
746 return 0;
747 }
748 } else {
749 lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, DM_THIN_MIN_DATA_BLOCK_SIZE);
750 if ((lp->chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ||
751 (lp->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE) ||
752 (lp->chunk_size & (lp->chunk_size - 1))) {
753 log_error("Chunk size must be a power of 2 in the "
754 "range %uK to %uK", (DM_THIN_MIN_DATA_BLOCK_SIZE / 2),
755 (DM_THIN_MIN_DATA_BLOCK_SIZE / 2));
756 return 0;
757 }
9ac61d2b 758 }
3bc41748 759 log_verbose("Setting chunksize to %u sectors.", lp->chunk_size);
e586401e 760
9ac61d2b
AK
761 if (!lp->thin && lp->snapshot && !(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
762 return_0;
763 } else {
764 if (arg_count(cmd, chunksize_ARG)) {
765 log_error("-c is only available with snapshots and thin pools");
453cdee5
AK
766 return 0;
767 }
768 }
769
052360e9 770 /*
9ac61d2b 771 * Should we zero the lv.
052360e9 772 */
9ac61d2b
AK
773 lp->zero = strcmp(arg_str_value(cmd, zero_ARG,
774 (lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n");
052360e9 775
5800aa5c
MB
776 if (lp->mirrors > DEFAULT_MIRROR_MAX_IMAGES) {
777 log_error("Only up to %d images in mirror supported currently.",
778 DEFAULT_MIRROR_MAX_IMAGES);
779 return 0;
780 }
781
052360e9 782 /*
9ac61d2b 783 * Allocation parameters
052360e9 784 */
9ac61d2b 785 contiguous = strcmp(arg_str_value(cmd, contiguous_ARG, "n"), "n");
e0096cab 786
9ac61d2b 787 lp->alloc = contiguous ? ALLOC_CONTIGUOUS : ALLOC_INHERIT;
052360e9 788
fbf6b89a 789 lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, lp->alloc);
052360e9 790
9ac61d2b
AK
791 if (contiguous && (lp->alloc != ALLOC_CONTIGUOUS)) {
792 log_error("Conflicting contiguous and alloc arguments");
ed8c4d99 793 return 0;
642c2e96
AK
794 }
795
f8452d8c
AK
796 dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
797 if (!grouped_arg_is_set(current_group->arg_values, addtag_ARG))
798 continue;
799
800 if (!(tag = grouped_arg_str_value(current_group->arg_values, addtag_ARG, NULL))) {
801 log_error("Failed to get tag");
802 return 0;
803 }
804
805 if (!str_list_add(cmd->mem, &lp->tags, tag)) {
9ac61d2b 806 log_error("Unable to allocate memory for tag %s", tag);
f8452d8c
AK
807 return 0;
808 }
9ac61d2b 809 }
9091827c 810
e6479dff
DW
811 lcp->pv_count = argc;
812 lcp->pvs = argv;
642c2e96 813
052360e9
JT
814 return 1;
815}
816
9ac61d2b
AK
817static int _check_thin_parameters(struct volume_group *vg, struct lvcreate_params *lp,
818 struct lvcreate_cmdline_params *lcp)
819{
820 struct lv_list *lvl;
821
822 if (!lp->thin && !lp->create_thin_pool) {
823 log_error("Please specify device size(s).");
824 return 0;
825 }
826
827 if (lp->thin && !lp->create_thin_pool) {
828 if (arg_count(vg->cmd, chunksize_ARG)) {
829 log_error("Only specify --chunksize when originally creating the thin pool.");
830 return 0;
831 }
832
833 if (lcp->pv_count) {
834 log_error("Only specify Physical volumes when allocating the thin pool.");
835 return 0;
836 }
837
838 if (arg_count(vg->cmd, alloc_ARG)) {
839 log_error("--alloc may only be specified when allocating the thin pool.");
840 return 0;
841 }
842
b8cac455
ZK
843 if (arg_count(vg->cmd, poolmetadatasize_ARG)) {
844 log_error("--poolmetadatasize may only be specified when allocating the thin pool.");
845 return 0;
846 }
847
9ac61d2b
AK
848 if (arg_count(vg->cmd, stripesize_ARG)) {
849 log_error("--stripesize may only be specified when allocating the thin pool.");
850 return 0;
851 }
852
853 if (arg_count(vg->cmd, stripes_ARG)) {
854 log_error("--stripes may only be specified when allocating the thin pool.");
855 return 0;
856 }
857
858 if (arg_count(vg->cmd, contiguous_ARG)) {
859 log_error("--contiguous may only be specified when allocating the thin pool.");
860 return 0;
861 }
862
863 if (arg_count(vg->cmd, zero_ARG)) {
864 log_error("--zero may only be specified when allocating the thin pool.");
865 return 0;
866 }
867 }
868
869 if (lp->create_thin_pool && lp->pool) {
870 if (find_lv_in_vg(vg, lp->pool)) {
871 log_error("Pool %s already exists in Volume group %s.", lp->pool, vg->name);
872 return 0;
873 }
874 } else if (lp->pool) {
875 if (!(lvl = find_lv_in_vg(vg, lp->pool))) {
876 log_error("Pool %s not found in Volume group %s.", lp->pool, vg->name);
877 return 0;
878 }
b88362ff 879 if (!lv_is_thin_pool(lvl->lv)) {
9ac61d2b
AK
880 log_error("Logical volume %s is not a thin pool.", lp->pool);
881 return 0;
882 }
883 } else if (!lp->create_thin_pool) {
884 log_error("Please specify name of existing pool.");
885 return 0;
886 }
887
888 if (!lp->thin && lp->lv_name) {
889 log_error("--name may only be given when creating a new thin Logical volume or snapshot.");
890 return 0;
891 }
892
893 if (!lp->thin) {
894 if (arg_count(vg->cmd, readahead_ARG)) {
895 log_error("--readhead may only be given when creating a new thin Logical volume or snapshot.");
896 return 0;
897 }
898 if (arg_count(vg->cmd, permission_ARG)) {
899 log_error("--permission may only be given when creating a new thin Logical volume or snapshot.");
900 return 0;
901 }
902 if (arg_count(vg->cmd, persistent_ARG)) {
903 log_error("--persistent may only be given when creating a new thin Logical volume or snapshot.");
904 return 0;
905 }
906 }
907
908 return 1;
909}
910
911/*
912 * Ensure the set of thin parameters extracted from the command line is consistent.
913 */
914static int _validate_internal_thin_processing(const struct lvcreate_params *lp)
915{
916 int r = 1;
917
918 /*
919 The final state should be one of:
920 thin create_thin_pool snapshot origin pool
921 1 1 0 0 y/n - create new pool and a thin LV in it
922 1 0 0 0 y - create new thin LV in existing pool
923 0 1 0 0 y/n - create new pool only
924 1 0 1 1 y - create thin snapshot of existing thin LV
925 */
926
927 if (!lp->create_thin_pool && !lp->pool) {
928 log_error(INTERNAL_ERROR "--thinpool not identified.");
929 r = 0;
930 }
931
932 if ((lp->snapshot && !lp->origin) || (!lp->snapshot && lp->origin)) {
933 log_error(INTERNAL_ERROR "Inconsistent snapshot and origin parameters identified.");
934 r = 0;
935 }
936
937 if (lp->snapshot && (lp->create_thin_pool || !lp->thin)) {
938 log_error(INTERNAL_ERROR "Inconsistent thin and snapshot parameters identified.");
939 r = 0;
940 }
941
942 if (!lp->thin && !lp->create_thin_pool) {
943 log_error(INTERNAL_ERROR "Failed to identify what type of thin target to use.");
944 r = 0;
945 }
946
947 if (seg_is_thin_pool(lp) && lp->thin) {
948 log_error(INTERNAL_ERROR "Thin volume cannot be created with thin pool segment type.");
949 r = 0;
950 }
951
952 return r;
953}
954
052360e9
JT
955int lvcreate(struct cmd_context *cmd, int argc, char **argv)
956{
e5f7352b 957 int r = ECMD_PROCESSED;
052360e9 958 struct lvcreate_params lp;
8842d526 959 struct lvcreate_cmdline_params lcp;
e5f7352b 960 struct volume_group *vg;
052360e9 961
8842d526 962 if (!_lvcreate_params(&lp, &lcp, cmd, argc, argv))
cfb7bfc7 963 return EINVALID_CMD_LINE;
052360e9 964
e5f7352b 965 log_verbose("Finding volume group \"%s\"", lp.vg_name);
b8b3508c 966 vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0);
4c611a22 967 if (vg_read_error(vg)) {
077a6755 968 release_vg(vg);
651ff9b3 969 stack;
cfb7bfc7 970 return ECMD_FAILED;
4c611a22 971 }
052360e9 972
0d505fb4 973 if (lp.snapshot && lp.origin && !_determine_snapshot_type(vg, &lp)) {
9ac61d2b
AK
974 r = ECMD_FAILED;
975 goto_out;
976 }
977
978 if (seg_is_thin(&lp) && !_check_thin_parameters(vg, &lp, &lcp)) {
979 r = ECMD_FAILED;
980 goto_out;
981 }
982
a538e369
ZK
983 /*
984 * Check activation parameters to support inactive thin snapshot creation
985 * FIXME: anything else needs to be moved past _determine_snapshot_type()?
986 */
987 if (!_read_activation_params(&lp, cmd)) {
988 r = ECMD_FAILED;
989 goto_out;
990 }
991
651ff9b3 992 if (!_update_extents_params(vg, &lp, &lcp)) {
ba3851fd
MB
993 r = ECMD_FAILED;
994 goto_out;
651ff9b3 995 }
8675b317 996
9ac61d2b
AK
997 if (seg_is_thin(&lp) && !_validate_internal_thin_processing(&lp)) {
998 r = ECMD_FAILED;
999 goto_out;
1000 }
1001
1002 if (lp.create_thin_pool)
1003 log_verbose("Making thin pool %s in VG %s using segtype %s",
1004 lp.pool ? : "with generated name", lp.vg_name, lp.segtype->name);
1005
1006 if (lp.thin)
1007 log_verbose("Making thin LV %s in pool %s in VG %s%s%s using segtype %s",
1008 lp.lv_name ? : "with generated name",
f2e3d659
AK
1009 lp.pool ? : "with generated name", lp.vg_name,
1010 lp.snapshot ? " as snapshot of " : "",
9ac61d2b
AK
1011 lp.snapshot ? lp.origin : "", lp.segtype->name);
1012
651ff9b3
AK
1013 if (!lv_create_single(vg, &lp)) {
1014 stack;
e5f7352b 1015 r = ECMD_FAILED;
651ff9b3 1016 }
ba3851fd 1017out:
077a6755 1018 unlock_and_release_vg(cmd, vg, lp.vg_name);
052360e9 1019 return r;
642c2e96 1020}
This page took 0.240098 seconds and 5 git commands to generate.