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