Home | History | Annotate | Line # | Download | only in clvmd
      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