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