186d7f5d3SJohn Marino /* $NetBSD: lvchange.c,v 1.1.1.3 2009/12/02 00:25:49 haad Exp $ */
286d7f5d3SJohn Marino
386d7f5d3SJohn Marino /*
486d7f5d3SJohn Marino * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
586d7f5d3SJohn Marino * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
686d7f5d3SJohn Marino *
786d7f5d3SJohn Marino * This file is part of LVM2.
886d7f5d3SJohn Marino *
986d7f5d3SJohn Marino * This copyrighted material is made available to anyone wishing to use,
1086d7f5d3SJohn Marino * modify, copy, or redistribute it subject to the terms and conditions
1186d7f5d3SJohn Marino * of the GNU Lesser General Public License v.2.1.
1286d7f5d3SJohn Marino *
1386d7f5d3SJohn Marino * You should have received a copy of the GNU Lesser General Public License
1486d7f5d3SJohn Marino * along with this program; if not, write to the Free Software Foundation,
1586d7f5d3SJohn Marino * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1686d7f5d3SJohn Marino */
1786d7f5d3SJohn Marino
1886d7f5d3SJohn Marino #include "tools.h"
1986d7f5d3SJohn Marino
lvchange_permission(struct cmd_context * cmd,struct logical_volume * lv)2086d7f5d3SJohn Marino static int lvchange_permission(struct cmd_context *cmd,
2186d7f5d3SJohn Marino struct logical_volume *lv)
2286d7f5d3SJohn Marino {
2386d7f5d3SJohn Marino uint32_t lv_access;
2486d7f5d3SJohn Marino struct lvinfo info;
2586d7f5d3SJohn Marino int r = 0;
2686d7f5d3SJohn Marino
2786d7f5d3SJohn Marino lv_access = arg_uint_value(cmd, permission_ARG, 0);
2886d7f5d3SJohn Marino
2986d7f5d3SJohn Marino if ((lv_access & LVM_WRITE) && (lv->status & LVM_WRITE)) {
3086d7f5d3SJohn Marino log_error("Logical volume \"%s\" is already writable",
3186d7f5d3SJohn Marino lv->name);
3286d7f5d3SJohn Marino return 0;
3386d7f5d3SJohn Marino }
3486d7f5d3SJohn Marino
3586d7f5d3SJohn Marino if (!(lv_access & LVM_WRITE) && !(lv->status & LVM_WRITE)) {
3686d7f5d3SJohn Marino log_error("Logical volume \"%s\" is already read only",
3786d7f5d3SJohn Marino lv->name);
3886d7f5d3SJohn Marino return 0;
3986d7f5d3SJohn Marino }
4086d7f5d3SJohn Marino
4186d7f5d3SJohn Marino if ((lv->status & MIRRORED) && (vg_is_clustered(lv->vg)) &&
4286d7f5d3SJohn Marino lv_info(cmd, lv, &info, 0, 0) && info.exists) {
4386d7f5d3SJohn Marino log_error("Cannot change permissions of mirror \"%s\" "
4486d7f5d3SJohn Marino "while active.", lv->name);
4586d7f5d3SJohn Marino return 0;
4686d7f5d3SJohn Marino }
4786d7f5d3SJohn Marino
4886d7f5d3SJohn Marino if (lv_access & LVM_WRITE) {
4986d7f5d3SJohn Marino lv->status |= LVM_WRITE;
5086d7f5d3SJohn Marino log_verbose("Setting logical volume \"%s\" read/write",
5186d7f5d3SJohn Marino lv->name);
5286d7f5d3SJohn Marino } else {
5386d7f5d3SJohn Marino lv->status &= ~LVM_WRITE;
5486d7f5d3SJohn Marino log_verbose("Setting logical volume \"%s\" read-only",
5586d7f5d3SJohn Marino lv->name);
5686d7f5d3SJohn Marino }
5786d7f5d3SJohn Marino
5886d7f5d3SJohn Marino log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
5986d7f5d3SJohn Marino if (!vg_write(lv->vg))
6086d7f5d3SJohn Marino return_0;
6186d7f5d3SJohn Marino
6286d7f5d3SJohn Marino if (!suspend_lv(cmd, lv)) {
6386d7f5d3SJohn Marino log_error("Failed to lock %s", lv->name);
6486d7f5d3SJohn Marino vg_revert(lv->vg);
6586d7f5d3SJohn Marino goto out;
6686d7f5d3SJohn Marino }
6786d7f5d3SJohn Marino
6886d7f5d3SJohn Marino if (!vg_commit(lv->vg)) {
6986d7f5d3SJohn Marino resume_lv(cmd, lv);
7086d7f5d3SJohn Marino goto_out;
7186d7f5d3SJohn Marino }
7286d7f5d3SJohn Marino
7386d7f5d3SJohn Marino log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name);
7486d7f5d3SJohn Marino if (!resume_lv(cmd, lv)) {
7586d7f5d3SJohn Marino log_error("Problem reactivating %s", lv->name);
7686d7f5d3SJohn Marino goto out;
7786d7f5d3SJohn Marino }
7886d7f5d3SJohn Marino
7986d7f5d3SJohn Marino r = 1;
8086d7f5d3SJohn Marino out:
8186d7f5d3SJohn Marino backup(lv->vg);
8286d7f5d3SJohn Marino return r;
8386d7f5d3SJohn Marino }
8486d7f5d3SJohn Marino
lvchange_monitoring(struct cmd_context * cmd,struct logical_volume * lv)8586d7f5d3SJohn Marino static int lvchange_monitoring(struct cmd_context *cmd,
8686d7f5d3SJohn Marino struct logical_volume *lv)
8786d7f5d3SJohn Marino {
8886d7f5d3SJohn Marino struct lvinfo info;
8986d7f5d3SJohn Marino
9086d7f5d3SJohn Marino if (!lv_info(cmd, lv, &info, 0, 0) || !info.exists) {
9186d7f5d3SJohn Marino log_error("Logical volume, %s, is not active", lv->name);
9286d7f5d3SJohn Marino return 0;
9386d7f5d3SJohn Marino }
9486d7f5d3SJohn Marino
9586d7f5d3SJohn Marino /* do not monitor pvmove lv's */
9686d7f5d3SJohn Marino if (lv->status & PVMOVE)
9786d7f5d3SJohn Marino return 1;
9886d7f5d3SJohn Marino
9986d7f5d3SJohn Marino if ((dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) &&
10086d7f5d3SJohn Marino !monitor_dev_for_events(cmd, lv, dmeventd_monitor_mode()))
10186d7f5d3SJohn Marino stack;
10286d7f5d3SJohn Marino
10386d7f5d3SJohn Marino return 1;
10486d7f5d3SJohn Marino }
10586d7f5d3SJohn Marino
lvchange_availability(struct cmd_context * cmd,struct logical_volume * lv)10686d7f5d3SJohn Marino static int lvchange_availability(struct cmd_context *cmd,
10786d7f5d3SJohn Marino struct logical_volume *lv)
10886d7f5d3SJohn Marino {
10986d7f5d3SJohn Marino int activate;
11086d7f5d3SJohn Marino
11186d7f5d3SJohn Marino activate = arg_uint_value(cmd, available_ARG, 0);
11286d7f5d3SJohn Marino
11386d7f5d3SJohn Marino if (activate == CHANGE_ALN) {
11486d7f5d3SJohn Marino log_verbose("Deactivating logical volume \"%s\" locally",
11586d7f5d3SJohn Marino lv->name);
11686d7f5d3SJohn Marino if (!deactivate_lv_local(cmd, lv))
11786d7f5d3SJohn Marino return_0;
11886d7f5d3SJohn Marino } else if (activate == CHANGE_AN) {
11986d7f5d3SJohn Marino log_verbose("Deactivating logical volume \"%s\"", lv->name);
12086d7f5d3SJohn Marino if (!deactivate_lv(cmd, lv))
12186d7f5d3SJohn Marino return_0;
12286d7f5d3SJohn Marino } else {
12386d7f5d3SJohn Marino if (lv_is_origin(lv) || (activate == CHANGE_AE)) {
12486d7f5d3SJohn Marino log_verbose("Activating logical volume \"%s\" "
12586d7f5d3SJohn Marino "exclusively", lv->name);
12686d7f5d3SJohn Marino if (!activate_lv_excl(cmd, lv))
12786d7f5d3SJohn Marino return_0;
12886d7f5d3SJohn Marino } else if (activate == CHANGE_ALY) {
12986d7f5d3SJohn Marino log_verbose("Activating logical volume \"%s\" locally",
13086d7f5d3SJohn Marino lv->name);
13186d7f5d3SJohn Marino if (!activate_lv_local(cmd, lv))
13286d7f5d3SJohn Marino return_0;
13386d7f5d3SJohn Marino } else {
13486d7f5d3SJohn Marino log_verbose("Activating logical volume \"%s\"",
13586d7f5d3SJohn Marino lv->name);
13686d7f5d3SJohn Marino if (!activate_lv(cmd, lv))
13786d7f5d3SJohn Marino return_0;
13886d7f5d3SJohn Marino }
13986d7f5d3SJohn Marino
14086d7f5d3SJohn Marino lv_spawn_background_polling(cmd, lv);
14186d7f5d3SJohn Marino }
14286d7f5d3SJohn Marino
14386d7f5d3SJohn Marino return 1;
14486d7f5d3SJohn Marino }
14586d7f5d3SJohn Marino
lvchange_refresh(struct cmd_context * cmd,struct logical_volume * lv)14686d7f5d3SJohn Marino static int lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv)
14786d7f5d3SJohn Marino {
14886d7f5d3SJohn Marino log_verbose("Refreshing logical volume \"%s\" (if active)", lv->name);
14986d7f5d3SJohn Marino return lv_refresh(cmd, lv);
15086d7f5d3SJohn Marino }
15186d7f5d3SJohn Marino
lvchange_resync(struct cmd_context * cmd,struct logical_volume * lv)15286d7f5d3SJohn Marino static int lvchange_resync(struct cmd_context *cmd,
15386d7f5d3SJohn Marino struct logical_volume *lv)
15486d7f5d3SJohn Marino {
15586d7f5d3SJohn Marino int active = 0;
15686d7f5d3SJohn Marino int monitored;
15786d7f5d3SJohn Marino struct lvinfo info;
15886d7f5d3SJohn Marino struct logical_volume *log_lv;
15986d7f5d3SJohn Marino
16086d7f5d3SJohn Marino if (!(lv->status & MIRRORED)) {
16186d7f5d3SJohn Marino log_error("Unable to resync %s because it is not mirrored.",
16286d7f5d3SJohn Marino lv->name);
16386d7f5d3SJohn Marino return 1;
16486d7f5d3SJohn Marino }
16586d7f5d3SJohn Marino
16686d7f5d3SJohn Marino if (lv->status & PVMOVE) {
16786d7f5d3SJohn Marino log_error("Unable to resync pvmove volume %s", lv->name);
16886d7f5d3SJohn Marino return 0;
16986d7f5d3SJohn Marino }
17086d7f5d3SJohn Marino
17186d7f5d3SJohn Marino if (lv->status & LOCKED) {
17286d7f5d3SJohn Marino log_error("Unable to resync locked volume %s", lv->name);
17386d7f5d3SJohn Marino return 0;
17486d7f5d3SJohn Marino }
17586d7f5d3SJohn Marino
17686d7f5d3SJohn Marino if (lv_info(cmd, lv, &info, 1, 0)) {
17786d7f5d3SJohn Marino if (info.open_count) {
17886d7f5d3SJohn Marino log_error("Can't resync open logical volume \"%s\"",
17986d7f5d3SJohn Marino lv->name);
18086d7f5d3SJohn Marino return 0;
18186d7f5d3SJohn Marino }
18286d7f5d3SJohn Marino
18386d7f5d3SJohn Marino if (info.exists) {
18486d7f5d3SJohn Marino if (!arg_count(cmd, yes_ARG) &&
18586d7f5d3SJohn Marino yes_no_prompt("Do you really want to deactivate "
18686d7f5d3SJohn Marino "logical volume %s to resync it? [y/n]: ",
18786d7f5d3SJohn Marino lv->name) == 'n') {
18886d7f5d3SJohn Marino log_print("Logical volume \"%s\" not resynced",
18986d7f5d3SJohn Marino lv->name);
19086d7f5d3SJohn Marino return 0;
19186d7f5d3SJohn Marino }
19286d7f5d3SJohn Marino
19386d7f5d3SJohn Marino if (sigint_caught())
19486d7f5d3SJohn Marino return 0;
19586d7f5d3SJohn Marino
19686d7f5d3SJohn Marino active = 1;
19786d7f5d3SJohn Marino }
19886d7f5d3SJohn Marino }
19986d7f5d3SJohn Marino
20086d7f5d3SJohn Marino /* Activate exclusively to ensure no nodes still have LV active */
20186d7f5d3SJohn Marino monitored = dmeventd_monitor_mode();
20286d7f5d3SJohn Marino init_dmeventd_monitor(0);
20386d7f5d3SJohn Marino
20486d7f5d3SJohn Marino if (!deactivate_lv(cmd, lv)) {
20586d7f5d3SJohn Marino log_error("Unable to deactivate %s for resync", lv->name);
20686d7f5d3SJohn Marino return 0;
20786d7f5d3SJohn Marino }
20886d7f5d3SJohn Marino
20986d7f5d3SJohn Marino if (vg_is_clustered(lv->vg) && lv_is_active(lv)) {
21086d7f5d3SJohn Marino log_error("Can't get exclusive access to clustered volume %s",
21186d7f5d3SJohn Marino lv->name);
21286d7f5d3SJohn Marino return 0;
21386d7f5d3SJohn Marino }
21486d7f5d3SJohn Marino
21586d7f5d3SJohn Marino init_dmeventd_monitor(monitored);
21686d7f5d3SJohn Marino
21786d7f5d3SJohn Marino log_lv = first_seg(lv)->log_lv;
21886d7f5d3SJohn Marino
21986d7f5d3SJohn Marino log_very_verbose("Starting resync of %s%s%s mirror \"%s\"",
22086d7f5d3SJohn Marino (active) ? "active " : "",
22186d7f5d3SJohn Marino vg_is_clustered(lv->vg) ? "clustered " : "",
22286d7f5d3SJohn Marino (log_lv) ? "disk-logged" : "core-logged",
22386d7f5d3SJohn Marino lv->name);
22486d7f5d3SJohn Marino
22586d7f5d3SJohn Marino /*
22686d7f5d3SJohn Marino * If this mirror has a core log (i.e. !log_lv),
22786d7f5d3SJohn Marino * then simply deactivating/activating will cause
22886d7f5d3SJohn Marino * it to reset the sync status. We only need to
22986d7f5d3SJohn Marino * worry about persistent logs.
23086d7f5d3SJohn Marino */
23186d7f5d3SJohn Marino if (!log_lv && !(lv->status & MIRROR_NOTSYNCED)) {
23286d7f5d3SJohn Marino if (active && !activate_lv(cmd, lv)) {
23386d7f5d3SJohn Marino log_error("Failed to reactivate %s to resynchronize "
23486d7f5d3SJohn Marino "mirror", lv->name);
23586d7f5d3SJohn Marino return 0;
23686d7f5d3SJohn Marino }
23786d7f5d3SJohn Marino return 1;
23886d7f5d3SJohn Marino }
23986d7f5d3SJohn Marino
24086d7f5d3SJohn Marino lv->status &= ~MIRROR_NOTSYNCED;
24186d7f5d3SJohn Marino
24286d7f5d3SJohn Marino if (log_lv) {
24386d7f5d3SJohn Marino /* Separate mirror log so we can clear it */
24486d7f5d3SJohn Marino detach_mirror_log(first_seg(lv));
24586d7f5d3SJohn Marino
24686d7f5d3SJohn Marino if (!vg_write(lv->vg)) {
24786d7f5d3SJohn Marino log_error("Failed to write intermediate VG metadata.");
24886d7f5d3SJohn Marino if (!attach_mirror_log(first_seg(lv), log_lv))
24986d7f5d3SJohn Marino stack;
25086d7f5d3SJohn Marino if (active && !activate_lv(cmd, lv))
25186d7f5d3SJohn Marino stack;
25286d7f5d3SJohn Marino return 0;
25386d7f5d3SJohn Marino }
25486d7f5d3SJohn Marino
25586d7f5d3SJohn Marino if (!vg_commit(lv->vg)) {
25686d7f5d3SJohn Marino log_error("Failed to commit intermediate VG metadata.");
25786d7f5d3SJohn Marino if (!attach_mirror_log(first_seg(lv), log_lv))
25886d7f5d3SJohn Marino stack;
25986d7f5d3SJohn Marino if (active && !activate_lv(cmd, lv))
26086d7f5d3SJohn Marino stack;
26186d7f5d3SJohn Marino return 0;
26286d7f5d3SJohn Marino }
26386d7f5d3SJohn Marino
26486d7f5d3SJohn Marino backup(lv->vg);
26586d7f5d3SJohn Marino
26686d7f5d3SJohn Marino if (!activate_lv(cmd, log_lv)) {
26786d7f5d3SJohn Marino log_error("Unable to activate %s for mirror log resync",
26886d7f5d3SJohn Marino log_lv->name);
26986d7f5d3SJohn Marino return 0;
27086d7f5d3SJohn Marino }
27186d7f5d3SJohn Marino
27286d7f5d3SJohn Marino log_very_verbose("Clearing log device %s", log_lv->name);
27386d7f5d3SJohn Marino if (!set_lv(cmd, log_lv, log_lv->size, 0)) {
27486d7f5d3SJohn Marino log_error("Unable to reset sync status for %s", lv->name);
27586d7f5d3SJohn Marino if (!deactivate_lv(cmd, log_lv))
27686d7f5d3SJohn Marino log_error("Failed to deactivate log LV after "
27786d7f5d3SJohn Marino "wiping failed");
27886d7f5d3SJohn Marino return 0;
27986d7f5d3SJohn Marino }
28086d7f5d3SJohn Marino
28186d7f5d3SJohn Marino if (!deactivate_lv(cmd, log_lv)) {
28286d7f5d3SJohn Marino log_error("Unable to deactivate log LV %s after wiping "
28386d7f5d3SJohn Marino "for resync", log_lv->name);
28486d7f5d3SJohn Marino return 0;
28586d7f5d3SJohn Marino }
28686d7f5d3SJohn Marino
28786d7f5d3SJohn Marino /* Put mirror log back in place */
28886d7f5d3SJohn Marino if (!attach_mirror_log(first_seg(lv), log_lv))
28986d7f5d3SJohn Marino stack;
29086d7f5d3SJohn Marino }
29186d7f5d3SJohn Marino
29286d7f5d3SJohn Marino log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
29386d7f5d3SJohn Marino if (!vg_write(lv->vg) || !vg_commit(lv->vg)) {
29486d7f5d3SJohn Marino log_error("Failed to update metadata on disk.");
29586d7f5d3SJohn Marino return 0;
29686d7f5d3SJohn Marino }
29786d7f5d3SJohn Marino
29886d7f5d3SJohn Marino if (active && !activate_lv(cmd, lv)) {
29986d7f5d3SJohn Marino log_error("Failed to reactivate %s after resync", lv->name);
30086d7f5d3SJohn Marino return 0;
30186d7f5d3SJohn Marino }
30286d7f5d3SJohn Marino
30386d7f5d3SJohn Marino return 1;
30486d7f5d3SJohn Marino }
30586d7f5d3SJohn Marino
lvchange_alloc(struct cmd_context * cmd,struct logical_volume * lv)30686d7f5d3SJohn Marino static int lvchange_alloc(struct cmd_context *cmd, struct logical_volume *lv)
30786d7f5d3SJohn Marino {
30886d7f5d3SJohn Marino int want_contiguous = 0;
30986d7f5d3SJohn Marino alloc_policy_t alloc;
31086d7f5d3SJohn Marino
31186d7f5d3SJohn Marino want_contiguous = strcmp(arg_str_value(cmd, contiguous_ARG, "n"), "n");
31286d7f5d3SJohn Marino alloc = want_contiguous ? ALLOC_CONTIGUOUS : ALLOC_INHERIT;
31386d7f5d3SJohn Marino alloc = arg_uint_value(cmd, alloc_ARG, alloc);
31486d7f5d3SJohn Marino
31586d7f5d3SJohn Marino if (alloc == lv->alloc) {
31686d7f5d3SJohn Marino log_error("Allocation policy of logical volume \"%s\" is "
31786d7f5d3SJohn Marino "already %s", lv->name, get_alloc_string(alloc));
31886d7f5d3SJohn Marino return 0;
31986d7f5d3SJohn Marino }
32086d7f5d3SJohn Marino
32186d7f5d3SJohn Marino lv->alloc = alloc;
32286d7f5d3SJohn Marino
32386d7f5d3SJohn Marino /* FIXME If contiguous, check existing extents already are */
32486d7f5d3SJohn Marino
32586d7f5d3SJohn Marino log_verbose("Setting contiguous allocation policy for \"%s\" to %s",
32686d7f5d3SJohn Marino lv->name, get_alloc_string(alloc));
32786d7f5d3SJohn Marino
32886d7f5d3SJohn Marino log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
32986d7f5d3SJohn Marino
33086d7f5d3SJohn Marino /* No need to suspend LV for this change */
33186d7f5d3SJohn Marino if (!vg_write(lv->vg) || !vg_commit(lv->vg))
33286d7f5d3SJohn Marino return_0;
33386d7f5d3SJohn Marino
33486d7f5d3SJohn Marino backup(lv->vg);
33586d7f5d3SJohn Marino
33686d7f5d3SJohn Marino return 1;
33786d7f5d3SJohn Marino }
33886d7f5d3SJohn Marino
lvchange_readahead(struct cmd_context * cmd,struct logical_volume * lv)33986d7f5d3SJohn Marino static int lvchange_readahead(struct cmd_context *cmd,
34086d7f5d3SJohn Marino struct logical_volume *lv)
34186d7f5d3SJohn Marino {
34286d7f5d3SJohn Marino unsigned read_ahead = 0;
34386d7f5d3SJohn Marino unsigned pagesize = (unsigned) lvm_getpagesize() >> SECTOR_SHIFT;
34486d7f5d3SJohn Marino int r = 0;
34586d7f5d3SJohn Marino
34686d7f5d3SJohn Marino read_ahead = arg_uint_value(cmd, readahead_ARG, 0);
34786d7f5d3SJohn Marino
34886d7f5d3SJohn Marino if (read_ahead != DM_READ_AHEAD_AUTO &&
34986d7f5d3SJohn Marino (lv->vg->fid->fmt->features & FMT_RESTRICTED_READAHEAD) &&
35086d7f5d3SJohn Marino (read_ahead < 2 || read_ahead > 120)) {
35186d7f5d3SJohn Marino log_error("Metadata only supports readahead values between 2 and 120.");
35286d7f5d3SJohn Marino return 0;
35386d7f5d3SJohn Marino }
35486d7f5d3SJohn Marino
35586d7f5d3SJohn Marino if (read_ahead != DM_READ_AHEAD_AUTO &&
35686d7f5d3SJohn Marino read_ahead != DM_READ_AHEAD_NONE && read_ahead % pagesize) {
35786d7f5d3SJohn Marino if (read_ahead < pagesize)
35886d7f5d3SJohn Marino read_ahead = pagesize;
35986d7f5d3SJohn Marino else
36086d7f5d3SJohn Marino read_ahead = (read_ahead / pagesize) * pagesize;
36186d7f5d3SJohn Marino log_warn("WARNING: Overriding readahead to %u sectors, a multiple "
36286d7f5d3SJohn Marino "of %uK page size.", read_ahead, pagesize >> 1);
36386d7f5d3SJohn Marino }
36486d7f5d3SJohn Marino
36586d7f5d3SJohn Marino if (lv->read_ahead == read_ahead) {
36686d7f5d3SJohn Marino if (read_ahead == DM_READ_AHEAD_AUTO)
36786d7f5d3SJohn Marino log_error("Read ahead is already auto for \"%s\"", lv->name);
36886d7f5d3SJohn Marino else
36986d7f5d3SJohn Marino log_error("Read ahead is already %u for \"%s\"",
37086d7f5d3SJohn Marino read_ahead, lv->name);
37186d7f5d3SJohn Marino return 0;
37286d7f5d3SJohn Marino }
37386d7f5d3SJohn Marino
37486d7f5d3SJohn Marino lv->read_ahead = read_ahead;
37586d7f5d3SJohn Marino
37686d7f5d3SJohn Marino log_verbose("Setting read ahead to %u for \"%s\"", read_ahead,
37786d7f5d3SJohn Marino lv->name);
37886d7f5d3SJohn Marino
37986d7f5d3SJohn Marino log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
38086d7f5d3SJohn Marino if (!vg_write(lv->vg))
38186d7f5d3SJohn Marino return_0;
38286d7f5d3SJohn Marino
38386d7f5d3SJohn Marino if (!suspend_lv(cmd, lv)) {
38486d7f5d3SJohn Marino log_error("Failed to lock %s", lv->name);
38586d7f5d3SJohn Marino vg_revert(lv->vg);
38686d7f5d3SJohn Marino goto out;
38786d7f5d3SJohn Marino }
38886d7f5d3SJohn Marino
38986d7f5d3SJohn Marino if (!vg_commit(lv->vg)) {
39086d7f5d3SJohn Marino resume_lv(cmd, lv);
39186d7f5d3SJohn Marino goto_out;
39286d7f5d3SJohn Marino }
39386d7f5d3SJohn Marino
39486d7f5d3SJohn Marino log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name);
39586d7f5d3SJohn Marino if (!resume_lv(cmd, lv)) {
39686d7f5d3SJohn Marino log_error("Problem reactivating %s", lv->name);
39786d7f5d3SJohn Marino goto out;
39886d7f5d3SJohn Marino }
39986d7f5d3SJohn Marino
40086d7f5d3SJohn Marino r = 1;
40186d7f5d3SJohn Marino out:
40286d7f5d3SJohn Marino backup(lv->vg);
40386d7f5d3SJohn Marino return r;
40486d7f5d3SJohn Marino }
40586d7f5d3SJohn Marino
lvchange_persistent(struct cmd_context * cmd,struct logical_volume * lv)40686d7f5d3SJohn Marino static int lvchange_persistent(struct cmd_context *cmd,
40786d7f5d3SJohn Marino struct logical_volume *lv)
40886d7f5d3SJohn Marino {
40986d7f5d3SJohn Marino struct lvinfo info;
41086d7f5d3SJohn Marino int active = 0;
41186d7f5d3SJohn Marino
41286d7f5d3SJohn Marino if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "n")) {
41386d7f5d3SJohn Marino if (!(lv->status & FIXED_MINOR)) {
41486d7f5d3SJohn Marino log_error("Minor number is already not persistent "
41586d7f5d3SJohn Marino "for \"%s\"", lv->name);
41686d7f5d3SJohn Marino return 0;
41786d7f5d3SJohn Marino }
41886d7f5d3SJohn Marino lv->status &= ~FIXED_MINOR;
41986d7f5d3SJohn Marino lv->minor = -1;
42086d7f5d3SJohn Marino lv->major = -1;
42186d7f5d3SJohn Marino log_verbose("Disabling persistent device number for \"%s\"",
42286d7f5d3SJohn Marino lv->name);
42386d7f5d3SJohn Marino } else {
42486d7f5d3SJohn Marino if (!arg_count(cmd, minor_ARG) && lv->minor < 0) {
42586d7f5d3SJohn Marino log_error("Minor number must be specified with -My");
42686d7f5d3SJohn Marino return 0;
42786d7f5d3SJohn Marino }
42886d7f5d3SJohn Marino if (!arg_count(cmd, major_ARG) && lv->major < 0) {
42986d7f5d3SJohn Marino log_error("Major number must be specified with -My");
43086d7f5d3SJohn Marino return 0;
43186d7f5d3SJohn Marino }
43286d7f5d3SJohn Marino if (lv_info(cmd, lv, &info, 0, 0) && info.exists)
43386d7f5d3SJohn Marino active = 1;
43486d7f5d3SJohn Marino if (active && !arg_count(cmd, force_ARG) &&
43586d7f5d3SJohn Marino yes_no_prompt("Logical volume %s will be "
43686d7f5d3SJohn Marino "deactivated temporarily. "
43786d7f5d3SJohn Marino "Continue? [y/n]: ", lv->name) == 'n') {
43886d7f5d3SJohn Marino log_print("%s device number not changed.",
43986d7f5d3SJohn Marino lv->name);
44086d7f5d3SJohn Marino return 0;
44186d7f5d3SJohn Marino }
44286d7f5d3SJohn Marino
44386d7f5d3SJohn Marino if (sigint_caught())
44486d7f5d3SJohn Marino return 0;
44586d7f5d3SJohn Marino
44686d7f5d3SJohn Marino log_verbose("Ensuring %s is inactive.", lv->name);
44786d7f5d3SJohn Marino if (!deactivate_lv(cmd, lv)) {
44886d7f5d3SJohn Marino log_error("%s: deactivation failed", lv->name);
44986d7f5d3SJohn Marino return 0;
45086d7f5d3SJohn Marino }
45186d7f5d3SJohn Marino lv->status |= FIXED_MINOR;
45286d7f5d3SJohn Marino lv->minor = arg_int_value(cmd, minor_ARG, lv->minor);
45386d7f5d3SJohn Marino lv->major = arg_int_value(cmd, major_ARG, lv->major);
45486d7f5d3SJohn Marino log_verbose("Setting persistent device number to (%d, %d) "
45586d7f5d3SJohn Marino "for \"%s\"", lv->major, lv->minor, lv->name);
45686d7f5d3SJohn Marino
45786d7f5d3SJohn Marino }
45886d7f5d3SJohn Marino
45986d7f5d3SJohn Marino log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
46086d7f5d3SJohn Marino if (!vg_write(lv->vg) || !vg_commit(lv->vg))
46186d7f5d3SJohn Marino return_0;
46286d7f5d3SJohn Marino
46386d7f5d3SJohn Marino backup(lv->vg);
46486d7f5d3SJohn Marino
46586d7f5d3SJohn Marino if (active) {
46686d7f5d3SJohn Marino log_verbose("Re-activating logical volume \"%s\"", lv->name);
46786d7f5d3SJohn Marino if (!activate_lv(cmd, lv)) {
46886d7f5d3SJohn Marino log_error("%s: reactivation failed", lv->name);
46986d7f5d3SJohn Marino return 0;
47086d7f5d3SJohn Marino }
47186d7f5d3SJohn Marino }
47286d7f5d3SJohn Marino
47386d7f5d3SJohn Marino return 1;
47486d7f5d3SJohn Marino }
47586d7f5d3SJohn Marino
lvchange_tag(struct cmd_context * cmd,struct logical_volume * lv,int arg)47686d7f5d3SJohn Marino static int lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv,
47786d7f5d3SJohn Marino int arg)
47886d7f5d3SJohn Marino {
47986d7f5d3SJohn Marino const char *tag;
48086d7f5d3SJohn Marino
48186d7f5d3SJohn Marino if (!(tag = arg_str_value(cmd, arg, NULL))) {
48286d7f5d3SJohn Marino log_error("Failed to get tag");
48386d7f5d3SJohn Marino return 0;
48486d7f5d3SJohn Marino }
48586d7f5d3SJohn Marino
48686d7f5d3SJohn Marino if (!(lv->vg->fid->fmt->features & FMT_TAGS)) {
48786d7f5d3SJohn Marino log_error("Logical volume %s/%s does not support tags",
48886d7f5d3SJohn Marino lv->vg->name, lv->name);
48986d7f5d3SJohn Marino return 0;
49086d7f5d3SJohn Marino }
49186d7f5d3SJohn Marino
49286d7f5d3SJohn Marino if ((arg == addtag_ARG)) {
49386d7f5d3SJohn Marino if (!str_list_add(cmd->mem, &lv->tags, tag)) {
49486d7f5d3SJohn Marino log_error("Failed to add tag %s to %s/%s",
49586d7f5d3SJohn Marino tag, lv->vg->name, lv->name);
49686d7f5d3SJohn Marino return 0;
49786d7f5d3SJohn Marino }
49886d7f5d3SJohn Marino } else {
49986d7f5d3SJohn Marino if (!str_list_del(&lv->tags, tag)) {
50086d7f5d3SJohn Marino log_error("Failed to remove tag %s from %s/%s",
50186d7f5d3SJohn Marino tag, lv->vg->name, lv->name);
50286d7f5d3SJohn Marino return 0;
50386d7f5d3SJohn Marino }
50486d7f5d3SJohn Marino }
50586d7f5d3SJohn Marino
50686d7f5d3SJohn Marino log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
50786d7f5d3SJohn Marino
50886d7f5d3SJohn Marino /* No need to suspend LV for this change */
50986d7f5d3SJohn Marino if (!vg_write(lv->vg) || !vg_commit(lv->vg))
51086d7f5d3SJohn Marino return_0;
51186d7f5d3SJohn Marino
51286d7f5d3SJohn Marino backup(lv->vg);
51386d7f5d3SJohn Marino
51486d7f5d3SJohn Marino return 1;
51586d7f5d3SJohn Marino }
51686d7f5d3SJohn Marino
lvchange_single(struct cmd_context * cmd,struct logical_volume * lv,void * handle __attribute ((unused)))51786d7f5d3SJohn Marino static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
51886d7f5d3SJohn Marino void *handle __attribute((unused)))
51986d7f5d3SJohn Marino {
52086d7f5d3SJohn Marino int doit = 0, docmds = 0;
52186d7f5d3SJohn Marino int archived = 0;
52286d7f5d3SJohn Marino struct logical_volume *origin;
52386d7f5d3SJohn Marino
52486d7f5d3SJohn Marino if (!(lv->vg->status & LVM_WRITE) &&
52586d7f5d3SJohn Marino (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
52686d7f5d3SJohn Marino arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
52786d7f5d3SJohn Marino arg_count(cmd, alloc_ARG))) {
52886d7f5d3SJohn Marino log_error("Only -a permitted with read-only volume "
52986d7f5d3SJohn Marino "group \"%s\"", lv->vg->name);
53086d7f5d3SJohn Marino return EINVALID_CMD_LINE;
53186d7f5d3SJohn Marino }
53286d7f5d3SJohn Marino
53386d7f5d3SJohn Marino if (lv_is_origin(lv) &&
53486d7f5d3SJohn Marino (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
53586d7f5d3SJohn Marino arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
53686d7f5d3SJohn Marino arg_count(cmd, alloc_ARG))) {
53786d7f5d3SJohn Marino log_error("Can't change logical volume \"%s\" under snapshot",
53886d7f5d3SJohn Marino lv->name);
53986d7f5d3SJohn Marino return ECMD_FAILED;
54086d7f5d3SJohn Marino }
54186d7f5d3SJohn Marino
54286d7f5d3SJohn Marino if (lv_is_cow(lv) && !lv_is_virtual_origin(origin_from_cow(lv)) &&
54386d7f5d3SJohn Marino arg_count(cmd, available_ARG)) {
54486d7f5d3SJohn Marino log_error("Can't change snapshot logical volume \"%s\"",
54586d7f5d3SJohn Marino lv->name);
54686d7f5d3SJohn Marino return ECMD_FAILED;
54786d7f5d3SJohn Marino }
54886d7f5d3SJohn Marino
54986d7f5d3SJohn Marino if (lv->status & PVMOVE) {
55086d7f5d3SJohn Marino log_error("Unable to change pvmove LV %s", lv->name);
55186d7f5d3SJohn Marino if (arg_count(cmd, available_ARG))
55286d7f5d3SJohn Marino log_error("Use 'pvmove --abort' to abandon a pvmove");
55386d7f5d3SJohn Marino return ECMD_FAILED;
55486d7f5d3SJohn Marino }
55586d7f5d3SJohn Marino
55686d7f5d3SJohn Marino if (lv->status & MIRROR_LOG) {
55786d7f5d3SJohn Marino log_error("Unable to change mirror log LV %s directly", lv->name);
55886d7f5d3SJohn Marino return ECMD_FAILED;
55986d7f5d3SJohn Marino }
56086d7f5d3SJohn Marino
56186d7f5d3SJohn Marino if (lv->status & MIRROR_IMAGE) {
56286d7f5d3SJohn Marino log_error("Unable to change mirror image LV %s directly",
56386d7f5d3SJohn Marino lv->name);
56486d7f5d3SJohn Marino return ECMD_FAILED;
56586d7f5d3SJohn Marino }
56686d7f5d3SJohn Marino
56786d7f5d3SJohn Marino /* If LV is sparse, activate origin instead */
56886d7f5d3SJohn Marino if (arg_count(cmd, available_ARG) && lv_is_cow(lv) &&
56986d7f5d3SJohn Marino lv_is_virtual_origin(origin = origin_from_cow(lv)))
57086d7f5d3SJohn Marino lv = origin;
57186d7f5d3SJohn Marino
57286d7f5d3SJohn Marino if (!(lv_is_visible(lv)) && !lv_is_virtual_origin(lv)) {
57386d7f5d3SJohn Marino log_error("Unable to change internal LV %s directly",
57486d7f5d3SJohn Marino lv->name);
57586d7f5d3SJohn Marino return ECMD_FAILED;
57686d7f5d3SJohn Marino }
57786d7f5d3SJohn Marino
57886d7f5d3SJohn Marino init_dmeventd_monitor(arg_int_value(cmd, monitor_ARG,
57986d7f5d3SJohn Marino (is_static() || arg_count(cmd, ignoremonitoring_ARG)) ?
58086d7f5d3SJohn Marino DMEVENTD_MONITOR_IGNORE : DEFAULT_DMEVENTD_MONITOR));
58186d7f5d3SJohn Marino
58286d7f5d3SJohn Marino /* access permission change */
58386d7f5d3SJohn Marino if (arg_count(cmd, permission_ARG)) {
58486d7f5d3SJohn Marino if (!archive(lv->vg)) {
58586d7f5d3SJohn Marino stack;
58686d7f5d3SJohn Marino return ECMD_FAILED;
58786d7f5d3SJohn Marino }
58886d7f5d3SJohn Marino archived = 1;
58986d7f5d3SJohn Marino doit += lvchange_permission(cmd, lv);
59086d7f5d3SJohn Marino docmds++;
59186d7f5d3SJohn Marino }
59286d7f5d3SJohn Marino
59386d7f5d3SJohn Marino /* allocation policy change */
59486d7f5d3SJohn Marino if (arg_count(cmd, contiguous_ARG) || arg_count(cmd, alloc_ARG)) {
59586d7f5d3SJohn Marino if (!archived && !archive(lv->vg)) {
59686d7f5d3SJohn Marino stack;
59786d7f5d3SJohn Marino return ECMD_FAILED;
59886d7f5d3SJohn Marino }
59986d7f5d3SJohn Marino archived = 1;
60086d7f5d3SJohn Marino doit += lvchange_alloc(cmd, lv);
60186d7f5d3SJohn Marino docmds++;
60286d7f5d3SJohn Marino }
60386d7f5d3SJohn Marino
60486d7f5d3SJohn Marino /* read ahead sector change */
60586d7f5d3SJohn Marino if (arg_count(cmd, readahead_ARG)) {
60686d7f5d3SJohn Marino if (!archived && !archive(lv->vg)) {
60786d7f5d3SJohn Marino stack;
60886d7f5d3SJohn Marino return ECMD_FAILED;
60986d7f5d3SJohn Marino }
61086d7f5d3SJohn Marino archived = 1;
61186d7f5d3SJohn Marino doit += lvchange_readahead(cmd, lv);
61286d7f5d3SJohn Marino docmds++;
61386d7f5d3SJohn Marino }
61486d7f5d3SJohn Marino
61586d7f5d3SJohn Marino /* persistent device number change */
61686d7f5d3SJohn Marino if (arg_count(cmd, persistent_ARG)) {
61786d7f5d3SJohn Marino if (!archived && !archive(lv->vg)) {
61886d7f5d3SJohn Marino stack;
61986d7f5d3SJohn Marino return ECMD_FAILED;
62086d7f5d3SJohn Marino }
62186d7f5d3SJohn Marino archived = 1;
62286d7f5d3SJohn Marino doit += lvchange_persistent(cmd, lv);
62386d7f5d3SJohn Marino docmds++;
62486d7f5d3SJohn Marino if (sigint_caught()) {
62586d7f5d3SJohn Marino stack;
62686d7f5d3SJohn Marino return ECMD_FAILED;
62786d7f5d3SJohn Marino }
62886d7f5d3SJohn Marino }
62986d7f5d3SJohn Marino
63086d7f5d3SJohn Marino /* add tag */
63186d7f5d3SJohn Marino if (arg_count(cmd, addtag_ARG)) {
63286d7f5d3SJohn Marino if (!archived && !archive(lv->vg)) {
63386d7f5d3SJohn Marino stack;
63486d7f5d3SJohn Marino return ECMD_FAILED;
63586d7f5d3SJohn Marino }
63686d7f5d3SJohn Marino archived = 1;
63786d7f5d3SJohn Marino doit += lvchange_tag(cmd, lv, addtag_ARG);
63886d7f5d3SJohn Marino docmds++;
63986d7f5d3SJohn Marino }
64086d7f5d3SJohn Marino
64186d7f5d3SJohn Marino /* del tag */
64286d7f5d3SJohn Marino if (arg_count(cmd, deltag_ARG)) {
64386d7f5d3SJohn Marino if (!archived && !archive(lv->vg)) {
64486d7f5d3SJohn Marino stack;
64586d7f5d3SJohn Marino return ECMD_FAILED;
64686d7f5d3SJohn Marino }
64786d7f5d3SJohn Marino archived = 1;
64886d7f5d3SJohn Marino doit += lvchange_tag(cmd, lv, deltag_ARG);
64986d7f5d3SJohn Marino docmds++;
65086d7f5d3SJohn Marino }
65186d7f5d3SJohn Marino
65286d7f5d3SJohn Marino if (doit)
65386d7f5d3SJohn Marino log_print("Logical volume \"%s\" changed", lv->name);
65486d7f5d3SJohn Marino
65586d7f5d3SJohn Marino if (arg_count(cmd, resync_ARG))
65686d7f5d3SJohn Marino if (!lvchange_resync(cmd, lv)) {
65786d7f5d3SJohn Marino stack;
65886d7f5d3SJohn Marino return ECMD_FAILED;
65986d7f5d3SJohn Marino }
66086d7f5d3SJohn Marino
66186d7f5d3SJohn Marino /* availability change */
66286d7f5d3SJohn Marino if (arg_count(cmd, available_ARG)) {
66386d7f5d3SJohn Marino if (!lvchange_availability(cmd, lv)) {
66486d7f5d3SJohn Marino stack;
66586d7f5d3SJohn Marino return ECMD_FAILED;
66686d7f5d3SJohn Marino }
66786d7f5d3SJohn Marino }
66886d7f5d3SJohn Marino
66986d7f5d3SJohn Marino if (arg_count(cmd, refresh_ARG))
67086d7f5d3SJohn Marino if (!lvchange_refresh(cmd, lv)) {
67186d7f5d3SJohn Marino stack;
67286d7f5d3SJohn Marino return ECMD_FAILED;
67386d7f5d3SJohn Marino }
67486d7f5d3SJohn Marino
67586d7f5d3SJohn Marino if (!arg_count(cmd, available_ARG) &&
67686d7f5d3SJohn Marino !arg_count(cmd, refresh_ARG) &&
67786d7f5d3SJohn Marino arg_count(cmd, monitor_ARG)) {
67886d7f5d3SJohn Marino if (!lvchange_monitoring(cmd, lv)) {
67986d7f5d3SJohn Marino stack;
68086d7f5d3SJohn Marino return ECMD_FAILED;
68186d7f5d3SJohn Marino }
68286d7f5d3SJohn Marino }
68386d7f5d3SJohn Marino
68486d7f5d3SJohn Marino if (doit != docmds) {
68586d7f5d3SJohn Marino stack;
68686d7f5d3SJohn Marino return ECMD_FAILED;
68786d7f5d3SJohn Marino }
68886d7f5d3SJohn Marino
68986d7f5d3SJohn Marino return ECMD_PROCESSED;
69086d7f5d3SJohn Marino }
69186d7f5d3SJohn Marino
lvchange(struct cmd_context * cmd,int argc,char ** argv)69286d7f5d3SJohn Marino int lvchange(struct cmd_context *cmd, int argc, char **argv)
69386d7f5d3SJohn Marino {
69486d7f5d3SJohn Marino if (!arg_count(cmd, available_ARG) && !arg_count(cmd, contiguous_ARG)
69586d7f5d3SJohn Marino && !arg_count(cmd, permission_ARG) && !arg_count(cmd, readahead_ARG)
69686d7f5d3SJohn Marino && !arg_count(cmd, minor_ARG) && !arg_count(cmd, major_ARG)
69786d7f5d3SJohn Marino && !arg_count(cmd, persistent_ARG) && !arg_count(cmd, addtag_ARG)
69886d7f5d3SJohn Marino && !arg_count(cmd, deltag_ARG) && !arg_count(cmd, refresh_ARG)
69986d7f5d3SJohn Marino && !arg_count(cmd, alloc_ARG) && !arg_count(cmd, monitor_ARG)
70086d7f5d3SJohn Marino && !arg_count(cmd, resync_ARG)) {
70186d7f5d3SJohn Marino log_error("Need 1 or more of -a, -C, -j, -m, -M, -p, -r, "
70286d7f5d3SJohn Marino "--resync, --refresh, --alloc, --addtag, --deltag "
70386d7f5d3SJohn Marino "or --monitor");
70486d7f5d3SJohn Marino return EINVALID_CMD_LINE;
70586d7f5d3SJohn Marino }
70686d7f5d3SJohn Marino
70786d7f5d3SJohn Marino int avail_only = /* i.e. only one of -a or --refresh is given */
70886d7f5d3SJohn Marino !(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
70986d7f5d3SJohn Marino arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
71086d7f5d3SJohn Marino arg_count(cmd, addtag_ARG) || arg_count(cmd, deltag_ARG) ||
71186d7f5d3SJohn Marino arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG));
71286d7f5d3SJohn Marino
71386d7f5d3SJohn Marino if (arg_count(cmd, ignorelockingfailure_ARG) && !avail_only) {
71486d7f5d3SJohn Marino log_error("Only -a permitted with --ignorelockingfailure");
71586d7f5d3SJohn Marino return EINVALID_CMD_LINE;
71686d7f5d3SJohn Marino }
71786d7f5d3SJohn Marino
71886d7f5d3SJohn Marino if (avail_only)
71986d7f5d3SJohn Marino cmd->handles_missing_pvs = 1;
72086d7f5d3SJohn Marino
72186d7f5d3SJohn Marino if (!argc) {
72286d7f5d3SJohn Marino log_error("Please give logical volume path(s)");
72386d7f5d3SJohn Marino return EINVALID_CMD_LINE;
72486d7f5d3SJohn Marino }
72586d7f5d3SJohn Marino
72686d7f5d3SJohn Marino if ((arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) &&
72786d7f5d3SJohn Marino !arg_count(cmd, persistent_ARG)) {
72886d7f5d3SJohn Marino log_error("--major and --minor require -My");
72986d7f5d3SJohn Marino return EINVALID_CMD_LINE;
73086d7f5d3SJohn Marino }
73186d7f5d3SJohn Marino
73286d7f5d3SJohn Marino if (arg_count(cmd, minor_ARG) && argc != 1) {
73386d7f5d3SJohn Marino log_error("Only give one logical volume when specifying minor");
73486d7f5d3SJohn Marino return EINVALID_CMD_LINE;
73586d7f5d3SJohn Marino }
73686d7f5d3SJohn Marino
73786d7f5d3SJohn Marino if (arg_count(cmd, contiguous_ARG) && arg_count(cmd, alloc_ARG)) {
73886d7f5d3SJohn Marino log_error("Only one of --alloc and --contiguous permitted");
73986d7f5d3SJohn Marino return EINVALID_CMD_LINE;
74086d7f5d3SJohn Marino }
74186d7f5d3SJohn Marino
74286d7f5d3SJohn Marino return process_each_lv(cmd, argc, argv,
74386d7f5d3SJohn Marino avail_only ? 0 : READ_FOR_UPDATE, NULL,
74486d7f5d3SJohn Marino &lvchange_single);
74586d7f5d3SJohn Marino }
746