Home | History | Annotate | Line # | Download | only in tools
      1      1.1  haad /*	$NetBSD: vgrename.c,v 1.1.1.3 2009/12/02 00:25:58 haad Exp $	*/
      2      1.1  haad 
      3      1.1  haad /*
      4      1.1  haad  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
      5  1.1.1.3  haad  * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
      6      1.1  haad  *
      7      1.1  haad  * This file is part of LVM2.
      8      1.1  haad  *
      9      1.1  haad  * This copyrighted material is made available to anyone wishing to use,
     10      1.1  haad  * modify, copy, or redistribute it subject to the terms and conditions
     11      1.1  haad  * of the GNU Lesser General Public License v.2.1.
     12      1.1  haad  *
     13      1.1  haad  * You should have received a copy of the GNU Lesser General Public License
     14      1.1  haad  * along with this program; if not, write to the Free Software Foundation,
     15      1.1  haad  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     16      1.1  haad  */
     17      1.1  haad 
     18      1.1  haad #include "tools.h"
     19      1.1  haad 
     20  1.1.1.3  haad static struct volume_group *vg_rename_old(struct cmd_context *cmd,
     21  1.1.1.3  haad 					  const char *vg_name_old,
     22  1.1.1.3  haad 					  const char *vgid)
     23  1.1.1.3  haad {
     24  1.1.1.3  haad 	struct volume_group *vg;
     25  1.1.1.3  haad 
     26  1.1.1.3  haad 	/* FIXME we used to print an error about EXPORTED, but proceeded
     27  1.1.1.3  haad 	   nevertheless. */
     28  1.1.1.3  haad 	vg = vg_read_for_update(cmd, vg_name_old, vgid, READ_ALLOW_EXPORTED);
     29  1.1.1.3  haad 	if (vg_read_error(vg)) {
     30  1.1.1.3  haad 		vg_release(vg);
     31  1.1.1.3  haad 		return_NULL;
     32  1.1.1.3  haad 	}
     33  1.1.1.3  haad 
     34  1.1.1.3  haad 	if (lvs_in_vg_activated_by_uuid_only(vg)) {
     35  1.1.1.3  haad 		unlock_and_release_vg(cmd, vg, vg_name_old);
     36  1.1.1.3  haad 		log_error("Volume group \"%s\" still has active LVs",
     37  1.1.1.3  haad 			  vg_name_old);
     38  1.1.1.3  haad 		/* FIXME Remove this restriction */
     39  1.1.1.3  haad 		return NULL;
     40  1.1.1.3  haad 	}
     41  1.1.1.3  haad 	return vg;
     42  1.1.1.3  haad }
     43  1.1.1.3  haad 
     44  1.1.1.3  haad static int vg_rename_new(struct cmd_context *cmd,
     45  1.1.1.3  haad 			 const char *vg_name_new)
     46  1.1.1.3  haad {
     47  1.1.1.3  haad 	int rc;
     48  1.1.1.3  haad 
     49  1.1.1.3  haad 	log_verbose("Checking for new volume group \"%s\"", vg_name_new);
     50  1.1.1.3  haad 
     51  1.1.1.3  haad 	rc = vg_lock_newname(cmd, vg_name_new);
     52  1.1.1.3  haad 
     53  1.1.1.3  haad 	if (rc == FAILED_LOCKING) {
     54  1.1.1.3  haad 		log_error("Can't get lock for %s", vg_name_new);
     55  1.1.1.3  haad 		return 0;
     56  1.1.1.3  haad 	}
     57  1.1.1.3  haad 
     58  1.1.1.3  haad 	if (rc == FAILED_EXIST) {
     59  1.1.1.3  haad 		log_error("New volume group \"%s\" already exists",
     60  1.1.1.3  haad 			  vg_name_new);
     61  1.1.1.3  haad 		return 0;
     62  1.1.1.3  haad 	}
     63  1.1.1.3  haad 	return 1;
     64  1.1.1.3  haad }
     65  1.1.1.3  haad 
     66      1.1  haad static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
     67      1.1  haad 			  const char *new_vg_path)
     68      1.1  haad {
     69      1.1  haad 	char *dev_dir;
     70      1.1  haad 	struct id id;
     71      1.1  haad 	int match = 0;
     72      1.1  haad 	int found_id = 0;
     73      1.1  haad 	struct dm_list *vgids;
     74      1.1  haad 	struct str_list *sl;
     75      1.1  haad 	char *vg_name_new;
     76      1.1  haad 	const char *vgid = NULL, *vg_name, *vg_name_old;
     77      1.1  haad 	char old_path[NAME_LEN], new_path[NAME_LEN];
     78  1.1.1.3  haad 	struct volume_group *vg = NULL;
     79  1.1.1.3  haad 	int lock_vg_old_first = 1;
     80      1.1  haad 
     81      1.1  haad 	vg_name_old = skip_dev_dir(cmd, old_vg_path, NULL);
     82      1.1  haad 	vg_name_new = skip_dev_dir(cmd, new_vg_path, NULL);
     83      1.1  haad 
     84      1.1  haad 	dev_dir = cmd->dev_dir;
     85      1.1  haad 
     86      1.1  haad 	if (!validate_vg_rename_params(cmd, vg_name_old, vg_name_new))
     87      1.1  haad 		return 0;
     88      1.1  haad 
     89      1.1  haad 	log_verbose("Checking for existing volume group \"%s\"", vg_name_old);
     90      1.1  haad 
     91      1.1  haad 	/* Avoid duplicates */
     92      1.1  haad 	if (!(vgids = get_vgids(cmd, 0)) || dm_list_empty(vgids)) {
     93      1.1  haad 		log_error("No complete volume groups found");
     94      1.1  haad 		return 0;
     95      1.1  haad 	}
     96      1.1  haad 
     97      1.1  haad 	dm_list_iterate_items(sl, vgids) {
     98      1.1  haad 		vgid = sl->str;
     99      1.1  haad 		if (!vgid || !(vg_name = vgname_from_vgid(NULL, vgid)) ||
    100      1.1  haad 		    is_orphan_vg(vg_name))
    101      1.1  haad 			continue;
    102      1.1  haad 		if (!strcmp(vg_name, vg_name_old)) {
    103      1.1  haad 			if (match) {
    104      1.1  haad 				log_error("Found more than one VG called %s. "
    105      1.1  haad 					  "Please supply VG uuid.", vg_name_old);
    106      1.1  haad 				return 0;
    107      1.1  haad 			}
    108      1.1  haad 			match = 1;
    109      1.1  haad 		}
    110      1.1  haad 	}
    111      1.1  haad 
    112      1.1  haad 	log_suppress(2);
    113      1.1  haad 	found_id = id_read_format(&id, vg_name_old);
    114      1.1  haad 	log_suppress(0);
    115      1.1  haad 	if (found_id && (vg_name = vgname_from_vgid(cmd->mem, (char *)id.uuid))) {
    116      1.1  haad 		vg_name_old = vg_name;
    117      1.1  haad 		vgid = (char *)id.uuid;
    118      1.1  haad 	} else
    119      1.1  haad 		vgid = NULL;
    120      1.1  haad 
    121  1.1.1.3  haad 	if (strcmp(vg_name_new, vg_name_old) < 0)
    122  1.1.1.3  haad 		lock_vg_old_first = 0;
    123      1.1  haad 
    124  1.1.1.3  haad 	if (lock_vg_old_first) {
    125  1.1.1.3  haad 		vg = vg_rename_old(cmd, vg_name_old, vgid);
    126  1.1.1.3  haad 		if (!vg)
    127  1.1.1.3  haad 			return 0;
    128  1.1.1.3  haad 
    129  1.1.1.3  haad 		if (!vg_rename_new(cmd, vg_name_new)) {
    130  1.1.1.3  haad 			unlock_and_release_vg(cmd, vg, vg_name_old);
    131  1.1.1.3  haad 			return 0;
    132  1.1.1.3  haad 		}
    133  1.1.1.3  haad 	} else {
    134  1.1.1.3  haad 		if (!vg_rename_new(cmd, vg_name_new)) {
    135  1.1.1.3  haad 			return 0;
    136  1.1.1.3  haad 		}
    137      1.1  haad 
    138  1.1.1.3  haad 		vg = vg_rename_old(cmd, vg_name_old, vgid);
    139  1.1.1.3  haad 		if (!vg)
    140  1.1.1.3  haad 			return 0;
    141      1.1  haad 	}
    142      1.1  haad 
    143      1.1  haad 	if (!archive(vg))
    144      1.1  haad 		goto error;
    145      1.1  haad 
    146      1.1  haad 	/* Remove references based on old name */
    147      1.1  haad 	drop_cached_metadata(vg);
    148      1.1  haad 
    149      1.1  haad 	/* Change the volume group name */
    150      1.1  haad 	vg_rename(cmd, vg, vg_name_new);
    151      1.1  haad 
    152  1.1.1.2  haad 	/* store it on disks */
    153  1.1.1.2  haad 	log_verbose("Writing out updated volume group");
    154  1.1.1.2  haad 	if (!vg_write(vg) || !vg_commit(vg)) {
    155  1.1.1.2  haad 		goto error;
    156  1.1.1.2  haad 	}
    157  1.1.1.2  haad 
    158      1.1  haad 	sprintf(old_path, "%s%s", dev_dir, vg_name_old);
    159      1.1  haad 	sprintf(new_path, "%s%s", dev_dir, vg_name_new);
    160      1.1  haad 
    161      1.1  haad 	if (activation() && dir_exists(old_path)) {
    162      1.1  haad 		log_verbose("Renaming \"%s\" to \"%s\"", old_path, new_path);
    163  1.1.1.2  haad 
    164      1.1  haad 		if (test_mode())
    165      1.1  haad 			log_verbose("Test mode: Skipping rename.");
    166      1.1  haad 
    167  1.1.1.2  haad 		else if (lvs_in_vg_activated_by_uuid_only(vg)) {
    168  1.1.1.2  haad 			if (!vg_refresh_visible(cmd, vg)) {
    169  1.1.1.2  haad 				log_error("Renaming \"%s\" to \"%s\" failed",
    170  1.1.1.2  haad 					old_path, new_path);
    171  1.1.1.2  haad 				goto error;
    172  1.1.1.2  haad 			}
    173  1.1.1.2  haad 		}
    174      1.1  haad 	}
    175      1.1  haad 
    176      1.1  haad /******* FIXME Rename any active LVs! *****/
    177      1.1  haad 
    178      1.1  haad 	backup(vg);
    179  1.1.1.3  haad 	backup_remove(cmd, vg_name_old);
    180      1.1  haad 
    181      1.1  haad 	unlock_vg(cmd, vg_name_new);
    182  1.1.1.3  haad 	unlock_and_release_vg(cmd, vg, vg_name_old);
    183      1.1  haad 
    184      1.1  haad 	log_print("Volume group \"%s\" successfully renamed to \"%s\"",
    185      1.1  haad 		  vg_name_old, vg_name_new);
    186      1.1  haad 
    187      1.1  haad 	/* FIXME lvmcache corruption - vginfo duplicated instead of renamed */
    188      1.1  haad 	persistent_filter_wipe(cmd->filter);
    189      1.1  haad 	lvmcache_destroy(cmd, 1);
    190      1.1  haad 
    191      1.1  haad 	return 1;
    192      1.1  haad 
    193      1.1  haad       error:
    194  1.1.1.3  haad 	if (lock_vg_old_first) {
    195  1.1.1.3  haad 		unlock_vg(cmd, vg_name_new);
    196  1.1.1.3  haad 		unlock_and_release_vg(cmd, vg, vg_name_old);
    197  1.1.1.3  haad 	} else {
    198  1.1.1.3  haad 		unlock_and_release_vg(cmd, vg, vg_name_old);
    199  1.1.1.3  haad 		unlock_vg(cmd, vg_name_new);
    200  1.1.1.3  haad 	}
    201      1.1  haad 	return 0;
    202      1.1  haad }
    203      1.1  haad 
    204      1.1  haad int vgrename(struct cmd_context *cmd, int argc, char **argv)
    205      1.1  haad {
    206      1.1  haad 	if (argc != 2) {
    207      1.1  haad 		log_error("Old and new volume group names need specifying");
    208      1.1  haad 		return EINVALID_CMD_LINE;
    209      1.1  haad 	}
    210      1.1  haad 
    211  1.1.1.3  haad 	if (!vg_rename_path(cmd, argv[0], argv[1])) {
    212  1.1.1.3  haad 		stack;
    213      1.1  haad 		return ECMD_FAILED;
    214  1.1.1.3  haad 	}
    215  1.1.1.3  haad 
    216      1.1  haad 	return ECMD_PROCESSED;
    217      1.1  haad }
    218      1.1  haad 
    219