2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
9 * of the GNU Lesser General Public License v.2.1.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 static struct volume_group *_get_old_vg_for_rename(struct cmd_context *cmd,
19 const char *vg_name_old,
22 struct volume_group *vg;
24 /* FIXME we used to print an error about EXPORTED, but proceeded
26 vg = vg_read_for_update(cmd, vg_name_old, vgid, READ_ALLOW_EXPORTED);
27 if (vg_read_error(vg)) {
35 static int _lock_new_vg_for_rename(struct cmd_context *cmd,
36 const char *vg_name_new)
40 log_verbose("Checking for new volume group \"%s\"", vg_name_new);
42 rc = vg_lock_newname(cmd, vg_name_new);
44 if (rc == FAILED_LOCKING) {
45 log_error("Can't get lock for %s", vg_name_new);
49 if (rc == FAILED_EXIST) {
50 log_error("New volume group \"%s\" already exists",
57 static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
58 const char *new_vg_path)
64 struct dm_list *vgids;
67 const char *vgid = NULL, *vg_name, *vg_name_old;
68 char old_path[NAME_LEN], new_path[NAME_LEN];
69 struct volume_group *vg = NULL;
70 int lock_vg_old_first = 1;
72 vg_name_old = skip_dev_dir(cmd, old_vg_path, NULL);
73 vg_name_new = skip_dev_dir(cmd, new_vg_path, NULL);
75 dev_dir = cmd->dev_dir;
77 if (!validate_vg_rename_params(cmd, vg_name_old, vg_name_new))
80 log_verbose("Checking for existing volume group \"%s\"", vg_name_old);
82 /* Avoid duplicates */
83 if (!(vgids = get_vgids(cmd, 0)) || dm_list_empty(vgids)) {
84 log_error("No complete volume groups found");
88 dm_list_iterate_items(sl, vgids) {
90 if (!vgid || !(vg_name = vgname_from_vgid(NULL, vgid)))
92 if (!strcmp(vg_name, vg_name_old)) {
94 log_error("Found more than one VG called %s. "
95 "Please supply VG uuid.", vg_name_old);
103 found_id = id_read_format(&id, vg_name_old);
105 if (found_id && (vg_name = vgname_from_vgid(cmd->mem, (char *)id.uuid))) {
106 vg_name_old = vg_name;
107 vgid = (char *)id.uuid;
111 if (strcmp(vg_name_new, vg_name_old) < 0)
112 lock_vg_old_first = 0;
114 if (lock_vg_old_first) {
115 vg = _get_old_vg_for_rename(cmd, vg_name_old, vgid);
119 if (!_lock_new_vg_for_rename(cmd, vg_name_new)) {
120 unlock_and_free_vg(cmd, vg, vg_name_old);
124 if (!_lock_new_vg_for_rename(cmd, vg_name_new))
127 vg = _get_old_vg_for_rename(cmd, vg_name_old, vgid);
129 unlock_vg(cmd, vg_name_new);
137 /* Remove references based on old name */
138 drop_cached_metadata(vg);
140 /* Change the volume group name */
141 vg_rename(cmd, vg, vg_name_new);
143 /* store it on disks */
144 log_verbose("Writing out updated volume group");
145 if (!vg_write(vg) || !vg_commit(vg)) {
149 sprintf(old_path, "%s%s", dev_dir, vg_name_old);
150 sprintf(new_path, "%s%s", dev_dir, vg_name_new);
152 if (activation() && dir_exists(old_path)) {
153 log_verbose("Renaming \"%s\" to \"%s\"", old_path, new_path);
156 log_verbose("Test mode: Skipping rename.");
158 else if (lvs_in_vg_activated(vg)) {
159 if (!vg_refresh_visible(cmd, vg)) {
160 log_error("Renaming \"%s\" to \"%s\" failed",
168 backup_remove(cmd, vg_name_old);
170 unlock_vg(cmd, vg_name_new);
171 unlock_and_free_vg(cmd, vg, vg_name_old);
173 log_print("Volume group \"%s\" successfully renamed to \"%s\"",
174 vg_name_old, vg_name_new);
176 /* FIXME lvmcache corruption - vginfo duplicated instead of renamed */
177 persistent_filter_wipe(cmd->filter);
178 lvmcache_destroy(cmd, 1);
183 if (lock_vg_old_first) {
184 unlock_vg(cmd, vg_name_new);
185 unlock_and_free_vg(cmd, vg, vg_name_old);
187 unlock_and_free_vg(cmd, vg, vg_name_old);
188 unlock_vg(cmd, vg_name_new);
193 int vgrename(struct cmd_context *cmd, int argc, char **argv)
196 log_error("Old and new volume group names need specifying");
197 return EINVALID_CMD_LINE;
200 if (!vg_rename_path(cmd, argv[0], argv[1])) {
205 return ECMD_PROCESSED;