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