]> sourceware.org Git - lvm2.git/blob - tools/pvmove.c
thin: tighten discard string conversions
[lvm2.git] / tools / pvmove.c
1 /*
2 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2010 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 #include "polldaemon.h"
18 #include "display.h"
19
20 #define PVMOVE_FIRST_TIME 0x00000001 /* Called for first time */
21 #define PVMOVE_EXCLUSIVE 0x00000002 /* Require exclusive LV */
22
23 static int _pvmove_target_present(struct cmd_context *cmd, int clustered)
24 {
25 const struct segment_type *segtype;
26 unsigned attr = 0;
27 int found = 1;
28 static int _clustered_found = -1;
29
30 if (clustered && _clustered_found >= 0)
31 return _clustered_found;
32
33 if (!(segtype = get_segtype_from_string(cmd, "mirror")))
34 return_0;
35
36 if (activation() && segtype->ops->target_present &&
37 !segtype->ops->target_present(cmd, NULL, clustered ? &attr : NULL))
38 found = 0;
39
40 if (activation() && clustered) {
41 if (found && (attr & MIRROR_LOG_CLUSTERED))
42 _clustered_found = found = 1;
43 else
44 _clustered_found = found = 0;
45 }
46
47 return found;
48 }
49
50 static unsigned _pvmove_is_exclusive(struct cmd_context *cmd,
51 struct volume_group *vg)
52 {
53 if (vg_is_clustered(vg))
54 if (!_pvmove_target_present(cmd, 1))
55 return 1;
56
57 return 0;
58 }
59
60 /* Allow /dev/vgname/lvname, vgname/lvname or lvname */
61 static const char *_extract_lvname(struct cmd_context *cmd, const char *vgname,
62 const char *arg)
63 {
64 const char *lvname;
65
66 /* Is an lvname supplied directly? */
67 if (!strchr(arg, '/'))
68 return arg;
69
70 lvname = skip_dev_dir(cmd, arg, NULL);
71 while (*lvname == '/')
72 lvname++;
73 if (!strchr(lvname, '/')) {
74 log_error("--name takes a logical volume name");
75 return NULL;
76 }
77 if (strncmp(vgname, lvname, strlen(vgname)) ||
78 (lvname += strlen(vgname), *lvname != '/')) {
79 log_error("Named LV and old PV must be in the same VG");
80 return NULL;
81 }
82 while (*lvname == '/')
83 lvname++;
84 if (!*lvname) {
85 log_error("Incomplete LV name supplied with --name");
86 return NULL;
87 }
88 return lvname;
89 }
90
91 static struct volume_group *_get_vg(struct cmd_context *cmd, const char *vgname)
92 {
93 dev_close_all();
94
95 return vg_read_for_update(cmd, vgname, NULL, 0);
96 }
97
98 /* Create list of PVs for allocation of replacement extents */
99 static struct dm_list *_get_allocatable_pvs(struct cmd_context *cmd, int argc,
100 char **argv, struct volume_group *vg,
101 struct physical_volume *pv,
102 alloc_policy_t alloc)
103 {
104 struct dm_list *allocatable_pvs, *pvht, *pvh;
105 struct pv_list *pvl;
106
107 if (argc)
108 allocatable_pvs = create_pv_list(cmd->mem, vg, argc, argv, 1);
109 else
110 allocatable_pvs = clone_pv_list(cmd->mem, &vg->pvs);
111
112 if (!allocatable_pvs)
113 return_NULL;
114
115 dm_list_iterate_safe(pvh, pvht, allocatable_pvs) {
116 pvl = dm_list_item(pvh, struct pv_list);
117
118 /* Don't allocate onto the PV we're clearing! */
119 if ((alloc != ALLOC_ANYWHERE) && (pvl->pv->dev == pv_dev(pv))) {
120 dm_list_del(&pvl->list);
121 continue;
122 }
123
124 /* Remove PV if full */
125 if (pvl->pv->pe_count == pvl->pv->pe_alloc_count)
126 dm_list_del(&pvl->list);
127 }
128
129 if (dm_list_empty(allocatable_pvs)) {
130 log_error("No extents available for allocation");
131 return NULL;
132 }
133
134 return allocatable_pvs;
135 }
136
137 /*
138 * Replace any LV segments on given PV with temporary mirror.
139 * Returns list of LVs changed.
140 */
141 static int _insert_pvmove_mirrors(struct cmd_context *cmd,
142 struct logical_volume *lv_mirr,
143 struct dm_list *source_pvl,
144 struct logical_volume *lv,
145 struct dm_list *lvs_changed)
146
147 {
148 struct pv_list *pvl;
149 uint32_t prev_le_count;
150
151 /* Only 1 PV may feature in source_pvl */
152 pvl = dm_list_item(source_pvl->n, struct pv_list);
153
154 prev_le_count = lv_mirr->le_count;
155 if (!insert_layer_for_segments_on_pv(cmd, lv, lv_mirr, PVMOVE,
156 pvl, lvs_changed))
157 return_0;
158
159 /* check if layer was inserted */
160 if (lv_mirr->le_count - prev_le_count) {
161 lv->status |= LOCKED;
162
163 log_verbose("Moving %u extents of logical volume %s/%s",
164 lv_mirr->le_count - prev_le_count,
165 lv->vg->name, lv->name);
166 }
167
168 return 1;
169 }
170
171 /* Create new LV with mirror segments for the required copies */
172 static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
173 struct volume_group *vg,
174 struct dm_list *source_pvl,
175 const char *lv_name,
176 struct dm_list *allocatable_pvs,
177 alloc_policy_t alloc,
178 struct dm_list **lvs_changed,
179 unsigned *exclusive)
180 {
181 struct logical_volume *lv_mirr, *lv;
182 struct lv_list *lvl;
183 uint32_t log_count = 0;
184 int lv_found = 0;
185 int lv_skipped = 0;
186 int lv_active_count = 0;
187 int lv_exclusive_count = 0;
188
189 /* FIXME Cope with non-contiguous => splitting existing segments */
190 if (!(lv_mirr = lv_create_empty("pvmove%d", NULL,
191 LVM_READ | LVM_WRITE,
192 ALLOC_CONTIGUOUS, vg))) {
193 log_error("Creation of temporary pvmove LV failed");
194 return NULL;
195 }
196
197 lv_mirr->status |= (PVMOVE | LOCKED);
198
199 if (!(*lvs_changed = dm_pool_alloc(cmd->mem, sizeof(**lvs_changed)))) {
200 log_error("lvs_changed list struct allocation failed");
201 return NULL;
202 }
203
204 dm_list_init(*lvs_changed);
205
206 /* Find segments to be moved and set up mirrors */
207 dm_list_iterate_items(lvl, &vg->lvs) {
208 lv = lvl->lv;
209 if (lv == lv_mirr)
210 continue;
211 if (lv_name) {
212 if (strcmp(lv->name, lv_name))
213 continue;
214 lv_found = 1;
215 }
216 if (lv_is_origin(lv) || lv_is_cow(lv)) {
217 lv_skipped = 1;
218 log_print("Skipping snapshot-related LV %s", lv->name);
219 continue;
220 }
221 if (lv->status & MIRRORED) {
222 lv_skipped = 1;
223 log_print("Skipping mirror LV %s", lv->name);
224 continue;
225 }
226 if (lv->status & MIRROR_LOG) {
227 lv_skipped = 1;
228 log_print("Skipping mirror log LV %s", lv->name);
229 continue;
230 }
231 if (lv->status & MIRROR_IMAGE) {
232 lv_skipped = 1;
233 log_print("Skipping mirror image LV %s", lv->name);
234 continue;
235 }
236 if (lv->status & LOCKED) {
237 lv_skipped = 1;
238 log_print("Skipping locked LV %s", lv->name);
239 continue;
240 }
241
242 if (vg_is_clustered(vg) &&
243 lv_is_active_exclusive_remotely(lv)) {
244 lv_skipped = 1;
245 log_print("Skipping LV %s which is activated "
246 "exclusively on remote node.", lv->name);
247 continue;
248 }
249
250 if (vg_is_clustered(vg)) {
251 if (lv_is_active_exclusive_locally(lv))
252 lv_exclusive_count++;
253 else if (lv_is_active(lv))
254 lv_active_count++;
255 }
256
257 if (!_insert_pvmove_mirrors(cmd, lv_mirr, source_pvl, lv,
258 *lvs_changed))
259 return_NULL;
260 }
261
262 if (lv_name && !lv_found) {
263 log_error("Logical volume %s not found.", lv_name);
264 return NULL;
265 }
266
267 /* Is temporary mirror empty? */
268 if (!lv_mirr->le_count) {
269 if (lv_skipped)
270 log_error("All data on source PV skipped. "
271 "It contains locked, hidden or "
272 "non-top level LVs only.");
273 log_error("No data to move for %s", vg->name);
274 return NULL;
275 }
276
277 if (vg_is_clustered(vg) && lv_active_count && *exclusive) {
278 log_error("Cannot move in clustered VG %s, "
279 "clustered mirror (cmirror) not detected "
280 "and LVs are activated non-exclusively.",
281 vg->name);
282 return NULL;
283 }
284
285 if (vg_is_clustered(vg) && lv_exclusive_count) {
286 if (lv_active_count) {
287 log_error("Cannot move in clustered VG %s "
288 "if some LVs are activated "
289 "exclusively while others don't.",
290 vg->name);
291 return NULL;
292 }
293 *exclusive = 1;
294 }
295
296 if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, 0, log_count,
297 allocatable_pvs, alloc, MIRROR_BY_SEG)) {
298 log_error("Failed to convert pvmove LV to mirrored");
299 return_NULL;
300 }
301
302 if (!split_parent_segments_for_layer(cmd, lv_mirr)) {
303 log_error("Failed to split segments being moved");
304 return_NULL;
305 }
306
307 return lv_mirr;
308 }
309
310 static int _activate_lv(struct cmd_context *cmd, struct logical_volume *lv_mirr,
311 unsigned exclusive)
312 {
313 int r = 0;
314
315 if (exclusive || lv_is_active_exclusive(lv_mirr))
316 r = activate_lv_excl(cmd, lv_mirr);
317 else
318 r = activate_lv(cmd, lv_mirr);
319
320 if (!r)
321 stack;
322
323 return r;
324 }
325
326 static int _detach_pvmove_mirror(struct cmd_context *cmd,
327 struct logical_volume *lv_mirr)
328 {
329 struct dm_list lvs_completed;
330 struct lv_list *lvl;
331
332 /* Update metadata to remove mirror segments and break dependencies */
333 dm_list_init(&lvs_completed);
334 if (!lv_remove_mirrors(cmd, lv_mirr, 1, 0, NULL, NULL, PVMOVE) ||
335 !remove_layers_for_segments_all(cmd, lv_mirr, PVMOVE,
336 &lvs_completed)) {
337 return 0;
338 }
339
340 dm_list_iterate_items(lvl, &lvs_completed)
341 /* FIXME Assumes only one pvmove at a time! */
342 lvl->lv->status &= ~LOCKED;
343
344 return 1;
345 }
346
347 static int _suspend_lvs(struct cmd_context *cmd, unsigned first_time,
348 struct logical_volume *lv_mirr,
349 struct dm_list *lvs_changed,
350 struct volume_group *vg_to_revert)
351 {
352 /*
353 * Suspend lvs_changed the first time.
354 * Suspend mirrors on subsequent calls.
355 */
356 if (first_time) {
357 if (!suspend_lvs(cmd, lvs_changed, vg_to_revert))
358 return_0;
359 } else if (!suspend_lv(cmd, lv_mirr)) {
360 if (vg_to_revert)
361 vg_revert(vg_to_revert);
362 return_0;
363 }
364
365 return 1;
366 }
367
368 static int _resume_lvs(struct cmd_context *cmd, unsigned first_time,
369 struct logical_volume *lv_mirr,
370 struct dm_list *lvs_changed)
371 {
372 /*
373 * Suspend lvs_changed the first time.
374 * Suspend mirrors on subsequent calls.
375 */
376
377 if (first_time) {
378 if (!resume_lvs(cmd, lvs_changed)) {
379 log_error("Unable to resume logical volumes");
380 return 0;
381 }
382 } else if (!resume_lv(cmd, lv_mirr)) {
383 log_error("Unable to reactivate logical volume \"%s\"",
384 lv_mirr->name);
385 return 0;
386 }
387
388 return 1;
389 }
390
391 /*
392 * Called to set up initial pvmove LV and to advance the mirror
393 * to successive sections of it.
394 * (Not called after the last section completes.)
395 */
396 static int _update_metadata(struct cmd_context *cmd, struct volume_group *vg,
397 struct logical_volume *lv_mirr,
398 struct dm_list *lvs_changed, unsigned flags)
399 {
400 unsigned exclusive = (flags & PVMOVE_EXCLUSIVE) ? 1 : 0;
401 unsigned first_time = (flags & PVMOVE_FIRST_TIME) ? 1 : 0;
402 int r = 0;
403
404 log_verbose("Updating volume group metadata");
405 if (!vg_write(vg)) {
406 log_error("ABORTING: Volume group metadata update failed.");
407 return 0;
408 }
409
410 if (!_suspend_lvs(cmd, first_time, lv_mirr, lvs_changed, vg)) {
411 log_error("ABORTING: Temporary pvmove mirror %s failed.", first_time ? "activation" : "reload");
412 /* FIXME Add a recovery path for first time too. */
413 if (!first_time && !revert_lv(cmd, lv_mirr))
414 stack;
415 return 0;
416 }
417
418 /* Commit on-disk metadata */
419 if (!vg_commit(vg)) {
420 log_error("ABORTING: Volume group metadata update failed.");
421 if (!_resume_lvs(cmd, first_time, lv_mirr, lvs_changed))
422 stack;
423 if (!first_time && !revert_lv(cmd, lv_mirr))
424 stack;
425 return 0;
426 }
427
428 /* Activate the temporary mirror LV */
429 /* Only the first mirror segment gets activated as a mirror */
430 /* FIXME: Add option to use a log */
431 if (first_time) {
432 if (!exclusive && _pvmove_is_exclusive(cmd, vg))
433 exclusive = 1;
434
435 if (!_activate_lv(cmd, lv_mirr, exclusive)) {
436 if (test_mode()) {
437 r = 1;
438 goto out;
439 }
440
441 /*
442 * FIXME Run --abort internally here.
443 */
444 log_error("ABORTING: Temporary pvmove mirror activation failed. Run pvmove --abort.");
445 goto_out;
446 }
447 }
448
449 r = 1;
450
451 out:
452 if (!_resume_lvs(cmd, first_time, lv_mirr, lvs_changed))
453 r = 0;
454
455 if (r)
456 backup(vg);
457
458 return r;
459 }
460
461 static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name,
462 int argc, char **argv)
463 {
464 const char *lv_name = NULL;
465 char *pv_name_arg;
466 struct volume_group *vg;
467 struct dm_list *source_pvl;
468 struct dm_list *allocatable_pvs;
469 alloc_policy_t alloc;
470 struct dm_list *lvs_changed;
471 struct physical_volume *pv;
472 struct logical_volume *lv_mirr;
473 unsigned flags = PVMOVE_FIRST_TIME;
474 unsigned exclusive;
475 int r = ECMD_FAILED;
476
477 pv_name_arg = argv[0];
478 argc--;
479 argv++;
480
481 /* Find PV (in VG) */
482 if (!(pv = find_pv_by_name(cmd, pv_name))) {
483 stack;
484 return EINVALID_CMD_LINE;
485 }
486
487 if (arg_count(cmd, name_ARG)) {
488 if (!(lv_name = _extract_lvname(cmd, pv_vg_name(pv),
489 arg_value(cmd, name_ARG)))) {
490 stack;
491 free_pv_fid(pv);
492 return EINVALID_CMD_LINE;
493 }
494
495 if (!validate_name(lv_name)) {
496 log_error("Logical volume name %s is invalid", lv_name);
497 free_pv_fid(pv);
498 return EINVALID_CMD_LINE;
499 }
500 }
501
502 /* Read VG */
503 log_verbose("Finding volume group \"%s\"", pv_vg_name(pv));
504
505 vg = _get_vg(cmd, pv_vg_name(pv));
506 if (vg_read_error(vg)) {
507 release_vg(vg);
508 stack;
509 return ECMD_FAILED;
510 }
511
512 exclusive = _pvmove_is_exclusive(cmd, vg);
513
514 if ((lv_mirr = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) {
515 log_print("Detected pvmove in progress for %s", pv_name);
516 if (argc || lv_name)
517 log_error("Ignoring remaining command line arguments");
518
519 if (!(lvs_changed = lvs_using_lv(cmd, vg, lv_mirr))) {
520 log_error("ABORTING: Failed to generate list of moving LVs");
521 goto out;
522 }
523
524 /* Ensure mirror LV is active */
525 if (!_activate_lv(cmd, lv_mirr, exclusive)) {
526 log_error("ABORTING: Temporary mirror activation failed.");
527 goto out;
528 }
529
530 flags &= ~PVMOVE_FIRST_TIME;
531 } else {
532 /* Determine PE ranges to be moved */
533 if (!(source_pvl = create_pv_list(cmd->mem, vg, 1,
534 &pv_name_arg, 0)))
535 goto_out;
536
537 alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT);
538 if (alloc == ALLOC_INHERIT)
539 alloc = vg->alloc;
540
541 /* Get PVs we can use for allocation */
542 if (!(allocatable_pvs = _get_allocatable_pvs(cmd, argc, argv,
543 vg, pv, alloc)))
544 goto_out;
545
546 if (!archive(vg))
547 goto_out;
548
549 if (!(lv_mirr = _set_up_pvmove_lv(cmd, vg, source_pvl, lv_name,
550 allocatable_pvs, alloc,
551 &lvs_changed, &exclusive)))
552 goto_out;
553 }
554
555 /* Lock lvs_changed and activate (with old metadata) */
556 if (!activate_lvs(cmd, lvs_changed, exclusive))
557 goto_out;
558
559 /* FIXME Presence of a mirror once set PVMOVE - now remove associated logic */
560 /* init_pvmove(1); */
561 /* vg->status |= PVMOVE; */
562
563 if (flags & PVMOVE_FIRST_TIME) {
564 if (exclusive)
565 flags |= PVMOVE_EXCLUSIVE;
566 if (!_update_metadata
567 (cmd, vg, lv_mirr, lvs_changed, flags))
568 goto_out;
569 }
570
571 /* LVs are all in status LOCKED */
572 r = ECMD_PROCESSED;
573 out:
574 free_pv_fid(pv);
575 unlock_and_release_vg(cmd, vg, pv_vg_name(pv));
576 return r;
577 }
578
579 static int _finish_pvmove(struct cmd_context *cmd, struct volume_group *vg,
580 struct logical_volume *lv_mirr,
581 struct dm_list *lvs_changed)
582 {
583 int r = 1;
584
585 if (!dm_list_empty(lvs_changed) &&
586 (!_detach_pvmove_mirror(cmd, lv_mirr) ||
587 !replace_lv_with_error_segment(lv_mirr))) {
588 log_error("ABORTING: Removal of temporary mirror failed");
589 return 0;
590 }
591
592 /* Store metadata without dependencies on mirror segments */
593 if (!vg_write(vg)) {
594 log_error("ABORTING: Failed to write new data locations "
595 "to disk.");
596 return 0;
597 }
598
599 /* Suspend LVs changed (implicitly suspends lv_mirr) */
600 if (!suspend_lvs(cmd, lvs_changed, vg)) {
601 log_error("ABORTING: Locking LVs to remove temporary mirror failed");
602 if (!revert_lv(cmd, lv_mirr))
603 stack;
604 return 0;
605 }
606
607 /* Store metadata without dependencies on mirror segments */
608 if (!vg_commit(vg)) {
609 log_error("ABORTING: Failed to write new data locations "
610 "to disk.");
611 if (!revert_lv(cmd, lv_mirr))
612 stack;
613 if (!revert_lvs(cmd, lvs_changed))
614 stack;
615 return 0;
616 }
617
618 /* Release mirror LV. (No pending I/O because it's been suspended.) */
619 if (!resume_lv(cmd, lv_mirr)) {
620 log_error("Unable to reactivate logical volume \"%s\"",
621 lv_mirr->name);
622 r = 0;
623 }
624
625 /* Unsuspend LVs */
626 if (!resume_lvs(cmd, lvs_changed))
627 stack;
628
629 /* Deactivate mirror LV */
630 if (!deactivate_lv(cmd, lv_mirr)) {
631 log_error("ABORTING: Unable to deactivate temporary logical "
632 "volume \"%s\"", lv_mirr->name);
633 r = 0;
634 }
635
636 log_verbose("Removing temporary pvmove LV");
637 if (!lv_remove(lv_mirr)) {
638 log_error("ABORTING: Removal of temporary pvmove LV failed");
639 return 0;
640 }
641
642 /* Store it on disks */
643 log_verbose("Writing out final volume group after pvmove");
644 if (!vg_write(vg) || !vg_commit(vg)) {
645 log_error("ABORTING: Failed to write new data locations "
646 "to disk.");
647 return 0;
648 }
649
650 /* FIXME backup positioning */
651 backup(vg);
652
653 return r;
654 }
655
656 static struct volume_group *_get_move_vg(struct cmd_context *cmd,
657 const char *name,
658 const char *uuid __attribute__((unused)))
659 {
660 struct physical_volume *pv;
661 struct volume_group *vg;
662
663 /* Reread all metadata in case it got changed */
664 if (!(pv = find_pv_by_name(cmd, name))) {
665 log_error("ABORTING: Can't reread PV %s", name);
666 /* What more could we do here? */
667 return NULL;
668 }
669
670 vg = _get_vg(cmd, pv_vg_name(pv));
671 free_pv_fid(pv);
672
673 return vg;
674 }
675
676 static struct poll_functions _pvmove_fns = {
677 .get_copy_name_from_lv = get_pvmove_pvname_from_lv_mirr,
678 .get_copy_vg = _get_move_vg,
679 .get_copy_lv = find_pvmove_lv_from_pvname,
680 .poll_progress = poll_mirror_progress,
681 .update_metadata = _update_metadata,
682 .finish_copy = _finish_pvmove,
683 };
684
685 int pvmove_poll(struct cmd_context *cmd, const char *pv_name,
686 unsigned background)
687 {
688 if (test_mode())
689 return ECMD_PROCESSED;
690
691 return poll_daemon(cmd, pv_name, NULL, background, PVMOVE, &_pvmove_fns,
692 "Moved");
693 }
694
695 int pvmove(struct cmd_context *cmd, int argc, char **argv)
696 {
697 char *pv_name = NULL;
698 char *colon;
699 int ret;
700
701 /* dm raid1 target must be present in every case */
702 if (!_pvmove_target_present(cmd, 0)) {
703 log_error("Required device-mapper target(s) not "
704 "detected in your kernel");
705 return ECMD_FAILED;
706 }
707
708 if (argc) {
709 if (!(pv_name = dm_pool_strdup(cmd->mem, argv[0]))) {
710 log_error("Failed to clone PV name");
711 return ECMD_FAILED;
712 }
713
714 dm_unescape_colons_and_at_signs(pv_name, &colon, NULL);
715
716 /* Drop any PE lists from PV name */
717 if (colon)
718 *colon = '\0';
719
720 if (!arg_count(cmd, abort_ARG) &&
721 (ret = _set_up_pvmove(cmd, pv_name, argc, argv)) !=
722 ECMD_PROCESSED) {
723 stack;
724 return ret;
725 }
726 }
727
728 return pvmove_poll(cmd, pv_name, arg_is_set(cmd, background_ARG));
729 }
This page took 0.069672 seconds and 5 git commands to generate.