2001-11-09 11:48:22 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2012-02-08 14:43:42 +04:00
* Copyright ( C ) 2004 - 2012 Red Hat , Inc . All rights reserved .
2001-11-09 11:48:22 +03:00
*
2004-03-30 23:35:44 +04:00
* 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
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
2001-11-09 11:48:22 +03:00
*/
2018-05-14 12:30:20 +03:00
# include "lib/misc/lib.h"
2002-02-11 23:50:53 +03:00
# include "fs.h"
2018-05-14 12:30:20 +03:00
# include "lib/activate/activate.h"
# include "lib/commands/toolcontext.h"
# include "lib/misc/lvm-string.h"
# include "lib/misc/lvm-file.h"
# include "lib/mm/memlock.h"
2002-02-11 23:50:53 +03:00
2001-11-12 14:48:31 +03:00
# include <sys/stat.h>
# include <fcntl.h>
2001-11-09 11:48:22 +03:00
# include <unistd.h>
2001-11-12 14:48:31 +03:00
# include <limits.h>
2003-01-03 16:50:47 +03:00
# include <dirent.h>
2002-01-11 02:21:07 +03:00
2011-01-10 16:44:39 +03:00
/*
* Library cookie to combine multiple fs transactions .
* Supports to wait for udev device settle only when needed .
*/
static uint32_t _fs_cookie = DM_COOKIE_AUTO_CREATE ;
2011-10-14 17:23:47 +04:00
static int _fs_create = 0 ;
2011-01-10 16:44:39 +03:00
2003-07-05 02:34:56 +04:00
static int _mk_dir ( const char * dev_dir , const char * vg_name )
2001-11-09 11:48:22 +03:00
{
2011-11-18 23:31:09 +04:00
static char vg_path [ PATH_MAX ] ;
2009-09-25 15:58:00 +04:00
mode_t old_umask ;
2001-11-09 11:48:22 +03:00
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( vg_path , sizeof ( vg_path ) , " %s%s " ,
2003-07-05 02:34:56 +04:00
dev_dir , vg_name ) = = - 1 ) {
2002-02-26 14:49:17 +03:00
log_error ( " Couldn't construct name of volume "
" group directory. " ) ;
2002-01-21 14:06:32 +03:00
return 0 ;
}
2001-12-05 02:20:27 +03:00
2002-03-12 01:23:24 +03:00
if ( dir_exists ( vg_path ) )
2002-03-11 23:43:58 +03:00
return 1 ;
2002-03-12 01:23:24 +03:00
log_very_verbose ( " Creating directory %s " , vg_path ) ;
2009-09-25 15:58:00 +04:00
2010-12-13 13:43:56 +03:00
( void ) dm_prepare_selinux_context ( vg_path , S_IFDIR ) ;
2009-09-25 15:58:00 +04:00
old_umask = umask ( DM_DEV_DIR_UMASK ) ;
2004-09-02 18:38:46 +04:00
if ( mkdir ( vg_path , 0777 ) ) {
2002-03-12 01:23:24 +03:00
log_sys_error ( " mkdir " , vg_path ) ;
2009-09-25 15:58:00 +04:00
umask ( old_umask ) ;
2010-12-13 13:43:56 +03:00
( void ) dm_prepare_selinux_context ( NULL , 0 ) ;
2002-03-11 23:43:58 +03:00
return 0 ;
}
2009-09-25 15:58:00 +04:00
umask ( old_umask ) ;
2010-12-13 13:43:56 +03:00
( void ) dm_prepare_selinux_context ( NULL , 0 ) ;
2002-03-11 23:43:58 +03:00
2002-03-12 01:23:24 +03:00
return 1 ;
2002-03-11 23:43:58 +03:00
}
2003-07-05 02:34:56 +04:00
static int _rm_dir ( const char * dev_dir , const char * vg_name )
2001-11-09 11:48:22 +03:00
{
2011-11-18 23:31:09 +04:00
static char vg_path [ PATH_MAX ] ;
2001-11-09 11:48:22 +03:00
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( vg_path , sizeof ( vg_path ) , " %s%s " ,
2003-07-05 02:34:56 +04:00
dev_dir , vg_name ) = = - 1 ) {
2002-02-26 14:49:17 +03:00
log_error ( " Couldn't construct name of volume "
" group directory. " ) ;
2002-01-21 14:06:32 +03:00
return 0 ;
}
2001-12-05 02:20:27 +03:00
2021-03-09 13:10:47 +03:00
if ( dir_exists ( vg_path ) & & dm_is_empty_dir ( vg_path ) ) {
2004-09-22 17:38:37 +04:00
log_very_verbose ( " Removing directory %s " , vg_path ) ;
2002-03-11 23:43:58 +03:00
rmdir ( vg_path ) ;
2004-09-22 17:38:37 +04:00
}
2002-01-21 14:06:32 +03:00
return 1 ;
2001-11-09 11:48:22 +03:00
}
2003-01-03 16:50:47 +03:00
static void _rm_blks ( const char * dir )
{
const char * name ;
2011-11-18 23:31:09 +04:00
static char path [ PATH_MAX ] ;
2003-01-03 16:50:47 +03:00
struct dirent * dirent ;
struct stat buf ;
DIR * d ;
if ( ! ( d = opendir ( dir ) ) ) {
2021-03-09 13:08:47 +03:00
log_sys_debug ( " opendir " , dir ) ;
2003-01-03 16:50:47 +03:00
return ;
}
while ( ( dirent = readdir ( d ) ) ) {
name = dirent - > d_name ;
if ( ! strcmp ( name , " . " ) | | ! strcmp ( name , " .. " ) )
continue ;
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( path , sizeof ( path ) , " %s/%s " , dir , name ) = = - 1 ) {
2021-03-09 13:08:47 +03:00
log_debug ( " Couldn't create path for %s. " , name ) ;
2003-01-03 16:50:47 +03:00
continue ;
}
if ( ! lstat ( path , & buf ) ) {
if ( ! S_ISBLK ( buf . st_mode ) )
continue ;
log_very_verbose ( " Removing %s " , path ) ;
2024-04-30 14:48:01 +03:00
if ( unlink ( path ) & & ( errno ! = ENOENT ) )
2021-03-09 13:08:47 +03:00
log_sys_debug ( " unlink " , path ) ;
2003-01-03 16:50:47 +03:00
}
}
2010-11-23 18:28:54 +03:00
if ( closedir ( d ) )
2021-03-09 13:08:47 +03:00
log_sys_debug ( " closedir " , dir ) ;
2003-01-03 16:50:47 +03:00
}
2003-07-05 02:34:56 +04:00
static int _mk_link ( const char * dev_dir , const char * vg_name ,
2010-01-07 22:54:21 +03:00
const char * lv_name , const char * dev , int check_udev )
2001-11-09 11:48:22 +03:00
{
2011-11-18 23:31:09 +04:00
static char lv_path [ PATH_MAX ] , link_path [ PATH_MAX ] , lvm1_group_path [ PATH_MAX ] ;
static char vg_path [ PATH_MAX ] ;
2009-08-05 01:44:20 +04:00
struct stat buf , buf_lp ;
2001-11-09 11:48:22 +03:00
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( vg_path , sizeof ( vg_path ) , " %s%s " ,
2003-07-05 02:34:56 +04:00
dev_dir , vg_name ) = = - 1 ) {
2003-01-03 16:50:47 +03:00
log_error ( " Couldn't create path for volume group dir %s " ,
2003-07-05 02:34:56 +04:00
vg_name ) ;
2003-01-03 16:50:47 +03:00
return 0 ;
}
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( lv_path , sizeof ( lv_path ) , " %s/%s " , vg_path ,
2003-07-05 02:34:56 +04:00
lv_name ) = = - 1 ) {
2002-02-26 14:49:17 +03:00
log_error ( " Couldn't create source pathname for "
2003-07-05 02:34:56 +04:00
" logical volume link %s " , lv_name ) ;
2002-01-21 14:06:32 +03:00
return 0 ;
}
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( link_path , sizeof ( link_path ) , " %s/%s " ,
2002-02-26 14:49:17 +03:00
dm_dir ( ) , dev ) = = - 1 ) {
log_error ( " Couldn't create destination pathname for "
2003-07-05 02:34:56 +04:00
" logical volume link for %s " , lv_name ) ;
2002-01-21 14:06:32 +03:00
return 0 ;
}
2001-11-12 14:42:29 +03:00
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( lvm1_group_path , sizeof ( lvm1_group_path ) , " %s/group " ,
2003-01-03 16:50:47 +03:00
vg_path ) = = - 1 ) {
log_error ( " Couldn't create pathname for LVM1 group file for %s " ,
2003-07-05 02:34:56 +04:00
vg_name ) ;
2003-01-03 16:50:47 +03:00
return 0 ;
}
/* To reach this point, the VG must have been locked.
2008-01-30 17:00:02 +03:00
* As locking fails if the VG is active under LVM1 , it ' s
2003-01-03 16:50:47 +03:00
* now safe to remove any LVM1 devices we find here
* ( as well as any existing LVM2 symlink ) . */
if ( ! lstat ( lvm1_group_path , & buf ) ) {
if ( ! S_ISCHR ( buf . st_mode ) ) {
log_error ( " Non-LVM1 character device found at %s " ,
lvm1_group_path ) ;
} else {
_rm_blks ( vg_path ) ;
log_very_verbose ( " Removing %s " , lvm1_group_path ) ;
2024-04-30 14:48:01 +03:00
if ( unlink ( lvm1_group_path ) & & ( errno ! = ENOENT ) )
2021-03-09 13:08:47 +03:00
log_sys_debug ( " unlink " , lvm1_group_path ) ;
2003-01-03 16:50:47 +03:00
}
}
2002-02-26 14:49:17 +03:00
if ( ! lstat ( lv_path , & buf ) ) {
2003-01-03 16:50:47 +03:00
if ( ! S_ISLNK ( buf . st_mode ) & & ! S_ISBLK ( buf . st_mode ) ) {
2002-01-22 22:58:37 +03:00
log_error ( " Symbolic link %s not created: file exists " ,
link_path ) ;
return 0 ;
}
2002-02-26 14:49:17 +03:00
2010-01-11 18:40:03 +03:00
if ( dm_udev_get_sync_support ( ) & & udev_checking ( ) & & check_udev ) {
2009-08-05 01:44:20 +04:00
/* Check udev created the correct link. */
if ( ! stat ( link_path , & buf_lp ) & &
! stat ( lv_path , & buf ) ) {
if ( buf_lp . st_rdev = = buf . st_rdev )
return 1 ;
2017-07-19 17:16:12 +03:00
log_warn ( " Symlink %s that should have been "
" created by udev does not have "
" correct target. Falling back to "
" direct link creation " , lv_path ) ;
2009-08-05 01:44:20 +04:00
} else
log_warn ( " Symlink %s that should have been "
" created by udev could not be checked "
" for its correctness. Falling back to "
" direct link creation. " , lv_path ) ;
}
2003-01-03 16:50:47 +03:00
log_very_verbose ( " Removing %s " , lv_path ) ;
2024-04-30 14:48:01 +03:00
if ( unlink ( lv_path ) & & ( errno ! = ENOENT ) ) {
2002-02-26 14:49:17 +03:00
log_sys_error ( " unlink " , lv_path ) ;
2002-01-22 22:58:37 +03:00
return 0 ;
}
2010-01-11 18:40:03 +03:00
} else if ( dm_udev_get_sync_support ( ) & & udev_checking ( ) & & check_udev )
2013-03-06 18:42:03 +04:00
log_warn ( " The link %s should have been created by udev "
2009-08-05 01:44:20 +04:00
" but it was not found. Falling back to "
" direct link creation. " , lv_path ) ;
2002-01-22 22:58:37 +03:00
2002-02-26 19:08:22 +03:00
log_very_verbose ( " Linking %s -> %s " , lv_path , link_path ) ;
2010-12-13 13:43:56 +03:00
( void ) dm_prepare_selinux_context ( lv_path , S_IFLNK ) ;
2002-02-26 14:49:17 +03:00
if ( symlink ( link_path , lv_path ) < 0 ) {
log_sys_error ( " symlink " , lv_path ) ;
2010-12-13 13:43:56 +03:00
( void ) dm_prepare_selinux_context ( NULL , 0 ) ;
2001-11-12 14:42:29 +03:00
return 0 ;
}
2010-12-13 13:43:56 +03:00
( void ) dm_prepare_selinux_context ( NULL , 0 ) ;
2004-04-07 18:08:22 +04:00
2001-11-12 14:42:29 +03:00
return 1 ;
}
2003-07-05 02:34:56 +04:00
static int _rm_link ( const char * dev_dir , const char * vg_name ,
2010-01-07 22:54:21 +03:00
const char * lv_name , int check_udev )
2001-11-12 14:42:29 +03:00
{
2002-01-25 23:17:44 +03:00
struct stat buf ;
2011-11-18 23:31:09 +04:00
static char lv_path [ PATH_MAX ] ;
2001-11-12 14:42:29 +03:00
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( lv_path , sizeof ( lv_path ) , " %s%s/%s " ,
2003-07-05 02:34:56 +04:00
dev_dir , vg_name , lv_name ) = = - 1 ) {
2002-01-28 00:30:47 +03:00
log_error ( " Couldn't determine link pathname. " ) ;
2002-01-21 14:06:32 +03:00
return 0 ;
}
2001-11-12 14:42:29 +03:00
2012-02-13 00:17:12 +04:00
if ( lstat ( lv_path , & buf ) ) {
if ( errno = = ENOENT )
return 1 ;
log_sys_error ( " lstat " , lv_path ) ;
return 0 ;
2017-07-19 17:16:12 +03:00
}
if ( dm_udev_get_sync_support ( ) & & udev_checking ( ) & & check_udev )
2009-08-03 22:31:53 +04:00
log_warn ( " The link %s should have been removed by udev "
" but it is still present. Falling back to "
" direct link removal. " , lv_path ) ;
2012-02-13 00:17:12 +04:00
if ( ! S_ISLNK ( buf . st_mode ) ) {
2004-09-22 17:38:37 +04:00
log_error ( " %s not symbolic link - not removing " , lv_path ) ;
2002-02-26 14:49:17 +03:00
return 0 ;
2002-01-25 23:17:44 +03:00
}
2002-02-26 14:49:17 +03:00
2003-01-03 16:50:47 +03:00
log_very_verbose ( " Removing link %s " , lv_path ) ;
2024-04-30 14:48:01 +03:00
if ( unlink ( lv_path ) & & ( errno ! = ENOENT ) ) {
2002-02-26 14:49:17 +03:00
log_sys_error ( " unlink " , lv_path ) ;
2001-11-12 14:42:29 +03:00
return 0 ;
}
return 1 ;
2001-11-09 11:48:22 +03:00
}
2003-07-05 02:34:56 +04:00
typedef enum {
FS_ADD ,
FS_DEL ,
2011-02-04 22:14:39 +03:00
FS_RENAME ,
NUM_FS_OPS
2003-07-05 02:34:56 +04:00
} fs_op_t ;
static int _do_fs_op ( fs_op_t type , const char * dev_dir , const char * vg_name ,
const char * lv_name , const char * dev ,
2010-01-07 22:54:21 +03:00
const char * old_lv_name , int check_udev )
2001-11-09 11:48:22 +03:00
{
2003-07-05 02:34:56 +04:00
switch ( type ) {
case FS_ADD :
if ( ! _mk_dir ( dev_dir , vg_name ) | |
2010-01-07 22:54:21 +03:00
! _mk_link ( dev_dir , vg_name , lv_name , dev , check_udev ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2003-07-05 02:34:56 +04:00
break ;
case FS_DEL :
2010-01-07 22:54:21 +03:00
if ( ! _rm_link ( dev_dir , vg_name , lv_name , check_udev ) | |
2008-01-30 16:19:47 +03:00
! _rm_dir ( dev_dir , vg_name ) )
return_0 ;
2003-07-05 02:34:56 +04:00
break ;
/* FIXME Use rename() */
case FS_RENAME :
2010-01-07 22:54:21 +03:00
if ( old_lv_name & & ! _rm_link ( dev_dir , vg_name , old_lv_name ,
check_udev ) )
2003-07-05 02:34:56 +04:00
stack ;
2010-01-07 22:54:21 +03:00
if ( ! _mk_link ( dev_dir , vg_name , lv_name , dev , check_udev ) )
2003-07-05 02:34:56 +04:00
stack ;
2011-02-05 01:07:43 +03:00
default :
; /* NOTREACHED */
2001-11-09 11:48:22 +03:00
}
return 1 ;
}
2008-11-04 01:14:30 +03:00
static DM_LIST_INIT ( _fs_ops ) ;
2011-02-04 22:14:39 +03:00
/*
* Count number of stacked fs_op_t operations to allow to skip dm_list search .
* FIXME : handling of FS_RENAME
*/
static int _count_fs_ops [ NUM_FS_OPS ] ;
2003-07-05 02:34:56 +04:00
struct fs_op_parms {
2008-11-04 01:14:30 +03:00
struct dm_list list ;
2003-07-05 02:34:56 +04:00
fs_op_t type ;
2010-01-07 22:54:21 +03:00
int check_udev ;
2003-07-05 02:34:56 +04:00
char * dev_dir ;
char * vg_name ;
char * lv_name ;
char * dev ;
char * old_lv_name ;
2021-09-22 18:05:09 +03:00
char names [ 0 ] ;
2003-07-05 02:34:56 +04:00
} ;
static void _store_str ( char * * pos , char * * ptr , const char * str )
2001-11-09 11:48:22 +03:00
{
2023-02-14 22:59:56 +03:00
size_t len = strlen ( str ) + 1 ;
memcpy ( * pos , str , len ) ;
2003-07-05 02:34:56 +04:00
* ptr = * pos ;
2023-02-14 22:59:56 +03:00
* pos + = len ;
2003-07-05 02:34:56 +04:00
}
2011-02-04 22:14:39 +03:00
static void _del_fs_op ( struct fs_op_parms * fsp )
{
_count_fs_ops [ fsp - > type ] - - ;
dm_list_del ( & fsp - > list ) ;
2018-06-08 15:40:53 +03:00
free ( fsp ) ;
2011-02-04 22:14:39 +03:00
}
/* Check if there is other the type of fs operation stacked */
static int _other_fs_ops ( fs_op_t type )
{
2011-04-08 18:40:18 +04:00
unsigned i ;
2011-02-04 22:14:39 +03:00
for ( i = 0 ; i < NUM_FS_OPS ; i + + )
if ( type ! = i & & _count_fs_ops [ i ] )
return 1 ;
return 0 ;
}
/* Check if udev is supposed to create nodes */
static int _check_udev ( int check_udev )
{
return check_udev & & dm_udev_get_sync_support ( ) & & dm_udev_get_checking ( ) ;
}
/* FIXME: duplication of the code from libdm-common.c */
2003-07-05 02:34:56 +04:00
static int _stack_fs_op ( fs_op_t type , const char * dev_dir , const char * vg_name ,
const char * lv_name , const char * dev ,
2010-01-07 22:54:21 +03:00
const char * old_lv_name , int check_udev )
2003-07-05 02:34:56 +04:00
{
2011-02-04 22:14:39 +03:00
struct dm_list * fsph , * fspht ;
2003-07-05 02:34:56 +04:00
struct fs_op_parms * fsp ;
size_t len = strlen ( dev_dir ) + strlen ( vg_name ) + strlen ( lv_name ) +
strlen ( dev ) + strlen ( old_lv_name ) + 5 ;
char * pos ;
2011-02-04 22:14:39 +03:00
if ( ( type = = FS_DEL ) & & _other_fs_ops ( type ) )
/*
* Ignore any outstanding operations on the fs_op if deleting it .
*/
dm_list_iterate_safe ( fsph , fspht , & _fs_ops ) {
fsp = dm_list_item ( fsph , struct fs_op_parms ) ;
if ( ! strcmp ( lv_name , fsp - > lv_name ) & &
! strcmp ( vg_name , fsp - > vg_name ) ) {
_del_fs_op ( fsp ) ;
if ( ! _other_fs_ops ( type ) )
break ; /* no other non DEL ops */
}
}
else if ( ( type = = FS_ADD ) & & _count_fs_ops [ FS_DEL ] & & _check_udev ( check_udev ) )
/*
* If udev is running ignore previous DEL operation on added fs_op .
2011-02-05 01:07:43 +03:00
* ( No other operations for this device then DEL could be stacked here ) .
2011-02-04 22:14:39 +03:00
*/
dm_list_iterate_safe ( fsph , fspht , & _fs_ops ) {
fsp = dm_list_item ( fsph , struct fs_op_parms ) ;
if ( ( fsp - > type = = FS_DEL ) & &
! strcmp ( lv_name , fsp - > lv_name ) & &
! strcmp ( vg_name , fsp - > vg_name ) ) {
_del_fs_op ( fsp ) ;
break ; /* no other DEL ops */
}
}
else if ( ( type = = FS_RENAME ) & & _check_udev ( check_udev ) )
/*
* If udev is running ignore any outstanding operations if renaming it .
*
* Currently RENAME operation happens through ' suspend - > resume ' .
* On ' resume ' device is added with read_ahead settings , so it
* safe to remove any stacked ADD , RENAME , READ_AHEAD operation
* There cannot be any DEL operation on the renamed device .
*/
dm_list_iterate_safe ( fsph , fspht , & _fs_ops ) {
fsp = dm_list_item ( fsph , struct fs_op_parms ) ;
if ( ! strcmp ( old_lv_name , fsp - > lv_name ) & &
! strcmp ( vg_name , fsp - > vg_name ) )
_del_fs_op ( fsp ) ;
}
2018-06-08 15:40:53 +03:00
if ( ! ( fsp = malloc ( sizeof ( * fsp ) + len ) ) ) {
2003-07-05 02:34:56 +04:00
log_error ( " No space to stack fs operation " ) ;
2001-11-09 11:48:22 +03:00
return 0 ;
}
2003-07-05 02:34:56 +04:00
pos = fsp - > names ;
fsp - > type = type ;
2010-01-07 22:54:21 +03:00
fsp - > check_udev = check_udev ;
2003-07-05 02:34:56 +04:00
_store_str ( & pos , & fsp - > dev_dir , dev_dir ) ;
_store_str ( & pos , & fsp - > vg_name , vg_name ) ;
_store_str ( & pos , & fsp - > lv_name , lv_name ) ;
_store_str ( & pos , & fsp - > dev , dev ) ;
_store_str ( & pos , & fsp - > old_lv_name , old_lv_name ) ;
2011-02-04 22:14:39 +03:00
_count_fs_ops [ type ] + + ;
2008-11-04 01:14:30 +03:00
dm_list_add ( & _fs_ops , & fsp - > list ) ;
2003-07-05 02:34:56 +04:00
2001-11-09 11:48:22 +03:00
return 1 ;
}
2003-07-05 02:34:56 +04:00
static void _pop_fs_ops ( void )
{
2008-11-04 01:14:30 +03:00
struct dm_list * fsph , * fspht ;
2003-07-05 02:34:56 +04:00
struct fs_op_parms * fsp ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_safe ( fsph , fspht , & _fs_ops ) {
fsp = dm_list_item ( fsph , struct fs_op_parms ) ;
2003-07-05 02:34:56 +04:00
_do_fs_op ( fsp - > type , fsp - > dev_dir , fsp - > vg_name , fsp - > lv_name ,
2010-01-07 22:54:21 +03:00
fsp - > dev , fsp - > old_lv_name , fsp - > check_udev ) ;
2011-02-04 22:14:39 +03:00
_del_fs_op ( fsp ) ;
2003-07-05 02:34:56 +04:00
}
2011-10-14 17:23:47 +04:00
_fs_create = 0 ;
2003-07-05 02:34:56 +04:00
}
static int _fs_op ( fs_op_t type , const char * dev_dir , const char * vg_name ,
2010-01-07 22:54:21 +03:00
const char * lv_name , const char * dev , const char * old_lv_name ,
int check_udev )
2003-07-05 02:34:56 +04:00
{
2018-03-15 12:28:43 +03:00
if ( prioritized_section ( ) ) {
2003-07-05 02:34:56 +04:00
if ( ! _stack_fs_op ( type , dev_dir , vg_name , lv_name , dev ,
2010-01-07 22:54:21 +03:00
old_lv_name , check_udev ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2003-07-05 02:34:56 +04:00
return 1 ;
}
2010-01-07 22:54:21 +03:00
return _do_fs_op ( type , dev_dir , vg_name , lv_name , dev ,
old_lv_name , check_udev ) ;
2003-07-05 02:34:56 +04:00
}
2003-11-12 22:16:48 +03:00
int fs_add_lv ( const struct logical_volume * lv , const char * dev )
2003-07-05 02:34:56 +04:00
{
return _fs_op ( FS_ADD , lv - > vg - > cmd - > dev_dir , lv - > vg - > name , lv - > name ,
2010-01-07 22:54:21 +03:00
dev , " " , lv - > vg - > cmd - > current_settings . udev_rules ) ;
2003-07-05 02:34:56 +04:00
}
2003-11-12 22:16:48 +03:00
int fs_del_lv ( const struct logical_volume * lv )
2003-07-05 02:34:56 +04:00
{
return _fs_op ( FS_DEL , lv - > vg - > cmd - > dev_dir , lv - > vg - > name , lv - > name ,
2010-01-07 22:54:21 +03:00
" " , " " , lv - > vg - > cmd - > current_settings . udev_rules ) ;
2003-07-05 02:34:56 +04:00
}
2010-01-07 22:54:21 +03:00
int fs_del_lv_byname ( const char * dev_dir , const char * vg_name ,
const char * lv_name , int check_udev )
2007-05-15 18:42:01 +04:00
{
2010-01-07 22:54:21 +03:00
return _fs_op ( FS_DEL , dev_dir , vg_name , lv_name , " " , " " , check_udev ) ;
2007-05-15 18:42:01 +04:00
}
2014-09-22 17:50:07 +04:00
int fs_rename_lv ( const struct logical_volume * lv , const char * dev ,
const char * old_vgname , const char * old_lvname )
2002-01-11 02:21:07 +03:00
{
2008-12-19 17:22:48 +03:00
if ( strcmp ( old_vgname , lv - > vg - > name ) ) {
return
2010-01-07 22:54:21 +03:00
( _fs_op ( FS_DEL , lv - > vg - > cmd - > dev_dir , old_vgname ,
old_lvname , " " , " " , lv - > vg - > cmd - > current_settings . udev_rules ) & &
_fs_op ( FS_ADD , lv - > vg - > cmd - > dev_dir , lv - > vg - > name ,
lv - > name , dev , " " , lv - > vg - > cmd - > current_settings . udev_rules ) ) ;
2008-12-19 17:22:48 +03:00
}
2017-07-19 17:16:12 +03:00
return _fs_op ( FS_RENAME , lv - > vg - > cmd - > dev_dir , lv - > vg - > name , lv - > name ,
dev , old_lvname , lv - > vg - > cmd - > current_settings . udev_rules ) ;
2003-07-05 02:34:56 +04:00
}
2002-01-11 02:21:07 +03:00
2003-07-05 02:34:56 +04:00
void fs_unlock ( void )
{
2019-02-06 14:37:47 +03:00
/* Do not allow syncing device name with suspended devices */
if ( ! dm_get_suspended_counter ( ) ) {
2013-01-08 02:30:29 +04:00
log_debug_activation ( " Syncing device names " ) ;
2011-01-10 16:44:39 +03:00
/* Wait for all processed udev devices */
if ( ! dm_udev_wait ( _fs_cookie ) )
stack ;
_fs_cookie = DM_COOKIE_AUTO_CREATE ; /* Reset cookie */
2003-07-05 02:34:56 +04:00
dm_lib_release ( ) ;
_pop_fs_ops ( ) ;
}
2002-01-11 02:21:07 +03:00
}
2011-01-10 16:44:39 +03:00
uint32_t fs_get_cookie ( void )
{
return _fs_cookie ;
}
void fs_set_cookie ( uint32_t cookie )
{
_fs_cookie = cookie ;
}
2011-02-03 04:16:35 +03:00
2011-10-14 17:23:47 +04:00
void fs_set_create ( void )
{
_fs_create = 1 ;
}
2011-02-03 04:16:35 +03:00
int fs_has_non_delete_ops ( void )
{
2011-10-14 17:23:47 +04:00
return _fs_create | | _other_fs_ops ( FS_DEL ) ;
2011-02-03 04:16:35 +03:00
}