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