2001-11-09 11:48:22 +03:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
* This file is released under the LGPL .
*/
2001-11-12 14:48:31 +03:00
# include <sys/types.h>
# 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>
# include <stdio.h>
# include <string.h>
# include "fs.h"
# include "log.h"
2002-01-21 14:06:32 +03:00
# include "names.h"
2001-11-09 11:48:22 +03:00
2001-11-21 22:32:35 +03:00
# include <libdevmapper.h>
2001-11-12 20:21:25 +03:00
2002-01-11 02:21:07 +03:00
2001-11-09 11:48:22 +03:00
/*
* Lazy programmer : I ' m just going to always try
* and create / remove the vg directory , and not say
* anything if it fails .
*/
2002-01-21 14:06:32 +03:00
static int _mk_dir ( struct volume_group * vg )
2001-11-09 11:48:22 +03:00
{
char vg_path [ PATH_MAX ] ;
2002-01-21 14:06:32 +03:00
if ( ! build_vg_path ( vg_path , sizeof ( vg_path ) ,
vg - > cmd - > dev_dir , vg - > name ) ) {
2002-01-22 22:58:37 +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
log_very_verbose ( " Creating directory %s " , vg_path ) ;
2001-11-09 11:48:22 +03:00
mkdir ( vg_path , 0555 ) ;
2002-01-21 14:06:32 +03:00
return 1 ;
2001-11-09 11:48:22 +03:00
}
2002-01-21 14:06:32 +03:00
static int _rm_dir ( struct volume_group * vg )
2001-11-09 11:48:22 +03:00
{
char vg_path [ PATH_MAX ] ;
2002-01-21 14:06:32 +03:00
if ( ! build_vg_path ( vg_path , sizeof ( vg_path ) ,
vg - > cmd - > dev_dir , vg - > name ) ) {
log_err ( " Couldn't remove volume group directory. " ) ;
return 0 ;
}
2001-12-05 02:20:27 +03:00
log_very_verbose ( " Removing directory %s " , vg_path ) ;
2001-11-09 11:48:22 +03:00
rmdir ( vg_path ) ;
2002-01-21 14:06:32 +03:00
return 1 ;
2001-11-09 11:48:22 +03:00
}
2001-11-12 14:42:29 +03:00
static int _mk_link ( struct logical_volume * lv )
2001-11-09 11:48:22 +03:00
{
char lv_path [ PATH_MAX ] , link_path [ PATH_MAX ] ;
2002-01-22 22:58:37 +03:00
struct stat buf ;
2001-11-09 11:48:22 +03:00
2002-01-21 14:06:32 +03:00
if ( ! build_dm_path ( lv_path , sizeof ( lv_path ) , lv - > vg - > name , lv - > name ) ) {
log_err ( " Couldn't create destination path for "
" logical volume link. " ) ;
return 0 ;
}
if ( ! build_lv_link_path ( link_path , sizeof ( link_path ) ,
lv - > vg - > cmd - > dev_dir ,
lv - > vg - > name , lv - > name ) ) {
log_err ( " Couldn't create source path for "
" logical volume link. " ) ;
return 0 ;
}
2001-11-12 14:42:29 +03:00
2002-01-22 22:58:37 +03:00
if ( ! lstat ( link_path , & buf ) ) {
if ( ! S_ISLNK ( buf . st_mode ) ) {
log_error ( " Symbolic link %s not created: file exists " ,
link_path ) ;
return 0 ;
}
if ( unlink ( link_path ) < 0 ) {
log_sys_error ( " unlink " , link_path ) ;
return 0 ;
}
}
2001-12-05 02:20:27 +03:00
log_very_verbose ( " Linking %s to %s " , link_path , lv_path ) ;
2001-11-12 14:42:29 +03:00
if ( symlink ( lv_path , link_path ) < 0 ) {
2001-11-12 20:21:25 +03:00
log_sys_error ( " symlink " , link_path ) ;
2001-11-12 14:42:29 +03:00
return 0 ;
}
return 1 ;
}
2002-01-11 02:21:07 +03:00
static int _rm_link ( struct logical_volume * lv , const char * lv_name )
2001-11-12 14:42:29 +03:00
{
char link_path [ PATH_MAX ] ;
2002-01-11 02:21:07 +03:00
if ( ! lv_name )
lv_name = lv - > name ;
2002-01-21 14:06:32 +03:00
if ( ! build_lv_link_path ( link_path , sizeof ( link_path ) ,
lv - > vg - > cmd - > dev_dir ,
lv - > vg - > name , lv - > name ) ) {
log_err ( " Couldn't create link path (in order to remove it. " ) ;
return 0 ;
}
2001-11-12 14:42:29 +03:00
2001-12-05 02:20:27 +03:00
log_very_verbose ( " Removing link %s " , link_path ) ;
2001-11-12 14:42:29 +03:00
if ( unlink ( link_path ) < 0 ) {
2001-11-12 20:21:25 +03:00
log_sys_error ( " unlink " , link_path ) ;
2001-11-12 14:42:29 +03:00
return 0 ;
}
return 1 ;
2001-11-09 11:48:22 +03:00
}
2001-11-12 14:42:29 +03:00
int fs_add_lv ( struct logical_volume * lv )
2001-11-09 11:48:22 +03:00
{
2002-01-21 14:06:32 +03:00
if ( ! _mk_dir ( lv - > vg ) | |
! _mk_link ( lv ) ) {
2001-11-09 11:48:22 +03:00
stack ;
return 0 ;
}
return 1 ;
}
int fs_del_lv ( struct logical_volume * lv )
{
2002-01-21 14:06:32 +03:00
if ( ! _rm_link ( lv , NULL ) | |
! _rm_dir ( lv - > vg ) ) {
2001-11-09 11:48:22 +03:00
stack ;
return 0 ;
}
return 1 ;
}
2002-01-11 02:21:07 +03:00
int fs_rename_lv ( const char * old_name , struct logical_volume * lv )
{
if ( ! _rm_link ( lv , old_name ) )
stack ;
if ( ! _mk_link ( lv ) )
stack ;
return 1 ;
}