xref: /dflybsd-src/contrib/lvm2/dist/tools/vgchange.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
186d7f5d3SJohn Marino /*	$NetBSD: vgchange.c,v 1.1.1.3 2009/12/02 00:25:51 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 
_monitor_lvs_in_vg(struct cmd_context * cmd,struct volume_group * vg,int reg)2086d7f5d3SJohn Marino static int _monitor_lvs_in_vg(struct cmd_context *cmd,
2186d7f5d3SJohn Marino 			       struct volume_group *vg, int reg)
2286d7f5d3SJohn Marino {
2386d7f5d3SJohn Marino 	struct lv_list *lvl;
2486d7f5d3SJohn Marino 	struct logical_volume *lv;
2586d7f5d3SJohn Marino 	struct lvinfo info;
2686d7f5d3SJohn Marino 	int lv_active;
2786d7f5d3SJohn Marino 	int count = 0;
2886d7f5d3SJohn Marino 
2986d7f5d3SJohn Marino 	dm_list_iterate_items(lvl, &vg->lvs) {
3086d7f5d3SJohn Marino 		lv = lvl->lv;
3186d7f5d3SJohn Marino 
3286d7f5d3SJohn Marino 		if (!lv_info(cmd, lv, &info, 0, 0))
3386d7f5d3SJohn Marino 			lv_active = 0;
3486d7f5d3SJohn Marino 		else
3586d7f5d3SJohn Marino 			lv_active = info.exists;
3686d7f5d3SJohn Marino 
3786d7f5d3SJohn Marino 		/*
3886d7f5d3SJohn Marino 		 * FIXME: Need to consider all cases... PVMOVE, etc
3986d7f5d3SJohn Marino 		 */
4086d7f5d3SJohn Marino 		if ((lv->status & PVMOVE) || !lv_active)
4186d7f5d3SJohn Marino 			continue;
4286d7f5d3SJohn Marino 
4386d7f5d3SJohn Marino 		if (!monitor_dev_for_events(cmd, lv, reg)) {
4486d7f5d3SJohn Marino 			continue;
4586d7f5d3SJohn Marino 		} else
4686d7f5d3SJohn Marino 			count++;
4786d7f5d3SJohn Marino 	}
4886d7f5d3SJohn Marino 
4986d7f5d3SJohn Marino 	/*
5086d7f5d3SJohn Marino 	 * returns the number of _new_ monitored devices
5186d7f5d3SJohn Marino 	 */
5286d7f5d3SJohn Marino 
5386d7f5d3SJohn Marino 	return count;
5486d7f5d3SJohn Marino }
5586d7f5d3SJohn Marino 
_activate_lvs_in_vg(struct cmd_context * cmd,struct volume_group * vg,int activate)5686d7f5d3SJohn Marino static int _activate_lvs_in_vg(struct cmd_context *cmd,
5786d7f5d3SJohn Marino 			       struct volume_group *vg, int activate)
5886d7f5d3SJohn Marino {
5986d7f5d3SJohn Marino 	struct lv_list *lvl;
6086d7f5d3SJohn Marino 	struct logical_volume *lv;
6186d7f5d3SJohn Marino 	int count = 0, expected_count = 0;
6286d7f5d3SJohn Marino 
6386d7f5d3SJohn Marino 	dm_list_iterate_items(lvl, &vg->lvs) {
6486d7f5d3SJohn Marino 		lv = lvl->lv;
6586d7f5d3SJohn Marino 
6686d7f5d3SJohn Marino 		if (!lv_is_visible(lv))
6786d7f5d3SJohn Marino 			continue;
6886d7f5d3SJohn Marino 
6986d7f5d3SJohn Marino 		/* Only request activation of snapshot origin devices */
7086d7f5d3SJohn Marino 		if ((lv->status & SNAPSHOT) || lv_is_cow(lv))
7186d7f5d3SJohn Marino 			continue;
7286d7f5d3SJohn Marino 
7386d7f5d3SJohn Marino 		/* Only request activation of mirror LV */
7486d7f5d3SJohn Marino 		if ((lv->status & MIRROR_IMAGE) || (lv->status & MIRROR_LOG))
7586d7f5d3SJohn Marino 			continue;
7686d7f5d3SJohn Marino 
7786d7f5d3SJohn Marino 		/* Can't deactivate a pvmove LV */
7886d7f5d3SJohn Marino 		/* FIXME There needs to be a controlled way of doing this */
7986d7f5d3SJohn Marino 		if (((activate == CHANGE_AN) || (activate == CHANGE_ALN)) &&
8086d7f5d3SJohn Marino 		    ((lv->status & PVMOVE) ))
8186d7f5d3SJohn Marino 			continue;
8286d7f5d3SJohn Marino 
8386d7f5d3SJohn Marino 		expected_count++;
8486d7f5d3SJohn Marino 
8586d7f5d3SJohn Marino 		if (activate == CHANGE_AN) {
8686d7f5d3SJohn Marino 			if (!deactivate_lv(cmd, lv))
8786d7f5d3SJohn Marino 				continue;
8886d7f5d3SJohn Marino 		} else if (activate == CHANGE_ALN) {
8986d7f5d3SJohn Marino 			if (!deactivate_lv_local(cmd, lv))
9086d7f5d3SJohn Marino 				continue;
9186d7f5d3SJohn Marino 		} else if (lv_is_origin(lv) || (activate == CHANGE_AE)) {
9286d7f5d3SJohn Marino 			if (!activate_lv_excl(cmd, lv))
9386d7f5d3SJohn Marino 				continue;
9486d7f5d3SJohn Marino 		} else if (activate == CHANGE_ALY) {
9586d7f5d3SJohn Marino 			if (!activate_lv_local(cmd, lv))
9686d7f5d3SJohn Marino 				continue;
9786d7f5d3SJohn Marino 		} else if (!activate_lv(cmd, lv))
9886d7f5d3SJohn Marino 			continue;
9986d7f5d3SJohn Marino 
10086d7f5d3SJohn Marino 		if (activate != CHANGE_AN && activate != CHANGE_ALN &&
10186d7f5d3SJohn Marino 		    (lv->status & (PVMOVE|CONVERTING)))
10286d7f5d3SJohn Marino 			lv_spawn_background_polling(cmd, lv);
10386d7f5d3SJohn Marino 
10486d7f5d3SJohn Marino 		count++;
10586d7f5d3SJohn Marino 	}
10686d7f5d3SJohn Marino 
10786d7f5d3SJohn Marino 	if (expected_count)
10886d7f5d3SJohn Marino 		log_verbose("%s %d logical volumes in volume group %s",
10986d7f5d3SJohn Marino 			    activate ? "Activated" : "Deactivated",
11086d7f5d3SJohn Marino 			    count, vg->name);
11186d7f5d3SJohn Marino 
11286d7f5d3SJohn Marino 	return (expected_count != count) ? ECMD_FAILED : ECMD_PROCESSED;
11386d7f5d3SJohn Marino }
11486d7f5d3SJohn Marino 
_vgchange_monitoring(struct cmd_context * cmd,struct volume_group * vg)11586d7f5d3SJohn Marino static int _vgchange_monitoring(struct cmd_context *cmd, struct volume_group *vg)
11686d7f5d3SJohn Marino {
11786d7f5d3SJohn Marino 	int active, monitored;
11886d7f5d3SJohn Marino 
11986d7f5d3SJohn Marino 	if ((active = lvs_in_vg_activated(vg)) &&
12086d7f5d3SJohn Marino 	    dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) {
12186d7f5d3SJohn Marino 		monitored = _monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode());
12286d7f5d3SJohn Marino 		log_print("%d logical volume(s) in volume group "
12386d7f5d3SJohn Marino 			    "\"%s\" %smonitored",
12486d7f5d3SJohn Marino 			    monitored, vg->name, (dmeventd_monitor_mode()) ? "" : "un");
12586d7f5d3SJohn Marino 	}
12686d7f5d3SJohn Marino 
12786d7f5d3SJohn Marino 	return ECMD_PROCESSED;
12886d7f5d3SJohn Marino }
12986d7f5d3SJohn Marino 
_vgchange_available(struct cmd_context * cmd,struct volume_group * vg)13086d7f5d3SJohn Marino static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
13186d7f5d3SJohn Marino {
13286d7f5d3SJohn Marino 	int lv_open, active, monitored;
13386d7f5d3SJohn Marino 	int available, ret;
13486d7f5d3SJohn Marino 	int activate = 1;
13586d7f5d3SJohn Marino 
13686d7f5d3SJohn Marino 	/*
13786d7f5d3SJohn Marino 	 * Safe, since we never write out new metadata here. Required for
13886d7f5d3SJohn Marino 	 * partial activation to work.
13986d7f5d3SJohn Marino 	 */
14086d7f5d3SJohn Marino 	cmd->handles_missing_pvs = 1;
14186d7f5d3SJohn Marino 
14286d7f5d3SJohn Marino 	available = arg_uint_value(cmd, available_ARG, 0);
14386d7f5d3SJohn Marino 
14486d7f5d3SJohn Marino 	if ((available == CHANGE_AN) || (available == CHANGE_ALN))
14586d7f5d3SJohn Marino 		activate = 0;
14686d7f5d3SJohn Marino 
14786d7f5d3SJohn Marino 	/* FIXME: Force argument to deactivate them? */
14886d7f5d3SJohn Marino 	if (!activate && (lv_open = lvs_in_vg_opened(vg))) {
14986d7f5d3SJohn Marino 		log_error("Can't deactivate volume group \"%s\" with %d open "
15086d7f5d3SJohn Marino 			  "logical volume(s)", vg->name, lv_open);
15186d7f5d3SJohn Marino 		return ECMD_FAILED;
15286d7f5d3SJohn Marino 	}
15386d7f5d3SJohn Marino 
15486d7f5d3SJohn Marino 	/* FIXME Move into library where clvmd can use it */
15586d7f5d3SJohn Marino 	if (activate)
15686d7f5d3SJohn Marino 		check_current_backup(vg);
15786d7f5d3SJohn Marino 
15886d7f5d3SJohn Marino 	if (activate && (active = lvs_in_vg_activated(vg))) {
15986d7f5d3SJohn Marino 		log_verbose("%d logical volume(s) in volume group \"%s\" "
16086d7f5d3SJohn Marino 			    "already active", active, vg->name);
16186d7f5d3SJohn Marino 		if (dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) {
16286d7f5d3SJohn Marino 			monitored = _monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode());
16386d7f5d3SJohn Marino 			log_verbose("%d existing logical volume(s) in volume "
16486d7f5d3SJohn Marino 				    "group \"%s\" %smonitored",
16586d7f5d3SJohn Marino 				    monitored, vg->name,
16686d7f5d3SJohn Marino 				    dmeventd_monitor_mode() ? "" : "un");
16786d7f5d3SJohn Marino 		}
16886d7f5d3SJohn Marino 	}
16986d7f5d3SJohn Marino 
17086d7f5d3SJohn Marino 	ret = _activate_lvs_in_vg(cmd, vg, available);
17186d7f5d3SJohn Marino 
17286d7f5d3SJohn Marino 	log_print("%d logical volume(s) in volume group \"%s\" now active",
17386d7f5d3SJohn Marino 		  lvs_in_vg_activated(vg), vg->name);
17486d7f5d3SJohn Marino 	return ret;
17586d7f5d3SJohn Marino }
17686d7f5d3SJohn Marino 
_vgchange_alloc(struct cmd_context * cmd,struct volume_group * vg)17786d7f5d3SJohn Marino static int _vgchange_alloc(struct cmd_context *cmd, struct volume_group *vg)
17886d7f5d3SJohn Marino {
17986d7f5d3SJohn Marino 	alloc_policy_t alloc;
18086d7f5d3SJohn Marino 
18186d7f5d3SJohn Marino 	alloc = arg_uint_value(cmd, alloc_ARG, ALLOC_NORMAL);
18286d7f5d3SJohn Marino 
18386d7f5d3SJohn Marino 	if (!archive(vg)) {
18486d7f5d3SJohn Marino 		stack;
18586d7f5d3SJohn Marino 		return ECMD_FAILED;
18686d7f5d3SJohn Marino 	}
18786d7f5d3SJohn Marino 
18886d7f5d3SJohn Marino 	/* FIXME: make consistent with vg_set_alloc_policy() */
18986d7f5d3SJohn Marino 	if (alloc == vg->alloc) {
19086d7f5d3SJohn Marino 		log_error("Volume group allocation policy is already %s",
19186d7f5d3SJohn Marino 			  get_alloc_string(vg->alloc));
19286d7f5d3SJohn Marino 		return ECMD_FAILED;
19386d7f5d3SJohn Marino 	}
19486d7f5d3SJohn Marino 	if (!vg_set_alloc_policy(vg, alloc)) {
19586d7f5d3SJohn Marino 		stack;
19686d7f5d3SJohn Marino 		return ECMD_FAILED;
19786d7f5d3SJohn Marino 	}
19886d7f5d3SJohn Marino 
19986d7f5d3SJohn Marino 	if (!vg_write(vg) || !vg_commit(vg)) {
20086d7f5d3SJohn Marino 		stack;
20186d7f5d3SJohn Marino 		return ECMD_FAILED;
20286d7f5d3SJohn Marino 	}
20386d7f5d3SJohn Marino 
20486d7f5d3SJohn Marino 	backup(vg);
20586d7f5d3SJohn Marino 
20686d7f5d3SJohn Marino 	log_print("Volume group \"%s\" successfully changed", vg->name);
20786d7f5d3SJohn Marino 
20886d7f5d3SJohn Marino 	return ECMD_PROCESSED;
20986d7f5d3SJohn Marino }
21086d7f5d3SJohn Marino 
_vgchange_resizeable(struct cmd_context * cmd,struct volume_group * vg)21186d7f5d3SJohn Marino static int _vgchange_resizeable(struct cmd_context *cmd,
21286d7f5d3SJohn Marino 				struct volume_group *vg)
21386d7f5d3SJohn Marino {
21486d7f5d3SJohn Marino 	int resizeable = !strcmp(arg_str_value(cmd, resizeable_ARG, "n"), "y");
21586d7f5d3SJohn Marino 
21686d7f5d3SJohn Marino 	if (resizeable && vg_is_resizeable(vg)) {
21786d7f5d3SJohn Marino 		log_error("Volume group \"%s\" is already resizeable",
21886d7f5d3SJohn Marino 			  vg->name);
21986d7f5d3SJohn Marino 		return ECMD_FAILED;
22086d7f5d3SJohn Marino 	}
22186d7f5d3SJohn Marino 
22286d7f5d3SJohn Marino 	if (!resizeable && !vg_is_resizeable(vg)) {
22386d7f5d3SJohn Marino 		log_error("Volume group \"%s\" is already not resizeable",
22486d7f5d3SJohn Marino 			  vg->name);
22586d7f5d3SJohn Marino 		return ECMD_FAILED;
22686d7f5d3SJohn Marino 	}
22786d7f5d3SJohn Marino 
22886d7f5d3SJohn Marino 	if (!archive(vg)) {
22986d7f5d3SJohn Marino 		stack;
23086d7f5d3SJohn Marino 		return ECMD_FAILED;
23186d7f5d3SJohn Marino 	}
23286d7f5d3SJohn Marino 
23386d7f5d3SJohn Marino 	if (resizeable)
23486d7f5d3SJohn Marino 		vg->status |= RESIZEABLE_VG;
23586d7f5d3SJohn Marino 	else
23686d7f5d3SJohn Marino 		vg->status &= ~RESIZEABLE_VG;
23786d7f5d3SJohn Marino 
23886d7f5d3SJohn Marino 	if (!vg_write(vg) || !vg_commit(vg)) {
23986d7f5d3SJohn Marino 		stack;
24086d7f5d3SJohn Marino 		return ECMD_FAILED;
24186d7f5d3SJohn Marino 	}
24286d7f5d3SJohn Marino 
24386d7f5d3SJohn Marino 	backup(vg);
24486d7f5d3SJohn Marino 
24586d7f5d3SJohn Marino 	log_print("Volume group \"%s\" successfully changed", vg->name);
24686d7f5d3SJohn Marino 
24786d7f5d3SJohn Marino 	return ECMD_PROCESSED;
24886d7f5d3SJohn Marino }
24986d7f5d3SJohn Marino 
_vgchange_clustered(struct cmd_context * cmd,struct volume_group * vg)25086d7f5d3SJohn Marino static int _vgchange_clustered(struct cmd_context *cmd,
25186d7f5d3SJohn Marino 			       struct volume_group *vg)
25286d7f5d3SJohn Marino {
25386d7f5d3SJohn Marino 	int clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y");
25486d7f5d3SJohn Marino 
25586d7f5d3SJohn Marino 	if (clustered && (vg_is_clustered(vg))) {
25686d7f5d3SJohn Marino 		log_error("Volume group \"%s\" is already clustered",
25786d7f5d3SJohn Marino 			  vg->name);
25886d7f5d3SJohn Marino 		return ECMD_FAILED;
25986d7f5d3SJohn Marino 	}
26086d7f5d3SJohn Marino 
26186d7f5d3SJohn Marino 	if (!clustered && !(vg_is_clustered(vg))) {
26286d7f5d3SJohn Marino 		log_error("Volume group \"%s\" is already not clustered",
26386d7f5d3SJohn Marino 			  vg->name);
26486d7f5d3SJohn Marino 		return ECMD_FAILED;
26586d7f5d3SJohn Marino 	}
26686d7f5d3SJohn Marino 
26786d7f5d3SJohn Marino 	if (!archive(vg)) {
26886d7f5d3SJohn Marino 		stack;
26986d7f5d3SJohn Marino 		return ECMD_FAILED;
27086d7f5d3SJohn Marino 	}
27186d7f5d3SJohn Marino 
27286d7f5d3SJohn Marino 	if (!vg_set_clustered(vg, clustered))
27386d7f5d3SJohn Marino 		return ECMD_FAILED;
27486d7f5d3SJohn Marino 
27586d7f5d3SJohn Marino 	if (!vg_write(vg) || !vg_commit(vg)) {
27686d7f5d3SJohn Marino 		stack;
27786d7f5d3SJohn Marino 		return ECMD_FAILED;
27886d7f5d3SJohn Marino 	}
27986d7f5d3SJohn Marino 
28086d7f5d3SJohn Marino 	backup(vg);
28186d7f5d3SJohn Marino 
28286d7f5d3SJohn Marino 	log_print("Volume group \"%s\" successfully changed", vg->name);
28386d7f5d3SJohn Marino 
28486d7f5d3SJohn Marino 	return ECMD_PROCESSED;
28586d7f5d3SJohn Marino }
28686d7f5d3SJohn Marino 
_vgchange_logicalvolume(struct cmd_context * cmd,struct volume_group * vg)28786d7f5d3SJohn Marino static int _vgchange_logicalvolume(struct cmd_context *cmd,
28886d7f5d3SJohn Marino 				   struct volume_group *vg)
28986d7f5d3SJohn Marino {
29086d7f5d3SJohn Marino 	uint32_t max_lv = arg_uint_value(cmd, logicalvolume_ARG, 0);
29186d7f5d3SJohn Marino 
29286d7f5d3SJohn Marino 	if (!archive(vg)) {
29386d7f5d3SJohn Marino 		stack;
29486d7f5d3SJohn Marino 		return ECMD_FAILED;
29586d7f5d3SJohn Marino 	}
29686d7f5d3SJohn Marino 
29786d7f5d3SJohn Marino 	if (!vg_set_max_lv(vg, max_lv)) {
29886d7f5d3SJohn Marino 		stack;
29986d7f5d3SJohn Marino 		return ECMD_FAILED;
30086d7f5d3SJohn Marino 	}
30186d7f5d3SJohn Marino 
30286d7f5d3SJohn Marino 	if (!vg_write(vg) || !vg_commit(vg)) {
30386d7f5d3SJohn Marino 		stack;
30486d7f5d3SJohn Marino 		return ECMD_FAILED;
30586d7f5d3SJohn Marino 	}
30686d7f5d3SJohn Marino 
30786d7f5d3SJohn Marino 	backup(vg);
30886d7f5d3SJohn Marino 
30986d7f5d3SJohn Marino 	log_print("Volume group \"%s\" successfully changed", vg->name);
31086d7f5d3SJohn Marino 
31186d7f5d3SJohn Marino 	return ECMD_PROCESSED;
31286d7f5d3SJohn Marino }
31386d7f5d3SJohn Marino 
_vgchange_physicalvolumes(struct cmd_context * cmd,struct volume_group * vg)31486d7f5d3SJohn Marino static int _vgchange_physicalvolumes(struct cmd_context *cmd,
31586d7f5d3SJohn Marino 				     struct volume_group *vg)
31686d7f5d3SJohn Marino {
31786d7f5d3SJohn Marino 	uint32_t max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0);
31886d7f5d3SJohn Marino 
31986d7f5d3SJohn Marino 	if (arg_sign_value(cmd, maxphysicalvolumes_ARG, 0) == SIGN_MINUS) {
32086d7f5d3SJohn Marino 		log_error("MaxPhysicalVolumes may not be negative");
32186d7f5d3SJohn Marino 		return EINVALID_CMD_LINE;
32286d7f5d3SJohn Marino 	}
32386d7f5d3SJohn Marino 
32486d7f5d3SJohn Marino 	if (!archive(vg)) {
32586d7f5d3SJohn Marino 		stack;
32686d7f5d3SJohn Marino 		return ECMD_FAILED;
32786d7f5d3SJohn Marino 	}
32886d7f5d3SJohn Marino 
32986d7f5d3SJohn Marino 	if (!vg_set_max_pv(vg, max_pv)) {
33086d7f5d3SJohn Marino 		stack;
33186d7f5d3SJohn Marino 		return ECMD_FAILED;
33286d7f5d3SJohn Marino 	}
33386d7f5d3SJohn Marino 
33486d7f5d3SJohn Marino 	if (!vg_write(vg) || !vg_commit(vg)) {
33586d7f5d3SJohn Marino 		stack;
33686d7f5d3SJohn Marino 		return ECMD_FAILED;
33786d7f5d3SJohn Marino 	}
33886d7f5d3SJohn Marino 
33986d7f5d3SJohn Marino 	backup(vg);
34086d7f5d3SJohn Marino 
34186d7f5d3SJohn Marino 	log_print("Volume group \"%s\" successfully changed", vg->name);
34286d7f5d3SJohn Marino 
34386d7f5d3SJohn Marino 	return ECMD_PROCESSED;
34486d7f5d3SJohn Marino }
34586d7f5d3SJohn Marino 
_vgchange_pesize(struct cmd_context * cmd,struct volume_group * vg)34686d7f5d3SJohn Marino static int _vgchange_pesize(struct cmd_context *cmd, struct volume_group *vg)
34786d7f5d3SJohn Marino {
34886d7f5d3SJohn Marino 	uint32_t extent_size;
34986d7f5d3SJohn Marino 
35086d7f5d3SJohn Marino 	if (arg_sign_value(cmd, physicalextentsize_ARG, 0) == SIGN_MINUS) {
35186d7f5d3SJohn Marino 		log_error("Physical extent size may not be negative");
35286d7f5d3SJohn Marino 		return EINVALID_CMD_LINE;
35386d7f5d3SJohn Marino 	}
35486d7f5d3SJohn Marino 
35586d7f5d3SJohn Marino 	extent_size = arg_uint_value(cmd, physicalextentsize_ARG, 0);
35686d7f5d3SJohn Marino 	/* FIXME: remove check - redundant with vg_change_pesize */
35786d7f5d3SJohn Marino 	if (extent_size == vg->extent_size) {
35886d7f5d3SJohn Marino 		log_error("Physical extent size of VG %s is already %s",
35986d7f5d3SJohn Marino 			  vg->name, display_size(cmd, (uint64_t) extent_size));
36086d7f5d3SJohn Marino 		return ECMD_PROCESSED;
36186d7f5d3SJohn Marino 	}
36286d7f5d3SJohn Marino 
36386d7f5d3SJohn Marino 	if (!archive(vg)) {
36486d7f5d3SJohn Marino 		stack;
36586d7f5d3SJohn Marino 		return ECMD_FAILED;
36686d7f5d3SJohn Marino 	}
36786d7f5d3SJohn Marino 
36886d7f5d3SJohn Marino 	if (!vg_set_extent_size(vg, extent_size)) {
36986d7f5d3SJohn Marino 		stack;
37086d7f5d3SJohn Marino 		return EINVALID_CMD_LINE;
37186d7f5d3SJohn Marino 	}
37286d7f5d3SJohn Marino 
37386d7f5d3SJohn Marino 	if (!vg_write(vg) || !vg_commit(vg)) {
37486d7f5d3SJohn Marino 		stack;
37586d7f5d3SJohn Marino 		return ECMD_FAILED;
37686d7f5d3SJohn Marino 	}
37786d7f5d3SJohn Marino 
37886d7f5d3SJohn Marino 	backup(vg);
37986d7f5d3SJohn Marino 
38086d7f5d3SJohn Marino 	log_print("Volume group \"%s\" successfully changed", vg->name);
38186d7f5d3SJohn Marino 
38286d7f5d3SJohn Marino 	return ECMD_PROCESSED;
38386d7f5d3SJohn Marino }
38486d7f5d3SJohn Marino 
_vgchange_tag(struct cmd_context * cmd,struct volume_group * vg,int arg)38586d7f5d3SJohn Marino static int _vgchange_tag(struct cmd_context *cmd, struct volume_group *vg,
38686d7f5d3SJohn Marino 			 int arg)
38786d7f5d3SJohn Marino {
38886d7f5d3SJohn Marino 	const char *tag;
38986d7f5d3SJohn Marino 
39086d7f5d3SJohn Marino 	if (!(tag = arg_str_value(cmd, arg, NULL))) {
39186d7f5d3SJohn Marino 		log_error("Failed to get tag");
39286d7f5d3SJohn Marino 		return ECMD_FAILED;
39386d7f5d3SJohn Marino 	}
39486d7f5d3SJohn Marino 
39586d7f5d3SJohn Marino 	if (!(vg->fid->fmt->features & FMT_TAGS)) {
39686d7f5d3SJohn Marino 		log_error("Volume group %s does not support tags", vg->name);
39786d7f5d3SJohn Marino 		return ECMD_FAILED;
39886d7f5d3SJohn Marino 	}
39986d7f5d3SJohn Marino 
40086d7f5d3SJohn Marino 	if (!archive(vg)) {
40186d7f5d3SJohn Marino 		stack;
40286d7f5d3SJohn Marino 		return ECMD_FAILED;
40386d7f5d3SJohn Marino 	}
40486d7f5d3SJohn Marino 
40586d7f5d3SJohn Marino 	if ((arg == addtag_ARG)) {
40686d7f5d3SJohn Marino 		if (!str_list_add(cmd->mem, &vg->tags, tag)) {
40786d7f5d3SJohn Marino 			log_error("Failed to add tag %s to volume group %s",
40886d7f5d3SJohn Marino 				  tag, vg->name);
40986d7f5d3SJohn Marino 			return ECMD_FAILED;
41086d7f5d3SJohn Marino 		}
41186d7f5d3SJohn Marino 	} else {
41286d7f5d3SJohn Marino 		if (!str_list_del(&vg->tags, tag)) {
41386d7f5d3SJohn Marino 			log_error("Failed to remove tag %s from volume group "
41486d7f5d3SJohn Marino 				  "%s", tag, vg->name);
41586d7f5d3SJohn Marino 			return ECMD_FAILED;
41686d7f5d3SJohn Marino 		}
41786d7f5d3SJohn Marino 	}
41886d7f5d3SJohn Marino 
41986d7f5d3SJohn Marino 	if (!vg_write(vg) || !vg_commit(vg)) {
42086d7f5d3SJohn Marino 		stack;
42186d7f5d3SJohn Marino 		return ECMD_FAILED;
42286d7f5d3SJohn Marino 	}
42386d7f5d3SJohn Marino 
42486d7f5d3SJohn Marino 	backup(vg);
42586d7f5d3SJohn Marino 
42686d7f5d3SJohn Marino 	log_print("Volume group \"%s\" successfully changed", vg->name);
42786d7f5d3SJohn Marino 
42886d7f5d3SJohn Marino 	return ECMD_PROCESSED;
42986d7f5d3SJohn Marino }
43086d7f5d3SJohn Marino 
_vgchange_uuid(struct cmd_context * cmd __attribute ((unused)),struct volume_group * vg)43186d7f5d3SJohn Marino static int _vgchange_uuid(struct cmd_context *cmd __attribute((unused)),
43286d7f5d3SJohn Marino 			  struct volume_group *vg)
43386d7f5d3SJohn Marino {
43486d7f5d3SJohn Marino 	struct lv_list *lvl;
43586d7f5d3SJohn Marino 
43686d7f5d3SJohn Marino 	if (lvs_in_vg_activated(vg)) {
43786d7f5d3SJohn Marino 		log_error("Volume group has active logical volumes");
43886d7f5d3SJohn Marino 		return ECMD_FAILED;
43986d7f5d3SJohn Marino 	}
44086d7f5d3SJohn Marino 
44186d7f5d3SJohn Marino 	if (!archive(vg)) {
44286d7f5d3SJohn Marino 		stack;
44386d7f5d3SJohn Marino 		return ECMD_FAILED;
44486d7f5d3SJohn Marino 	}
44586d7f5d3SJohn Marino 
44686d7f5d3SJohn Marino 	if (!id_create(&vg->id)) {
44786d7f5d3SJohn Marino 		log_error("Failed to generate new random UUID for VG %s.",
44886d7f5d3SJohn Marino 			  vg->name);
44986d7f5d3SJohn Marino 		return ECMD_FAILED;
45086d7f5d3SJohn Marino 	}
45186d7f5d3SJohn Marino 
45286d7f5d3SJohn Marino 	dm_list_iterate_items(lvl, &vg->lvs) {
45386d7f5d3SJohn Marino 		memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id));
45486d7f5d3SJohn Marino 	}
45586d7f5d3SJohn Marino 
45686d7f5d3SJohn Marino 	if (!vg_write(vg) || !vg_commit(vg)) {
45786d7f5d3SJohn Marino 		stack;
45886d7f5d3SJohn Marino 		return ECMD_FAILED;
45986d7f5d3SJohn Marino 	}
46086d7f5d3SJohn Marino 
46186d7f5d3SJohn Marino 	backup(vg);
46286d7f5d3SJohn Marino 
46386d7f5d3SJohn Marino 	log_print("Volume group \"%s\" successfully changed", vg->name);
46486d7f5d3SJohn Marino 
46586d7f5d3SJohn Marino 	return ECMD_PROCESSED;
46686d7f5d3SJohn Marino }
46786d7f5d3SJohn Marino 
_vgchange_refresh(struct cmd_context * cmd,struct volume_group * vg)46886d7f5d3SJohn Marino static int _vgchange_refresh(struct cmd_context *cmd, struct volume_group *vg)
46986d7f5d3SJohn Marino {
47086d7f5d3SJohn Marino 	log_verbose("Refreshing volume group \"%s\"", vg->name);
47186d7f5d3SJohn Marino 
47286d7f5d3SJohn Marino 	if (!vg_refresh_visible(cmd, vg)) {
47386d7f5d3SJohn Marino 		stack;
47486d7f5d3SJohn Marino 		return ECMD_FAILED;
47586d7f5d3SJohn Marino 	}
47686d7f5d3SJohn Marino 
47786d7f5d3SJohn Marino 	return ECMD_PROCESSED;
47886d7f5d3SJohn Marino }
47986d7f5d3SJohn Marino 
vgchange_single(struct cmd_context * cmd,const char * vg_name,struct volume_group * vg,void * handle __attribute ((unused)))48086d7f5d3SJohn Marino static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
48186d7f5d3SJohn Marino 			   struct volume_group *vg,
48286d7f5d3SJohn Marino 			   void *handle __attribute((unused)))
48386d7f5d3SJohn Marino {
48486d7f5d3SJohn Marino 	int r = ECMD_FAILED;
48586d7f5d3SJohn Marino 
48686d7f5d3SJohn Marino 	if (vg_is_exported(vg)) {
48786d7f5d3SJohn Marino 		log_error("Volume group \"%s\" is exported", vg_name);
48886d7f5d3SJohn Marino 		return ECMD_FAILED;
48986d7f5d3SJohn Marino 	}
49086d7f5d3SJohn Marino 
49186d7f5d3SJohn Marino 	init_dmeventd_monitor(arg_int_value(cmd, monitor_ARG,
49286d7f5d3SJohn Marino 					    (is_static() || arg_count(cmd, ignoremonitoring_ARG)) ?
49386d7f5d3SJohn Marino 					    DMEVENTD_MONITOR_IGNORE : DEFAULT_DMEVENTD_MONITOR));
49486d7f5d3SJohn Marino 
49586d7f5d3SJohn Marino 	if (arg_count(cmd, available_ARG))
49686d7f5d3SJohn Marino 		r = _vgchange_available(cmd, vg);
49786d7f5d3SJohn Marino 
49886d7f5d3SJohn Marino 	else if (arg_count(cmd, monitor_ARG))
49986d7f5d3SJohn Marino 		r = _vgchange_monitoring(cmd, vg);
50086d7f5d3SJohn Marino 
50186d7f5d3SJohn Marino 	else if (arg_count(cmd, resizeable_ARG))
50286d7f5d3SJohn Marino 		r = _vgchange_resizeable(cmd, vg);
50386d7f5d3SJohn Marino 
50486d7f5d3SJohn Marino 	else if (arg_count(cmd, logicalvolume_ARG))
50586d7f5d3SJohn Marino 		r = _vgchange_logicalvolume(cmd, vg);
50686d7f5d3SJohn Marino 
50786d7f5d3SJohn Marino 	else if (arg_count(cmd, maxphysicalvolumes_ARG))
50886d7f5d3SJohn Marino 		r = _vgchange_physicalvolumes(cmd, vg);
50986d7f5d3SJohn Marino 
51086d7f5d3SJohn Marino 	else if (arg_count(cmd, addtag_ARG))
51186d7f5d3SJohn Marino 		r = _vgchange_tag(cmd, vg, addtag_ARG);
51286d7f5d3SJohn Marino 
51386d7f5d3SJohn Marino 	else if (arg_count(cmd, deltag_ARG))
51486d7f5d3SJohn Marino 		r = _vgchange_tag(cmd, vg, deltag_ARG);
51586d7f5d3SJohn Marino 
51686d7f5d3SJohn Marino 	else if (arg_count(cmd, physicalextentsize_ARG))
51786d7f5d3SJohn Marino 		r = _vgchange_pesize(cmd, vg);
51886d7f5d3SJohn Marino 
51986d7f5d3SJohn Marino 	else if (arg_count(cmd, uuid_ARG))
52086d7f5d3SJohn Marino 		r = _vgchange_uuid(cmd, vg);
52186d7f5d3SJohn Marino 
52286d7f5d3SJohn Marino 	else if (arg_count(cmd, alloc_ARG))
52386d7f5d3SJohn Marino 		r = _vgchange_alloc(cmd, vg);
52486d7f5d3SJohn Marino 
52586d7f5d3SJohn Marino 	else if (arg_count(cmd, clustered_ARG))
52686d7f5d3SJohn Marino 		r = _vgchange_clustered(cmd, vg);
52786d7f5d3SJohn Marino 
52886d7f5d3SJohn Marino 	else if (arg_count(cmd, refresh_ARG))
52986d7f5d3SJohn Marino 		r = _vgchange_refresh(cmd, vg);
53086d7f5d3SJohn Marino 
53186d7f5d3SJohn Marino 	return r;
53286d7f5d3SJohn Marino }
53386d7f5d3SJohn Marino 
vgchange(struct cmd_context * cmd,int argc,char ** argv)53486d7f5d3SJohn Marino int vgchange(struct cmd_context *cmd, int argc, char **argv)
53586d7f5d3SJohn Marino {
53686d7f5d3SJohn Marino 	if (!
53786d7f5d3SJohn Marino 	    (arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
53886d7f5d3SJohn Marino 	     arg_count(cmd, maxphysicalvolumes_ARG) +
53986d7f5d3SJohn Marino 	     arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
54086d7f5d3SJohn Marino 	     arg_count(cmd, addtag_ARG) + arg_count(cmd, uuid_ARG) +
54186d7f5d3SJohn Marino 	     arg_count(cmd, physicalextentsize_ARG) +
54286d7f5d3SJohn Marino 	     arg_count(cmd, clustered_ARG) + arg_count(cmd, alloc_ARG) +
54386d7f5d3SJohn Marino 	     arg_count(cmd, monitor_ARG) + arg_count(cmd, refresh_ARG))) {
54486d7f5d3SJohn Marino 		log_error("One of -a, -c, -l, -p, -s, -x, --refresh, "
54586d7f5d3SJohn Marino 				"--uuid, --alloc, --addtag or --deltag required");
54686d7f5d3SJohn Marino 		return EINVALID_CMD_LINE;
54786d7f5d3SJohn Marino 	}
54886d7f5d3SJohn Marino 
54986d7f5d3SJohn Marino 	/* FIXME Cope with several changes at once! */
55086d7f5d3SJohn Marino 	if (arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
55186d7f5d3SJohn Marino 	    arg_count(cmd, maxphysicalvolumes_ARG) +
55286d7f5d3SJohn Marino 	    arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
55386d7f5d3SJohn Marino 	    arg_count(cmd, addtag_ARG) + arg_count(cmd, alloc_ARG) +
55486d7f5d3SJohn Marino 	    arg_count(cmd, uuid_ARG) + arg_count(cmd, clustered_ARG) +
55586d7f5d3SJohn Marino 	    arg_count(cmd, physicalextentsize_ARG) > 1) {
55686d7f5d3SJohn Marino 		log_error("Only one of -a, -c, -l, -p, -s, -x, --uuid, "
55786d7f5d3SJohn Marino 			  "--alloc, --addtag or --deltag allowed");
55886d7f5d3SJohn Marino 		return EINVALID_CMD_LINE;
55986d7f5d3SJohn Marino 	}
56086d7f5d3SJohn Marino 
56186d7f5d3SJohn Marino 	if (arg_count(cmd, ignorelockingfailure_ARG) &&
56286d7f5d3SJohn Marino 	    !arg_count(cmd, available_ARG)) {
56386d7f5d3SJohn Marino 		log_error("--ignorelockingfailure only available with -a");
56486d7f5d3SJohn Marino 		return EINVALID_CMD_LINE;
56586d7f5d3SJohn Marino 	}
56686d7f5d3SJohn Marino 
56786d7f5d3SJohn Marino 	if (arg_count(cmd, available_ARG) == 1
56886d7f5d3SJohn Marino 	    && arg_count(cmd, autobackup_ARG)) {
56986d7f5d3SJohn Marino 		log_error("-A option not necessary with -a option");
57086d7f5d3SJohn Marino 		return EINVALID_CMD_LINE;
57186d7f5d3SJohn Marino 	}
57286d7f5d3SJohn Marino 
57386d7f5d3SJohn Marino 	return process_each_vg(cmd, argc, argv,
57486d7f5d3SJohn Marino 			       (arg_count(cmd, available_ARG)) ?
57586d7f5d3SJohn Marino 			       0 : READ_FOR_UPDATE,
57686d7f5d3SJohn Marino 			       NULL,
57786d7f5d3SJohn Marino 			       &vgchange_single);
57886d7f5d3SJohn Marino }
579