Home | History | Annotate | Line # | Download | only in tools
      1      1.1  haad /*	$NetBSD: lvconvert.c,v 1.1.1.2 2009/12/02 00:25:50 haad Exp $	*/
      2      1.1  haad 
      3      1.1  haad /*
      4      1.1  haad  * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
      5      1.1  haad  *
      6      1.1  haad  * This file is part of LVM2.
      7      1.1  haad  *
      8      1.1  haad  * This copyrighted material is made available to anyone wishing to use,
      9      1.1  haad  * modify, copy, or redistribute it subject to the terms and conditions
     10      1.1  haad  * of the GNU Lesser General Public License v.2.1.
     11      1.1  haad  *
     12      1.1  haad  * You should have received a copy of the GNU Lesser General Public License
     13      1.1  haad  * along with this program; if not, write to the Free Software Foundation,
     14      1.1  haad  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     15      1.1  haad  */
     16      1.1  haad 
     17      1.1  haad #include "tools.h"
     18      1.1  haad #include "polldaemon.h"
     19      1.1  haad #include "lv_alloc.h"
     20      1.1  haad 
     21      1.1  haad struct lvconvert_params {
     22      1.1  haad 	int snapshot;
     23      1.1  haad 	int zero;
     24      1.1  haad 
     25      1.1  haad 	const char *origin;
     26      1.1  haad 	const char *lv_name;
     27      1.1  haad 	const char *lv_name_full;
     28      1.1  haad 	const char *vg_name;
     29      1.1  haad 	int wait_completion;
     30      1.1  haad 	int need_polling;
     31      1.1  haad 
     32      1.1  haad 	uint32_t chunk_size;
     33      1.1  haad 	uint32_t region_size;
     34      1.1  haad 
     35      1.1  haad 	uint32_t mirrors;
     36      1.1  haad 	sign_t mirrors_sign;
     37      1.1  haad 
     38      1.1  haad 	struct segment_type *segtype;
     39      1.1  haad 
     40      1.1  haad 	alloc_policy_t alloc;
     41      1.1  haad 
     42      1.1  haad 	int pv_count;
     43      1.1  haad 	char **pvs;
     44      1.1  haad 	struct dm_list *pvh;
     45      1.1  haad };
     46      1.1  haad 
     47      1.1  haad static int _lvconvert_name_params(struct lvconvert_params *lp,
     48      1.1  haad 				  struct cmd_context *cmd,
     49      1.1  haad 				  int *pargc, char ***pargv)
     50      1.1  haad {
     51      1.1  haad 	char *ptr;
     52      1.1  haad 	const char *vg_name = NULL;
     53      1.1  haad 
     54      1.1  haad 	if (lp->snapshot) {
     55      1.1  haad 		if (!*pargc) {
     56      1.1  haad 			log_error("Please specify a logical volume to act as "
     57      1.1  haad 				  "the snapshot origin.");
     58      1.1  haad 			return 0;
     59      1.1  haad 		}
     60      1.1  haad 
     61      1.1  haad 		lp->origin = *pargv[0];
     62      1.1  haad 		(*pargv)++, (*pargc)--;
     63      1.1  haad 		if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) {
     64      1.1  haad 			log_error("The origin name should include the "
     65      1.1  haad 				  "volume group.");
     66      1.1  haad 			return 0;
     67      1.1  haad 		}
     68      1.1  haad 
     69      1.1  haad 		/* Strip the volume group from the origin */
     70      1.1  haad 		if ((ptr = strrchr(lp->origin, (int) '/')))
     71      1.1  haad 			lp->origin = ptr + 1;
     72      1.1  haad 	}
     73      1.1  haad 
     74      1.1  haad 	if (!*pargc) {
     75      1.1  haad 		log_error("Please provide logical volume path");
     76      1.1  haad 		return 0;
     77      1.1  haad 	}
     78      1.1  haad 
     79      1.1  haad 	lp->lv_name = lp->lv_name_full = (*pargv)[0];
     80      1.1  haad 	(*pargv)++, (*pargc)--;
     81      1.1  haad 
     82      1.1  haad 	if (strchr(lp->lv_name_full, '/') &&
     83      1.1  haad 	    (vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
     84      1.1  haad 	    lp->vg_name && strcmp(vg_name, lp->vg_name)) {
     85      1.1  haad 		log_error("Please use a single volume group name "
     86      1.1  haad 			  "(\"%s\" or \"%s\")", vg_name, lp->vg_name);
     87      1.1  haad 		return 0;
     88      1.1  haad 	}
     89      1.1  haad 
     90      1.1  haad 	if (!lp->vg_name)
     91      1.1  haad 		lp->vg_name = vg_name;
     92      1.1  haad 
     93      1.1  haad 	if (!validate_name(lp->vg_name)) {
     94      1.1  haad 		log_error("Please provide a valid volume group name");
     95      1.1  haad 		return 0;
     96      1.1  haad 	}
     97      1.1  haad 
     98      1.1  haad 	if ((ptr = strrchr(lp->lv_name_full, '/')))
     99      1.1  haad 		lp->lv_name = ptr + 1;
    100      1.1  haad 
    101      1.1  haad 	if (!apply_lvname_restrictions(lp->lv_name))
    102      1.1  haad 		return_0;
    103      1.1  haad 
    104      1.1  haad 	return 1;
    105      1.1  haad }
    106      1.1  haad 
    107      1.1  haad static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
    108      1.1  haad 			int argc, char **argv)
    109      1.1  haad {
    110      1.1  haad 	int region_size;
    111      1.1  haad 	int pagesize = lvm_getpagesize();
    112      1.1  haad 
    113      1.1  haad 	memset(lp, 0, sizeof(*lp));
    114      1.1  haad 
    115      1.1  haad 	if (arg_count(cmd, snapshot_ARG) &&
    116  1.1.1.2  haad 	    (arg_count(cmd, mirrorlog_ARG) || arg_count(cmd, mirrors_ARG) ||
    117  1.1.1.2  haad 	     arg_count(cmd, repair_ARG))) {
    118  1.1.1.2  haad 		log_error("--snapshot argument cannot be mixed "
    119  1.1.1.2  haad 			  "with --mirrors, --repair or --log");
    120      1.1  haad 		return 0;
    121      1.1  haad 	}
    122      1.1  haad 
    123      1.1  haad 	if (!arg_count(cmd, background_ARG))
    124      1.1  haad 		lp->wait_completion = 1;
    125      1.1  haad 
    126      1.1  haad 	if (arg_count(cmd, snapshot_ARG))
    127      1.1  haad 		lp->snapshot = 1;
    128      1.1  haad 
    129      1.1  haad 	if (arg_count(cmd, mirrors_ARG)) {
    130      1.1  haad 		lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0);
    131      1.1  haad 		lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, 0);
    132      1.1  haad 	}
    133      1.1  haad 
    134  1.1.1.2  haad 	lp->alloc = arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT);
    135      1.1  haad 
    136      1.1  haad 	if (lp->snapshot) {
    137      1.1  haad 		if (arg_count(cmd, regionsize_ARG)) {
    138      1.1  haad 			log_error("--regionsize is only available with mirrors");
    139      1.1  haad 			return 0;
    140      1.1  haad 		}
    141      1.1  haad 
    142      1.1  haad 		if (arg_sign_value(cmd, chunksize_ARG, 0) == SIGN_MINUS) {
    143      1.1  haad 			log_error("Negative chunk size is invalid");
    144      1.1  haad 			return 0;
    145      1.1  haad 		}
    146      1.1  haad 		lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
    147      1.1  haad 		if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
    148      1.1  haad 		    (lp->chunk_size & (lp->chunk_size - 1))) {
    149      1.1  haad 			log_error("Chunk size must be a power of 2 in the "
    150      1.1  haad 				  "range 4K to 512K");
    151      1.1  haad 			return 0;
    152      1.1  haad 		}
    153      1.1  haad 		log_verbose("Setting chunksize to %d sectors.", lp->chunk_size);
    154      1.1  haad 
    155      1.1  haad 		if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
    156      1.1  haad 			return_0;
    157      1.1  haad 
    158      1.1  haad 		lp->zero = strcmp(arg_str_value(cmd, zero_ARG,
    159      1.1  haad 						(lp->segtype->flags &
    160      1.1  haad 						 SEG_CANNOT_BE_ZEROED) ?
    161      1.1  haad 						"n" : "y"), "n");
    162      1.1  haad 
    163      1.1  haad 	} else {	/* Mirrors */
    164      1.1  haad 		if (arg_count(cmd, chunksize_ARG)) {
    165      1.1  haad 			log_error("--chunksize is only available with "
    166      1.1  haad 				  "snapshots");
    167      1.1  haad 			return 0;
    168      1.1  haad 		}
    169      1.1  haad 
    170      1.1  haad 		if (arg_count(cmd, zero_ARG)) {
    171      1.1  haad 			log_error("--zero is only available with snapshots");
    172      1.1  haad 			return 0;
    173      1.1  haad 		}
    174      1.1  haad 
    175      1.1  haad 		/*
    176      1.1  haad 	 	 * --regionsize is only valid if converting an LV into a mirror.
    177      1.1  haad 	 	 * Checked when we know the state of the LV being converted.
    178      1.1  haad 	 	 */
    179      1.1  haad 
    180      1.1  haad 		if (arg_count(cmd, regionsize_ARG)) {
    181      1.1  haad 			if (arg_sign_value(cmd, regionsize_ARG, 0) ==
    182      1.1  haad 				    SIGN_MINUS) {
    183      1.1  haad 				log_error("Negative regionsize is invalid");
    184      1.1  haad 				return 0;
    185      1.1  haad 			}
    186      1.1  haad 			lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
    187      1.1  haad 		} else {
    188      1.1  haad 			region_size = 2 * find_config_tree_int(cmd,
    189      1.1  haad 						"activation/mirror_region_size",
    190      1.1  haad 						DEFAULT_MIRROR_REGION_SIZE);
    191      1.1  haad 			if (region_size < 0) {
    192      1.1  haad 				log_error("Negative regionsize in "
    193      1.1  haad 					  "configuration file is invalid");
    194      1.1  haad 				return 0;
    195      1.1  haad 			}
    196      1.1  haad 			lp->region_size = region_size;
    197      1.1  haad 		}
    198      1.1  haad 
    199      1.1  haad 		if (lp->region_size % (pagesize >> SECTOR_SHIFT)) {
    200      1.1  haad 			log_error("Region size (%" PRIu32 ") must be "
    201      1.1  haad 				  "a multiple of machine memory "
    202      1.1  haad 				  "page size (%d)",
    203      1.1  haad 				  lp->region_size, pagesize >> SECTOR_SHIFT);
    204      1.1  haad 			return 0;
    205      1.1  haad 		}
    206      1.1  haad 
    207      1.1  haad 		if (lp->region_size & (lp->region_size - 1)) {
    208      1.1  haad 			log_error("Region size (%" PRIu32
    209      1.1  haad 				  ") must be a power of 2", lp->region_size);
    210      1.1  haad 			return 0;
    211      1.1  haad 		}
    212      1.1  haad 
    213      1.1  haad 		if (!lp->region_size) {
    214      1.1  haad 			log_error("Non-zero region size must be supplied.");
    215      1.1  haad 			return 0;
    216      1.1  haad 		}
    217      1.1  haad 
    218      1.1  haad 		if (!(lp->segtype = get_segtype_from_string(cmd, "mirror")))
    219      1.1  haad 			return_0;
    220      1.1  haad 	}
    221      1.1  haad 
    222      1.1  haad 	if (activation() && lp->segtype->ops->target_present &&
    223  1.1.1.2  haad 	    !lp->segtype->ops->target_present(cmd, NULL, NULL)) {
    224      1.1  haad 		log_error("%s: Required device-mapper target(s) not "
    225      1.1  haad 			  "detected in your kernel", lp->segtype->name);
    226      1.1  haad 		return 0;
    227      1.1  haad 	}
    228      1.1  haad 
    229      1.1  haad 	if (!_lvconvert_name_params(lp, cmd, &argc, &argv))
    230      1.1  haad 		return_0;
    231      1.1  haad 
    232      1.1  haad 	lp->pv_count = argc;
    233      1.1  haad 	lp->pvs = argv;
    234      1.1  haad 
    235      1.1  haad 	return 1;
    236      1.1  haad }
    237      1.1  haad 
    238      1.1  haad static struct volume_group *_get_lvconvert_vg(struct cmd_context *cmd,
    239  1.1.1.2  haad 					      const char *lv_name, const char *uuid)
    240      1.1  haad {
    241      1.1  haad 	dev_close_all();
    242      1.1  haad 
    243  1.1.1.2  haad         return vg_read_for_update(cmd, extract_vgname(cmd, lv_name),
    244  1.1.1.2  haad 				  NULL, 0);
    245      1.1  haad }
    246      1.1  haad 
    247      1.1  haad static struct logical_volume *_get_lvconvert_lv(struct cmd_context *cmd __attribute((unused)),
    248      1.1  haad 						struct volume_group *vg,
    249      1.1  haad 						const char *name,
    250  1.1.1.2  haad 						const char *uuid,
    251      1.1  haad 						uint32_t lv_type __attribute((unused)))
    252      1.1  haad {
    253  1.1.1.2  haad 	struct logical_volume *lv = find_lv(vg, name);
    254  1.1.1.2  haad 
    255  1.1.1.2  haad 	if (!lv || (uuid && strcmp(uuid, (char *)&lv->lvid)))
    256  1.1.1.2  haad 		return NULL;
    257  1.1.1.2  haad 
    258  1.1.1.2  haad 	return lv;
    259      1.1  haad }
    260      1.1  haad 
    261      1.1  haad static int _update_lvconvert_mirror(struct cmd_context *cmd __attribute((unused)),
    262      1.1  haad 				    struct volume_group *vg __attribute((unused)),
    263      1.1  haad 				    struct logical_volume *lv __attribute((unused)),
    264      1.1  haad 				    struct dm_list *lvs_changed __attribute((unused)),
    265      1.1  haad 				    unsigned flags __attribute((unused)))
    266      1.1  haad {
    267      1.1  haad 	/* lvconvert mirror doesn't require periodical metadata update */
    268      1.1  haad 	return 1;
    269      1.1  haad }
    270      1.1  haad 
    271      1.1  haad static int _finish_lvconvert_mirror(struct cmd_context *cmd,
    272      1.1  haad 				    struct volume_group *vg,
    273      1.1  haad 				    struct logical_volume *lv,
    274      1.1  haad 				    struct dm_list *lvs_changed __attribute((unused)))
    275      1.1  haad {
    276  1.1.1.2  haad 	int r = 0;
    277  1.1.1.2  haad 
    278      1.1  haad 	if (!collapse_mirrored_lv(lv)) {
    279      1.1  haad 		log_error("Failed to remove temporary sync layer.");
    280      1.1  haad 		return 0;
    281      1.1  haad 	}
    282      1.1  haad 
    283      1.1  haad 	lv->status &= ~CONVERTING;
    284      1.1  haad 
    285      1.1  haad 	log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
    286      1.1  haad 
    287      1.1  haad 	if (!vg_write(vg))
    288      1.1  haad 		return_0;
    289      1.1  haad 
    290      1.1  haad 	if (!suspend_lv(cmd, lv)) {
    291      1.1  haad 		log_error("Failed to lock %s", lv->name);
    292      1.1  haad 		vg_revert(vg);
    293  1.1.1.2  haad 		goto out;
    294      1.1  haad 	}
    295      1.1  haad 
    296      1.1  haad 	if (!vg_commit(vg)) {
    297      1.1  haad 		resume_lv(cmd, lv);
    298  1.1.1.2  haad 		goto_out;
    299      1.1  haad 	}
    300      1.1  haad 
    301      1.1  haad 	log_very_verbose("Updating \"%s\" in kernel", lv->name);
    302      1.1  haad 
    303      1.1  haad 	if (!resume_lv(cmd, lv)) {
    304      1.1  haad 		log_error("Problem reactivating %s", lv->name);
    305  1.1.1.2  haad 		goto out;
    306      1.1  haad 	}
    307      1.1  haad 
    308  1.1.1.2  haad 	r = 1;
    309      1.1  haad 	log_print("Logical volume %s converted.", lv->name);
    310  1.1.1.2  haad out:
    311  1.1.1.2  haad 	backup(vg);
    312  1.1.1.2  haad 	return r;
    313      1.1  haad }
    314      1.1  haad 
    315      1.1  haad static struct poll_functions _lvconvert_mirror_fns = {
    316      1.1  haad 	.get_copy_vg = _get_lvconvert_vg,
    317      1.1  haad 	.get_copy_lv = _get_lvconvert_lv,
    318  1.1.1.2  haad 	.poll_progress = poll_mirror_progress,
    319      1.1  haad 	.update_metadata = _update_lvconvert_mirror,
    320      1.1  haad 	.finish_copy = _finish_lvconvert_mirror,
    321      1.1  haad };
    322      1.1  haad 
    323  1.1.1.2  haad int lvconvert_poll(struct cmd_context *cmd, struct logical_volume *lv,
    324      1.1  haad 		   unsigned background)
    325      1.1  haad {
    326  1.1.1.2  haad 	int len = strlen(lv->vg->name) + strlen(lv->name) + 2;
    327  1.1.1.2  haad 	char *uuid = alloca(sizeof(lv->lvid));
    328  1.1.1.2  haad 	char *lv_full_name = alloca(len);
    329  1.1.1.2  haad 
    330  1.1.1.2  haad 
    331  1.1.1.2  haad 	if (!uuid || !lv_full_name)
    332  1.1.1.2  haad 		return_0;
    333  1.1.1.2  haad 
    334  1.1.1.2  haad 	if (!dm_snprintf(lv_full_name, len, "%s/%s", lv->vg->name, lv->name))
    335  1.1.1.2  haad 		return_0;
    336  1.1.1.2  haad 
    337  1.1.1.2  haad 	memcpy(uuid, &lv->lvid, sizeof(lv->lvid));
    338  1.1.1.2  haad 
    339  1.1.1.2  haad 	return poll_daemon(cmd, lv_full_name, uuid, background, 0,
    340  1.1.1.2  haad 			   &_lvconvert_mirror_fns, "Converted");
    341      1.1  haad }
    342      1.1  haad 
    343      1.1  haad static int _insert_lvconvert_layer(struct cmd_context *cmd,
    344      1.1  haad 				   struct logical_volume *lv)
    345      1.1  haad {
    346      1.1  haad 	char *format, *layer_name;
    347      1.1  haad 	size_t len;
    348      1.1  haad 	int i;
    349      1.1  haad 
    350      1.1  haad 	/*
    351      1.1  haad  	 * We would like to give the same number for this layer
    352      1.1  haad  	 * and the newly added mimage.
    353      1.1  haad  	 * However, LV name of newly added mimage is determined *after*
    354      1.1  haad 	 * the LV name of this layer is determined.
    355      1.1  haad 	 *
    356      1.1  haad 	 * So, use generate_lv_name() to generate mimage name first
    357      1.1  haad 	 * and take the number from it.
    358      1.1  haad 	 */
    359      1.1  haad 
    360      1.1  haad 	len = strlen(lv->name) + 32;
    361      1.1  haad 	if (!(format = alloca(len)) ||
    362      1.1  haad 	    !(layer_name = alloca(len)) ||
    363      1.1  haad 	    dm_snprintf(format, len, "%s_mimage_%%d", lv->name) < 0) {
    364      1.1  haad 		log_error("lvconvert: layer name allocation failed.");
    365      1.1  haad 		return 0;
    366      1.1  haad 	}
    367      1.1  haad 
    368      1.1  haad 	if (!generate_lv_name(lv->vg, format, layer_name, len) ||
    369      1.1  haad 	    sscanf(layer_name, format, &i) != 1) {
    370      1.1  haad 		log_error("lvconvert: layer name generation failed.");
    371      1.1  haad 		return 0;
    372      1.1  haad 	}
    373      1.1  haad 
    374      1.1  haad 	if (dm_snprintf(layer_name, len, MIRROR_SYNC_LAYER "_%d", i) < 0) {
    375      1.1  haad 		log_error("layer name allocation failed.");
    376      1.1  haad 		return 0;
    377      1.1  haad 	}
    378      1.1  haad 
    379      1.1  haad 	if (!insert_layer_for_lv(cmd, lv, 0, layer_name)) {
    380      1.1  haad 		log_error("Failed to insert resync layer");
    381      1.1  haad 		return 0;
    382      1.1  haad 	}
    383      1.1  haad 
    384      1.1  haad 	return 1;
    385      1.1  haad }
    386      1.1  haad 
    387  1.1.1.2  haad static int _area_missing(struct lv_segment *lvseg, int s)
    388  1.1.1.2  haad {
    389  1.1.1.2  haad 	if (seg_type(lvseg, s) == AREA_LV) {
    390  1.1.1.2  haad 		if (seg_lv(lvseg, s)->status & PARTIAL_LV)
    391  1.1.1.2  haad 			return 1;
    392  1.1.1.2  haad 	} else if ((seg_type(lvseg, s) == AREA_PV) &&
    393  1.1.1.2  haad 		   (seg_pv(lvseg, s)->status & MISSING_PV))
    394  1.1.1.2  haad 		return 1;
    395  1.1.1.2  haad 
    396  1.1.1.2  haad 	return 0;
    397  1.1.1.2  haad }
    398  1.1.1.2  haad 
    399  1.1.1.2  haad /* FIXME we want to handle mirror stacks here... */
    400  1.1.1.2  haad static int _failed_mirrors_count(struct logical_volume *lv)
    401  1.1.1.2  haad {
    402  1.1.1.2  haad 	struct lv_segment *lvseg;
    403  1.1.1.2  haad 	int ret = 0;
    404  1.1.1.2  haad 	int s;
    405  1.1.1.2  haad 
    406  1.1.1.2  haad 	dm_list_iterate_items(lvseg, &lv->segments) {
    407  1.1.1.2  haad 		if (!seg_is_mirrored(lvseg))
    408  1.1.1.2  haad 			return -1;
    409  1.1.1.2  haad 		for (s = 0; s < lvseg->area_count; s++)
    410  1.1.1.2  haad 			if (_area_missing(lvseg, s))
    411  1.1.1.2  haad 				ret++;
    412  1.1.1.2  haad 	}
    413  1.1.1.2  haad 
    414  1.1.1.2  haad 	return ret;
    415  1.1.1.2  haad }
    416  1.1.1.2  haad 
    417  1.1.1.2  haad static struct dm_list *_failed_pv_list(struct volume_group *vg)
    418  1.1.1.2  haad {
    419  1.1.1.2  haad 	struct dm_list *failed_pvs;
    420  1.1.1.2  haad 	struct pv_list *pvl, *new_pvl;
    421  1.1.1.2  haad 
    422  1.1.1.2  haad 	if (!(failed_pvs = dm_pool_alloc(vg->vgmem, sizeof(*failed_pvs)))) {
    423  1.1.1.2  haad 		log_error("Allocation of list of failed_pvs failed.");
    424  1.1.1.2  haad 		return_NULL;
    425  1.1.1.2  haad 	}
    426  1.1.1.2  haad 
    427  1.1.1.2  haad 	dm_list_init(failed_pvs);
    428  1.1.1.2  haad 
    429  1.1.1.2  haad 	dm_list_iterate_items(pvl, &vg->pvs) {
    430  1.1.1.2  haad 		if (!(pvl->pv->status & MISSING_PV))
    431  1.1.1.2  haad 			continue;
    432  1.1.1.2  haad 
    433  1.1.1.2  haad 		if (!(new_pvl = dm_pool_alloc(vg->vgmem, sizeof(*new_pvl)))) {
    434  1.1.1.2  haad 			log_error("Allocation of failed_pvs list entry failed.");
    435  1.1.1.2  haad 			return_NULL;
    436  1.1.1.2  haad 		}
    437  1.1.1.2  haad 		new_pvl->pv = pvl->pv;
    438  1.1.1.2  haad 		dm_list_add(failed_pvs, &new_pvl->list);
    439  1.1.1.2  haad 	}
    440  1.1.1.2  haad 
    441  1.1.1.2  haad 	return failed_pvs;
    442  1.1.1.2  haad }
    443  1.1.1.2  haad 
    444  1.1.1.2  haad /*
    445  1.1.1.2  haad  * Walk down the stacked mirror LV to the original mirror LV.
    446  1.1.1.2  haad  */
    447      1.1  haad static struct logical_volume *_original_lv(struct logical_volume *lv)
    448      1.1  haad {
    449      1.1  haad 	struct logical_volume *next_lv = lv, *tmp_lv;
    450      1.1  haad 
    451      1.1  haad 	while ((tmp_lv = find_temporary_mirror(next_lv)))
    452      1.1  haad 		next_lv = tmp_lv;
    453      1.1  haad 
    454      1.1  haad 	return next_lv;
    455      1.1  haad }
    456      1.1  haad 
    457  1.1.1.2  haad static void _lvconvert_mirrors_repair_ask(struct cmd_context *cmd,
    458  1.1.1.2  haad 					  int failed_log, int failed_mirrors,
    459  1.1.1.2  haad 					  int *replace_log, int *replace_mirrors)
    460  1.1.1.2  haad {
    461  1.1.1.2  haad 	const char *leg_policy = NULL, *log_policy = NULL;
    462  1.1.1.2  haad 
    463  1.1.1.2  haad 	int force = arg_count(cmd, force_ARG);
    464  1.1.1.2  haad 	int yes = arg_count(cmd, yes_ARG);
    465  1.1.1.2  haad 
    466  1.1.1.2  haad 	*replace_log = *replace_mirrors = 1;
    467  1.1.1.2  haad 
    468  1.1.1.2  haad 	if (arg_count(cmd, use_policies_ARG)) {
    469  1.1.1.2  haad 		leg_policy = find_config_tree_str(cmd,
    470  1.1.1.2  haad 					"activation/mirror_device_fault_policy",
    471  1.1.1.2  haad 					DEFAULT_MIRROR_DEVICE_FAULT_POLICY);
    472  1.1.1.2  haad 		log_policy = find_config_tree_str(cmd,
    473  1.1.1.2  haad 					"activation/mirror_log_fault_policy",
    474  1.1.1.2  haad 					DEFAULT_MIRROR_LOG_FAULT_POLICY);
    475  1.1.1.2  haad 		*replace_mirrors = strcmp(leg_policy, "remove");
    476  1.1.1.2  haad 		*replace_log = strcmp(log_policy, "remove");
    477  1.1.1.2  haad 		return;
    478  1.1.1.2  haad 	}
    479  1.1.1.2  haad 
    480  1.1.1.2  haad 	if (yes)
    481  1.1.1.2  haad 		return;
    482  1.1.1.2  haad 
    483  1.1.1.2  haad 	if (force != PROMPT) {
    484  1.1.1.2  haad 		*replace_log = *replace_mirrors = 0;
    485  1.1.1.2  haad 		return;
    486  1.1.1.2  haad 	}
    487  1.1.1.2  haad 
    488  1.1.1.2  haad 	if (failed_log &&
    489  1.1.1.2  haad 	    yes_no_prompt("Attempt to replace failed mirror log? [y/n]: ") == 'n') {
    490  1.1.1.2  haad 		*replace_log = 0;
    491  1.1.1.2  haad 	}
    492  1.1.1.2  haad 
    493  1.1.1.2  haad 	if (failed_mirrors &&
    494  1.1.1.2  haad 	    yes_no_prompt("Attempt to replace failed mirror images "
    495  1.1.1.2  haad 			  "(requires full device resync)? [y/n]: ") == 'n') {
    496  1.1.1.2  haad 		*replace_mirrors = 0;
    497  1.1.1.2  haad 	}
    498  1.1.1.2  haad }
    499  1.1.1.2  haad 
    500  1.1.1.2  haad static int _using_corelog(struct logical_volume *lv)
    501  1.1.1.2  haad {
    502  1.1.1.2  haad 	return !first_seg(_original_lv(lv))->log_lv;
    503  1.1.1.2  haad }
    504  1.1.1.2  haad 
    505  1.1.1.2  haad static int _lv_update_log_type(struct cmd_context *cmd,
    506  1.1.1.2  haad 			       struct lvconvert_params *lp,
    507  1.1.1.2  haad 			       struct logical_volume *lv,
    508  1.1.1.2  haad 			       int corelog)
    509  1.1.1.2  haad {
    510  1.1.1.2  haad 	struct logical_volume *original_lv = _original_lv(lv);
    511  1.1.1.2  haad 	if (_using_corelog(lv) && !corelog) {
    512  1.1.1.2  haad 		if (!add_mirror_log(cmd, original_lv, 1,
    513  1.1.1.2  haad 				    adjusted_mirror_region_size(
    514  1.1.1.2  haad 					lv->vg->extent_size,
    515  1.1.1.2  haad 					lv->le_count,
    516  1.1.1.2  haad 					lp->region_size),
    517  1.1.1.2  haad 				    lp->pvh, lp->alloc))
    518  1.1.1.2  haad 			return_0;
    519  1.1.1.2  haad 	} else if (!_using_corelog(lv) && corelog) {
    520  1.1.1.2  haad 		if (!remove_mirror_log(cmd, original_lv,
    521  1.1.1.2  haad 				       lp->pv_count ? lp->pvh : NULL))
    522  1.1.1.2  haad 			return_0;
    523  1.1.1.2  haad 	}
    524  1.1.1.2  haad 	return 1;
    525  1.1.1.2  haad }
    526  1.1.1.2  haad 
    527  1.1.1.2  haad static int _lvconvert_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
    528  1.1.1.2  haad 			      struct lvconvert_params *lp)
    529      1.1  haad {
    530      1.1  haad 	struct lv_segment *seg;
    531      1.1  haad 	uint32_t existing_mirrors;
    532      1.1  haad 	const char *mirrorlog;
    533      1.1  haad 	unsigned corelog = 0;
    534  1.1.1.2  haad 	int r = 0;
    535  1.1.1.2  haad 	struct logical_volume *log_lv, *layer_lv;
    536  1.1.1.2  haad 	int failed_mirrors = 0, failed_log = 0;
    537  1.1.1.2  haad 	struct dm_list *old_pvh = NULL, *remove_pvs = NULL;
    538  1.1.1.2  haad 
    539  1.1.1.2  haad 	int repair = arg_count(cmd, repair_ARG);
    540  1.1.1.2  haad 	int replace_log = 1, replace_mirrors = 1;
    541      1.1  haad 
    542      1.1  haad 	seg = first_seg(lv);
    543      1.1  haad 	existing_mirrors = lv_mirror_count(lv);
    544      1.1  haad 
    545      1.1  haad 	/* If called with no argument, try collapsing the resync layers */
    546      1.1  haad 	if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG) &&
    547  1.1.1.2  haad 	    !arg_count(cmd, corelog_ARG) && !arg_count(cmd, regionsize_ARG) &&
    548  1.1.1.2  haad 	    !repair) {
    549  1.1.1.2  haad 		if (find_temporary_mirror(lv) || (lv->status & CONVERTING))
    550  1.1.1.2  haad 			lp->need_polling = 1;
    551      1.1  haad 		return 1;
    552      1.1  haad 	}
    553      1.1  haad 
    554  1.1.1.2  haad 	if (arg_count(cmd, mirrors_ARG) && repair) {
    555  1.1.1.2  haad 		log_error("You may only use one of --mirrors and --repair.");
    556  1.1.1.2  haad 		return 0;
    557  1.1.1.2  haad 	}
    558  1.1.1.2  haad 
    559      1.1  haad 	/*
    560      1.1  haad 	 * Adjust required number of mirrors
    561      1.1  haad 	 *
    562      1.1  haad 	 * We check mirrors_ARG again to see if it
    563      1.1  haad 	 * was supplied.  If not, they want the mirror
    564      1.1  haad 	 * count to remain the same.  They may be changing
    565      1.1  haad 	 * the logging type.
    566      1.1  haad 	 */
    567      1.1  haad 	if (!arg_count(cmd, mirrors_ARG))
    568      1.1  haad 		lp->mirrors = existing_mirrors;
    569      1.1  haad 	else if (lp->mirrors_sign == SIGN_PLUS)
    570      1.1  haad 		lp->mirrors = existing_mirrors + lp->mirrors;
    571      1.1  haad 	else if (lp->mirrors_sign == SIGN_MINUS)
    572      1.1  haad 		lp->mirrors = existing_mirrors - lp->mirrors;
    573      1.1  haad 	else
    574      1.1  haad 		lp->mirrors += 1;
    575      1.1  haad 
    576  1.1.1.2  haad 	if (repair) {
    577  1.1.1.2  haad 		cmd->handles_missing_pvs = 1;
    578  1.1.1.2  haad 		cmd->partial_activation = 1;
    579  1.1.1.2  haad 		lp->need_polling = 0;
    580  1.1.1.2  haad 		if (!(lv->status & PARTIAL_LV)) {
    581  1.1.1.2  haad 			log_error("The mirror is consistent, nothing to repair.");
    582  1.1.1.2  haad 			return 0;
    583  1.1.1.2  haad 		}
    584  1.1.1.2  haad 		if ((failed_mirrors = _failed_mirrors_count(lv)) < 0)
    585  1.1.1.2  haad 			return_0;
    586  1.1.1.2  haad 		lp->mirrors -= failed_mirrors;
    587  1.1.1.2  haad 		log_error("Mirror status: %d of %d images failed.",
    588  1.1.1.2  haad 			  failed_mirrors, existing_mirrors);
    589  1.1.1.2  haad 		old_pvh = lp->pvh;
    590  1.1.1.2  haad 		if (!(lp->pvh = _failed_pv_list(lv->vg)))
    591  1.1.1.2  haad 			return_0;
    592  1.1.1.2  haad 		log_lv=first_seg(lv)->log_lv;
    593  1.1.1.2  haad 		if (!log_lv || log_lv->status & PARTIAL_LV)
    594  1.1.1.2  haad 			failed_log = corelog = 1;
    595  1.1.1.2  haad 	} else {
    596  1.1.1.2  haad 		/*
    597  1.1.1.2  haad 		 * Did the user try to subtract more legs than available?
    598  1.1.1.2  haad 		 */
    599  1.1.1.2  haad 		if (lp->mirrors < 1) {
    600  1.1.1.2  haad 			log_error("Logical volume %s only has %" PRIu32 " mirrors.",
    601  1.1.1.2  haad 				  lv->name, existing_mirrors);
    602  1.1.1.2  haad 			return 0;
    603  1.1.1.2  haad 		}
    604      1.1  haad 
    605  1.1.1.2  haad 		/*
    606  1.1.1.2  haad 		 * Adjust log type
    607  1.1.1.2  haad 		 */
    608  1.1.1.2  haad 		if (arg_count(cmd, corelog_ARG))
    609  1.1.1.2  haad 			corelog = 1;
    610      1.1  haad 
    611  1.1.1.2  haad 		mirrorlog = arg_str_value(cmd, mirrorlog_ARG,
    612  1.1.1.2  haad 					  corelog ? "core" : DEFAULT_MIRRORLOG);
    613  1.1.1.2  haad 		if (!strcmp("disk", mirrorlog)) {
    614  1.1.1.2  haad 			if (corelog) {
    615  1.1.1.2  haad 				log_error("--mirrorlog disk and --corelog "
    616  1.1.1.2  haad 					  "are incompatible");
    617  1.1.1.2  haad 				return 0;
    618  1.1.1.2  haad 			}
    619  1.1.1.2  haad 			corelog = 0;
    620  1.1.1.2  haad 		} else if (!strcmp("core", mirrorlog))
    621  1.1.1.2  haad 			corelog = 1;
    622  1.1.1.2  haad 		else {
    623  1.1.1.2  haad 			log_error("Unknown mirrorlog type: %s", mirrorlog);
    624      1.1  haad 			return 0;
    625      1.1  haad 		}
    626      1.1  haad 
    627  1.1.1.2  haad 		log_verbose("Setting logging type to %s", mirrorlog);
    628  1.1.1.2  haad 	}
    629      1.1  haad 
    630      1.1  haad 	/*
    631      1.1  haad 	 * Region size must not change on existing mirrors
    632      1.1  haad 	 */
    633      1.1  haad 	if (arg_count(cmd, regionsize_ARG) && (lv->status & MIRRORED) &&
    634      1.1  haad 	    (lp->region_size != seg->region_size)) {
    635      1.1  haad 		log_error("Mirror log region size cannot be changed on "
    636      1.1  haad 			  "an existing mirror.");
    637      1.1  haad 		return 0;
    638      1.1  haad 	}
    639      1.1  haad 
    640      1.1  haad 	/*
    641  1.1.1.2  haad 	 * For the most part, we cannot handle multi-segment mirrors. Bail out
    642  1.1.1.2  haad 	 * early if we have encountered one.
    643  1.1.1.2  haad 	 */
    644  1.1.1.2  haad 	if ((lv->status & MIRRORED) && dm_list_size(&lv->segments) != 1) {
    645  1.1.1.2  haad 		log_error("Logical volume %s has multiple "
    646  1.1.1.2  haad 			  "mirror segments.", lv->name);
    647  1.1.1.2  haad 		return 0;
    648  1.1.1.2  haad 	}
    649  1.1.1.2  haad 
    650  1.1.1.2  haad 	if (repair)
    651  1.1.1.2  haad 		_lvconvert_mirrors_repair_ask(cmd, failed_log, failed_mirrors,
    652  1.1.1.2  haad 					      &replace_log, &replace_mirrors);
    653  1.1.1.2  haad 
    654  1.1.1.2  haad  restart:
    655  1.1.1.2  haad 	/*
    656      1.1  haad 	 * Converting from mirror to linear
    657      1.1  haad 	 */
    658      1.1  haad 	if ((lp->mirrors == 1)) {
    659      1.1  haad 		if (!(lv->status & MIRRORED)) {
    660      1.1  haad 			log_error("Logical volume %s is already not mirrored.",
    661      1.1  haad 				  lv->name);
    662      1.1  haad 			return 1;
    663      1.1  haad 		}
    664      1.1  haad 	}
    665      1.1  haad 
    666      1.1  haad 	/*
    667  1.1.1.2  haad 	 * Downconversion.
    668      1.1  haad 	 */
    669  1.1.1.2  haad 	if (lp->mirrors < existing_mirrors) {
    670  1.1.1.2  haad 		/* Reduce number of mirrors */
    671  1.1.1.2  haad 		if (repair || lp->pv_count)
    672  1.1.1.2  haad 			remove_pvs = lp->pvh;
    673  1.1.1.2  haad 		if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
    674  1.1.1.2  haad 				       (corelog || lp->mirrors == 1) ? 1U : 0U,
    675  1.1.1.2  haad 				       remove_pvs, 0))
    676  1.1.1.2  haad 			return_0;
    677  1.1.1.2  haad 		if (lp->mirrors > 1 &&
    678  1.1.1.2  haad 		    !_lv_update_log_type(cmd, lp, lv, corelog))
    679  1.1.1.2  haad 			return_0;
    680  1.1.1.2  haad 	} else if (!(lv->status & MIRRORED)) {
    681  1.1.1.2  haad 		/*
    682  1.1.1.2  haad 		 * Converting from linear to mirror
    683  1.1.1.2  haad 		 */
    684  1.1.1.2  haad 
    685      1.1  haad 		/* FIXME Share code with lvcreate */
    686      1.1  haad 
    687      1.1  haad 		/* FIXME Why is this restriction here?  Fix it! */
    688      1.1  haad 		dm_list_iterate_items(seg, &lv->segments) {
    689      1.1  haad 			if (seg_is_striped(seg) && seg->area_count > 1) {
    690      1.1  haad 				log_error("Mirrors of striped volumes are not yet supported.");
    691      1.1  haad 				return 0;
    692      1.1  haad 			}
    693      1.1  haad 		}
    694      1.1  haad 
    695  1.1.1.2  haad 		/*
    696  1.1.1.2  haad 		 * FIXME should we give not only lp->pvh, but also all PVs
    697  1.1.1.2  haad 		 * currently taken by the mirror? Would make more sense from
    698  1.1.1.2  haad 		 * user perspective.
    699  1.1.1.2  haad 		 */
    700      1.1  haad 		if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, 1,
    701      1.1  haad 				    adjusted_mirror_region_size(
    702      1.1  haad 						lv->vg->extent_size,
    703      1.1  haad 						lv->le_count,
    704      1.1  haad 						lp->region_size),
    705      1.1  haad 				    corelog ? 0U : 1U, lp->pvh, lp->alloc,
    706      1.1  haad 				    MIRROR_BY_LV))
    707      1.1  haad 			return_0;
    708      1.1  haad 		if (lp->wait_completion)
    709      1.1  haad 			lp->need_polling = 1;
    710  1.1.1.2  haad 	} else if (lp->mirrors > existing_mirrors || failed_mirrors) {
    711  1.1.1.2  haad 		if (lv->status & MIRROR_NOTSYNCED) {
    712  1.1.1.2  haad 			log_error("Can't add mirror to out-of-sync mirrored "
    713  1.1.1.2  haad 				  "LV: use lvchange --resync first.");
    714  1.1.1.2  haad 			return 0;
    715  1.1.1.2  haad 		}
    716      1.1  haad 
    717      1.1  haad 		/*
    718  1.1.1.2  haad 		 * We allow snapshots of mirrors, but for now, we
    719  1.1.1.2  haad 		 * do not allow up converting mirrors that are under
    720  1.1.1.2  haad 		 * snapshots.  The layering logic is somewhat complex,
    721  1.1.1.2  haad 		 * and preliminary test show that the conversion can't
    722  1.1.1.2  haad 		 * seem to get the correct %'age of completion.
    723      1.1  haad 		 */
    724  1.1.1.2  haad 		if (lv_is_origin(lv)) {
    725  1.1.1.2  haad 			log_error("Can't add additional mirror images to "
    726  1.1.1.2  haad 				  "mirrors that are under snapshots");
    727      1.1  haad 			return 0;
    728      1.1  haad 		}
    729  1.1.1.2  haad 
    730      1.1  haad 		/*
    731      1.1  haad 		 * Log addition/removal should be done before the layer
    732      1.1  haad 		 * insertion to make the end result consistent with
    733      1.1  haad 		 * linear-to-mirror conversion.
    734      1.1  haad 		 */
    735  1.1.1.2  haad 		if (!_lv_update_log_type(cmd, lp, lv, corelog))
    736  1.1.1.2  haad 			return_0;
    737      1.1  haad 		/* Insert a temporary layer for syncing,
    738      1.1  haad 		 * only if the original lv is using disk log. */
    739      1.1  haad 		if (seg->log_lv && !_insert_lvconvert_layer(cmd, lv)) {
    740      1.1  haad 			log_error("Failed to insert resync layer");
    741      1.1  haad 			return 0;
    742      1.1  haad 		}
    743      1.1  haad 		/* FIXME: can't have multiple mlogs. force corelog. */
    744      1.1  haad 		if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
    745      1.1  haad 				    adjusted_mirror_region_size(
    746      1.1  haad 						lv->vg->extent_size,
    747      1.1  haad 						lv->le_count,
    748      1.1  haad 						lp->region_size),
    749      1.1  haad 				    0U, lp->pvh, lp->alloc,
    750  1.1.1.2  haad 				    MIRROR_BY_LV)) {
    751  1.1.1.2  haad 			layer_lv = seg_lv(first_seg(lv), 0);
    752  1.1.1.2  haad 			if (!remove_layer_from_lv(lv, layer_lv) ||
    753  1.1.1.2  haad 			    !deactivate_lv(cmd, layer_lv) ||
    754  1.1.1.2  haad 			    !lv_remove(layer_lv) || !vg_write(lv->vg) ||
    755  1.1.1.2  haad 			    !vg_commit(lv->vg)) {
    756  1.1.1.2  haad 				log_error("ABORTING: Failed to remove "
    757  1.1.1.2  haad 					  "temporary mirror layer %s.",
    758  1.1.1.2  haad 					  layer_lv->name);
    759  1.1.1.2  haad 				log_error("Manual cleanup with vgcfgrestore "
    760  1.1.1.2  haad 					  "and dmsetup may be required.");
    761  1.1.1.2  haad 				return 0;
    762  1.1.1.2  haad 			}
    763      1.1  haad 			return_0;
    764  1.1.1.2  haad 		}
    765      1.1  haad 		lv->status |= CONVERTING;
    766      1.1  haad 		lp->need_polling = 1;
    767      1.1  haad 	}
    768      1.1  haad 
    769  1.1.1.2  haad 	if (lp->mirrors == existing_mirrors) {
    770  1.1.1.2  haad 		if (_using_corelog(lv) != corelog) {
    771  1.1.1.2  haad 			if (!_lv_update_log_type(cmd, lp, lv, corelog))
    772  1.1.1.2  haad 				return_0;
    773  1.1.1.2  haad 		} else {
    774  1.1.1.2  haad 			log_error("Logical volume %s already has %"
    775  1.1.1.2  haad 				  PRIu32 " mirror(s).", lv->name,
    776  1.1.1.2  haad 				  lp->mirrors - 1);
    777  1.1.1.2  haad 			if (lv->status & CONVERTING)
    778  1.1.1.2  haad 				lp->need_polling = 1;
    779  1.1.1.2  haad 			return 1;
    780  1.1.1.2  haad 		}
    781  1.1.1.2  haad 	}
    782  1.1.1.2  haad 
    783      1.1  haad 	log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
    784      1.1  haad 
    785      1.1  haad 	if (!vg_write(lv->vg))
    786      1.1  haad 		return_0;
    787      1.1  haad 
    788      1.1  haad 	if (!suspend_lv(cmd, lv)) {
    789      1.1  haad 		log_error("Failed to lock %s", lv->name);
    790      1.1  haad 		vg_revert(lv->vg);
    791  1.1.1.2  haad 		goto out;
    792      1.1  haad 	}
    793      1.1  haad 
    794      1.1  haad 	if (!vg_commit(lv->vg)) {
    795      1.1  haad 		resume_lv(cmd, lv);
    796  1.1.1.2  haad 		goto_out;
    797      1.1  haad 	}
    798      1.1  haad 
    799      1.1  haad 	log_very_verbose("Updating \"%s\" in kernel", lv->name);
    800      1.1  haad 
    801      1.1  haad 	if (!resume_lv(cmd, lv)) {
    802      1.1  haad 		log_error("Problem reactivating %s", lv->name);
    803  1.1.1.2  haad 		goto out;
    804  1.1.1.2  haad 	}
    805  1.1.1.2  haad 
    806  1.1.1.2  haad 	if (failed_log || failed_mirrors) {
    807  1.1.1.2  haad 		lp->pvh = old_pvh;
    808  1.1.1.2  haad 		if (failed_log && replace_log)
    809  1.1.1.2  haad 			failed_log = corelog = 0;
    810  1.1.1.2  haad 		if (replace_mirrors)
    811  1.1.1.2  haad 			lp->mirrors += failed_mirrors;
    812  1.1.1.2  haad 		failed_mirrors = 0;
    813  1.1.1.2  haad 		existing_mirrors = lv_mirror_count(lv);
    814  1.1.1.2  haad 		/* Now replace missing devices. */
    815  1.1.1.2  haad 		if (replace_log || replace_mirrors)
    816  1.1.1.2  haad 			goto restart;
    817      1.1  haad 	}
    818      1.1  haad 
    819      1.1  haad 	if (!lp->need_polling)
    820      1.1  haad 		log_print("Logical volume %s converted.", lv->name);
    821      1.1  haad 
    822  1.1.1.2  haad 	r = 1;
    823  1.1.1.2  haad out:
    824  1.1.1.2  haad 	backup(lv->vg);
    825  1.1.1.2  haad 	return r;
    826      1.1  haad }
    827      1.1  haad 
    828      1.1  haad static int lvconvert_snapshot(struct cmd_context *cmd,
    829      1.1  haad 			      struct logical_volume *lv,
    830      1.1  haad 			      struct lvconvert_params *lp)
    831      1.1  haad {
    832      1.1  haad 	struct logical_volume *org;
    833  1.1.1.2  haad 	int r = 0;
    834      1.1  haad 
    835      1.1  haad 	if (!(org = find_lv(lv->vg, lp->origin))) {
    836      1.1  haad 		log_error("Couldn't find origin volume '%s'.", lp->origin);
    837      1.1  haad 		return 0;
    838      1.1  haad 	}
    839      1.1  haad 
    840      1.1  haad 	if (org == lv) {
    841      1.1  haad 		log_error("Unable to use \"%s\" as both snapshot and origin.",
    842      1.1  haad 			  lv->name);
    843      1.1  haad 		return 0;
    844      1.1  haad 	}
    845      1.1  haad 
    846      1.1  haad 	if (org->status & (LOCKED|PVMOVE|MIRRORED) || lv_is_cow(org)) {
    847      1.1  haad 		log_error("Unable to create a snapshot of a %s LV.",
    848      1.1  haad 			  org->status & LOCKED ? "locked" :
    849      1.1  haad 			  org->status & PVMOVE ? "pvmove" :
    850      1.1  haad 			  org->status & MIRRORED ? "mirrored" :
    851      1.1  haad 			  "snapshot");
    852      1.1  haad 		return 0;
    853      1.1  haad 	}
    854      1.1  haad 
    855      1.1  haad 	if (!lp->zero || !(lv->status & LVM_WRITE))
    856      1.1  haad 		log_warn("WARNING: \"%s\" not zeroed", lv->name);
    857      1.1  haad 	else if (!set_lv(cmd, lv, UINT64_C(0), 0)) {
    858      1.1  haad 		log_error("Aborting. Failed to wipe snapshot "
    859      1.1  haad 			  "exception store.");
    860      1.1  haad 		return 0;
    861      1.1  haad 	}
    862      1.1  haad 
    863      1.1  haad 	if (!deactivate_lv(cmd, lv)) {
    864      1.1  haad 		log_error("Couldn't deactivate LV %s.", lv->name);
    865      1.1  haad 		return 0;
    866      1.1  haad 	}
    867      1.1  haad 
    868  1.1.1.2  haad 	if (!vg_add_snapshot(org, lv, NULL, org->le_count, lp->chunk_size)) {
    869      1.1  haad 		log_error("Couldn't create snapshot.");
    870      1.1  haad 		return 0;
    871      1.1  haad 	}
    872      1.1  haad 
    873      1.1  haad 	/* store vg on disk(s) */
    874      1.1  haad 	if (!vg_write(lv->vg))
    875      1.1  haad 		return_0;
    876      1.1  haad 
    877      1.1  haad 	if (!suspend_lv(cmd, org)) {
    878      1.1  haad 		log_error("Failed to suspend origin %s", org->name);
    879      1.1  haad 		vg_revert(lv->vg);
    880  1.1.1.2  haad 		goto out;
    881      1.1  haad 	}
    882      1.1  haad 
    883      1.1  haad 	if (!vg_commit(lv->vg))
    884  1.1.1.2  haad 		goto_out;
    885      1.1  haad 
    886      1.1  haad 	if (!resume_lv(cmd, org)) {
    887      1.1  haad 		log_error("Problem reactivating origin %s", org->name);
    888  1.1.1.2  haad 		goto out;
    889      1.1  haad 	}
    890      1.1  haad 
    891      1.1  haad 	log_print("Logical volume %s converted to snapshot.", lv->name);
    892  1.1.1.2  haad 	r = 1;
    893  1.1.1.2  haad out:
    894  1.1.1.2  haad 	backup(lv->vg);
    895  1.1.1.2  haad 	return r;
    896      1.1  haad }
    897      1.1  haad 
    898      1.1  haad static int lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
    899      1.1  haad 			    void *handle)
    900      1.1  haad {
    901      1.1  haad 	struct lvconvert_params *lp = handle;
    902      1.1  haad 
    903      1.1  haad 	if (lv->status & LOCKED) {
    904      1.1  haad 		log_error("Cannot convert locked LV %s", lv->name);
    905      1.1  haad 		return ECMD_FAILED;
    906      1.1  haad 	}
    907      1.1  haad 
    908      1.1  haad 	if (lv_is_cow(lv)) {
    909      1.1  haad 		log_error("Can't convert snapshot logical volume \"%s\"",
    910      1.1  haad 			  lv->name);
    911      1.1  haad 		return ECMD_FAILED;
    912      1.1  haad 	}
    913      1.1  haad 
    914      1.1  haad 	if (lv->status & PVMOVE) {
    915      1.1  haad 		log_error("Unable to convert pvmove LV %s", lv->name);
    916      1.1  haad 		return ECMD_FAILED;
    917      1.1  haad 	}
    918      1.1  haad 
    919  1.1.1.2  haad 	if (arg_count(cmd, repair_ARG) && !(lv->status & MIRRORED)) {
    920  1.1.1.2  haad 		log_error("Can't repair non-mirrored LV \"%s\".", lv->name);
    921  1.1.1.2  haad 		return ECMD_FAILED;
    922  1.1.1.2  haad 	}
    923  1.1.1.2  haad 
    924      1.1  haad 	if (lp->snapshot) {
    925      1.1  haad 		if (lv->status & MIRRORED) {
    926      1.1  haad 			log_error("Unable to convert mirrored LV \"%s\" into a snapshot.", lv->name);
    927      1.1  haad 			return ECMD_FAILED;
    928      1.1  haad 		}
    929  1.1.1.2  haad 		if (!archive(lv->vg)) {
    930  1.1.1.2  haad 			stack;
    931      1.1  haad 			return ECMD_FAILED;
    932  1.1.1.2  haad 		}
    933  1.1.1.2  haad 		if (!lvconvert_snapshot(cmd, lv, lp)) {
    934  1.1.1.2  haad 			stack;
    935      1.1  haad 			return ECMD_FAILED;
    936  1.1.1.2  haad 		}
    937      1.1  haad 	} else if (arg_count(cmd, mirrors_ARG) || (lv->status & MIRRORED)) {
    938  1.1.1.2  haad 		if (!archive(lv->vg)) {
    939  1.1.1.2  haad 			stack;
    940      1.1  haad 			return ECMD_FAILED;
    941  1.1.1.2  haad 		}
    942  1.1.1.2  haad 		if (!_lvconvert_mirrors(cmd, lv, lp)) {
    943  1.1.1.2  haad 			stack;
    944      1.1  haad 			return ECMD_FAILED;
    945  1.1.1.2  haad 		}
    946      1.1  haad 	}
    947      1.1  haad 
    948      1.1  haad 	return ECMD_PROCESSED;
    949      1.1  haad }
    950      1.1  haad 
    951      1.1  haad int lvconvert(struct cmd_context * cmd, int argc, char **argv)
    952      1.1  haad {
    953      1.1  haad 	struct volume_group *vg;
    954      1.1  haad 	struct lv_list *lvl;
    955      1.1  haad 	struct lvconvert_params lp;
    956      1.1  haad 	int ret = ECMD_FAILED;
    957      1.1  haad 	struct lvinfo info;
    958  1.1.1.2  haad 	int saved_ignore_suspended_devices = ignore_suspended_devices();
    959      1.1  haad 
    960      1.1  haad 	if (!_read_params(&lp, cmd, argc, argv)) {
    961      1.1  haad 		stack;
    962      1.1  haad 		return EINVALID_CMD_LINE;
    963      1.1  haad 	}
    964      1.1  haad 
    965  1.1.1.2  haad 	if (arg_count(cmd, repair_ARG)) {
    966  1.1.1.2  haad 		init_ignore_suspended_devices(1);
    967  1.1.1.2  haad 		cmd->handles_missing_pvs = 1;
    968  1.1.1.2  haad 	}
    969  1.1.1.2  haad 
    970      1.1  haad 	log_verbose("Checking for existing volume group \"%s\"", lp.vg_name);
    971      1.1  haad 
    972  1.1.1.2  haad 	vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0);
    973  1.1.1.2  haad 	if (vg_read_error(vg))
    974  1.1.1.2  haad 		goto out;
    975      1.1  haad 
    976      1.1  haad 	if (!(lvl = find_lv_in_vg(vg, lp.lv_name))) {
    977      1.1  haad 		log_error("Logical volume \"%s\" not found in "
    978      1.1  haad 			  "volume group \"%s\"", lp.lv_name, lp.vg_name);
    979      1.1  haad 		goto bad;
    980      1.1  haad 	}
    981      1.1  haad 
    982      1.1  haad 	if (lp.pv_count) {
    983      1.1  haad 		if (!(lp.pvh = create_pv_list(cmd->mem, vg, lp.pv_count,
    984      1.1  haad 					      lp.pvs, 0)))
    985      1.1  haad 			goto_bad;
    986      1.1  haad 	} else
    987      1.1  haad 		lp.pvh = &vg->pvs;
    988      1.1  haad 
    989      1.1  haad 	ret = lvconvert_single(cmd, lvl->lv, &lp);
    990      1.1  haad 
    991      1.1  haad bad:
    992      1.1  haad 	unlock_vg(cmd, lp.vg_name);
    993      1.1  haad 
    994      1.1  haad 	if (ret == ECMD_PROCESSED && lp.need_polling) {
    995      1.1  haad 		if (!lv_info(cmd, lvl->lv, &info, 1, 0) || !info.exists) {
    996      1.1  haad 			log_print("Conversion starts after activation");
    997  1.1.1.2  haad 			goto out;
    998      1.1  haad 		}
    999  1.1.1.2  haad 		ret = lvconvert_poll(cmd, lvl->lv,
   1000      1.1  haad 				     lp.wait_completion ? 0 : 1U);
   1001      1.1  haad 	}
   1002  1.1.1.2  haad out:
   1003  1.1.1.2  haad 	init_ignore_suspended_devices(saved_ignore_suspended_devices);
   1004  1.1.1.2  haad 	vg_release(vg);
   1005      1.1  haad 	return ret;
   1006      1.1  haad }
   1007