2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
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.
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
18 struct lvrename_params
{
20 const char *lv_name_old
;
21 const char *lv_name_new
;
25 * Dummy LV to represent historical LV.
27 static struct logical_volume _historical_lv
= {
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
),
39 static int _lvrename_single(struct cmd_context
*cmd
, const char *vg_name
,
40 struct volume_group
*vg
, struct processing_handle
*handle
)
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
;
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
);
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" :
61 if (lv_is_raid_with_tracking(lv
)) {
62 log_error("Cannot rename %s while it is tracking a split image",
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
);
73 _historical_lv
.vg
= vg
;
74 _historical_lv
.name
= lp
->lv_name_old
;
75 _historical_lv
.this_glv
= glv
;
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.
88 if (!lockd_lv(cmd
, lv
, "ex", 0))
91 if (!lv_rename(cmd
, lv
, lp
->lv_name_new
))
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
,
105 * lvrename command implementation.
106 * Check arguments and call lv_rename() to execute the request.
108 int lvrename(struct cmd_context
*cmd
, int argc
, char **argv
)
110 struct processing_handle
*handle
= NULL
;
111 struct lvrename_params lp
= { 0 };
113 char *lv_name_old
, *lv_name_new
;
114 const char *vg_name
, *vg_name_new
, *vg_name_old
;
119 cmd
->include_historical_lvs
= 1;
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
;
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
);
137 log_error("Old and new logical volume names required");
138 return EINVALID_CMD_LINE
;
141 if (!validate_name(vg_name
)) {
142 log_error("Please provide a valid volume group name");
143 return EINVALID_CMD_LINE
;
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
;
155 if ((st
= strrchr(lv_name_old
, '/')))
156 lv_name_old
= st
+ 1;
158 if ((st
= strrchr(lv_name_new
, '/')))
159 lv_name_new
= st
+ 1;
161 if (!strncmp(lv_name_old
, HISTORICAL_LV_PREFIX
, strlen(HISTORICAL_LV_PREFIX
))) {
162 lv_name_old
= lv_name_old
+ strlen(HISTORICAL_LV_PREFIX
);
166 if (!strncmp(lv_name_new
, HISTORICAL_LV_PREFIX
, strlen(HISTORICAL_LV_PREFIX
))) {
168 lv_name_new
= lv_name_old
+ strlen(HISTORICAL_LV_PREFIX
);
170 log_error("Old name references live LV while "
171 "new name is for historical LV.");
172 return EINVALID_CMD_LINE
;
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
;
185 log_error("New logical volume name may not be blank");
186 return EINVALID_CMD_LINE
;
189 if (!apply_lvname_restrictions(lv_name_new
)) {
191 return EINVALID_CMD_LINE
;
194 if (!validate_name(lv_name_new
)) {
195 log_error("New logical volume name \"%s\" is invalid",
197 return EINVALID_CMD_LINE
;
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
;
205 lp
.historical
= historical
;
207 if (!(lp
.lv_name_old
= dm_pool_strdup(cmd
->mem
, lv_name_old
)))
210 if (!(lp
.lv_name_new
= dm_pool_strdup(cmd
->mem
, lv_name_new
)))
213 if (!(handle
= init_processing_handle(cmd
, NULL
))) {
214 log_error("Failed to initialize processing handle.");
218 handle
->custom_handle
= &lp
;
220 ret
= process_each_vg(cmd
, 0, NULL
, vg_name
, NULL
, READ_FOR_UPDATE
, 0, handle
,
223 destroy_processing_handle(cmd
, handle
);