2002-04-08 16:04:50 +00:00
/*
* Copyright ( C ) 2002 Sistina Software ( UK ) Limited .
*
* This file is released under the LGPL .
*
*/
# include "log.h"
# include "locking.h"
# include "locking_types.h"
# include "activate.h"
# include "config.h"
# include "defaults.h"
# include "lvm-file.h"
# include "lvm-string.h"
# include "dbg_malloc.h"
# include <limits.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/file.h>
# include <fcntl.h>
# include <dlfcn.h>
# include <signal.h>
static void * locking_module = NULL ;
2002-04-24 18:20:51 +00:00
static void ( * end_fn ) ( void ) = NULL ;
static int ( * lock_fn ) ( struct cmd_context * cmd , const char * resource ,
int flags ) = NULL ;
static int ( * init_fn ) ( int type , struct config_file * cf ) = NULL ;
2002-04-08 16:04:50 +00:00
2002-04-24 18:20:51 +00:00
static int lock_resource ( struct cmd_context * cmd , const char * resource ,
int flags )
2002-04-08 16:04:50 +00:00
{
2002-04-24 18:20:51 +00:00
if ( lock_fn )
return lock_fn ( cmd , resource , flags ) ;
else
return 0 ;
2002-04-08 16:04:50 +00:00
}
static void fin_external_locking ( void )
{
2002-04-24 18:20:51 +00:00
if ( end_fn )
end_fn ( ) ;
2002-04-08 16:04:50 +00:00
2002-04-24 18:20:51 +00:00
dlclose ( locking_module ) ;
2002-04-08 16:04:50 +00:00
2002-04-24 18:20:51 +00:00
locking_module = NULL ;
end_fn = NULL ;
lock_fn = NULL ;
2002-04-08 16:04:50 +00:00
}
int init_external_locking ( struct locking_type * locking , struct config_file * cf )
{
2002-04-24 18:20:51 +00:00
char _lock_lib [ PATH_MAX ] ;
2002-04-08 16:04:50 +00:00
2002-04-24 18:20:51 +00:00
if ( locking_module ) {
log_error ( " External locking already initialised " ) ;
return 1 ;
2002-04-08 16:04:50 +00:00
}
locking - > lock_resource = lock_resource ;
locking - > fin_locking = fin_external_locking ;
/* Get locking module name from config file */
strncpy ( _lock_lib , find_config_str ( cf - > root , " global/locking_library " ,
' / ' , " lvm2_locking.so " ) ,
sizeof ( _lock_lib ) ) ;
/* If there is a module_dir in the config file then
look for the locking module in there first and then
using the normal dlopen ( 3 ) mechanism of looking
down LD_LIBRARY_PATH and / lib , / usr / lib .
If course , if the library name starts with a slash then
just use the name . . . */
2002-04-24 18:20:51 +00:00
if ( _lock_lib [ 0 ] ! = ' / ' ) {
struct stat st ;
char _lock_lib1 [ PATH_MAX ] ;
lvm_snprintf ( _lock_lib1 , sizeof ( _lock_lib1 ) ,
" %s/%s " ,
find_config_str ( cf - > root , " global/module_dir " ,
' / ' , " RUBBISH " ) , _lock_lib ) ;
/* Does it exist ? */
if ( stat ( _lock_lib1 , & st ) = = 0 ) {
strcpy ( _lock_lib , _lock_lib1 ) ;
}
2002-04-08 16:04:50 +00:00
}
2002-04-10 15:49:47 +00:00
log_very_verbose ( " Opening locking library %s " , _lock_lib ) ;
2002-04-08 16:04:50 +00:00
locking_module = dlopen ( _lock_lib , RTLD_LAZY ) ;
2002-04-24 18:20:51 +00:00
if ( ! locking_module ) {
log_error ( " Unable to open external locking module %s " ,
_lock_lib ) ;
return 0 ;
2002-04-08 16:04:50 +00:00
}
/* Get the functions we need */
init_fn = dlsym ( locking_module , " init_locking " ) ;
lock_fn = dlsym ( locking_module , " lock_resource " ) ;
2002-04-24 18:20:51 +00:00
end_fn = dlsym ( locking_module , " end_locking " ) ;
2002-04-08 16:04:50 +00:00
/* Are they all there ? */
2002-04-24 18:20:51 +00:00
if ( ! end_fn | | ! init_fn | | ! lock_fn ) {
log_error ( " Shared library %s does not contain locking "
" functions " , _lock_lib ) ;
dlclose ( locking_module ) ;
return 0 ;
2002-04-08 16:04:50 +00:00
}
2002-04-10 15:49:47 +00:00
log_verbose ( " Opened external locking module %s " , _lock_lib ) ;
2002-04-08 16:04:50 +00:00
return init_fn ( 2 , cf ) ;
}