1 /*	$NetBSD: import_vsn1.c,v 1.1.1.2 2009/12/02 00:26:30 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 "metadata.h"
20 #include "import-export.h"
21 #include "display.h"
22 #include "toolcontext.h"
23 #include "lvmcache.h"
24 #include "lv_alloc.h"
25 #include "pv_alloc.h"
26 #include "segtype.h"
27 #include "text_import.h"
28 
29 typedef int (*section_fn) (struct format_instance * fid, struct dm_pool * mem,
30 			   struct volume_group * vg, struct config_node * pvn,
31 			   struct config_node * vgn,
32 			   struct dm_hash_table * pv_hash);
33 
34 #define _read_int32(root, path, result) \
35 	get_config_uint32(root, path, (uint32_t *) result)
36 
37 #define _read_uint32(root, path, result) \
38 	get_config_uint32(root, path, result)
39 
40 #define _read_int64(root, path, result) \
41 	get_config_uint64(root, path, result)
42 
43 /*
44  * Logs an attempt to read an invalid format file.
45  */
46 static void _invalid_format(const char *str)
47 {
48 	log_error("Can't process text format file - %s.", str);
49 }
50 
51 /*
52  * Checks that the config file contains vg metadata, and that it
53  * we recognise the version number,
54  */
55 static int _check_version(struct config_tree *cft)
56 {
57 	struct config_node *cn;
58 	struct config_value *cv;
59 
60 	/*
61 	 * Check the contents field.
62 	 */
63 	if (!(cn = find_config_node(cft->root, CONTENTS_FIELD))) {
64 		_invalid_format("missing contents field");
65 		return 0;
66 	}
67 
68 	cv = cn->v;
69 	if (!cv || cv->type != CFG_STRING || strcmp(cv->v.str, CONTENTS_VALUE)) {
70 		_invalid_format("unrecognised contents field");
71 		return 0;
72 	}
73 
74 	/*
75 	 * Check the version number.
76 	 */
77 	if (!(cn = find_config_node(cft->root, FORMAT_VERSION_FIELD))) {
78 		_invalid_format("missing version number");
79 		return 0;
80 	}
81 
82 	cv = cn->v;
83 	if (!cv || cv->type != CFG_INT || cv->v.i != FORMAT_VERSION_VALUE) {
84 		_invalid_format("unrecognised version number");
85 		return 0;
86 	}
87 
88 	return 1;
89 }
90 
91 static int _is_converting(struct logical_volume *lv)
92 {
93 	struct lv_segment *seg;
94 
95 	if (lv->status & MIRRORED) {
96 		seg = first_seg(lv);
97 		/* Can't use is_temporary_mirror() because the metadata for
98 		 * seg_lv may not be read in and flags may not be set yet. */
99 		if (seg_type(seg, 0) == AREA_LV &&
100 		    strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER))
101 			return 1;
102 	}
103 
104 	return 0;
105 }
106 
107 static int _read_id(struct id *id, struct config_node *cn, const char *path)
108 {
109 	struct config_value *cv;
110 
111 	if (!(cn = find_config_node(cn, path))) {
112 		log_error("Couldn't find uuid.");
113 		return 0;
114 	}
115 
116 	cv = cn->v;
117 	if (!cv || !cv->v.str) {
118 		log_error("uuid must be a string.");
119 		return 0;
120 	}
121 
122 	if (!id_read_format(id, cv->v.str)) {
123 		log_error("Invalid uuid.");
124 		return 0;
125 	}
126 
127 	return 1;
128 }
129 
130 static int _read_flag_config(struct config_node *n, uint32_t *status, int type)
131 {
132 	struct config_node *cn;
133 	*status = 0;
134 
135 	if (!(cn = find_config_node(n, "status"))) {
136 		log_error("Could not find status flags.");
137 		return 0;
138 	}
139 
140 	if (!(read_flags(status, type | STATUS_FLAG, cn->v))) {
141 		log_error("Could not read status flags.");
142 		return 0;
143 	}
144 
145 	if ((cn = find_config_node(n, "flags"))) {
146 		if (!(read_flags(status, type, cn->v))) {
147 			log_error("Could not read flags.");
148 			return 0;
149 		}
150 	}
151 
152 	return 1;
153 }
154 
155 static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
156 		    struct volume_group *vg, struct config_node *pvn,
157 		    struct config_node *vgn __attribute((unused)),
158 		    struct dm_hash_table *pv_hash)
159 {
160 	struct physical_volume *pv;
161 	struct pv_list *pvl;
162 	struct config_node *cn;
163 	uint64_t size;
164 
165 	if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
166 	    !(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv))))
167 		return_0;
168 
169 	pv = pvl->pv;
170 
171 	/*
172 	 * Add the pv to the pv hash for quick lookup when we read
173 	 * the lv segments.
174 	 */
175 	if (!dm_hash_insert(pv_hash, pvn->key, pv))
176 		return_0;
177 
178 	if (!(pvn = pvn->child)) {
179 		log_error("Empty pv section.");
180 		return 0;
181 	}
182 
183 	if (!_read_id(&pv->id, pvn, "id")) {
184 		log_error("Couldn't read uuid for physical volume.");
185 		return 0;
186 	}
187 
188 	/*
189 	 * Convert the uuid into a device.
190 	 */
191 	if (!(pv->dev = device_from_pvid(fid->fmt->cmd, &pv->id))) {
192 		char buffer[64] __attribute((aligned(8)));
193 
194 		if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
195 			log_error("Couldn't find device.");
196 		else
197 			log_error("Couldn't find device with uuid '%s'.",
198 				  buffer);
199 	}
200 
201 	if (!(pv->vg_name = dm_pool_strdup(mem, vg->name)))
202 		return_0;
203 
204 	memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
205 
206 	if (!_read_flag_config(pvn, &pv->status, PV_FLAGS)) {
207 		log_error("Couldn't read status flags for physical volume.");
208 		return 0;
209 	}
210 
211 	if (!pv->dev)
212 		pv->status |= MISSING_PV;
213 
214 	/* Late addition */
215 	_read_int64(pvn, "dev_size", &pv->size);
216 
217 	if (!_read_int64(pvn, "pe_start", &pv->pe_start)) {
218 		log_error("Couldn't read extent size for physical volume.");
219 		return 0;
220 	}
221 
222 	if (!_read_int32(pvn, "pe_count", &pv->pe_count)) {
223 		log_error("Couldn't find extent count (pe_count) for "
224 			  "physical volume.");
225 		return 0;
226 	}
227 
228 	dm_list_init(&pv->tags);
229 	dm_list_init(&pv->segments);
230 
231 	/* Optional tags */
232 	if ((cn = find_config_node(pvn, "tags")) &&
233 	    !(read_tags(mem, &pv->tags, cn->v))) {
234 		log_error("Couldn't read tags for physical volume %s in %s.",
235 			  pv_dev_name(pv), vg->name);
236 		return 0;
237 	}
238 
239 	/* adjust the volume group. */
240 	vg->extent_count += pv->pe_count;
241 	vg->free_count += pv->pe_count;
242 
243 	pv->pe_size = vg->extent_size;
244 
245 	pv->pe_alloc_count = 0;
246 	pv->pe_align = 0;
247 	pv->fmt = fid->fmt;
248 
249 	/* Fix up pv size if missing or impossibly large */
250 	if ((!pv->size || pv->size > (1ULL << 62)) && pv->dev) {
251 		if (!dev_get_size(pv->dev, &pv->size)) {
252 			log_error("%s: Couldn't get size.", pv_dev_name(pv));
253 			return 0;
254 		}
255 		log_verbose("Fixing up missing size (%s) "
256 			    "for PV %s", display_size(fid->fmt->cmd, pv->size),
257 			    pv_dev_name(pv));
258 		if (vg) {
259 			size = pv->pe_count * (uint64_t) vg->extent_size +
260 			       pv->pe_start;
261 			if (size > pv->size)
262 				log_error("WARNING: Physical Volume %s is too "
263 					  "large for underlying device",
264 					  pv_dev_name(pv));
265 		}
266 	}
267 
268 	if (!alloc_pv_segment_whole_pv(mem, pv))
269 		return_0;
270 
271 	vg->pv_count++;
272 	dm_list_add(&vg->pvs, &pvl->list);
273 
274 	return 1;
275 }
276 
277 static void _insert_segment(struct logical_volume *lv, struct lv_segment *seg)
278 {
279 	struct lv_segment *comp;
280 
281 	dm_list_iterate_items(comp, &lv->segments) {
282 		if (comp->le > seg->le) {
283 			dm_list_add(&comp->list, &seg->list);
284 			return;
285 		}
286 	}
287 
288 	lv->le_count += seg->len;
289 	dm_list_add(&lv->segments, &seg->list);
290 }
291 
292 static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
293 			 struct logical_volume *lv, struct config_node *sn,
294 			 struct dm_hash_table *pv_hash)
295 {
296 	uint32_t area_count = 0u;
297 	struct lv_segment *seg;
298 	struct config_node *cn, *sn_child = sn->child;
299 	struct config_value *cv;
300 	uint32_t start_extent, extent_count;
301 	struct segment_type *segtype;
302 	const char *segtype_str;
303 
304 	if (!sn_child) {
305 		log_error("Empty segment section.");
306 		return 0;
307 	}
308 
309 	if (!_read_int32(sn_child, "start_extent", &start_extent)) {
310 		log_error("Couldn't read 'start_extent' for segment '%s' "
311 			  "of logical volume %s.", sn->key, lv->name);
312 		return 0;
313 	}
314 
315 	if (!_read_int32(sn_child, "extent_count", &extent_count)) {
316 		log_error("Couldn't read 'extent_count' for segment '%s' "
317 			  "of logical volume %s.", sn->key, lv->name);
318 		return 0;
319 	}
320 
321 	segtype_str = "striped";
322 
323 	if ((cn = find_config_node(sn_child, "type"))) {
324 		cv = cn->v;
325 		if (!cv || !cv->v.str) {
326 			log_error("Segment type must be a string.");
327 			return 0;
328 		}
329 		segtype_str = cv->v.str;
330 	}
331 
332 	if (!(segtype = get_segtype_from_string(vg->cmd, segtype_str)))
333 		return_0;
334 
335 	if (segtype->ops->text_import_area_count &&
336 	    !segtype->ops->text_import_area_count(sn_child, &area_count))
337 		return_0;
338 
339 	if (!(seg = alloc_lv_segment(mem, segtype, lv, start_extent,
340 				     extent_count, 0, 0, NULL, area_count,
341 				     extent_count, 0, 0, 0))) {
342 		log_error("Segment allocation failed");
343 		return 0;
344 	}
345 
346 	if (seg->segtype->ops->text_import &&
347 	    !seg->segtype->ops->text_import(seg, sn_child, pv_hash))
348 		return_0;
349 
350 	/* Optional tags */
351 	if ((cn = find_config_node(sn_child, "tags")) &&
352 	    !(read_tags(mem, &seg->tags, cn->v))) {
353 		log_error("Couldn't read tags for a segment of %s/%s.",
354 			  vg->name, lv->name);
355 		return 0;
356 	}
357 
358 	/*
359 	 * Insert into correct part of segment list.
360 	 */
361 	_insert_segment(lv, seg);
362 
363 	if (seg_is_mirrored(seg))
364 		lv->status |= MIRRORED;
365 
366 	if (seg_is_virtual(seg))
367 		lv->status |= VIRTUAL;
368 
369 	if (_is_converting(lv))
370 		lv->status |= CONVERTING;
371 
372 	return 1;
373 }
374 
375 int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
376 		      const struct config_node *cn, struct dm_hash_table *pv_hash,
377 		      uint32_t flags)
378 {
379 	unsigned int s;
380 	struct config_value *cv;
381 	struct logical_volume *lv1;
382 	struct physical_volume *pv;
383 	const char *seg_name = config_parent_name(sn);
384 
385 	if (!seg->area_count) {
386 		log_error("Zero areas not allowed for segment %s", seg_name);
387 		return 0;
388 	}
389 
390 	for (cv = cn->v, s = 0; cv && s < seg->area_count; s++, cv = cv->next) {
391 
392 		/* first we read the pv */
393 		if (cv->type != CFG_STRING) {
394 			log_error("Bad volume name in areas array for segment %s.", seg_name);
395 			return 0;
396 		}
397 
398 		if (!cv->next) {
399 			log_error("Missing offset in areas array for segment %s.", seg_name);
400 			return 0;
401 		}
402 
403 		if (cv->next->type != CFG_INT) {
404 			log_error("Bad offset in areas array for segment %s.", seg_name);
405 			return 0;
406 		}
407 
408 		/* FIXME Cope if LV not yet read in */
409 		if ((pv = dm_hash_lookup(pv_hash, cv->v.str))) {
410 			if (!set_lv_segment_area_pv(seg, s, pv, (uint32_t) cv->next->v.i))
411 				return_0;
412 		} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
413 			if (!set_lv_segment_area_lv(seg, s, lv1,
414 						    (uint32_t) cv->next->v.i,
415 						    flags))
416 				return_0;
417 		} else {
418 			log_error("Couldn't find volume '%s' "
419 				  "for segment '%s'.",
420 				  cv->v.str ? : "NULL", seg_name);
421 			return 0;
422 		}
423 
424 		cv = cv->next;
425 	}
426 
427 	/*
428 	 * Check we read the correct number of stripes.
429 	 */
430 	if (cv || (s < seg->area_count)) {
431 		log_error("Incorrect number of areas in area array "
432 			  "for segment '%s'.", seg_name);
433 		return 0;
434 	}
435 
436 	return 1;
437 }
438 
439 static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
440 			  struct logical_volume *lv, struct config_node *lvn,
441 			  struct dm_hash_table *pv_hash)
442 {
443 	struct config_node *sn;
444 	int count = 0, seg_count;
445 
446 	for (sn = lvn; sn; sn = sn->sib) {
447 
448 		/*
449 		 * All sub-sections are assumed to be segments.
450 		 */
451 		if (!sn->v) {
452 			if (!_read_segment(mem, vg, lv, sn, pv_hash))
453 				return_0;
454 
455 			count++;
456 		}
457 		/* FIXME Remove this restriction */
458 		if ((lv->status & SNAPSHOT) && count > 1) {
459 			log_error("Only one segment permitted for snapshot");
460 			return 0;
461 		}
462 	}
463 
464 	if (!_read_int32(lvn, "segment_count", &seg_count)) {
465 		log_error("Couldn't read segment count for logical volume %s.",
466 			  lv->name);
467 		return 0;
468 	}
469 
470 	if (seg_count != count) {
471 		log_error("segment_count and actual number of segments "
472 			  "disagree for logical volume %s.", lv->name);
473 		return 0;
474 	}
475 
476 	/*
477 	 * Check there are no gaps or overlaps in the lv.
478 	 */
479 	if (!check_lv_segments(lv, 0))
480 		return_0;
481 
482 	/*
483 	 * Merge segments in case someones been editing things by hand.
484 	 */
485 	if (!lv_merge_segments(lv))
486 		return_0;
487 
488 	return 1;
489 }
490 
491 static int _read_lvnames(struct format_instance *fid __attribute((unused)),
492 			 struct dm_pool *mem,
493 			 struct volume_group *vg, struct config_node *lvn,
494 			 struct config_node *vgn __attribute((unused)),
495 			 struct dm_hash_table *pv_hash __attribute((unused)))
496 {
497 	struct logical_volume *lv;
498 	struct config_node *cn;
499 
500 	if (!(lv = alloc_lv(mem)))
501 		return_0;
502 
503 	if (!(lv->name = dm_pool_strdup(mem, lvn->key)))
504 		return_0;
505 
506 	if (!(lvn = lvn->child)) {
507 		log_error("Empty logical volume section.");
508 		return 0;
509 	}
510 
511 	if (!_read_flag_config(lvn, &lv->status, LV_FLAGS)) {
512 		log_error("Couldn't read status flags for logical volume %s.",
513 			  lv->name);
514 		return 0;
515 	}
516 
517 	lv->alloc = ALLOC_INHERIT;
518 	if ((cn = find_config_node(lvn, "allocation_policy"))) {
519 		struct config_value *cv = cn->v;
520 		if (!cv || !cv->v.str) {
521 			log_error("allocation_policy must be a string.");
522 			return 0;
523 		}
524 
525 		lv->alloc = get_alloc_from_string(cv->v.str);
526 		if (lv->alloc == ALLOC_INVALID)
527 			return_0;
528 	}
529 
530 	if (!_read_int32(lvn, "read_ahead", &lv->read_ahead))
531 		/* If not present, choice of auto or none is configurable */
532 		lv->read_ahead = vg->cmd->default_settings.read_ahead;
533 	else {
534 		switch (lv->read_ahead) {
535 		case 0:
536 			lv->read_ahead = DM_READ_AHEAD_AUTO;
537 			break;
538 		case (uint32_t) -1:
539 			lv->read_ahead = DM_READ_AHEAD_NONE;
540 			break;
541 		default:
542 			;
543 		}
544 	}
545 
546 	/* Optional tags */
547 	if ((cn = find_config_node(lvn, "tags")) &&
548 	    !(read_tags(mem, &lv->tags, cn->v))) {
549 		log_error("Couldn't read tags for logical volume %s/%s.",
550 			  vg->name, lv->name);
551 		return 0;
552 	}
553 
554 	return link_lv_to_vg(vg, lv);
555 }
556 
557 static int _read_lvsegs(struct format_instance *fid __attribute((unused)),
558 			struct dm_pool *mem,
559 			struct volume_group *vg, struct config_node *lvn,
560 			struct config_node *vgn __attribute((unused)),
561 			struct dm_hash_table *pv_hash)
562 {
563 	struct logical_volume *lv;
564 	struct lv_list *lvl;
565 
566 	if (!(lvl = find_lv_in_vg(vg, lvn->key))) {
567 		log_error("Lost logical volume reference %s", lvn->key);
568 		return 0;
569 	}
570 
571 	lv = lvl->lv;
572 
573 	if (!(lvn = lvn->child)) {
574 		log_error("Empty logical volume section.");
575 		return 0;
576 	}
577 
578 	/* FIXME: read full lvid */
579 	if (!_read_id(&lv->lvid.id[1], lvn, "id")) {
580 		log_error("Couldn't read uuid for logical volume %s.",
581 			  lv->name);
582 		return 0;
583 	}
584 
585 	memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
586 
587 	if (!_read_segments(mem, vg, lv, lvn, pv_hash))
588 		return_0;
589 
590 	lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
591 
592 	lv->minor = -1;
593 	if ((lv->status & FIXED_MINOR) &&
594 	    !_read_int32(lvn, "minor", &lv->minor)) {
595 		log_error("Couldn't read minor number for logical "
596 			  "volume %s.", lv->name);
597 		return 0;
598 	}
599 
600 	lv->major = -1;
601 	if ((lv->status & FIXED_MINOR) &&
602 	    !_read_int32(lvn, "major", &lv->major)) {
603 		log_error("Couldn't read major number for logical "
604 			  "volume %s.", lv->name);
605 	}
606 
607 	return 1;
608 }
609 
610 static int _read_sections(struct format_instance *fid,
611 			  const char *section, section_fn fn,
612 			  struct dm_pool *mem,
613 			  struct volume_group *vg, struct config_node *vgn,
614 			  struct dm_hash_table *pv_hash, int optional)
615 {
616 	struct config_node *n;
617 
618 	if (!(n = find_config_node(vgn, section))) {
619 		if (!optional) {
620 			log_error("Couldn't find section '%s'.", section);
621 			return 0;
622 		}
623 
624 		return 1;
625 	}
626 
627 	for (n = n->child; n; n = n->sib) {
628 		if (!fn(fid, mem, vg, n, vgn, pv_hash))
629 			return_0;
630 	}
631 
632 	return 1;
633 }
634 
635 static struct volume_group *_read_vg(struct format_instance *fid,
636 				     struct config_tree *cft)
637 {
638 	struct config_node *vgn, *cn;
639 	struct volume_group *vg;
640 	struct dm_hash_table *pv_hash = NULL;
641 	struct dm_pool *mem = dm_pool_create("lvm2 vg_read", VG_MEMPOOL_CHUNK);
642 
643 	if (!mem)
644 		return_NULL;
645 
646 	/* skip any top-level values */
647 	for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
648 
649 	if (!vgn) {
650 		log_error("Couldn't find volume group in file.");
651 		goto bad;
652 	}
653 
654 	if (!(vg = dm_pool_zalloc(mem, sizeof(*vg))))
655 		goto_bad;
656 
657 	vg->vgmem = mem;
658 	vg->cmd = fid->fmt->cmd;
659 
660 	/* FIXME Determine format type from file contents */
661 	/* eg Set to instance of fmt1 here if reading a format1 backup? */
662 	vg->fid = fid;
663 
664 	if (!(vg->name = dm_pool_strdup(mem, vgn->key)))
665 		goto_bad;
666 
667 	if (!(vg->system_id = dm_pool_zalloc(mem, NAME_LEN)))
668 		goto_bad;
669 
670 	vgn = vgn->child;
671 
672 	if ((cn = find_config_node(vgn, "system_id")) && cn->v) {
673 		if (!cn->v->v.str) {
674 			log_error("system_id must be a string");
675 			goto bad;
676 		}
677 		strncpy(vg->system_id, cn->v->v.str, NAME_LEN);
678 	}
679 
680 	if (!_read_id(&vg->id, vgn, "id")) {
681 		log_error("Couldn't read uuid for volume group %s.", vg->name);
682 		goto bad;
683 	}
684 
685 	if (!_read_int32(vgn, "seqno", &vg->seqno)) {
686 		log_error("Couldn't read 'seqno' for volume group %s.",
687 			  vg->name);
688 		goto bad;
689 	}
690 
691 	if (!_read_flag_config(vgn, &vg->status, VG_FLAGS)) {
692 		log_error("Error reading flags of volume group %s.",
693 			  vg->name);
694 		goto bad;
695 	}
696 
697 	if (!_read_int32(vgn, "extent_size", &vg->extent_size)) {
698 		log_error("Couldn't read extent size for volume group %s.",
699 			  vg->name);
700 		goto bad;
701 	}
702 
703 	/*
704 	 * 'extent_count' and 'free_count' get filled in
705 	 * implicitly when reading in the pv's and lv's.
706 	 */
707 
708 	if (!_read_int32(vgn, "max_lv", &vg->max_lv)) {
709 		log_error("Couldn't read 'max_lv' for volume group %s.",
710 			  vg->name);
711 		goto bad;
712 	}
713 
714 	if (!_read_int32(vgn, "max_pv", &vg->max_pv)) {
715 		log_error("Couldn't read 'max_pv' for volume group %s.",
716 			  vg->name);
717 		goto bad;
718 	}
719 
720 	vg->alloc = ALLOC_NORMAL;
721 	if ((cn = find_config_node(vgn, "allocation_policy"))) {
722 		struct config_value *cv = cn->v;
723 		if (!cv || !cv->v.str) {
724 			log_error("allocation_policy must be a string.");
725 			return 0;
726 		}
727 
728 		vg->alloc = get_alloc_from_string(cv->v.str);
729 		if (vg->alloc == ALLOC_INVALID)
730 			return_0;
731 	}
732 
733 	/*
734 	 * The pv hash memoises the pv section names -> pv
735 	 * structures.
736 	 */
737 	if (!(pv_hash = dm_hash_create(32))) {
738 		log_error("Couldn't create hash table.");
739 		goto bad;
740 	}
741 
742 	dm_list_init(&vg->pvs);
743 	if (!_read_sections(fid, "physical_volumes", _read_pv, mem, vg,
744 			    vgn, pv_hash, 0)) {
745 		log_error("Couldn't find all physical volumes for volume "
746 			  "group %s.", vg->name);
747 		goto bad;
748 	}
749 
750 	dm_list_init(&vg->lvs);
751 	dm_list_init(&vg->tags);
752 	dm_list_init(&vg->removed_pvs);
753 
754 	/* Optional tags */
755 	if ((cn = find_config_node(vgn, "tags")) &&
756 	    !(read_tags(mem, &vg->tags, cn->v))) {
757 		log_error("Couldn't read tags for volume group %s.", vg->name);
758 		goto bad;
759 	}
760 
761 	if (!_read_sections(fid, "logical_volumes", _read_lvnames, mem, vg,
762 			    vgn, pv_hash, 1)) {
763 		log_error("Couldn't read all logical volume names for volume "
764 			  "group %s.", vg->name);
765 		goto bad;
766 	}
767 
768 	if (!_read_sections(fid, "logical_volumes", _read_lvsegs, mem, vg,
769 			    vgn, pv_hash, 1)) {
770 		log_error("Couldn't read all logical volumes for "
771 			  "volume group %s.", vg->name);
772 		goto bad;
773 	}
774 
775 	if (!fixup_imported_mirrors(vg)) {
776 		log_error("Failed to fixup mirror pointers after import for "
777 			  "volume group %s.", vg->name);
778 		goto bad;
779 	}
780 
781 	dm_hash_destroy(pv_hash);
782 
783 	/*
784 	 * Finished.
785 	 */
786 	return vg;
787 
788       bad:
789 	if (pv_hash)
790 		dm_hash_destroy(pv_hash);
791 
792 	dm_pool_destroy(mem);
793 	return NULL;
794 }
795 
796 static void _read_desc(struct dm_pool *mem,
797 		       struct config_tree *cft, time_t *when, char **desc)
798 {
799 	const char *d;
800 	unsigned int u = 0u;
801 	int old_suppress;
802 
803 	old_suppress = log_suppress(1);
804 	d = find_config_str(cft->root, "description", "");
805 	log_suppress(old_suppress);
806 	*desc = dm_pool_strdup(mem, d);
807 
808 	get_config_uint32(cft->root, "creation_time", &u);
809 	*when = u;
810 }
811 
812 static const char *_read_vgname(const struct format_type *fmt,
813 				struct config_tree *cft, struct id *vgid,
814 				uint32_t *vgstatus, char **creation_host)
815 {
816 	struct config_node *vgn;
817 	struct dm_pool *mem = fmt->cmd->mem;
818 	char *vgname;
819 	int old_suppress;
820 
821 	old_suppress = log_suppress(2);
822 	*creation_host = dm_pool_strdup(mem,
823 					find_config_str(cft->root,
824 							"creation_host", ""));
825 	log_suppress(old_suppress);
826 
827 	/* skip any top-level values */
828 	for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
829 
830 	if (!vgn) {
831 		log_error("Couldn't find volume group in file.");
832 		return 0;
833 	}
834 
835 	if (!(vgname = dm_pool_strdup(mem, vgn->key)))
836 		return_0;
837 
838 	vgn = vgn->child;
839 
840 	if (!_read_id(vgid, vgn, "id")) {
841 		log_error("Couldn't read uuid for volume group %s.", vgname);
842 		return 0;
843 	}
844 
845 	if (!_read_flag_config(vgn, vgstatus, VG_FLAGS)) {
846 		log_error("Couldn't find status flags for volume group %s.",
847 			  vgname);
848 		return 0;
849 	}
850 
851 	return vgname;
852 }
853 
854 static struct text_vg_version_ops _vsn1_ops = {
855 	.check_version = _check_version,
856 	.read_vg = _read_vg,
857 	.read_desc = _read_desc,
858 	.read_vgname = _read_vgname,
859 };
860 
861 struct text_vg_version_ops *text_vg_vsn1_init(void)
862 {
863 	return &_vsn1_ops;
864 }
865