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