1 /* $NetBSD: locking.c,v 1.1.1.3 2009/12/02 00:26:25 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 * 7 * This file is part of LVM2. 8 * 9 * This copyrighted material is made available to anyone wishing to use, 10 * modify, copy, or redistribute it subject to the terms and conditions 11 * of the GNU Lesser General Public License v.2.1. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #include "lib.h" 19 #include "locking.h" 20 #include "locking_types.h" 21 #include "lvm-string.h" 22 #include "activate.h" 23 #include "toolcontext.h" 24 #include "memlock.h" 25 #include "defaults.h" 26 #include "lvmcache.h" 27 28 #include <assert.h> 29 #include <signal.h> 30 #include <sys/stat.h> 31 #include <limits.h> 32 #include <unistd.h> 33 34 static struct locking_type _locking; 35 static sigset_t _oldset; 36 37 static int _vg_lock_count = 0; /* Number of locks held */ 38 static int _vg_write_lock_held = 0; /* VG write lock held? */ 39 static int _signals_blocked = 0; 40 static int _blocking_supported = 0; 41 42 static volatile sig_atomic_t _sigint_caught = 0; 43 static volatile sig_atomic_t _handler_installed; 44 static struct sigaction _oldhandler; 45 static int _oldmasked; 46 47 typedef enum { 48 LV_NOOP, 49 LV_SUSPEND, 50 LV_RESUME 51 } lv_operation_t; 52 53 static void _catch_sigint(int unused __attribute__((unused))) 54 { 55 _sigint_caught = 1; 56 } 57 58 int sigint_caught(void) { 59 return _sigint_caught; 60 } 61 62 void sigint_clear(void) 63 { 64 _sigint_caught = 0; 65 } 66 67 /* 68 * Temporarily allow keyboard interrupts to be intercepted and noted; 69 * saves interrupt handler state for sigint_restore(). Users should 70 * use the sigint_caught() predicate to check whether interrupt was 71 * requested and act appropriately. Interrupt flags are never 72 * cleared automatically by this code, but the tools clear the flag 73 * before running each command in lvm_run_command(). All other places 74 * where the flag needs to be cleared need to call sigint_clear(). 75 */ 76 77 void sigint_allow(void) 78 { 79 struct sigaction handler; 80 sigset_t sigs; 81 82 /* 83 * Do not overwrite the backed-up handler data - 84 * just increase nesting count. 85 */ 86 if (_handler_installed) { 87 _handler_installed++; 88 return; 89 } 90 91 /* Grab old sigaction for SIGINT: shall not fail. */ 92 sigaction(SIGINT, NULL, &handler); 93 handler.sa_flags &= ~SA_RESTART; /* Clear restart flag */ 94 handler.sa_handler = _catch_sigint; 95 96 _handler_installed = 1; 97 98 /* Override the signal handler: shall not fail. */ 99 sigaction(SIGINT, &handler, &_oldhandler); 100 101 /* Unmask SIGINT. Remember to mask it again on restore. */ 102 sigprocmask(0, NULL, &sigs); 103 if ((_oldmasked = sigismember(&sigs, SIGINT))) { 104 sigdelset(&sigs, SIGINT); 105 sigprocmask(SIG_SETMASK, &sigs, NULL); 106 } 107 } 108 109 void sigint_restore(void) 110 { 111 if (!_handler_installed) 112 return; 113 114 if (_handler_installed > 1) { 115 _handler_installed--; 116 return; 117 } 118 119 /* Nesting count went down to 0. */ 120 _handler_installed = 0; 121 122 if (_oldmasked) { 123 sigset_t sigs; 124 sigprocmask(0, NULL, &sigs); 125 sigaddset(&sigs, SIGINT); 126 sigprocmask(SIG_SETMASK, &sigs, NULL); 127 } 128 129 sigaction(SIGINT, &_oldhandler, NULL); 130 } 131 132 static void _block_signals(uint32_t flags __attribute((unused))) 133 { 134 sigset_t set; 135 136 if (_signals_blocked) 137 return; 138 139 if (sigfillset(&set)) { 140 log_sys_error("sigfillset", "_block_signals"); 141 return; 142 } 143 144 if (sigprocmask(SIG_SETMASK, &set, &_oldset)) { 145 log_sys_error("sigprocmask", "_block_signals"); 146 return; 147 } 148 149 _signals_blocked = 1; 150 151 return; 152 } 153 154 static void _unblock_signals(void) 155 { 156 /* Don't unblock signals while any locks are held */ 157 if (!_signals_blocked || _vg_lock_count) 158 return; 159 160 if (sigprocmask(SIG_SETMASK, &_oldset, NULL)) { 161 log_sys_error("sigprocmask", "_block_signals"); 162 return; 163 } 164 165 _signals_blocked = 0; 166 167 return; 168 } 169 170 static void _lock_memory(lv_operation_t lv_op) 171 { 172 if (!(_locking.flags & LCK_PRE_MEMLOCK)) 173 return; 174 175 if (lv_op == LV_SUSPEND) 176 memlock_inc(); 177 } 178 179 static void _unlock_memory(lv_operation_t lv_op) 180 { 181 if (!(_locking.flags & LCK_PRE_MEMLOCK)) 182 return; 183 184 if (lv_op == LV_RESUME) 185 memlock_dec(); 186 } 187 188 void reset_locking(void) 189 { 190 int was_locked = _vg_lock_count; 191 192 _vg_lock_count = 0; 193 _vg_write_lock_held = 0; 194 195 _locking.reset_locking(); 196 197 if (was_locked) 198 _unblock_signals(); 199 } 200 201 static void _update_vg_lock_count(const char *resource, uint32_t flags) 202 { 203 /* Ignore locks not associated with updating VG metadata */ 204 if ((flags & LCK_SCOPE_MASK) != LCK_VG || 205 (flags & LCK_CACHE) || 206 !strcmp(resource, VG_GLOBAL)) 207 return; 208 209 if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK) 210 _vg_lock_count--; 211 else 212 _vg_lock_count++; 213 214 /* We don't bother to reset this until all VG locks are dropped */ 215 if ((flags & LCK_TYPE_MASK) == LCK_WRITE) 216 _vg_write_lock_held = 1; 217 else if (!_vg_lock_count) 218 _vg_write_lock_held = 0; 219 } 220 221 /* 222 * Select a locking type 223 * type: locking type; if < 0, then read config tree value 224 */ 225 int init_locking(int type, struct cmd_context *cmd) 226 { 227 if (type < 0) 228 type = find_config_tree_int(cmd, "global/locking_type", 1); 229 230 _blocking_supported = find_config_tree_int(cmd, 231 "global/wait_for_locks", DEFAULT_WAIT_FOR_LOCKS); 232 233 switch (type) { 234 case 0: 235 init_no_locking(&_locking, cmd); 236 log_warn("WARNING: Locking disabled. Be careful! " 237 "This could corrupt your metadata."); 238 return 1; 239 240 case 1: 241 log_very_verbose("%sFile-based locking selected.", 242 _blocking_supported ? "" : "Non-blocking "); 243 244 if (!init_file_locking(&_locking, cmd)) 245 break; 246 return 1; 247 248 #ifdef HAVE_LIBDL 249 case 2: 250 if (!is_static()) { 251 log_very_verbose("External locking selected."); 252 if (init_external_locking(&_locking, cmd)) 253 return 1; 254 } 255 if (!find_config_tree_int(cmd, "locking/fallback_to_clustered_locking", 256 find_config_tree_int(cmd, "global/fallback_to_clustered_locking", 257 DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING))) 258 break; 259 #endif 260 261 #ifdef CLUSTER_LOCKING_INTERNAL 262 log_very_verbose("Falling back to internal clustered locking."); 263 /* Fall through */ 264 265 case 3: 266 log_very_verbose("Cluster locking selected."); 267 if (!init_cluster_locking(&_locking, cmd)) 268 break; 269 return 1; 270 #endif 271 272 case 4: 273 log_verbose("Read-only locking selected. " 274 "Only read operations permitted."); 275 if (!init_readonly_locking(&_locking, cmd)) 276 break; 277 return 1; 278 279 default: 280 log_error("Unknown locking type requested."); 281 return 0; 282 } 283 284 if ((type == 2 || type == 3) && 285 find_config_tree_int(cmd, "locking/fallback_to_local_locking", 286 find_config_tree_int(cmd, "global/fallback_to_local_locking", 287 DEFAULT_FALLBACK_TO_LOCAL_LOCKING))) { 288 log_warn("WARNING: Falling back to local file-based locking."); 289 log_warn("Volume Groups with the clustered attribute will " 290 "be inaccessible."); 291 if (init_file_locking(&_locking, cmd)) 292 return 1; 293 } 294 295 if (!ignorelockingfailure()) 296 return 0; 297 298 log_verbose("Locking disabled - only read operations permitted."); 299 init_readonly_locking(&_locking, cmd); 300 301 return 1; 302 } 303 304 void fin_locking(void) 305 { 306 _locking.fin_locking(); 307 } 308 309 /* 310 * Does the LVM1 driver know of this VG name? 311 */ 312 int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname) 313 { 314 struct stat info; 315 char path[PATH_MAX]; 316 317 /* We'll allow operations on orphans */ 318 if (is_orphan_vg(vgname)) 319 return 1; 320 321 /* LVM1 is only present in 2.4 kernels. */ 322 if (strncmp(cmd->kernel_vsn, "2.4.", 4)) 323 return 1; 324 325 if (dm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir, 326 vgname) < 0) { 327 log_error("LVM1 proc VG pathname too long for %s", vgname); 328 return 0; 329 } 330 331 if (stat(path, &info) == 0) { 332 log_error("%s exists: Is the original LVM driver using " 333 "this volume group?", path); 334 return 0; 335 } else if (errno != ENOENT && errno != ENOTDIR) { 336 log_sys_error("stat", path); 337 return 0; 338 } 339 340 return 1; 341 } 342 343 /* 344 * VG locking is by VG name. 345 * FIXME This should become VG uuid. 346 */ 347 static int _lock_vol(struct cmd_context *cmd, const char *resource, 348 uint32_t flags, lv_operation_t lv_op) 349 { 350 int ret = 0; 351 352 _block_signals(flags); 353 _lock_memory(lv_op); 354 355 assert(resource); 356 357 if (!*resource) { 358 log_error("Internal error: Use of P_orphans is deprecated."); 359 return 0; 360 } 361 362 if (*resource == '#' && (flags & LCK_CACHE)) { 363 log_error("Internal error: P_%s referenced", resource); 364 return 0; 365 } 366 367 if ((ret = _locking.lock_resource(cmd, resource, flags))) { 368 if ((flags & LCK_SCOPE_MASK) == LCK_VG && 369 !(flags & LCK_CACHE)) { 370 if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK) 371 lvmcache_unlock_vgname(resource); 372 else 373 lvmcache_lock_vgname(resource, (flags & LCK_TYPE_MASK) 374 == LCK_READ); 375 } 376 377 _update_vg_lock_count(resource, flags); 378 } 379 380 _unlock_memory(lv_op); 381 _unblock_signals(); 382 383 return ret; 384 } 385 386 int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags) 387 { 388 char resource[258] __attribute((aligned(8))); 389 lv_operation_t lv_op; 390 391 switch (flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) { 392 case LCK_LV_SUSPEND: 393 lv_op = LV_SUSPEND; 394 break; 395 case LCK_LV_RESUME: 396 lv_op = LV_RESUME; 397 break; 398 default: lv_op = LV_NOOP; 399 } 400 401 402 if (flags == LCK_NONE) { 403 log_debug("Internal error: %s: LCK_NONE lock requested", vol); 404 return 1; 405 } 406 407 switch (flags & LCK_SCOPE_MASK) { 408 case LCK_VG: 409 /* 410 * Automatically set LCK_NONBLOCK if one or more VGs locked. 411 * This will enforce correctness and prevent deadlocks rather 412 * than relying on the caller to set the flag properly. 413 */ 414 if (!_blocking_supported || vgs_locked()) 415 flags |= LCK_NONBLOCK; 416 417 if (vol[0] != '#' && 418 ((flags & LCK_TYPE_MASK) != LCK_UNLOCK) && 419 (!(flags & LCK_CACHE)) && 420 !lvmcache_verify_lock_order(vol)) 421 return 0; 422 423 /* Lock VG to change on-disk metadata. */ 424 /* If LVM1 driver knows about the VG, it can't be accessed. */ 425 if (!check_lvm1_vg_inactive(cmd, vol)) 426 return 0; 427 break; 428 case LCK_LV: 429 /* All LV locks are non-blocking. */ 430 flags |= LCK_NONBLOCK; 431 break; 432 default: 433 log_error("Unrecognised lock scope: %d", 434 flags & LCK_SCOPE_MASK); 435 return 0; 436 } 437 438 strncpy(resource, vol, sizeof(resource)); 439 440 if (!_lock_vol(cmd, resource, flags, lv_op)) 441 return 0; 442 443 /* 444 * If a real lock was acquired (i.e. not LCK_CACHE), 445 * perform an immediate unlock unless LCK_HOLD was requested. 446 */ 447 if (!(flags & LCK_CACHE) && !(flags & LCK_HOLD) && 448 ((flags & LCK_TYPE_MASK) != LCK_UNLOCK)) { 449 if (!_lock_vol(cmd, resource, 450 (flags & ~LCK_TYPE_MASK) | LCK_UNLOCK, lv_op)) 451 return 0; 452 } 453 454 return 1; 455 } 456 457 /* Unlock list of LVs */ 458 int resume_lvs(struct cmd_context *cmd, struct dm_list *lvs) 459 { 460 struct lv_list *lvl; 461 462 dm_list_iterate_items(lvl, lvs) 463 resume_lv(cmd, lvl->lv); 464 465 return 1; 466 } 467 468 /* Lock a list of LVs */ 469 int suspend_lvs(struct cmd_context *cmd, struct dm_list *lvs) 470 { 471 struct dm_list *lvh; 472 struct lv_list *lvl; 473 474 dm_list_iterate_items(lvl, lvs) { 475 if (!suspend_lv(cmd, lvl->lv)) { 476 log_error("Failed to suspend %s", lvl->lv->name); 477 dm_list_uniterate(lvh, lvs, &lvl->list) { 478 lvl = dm_list_item(lvh, struct lv_list); 479 resume_lv(cmd, lvl->lv); 480 } 481 482 return 0; 483 } 484 } 485 486 return 1; 487 } 488 489 /* Lock a list of LVs */ 490 int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive) 491 { 492 struct dm_list *lvh; 493 struct lv_list *lvl; 494 495 dm_list_iterate_items(lvl, lvs) { 496 if (!exclusive) { 497 if (!activate_lv(cmd, lvl->lv)) { 498 log_error("Failed to activate %s", lvl->lv->name); 499 return 0; 500 } 501 } else if (!activate_lv_excl(cmd, lvl->lv)) { 502 log_error("Failed to activate %s", lvl->lv->name); 503 dm_list_uniterate(lvh, lvs, &lvl->list) { 504 lvl = dm_list_item(lvh, struct lv_list); 505 activate_lv(cmd, lvl->lv); 506 } 507 return 0; 508 } 509 } 510 511 return 1; 512 } 513 514 int vg_write_lock_held(void) 515 { 516 return _vg_write_lock_held; 517 } 518 519 int locking_is_clustered(void) 520 { 521 return (_locking.flags & LCK_CLUSTERED) ? 1 : 0; 522 } 523 524 int remote_lock_held(const char *vol) 525 { 526 int mode = LCK_NULL; 527 528 if (!locking_is_clustered()) 529 return 0; 530 531 if (!_locking.query_resource) 532 return -1; 533 534 /* 535 * If an error occured, expect that volume is active 536 */ 537 if (!_locking.query_resource(vol, &mode)) { 538 stack; 539 return 1; 540 } 541 542 return mode == LCK_NULL ? 0 : 1; 543 } 544