1 1.1 haad /* $NetBSD: lvchange.c,v 1.1.1.3 2009/12/02 00:25:49 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 lvchange_permission(struct cmd_context *cmd, 21 1.1 haad struct logical_volume *lv) 22 1.1 haad { 23 1.1 haad uint32_t lv_access; 24 1.1 haad struct lvinfo info; 25 1.1.1.3 haad int r = 0; 26 1.1 haad 27 1.1 haad lv_access = arg_uint_value(cmd, permission_ARG, 0); 28 1.1 haad 29 1.1 haad if ((lv_access & LVM_WRITE) && (lv->status & LVM_WRITE)) { 30 1.1 haad log_error("Logical volume \"%s\" is already writable", 31 1.1 haad lv->name); 32 1.1 haad return 0; 33 1.1 haad } 34 1.1 haad 35 1.1 haad if (!(lv_access & LVM_WRITE) && !(lv->status & LVM_WRITE)) { 36 1.1 haad log_error("Logical volume \"%s\" is already read only", 37 1.1 haad lv->name); 38 1.1 haad return 0; 39 1.1 haad } 40 1.1 haad 41 1.1 haad if ((lv->status & MIRRORED) && (vg_is_clustered(lv->vg)) && 42 1.1 haad lv_info(cmd, lv, &info, 0, 0) && info.exists) { 43 1.1 haad log_error("Cannot change permissions of mirror \"%s\" " 44 1.1 haad "while active.", lv->name); 45 1.1 haad return 0; 46 1.1 haad } 47 1.1 haad 48 1.1 haad if (lv_access & LVM_WRITE) { 49 1.1 haad lv->status |= LVM_WRITE; 50 1.1 haad log_verbose("Setting logical volume \"%s\" read/write", 51 1.1 haad lv->name); 52 1.1 haad } else { 53 1.1 haad lv->status &= ~LVM_WRITE; 54 1.1 haad log_verbose("Setting logical volume \"%s\" read-only", 55 1.1 haad lv->name); 56 1.1 haad } 57 1.1 haad 58 1.1 haad log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 59 1.1 haad if (!vg_write(lv->vg)) 60 1.1 haad return_0; 61 1.1 haad 62 1.1 haad if (!suspend_lv(cmd, lv)) { 63 1.1 haad log_error("Failed to lock %s", lv->name); 64 1.1 haad vg_revert(lv->vg); 65 1.1.1.3 haad goto out; 66 1.1 haad } 67 1.1 haad 68 1.1 haad if (!vg_commit(lv->vg)) { 69 1.1 haad resume_lv(cmd, lv); 70 1.1.1.3 haad goto_out; 71 1.1 haad } 72 1.1 haad 73 1.1 haad log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name); 74 1.1 haad if (!resume_lv(cmd, lv)) { 75 1.1 haad log_error("Problem reactivating %s", lv->name); 76 1.1.1.3 haad goto out; 77 1.1 haad } 78 1.1 haad 79 1.1.1.3 haad r = 1; 80 1.1.1.3 haad out: 81 1.1.1.3 haad backup(lv->vg); 82 1.1.1.3 haad return r; 83 1.1 haad } 84 1.1 haad 85 1.1 haad static int lvchange_monitoring(struct cmd_context *cmd, 86 1.1 haad struct logical_volume *lv) 87 1.1 haad { 88 1.1 haad struct lvinfo info; 89 1.1 haad 90 1.1 haad if (!lv_info(cmd, lv, &info, 0, 0) || !info.exists) { 91 1.1 haad log_error("Logical volume, %s, is not active", lv->name); 92 1.1 haad return 0; 93 1.1 haad } 94 1.1 haad 95 1.1 haad /* do not monitor pvmove lv's */ 96 1.1 haad if (lv->status & PVMOVE) 97 1.1 haad return 1; 98 1.1 haad 99 1.1 haad if ((dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) && 100 1.1 haad !monitor_dev_for_events(cmd, lv, dmeventd_monitor_mode())) 101 1.1 haad stack; 102 1.1 haad 103 1.1 haad return 1; 104 1.1 haad } 105 1.1 haad 106 1.1 haad static int lvchange_availability(struct cmd_context *cmd, 107 1.1 haad struct logical_volume *lv) 108 1.1 haad { 109 1.1 haad int activate; 110 1.1 haad 111 1.1 haad activate = arg_uint_value(cmd, available_ARG, 0); 112 1.1 haad 113 1.1 haad if (activate == CHANGE_ALN) { 114 1.1 haad log_verbose("Deactivating logical volume \"%s\" locally", 115 1.1 haad lv->name); 116 1.1 haad if (!deactivate_lv_local(cmd, lv)) 117 1.1 haad return_0; 118 1.1 haad } else if (activate == CHANGE_AN) { 119 1.1 haad log_verbose("Deactivating logical volume \"%s\"", lv->name); 120 1.1 haad if (!deactivate_lv(cmd, lv)) 121 1.1 haad return_0; 122 1.1 haad } else { 123 1.1 haad if (lv_is_origin(lv) || (activate == CHANGE_AE)) { 124 1.1 haad log_verbose("Activating logical volume \"%s\" " 125 1.1 haad "exclusively", lv->name); 126 1.1 haad if (!activate_lv_excl(cmd, lv)) 127 1.1 haad return_0; 128 1.1 haad } else if (activate == CHANGE_ALY) { 129 1.1 haad log_verbose("Activating logical volume \"%s\" locally", 130 1.1 haad lv->name); 131 1.1 haad if (!activate_lv_local(cmd, lv)) 132 1.1 haad return_0; 133 1.1 haad } else { 134 1.1 haad log_verbose("Activating logical volume \"%s\"", 135 1.1 haad lv->name); 136 1.1 haad if (!activate_lv(cmd, lv)) 137 1.1 haad return_0; 138 1.1 haad } 139 1.1 haad 140 1.1.1.3 haad lv_spawn_background_polling(cmd, lv); 141 1.1 haad } 142 1.1 haad 143 1.1 haad return 1; 144 1.1 haad } 145 1.1 haad 146 1.1 haad static int lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv) 147 1.1 haad { 148 1.1 haad log_verbose("Refreshing logical volume \"%s\" (if active)", lv->name); 149 1.1.1.2 haad return lv_refresh(cmd, lv); 150 1.1 haad } 151 1.1 haad 152 1.1 haad static int lvchange_resync(struct cmd_context *cmd, 153 1.1 haad struct logical_volume *lv) 154 1.1 haad { 155 1.1 haad int active = 0; 156 1.1 haad int monitored; 157 1.1 haad struct lvinfo info; 158 1.1 haad struct logical_volume *log_lv; 159 1.1 haad 160 1.1 haad if (!(lv->status & MIRRORED)) { 161 1.1 haad log_error("Unable to resync %s because it is not mirrored.", 162 1.1 haad lv->name); 163 1.1 haad return 1; 164 1.1 haad } 165 1.1 haad 166 1.1 haad if (lv->status & PVMOVE) { 167 1.1 haad log_error("Unable to resync pvmove volume %s", lv->name); 168 1.1 haad return 0; 169 1.1 haad } 170 1.1 haad 171 1.1 haad if (lv->status & LOCKED) { 172 1.1 haad log_error("Unable to resync locked volume %s", lv->name); 173 1.1 haad return 0; 174 1.1 haad } 175 1.1 haad 176 1.1 haad if (lv_info(cmd, lv, &info, 1, 0)) { 177 1.1 haad if (info.open_count) { 178 1.1 haad log_error("Can't resync open logical volume \"%s\"", 179 1.1 haad lv->name); 180 1.1.1.3 haad return 0; 181 1.1 haad } 182 1.1 haad 183 1.1 haad if (info.exists) { 184 1.1 haad if (!arg_count(cmd, yes_ARG) && 185 1.1 haad yes_no_prompt("Do you really want to deactivate " 186 1.1 haad "logical volume %s to resync it? [y/n]: ", 187 1.1 haad lv->name) == 'n') { 188 1.1 haad log_print("Logical volume \"%s\" not resynced", 189 1.1 haad lv->name); 190 1.1.1.3 haad return 0; 191 1.1 haad } 192 1.1 haad 193 1.1 haad if (sigint_caught()) 194 1.1.1.3 haad return 0; 195 1.1 haad 196 1.1 haad active = 1; 197 1.1 haad } 198 1.1 haad } 199 1.1 haad 200 1.1 haad /* Activate exclusively to ensure no nodes still have LV active */ 201 1.1 haad monitored = dmeventd_monitor_mode(); 202 1.1 haad init_dmeventd_monitor(0); 203 1.1 haad 204 1.1 haad if (!deactivate_lv(cmd, lv)) { 205 1.1 haad log_error("Unable to deactivate %s for resync", lv->name); 206 1.1 haad return 0; 207 1.1 haad } 208 1.1 haad 209 1.1.1.3 haad if (vg_is_clustered(lv->vg) && lv_is_active(lv)) { 210 1.1.1.3 haad log_error("Can't get exclusive access to clustered volume %s", 211 1.1.1.3 haad lv->name); 212 1.1.1.3 haad return 0; 213 1.1.1.3 haad } 214 1.1.1.3 haad 215 1.1 haad init_dmeventd_monitor(monitored); 216 1.1 haad 217 1.1 haad log_lv = first_seg(lv)->log_lv; 218 1.1 haad 219 1.1 haad log_very_verbose("Starting resync of %s%s%s mirror \"%s\"", 220 1.1 haad (active) ? "active " : "", 221 1.1 haad vg_is_clustered(lv->vg) ? "clustered " : "", 222 1.1 haad (log_lv) ? "disk-logged" : "core-logged", 223 1.1 haad lv->name); 224 1.1 haad 225 1.1 haad /* 226 1.1 haad * If this mirror has a core log (i.e. !log_lv), 227 1.1 haad * then simply deactivating/activating will cause 228 1.1 haad * it to reset the sync status. We only need to 229 1.1 haad * worry about persistent logs. 230 1.1 haad */ 231 1.1 haad if (!log_lv && !(lv->status & MIRROR_NOTSYNCED)) { 232 1.1 haad if (active && !activate_lv(cmd, lv)) { 233 1.1 haad log_error("Failed to reactivate %s to resynchronize " 234 1.1 haad "mirror", lv->name); 235 1.1 haad return 0; 236 1.1 haad } 237 1.1 haad return 1; 238 1.1 haad } 239 1.1 haad 240 1.1 haad lv->status &= ~MIRROR_NOTSYNCED; 241 1.1 haad 242 1.1 haad if (log_lv) { 243 1.1 haad /* Separate mirror log so we can clear it */ 244 1.1 haad detach_mirror_log(first_seg(lv)); 245 1.1 haad 246 1.1 haad if (!vg_write(lv->vg)) { 247 1.1 haad log_error("Failed to write intermediate VG metadata."); 248 1.1 haad if (!attach_mirror_log(first_seg(lv), log_lv)) 249 1.1 haad stack; 250 1.1 haad if (active && !activate_lv(cmd, lv)) 251 1.1 haad stack; 252 1.1 haad return 0; 253 1.1 haad } 254 1.1 haad 255 1.1 haad if (!vg_commit(lv->vg)) { 256 1.1 haad log_error("Failed to commit intermediate VG metadata."); 257 1.1 haad if (!attach_mirror_log(first_seg(lv), log_lv)) 258 1.1 haad stack; 259 1.1 haad if (active && !activate_lv(cmd, lv)) 260 1.1 haad stack; 261 1.1 haad return 0; 262 1.1 haad } 263 1.1 haad 264 1.1.1.3 haad backup(lv->vg); 265 1.1.1.3 haad 266 1.1 haad if (!activate_lv(cmd, log_lv)) { 267 1.1 haad log_error("Unable to activate %s for mirror log resync", 268 1.1 haad log_lv->name); 269 1.1 haad return 0; 270 1.1 haad } 271 1.1 haad 272 1.1 haad log_very_verbose("Clearing log device %s", log_lv->name); 273 1.1 haad if (!set_lv(cmd, log_lv, log_lv->size, 0)) { 274 1.1 haad log_error("Unable to reset sync status for %s", lv->name); 275 1.1 haad if (!deactivate_lv(cmd, log_lv)) 276 1.1 haad log_error("Failed to deactivate log LV after " 277 1.1 haad "wiping failed"); 278 1.1 haad return 0; 279 1.1 haad } 280 1.1 haad 281 1.1 haad if (!deactivate_lv(cmd, log_lv)) { 282 1.1 haad log_error("Unable to deactivate log LV %s after wiping " 283 1.1 haad "for resync", log_lv->name); 284 1.1 haad return 0; 285 1.1 haad } 286 1.1 haad 287 1.1 haad /* Put mirror log back in place */ 288 1.1 haad if (!attach_mirror_log(first_seg(lv), log_lv)) 289 1.1 haad stack; 290 1.1 haad } 291 1.1 haad 292 1.1 haad log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 293 1.1 haad if (!vg_write(lv->vg) || !vg_commit(lv->vg)) { 294 1.1 haad log_error("Failed to update metadata on disk."); 295 1.1 haad return 0; 296 1.1 haad } 297 1.1 haad 298 1.1 haad if (active && !activate_lv(cmd, lv)) { 299 1.1 haad log_error("Failed to reactivate %s after resync", lv->name); 300 1.1 haad return 0; 301 1.1 haad } 302 1.1 haad 303 1.1 haad return 1; 304 1.1 haad } 305 1.1 haad 306 1.1 haad static int lvchange_alloc(struct cmd_context *cmd, struct logical_volume *lv) 307 1.1 haad { 308 1.1 haad int want_contiguous = 0; 309 1.1 haad alloc_policy_t alloc; 310 1.1 haad 311 1.1 haad want_contiguous = strcmp(arg_str_value(cmd, contiguous_ARG, "n"), "n"); 312 1.1 haad alloc = want_contiguous ? ALLOC_CONTIGUOUS : ALLOC_INHERIT; 313 1.1 haad alloc = arg_uint_value(cmd, alloc_ARG, alloc); 314 1.1 haad 315 1.1 haad if (alloc == lv->alloc) { 316 1.1 haad log_error("Allocation policy of logical volume \"%s\" is " 317 1.1 haad "already %s", lv->name, get_alloc_string(alloc)); 318 1.1 haad return 0; 319 1.1 haad } 320 1.1 haad 321 1.1 haad lv->alloc = alloc; 322 1.1 haad 323 1.1 haad /* FIXME If contiguous, check existing extents already are */ 324 1.1 haad 325 1.1 haad log_verbose("Setting contiguous allocation policy for \"%s\" to %s", 326 1.1 haad lv->name, get_alloc_string(alloc)); 327 1.1 haad 328 1.1 haad log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 329 1.1 haad 330 1.1.1.3 haad /* No need to suspend LV for this change */ 331 1.1.1.3 haad if (!vg_write(lv->vg) || !vg_commit(lv->vg)) 332 1.1 haad return_0; 333 1.1 haad 334 1.1 haad backup(lv->vg); 335 1.1 haad 336 1.1 haad return 1; 337 1.1 haad } 338 1.1 haad 339 1.1 haad static int lvchange_readahead(struct cmd_context *cmd, 340 1.1 haad struct logical_volume *lv) 341 1.1 haad { 342 1.1 haad unsigned read_ahead = 0; 343 1.1 haad unsigned pagesize = (unsigned) lvm_getpagesize() >> SECTOR_SHIFT; 344 1.1.1.3 haad int r = 0; 345 1.1 haad 346 1.1 haad read_ahead = arg_uint_value(cmd, readahead_ARG, 0); 347 1.1 haad 348 1.1 haad if (read_ahead != DM_READ_AHEAD_AUTO && 349 1.1 haad (lv->vg->fid->fmt->features & FMT_RESTRICTED_READAHEAD) && 350 1.1 haad (read_ahead < 2 || read_ahead > 120)) { 351 1.1 haad log_error("Metadata only supports readahead values between 2 and 120."); 352 1.1 haad return 0; 353 1.1 haad } 354 1.1 haad 355 1.1 haad if (read_ahead != DM_READ_AHEAD_AUTO && 356 1.1 haad read_ahead != DM_READ_AHEAD_NONE && read_ahead % pagesize) { 357 1.1.1.3 haad if (read_ahead < pagesize) 358 1.1.1.3 haad read_ahead = pagesize; 359 1.1.1.3 haad else 360 1.1.1.3 haad read_ahead = (read_ahead / pagesize) * pagesize; 361 1.1.1.3 haad log_warn("WARNING: Overriding readahead to %u sectors, a multiple " 362 1.1.1.3 haad "of %uK page size.", read_ahead, pagesize >> 1); 363 1.1 haad } 364 1.1 haad 365 1.1 haad if (lv->read_ahead == read_ahead) { 366 1.1 haad if (read_ahead == DM_READ_AHEAD_AUTO) 367 1.1 haad log_error("Read ahead is already auto for \"%s\"", lv->name); 368 1.1 haad else 369 1.1 haad log_error("Read ahead is already %u for \"%s\"", 370 1.1 haad read_ahead, lv->name); 371 1.1 haad return 0; 372 1.1 haad } 373 1.1 haad 374 1.1 haad lv->read_ahead = read_ahead; 375 1.1 haad 376 1.1 haad log_verbose("Setting read ahead to %u for \"%s\"", read_ahead, 377 1.1 haad lv->name); 378 1.1 haad 379 1.1 haad log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 380 1.1 haad if (!vg_write(lv->vg)) 381 1.1 haad return_0; 382 1.1 haad 383 1.1 haad if (!suspend_lv(cmd, lv)) { 384 1.1 haad log_error("Failed to lock %s", lv->name); 385 1.1 haad vg_revert(lv->vg); 386 1.1.1.3 haad goto out; 387 1.1 haad } 388 1.1 haad 389 1.1 haad if (!vg_commit(lv->vg)) { 390 1.1 haad resume_lv(cmd, lv); 391 1.1.1.3 haad goto_out; 392 1.1 haad } 393 1.1 haad 394 1.1 haad log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name); 395 1.1 haad if (!resume_lv(cmd, lv)) { 396 1.1 haad log_error("Problem reactivating %s", lv->name); 397 1.1.1.3 haad goto out; 398 1.1 haad } 399 1.1 haad 400 1.1.1.3 haad r = 1; 401 1.1.1.3 haad out: 402 1.1.1.3 haad backup(lv->vg); 403 1.1.1.3 haad return r; 404 1.1 haad } 405 1.1 haad 406 1.1 haad static int lvchange_persistent(struct cmd_context *cmd, 407 1.1 haad struct logical_volume *lv) 408 1.1 haad { 409 1.1 haad struct lvinfo info; 410 1.1 haad int active = 0; 411 1.1 haad 412 1.1 haad if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "n")) { 413 1.1 haad if (!(lv->status & FIXED_MINOR)) { 414 1.1 haad log_error("Minor number is already not persistent " 415 1.1 haad "for \"%s\"", lv->name); 416 1.1 haad return 0; 417 1.1 haad } 418 1.1 haad lv->status &= ~FIXED_MINOR; 419 1.1 haad lv->minor = -1; 420 1.1 haad lv->major = -1; 421 1.1 haad log_verbose("Disabling persistent device number for \"%s\"", 422 1.1 haad lv->name); 423 1.1 haad } else { 424 1.1 haad if (!arg_count(cmd, minor_ARG) && lv->minor < 0) { 425 1.1 haad log_error("Minor number must be specified with -My"); 426 1.1 haad return 0; 427 1.1 haad } 428 1.1 haad if (!arg_count(cmd, major_ARG) && lv->major < 0) { 429 1.1 haad log_error("Major number must be specified with -My"); 430 1.1 haad return 0; 431 1.1 haad } 432 1.1 haad if (lv_info(cmd, lv, &info, 0, 0) && info.exists) 433 1.1 haad active = 1; 434 1.1 haad if (active && !arg_count(cmd, force_ARG) && 435 1.1 haad yes_no_prompt("Logical volume %s will be " 436 1.1 haad "deactivated temporarily. " 437 1.1 haad "Continue? [y/n]: ", lv->name) == 'n') { 438 1.1 haad log_print("%s device number not changed.", 439 1.1 haad lv->name); 440 1.1 haad return 0; 441 1.1 haad } 442 1.1 haad 443 1.1 haad if (sigint_caught()) 444 1.1 haad return 0; 445 1.1 haad 446 1.1 haad log_verbose("Ensuring %s is inactive.", lv->name); 447 1.1 haad if (!deactivate_lv(cmd, lv)) { 448 1.1 haad log_error("%s: deactivation failed", lv->name); 449 1.1 haad return 0; 450 1.1 haad } 451 1.1 haad lv->status |= FIXED_MINOR; 452 1.1 haad lv->minor = arg_int_value(cmd, minor_ARG, lv->minor); 453 1.1 haad lv->major = arg_int_value(cmd, major_ARG, lv->major); 454 1.1 haad log_verbose("Setting persistent device number to (%d, %d) " 455 1.1 haad "for \"%s\"", lv->major, lv->minor, lv->name); 456 1.1 haad 457 1.1 haad } 458 1.1 haad 459 1.1 haad log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 460 1.1.1.3 haad if (!vg_write(lv->vg) || !vg_commit(lv->vg)) 461 1.1 haad return_0; 462 1.1 haad 463 1.1 haad backup(lv->vg); 464 1.1 haad 465 1.1 haad if (active) { 466 1.1 haad log_verbose("Re-activating logical volume \"%s\"", lv->name); 467 1.1 haad if (!activate_lv(cmd, lv)) { 468 1.1 haad log_error("%s: reactivation failed", lv->name); 469 1.1 haad return 0; 470 1.1 haad } 471 1.1 haad } 472 1.1 haad 473 1.1 haad return 1; 474 1.1 haad } 475 1.1 haad 476 1.1 haad static int lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv, 477 1.1 haad int arg) 478 1.1 haad { 479 1.1 haad const char *tag; 480 1.1 haad 481 1.1 haad if (!(tag = arg_str_value(cmd, arg, NULL))) { 482 1.1 haad log_error("Failed to get tag"); 483 1.1 haad return 0; 484 1.1 haad } 485 1.1 haad 486 1.1 haad if (!(lv->vg->fid->fmt->features & FMT_TAGS)) { 487 1.1 haad log_error("Logical volume %s/%s does not support tags", 488 1.1 haad lv->vg->name, lv->name); 489 1.1 haad return 0; 490 1.1 haad } 491 1.1 haad 492 1.1 haad if ((arg == addtag_ARG)) { 493 1.1 haad if (!str_list_add(cmd->mem, &lv->tags, tag)) { 494 1.1 haad log_error("Failed to add tag %s to %s/%s", 495 1.1 haad tag, lv->vg->name, lv->name); 496 1.1 haad return 0; 497 1.1 haad } 498 1.1 haad } else { 499 1.1 haad if (!str_list_del(&lv->tags, tag)) { 500 1.1 haad log_error("Failed to remove tag %s from %s/%s", 501 1.1 haad tag, lv->vg->name, lv->name); 502 1.1 haad return 0; 503 1.1 haad } 504 1.1 haad } 505 1.1 haad 506 1.1 haad log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); 507 1.1 haad 508 1.1 haad /* No need to suspend LV for this change */ 509 1.1.1.3 haad if (!vg_write(lv->vg) || !vg_commit(lv->vg)) 510 1.1 haad return_0; 511 1.1 haad 512 1.1.1.3 haad backup(lv->vg); 513 1.1.1.3 haad 514 1.1 haad return 1; 515 1.1 haad } 516 1.1 haad 517 1.1 haad static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv, 518 1.1 haad void *handle __attribute((unused))) 519 1.1 haad { 520 1.1 haad int doit = 0, docmds = 0; 521 1.1 haad int archived = 0; 522 1.1.1.3 haad struct logical_volume *origin; 523 1.1 haad 524 1.1 haad if (!(lv->vg->status & LVM_WRITE) && 525 1.1 haad (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) || 526 1.1 haad arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) || 527 1.1 haad arg_count(cmd, alloc_ARG))) { 528 1.1 haad log_error("Only -a permitted with read-only volume " 529 1.1 haad "group \"%s\"", lv->vg->name); 530 1.1 haad return EINVALID_CMD_LINE; 531 1.1 haad } 532 1.1 haad 533 1.1 haad if (lv_is_origin(lv) && 534 1.1 haad (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) || 535 1.1 haad arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) || 536 1.1 haad arg_count(cmd, alloc_ARG))) { 537 1.1 haad log_error("Can't change logical volume \"%s\" under snapshot", 538 1.1 haad lv->name); 539 1.1 haad return ECMD_FAILED; 540 1.1 haad } 541 1.1 haad 542 1.1.1.3 haad if (lv_is_cow(lv) && !lv_is_virtual_origin(origin_from_cow(lv)) && 543 1.1.1.3 haad arg_count(cmd, available_ARG)) { 544 1.1 haad log_error("Can't change snapshot logical volume \"%s\"", 545 1.1 haad lv->name); 546 1.1 haad return ECMD_FAILED; 547 1.1 haad } 548 1.1 haad 549 1.1 haad if (lv->status & PVMOVE) { 550 1.1 haad log_error("Unable to change pvmove LV %s", lv->name); 551 1.1 haad if (arg_count(cmd, available_ARG)) 552 1.1 haad log_error("Use 'pvmove --abort' to abandon a pvmove"); 553 1.1 haad return ECMD_FAILED; 554 1.1 haad } 555 1.1 haad 556 1.1 haad if (lv->status & MIRROR_LOG) { 557 1.1 haad log_error("Unable to change mirror log LV %s directly", lv->name); 558 1.1 haad return ECMD_FAILED; 559 1.1 haad } 560 1.1 haad 561 1.1 haad if (lv->status & MIRROR_IMAGE) { 562 1.1 haad log_error("Unable to change mirror image LV %s directly", 563 1.1 haad lv->name); 564 1.1 haad return ECMD_FAILED; 565 1.1 haad } 566 1.1 haad 567 1.1.1.3 haad /* If LV is sparse, activate origin instead */ 568 1.1.1.3 haad if (arg_count(cmd, available_ARG) && lv_is_cow(lv) && 569 1.1.1.3 haad lv_is_virtual_origin(origin = origin_from_cow(lv))) 570 1.1.1.3 haad lv = origin; 571 1.1.1.3 haad 572 1.1.1.3 haad if (!(lv_is_visible(lv)) && !lv_is_virtual_origin(lv)) { 573 1.1 haad log_error("Unable to change internal LV %s directly", 574 1.1 haad lv->name); 575 1.1 haad return ECMD_FAILED; 576 1.1 haad } 577 1.1 haad 578 1.1 haad init_dmeventd_monitor(arg_int_value(cmd, monitor_ARG, 579 1.1.1.2 haad (is_static() || arg_count(cmd, ignoremonitoring_ARG)) ? 580 1.1 haad DMEVENTD_MONITOR_IGNORE : DEFAULT_DMEVENTD_MONITOR)); 581 1.1 haad 582 1.1 haad /* access permission change */ 583 1.1 haad if (arg_count(cmd, permission_ARG)) { 584 1.1.1.3 haad if (!archive(lv->vg)) { 585 1.1.1.3 haad stack; 586 1.1 haad return ECMD_FAILED; 587 1.1.1.3 haad } 588 1.1 haad archived = 1; 589 1.1 haad doit += lvchange_permission(cmd, lv); 590 1.1 haad docmds++; 591 1.1 haad } 592 1.1 haad 593 1.1 haad /* allocation policy change */ 594 1.1 haad if (arg_count(cmd, contiguous_ARG) || arg_count(cmd, alloc_ARG)) { 595 1.1.1.3 haad if (!archived && !archive(lv->vg)) { 596 1.1.1.3 haad stack; 597 1.1 haad return ECMD_FAILED; 598 1.1.1.3 haad } 599 1.1 haad archived = 1; 600 1.1 haad doit += lvchange_alloc(cmd, lv); 601 1.1 haad docmds++; 602 1.1 haad } 603 1.1 haad 604 1.1 haad /* read ahead sector change */ 605 1.1 haad if (arg_count(cmd, readahead_ARG)) { 606 1.1.1.3 haad if (!archived && !archive(lv->vg)) { 607 1.1.1.3 haad stack; 608 1.1 haad return ECMD_FAILED; 609 1.1.1.3 haad } 610 1.1 haad archived = 1; 611 1.1 haad doit += lvchange_readahead(cmd, lv); 612 1.1 haad docmds++; 613 1.1 haad } 614 1.1 haad 615 1.1.1.3 haad /* persistent device number change */ 616 1.1 haad if (arg_count(cmd, persistent_ARG)) { 617 1.1.1.3 haad if (!archived && !archive(lv->vg)) { 618 1.1.1.3 haad stack; 619 1.1 haad return ECMD_FAILED; 620 1.1.1.3 haad } 621 1.1 haad archived = 1; 622 1.1 haad doit += lvchange_persistent(cmd, lv); 623 1.1 haad docmds++; 624 1.1.1.3 haad if (sigint_caught()) { 625 1.1.1.3 haad stack; 626 1.1 haad return ECMD_FAILED; 627 1.1.1.3 haad } 628 1.1 haad } 629 1.1 haad 630 1.1 haad /* add tag */ 631 1.1 haad if (arg_count(cmd, addtag_ARG)) { 632 1.1.1.3 haad if (!archived && !archive(lv->vg)) { 633 1.1.1.3 haad stack; 634 1.1 haad return ECMD_FAILED; 635 1.1.1.3 haad } 636 1.1 haad archived = 1; 637 1.1 haad doit += lvchange_tag(cmd, lv, addtag_ARG); 638 1.1 haad docmds++; 639 1.1 haad } 640 1.1 haad 641 1.1 haad /* del tag */ 642 1.1 haad if (arg_count(cmd, deltag_ARG)) { 643 1.1.1.3 haad if (!archived && !archive(lv->vg)) { 644 1.1.1.3 haad stack; 645 1.1 haad return ECMD_FAILED; 646 1.1.1.3 haad } 647 1.1 haad archived = 1; 648 1.1 haad doit += lvchange_tag(cmd, lv, deltag_ARG); 649 1.1 haad docmds++; 650 1.1 haad } 651 1.1 haad 652 1.1 haad if (doit) 653 1.1 haad log_print("Logical volume \"%s\" changed", lv->name); 654 1.1 haad 655 1.1 haad if (arg_count(cmd, resync_ARG)) 656 1.1.1.3 haad if (!lvchange_resync(cmd, lv)) { 657 1.1.1.3 haad stack; 658 1.1 haad return ECMD_FAILED; 659 1.1.1.3 haad } 660 1.1 haad 661 1.1 haad /* availability change */ 662 1.1 haad if (arg_count(cmd, available_ARG)) { 663 1.1.1.3 haad if (!lvchange_availability(cmd, lv)) { 664 1.1.1.3 haad stack; 665 1.1 haad return ECMD_FAILED; 666 1.1.1.3 haad } 667 1.1 haad } 668 1.1 haad 669 1.1 haad if (arg_count(cmd, refresh_ARG)) 670 1.1.1.3 haad if (!lvchange_refresh(cmd, lv)) { 671 1.1.1.3 haad stack; 672 1.1 haad return ECMD_FAILED; 673 1.1.1.3 haad } 674 1.1 haad 675 1.1 haad if (!arg_count(cmd, available_ARG) && 676 1.1 haad !arg_count(cmd, refresh_ARG) && 677 1.1 haad arg_count(cmd, monitor_ARG)) { 678 1.1.1.3 haad if (!lvchange_monitoring(cmd, lv)) { 679 1.1.1.3 haad stack; 680 1.1 haad return ECMD_FAILED; 681 1.1.1.3 haad } 682 1.1 haad } 683 1.1 haad 684 1.1.1.3 haad if (doit != docmds) { 685 1.1.1.3 haad stack; 686 1.1 haad return ECMD_FAILED; 687 1.1.1.3 haad } 688 1.1 haad 689 1.1 haad return ECMD_PROCESSED; 690 1.1 haad } 691 1.1 haad 692 1.1 haad int lvchange(struct cmd_context *cmd, int argc, char **argv) 693 1.1 haad { 694 1.1 haad if (!arg_count(cmd, available_ARG) && !arg_count(cmd, contiguous_ARG) 695 1.1 haad && !arg_count(cmd, permission_ARG) && !arg_count(cmd, readahead_ARG) 696 1.1 haad && !arg_count(cmd, minor_ARG) && !arg_count(cmd, major_ARG) 697 1.1 haad && !arg_count(cmd, persistent_ARG) && !arg_count(cmd, addtag_ARG) 698 1.1 haad && !arg_count(cmd, deltag_ARG) && !arg_count(cmd, refresh_ARG) 699 1.1 haad && !arg_count(cmd, alloc_ARG) && !arg_count(cmd, monitor_ARG) 700 1.1 haad && !arg_count(cmd, resync_ARG)) { 701 1.1 haad log_error("Need 1 or more of -a, -C, -j, -m, -M, -p, -r, " 702 1.1 haad "--resync, --refresh, --alloc, --addtag, --deltag " 703 1.1 haad "or --monitor"); 704 1.1 haad return EINVALID_CMD_LINE; 705 1.1 haad } 706 1.1 haad 707 1.1.1.3 haad int avail_only = /* i.e. only one of -a or --refresh is given */ 708 1.1.1.3 haad !(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) || 709 1.1 haad arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) || 710 1.1 haad arg_count(cmd, addtag_ARG) || arg_count(cmd, deltag_ARG) || 711 1.1.1.3 haad arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG)); 712 1.1.1.3 haad 713 1.1.1.3 haad if (arg_count(cmd, ignorelockingfailure_ARG) && !avail_only) { 714 1.1 haad log_error("Only -a permitted with --ignorelockingfailure"); 715 1.1 haad return EINVALID_CMD_LINE; 716 1.1 haad } 717 1.1 haad 718 1.1.1.3 haad if (avail_only) 719 1.1.1.3 haad cmd->handles_missing_pvs = 1; 720 1.1.1.3 haad 721 1.1 haad if (!argc) { 722 1.1 haad log_error("Please give logical volume path(s)"); 723 1.1 haad return EINVALID_CMD_LINE; 724 1.1 haad } 725 1.1 haad 726 1.1 haad if ((arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) && 727 1.1 haad !arg_count(cmd, persistent_ARG)) { 728 1.1 haad log_error("--major and --minor require -My"); 729 1.1 haad return EINVALID_CMD_LINE; 730 1.1 haad } 731 1.1 haad 732 1.1 haad if (arg_count(cmd, minor_ARG) && argc != 1) { 733 1.1 haad log_error("Only give one logical volume when specifying minor"); 734 1.1 haad return EINVALID_CMD_LINE; 735 1.1 haad } 736 1.1 haad 737 1.1 haad if (arg_count(cmd, contiguous_ARG) && arg_count(cmd, alloc_ARG)) { 738 1.1 haad log_error("Only one of --alloc and --contiguous permitted"); 739 1.1 haad return EINVALID_CMD_LINE; 740 1.1 haad } 741 1.1 haad 742 1.1.1.3 haad return process_each_lv(cmd, argc, argv, 743 1.1.1.3 haad avail_only ? 0 : READ_FOR_UPDATE, NULL, 744 1.1 haad &lvchange_single); 745 1.1 haad } 746