2002-01-03 18:46:48 +03:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
* This file is released under the GPL .
*/
2002-01-07 14:12:11 +03:00
# include "log.h"
2002-01-03 18:46:48 +03:00
# include "archive.h"
# include "dbg_malloc.h"
2002-01-07 14:12:11 +03:00
# include "format-text.h"
# include "lvm-string.h"
2002-01-09 16:17:14 +03:00
# include "toollib.h"
2002-01-07 14:12:11 +03:00
2002-01-11 02:21:07 +03:00
# include "tools.h"
2002-01-09 22:16:48 +03:00
# include <unistd.h>
2002-01-07 14:12:11 +03:00
# include <limits.h>
2002-01-03 18:46:48 +03:00
static struct {
int enabled ;
char * dir ;
unsigned int keep_days ;
unsigned int keep_number ;
} _archive_params ;
2002-02-12 00:00:35 +03:00
int archive_init ( const char * dir , unsigned int keep_days , unsigned int keep_min )
2002-01-03 18:46:48 +03:00
{
2002-01-09 16:17:14 +03:00
_archive_params . dir = NULL ;
if ( ! * dir )
return 1 ;
if ( ! create_dir ( dir ) )
return 0 ;
2002-01-03 18:46:48 +03:00
if ( ! ( _archive_params . dir = dbg_strdup ( dir ) ) ) {
2002-01-09 16:17:14 +03:00
log_error ( " Couldn't copy archive directory name. " ) ;
2002-01-03 18:46:48 +03:00
return 0 ;
}
_archive_params . keep_days = keep_days ;
2002-01-07 14:12:11 +03:00
_archive_params . keep_number = keep_min ;
2002-01-03 18:46:48 +03:00
_archive_params . enabled = 1 ;
return 1 ;
}
void archive_exit ( void )
{
2002-01-09 16:17:14 +03:00
if ( _archive_params . dir )
dbg_free ( _archive_params . dir ) ;
2002-01-03 18:46:48 +03:00
memset ( & _archive_params , 0 , sizeof ( _archive_params ) ) ;
}
2002-01-07 12:05:31 +03:00
void archive_enable ( int flag )
2002-01-03 18:46:48 +03:00
{
2002-01-07 12:05:31 +03:00
_archive_params . enabled = flag ;
2002-01-03 18:46:48 +03:00
}
2002-02-08 14:13:47 +03:00
static char * _build_desc ( struct pool * mem , const char * line , int before )
{
size_t len = strlen ( line ) + 32 ;
char * buffer ;
if ( ! ( buffer = pool_zalloc ( mem , strlen ( line ) + 32 ) ) ) {
stack ;
return NULL ;
}
if ( snprintf ( buffer , len ,
" Created %s executing '%s' " ,
before ? " *before* " : " *after* " , line ) < 0 ) {
stack ;
return NULL ;
}
return buffer ;
}
2002-01-03 18:46:48 +03:00
static int __archive ( struct volume_group * vg )
{
2002-02-08 14:13:47 +03:00
char * desc ;
if ( ! ( desc = _build_desc ( vg - > cmd - > mem , vg - > cmd - > cmd_line , 1 ) ) ) {
stack ;
return 0 ;
}
2002-01-03 18:46:48 +03:00
2002-02-08 14:58:18 +03:00
return archive_vg ( vg , _archive_params . dir , desc ,
_archive_params . keep_days ,
_archive_params . keep_number ) ;
2002-01-03 18:46:48 +03:00
}
int archive ( struct volume_group * vg )
{
2002-01-09 16:17:14 +03:00
if ( ! _archive_params . enabled | | ! _archive_params . dir )
2002-01-03 18:46:48 +03:00
return 1 ;
if ( test_mode ( ) ) {
log_print ( " Test mode: Skipping archiving of volume group. " ) ;
return 1 ;
}
2002-01-30 18:04:48 +03:00
log_verbose ( " Archiving volume group \" %s \" metadata. " , vg - > name ) ;
2002-01-03 18:46:48 +03:00
if ( ! __archive ( vg ) ) {
2002-01-30 18:04:48 +03:00
log_error ( " Volume group \" %s \" metadata archive failed. " ,
2002-01-09 16:17:14 +03:00
vg - > name ) ;
2002-01-03 18:46:48 +03:00
return 0 ;
}
return 1 ;
}
2002-02-11 23:50:53 +03:00
int archive_display ( struct cmd_context * cmd , const char * vg_name )
2002-02-11 14:43:17 +03:00
{
2002-02-11 23:50:53 +03:00
return archive_list ( cmd , cmd - > um , _archive_params . dir , vg_name ) ;
2002-02-11 14:43:17 +03:00
}
2002-01-03 18:46:48 +03:00
static struct {
int enabled ;
char * dir ;
} _backup_params ;
int backup_init ( const char * dir )
{
2002-01-09 16:17:14 +03:00
_backup_params . dir = NULL ;
if ( ! * dir )
return 1 ;
if ( ! create_dir ( dir ) )
return 0 ;
2002-01-03 18:46:48 +03:00
if ( ! ( _backup_params . dir = dbg_strdup ( dir ) ) ) {
2002-01-09 16:17:14 +03:00
log_error ( " Couldn't copy backup directory name. " ) ;
2002-01-03 18:46:48 +03:00
return 0 ;
}
return 1 ;
}
void backup_exit ( void )
{
2002-01-09 16:17:14 +03:00
if ( _backup_params . dir )
dbg_free ( _backup_params . dir ) ;
2002-01-07 14:12:11 +03:00
memset ( & _backup_params , 0 , sizeof ( _backup_params ) ) ;
2002-01-03 18:46:48 +03:00
}
2002-01-07 12:05:31 +03:00
void backup_enable ( int flag )
{
_backup_params . enabled = flag ;
}
2002-01-03 18:46:48 +03:00
static int __backup ( struct volume_group * vg )
{
int r ;
struct format_instance * tf ;
char name [ PATH_MAX ] ;
2002-02-08 14:13:47 +03:00
char * desc ;
if ( ! ( desc = _build_desc ( vg - > cmd - > mem , vg - > cmd - > cmd_line , 0 ) ) ) {
stack ;
return 0 ;
}
2002-01-03 18:46:48 +03:00
if ( lvm_snprintf ( name , sizeof ( name ) , " %s/%s " ,
_backup_params . dir , vg - > name ) < 0 ) {
2002-01-09 16:17:14 +03:00
log_error ( " Failed to generate volume group metadata backup "
" filename. " ) ;
2002-01-03 18:46:48 +03:00
return 0 ;
}
2002-01-30 18:04:48 +03:00
log_verbose ( " Creating volume group backup \" %s \" " , name ) ;
2002-01-09 16:17:14 +03:00
2002-02-11 23:50:53 +03:00
if ( ! ( tf = text_format_create ( vg - > cmd , name , vg - > cmd - > um , desc ) ) ) {
2002-01-09 16:17:14 +03:00
stack ;
2002-01-03 18:46:48 +03:00
return 0 ;
}
if ( ! ( r = tf - > ops - > vg_write ( tf , vg ) ) )
stack ;
tf - > ops - > destroy ( tf ) ;
return r ;
}
int backup ( struct volume_group * vg )
{
2002-01-09 16:17:14 +03:00
if ( ! _backup_params . enabled | | ! _backup_params . dir ) {
log_print ( " WARNING: This metadata update is NOT backed up " ) ;
2002-01-03 18:46:48 +03:00
return 1 ;
2002-01-09 16:17:14 +03:00
}
2002-01-03 18:46:48 +03:00
if ( test_mode ( ) ) {
log_print ( " Test mode: Skipping volume group backup. " ) ;
return 1 ;
}
if ( ! __backup ( vg ) ) {
2002-01-09 16:17:14 +03:00
log_error ( " Backup of volume group %s metadata failed. " ,
vg - > name ) ;
2002-01-03 18:46:48 +03:00
return 0 ;
}
return 1 ;
}
2002-01-09 17:07:49 +03:00
int backup_remove ( const char * vg_name )
{
char path [ PATH_MAX ] ;
if ( lvm_snprintf ( path , sizeof ( path ) , " %s/%s " ,
_backup_params . dir , vg_name ) < 0 ) {
log_err ( " Failed to generate backup filename (for removal). " ) ;
return 0 ;
}
/*
* Let this fail silently .
*/
unlink ( path ) ;
return 1 ;
}
2002-01-11 02:21:07 +03:00
static struct volume_group * _read_vg ( struct cmd_context * cmd ,
2002-02-12 00:00:35 +03:00
const char * vg_name , const char * file )
2002-01-10 17:27:47 +03:00
{
2002-01-11 02:21:07 +03:00
struct volume_group * vg ;
2002-01-10 17:27:47 +03:00
struct format_instance * tf ;
2002-02-12 00:00:35 +03:00
if ( ! ( tf = text_format_create ( cmd , file , cmd - > um , cmd - > cmd_line ) ) ) {
2002-01-10 17:27:47 +03:00
log_error ( " Couldn't create text format object. " ) ;
2002-02-08 14:13:47 +03:00
return NULL ;
2002-01-10 17:27:47 +03:00
}
2002-01-11 02:21:07 +03:00
if ( ! ( vg = tf - > ops - > vg_read ( tf , vg_name ) ) )
2002-01-10 17:27:47 +03:00
stack ;
tf - > ops - > destroy ( tf ) ;
2002-01-11 02:21:07 +03:00
return vg ;
2002-01-10 17:27:47 +03:00
}
2002-02-12 00:00:35 +03:00
int backup_restore_from_file ( struct cmd_context * cmd , const char * vg_name ,
const char * file )
2002-01-10 17:27:47 +03:00
{
struct volume_group * vg ;
/*
* Read in the volume group .
*/
2002-02-11 23:50:53 +03:00
if ( ! ( vg = _read_vg ( cmd , vg_name , file ) ) ) {
2002-01-10 17:27:47 +03:00
stack ;
return 0 ;
}
/*
* Check that those pv ' s referenced in the backup are
* currently orphans or members of the vg . s
*/
/*
* FIXME : waiting for label code .
*/
/*
* Write the vg .
*/
2002-02-11 23:50:53 +03:00
if ( ! cmd - > fid - > ops - > vg_write ( cmd - > fid , vg ) ) {
2002-01-10 17:27:47 +03:00
stack ;
return 0 ;
}
return 1 ;
}
2002-02-11 23:50:53 +03:00
int backup_restore ( struct cmd_context * cmd , const char * vg_name )
2002-01-10 17:27:47 +03:00
{
char path [ PATH_MAX ] ;
if ( lvm_snprintf ( path , sizeof ( path ) , " %s/%s " ,
_backup_params . dir , vg_name ) < 0 ) {
log_err ( " Failed to generate backup filename (for restore). " ) ;
return 0 ;
}
2002-02-11 23:50:53 +03:00
return backup_restore_from_file ( cmd , vg_name , path ) ;
2002-01-10 17:27:47 +03:00
}