2002-01-03 18:46:48 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2007 Red Hat , Inc . All rights reserved .
2002-01-03 18:46:48 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2002-01-03 18:46:48 +03:00
*/
2005-05-17 17:46:38 +04:00
# include "lib.h"
# include "archiver.h"
# include "format-text.h"
# include "lvm-string.h"
# include "lvmcache.h"
2013-09-18 13:22:49 +04:00
# include "lvmetad.h"
2014-09-19 17:31:41 +04:00
# include "memlock.h"
2005-05-17 17:46:38 +04:00
# include "toolcontext.h"
2009-04-22 13:39:45 +04:00
# include "locking.h"
2002-01-11 02:21:07 +03:00
2005-05-17 17:46:38 +04:00
# include <unistd.h>
struct archive_params {
2002-01-03 18:46:48 +03:00
int enabled ;
char * dir ;
unsigned int keep_days ;
unsigned int keep_number ;
2005-05-17 17:46:38 +04:00
} ;
2002-01-03 18:46:48 +03:00
2005-05-17 17:46:38 +04:00
struct backup_params {
2003-09-15 19:03:22 +04:00
int enabled ;
char * dir ;
2005-05-17 17:46:38 +04:00
} ;
2003-09-15 19:03:22 +04:00
2005-05-17 17:46:38 +04:00
int archive_init ( struct cmd_context * cmd , const char * dir ,
2008-12-11 06:32:56 +03:00
unsigned int keep_days , unsigned int keep_min ,
int enabled )
2002-01-03 18:46:48 +03:00
{
2010-09-09 17:07:13 +04:00
archive_exit ( cmd ) ;
2005-10-17 03:03:59 +04:00
if ( ! ( cmd - > archive_params = dm_pool_zalloc ( cmd - > libmem ,
2005-05-24 21:37:39 +04:00
sizeof ( * cmd - > archive_params ) ) ) ) {
2005-05-17 17:46:38 +04:00
log_error ( " archive_params alloc failed " ) ;
return 0 ;
}
cmd - > archive_params - > dir = NULL ;
2002-01-09 16:17:14 +03:00
if ( ! * dir )
return 1 ;
2005-10-17 03:03:59 +04:00
if ( ! ( cmd - > archive_params - > dir = dm_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 ;
}
2005-05-17 17:46:38 +04:00
cmd - > archive_params - > keep_days = keep_days ;
cmd - > archive_params - > keep_number = keep_min ;
2008-12-11 06:32:56 +03:00
archive_enable ( cmd , enabled ) ;
2005-05-17 17:46:38 +04:00
2002-01-03 18:46:48 +03:00
return 1 ;
}
2005-05-17 17:46:38 +04:00
void archive_exit ( struct cmd_context * cmd )
2002-01-03 18:46:48 +03:00
{
2009-07-09 02:18:32 +04:00
if ( ! cmd - > archive_params )
return ;
2011-01-28 13:16:04 +03:00
dm_free ( cmd - > archive_params - > dir ) ;
2005-05-17 17:46:38 +04:00
memset ( cmd - > archive_params , 0 , sizeof ( * cmd - > archive_params ) ) ;
2002-01-03 18:46:48 +03:00
}
2005-05-17 17:46:38 +04:00
void archive_enable ( struct cmd_context * cmd , int flag )
2002-01-03 18:46:48 +03:00
{
2005-05-17 17:46:38 +04:00
cmd - > archive_params - > enabled = flag ;
2002-01-03 18:46:48 +03:00
}
2005-10-17 03:03:59 +04:00
static char * _build_desc ( struct dm_pool * mem , const char * line , int before )
2002-02-08 14:13:47 +03:00
{
size_t len = strlen ( line ) + 32 ;
char * buffer ;
2012-02-08 16:50:10 +04:00
if ( ! ( buffer = dm_pool_alloc ( mem , len ) ) ) {
log_error ( " Failed to allocate desc. " ) ;
return NULL ;
}
2002-02-08 14:13:47 +03:00
2012-02-08 16:50:10 +04:00
if ( dm_snprintf ( buffer , len , " Created %s executing '%s' " ,
before ? " *before* " : " *after* " , line ) < 0 ) {
log_error ( " Failed to build desc. " ) ;
return NULL ;
}
2002-02-08 14:13:47 +03:00
return buffer ;
}
2015-12-03 19:32:47 +03:00
static int _archive ( struct volume_group * vg , int compulsory )
2002-01-03 18:46:48 +03:00
{
2002-02-08 14:13:47 +03:00
char * desc ;
2014-01-17 03:02:59 +04:00
/* Don't archive orphan VGs. */
if ( is_orphan_vg ( vg - > name ) )
return 1 ;
2013-06-30 20:01:19 +04:00
if ( vg_is_archived ( vg ) )
return 1 ; /* VG has been already archived */
2013-07-02 13:07:15 +04:00
if ( ! vg - > cmd - > archive_params - > enabled | | ! vg - > cmd - > archive_params - > dir ) {
vg - > status | = ARCHIVED_VG ;
2002-01-03 18:46:48 +03:00
return 1 ;
2013-07-02 13:07:15 +04:00
}
2002-01-03 18:46:48 +03:00
if ( test_mode ( ) ) {
2013-07-02 13:07:15 +04:00
vg - > status | = ARCHIVED_VG ;
2002-11-18 17:04:08 +03:00
log_verbose ( " Test mode: Skipping archiving of volume group. " ) ;
2002-01-03 18:46:48 +03:00
return 1 ;
}
2015-12-03 19:32:47 +03:00
if ( ! dm_create_dir ( vg - > cmd - > archive_params - > dir ) ) {
/* FIXME: !compulsory logs error here */
log_error ( " Cannot create archiving directory %s. " ,
vg - > cmd - > archive_params - > dir ) ;
return compulsory ? 0 : 1 ;
}
2005-05-03 21:31:56 +04:00
2005-05-17 17:44:02 +04:00
/* Trap a read-only file system */
2008-01-30 17:00:02 +03:00
if ( ( access ( vg - > cmd - > archive_params - > dir , R_OK | W_OK | X_OK ) = = - 1 ) & &
2015-12-03 19:32:47 +03:00
( errno = = EROFS ) ) {
/* FIXME: !compulsory logs error here */
log_error ( " Cannot archive volume group metadata for %s to read-only filesystem. " ,
vg - > name ) ;
return compulsory ? 0 : 1 ;
}
2005-05-17 17:44:02 +04:00
log_verbose ( " Archiving volume group \" %s \" metadata (seqno %u). " , vg - > name ,
vg - > seqno ) ;
2015-12-03 19:32:47 +03:00
if ( ! ( desc = _build_desc ( vg - > cmd - > mem , vg - > cmd - > cmd_line , 1 ) ) )
return_0 ;
if ( ! archive_vg ( vg , vg - > cmd - > archive_params - > dir , desc ,
vg - > cmd - > archive_params - > keep_days ,
vg - > cmd - > archive_params - > keep_number ) )
return_0 ;
2002-01-03 18:46:48 +03:00
2013-06-30 20:01:19 +04:00
vg - > status | = ARCHIVED_VG ;
2002-01-03 18:46:48 +03:00
return 1 ;
}
2015-12-03 19:32:47 +03:00
int archive ( struct volume_group * vg )
{
return _archive ( vg , 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
{
2003-09-15 19:03:22 +04:00
int r1 , r2 ;
2002-02-11 14:43:17 +03:00
2005-05-17 17:46:38 +04:00
r1 = archive_list ( cmd , cmd - > archive_params - > dir , vg_name ) ;
r2 = backup_list ( cmd , cmd - > backup_params - > dir , vg_name ) ;
2002-01-03 18:46:48 +03:00
2003-09-15 19:03:22 +04:00
return r1 & & r2 ;
}
2002-01-03 18:46:48 +03:00
2007-06-09 02:38:48 +04:00
int archive_display_file ( struct cmd_context * cmd , const char * file )
{
int r ;
r = archive_list_file ( cmd , file ) ;
return r ;
}
2008-12-11 06:33:35 +03:00
int backup_init ( struct cmd_context * cmd , const char * dir ,
int enabled )
2002-01-03 18:46:48 +03:00
{
2010-09-09 17:07:13 +04:00
backup_exit ( cmd ) ;
2005-10-17 03:03:59 +04:00
if ( ! ( cmd - > backup_params = dm_pool_zalloc ( cmd - > libmem ,
2009-03-24 00:56:32 +03:00
sizeof ( * cmd - > backup_params ) ) ) ) {
log_error ( " backup_params alloc failed " ) ;
2005-05-17 17:46:38 +04:00
return 0 ;
}
cmd - > backup_params - > dir = NULL ;
2002-01-09 16:17:14 +03:00
if ( ! * dir )
return 1 ;
2005-10-17 03:03:59 +04:00
if ( ! ( cmd - > backup_params - > dir = dm_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 ;
}
2008-12-11 06:33:35 +03:00
backup_enable ( cmd , enabled ) ;
2002-01-03 18:46:48 +03:00
return 1 ;
}
2005-05-17 17:46:38 +04:00
void backup_exit ( struct cmd_context * cmd )
2002-01-03 18:46:48 +03:00
{
2009-07-09 02:18:32 +04:00
if ( ! cmd - > backup_params )
return ;
2011-01-28 13:16:04 +03:00
dm_free ( cmd - > backup_params - > dir ) ;
2005-05-17 17:46:38 +04:00
memset ( cmd - > backup_params , 0 , sizeof ( * cmd - > backup_params ) ) ;
2002-01-03 18:46:48 +03:00
}
2005-05-17 17:46:38 +04:00
void backup_enable ( struct cmd_context * cmd , int flag )
2002-01-07 12:05:31 +03:00
{
2005-05-17 17:46:38 +04:00
cmd - > backup_params - > enabled = flag ;
2002-01-07 12:05:31 +03:00
}
2015-12-03 19:32:47 +03:00
static int _backup ( struct volume_group * vg )
2002-01-03 18:46:48 +03:00
{
char name [ PATH_MAX ] ;
2002-02-08 14:13:47 +03:00
char * desc ;
2008-01-30 16:19:47 +03:00
if ( ! ( desc = _build_desc ( vg - > cmd - > mem , vg - > cmd - > cmd_line , 0 ) ) )
return_0 ;
2002-01-03 18:46:48 +03:00
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( name , sizeof ( name ) , " %s/%s " ,
2005-05-17 17:46:38 +04:00
vg - > cmd - > 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-11-18 17:04:08 +03:00
return backup_to_file ( name , desc , vg ) ;
2002-01-03 18:46:48 +03:00
}
2009-04-22 13:39:45 +04:00
int backup_locally ( struct volume_group * vg )
2002-01-03 18:46:48 +03:00
{
2005-05-17 17:46:38 +04:00
if ( ! vg - > cmd - > backup_params - > enabled | | ! vg - > cmd - > backup_params - > dir ) {
2007-06-28 21:33:44 +04:00
log_warn ( " 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 ( ) ) {
2011-02-28 23:50:01 +03:00
log_verbose ( " Test mode: Skipping backup of volume group. " ) ;
2002-01-03 18:46:48 +03:00
return 1 ;
}
2007-07-28 16:26:21 +04:00
if ( ! dm_create_dir ( vg - > cmd - > backup_params - > dir ) )
2005-05-03 21:31:56 +04:00
return 0 ;
2005-05-17 17:44:02 +04:00
/* Trap a read-only file system */
2008-01-30 17:00:02 +03:00
if ( ( access ( vg - > cmd - > backup_params - > dir , R_OK | W_OK | X_OK ) = = - 1 ) & &
2015-12-03 19:32:47 +03:00
( errno = = EROFS ) ) {
log_warn ( " WARNING: Cannot backup of volume group %s metadata to read-only fs. " ,
vg - > name ) ;
2008-01-30 17:00:02 +03:00
return 0 ;
2015-12-03 19:32:47 +03:00
}
2005-05-17 17:44:02 +04:00
2015-12-03 19:32:47 +03:00
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
2009-04-22 13:39:45 +04:00
int backup ( struct volume_group * vg )
{
2014-09-19 17:31:41 +04:00
/* Unlock memory if possible */
memlock_unlock ( vg - > cmd ) ;
2014-01-17 03:02:59 +04:00
/* Don't back up orphan VGs. */
if ( is_orphan_vg ( vg - > name ) )
return 1 ;
2009-04-22 13:39:45 +04:00
if ( vg_is_clustered ( vg ) )
2012-02-27 15:35:59 +04:00
if ( ! remote_backup_metadata ( vg ) )
stack ;
2009-04-22 13:39:45 +04:00
return backup_locally ( vg ) ;
}
2005-05-17 17:46:38 +04:00
int backup_remove ( struct cmd_context * cmd , const char * vg_name )
2002-01-09 17:07:49 +03:00
{
char path [ PATH_MAX ] ;
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( path , sizeof ( path ) , " %s/%s " ,
2005-05-17 17:46:38 +04:00
cmd - > backup_params - > dir , vg_name ) < 0 ) {
2009-07-16 00:02:46 +04:00
log_error ( " Failed to generate backup filename (for removal). " ) ;
2002-01-09 17:07:49 +03:00
return 0 ;
}
/*
* Let this fail silently .
*/
2011-01-05 18:06:10 +03:00
if ( unlink ( path ) )
log_sys_debug ( " unlink " , path ) ;
2002-01-09 17:07:49 +03:00
return 1 ;
}
2002-11-18 17:04:08 +03:00
struct volume_group * backup_read_vg ( struct cmd_context * cmd ,
const char * vg_name , const char * file )
2002-01-10 17:27:47 +03:00
{
2002-12-20 02:25:55 +03:00
struct volume_group * vg = NULL ;
2002-01-10 17:27:47 +03:00
struct format_instance * tf ;
2011-02-21 15:07:03 +03:00
struct format_instance_ctx fic ;
2011-03-11 17:45:17 +03:00
struct text_context tc = { . path_live = file ,
. path_edit = NULL ,
. desc = cmd - > cmd_line } ;
2002-11-18 17:04:08 +03:00
struct metadata_area * mda ;
2002-01-10 17:27:47 +03:00
2012-02-13 03:01:19 +04:00
fic . type = FMT_INSTANCE_PRIVATE_MDAS ;
2011-03-11 17:45:17 +03:00
fic . context . private = & tc ;
if ( ! ( tf = cmd - > fmt_backup - > ops - > create_instance ( cmd - > fmt_backup , & fic ) ) ) {
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
}
2010-06-29 00:32:44 +04:00
dm_list_iterate_items ( mda , & tf - > metadata_areas_in_use ) {
2015-03-19 02:43:02 +03:00
if ( ! ( vg = mda - > ops - > vg_read ( tf , vg_name , mda , NULL , NULL , 0 ) ) )
2002-11-18 17:04:08 +03:00
stack ;
break ;
}
2002-01-10 17:27:47 +03:00
2011-03-11 18:08:31 +03:00
if ( ! vg )
tf - > fmt - > ops - > destroy_instance ( tf ) ;
2002-01-11 02:21:07 +03:00
return vg ;
2002-01-10 17:27:47 +03:00
}
2002-11-18 17:04:08 +03:00
/* ORPHAN and VG locks held before calling this */
2013-09-18 14:53:11 +04:00
int backup_restore_vg ( struct cmd_context * cmd , struct volume_group * vg , int drop_lvmetad )
2002-01-10 17:27:47 +03:00
{
2003-10-16 00:02:46 +04:00
struct pv_list * pvl ;
2011-02-21 15:07:03 +03:00
struct format_instance * fid ;
struct format_instance_ctx fic ;
2011-02-25 17:12:14 +03:00
uint32_t tmp ;
2002-01-10 17:27:47 +03:00
/*
2002-11-18 17:04:08 +03:00
* FIXME : Check that the PVs referenced in the backup are
* not members of other existing VGs .
2002-01-10 17:27:47 +03:00
*/
2002-11-18 17:04:08 +03:00
/* Attempt to write out using currently active format */
2012-02-13 03:01:19 +04:00
fic . type = FMT_INSTANCE_AUX_MDAS ;
2011-02-21 15:07:03 +03:00
fic . context . vg_ref . vg_name = vg - > name ;
fic . context . vg_ref . vg_id = NULL ;
2011-02-21 15:10:58 +03:00
if ( ! ( fid = cmd - > fmt - > ops - > create_instance ( cmd - > fmt , & fic ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " Failed to allocate format instance " ) ;
2002-01-10 17:27:47 +03:00
return 0 ;
}
2011-02-21 15:10:58 +03:00
vg_set_fid ( vg , fid ) ;
2002-01-10 17:27:47 +03:00
2010-04-14 17:09:16 +04:00
/*
* Setting vg - > old_name to a blank value will explicitly
* disable any attempt to check VG name in existing metadata .
*/
2013-11-22 16:12:35 +04:00
if ( ! ( vg - > old_name = dm_pool_strdup ( vg - > vgmem , " " ) ) ) {
log_error ( " Failed to duplicate empty name. " ) ;
return 0 ;
}
2010-04-14 17:09:16 +04:00
2002-11-18 17:04:08 +03:00
/* Add any metadata areas on the PVs */
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( pvl , & vg - > pvs ) {
2011-02-25 17:12:14 +03:00
tmp = vg - > extent_size ;
vg - > extent_size = 0 ;
2011-02-25 16:59:47 +03:00
if ( ! vg - > fid - > fmt - > ops - > pv_setup ( vg - > fid - > fmt , pvl - > pv , vg ) ) {
2013-11-22 16:12:35 +04:00
vg - > extent_size = tmp ;
2002-11-18 17:04:08 +03:00
log_error ( " Format-specific setup for %s failed " ,
2011-02-25 16:59:47 +03:00
pv_dev_name ( pvl - > pv ) ) ;
2002-11-18 17:04:08 +03:00
return 0 ;
}
2011-02-25 17:12:14 +03:00
vg - > extent_size = tmp ;
2002-04-24 22:20:51 +04:00
}
2013-09-18 13:22:49 +04:00
if ( ! vg_write ( vg ) )
return_0 ;
2013-09-18 14:53:11 +04:00
if ( drop_lvmetad & & lvmetad_active ( ) ) {
2013-09-18 13:22:49 +04:00
struct volume_group * vg_lvmetad = lvmetad_vg_lookup ( cmd , vg - > name , NULL ) ;
if ( vg_lvmetad ) {
2013-09-23 18:43:37 +04:00
/* FIXME Cope with failure to update lvmetad */
if ( ! lvmetad_vg_remove ( vg_lvmetad ) )
stack ;
2013-09-18 13:22:49 +04:00
release_vg ( vg_lvmetad ) ;
}
}
if ( ! vg_commit ( vg ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2002-01-10 17:27:47 +03:00
return 1 ;
}
2002-11-18 17:04:08 +03:00
/* ORPHAN and VG locks held before calling this */
int backup_restore_from_file ( struct cmd_context * cmd , const char * vg_name ,
2012-11-27 02:45:35 +04:00
const char * file , int force )
2002-11-18 17:04:08 +03:00
{
struct volume_group * vg ;
2009-05-19 13:45:33 +04:00
int missing_pvs , r = 0 ;
2012-01-20 15:01:13 +04:00
const struct lv_list * lvl ;
2002-11-18 17:04:08 +03:00
/*
* Read in the volume group from the text file .
*/
2008-01-30 16:19:47 +03:00
if ( ! ( vg = backup_read_vg ( cmd , vg_name , file ) ) )
return_0 ;
2002-11-18 17:04:08 +03:00
2012-01-20 15:01:13 +04:00
/* FIXME: Restore support is missing for now */
2012-11-27 02:45:35 +04:00
dm_list_iterate_items ( lvl , & vg - > lvs ) {
2012-01-20 15:01:13 +04:00
if ( lv_is_thin_type ( lvl - > lv ) ) {
2012-11-27 02:45:35 +04:00
if ( ! force ) {
log_error ( " Consider using option --force to restore "
" Volume Group %s with thin volumes. " ,
vg - > name ) ;
goto out ;
} else {
log_warn ( " WARNING: Forced restore of Volume Group "
" %s with thin volumes. " , vg - > name ) ;
break ;
}
2012-01-20 15:01:13 +04:00
}
2012-11-27 02:45:35 +04:00
}
2012-01-20 15:01:13 +04:00
2009-05-19 13:45:33 +04:00
missing_pvs = vg_missing_pv_count ( vg ) ;
if ( missing_pvs = = 0 )
2013-09-18 14:53:11 +04:00
r = backup_restore_vg ( cmd , vg , 1 ) ;
2009-05-19 13:45:33 +04:00
else
log_error ( " Cannot restore Volume Group %s with %i PVs "
" marked as missing. " , vg - > name , missing_pvs ) ;
2009-03-24 16:16:34 +03:00
2012-01-20 15:01:13 +04:00
out :
2011-08-11 00:25:29 +04:00
release_vg ( vg ) ;
2009-04-10 14:00:37 +04:00
return r ;
2002-11-18 17:04:08 +03:00
}
2012-11-27 02:45:35 +04:00
int backup_restore ( struct cmd_context * cmd , const char * vg_name , int force )
2002-01-10 17:27:47 +03:00
{
char path [ PATH_MAX ] ;
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( path , sizeof ( path ) , " %s/%s " ,
2005-05-17 17:46:38 +04:00
cmd - > backup_params - > dir , vg_name ) < 0 ) {
2009-07-16 00:02:46 +04:00
log_error ( " Failed to generate backup filename (for restore). " ) ;
2002-01-10 17:27:47 +03:00
return 0 ;
}
2012-11-27 02:45:35 +04:00
return backup_restore_from_file ( cmd , vg_name , path , force ) ;
2002-01-10 17:27:47 +03:00
}
2002-11-18 17:04:08 +03:00
int backup_to_file ( const char * file , const char * desc , struct volume_group * vg )
{
2002-12-20 02:25:55 +03:00
int r = 0 ;
2002-11-18 17:04:08 +03:00
struct format_instance * tf ;
2011-02-21 15:07:03 +03:00
struct format_instance_ctx fic ;
2011-03-11 17:45:17 +03:00
struct text_context tc = { . path_live = file ,
. path_edit = NULL ,
. desc = desc } ;
2002-11-18 17:04:08 +03:00
struct metadata_area * mda ;
struct cmd_context * cmd ;
cmd = vg - > cmd ;
2005-05-17 17:44:02 +04:00
log_verbose ( " Creating volume group backup \" %s \" (seqno %u). " , file , vg - > seqno ) ;
2004-06-19 22:55:29 +04:00
2012-02-13 03:01:19 +04:00
fic . type = FMT_INSTANCE_PRIVATE_MDAS ;
2011-03-11 17:45:17 +03:00
fic . context . private = & tc ;
if ( ! ( tf = cmd - > fmt_backup - > ops - > create_instance ( cmd - > fmt_backup , & fic ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " Couldn't create backup object. " ) ;
return 0 ;
}
2013-07-17 16:49:21 +04:00
if ( dm_list_empty ( & tf - > metadata_areas_in_use ) ) {
2010-06-29 19:03:59 +04:00
log_error ( INTERNAL_ERROR " No in use metadata areas to write. " ) ;
2011-03-11 18:08:31 +03:00
tf - > fmt - > ops - > destroy_instance ( tf ) ;
2010-06-29 19:03:59 +04:00
return 0 ;
}
2002-11-18 17:04:08 +03:00
/* Write and commit the metadata area */
2010-06-29 00:32:44 +04:00
dm_list_iterate_items ( mda , & tf - > metadata_areas_in_use ) {
2002-11-18 17:04:08 +03:00
if ( ! ( r = mda - > ops - > vg_write ( tf , vg , mda ) ) ) {
stack ;
continue ;
}
if ( mda - > ops - > vg_commit & &
! ( r = mda - > ops - > vg_commit ( tf , vg , mda ) ) ) {
stack ;
}
}
tf - > fmt - > ops - > destroy_instance ( tf ) ;
return r ;
}
2005-05-17 17:44:02 +04:00
/*
* Update backup ( and archive ) if they ' re out - of - date or don ' t exist .
*/
void check_current_backup ( struct volume_group * vg )
{
char path [ PATH_MAX ] ;
struct volume_group * vg_backup ;
2009-04-03 01:34:41 +04:00
int old_suppress ;
2005-05-17 17:44:02 +04:00
2014-03-19 03:20:39 +04:00
if ( ! vg - > cmd - > backup_params - > enabled | | ! vg - > cmd - > backup_params - > dir ) {
log_debug ( " Skipping check for current backup, since backup is disabled. " ) ;
return ;
}
2009-09-14 23:44:15 +04:00
if ( vg_is_exported ( vg ) )
2005-05-17 17:44:02 +04:00
return ;
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( path , sizeof ( path ) , " %s/%s " ,
2015-12-03 19:32:47 +03:00
vg - > cmd - > backup_params - > dir , vg - > name ) < 0 ) {
log_warn ( " WARNING: Failed to generate backup pathname %s/%s. " ,
vg - > cmd - > backup_params - > dir , vg - > name ) ;
2005-05-17 17:44:02 +04:00
return ;
}
2009-04-03 01:34:41 +04:00
old_suppress = log_suppress ( 1 ) ;
2005-05-17 17:44:02 +04:00
/* Up-to-date backup exists? */
if ( ( vg_backup = backup_read_vg ( vg - > cmd , vg - > name , path ) ) & &
( vg - > seqno = = vg_backup - > seqno ) & &
2009-03-24 01:57:27 +03:00
( id_equal ( & vg - > id , & vg_backup - > id ) ) ) {
2009-04-03 01:34:41 +04:00
log_suppress ( old_suppress ) ;
2011-08-11 00:25:29 +04:00
release_vg ( vg_backup ) ;
2005-05-17 17:44:02 +04:00
return ;
2009-03-24 01:57:27 +03:00
}
2009-04-03 01:34:41 +04:00
log_suppress ( old_suppress ) ;
2005-05-17 17:44:02 +04:00
2009-04-10 14:00:37 +04:00
if ( vg_backup ) {
2015-12-03 19:32:47 +03:00
if ( ! _archive ( vg_backup , 0 ) )
2010-12-22 16:45:33 +03:00
stack ;
2011-08-11 00:25:29 +04:00
release_vg ( vg_backup ) ;
2009-04-10 14:00:37 +04:00
}
2015-12-03 19:32:47 +03:00
if ( ! _archive ( vg , 0 ) )
2010-12-22 16:45:33 +03:00
stack ;
if ( ! backup_locally ( vg ) )
stack ;
2005-05-17 17:44:02 +04:00
}