lvconvert.c revision 1.1.1.1 1 /* $NetBSD: lvconvert.c,v 1.1.1.1 2008/12/22 00:19:01 haad Exp $ */
2
3 /*
4 * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
5 *
6 * This file is part of LVM2.
7 *
8 * This copyrighted material is made available to anyone wishing to use,
9 * modify, copy, or redistribute it subject to the terms and conditions
10 * of the GNU Lesser General Public License v.2.1.
11 *
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17 #include "tools.h"
18 #include "polldaemon.h"
19 #include "lv_alloc.h"
20
21 struct lvconvert_params {
22 int snapshot;
23 int zero;
24
25 const char *origin;
26 const char *lv_name;
27 const char *lv_name_full;
28 const char *vg_name;
29 int wait_completion;
30 int need_polling;
31
32 uint32_t chunk_size;
33 uint32_t region_size;
34
35 uint32_t mirrors;
36 sign_t mirrors_sign;
37
38 struct segment_type *segtype;
39
40 alloc_policy_t alloc;
41
42 int pv_count;
43 char **pvs;
44 struct dm_list *pvh;
45 };
46
47 static int _lvconvert_name_params(struct lvconvert_params *lp,
48 struct cmd_context *cmd,
49 int *pargc, char ***pargv)
50 {
51 char *ptr;
52 const char *vg_name = NULL;
53
54 if (lp->snapshot) {
55 if (!*pargc) {
56 log_error("Please specify a logical volume to act as "
57 "the snapshot origin.");
58 return 0;
59 }
60
61 lp->origin = *pargv[0];
62 (*pargv)++, (*pargc)--;
63 if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) {
64 log_error("The origin name should include the "
65 "volume group.");
66 return 0;
67 }
68
69 /* Strip the volume group from the origin */
70 if ((ptr = strrchr(lp->origin, (int) '/')))
71 lp->origin = ptr + 1;
72 }
73
74 if (!*pargc) {
75 log_error("Please provide logical volume path");
76 return 0;
77 }
78
79 lp->lv_name = lp->lv_name_full = (*pargv)[0];
80 (*pargv)++, (*pargc)--;
81
82 if (strchr(lp->lv_name_full, '/') &&
83 (vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
84 lp->vg_name && strcmp(vg_name, lp->vg_name)) {
85 log_error("Please use a single volume group name "
86 "(\"%s\" or \"%s\")", vg_name, lp->vg_name);
87 return 0;
88 }
89
90 if (!lp->vg_name)
91 lp->vg_name = vg_name;
92
93 if (!validate_name(lp->vg_name)) {
94 log_error("Please provide a valid volume group name");
95 return 0;
96 }
97
98 if ((ptr = strrchr(lp->lv_name_full, '/')))
99 lp->lv_name = ptr + 1;
100
101 if (!apply_lvname_restrictions(lp->lv_name))
102 return_0;
103
104 return 1;
105 }
106
107 static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
108 int argc, char **argv)
109 {
110 int region_size;
111 int pagesize = lvm_getpagesize();
112
113 memset(lp, 0, sizeof(*lp));
114
115 if (arg_count(cmd, snapshot_ARG) &&
116 (arg_count(cmd, mirrorlog_ARG) || arg_count(cmd, mirrors_ARG))) {
117 log_error("--snapshots argument cannot be mixed "
118 "with --mirrors or --log");
119 return 0;
120 }
121
122 if (!arg_count(cmd, background_ARG))
123 lp->wait_completion = 1;
124
125 if (arg_count(cmd, snapshot_ARG))
126 lp->snapshot = 1;
127
128 if (arg_count(cmd, mirrors_ARG)) {
129 lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0);
130 lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, 0);
131 }
132
133 lp->alloc = ALLOC_INHERIT;
134 if (arg_count(cmd, alloc_ARG))
135 lp->alloc = arg_uint_value(cmd, alloc_ARG, lp->alloc);
136
137 if (lp->snapshot) {
138 if (arg_count(cmd, regionsize_ARG)) {
139 log_error("--regionsize is only available with mirrors");
140 return 0;
141 }
142
143 if (arg_sign_value(cmd, chunksize_ARG, 0) == SIGN_MINUS) {
144 log_error("Negative chunk size is invalid");
145 return 0;
146 }
147 lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
148 if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
149 (lp->chunk_size & (lp->chunk_size - 1))) {
150 log_error("Chunk size must be a power of 2 in the "
151 "range 4K to 512K");
152 return 0;
153 }
154 log_verbose("Setting chunksize to %d sectors.", lp->chunk_size);
155
156 if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
157 return_0;
158
159 lp->zero = strcmp(arg_str_value(cmd, zero_ARG,
160 (lp->segtype->flags &
161 SEG_CANNOT_BE_ZEROED) ?
162 "n" : "y"), "n");
163
164 } else { /* Mirrors */
165 if (arg_count(cmd, chunksize_ARG)) {
166 log_error("--chunksize is only available with "
167 "snapshots");
168 return 0;
169 }
170
171 if (arg_count(cmd, zero_ARG)) {
172 log_error("--zero is only available with snapshots");
173 return 0;
174 }
175
176 /*
177 * --regionsize is only valid if converting an LV into a mirror.
178 * Checked when we know the state of the LV being converted.
179 */
180
181 if (arg_count(cmd, regionsize_ARG)) {
182 if (arg_sign_value(cmd, regionsize_ARG, 0) ==
183 SIGN_MINUS) {
184 log_error("Negative regionsize is invalid");
185 return 0;
186 }
187 lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
188 } else {
189 region_size = 2 * find_config_tree_int(cmd,
190 "activation/mirror_region_size",
191 DEFAULT_MIRROR_REGION_SIZE);
192 if (region_size < 0) {
193 log_error("Negative regionsize in "
194 "configuration file is invalid");
195 return 0;
196 }
197 lp->region_size = region_size;
198 }
199
200 if (lp->region_size % (pagesize >> SECTOR_SHIFT)) {
201 log_error("Region size (%" PRIu32 ") must be "
202 "a multiple of machine memory "
203 "page size (%d)",
204 lp->region_size, pagesize >> SECTOR_SHIFT);
205 return 0;
206 }
207
208 if (lp->region_size & (lp->region_size - 1)) {
209 log_error("Region size (%" PRIu32
210 ") must be a power of 2", lp->region_size);
211 return 0;
212 }
213
214 if (!lp->region_size) {
215 log_error("Non-zero region size must be supplied.");
216 return 0;
217 }
218
219 if (!(lp->segtype = get_segtype_from_string(cmd, "mirror")))
220 return_0;
221 }
222
223 if (activation() && lp->segtype->ops->target_present &&
224 !lp->segtype->ops->target_present(NULL, NULL)) {
225 log_error("%s: Required device-mapper target(s) not "
226 "detected in your kernel", lp->segtype->name);
227 return 0;
228 }
229
230 if (!_lvconvert_name_params(lp, cmd, &argc, &argv))
231 return_0;
232
233 lp->pv_count = argc;
234 lp->pvs = argv;
235
236 return 1;
237 }
238
239
240 static struct volume_group *_get_lvconvert_vg(struct cmd_context *cmd,
241 const char *lv_name)
242 {
243 dev_close_all();
244
245 return vg_lock_and_read(cmd, extract_vgname(cmd, lv_name),
246 NULL, LCK_VG_WRITE,
247 CLUSTERED | EXPORTED_VG | LVM_WRITE,
248 CORRECT_INCONSISTENT | FAIL_INCONSISTENT);
249 }
250
251 static struct logical_volume *_get_lvconvert_lv(struct cmd_context *cmd __attribute((unused)),
252 struct volume_group *vg,
253 const char *name,
254 uint32_t lv_type __attribute((unused)))
255 {
256 return find_lv(vg, name);
257 }
258
259 static int _update_lvconvert_mirror(struct cmd_context *cmd __attribute((unused)),
260 struct volume_group *vg __attribute((unused)),
261 struct logical_volume *lv __attribute((unused)),
262 struct dm_list *lvs_changed __attribute((unused)),
263 unsigned flags __attribute((unused)))
264 {
265 /* lvconvert mirror doesn't require periodical metadata update */
266 return 1;
267 }
268
269 static int _finish_lvconvert_mirror(struct cmd_context *cmd,
270 struct volume_group *vg,
271 struct logical_volume *lv,
272 struct dm_list *lvs_changed __attribute((unused)))
273 {
274 if (!collapse_mirrored_lv(lv)) {
275 log_error("Failed to remove temporary sync layer.");
276 return 0;
277 }
278
279 lv->status &= ~CONVERTING;
280
281 log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
282
283 if (!vg_write(vg))
284 return_0;
285
286 backup(vg);
287
288 if (!suspend_lv(cmd, lv)) {
289 log_error("Failed to lock %s", lv->name);
290 vg_revert(vg);
291 return 0;
292 }
293
294 if (!vg_commit(vg)) {
295 resume_lv(cmd, lv);
296 return 0;
297 }
298
299 log_very_verbose("Updating \"%s\" in kernel", lv->name);
300
301 if (!resume_lv(cmd, lv)) {
302 log_error("Problem reactivating %s", lv->name);
303 return 0;
304 }
305
306 log_print("Logical volume %s converted.", lv->name);
307
308 return 1;
309 }
310
311 static struct poll_functions _lvconvert_mirror_fns = {
312 .get_copy_vg = _get_lvconvert_vg,
313 .get_copy_lv = _get_lvconvert_lv,
314 .update_metadata = _update_lvconvert_mirror,
315 .finish_copy = _finish_lvconvert_mirror,
316 };
317
318 int lvconvert_poll(struct cmd_context *cmd, const char *lv_name,
319 unsigned background)
320 {
321 return poll_daemon(cmd, lv_name, background, 0, &_lvconvert_mirror_fns,
322 "Converted");
323 }
324
325 static int _insert_lvconvert_layer(struct cmd_context *cmd,
326 struct logical_volume *lv)
327 {
328 char *format, *layer_name;
329 size_t len;
330 int i;
331
332 /*
333 * We would like to give the same number for this layer
334 * and the newly added mimage.
335 * However, LV name of newly added mimage is determined *after*
336 * the LV name of this layer is determined.
337 *
338 * So, use generate_lv_name() to generate mimage name first
339 * and take the number from it.
340 */
341
342 len = strlen(lv->name) + 32;
343 if (!(format = alloca(len)) ||
344 !(layer_name = alloca(len)) ||
345 dm_snprintf(format, len, "%s_mimage_%%d", lv->name) < 0) {
346 log_error("lvconvert: layer name allocation failed.");
347 return 0;
348 }
349
350 if (!generate_lv_name(lv->vg, format, layer_name, len) ||
351 sscanf(layer_name, format, &i) != 1) {
352 log_error("lvconvert: layer name generation failed.");
353 return 0;
354 }
355
356 if (dm_snprintf(layer_name, len, MIRROR_SYNC_LAYER "_%d", i) < 0) {
357 log_error("layer name allocation failed.");
358 return 0;
359 }
360
361 if (!insert_layer_for_lv(cmd, lv, 0, layer_name)) {
362 log_error("Failed to insert resync layer");
363 return 0;
364 }
365
366 return 1;
367 }
368
369 /* walk down the stacked mirror LV to the original mirror LV */
370 static struct logical_volume *_original_lv(struct logical_volume *lv)
371 {
372 struct logical_volume *next_lv = lv, *tmp_lv;
373
374 while ((tmp_lv = find_temporary_mirror(next_lv)))
375 next_lv = tmp_lv;
376
377 return next_lv;
378 }
379
380 static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * lv,
381 struct lvconvert_params *lp)
382 {
383 struct lv_segment *seg;
384 uint32_t existing_mirrors;
385 const char *mirrorlog;
386 unsigned corelog = 0;
387 struct logical_volume *original_lv;
388
389 seg = first_seg(lv);
390 existing_mirrors = lv_mirror_count(lv);
391
392 /* If called with no argument, try collapsing the resync layers */
393 if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG) &&
394 !arg_count(cmd, corelog_ARG) && !arg_count(cmd, regionsize_ARG)) {
395 lp->need_polling = 1;
396 return 1;
397 }
398
399 /*
400 * Adjust required number of mirrors
401 *
402 * We check mirrors_ARG again to see if it
403 * was supplied. If not, they want the mirror
404 * count to remain the same. They may be changing
405 * the logging type.
406 */
407 if (!arg_count(cmd, mirrors_ARG))
408 lp->mirrors = existing_mirrors;
409 else if (lp->mirrors_sign == SIGN_PLUS)
410 lp->mirrors = existing_mirrors + lp->mirrors;
411 else if (lp->mirrors_sign == SIGN_MINUS)
412 lp->mirrors = existing_mirrors - lp->mirrors;
413 else
414 lp->mirrors += 1;
415
416 /*
417 * Did the user try to subtract more legs than available?
418 */
419 if (lp->mirrors < 1) {
420 log_error("Logical volume %s only has %" PRIu32 " mirrors.",
421 lv->name, existing_mirrors);
422 return 0;
423 }
424
425 /*
426 * Adjust log type
427 */
428 if (arg_count(cmd, corelog_ARG))
429 corelog = 1;
430
431 mirrorlog = arg_str_value(cmd, mirrorlog_ARG,
432 corelog ? "core" : DEFAULT_MIRRORLOG);
433 if (!strcmp("disk", mirrorlog)) {
434 if (corelog) {
435 log_error("--mirrorlog disk and --corelog "
436 "are incompatible");
437 return 0;
438 }
439 corelog = 0;
440 } else if (!strcmp("core", mirrorlog))
441 corelog = 1;
442 else {
443 log_error("Unknown mirrorlog type: %s", mirrorlog);
444 return 0;
445 }
446
447 log_verbose("Setting logging type to %s", mirrorlog);
448
449 /*
450 * Region size must not change on existing mirrors
451 */
452 if (arg_count(cmd, regionsize_ARG) && (lv->status & MIRRORED) &&
453 (lp->region_size != seg->region_size)) {
454 log_error("Mirror log region size cannot be changed on "
455 "an existing mirror.");
456 return 0;
457 }
458
459 /*
460 * Converting from mirror to linear
461 */
462 if ((lp->mirrors == 1)) {
463 if (!(lv->status & MIRRORED)) {
464 log_error("Logical volume %s is already not mirrored.",
465 lv->name);
466 return 1;
467 }
468
469 if (!lv_remove_mirrors(cmd, lv, existing_mirrors - 1, 1,
470 lp->pv_count ? lp->pvh : NULL, 0))
471 return_0;
472 goto commit_changes;
473 }
474
475 /*
476 * Converting from linear to mirror
477 */
478 if (!(lv->status & MIRRORED)) {
479 /* FIXME Share code with lvcreate */
480
481 /* FIXME Why is this restriction here? Fix it! */
482 dm_list_iterate_items(seg, &lv->segments) {
483 if (seg_is_striped(seg) && seg->area_count > 1) {
484 log_error("Mirrors of striped volumes are not yet supported.");
485 return 0;
486 }
487 }
488
489 if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, 1,
490 adjusted_mirror_region_size(
491 lv->vg->extent_size,
492 lv->le_count,
493 lp->region_size),
494 corelog ? 0U : 1U, lp->pvh, lp->alloc,
495 MIRROR_BY_LV))
496 return_0;
497 if (lp->wait_completion)
498 lp->need_polling = 1;
499 goto commit_changes;
500 }
501
502 /*
503 * Converting from mirror to mirror with different leg count,
504 * or different log type.
505 */
506 if (dm_list_size(&lv->segments) != 1) {
507 log_error("Logical volume %s has multiple "
508 "mirror segments.", lv->name);
509 return 0;
510 }
511
512 if (lp->mirrors == existing_mirrors) {
513 /*
514 * Convert Mirror log type
515 */
516 original_lv = _original_lv(lv);
517 if (!first_seg(original_lv)->log_lv && !corelog) {
518 if (!add_mirror_log(cmd, original_lv, 1,
519 adjusted_mirror_region_size(
520 lv->vg->extent_size,
521 lv->le_count,
522 lp->region_size),
523 lp->pvh, lp->alloc))
524 return_0;
525 } else if (first_seg(original_lv)->log_lv && corelog) {
526 if (!remove_mirror_log(cmd, original_lv,
527 lp->pv_count ? lp->pvh : NULL))
528 return_0;
529 } else {
530 /* No change */
531 log_error("Logical volume %s already has %"
532 PRIu32 " mirror(s).", lv->name,
533 lp->mirrors - 1);
534 if (lv->status & CONVERTING)
535 lp->need_polling = 1;
536 return 1;
537 }
538 } else if (lp->mirrors > existing_mirrors) {
539 if (lv->status & MIRROR_NOTSYNCED) {
540 log_error("Not adding mirror to mirrored LV "
541 "without initial resync");
542 return 0;
543 }
544 /*
545 * Log addition/removal should be done before the layer
546 * insertion to make the end result consistent with
547 * linear-to-mirror conversion.
548 */
549 original_lv = _original_lv(lv);
550 if (!first_seg(original_lv)->log_lv && !corelog) {
551 if (!add_mirror_log(cmd, original_lv, 1,
552 adjusted_mirror_region_size(
553 lv->vg->extent_size,
554 lv->le_count,
555 lp->region_size),
556 lp->pvh, lp->alloc))
557 return_0;
558 } else if (first_seg(original_lv)->log_lv && corelog) {
559 if (!remove_mirror_log(cmd, original_lv,
560 lp->pv_count ? lp->pvh : NULL))
561 return_0;
562 }
563 /* Insert a temporary layer for syncing,
564 * only if the original lv is using disk log. */
565 if (seg->log_lv && !_insert_lvconvert_layer(cmd, lv)) {
566 log_error("Failed to insert resync layer");
567 return 0;
568 }
569 /* FIXME: can't have multiple mlogs. force corelog. */
570 if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
571 adjusted_mirror_region_size(
572 lv->vg->extent_size,
573 lv->le_count,
574 lp->region_size),
575 0U, lp->pvh, lp->alloc,
576 MIRROR_BY_LV))
577 return_0;
578 lv->status |= CONVERTING;
579 lp->need_polling = 1;
580 } else {
581 /* Reduce number of mirrors */
582 if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
583 corelog ? 1U : 0U,
584 lp->pv_count ? lp->pvh : NULL, 0))
585 return_0;
586 }
587
588 commit_changes:
589 log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
590
591 if (!vg_write(lv->vg))
592 return_0;
593
594 backup(lv->vg);
595
596 if (!suspend_lv(cmd, lv)) {
597 log_error("Failed to lock %s", lv->name);
598 vg_revert(lv->vg);
599 return 0;
600 }
601
602 if (!vg_commit(lv->vg)) {
603 resume_lv(cmd, lv);
604 return 0;
605 }
606
607 log_very_verbose("Updating \"%s\" in kernel", lv->name);
608
609 if (!resume_lv(cmd, lv)) {
610 log_error("Problem reactivating %s", lv->name);
611 return 0;
612 }
613
614 if (!lp->need_polling)
615 log_print("Logical volume %s converted.", lv->name);
616
617 return 1;
618 }
619
620 static int lvconvert_snapshot(struct cmd_context *cmd,
621 struct logical_volume *lv,
622 struct lvconvert_params *lp)
623 {
624 struct logical_volume *org;
625
626 if (!(org = find_lv(lv->vg, lp->origin))) {
627 log_error("Couldn't find origin volume '%s'.", lp->origin);
628 return 0;
629 }
630
631 if (org == lv) {
632 log_error("Unable to use \"%s\" as both snapshot and origin.",
633 lv->name);
634 return 0;
635 }
636
637 if (org->status & (LOCKED|PVMOVE|MIRRORED) || lv_is_cow(org)) {
638 log_error("Unable to create a snapshot of a %s LV.",
639 org->status & LOCKED ? "locked" :
640 org->status & PVMOVE ? "pvmove" :
641 org->status & MIRRORED ? "mirrored" :
642 "snapshot");
643 return 0;
644 }
645
646 if (!lp->zero || !(lv->status & LVM_WRITE))
647 log_warn("WARNING: \"%s\" not zeroed", lv->name);
648 else if (!set_lv(cmd, lv, UINT64_C(0), 0)) {
649 log_error("Aborting. Failed to wipe snapshot "
650 "exception store.");
651 return 0;
652 }
653
654 if (!deactivate_lv(cmd, lv)) {
655 log_error("Couldn't deactivate LV %s.", lv->name);
656 return 0;
657 }
658
659 if (!vg_add_snapshot(NULL, org, lv, NULL, org->le_count,
660 lp->chunk_size)) {
661 log_error("Couldn't create snapshot.");
662 return 0;
663 }
664
665 /* store vg on disk(s) */
666 if (!vg_write(lv->vg))
667 return_0;
668
669 backup(lv->vg);
670
671 if (!suspend_lv(cmd, org)) {
672 log_error("Failed to suspend origin %s", org->name);
673 vg_revert(lv->vg);
674 return 0;
675 }
676
677 if (!vg_commit(lv->vg))
678 return_0;
679
680 if (!resume_lv(cmd, org)) {
681 log_error("Problem reactivating origin %s", org->name);
682 return 0;
683 }
684
685 log_print("Logical volume %s converted to snapshot.", lv->name);
686
687 return 1;
688 }
689
690 static int lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
691 void *handle)
692 {
693 struct lvconvert_params *lp = handle;
694
695 if (lv->status & LOCKED) {
696 log_error("Cannot convert locked LV %s", lv->name);
697 return ECMD_FAILED;
698 }
699
700 if (lv_is_origin(lv)) {
701 log_error("Can't convert logical volume \"%s\" under snapshot",
702 lv->name);
703 return ECMD_FAILED;
704 }
705
706 if (lv_is_cow(lv)) {
707 log_error("Can't convert snapshot logical volume \"%s\"",
708 lv->name);
709 return ECMD_FAILED;
710 }
711
712 if (lv->status & PVMOVE) {
713 log_error("Unable to convert pvmove LV %s", lv->name);
714 return ECMD_FAILED;
715 }
716
717 if (lp->snapshot) {
718 if (lv->status & MIRRORED) {
719 log_error("Unable to convert mirrored LV \"%s\" into a snapshot.", lv->name);
720 return ECMD_FAILED;
721 }
722 if (!archive(lv->vg))
723 return ECMD_FAILED;
724 if (!lvconvert_snapshot(cmd, lv, lp))
725 return ECMD_FAILED;
726 } else if (arg_count(cmd, mirrors_ARG) || (lv->status & MIRRORED)) {
727 if (!archive(lv->vg))
728 return ECMD_FAILED;
729 if (!lvconvert_mirrors(cmd, lv, lp))
730 return ECMD_FAILED;
731 }
732
733 return ECMD_PROCESSED;
734 }
735
736 int lvconvert(struct cmd_context * cmd, int argc, char **argv)
737 {
738 struct volume_group *vg;
739 struct lv_list *lvl;
740 struct lvconvert_params lp;
741 int ret = ECMD_FAILED;
742 struct lvinfo info;
743
744 if (!_read_params(&lp, cmd, argc, argv)) {
745 stack;
746 return EINVALID_CMD_LINE;
747 }
748
749 log_verbose("Checking for existing volume group \"%s\"", lp.vg_name);
750
751 if (!(vg = vg_lock_and_read(cmd, lp.vg_name, NULL, LCK_VG_WRITE,
752 CLUSTERED | EXPORTED_VG | LVM_WRITE,
753 CORRECT_INCONSISTENT)))
754 return ECMD_FAILED;
755
756 if (!(lvl = find_lv_in_vg(vg, lp.lv_name))) {
757 log_error("Logical volume \"%s\" not found in "
758 "volume group \"%s\"", lp.lv_name, lp.vg_name);
759 goto bad;
760 }
761
762 if (lp.pv_count) {
763 if (!(lp.pvh = create_pv_list(cmd->mem, vg, lp.pv_count,
764 lp.pvs, 0)))
765 goto_bad;
766 } else
767 lp.pvh = &vg->pvs;
768
769 ret = lvconvert_single(cmd, lvl->lv, &lp);
770
771 bad:
772 unlock_vg(cmd, lp.vg_name);
773
774 if (ret == ECMD_PROCESSED && lp.need_polling) {
775 if (!lv_info(cmd, lvl->lv, &info, 1, 0) || !info.exists) {
776 log_print("Conversion starts after activation");
777 return ret;
778 }
779 ret = lvconvert_poll(cmd, lp.lv_name_full,
780 lp.wait_completion ? 0 : 1U);
781 }
782
783 return ret;
784 }
785