2001-11-09 11:48:22 +03:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
* This file is released under the LGPL .
*/
2002-02-11 23:50:53 +03:00
# include "fs.h"
# include "log.h"
# include "toolcontext.h"
2002-02-26 14:49:17 +03:00
# include "lvm-string.h"
2002-02-11 23:50:53 +03:00
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>
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-02-26 19:08:22 +03:00
if ( lvm_snprintf ( vg_path , sizeof ( vg_path ) , " %s%s " ,
2002-02-26 14:49:17 +03:00
vg - > cmd - > dev_dir , vg - > name ) = = - 1 ) {
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-02-26 19:08:22 +03:00
if ( lvm_snprintf ( vg_path , sizeof ( vg_path ) , " %s%s " ,
2002-02-26 14:49:17 +03:00
vg - > cmd - > dev_dir , vg - > name ) = = - 1 ) {
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 ( " 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
}
2002-02-26 14:49:17 +03:00
static int _mk_link ( struct logical_volume * lv , const char * dev )
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-02-26 19:08:22 +03:00
if ( lvm_snprintf ( lv_path , sizeof ( lv_path ) , " %s%s/%s " ,
2002-02-26 14:49:17 +03:00
lv - > vg - > cmd - > dev_dir , lv - > vg - > name , lv - > name ) = = - 1 ) {
log_error ( " Couldn't create source pathname for "
" logical volume link %s " , lv - > name ) ;
2002-01-21 14:06:32 +03:00
return 0 ;
}
2002-02-26 14:49:17 +03:00
if ( lvm_snprintf ( link_path , sizeof ( link_path ) , " %s/%s " ,
dm_dir ( ) , dev ) = = - 1 ) {
log_error ( " Couldn't create destination pathname for "
" 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
2002-02-26 14:49:17 +03:00
if ( ! lstat ( lv_path , & buf ) ) {
2002-01-22 22:58:37 +03:00
if ( ! S_ISLNK ( buf . st_mode ) ) {
log_error ( " Symbolic link %s not created: file exists " ,
link_path ) ;
return 0 ;
}
2002-02-26 14:49:17 +03:00
if ( unlink ( lv_path ) < 0 ) {
log_sys_error ( " unlink " , lv_path ) ;
2002-01-22 22:58:37 +03:00
return 0 ;
}
}
2002-02-26 19:08:22 +03:00
log_very_verbose ( " Linking %s -> %s " , lv_path , link_path ) ;
2002-02-26 14:49:17 +03:00
if ( symlink ( link_path , lv_path ) < 0 ) {
log_sys_error ( " symlink " , lv_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
{
2002-01-25 23:17:44 +03:00
struct stat buf ;
2002-02-26 14:49:17 +03:00
char lv_path [ PATH_MAX ] ;
2001-11-12 14:42:29 +03:00
2002-02-26 19:08:22 +03:00
if ( lvm_snprintf ( lv_path , sizeof ( lv_path ) , " %s%s/%s " ,
2002-02-26 14:49:17 +03:00
lv - > vg - > cmd - > dev_dir , lv - > 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
2002-02-26 14:49:17 +03:00
log_very_verbose ( " Removing link %s " , lv_path ) ;
if ( lstat ( lv_path , & buf ) | | ! S_ISLNK ( buf . st_mode ) ) {
log_error ( " %s not symbolic link - not removing " , lv_path ) ;
return 0 ;
2002-01-25 23:17:44 +03:00
}
2002-02-26 14:49:17 +03:00
if ( unlink ( lv_path ) < 0 ) {
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
}
2002-02-26 14:49:17 +03:00
int fs_add_lv ( struct logical_volume * lv , const char * dev )
2001-11-09 11:48:22 +03:00
{
2002-01-21 14:06:32 +03:00
if ( ! _mk_dir ( lv - > vg ) | |
2002-02-26 14:49:17 +03:00
! _mk_link ( lv , dev ) ) {
2001-11-09 11:48:22 +03:00
stack ;
return 0 ;
}
return 1 ;
}
int fs_del_lv ( struct logical_volume * lv )
{
2002-02-26 14:49:17 +03:00
if ( ! _rm_link ( lv , lv - > name ) | |
2002-01-21 14:06:32 +03:00
! _rm_dir ( lv - > vg ) ) {
2001-11-09 11:48:22 +03:00
stack ;
return 0 ;
}
return 1 ;
}
2002-02-26 14:49:17 +03:00
int fs_rename_lv ( struct logical_volume * lv ,
const char * dev , const char * old_name )
2002-01-11 02:21:07 +03:00
{
if ( ! _rm_link ( lv , old_name ) )
stack ;
2002-02-26 14:49:17 +03:00
if ( ! _mk_link ( lv , dev ) )
2002-01-11 02:21:07 +03:00
stack ;
return 1 ;
}