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