4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
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.
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
20 /* FIXME Why not (lv->vg == vg) ? */
21 static int _lv_is_in_vg(struct volume_group
*vg
, struct logical_volume
*lv
)
25 dm_list_iterate_items(lvl
, &vg
->lvs
)
32 static int _move_one_lv(struct volume_group
*vg_from
,
33 struct volume_group
*vg_to
,
36 struct logical_volume
*lv
= dm_list_item(lvh
, struct lv_list
)->lv
;
38 dm_list_move(&vg_to
->lvs
, lvh
);
40 if (lv_is_active(lv
)) {
41 log_error("Logical volume \"%s\" must be inactive", lv
->name
);
48 static int _move_lvs(struct volume_group
*vg_from
, struct volume_group
*vg_to
)
50 struct dm_list
*lvh
, *lvht
;
51 struct logical_volume
*lv
;
52 struct lv_segment
*seg
;
53 struct physical_volume
*pv
;
54 struct volume_group
*vg_with
;
57 dm_list_iterate_safe(lvh
, lvht
, &vg_from
->lvs
) {
58 lv
= dm_list_item(lvh
, struct lv_list
)->lv
;
60 if ((lv
->status
& SNAPSHOT
))
63 if ((lv
->status
& MIRRORED
))
66 /* Ensure all the PVs used by this LV remain in the same */
67 /* VG as each other */
69 dm_list_iterate_items(seg
, &lv
->segments
) {
70 for (s
= 0; s
< seg
->area_count
; s
++) {
71 /* FIXME Check AREA_LV too */
72 if (seg_type(seg
, s
) != AREA_PV
)
77 if (!pv_is_in_vg(vg_with
, pv
)) {
78 log_error("Can't split Logical "
87 if (pv_is_in_vg(vg_from
, pv
)) {
91 if (pv_is_in_vg(vg_to
, pv
)) {
95 log_error("Physical Volume %s not found",
102 if (vg_with
== vg_from
)
106 if (!_move_one_lv(vg_from
, vg_to
, lvh
))
110 /* FIXME Ensure no LVs contain segs pointing at LVs in the other VG */
116 * Move the hidden / internal "snapshotN" LVs.from 'vg_from' to 'vg_to'.
118 static int _move_snapshots(struct volume_group
*vg_from
,
119 struct volume_group
*vg_to
)
121 struct dm_list
*lvh
, *lvht
;
122 struct logical_volume
*lv
;
123 struct lv_segment
*seg
;
127 dm_list_iterate_safe(lvh
, lvht
, &vg_from
->lvs
) {
128 lv
= dm_list_item(lvh
, struct lv_list
)->lv
;
130 if (!(lv
->status
& SNAPSHOT
))
133 dm_list_iterate_items(seg
, &lv
->segments
) {
134 cow_from
= _lv_is_in_vg(vg_from
, seg
->cow
);
135 origin_from
= _lv_is_in_vg(vg_from
, seg
->origin
);
137 if (cow_from
&& origin_from
)
139 if ((!cow_from
&& origin_from
) ||
140 (cow_from
&& !origin_from
)) {
141 log_error("Can't split snapshot %s between"
142 " two Volume Groups", seg
->cow
->name
);
147 * At this point, the cow and origin should already be
150 if (_lv_is_in_vg(vg_to
, seg
->cow
) &&
151 _lv_is_in_vg(vg_to
, seg
->origin
)) {
152 if (!_move_one_lv(vg_from
, vg_to
, lvh
))
162 static int _move_mirrors(struct volume_group
*vg_from
,
163 struct volume_group
*vg_to
)
165 struct dm_list
*lvh
, *lvht
;
166 struct logical_volume
*lv
;
167 struct lv_segment
*seg
;
168 unsigned s
, seg_in
, log_in
;
170 dm_list_iterate_safe(lvh
, lvht
, &vg_from
->lvs
) {
171 lv
= dm_list_item(lvh
, struct lv_list
)->lv
;
173 if (!(lv
->status
& MIRRORED
))
179 for (s
= 0; s
< seg
->area_count
; s
++)
180 if (_lv_is_in_vg(vg_to
, seg_lv(seg
, s
)))
183 log_in
= (!seg
->log_lv
|| _lv_is_in_vg(vg_to
, seg
->log_lv
));
185 if ((seg_in
&& seg_in
< seg
->area_count
) ||
186 (seg_in
&& seg
->log_lv
&& !log_in
) ||
187 (!seg_in
&& seg
->log_lv
&& log_in
)) {
188 log_error("Can't split mirror %s between "
189 "two Volume Groups", lv
->name
);
193 if (seg_in
== seg
->area_count
&& log_in
) {
194 if (!_move_one_lv(vg_from
, vg_to
, lvh
))
203 * Create or open the destination of the vgsplit operation.
205 * - non-NULL: VG handle w/VG lock held
206 * - NULL: no VG lock held
208 static struct volume_group
*_vgsplit_to(struct cmd_context
*cmd
,
209 const char *vg_name_to
,
212 struct volume_group
*vg_to
= NULL
;
214 log_verbose("Checking for new volume group \"%s\"", vg_name_to
);
216 * First try to create a new VG. If we cannot create it,
217 * and we get FAILED_EXIST (we will not be holding a lock),
218 * a VG must already exist with this name. We then try to
219 * read the existing VG - the vgsplit will be into an existing VG.
221 * Otherwise, if the lock was successful, it must be the case that
222 * we obtained a WRITE lock and could not find the vgname in the
223 * system. Thus, the split will be into a new VG.
225 vg_to
= vg_create(cmd
, vg_name_to
);
226 if (vg_read_error(vg_to
) == FAILED_LOCKING
) {
227 log_error("Can't get lock for %s", vg_name_to
);
231 if (vg_read_error(vg_to
) == FAILED_EXIST
) {
234 vg_to
= vg_read_for_update(cmd
, vg_name_to
, NULL
, 0);
236 if (vg_read_error(vg_to
)) {
242 } else if (vg_read_error(vg_to
) == SUCCESS
) {
249 * Open the source of the vgsplit operation.
251 * - non-NULL: VG handle w/VG lock held
252 * - NULL: no VG lock held
254 static struct volume_group
*_vgsplit_from(struct cmd_context
*cmd
,
255 const char *vg_name_from
)
257 struct volume_group
*vg_from
;
259 log_verbose("Checking for volume group \"%s\"", vg_name_from
);
261 vg_from
= vg_read_for_update(cmd
, vg_name_from
, NULL
, 0);
262 if (vg_read_error(vg_from
)) {
270 * Has the user given an option related to a new vg as the split destination?
272 static int new_vg_option_specified(struct cmd_context
*cmd
)
274 return(arg_count(cmd
, clustered_ARG
) ||
275 arg_count(cmd
, alloc_ARG
) ||
276 arg_count(cmd
, maxphysicalvolumes_ARG
) ||
277 arg_count(cmd
, maxlogicalvolumes_ARG
));
280 int vgsplit(struct cmd_context
*cmd
, int argc
, char **argv
)
282 struct vgcreate_params vp_new
;
283 struct vgcreate_params vp_def
;
284 char *vg_name_from
, *vg_name_to
;
285 struct volume_group
*vg_to
= NULL
, *vg_from
= NULL
;
290 int lock_vg_from_first
= 1;
292 if ((arg_count(cmd
, name_ARG
) + argc
) < 3) {
293 log_error("Existing VG, new VG and either physical volumes "
294 "or logical volume required.");
295 return EINVALID_CMD_LINE
;
298 if (arg_count(cmd
, name_ARG
) && (argc
> 2)) {
299 log_error("A logical volume name cannot be given with "
300 "physical volumes.");
304 if (arg_count(cmd
, name_ARG
))
305 lv_name
= arg_value(cmd
, name_ARG
);
309 vg_name_from
= skip_dev_dir(cmd
, argv
[0], NULL
);
310 vg_name_to
= skip_dev_dir(cmd
, argv
[1], NULL
);
314 if (!strcmp(vg_name_to
, vg_name_from
)) {
315 log_error("Duplicate volume group name \"%s\"", vg_name_from
);
319 if (strcmp(vg_name_to
, vg_name_from
) < 0)
320 lock_vg_from_first
= 0;
322 if (lock_vg_from_first
) {
323 vg_from
= _vgsplit_from(cmd
, vg_name_from
);
329 * Set metadata format of original VG.
330 * NOTE: We must set the format before calling vg_create()
331 * since vg_create() calls the per-format constructor.
333 cmd
->fmt
= vg_from
->fid
->fmt
;
335 vg_to
= _vgsplit_to(cmd
, vg_name_to
, &existing_vg
);
337 unlock_and_release_vg(cmd
, vg_from
, vg_name_from
);
342 vg_to
= _vgsplit_to(cmd
, vg_name_to
, &existing_vg
);
347 vg_from
= _vgsplit_from(cmd
, vg_name_from
);
349 unlock_and_release_vg(cmd
, vg_to
, vg_name_to
);
354 if (cmd
->fmt
!= vg_from
->fid
->fmt
) {
355 /* In this case we don't know the vg_from->fid->fmt */
356 log_error("Unable to set new VG metadata type based on "
357 "source VG format - use -M option.");
363 if (new_vg_option_specified(cmd
)) {
364 log_error("Volume group \"%s\" exists, but new VG "
365 "option specified", vg_name_to
);
368 if (!vgs_are_compatible(cmd
, vg_from
,vg_to
))
371 vgcreate_params_set_defaults(&vp_def
, vg_from
);
372 vp_def
.vg_name
= vg_name_to
;
373 if (vgcreate_params_set_from_args(cmd
, &vp_new
, &vp_def
)) {
374 r
= EINVALID_CMD_LINE
;
378 if (vgcreate_params_validate(cmd
, &vp_new
)) {
379 r
= EINVALID_CMD_LINE
;
383 if (!vg_set_extent_size(vg_to
, vp_new
.extent_size
) ||
384 !vg_set_max_lv(vg_to
, vp_new
.max_lv
) ||
385 !vg_set_max_pv(vg_to
, vp_new
.max_pv
) ||
386 !vg_set_alloc_policy(vg_to
, vp_new
.alloc
) ||
387 !vg_set_clustered(vg_to
, vp_new
.clustered
))
391 /* Archive vg_from before changing it */
392 if (!archive(vg_from
))
395 /* Move PVs across to new structure */
396 for (opt
= 0; opt
< argc
; opt
++) {
397 if (!move_pv(vg_from
, vg_to
, argv
[opt
]))
401 /* If an LV given on the cmdline, move used_by PVs */
402 if (lv_name
&& !move_pvs_used_by_lv(vg_from
, vg_to
, lv_name
))
405 /* Move required LVs across, checking consistency */
406 if (!(_move_lvs(vg_from
, vg_to
)))
409 /* FIXME Separate the 'move' from the 'validation' to fix dev stacks */
410 /* Move required mirrors across */
411 if (!(_move_mirrors(vg_from
, vg_to
)))
414 /* Move required snapshots across */
415 if (!(_move_snapshots(vg_from
, vg_to
)))
418 /* Split metadata areas and check if both vgs have at least one area */
419 if (!(vg_split_mdas(cmd
, vg_from
, vg_to
)) && vg_from
->pv_count
) {
420 log_error("Cannot split: Nowhere to store metadata for new Volume Group");
424 /* Set proper name for all PVs in new VG */
425 if (!vg_rename(cmd
, vg_to
, vg_name_to
))
428 /* store it on disks */
429 log_verbose("Writing out updated volume groups");
432 * First, write out the new VG as EXPORTED. We do this first in case
433 * there is a crash - we will still have the new VG information, in an
434 * exported state. Recovery after this point would be removal of the
435 * new VG and redoing the vgsplit.
436 * FIXME: recover automatically or instruct the user?
438 vg_to
->status
|= EXPORTED_VG
;
443 if (!vg_write(vg_to
) || !vg_commit(vg_to
))
449 * Next, write out the updated old VG. If we crash after this point,
450 * recovery is a vgimport on the new VG.
451 * FIXME: recover automatically or instruct the user?
453 if (vg_from
->pv_count
) {
454 if (!vg_write(vg_from
) || !vg_commit(vg_from
))
461 * Finally, remove the EXPORTED flag from the new VG and write it out.
465 vg_to
= vg_read_for_update(cmd
, vg_name_to
, NULL
,
466 READ_ALLOW_EXPORTED
);
467 if (vg_read_error(vg_to
)) {
468 log_error("Volume group \"%s\" became inconsistent: "
469 "please fix manually", vg_name_to
);
474 vg_to
->status
&= ~EXPORTED_VG
;
476 if (!vg_write(vg_to
) || !vg_commit(vg_to
))
481 log_print("%s volume group \"%s\" successfully split from \"%s\"",
482 existing_vg
? "Existing" : "New",
483 vg_to
->name
, vg_from
->name
);
488 if (lock_vg_from_first
) {
489 unlock_and_release_vg(cmd
, vg_to
, vg_name_to
);
490 unlock_and_release_vg(cmd
, vg_from
, vg_name_from
);
492 unlock_and_release_vg(cmd
, vg_from
, vg_name_from
);
493 unlock_and_release_vg(cmd
, vg_to
, vg_name_to
);