2002-02-11 18:42:34 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2014-01-27 15:11:09 +04:00
* Copyright ( C ) 2004 - 2014 Red Hat , Inc . All rights reserved .
2002-02-11 18:42:34 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
2002-02-11 18:42:34 +03:00
*
2004-03-30 23:35:44 +04:00
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2002-02-11 18:42:34 +03:00
*/
2018-05-14 12:30:20 +03:00
# include "lib/misc/lib.h"
# include "lib/locking/locking.h"
2002-02-11 18:42:34 +03:00
# include "locking_types.h"
2018-05-14 12:30:20 +03:00
# include "lib/activate/activate.h"
# include "lib/config/config.h"
# include "lib/config/defaults.h"
# include "lib/misc/lvm-string.h"
# include "lib/misc/lvm-flock.h"
2002-02-11 18:42:34 +03:00
# include <limits.h>
# include <unistd.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <signal.h>
2014-03-19 03:22:18 +04:00
static char _lock_dir [ PATH_MAX ] ;
2002-02-11 18:42:34 +03:00
2002-12-20 02:25:55 +03:00
static void _fin_file_locking ( void )
2002-02-11 18:42:34 +03:00
{
2014-05-01 20:37:14 +04:00
release_flocks ( 1 ) ;
2003-05-06 16:03:13 +04:00
}
static void _reset_file_locking ( void )
{
2014-05-01 20:37:14 +04:00
release_flocks ( 0 ) ;
2002-02-11 18:42:34 +03:00
}
2002-12-20 02:25:55 +03:00
static int _file_lock_resource ( struct cmd_context * cmd , const char * resource ,
2014-09-22 17:50:07 +04:00
uint32_t flags , const struct logical_volume * lv )
2002-02-11 18:42:34 +03:00
{
char lockfile [ PATH_MAX ] ;
switch ( flags & LCK_SCOPE_MASK ) {
case LCK_VG :
2008-05-09 23:26:58 +04:00
/* LCK_CACHE does not require a real lock */
if ( flags & LCK_CACHE )
2008-04-15 18:46:19 +04:00
break ;
2008-05-09 23:26:58 +04:00
2011-01-05 18:10:30 +03:00
if ( is_orphan_vg ( resource ) | | is_global_vg ( resource ) ) {
if ( dm_snprintf ( lockfile , sizeof ( lockfile ) ,
" %s/P_%s " , _lock_dir , resource + 1 ) < 0 ) {
log_error ( " Too long locking filename %s/P_%s. " ,
_lock_dir , resource + 1 ) ;
return 0 ;
}
} else
if ( dm_snprintf ( lockfile , sizeof ( lockfile ) ,
" %s/V_%s " , _lock_dir , resource ) < 0 ) {
log_error ( " Too long locking filename %s/V_%s. " ,
_lock_dir , resource ) ;
return 0 ;
}
2003-07-05 02:34:56 +04:00
2014-05-01 20:37:14 +04:00
if ( ! lock_file ( lockfile , flags ) )
2008-04-03 22:56:40 +04:00
return_0 ;
2002-02-11 18:42:34 +03:00
break ;
2002-02-25 15:56:16 +03:00
default :
log_error ( " Unrecognised lock scope: %d " ,
flags & LCK_SCOPE_MASK ) ;
return 0 ;
2002-02-21 00:30:27 +03:00
}
2002-02-25 15:56:16 +03:00
return 1 ;
}
2011-08-09 15:44:57 +04:00
int init_file_locking ( struct locking_type * locking , struct cmd_context * cmd ,
int suppress_messages )
2002-02-11 18:42:34 +03:00
{
2011-04-08 18:13:08 +04:00
int r ;
2012-02-08 15:17:34 +04:00
const char * locking_dir ;
2011-04-08 18:13:08 +04:00
2014-05-01 20:37:14 +04:00
init_flock ( cmd ) ;
2002-12-20 02:25:55 +03:00
locking - > lock_resource = _file_lock_resource ;
2003-05-06 16:03:13 +04:00
locking - > reset_locking = _reset_file_locking ;
2002-12-20 02:25:55 +03:00
locking - > fin_locking = _fin_file_locking ;
2018-06-07 00:31:59 +03:00
locking - > flags = LCK_FLOCK ;
2002-02-11 18:42:34 +03:00
/* Get lockfile directory from config file */
2013-06-25 14:29:54 +04:00
locking_dir = find_config_tree_str ( cmd , global_locking_dir_CFG , NULL ) ;
2016-04-21 21:19:53 +03:00
if ( ! dm_strncpy ( _lock_dir , locking_dir , sizeof ( _lock_dir ) ) ) {
2012-02-08 15:17:34 +04:00
log_error ( " Path for locking_dir %s is invalid. " , locking_dir ) ;
return 0 ;
}
2010-12-13 13:43:56 +03:00
( void ) dm_prepare_selinux_context ( _lock_dir , S_IFDIR ) ;
r = dm_create_dir ( _lock_dir ) ;
( void ) dm_prepare_selinux_context ( NULL , 0 ) ;
if ( ! r )
2016-06-23 23:31:49 +03:00
return 0 ;
2002-02-11 18:42:34 +03:00
2002-07-11 00:43:32 +04:00
/* Trap a read-only file system */
2016-06-23 23:31:49 +03:00
if ( ( access ( _lock_dir , R_OK | W_OK | X_OK ) = = - 1 ) & & ( errno = = EROFS ) )
2002-07-11 00:43:32 +04:00
return 0 ;
2002-02-11 18:42:34 +03:00
return 1 ;
}