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