1 1.1 haad /* $NetBSD: vgchange.c,v 1.1.1.3 2009/12/02 00:25:51 haad Exp $ */ 2 1.1 haad 3 1.1 haad /* 4 1.1 haad * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 1.1 haad * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 1.1 haad * 7 1.1 haad * This file is part of LVM2. 8 1.1 haad * 9 1.1 haad * This copyrighted material is made available to anyone wishing to use, 10 1.1 haad * modify, copy, or redistribute it subject to the terms and conditions 11 1.1 haad * of the GNU Lesser General Public License v.2.1. 12 1.1 haad * 13 1.1 haad * You should have received a copy of the GNU Lesser General Public License 14 1.1 haad * along with this program; if not, write to the Free Software Foundation, 15 1.1 haad * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 1.1 haad */ 17 1.1 haad 18 1.1 haad #include "tools.h" 19 1.1 haad 20 1.1 haad static int _monitor_lvs_in_vg(struct cmd_context *cmd, 21 1.1 haad struct volume_group *vg, int reg) 22 1.1 haad { 23 1.1 haad struct lv_list *lvl; 24 1.1 haad struct logical_volume *lv; 25 1.1 haad struct lvinfo info; 26 1.1 haad int lv_active; 27 1.1 haad int count = 0; 28 1.1 haad 29 1.1 haad dm_list_iterate_items(lvl, &vg->lvs) { 30 1.1 haad lv = lvl->lv; 31 1.1 haad 32 1.1 haad if (!lv_info(cmd, lv, &info, 0, 0)) 33 1.1 haad lv_active = 0; 34 1.1 haad else 35 1.1 haad lv_active = info.exists; 36 1.1 haad 37 1.1 haad /* 38 1.1 haad * FIXME: Need to consider all cases... PVMOVE, etc 39 1.1 haad */ 40 1.1 haad if ((lv->status & PVMOVE) || !lv_active) 41 1.1 haad continue; 42 1.1 haad 43 1.1 haad if (!monitor_dev_for_events(cmd, lv, reg)) { 44 1.1 haad continue; 45 1.1 haad } else 46 1.1 haad count++; 47 1.1 haad } 48 1.1 haad 49 1.1 haad /* 50 1.1 haad * returns the number of _new_ monitored devices 51 1.1 haad */ 52 1.1 haad 53 1.1 haad return count; 54 1.1 haad } 55 1.1 haad 56 1.1 haad static int _activate_lvs_in_vg(struct cmd_context *cmd, 57 1.1 haad struct volume_group *vg, int activate) 58 1.1 haad { 59 1.1 haad struct lv_list *lvl; 60 1.1 haad struct logical_volume *lv; 61 1.1.1.3 haad int count = 0, expected_count = 0; 62 1.1 haad 63 1.1 haad dm_list_iterate_items(lvl, &vg->lvs) { 64 1.1 haad lv = lvl->lv; 65 1.1 haad 66 1.1.1.3 haad if (!lv_is_visible(lv)) 67 1.1.1.3 haad continue; 68 1.1.1.3 haad 69 1.1 haad /* Only request activation of snapshot origin devices */ 70 1.1 haad if ((lv->status & SNAPSHOT) || lv_is_cow(lv)) 71 1.1 haad continue; 72 1.1 haad 73 1.1 haad /* Only request activation of mirror LV */ 74 1.1 haad if ((lv->status & MIRROR_IMAGE) || (lv->status & MIRROR_LOG)) 75 1.1 haad continue; 76 1.1 haad 77 1.1 haad /* Can't deactivate a pvmove LV */ 78 1.1 haad /* FIXME There needs to be a controlled way of doing this */ 79 1.1 haad if (((activate == CHANGE_AN) || (activate == CHANGE_ALN)) && 80 1.1 haad ((lv->status & PVMOVE) )) 81 1.1 haad continue; 82 1.1 haad 83 1.1.1.3 haad expected_count++; 84 1.1.1.3 haad 85 1.1 haad if (activate == CHANGE_AN) { 86 1.1 haad if (!deactivate_lv(cmd, lv)) 87 1.1 haad continue; 88 1.1 haad } else if (activate == CHANGE_ALN) { 89 1.1 haad if (!deactivate_lv_local(cmd, lv)) 90 1.1 haad continue; 91 1.1 haad } else if (lv_is_origin(lv) || (activate == CHANGE_AE)) { 92 1.1 haad if (!activate_lv_excl(cmd, lv)) 93 1.1 haad continue; 94 1.1 haad } else if (activate == CHANGE_ALY) { 95 1.1 haad if (!activate_lv_local(cmd, lv)) 96 1.1 haad continue; 97 1.1 haad } else if (!activate_lv(cmd, lv)) 98 1.1 haad continue; 99 1.1 haad 100 1.1.1.3 haad if (activate != CHANGE_AN && activate != CHANGE_ALN && 101 1.1.1.3 haad (lv->status & (PVMOVE|CONVERTING))) 102 1.1.1.3 haad lv_spawn_background_polling(cmd, lv); 103 1.1 haad 104 1.1 haad count++; 105 1.1 haad } 106 1.1 haad 107 1.1.1.3 haad if (expected_count) 108 1.1.1.3 haad log_verbose("%s %d logical volumes in volume group %s", 109 1.1.1.3 haad activate ? "Activated" : "Deactivated", 110 1.1.1.3 haad count, vg->name); 111 1.1.1.3 haad 112 1.1.1.3 haad return (expected_count != count) ? ECMD_FAILED : ECMD_PROCESSED; 113 1.1 haad } 114 1.1 haad 115 1.1 haad static int _vgchange_monitoring(struct cmd_context *cmd, struct volume_group *vg) 116 1.1 haad { 117 1.1 haad int active, monitored; 118 1.1 haad 119 1.1 haad if ((active = lvs_in_vg_activated(vg)) && 120 1.1 haad dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) { 121 1.1 haad monitored = _monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode()); 122 1.1 haad log_print("%d logical volume(s) in volume group " 123 1.1 haad "\"%s\" %smonitored", 124 1.1 haad monitored, vg->name, (dmeventd_monitor_mode()) ? "" : "un"); 125 1.1 haad } 126 1.1 haad 127 1.1 haad return ECMD_PROCESSED; 128 1.1 haad } 129 1.1 haad 130 1.1 haad static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg) 131 1.1 haad { 132 1.1 haad int lv_open, active, monitored; 133 1.1.1.3 haad int available, ret; 134 1.1 haad int activate = 1; 135 1.1 haad 136 1.1.1.3 haad /* 137 1.1.1.3 haad * Safe, since we never write out new metadata here. Required for 138 1.1.1.3 haad * partial activation to work. 139 1.1.1.3 haad */ 140 1.1.1.3 haad cmd->handles_missing_pvs = 1; 141 1.1.1.3 haad 142 1.1 haad available = arg_uint_value(cmd, available_ARG, 0); 143 1.1 haad 144 1.1 haad if ((available == CHANGE_AN) || (available == CHANGE_ALN)) 145 1.1 haad activate = 0; 146 1.1 haad 147 1.1 haad /* FIXME: Force argument to deactivate them? */ 148 1.1 haad if (!activate && (lv_open = lvs_in_vg_opened(vg))) { 149 1.1 haad log_error("Can't deactivate volume group \"%s\" with %d open " 150 1.1 haad "logical volume(s)", vg->name, lv_open); 151 1.1 haad return ECMD_FAILED; 152 1.1 haad } 153 1.1 haad 154 1.1 haad /* FIXME Move into library where clvmd can use it */ 155 1.1.1.3 haad if (activate) 156 1.1 haad check_current_backup(vg); 157 1.1 haad 158 1.1 haad if (activate && (active = lvs_in_vg_activated(vg))) { 159 1.1 haad log_verbose("%d logical volume(s) in volume group \"%s\" " 160 1.1 haad "already active", active, vg->name); 161 1.1 haad if (dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) { 162 1.1 haad monitored = _monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode()); 163 1.1 haad log_verbose("%d existing logical volume(s) in volume " 164 1.1 haad "group \"%s\" %smonitored", 165 1.1 haad monitored, vg->name, 166 1.1 haad dmeventd_monitor_mode() ? "" : "un"); 167 1.1 haad } 168 1.1 haad } 169 1.1 haad 170 1.1.1.3 haad ret = _activate_lvs_in_vg(cmd, vg, available); 171 1.1 haad 172 1.1 haad log_print("%d logical volume(s) in volume group \"%s\" now active", 173 1.1 haad lvs_in_vg_activated(vg), vg->name); 174 1.1.1.3 haad return ret; 175 1.1 haad } 176 1.1 haad 177 1.1 haad static int _vgchange_alloc(struct cmd_context *cmd, struct volume_group *vg) 178 1.1 haad { 179 1.1 haad alloc_policy_t alloc; 180 1.1 haad 181 1.1 haad alloc = arg_uint_value(cmd, alloc_ARG, ALLOC_NORMAL); 182 1.1 haad 183 1.1.1.3 haad if (!archive(vg)) { 184 1.1.1.3 haad stack; 185 1.1.1.3 haad return ECMD_FAILED; 186 1.1 haad } 187 1.1 haad 188 1.1.1.3 haad /* FIXME: make consistent with vg_set_alloc_policy() */ 189 1.1 haad if (alloc == vg->alloc) { 190 1.1 haad log_error("Volume group allocation policy is already %s", 191 1.1 haad get_alloc_string(vg->alloc)); 192 1.1 haad return ECMD_FAILED; 193 1.1 haad } 194 1.1.1.3 haad if (!vg_set_alloc_policy(vg, alloc)) { 195 1.1.1.3 haad stack; 196 1.1 haad return ECMD_FAILED; 197 1.1.1.3 haad } 198 1.1 haad 199 1.1.1.3 haad if (!vg_write(vg) || !vg_commit(vg)) { 200 1.1.1.3 haad stack; 201 1.1 haad return ECMD_FAILED; 202 1.1.1.3 haad } 203 1.1 haad 204 1.1 haad backup(vg); 205 1.1 haad 206 1.1 haad log_print("Volume group \"%s\" successfully changed", vg->name); 207 1.1 haad 208 1.1 haad return ECMD_PROCESSED; 209 1.1 haad } 210 1.1 haad 211 1.1 haad static int _vgchange_resizeable(struct cmd_context *cmd, 212 1.1 haad struct volume_group *vg) 213 1.1 haad { 214 1.1 haad int resizeable = !strcmp(arg_str_value(cmd, resizeable_ARG, "n"), "y"); 215 1.1 haad 216 1.1.1.3 haad if (resizeable && vg_is_resizeable(vg)) { 217 1.1 haad log_error("Volume group \"%s\" is already resizeable", 218 1.1 haad vg->name); 219 1.1 haad return ECMD_FAILED; 220 1.1 haad } 221 1.1 haad 222 1.1.1.3 haad if (!resizeable && !vg_is_resizeable(vg)) { 223 1.1 haad log_error("Volume group \"%s\" is already not resizeable", 224 1.1 haad vg->name); 225 1.1 haad return ECMD_FAILED; 226 1.1 haad } 227 1.1 haad 228 1.1.1.3 haad if (!archive(vg)) { 229 1.1.1.3 haad stack; 230 1.1 haad return ECMD_FAILED; 231 1.1.1.3 haad } 232 1.1 haad 233 1.1 haad if (resizeable) 234 1.1 haad vg->status |= RESIZEABLE_VG; 235 1.1 haad else 236 1.1 haad vg->status &= ~RESIZEABLE_VG; 237 1.1 haad 238 1.1.1.3 haad if (!vg_write(vg) || !vg_commit(vg)) { 239 1.1.1.3 haad stack; 240 1.1 haad return ECMD_FAILED; 241 1.1.1.3 haad } 242 1.1 haad 243 1.1 haad backup(vg); 244 1.1 haad 245 1.1 haad log_print("Volume group \"%s\" successfully changed", vg->name); 246 1.1 haad 247 1.1 haad return ECMD_PROCESSED; 248 1.1 haad } 249 1.1 haad 250 1.1 haad static int _vgchange_clustered(struct cmd_context *cmd, 251 1.1 haad struct volume_group *vg) 252 1.1 haad { 253 1.1 haad int clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y"); 254 1.1 haad 255 1.1 haad if (clustered && (vg_is_clustered(vg))) { 256 1.1 haad log_error("Volume group \"%s\" is already clustered", 257 1.1 haad vg->name); 258 1.1 haad return ECMD_FAILED; 259 1.1 haad } 260 1.1 haad 261 1.1 haad if (!clustered && !(vg_is_clustered(vg))) { 262 1.1 haad log_error("Volume group \"%s\" is already not clustered", 263 1.1 haad vg->name); 264 1.1 haad return ECMD_FAILED; 265 1.1 haad } 266 1.1 haad 267 1.1.1.3 haad if (!archive(vg)) { 268 1.1.1.3 haad stack; 269 1.1.1.3 haad return ECMD_FAILED; 270 1.1 haad } 271 1.1 haad 272 1.1.1.3 haad if (!vg_set_clustered(vg, clustered)) 273 1.1 haad return ECMD_FAILED; 274 1.1 haad 275 1.1.1.3 haad if (!vg_write(vg) || !vg_commit(vg)) { 276 1.1.1.3 haad stack; 277 1.1 haad return ECMD_FAILED; 278 1.1.1.3 haad } 279 1.1 haad 280 1.1 haad backup(vg); 281 1.1 haad 282 1.1 haad log_print("Volume group \"%s\" successfully changed", vg->name); 283 1.1 haad 284 1.1 haad return ECMD_PROCESSED; 285 1.1 haad } 286 1.1 haad 287 1.1 haad static int _vgchange_logicalvolume(struct cmd_context *cmd, 288 1.1 haad struct volume_group *vg) 289 1.1 haad { 290 1.1 haad uint32_t max_lv = arg_uint_value(cmd, logicalvolume_ARG, 0); 291 1.1 haad 292 1.1.1.3 haad if (!archive(vg)) { 293 1.1.1.3 haad stack; 294 1.1 haad return ECMD_FAILED; 295 1.1 haad } 296 1.1 haad 297 1.1.1.3 haad if (!vg_set_max_lv(vg, max_lv)) { 298 1.1.1.3 haad stack; 299 1.1 haad return ECMD_FAILED; 300 1.1 haad } 301 1.1 haad 302 1.1.1.3 haad if (!vg_write(vg) || !vg_commit(vg)) { 303 1.1.1.3 haad stack; 304 1.1 haad return ECMD_FAILED; 305 1.1.1.3 haad } 306 1.1 haad 307 1.1 haad backup(vg); 308 1.1 haad 309 1.1 haad log_print("Volume group \"%s\" successfully changed", vg->name); 310 1.1 haad 311 1.1 haad return ECMD_PROCESSED; 312 1.1 haad } 313 1.1 haad 314 1.1 haad static int _vgchange_physicalvolumes(struct cmd_context *cmd, 315 1.1 haad struct volume_group *vg) 316 1.1 haad { 317 1.1 haad uint32_t max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0); 318 1.1 haad 319 1.1 haad if (arg_sign_value(cmd, maxphysicalvolumes_ARG, 0) == SIGN_MINUS) { 320 1.1 haad log_error("MaxPhysicalVolumes may not be negative"); 321 1.1 haad return EINVALID_CMD_LINE; 322 1.1 haad } 323 1.1 haad 324 1.1.1.3 haad if (!archive(vg)) { 325 1.1.1.3 haad stack; 326 1.1 haad return ECMD_FAILED; 327 1.1 haad } 328 1.1 haad 329 1.1.1.3 haad if (!vg_set_max_pv(vg, max_pv)) { 330 1.1.1.3 haad stack; 331 1.1 haad return ECMD_FAILED; 332 1.1.1.3 haad } 333 1.1 haad 334 1.1.1.3 haad if (!vg_write(vg) || !vg_commit(vg)) { 335 1.1.1.3 haad stack; 336 1.1 haad return ECMD_FAILED; 337 1.1.1.3 haad } 338 1.1 haad 339 1.1 haad backup(vg); 340 1.1 haad 341 1.1 haad log_print("Volume group \"%s\" successfully changed", vg->name); 342 1.1 haad 343 1.1 haad return ECMD_PROCESSED; 344 1.1 haad } 345 1.1 haad 346 1.1 haad static int _vgchange_pesize(struct cmd_context *cmd, struct volume_group *vg) 347 1.1 haad { 348 1.1 haad uint32_t extent_size; 349 1.1 haad 350 1.1 haad if (arg_sign_value(cmd, physicalextentsize_ARG, 0) == SIGN_MINUS) { 351 1.1 haad log_error("Physical extent size may not be negative"); 352 1.1 haad return EINVALID_CMD_LINE; 353 1.1 haad } 354 1.1 haad 355 1.1 haad extent_size = arg_uint_value(cmd, physicalextentsize_ARG, 0); 356 1.1.1.3 haad /* FIXME: remove check - redundant with vg_change_pesize */ 357 1.1 haad if (extent_size == vg->extent_size) { 358 1.1 haad log_error("Physical extent size of VG %s is already %s", 359 1.1 haad vg->name, display_size(cmd, (uint64_t) extent_size)); 360 1.1 haad return ECMD_PROCESSED; 361 1.1 haad } 362 1.1 haad 363 1.1.1.3 haad if (!archive(vg)) { 364 1.1.1.3 haad stack; 365 1.1.1.3 haad return ECMD_FAILED; 366 1.1 haad } 367 1.1 haad 368 1.1.1.3 haad if (!vg_set_extent_size(vg, extent_size)) { 369 1.1.1.3 haad stack; 370 1.1.1.3 haad return EINVALID_CMD_LINE; 371 1.1 haad } 372 1.1 haad 373 1.1.1.3 haad if (!vg_write(vg) || !vg_commit(vg)) { 374 1.1 haad stack; 375 1.1 haad return ECMD_FAILED; 376 1.1 haad } 377 1.1 haad 378 1.1 haad backup(vg); 379 1.1 haad 380 1.1 haad log_print("Volume group \"%s\" successfully changed", vg->name); 381 1.1 haad 382 1.1 haad return ECMD_PROCESSED; 383 1.1 haad } 384 1.1 haad 385 1.1 haad static int _vgchange_tag(struct cmd_context *cmd, struct volume_group *vg, 386 1.1 haad int arg) 387 1.1 haad { 388 1.1 haad const char *tag; 389 1.1 haad 390 1.1 haad if (!(tag = arg_str_value(cmd, arg, NULL))) { 391 1.1 haad log_error("Failed to get tag"); 392 1.1 haad return ECMD_FAILED; 393 1.1 haad } 394 1.1 haad 395 1.1 haad if (!(vg->fid->fmt->features & FMT_TAGS)) { 396 1.1 haad log_error("Volume group %s does not support tags", vg->name); 397 1.1 haad return ECMD_FAILED; 398 1.1 haad } 399 1.1 haad 400 1.1.1.3 haad if (!archive(vg)) { 401 1.1.1.3 haad stack; 402 1.1 haad return ECMD_FAILED; 403 1.1.1.3 haad } 404 1.1 haad 405 1.1 haad if ((arg == addtag_ARG)) { 406 1.1 haad if (!str_list_add(cmd->mem, &vg->tags, tag)) { 407 1.1 haad log_error("Failed to add tag %s to volume group %s", 408 1.1 haad tag, vg->name); 409 1.1 haad return ECMD_FAILED; 410 1.1 haad } 411 1.1 haad } else { 412 1.1 haad if (!str_list_del(&vg->tags, tag)) { 413 1.1 haad log_error("Failed to remove tag %s from volume group " 414 1.1 haad "%s", tag, vg->name); 415 1.1 haad return ECMD_FAILED; 416 1.1 haad } 417 1.1 haad } 418 1.1 haad 419 1.1.1.3 haad if (!vg_write(vg) || !vg_commit(vg)) { 420 1.1.1.3 haad stack; 421 1.1 haad return ECMD_FAILED; 422 1.1.1.3 haad } 423 1.1 haad 424 1.1 haad backup(vg); 425 1.1 haad 426 1.1 haad log_print("Volume group \"%s\" successfully changed", vg->name); 427 1.1 haad 428 1.1 haad return ECMD_PROCESSED; 429 1.1 haad } 430 1.1 haad 431 1.1 haad static int _vgchange_uuid(struct cmd_context *cmd __attribute((unused)), 432 1.1 haad struct volume_group *vg) 433 1.1 haad { 434 1.1 haad struct lv_list *lvl; 435 1.1 haad 436 1.1 haad if (lvs_in_vg_activated(vg)) { 437 1.1 haad log_error("Volume group has active logical volumes"); 438 1.1 haad return ECMD_FAILED; 439 1.1 haad } 440 1.1 haad 441 1.1.1.3 haad if (!archive(vg)) { 442 1.1.1.3 haad stack; 443 1.1 haad return ECMD_FAILED; 444 1.1.1.3 haad } 445 1.1 haad 446 1.1 haad if (!id_create(&vg->id)) { 447 1.1 haad log_error("Failed to generate new random UUID for VG %s.", 448 1.1 haad vg->name); 449 1.1 haad return ECMD_FAILED; 450 1.1 haad } 451 1.1 haad 452 1.1 haad dm_list_iterate_items(lvl, &vg->lvs) { 453 1.1 haad memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id)); 454 1.1 haad } 455 1.1 haad 456 1.1.1.3 haad if (!vg_write(vg) || !vg_commit(vg)) { 457 1.1.1.3 haad stack; 458 1.1 haad return ECMD_FAILED; 459 1.1.1.3 haad } 460 1.1 haad 461 1.1 haad backup(vg); 462 1.1 haad 463 1.1 haad log_print("Volume group \"%s\" successfully changed", vg->name); 464 1.1 haad 465 1.1 haad return ECMD_PROCESSED; 466 1.1 haad } 467 1.1 haad 468 1.1.1.2 haad static int _vgchange_refresh(struct cmd_context *cmd, struct volume_group *vg) 469 1.1.1.2 haad { 470 1.1.1.2 haad log_verbose("Refreshing volume group \"%s\"", vg->name); 471 1.1.1.2 haad 472 1.1.1.3 haad if (!vg_refresh_visible(cmd, vg)) { 473 1.1.1.3 haad stack; 474 1.1.1.2 haad return ECMD_FAILED; 475 1.1.1.3 haad } 476 1.1.1.3 haad 477 1.1.1.2 haad return ECMD_PROCESSED; 478 1.1.1.2 haad } 479 1.1.1.2 haad 480 1.1 haad static int vgchange_single(struct cmd_context *cmd, const char *vg_name, 481 1.1.1.3 haad struct volume_group *vg, 482 1.1 haad void *handle __attribute((unused))) 483 1.1 haad { 484 1.1 haad int r = ECMD_FAILED; 485 1.1 haad 486 1.1.1.3 haad if (vg_is_exported(vg)) { 487 1.1 haad log_error("Volume group \"%s\" is exported", vg_name); 488 1.1 haad return ECMD_FAILED; 489 1.1 haad } 490 1.1 haad 491 1.1 haad init_dmeventd_monitor(arg_int_value(cmd, monitor_ARG, 492 1.1.1.2 haad (is_static() || arg_count(cmd, ignoremonitoring_ARG)) ? 493 1.1 haad DMEVENTD_MONITOR_IGNORE : DEFAULT_DMEVENTD_MONITOR)); 494 1.1 haad 495 1.1 haad if (arg_count(cmd, available_ARG)) 496 1.1 haad r = _vgchange_available(cmd, vg); 497 1.1 haad 498 1.1 haad else if (arg_count(cmd, monitor_ARG)) 499 1.1 haad r = _vgchange_monitoring(cmd, vg); 500 1.1 haad 501 1.1 haad else if (arg_count(cmd, resizeable_ARG)) 502 1.1 haad r = _vgchange_resizeable(cmd, vg); 503 1.1 haad 504 1.1 haad else if (arg_count(cmd, logicalvolume_ARG)) 505 1.1 haad r = _vgchange_logicalvolume(cmd, vg); 506 1.1 haad 507 1.1 haad else if (arg_count(cmd, maxphysicalvolumes_ARG)) 508 1.1 haad r = _vgchange_physicalvolumes(cmd, vg); 509 1.1 haad 510 1.1 haad else if (arg_count(cmd, addtag_ARG)) 511 1.1 haad r = _vgchange_tag(cmd, vg, addtag_ARG); 512 1.1 haad 513 1.1 haad else if (arg_count(cmd, deltag_ARG)) 514 1.1 haad r = _vgchange_tag(cmd, vg, deltag_ARG); 515 1.1 haad 516 1.1 haad else if (arg_count(cmd, physicalextentsize_ARG)) 517 1.1 haad r = _vgchange_pesize(cmd, vg); 518 1.1 haad 519 1.1 haad else if (arg_count(cmd, uuid_ARG)) 520 1.1 haad r = _vgchange_uuid(cmd, vg); 521 1.1 haad 522 1.1 haad else if (arg_count(cmd, alloc_ARG)) 523 1.1 haad r = _vgchange_alloc(cmd, vg); 524 1.1 haad 525 1.1 haad else if (arg_count(cmd, clustered_ARG)) 526 1.1 haad r = _vgchange_clustered(cmd, vg); 527 1.1 haad 528 1.1.1.2 haad else if (arg_count(cmd, refresh_ARG)) 529 1.1.1.2 haad r = _vgchange_refresh(cmd, vg); 530 1.1.1.2 haad 531 1.1 haad return r; 532 1.1 haad } 533 1.1 haad 534 1.1 haad int vgchange(struct cmd_context *cmd, int argc, char **argv) 535 1.1 haad { 536 1.1 haad if (! 537 1.1 haad (arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) + 538 1.1 haad arg_count(cmd, maxphysicalvolumes_ARG) + 539 1.1 haad arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) + 540 1.1 haad arg_count(cmd, addtag_ARG) + arg_count(cmd, uuid_ARG) + 541 1.1 haad arg_count(cmd, physicalextentsize_ARG) + 542 1.1 haad arg_count(cmd, clustered_ARG) + arg_count(cmd, alloc_ARG) + 543 1.1.1.2 haad arg_count(cmd, monitor_ARG) + arg_count(cmd, refresh_ARG))) { 544 1.1.1.2 haad log_error("One of -a, -c, -l, -p, -s, -x, --refresh, " 545 1.1.1.2 haad "--uuid, --alloc, --addtag or --deltag required"); 546 1.1 haad return EINVALID_CMD_LINE; 547 1.1 haad } 548 1.1 haad 549 1.1 haad /* FIXME Cope with several changes at once! */ 550 1.1 haad if (arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) + 551 1.1 haad arg_count(cmd, maxphysicalvolumes_ARG) + 552 1.1 haad arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) + 553 1.1 haad arg_count(cmd, addtag_ARG) + arg_count(cmd, alloc_ARG) + 554 1.1 haad arg_count(cmd, uuid_ARG) + arg_count(cmd, clustered_ARG) + 555 1.1 haad arg_count(cmd, physicalextentsize_ARG) > 1) { 556 1.1 haad log_error("Only one of -a, -c, -l, -p, -s, -x, --uuid, " 557 1.1 haad "--alloc, --addtag or --deltag allowed"); 558 1.1 haad return EINVALID_CMD_LINE; 559 1.1 haad } 560 1.1 haad 561 1.1 haad if (arg_count(cmd, ignorelockingfailure_ARG) && 562 1.1 haad !arg_count(cmd, available_ARG)) { 563 1.1 haad log_error("--ignorelockingfailure only available with -a"); 564 1.1 haad return EINVALID_CMD_LINE; 565 1.1 haad } 566 1.1 haad 567 1.1 haad if (arg_count(cmd, available_ARG) == 1 568 1.1 haad && arg_count(cmd, autobackup_ARG)) { 569 1.1 haad log_error("-A option not necessary with -a option"); 570 1.1 haad return EINVALID_CMD_LINE; 571 1.1 haad } 572 1.1 haad 573 1.1 haad return process_each_vg(cmd, argc, argv, 574 1.1 haad (arg_count(cmd, available_ARG)) ? 575 1.1.1.3 haad 0 : READ_FOR_UPDATE, 576 1.1.1.3 haad NULL, 577 1.1 haad &vgchange_single); 578 1.1 haad } 579