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