Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / contrib / lvm2 / dist / tools / vgrename.c
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