1 /* $NetBSD: lvchange.c,v 1.1.1.3 2009/12/02 00:25:49 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 * 7 * This file is part of LVM2. 8 * 9 * This copyrighted material is made available to anyone wishing to use, 10 * modify, copy, or redistribute it subject to the terms and conditions 11 * of the GNU Lesser General Public License v.2.1. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #include "tools.h" 19 20 static int lvchange_permission(struct cmd_context *cmd, 21 struct logical_volume *lv) 22 { 23 uint32_t lv_access; 24 struct lvinfo info; 25 int r = 0; 26 27 lv_access = arg_uint_value(cmd, permission_ARG, 0); 28 29 if ((lv_access & LVM_WRITE) && (lv->status & LVM_WRITE)) { 30 log_error("Logical volume \"%s\" is already writable", 31 lv->name); 32 return 0; 33 } 34 35 if (!(lv_access & LVM_WRITE) && !(lv->status & LVM_WRITE)) { 36 log_error("Logical volume \"%s\" is already read only", 37 lv->name); 38 return 0; 39 } 40 41 if ((lv->status & MIRRORED) && (vg_is_clustered(lv->vg)) && 42 lv_info(cmd, lv, &info, 0, 0) && info.exists) { 43 log_error("Cannot change permissions of mirror \"%s\" " 44 "while active.", lv->name); 45 return 0; 46 } 47 48 if (lv_access & LVM_WRITE) { 49 lv->status |= LVM_WRITE; 50 log_verbose("Setting logical volume \"%s\" read/write", 51 lv->name); 52 } else { 53 lv->status &= ~LVM_WRITE; 54 log_verbose("Setting logical volume \"%s\" read-only", 55 lv->name); 56 } 57 58 log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 59 if (!vg_write(lv->vg)) 60 return_0; 61 62 if (!suspend_lv(cmd, lv)) { 63 log_error("Failed to lock %s", lv->name); 64 vg_revert(lv->vg); 65 goto out; 66 } 67 68 if (!vg_commit(lv->vg)) { 69 resume_lv(cmd, lv); 70 goto_out; 71 } 72 73 log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name); 74 if (!resume_lv(cmd, lv)) { 75 log_error("Problem reactivating %s", lv->name); 76 goto out; 77 } 78 79 r = 1; 80 out: 81 backup(lv->vg); 82 return r; 83 } 84 85 static int lvchange_monitoring(struct cmd_context *cmd, 86 struct logical_volume *lv) 87 { 88 struct lvinfo info; 89 90 if (!lv_info(cmd, lv, &info, 0, 0) || !info.exists) { 91 log_error("Logical volume, %s, is not active", lv->name); 92 return 0; 93 } 94 95 /* do not monitor pvmove lv's */ 96 if (lv->status & PVMOVE) 97 return 1; 98 99 if ((dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) && 100 !monitor_dev_for_events(cmd, lv, dmeventd_monitor_mode())) 101 stack; 102 103 return 1; 104 } 105 106 static int lvchange_availability(struct cmd_context *cmd, 107 struct logical_volume *lv) 108 { 109 int activate; 110 111 activate = arg_uint_value(cmd, available_ARG, 0); 112 113 if (activate == CHANGE_ALN) { 114 log_verbose("Deactivating logical volume \"%s\" locally", 115 lv->name); 116 if (!deactivate_lv_local(cmd, lv)) 117 return_0; 118 } else if (activate == CHANGE_AN) { 119 log_verbose("Deactivating logical volume \"%s\"", lv->name); 120 if (!deactivate_lv(cmd, lv)) 121 return_0; 122 } else { 123 if (lv_is_origin(lv) || (activate == CHANGE_AE)) { 124 log_verbose("Activating logical volume \"%s\" " 125 "exclusively", lv->name); 126 if (!activate_lv_excl(cmd, lv)) 127 return_0; 128 } else if (activate == CHANGE_ALY) { 129 log_verbose("Activating logical volume \"%s\" locally", 130 lv->name); 131 if (!activate_lv_local(cmd, lv)) 132 return_0; 133 } else { 134 log_verbose("Activating logical volume \"%s\"", 135 lv->name); 136 if (!activate_lv(cmd, lv)) 137 return_0; 138 } 139 140 lv_spawn_background_polling(cmd, lv); 141 } 142 143 return 1; 144 } 145 146 static int lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv) 147 { 148 log_verbose("Refreshing logical volume \"%s\" (if active)", lv->name); 149 return lv_refresh(cmd, lv); 150 } 151 152 static int lvchange_resync(struct cmd_context *cmd, 153 struct logical_volume *lv) 154 { 155 int active = 0; 156 int monitored; 157 struct lvinfo info; 158 struct logical_volume *log_lv; 159 160 if (!(lv->status & MIRRORED)) { 161 log_error("Unable to resync %s because it is not mirrored.", 162 lv->name); 163 return 1; 164 } 165 166 if (lv->status & PVMOVE) { 167 log_error("Unable to resync pvmove volume %s", lv->name); 168 return 0; 169 } 170 171 if (lv->status & LOCKED) { 172 log_error("Unable to resync locked volume %s", lv->name); 173 return 0; 174 } 175 176 if (lv_info(cmd, lv, &info, 1, 0)) { 177 if (info.open_count) { 178 log_error("Can't resync open logical volume \"%s\"", 179 lv->name); 180 return 0; 181 } 182 183 if (info.exists) { 184 if (!arg_count(cmd, yes_ARG) && 185 yes_no_prompt("Do you really want to deactivate " 186 "logical volume %s to resync it? [y/n]: ", 187 lv->name) == 'n') { 188 log_print("Logical volume \"%s\" not resynced", 189 lv->name); 190 return 0; 191 } 192 193 if (sigint_caught()) 194 return 0; 195 196 active = 1; 197 } 198 } 199 200 /* Activate exclusively to ensure no nodes still have LV active */ 201 monitored = dmeventd_monitor_mode(); 202 init_dmeventd_monitor(0); 203 204 if (!deactivate_lv(cmd, lv)) { 205 log_error("Unable to deactivate %s for resync", lv->name); 206 return 0; 207 } 208 209 if (vg_is_clustered(lv->vg) && lv_is_active(lv)) { 210 log_error("Can't get exclusive access to clustered volume %s", 211 lv->name); 212 return 0; 213 } 214 215 init_dmeventd_monitor(monitored); 216 217 log_lv = first_seg(lv)->log_lv; 218 219 log_very_verbose("Starting resync of %s%s%s mirror \"%s\"", 220 (active) ? "active " : "", 221 vg_is_clustered(lv->vg) ? "clustered " : "", 222 (log_lv) ? "disk-logged" : "core-logged", 223 lv->name); 224 225 /* 226 * If this mirror has a core log (i.e. !log_lv), 227 * then simply deactivating/activating will cause 228 * it to reset the sync status. We only need to 229 * worry about persistent logs. 230 */ 231 if (!log_lv && !(lv->status & MIRROR_NOTSYNCED)) { 232 if (active && !activate_lv(cmd, lv)) { 233 log_error("Failed to reactivate %s to resynchronize " 234 "mirror", lv->name); 235 return 0; 236 } 237 return 1; 238 } 239 240 lv->status &= ~MIRROR_NOTSYNCED; 241 242 if (log_lv) { 243 /* Separate mirror log so we can clear it */ 244 detach_mirror_log(first_seg(lv)); 245 246 if (!vg_write(lv->vg)) { 247 log_error("Failed to write intermediate VG metadata."); 248 if (!attach_mirror_log(first_seg(lv), log_lv)) 249 stack; 250 if (active && !activate_lv(cmd, lv)) 251 stack; 252 return 0; 253 } 254 255 if (!vg_commit(lv->vg)) { 256 log_error("Failed to commit intermediate VG metadata."); 257 if (!attach_mirror_log(first_seg(lv), log_lv)) 258 stack; 259 if (active && !activate_lv(cmd, lv)) 260 stack; 261 return 0; 262 } 263 264 backup(lv->vg); 265 266 if (!activate_lv(cmd, log_lv)) { 267 log_error("Unable to activate %s for mirror log resync", 268 log_lv->name); 269 return 0; 270 } 271 272 log_very_verbose("Clearing log device %s", log_lv->name); 273 if (!set_lv(cmd, log_lv, log_lv->size, 0)) { 274 log_error("Unable to reset sync status for %s", lv->name); 275 if (!deactivate_lv(cmd, log_lv)) 276 log_error("Failed to deactivate log LV after " 277 "wiping failed"); 278 return 0; 279 } 280 281 if (!deactivate_lv(cmd, log_lv)) { 282 log_error("Unable to deactivate log LV %s after wiping " 283 "for resync", log_lv->name); 284 return 0; 285 } 286 287 /* Put mirror log back in place */ 288 if (!attach_mirror_log(first_seg(lv), log_lv)) 289 stack; 290 } 291 292 log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 293 if (!vg_write(lv->vg) || !vg_commit(lv->vg)) { 294 log_error("Failed to update metadata on disk."); 295 return 0; 296 } 297 298 if (active && !activate_lv(cmd, lv)) { 299 log_error("Failed to reactivate %s after resync", lv->name); 300 return 0; 301 } 302 303 return 1; 304 } 305 306 static int lvchange_alloc(struct cmd_context *cmd, struct logical_volume *lv) 307 { 308 int want_contiguous = 0; 309 alloc_policy_t alloc; 310 311 want_contiguous = strcmp(arg_str_value(cmd, contiguous_ARG, "n"), "n"); 312 alloc = want_contiguous ? ALLOC_CONTIGUOUS : ALLOC_INHERIT; 313 alloc = arg_uint_value(cmd, alloc_ARG, alloc); 314 315 if (alloc == lv->alloc) { 316 log_error("Allocation policy of logical volume \"%s\" is " 317 "already %s", lv->name, get_alloc_string(alloc)); 318 return 0; 319 } 320 321 lv->alloc = alloc; 322 323 /* FIXME If contiguous, check existing extents already are */ 324 325 log_verbose("Setting contiguous allocation policy for \"%s\" to %s", 326 lv->name, get_alloc_string(alloc)); 327 328 log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 329 330 /* No need to suspend LV for this change */ 331 if (!vg_write(lv->vg) || !vg_commit(lv->vg)) 332 return_0; 333 334 backup(lv->vg); 335 336 return 1; 337 } 338 339 static int lvchange_readahead(struct cmd_context *cmd, 340 struct logical_volume *lv) 341 { 342 unsigned read_ahead = 0; 343 unsigned pagesize = (unsigned) lvm_getpagesize() >> SECTOR_SHIFT; 344 int r = 0; 345 346 read_ahead = arg_uint_value(cmd, readahead_ARG, 0); 347 348 if (read_ahead != DM_READ_AHEAD_AUTO && 349 (lv->vg->fid->fmt->features & FMT_RESTRICTED_READAHEAD) && 350 (read_ahead < 2 || read_ahead > 120)) { 351 log_error("Metadata only supports readahead values between 2 and 120."); 352 return 0; 353 } 354 355 if (read_ahead != DM_READ_AHEAD_AUTO && 356 read_ahead != DM_READ_AHEAD_NONE && read_ahead % pagesize) { 357 if (read_ahead < pagesize) 358 read_ahead = pagesize; 359 else 360 read_ahead = (read_ahead / pagesize) * pagesize; 361 log_warn("WARNING: Overriding readahead to %u sectors, a multiple " 362 "of %uK page size.", read_ahead, pagesize >> 1); 363 } 364 365 if (lv->read_ahead == read_ahead) { 366 if (read_ahead == DM_READ_AHEAD_AUTO) 367 log_error("Read ahead is already auto for \"%s\"", lv->name); 368 else 369 log_error("Read ahead is already %u for \"%s\"", 370 read_ahead, lv->name); 371 return 0; 372 } 373 374 lv->read_ahead = read_ahead; 375 376 log_verbose("Setting read ahead to %u for \"%s\"", read_ahead, 377 lv->name); 378 379 log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 380 if (!vg_write(lv->vg)) 381 return_0; 382 383 if (!suspend_lv(cmd, lv)) { 384 log_error("Failed to lock %s", lv->name); 385 vg_revert(lv->vg); 386 goto out; 387 } 388 389 if (!vg_commit(lv->vg)) { 390 resume_lv(cmd, lv); 391 goto_out; 392 } 393 394 log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name); 395 if (!resume_lv(cmd, lv)) { 396 log_error("Problem reactivating %s", lv->name); 397 goto out; 398 } 399 400 r = 1; 401 out: 402 backup(lv->vg); 403 return r; 404 } 405 406 static int lvchange_persistent(struct cmd_context *cmd, 407 struct logical_volume *lv) 408 { 409 struct lvinfo info; 410 int active = 0; 411 412 if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "n")) { 413 if (!(lv->status & FIXED_MINOR)) { 414 log_error("Minor number is already not persistent " 415 "for \"%s\"", lv->name); 416 return 0; 417 } 418 lv->status &= ~FIXED_MINOR; 419 lv->minor = -1; 420 lv->major = -1; 421 log_verbose("Disabling persistent device number for \"%s\"", 422 lv->name); 423 } else { 424 if (!arg_count(cmd, minor_ARG) && lv->minor < 0) { 425 log_error("Minor number must be specified with -My"); 426 return 0; 427 } 428 if (!arg_count(cmd, major_ARG) && lv->major < 0) { 429 log_error("Major number must be specified with -My"); 430 return 0; 431 } 432 if (lv_info(cmd, lv, &info, 0, 0) && info.exists) 433 active = 1; 434 if (active && !arg_count(cmd, force_ARG) && 435 yes_no_prompt("Logical volume %s will be " 436 "deactivated temporarily. " 437 "Continue? [y/n]: ", lv->name) == 'n') { 438 log_print("%s device number not changed.", 439 lv->name); 440 return 0; 441 } 442 443 if (sigint_caught()) 444 return 0; 445 446 log_verbose("Ensuring %s is inactive.", lv->name); 447 if (!deactivate_lv(cmd, lv)) { 448 log_error("%s: deactivation failed", lv->name); 449 return 0; 450 } 451 lv->status |= FIXED_MINOR; 452 lv->minor = arg_int_value(cmd, minor_ARG, lv->minor); 453 lv->major = arg_int_value(cmd, major_ARG, lv->major); 454 log_verbose("Setting persistent device number to (%d, %d) " 455 "for \"%s\"", lv->major, lv->minor, lv->name); 456 457 } 458 459 log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 460 if (!vg_write(lv->vg) || !vg_commit(lv->vg)) 461 return_0; 462 463 backup(lv->vg); 464 465 if (active) { 466 log_verbose("Re-activating logical volume \"%s\"", lv->name); 467 if (!activate_lv(cmd, lv)) { 468 log_error("%s: reactivation failed", lv->name); 469 return 0; 470 } 471 } 472 473 return 1; 474 } 475 476 static int lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv, 477 int arg) 478 { 479 const char *tag; 480 481 if (!(tag = arg_str_value(cmd, arg, NULL))) { 482 log_error("Failed to get tag"); 483 return 0; 484 } 485 486 if (!(lv->vg->fid->fmt->features & FMT_TAGS)) { 487 log_error("Logical volume %s/%s does not support tags", 488 lv->vg->name, lv->name); 489 return 0; 490 } 491 492 if ((arg == addtag_ARG)) { 493 if (!str_list_add(cmd->mem, &lv->tags, tag)) { 494 log_error("Failed to add tag %s to %s/%s", 495 tag, lv->vg->name, lv->name); 496 return 0; 497 } 498 } else { 499 if (!str_list_del(&lv->tags, tag)) { 500 log_error("Failed to remove tag %s from %s/%s", 501 tag, lv->vg->name, lv->name); 502 return 0; 503 } 504 } 505 506 log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 507 508 /* No need to suspend LV for this change */ 509 if (!vg_write(lv->vg) || !vg_commit(lv->vg)) 510 return_0; 511 512 backup(lv->vg); 513 514 return 1; 515 } 516 517 static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv, 518 void *handle __attribute((unused))) 519 { 520 int doit = 0, docmds = 0; 521 int archived = 0; 522 struct logical_volume *origin; 523 524 if (!(lv->vg->status & LVM_WRITE) && 525 (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) || 526 arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) || 527 arg_count(cmd, alloc_ARG))) { 528 log_error("Only -a permitted with read-only volume " 529 "group \"%s\"", lv->vg->name); 530 return EINVALID_CMD_LINE; 531 } 532 533 if (lv_is_origin(lv) && 534 (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) || 535 arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) || 536 arg_count(cmd, alloc_ARG))) { 537 log_error("Can't change logical volume \"%s\" under snapshot", 538 lv->name); 539 return ECMD_FAILED; 540 } 541 542 if (lv_is_cow(lv) && !lv_is_virtual_origin(origin_from_cow(lv)) && 543 arg_count(cmd, available_ARG)) { 544 log_error("Can't change snapshot logical volume \"%s\"", 545 lv->name); 546 return ECMD_FAILED; 547 } 548 549 if (lv->status & PVMOVE) { 550 log_error("Unable to change pvmove LV %s", lv->name); 551 if (arg_count(cmd, available_ARG)) 552 log_error("Use 'pvmove --abort' to abandon a pvmove"); 553 return ECMD_FAILED; 554 } 555 556 if (lv->status & MIRROR_LOG) { 557 log_error("Unable to change mirror log LV %s directly", lv->name); 558 return ECMD_FAILED; 559 } 560 561 if (lv->status & MIRROR_IMAGE) { 562 log_error("Unable to change mirror image LV %s directly", 563 lv->name); 564 return ECMD_FAILED; 565 } 566 567 /* If LV is sparse, activate origin instead */ 568 if (arg_count(cmd, available_ARG) && lv_is_cow(lv) && 569 lv_is_virtual_origin(origin = origin_from_cow(lv))) 570 lv = origin; 571 572 if (!(lv_is_visible(lv)) && !lv_is_virtual_origin(lv)) { 573 log_error("Unable to change internal LV %s directly", 574 lv->name); 575 return ECMD_FAILED; 576 } 577 578 init_dmeventd_monitor(arg_int_value(cmd, monitor_ARG, 579 (is_static() || arg_count(cmd, ignoremonitoring_ARG)) ? 580 DMEVENTD_MONITOR_IGNORE : DEFAULT_DMEVENTD_MONITOR)); 581 582 /* access permission change */ 583 if (arg_count(cmd, permission_ARG)) { 584 if (!archive(lv->vg)) { 585 stack; 586 return ECMD_FAILED; 587 } 588 archived = 1; 589 doit += lvchange_permission(cmd, lv); 590 docmds++; 591 } 592 593 /* allocation policy change */ 594 if (arg_count(cmd, contiguous_ARG) || arg_count(cmd, alloc_ARG)) { 595 if (!archived && !archive(lv->vg)) { 596 stack; 597 return ECMD_FAILED; 598 } 599 archived = 1; 600 doit += lvchange_alloc(cmd, lv); 601 docmds++; 602 } 603 604 /* read ahead sector change */ 605 if (arg_count(cmd, readahead_ARG)) { 606 if (!archived && !archive(lv->vg)) { 607 stack; 608 return ECMD_FAILED; 609 } 610 archived = 1; 611 doit += lvchange_readahead(cmd, lv); 612 docmds++; 613 } 614 615 /* persistent device number change */ 616 if (arg_count(cmd, persistent_ARG)) { 617 if (!archived && !archive(lv->vg)) { 618 stack; 619 return ECMD_FAILED; 620 } 621 archived = 1; 622 doit += lvchange_persistent(cmd, lv); 623 docmds++; 624 if (sigint_caught()) { 625 stack; 626 return ECMD_FAILED; 627 } 628 } 629 630 /* add tag */ 631 if (arg_count(cmd, addtag_ARG)) { 632 if (!archived && !archive(lv->vg)) { 633 stack; 634 return ECMD_FAILED; 635 } 636 archived = 1; 637 doit += lvchange_tag(cmd, lv, addtag_ARG); 638 docmds++; 639 } 640 641 /* del tag */ 642 if (arg_count(cmd, deltag_ARG)) { 643 if (!archived && !archive(lv->vg)) { 644 stack; 645 return ECMD_FAILED; 646 } 647 archived = 1; 648 doit += lvchange_tag(cmd, lv, deltag_ARG); 649 docmds++; 650 } 651 652 if (doit) 653 log_print("Logical volume \"%s\" changed", lv->name); 654 655 if (arg_count(cmd, resync_ARG)) 656 if (!lvchange_resync(cmd, lv)) { 657 stack; 658 return ECMD_FAILED; 659 } 660 661 /* availability change */ 662 if (arg_count(cmd, available_ARG)) { 663 if (!lvchange_availability(cmd, lv)) { 664 stack; 665 return ECMD_FAILED; 666 } 667 } 668 669 if (arg_count(cmd, refresh_ARG)) 670 if (!lvchange_refresh(cmd, lv)) { 671 stack; 672 return ECMD_FAILED; 673 } 674 675 if (!arg_count(cmd, available_ARG) && 676 !arg_count(cmd, refresh_ARG) && 677 arg_count(cmd, monitor_ARG)) { 678 if (!lvchange_monitoring(cmd, lv)) { 679 stack; 680 return ECMD_FAILED; 681 } 682 } 683 684 if (doit != docmds) { 685 stack; 686 return ECMD_FAILED; 687 } 688 689 return ECMD_PROCESSED; 690 } 691 692 int lvchange(struct cmd_context *cmd, int argc, char **argv) 693 { 694 if (!arg_count(cmd, available_ARG) && !arg_count(cmd, contiguous_ARG) 695 && !arg_count(cmd, permission_ARG) && !arg_count(cmd, readahead_ARG) 696 && !arg_count(cmd, minor_ARG) && !arg_count(cmd, major_ARG) 697 && !arg_count(cmd, persistent_ARG) && !arg_count(cmd, addtag_ARG) 698 && !arg_count(cmd, deltag_ARG) && !arg_count(cmd, refresh_ARG) 699 && !arg_count(cmd, alloc_ARG) && !arg_count(cmd, monitor_ARG) 700 && !arg_count(cmd, resync_ARG)) { 701 log_error("Need 1 or more of -a, -C, -j, -m, -M, -p, -r, " 702 "--resync, --refresh, --alloc, --addtag, --deltag " 703 "or --monitor"); 704 return EINVALID_CMD_LINE; 705 } 706 707 int avail_only = /* i.e. only one of -a or --refresh is given */ 708 !(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) || 709 arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) || 710 arg_count(cmd, addtag_ARG) || arg_count(cmd, deltag_ARG) || 711 arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG)); 712 713 if (arg_count(cmd, ignorelockingfailure_ARG) && !avail_only) { 714 log_error("Only -a permitted with --ignorelockingfailure"); 715 return EINVALID_CMD_LINE; 716 } 717 718 if (avail_only) 719 cmd->handles_missing_pvs = 1; 720 721 if (!argc) { 722 log_error("Please give logical volume path(s)"); 723 return EINVALID_CMD_LINE; 724 } 725 726 if ((arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) && 727 !arg_count(cmd, persistent_ARG)) { 728 log_error("--major and --minor require -My"); 729 return EINVALID_CMD_LINE; 730 } 731 732 if (arg_count(cmd, minor_ARG) && argc != 1) { 733 log_error("Only give one logical volume when specifying minor"); 734 return EINVALID_CMD_LINE; 735 } 736 737 if (arg_count(cmd, contiguous_ARG) && arg_count(cmd, alloc_ARG)) { 738 log_error("Only one of --alloc and --contiguous permitted"); 739 return EINVALID_CMD_LINE; 740 } 741 742 return process_each_lv(cmd, argc, argv, 743 avail_only ? 0 : READ_FOR_UPDATE, NULL, 744 &lvchange_single); 745 } 746