xref: /netbsd-src/external/gpl2/lvm2/dist/tools/lvconvert.c (revision 500db002748d9818288e46e10f026a2b09548086)
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