2001-11-21 12:20:05 +03:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
* This file is released under the LGPL .
*/
# include "format-text.h"
2002-01-07 12:16:20 +03:00
# include "import-export.h"
2001-11-21 12:20:05 +03:00
2002-01-09 22:16:48 +03:00
# include "lvm-file.h"
2001-11-21 12:20:05 +03:00
# include "log.h"
# include "pool.h"
# include "config.h"
# include "hash.h"
2002-01-09 22:16:48 +03:00
# include <unistd.h>
# include <sys/types.h>
# include <sys/file.h>
# include <limits.h>
2001-11-21 12:20:05 +03:00
/*
2002-01-07 12:05:31 +03:00
* NOTE : Currently there can be only one vg per file .
2001-11-21 12:20:05 +03:00
*/
2002-01-07 12:05:31 +03:00
static void _not_written ( const char * cmd )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
log_err ( " The text format is lacking an implementation for '%s' " , cmd ) ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static struct list * _get_vgs ( struct format_instance * fi )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
_not_written ( " _get_vgs " ) ;
return NULL ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static struct list * _get_pvs ( struct format_instance * fi )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
_not_written ( " _get_vgs " ) ;
return NULL ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static struct physical_volume * _pv_read ( struct format_instance * fi ,
const char * pv_name )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
_not_written ( " _get_vgs " ) ;
return NULL ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static int _pv_setup ( struct format_instance * fi , struct physical_volume * pv ,
struct volume_group * vg )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
_not_written ( " _get_vgs " ) ;
2002-01-07 12:16:20 +03:00
return 0 ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static int _pv_write ( struct format_instance * fi , struct physical_volume * pv )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
_not_written ( " _get_vgs " ) ;
2002-01-07 12:16:20 +03:00
return 0 ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static int _vg_setup ( struct format_instance * fi , struct volume_group * vg )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
_not_written ( " _get_vgs " ) ;
2002-01-07 12:16:20 +03:00
return 0 ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static struct volume_group * _vg_read ( struct format_instance * fi ,
const char * vg_name )
2001-11-21 12:20:05 +03:00
{
2002-01-10 17:27:47 +03:00
char * file = ( char * ) fi - > private ;
struct volume_group * vg ;
if ( ! ( vg = text_vg_import ( fi - > cmd , file ) ) ) {
stack ;
return NULL ;
}
/*
* Currently you can only have a single volume group per
* text file ( this restriction may remain ) . We need to
* check that it contains the correct volume group .
*/
if ( strcmp ( vg_name , vg - > name ) ) {
pool_free ( fi - > cmd - > mem , vg ) ;
log_err ( " '%s' does not contain volume group '%s'. " ,
file , vg_name ) ;
return NULL ;
}
return vg ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static int _vg_write ( struct format_instance * fi , struct volume_group * vg )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
FILE * fp ;
2002-01-10 17:27:47 +03:00
int fd ;
2002-01-09 22:16:48 +03:00
char * slash ;
2002-01-07 12:05:31 +03:00
char * file = ( char * ) fi - > private ;
2002-01-09 22:16:48 +03:00
char temp_file [ PATH_MAX ] , temp_dir [ PATH_MAX ] ;
slash = rindex ( file , ' / ' ) ;
2001-11-21 12:20:05 +03:00
2002-01-09 22:16:48 +03:00
if ( slash = = 0 )
strcpy ( temp_dir , " . " ) ;
else if ( slash - file < PATH_MAX ) {
strncpy ( temp_dir , file , slash - file ) ;
temp_dir [ slash - file ] = ' \0 ' ;
2002-01-10 17:27:47 +03:00
2002-01-09 22:16:48 +03:00
} else {
log_error ( " Text format failed to determine directory. " ) ;
return 0 ;
}
if ( ! create_temp_name ( temp_dir , temp_file , sizeof ( temp_file ) , & fd ) ) {
log_err ( " Couldn't create temporary text file name. " ) ;
return 0 ;
}
if ( ! ( fp = fdopen ( fd , " w " ) ) ) {
log_sys_error ( " fdopen " , temp_file ) ;
close ( fd ) ;
2002-01-07 12:05:31 +03:00
return 0 ;
}
2001-11-21 12:20:05 +03:00
2002-01-07 12:05:31 +03:00
if ( ! text_vg_export ( fp , vg ) ) {
2002-01-09 22:16:48 +03:00
log_error ( " Failed to write metadata to %s. " , temp_file ) ;
2002-01-09 16:07:03 +03:00
fclose ( fp ) ;
return 0 ;
}
2002-01-09 22:16:48 +03:00
if ( fclose ( fp ) ) {
2002-01-09 16:07:03 +03:00
log_sys_error ( " fclose " , file ) ;
2002-01-07 12:05:31 +03:00
return 0 ;
}
2001-11-21 12:20:05 +03:00
2002-01-09 22:16:48 +03:00
if ( rename ( temp_file , file ) ) {
log_error ( " %s: rename to %s failed: %s " , temp_file , file ,
strerror ( errno ) ) ;
return 0 ;
}
2002-01-07 12:05:31 +03:00
return 1 ;
2001-11-21 12:20:05 +03:00
}
2002-01-07 14:12:11 +03:00
static void _destroy ( struct format_instance * fi )
2001-11-21 12:20:05 +03:00
{
2002-01-10 17:27:47 +03:00
dbg_free ( fi - > private ) ;
dbg_free ( fi ) ;
2001-11-21 12:20:05 +03:00
}
static struct format_handler _text_handler = {
get_vgs : _get_vgs ,
get_pvs : _get_pvs ,
pv_read : _pv_read ,
pv_setup : _pv_setup ,
pv_write : _pv_write ,
vg_setup : _vg_setup ,
vg_read : _vg_read ,
vg_write : _vg_write ,
destroy : _destroy
} ;
2002-01-07 12:05:31 +03:00
struct format_instance * text_format_create ( struct cmd_context * cmd ,
const char * file )
2001-11-21 12:20:05 +03:00
{
2002-01-07 12:05:31 +03:00
const char * no_alloc = " Couldn't allocate text format object. " ;
2001-11-21 12:20:05 +03:00
struct format_instance * fi ;
2002-01-07 12:16:20 +03:00
char * path ;
2001-11-21 12:20:05 +03:00
2002-01-10 17:27:47 +03:00
if ( ! ( fi = dbg_malloc ( sizeof ( * fi ) ) ) ) {
2002-01-07 12:05:31 +03:00
log_err ( no_alloc ) ;
2001-11-21 12:20:05 +03:00
return NULL ;
}
2002-01-10 17:27:47 +03:00
if ( ! ( path = dbg_strdup ( file ) ) ) {
dbg_free ( fi ) ;
2002-01-07 12:05:31 +03:00
log_err ( no_alloc ) ;
return NULL ;
2001-11-21 12:20:05 +03:00
}
fi - > cmd = cmd ;
2002-01-07 12:16:20 +03:00
fi - > ops = & _text_handler ;
fi - > private = path ;
2001-11-21 12:20:05 +03:00
return fi ;
}