1 /* $NetBSD: format-text.c,v 1.1.1.3 2009/12/02 00:26:32 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-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 "format-text.h" 20 #include "import-export.h" 21 #include "device.h" 22 #include "lvm-file.h" 23 #include "config.h" 24 #include "display.h" 25 #include "toolcontext.h" 26 #include "lvm-string.h" 27 #include "uuid.h" 28 #include "layout.h" 29 #include "crc.h" 30 #include "xlate.h" 31 #include "label.h" 32 #include "memlock.h" 33 #include "lvmcache.h" 34 35 #include <unistd.h> 36 #include <sys/file.h> 37 #include <sys/param.h> 38 #include <limits.h> 39 #include <dirent.h> 40 #include <ctype.h> 41 42 static struct mda_header *_raw_read_mda_header(const struct format_type *fmt, 43 struct device_area *dev_area); 44 45 static struct format_instance *_text_create_text_instance(const struct format_type 46 *fmt, const char *vgname, 47 const char *vgid, 48 void *context); 49 50 struct text_fid_context { 51 char *raw_metadata_buf; 52 uint32_t raw_metadata_buf_size; 53 }; 54 55 struct dir_list { 56 struct dm_list list; 57 char dir[0]; 58 }; 59 60 struct raw_list { 61 struct dm_list list; 62 struct device_area dev_area; 63 }; 64 65 struct text_context { 66 char *path_live; /* Path to file holding live metadata */ 67 char *path_edit; /* Path to file holding edited metadata */ 68 char *desc; /* Description placed inside file */ 69 }; 70 71 /* 72 * NOTE: Currently there can be only one vg per text file. 73 */ 74 75 static int _text_vg_setup(struct format_instance *fid __attribute((unused)), 76 struct volume_group *vg) 77 { 78 if (vg->extent_size & (vg->extent_size - 1)) { 79 log_error("Extent size must be power of 2"); 80 return 0; 81 } 82 83 return 1; 84 } 85 86 static uint64_t _mda_free_sectors_raw(struct metadata_area *mda) 87 { 88 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 89 90 return mdac->free_sectors; 91 } 92 93 static uint64_t _mda_total_sectors_raw(struct metadata_area *mda) 94 { 95 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 96 97 return mdac->area.size >> SECTOR_SHIFT; 98 } 99 100 /* 101 * Check if metadata area belongs to vg 102 */ 103 static int _mda_in_vg_raw(struct format_instance *fid __attribute((unused)), 104 struct volume_group *vg, struct metadata_area *mda) 105 { 106 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 107 struct pv_list *pvl; 108 109 dm_list_iterate_items(pvl, &vg->pvs) 110 if (pvl->pv->dev == mdac->area.dev) 111 return 1; 112 113 return 0; 114 } 115 116 /* 117 * For circular region between region_start and region_start + region_size, 118 * back up one SECTOR_SIZE from 'region_ptr' and return the value. 119 * This allows reverse traversal through text metadata area to find old 120 * metadata. 121 * 122 * Parameters: 123 * region_start: start of the region (bytes) 124 * region_size: size of the region (bytes) 125 * region_ptr: pointer within the region (bytes) 126 * NOTE: region_start <= region_ptr <= region_start + region_size 127 */ 128 static uint64_t _get_prev_sector_circular(uint64_t region_start, 129 uint64_t region_size, 130 uint64_t region_ptr) 131 { 132 if (region_ptr >= region_start + SECTOR_SIZE) 133 return region_ptr - SECTOR_SIZE; 134 else 135 return (region_start + region_size - SECTOR_SIZE); 136 } 137 138 /* 139 * Analyze a metadata area for old metadata records in the circular buffer. 140 * This function just looks through and makes a first pass at the data in 141 * the sectors for particular things. 142 * FIXME: do something with each metadata area (try to extract vg, write 143 * raw data to file, etc) 144 */ 145 static int _pv_analyze_mda_raw (const struct format_type * fmt, 146 struct metadata_area *mda) 147 { 148 struct mda_header *mdah; 149 struct raw_locn *rlocn; 150 uint64_t area_start; 151 uint64_t area_size; 152 uint64_t prev_sector, prev_sector2; 153 uint64_t latest_mrec_offset; 154 int i; 155 uint64_t offset; 156 uint64_t offset2; 157 size_t size; 158 size_t size2; 159 char *buf=NULL; 160 struct device_area *area; 161 struct mda_context *mdac; 162 int r=0; 163 164 mdac = (struct mda_context *) mda->metadata_locn; 165 166 log_print("Found text metadata area: offset=%" PRIu64 ", size=%" 167 PRIu64, mdac->area.start, mdac->area.size); 168 area = &mdac->area; 169 170 if (!dev_open(area->dev)) 171 return_0; 172 173 if (!(mdah = _raw_read_mda_header(fmt, area))) 174 goto_out; 175 176 rlocn = mdah->raw_locns; 177 178 /* 179 * The device area includes the metadata header as well as the 180 * records, so remove the metadata header from the start and size 181 */ 182 area_start = area->start + MDA_HEADER_SIZE; 183 area_size = area->size - MDA_HEADER_SIZE; 184 latest_mrec_offset = rlocn->offset + area->start; 185 186 /* 187 * Start searching at rlocn (point of live metadata) and go 188 * backwards. 189 */ 190 prev_sector = _get_prev_sector_circular(area_start, area_size, 191 latest_mrec_offset); 192 offset = prev_sector; 193 size = SECTOR_SIZE; 194 offset2 = size2 = 0; 195 i = 0; 196 while (prev_sector != latest_mrec_offset) { 197 prev_sector2 = prev_sector; 198 prev_sector = _get_prev_sector_circular(area_start, area_size, 199 prev_sector); 200 if (prev_sector > prev_sector2) 201 goto_out; 202 /* 203 * FIXME: for some reason, the whole metadata region from 204 * area->start to area->start+area->size is not used. 205 * Only ~32KB seems to contain valid metadata records 206 * (LVM2 format - format_text). As a result, I end up with 207 * "maybe_config_section" returning true when there's no valid 208 * metadata in a sector (sectors with all nulls). 209 */ 210 if (!(buf = dm_pool_alloc(fmt->cmd->mem, size + size2))) 211 goto_out; 212 213 if (!dev_read_circular(area->dev, offset, size, 214 offset2, size2, buf)) 215 goto_out; 216 217 /* 218 * FIXME: We could add more sophisticated metadata detection 219 */ 220 if (maybe_config_section(buf, size + size2)) { 221 /* FIXME: Validate region, pull out timestamp?, etc */ 222 /* FIXME: Do something with this region */ 223 log_verbose ("Found LVM2 metadata record at " 224 "offset=%"PRIu64", size=%"PRIsize_t", " 225 "offset2=%"PRIu64" size2=%"PRIsize_t, 226 offset, size, offset2, size2); 227 offset = prev_sector; 228 size = SECTOR_SIZE; 229 offset2 = size2 = 0; 230 } else { 231 /* 232 * Not a complete metadata record, assume we have 233 * metadata and just increase the size and offset. 234 * Start the second region if the previous sector is 235 * wrapping around towards the end of the disk. 236 */ 237 if (prev_sector > offset) { 238 offset2 = prev_sector; 239 size2 += SECTOR_SIZE; 240 } else { 241 offset = prev_sector; 242 size += SECTOR_SIZE; 243 } 244 } 245 dm_pool_free(fmt->cmd->mem, buf); 246 buf = NULL; 247 } 248 249 r = 1; 250 out: 251 if (buf) 252 dm_pool_free(fmt->cmd->mem, buf); 253 if (!dev_close(area->dev)) 254 stack; 255 return r; 256 } 257 258 259 260 static int _text_lv_setup(struct format_instance *fid __attribute((unused)), 261 struct logical_volume *lv) 262 { 263 /******** FIXME Any LV size restriction? 264 uint64_t max_size = UINT_MAX; 265 266 if (lv->size > max_size) { 267 char *dummy = display_size(max_size); 268 log_error("logical volumes cannot be larger than %s", dummy); 269 dm_free(dummy); 270 return 0; 271 } 272 */ 273 274 if (!*lv->lvid.s && !lvid_create(&lv->lvid, &lv->vg->id)) { 275 log_error("Random lvid creation failed for %s/%s.", 276 lv->vg->name, lv->name); 277 return 0; 278 } 279 280 return 1; 281 } 282 283 static void _xlate_mdah(struct mda_header *mdah) 284 { 285 struct raw_locn *rl; 286 287 mdah->version = xlate32(mdah->version); 288 mdah->start = xlate64(mdah->start); 289 mdah->size = xlate64(mdah->size); 290 291 rl = &mdah->raw_locns[0]; 292 while (rl->offset) { 293 rl->checksum = xlate32(rl->checksum); 294 rl->offset = xlate64(rl->offset); 295 rl->size = xlate64(rl->size); 296 rl++; 297 } 298 } 299 300 static struct mda_header *_raw_read_mda_header(const struct format_type *fmt, 301 struct device_area *dev_area) 302 { 303 struct mda_header *mdah; 304 305 if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) { 306 log_error("struct mda_header allocation failed"); 307 return NULL; 308 } 309 310 if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) 311 goto_bad; 312 313 if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, mdah->magic, 314 MDA_HEADER_SIZE - 315 sizeof(mdah->checksum_xl)))) { 316 log_error("Incorrect metadata area header checksum"); 317 goto bad; 318 } 319 320 _xlate_mdah(mdah); 321 322 if (strncmp((char *)mdah->magic, FMTT_MAGIC, sizeof(mdah->magic))) { 323 log_error("Wrong magic number in metadata area header"); 324 goto bad; 325 } 326 327 if (mdah->version != FMTT_VERSION) { 328 log_error("Incompatible metadata area header version: %d", 329 mdah->version); 330 goto bad; 331 } 332 333 if (mdah->start != dev_area->start) { 334 log_error("Incorrect start sector in metadata area header: %" 335 PRIu64, mdah->start); 336 goto bad; 337 } 338 339 return mdah; 340 341 bad: 342 dm_pool_free(fmt->cmd->mem, mdah); 343 return NULL; 344 } 345 346 static int _raw_write_mda_header(const struct format_type *fmt, 347 struct device *dev, 348 uint64_t start_byte, struct mda_header *mdah) 349 { 350 strncpy((char *)mdah->magic, FMTT_MAGIC, sizeof(mdah->magic)); 351 mdah->version = FMTT_VERSION; 352 mdah->start = start_byte; 353 354 _xlate_mdah(mdah); 355 mdah->checksum_xl = xlate32(calc_crc(INITIAL_CRC, mdah->magic, 356 MDA_HEADER_SIZE - 357 sizeof(mdah->checksum_xl))); 358 359 if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) 360 return_0; 361 362 return 1; 363 } 364 365 static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area, 366 struct mda_header *mdah, 367 const char *vgname, 368 int *precommitted) 369 { 370 size_t len; 371 char vgnamebuf[NAME_LEN + 2] __attribute((aligned(8))); 372 struct raw_locn *rlocn, *rlocn_precommitted; 373 struct lvmcache_info *info; 374 375 rlocn = mdah->raw_locns; /* Slot 0 */ 376 rlocn_precommitted = rlocn + 1; /* Slot 1 */ 377 378 /* Should we use precommitted metadata? */ 379 if (*precommitted && rlocn_precommitted->size && 380 (rlocn_precommitted->offset != rlocn->offset)) { 381 rlocn = rlocn_precommitted; 382 } else 383 *precommitted = 0; 384 385 /* FIXME Loop through rlocns two-at-a-time. List null-terminated. */ 386 /* FIXME Ignore if checksum incorrect!!! */ 387 if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset, 388 sizeof(vgnamebuf), vgnamebuf)) 389 goto_bad; 390 391 if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) && 392 (isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) { 393 return rlocn; 394 } 395 396 bad: 397 if ((info = info_from_pvid(dev_area->dev->pvid, 0))) 398 lvmcache_update_vgname_and_id(info, FMT_TEXT_ORPHAN_VG_NAME, 399 FMT_TEXT_ORPHAN_VG_NAME, 0, NULL); 400 401 return NULL; 402 } 403 404 /* 405 * Determine offset for uncommitted metadata 406 */ 407 static uint64_t _next_rlocn_offset(struct raw_locn *rlocn, 408 struct mda_header *mdah) 409 { 410 if (!rlocn) 411 /* Find an empty slot */ 412 /* FIXME Assume only one VG per mdah for now */ 413 return MDA_HEADER_SIZE; 414 415 /* Start of free space - round up to next sector; circular */ 416 return ((rlocn->offset + rlocn->size + 417 (SECTOR_SIZE - rlocn->size % SECTOR_SIZE) - 418 MDA_HEADER_SIZE) % (mdah->size - MDA_HEADER_SIZE)) 419 + MDA_HEADER_SIZE; 420 } 421 422 static int _raw_holds_vgname(struct format_instance *fid, 423 struct device_area *dev_area, const char *vgname) 424 { 425 int r = 0; 426 int noprecommit = 0; 427 struct mda_header *mdah; 428 429 if (!dev_open(dev_area->dev)) 430 return_0; 431 432 if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area))) 433 return_0; 434 435 if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit)) 436 r = 1; 437 438 if (!dev_close(dev_area->dev)) 439 stack; 440 441 return r; 442 } 443 444 static struct volume_group *_vg_read_raw_area(struct format_instance *fid, 445 const char *vgname, 446 struct device_area *area, 447 int precommitted) 448 { 449 struct volume_group *vg = NULL; 450 struct raw_locn *rlocn; 451 struct mda_header *mdah; 452 time_t when; 453 char *desc; 454 uint32_t wrap = 0; 455 456 if (!dev_open(area->dev)) 457 return_NULL; 458 459 if (!(mdah = _raw_read_mda_header(fid->fmt, area))) 460 goto_out; 461 462 if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) { 463 log_debug("VG %s not found on %s", vgname, dev_name(area->dev)); 464 goto out; 465 } 466 467 if (rlocn->offset + rlocn->size > mdah->size) 468 wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size); 469 470 if (wrap > rlocn->offset) { 471 log_error("VG %s metadata too large for circular buffer", 472 vg->name); 473 goto out; 474 } 475 476 /* FIXME 64-bit */ 477 if (!(vg = text_vg_import_fd(fid, NULL, area->dev, 478 (off_t) (area->start + rlocn->offset), 479 (uint32_t) (rlocn->size - wrap), 480 (off_t) (area->start + MDA_HEADER_SIZE), 481 wrap, calc_crc, rlocn->checksum, &when, 482 &desc))) 483 goto_out; 484 log_debug("Read %s %smetadata (%u) from %s at %" PRIu64 " size %" 485 PRIu64, vg->name, precommitted ? "pre-commit " : "", 486 vg->seqno, dev_name(area->dev), 487 area->start + rlocn->offset, rlocn->size); 488 489 if (precommitted) 490 vg->status |= PRECOMMITTED; 491 492 out: 493 if (!dev_close(area->dev)) 494 stack; 495 496 return vg; 497 } 498 499 static struct volume_group *_vg_read_raw(struct format_instance *fid, 500 const char *vgname, 501 struct metadata_area *mda) 502 { 503 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 504 505 return _vg_read_raw_area(fid, vgname, &mdac->area, 0); 506 } 507 508 static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid, 509 const char *vgname, 510 struct metadata_area *mda) 511 { 512 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 513 514 return _vg_read_raw_area(fid, vgname, &mdac->area, 1); 515 } 516 517 static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg, 518 struct metadata_area *mda) 519 { 520 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 521 struct text_fid_context *fidtc = (struct text_fid_context *) fid->private; 522 struct raw_locn *rlocn; 523 struct mda_header *mdah; 524 struct pv_list *pvl; 525 int r = 0; 526 uint64_t new_wrap = 0, old_wrap = 0, new_end; 527 int found = 0; 528 int noprecommit = 0; 529 530 /* Ignore any mda on a PV outside the VG. vgsplit relies on this */ 531 dm_list_iterate_items(pvl, &vg->pvs) { 532 if (pvl->pv->dev == mdac->area.dev) { 533 found = 1; 534 break; 535 } 536 } 537 538 if (!found) 539 return 1; 540 541 if (!dev_open(mdac->area.dev)) 542 return_0; 543 544 if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) 545 goto_out; 546 547 rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit); 548 mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah); 549 550 if (!fidtc->raw_metadata_buf && 551 !(fidtc->raw_metadata_buf_size = 552 text_vg_export_raw(vg, "", &fidtc->raw_metadata_buf))) { 553 log_error("VG %s metadata writing failed", vg->name); 554 goto out; 555 } 556 557 mdac->rlocn.size = fidtc->raw_metadata_buf_size; 558 559 if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size) 560 new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size; 561 562 if (rlocn && (rlocn->offset + rlocn->size > mdah->size)) 563 old_wrap = (rlocn->offset + rlocn->size) - mdah->size; 564 565 new_end = new_wrap ? new_wrap + MDA_HEADER_SIZE : 566 mdac->rlocn.offset + mdac->rlocn.size; 567 568 if ((new_wrap && old_wrap) || 569 (rlocn && (new_wrap || old_wrap) && (new_end > rlocn->offset)) || 570 (mdac->rlocn.size >= mdah->size)) { 571 log_error("VG %s metadata too large for circular buffer", 572 vg->name); 573 goto out; 574 } 575 576 log_debug("Writing %s metadata to %s at %" PRIu64 " len %" PRIu64, 577 vg->name, dev_name(mdac->area.dev), mdac->area.start + 578 mdac->rlocn.offset, mdac->rlocn.size - new_wrap); 579 580 /* Write text out, circularly */ 581 if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset, 582 (size_t) (mdac->rlocn.size - new_wrap), 583 fidtc->raw_metadata_buf)) 584 goto_out; 585 586 if (new_wrap) { 587 log_debug("Writing metadata to %s at %" PRIu64 " len %" PRIu64, 588 dev_name(mdac->area.dev), mdac->area.start + 589 MDA_HEADER_SIZE, new_wrap); 590 591 if (!dev_write(mdac->area.dev, 592 mdac->area.start + MDA_HEADER_SIZE, 593 (size_t) new_wrap, 594 fidtc->raw_metadata_buf + 595 mdac->rlocn.size - new_wrap)) 596 goto_out; 597 } 598 599 mdac->rlocn.checksum = calc_crc(INITIAL_CRC, fidtc->raw_metadata_buf, 600 (uint32_t) (mdac->rlocn.size - 601 new_wrap)); 602 if (new_wrap) 603 mdac->rlocn.checksum = calc_crc(mdac->rlocn.checksum, 604 fidtc->raw_metadata_buf + 605 mdac->rlocn.size - 606 new_wrap, (uint32_t) new_wrap); 607 608 r = 1; 609 610 out: 611 if (!r) { 612 if (!dev_close(mdac->area.dev)) 613 stack; 614 615 if (fidtc->raw_metadata_buf) { 616 dm_free(fidtc->raw_metadata_buf); 617 fidtc->raw_metadata_buf = NULL; 618 } 619 } 620 621 return r; 622 } 623 624 static int _vg_commit_raw_rlocn(struct format_instance *fid, 625 struct volume_group *vg, 626 struct metadata_area *mda, 627 int precommit) 628 { 629 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 630 struct text_fid_context *fidtc = (struct text_fid_context *) fid->private; 631 struct mda_header *mdah; 632 struct raw_locn *rlocn; 633 struct pv_list *pvl; 634 int r = 0; 635 int found = 0; 636 int noprecommit = 0; 637 638 /* Ignore any mda on a PV outside the VG. vgsplit relies on this */ 639 dm_list_iterate_items(pvl, &vg->pvs) { 640 if (pvl->pv->dev == mdac->area.dev) { 641 found = 1; 642 break; 643 } 644 } 645 646 if (!found) 647 return 1; 648 649 if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) 650 goto_out; 651 652 if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) { 653 mdah->raw_locns[0].offset = 0; 654 mdah->raw_locns[0].size = 0; 655 mdah->raw_locns[0].checksum = 0; 656 mdah->raw_locns[1].offset = 0; 657 mdah->raw_locns[1].size = 0; 658 mdah->raw_locns[1].checksum = 0; 659 mdah->raw_locns[2].offset = 0; 660 mdah->raw_locns[2].size = 0; 661 mdah->raw_locns[2].checksum = 0; 662 rlocn = &mdah->raw_locns[0]; 663 } 664 665 if (precommit) 666 rlocn++; 667 else { 668 /* If not precommitting, wipe the precommitted rlocn */ 669 mdah->raw_locns[1].offset = 0; 670 mdah->raw_locns[1].size = 0; 671 mdah->raw_locns[1].checksum = 0; 672 } 673 674 /* Is there new metadata to commit? */ 675 if (mdac->rlocn.size) { 676 rlocn->offset = mdac->rlocn.offset; 677 rlocn->size = mdac->rlocn.size; 678 rlocn->checksum = mdac->rlocn.checksum; 679 log_debug("%sCommitting %s metadata (%u) to %s header at %" 680 PRIu64, precommit ? "Pre-" : "", vg->name, vg->seqno, 681 dev_name(mdac->area.dev), mdac->area.start); 682 } else 683 log_debug("Wiping pre-committed %s metadata from %s " 684 "header at %" PRIu64, vg->name, 685 dev_name(mdac->area.dev), mdac->area.start); 686 687 if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start, 688 mdah)) { 689 dm_pool_free(fid->fmt->cmd->mem, mdah); 690 log_error("Failed to write metadata area header"); 691 goto out; 692 } 693 694 r = 1; 695 696 out: 697 if (!precommit) { 698 if (!dev_close(mdac->area.dev)) 699 stack; 700 if (fidtc->raw_metadata_buf) { 701 dm_free(fidtc->raw_metadata_buf); 702 fidtc->raw_metadata_buf = NULL; 703 } 704 } 705 706 return r; 707 } 708 709 static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg, 710 struct metadata_area *mda) 711 { 712 return _vg_commit_raw_rlocn(fid, vg, mda, 0); 713 } 714 715 static int _vg_precommit_raw(struct format_instance *fid, 716 struct volume_group *vg, 717 struct metadata_area *mda) 718 { 719 return _vg_commit_raw_rlocn(fid, vg, mda, 1); 720 } 721 722 /* Close metadata area devices */ 723 static int _vg_revert_raw(struct format_instance *fid, struct volume_group *vg, 724 struct metadata_area *mda) 725 { 726 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 727 struct pv_list *pvl; 728 int found = 0; 729 730 /* Ignore any mda on a PV outside the VG. vgsplit relies on this */ 731 dm_list_iterate_items(pvl, &vg->pvs) { 732 if (pvl->pv->dev == mdac->area.dev) { 733 found = 1; 734 break; 735 } 736 } 737 738 if (!found) 739 return 1; 740 741 /* Wipe pre-committed metadata */ 742 mdac->rlocn.size = 0; 743 return _vg_commit_raw_rlocn(fid, vg, mda, 0); 744 } 745 746 static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg, 747 struct metadata_area *mda) 748 { 749 struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; 750 struct mda_header *mdah; 751 struct raw_locn *rlocn; 752 int r = 0; 753 int noprecommit = 0; 754 755 if (!dev_open(mdac->area.dev)) 756 return_0; 757 758 if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) 759 goto_out; 760 761 if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) { 762 rlocn = &mdah->raw_locns[0]; 763 mdah->raw_locns[1].offset = 0; 764 } 765 766 rlocn->offset = 0; 767 rlocn->size = 0; 768 rlocn->checksum = 0; 769 770 if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start, 771 mdah)) { 772 dm_pool_free(fid->fmt->cmd->mem, mdah); 773 log_error("Failed to write metadata area header"); 774 goto out; 775 } 776 777 r = 1; 778 779 out: 780 if (!dev_close(mdac->area.dev)) 781 stack; 782 783 return r; 784 } 785 786 static struct volume_group *_vg_read_file_name(struct format_instance *fid, 787 const char *vgname, 788 const char *read_path) 789 { 790 struct volume_group *vg; 791 time_t when; 792 char *desc; 793 794 if (!(vg = text_vg_import_file(fid, read_path, &when, &desc))) 795 return_NULL; 796 797 /* 798 * Currently you can only have a single volume group per 799 * text file (this restriction may remain). We need to 800 * check that it contains the correct volume group. 801 */ 802 if (vgname && strcmp(vgname, vg->name)) { 803 dm_pool_free(fid->fmt->cmd->mem, vg); 804 log_error("'%s' does not contain volume group '%s'.", 805 read_path, vgname); 806 return NULL; 807 } else 808 log_debug("Read volume group %s from %s", vg->name, read_path); 809 810 return vg; 811 } 812 813 static struct volume_group *_vg_read_file(struct format_instance *fid, 814 const char *vgname, 815 struct metadata_area *mda) 816 { 817 struct text_context *tc = (struct text_context *) mda->metadata_locn; 818 819 return _vg_read_file_name(fid, vgname, tc->path_live); 820 } 821 822 static struct volume_group *_vg_read_precommit_file(struct format_instance *fid, 823 const char *vgname, 824 struct metadata_area *mda) 825 { 826 struct text_context *tc = (struct text_context *) mda->metadata_locn; 827 struct volume_group *vg; 828 829 if ((vg = _vg_read_file_name(fid, vgname, tc->path_edit))) 830 vg->status |= PRECOMMITTED; 831 else 832 vg = _vg_read_file_name(fid, vgname, tc->path_live); 833 834 return vg; 835 } 836 837 static int _vg_write_file(struct format_instance *fid __attribute((unused)), 838 struct volume_group *vg, struct metadata_area *mda) 839 { 840 struct text_context *tc = (struct text_context *) mda->metadata_locn; 841 842 FILE *fp; 843 int fd; 844 char *slash; 845 char temp_file[PATH_MAX], temp_dir[PATH_MAX]; 846 847 slash = strrchr(tc->path_edit, '/'); 848 849 if (slash == 0) 850 strcpy(temp_dir, "."); 851 else if (slash - tc->path_edit < PATH_MAX) { 852 strncpy(temp_dir, tc->path_edit, 853 (size_t) (slash - tc->path_edit)); 854 temp_dir[slash - tc->path_edit] = '\0'; 855 856 } else { 857 log_error("Text format failed to determine directory."); 858 return 0; 859 } 860 861 if (!create_temp_name(temp_dir, temp_file, sizeof(temp_file), &fd, 862 &vg->cmd->rand_seed)) { 863 log_error("Couldn't create temporary text file name."); 864 return 0; 865 } 866 867 if (!(fp = fdopen(fd, "w"))) { 868 log_sys_error("fdopen", temp_file); 869 if (close(fd)) 870 log_sys_error("fclose", temp_file); 871 return 0; 872 } 873 874 log_debug("Writing %s metadata to %s", vg->name, temp_file); 875 876 if (!text_vg_export_file(vg, tc->desc, fp)) { 877 log_error("Failed to write metadata to %s.", temp_file); 878 if (fclose(fp)) 879 log_sys_error("fclose", temp_file); 880 return 0; 881 } 882 883 if (fsync(fd) && (errno != EROFS) && (errno != EINVAL)) { 884 log_sys_error("fsync", tc->path_edit); 885 if (fclose(fp)) 886 log_sys_error("fclose", tc->path_edit); 887 return 0; 888 } 889 890 if (lvm_fclose(fp, tc->path_edit)) 891 return_0; 892 893 if (rename(temp_file, tc->path_edit)) { 894 log_debug("Renaming %s to %s", temp_file, tc->path_edit); 895 log_error("%s: rename to %s failed: %s", temp_file, 896 tc->path_edit, strerror(errno)); 897 return 0; 898 } 899 900 return 1; 901 } 902 903 static int _vg_commit_file_backup(struct format_instance *fid __attribute((unused)), 904 struct volume_group *vg, 905 struct metadata_area *mda) 906 { 907 struct text_context *tc = (struct text_context *) mda->metadata_locn; 908 909 if (test_mode()) { 910 log_verbose("Test mode: Skipping committing %s metadata (%u)", 911 vg->name, vg->seqno); 912 if (unlink(tc->path_edit)) { 913 log_debug("Unlinking %s", tc->path_edit); 914 log_sys_error("unlink", tc->path_edit); 915 return 0; 916 } 917 } else { 918 log_debug("Committing %s metadata (%u)", vg->name, vg->seqno); 919 log_debug("Renaming %s to %s", tc->path_edit, tc->path_live); 920 if (rename(tc->path_edit, tc->path_live)) { 921 log_error("%s: rename to %s failed: %s", tc->path_edit, 922 tc->path_live, strerror(errno)); 923 return 0; 924 } 925 } 926 927 sync_dir(tc->path_edit); 928 929 return 1; 930 } 931 932 static int _vg_commit_file(struct format_instance *fid, struct volume_group *vg, 933 struct metadata_area *mda) 934 { 935 struct text_context *tc = (struct text_context *) mda->metadata_locn; 936 char *slash; 937 char new_name[PATH_MAX]; 938 size_t len; 939 940 if (!_vg_commit_file_backup(fid, vg, mda)) 941 return 0; 942 943 /* vgrename? */ 944 if ((slash = strrchr(tc->path_live, '/'))) 945 slash = slash + 1; 946 else 947 slash = tc->path_live; 948 949 if (strcmp(slash, vg->name)) { 950 len = slash - tc->path_live; 951 strncpy(new_name, tc->path_live, len); 952 strcpy(new_name + len, vg->name); 953 log_debug("Renaming %s to %s", tc->path_live, new_name); 954 if (test_mode()) 955 log_verbose("Test mode: Skipping rename"); 956 else { 957 if (rename(tc->path_live, new_name)) { 958 log_error("%s: rename to %s failed: %s", 959 tc->path_live, new_name, 960 strerror(errno)); 961 sync_dir(new_name); 962 return 0; 963 } 964 } 965 } 966 967 return 1; 968 } 969 970 static int _vg_remove_file(struct format_instance *fid __attribute((unused)), 971 struct volume_group *vg __attribute((unused)), 972 struct metadata_area *mda) 973 { 974 struct text_context *tc = (struct text_context *) mda->metadata_locn; 975 976 if (path_exists(tc->path_edit) && unlink(tc->path_edit)) { 977 log_sys_error("unlink", tc->path_edit); 978 return 0; 979 } 980 981 if (path_exists(tc->path_live) && unlink(tc->path_live)) { 982 log_sys_error("unlink", tc->path_live); 983 return 0; 984 } 985 986 sync_dir(tc->path_live); 987 988 return 1; 989 } 990 991 static int _scan_file(const struct format_type *fmt) 992 { 993 struct dirent *dirent; 994 struct dir_list *dl; 995 struct dm_list *dir_list; 996 char *tmp; 997 DIR *d; 998 struct volume_group *vg; 999 struct format_instance *fid; 1000 char path[PATH_MAX]; 1001 char *vgname; 1002 1003 dir_list = &((struct mda_lists *) fmt->private)->dirs; 1004 1005 dm_list_iterate_items(dl, dir_list) { 1006 if (!(d = opendir(dl->dir))) { 1007 log_sys_error("opendir", dl->dir); 1008 continue; 1009 } 1010 while ((dirent = readdir(d))) 1011 if (strcmp(dirent->d_name, ".") && 1012 strcmp(dirent->d_name, "..") && 1013 (!(tmp = strstr(dirent->d_name, ".tmp")) || 1014 tmp != dirent->d_name + strlen(dirent->d_name) 1015 - 4)) { 1016 vgname = dirent->d_name; 1017 if (dm_snprintf(path, PATH_MAX, "%s/%s", 1018 dl->dir, vgname) < 0) { 1019 log_error("Name too long %s/%s", 1020 dl->dir, vgname); 1021 break; 1022 } 1023 1024 /* FIXME stat file to see if it's changed */ 1025 fid = _text_create_text_instance(fmt, NULL, NULL, 1026 NULL); 1027 if ((vg = _vg_read_file_name(fid, vgname, 1028 path))) 1029 /* FIXME Store creation host in vg */ 1030 lvmcache_update_vg(vg, 0); 1031 } 1032 1033 if (closedir(d)) 1034 log_sys_error("closedir", dl->dir); 1035 } 1036 1037 return 1; 1038 } 1039 1040 const char *vgname_from_mda(const struct format_type *fmt, 1041 struct device_area *dev_area, struct id *vgid, 1042 uint32_t *vgstatus, char **creation_host, 1043 uint64_t *mda_free_sectors) 1044 { 1045 struct raw_locn *rlocn; 1046 struct mda_header *mdah; 1047 uint32_t wrap = 0; 1048 const char *vgname = NULL; 1049 unsigned int len = 0; 1050 char buf[NAME_LEN + 1] __attribute((aligned(8))); 1051 char uuid[64] __attribute((aligned(8))); 1052 uint64_t buffer_size, current_usage; 1053 1054 if (mda_free_sectors) 1055 *mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT; 1056 1057 if (!dev_open(dev_area->dev)) 1058 return_NULL; 1059 1060 if (!(mdah = _raw_read_mda_header(fmt, dev_area))) 1061 goto_out; 1062 1063 /* FIXME Cope with returning a list */ 1064 rlocn = mdah->raw_locns; 1065 1066 /* 1067 * If no valid offset, do not try to search for vgname 1068 */ 1069 if (!rlocn->offset) 1070 goto out; 1071 1072 /* Do quick check for a vgname */ 1073 if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset, 1074 NAME_LEN, buf)) 1075 goto_out; 1076 1077 while (buf[len] && !isspace(buf[len]) && buf[len] != '{' && 1078 len < (NAME_LEN - 1)) 1079 len++; 1080 1081 buf[len] = '\0'; 1082 1083 /* Ignore this entry if the characters aren't permissible */ 1084 if (!validate_name(buf)) 1085 goto_out; 1086 1087 /* We found a VG - now check the metadata */ 1088 if (rlocn->offset + rlocn->size > mdah->size) 1089 wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size); 1090 1091 if (wrap > rlocn->offset) { 1092 log_error("%s: metadata too large for circular buffer", 1093 dev_name(dev_area->dev)); 1094 goto out; 1095 } 1096 1097 /* FIXME 64-bit */ 1098 if (!(vgname = text_vgname_import(fmt, dev_area->dev, 1099 (off_t) (dev_area->start + 1100 rlocn->offset), 1101 (uint32_t) (rlocn->size - wrap), 1102 (off_t) (dev_area->start + 1103 MDA_HEADER_SIZE), 1104 wrap, calc_crc, rlocn->checksum, 1105 vgid, vgstatus, creation_host))) 1106 goto_out; 1107 1108 /* Ignore this entry if the characters aren't permissible */ 1109 if (!validate_name(vgname)) { 1110 vgname = NULL; 1111 goto_out; 1112 } 1113 1114 if (!id_write_format(vgid, uuid, sizeof(uuid))) { 1115 vgname = NULL; 1116 goto_out; 1117 } 1118 1119 log_debug("%s: Found metadata at %" PRIu64 " size %" PRIu64 1120 " (in area at %" PRIu64 " size %" PRIu64 1121 ") for %s (%s)", 1122 dev_name(dev_area->dev), dev_area->start + rlocn->offset, 1123 rlocn->size, dev_area->start, dev_area->size, vgname, uuid); 1124 1125 if (mda_free_sectors) { 1126 current_usage = (rlocn->size + SECTOR_SIZE - UINT64_C(1)) - 1127 (rlocn->size + SECTOR_SIZE - UINT64_C(1)) % SECTOR_SIZE; 1128 buffer_size = mdah->size - MDA_HEADER_SIZE; 1129 1130 if (current_usage * 2 >= buffer_size) 1131 *mda_free_sectors = UINT64_C(0); 1132 else 1133 *mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT; 1134 } 1135 1136 out: 1137 if (!dev_close(dev_area->dev)) 1138 stack; 1139 1140 return vgname; 1141 } 1142 1143 static int _scan_raw(const struct format_type *fmt) 1144 { 1145 struct raw_list *rl; 1146 struct dm_list *raw_list; 1147 const char *vgname; 1148 struct volume_group *vg; 1149 struct format_instance fid; 1150 struct id vgid; 1151 uint32_t vgstatus; 1152 1153 raw_list = &((struct mda_lists *) fmt->private)->raws; 1154 1155 fid.fmt = fmt; 1156 dm_list_init(&fid.metadata_areas); 1157 1158 dm_list_iterate_items(rl, raw_list) { 1159 /* FIXME We're reading mdah twice here... */ 1160 if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid, &vgstatus, 1161 NULL, NULL))) { 1162 if ((vg = _vg_read_raw_area(&fid, vgname, 1163 &rl->dev_area, 0))) 1164 lvmcache_update_vg(vg, 0); 1165 } 1166 } 1167 1168 return 1; 1169 } 1170 1171 static int _text_scan(const struct format_type *fmt) 1172 { 1173 return (_scan_file(fmt) & _scan_raw(fmt)); 1174 } 1175 1176 /* For orphan, creates new mdas according to policy. 1177 Always have an mda between end-of-label and pe_align() boundary */ 1178 static int _mda_setup(const struct format_type *fmt, 1179 uint64_t pe_start, uint64_t pe_end, 1180 int pvmetadatacopies, 1181 uint64_t pvmetadatasize, struct dm_list *mdas, 1182 struct physical_volume *pv, 1183 struct volume_group *vg __attribute((unused))) 1184 { 1185 uint64_t mda_adjustment, disk_size, alignment, alignment_offset; 1186 uint64_t start1, mda_size1; /* First area - start of disk */ 1187 uint64_t start2, mda_size2; /* Second area - end of disk */ 1188 uint64_t wipe_size = 8 << SECTOR_SHIFT; 1189 size_t pagesize = lvm_getpagesize(); 1190 1191 if (!pvmetadatacopies) 1192 return 1; 1193 1194 alignment = pv->pe_align << SECTOR_SHIFT; 1195 alignment_offset = pv->pe_align_offset << SECTOR_SHIFT; 1196 disk_size = pv->size << SECTOR_SHIFT; 1197 pe_start <<= SECTOR_SHIFT; 1198 pe_end <<= SECTOR_SHIFT; 1199 1200 if (pe_end > disk_size) { 1201 log_error("Physical extents end beyond end of device %s!", 1202 pv_dev_name(pv)); 1203 return 0; 1204 } 1205 1206 /* Requested metadatasize */ 1207 mda_size1 = pvmetadatasize << SECTOR_SHIFT; 1208 1209 /* Place mda straight after label area at start of disk */ 1210 start1 = LABEL_SCAN_SIZE; 1211 1212 /* Unless the space available is tiny, round to PAGE_SIZE boundary */ 1213 if ((!pe_start && !pe_end) || 1214 ((pe_start > start1) && (pe_start - start1 >= MDA_SIZE_MIN))) { 1215 mda_adjustment = start1 % pagesize; 1216 if (mda_adjustment) 1217 start1 += (pagesize - mda_adjustment); 1218 } 1219 1220 /* Round up to pe_align boundary */ 1221 mda_adjustment = (mda_size1 + start1) % alignment; 1222 if (mda_adjustment) { 1223 mda_size1 += (alignment - mda_adjustment); 1224 /* Revert if it's now too large */ 1225 if (start1 + mda_size1 > disk_size) 1226 mda_size1 -= (alignment - mda_adjustment); 1227 } 1228 1229 /* Add pe_align_offset if on pe_align boundary */ 1230 if (alignment_offset && 1231 (((start1 + mda_size1) % alignment) == 0)) { 1232 mda_size1 += alignment_offset; 1233 /* Revert if it's now too large */ 1234 if (start1 + mda_size1 > disk_size) 1235 mda_size1 -= alignment_offset; 1236 } 1237 1238 /* Ensure it's not going to be bigger than the disk! */ 1239 if (start1 + mda_size1 > disk_size) { 1240 log_warn("WARNING: metadata area fills disk leaving no " 1241 "space for data on %s.", pv_dev_name(pv)); 1242 /* Leave some free space for rounding */ 1243 /* Avoid empty data area as could cause tools problems */ 1244 mda_size1 = disk_size - start1 - alignment * 2; 1245 if (start1 + mda_size1 > disk_size) { 1246 log_error("Insufficient space for first mda on %s", 1247 pv_dev_name(pv)); 1248 return 0; 1249 } 1250 /* Round up to pe_align boundary */ 1251 mda_adjustment = (mda_size1 + start1) % alignment; 1252 if (mda_adjustment) 1253 mda_size1 += (alignment - mda_adjustment); 1254 /* Only have 1 mda in this case */ 1255 pvmetadatacopies = 1; 1256 } 1257 1258 /* If we already have PEs, avoid overlap */ 1259 if (pe_start || pe_end) { 1260 if (pe_start <= start1) 1261 mda_size1 = 0; 1262 else if (start1 + mda_size1 > pe_start) 1263 mda_size1 = pe_start - start1; 1264 } 1265 1266 /* FIXME If creating new mdas, wipe them! */ 1267 if (mda_size1) { 1268 if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start1, 1269 mda_size1)) 1270 return 0; 1271 1272 if (!dev_set((struct device *) pv->dev, start1, 1273 (size_t) (mda_size1 > 1274 wipe_size ? : mda_size1), 0)) { 1275 log_error("Failed to wipe new metadata area"); 1276 return 0; 1277 } 1278 1279 if (pvmetadatacopies == 1) 1280 return 1; 1281 } else 1282 start1 = 0; 1283 1284 /* A second copy at end of disk */ 1285 mda_size2 = pvmetadatasize << SECTOR_SHIFT; 1286 1287 /* Ensure it's not going to be bigger than the disk! */ 1288 if (mda_size2 > disk_size) 1289 mda_size2 = disk_size - start1 - mda_size1; 1290 1291 mda_adjustment = (disk_size - mda_size2) % alignment; 1292 if (mda_adjustment) 1293 mda_size2 += mda_adjustment; 1294 1295 start2 = disk_size - mda_size2; 1296 1297 /* If we already have PEs, avoid overlap */ 1298 if (pe_start || pe_end) { 1299 if (start2 < pe_end) { 1300 mda_size2 -= (pe_end - start2); 1301 start2 = pe_end; 1302 } 1303 } 1304 1305 /* If we already have a first mda, avoid overlap */ 1306 if (mda_size1) { 1307 if (start2 < start1 + mda_size1) { 1308 mda_size2 -= (start1 + mda_size1 - start2); 1309 start2 = start1 + mda_size1; 1310 } 1311 /* No room for any PEs here now! */ 1312 } 1313 1314 if (mda_size2) { 1315 if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start2, 1316 mda_size2)) return 0; 1317 if (!dev_set(pv->dev, start2, 1318 (size_t) (mda_size1 > 1319 wipe_size ? : mda_size1), 0)) { 1320 log_error("Failed to wipe new metadata area"); 1321 return 0; 1322 } 1323 } else 1324 return 0; 1325 1326 return 1; 1327 } 1328 1329 /* Only for orphans */ 1330 /* Set label_sector to -1 if rewriting existing label into same sector */ 1331 /* If mdas is supplied it overwrites existing mdas e.g. used with pvcreate */ 1332 static int _text_pv_write(const struct format_type *fmt, struct physical_volume *pv, 1333 struct dm_list *mdas, int64_t label_sector) 1334 { 1335 struct label *label; 1336 struct lvmcache_info *info; 1337 struct mda_context *mdac; 1338 struct metadata_area *mda; 1339 char buf[MDA_HEADER_SIZE] __attribute((aligned(8))); 1340 struct mda_header *mdah = (struct mda_header *) buf; 1341 uint64_t adjustment; 1342 struct data_area_list *da; 1343 1344 /* FIXME Test mode don't update cache? */ 1345 1346 if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev, 1347 FMT_TEXT_ORPHAN_VG_NAME, NULL, 0))) 1348 return_0; 1349 label = info->label; 1350 1351 if (label_sector != -1) 1352 label->sector = label_sector; 1353 1354 info->device_size = pv->size << SECTOR_SHIFT; 1355 info->fmt = fmt; 1356 1357 /* If mdas supplied, use them regardless of existing ones, */ 1358 /* otherwise retain existing ones */ 1359 if (mdas) { 1360 if (info->mdas.n) 1361 del_mdas(&info->mdas); 1362 else 1363 dm_list_init(&info->mdas); 1364 dm_list_iterate_items(mda, mdas) { 1365 mdac = mda->metadata_locn; 1366 log_debug("Creating metadata area on %s at sector %" 1367 PRIu64 " size %" PRIu64 " sectors", 1368 dev_name(mdac->area.dev), 1369 mdac->area.start >> SECTOR_SHIFT, 1370 mdac->area.size >> SECTOR_SHIFT); 1371 add_mda(fmt, NULL, &info->mdas, mdac->area.dev, 1372 mdac->area.start, mdac->area.size); 1373 } 1374 /* FIXME Temporary until mda creation supported by tools */ 1375 } else if (!info->mdas.n) { 1376 dm_list_init(&info->mdas); 1377 } 1378 1379 /* 1380 * If no pe_start supplied but PV already exists, 1381 * get existing value; use-cases include: 1382 * - pvcreate on PV without prior pvremove 1383 * - vgremove on VG with PV(s) that have pe_start=0 (hacked cfg) 1384 */ 1385 if (info->das.n) { 1386 if (!pv->pe_start) 1387 dm_list_iterate_items(da, &info->das) 1388 pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT; 1389 del_das(&info->das); 1390 } else 1391 dm_list_init(&info->das); 1392 1393 #if 0 1394 /* 1395 * FIXME: ideally a pre-existing pe_start seen in .pv_write 1396 * would always be preserved BUT 'pvcreate on PV without prior pvremove' 1397 * could easily cause the pe_start to overlap with the first mda! 1398 */ 1399 if (pv->pe_start) { 1400 log_very_verbose("%s: preserving pe_start=%lu", 1401 pv_dev_name(pv), pv->pe_start); 1402 goto preserve_pe_start; 1403 } 1404 #endif 1405 1406 /* 1407 * If pe_start is still unset, set it to first aligned 1408 * sector after any metadata areas that begin before pe_start. 1409 */ 1410 if (!pv->pe_start) { 1411 pv->pe_start = pv->pe_align; 1412 if (pv->pe_align_offset) 1413 pv->pe_start += pv->pe_align_offset; 1414 } 1415 dm_list_iterate_items(mda, &info->mdas) { 1416 mdac = (struct mda_context *) mda->metadata_locn; 1417 if (pv->dev == mdac->area.dev && 1418 ((mdac->area.start <= (pv->pe_start << SECTOR_SHIFT)) || 1419 (mdac->area.start <= lvm_getpagesize() && 1420 pv->pe_start < (lvm_getpagesize() >> SECTOR_SHIFT))) && 1421 (mdac->area.start + mdac->area.size > 1422 (pv->pe_start << SECTOR_SHIFT))) { 1423 pv->pe_start = (mdac->area.start + mdac->area.size) 1424 >> SECTOR_SHIFT; 1425 /* Adjust pe_start to: (N * pe_align) + pe_align_offset */ 1426 if (pv->pe_align) { 1427 adjustment = 1428 (pv->pe_start - pv->pe_align_offset) % pv->pe_align; 1429 if (adjustment) 1430 pv->pe_start += pv->pe_align - adjustment; 1431 1432 log_very_verbose("%s: setting pe_start=%" PRIu64 1433 " (orig_pe_start=%" PRIu64 ", " 1434 "pe_align=%lu, pe_align_offset=%lu, " 1435 "adjustment=%" PRIu64 ")", 1436 pv_dev_name(pv), pv->pe_start, 1437 (adjustment ? 1438 pv->pe_start -= pv->pe_align - adjustment : 1439 pv->pe_start), 1440 pv->pe_align, pv->pe_align_offset, adjustment); 1441 } 1442 } 1443 } 1444 if (pv->pe_start >= pv->size) { 1445 log_error("Data area is beyond end of device %s!", 1446 pv_dev_name(pv)); 1447 return 0; 1448 } 1449 1450 /* FIXME: preserve_pe_start: */ 1451 if (!add_da 1452 (NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0))) 1453 return_0; 1454 1455 if (!dev_open(pv->dev)) 1456 return_0; 1457 1458 dm_list_iterate_items(mda, &info->mdas) { 1459 mdac = mda->metadata_locn; 1460 memset(&buf, 0, sizeof(buf)); 1461 mdah->size = mdac->area.size; 1462 if (!_raw_write_mda_header(fmt, mdac->area.dev, 1463 mdac->area.start, mdah)) { 1464 if (!dev_close(pv->dev)) 1465 stack; 1466 return_0; 1467 } 1468 } 1469 1470 if (!label_write(pv->dev, label)) { 1471 dev_close(pv->dev); 1472 return_0; 1473 } 1474 1475 if (!dev_close(pv->dev)) 1476 return_0; 1477 1478 return 1; 1479 } 1480 1481 static int _add_raw(struct dm_list *raw_list, struct device_area *dev_area) 1482 { 1483 struct raw_list *rl; 1484 1485 /* Already present? */ 1486 dm_list_iterate_items(rl, raw_list) { 1487 /* FIXME Check size/overlap consistency too */ 1488 if (rl->dev_area.dev == dev_area->dev && 1489 rl->dev_area.start == dev_area->start) 1490 return 1; 1491 } 1492 1493 if (!(rl = dm_malloc(sizeof(struct raw_list)))) { 1494 log_error("_add_raw allocation failed"); 1495 return 0; 1496 } 1497 memcpy(&rl->dev_area, dev_area, sizeof(*dev_area)); 1498 dm_list_add(raw_list, &rl->list); 1499 1500 return 1; 1501 } 1502 1503 static int _get_pv_if_in_vg(struct lvmcache_info *info, 1504 struct physical_volume *pv) 1505 { 1506 if (info->vginfo && info->vginfo->vgname && 1507 !is_orphan_vg(info->vginfo->vgname) && 1508 get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname, 1509 info->vginfo->vgid, info->dev->pvid, pv)) 1510 return 1; 1511 1512 return 0; 1513 } 1514 1515 static int _populate_pv_fields(struct lvmcache_info *info, 1516 struct physical_volume *pv, 1517 int scan_label_only) 1518 { 1519 struct data_area_list *da; 1520 1521 /* Have we already cached vgname? */ 1522 if (!scan_label_only && _get_pv_if_in_vg(info, pv)) 1523 return 1; 1524 1525 /* Perform full scan (just the first time) and try again */ 1526 if (!scan_label_only && !memlock() && !full_scan_done()) { 1527 lvmcache_label_scan(info->fmt->cmd, 2); 1528 1529 if (_get_pv_if_in_vg(info, pv)) 1530 return 1; 1531 } 1532 1533 /* Orphan */ 1534 pv->dev = info->dev; 1535 pv->fmt = info->fmt; 1536 pv->size = info->device_size >> SECTOR_SHIFT; 1537 pv->vg_name = FMT_TEXT_ORPHAN_VG_NAME; 1538 memcpy(&pv->id, &info->dev->pvid, sizeof(pv->id)); 1539 1540 /* Currently only support exactly one data area */ 1541 if (dm_list_size(&info->das) != 1) { 1542 log_error("Must be exactly one data area (found %d) on PV %s", 1543 dm_list_size(&info->das), dev_name(info->dev)); 1544 return 0; 1545 } 1546 1547 dm_list_iterate_items(da, &info->das) 1548 pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT; 1549 1550 return 1; 1551 } 1552 1553 static int _text_pv_read(const struct format_type *fmt, const char *pv_name, 1554 struct physical_volume *pv, struct dm_list *mdas, 1555 int scan_label_only) 1556 { 1557 struct label *label; 1558 struct device *dev; 1559 struct lvmcache_info *info; 1560 struct metadata_area *mda, *mda_new; 1561 struct mda_context *mdac, *mdac_new; 1562 1563 if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) 1564 return_0; 1565 1566 if (!(label_read(dev, &label, UINT64_C(0)))) 1567 return_0; 1568 info = (struct lvmcache_info *) label->info; 1569 1570 if (!_populate_pv_fields(info, pv, scan_label_only)) 1571 return 0; 1572 1573 if (!mdas) 1574 return 1; 1575 1576 /* Add copy of mdas to supplied list */ 1577 dm_list_iterate_items(mda, &info->mdas) { 1578 mdac = (struct mda_context *) mda->metadata_locn; 1579 if (!(mda_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda_new)))) { 1580 log_error("metadata_area allocation failed"); 1581 return 0; 1582 } 1583 if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac_new)))) { 1584 log_error("metadata_area allocation failed"); 1585 return 0; 1586 } 1587 memcpy(mda_new, mda, sizeof(*mda)); 1588 memcpy(mdac_new, mdac, sizeof(*mdac)); 1589 mda_new->metadata_locn = mdac_new; 1590 dm_list_add(mdas, &mda_new->list); 1591 } 1592 1593 return 1; 1594 } 1595 1596 static void _text_destroy_instance(struct format_instance *fid __attribute((unused))) 1597 { 1598 return; 1599 } 1600 1601 static void _free_dirs(struct dm_list *dir_list) 1602 { 1603 struct dm_list *dl, *tmp; 1604 1605 dm_list_iterate_safe(dl, tmp, dir_list) { 1606 dm_list_del(dl); 1607 dm_free(dl); 1608 } 1609 } 1610 1611 static void _free_raws(struct dm_list *raw_list) 1612 { 1613 struct dm_list *rl, *tmp; 1614 1615 dm_list_iterate_safe(rl, tmp, raw_list) { 1616 dm_list_del(rl); 1617 dm_free(rl); 1618 } 1619 } 1620 1621 static void _text_destroy(const struct format_type *fmt) 1622 { 1623 if (fmt->private) { 1624 _free_dirs(&((struct mda_lists *) fmt->private)->dirs); 1625 _free_raws(&((struct mda_lists *) fmt->private)->raws); 1626 dm_free(fmt->private); 1627 } 1628 1629 dm_free((void *)fmt); 1630 } 1631 1632 static struct metadata_area_ops _metadata_text_file_ops = { 1633 .vg_read = _vg_read_file, 1634 .vg_read_precommit = _vg_read_precommit_file, 1635 .vg_write = _vg_write_file, 1636 .vg_remove = _vg_remove_file, 1637 .vg_commit = _vg_commit_file 1638 }; 1639 1640 static struct metadata_area_ops _metadata_text_file_backup_ops = { 1641 .vg_read = _vg_read_file, 1642 .vg_write = _vg_write_file, 1643 .vg_remove = _vg_remove_file, 1644 .vg_commit = _vg_commit_file_backup 1645 }; 1646 1647 static struct metadata_area_ops _metadata_text_raw_ops = { 1648 .vg_read = _vg_read_raw, 1649 .vg_read_precommit = _vg_read_precommit_raw, 1650 .vg_write = _vg_write_raw, 1651 .vg_remove = _vg_remove_raw, 1652 .vg_precommit = _vg_precommit_raw, 1653 .vg_commit = _vg_commit_raw, 1654 .vg_revert = _vg_revert_raw, 1655 .mda_free_sectors = _mda_free_sectors_raw, 1656 .mda_total_sectors = _mda_total_sectors_raw, 1657 .mda_in_vg = _mda_in_vg_raw, 1658 .pv_analyze_mda = _pv_analyze_mda_raw, 1659 }; 1660 1661 /* pvmetadatasize in sectors */ 1662 /* 1663 * pe_start goal: FIXME -- reality of .pv_write complexity undermines this goal 1664 * - In cases where a pre-existing pe_start is provided (pvcreate --restorefile 1665 * and vgconvert): pe_start must not be changed (so pv->pe_start = pe_start). 1666 * - In cases where pe_start is 0: leave pv->pe_start as 0 and defer the 1667 * setting of pv->pe_start to .pv_write 1668 */ 1669 static int _text_pv_setup(const struct format_type *fmt, 1670 uint64_t pe_start, uint32_t extent_count, 1671 uint32_t extent_size, unsigned long data_alignment, 1672 unsigned long data_alignment_offset, 1673 int pvmetadatacopies, 1674 uint64_t pvmetadatasize, struct dm_list *mdas, 1675 struct physical_volume *pv, struct volume_group *vg) 1676 { 1677 struct metadata_area *mda, *mda_new, *mda2; 1678 struct mda_context *mdac, *mdac_new, *mdac2; 1679 struct dm_list *pvmdas; 1680 struct lvmcache_info *info; 1681 int found; 1682 uint64_t pe_end = 0; 1683 unsigned mda_count = 0; 1684 uint64_t mda_size2 = 0; 1685 uint64_t pe_count; 1686 1687 /* FIXME Cope with pvchange */ 1688 /* FIXME Merge code with _text_create_text_instance */ 1689 1690 /* If new vg, add any further mdas on this PV to the fid's mda list */ 1691 if (vg) { 1692 /* Iterate through all mdas on this PV */ 1693 if ((info = info_from_pvid(pv->dev->pvid, 0))) { 1694 pvmdas = &info->mdas; 1695 dm_list_iterate_items(mda, pvmdas) { 1696 mda_count++; 1697 mdac = 1698 (struct mda_context *) mda->metadata_locn; 1699 1700 /* FIXME Check it isn't already in use */ 1701 1702 /* Reduce usable device size */ 1703 if (mda_count > 1) 1704 mda_size2 = mdac->area.size >> SECTOR_SHIFT; 1705 1706 /* Ensure it isn't already on list */ 1707 found = 0; 1708 dm_list_iterate_items(mda2, mdas) { 1709 if (mda2->ops != 1710 &_metadata_text_raw_ops) continue; 1711 mdac2 = 1712 (struct mda_context *) 1713 mda2->metadata_locn; 1714 if (!memcmp 1715 (&mdac2->area, &mdac->area, 1716 sizeof(mdac->area))) { 1717 found = 1; 1718 break; 1719 } 1720 } 1721 if (found) 1722 continue; 1723 1724 if (!(mda_new = dm_pool_alloc(fmt->cmd->mem, 1725 sizeof(*mda_new)))) 1726 return_0; 1727 1728 if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem, 1729 sizeof(*mdac_new)))) 1730 return_0; 1731 /* FIXME multiple dev_areas inside area */ 1732 memcpy(mda_new, mda, sizeof(*mda)); 1733 memcpy(mdac_new, mdac, sizeof(*mdac)); 1734 mda_new->metadata_locn = mdac_new; 1735 dm_list_add(mdas, &mda_new->list); 1736 } 1737 } 1738 1739 /* FIXME Cope with genuine pe_count 0 */ 1740 1741 /* If missing, estimate pv->size from file-based metadata */ 1742 if (!pv->size && pv->pe_count) 1743 pv->size = pv->pe_count * (uint64_t) vg->extent_size + 1744 pv->pe_start + mda_size2; 1745 1746 /* Recalculate number of extents that will fit */ 1747 if (!pv->pe_count) { 1748 pe_count = (pv->size - pv->pe_start - mda_size2) / 1749 vg->extent_size; 1750 if (pe_count > UINT32_MAX) { 1751 log_error("PV %s too large for extent size %s.", 1752 pv_dev_name(pv), 1753 display_size(vg->cmd, (uint64_t) vg->extent_size)); 1754 return 0; 1755 } 1756 pv->pe_count = (uint32_t) pe_count; 1757 } 1758 1759 /* Unlike LVM1, we don't store this outside a VG */ 1760 /* FIXME Default from config file? vgextend cmdline flag? */ 1761 pv->status |= ALLOCATABLE_PV; 1762 } else { 1763 if (pe_start) 1764 pv->pe_start = pe_start; 1765 1766 if (!data_alignment) 1767 data_alignment = find_config_tree_int(pv->fmt->cmd, 1768 "devices/data_alignment", 1769 0) * 2; 1770 1771 if (set_pe_align(pv, data_alignment) != data_alignment && 1772 data_alignment) 1773 log_warn("WARNING: %s: Overriding data alignment to " 1774 "%lu sectors (requested %lu sectors)", 1775 pv_dev_name(pv), pv->pe_align, data_alignment); 1776 1777 if (set_pe_align_offset(pv, data_alignment_offset) != data_alignment_offset && 1778 data_alignment_offset) 1779 log_warn("WARNING: %s: Overriding data alignment offset to " 1780 "%lu sectors (requested %lu sectors)", 1781 pv_dev_name(pv), pv->pe_align_offset, data_alignment_offset); 1782 1783 if (pv->pe_align < pv->pe_align_offset) { 1784 log_error("%s: pe_align (%lu sectors) must not be less " 1785 "than pe_align_offset (%lu sectors)", 1786 pv_dev_name(pv), pv->pe_align, pv->pe_align_offset); 1787 return 0; 1788 } 1789 1790 /* 1791 * This initialization has a side-effect of allowing 1792 * orphaned PVs to be created with the proper alignment. 1793 * Setting pv->pe_start here circumvents .pv_write's 1794 * "pvcreate on PV without prior pvremove" retreival of 1795 * the PV's previous pe_start. 1796 * - Without this you get actual != expected pe_start 1797 * failures in the testsuite. 1798 */ 1799 if (!pe_start && pv->pe_start < pv->pe_align) 1800 pv->pe_start = pv->pe_align; 1801 1802 if (extent_count) 1803 pe_end = pe_start + extent_count * extent_size - 1; 1804 if (!_mda_setup(fmt, pe_start, pe_end, pvmetadatacopies, 1805 pvmetadatasize, mdas, pv, vg)) 1806 return_0; 1807 } 1808 1809 return 1; 1810 } 1811 1812 /* NULL vgname means use only the supplied context e.g. an archive file */ 1813 static struct format_instance *_text_create_text_instance(const struct format_type 1814 *fmt, const char *vgname, 1815 const char *vgid, 1816 void *context) 1817 { 1818 struct format_instance *fid; 1819 struct text_fid_context *fidtc; 1820 struct metadata_area *mda, *mda_new; 1821 struct mda_context *mdac, *mdac_new; 1822 struct dir_list *dl; 1823 struct raw_list *rl; 1824 struct dm_list *dir_list, *raw_list, *mdas; 1825 char path[PATH_MAX]; 1826 struct lvmcache_vginfo *vginfo; 1827 struct lvmcache_info *info; 1828 1829 if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) { 1830 log_error("Couldn't allocate format instance object."); 1831 return NULL; 1832 } 1833 1834 if (!(fidtc = (struct text_fid_context *) 1835 dm_pool_zalloc(fmt->cmd->mem,sizeof(*fidtc)))) { 1836 log_error("Couldn't allocate text_fid_context."); 1837 return NULL; 1838 } 1839 1840 fidtc->raw_metadata_buf = NULL; 1841 fid->private = (void *) fidtc; 1842 1843 fid->fmt = fmt; 1844 dm_list_init(&fid->metadata_areas); 1845 1846 if (!vgname) { 1847 if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) 1848 return_NULL; 1849 mda->ops = &_metadata_text_file_backup_ops; 1850 mda->metadata_locn = context; 1851 dm_list_add(&fid->metadata_areas, &mda->list); 1852 } else { 1853 dir_list = &((struct mda_lists *) fmt->private)->dirs; 1854 1855 dm_list_iterate_items(dl, dir_list) { 1856 if (dm_snprintf(path, PATH_MAX, "%s/%s", 1857 dl->dir, vgname) < 0) { 1858 log_error("Name too long %s/%s", dl->dir, 1859 vgname); 1860 return NULL; 1861 } 1862 1863 context = create_text_context(fmt->cmd, path, NULL); 1864 if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) 1865 return_NULL; 1866 mda->ops = &_metadata_text_file_ops; 1867 mda->metadata_locn = context; 1868 dm_list_add(&fid->metadata_areas, &mda->list); 1869 } 1870 1871 raw_list = &((struct mda_lists *) fmt->private)->raws; 1872 1873 dm_list_iterate_items(rl, raw_list) { 1874 /* FIXME Cache this; rescan below if some missing */ 1875 if (!_raw_holds_vgname(fid, &rl->dev_area, vgname)) 1876 continue; 1877 1878 if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) 1879 return_NULL; 1880 1881 if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) 1882 return_NULL; 1883 mda->metadata_locn = mdac; 1884 /* FIXME Allow multiple dev_areas inside area */ 1885 memcpy(&mdac->area, &rl->dev_area, sizeof(mdac->area)); 1886 mda->ops = &_metadata_text_raw_ops; 1887 /* FIXME MISTAKE? mda->metadata_locn = context; */ 1888 dm_list_add(&fid->metadata_areas, &mda->list); 1889 } 1890 1891 /* Scan PVs in VG for any further MDAs */ 1892 lvmcache_label_scan(fmt->cmd, 0); 1893 if (!(vginfo = vginfo_from_vgname(vgname, vgid))) 1894 goto_out; 1895 dm_list_iterate_items(info, &vginfo->infos) { 1896 mdas = &info->mdas; 1897 dm_list_iterate_items(mda, mdas) { 1898 mdac = 1899 (struct mda_context *) mda->metadata_locn; 1900 1901 /* FIXME Check it holds this VG */ 1902 if (!(mda_new = dm_pool_alloc(fmt->cmd->mem, 1903 sizeof(*mda_new)))) 1904 return_NULL; 1905 1906 if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem, 1907 sizeof(*mdac_new)))) 1908 return_NULL; 1909 /* FIXME multiple dev_areas inside area */ 1910 memcpy(mda_new, mda, sizeof(*mda)); 1911 memcpy(mdac_new, mdac, sizeof(*mdac)); 1912 mda_new->metadata_locn = mdac_new; 1913 dm_list_add(&fid->metadata_areas, &mda_new->list); 1914 } 1915 } 1916 /* FIXME Check raw metadata area count - rescan if required */ 1917 } 1918 1919 out: 1920 return fid; 1921 } 1922 1923 void *create_text_context(struct cmd_context *cmd, const char *path, 1924 const char *desc) 1925 { 1926 struct text_context *tc; 1927 char *tmp; 1928 1929 if ((tmp = strstr(path, ".tmp")) && (tmp == path + strlen(path) - 4)) { 1930 log_error("%s: Volume group filename may not end in .tmp", 1931 path); 1932 return NULL; 1933 } 1934 1935 if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc)))) 1936 return_NULL; 1937 1938 if (!(tc->path_live = dm_pool_strdup(cmd->mem, path))) 1939 goto_bad; 1940 1941 if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5))) 1942 goto_bad; 1943 1944 sprintf(tc->path_edit, "%s.tmp", path); 1945 1946 if (!desc) 1947 desc = ""; 1948 1949 if (!(tc->desc = dm_pool_strdup(cmd->mem, desc))) 1950 goto_bad; 1951 1952 return (void *) tc; 1953 1954 bad: 1955 dm_pool_free(cmd->mem, tc); 1956 1957 log_error("Couldn't allocate text format context object."); 1958 return NULL; 1959 } 1960 1961 static struct format_handler _text_handler = { 1962 .scan = _text_scan, 1963 .pv_read = _text_pv_read, 1964 .pv_setup = _text_pv_setup, 1965 .pv_write = _text_pv_write, 1966 .vg_setup = _text_vg_setup, 1967 .lv_setup = _text_lv_setup, 1968 .create_instance = _text_create_text_instance, 1969 .destroy_instance = _text_destroy_instance, 1970 .destroy = _text_destroy 1971 }; 1972 1973 static int _add_dir(const char *dir, struct dm_list *dir_list) 1974 { 1975 struct dir_list *dl; 1976 1977 if (dm_create_dir(dir)) { 1978 if (!(dl = dm_malloc(sizeof(struct dm_list) + strlen(dir) + 1))) { 1979 log_error("_add_dir allocation failed"); 1980 return 0; 1981 } 1982 log_very_verbose("Adding text format metadata dir: %s", dir); 1983 strcpy(dl->dir, dir); 1984 dm_list_add(dir_list, &dl->list); 1985 return 1; 1986 } 1987 1988 return 0; 1989 } 1990 1991 static int _get_config_disk_area(struct cmd_context *cmd, 1992 struct config_node *cn, struct dm_list *raw_list) 1993 { 1994 struct device_area dev_area; 1995 char *id_str; 1996 struct id id; 1997 1998 if (!(cn = cn->child)) { 1999 log_error("Empty metadata disk_area section of config file"); 2000 return 0; 2001 } 2002 2003 if (!get_config_uint64(cn, "start_sector", &dev_area.start)) { 2004 log_error("Missing start_sector in metadata disk_area section " 2005 "of config file"); 2006 return 0; 2007 } 2008 dev_area.start <<= SECTOR_SHIFT; 2009 2010 if (!get_config_uint64(cn, "size", &dev_area.size)) { 2011 log_error("Missing size in metadata disk_area section " 2012 "of config file"); 2013 return 0; 2014 } 2015 dev_area.size <<= SECTOR_SHIFT; 2016 2017 if (!get_config_str(cn, "id", &id_str)) { 2018 log_error("Missing uuid in metadata disk_area section " 2019 "of config file"); 2020 return 0; 2021 } 2022 2023 if (!id_read_format(&id, id_str)) { 2024 log_error("Invalid uuid in metadata disk_area section " 2025 "of config file: %s", id_str); 2026 return 0; 2027 } 2028 2029 if (!(dev_area.dev = device_from_pvid(cmd, &id))) { 2030 char buffer[64] __attribute((aligned(8))); 2031 2032 if (!id_write_format(&id, buffer, sizeof(buffer))) 2033 log_error("Couldn't find device."); 2034 else 2035 log_error("Couldn't find device with uuid '%s'.", 2036 buffer); 2037 2038 return 0; 2039 } 2040 2041 return _add_raw(raw_list, &dev_area); 2042 } 2043 2044 struct format_type *create_text_format(struct cmd_context *cmd) 2045 { 2046 struct format_type *fmt; 2047 struct config_node *cn; 2048 struct config_value *cv; 2049 struct mda_lists *mda_lists; 2050 2051 if (!(fmt = dm_malloc(sizeof(*fmt)))) 2052 return_NULL; 2053 2054 fmt->cmd = cmd; 2055 fmt->ops = &_text_handler; 2056 fmt->name = FMT_TEXT_NAME; 2057 fmt->alias = FMT_TEXT_ALIAS; 2058 fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME); 2059 fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT | 2060 FMT_UNLIMITED_VOLS | FMT_RESIZE_PV | 2061 FMT_UNLIMITED_STRIPESIZE; 2062 2063 if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) { 2064 log_error("Failed to allocate dir_list"); 2065 dm_free(fmt); 2066 return NULL; 2067 } 2068 2069 dm_list_init(&mda_lists->dirs); 2070 dm_list_init(&mda_lists->raws); 2071 mda_lists->file_ops = &_metadata_text_file_ops; 2072 mda_lists->raw_ops = &_metadata_text_raw_ops; 2073 fmt->private = (void *) mda_lists; 2074 2075 if (!(fmt->labeller = text_labeller_create(fmt))) { 2076 log_error("Couldn't create text label handler."); 2077 dm_free(fmt); 2078 return NULL; 2079 } 2080 2081 if (!(label_register_handler(FMT_TEXT_NAME, fmt->labeller))) { 2082 log_error("Couldn't register text label handler."); 2083 dm_free(fmt); 2084 return NULL; 2085 } 2086 2087 if ((cn = find_config_tree_node(cmd, "metadata/dirs"))) { 2088 for (cv = cn->v; cv; cv = cv->next) { 2089 if (cv->type != CFG_STRING) { 2090 log_error("Invalid string in config file: " 2091 "metadata/dirs"); 2092 goto err; 2093 } 2094 2095 if (!_add_dir(cv->v.str, &mda_lists->dirs)) { 2096 log_error("Failed to add %s to text format " 2097 "metadata directory list ", cv->v.str); 2098 goto err; 2099 } 2100 } 2101 } 2102 2103 if ((cn = find_config_tree_node(cmd, "metadata/disk_areas"))) { 2104 for (cn = cn->child; cn; cn = cn->sib) { 2105 if (!_get_config_disk_area(cmd, cn, &mda_lists->raws)) 2106 goto err; 2107 } 2108 } 2109 2110 log_very_verbose("Initialised format: %s", fmt->name); 2111 2112 return fmt; 2113 2114 err: 2115 _free_dirs(&mda_lists->dirs); 2116 2117 dm_free(fmt); 2118 return NULL; 2119 } 2120