1 1.1 haad /* $NetBSD: lvm-functions.c,v 1.1.1.3 2009/12/02 00:27:06 haad Exp $ */ 2 1.1 haad 3 1.1 haad /* 4 1.1 haad * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved. 5 1.1.1.3 haad * Copyright (C) 2004-2009 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 General Public License v.2. 12 1.1 haad * 13 1.1 haad * You should have received a copy of the GNU 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 #define _GNU_SOURCE 19 1.1 haad #define _FILE_OFFSET_BITS 64 20 1.1 haad 21 1.1 haad #include <configure.h> 22 1.1 haad #include <pthread.h> 23 1.1 haad #include <sys/types.h> 24 1.1 haad #include <sys/utsname.h> 25 1.1 haad #include <sys/ioctl.h> 26 1.1 haad #include <sys/socket.h> 27 1.1 haad #include <sys/stat.h> 28 1.1 haad #include <stdio.h> 29 1.1 haad #include <stdlib.h> 30 1.1 haad #include <stdint.h> 31 1.1 haad #include <fcntl.h> 32 1.1 haad #include <string.h> 33 1.1 haad #include <stddef.h> 34 1.1 haad #include <stdint.h> 35 1.1 haad #include <unistd.h> 36 1.1 haad #include <errno.h> 37 1.1 haad #include <syslog.h> 38 1.1 haad #include <assert.h> 39 1.1 haad #include <libdevmapper.h> 40 1.1 haad #include <libdlm.h> 41 1.1 haad 42 1.1 haad #include "lvm-types.h" 43 1.1 haad #include "clvm.h" 44 1.1 haad #include "clvmd-comms.h" 45 1.1 haad #include "clvmd.h" 46 1.1 haad #include "lvm-functions.h" 47 1.1 haad 48 1.1 haad /* LVM2 headers */ 49 1.1 haad #include "toolcontext.h" 50 1.1 haad #include "lvmcache.h" 51 1.1 haad #include "lvm-logging.h" 52 1.1 haad #include "lvm-globals.h" 53 1.1 haad #include "activate.h" 54 1.1 haad #include "locking.h" 55 1.1 haad #include "archiver.h" 56 1.1 haad #include "defaults.h" 57 1.1 haad 58 1.1 haad static struct cmd_context *cmd = NULL; 59 1.1 haad static struct dm_hash_table *lv_hash = NULL; 60 1.1 haad static pthread_mutex_t lv_hash_lock; 61 1.1 haad static pthread_mutex_t lvm_lock; 62 1.1 haad static char last_error[1024]; 63 1.1 haad static int suspended = 0; 64 1.1 haad 65 1.1 haad struct lv_info { 66 1.1 haad int lock_id; 67 1.1 haad int lock_mode; 68 1.1 haad }; 69 1.1 haad 70 1.1 haad static const char *decode_locking_cmd(unsigned char cmdl) 71 1.1 haad { 72 1.1 haad static char buf[128]; 73 1.1 haad const char *type; 74 1.1 haad const char *scope; 75 1.1 haad const char *command; 76 1.1 haad 77 1.1 haad switch (cmdl & LCK_TYPE_MASK) { 78 1.1 haad case LCK_NULL: 79 1.1 haad type = "NULL"; 80 1.1 haad break; 81 1.1 haad case LCK_READ: 82 1.1 haad type = "READ"; 83 1.1 haad break; 84 1.1 haad case LCK_PREAD: 85 1.1 haad type = "PREAD"; 86 1.1 haad break; 87 1.1 haad case LCK_WRITE: 88 1.1 haad type = "WRITE"; 89 1.1 haad break; 90 1.1 haad case LCK_EXCL: 91 1.1 haad type = "EXCL"; 92 1.1 haad break; 93 1.1 haad case LCK_UNLOCK: 94 1.1 haad type = "UNLOCK"; 95 1.1 haad break; 96 1.1 haad default: 97 1.1 haad type = "unknown"; 98 1.1 haad break; 99 1.1 haad } 100 1.1 haad 101 1.1 haad switch (cmdl & LCK_SCOPE_MASK) { 102 1.1 haad case LCK_VG: 103 1.1 haad scope = "VG"; 104 1.1 haad break; 105 1.1 haad case LCK_LV: 106 1.1 haad scope = "LV"; 107 1.1 haad break; 108 1.1 haad default: 109 1.1 haad scope = "unknown"; 110 1.1 haad break; 111 1.1 haad } 112 1.1 haad 113 1.1 haad switch (cmdl & LCK_MASK) { 114 1.1 haad case LCK_LV_EXCLUSIVE & LCK_MASK: 115 1.1 haad command = "LCK_LV_EXCLUSIVE"; 116 1.1 haad break; 117 1.1 haad case LCK_LV_SUSPEND & LCK_MASK: 118 1.1 haad command = "LCK_LV_SUSPEND"; 119 1.1 haad break; 120 1.1 haad case LCK_LV_RESUME & LCK_MASK: 121 1.1 haad command = "LCK_LV_RESUME"; 122 1.1 haad break; 123 1.1 haad case LCK_LV_ACTIVATE & LCK_MASK: 124 1.1 haad command = "LCK_LV_ACTIVATE"; 125 1.1 haad break; 126 1.1 haad case LCK_LV_DEACTIVATE & LCK_MASK: 127 1.1 haad command = "LCK_LV_DEACTIVATE"; 128 1.1 haad break; 129 1.1 haad default: 130 1.1 haad command = "unknown"; 131 1.1 haad break; 132 1.1 haad } 133 1.1 haad 134 1.1 haad sprintf(buf, "0x%x %s (%s|%s%s%s%s%s%s)", cmdl, command, type, scope, 135 1.1 haad cmdl & LCK_NONBLOCK ? "|NONBLOCK" : "", 136 1.1 haad cmdl & LCK_HOLD ? "|HOLD" : "", 137 1.1 haad cmdl & LCK_LOCAL ? "|LOCAL" : "", 138 1.1 haad cmdl & LCK_CLUSTER_VG ? "|CLUSTER_VG" : "", 139 1.1 haad cmdl & LCK_CACHE ? "|CACHE" : ""); 140 1.1 haad 141 1.1 haad return buf; 142 1.1 haad } 143 1.1 haad 144 1.1 haad static const char *decode_flags(unsigned char flags) 145 1.1 haad { 146 1.1 haad static char buf[128]; 147 1.1 haad 148 1.1.1.3 haad sprintf(buf, "0x%x (%s%s%s%s)", flags, 149 1.1.1.3 haad flags & LCK_PARTIAL_MODE ? "PARTIAL_MODE " : "", 150 1.1 haad flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC " : "", 151 1.1.1.3 haad flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR " : "", 152 1.1.1.3 haad flags & LCK_CONVERT ? "CONVERT " : ""); 153 1.1 haad 154 1.1 haad return buf; 155 1.1 haad } 156 1.1 haad 157 1.1 haad char *get_last_lvm_error() 158 1.1 haad { 159 1.1 haad return last_error; 160 1.1 haad } 161 1.1 haad 162 1.1.1.3 haad /* 163 1.1.1.3 haad * Hash lock info helpers 164 1.1.1.3 haad */ 165 1.1.1.3 haad static struct lv_info *lookup_info(const char *resource) 166 1.1 haad { 167 1.1 haad struct lv_info *lvi; 168 1.1 haad 169 1.1 haad pthread_mutex_lock(&lv_hash_lock); 170 1.1 haad lvi = dm_hash_lookup(lv_hash, resource); 171 1.1 haad pthread_mutex_unlock(&lv_hash_lock); 172 1.1.1.3 haad 173 1.1.1.3 haad return lvi; 174 1.1.1.3 haad } 175 1.1.1.3 haad 176 1.1.1.3 haad static void insert_info(const char *resource, struct lv_info *lvi) 177 1.1.1.3 haad { 178 1.1.1.3 haad pthread_mutex_lock(&lv_hash_lock); 179 1.1.1.3 haad dm_hash_insert(lv_hash, resource, lvi); 180 1.1.1.3 haad pthread_mutex_unlock(&lv_hash_lock); 181 1.1.1.3 haad } 182 1.1.1.3 haad 183 1.1.1.3 haad static void remove_info(const char *resource) 184 1.1.1.3 haad { 185 1.1.1.3 haad pthread_mutex_lock(&lv_hash_lock); 186 1.1.1.3 haad dm_hash_remove(lv_hash, resource); 187 1.1.1.3 haad pthread_mutex_unlock(&lv_hash_lock); 188 1.1.1.3 haad } 189 1.1.1.3 haad 190 1.1.1.3 haad /* 191 1.1.1.3 haad * Return the mode a lock is currently held at (or -1 if not held) 192 1.1.1.3 haad */ 193 1.1.1.3 haad static int get_current_lock(char *resource) 194 1.1.1.3 haad { 195 1.1.1.3 haad struct lv_info *lvi; 196 1.1.1.3 haad 197 1.1.1.3 haad if ((lvi = lookup_info(resource))) 198 1.1 haad return lvi->lock_mode; 199 1.1.1.3 haad 200 1.1.1.3 haad return -1; 201 1.1.1.3 haad } 202 1.1.1.3 haad 203 1.1.1.3 haad 204 1.1.1.3 haad void init_lvhash() 205 1.1.1.3 haad { 206 1.1.1.3 haad /* Create hash table for keeping LV locks & status */ 207 1.1.1.3 haad lv_hash = dm_hash_create(100); 208 1.1.1.3 haad pthread_mutex_init(&lv_hash_lock, NULL); 209 1.1.1.3 haad pthread_mutex_init(&lvm_lock, NULL); 210 1.1 haad } 211 1.1 haad 212 1.1 haad /* Called at shutdown to tidy the lockspace */ 213 1.1.1.3 haad void destroy_lvhash() 214 1.1 haad { 215 1.1 haad struct dm_hash_node *v; 216 1.1.1.3 haad struct lv_info *lvi; 217 1.1.1.3 haad char *resource; 218 1.1.1.3 haad int status; 219 1.1 haad 220 1.1 haad pthread_mutex_lock(&lv_hash_lock); 221 1.1.1.3 haad 222 1.1 haad dm_hash_iterate(v, lv_hash) { 223 1.1.1.3 haad lvi = dm_hash_get_data(lv_hash, v); 224 1.1.1.3 haad resource = dm_hash_get_key(lv_hash, v); 225 1.1 haad 226 1.1.1.3 haad if ((status = sync_unlock(resource, lvi->lock_id))) 227 1.1.1.3 haad DEBUGLOG("unlock_all. unlock failed(%d): %s\n", 228 1.1.1.3 haad status, strerror(errno)); 229 1.1.1.3 haad free(lvi); 230 1.1 haad } 231 1.1.1.3 haad 232 1.1.1.3 haad dm_hash_destroy(lv_hash); 233 1.1.1.3 haad lv_hash = NULL; 234 1.1.1.3 haad 235 1.1 haad pthread_mutex_unlock(&lv_hash_lock); 236 1.1 haad } 237 1.1 haad 238 1.1 haad /* Gets a real lock and keeps the info in the hash table */ 239 1.1 haad int hold_lock(char *resource, int mode, int flags) 240 1.1 haad { 241 1.1 haad int status; 242 1.1 haad int saved_errno; 243 1.1 haad struct lv_info *lvi; 244 1.1 haad 245 1.1.1.3 haad /* Mask off invalid options */ 246 1.1.1.3 haad flags &= LKF_NOQUEUE | LKF_CONVERT; 247 1.1 haad 248 1.1.1.3 haad lvi = lookup_info(resource); 249 1.1.1.3 haad 250 1.1.1.3 haad /* Only allow explicit conversions */ 251 1.1.1.3 haad if (lvi && !(flags & LKF_CONVERT)) { 252 1.1.1.3 haad errno = EBUSY; 253 1.1.1.3 haad return -1; 254 1.1.1.3 haad } 255 1.1 haad if (lvi) { 256 1.1 haad /* Already exists - convert it */ 257 1.1 haad status = 258 1.1.1.3 haad sync_lock(resource, mode, flags, &lvi->lock_id); 259 1.1 haad saved_errno = errno; 260 1.1 haad if (!status) 261 1.1 haad lvi->lock_mode = mode; 262 1.1 haad 263 1.1 haad if (status) { 264 1.1 haad DEBUGLOG("hold_lock. convert to %d failed: %s\n", mode, 265 1.1 haad strerror(errno)); 266 1.1 haad } 267 1.1 haad errno = saved_errno; 268 1.1 haad } else { 269 1.1 haad lvi = malloc(sizeof(struct lv_info)); 270 1.1 haad if (!lvi) 271 1.1 haad return -1; 272 1.1 haad 273 1.1 haad lvi->lock_mode = mode; 274 1.1 haad status = sync_lock(resource, mode, flags, &lvi->lock_id); 275 1.1 haad saved_errno = errno; 276 1.1 haad if (status) { 277 1.1 haad free(lvi); 278 1.1 haad DEBUGLOG("hold_lock. lock at %d failed: %s\n", mode, 279 1.1 haad strerror(errno)); 280 1.1.1.3 haad } else 281 1.1.1.3 haad insert_info(resource, lvi); 282 1.1.1.3 haad 283 1.1 haad errno = saved_errno; 284 1.1 haad } 285 1.1 haad return status; 286 1.1 haad } 287 1.1 haad 288 1.1 haad /* Unlock and remove it from the hash table */ 289 1.1 haad int hold_unlock(char *resource) 290 1.1 haad { 291 1.1 haad struct lv_info *lvi; 292 1.1 haad int status; 293 1.1 haad int saved_errno; 294 1.1 haad 295 1.1.1.3 haad if (!(lvi = lookup_info(resource))) { 296 1.1 haad DEBUGLOG("hold_unlock, lock not already held\n"); 297 1.1 haad return 0; 298 1.1 haad } 299 1.1 haad 300 1.1 haad status = sync_unlock(resource, lvi->lock_id); 301 1.1 haad saved_errno = errno; 302 1.1 haad if (!status) { 303 1.1.1.3 haad remove_info(resource); 304 1.1 haad free(lvi); 305 1.1 haad } else { 306 1.1 haad DEBUGLOG("hold_unlock. unlock failed(%d): %s\n", status, 307 1.1 haad strerror(errno)); 308 1.1 haad } 309 1.1 haad 310 1.1 haad errno = saved_errno; 311 1.1 haad return status; 312 1.1 haad } 313 1.1 haad 314 1.1 haad /* Watch the return codes here. 315 1.1 haad liblvm API functions return 1(true) for success, 0(false) for failure and don't set errno. 316 1.1 haad libdlm API functions return 0 for success, -1 for failure and do set errno. 317 1.1 haad These functions here return 0 for success or >0 for failure (where the retcode is errno) 318 1.1 haad */ 319 1.1 haad 320 1.1 haad /* Activate LV exclusive or non-exclusive */ 321 1.1 haad static int do_activate_lv(char *resource, unsigned char lock_flags, int mode) 322 1.1 haad { 323 1.1 haad int oldmode; 324 1.1 haad int status; 325 1.1 haad int activate_lv; 326 1.1 haad int exclusive = 0; 327 1.1 haad struct lvinfo lvi; 328 1.1 haad 329 1.1 haad /* Is it already open ? */ 330 1.1 haad oldmode = get_current_lock(resource); 331 1.1 haad if (oldmode == mode) { 332 1.1 haad return 0; /* Nothing to do */ 333 1.1 haad } 334 1.1 haad 335 1.1 haad /* Does the config file want us to activate this LV ? */ 336 1.1 haad if (!lv_activation_filter(cmd, resource, &activate_lv)) 337 1.1 haad return EIO; 338 1.1 haad 339 1.1 haad if (!activate_lv) 340 1.1 haad return 0; /* Success, we did nothing! */ 341 1.1 haad 342 1.1 haad /* Do we need to activate exclusively? */ 343 1.1 haad if ((activate_lv == 2) || (mode == LKM_EXMODE)) { 344 1.1 haad exclusive = 1; 345 1.1 haad mode = LKM_EXMODE; 346 1.1 haad } 347 1.1 haad 348 1.1 haad /* Try to get the lock if it's a clustered volume group */ 349 1.1 haad if (lock_flags & LCK_CLUSTER_VG) { 350 1.1.1.3 haad status = hold_lock(resource, mode, LKF_NOQUEUE | (lock_flags & LCK_CONVERT?LKF_CONVERT:0)); 351 1.1 haad if (status) { 352 1.1 haad /* Return an LVM-sensible error for this. 353 1.1 haad * Forcing EIO makes the upper level return this text 354 1.1 haad * rather than the strerror text for EAGAIN. 355 1.1 haad */ 356 1.1 haad if (errno == EAGAIN) { 357 1.1 haad sprintf(last_error, "Volume is busy on another node"); 358 1.1 haad errno = EIO; 359 1.1 haad } 360 1.1 haad return errno; 361 1.1 haad } 362 1.1 haad } 363 1.1 haad 364 1.1 haad /* If it's suspended then resume it */ 365 1.1 haad if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0)) 366 1.1 haad return EIO; 367 1.1 haad 368 1.1 haad if (lvi.suspended) 369 1.1 haad if (!lv_resume(cmd, resource)) 370 1.1 haad return EIO; 371 1.1 haad 372 1.1 haad /* Now activate it */ 373 1.1 haad if (!lv_activate(cmd, resource, exclusive)) 374 1.1 haad return EIO; 375 1.1 haad 376 1.1 haad return 0; 377 1.1 haad } 378 1.1 haad 379 1.1 haad /* Resume the LV if it was active */ 380 1.1 haad static int do_resume_lv(char *resource) 381 1.1 haad { 382 1.1 haad int oldmode; 383 1.1 haad 384 1.1 haad /* Is it open ? */ 385 1.1 haad oldmode = get_current_lock(resource); 386 1.1 haad if (oldmode == -1) { 387 1.1 haad DEBUGLOG("do_resume_lv, lock not already held\n"); 388 1.1 haad return 0; /* We don't need to do anything */ 389 1.1 haad } 390 1.1 haad 391 1.1 haad if (!lv_resume_if_active(cmd, resource)) 392 1.1 haad return EIO; 393 1.1 haad 394 1.1 haad return 0; 395 1.1 haad } 396 1.1 haad 397 1.1 haad /* Suspend the device if active */ 398 1.1 haad static int do_suspend_lv(char *resource) 399 1.1 haad { 400 1.1 haad int oldmode; 401 1.1 haad struct lvinfo lvi; 402 1.1 haad 403 1.1 haad /* Is it open ? */ 404 1.1 haad oldmode = get_current_lock(resource); 405 1.1 haad if (oldmode == -1) { 406 1.1 haad DEBUGLOG("do_suspend_lv, lock held at %d\n", oldmode); 407 1.1 haad return 0; /* Not active, so it's OK */ 408 1.1 haad } 409 1.1 haad 410 1.1 haad /* Only suspend it if it exists */ 411 1.1 haad if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0)) 412 1.1 haad return EIO; 413 1.1 haad 414 1.1 haad if (lvi.exists) { 415 1.1 haad if (!lv_suspend_if_active(cmd, resource)) { 416 1.1 haad return EIO; 417 1.1 haad } 418 1.1 haad } 419 1.1 haad return 0; 420 1.1 haad } 421 1.1 haad 422 1.1 haad static int do_deactivate_lv(char *resource, unsigned char lock_flags) 423 1.1 haad { 424 1.1 haad int oldmode; 425 1.1 haad int status; 426 1.1 haad 427 1.1 haad /* Is it open ? */ 428 1.1 haad oldmode = get_current_lock(resource); 429 1.1 haad if (oldmode == -1 && (lock_flags & LCK_CLUSTER_VG)) { 430 1.1 haad DEBUGLOG("do_deactivate_lock, lock not already held\n"); 431 1.1 haad return 0; /* We don't need to do anything */ 432 1.1 haad } 433 1.1 haad 434 1.1 haad if (!lv_deactivate(cmd, resource)) 435 1.1 haad return EIO; 436 1.1 haad 437 1.1 haad if (lock_flags & LCK_CLUSTER_VG) { 438 1.1 haad status = hold_unlock(resource); 439 1.1 haad if (status) 440 1.1 haad return errno; 441 1.1 haad } 442 1.1 haad 443 1.1 haad return 0; 444 1.1 haad } 445 1.1 haad 446 1.1.1.3 haad const char *do_lock_query(char *resource) 447 1.1.1.3 haad { 448 1.1.1.3 haad int mode; 449 1.1.1.3 haad const char *type = NULL; 450 1.1.1.3 haad 451 1.1.1.3 haad mode = get_current_lock(resource); 452 1.1.1.3 haad switch (mode) { 453 1.1.1.3 haad case LKM_NLMODE: type = "NL"; break; 454 1.1.1.3 haad case LKM_CRMODE: type = "CR"; break; 455 1.1.1.3 haad case LKM_CWMODE: type = "CW"; break; 456 1.1.1.3 haad case LKM_PRMODE: type = "PR"; break; 457 1.1.1.3 haad case LKM_PWMODE: type = "PW"; break; 458 1.1.1.3 haad case LKM_EXMODE: type = "EX"; break; 459 1.1.1.3 haad } 460 1.1.1.3 haad 461 1.1.1.3 haad DEBUGLOG("do_lock_query: resource '%s', mode %i (%s)\n", resource, mode, type ?: "?"); 462 1.1.1.3 haad 463 1.1.1.3 haad return type; 464 1.1.1.3 haad } 465 1.1.1.3 haad 466 1.1 haad /* This is the LOCK_LV part that happens on all nodes in the cluster - 467 1.1 haad it is responsible for the interaction with device-mapper and LVM */ 468 1.1 haad int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource) 469 1.1 haad { 470 1.1 haad int status = 0; 471 1.1 haad 472 1.1 haad DEBUGLOG("do_lock_lv: resource '%s', cmd = %s, flags = %s\n", 473 1.1 haad resource, decode_locking_cmd(command), decode_flags(lock_flags)); 474 1.1 haad 475 1.1 haad if (!cmd->config_valid || config_files_changed(cmd)) { 476 1.1 haad /* Reinitialise various settings inc. logging, filters */ 477 1.1 haad if (do_refresh_cache()) { 478 1.1 haad log_error("Updated config file invalid. Aborting."); 479 1.1 haad return EINVAL; 480 1.1 haad } 481 1.1 haad } 482 1.1 haad 483 1.1.1.3 haad pthread_mutex_lock(&lvm_lock); 484 1.1 haad if (lock_flags & LCK_MIRROR_NOSYNC_MODE) 485 1.1 haad init_mirror_in_sync(1); 486 1.1 haad 487 1.1 haad if (!(lock_flags & LCK_DMEVENTD_MONITOR_MODE)) 488 1.1 haad init_dmeventd_monitor(0); 489 1.1 haad 490 1.1.1.3 haad cmd->partial_activation = (lock_flags & LCK_PARTIAL_MODE) ? 1 : 0; 491 1.1.1.3 haad 492 1.1.1.3 haad switch (command & LCK_MASK) { 493 1.1 haad case LCK_LV_EXCLUSIVE: 494 1.1 haad status = do_activate_lv(resource, lock_flags, LKM_EXMODE); 495 1.1 haad break; 496 1.1 haad 497 1.1 haad case LCK_LV_SUSPEND: 498 1.1 haad status = do_suspend_lv(resource); 499 1.1 haad if (!status) 500 1.1 haad suspended++; 501 1.1 haad break; 502 1.1 haad 503 1.1 haad case LCK_UNLOCK: 504 1.1 haad case LCK_LV_RESUME: /* if active */ 505 1.1 haad status = do_resume_lv(resource); 506 1.1 haad if (!status) 507 1.1 haad suspended--; 508 1.1 haad break; 509 1.1 haad 510 1.1 haad case LCK_LV_ACTIVATE: 511 1.1 haad status = do_activate_lv(resource, lock_flags, LKM_CRMODE); 512 1.1 haad break; 513 1.1 haad 514 1.1 haad case LCK_LV_DEACTIVATE: 515 1.1 haad status = do_deactivate_lv(resource, lock_flags); 516 1.1 haad break; 517 1.1 haad 518 1.1 haad default: 519 1.1 haad DEBUGLOG("Invalid LV command 0x%x\n", command); 520 1.1 haad status = EINVAL; 521 1.1 haad break; 522 1.1 haad } 523 1.1 haad 524 1.1 haad if (lock_flags & LCK_MIRROR_NOSYNC_MODE) 525 1.1 haad init_mirror_in_sync(0); 526 1.1 haad 527 1.1 haad if (!(lock_flags & LCK_DMEVENTD_MONITOR_MODE)) 528 1.1 haad init_dmeventd_monitor(DEFAULT_DMEVENTD_MONITOR); 529 1.1 haad 530 1.1.1.3 haad cmd->partial_activation = 0; 531 1.1.1.3 haad 532 1.1 haad /* clean the pool for another command */ 533 1.1 haad dm_pool_empty(cmd->mem); 534 1.1 haad pthread_mutex_unlock(&lvm_lock); 535 1.1 haad 536 1.1 haad DEBUGLOG("Command return is %d\n", status); 537 1.1 haad return status; 538 1.1 haad } 539 1.1 haad 540 1.1 haad /* Functions to do on the local node only BEFORE the cluster-wide stuff above happens */ 541 1.1 haad int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource) 542 1.1 haad { 543 1.1 haad /* Nearly all the stuff happens cluster-wide. Apart from SUSPEND. Here we get the 544 1.1 haad lock out on this node (because we are the node modifying the metadata) 545 1.1 haad before suspending cluster-wide. 546 1.1 haad */ 547 1.1 haad if (command == LCK_LV_SUSPEND) { 548 1.1 haad DEBUGLOG("pre_lock_lv: resource '%s', cmd = %s, flags = %s\n", 549 1.1 haad resource, decode_locking_cmd(command), decode_flags(lock_flags)); 550 1.1 haad 551 1.1.1.3 haad if (hold_lock(resource, LKM_PWMODE, LKF_NOQUEUE| (lock_flags & LCK_CONVERT?LKF_CONVERT:0))) 552 1.1 haad return errno; 553 1.1 haad } 554 1.1 haad return 0; 555 1.1 haad } 556 1.1 haad 557 1.1 haad /* Functions to do on the local node only AFTER the cluster-wide stuff above happens */ 558 1.1 haad int post_lock_lv(unsigned char command, unsigned char lock_flags, 559 1.1 haad char *resource) 560 1.1 haad { 561 1.1 haad int status; 562 1.1 haad 563 1.1 haad /* Opposite of above, done on resume after a metadata update */ 564 1.1 haad if (command == LCK_LV_RESUME) { 565 1.1 haad int oldmode; 566 1.1 haad 567 1.1 haad DEBUGLOG 568 1.1 haad ("post_lock_lv: resource '%s', cmd = %s, flags = %s\n", 569 1.1 haad resource, decode_locking_cmd(command), decode_flags(lock_flags)); 570 1.1 haad 571 1.1 haad /* If the lock state is PW then restore it to what it was */ 572 1.1 haad oldmode = get_current_lock(resource); 573 1.1 haad if (oldmode == LKM_PWMODE) { 574 1.1 haad struct lvinfo lvi; 575 1.1 haad 576 1.1 haad pthread_mutex_lock(&lvm_lock); 577 1.1 haad status = lv_info_by_lvid(cmd, resource, &lvi, 0, 0); 578 1.1 haad pthread_mutex_unlock(&lvm_lock); 579 1.1 haad if (!status) 580 1.1 haad return EIO; 581 1.1 haad 582 1.1 haad if (lvi.exists) { 583 1.1.1.3 haad if (hold_lock(resource, LKM_CRMODE, lock_flags & LCK_CONVERT?LKF_CONVERT:0)) 584 1.1 haad return errno; 585 1.1 haad } else { 586 1.1 haad if (hold_unlock(resource)) 587 1.1 haad return errno; 588 1.1 haad } 589 1.1 haad } 590 1.1 haad } 591 1.1 haad return 0; 592 1.1 haad } 593 1.1 haad 594 1.1 haad /* Check if a VG is in use by LVM1 so we don't stomp on it */ 595 1.1 haad int do_check_lvm1(const char *vgname) 596 1.1 haad { 597 1.1 haad int status; 598 1.1 haad 599 1.1 haad status = check_lvm1_vg_inactive(cmd, vgname); 600 1.1 haad 601 1.1 haad return status == 1 ? 0 : EBUSY; 602 1.1 haad } 603 1.1 haad 604 1.1 haad int do_refresh_cache() 605 1.1 haad { 606 1.1 haad DEBUGLOG("Refreshing context\n"); 607 1.1 haad log_notice("Refreshing context"); 608 1.1 haad 609 1.1.1.3 haad pthread_mutex_lock(&lvm_lock); 610 1.1.1.3 haad 611 1.1.1.3 haad if (!refresh_toolcontext(cmd)) { 612 1.1.1.3 haad pthread_mutex_unlock(&lvm_lock); 613 1.1.1.3 haad return -1; 614 1.1.1.3 haad } 615 1.1.1.3 haad 616 1.1 haad init_full_scan_done(0); 617 1.1 haad lvmcache_label_scan(cmd, 2); 618 1.1.1.3 haad dm_pool_empty(cmd->mem); 619 1.1.1.3 haad 620 1.1.1.3 haad pthread_mutex_unlock(&lvm_lock); 621 1.1 haad 622 1.1.1.3 haad return 0; 623 1.1 haad } 624 1.1 haad 625 1.1 haad 626 1.1 haad /* Only called at gulm startup. Drop any leftover VG or P_orphan locks 627 1.1 haad that might be hanging around if we died for any reason 628 1.1 haad */ 629 1.1 haad static void drop_vg_locks() 630 1.1 haad { 631 1.1 haad char vg[128]; 632 1.1 haad char line[255]; 633 1.1 haad FILE *vgs = 634 1.1 haad popen 635 1.1 haad ("lvm pvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_name", "r"); 636 1.1 haad 637 1.1 haad sync_unlock("P_" VG_ORPHANS, LCK_EXCL); 638 1.1 haad sync_unlock("P_" VG_GLOBAL, LCK_EXCL); 639 1.1 haad 640 1.1 haad if (!vgs) 641 1.1 haad return; 642 1.1 haad 643 1.1 haad while (fgets(line, sizeof(line), vgs)) { 644 1.1 haad char *vgend; 645 1.1 haad char *vgstart; 646 1.1 haad 647 1.1 haad if (line[strlen(line)-1] == '\n') 648 1.1 haad line[strlen(line)-1] = '\0'; 649 1.1 haad 650 1.1 haad vgstart = line + strspn(line, " "); 651 1.1 haad vgend = vgstart + strcspn(vgstart, " "); 652 1.1 haad *vgend = '\0'; 653 1.1 haad 654 1.1 haad if (strncmp(vgstart, "WARNING:", 8) == 0) 655 1.1 haad continue; 656 1.1 haad 657 1.1 haad sprintf(vg, "V_%s", vgstart); 658 1.1 haad sync_unlock(vg, LCK_EXCL); 659 1.1 haad 660 1.1 haad } 661 1.1 haad if (fclose(vgs)) 662 1.1 haad DEBUGLOG("vgs fclose failed: %s\n", strerror(errno)); 663 1.1 haad } 664 1.1 haad 665 1.1 haad /* 666 1.1 haad * Drop lvmcache metadata 667 1.1 haad */ 668 1.1 haad void drop_metadata(const char *vgname) 669 1.1 haad { 670 1.1 haad DEBUGLOG("Dropping metadata for VG %s\n", vgname); 671 1.1 haad pthread_mutex_lock(&lvm_lock); 672 1.1 haad lvmcache_drop_metadata(vgname); 673 1.1 haad pthread_mutex_unlock(&lvm_lock); 674 1.1 haad } 675 1.1 haad 676 1.1 haad /* 677 1.1 haad * Ideally, clvmd should be started before any LVs are active 678 1.1 haad * but this may not be the case... 679 1.1 haad * I suppose this also comes in handy if clvmd crashes, not that it would! 680 1.1 haad */ 681 1.1 haad static void *get_initial_state() 682 1.1 haad { 683 1.1 haad char lv[64], vg[64], flags[25], vg_flags[25]; 684 1.1 haad char uuid[65]; 685 1.1 haad char line[255]; 686 1.1 haad FILE *lvs = 687 1.1 haad popen 688 1.1 haad ("lvm lvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr", 689 1.1 haad "r"); 690 1.1 haad 691 1.1 haad if (!lvs) 692 1.1 haad return NULL; 693 1.1 haad 694 1.1 haad while (fgets(line, sizeof(line), lvs)) { 695 1.1 haad if (sscanf(line, "%s %s %s %s\n", vg, lv, flags, vg_flags) == 4) { 696 1.1 haad 697 1.1 haad /* States: s:suspended a:active S:dropped snapshot I:invalid snapshot */ 698 1.1 haad if (strlen(vg) == 38 && /* is is a valid UUID ? */ 699 1.1 haad (flags[4] == 'a' || flags[4] == 's') && /* is it active or suspended? */ 700 1.1 haad vg_flags[5] == 'c') { /* is it clustered ? */ 701 1.1 haad /* Convert hyphen-separated UUIDs into one */ 702 1.1 haad memcpy(&uuid[0], &vg[0], 6); 703 1.1 haad memcpy(&uuid[6], &vg[7], 4); 704 1.1 haad memcpy(&uuid[10], &vg[12], 4); 705 1.1 haad memcpy(&uuid[14], &vg[17], 4); 706 1.1 haad memcpy(&uuid[18], &vg[22], 4); 707 1.1 haad memcpy(&uuid[22], &vg[27], 4); 708 1.1 haad memcpy(&uuid[26], &vg[32], 6); 709 1.1 haad memcpy(&uuid[32], &lv[0], 6); 710 1.1 haad memcpy(&uuid[38], &lv[7], 4); 711 1.1 haad memcpy(&uuid[42], &lv[12], 4); 712 1.1 haad memcpy(&uuid[46], &lv[17], 4); 713 1.1 haad memcpy(&uuid[50], &lv[22], 4); 714 1.1 haad memcpy(&uuid[54], &lv[27], 4); 715 1.1 haad memcpy(&uuid[58], &lv[32], 6); 716 1.1 haad uuid[64] = '\0'; 717 1.1 haad 718 1.1 haad DEBUGLOG("getting initial lock for %s\n", uuid); 719 1.1 haad hold_lock(uuid, LKM_CRMODE, LKF_NOQUEUE); 720 1.1 haad } 721 1.1 haad } 722 1.1 haad } 723 1.1 haad if (fclose(lvs)) 724 1.1 haad DEBUGLOG("lvs fclose failed: %s\n", strerror(errno)); 725 1.1 haad return NULL; 726 1.1 haad } 727 1.1 haad 728 1.1.1.3 haad static void lvm2_log_fn(int level, const char *file, int line, int dm_errno, 729 1.1 haad const char *message) 730 1.1 haad { 731 1.1 haad 732 1.1 haad /* Send messages to the normal LVM2 logging system too, 733 1.1 haad so we get debug output when it's asked for. 734 1.1 haad We need to NULL the function ptr otherwise it will just call 735 1.1 haad back into here! */ 736 1.1 haad init_log_fn(NULL); 737 1.1.1.3 haad print_log(level, file, line, dm_errno, "%s", message); 738 1.1 haad init_log_fn(lvm2_log_fn); 739 1.1 haad 740 1.1 haad /* 741 1.1 haad * Ignore non-error messages, but store the latest one for returning 742 1.1 haad * to the user. 743 1.1 haad */ 744 1.1 haad if (level != _LOG_ERR && level != _LOG_FATAL) 745 1.1 haad return; 746 1.1 haad 747 1.1 haad strncpy(last_error, message, sizeof(last_error)); 748 1.1 haad last_error[sizeof(last_error)-1] = '\0'; 749 1.1 haad } 750 1.1 haad 751 1.1 haad /* This checks some basic cluster-LVM configuration stuff */ 752 1.1 haad static void check_config() 753 1.1 haad { 754 1.1 haad int locking_type; 755 1.1 haad 756 1.1 haad locking_type = find_config_tree_int(cmd, "global/locking_type", 1); 757 1.1 haad 758 1.1 haad if (locking_type == 3) /* compiled-in cluster support */ 759 1.1 haad return; 760 1.1 haad 761 1.1 haad if (locking_type == 2) { /* External library, check name */ 762 1.1 haad const char *libname; 763 1.1 haad 764 1.1 haad libname = find_config_tree_str(cmd, "global/locking_library", 765 1.1 haad ""); 766 1.1 haad if (strstr(libname, "liblvm2clusterlock.so")) 767 1.1 haad return; 768 1.1 haad 769 1.1 haad log_error("Incorrect LVM locking library specified in lvm.conf, cluster operations may not work."); 770 1.1 haad return; 771 1.1 haad } 772 1.1 haad log_error("locking_type not set correctly in lvm.conf, cluster operations will not work."); 773 1.1 haad } 774 1.1 haad 775 1.1 haad /* Backups up the LVM metadata if it's changed */ 776 1.1 haad void lvm_do_backup(const char *vgname) 777 1.1 haad { 778 1.1 haad struct volume_group * vg; 779 1.1 haad int consistent = 0; 780 1.1 haad 781 1.1 haad DEBUGLOG("Triggering backup of VG metadata for %s. suspended=%d\n", vgname, suspended); 782 1.1 haad 783 1.1.1.3 haad pthread_mutex_lock(&lvm_lock); 784 1.1.1.3 haad 785 1.1.1.3 haad vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, &consistent); 786 1.1.1.3 haad 787 1.1.1.3 haad if (vg && consistent) 788 1.1.1.3 haad check_current_backup(vg); 789 1.1.1.3 haad else 790 1.1 haad log_error("Error backing up metadata, can't find VG for group %s", vgname); 791 1.1.1.3 haad 792 1.1.1.3 haad vg_release(vg); 793 1.1.1.3 haad dm_pool_empty(cmd->mem); 794 1.1.1.3 haad 795 1.1.1.3 haad pthread_mutex_unlock(&lvm_lock); 796 1.1 haad } 797 1.1 haad 798 1.1 haad /* Called to initialise the LVM context of the daemon */ 799 1.1 haad int init_lvm(int using_gulm) 800 1.1 haad { 801 1.1.1.3 haad if (!(cmd = create_toolcontext(1, NULL))) { 802 1.1 haad log_error("Failed to allocate command context"); 803 1.1 haad return 0; 804 1.1 haad } 805 1.1 haad 806 1.1.1.3 haad if (stored_errno()) { 807 1.1.1.3 haad destroy_toolcontext(cmd); 808 1.1.1.3 haad return 0; 809 1.1.1.3 haad } 810 1.1.1.3 haad 811 1.1 haad /* Use LOG_DAEMON for syslog messages instead of LOG_USER */ 812 1.1 haad init_syslog(LOG_DAEMON); 813 1.1 haad openlog("clvmd", LOG_PID, LOG_DAEMON); 814 1.1.1.3 haad cmd->cmd_line = "clvmd"; 815 1.1 haad 816 1.1 haad /* Check lvm.conf is setup for cluster-LVM */ 817 1.1 haad check_config(); 818 1.1 haad 819 1.1 haad /* Remove any non-LV locks that may have been left around */ 820 1.1 haad if (using_gulm) 821 1.1 haad drop_vg_locks(); 822 1.1 haad 823 1.1 haad get_initial_state(); 824 1.1 haad 825 1.1 haad /* Trap log messages so we can pass them back to the user */ 826 1.1 haad init_log_fn(lvm2_log_fn); 827 1.1 haad 828 1.1 haad return 1; 829 1.1 haad } 830 1.1.1.3 haad 831 1.1.1.3 haad void destroy_lvm(void) 832 1.1.1.3 haad { 833 1.1.1.3 haad if (cmd) 834 1.1.1.3 haad destroy_toolcontext(cmd); 835 1.1.1.3 haad cmd = NULL; 836 1.1.1.3 haad } 837