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
20static 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;
80out:
81	backup(lv->vg);
82	return r;
83}
84
85static 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
106static 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
146static 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
152static 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
306static 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
339static 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;
401out:
402	backup(lv->vg);
403	return r;
404}
405
406static 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
476static 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
517static 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
692int 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