2001-10-03 21:03:25 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2009-09-03 01:29:23 +04:00
* Copyright ( C ) 2004 - 2009 Red Hat , Inc . All rights reserved .
2001-10-03 21:03:25 +04:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
2001-10-03 21:03:25 +04:00
*
2004-03-30 23:35:44 +04:00
* 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 .
2001-10-03 21:03:25 +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
2001-10-03 21:03:25 +04:00
*/
# include "tools.h"
2010-04-14 17:03:06 +04:00
static struct volume_group * _get_old_vg_for_rename ( struct cmd_context * cmd ,
const char * vg_name_old ,
const char * vgid )
2009-09-03 01:29:23 +04:00
{
struct volume_group * vg ;
/* FIXME we used to print an error about EXPORTED, but proceeded
nevertheless . */
vg = vg_read_for_update ( cmd , vg_name_old , vgid , READ_ALLOW_EXPORTED ) ;
if ( vg_read_error ( vg ) ) {
2011-08-11 00:25:29 +04:00
release_vg ( vg ) ;
2009-09-03 01:29:23 +04:00
return_NULL ;
}
return vg ;
}
2010-04-14 17:03:06 +04:00
static int _lock_new_vg_for_rename ( struct cmd_context * cmd ,
const char * vg_name_new )
2009-09-03 01:29:23 +04:00
{
int rc ;
log_verbose ( " Checking for new volume group \" %s \" " , vg_name_new ) ;
rc = vg_lock_newname ( cmd , vg_name_new ) ;
if ( rc = = FAILED_LOCKING ) {
log_error ( " Can't get lock for %s " , vg_name_new ) ;
return 0 ;
}
if ( rc = = FAILED_EXIST ) {
log_error ( " New volume group \" %s \" already exists " ,
vg_name_new ) ;
return 0 ;
}
return 1 ;
}
2007-08-31 23:09:49 +04:00
static int vg_rename_path ( struct cmd_context * cmd , const char * old_vg_path ,
const char * new_vg_path )
2001-10-03 21:03:25 +04:00
{
2001-11-15 20:27:45 +03:00
char * dev_dir ;
2006-04-14 01:08:29 +04:00
struct id id ;
int match = 0 ;
int found_id = 0 ;
2008-11-04 01:14:30 +03:00
struct dm_list * vgids ;
2006-04-14 01:08:29 +04:00
struct str_list * sl ;
2011-02-18 17:47:28 +03:00
const char * vg_name_new ;
2006-04-14 01:08:29 +04:00
const char * vgid = NULL , * vg_name , * vg_name_old ;
2001-10-08 22:44:22 +04:00
char old_path [ NAME_LEN ] , new_path [ NAME_LEN ] ;
2009-06-09 18:30:16 +04:00
struct volume_group * vg = NULL ;
2009-09-03 01:29:40 +04:00
int lock_vg_old_first = 1 ;
2001-10-03 21:03:25 +04:00
2007-08-31 23:09:49 +04:00
vg_name_old = skip_dev_dir ( cmd , old_vg_path , NULL ) ;
vg_name_new = skip_dev_dir ( cmd , new_vg_path , NULL ) ;
2001-10-03 21:03:25 +04:00
2002-02-11 23:50:53 +03:00
dev_dir = cmd - > dev_dir ;
2001-10-03 21:03:25 +04:00
2008-01-16 01:56:30 +03:00
if ( ! validate_vg_rename_params ( cmd , vg_name_old , vg_name_new ) )
2010-04-14 17:03:06 +04:00
return_0 ;
2001-10-03 21:03:25 +04:00
2002-01-30 18:04:48 +03:00
log_verbose ( " Checking for existing volume group \" %s \" " , vg_name_old ) ;
2002-02-11 18:42:34 +03:00
2012-02-28 22:08:08 +04:00
/* populate lvmcache */
if ( ! lvmetad_vg_list_to_lvmcache ( cmd ) )
stack ;
2012-02-23 17:11:07 +04:00
2006-04-14 01:08:29 +04:00
/* Avoid duplicates */
2010-03-16 19:57:03 +03:00
if ( ! ( vgids = get_vgids ( cmd , 0 ) ) | | dm_list_empty ( vgids ) ) {
2006-04-14 01:08:29 +04:00
log_error ( " No complete volume groups found " ) ;
2007-08-31 23:09:49 +04:00
return 0 ;
2002-02-12 00:00:35 +03:00
}
2002-02-11 18:42:34 +03:00
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( sl , vgids ) {
2006-04-14 01:08:29 +04:00
vgid = sl - > str ;
2012-02-10 05:28:27 +04:00
if ( ! vgid | | ! ( vg_name = lvmcache_vgname_from_vgid ( NULL , vgid ) ) )
2006-04-14 01:08:29 +04:00
continue ;
if ( ! strcmp ( vg_name , vg_name_old ) ) {
if ( match ) {
log_error ( " Found more than one VG called %s. "
" Please supply VG uuid. " , vg_name_old ) ;
2007-08-31 23:09:49 +04:00
return 0 ;
2006-04-14 01:08:29 +04:00
}
match = 1 ;
}
}
log_suppress ( 2 ) ;
found_id = id_read_format ( & id , vg_name_old ) ;
log_suppress ( 0 ) ;
2012-02-10 05:28:27 +04:00
if ( found_id & & ( vg_name = lvmcache_vgname_from_vgid ( cmd - > mem , ( char * ) id . uuid ) ) ) {
2006-04-14 01:08:29 +04:00
vg_name_old = vg_name ;
2006-05-10 01:23:51 +04:00
vgid = ( char * ) id . uuid ;
2006-04-14 01:08:29 +04:00
} else
vgid = NULL ;
2009-09-03 01:29:40 +04:00
if ( strcmp ( vg_name_new , vg_name_old ) < 0 )
lock_vg_old_first = 0 ;
2009-06-09 18:30:16 +04:00
2009-09-03 01:29:40 +04:00
if ( lock_vg_old_first ) {
2010-04-14 17:03:06 +04:00
vg = _get_old_vg_for_rename ( cmd , vg_name_old , vgid ) ;
2009-09-03 01:29:40 +04:00
if ( ! vg )
2010-04-14 17:03:06 +04:00
return_0 ;
2009-09-03 01:29:40 +04:00
2010-04-14 17:03:06 +04:00
if ( ! _lock_new_vg_for_rename ( cmd , vg_name_new ) ) {
2011-08-11 00:25:29 +04:00
unlock_and_release_vg ( cmd , vg , vg_name_old ) ;
2010-04-14 17:03:06 +04:00
return_0 ;
2009-09-03 01:29:40 +04:00
}
} else {
2010-04-14 17:03:06 +04:00
if ( ! _lock_new_vg_for_rename ( cmd , vg_name_new ) )
return_0 ;
2009-09-03 01:29:40 +04:00
2010-04-14 17:03:06 +04:00
vg = _get_old_vg_for_rename ( cmd , vg_name_old , vgid ) ;
if ( ! vg ) {
unlock_vg ( cmd , vg_name_new ) ;
return_0 ;
}
2001-10-03 21:03:25 +04:00
}
2008-06-06 20:13:35 +04:00
if ( ! archive ( vg ) )
2002-02-11 18:42:34 +03:00
goto error ;
2002-01-09 16:17:14 +03:00
2008-06-06 20:13:35 +04:00
/* Remove references based on old name */
2012-03-02 01:16:44 +04:00
if ( ! drop_cached_metadata ( vg ) )
stack ;
2008-06-06 20:13:35 +04:00
2001-10-08 22:44:22 +04:00
/* Change the volume group name */
2008-06-06 20:13:35 +04:00
vg_rename ( cmd , vg , vg_name_new ) ;
2001-10-03 21:03:25 +04:00
2008-12-19 17:22:48 +03:00
/* store it on disks */
log_verbose ( " Writing out updated volume group " ) ;
if ( ! vg_write ( vg ) | | ! vg_commit ( vg ) ) {
goto error ;
}
2001-11-15 20:27:45 +03:00
sprintf ( old_path , " %s%s " , dev_dir , vg_name_old ) ;
sprintf ( new_path , " %s%s " , dev_dir , vg_name_new ) ;
2001-10-03 21:03:25 +04:00
2008-04-30 18:34:02 +04:00
if ( activation ( ) & & dir_exists ( old_path ) ) {
2002-02-11 18:42:34 +03:00
log_verbose ( " Renaming \" %s \" to \" %s \" " , old_path , new_path ) ;
2008-12-19 17:22:48 +03:00
2002-11-18 17:04:08 +03:00
if ( test_mode ( ) )
log_verbose ( " Test mode: Skipping rename. " ) ;
2001-10-03 21:03:25 +04:00
2010-02-24 23:01:40 +03:00
else if ( lvs_in_vg_activated ( vg ) ) {
2008-12-22 12:00:51 +03:00
if ( ! vg_refresh_visible ( cmd , vg ) ) {
2008-12-19 17:22:48 +03:00
log_error ( " Renaming \" %s \" to \" %s \" failed " ,
old_path , new_path ) ;
goto error ;
}
}
2001-10-03 21:03:25 +04:00
}
2010-12-22 18:36:41 +03:00
if ( ! backup ( vg ) )
stack ;
if ( ! backup_remove ( cmd , vg_name_old ) )
stack ;
2001-10-03 21:03:25 +04:00
2009-06-09 18:30:16 +04:00
unlock_vg ( cmd , vg_name_new ) ;
2011-08-11 00:25:29 +04:00
unlock_and_release_vg ( cmd , vg , vg_name_old ) ;
2002-02-11 18:42:34 +03:00
2002-01-30 18:04:48 +03:00
log_print ( " Volume group \" %s \" successfully renamed to \" %s \" " ,
2001-10-03 21:03:25 +04:00
vg_name_old , vg_name_new ) ;
2006-04-14 01:08:29 +04:00
/* FIXME lvmcache corruption - vginfo duplicated instead of renamed */
2008-01-30 17:00:02 +03:00
persistent_filter_wipe ( cmd - > filter ) ;
2008-04-08 16:49:21 +04:00
lvmcache_destroy ( cmd , 1 ) ;
2006-04-14 01:08:29 +04:00
2007-08-31 23:09:49 +04:00
return 1 ;
2002-02-11 18:42:34 +03:00
error :
2009-09-03 01:29:40 +04:00
if ( lock_vg_old_first ) {
unlock_vg ( cmd , vg_name_new ) ;
2011-08-11 00:25:29 +04:00
unlock_and_release_vg ( cmd , vg , vg_name_old ) ;
2009-09-03 01:29:40 +04:00
} else {
2011-08-11 00:25:29 +04:00
unlock_and_release_vg ( cmd , vg , vg_name_old ) ;
2009-09-03 01:29:40 +04:00
unlock_vg ( cmd , vg_name_new ) ;
}
2007-08-31 23:09:49 +04:00
return 0 ;
}
int vgrename ( struct cmd_context * cmd , int argc , char * * argv )
{
if ( argc ! = 2 ) {
log_error ( " Old and new volume group names need specifying " ) ;
return EINVALID_CMD_LINE ;
}
2009-09-15 02:47:49 +04:00
if ( ! vg_rename_path ( cmd , argv [ 0 ] , argv [ 1 ] ) ) {
stack ;
2007-08-31 23:09:49 +04:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2009-09-03 01:29:23 +04:00
2007-08-31 23:09:49 +04:00
return ECMD_PROCESSED ;
2001-10-03 21:03:25 +04:00
}