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