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 ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2001-10-03 21:03:25 +04:00
*/
# include "tools.h"
2015-12-01 23:09:01 +03:00
struct vgrename_params {
const char * vg_name_old ;
const char * vg_name_new ;
unsigned int old_name_is_uuid : 1 ;
unsigned int lock_vg_old_first : 1 ;
unsigned int unlock_new_name : 1 ;
} ;
2009-09-03 01:29:23 +04:00
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
{
2015-12-01 23:09:01 +03:00
if ( ! lock_vol ( cmd , vg_name_new , LCK_VG_WRITE , NULL ) ) {
2009-09-03 01:29:23 +04:00
log_error ( " Can't get lock for %s " , vg_name_new ) ;
return 0 ;
}
return 1 ;
}
2015-12-01 23:09:01 +03:00
static int _vgrename_single ( struct cmd_context * cmd , const char * vg_name ,
struct volume_group * vg , struct processing_handle * handle )
2001-10-03 21:03:25 +04:00
{
2015-12-01 23:09:01 +03:00
struct vgrename_params * vp = ( struct vgrename_params * ) handle - > custom_handle ;
char old_path [ NAME_LEN ] ;
char new_path [ NAME_LEN ] ;
2006-04-14 01:08:29 +04:00
struct id id ;
2015-12-01 23:09:01 +03:00
const char * name ;
char * dev_dir ;
2013-10-08 13:15:05 +04:00
2015-12-01 23:09:01 +03:00
/*
* vg_name_old may be a UUID which process_each_vg
* replaced with the real VG name . In that case ,
* vp - > vg_name_old will be the UUID and vg_name will be
* the actual VG name . Check again if the old and new
* names match , using the real names .
*/
if ( vp - > old_name_is_uuid & & ! strcmp ( vp - > vg_name_new , vg_name ) ) {
log_error ( " New VG name must differ from the old VG name. " ) ;
return ECMD_FAILED ;
2002-02-12 00:00:35 +03:00
}
2002-02-11 18:42:34 +03:00
2015-12-01 23:09:01 +03:00
/*
* Check if a VG already exists with the new VG name .
*
* When not using lvmetad , it ' s essential that a full scan has
* been done to ensure we see all existing VG names , so we
* do not use an existing name . This has been done by
* process_each_vg REQUIRES_FULL_LABEL_SCAN .
*
* ( FIXME : We could look for the new name in the list of all
* VGs that process_each_vg created , but we don ' t have access
* to that list here , so we have to look in lvmcache .
* This requires populating lvmcache when using lvmetad . )
*/
lvmcache_seed_infos_from_lvmetad ( cmd ) ;
2016-02-23 21:57:56 +03:00
if ( lvmcache_vginfo_from_vgname ( vp - > vg_name_new , NULL ) ) {
2015-12-01 23:09:01 +03:00
log_error ( " New VG name \" %s \" already exists " , vp - > vg_name_new ) ;
return ECMD_FAILED ;
2006-04-14 01:08:29 +04:00
}
2015-12-01 23:09:01 +03:00
if ( id_read_format_try ( & id , vp - > vg_name_new ) & &
( name = lvmcache_vgname_from_vgid ( cmd - > mem , ( const char * ) & id ) ) ) {
log_error ( " New VG name \" %s \" matches the UUID of existing VG %s " , vp - > vg_name_new , name ) ;
return ECMD_FAILED ;
}
2009-09-03 01:29:40 +04:00
2015-12-01 23:09:01 +03:00
/*
* Lock the old VG name first :
* . The old VG name has already been locked by process_each_vg .
* . Now lock the new VG name here , second .
*
* Lock the new VG name first :
* . The new VG name has already been pre - locked below ,
* before process_each_vg was called .
* . process_each_vg then locked the old VG name second .
* . Nothing to do here .
*
* Special case when the old VG name is a uuid :
* . The old VG ' s real name wasn ' t known before process_each_vg ,
* so the correct lock ordering wasn ' t known beforehand ,
* so no pre - locking was done .
* . The old VG ' s real name has been locked by process_each_vg .
* . Now lock the new VG name here , second .
* . Suppress lock ordering checks because the lock order may
* have wanted the new name first , which wasn ' t possible in
* this uuid - for - name case .
*/
if ( vp - > lock_vg_old_first | | vp - > old_name_is_uuid ) {
if ( vp - > old_name_is_uuid )
lvmcache_lock_ordering ( 0 ) ;
if ( ! _lock_new_vg_for_rename ( cmd , vp - > vg_name_new ) )
return ECMD_FAILED ;
lvmcache_lock_ordering ( 1 ) ;
2001-10-03 21:03:25 +04:00
}
2015-12-01 23:09:01 +03:00
dev_dir = cmd - > dev_dir ;
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
2015-09-03 18:38:16 +03:00
if ( ! lockd_rename_vg_before ( cmd , vg ) ) {
stack ;
2015-09-03 18:21:44 +03:00
goto error ;
2015-09-03 18:38:16 +03:00
}
2015-03-05 23:00:44 +03:00
2001-10-08 22:44:22 +04:00
/* Change the volume group name */
2015-12-01 23:09:01 +03:00
vg_rename ( cmd , vg , vp - > 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 ;
}
2015-12-01 23:09:01 +03:00
sprintf ( old_path , " %s%s " , dev_dir , vg_name ) ;
sprintf ( new_path , " %s%s " , dev_dir , vp - > 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
}
2015-03-05 23:00:44 +03:00
lockd_rename_vg_final ( cmd , vg , 1 ) ;
2010-12-22 18:36:41 +03:00
if ( ! backup ( vg ) )
stack ;
2015-12-01 23:09:01 +03:00
if ( ! backup_remove ( cmd , vg_name ) )
2010-12-22 18:36:41 +03:00
stack ;
2001-10-03 21:03:25 +04:00
2015-12-01 23:09:01 +03:00
unlock_vg ( cmd , vp - > vg_name_new ) ;
vp - > unlock_new_name = 0 ;
2002-02-11 18:42:34 +03:00
config: add silent mode
Accept -q as the short form of --quiet.
Suppress non-essential standard output if -q is given twice.
Treat log/silent in lvm.conf as equivalent to -qq.
Review all log_print messages and change some to
log_print_unless_silent.
When silent, the following commands still produce output:
dumpconfig, lvdisplay, lvmdiskscan, lvs, pvck, pvdisplay,
pvs, version, vgcfgrestore -l, vgdisplay, vgs.
[Needs checking.]
Non-essential messages are shifted from log level 4 to log level 5
for syslog and lvm2_log_fn purposes.
2012-08-25 23:35:48 +04:00
log_print_unless_silent ( " Volume group \" %s \" successfully renamed to \" %s \" " ,
2015-12-01 23:09:01 +03:00
vp - > vg_name_old , vp - > vg_name_new ) ;
2007-08-31 23:09:49 +04:00
return 1 ;
2002-02-11 18:42:34 +03:00
2015-12-01 23:09:01 +03:00
error :
unlock_vg ( cmd , vp - > vg_name_new ) ;
vp - > unlock_new_name = 0 ;
2015-03-05 23:00:44 +03:00
lockd_rename_vg_final ( cmd , vg , 0 ) ;
2007-08-31 23:09:49 +04:00
return 0 ;
}
int vgrename ( struct cmd_context * cmd , int argc , char * * argv )
{
2015-12-01 23:09:01 +03:00
struct vgrename_params vp = { 0 } ;
struct processing_handle * handle ;
const char * vg_name_new ;
const char * vg_name_old ;
struct id id ;
int ret ;
2007-08-31 23:09:49 +04:00
if ( argc ! = 2 ) {
log_error ( " Old and new volume group names need specifying " ) ;
return EINVALID_CMD_LINE ;
}
2015-12-01 23:09:01 +03:00
vg_name_old = skip_dev_dir ( cmd , argv [ 0 ] , NULL ) ;
vg_name_new = skip_dev_dir ( cmd , argv [ 1 ] , NULL ) ;
if ( ! validate_vg_rename_params ( cmd , vg_name_old , vg_name_new ) )
return_0 ;
if ( ! ( vp . vg_name_old = dm_pool_strdup ( cmd - > mem , vg_name_old ) ) )
return_ECMD_FAILED ;
if ( ! ( vp . vg_name_new = dm_pool_strdup ( cmd - > mem , vg_name_new ) ) )
return_ECMD_FAILED ;
2015-03-05 23:00:44 +03:00
/* Needed change the global VG namespace. */
if ( ! lockd_gl ( cmd , " ex " , LDGL_UPDATE_NAMES ) )
return_ECMD_FAILED ;
2015-12-01 23:09:01 +03:00
/*
* Special case where vg_name_old may be a UUID :
* If vg_name_old is a UUID , then process_each may
* translate it to an actual VG name that we don ' t
* yet know . The lock ordering , and pre - locking ,
* needs to be done based on VG names . When
* vg_name_old is a UUID , do not do any pre - locking
* based on it , since it ' s likely to be wrong , and
* defer all the locking to the _single function .
*
* When it ' s not a UUID , we know the two VG names ,
* and we can pre - lock the new VG name if the lock
* ordering wants it locked before the old VG name
* which will be locked by process_each . If lock
* ordering wants the old name locked first , then
* the _single function will lock the new VG name .
*/
if ( ! ( vp . old_name_is_uuid = id_read_format_try ( & id , vg_name_old ) ) ) {
if ( strcmp ( vg_name_new , vg_name_old ) < 0 ) {
vp . lock_vg_old_first = 0 ;
vp . unlock_new_name = 1 ;
if ( ! _lock_new_vg_for_rename ( cmd , vg_name_new ) )
return ECMD_FAILED ;
} else {
/* The old VG is locked by process_each_vg. */
vp . lock_vg_old_first = 1 ;
}
}
if ( ! ( handle = init_processing_handle ( cmd ) ) ) {
log_error ( " Failed to initialize processing handle. " ) ;
return ECMD_FAILED ;
}
handle - > custom_handle = & vp ;
ret = process_each_vg ( cmd , 0 , NULL , vg_name_old ,
READ_FOR_UPDATE | READ_ALLOW_EXPORTED ,
handle , _vgrename_single ) ;
/* Needed if process_each_vg returns error before calling _single. */
if ( vp . unlock_new_name )
unlock_vg ( cmd , vg_name_new ) ;
2009-09-03 01:29:23 +04:00
2015-12-01 23:09:01 +03:00
destroy_processing_handle ( cmd , handle ) ;
return ret ;
2001-10-03 21:03:25 +04:00
}