]>
Commit | Line | Data |
---|---|---|
a381c45a | 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. |
a381c45a | 4 | * |
6606c3ae | 5 | * This file is part of LVM2. |
a381c45a | 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. |
a381c45a | 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 | |
a381c45a AK |
14 | */ |
15 | ||
16 | #include "tools.h" | |
17 | ||
d1e8046f AK |
18 | /* |
19 | * Increments *count by the number of _new_ monitored devices. | |
20 | */ | |
8a37910d | 21 | static int _monitor_lvs_in_vg(struct cmd_context *cmd, |
d1e8046f | 22 | struct volume_group *vg, int reg, int *count) |
3e3d5d85 AK |
23 | { |
24 | struct lv_list *lvl; | |
25 | struct logical_volume *lv; | |
26 | struct lvinfo info; | |
27 | int lv_active; | |
176bbea0 | 28 | int r = 1; |
3e3d5d85 | 29 | |
2c44337b | 30 | dm_list_iterate_items(lvl, &vg->lvs) { |
3e3d5d85 AK |
31 | lv = lvl->lv; |
32 | ||
2d6fcbf6 | 33 | if (!lv_info(cmd, lv, 0, &info, 0, 0)) |
3e3d5d85 AK |
34 | lv_active = 0; |
35 | else | |
36 | lv_active = info.exists; | |
37 | ||
38 | /* | |
39 | * FIXME: Need to consider all cases... PVMOVE, etc | |
40 | */ | |
41 | if ((lv->status & PVMOVE) || !lv_active) | |
42 | continue; | |
43 | ||
2d6fcbf6 | 44 | if (!monitor_dev_for_events(cmd, lv, 0, reg)) { |
176bbea0 | 45 | r = 0; |
3e3d5d85 | 46 | continue; |
8a37910d | 47 | } else |
d1e8046f | 48 | (*count)++; |
3e3d5d85 AK |
49 | } |
50 | ||
d1e8046f | 51 | return r; |
3e3d5d85 AK |
52 | } |
53 | ||
7a8fa6aa MS |
54 | static int _poll_lvs_in_vg(struct cmd_context *cmd, |
55 | struct volume_group *vg) | |
56 | { | |
57 | struct lv_list *lvl; | |
58 | struct logical_volume *lv; | |
59 | struct lvinfo info; | |
60 | int lv_active; | |
61 | int count = 0; | |
62 | ||
63 | dm_list_iterate_items(lvl, &vg->lvs) { | |
64 | lv = lvl->lv; | |
65 | ||
2d6fcbf6 | 66 | if (!lv_info(cmd, lv, 0, &info, 0, 0)) |
7a8fa6aa MS |
67 | lv_active = 0; |
68 | else | |
69 | lv_active = info.exists; | |
70 | ||
df06d9ac | 71 | if (lv_active && |
c52678ee | 72 | (lv->status & (PVMOVE|CONVERTING|MERGING))) { |
df06d9ac MS |
73 | lv_spawn_background_polling(cmd, lv); |
74 | count++; | |
75 | } | |
7a8fa6aa MS |
76 | } |
77 | ||
78 | /* | |
79 | * returns the number of polled devices | |
80 | * - there is no way to know if lv is already being polled | |
81 | */ | |
82 | ||
83 | return count; | |
84 | } | |
85 | ||
8c013da4 | 86 | static int _activate_lvs_in_vg(struct cmd_context *cmd, |
23289e6d | 87 | struct volume_group *vg, int activate) |
8c013da4 | 88 | { |
f2b7349e | 89 | struct lv_list *lvl; |
8c013da4 | 90 | struct logical_volume *lv; |
155c608c | 91 | int count = 0, expected_count = 0; |
8c013da4 | 92 | |
41449383 | 93 | sigint_allow(); |
2c44337b | 94 | dm_list_iterate_items(lvl, &vg->lvs) { |
41449383 ZK |
95 | if (sigint_caught()) |
96 | return_0; | |
97 | ||
f2b7349e | 98 | lv = lvl->lv; |
8c013da4 | 99 | |
b9ac4b0c MB |
100 | if (!lv_is_visible(lv)) |
101 | continue; | |
102 | ||
89880365 MB |
103 | /* If LV is sparse, activate origin instead */ |
104 | if (lv_is_cow(lv) && lv_is_virtual_origin(origin_from_cow(lv))) | |
105 | lv = origin_from_cow(lv); | |
106 | ||
46a29c02 | 107 | /* Only request activation of snapshot origin devices */ |
072893aa | 108 | if ((lv->status & SNAPSHOT) || lv_is_cow(lv)) |
a76ba817 AK |
109 | continue; |
110 | ||
c8c24ccd MB |
111 | /* Only request activation of mirror LV */ |
112 | if ((lv->status & MIRROR_IMAGE) || (lv->status & MIRROR_LOG)) | |
113 | continue; | |
114 | ||
8eed925e ZK |
115 | /* Only request activation of the first replicator-dev LV */ |
116 | /* Avoids retry with all heads in case of failure */ | |
117 | if (lv_is_replicator_dev(lv) && (lv != first_replicator_dev(lv))) | |
118 | continue; | |
119 | ||
c8c24ccd | 120 | /* Can't deactivate a pvmove LV */ |
b86ef8e2 AK |
121 | /* FIXME There needs to be a controlled way of doing this */ |
122 | if (((activate == CHANGE_AN) || (activate == CHANGE_ALN)) && | |
c8c24ccd | 123 | ((lv->status & PVMOVE) )) |
46a29c02 AK |
124 | continue; |
125 | ||
27ff8813 JEB |
126 | /* |
127 | * If the LV is active exclusive remotely, | |
128 | * then ignore it here | |
129 | */ | |
130 | if (lv_is_active_exclusive_remotely(lv)) { | |
131 | log_verbose("%s/%s is exclusively active on" | |
132 | " a remote node", vg->name, lv->name); | |
133 | continue; | |
134 | } | |
135 | ||
155c608c MB |
136 | expected_count++; |
137 | ||
b86ef8e2 | 138 | if (activate == CHANGE_AN) { |
56b3d204 MS |
139 | if (!deactivate_lv(cmd, lv)) { |
140 | stack; | |
23289e6d | 141 | continue; |
56b3d204 | 142 | } |
b86ef8e2 | 143 | } else if (activate == CHANGE_ALN) { |
56b3d204 MS |
144 | if (!deactivate_lv_local(cmd, lv)) { |
145 | stack; | |
b86ef8e2 | 146 | continue; |
56b3d204 | 147 | } |
ed32476c ZK |
148 | } else if ((activate == CHANGE_AE) || |
149 | lv_is_origin(lv) || | |
150 | lv_is_thin_type(lv)) { | |
151 | /* FIXME: duplicated test code with lvchange */ | |
56b3d204 MS |
152 | if (!activate_lv_excl(cmd, lv)) { |
153 | stack; | |
23289e6d | 154 | continue; |
56b3d204 | 155 | } |
b86ef8e2 | 156 | } else if (activate == CHANGE_ALY) { |
56b3d204 MS |
157 | if (!activate_lv_local(cmd, lv)) { |
158 | stack; | |
b86ef8e2 | 159 | continue; |
56b3d204 MS |
160 | } |
161 | } else if (!activate_lv(cmd, lv)) { | |
162 | stack; | |
8c013da4 | 163 | continue; |
56b3d204 | 164 | } |
8c013da4 | 165 | |
7a8fa6aa MS |
166 | if (background_polling() && |
167 | activate != CHANGE_AN && activate != CHANGE_ALN && | |
c52678ee | 168 | (lv->status & (PVMOVE|CONVERTING|MERGING))) |
93bbc31c | 169 | lv_spawn_background_polling(cmd, lv); |
46a29c02 | 170 | |
8c013da4 AK |
171 | count++; |
172 | } | |
173 | ||
41449383 ZK |
174 | sigint_restore(); |
175 | ||
155c608c MB |
176 | if (expected_count) |
177 | log_verbose("%s %d logical volumes in volume group %s", | |
6911c900 DW |
178 | (activate == CHANGE_AN || activate == CHANGE_ALN)? |
179 | "Deactivated" : "Activated", count, vg->name); | |
155c608c | 180 | |
176bbea0 | 181 | return (expected_count != count) ? 0 : 1; |
8c013da4 AK |
182 | } |
183 | ||
3e3d5d85 AK |
184 | static int _vgchange_monitoring(struct cmd_context *cmd, struct volume_group *vg) |
185 | { | |
176bbea0 | 186 | int r = 1; |
d1e8046f | 187 | int monitored = 0; |
3e3d5d85 | 188 | |
e78d473b | 189 | if (lvs_in_vg_activated(vg) && |
20db8ffc | 190 | dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) { |
176bbea0 AK |
191 | if (!_monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode(), &monitored)) |
192 | r = 0; | |
3e3d5d85 | 193 | log_print("%d logical volume(s) in volume group " |
8ef6eb30 | 194 | "\"%s\" %smonitored", |
8a37910d | 195 | monitored, vg->name, (dmeventd_monitor_mode()) ? "" : "un"); |
3e3d5d85 AK |
196 | } |
197 | ||
176bbea0 | 198 | return r; |
3e3d5d85 AK |
199 | } |
200 | ||
7a8fa6aa MS |
201 | static int _vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg) |
202 | { | |
203 | int polled; | |
204 | ||
205 | if (lvs_in_vg_activated(vg) && background_polling()) { | |
206 | polled = _poll_lvs_in_vg(cmd, vg); | |
178ff2be MS |
207 | if (polled) |
208 | log_print("Background polling started for %d logical volume(s) " | |
209 | "in volume group \"%s\"", | |
210 | polled, vg->name); | |
7a8fa6aa MS |
211 | } |
212 | ||
176bbea0 | 213 | return 1; |
7a8fa6aa MS |
214 | } |
215 | ||
4922197a | 216 | static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg) |
a381c45a | 217 | { |
f92b4f94 | 218 | int lv_open, active, monitored = 0; |
176bbea0 | 219 | int available, r = 1; |
88be836f | 220 | int activate = 1; |
36cfd887 | 221 | |
19089ba3 PR |
222 | /* |
223 | * Safe, since we never write out new metadata here. Required for | |
224 | * partial activation to work. | |
225 | */ | |
226 | cmd->handles_missing_pvs = 1; | |
227 | ||
36cfd887 | 228 | available = arg_uint_value(cmd, available_ARG, 0); |
a381c45a | 229 | |
88be836f AK |
230 | if ((available == CHANGE_AN) || (available == CHANGE_ALN)) |
231 | activate = 0; | |
232 | ||
a381c45a | 233 | /* FIXME: Force argument to deactivate them? */ |
88be836f | 234 | if (!activate && (lv_open = lvs_in_vg_opened(vg))) { |
08907484 | 235 | log_error("Can't deactivate volume group \"%s\" with %d open " |
a381c45a | 236 | "logical volume(s)", vg->name, lv_open); |
176bbea0 | 237 | return 0; |
a381c45a AK |
238 | } |
239 | ||
24e65464 | 240 | /* FIXME Move into library where clvmd can use it */ |
6ee7d2aa | 241 | if (activate) |
24e65464 AK |
242 | check_current_backup(vg); |
243 | ||
3e3d5d85 | 244 | if (activate && (active = lvs_in_vg_activated(vg))) { |
08907484 | 245 | log_verbose("%d logical volume(s) in volume group \"%s\" " |
8c013da4 | 246 | "already active", active, vg->name); |
20db8ffc | 247 | if (dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) { |
176bbea0 AK |
248 | if (!_monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode(), &monitored)) |
249 | r = 0; | |
20db8ffc AK |
250 | log_verbose("%d existing logical volume(s) in volume " |
251 | "group \"%s\" %smonitored", | |
252 | monitored, vg->name, | |
253 | dmeventd_monitor_mode() ? "" : "un"); | |
254 | } | |
3e3d5d85 | 255 | } |
3080a754 | 256 | |
176bbea0 AK |
257 | if (!_activate_lvs_in_vg(cmd, vg, available)) |
258 | r = 0; | |
a381c45a | 259 | |
df7edc00 ZK |
260 | /* Print message only if there was not found a missing VG */ |
261 | if (!vg->cmd_missing_vgs) | |
262 | log_print("%d logical volume(s) in volume group \"%s\" now active", | |
263 | lvs_in_vg_activated(vg), vg->name); | |
176bbea0 AK |
264 | return r; |
265 | } | |
266 | ||
267 | static int _vgchange_refresh(struct cmd_context *cmd, struct volume_group *vg) | |
268 | { | |
269 | log_verbose("Refreshing volume group \"%s\"", vg->name); | |
270 | ||
271 | if (!vg_refresh_visible(cmd, vg)) { | |
272 | stack; | |
273 | return 0; | |
274 | } | |
275 | ||
276 | return 1; | |
a381c45a AK |
277 | } |
278 | ||
a0a23eff AK |
279 | static int _vgchange_alloc(struct cmd_context *cmd, struct volume_group *vg) |
280 | { | |
281 | alloc_policy_t alloc; | |
282 | ||
fbf6b89a | 283 | alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_NORMAL); |
a0a23eff | 284 | |
5d623bde | 285 | /* FIXME: make consistent with vg_set_alloc_policy() */ |
a0a23eff AK |
286 | if (alloc == vg->alloc) { |
287 | log_error("Volume group allocation policy is already %s", | |
288 | get_alloc_string(vg->alloc)); | |
176bbea0 | 289 | return 0; |
651ff9b3 | 290 | } |
a0a23eff | 291 | |
176bbea0 AK |
292 | if (!vg_set_alloc_policy(vg, alloc)) |
293 | return_0; | |
a0a23eff | 294 | |
176bbea0 | 295 | return 1; |
a0a23eff AK |
296 | } |
297 | ||
cfb7bfc7 AK |
298 | static int _vgchange_resizeable(struct cmd_context *cmd, |
299 | struct volume_group *vg) | |
a381c45a | 300 | { |
6fda126d | 301 | int resizeable = !strcmp(arg_str_value(cmd, resizeable_ARG, "n"), "y"); |
a381c45a | 302 | |
68fac97a | 303 | if (resizeable && vg_is_resizeable(vg)) { |
6fda126d AK |
304 | log_error("Volume group \"%s\" is already resizeable", |
305 | vg->name); | |
176bbea0 | 306 | return 0; |
a381c45a AK |
307 | } |
308 | ||
68fac97a | 309 | if (!resizeable && !vg_is_resizeable(vg)) { |
08907484 | 310 | log_error("Volume group \"%s\" is already not resizeable", |
a381c45a | 311 | vg->name); |
176bbea0 | 312 | return 0; |
651ff9b3 | 313 | } |
614a4508 | 314 | |
b80f32dd AK |
315 | if (resizeable) |
316 | vg->status |= RESIZEABLE_VG; | |
a381c45a | 317 | else |
b80f32dd | 318 | vg->status &= ~RESIZEABLE_VG; |
a381c45a | 319 | |
176bbea0 | 320 | return 1; |
a381c45a AK |
321 | } |
322 | ||
343a8c92 AK |
323 | static int _vgchange_clustered(struct cmd_context *cmd, |
324 | struct volume_group *vg) | |
325 | { | |
326 | int clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y"); | |
327 | ||
985ca02b | 328 | if (clustered && (vg_is_clustered(vg))) { |
343a8c92 AK |
329 | log_error("Volume group \"%s\" is already clustered", |
330 | vg->name); | |
176bbea0 | 331 | return 0; |
343a8c92 AK |
332 | } |
333 | ||
985ca02b | 334 | if (!clustered && !(vg_is_clustered(vg))) { |
343a8c92 AK |
335 | log_error("Volume group \"%s\" is already not clustered", |
336 | vg->name); | |
176bbea0 | 337 | return 0; |
651ff9b3 | 338 | } |
343a8c92 | 339 | |
0e6c4e93 | 340 | if (!vg_set_clustered(vg, clustered)) |
176bbea0 | 341 | return_0; |
343a8c92 | 342 | |
176bbea0 | 343 | return 1; |
343a8c92 AK |
344 | } |
345 | ||
cfb7bfc7 AK |
346 | static int _vgchange_logicalvolume(struct cmd_context *cmd, |
347 | struct volume_group *vg) | |
a381c45a | 348 | { |
8ef2b021 | 349 | uint32_t max_lv = arg_uint_value(cmd, logicalvolume_ARG, 0); |
a381c45a | 350 | |
176bbea0 AK |
351 | if (!vg_set_max_lv(vg, max_lv)) |
352 | return_0; | |
a381c45a | 353 | |
176bbea0 | 354 | return 1; |
a381c45a | 355 | } |
5a52dca9 | 356 | |
e95d8284 AK |
357 | static int _vgchange_physicalvolumes(struct cmd_context *cmd, |
358 | struct volume_group *vg) | |
359 | { | |
360 | uint32_t max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0); | |
361 | ||
176bbea0 AK |
362 | if (!vg_set_max_pv(vg, max_pv)) |
363 | return_0; | |
e95d8284 | 364 | |
176bbea0 | 365 | return 1; |
e95d8284 AK |
366 | } |
367 | ||
66278a80 AK |
368 | static int _vgchange_pesize(struct cmd_context *cmd, struct volume_group *vg) |
369 | { | |
370 | uint32_t extent_size; | |
371 | ||
be3510b2 MB |
372 | if (arg_uint64_value(cmd, physicalextentsize_ARG, 0) > MAX_EXTENT_SIZE) { |
373 | log_error("Physical extent size cannot be larger than %s", | |
374 | display_size(cmd, (uint64_t) MAX_EXTENT_SIZE)); | |
375 | return 1; | |
376 | } | |
377 | ||
204a12e5 | 378 | extent_size = arg_uint_value(cmd, physicalextentsize_ARG, 0); |
de5dfec5 | 379 | /* FIXME: remove check - redundant with vg_change_pesize */ |
66278a80 AK |
380 | if (extent_size == vg->extent_size) { |
381 | log_error("Physical extent size of VG %s is already %s", | |
72b2cb61 | 382 | vg->name, display_size(cmd, (uint64_t) extent_size)); |
176bbea0 | 383 | return 1; |
66278a80 AK |
384 | } |
385 | ||
176bbea0 AK |
386 | if (!vg_set_extent_size(vg, extent_size)) |
387 | return_0; | |
66278a80 | 388 | |
176bbea0 | 389 | return 1; |
66278a80 AK |
390 | } |
391 | ||
176bbea0 AK |
392 | static int _vgchange_addtag(struct cmd_context *cmd, struct volume_group *vg) |
393 | { | |
b51cd542 | 394 | return change_tag(cmd, vg, NULL, NULL, addtag_ARG); |
176bbea0 | 395 | } |
cf6dd251 | 396 | |
176bbea0 AK |
397 | static int _vgchange_deltag(struct cmd_context *cmd, struct volume_group *vg) |
398 | { | |
b51cd542 | 399 | return change_tag(cmd, vg, NULL, NULL, deltag_ARG); |
cf6dd251 AK |
400 | } |
401 | ||
08f1ddea | 402 | static int _vgchange_uuid(struct cmd_context *cmd __attribute__((unused)), |
72b2cb61 | 403 | struct volume_group *vg) |
15e6db35 AK |
404 | { |
405 | struct lv_list *lvl; | |
406 | ||
407 | if (lvs_in_vg_activated(vg)) { | |
408 | log_error("Volume group has active logical volumes"); | |
176bbea0 | 409 | return 0; |
651ff9b3 | 410 | } |
15e6db35 | 411 | |
52f9afec AK |
412 | if (!id_create(&vg->id)) { |
413 | log_error("Failed to generate new random UUID for VG %s.", | |
414 | vg->name); | |
176bbea0 | 415 | return 0; |
52f9afec | 416 | } |
15e6db35 | 417 | |
2c44337b | 418 | dm_list_iterate_items(lvl, &vg->lvs) { |
15e6db35 AK |
419 | memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id)); |
420 | } | |
421 | ||
176bbea0 | 422 | return 1; |
da1ba4ed PR |
423 | } |
424 | ||
1779cc34 DW |
425 | static int _vgchange_metadata_copies(struct cmd_context *cmd, |
426 | struct volume_group *vg) | |
427 | { | |
12eadbab AK |
428 | uint32_t mda_copies = arg_uint_value(cmd, vgmetadatacopies_ARG, DEFAULT_VGMETADATACOPIES); |
429 | ||
1779cc34 | 430 | if (mda_copies == vg_mda_copies(vg)) { |
12eadbab AK |
431 | if (vg_mda_copies(vg) == VGMETADATACOPIES_UNMANAGED) |
432 | log_error("Number of metadata copies for VG %s is already unmanaged.", | |
433 | vg->name); | |
434 | else | |
435 | log_error("Number of metadata copies for VG %s is already %" PRIu32, | |
436 | vg->name, mda_copies); | |
176bbea0 | 437 | return 1; |
1779cc34 DW |
438 | } |
439 | ||
176bbea0 AK |
440 | if (!vg_set_mda_copies(vg, mda_copies)) |
441 | return_0; | |
1779cc34 | 442 | |
176bbea0 | 443 | return 1; |
1779cc34 DW |
444 | } |
445 | ||
5a52dca9 | 446 | static int vgchange_single(struct cmd_context *cmd, const char *vg_name, |
13e8c7e4 | 447 | struct volume_group *vg, |
08f1ddea | 448 | void *handle __attribute__((unused))) |
5a52dca9 | 449 | { |
176bbea0 AK |
450 | int archived = 0; |
451 | int i; | |
452 | ||
453 | static struct { | |
454 | int arg; | |
455 | int (*fn)(struct cmd_context *cmd, struct volume_group *vg); | |
456 | } _vgchange_args[] = { | |
457 | { logicalvolume_ARG, &_vgchange_logicalvolume }, | |
458 | { maxphysicalvolumes_ARG, &_vgchange_physicalvolumes }, | |
459 | { resizeable_ARG, &_vgchange_resizeable }, | |
460 | { deltag_ARG, &_vgchange_deltag }, | |
461 | { addtag_ARG, &_vgchange_addtag }, | |
462 | { physicalextentsize_ARG, &_vgchange_pesize }, | |
463 | { uuid_ARG, &_vgchange_uuid }, | |
464 | { alloc_ARG, &_vgchange_alloc }, | |
465 | { clustered_ARG, &_vgchange_clustered }, | |
466 | { vgmetadatacopies_ARG, &_vgchange_metadata_copies }, | |
467 | { -1, NULL }, | |
468 | }; | |
cfb7bfc7 | 469 | |
905240f9 | 470 | if (vg_is_exported(vg)) { |
5a52dca9 AK |
471 | log_error("Volume group \"%s\" is exported", vg_name); |
472 | return ECMD_FAILED; | |
473 | } | |
474 | ||
f407c8af MS |
475 | /* |
476 | * FIXME: DEFAULT_BACKGROUND_POLLING should be "unspecified". | |
477 | * If --poll is explicitly provided use it; otherwise polling | |
478 | * should only be started if the LV is not already active. So: | |
479 | * 1) change the activation code to say if the LV was actually activated | |
480 | * 2) make polling of an LV tightly coupled with LV activation | |
d50c6d4b PR |
481 | * |
482 | * Do not initiate any polling if --sysinit option is used. | |
f407c8af | 483 | */ |
d50c6d4b PR |
484 | init_background_polling(arg_count(cmd, sysinit_ARG) ? 0 : |
485 | arg_int_value(cmd, poll_ARG, | |
486 | DEFAULT_BACKGROUND_POLLING)); | |
7a8fa6aa | 487 | |
176bbea0 AK |
488 | for (i = 0; _vgchange_args[i].arg >= 0; i++) { |
489 | if (arg_count(cmd, _vgchange_args[i].arg)) { | |
490 | if (!archived && !archive(vg)) { | |
491 | stack; | |
492 | return ECMD_FAILED; | |
493 | } | |
494 | archived = 1; | |
495 | if (!_vgchange_args[i].fn(cmd, vg)) { | |
496 | stack; | |
497 | return ECMD_FAILED; | |
498 | } | |
499 | } | |
500 | } | |
501 | ||
502 | if (archived) { | |
503 | if (!vg_write(vg) || !vg_commit(vg)) { | |
504 | stack; | |
505 | return ECMD_FAILED; | |
506 | } | |
507 | ||
508 | backup(vg); | |
509 | ||
510 | log_print("Volume group \"%s\" successfully changed", vg->name); | |
511 | } | |
512 | ||
178ff2be | 513 | if (arg_count(cmd, available_ARG)) { |
176bbea0 AK |
514 | if (!_vgchange_available(cmd, vg)) |
515 | return ECMD_FAILED; | |
178ff2be MS |
516 | } |
517 | ||
518 | if (arg_count(cmd, refresh_ARG)) { | |
519 | /* refreshes the visible LVs (which starts polling) */ | |
176bbea0 AK |
520 | if (!_vgchange_refresh(cmd, vg)) |
521 | return ECMD_FAILED; | |
178ff2be | 522 | } |
5a52dca9 | 523 | |
178ff2be MS |
524 | if (!arg_count(cmd, available_ARG) && |
525 | !arg_count(cmd, refresh_ARG) && | |
526 | arg_count(cmd, monitor_ARG)) { | |
527 | /* -ay* will have already done monitoring changes */ | |
176bbea0 AK |
528 | if (!_vgchange_monitoring(cmd, vg)) |
529 | return ECMD_FAILED; | |
178ff2be | 530 | } |
3e3d5d85 | 531 | |
178ff2be | 532 | if (!arg_count(cmd, refresh_ARG) && |
df390f17 | 533 | background_polling()) |
176bbea0 AK |
534 | if (!_vgchange_background_polling(cmd, vg)) |
535 | return ECMD_FAILED; | |
cf6dd251 | 536 | |
176bbea0 | 537 | return ECMD_PROCESSED; |
5a52dca9 AK |
538 | } |
539 | ||
540 | int vgchange(struct cmd_context *cmd, int argc, char **argv) | |
541 | { | |
176bbea0 AK |
542 | /* Update commands that can be combined */ |
543 | int update = | |
544 | arg_count(cmd, logicalvolume_ARG) || | |
545 | arg_count(cmd, maxphysicalvolumes_ARG) || | |
546 | arg_count(cmd, resizeable_ARG) || | |
547 | arg_count(cmd, deltag_ARG) || | |
548 | arg_count(cmd, addtag_ARG) || | |
549 | arg_count(cmd, uuid_ARG) || | |
550 | arg_count(cmd, physicalextentsize_ARG) || | |
551 | arg_count(cmd, clustered_ARG) || | |
552 | arg_count(cmd, alloc_ARG) || | |
553 | arg_count(cmd, vgmetadatacopies_ARG); | |
554 | ||
555 | if (!update && | |
556 | !arg_count(cmd, available_ARG) && | |
557 | !arg_count(cmd, monitor_ARG) && | |
558 | !arg_count(cmd, poll_ARG) && | |
559 | !arg_count(cmd, refresh_ARG)) { | |
7a8fa6aa MS |
560 | log_error("Need 1 or more of -a, -c, -l, -p, -s, -x, " |
561 | "--refresh, --uuid, --alloc, --addtag, --deltag, " | |
1779cc34 DW |
562 | "--monitor, --poll, --vgmetadatacopies or " |
563 | "--metadatacopies"); | |
5a52dca9 AK |
564 | return EINVALID_CMD_LINE; |
565 | } | |
566 | ||
178ff2be MS |
567 | if (arg_count(cmd, available_ARG) && arg_count(cmd, refresh_ARG)) { |
568 | log_error("Only one of -a and --refresh permitted."); | |
569 | return EINVALID_CMD_LINE; | |
570 | } | |
571 | ||
d50c6d4b | 572 | if ((arg_count(cmd, ignorelockingfailure_ARG) || |
176bbea0 | 573 | arg_count(cmd, sysinit_ARG)) && update) { |
99cd5c70 | 574 | log_error("Only -a permitted with --ignorelockingfailure and --sysinit"); |
d50c6d4b PR |
575 | return EINVALID_CMD_LINE; |
576 | } | |
577 | ||
178ff2be MS |
578 | if (arg_count(cmd, available_ARG) && |
579 | (arg_count(cmd, monitor_ARG) || arg_count(cmd, poll_ARG))) { | |
580 | int activate = arg_uint_value(cmd, available_ARG, 0); | |
581 | if (activate == CHANGE_AN || activate == CHANGE_ALN) { | |
582 | log_error("Only -ay* allowed with --monitor or --poll."); | |
583 | return EINVALID_CMD_LINE; | |
584 | } | |
585 | } | |
586 | ||
d50c6d4b PR |
587 | if (arg_count(cmd, poll_ARG) && arg_count(cmd, sysinit_ARG)) { |
588 | log_error("Only one of --poll and --sysinit permitted."); | |
5a52dca9 AK |
589 | return EINVALID_CMD_LINE; |
590 | } | |
591 | ||
592 | if (arg_count(cmd, available_ARG) == 1 | |
593 | && arg_count(cmd, autobackup_ARG)) { | |
594 | log_error("-A option not necessary with -a option"); | |
595 | return EINVALID_CMD_LINE; | |
596 | } | |
597 | ||
176bbea0 | 598 | if (arg_count(cmd, maxphysicalvolumes_ARG) && |
fbf6b89a | 599 | arg_sign_value(cmd, maxphysicalvolumes_ARG, SIGN_NONE) == SIGN_MINUS) { |
176bbea0 AK |
600 | log_error("MaxPhysicalVolumes may not be negative"); |
601 | return EINVALID_CMD_LINE; | |
602 | } | |
603 | ||
604 | if (arg_count(cmd, physicalextentsize_ARG) && | |
fbf6b89a | 605 | arg_sign_value(cmd, physicalextentsize_ARG, SIGN_NONE) == SIGN_MINUS) { |
176bbea0 AK |
606 | log_error("Physical extent size may not be negative"); |
607 | return EINVALID_CMD_LINE; | |
608 | } | |
609 | ||
610 | return process_each_vg(cmd, argc, argv, update ? READ_FOR_UPDATE : 0, | |
611 | NULL, &vgchange_single); | |
5a52dca9 | 612 | } |