1 /* $NetBSD: vgrename.c,v 1.1.1.2 2009/02/18 11:17:51 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2007 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 int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path, 21 const char *new_vg_path) 22 { 23 char *dev_dir; 24 struct id id; 25 int consistent = 1; 26 int match = 0; 27 int found_id = 0; 28 struct dm_list *vgids; 29 struct str_list *sl; 30 char *vg_name_new; 31 const char *vgid = NULL, *vg_name, *vg_name_old; 32 char old_path[NAME_LEN], new_path[NAME_LEN]; 33 struct volume_group *vg, *vg_new; 34 35 vg_name_old = skip_dev_dir(cmd, old_vg_path, NULL); 36 vg_name_new = skip_dev_dir(cmd, new_vg_path, NULL); 37 38 dev_dir = cmd->dev_dir; 39 40 if (!validate_vg_rename_params(cmd, vg_name_old, vg_name_new)) 41 return 0; 42 43 log_verbose("Checking for existing volume group \"%s\"", vg_name_old); 44 45 /* Avoid duplicates */ 46 if (!(vgids = get_vgids(cmd, 0)) || dm_list_empty(vgids)) { 47 log_error("No complete volume groups found"); 48 return 0; 49 } 50 51 dm_list_iterate_items(sl, vgids) { 52 vgid = sl->str; 53 if (!vgid || !(vg_name = vgname_from_vgid(NULL, vgid)) || 54 is_orphan_vg(vg_name)) 55 continue; 56 if (!strcmp(vg_name, vg_name_old)) { 57 if (match) { 58 log_error("Found more than one VG called %s. " 59 "Please supply VG uuid.", vg_name_old); 60 return 0; 61 } 62 match = 1; 63 } 64 } 65 66 log_suppress(2); 67 found_id = id_read_format(&id, vg_name_old); 68 log_suppress(0); 69 if (found_id && (vg_name = vgname_from_vgid(cmd->mem, (char *)id.uuid))) { 70 vg_name_old = vg_name; 71 vgid = (char *)id.uuid; 72 } else 73 vgid = NULL; 74 75 if (!lock_vol(cmd, vg_name_old, LCK_VG_WRITE)) { 76 log_error("Can't get lock for %s", vg_name_old); 77 return 0; 78 } 79 80 if (!(vg = vg_read(cmd, vg_name_old, vgid, &consistent)) || !consistent) { 81 log_error("Volume group %s %s%s%snot found.", vg_name_old, 82 vgid ? "(" : "", vgid ? vgid : "", vgid ? ") " : ""); 83 unlock_vg(cmd, vg_name_old); 84 return 0; 85 } 86 87 if (!vg_check_status(vg, CLUSTERED | LVM_WRITE)) { 88 unlock_vg(cmd, vg_name_old); 89 return 0; 90 } 91 92 /* Don't return failure for EXPORTED_VG */ 93 vg_check_status(vg, EXPORTED_VG); 94 95 if (lvs_in_vg_activated_by_uuid_only(vg)) { 96 unlock_vg(cmd, vg_name_old); 97 log_error("Volume group \"%s\" still has active LVs", 98 vg_name_old); 99 /* FIXME Remove this restriction */ 100 return 0; 101 } 102 103 log_verbose("Checking for new volume group \"%s\"", vg_name_new); 104 105 if (!lock_vol(cmd, vg_name_new, LCK_VG_WRITE | LCK_NONBLOCK)) { 106 unlock_vg(cmd, vg_name_old); 107 log_error("Can't get lock for %s", vg_name_new); 108 return 0; 109 } 110 111 consistent = 0; 112 if ((vg_new = vg_read(cmd, vg_name_new, NULL, &consistent))) { 113 log_error("New volume group \"%s\" already exists", 114 vg_name_new); 115 goto error; 116 } 117 118 if (!archive(vg)) 119 goto error; 120 121 /* Remove references based on old name */ 122 drop_cached_metadata(vg); 123 124 /* Change the volume group name */ 125 vg_rename(cmd, vg, vg_name_new); 126 127 /* store it on disks */ 128 log_verbose("Writing out updated volume group"); 129 if (!vg_write(vg) || !vg_commit(vg)) { 130 goto error; 131 } 132 133 sprintf(old_path, "%s%s", dev_dir, vg_name_old); 134 sprintf(new_path, "%s%s", dev_dir, vg_name_new); 135 136 if (activation() && dir_exists(old_path)) { 137 log_verbose("Renaming \"%s\" to \"%s\"", old_path, new_path); 138 139 if (test_mode()) 140 log_verbose("Test mode: Skipping rename."); 141 142 else if (lvs_in_vg_activated_by_uuid_only(vg)) { 143 if (!vg_refresh_visible(cmd, vg)) { 144 log_error("Renaming \"%s\" to \"%s\" failed", 145 old_path, new_path); 146 goto error; 147 } 148 } 149 } 150 151 /******* FIXME Rename any active LVs! *****/ 152 153 backup(vg); 154 155 unlock_vg(cmd, vg_name_new); 156 unlock_vg(cmd, vg_name_old); 157 158 log_print("Volume group \"%s\" successfully renamed to \"%s\"", 159 vg_name_old, vg_name_new); 160 161 /* FIXME lvmcache corruption - vginfo duplicated instead of renamed */ 162 persistent_filter_wipe(cmd->filter); 163 lvmcache_destroy(cmd, 1); 164 165 return 1; 166 167 error: 168 unlock_vg(cmd, vg_name_new); 169 unlock_vg(cmd, vg_name_old); 170 return 0; 171 } 172 173 int vgrename(struct cmd_context *cmd, int argc, char **argv) 174 { 175 if (argc != 2) { 176 log_error("Old and new volume group names need specifying"); 177 return EINVALID_CMD_LINE; 178 } 179 180 if (!vg_rename_path(cmd, argv[0], argv[1])) 181 return ECMD_FAILED; 182 183 return ECMD_PROCESSED; 184 } 185 186