2004-06-24 12:02:38 +04:00
/*
* Copyright ( C ) 2002 - 2004 Sistina Software , Inc . All rights reserved .
* Copyright ( C ) 2004 Red Hat , Inc . All rights reserved .
*
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
* of the GNU General Public License v .2 .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <pthread.h>
# include <sys/types.h>
# include <sys/utsname.h>
# include <sys/ioctl.h>
# include <sys/socket.h>
# include <sys/stat.h>
# include <stdio.h>
# include <stdlib.h>
# include <stdint.h>
# include <fcntl.h>
# include <string.h>
# include <stddef.h>
# include <stdint.h>
# include <unistd.h>
# include <errno.h>
# include <syslog.h>
# include <assert.h>
2005-11-09 12:24:10 +03:00
# include "libdevmapper.h"
# include "list.h"
# include "lvm-types.h"
2004-06-24 12:02:38 +04:00
# include "libdlm.h"
# include "clvm.h"
# include "clvmd-comms.h"
# include "clvmd.h"
# include "lvm-functions.h"
/* LVM2 headers */
# include "toolcontext.h"
# include "log.h"
# include "activate.h"
# include "locking.h"
2006-05-15 16:32:08 +04:00
# include "defaults.h"
2004-06-24 12:02:38 +04:00
static struct cmd_context * cmd = NULL ;
2005-11-09 12:24:10 +03:00
static struct dm_hash_table * lv_hash = NULL ;
2004-09-22 16:10:34 +04:00
static pthread_mutex_t lv_hash_lock ;
2007-04-24 19:13:13 +04:00
static pthread_mutex_t lvm_lock ;
2006-10-05 17:55:50 +04:00
static char last_error [ 1024 ] ;
2004-06-24 12:02:38 +04:00
struct lv_info {
int lock_id ;
int lock_mode ;
} ;
2006-10-05 17:55:50 +04:00
char * get_last_lvm_error ( )
{
return last_error ;
}
2004-06-24 12:02:38 +04:00
/* Return the mode a lock is currently held at (or -1 if not held) */
static int get_current_lock ( char * resource )
{
struct lv_info * lvi ;
2004-09-22 16:10:34 +04:00
pthread_mutex_lock ( & lv_hash_lock ) ;
2005-11-09 12:24:10 +03:00
lvi = dm_hash_lookup ( lv_hash , resource ) ;
2004-09-22 16:10:34 +04:00
pthread_mutex_unlock ( & lv_hash_lock ) ;
2004-06-24 12:02:38 +04:00
if ( lvi ) {
return lvi - > lock_mode ;
} else {
return - 1 ;
}
}
/* Called at shutdown to tidy the lockspace */
void unlock_all ( )
{
2005-11-09 12:24:10 +03:00
struct dm_hash_node * v ;
2004-09-22 16:10:34 +04:00
pthread_mutex_lock ( & lv_hash_lock ) ;
2005-11-09 12:24:10 +03:00
dm_hash_iterate ( v , lv_hash ) {
struct lv_info * lvi = dm_hash_get_data ( lv_hash , v ) ;
2004-06-24 12:02:38 +04:00
2005-11-09 12:24:10 +03:00
sync_unlock ( dm_hash_get_key ( lv_hash , v ) , lvi - > lock_id ) ;
2004-06-24 12:02:38 +04:00
}
2004-09-22 16:10:34 +04:00
pthread_mutex_unlock ( & lv_hash_lock ) ;
2004-06-24 12:02:38 +04:00
}
/* Gets a real lock and keeps the info in the hash table */
int hold_lock ( char * resource , int mode , int flags )
{
int status ;
int saved_errno ;
struct lv_info * lvi ;
flags & = LKF_NOQUEUE ; /* Only LKF_NOQUEUE is valid here */
2004-09-22 16:10:34 +04:00
pthread_mutex_lock ( & lv_hash_lock ) ;
2005-11-09 12:24:10 +03:00
lvi = dm_hash_lookup ( lv_hash , resource ) ;
2004-09-22 16:10:34 +04:00
pthread_mutex_unlock ( & lv_hash_lock ) ;
2004-06-24 12:02:38 +04:00
if ( lvi ) {
/* Already exists - convert it */
status =
sync_lock ( resource , mode , LKF_CONVERT | flags ,
& lvi - > lock_id ) ;
saved_errno = errno ;
if ( ! status )
lvi - > lock_mode = mode ;
if ( status ) {
DEBUGLOG ( " hold_lock. convert to %d failed: %s \n " , mode ,
strerror ( errno ) ) ;
}
errno = saved_errno ;
} else {
lvi = malloc ( sizeof ( struct lv_info ) ) ;
if ( ! lvi )
return - 1 ;
lvi - > lock_mode = mode ;
status = sync_lock ( resource , mode , flags , & lvi - > lock_id ) ;
saved_errno = errno ;
if ( status ) {
free ( lvi ) ;
DEBUGLOG ( " hold_lock. lock at %d failed: %s \n " , mode ,
strerror ( errno ) ) ;
} else {
2004-09-22 16:10:34 +04:00
pthread_mutex_lock ( & lv_hash_lock ) ;
2005-11-09 12:24:10 +03:00
dm_hash_insert ( lv_hash , resource , lvi ) ;
2004-09-22 16:10:34 +04:00
pthread_mutex_unlock ( & lv_hash_lock ) ;
2004-06-24 12:02:38 +04:00
}
errno = saved_errno ;
}
return status ;
}
/* Unlock and remove it from the hash table */
int hold_unlock ( char * resource )
{
struct lv_info * lvi ;
int status ;
int saved_errno ;
2004-09-22 16:10:34 +04:00
pthread_mutex_lock ( & lv_hash_lock ) ;
2005-11-09 12:24:10 +03:00
lvi = dm_hash_lookup ( lv_hash , resource ) ;
2004-09-22 16:10:34 +04:00
pthread_mutex_unlock ( & lv_hash_lock ) ;
2004-06-24 12:02:38 +04:00
if ( ! lvi ) {
DEBUGLOG ( " hold_unlock, lock not already held \n " ) ;
return 0 ;
}
status = sync_unlock ( resource , lvi - > lock_id ) ;
saved_errno = errno ;
if ( ! status ) {
2004-09-22 16:10:34 +04:00
pthread_mutex_lock ( & lv_hash_lock ) ;
2005-11-09 12:24:10 +03:00
dm_hash_remove ( lv_hash , resource ) ;
2004-09-22 16:10:34 +04:00
pthread_mutex_unlock ( & lv_hash_lock ) ;
2004-06-24 12:02:38 +04:00
free ( lvi ) ;
} else {
DEBUGLOG ( " hold_unlock. unlock failed(%d): %s \n " , status ,
strerror ( errno ) ) ;
}
errno = saved_errno ;
return status ;
}
/* Watch the return codes here.
liblvm API functions return 1 ( true ) for success , 0 ( false ) for failure and don ' t set errno .
libdlm API functions return 0 for success , - 1 for failure and do set errno .
These functions here return 0 for success or > 0 for failure ( where the retcode is errno )
*/
/* Activate LV exclusive or non-exclusive */
2005-08-16 12:25:09 +04:00
static int do_activate_lv ( char * resource , unsigned char lock_flags , int mode )
2004-06-24 12:02:38 +04:00
{
int oldmode ;
int status ;
int activate_lv ;
2005-08-15 03:18:28 +04:00
int exclusive = 0 ;
2004-06-24 12:02:38 +04:00
struct lvinfo lvi ;
/* Is it already open ? */
oldmode = get_current_lock ( resource ) ;
if ( oldmode = = mode ) {
return 0 ; /* Nothing to do */
}
/* Does the config file want us to activate this LV ? */
if ( ! lv_activation_filter ( cmd , resource , & activate_lv ) )
return EIO ;
if ( ! activate_lv )
return 0 ; /* Success, we did nothing! */
/* Do we need to activate exclusively? */
2005-08-15 03:18:28 +04:00
if ( ( activate_lv = = 2 ) | | ( mode = = LKM_EXMODE ) ) {
exclusive = 1 ;
2004-06-24 12:02:38 +04:00
mode = LKM_EXMODE ;
2005-08-15 03:18:28 +04:00
}
2004-06-24 12:02:38 +04:00
2005-08-16 12:25:09 +04:00
/* Try to get the lock if it's a clustered volume group */
if ( lock_flags & LCK_CLUSTER_VG ) {
status = hold_lock ( resource , mode , LKF_NOQUEUE ) ;
2006-10-05 17:55:50 +04:00
if ( status ) {
/* Return an LVM-sensible error for this.
* Forcing EIO makes the upper level return this text
* rather than the strerror text for EAGAIN .
*/
if ( errno = = EAGAIN ) {
sprintf ( last_error , " Volume is busy on another node " ) ;
errno = EIO ;
}
2005-08-16 12:25:09 +04:00
return errno ;
2006-10-05 17:55:50 +04:00
}
2005-08-16 12:25:09 +04:00
}
2004-06-24 12:02:38 +04:00
/* If it's suspended then resume it */
2005-01-19 21:10:09 +03:00
if ( ! lv_info_by_lvid ( cmd , resource , & lvi , 0 ) )
2004-06-24 12:02:38 +04:00
return EIO ;
if ( lvi . suspended )
if ( ! lv_resume ( cmd , resource ) )
return EIO ;
/* Now activate it */
2005-08-15 03:18:28 +04:00
if ( ! lv_activate ( cmd , resource , exclusive ) )
2004-06-24 12:02:38 +04:00
return EIO ;
return 0 ;
}
/* Resume the LV if it was active */
static int do_resume_lv ( char * resource )
{
int oldmode ;
/* Is it open ? */
oldmode = get_current_lock ( resource ) ;
if ( oldmode = = - 1 ) {
2006-10-24 22:49:31 +04:00
DEBUGLOG ( " do_resume_lv, lock not already held \n " ) ;
2004-06-24 12:02:38 +04:00
return 0 ; /* We don't need to do anything */
}
if ( ! lv_resume_if_active ( cmd , resource ) )
return EIO ;
return 0 ;
}
/* Suspend the device if active */
static int do_suspend_lv ( char * resource )
{
int oldmode ;
struct lvinfo lvi ;
/* Is it open ? */
oldmode = get_current_lock ( resource ) ;
if ( oldmode = = - 1 ) {
DEBUGLOG ( " do_suspend_lv, lock held at %d \n " , oldmode ) ;
return 0 ; /* Not active, so it's OK */
}
/* Only suspend it if it exists */
2005-01-19 21:10:09 +03:00
if ( ! lv_info_by_lvid ( cmd , resource , & lvi , 0 ) )
2004-06-24 12:02:38 +04:00
return EIO ;
if ( lvi . exists ) {
if ( ! lv_suspend_if_active ( cmd , resource ) ) {
return EIO ;
}
}
return 0 ;
}
2005-08-16 12:25:09 +04:00
static int do_deactivate_lv ( char * resource , unsigned char lock_flags )
2004-06-24 12:02:38 +04:00
{
int oldmode ;
int status ;
/* Is it open ? */
oldmode = get_current_lock ( resource ) ;
2005-08-16 12:25:09 +04:00
if ( oldmode = = - 1 & & ( lock_flags & LCK_CLUSTER_VG ) ) {
2004-06-24 12:02:38 +04:00
DEBUGLOG ( " do_deactivate_lock, lock not already held \n " ) ;
return 0 ; /* We don't need to do anything */
}
if ( ! lv_deactivate ( cmd , resource ) )
return EIO ;
2005-08-16 12:25:09 +04:00
if ( lock_flags & LCK_CLUSTER_VG ) {
status = hold_unlock ( resource ) ;
if ( status )
return errno ;
}
2004-06-24 12:02:38 +04:00
return 0 ;
}
/* This is the LOCK_LV part that happens on all nodes in the cluster -
it is responsible for the interaction with device - mapper and LVM */
int do_lock_lv ( unsigned char command , unsigned char lock_flags , char * resource )
{
int status = 0 ;
2005-08-16 12:25:09 +04:00
DEBUGLOG ( " do_lock_lv: resource '%s', cmd = 0x%x, flags = %x \n " ,
2004-06-24 12:02:38 +04:00
resource , command , lock_flags ) ;
2007-04-24 19:13:13 +04:00
pthread_mutex_lock ( & lvm_lock ) ;
2004-06-24 12:02:38 +04:00
if ( ! cmd - > config_valid | | config_files_changed ( cmd ) ) {
/* Reinitialise various settings inc. logging, filters */
if ( ! refresh_toolcontext ( cmd ) ) {
log_error ( " Updated config file invalid. Aborting. " ) ;
2007-04-24 19:13:13 +04:00
pthread_mutex_unlock ( & lvm_lock ) ;
2004-06-24 12:02:38 +04:00
return EINVAL ;
}
}
2006-03-10 01:34:13 +03:00
if ( lock_flags & LCK_PARTIAL_MODE )
init_partial ( 1 ) ;
2006-05-11 23:05:21 +04:00
if ( lock_flags & LCK_MIRROR_NOSYNC_MODE )
init_mirror_in_sync ( 1 ) ;
2007-01-20 01:21:45 +03:00
if ( ! ( lock_flags & LCK_DMEVENTD_MONITOR_MODE ) )
init_dmeventd_monitor ( 0 ) ;
2006-05-12 23:16:48 +04:00
2004-06-24 12:02:38 +04:00
switch ( command ) {
case LCK_LV_EXCLUSIVE :
2005-08-16 12:25:09 +04:00
status = do_activate_lv ( resource , lock_flags , LKM_EXMODE ) ;
2004-06-24 12:02:38 +04:00
break ;
case LCK_LV_SUSPEND :
status = do_suspend_lv ( resource ) ;
break ;
case LCK_UNLOCK :
case LCK_LV_RESUME : /* if active */
status = do_resume_lv ( resource ) ;
break ;
case LCK_LV_ACTIVATE :
2005-08-16 12:25:09 +04:00
status = do_activate_lv ( resource , lock_flags , LKM_CRMODE ) ;
2004-06-24 12:02:38 +04:00
break ;
case LCK_LV_DEACTIVATE :
2005-08-16 12:25:09 +04:00
status = do_deactivate_lv ( resource , lock_flags ) ;
2004-06-24 12:02:38 +04:00
break ;
default :
DEBUGLOG ( " Invalid LV command 0x%x \n " , command ) ;
status = EINVAL ;
break ;
}
2006-03-10 01:34:13 +03:00
if ( lock_flags & LCK_PARTIAL_MODE )
init_partial ( 0 ) ;
2006-05-12 23:16:48 +04:00
if ( lock_flags & LCK_MIRROR_NOSYNC_MODE )
init_mirror_in_sync ( 0 ) ;
2007-01-20 01:21:45 +03:00
if ( ! ( lock_flags & LCK_DMEVENTD_MONITOR_MODE ) )
init_dmeventd_monitor ( DEFAULT_DMEVENTD_MONITOR ) ;
2006-05-12 23:16:48 +04:00
2004-06-24 12:02:38 +04:00
/* clean the pool for another command */
2005-10-17 03:03:59 +04:00
dm_pool_empty ( cmd - > mem ) ;
2007-04-24 19:13:13 +04:00
pthread_mutex_unlock ( & lvm_lock ) ;
2004-06-24 12:02:38 +04:00
DEBUGLOG ( " Command return is %d \n " , status ) ;
return status ;
}
/* Functions to do on the local node only BEFORE the cluster-wide stuff above happens */
int pre_lock_lv ( unsigned char command , unsigned char lock_flags , char * resource )
{
/* Nearly all the stuff happens cluster-wide. Apart from SUSPEND. Here we get the
lock out on this node ( because we are the node modifying the metadata )
before suspending cluster - wide .
*/
if ( command = = LCK_LV_SUSPEND ) {
DEBUGLOG ( " pre_lock_lv: resource '%s', cmd = 0x%x, flags = %d \n " ,
resource , command , lock_flags ) ;
if ( hold_lock ( resource , LKM_PWMODE , LKF_NOQUEUE ) )
return errno ;
}
return 0 ;
}
/* Functions to do on the local node only AFTER the cluster-wide stuff above happens */
int post_lock_lv ( unsigned char command , unsigned char lock_flags ,
char * resource )
{
2007-04-24 19:13:13 +04:00
int status ;
2004-06-24 12:02:38 +04:00
/* Opposite of above, done on resume after a metadata update */
if ( command = = LCK_LV_RESUME ) {
int oldmode ;
DEBUGLOG
( " post_lock_lv: resource '%s', cmd = 0x%x, flags = %d \n " ,
resource , command , lock_flags ) ;
/* If the lock state is PW then restore it to what it was */
oldmode = get_current_lock ( resource ) ;
if ( oldmode = = LKM_PWMODE ) {
struct lvinfo lvi ;
2007-04-24 19:13:13 +04:00
pthread_mutex_lock ( & lvm_lock ) ;
status = lv_info_by_lvid ( cmd , resource , & lvi , 0 ) ;
pthread_mutex_unlock ( & lvm_lock ) ;
if ( ! status )
2004-06-24 12:02:38 +04:00
return EIO ;
if ( lvi . exists ) {
if ( hold_lock ( resource , LKM_CRMODE , 0 ) )
return errno ;
} else {
if ( hold_unlock ( resource ) )
return errno ;
}
}
}
return 0 ;
}
/* Check if a VG is un use by LVM1 so we don't stomp on it */
int do_check_lvm1 ( char * vgname )
{
int status ;
status = check_lvm1_vg_inactive ( cmd , vgname ) ;
return status = = 1 ? 0 : EBUSY ;
}
2006-10-04 12:22:16 +04:00
int do_refresh_cache ( )
{
DEBUGLOG ( " Refreshing context \n " ) ;
log_notice ( " Refreshing context " ) ;
return refresh_toolcontext ( cmd ) = = 1 ? 0 : - 1 ;
}
2005-03-07 20:03:44 +03:00
/* Only called at gulm startup. Drop any leftover VG or P_orphan locks
that might be hanging around if we died for any reason
*/
static void drop_vg_locks ( )
{
char vg [ 128 ] ;
char line [ 255 ] ;
FILE * vgs =
popen
( " lvm pvs --nolocking --noheadings -o vg_name " , " r " ) ;
sync_unlock ( " P_orphans " , LCK_EXCL ) ;
if ( ! vgs )
return ;
while ( fgets ( line , sizeof ( line ) , vgs ) ) {
char * vgend ;
char * vgstart ;
if ( line [ strlen ( line ) - 1 ] = = ' \n ' )
line [ strlen ( line ) - 1 ] = ' \0 ' ;
vgstart = line + strspn ( line , " " ) ;
vgend = vgstart + strcspn ( vgstart , " " ) ;
* vgend = ' \0 ' ;
if ( strncmp ( vgstart , " WARNING: " , 8 ) = = 0 )
continue ;
sprintf ( vg , " V_%s " , vgstart ) ;
sync_unlock ( vg , LCK_EXCL ) ;
}
2007-01-25 17:37:48 +03:00
if ( fclose ( vgs ) )
DEBUGLOG ( " vgs fclose failed: %s \n " , strerror ( errno ) ) ;
2005-03-07 20:03:44 +03:00
}
2005-02-07 17:45:38 +03:00
/*
* Ideally , clvmd should be started before any LVs are active
* but this may not be the case . . .
* I suppose this also comes in handy if clvmd crashes , not that it would !
*/
static void * get_initial_state ( )
2004-06-24 12:02:38 +04:00
{
2005-08-16 12:25:09 +04:00
char lv [ 64 ] , vg [ 64 ] , flags [ 25 ] , vg_flags [ 25 ] ;
2005-02-07 17:45:38 +03:00
char uuid [ 65 ] ;
char line [ 255 ] ;
FILE * lvs =
popen
2005-08-16 12:25:09 +04:00
( " lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr " ,
2005-02-07 17:45:38 +03:00
" r " ) ;
2004-06-24 12:02:38 +04:00
2005-02-07 17:45:38 +03:00
if ( ! lvs )
return NULL ;
while ( fgets ( line , sizeof ( line ) , lvs ) ) {
2005-08-16 12:25:09 +04:00
if ( sscanf ( line , " %s %s %s %s \n " , vg , lv , flags , vg_flags ) = = 4 ) {
2004-10-04 13:23:52 +04:00
2004-06-24 12:02:38 +04:00
/* States: s:suspended a:active S:dropped snapshot I:invalid snapshot */
2005-02-07 17:45:38 +03:00
if ( strlen ( vg ) = = 38 & & /* is is a valid UUID ? */
2005-08-16 12:25:09 +04:00
( flags [ 4 ] = = ' a ' | | flags [ 4 ] = = ' s ' ) & & /* is it active or suspended? */
vg_flags [ 5 ] = = ' c ' ) { /* is it clustered ? */
2004-06-24 12:02:38 +04:00
/* Convert hyphen-separated UUIDs into one */
memcpy ( & uuid [ 0 ] , & vg [ 0 ] , 6 ) ;
memcpy ( & uuid [ 6 ] , & vg [ 7 ] , 4 ) ;
memcpy ( & uuid [ 10 ] , & vg [ 12 ] , 4 ) ;
memcpy ( & uuid [ 14 ] , & vg [ 17 ] , 4 ) ;
memcpy ( & uuid [ 18 ] , & vg [ 22 ] , 4 ) ;
memcpy ( & uuid [ 22 ] , & vg [ 27 ] , 4 ) ;
memcpy ( & uuid [ 26 ] , & vg [ 32 ] , 6 ) ;
memcpy ( & uuid [ 32 ] , & lv [ 0 ] , 6 ) ;
memcpy ( & uuid [ 38 ] , & lv [ 7 ] , 4 ) ;
memcpy ( & uuid [ 42 ] , & lv [ 12 ] , 4 ) ;
memcpy ( & uuid [ 46 ] , & lv [ 17 ] , 4 ) ;
memcpy ( & uuid [ 50 ] , & lv [ 22 ] , 4 ) ;
memcpy ( & uuid [ 54 ] , & lv [ 27 ] , 4 ) ;
memcpy ( & uuid [ 58 ] , & lv [ 32 ] , 6 ) ;
uuid [ 64 ] = ' \0 ' ;
DEBUGLOG ( " getting initial lock for %s \n " , uuid ) ;
hold_lock ( uuid , LKM_CRMODE , LKF_NOQUEUE ) ;
}
}
}
2007-01-25 17:37:48 +03:00
if ( fclose ( lvs ) )
DEBUGLOG ( " lvs fclose failed: %s \n " , strerror ( errno ) ) ;
2005-02-07 17:45:38 +03:00
return NULL ;
2004-06-24 12:02:38 +04:00
}
2006-10-05 17:55:50 +04:00
static void lvm2_log_fn ( int level , const char * file , int line ,
const char * message )
{
/*
2007-04-24 19:13:13 +04:00
* Ignore non - error messages , but store the latest one for returning
2006-10-05 17:55:50 +04:00
* to the user .
*/
if ( level ! = _LOG_ERR & & level ! = _LOG_FATAL )
return ;
2006-10-06 14:06:37 +04:00
strncpy ( last_error , message , sizeof ( last_error ) ) ;
last_error [ sizeof ( last_error ) - 1 ] = ' \0 ' ;
2006-10-05 17:55:50 +04:00
}
2005-02-02 14:42:29 +03:00
/* This checks some basic cluster-LVM configuration stuff */
static void check_config ( )
{
int locking_type ;
2006-05-16 20:48:31 +04:00
locking_type = find_config_tree_int ( cmd , " global/locking_type " , 1 ) ;
2005-02-02 14:42:29 +03:00
if ( locking_type = = 3 ) /* compiled-in cluster support */
return ;
if ( locking_type = = 2 ) { /* External library, check name */
2005-02-14 12:07:14 +03:00
const char * libname ;
2005-02-02 14:42:29 +03:00
2006-05-16 20:48:31 +04:00
libname = find_config_tree_str ( cmd , " global/locking_library " ,
2005-02-02 14:42:29 +03:00
" " ) ;
2005-02-14 12:07:14 +03:00
if ( strstr ( libname , " liblvm2clusterlock.so " ) )
2005-02-02 14:42:29 +03:00
return ;
log_error ( " Incorrect LVM locking library specified in lvm.conf, cluster operations may not work. " ) ;
return ;
}
log_error ( " locking_type not set correctly in lvm.conf, cluster operations will not work. " ) ;
}
2004-06-24 12:02:38 +04:00
void init_lvhash ( )
{
/* Create hash table for keeping LV locks & status */
2005-11-09 12:24:10 +03:00
lv_hash = dm_hash_create ( 100 ) ;
2004-09-22 16:10:34 +04:00
pthread_mutex_init ( & lv_hash_lock , NULL ) ;
2007-04-24 19:13:13 +04:00
pthread_mutex_init ( & lvm_lock , NULL ) ;
2004-06-24 12:02:38 +04:00
}
/* Called to initialise the LVM context of the daemon */
2005-03-07 20:03:44 +03:00
int init_lvm ( int using_gulm )
2004-06-24 12:02:38 +04:00
{
2007-01-23 18:58:06 +03:00
if ( ! ( cmd = create_toolcontext ( NULL , 0 , 1 ) ) ) {
2004-06-24 12:02:38 +04:00
log_error ( " Failed to allocate command context " ) ;
return 0 ;
}
/* Use LOG_DAEMON for syslog messages instead of LOG_USER */
init_syslog ( LOG_DAEMON ) ;
2004-06-28 14:26:42 +04:00
init_debug ( _LOG_ERR ) ;
2004-06-24 12:02:38 +04:00
2005-02-02 14:42:29 +03:00
/* Check lvm.conf is setup for cluster-LVM */
check_config ( ) ;
2005-03-07 20:03:44 +03:00
/* Remove any non-LV locks that may have been left around */
if ( using_gulm )
drop_vg_locks ( ) ;
2004-06-24 12:02:38 +04:00
get_initial_state ( ) ;
2006-10-05 17:55:50 +04:00
/* Trap log messages so we can pass them back to the user */
init_log_fn ( lvm2_log_fn ) ;
2004-06-24 12:02:38 +04:00
return 1 ;
}