xref: /dragonfly/contrib/lvm2/dist/tools/vgrename.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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 
vg_rename_old(struct cmd_context * cmd,const char * vg_name_old,const char * vgid)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 
vg_rename_new(struct cmd_context * cmd,const char * vg_name_new)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 
vg_rename_path(struct cmd_context * cmd,const char * old_vg_path,const char * new_vg_path)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 
vgrename(struct cmd_context * cmd,int argc,char ** argv)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