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