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