1 /* $NetBSD: dev_manager.c,v 1.1.1.2 2009/02/18 11:16:50 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2002-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 "lib.h" 19 #include "str_list.h" 20 #include "dev_manager.h" 21 #include "lvm-string.h" 22 #include "fs.h" 23 #include "defaults.h" 24 #include "segtype.h" 25 #include "display.h" 26 #include "toolcontext.h" 27 #include "targets.h" 28 #include "config.h" 29 #include "filter.h" 30 #include "activate.h" 31 32 #include <limits.h> 33 #include <dirent.h> 34 35 #define MAX_TARGET_PARAMSIZE 50000 36 #define UUID_PREFIX "LVM-" 37 38 typedef enum { 39 PRELOAD, 40 ACTIVATE, 41 DEACTIVATE, 42 SUSPEND, 43 SUSPEND_WITH_LOCKFS, 44 CLEAN 45 } action_t; 46 47 struct dev_manager { 48 struct dm_pool *mem; 49 50 struct cmd_context *cmd; 51 52 void *target_state; 53 uint32_t pvmove_mirror_count; 54 55 char *vg_name; 56 }; 57 58 struct lv_layer { 59 struct logical_volume *lv; 60 const char *old_name; 61 }; 62 63 static char *_build_dlid(struct dm_pool *mem, const char *lvid, const char *layer) 64 { 65 char *dlid; 66 size_t len; 67 68 if (!layer) 69 layer = ""; 70 71 len = sizeof(UUID_PREFIX) + sizeof(union lvid) + strlen(layer); 72 73 if (!(dlid = dm_pool_alloc(mem, len))) { 74 log_error("_build_dlid: pool allocation failed for %" PRIsize_t 75 " %s %s.", len, lvid, layer); 76 return NULL; 77 } 78 79 sprintf(dlid, UUID_PREFIX "%s%s%s", lvid, (*layer) ? "-" : "", layer); 80 81 return dlid; 82 } 83 84 char *build_dlid(struct dev_manager *dm, const char *lvid, const char *layer) 85 { 86 return _build_dlid(dm->mem, lvid, layer); 87 } 88 89 static int _read_only_lv(struct logical_volume *lv) 90 { 91 return (!(lv->vg->status & LVM_WRITE) || !(lv->status & LVM_WRITE)); 92 } 93 94 /* 95 * Low level device-layer operations. 96 */ 97 static struct dm_task *_setup_task(const char *name, const char *uuid, 98 uint32_t *event_nr, int task, 99 uint32_t major, uint32_t minor) 100 { 101 struct dm_task *dmt; 102 103 if (!(dmt = dm_task_create(task))) 104 return_NULL; 105 106 if (name) 107 dm_task_set_name(dmt, name); 108 109 if (uuid && *uuid) 110 dm_task_set_uuid(dmt, uuid); 111 112 if (event_nr) 113 dm_task_set_event_nr(dmt, *event_nr); 114 115 if (major) { 116 dm_task_set_major(dmt, major); 117 dm_task_set_minor(dmt, minor); 118 } 119 120 return dmt; 121 } 122 123 static int _info_run(const char *name, const char *dlid, struct dm_info *info, 124 uint32_t *read_ahead, int mknodes, int with_open_count, 125 int with_read_ahead, uint32_t major, uint32_t minor) 126 { 127 int r = 0; 128 struct dm_task *dmt; 129 int dmtask; 130 131 dmtask = mknodes ? DM_DEVICE_MKNODES : DM_DEVICE_INFO; 132 133 if (!(dmt = _setup_task(name, dlid, 0, dmtask, major, minor))) 134 return_0; 135 136 if (!with_open_count) 137 if (!dm_task_no_open_count(dmt)) 138 log_error("Failed to disable open_count"); 139 140 if (!dm_task_run(dmt)) 141 goto_out; 142 143 if (!dm_task_get_info(dmt, info)) 144 goto_out; 145 146 if (with_read_ahead) { 147 if (!dm_task_get_read_ahead(dmt, read_ahead)) 148 goto_out; 149 } else if (read_ahead) 150 *read_ahead = DM_READ_AHEAD_NONE; 151 152 r = 1; 153 154 out: 155 dm_task_destroy(dmt); 156 return r; 157 } 158 159 int device_is_usable(dev_t dev) 160 { 161 struct dm_task *dmt; 162 struct dm_info info; 163 const char *name; 164 uint64_t start, length; 165 char *target_type = NULL; 166 char *params; 167 void *next = NULL; 168 int r = 0; 169 170 if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) { 171 log_error("Failed to allocate dm_task struct to check dev status"); 172 return 0; 173 } 174 175 if (!dm_task_set_major(dmt, MAJOR(dev)) || !dm_task_set_minor(dmt, MINOR(dev))) 176 goto_out; 177 178 if (!dm_task_run(dmt)) { 179 log_error("Failed to get state of mapped device"); 180 goto out; 181 } 182 183 if (!dm_task_get_info(dmt, &info)) 184 goto_out; 185 186 if (!info.exists || info.suspended) 187 goto out; 188 189 name = dm_task_get_name(dmt); 190 191 /* FIXME Also check for mirror block_on_error and mpath no paths */ 192 /* For now, we exclude all mirrors */ 193 194 do { 195 next = dm_get_next_target(dmt, next, &start, &length, 196 &target_type, ¶ms); 197 /* Skip if target type doesn't match */ 198 if (target_type && !strcmp(target_type, "mirror")) 199 goto out; 200 } while (next); 201 202 /* FIXME Also check dependencies? */ 203 204 r = 1; 205 206 out: 207 dm_task_destroy(dmt); 208 return r; 209 } 210 211 static int _info(const char *name, const char *dlid, int mknodes, 212 int with_open_count, int with_read_ahead, 213 struct dm_info *info, uint32_t *read_ahead) 214 { 215 if (!mknodes && dlid && *dlid) { 216 if (_info_run(NULL, dlid, info, read_ahead, 0, with_open_count, 217 with_read_ahead, 0, 0) && 218 info->exists) 219 return 1; 220 else if (_info_run(NULL, dlid + sizeof(UUID_PREFIX) - 1, info, 221 read_ahead, 0, with_open_count, 222 with_read_ahead, 0, 0) && 223 info->exists) 224 return 1; 225 } 226 227 if (name) 228 return _info_run(name, NULL, info, read_ahead, mknodes, 229 with_open_count, with_read_ahead, 0, 0); 230 231 return 0; 232 } 233 234 static int _info_by_dev(uint32_t major, uint32_t minor, struct dm_info *info) 235 { 236 return _info_run(NULL, NULL, info, NULL, 0, 0, 0, major, minor); 237 } 238 239 int dev_manager_info(struct dm_pool *mem, const char *name, 240 const struct logical_volume *lv, int with_mknodes, 241 int with_open_count, int with_read_ahead, 242 struct dm_info *info, uint32_t *read_ahead) 243 { 244 const char *dlid; 245 246 if (!(dlid = _build_dlid(mem, lv->lvid.s, NULL))) { 247 log_error("dlid build failed for %s", lv->name); 248 return 0; 249 } 250 251 return _info(name, dlid, with_mknodes, with_open_count, with_read_ahead, 252 info, read_ahead); 253 } 254 255 /* FIXME Interface must cope with multiple targets */ 256 static int _status_run(const char *name, const char *uuid, 257 unsigned long long *s, unsigned long long *l, 258 char **t, uint32_t t_size, char **p, uint32_t p_size) 259 { 260 int r = 0; 261 struct dm_task *dmt; 262 struct dm_info info; 263 void *next = NULL; 264 uint64_t start, length; 265 char *type = NULL; 266 char *params = NULL; 267 268 if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_STATUS, 0, 0))) 269 return_0; 270 271 if (!dm_task_no_open_count(dmt)) 272 log_error("Failed to disable open_count"); 273 274 if (!dm_task_run(dmt)) 275 goto_out; 276 277 if (!dm_task_get_info(dmt, &info) || !info.exists) 278 goto_out; 279 280 do { 281 next = dm_get_next_target(dmt, next, &start, &length, 282 &type, ¶ms); 283 if (type) { 284 *s = start; 285 *l = length; 286 /* Make sure things are null terminated */ 287 strncpy(*t, type, t_size); 288 (*t)[t_size - 1] = '\0'; 289 strncpy(*p, params, p_size); 290 (*p)[p_size - 1] = '\0'; 291 292 r = 1; 293 /* FIXME Cope with multiple targets! */ 294 break; 295 } 296 297 } while (next); 298 299 out: 300 dm_task_destroy(dmt); 301 return r; 302 } 303 304 static int _status(const char *name, const char *uuid, 305 unsigned long long *start, unsigned long long *length, 306 char **type, uint32_t type_size, char **params, 307 uint32_t param_size) __attribute__ ((unused)); 308 309 static int _status(const char *name, const char *uuid, 310 unsigned long long *start, unsigned long long *length, 311 char **type, uint32_t type_size, char **params, 312 uint32_t param_size) 313 { 314 if (uuid && *uuid) { 315 if (_status_run(NULL, uuid, start, length, type, 316 type_size, params, param_size) && 317 *params) 318 return 1; 319 else if (_status_run(NULL, uuid + sizeof(UUID_PREFIX) - 1, start, 320 length, type, type_size, params, 321 param_size) && 322 *params) 323 return 1; 324 } 325 326 if (name && _status_run(name, NULL, start, length, type, type_size, 327 params, param_size)) 328 return 1; 329 330 return 0; 331 } 332 333 static int _percent_run(struct dev_manager *dm, const char *name, 334 const char *dlid, 335 const char *target_type, int wait, 336 struct logical_volume *lv, float *percent, 337 uint32_t *event_nr) 338 { 339 int r = 0; 340 struct dm_task *dmt; 341 struct dm_info info; 342 void *next = NULL; 343 uint64_t start, length; 344 char *type = NULL; 345 char *params = NULL; 346 struct dm_list *segh = &lv->segments; 347 struct lv_segment *seg = NULL; 348 struct segment_type *segtype; 349 350 uint64_t total_numerator = 0, total_denominator = 0; 351 352 *percent = -1; 353 354 if (!(dmt = _setup_task(name, dlid, event_nr, 355 wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS, 0, 0))) 356 return_0; 357 358 if (!dm_task_no_open_count(dmt)) 359 log_error("Failed to disable open_count"); 360 361 if (!dm_task_run(dmt)) 362 goto_out; 363 364 if (!dm_task_get_info(dmt, &info) || !info.exists) 365 goto_out; 366 367 if (event_nr) 368 *event_nr = info.event_nr; 369 370 do { 371 next = dm_get_next_target(dmt, next, &start, &length, &type, 372 ¶ms); 373 if (lv) { 374 if (!(segh = dm_list_next(&lv->segments, segh))) { 375 log_error("Number of segments in active LV %s " 376 "does not match metadata", lv->name); 377 goto out; 378 } 379 seg = dm_list_item(segh, struct lv_segment); 380 } 381 382 if (!type || !params || strcmp(type, target_type)) 383 continue; 384 385 if (!(segtype = get_segtype_from_string(dm->cmd, type))) 386 continue; 387 388 if (segtype->ops->target_percent && 389 !segtype->ops->target_percent(&dm->target_state, dm->mem, 390 dm->cmd, seg, params, 391 &total_numerator, 392 &total_denominator)) 393 goto_out; 394 395 } while (next); 396 397 if (lv && (segh = dm_list_next(&lv->segments, segh))) { 398 log_error("Number of segments in active LV %s does not " 399 "match metadata", lv->name); 400 goto out; 401 } 402 403 if (total_denominator) 404 *percent = (float) total_numerator *100 / total_denominator; 405 else 406 *percent = 100; 407 408 log_debug("LV percent: %f", *percent); 409 r = 1; 410 411 out: 412 dm_task_destroy(dmt); 413 return r; 414 } 415 416 static int _percent(struct dev_manager *dm, const char *name, const char *dlid, 417 const char *target_type, int wait, 418 struct logical_volume *lv, float *percent, 419 uint32_t *event_nr) 420 { 421 if (dlid && *dlid) { 422 if (_percent_run(dm, NULL, dlid, target_type, wait, lv, percent, 423 event_nr)) 424 return 1; 425 else if (_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1, 426 target_type, wait, lv, percent, 427 event_nr)) 428 return 1; 429 } 430 431 if (name && _percent_run(dm, name, NULL, target_type, wait, lv, percent, 432 event_nr)) 433 return 1; 434 435 return 0; 436 } 437 438 /* 439 * dev_manager implementation. 440 */ 441 struct dev_manager *dev_manager_create(struct cmd_context *cmd, 442 const char *vg_name) 443 { 444 struct dm_pool *mem; 445 struct dev_manager *dm; 446 447 if (!(mem = dm_pool_create("dev_manager", 16 * 1024))) 448 return_NULL; 449 450 if (!(dm = dm_pool_alloc(mem, sizeof(*dm)))) 451 goto_bad; 452 453 dm->cmd = cmd; 454 dm->mem = mem; 455 456 if (!(dm->vg_name = dm_pool_strdup(dm->mem, vg_name))) 457 goto_bad; 458 459 dm->target_state = NULL; 460 461 return dm; 462 463 bad: 464 dm_pool_destroy(mem); 465 return NULL; 466 } 467 468 void dev_manager_destroy(struct dev_manager *dm) 469 { 470 dm_pool_destroy(dm->mem); 471 } 472 473 void dev_manager_release(void) 474 { 475 dm_lib_release(); 476 } 477 478 void dev_manager_exit(void) 479 { 480 dm_lib_exit(); 481 } 482 483 int dev_manager_snapshot_percent(struct dev_manager *dm, 484 const struct logical_volume *lv, 485 float *percent) 486 { 487 char *name; 488 const char *dlid; 489 490 /* 491 * Build a name for the top layer. 492 */ 493 if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL))) 494 return_0; 495 496 if (!(dlid = build_dlid(dm, lv->lvid.s, NULL))) 497 return_0; 498 499 /* 500 * Try and get some info on this device. 501 */ 502 log_debug("Getting device status percentage for %s", name); 503 if (!(_percent(dm, name, dlid, "snapshot", 0, NULL, percent, 504 NULL))) 505 return_0; 506 507 /* FIXME dm_pool_free ? */ 508 509 /* If the snapshot isn't available, percent will be -1 */ 510 return 1; 511 } 512 513 /* FIXME Merge with snapshot_percent, auto-detecting target type */ 514 /* FIXME Cope with more than one target */ 515 int dev_manager_mirror_percent(struct dev_manager *dm, 516 struct logical_volume *lv, int wait, 517 float *percent, uint32_t *event_nr) 518 { 519 char *name; 520 const char *dlid; 521 522 /* 523 * Build a name for the top layer. 524 */ 525 if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL))) 526 return_0; 527 528 /* FIXME dm_pool_free ? */ 529 530 if (!(dlid = build_dlid(dm, lv->lvid.s, NULL))) { 531 log_error("dlid build failed for %s", lv->name); 532 return 0; 533 } 534 535 log_debug("Getting device mirror status percentage for %s", name); 536 if (!(_percent(dm, name, dlid, "mirror", wait, lv, percent, 537 event_nr))) 538 return_0; 539 540 return 1; 541 } 542 543 #if 0 544 log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name); 545 546 log_verbose("Loading %s", dl->name); 547 log_very_verbose("Activating %s read-only", dl->name); 548 log_very_verbose("Activated %s %s %03u:%03u", dl->name, 549 dl->dlid, dl->info.major, dl->info.minor); 550 551 if (_get_flag(dl, VISIBLE)) 552 log_verbose("Removing %s", dl->name); 553 else 554 log_very_verbose("Removing %s", dl->name); 555 556 log_debug("Adding target: %" PRIu64 " %" PRIu64 " %s %s", 557 extent_size * seg->le, extent_size * seg->len, target, params); 558 559 log_debug("Adding target: 0 %" PRIu64 " snapshot-origin %s", 560 dl->lv->size, params); 561 log_debug("Adding target: 0 %" PRIu64 " snapshot %s", size, params); 562 log_debug("Getting device info for %s", dl->name); 563 564 /* Rename? */ 565 if ((suffix = strrchr(dl->dlid + sizeof(UUID_PREFIX) - 1, '-'))) 566 suffix++; 567 new_name = build_dm_name(dm->mem, dm->vg_name, dl->lv->name, 568 suffix); 569 570 static int _belong_to_vg(const char *vgname, const char *name) 571 { 572 const char *v = vgname, *n = name; 573 574 while (*v) { 575 if ((*v != *n) || (*v == '-' && *(++n) != '-')) 576 return 0; 577 v++, n++; 578 } 579 580 if (*n == '-' && *(n + 1) != '-') 581 return 1; 582 else 583 return 0; 584 } 585 586 if (!(snap_seg = find_cow(lv))) 587 return 1; 588 589 old_origin = snap_seg->origin; 590 591 /* Was this the last active snapshot with this origin? */ 592 dm_list_iterate_items(lvl, active_head) { 593 active = lvl->lv; 594 if ((snap_seg = find_cow(active)) && 595 snap_seg->origin == old_origin) { 596 return 1; 597 } 598 } 599 600 #endif 601 602 /*************************/ 603 /* NEW CODE STARTS HERE */ 604 /*************************/ 605 606 int dev_manager_lv_mknodes(const struct logical_volume *lv) 607 { 608 char *name; 609 610 if (!(name = build_dm_name(lv->vg->cmd->mem, lv->vg->name, 611 lv->name, NULL))) 612 return_0; 613 614 return fs_add_lv(lv, name); 615 } 616 617 int dev_manager_lv_rmnodes(const struct logical_volume *lv) 618 { 619 return fs_del_lv(lv); 620 } 621 622 static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, 623 struct logical_volume *lv, const char *layer) 624 { 625 char *dlid, *name; 626 struct dm_info info, info2; 627 628 if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer))) 629 return_0; 630 631 if (!(dlid = build_dlid(dm, lv->lvid.s, layer))) 632 return_0; 633 634 log_debug("Getting device info for %s [%s]", name, dlid); 635 if (!_info(name, dlid, 0, 1, 0, &info, NULL)) { 636 log_error("Failed to get info for %s [%s].", name, dlid); 637 return 0; 638 } 639 640 /* 641 * For top level volumes verify that existing device match 642 * requested major/minor and that major/minor pair is available for use 643 */ 644 if (!layer && lv->major != -1 && lv->minor != -1) { 645 if (info.exists && (info.major != lv->major || info.minor != lv->minor)) { 646 log_error("Volume %s (%" PRIu32 ":%" PRIu32")" 647 " differs from already active device " 648 "(%" PRIu32 ":%" PRIu32")", 649 lv->name, lv->major, lv->minor, info.major, info.minor); 650 return 0; 651 } 652 if (!info.exists && _info_by_dev(lv->major, lv->minor, &info2) && 653 info2.exists) { 654 log_error("The requested major:minor pair " 655 "(%" PRIu32 ":%" PRIu32") is already used", 656 lv->major, lv->minor); 657 return 0; 658 } 659 } 660 661 if (info.exists && !dm_tree_add_dev(dtree, info.major, info.minor)) { 662 log_error("Failed to add device (%" PRIu32 ":%" PRIu32") to dtree", 663 info.major, info.minor); 664 return 0; 665 } 666 667 return 1; 668 } 669 670 /* 671 * Add LV and any known dependencies 672 */ 673 static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, struct logical_volume *lv) 674 { 675 if (!_add_dev_to_dtree(dm, dtree, lv, NULL)) 676 return_0; 677 678 /* FIXME Can we avoid doing this every time? */ 679 if (!_add_dev_to_dtree(dm, dtree, lv, "real")) 680 return_0; 681 682 if (!_add_dev_to_dtree(dm, dtree, lv, "cow")) 683 return_0; 684 685 if (!_add_dev_to_dtree(dm, dtree, lv, "_mlog")) 686 return_0; 687 688 return 1; 689 } 690 691 static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logical_volume *lv) 692 { 693 struct dm_tree *dtree; 694 struct dm_list *snh, *snht; 695 struct lv_segment *seg; 696 uint32_t s; 697 698 if (!(dtree = dm_tree_create())) { 699 log_error("Partial dtree creation failed for %s.", lv->name); 700 return NULL; 701 } 702 703 if (!_add_lv_to_dtree(dm, dtree, lv)) 704 goto_bad; 705 706 /* Add any snapshots of this LV */ 707 dm_list_iterate_safe(snh, snht, &lv->snapshot_segs) 708 if (!_add_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow)) 709 goto_bad; 710 711 /* Add any LVs used by segments in this LV */ 712 dm_list_iterate_items(seg, &lv->segments) 713 for (s = 0; s < seg->area_count; s++) 714 if (seg_type(seg, s) == AREA_LV && seg_lv(seg, s)) { 715 if (!_add_lv_to_dtree(dm, dtree, seg_lv(seg, s))) 716 goto_bad; 717 } 718 719 return dtree; 720 721 bad: 722 dm_tree_free(dtree); 723 return NULL; 724 } 725 726 static char *_add_error_device(struct dev_manager *dm, struct dm_tree *dtree, 727 struct lv_segment *seg, int s) 728 { 729 char *id, *name; 730 char errid[32]; 731 struct dm_tree_node *node; 732 struct lv_segment *seg_i; 733 int segno = -1, i = 0;; 734 uint64_t size = seg->len * seg->lv->vg->extent_size; 735 736 dm_list_iterate_items(seg_i, &seg->lv->segments) { 737 if (seg == seg_i) 738 segno = i; 739 ++i; 740 } 741 742 if (segno < 0) { 743 log_error("_add_error_device called with bad segment"); 744 return_NULL; 745 } 746 747 sprintf(errid, "missing_%d_%d", segno, s); 748 749 if (!(id = build_dlid(dm, seg->lv->lvid.s, errid))) 750 return_NULL; 751 752 if (!(name = build_dm_name(dm->mem, seg->lv->vg->name, 753 seg->lv->name, errid))) 754 return_NULL; 755 if (!(node = dm_tree_add_new_dev(dtree, name, id, 0, 0, 0, 0, 0))) 756 return_NULL; 757 if (!dm_tree_node_add_error_target(node, size)) 758 return_NULL; 759 760 return id; 761 } 762 763 static int _add_error_area(struct dev_manager *dm, struct dm_tree_node *node, 764 struct lv_segment *seg, int s) 765 { 766 char *dlid; 767 uint64_t extent_size = seg->lv->vg->extent_size; 768 769 if (!strcmp(dm->cmd->stripe_filler, "error")) { 770 /* 771 * FIXME, the tree pointer is first field of dm_tree_node, but 772 * we don't have the struct definition available. 773 */ 774 struct dm_tree **tree = (struct dm_tree **) node; 775 dlid = _add_error_device(dm, *tree, seg, s); 776 if (!dlid) 777 return_0; 778 dm_tree_node_add_target_area(node, NULL, dlid, 779 extent_size * seg_le(seg, s)); 780 } else 781 dm_tree_node_add_target_area(node, 782 dm->cmd->stripe_filler, 783 NULL, UINT64_C(0)); 784 785 return 1; 786 } 787 788 int add_areas_line(struct dev_manager *dm, struct lv_segment *seg, 789 struct dm_tree_node *node, uint32_t start_area, 790 uint32_t areas) 791 { 792 uint64_t extent_size = seg->lv->vg->extent_size; 793 uint32_t s; 794 char *dlid; 795 796 for (s = start_area; s < areas; s++) { 797 if ((seg_type(seg, s) == AREA_PV && 798 (!seg_pvseg(seg, s) || 799 !seg_pv(seg, s) || 800 !seg_dev(seg, s))) || 801 (seg_type(seg, s) == AREA_LV && !seg_lv(seg, s))) { 802 if (!_add_error_area(dm, node, seg, s)) 803 return_0; 804 } else if (seg_type(seg, s) == AREA_PV) 805 dm_tree_node_add_target_area(node, 806 dev_name(seg_dev(seg, s)), 807 NULL, 808 (seg_pv(seg, s)->pe_start + 809 (extent_size * seg_pe(seg, s)))); 810 else if (seg_type(seg, s) == AREA_LV) { 811 if (!(dlid = build_dlid(dm, 812 seg_lv(seg, s)->lvid.s, 813 NULL))) 814 return_0; 815 dm_tree_node_add_target_area(node, NULL, dlid, 816 extent_size * seg_le(seg, s)); 817 } else { 818 log_error("Internal error: Unassigned area found in LV %s.", 819 seg->lv->name); 820 return 0; 821 } 822 } 823 824 return 1; 825 } 826 827 static int _add_origin_target_to_dtree(struct dev_manager *dm, 828 struct dm_tree_node *dnode, 829 struct logical_volume *lv) 830 { 831 const char *real_dlid; 832 833 if (!(real_dlid = build_dlid(dm, lv->lvid.s, "real"))) 834 return_0; 835 836 if (!dm_tree_node_add_snapshot_origin_target(dnode, lv->size, real_dlid)) 837 return_0; 838 839 return 1; 840 } 841 842 static int _add_snapshot_target_to_dtree(struct dev_manager *dm, 843 struct dm_tree_node *dnode, 844 struct logical_volume *lv) 845 { 846 const char *origin_dlid; 847 const char *cow_dlid; 848 struct lv_segment *snap_seg; 849 uint64_t size; 850 851 if (!(snap_seg = find_cow(lv))) { 852 log_error("Couldn't find snapshot for '%s'.", lv->name); 853 return 0; 854 } 855 856 if (!(origin_dlid = build_dlid(dm, snap_seg->origin->lvid.s, "real"))) 857 return_0; 858 859 if (!(cow_dlid = build_dlid(dm, snap_seg->cow->lvid.s, "cow"))) 860 return_0; 861 862 size = (uint64_t) snap_seg->len * snap_seg->origin->vg->extent_size; 863 864 if (!dm_tree_node_add_snapshot_target(dnode, size, origin_dlid, cow_dlid, 1, snap_seg->chunk_size)) 865 return_0; 866 867 return 1; 868 } 869 870 static int _add_target_to_dtree(struct dev_manager *dm, 871 struct dm_tree_node *dnode, 872 struct lv_segment *seg) 873 { 874 uint64_t extent_size = seg->lv->vg->extent_size; 875 876 if (!seg->segtype->ops->add_target_line) { 877 log_error("_emit_target: Internal error: Can't handle " 878 "segment type %s", seg->segtype->name); 879 return 0; 880 } 881 882 return seg->segtype->ops->add_target_line(dm, dm->mem, dm->cmd, 883 &dm->target_state, seg, 884 dnode, 885 extent_size * seg->len, 886 &dm-> pvmove_mirror_count); 887 } 888 889 static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, 890 struct logical_volume *lv, const char *layer); 891 892 static int _add_segment_to_dtree(struct dev_manager *dm, 893 struct dm_tree *dtree, 894 struct dm_tree_node *dnode, 895 struct lv_segment *seg, 896 const char *layer) 897 { 898 uint32_t s; 899 struct dm_list *snh; 900 struct lv_segment *seg_present; 901 902 /* Ensure required device-mapper targets are loaded */ 903 seg_present = find_cow(seg->lv) ? : seg; 904 905 log_debug("Checking kernel supports %s segment type for %s%s%s", 906 seg_present->segtype->name, seg->lv->name, 907 layer ? "-" : "", layer ? : ""); 908 909 if (seg_present->segtype->ops->target_present && 910 !seg_present->segtype->ops->target_present(seg_present, NULL)) { 911 log_error("Can't expand LV %s: %s target support missing " 912 "from kernel?", seg->lv->name, seg_present->segtype->name); 913 return 0; 914 } 915 916 /* Add mirror log */ 917 if (seg->log_lv && 918 !_add_new_lv_to_dtree(dm, dtree, seg->log_lv, NULL)) 919 return_0; 920 921 /* If this is a snapshot origin, add real LV */ 922 if (lv_is_origin(seg->lv) && !layer) { 923 if (vg_is_clustered(seg->lv->vg)) { 924 log_error("Clustered snapshots are not yet supported"); 925 return 0; 926 } 927 if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, "real")) 928 return_0; 929 } else if (lv_is_cow(seg->lv) && !layer) { 930 if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, "cow")) 931 return_0; 932 } else { 933 /* Add any LVs used by this segment */ 934 for (s = 0; s < seg->area_count; s++) 935 if ((seg_type(seg, s) == AREA_LV) && 936 (!_add_new_lv_to_dtree(dm, dtree, seg_lv(seg, s), NULL))) 937 return_0; 938 } 939 940 /* Now we've added its dependencies, we can add the target itself */ 941 if (lv_is_origin(seg->lv) && !layer) { 942 if (!_add_origin_target_to_dtree(dm, dnode, seg->lv)) 943 return_0; 944 } else if (lv_is_cow(seg->lv) && !layer) { 945 if (!_add_snapshot_target_to_dtree(dm, dnode, seg->lv)) 946 return_0; 947 } else if (!_add_target_to_dtree(dm, dnode, seg)) 948 return_0; 949 950 if (lv_is_origin(seg->lv) && !layer) 951 /* Add any snapshots of this LV */ 952 dm_list_iterate(snh, &seg->lv->snapshot_segs) 953 if (!_add_new_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow, NULL)) 954 return_0; 955 956 return 1; 957 } 958 959 static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, 960 struct logical_volume *lv, const char *layer) 961 { 962 struct lv_segment *seg; 963 struct lv_layer *lvlayer; 964 struct dm_tree_node *dnode; 965 char *name, *dlid; 966 uint32_t max_stripe_size = UINT32_C(0); 967 uint32_t read_ahead = lv->read_ahead; 968 uint32_t read_ahead_flags = UINT32_C(0); 969 970 if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer))) 971 return_0; 972 973 if (!(dlid = build_dlid(dm, lv->lvid.s, layer))) 974 return_0; 975 976 /* We've already processed this node if it already has a context ptr */ 977 if ((dnode = dm_tree_find_node_by_uuid(dtree, dlid)) && 978 dm_tree_node_get_context(dnode)) 979 return 1; 980 981 if (!(lvlayer = dm_pool_alloc(dm->mem, sizeof(*lvlayer)))) { 982 log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.", lv->name, layer); 983 return 0; 984 } 985 986 lvlayer->lv = lv; 987 988 /* 989 * Add LV to dtree. 990 * If we're working with precommitted metadata, clear any 991 * existing inactive table left behind. 992 * Major/minor settings only apply to the visible layer. 993 */ 994 if (!(dnode = dm_tree_add_new_dev(dtree, name, dlid, 995 layer ? UINT32_C(0) : (uint32_t) lv->major, 996 layer ? UINT32_C(0) : (uint32_t) lv->minor, 997 _read_only_lv(lv), 998 (lv->vg->status & PRECOMMITTED) ? 1 : 0, 999 lvlayer))) 1000 return_0; 1001 1002 /* Store existing name so we can do rename later */ 1003 lvlayer->old_name = dm_tree_node_get_name(dnode); 1004 1005 /* Create table */ 1006 dm->pvmove_mirror_count = 0u; 1007 dm_list_iterate_items(seg, &lv->segments) { 1008 if (!_add_segment_to_dtree(dm, dtree, dnode, seg, layer)) 1009 return_0; 1010 /* These aren't real segments in the LVM2 metadata */ 1011 if (lv_is_origin(lv) && !layer) 1012 break; 1013 if (lv_is_cow(lv) && !layer) 1014 break; 1015 if (max_stripe_size < seg->stripe_size * seg->area_count) 1016 max_stripe_size = seg->stripe_size * seg->area_count; 1017 } 1018 1019 if (read_ahead == DM_READ_AHEAD_AUTO) { 1020 /* we need RA at least twice a whole stripe - see the comment in md/raid0.c */ 1021 read_ahead = max_stripe_size * 2; 1022 read_ahead_flags = DM_READ_AHEAD_MINIMUM_FLAG; 1023 } 1024 1025 dm_tree_node_set_read_ahead(dnode, read_ahead, read_ahead_flags); 1026 1027 return 1; 1028 } 1029 1030 /* FIXME: symlinks should be created/destroyed at the same time 1031 * as the kernel devices but we can't do that from within libdevmapper 1032 * at present so we must walk the tree twice instead. */ 1033 1034 /* 1035 * Create LV symlinks for children of supplied root node. 1036 */ 1037 static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root) 1038 { 1039 void *handle = NULL; 1040 struct dm_tree_node *child; 1041 struct lv_layer *lvlayer; 1042 char *old_vgname, *old_lvname, *old_layer; 1043 char *new_vgname, *new_lvname, *new_layer; 1044 const char *name; 1045 int r = 1; 1046 1047 while ((child = dm_tree_next_child(&handle, root, 0))) { 1048 if (!(lvlayer = (struct lv_layer *) dm_tree_node_get_context(child))) 1049 continue; 1050 1051 /* Detect rename */ 1052 name = dm_tree_node_get_name(child); 1053 1054 if (name && lvlayer->old_name && *lvlayer->old_name && strcmp(name, lvlayer->old_name)) { 1055 if (!dm_split_lvm_name(dm->mem, lvlayer->old_name, &old_vgname, &old_lvname, &old_layer)) { 1056 log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer->old_name); 1057 return 0; 1058 } 1059 if (!dm_split_lvm_name(dm->mem, name, &new_vgname, &new_lvname, &new_layer)) { 1060 log_error("_create_lv_symlinks: Couldn't split up new device name %s", name); 1061 return 0; 1062 } 1063 if (!fs_rename_lv(lvlayer->lv, name, old_vgname, old_lvname)) 1064 r = 0; 1065 } else if (!dev_manager_lv_mknodes(lvlayer->lv)) 1066 r = 0; 1067 } 1068 1069 return r; 1070 } 1071 1072 /* 1073 * Remove LV symlinks for children of supplied root node. 1074 */ 1075 static int _remove_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root) 1076 { 1077 void *handle = NULL; 1078 struct dm_tree_node *child; 1079 char *vgname, *lvname, *layer; 1080 int r = 1; 1081 1082 while ((child = dm_tree_next_child(&handle, root, 0))) { 1083 if (!dm_split_lvm_name(dm->mem, dm_tree_node_get_name(child), &vgname, &lvname, &layer)) { 1084 r = 0; 1085 continue; 1086 } 1087 1088 if (!*vgname) 1089 continue; 1090 1091 /* only top level layer has symlinks */ 1092 if (*layer) 1093 continue; 1094 1095 fs_del_lv_byname(dm->cmd->dev_dir, vgname, lvname); 1096 } 1097 1098 return r; 1099 } 1100 1101 static int _clean_tree(struct dev_manager *dm, struct dm_tree_node *root) 1102 { 1103 void *handle = NULL; 1104 struct dm_tree_node *child; 1105 char *vgname, *lvname, *layer; 1106 const char *name, *uuid; 1107 1108 while ((child = dm_tree_next_child(&handle, root, 0))) { 1109 if (!(name = dm_tree_node_get_name(child))) 1110 continue; 1111 1112 if (!(uuid = dm_tree_node_get_uuid(child))) 1113 continue; 1114 1115 if (!dm_split_lvm_name(dm->mem, name, &vgname, &lvname, &layer)) { 1116 log_error("_clean_tree: Couldn't split up device name %s.", name); 1117 return 0; 1118 } 1119 1120 /* Not meant to be top level? */ 1121 if (!*layer) 1122 continue; 1123 1124 if (!dm_tree_deactivate_children(root, uuid, strlen(uuid))) 1125 return_0; 1126 } 1127 1128 return 1; 1129 } 1130 1131 static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, action_t action) 1132 { 1133 struct dm_tree *dtree; 1134 struct dm_tree_node *root; 1135 char *dlid; 1136 int r = 0; 1137 1138 if (!(dtree = _create_partial_dtree(dm, lv))) 1139 return_0; 1140 1141 if (!(root = dm_tree_find_node(dtree, 0, 0))) { 1142 log_error("Lost dependency tree root node"); 1143 goto out; 1144 } 1145 1146 if (!(dlid = build_dlid(dm, lv->lvid.s, NULL))) 1147 goto_out; 1148 1149 /* Only process nodes with uuid of "LVM-" plus VG id. */ 1150 switch(action) { 1151 case CLEAN: 1152 /* Deactivate any unused non-toplevel nodes */ 1153 if (!_clean_tree(dm, root)) 1154 goto_out; 1155 break; 1156 case DEACTIVATE: 1157 /* Deactivate LV and all devices it references that nothing else has open. */ 1158 if (!dm_tree_deactivate_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1)) 1159 goto_out; 1160 if (!_remove_lv_symlinks(dm, root)) 1161 log_error("Failed to remove all device symlinks associated with %s.", lv->name); 1162 break; 1163 case SUSPEND: 1164 dm_tree_skip_lockfs(root); 1165 if ((lv->status & MIRRORED) && !(lv->status & PVMOVE)) 1166 dm_tree_use_no_flush_suspend(root); 1167 case SUSPEND_WITH_LOCKFS: 1168 if (!dm_tree_suspend_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1)) 1169 goto_out; 1170 break; 1171 case PRELOAD: 1172 case ACTIVATE: 1173 /* Add all required new devices to tree */ 1174 if (!_add_new_lv_to_dtree(dm, dtree, lv, NULL)) 1175 goto_out; 1176 1177 /* Preload any devices required before any suspensions */ 1178 if (!dm_tree_preload_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1)) 1179 goto_out; 1180 1181 if ((action == ACTIVATE) && 1182 !dm_tree_activate_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1)) 1183 goto_out; 1184 1185 if (!_create_lv_symlinks(dm, root)) { 1186 log_error("Failed to create symlinks for %s.", lv->name); 1187 goto out; 1188 } 1189 break; 1190 default: 1191 log_error("_tree_action: Action %u not supported.", action); 1192 goto out; 1193 } 1194 1195 r = 1; 1196 1197 out: 1198 dm_tree_free(dtree); 1199 1200 return r; 1201 } 1202 1203 int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv) 1204 { 1205 if (!_tree_action(dm, lv, ACTIVATE)) 1206 return_0; 1207 1208 return _tree_action(dm, lv, CLEAN); 1209 } 1210 1211 int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv) 1212 { 1213 /* FIXME Update the pvmove implementation! */ 1214 if ((lv->status & PVMOVE) || (lv->status & LOCKED)) 1215 return 1; 1216 1217 return _tree_action(dm, lv, PRELOAD); 1218 } 1219 1220 int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv) 1221 { 1222 int r; 1223 1224 r = _tree_action(dm, lv, DEACTIVATE); 1225 1226 fs_del_lv(lv); 1227 1228 return r; 1229 } 1230 1231 int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv, 1232 int lockfs) 1233 { 1234 return _tree_action(dm, lv, lockfs ? SUSPEND_WITH_LOCKFS : SUSPEND); 1235 } 1236 1237 /* 1238 * Does device use VG somewhere in its construction? 1239 * Returns 1 if uncertain. 1240 */ 1241 int dev_manager_device_uses_vg(struct device *dev, 1242 struct volume_group *vg) 1243 { 1244 struct dm_tree *dtree; 1245 struct dm_tree_node *root; 1246 char dlid[sizeof(UUID_PREFIX) + sizeof(struct id) - 1] __attribute((aligned(8))); 1247 int r = 1; 1248 1249 if (!(dtree = dm_tree_create())) { 1250 log_error("partial dtree creation failed"); 1251 return r; 1252 } 1253 1254 if (!dm_tree_add_dev(dtree, (uint32_t) MAJOR(dev->dev), (uint32_t) MINOR(dev->dev))) { 1255 log_error("Failed to add device %s (%" PRIu32 ":%" PRIu32") to dtree", 1256 dev_name(dev), (uint32_t) MAJOR(dev->dev), (uint32_t) MINOR(dev->dev)); 1257 goto out; 1258 } 1259 1260 memcpy(dlid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1); 1261 memcpy(dlid + sizeof(UUID_PREFIX) - 1, &vg->id.uuid[0], sizeof(vg->id)); 1262 1263 if (!(root = dm_tree_find_node(dtree, 0, 0))) { 1264 log_error("Lost dependency tree root node"); 1265 goto out; 1266 } 1267 1268 if (dm_tree_children_use_uuid(root, dlid, sizeof(UUID_PREFIX) + sizeof(vg->id) - 1)) 1269 goto_out; 1270 1271 r = 0; 1272 1273 out: 1274 dm_tree_free(dtree); 1275 return r; 1276 } 1277