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