2001-09-25 16:49:28 +04:00
/*
* Copyright ( C ) 2001 Sistina Software
*
* This LVM library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation ; either
* version 2 of the License , or ( at your option ) any later version .
*
* This LVM library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library ; if not , write to the Free
* Software Foundation , Inc . , 59 Temple Place - Suite 330 , Boston ,
* MA 02111 - 1307 , USA
*
*/
2001-10-06 01:39:30 +04:00
# include "tools.h"
2001-09-25 16:49:28 +04:00
2001-10-08 22:44:22 +04:00
# include <ctype.h>
2001-09-25 16:49:28 +04:00
static int _autobackup = 1 ;
int autobackup_set ( )
{
2001-10-02 21:09:05 +04:00
return _autobackup ;
2001-09-25 16:49:28 +04:00
}
int init_autobackup ( )
{
2001-10-02 21:09:05 +04:00
char * lvm_autobackup ;
2001-09-25 16:49:28 +04:00
2001-10-05 02:53:37 +04:00
if ( arg_count ( autobackup_ARG ) ) {
2001-10-02 21:09:05 +04:00
_autobackup = strcmp ( arg_str_value ( autobackup_ARG , " y " ) , " n " ) ;
2001-10-05 02:53:37 +04:00
return 0 ;
}
_autobackup = 1 ; /* default */
lvm_autobackup = getenv ( " LVM_AUTOBACKUP " ) ;
if ( ! lvm_autobackup )
return 0 ;
2001-09-25 16:49:28 +04:00
2001-10-05 02:53:37 +04:00
log_print ( " using environment variable LVM_AUTOBACKUP "
" to set option A " ) ;
if ( ! strcasecmp ( lvm_autobackup , " no " ) )
_autobackup = 0 ;
else if ( strcasecmp ( lvm_autobackup , " yes " ) ) {
log_error ( " environment variable LVM_AUTOBACKUP has "
" invalid value \" %s \" ! " , lvm_autobackup ) ;
return - 1 ;
2001-09-25 16:49:28 +04:00
}
2001-10-02 21:09:05 +04:00
return 0 ;
2001-09-25 16:49:28 +04:00
}
2001-10-06 01:39:30 +04:00
int do_autobackup ( struct volume_group * vg )
2001-09-25 16:49:28 +04:00
{
2001-10-06 01:39:30 +04:00
/***************
2001-10-02 21:09:05 +04:00
log_verbose ( " Changing lvmtab " ) ;
2001-10-06 01:39:30 +04:00
if ( ( vg_cfgbackup ( vg_name , LVMTAB_DIR , vg ) ) ) {
2001-10-02 21:09:05 +04:00
log_error ( " \" %s \" writing \" %s \" " , lvm_error ( ret ) , LVMTAB ) ;
return LVM_E_VG_CFGBACKUP ;
}
2001-10-06 01:39:30 +04:00
* * * * * * * * * * * * * */
2001-09-25 16:49:28 +04:00
2001-10-02 21:09:05 +04:00
if ( ! autobackup_set ( ) ) {
log_print
2001-10-06 01:39:30 +04:00
( " WARNING: You don't have an automatic backup of %s " ,
vg - > name ) ;
2001-10-02 21:09:05 +04:00
return 0 ;
}
2001-09-25 16:49:28 +04:00
2001-10-06 01:39:30 +04:00
/***************
2001-10-02 21:09:05 +04:00
log_print ( " Creating automatic backup of volume group \" %s \" " , vg_name ) ;
2001-10-06 01:39:30 +04:00
if ( ( vg_cfgbackup ( vg_name , VG_BACKUP_DIR , vg ) ) ) {
2001-10-02 21:09:05 +04:00
log_error ( " \" %s \" writing VG backup of \" %s \" " , lvm_error ( ret ) ,
vg_name ) ;
return LVM_E_VG_CFGBACKUP ;
}
2001-10-06 01:39:30 +04:00
* * * * * * * * * * * * * * */
2001-09-25 16:49:28 +04:00
2001-10-02 21:09:05 +04:00
return 0 ;
2001-09-25 16:49:28 +04:00
}
2001-10-06 01:39:30 +04:00
2001-11-14 21:38:07 +03:00
int process_each_lv ( int argc , char * * argv ,
int ( * process_single ) ( struct volume_group * vg ,
struct logical_volume * lv ) )
{
int opt = 0 ;
int ret_max = 0 ;
int ret = 0 ;
int vg_count = 0 ;
struct list * lvh ;
struct list * vgh , * vgs ;
struct volume_group * vg ;
struct logical_volume * lv ;
char * vg_name ;
if ( argc ) {
log_verbose ( " Using logical volume(s) on command line " ) ;
for ( ; opt < argc ; opt + + ) {
char * lv_name = argv [ opt ] ;
/* does VG exist? */
if ( ! ( vg_name = extract_vgname ( fid , lv_name ) ) ) {
if ( ret_max < ECMD_FAILED )
ret_max = ECMD_FAILED ;
continue ;
}
log_verbose ( " Finding volume group %s " , vg_name ) ;
if ( ! ( vg = fid - > ops - > vg_read ( fid , vg_name ) ) ) {
log_error ( " Volume group %s doesn't exist " ,
vg_name ) ;
if ( ret_max < ECMD_FAILED )
ret_max = ECMD_FAILED ;
continue ;
}
if ( ! ( lvh = find_lv_in_vg ( vg , lv_name ) ) ) {
log_error ( " Can't find logical volume %s "
" in volume group %s " ,
lv_name , vg_name ) ;
if ( ret_max < ECMD_FAILED )
ret_max = ECMD_FAILED ;
continue ;
}
lv = & list_item ( lvh , struct lv_list ) - > lv ;
if ( ( ret = process_single ( vg , lv ) ) > ret_max )
ret_max = ret ;
}
} else {
log_verbose ( " Finding all logical volume(s) " ) ;
if ( ! ( vgs = fid - > ops - > get_vgs ( fid ) ) ) {
log_error ( " No volume groups found " ) ;
return ECMD_FAILED ;
}
list_iterate ( vgh , vgs ) {
vg_name = list_item ( vgh , struct name_list ) - > name ;
if ( ! ( vg = fid - > ops - > vg_read ( fid , vg_name ) ) ) {
log_error ( " Volume group %s not found " , vg_name ) ;
if ( ret_max < ECMD_FAILED )
ret_max = ECMD_FAILED ;
continue ;
}
/* FIXME Export-handling */
if ( vg - > status & EXPORTED_VG ) {
log_error ( " Volume group %s is exported " ,
vg_name ) ;
if ( ret_max < ECMD_FAILED )
ret_max = ECMD_FAILED ;
continue ;
}
list_iterate ( lvh , & vg - > lvs ) {
lv = & list_item ( lvh , struct lv_list ) - > lv ;
ret = process_single ( vg , lv ) ;
if ( ret > ret_max )
ret_max = ret ;
}
vg_count + + ;
}
}
return ret_max ;
}
2001-10-06 01:39:30 +04:00
int process_each_vg ( int argc , char * * argv ,
int ( * process_single ) ( const char * vg_name ) )
{
int opt = 0 ;
int ret_max = 0 ;
int ret = 0 ;
2001-10-31 15:47:01 +03:00
struct list * vgh ;
2001-11-14 21:38:07 +03:00
struct list * vgs ;
2001-10-06 01:39:30 +04:00
if ( argc ) {
log_verbose ( " Using volume group(s) on command line " ) ;
for ( ; opt < argc ; opt + + )
if ( ( ret = process_single ( argv [ opt ] ) ) > ret_max )
ret_max = ret ;
} else {
log_verbose ( " Finding all volume group(s) " ) ;
2001-11-14 21:38:07 +03:00
if ( ! ( vgs = fid - > ops - > get_vgs ( fid ) ) ) {
2001-10-06 01:39:30 +04:00
log_error ( " No volume groups found " ) ;
return ECMD_FAILED ;
}
2001-11-14 21:38:07 +03:00
list_iterate ( vgh , vgs ) {
ret =
process_single ( list_item ( vgh , struct name_list ) - >
name ) ;
2001-10-06 01:39:30 +04:00
if ( ret > ret_max )
ret_max = ret ;
}
}
return ret_max ;
}
2001-10-08 22:44:22 +04:00
2001-10-12 01:35:55 +04:00
int process_each_pv ( int argc , char * * argv , struct volume_group * vg ,
int ( * process_single ) ( struct volume_group * vg ,
struct physical_volume * pv ) )
{
int opt = 0 ;
int ret_max = 0 ;
int ret = 0 ;
2001-10-31 15:47:01 +03:00
struct list * pvh ;
2001-10-12 01:35:55 +04:00
if ( argc ) {
log_verbose ( " Using physical volume(s) on command line " ) ;
for ( ; opt < argc ; opt + + ) {
if ( ! ( pvh = find_pv_in_vg ( vg , argv [ opt ] ) ) ) {
log_error ( " Physical Volume %s not found in "
" Volume Group %s " , argv [ opt ] ,
vg - > name ) ;
continue ;
}
2001-11-14 21:38:07 +03:00
ret = process_single ( vg ,
& list_item ( pvh ,
struct pv_list ) - > pv ) ;
2001-10-12 01:35:55 +04:00
if ( ret > ret_max )
ret_max = ret ;
}
} else {
log_verbose ( " Using all physical volume(s) in volume group " ) ;
2001-10-31 15:47:01 +03:00
list_iterate ( pvh , & vg - > pvs ) {
2001-11-14 21:38:07 +03:00
ret = process_single ( vg ,
& list_item ( pvh ,
struct pv_list ) - > pv ) ;
2001-10-12 01:35:55 +04:00
if ( ret > ret_max )
ret_max = ret ;
}
}
return ret_max ;
}
2001-10-08 22:44:22 +04:00
int is_valid_chars ( char * n )
{
register char c ;
while ( ( c = * n + + ) )
2001-10-12 01:35:55 +04:00
if ( ! isalnum ( c ) & & c ! = ' . ' & & c ! = ' _ ' & & c ! = ' - ' & & c ! = ' + ' )
2001-10-08 22:44:22 +04:00
return 0 ;
return 1 ;
}
2001-11-12 18:10:01 +03:00
char * extract_vgname ( struct format_instance * fi , char * lv_name )
2001-11-14 21:38:07 +03:00
{
2001-10-29 16:52:23 +03:00
char * vg_name = lv_name ;
2001-11-06 22:02:26 +03:00
char * st ;
2001-11-12 18:10:01 +03:00
char * dev_dir = fi - > cmd - > dev_dir ;
2001-10-29 16:52:23 +03:00
/* Path supplied? */
2001-11-06 22:02:26 +03:00
if ( vg_name & & strchr ( vg_name , ' / ' ) ) {
2001-10-29 16:52:23 +03:00
/* Strip prefix (optional) */
2001-11-12 18:10:01 +03:00
if ( ! strncmp ( vg_name , dev_dir , strlen ( dev_dir ) ) )
vg_name + = strlen ( dev_dir ) ;
2001-10-29 16:52:23 +03:00
/* Require exactly one slash */
2001-10-29 21:23:35 +03:00
/* FIXME But allow for consecutive slashes */
2001-10-29 16:52:23 +03:00
if ( ! ( st = strchr ( vg_name , ' / ' ) ) | | ( strchr ( st + 1 , ' / ' ) ) ) {
2001-11-14 21:38:07 +03:00
log_error ( " %s: Invalid path for Logical Volume " ,
lv_name ) ;
2001-10-29 16:52:23 +03:00
return 0 ;
}
2001-11-12 18:10:01 +03:00
vg_name = pool_strdup ( fid - > cmd - > mem , vg_name ) ;
2001-10-29 16:52:23 +03:00
if ( ! vg_name ) {
log_error ( " Allocation of vg_name failed " ) ;
return 0 ;
}
* strchr ( vg_name , ' / ' ) = ' \0 ' ;
return vg_name ;
}
2001-11-06 22:02:26 +03:00
2001-11-12 18:10:01 +03:00
if ( ! ( vg_name = default_vgname ( fid ) ) ) {
2001-11-06 22:02:26 +03:00
if ( lv_name )
2001-11-14 21:38:07 +03:00
log_error ( " Path required for Logical Volume %s " ,
lv_name ) ;
2001-11-06 22:02:26 +03:00
return 0 ;
}
2001-11-14 21:38:07 +03:00
2001-11-06 22:02:26 +03:00
return vg_name ;
}
2001-11-12 18:10:01 +03:00
char * default_vgname ( struct format_instance * fi )
2001-11-06 22:02:26 +03:00
{
char * vg_path ;
2001-11-12 18:10:01 +03:00
char * dev_dir = fi - > cmd - > dev_dir ;
2001-11-06 22:02:26 +03:00
2001-10-29 16:52:23 +03:00
/* Take default VG from environment? */
2001-11-14 21:38:07 +03:00
vg_path = getenv ( " LVM_VG_NAME " ) ;
2001-11-06 22:02:26 +03:00
if ( ! vg_path )
2001-10-29 16:52:23 +03:00
return 0 ;
/* Strip prefix (optional) */
2001-11-12 18:10:01 +03:00
if ( ! strncmp ( vg_path , dev_dir , strlen ( dev_dir ) ) )
vg_path + = strlen ( dev_dir ) ;
2001-10-29 16:52:23 +03:00
if ( strchr ( vg_path , ' / ' ) ) {
2001-11-14 21:38:07 +03:00
log_error ( " Environment Volume Group in LVM_VG_NAME invalid: %s " ,
2001-10-29 16:52:23 +03:00
vg_path ) ;
return 0 ;
}
2001-11-12 18:10:01 +03:00
return pool_strdup ( fid - > cmd - > mem , vg_path ) ;
2001-10-29 16:52:23 +03:00
}