]> sourceware.org Git - lvm2.git/blame - tools/pvchange.c
thin: tighten discard string conversions
[lvm2.git] / tools / pvchange.c
CommitLineData
317919c7 1/*
67cdbd7e 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
be684599 3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
317919c7 4 *
6606c3ae 5 * This file is part of LVM2.
317919c7 6 *
6606c3ae
AK
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
be684599 9 * of the GNU Lesser General Public License v.2.1.
317919c7 10 *
be684599 11 * You should have received a copy of the GNU Lesser General Public License
6606c3ae
AK
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
317919c7
AK
14 */
15
16#include "tools.h"
17
1a832398
DW
18static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
19 struct physical_volume *pv,
08f1ddea 20 void *handle __attribute__((unused)))
317919c7 21{
bd236f65 22 uint32_t orig_pe_alloc_count;
239c4fe6
AK
23 /* FIXME Next three only required for format1. */
24 uint32_t orig_pe_count, orig_pe_size;
25 uint64_t orig_pe_start;
317919c7 26
1b8de4cb 27 const char *pv_name = pv_dev_name(pv);
bd236f65 28 const char *orig_vg_name;
08f1ddea 29 char uuid[64] __attribute__((aligned(8)));
317919c7 30
15e6db35 31 int allocatable = 0;
b51cd542 32 int tagargs = 0;
88fc1b14 33 int mda_ignore = 0;
cf6dd251 34
b51cd542 35 tagargs = arg_count(cmd, addtag_ARG) + arg_count(cmd, deltag_ARG);
15e6db35
AK
36
37 if (arg_count(cmd, allocatable_ARG))
38 allocatable = !strcmp(arg_str_value(cmd, allocatable_ARG, "n"),
39 "y");
88fc1b14
DW
40 if (arg_count(cmd, metadataignore_ARG))
41 mda_ignore = !strcmp(arg_str_value(cmd, metadataignore_ARG, "n"),
42 "y");
317919c7 43
f53c6aa6 44 /* If in a VG, must change using volume group. */
9c1dbeb3 45 if (!is_orphan(pv)) {
b51cd542 46 if (tagargs && !(vg->fid->fmt->features & FMT_TAGS)) {
cf6dd251
AK
47 log_error("Volume group containing %s does not "
48 "support tags", pv_name);
b51cd542 49 return 0;
cf6dd251 50 }
15e6db35 51 if (arg_count(cmd, uuid_ARG) && lvs_in_vg_activated(vg)) {
15e6db35
AK
52 log_error("Volume group containing %s has active "
53 "logical volumes", pv_name);
b51cd542 54 return 0;
15e6db35 55 }
614a4508 56 if (!archive(vg))
b51cd542 57 return 0;
5a52dca9 58 } else {
b51cd542 59 if (tagargs) {
cf6dd251
AK
60 log_error("Can't change tag on Physical Volume %s not "
61 "in volume group", pv_name);
62 return 0;
63 }
8f8a968d 64 }
317919c7 65
15e6db35 66 if (arg_count(cmd, allocatable_ARG)) {
9c1dbeb3 67 if (is_orphan(pv) &&
15e6db35
AK
68 !(pv->fmt->features & FMT_ORPHAN_ALLOCATABLE)) {
69 log_error("Allocatability not supported by orphan "
70 "%s format PV %s", pv->fmt->name, pv_name);
b51cd542 71 return 0;
15e6db35 72 }
317919c7 73
15e6db35 74 /* change allocatability for a PV */
ff77bb1a 75 if (allocatable && (pv_status(pv) & ALLOCATABLE_PV)) {
15e6db35
AK
76 log_error("Physical volume \"%s\" is already "
77 "allocatable", pv_name);
b51cd542 78 return 1;
15e6db35 79 }
317919c7 80
ff77bb1a 81 if (!allocatable && !(pv_status(pv) & ALLOCATABLE_PV)) {
15e6db35
AK
82 log_error("Physical volume \"%s\" is already "
83 "unallocatable", pv_name);
b51cd542 84 return 1;
15e6db35
AK
85 }
86
87 if (allocatable) {
88 log_verbose("Setting physical volume \"%s\" "
89 "allocatable", pv_name);
90 pv->status |= ALLOCATABLE_PV;
91 } else {
92 log_verbose("Setting physical volume \"%s\" NOT "
93 "allocatable", pv_name);
94 pv->status &= ~ALLOCATABLE_PV;
95 }
b51cd542 96 }
f8452d8c 97
b51cd542
AK
98 if (tagargs) {
99 /* tag or deltag */
100 if (arg_count(cmd, addtag_ARG) && !change_tag(cmd, NULL, NULL, pv, addtag_ARG))
101 return_0;
f8452d8c 102
b51cd542
AK
103 if (arg_count(cmd, deltag_ARG) && !change_tag(cmd, NULL, NULL, pv, deltag_ARG))
104 return_0;
105
106 }
f8452d8c 107
b51cd542 108 if (arg_count(cmd, metadataignore_ARG)) {
90b96af6 109 if ((vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) &&
96c3c464 110 (arg_count(cmd, force_ARG) == PROMPT) &&
69e80c9e
DW
111 yes_no_prompt("Override preferred number of copies "
112 "of VG %s metadata? [y/n]: ",
113 pv_vg_name(pv)) == 'n') {
90b96af6 114 log_error("Physical volume %s not changed", pv_name);
b51cd542 115 return 0;
90b96af6 116 }
a375ced3 117 if (!pv_change_metadataignore(pv, mda_ignore))
b51cd542
AK
118 return_0;
119 }
120
121 if (arg_count(cmd, uuid_ARG)) {
15e6db35 122 /* --uuid: Change PV ID randomly */
51aed199 123 memcpy(&pv->old_id, &pv->id, sizeof(pv->id));
52f9afec
AK
124 if (!id_create(&pv->id)) {
125 log_error("Failed to generate new random UUID for %s.",
126 pv_name);
b51cd542 127 return 0;
bd236f65 128 }
043b1362 129 if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
b51cd542 130 return 0;
bd236f65 131 log_verbose("Changing uuid of %s to %s.", pv_name, uuid);
9c1dbeb3 132 if (!is_orphan(pv)) {
ff77bb1a
DW
133 orig_vg_name = pv_vg_name(pv);
134 orig_pe_alloc_count = pv_pe_alloc_count(pv);
239c4fe6
AK
135
136 /* FIXME format1 pv_write doesn't preserve these. */
137 orig_pe_size = pv_pe_size(pv);
138 orig_pe_start = pv_pe_start(pv);
139 orig_pe_count = pv_pe_count(pv);
140
bb097a97 141 pv->vg_name = pv->fmt->orphan_vg_name;
bd236f65 142 pv->pe_alloc_count = 0;
3b97e8d6 143 if (!(pv_write(cmd, pv, 0))) {
bd236f65
AK
144 log_error("pv_write with new uuid failed "
145 "for %s.", pv_name);
b51cd542 146 return 0;
bd236f65
AK
147 }
148 pv->vg_name = orig_vg_name;
149 pv->pe_alloc_count = orig_pe_alloc_count;
239c4fe6
AK
150
151 pv->pe_size = orig_pe_size;
152 pv->pe_start = orig_pe_start;
153 pv->pe_count = orig_pe_count;
bd236f65 154 }
317919c7
AK
155 }
156
08907484 157 log_verbose("Updating physical volume \"%s\"", pv_name);
9c1dbeb3 158 if (!is_orphan(pv)) {
914c9723 159 if (!vg_write(vg) || !vg_commit(vg)) {
08907484
HM
160 log_error("Failed to store physical volume \"%s\" in "
161 "volume group \"%s\"", pv_name, vg->name);
b51cd542 162 return 0;
317919c7 163 }
197c3f2a 164 backup(vg);
3b97e8d6 165 } else if (!(pv_write(cmd, pv, 0))) {
d38bf361
AK
166 log_error("Failed to store physical volume \"%s\"",
167 pv_name);
b51cd542 168 return 0;
317919c7 169 }
8f8a968d 170
08907484 171 log_print("Physical volume \"%s\" changed", pv_name);
8f8a968d 172
b51cd542 173 return 1;
317919c7 174}
5a52dca9
AK
175
176int pvchange(struct cmd_context *cmd, int argc, char **argv)
177{
178 int opt = 0;
179 int done = 0;
180 int total = 0;
181
1a832398 182 struct volume_group *vg;
bad35c65
PR
183 const char *vg_name;
184 char *pv_name;
5a52dca9 185
f2b7349e 186 struct pv_list *pvl;
1a832398
DW
187 struct dm_list *vgnames;
188 struct str_list *sll;
5a52dca9 189
b51cd542 190 if (!(arg_count(cmd, allocatable_ARG) + arg_is_set(cmd, addtag_ARG) +
f8452d8c 191 arg_is_set(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) +
b51cd542
AK
192 arg_count(cmd, metadataignore_ARG))) {
193 log_error("Please give one or more of -x, -uuid, "
194 "--addtag, --deltag or --metadataignore");
5a52dca9
AK
195 return EINVALID_CMD_LINE;
196 }
197
198 if (!(arg_count(cmd, all_ARG)) && !argc) {
199 log_error("Please give a physical volume path");
200 return EINVALID_CMD_LINE;
201 }
202
203 if (arg_count(cmd, all_ARG) && argc) {
204 log_error("Option a and PhysicalVolumePath are exclusive");
205 return EINVALID_CMD_LINE;
206 }
207
208 if (argc) {
209 log_verbose("Using physical volume(s) on command line");
210 for (; opt < argc; opt++) {
211 pv_name = argv[opt];
e59e2f7c 212 dm_unescape_colons_and_at_signs(pv_name, NULL, NULL);
1a832398
DW
213 vg_name = find_vgname_from_pvname(cmd, pv_name);
214 if (!vg_name) {
c29d2465
AK
215 log_error("Failed to read physical volume %s",
216 pv_name);
5a52dca9
AK
217 continue;
218 }
1a832398
DW
219 vg = vg_read_for_update(cmd, vg_name, NULL, 0);
220 if (vg_read_error(vg)) {
077a6755 221 release_vg(vg);
1a832398
DW
222 stack;
223 continue;
224 }
225 pvl = find_pv_in_vg(vg, pv_name);
226 if (!pvl || !pvl->pv) {
227 log_error("Unable to find %s in %s",
228 pv_name, vg_name);
229 continue;
1b8b6246
AK
230 }
231
5a52dca9 232 total++;
1a832398
DW
233 done += _pvchange_single(cmd, vg,
234 pvl->pv, NULL);
077a6755 235 unlock_and_release_vg(cmd, vg, vg_name);
5a52dca9
AK
236 }
237 } else {
238 log_verbose("Scanning for physical volume names");
1a832398
DW
239 /* FIXME: share code with toollib */
240 /*
241 * Take the global lock here so the lvmcache remains
242 * consistent across orphan/non-orphan vg locks. If we don't
243 * take the lock here, pvs with 0 mdas in a non-orphan VG will
244 * be processed twice.
245 */
246 if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_WRITE)) {
247 log_error("Unable to obtain global lock.");
5a52dca9
AK
248 return ECMD_FAILED;
249 }
250
1a832398
DW
251 if ((vgnames = get_vgnames(cmd, 1)) &&
252 !dm_list_empty(vgnames)) {
253 dm_list_iterate_items(sll, vgnames) {
254 vg = vg_read_for_update(cmd, sll->str, NULL, 0);
255 if (vg_read_error(vg)) {
077a6755 256 release_vg(vg);
1a832398
DW
257 stack;
258 continue;
259 }
260 dm_list_iterate_items(pvl, &vg->pvs) {
261 total++;
262 done += _pvchange_single(cmd, vg,
263 pvl->pv,
264 NULL);
265 }
077a6755 266 unlock_and_release_vg(cmd, vg, sll->str);
1a832398 267 }
5a52dca9 268 }
fadd9341 269 unlock_vg(cmd, VG_GLOBAL);
5a52dca9
AK
270 }
271
272 log_print("%d physical volume%s changed / %d physical volume%s "
273 "not changed",
15e6db35
AK
274 done, done == 1 ? "" : "s",
275 total - done, (total - done) == 1 ? "" : "s");
5a52dca9 276
cfb7bfc7 277 return (total == done) ? ECMD_PROCESSED : ECMD_FAILED;
5a52dca9 278}
This page took 0.129523 seconds and 5 git commands to generate.