2 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2010 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include "polldaemon.h"
20 #define PVMOVE_FIRST_TIME 0x00000001 /* Called for first time */
22 static int _pvmove_target_present(struct cmd_context
*cmd
, int clustered
)
24 const struct segment_type
*segtype
;
27 static int _clustered_found
= -1;
29 if (clustered
&& _clustered_found
>= 0)
30 return _clustered_found
;
32 if (!(segtype
= get_segtype_from_string(cmd
, "mirror")))
35 if (activation() && segtype
->ops
->target_present
&&
36 !segtype
->ops
->target_present(cmd
, NULL
, clustered
? &attr
: NULL
))
39 if (activation() && clustered
) {
40 if (found
&& (attr
& MIRROR_LOG_CLUSTERED
))
41 _clustered_found
= found
= 1;
43 _clustered_found
= found
= 0;
49 static unsigned _pvmove_is_exclusive(struct cmd_context
*cmd
,
50 struct volume_group
*vg
)
52 if (vg_is_clustered(vg
))
53 if (!_pvmove_target_present(cmd
, 1))
59 /* Allow /dev/vgname/lvname, vgname/lvname or lvname */
60 static const char *_extract_lvname(struct cmd_context
*cmd
, const char *vgname
,
65 /* Is an lvname supplied directly? */
66 if (!strchr(arg
, '/'))
69 lvname
= skip_dev_dir(cmd
, arg
, NULL
);
70 while (*lvname
== '/')
72 if (!strchr(lvname
, '/')) {
73 log_error("--name takes a logical volume name");
76 if (strncmp(vgname
, lvname
, strlen(vgname
)) ||
77 (lvname
+= strlen(vgname
), *lvname
!= '/')) {
78 log_error("Named LV and old PV must be in the same VG");
81 while (*lvname
== '/')
84 log_error("Incomplete LV name supplied with --name");
90 static struct volume_group
*_get_vg(struct cmd_context
*cmd
, const char *vgname
)
94 return vg_read_for_update(cmd
, vgname
, NULL
, 0);
97 /* Create list of PVs for allocation of replacement extents */
98 static struct dm_list
*_get_allocatable_pvs(struct cmd_context
*cmd
, int argc
,
99 char **argv
, struct volume_group
*vg
,
100 struct physical_volume
*pv
,
101 alloc_policy_t alloc
)
103 struct dm_list
*allocatable_pvs
, *pvht
, *pvh
;
107 allocatable_pvs
= create_pv_list(cmd
->mem
, vg
, argc
, argv
, 1);
109 allocatable_pvs
= clone_pv_list(cmd
->mem
, &vg
->pvs
);
111 if (!allocatable_pvs
)
114 dm_list_iterate_safe(pvh
, pvht
, allocatable_pvs
) {
115 pvl
= dm_list_item(pvh
, struct pv_list
);
117 /* Don't allocate onto the PV we're clearing! */
118 if ((alloc
!= ALLOC_ANYWHERE
) && (pvl
->pv
->dev
== pv_dev(pv
))) {
119 dm_list_del(&pvl
->list
);
123 /* Remove PV if full */
124 if (pvl
->pv
->pe_count
== pvl
->pv
->pe_alloc_count
)
125 dm_list_del(&pvl
->list
);
128 if (dm_list_empty(allocatable_pvs
)) {
129 log_error("No extents available for allocation");
133 return allocatable_pvs
;
137 * Replace any LV segments on given PV with temporary mirror.
138 * Returns list of LVs changed.
140 static int _insert_pvmove_mirrors(struct cmd_context
*cmd
,
141 struct logical_volume
*lv_mirr
,
142 struct dm_list
*source_pvl
,
143 struct logical_volume
*lv
,
144 struct dm_list
*lvs_changed
)
148 uint32_t prev_le_count
;
150 /* Only 1 PV may feature in source_pvl */
151 pvl
= dm_list_item(source_pvl
->n
, struct pv_list
);
153 prev_le_count
= lv_mirr
->le_count
;
154 if (!insert_layer_for_segments_on_pv(cmd
, lv
, lv_mirr
, PVMOVE
,
158 /* check if layer was inserted */
159 if (lv_mirr
->le_count
- prev_le_count
) {
160 lv
->status
|= LOCKED
;
162 log_verbose("Moving %u extents of logical volume %s/%s",
163 lv_mirr
->le_count
- prev_le_count
,
164 lv
->vg
->name
, lv
->name
);
170 /* Create new LV with mirror segments for the required copies */
171 static struct logical_volume
*_set_up_pvmove_lv(struct cmd_context
*cmd
,
172 struct volume_group
*vg
,
173 struct dm_list
*source_pvl
,
175 struct dm_list
*allocatable_pvs
,
176 alloc_policy_t alloc
,
177 struct dm_list
**lvs_changed
)
179 struct logical_volume
*lv_mirr
, *lv
;
181 uint32_t log_count
= 0;
185 /* FIXME Cope with non-contiguous => splitting existing segments */
186 if (!(lv_mirr
= lv_create_empty("pvmove%d", NULL
,
187 LVM_READ
| LVM_WRITE
,
188 ALLOC_CONTIGUOUS
, vg
))) {
189 log_error("Creation of temporary pvmove LV failed");
193 lv_mirr
->status
|= (PVMOVE
| LOCKED
);
195 if (!(*lvs_changed
= dm_pool_alloc(cmd
->mem
, sizeof(**lvs_changed
)))) {
196 log_error("lvs_changed list struct allocation failed");
200 dm_list_init(*lvs_changed
);
202 /* Find segments to be moved and set up mirrors */
203 dm_list_iterate_items(lvl
, &vg
->lvs
) {
208 if (strcmp(lv
->name
, lv_name
))
212 if (lv_is_origin(lv
) || lv_is_cow(lv
)) {
214 log_print("Skipping snapshot-related LV %s", lv
->name
);
217 if (lv
->status
& MIRRORED
) {
219 log_print("Skipping mirror LV %s", lv
->name
);
222 if (lv
->status
& MIRROR_LOG
) {
224 log_print("Skipping mirror log LV %s", lv
->name
);
227 if (lv
->status
& MIRROR_IMAGE
) {
229 log_print("Skipping mirror image LV %s", lv
->name
);
232 if (lv
->status
& LOCKED
) {
234 log_print("Skipping locked LV %s", lv
->name
);
237 if (!_insert_pvmove_mirrors(cmd
, lv_mirr
, source_pvl
, lv
,
242 if (lv_name
&& !lv_found
) {
243 log_error("Logical volume %s not found.", lv_name
);
247 /* Is temporary mirror empty? */
248 if (!lv_mirr
->le_count
) {
250 log_error("All data on source PV skipped. "
251 "It contains locked, hidden or "
252 "non-top level LVs only.");
253 log_error("No data to move for %s", vg
->name
);
257 if (!lv_add_mirrors(cmd
, lv_mirr
, 1, 1, 0, 0, log_count
,
258 allocatable_pvs
, alloc
, MIRROR_BY_SEG
)) {
259 log_error("Failed to convert pvmove LV to mirrored");
263 if (!split_parent_segments_for_layer(cmd
, lv_mirr
)) {
264 log_error("Failed to split segments being moved");
271 static int _activate_lv(struct cmd_context
*cmd
, struct logical_volume
*lv_mirr
,
277 r
= activate_lv_excl(cmd
, lv_mirr
);
279 r
= activate_lv(cmd
, lv_mirr
);
287 static int _detach_pvmove_mirror(struct cmd_context
*cmd
,
288 struct logical_volume
*lv_mirr
)
290 struct dm_list lvs_completed
;
293 /* Update metadata to remove mirror segments and break dependencies */
294 dm_list_init(&lvs_completed
);
295 if (!lv_remove_mirrors(cmd
, lv_mirr
, 1, 0, NULL
, NULL
, PVMOVE
) ||
296 !remove_layers_for_segments_all(cmd
, lv_mirr
, PVMOVE
,
301 dm_list_iterate_items(lvl
, &lvs_completed
)
302 /* FIXME Assumes only one pvmove at a time! */
303 lvl
->lv
->status
&= ~LOCKED
;
308 static int _suspend_lvs(struct cmd_context
*cmd
, unsigned first_time
,
309 struct logical_volume
*lv_mirr
,
310 struct dm_list
*lvs_changed
,
311 struct volume_group
*vg_to_revert
)
314 * Suspend lvs_changed the first time.
315 * Suspend mirrors on subsequent calls.
318 if (!suspend_lvs(cmd
, lvs_changed
, vg_to_revert
))
320 } else if (!suspend_lv(cmd
, lv_mirr
)) {
322 vg_revert(vg_to_revert
);
329 static int _resume_lvs(struct cmd_context
*cmd
, unsigned first_time
,
330 struct logical_volume
*lv_mirr
,
331 struct dm_list
*lvs_changed
)
334 * Suspend lvs_changed the first time.
335 * Suspend mirrors on subsequent calls.
339 if (!resume_lvs(cmd
, lvs_changed
)) {
340 log_error("Unable to resume logical volumes");
343 } else if (!resume_lv(cmd
, lv_mirr
)) {
344 log_error("Unable to reactivate logical volume \"%s\"",
353 * Called to set up initial pvmove LV and to advance the mirror
354 * to successive sections of it.
355 * (Not called after the last section completes.)
357 static int _update_metadata(struct cmd_context
*cmd
, struct volume_group
*vg
,
358 struct logical_volume
*lv_mirr
,
359 struct dm_list
*lvs_changed
, unsigned flags
)
361 unsigned exclusive
= _pvmove_is_exclusive(cmd
, vg
);
362 unsigned first_time
= (flags
& PVMOVE_FIRST_TIME
) ? 1 : 0;
365 log_verbose("Updating volume group metadata");
367 log_error("ABORTING: Volume group metadata update failed.");
371 if (!_suspend_lvs(cmd
, first_time
, lv_mirr
, lvs_changed
, vg
)) {
372 log_error("ABORTING: Volume group metadata update failed. (first_time: %d)", first_time
);
373 /* FIXME Add a recovery path for first time too. */
374 if (!first_time
&& !revert_lv(cmd
, lv_mirr
))
379 /* Commit on-disk metadata */
380 if (!vg_commit(vg
)) {
381 log_error("ABORTING: Volume group metadata update failed.");
382 if (!_resume_lvs(cmd
, first_time
, lv_mirr
, lvs_changed
))
384 if (!first_time
&& !revert_lv(cmd
, lv_mirr
))
389 /* Activate the temporary mirror LV */
390 /* Only the first mirror segment gets activated as a mirror */
391 /* FIXME: Add option to use a log */
393 if (!_activate_lv(cmd
, lv_mirr
, exclusive
)) {
400 * FIXME Run --abort internally here.
402 log_error("ABORTING: Temporary pvmove mirror activation failed. Run pvmove --abort.");
410 if (!_resume_lvs(cmd
, first_time
, lv_mirr
, lvs_changed
))
419 static int _set_up_pvmove(struct cmd_context
*cmd
, const char *pv_name
,
420 int argc
, char **argv
)
422 const char *lv_name
= NULL
;
424 struct volume_group
*vg
;
425 struct dm_list
*source_pvl
;
426 struct dm_list
*allocatable_pvs
;
427 alloc_policy_t alloc
;
428 struct dm_list
*lvs_changed
;
429 struct physical_volume
*pv
;
430 struct logical_volume
*lv_mirr
;
431 unsigned first_time
= 1;
435 pv_name_arg
= argv
[0];
439 /* Find PV (in VG) */
440 if (!(pv
= find_pv_by_name(cmd
, pv_name
))) {
442 return EINVALID_CMD_LINE
;
445 if (arg_count(cmd
, name_ARG
)) {
446 if (!(lv_name
= _extract_lvname(cmd
, pv_vg_name(pv
),
447 arg_value(cmd
, name_ARG
)))) {
450 return EINVALID_CMD_LINE
;
453 if (!validate_name(lv_name
)) {
454 log_error("Logical volume name %s is invalid", lv_name
);
456 return EINVALID_CMD_LINE
;
461 log_verbose("Finding volume group \"%s\"", pv_vg_name(pv
));
463 vg
= _get_vg(cmd
, pv_vg_name(pv
));
464 if (vg_read_error(vg
)) {
470 exclusive
= _pvmove_is_exclusive(cmd
, vg
);
472 if ((lv_mirr
= find_pvmove_lv(vg
, pv_dev(pv
), PVMOVE
))) {
473 log_print("Detected pvmove in progress for %s", pv_name
);
475 log_error("Ignoring remaining command line arguments");
477 if (!(lvs_changed
= lvs_using_lv(cmd
, vg
, lv_mirr
))) {
478 log_error("ABORTING: Failed to generate list of moving LVs");
482 /* Ensure mirror LV is active */
483 if (!_activate_lv(cmd
, lv_mirr
, exclusive
)) {
484 log_error("ABORTING: Temporary mirror activation failed.");
490 /* Determine PE ranges to be moved */
491 if (!(source_pvl
= create_pv_list(cmd
->mem
, vg
, 1,
495 alloc
= (alloc_policy_t
) arg_uint_value(cmd
, alloc_ARG
, ALLOC_INHERIT
);
496 if (alloc
== ALLOC_INHERIT
)
499 /* Get PVs we can use for allocation */
500 if (!(allocatable_pvs
= _get_allocatable_pvs(cmd
, argc
, argv
,
507 if (!(lv_mirr
= _set_up_pvmove_lv(cmd
, vg
, source_pvl
, lv_name
,
508 allocatable_pvs
, alloc
,
513 /* Lock lvs_changed and activate (with old metadata) */
514 if (!activate_lvs(cmd
, lvs_changed
, exclusive
))
517 /* FIXME Presence of a mirror once set PVMOVE - now remove associated logic */
518 /* init_pvmove(1); */
519 /* vg->status |= PVMOVE; */
522 if (!_update_metadata
523 (cmd
, vg
, lv_mirr
, lvs_changed
, PVMOVE_FIRST_TIME
))
527 /* LVs are all in status LOCKED */
531 unlock_and_release_vg(cmd
, vg
, pv_vg_name(pv
));
535 static int _finish_pvmove(struct cmd_context
*cmd
, struct volume_group
*vg
,
536 struct logical_volume
*lv_mirr
,
537 struct dm_list
*lvs_changed
)
541 if (!dm_list_empty(lvs_changed
) &&
542 (!_detach_pvmove_mirror(cmd
, lv_mirr
) ||
543 !replace_lv_with_error_segment(lv_mirr
))) {
544 log_error("ABORTING: Removal of temporary mirror failed");
548 /* Store metadata without dependencies on mirror segments */
550 log_error("ABORTING: Failed to write new data locations "
555 /* Suspend LVs changed (implicitly suspends lv_mirr) */
556 if (!suspend_lvs(cmd
, lvs_changed
, vg
)) {
557 log_error("ABORTING: Locking LVs to remove temporary mirror failed");
558 if (!revert_lv(cmd
, lv_mirr
))
563 /* Store metadata without dependencies on mirror segments */
564 if (!vg_commit(vg
)) {
565 log_error("ABORTING: Failed to write new data locations "
567 if (!revert_lv(cmd
, lv_mirr
))
569 if (!revert_lvs(cmd
, lvs_changed
))
574 /* Release mirror LV. (No pending I/O because it's been suspended.) */
575 if (!resume_lv(cmd
, lv_mirr
)) {
576 log_error("Unable to reactivate logical volume \"%s\"",
582 if (!resume_lvs(cmd
, lvs_changed
))
585 /* Deactivate mirror LV */
586 if (!deactivate_lv(cmd
, lv_mirr
)) {
587 log_error("ABORTING: Unable to deactivate temporary logical "
588 "volume \"%s\"", lv_mirr
->name
);
592 log_verbose("Removing temporary pvmove LV");
593 if (!lv_remove(lv_mirr
)) {
594 log_error("ABORTING: Removal of temporary pvmove LV failed");
598 /* Store it on disks */
599 log_verbose("Writing out final volume group after pvmove");
600 if (!vg_write(vg
) || !vg_commit(vg
)) {
601 log_error("ABORTING: Failed to write new data locations "
606 /* FIXME backup positioning */
612 static struct volume_group
*_get_move_vg(struct cmd_context
*cmd
,
614 const char *uuid
__attribute__((unused
)))
616 struct physical_volume
*pv
;
617 struct volume_group
*vg
;
619 /* Reread all metadata in case it got changed */
620 if (!(pv
= find_pv_by_name(cmd
, name
))) {
621 log_error("ABORTING: Can't reread PV %s", name
);
622 /* What more could we do here? */
626 vg
= _get_vg(cmd
, pv_vg_name(pv
));
632 static struct poll_functions _pvmove_fns
= {
633 .get_copy_name_from_lv
= get_pvmove_pvname_from_lv_mirr
,
634 .get_copy_vg
= _get_move_vg
,
635 .get_copy_lv
= find_pvmove_lv_from_pvname
,
636 .poll_progress
= poll_mirror_progress
,
637 .update_metadata
= _update_metadata
,
638 .finish_copy
= _finish_pvmove
,
641 int pvmove_poll(struct cmd_context
*cmd
, const char *pv_name
,
645 return ECMD_PROCESSED
;
647 return poll_daemon(cmd
, pv_name
, NULL
, background
, PVMOVE
, &_pvmove_fns
,
651 int pvmove(struct cmd_context
*cmd
, int argc
, char **argv
)
653 char *pv_name
= NULL
;
657 /* dm raid1 target must be present in every case */
658 if (!_pvmove_target_present(cmd
, 0)) {
659 log_error("Required device-mapper target(s) not "
660 "detected in your kernel");
665 if (!(pv_name
= dm_pool_strdup(cmd
->mem
, argv
[0]))) {
666 log_error("Failed to clone PV name");
670 dm_unescape_colons_and_at_signs(pv_name
, &colon
, NULL
);
672 /* Drop any PE lists from PV name */
676 if (!arg_count(cmd
, abort_ARG
) &&
677 (ret
= _set_up_pvmove(cmd
, pv_name
, argc
, argv
)) !=
684 return pvmove_poll(cmd
, pv_name
, arg_is_set(cmd
, background_ARG
));