]> sourceware.org Git - lvm2.git/blob - tools/lvrename.c
74248ee91c8e9c6ea5951b78083c05bdc376163d
[lvm2.git] / tools / lvrename.c
1 /*
2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14 */
15
16 #include "tools.h"
17
18 struct lvrename_params {
19 int historical;
20 const char *lv_name_old;
21 const char *lv_name_new;
22 };
23
24 /*
25 * Dummy LV to represent historical LV.
26 */
27 static struct logical_volume _historical_lv = {
28 .name = "",
29 .major = -1,
30 .minor = -1,
31 .snapshot_segs = DM_LIST_HEAD_INIT(_historical_lv.snapshot_segs),
32 .segments = DM_LIST_HEAD_INIT(_historical_lv.segments),
33 .tags = DM_LIST_HEAD_INIT(_historical_lv.tags),
34 .segs_using_this_lv = DM_LIST_HEAD_INIT(_historical_lv.segs_using_this_lv),
35 .indirect_glvs = DM_LIST_HEAD_INIT(_historical_lv.indirect_glvs),
36 .hostname = "",
37 };
38
39 static int _lvrename_single(struct cmd_context *cmd, const char *vg_name,
40 struct volume_group *vg, struct processing_handle *handle)
41 {
42 struct lvrename_params *lp = (struct lvrename_params *) handle->custom_handle;
43 struct generic_logical_volume *glv;
44 struct logical_volume *lv;
45 int ret = ECMD_FAILED;
46
47 if (!lp->historical) {
48 if (!(lv = find_lv(vg, lp->lv_name_old))) {
49 log_error("Existing logical volume \"%s\" not found in "
50 "volume group \"%s\"", lp->lv_name_old, vg_name);
51 goto bad;
52 }
53
54 if (lv_is_raid_image(lv) || lv_is_raid_metadata(lv)) {
55 log_error("Cannot rename a RAID %s directly",
56 lv_is_raid_image(lv) ? "image" :
57 "metadata area");
58 goto bad;
59 }
60
61 if (lv_is_raid_with_tracking(lv)) {
62 log_error("Cannot rename %s while it is tracking a split image",
63 lv->name);
64 goto bad;
65 }
66 } else {
67 if (!(glv = find_historical_glv(vg, lp->lv_name_old, 0, NULL))) {
68 log_error("Existing historical logical volume \"%s\" not found in "
69 "volume group \"%s\"", lp->lv_name_old, vg_name);
70 goto bad;
71 }
72
73 _historical_lv.vg = vg;
74 _historical_lv.name = lp->lv_name_old;
75 _historical_lv.this_glv = glv;
76 lv = &_historical_lv;
77 }
78
79 /*
80 * The lvmlockd LV lock is only acquired here to ensure the LV is not
81 * active on another host. This requests a transient LV lock.
82 * If the LV is active, a persistent LV lock already exists in
83 * lvmlockd, and the transient lock request does nothing.
84 * If the LV is not active, then no LV lock exists and the transient
85 * lock request acquires the LV lock (or fails). The transient lock
86 * is automatically released when the command exits.
87 */
88 if (!lockd_lv(cmd, lv, "ex", 0))
89 goto_bad;
90
91 if (!lv_rename(cmd, lv, lp->lv_name_new))
92 goto_bad;
93
94 log_print_unless_silent("Renamed \"%s%s\" to \"%s%s\" in volume group \"%s\"",
95 lp->historical ? HISTORICAL_LV_PREFIX : "", lp->lv_name_old,
96 lp->historical ? HISTORICAL_LV_PREFIX : "", lp->lv_name_new,
97 vg_name);
98
99 ret = ECMD_PROCESSED;
100 bad:
101 return ret;
102 }
103
104 /*
105 * lvrename command implementation.
106 * Check arguments and call lv_rename() to execute the request.
107 */
108 int lvrename(struct cmd_context *cmd, int argc, char **argv)
109 {
110 struct processing_handle *handle = NULL;
111 struct lvrename_params lp = { 0 };
112 size_t maxlen;
113 char *lv_name_old, *lv_name_new;
114 const char *vg_name, *vg_name_new, *vg_name_old;
115 int historical = 0;
116 char *st;
117 int ret;
118
119 cmd->include_historical_lvs = 1;
120
121 if (argc == 3) {
122 vg_name = skip_dev_dir(cmd, argv[0], NULL);
123 lv_name_old = argv[1];
124 lv_name_new = argv[2];
125 if (strchr(lv_name_old, '/') &&
126 (vg_name_old = extract_vgname(cmd, lv_name_old)) &&
127 strcmp(vg_name_old, vg_name)) {
128 log_error("Please use a single volume group name "
129 "(\"%s\" or \"%s\")", vg_name, vg_name_old);
130 return EINVALID_CMD_LINE;
131 }
132 } else if (argc == 2) {
133 lv_name_old = argv[0];
134 lv_name_new = argv[1];
135 vg_name = extract_vgname(cmd, lv_name_old);
136 } else {
137 log_error("Old and new logical volume names required");
138 return EINVALID_CMD_LINE;
139 }
140
141 if (!validate_name(vg_name)) {
142 log_error("Please provide a valid volume group name");
143 return EINVALID_CMD_LINE;
144 }
145
146 if (strchr(lv_name_new, '/') &&
147 (vg_name_new = extract_vgname(cmd, lv_name_new)) &&
148 strcmp(vg_name, vg_name_new)) {
149 log_error("Logical volume names must "
150 "have the same volume group (\"%s\" or \"%s\")",
151 vg_name, vg_name_new);
152 return EINVALID_CMD_LINE;
153 }
154
155 if ((st = strrchr(lv_name_old, '/')))
156 lv_name_old = st + 1;
157
158 if ((st = strrchr(lv_name_new, '/')))
159 lv_name_new = st + 1;
160
161 if (!strncmp(lv_name_old, HISTORICAL_LV_PREFIX, strlen(HISTORICAL_LV_PREFIX))) {
162 lv_name_old = lv_name_old + strlen(HISTORICAL_LV_PREFIX);
163 historical = 1;
164 }
165
166 if (!strncmp(lv_name_new, HISTORICAL_LV_PREFIX, strlen(HISTORICAL_LV_PREFIX))) {
167 if (historical)
168 lv_name_new = lv_name_old + strlen(HISTORICAL_LV_PREFIX);
169 else {
170 log_error("Old name references live LV while "
171 "new name is for historical LV.");
172 return EINVALID_CMD_LINE;
173 }
174 }
175
176 /* Check sanity of new name */
177 maxlen = NAME_LEN - strlen(vg_name) - 3;
178 if (strlen(lv_name_new) > maxlen) {
179 log_error("New logical volume name \"%s\" may not exceed %"
180 PRIsize_t " characters.", lv_name_new, maxlen);
181 return EINVALID_CMD_LINE;
182 }
183
184 if (!*lv_name_new) {
185 log_error("New logical volume name may not be blank");
186 return EINVALID_CMD_LINE;
187 }
188
189 if (!apply_lvname_restrictions(lv_name_new)) {
190 stack;
191 return EINVALID_CMD_LINE;
192 }
193
194 if (!validate_name(lv_name_new)) {
195 log_error("New logical volume name \"%s\" is invalid",
196 lv_name_new);
197 return EINVALID_CMD_LINE;
198 }
199
200 if (!strcmp(lv_name_old, lv_name_new)) {
201 log_error("Old and new logical volume names must differ");
202 return EINVALID_CMD_LINE;
203 }
204
205 lp.historical = historical;
206
207 if (!(lp.lv_name_old = dm_pool_strdup(cmd->mem, lv_name_old)))
208 return ECMD_FAILED;
209
210 if (!(lp.lv_name_new = dm_pool_strdup(cmd->mem, lv_name_new)))
211 return ECMD_FAILED;
212
213 if (!(handle = init_processing_handle(cmd, NULL))) {
214 log_error("Failed to initialize processing handle.");
215 return ECMD_FAILED;
216 }
217
218 handle->custom_handle = &lp;
219
220 ret = process_each_vg(cmd, 0, NULL, vg_name, NULL, READ_FOR_UPDATE, 0, handle,
221 _lvrename_single);
222
223 destroy_processing_handle(cmd, handle);
224
225 return ret;
226 }
This page took 0.053722 seconds and 6 git commands to generate.