xref: /netbsd-src/external/gpl2/lvm2/dist/lib/cache/lvmcache.c (revision 274254cdae52594c1aa480a736aef78313d15c9c)
1 /*	$NetBSD: lvmcache.c,v 1.1.1.2 2009/02/18 11:16:52 haad Exp $	*/
2 
3 /*
4  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5  * Copyright (C) 2004-2008 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 "lvmcache.h"
20 #include "toolcontext.h"
21 #include "dev-cache.h"
22 #include "locking.h"
23 #include "metadata.h"
24 #include "filter.h"
25 #include "memlock.h"
26 #include "str_list.h"
27 #include "format-text.h"
28 #include "format_pool.h"
29 #include "format1.h"
30 
31 static struct dm_hash_table *_pvid_hash = NULL;
32 static struct dm_hash_table *_vgid_hash = NULL;
33 static struct dm_hash_table *_vgname_hash = NULL;
34 static struct dm_hash_table *_lock_hash = NULL;
35 static struct dm_list _vginfos;
36 static int _scanning_in_progress = 0;
37 static int _has_scanned = 0;
38 static int _vgs_locked = 0;
39 static int _vg_global_lock_held = 0;	/* Global lock held when cache wiped? */
40 
41 int lvmcache_init(void)
42 {
43 	dm_list_init(&_vginfos);
44 
45 	if (!(_vgname_hash = dm_hash_create(128)))
46 		return 0;
47 
48 	if (!(_vgid_hash = dm_hash_create(128)))
49 		return 0;
50 
51 	if (!(_pvid_hash = dm_hash_create(128)))
52 		return 0;
53 
54 	if (!(_lock_hash = dm_hash_create(128)))
55 		return 0;
56 
57 	if (_vg_global_lock_held)
58 		lvmcache_lock_vgname(VG_GLOBAL, 0);
59 
60 	return 1;
61 }
62 
63 /* Volume Group metadata cache functions */
64 static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
65 {
66 	if (!vginfo || !vginfo->vgmetadata)
67 		return;
68 
69 	dm_free(vginfo->vgmetadata);
70 
71 	vginfo->vgmetadata = NULL;
72 
73 	log_debug("Metadata cache: VG %s wiped.", vginfo->vgname);
74 }
75 
76 static void _store_metadata(struct lvmcache_vginfo *vginfo,
77 			    struct volume_group *vg, unsigned precommitted)
78 {
79 	int size;
80 
81 	if (vginfo->vgmetadata)
82 		_free_cached_vgmetadata(vginfo);
83 
84 	if (!(size = export_vg_to_buffer(vg, &vginfo->vgmetadata))) {
85 		stack;
86 		return;
87 	}
88 
89 	vginfo->precommitted = precommitted;
90 
91 	log_debug("Metadata cache: VG %s stored (%d bytes%s).", vginfo->vgname,
92 		  size, precommitted ? ", precommitted" : "");
93 }
94 
95 static void _update_cache_info_lock_state(struct lvmcache_info *info,
96 					  int locked,
97 					  int *cached_vgmetadata_valid)
98 {
99 	int was_locked = (info->status & CACHE_LOCKED) ? 1 : 0;
100 
101 	/*
102 	 * Cache becomes invalid whenever lock state changes unless
103 	 * exclusive VG_GLOBAL is held (i.e. while scanning).
104 	 */
105 	if (!vgname_is_locked(VG_GLOBAL) && (was_locked != locked)) {
106 		info->status |= CACHE_INVALID;
107 		*cached_vgmetadata_valid = 0;
108 	}
109 
110 	if (locked)
111 		info->status |= CACHE_LOCKED;
112 	else
113 		info->status &= ~CACHE_LOCKED;
114 }
115 
116 static void _update_cache_vginfo_lock_state(struct lvmcache_vginfo *vginfo,
117 					    int locked)
118 {
119 	struct lvmcache_info *info;
120 	int cached_vgmetadata_valid = 1;
121 
122 	dm_list_iterate_items(info, &vginfo->infos)
123 		_update_cache_info_lock_state(info, locked,
124 					      &cached_vgmetadata_valid);
125 
126 	if (!cached_vgmetadata_valid)
127 		_free_cached_vgmetadata(vginfo);
128 }
129 
130 static void _update_cache_lock_state(const char *vgname, int locked)
131 {
132 	struct lvmcache_vginfo *vginfo;
133 
134 	if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
135 		return;
136 
137 	_update_cache_vginfo_lock_state(vginfo, locked);
138 }
139 
140 static void _drop_metadata(const char *vgname)
141 {
142 	struct lvmcache_vginfo *vginfo;
143 	struct lvmcache_info *info;
144 
145 	if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
146 		return;
147 
148 	/*
149 	 * Invalidate cached PV labels.
150 	 * If cached precommitted metadata exists that means we
151 	 * already invalidated the PV labels (before caching it)
152 	 * and we must not do it again.
153 	 */
154 
155 	if (!vginfo->precommitted)
156 		dm_list_iterate_items(info, &vginfo->infos)
157 			info->status |= CACHE_INVALID;
158 
159 	_free_cached_vgmetadata(vginfo);
160 }
161 
162 void lvmcache_drop_metadata(const char *vgname)
163 {
164 	/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
165 	if (!strcmp(vgname, VG_ORPHANS)) {
166 		_drop_metadata(FMT_TEXT_ORPHAN_VG_NAME);
167 		_drop_metadata(FMT_LVM1_ORPHAN_VG_NAME);
168 		_drop_metadata(FMT_POOL_ORPHAN_VG_NAME);
169 
170 		/* Indicate that PVs could now be missing from the cache */
171 		init_full_scan_done(0);
172 	} else if (!vgname_is_locked(VG_GLOBAL))
173 		_drop_metadata(vgname);
174 }
175 
176 void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)))
177 {
178 	if (!_lock_hash && !lvmcache_init()) {
179 		log_error("Internal cache initialisation failed");
180 		return;
181 	}
182 
183 	if (dm_hash_lookup(_lock_hash, vgname))
184 		log_error("Internal error: Nested locking attempted on VG %s.",
185 			  vgname);
186 
187 	if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
188 		log_error("Cache locking failure for %s", vgname);
189 
190 	_update_cache_lock_state(vgname, 1);
191 
192 	if (strcmp(vgname, VG_GLOBAL))
193 		_vgs_locked++;
194 }
195 
196 int vgname_is_locked(const char *vgname)
197 {
198 	if (!_lock_hash)
199 		return 0;
200 
201 	return dm_hash_lookup(_lock_hash, vgname) ? 1 : 0;
202 }
203 
204 void lvmcache_unlock_vgname(const char *vgname)
205 {
206 	if (!dm_hash_lookup(_lock_hash, vgname))
207 		log_error("Internal error: Attempt to unlock unlocked VG %s.",
208 			  vgname);
209 
210 	_update_cache_lock_state(vgname, 0);
211 
212 	dm_hash_remove(_lock_hash, vgname);
213 
214 	/* FIXME Do this per-VG */
215 	if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked)
216 		dev_close_all();
217 }
218 
219 int vgs_locked(void)
220 {
221 	return _vgs_locked;
222 }
223 
224 static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo,
225 				struct lvmcache_info *info)
226 {
227 	if (!vginfo)
228 		return;
229 
230 	info->vginfo = vginfo;
231 	dm_list_add(&vginfo->infos, &info->list);
232 }
233 
234 static void _vginfo_detach_info(struct lvmcache_info *info)
235 {
236 	if (!dm_list_empty(&info->list)) {
237 		dm_list_del(&info->list);
238 		dm_list_init(&info->list);
239 	}
240 
241 	info->vginfo = NULL;
242 }
243 
244 /* If vgid supplied, require a match. */
245 struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname, const char *vgid)
246 {
247 	struct lvmcache_vginfo *vginfo;
248 
249 	if (!vgname)
250 		return vginfo_from_vgid(vgid);
251 
252 	if (!_vgname_hash)
253 		return NULL;
254 
255 	if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
256 		return NULL;
257 
258 	if (vgid)
259 		do
260 			if (!strncmp(vgid, vginfo->vgid, ID_LEN))
261 				return vginfo;
262 		while ((vginfo = vginfo->next));
263 
264 	return vginfo;
265 }
266 
267 const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
268 {
269 	struct lvmcache_vginfo *vginfo;
270 	struct lvmcache_info *info;
271 	struct label *label;
272 	struct dm_list *devh, *tmp;
273 	struct dm_list devs;
274 	struct device_list *devl;
275 	char vgid_found[ID_LEN + 1] __attribute((aligned(8)));
276 
277 	if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
278 		return NULL;
279 
280 	/* This function is normally called before reading metadata so
281  	 * we check cached labels here. Unfortunately vginfo is volatile. */
282 	dm_list_init(&devs);
283 	dm_list_iterate_items(info, &vginfo->infos) {
284 		if (!(devl = dm_malloc(sizeof(*devl)))) {
285 			log_error("device_list element allocation failed");
286 			return NULL;
287 		}
288 		devl->dev = info->dev;
289 		dm_list_add(&devs, &devl->list);
290 	}
291 
292 	memcpy(vgid_found, vginfo->vgid, sizeof(vgid_found));
293 
294 	dm_list_iterate_safe(devh, tmp, &devs) {
295 		devl = dm_list_item(devh, struct device_list);
296 		label_read(devl->dev, &label, UINT64_C(0));
297 		dm_list_del(&devl->list);
298 		dm_free(devl);
299 	}
300 
301 	/* If vginfo changed, caller needs to rescan */
302 	if (!(vginfo = vginfo_from_vgname(vgname, vgid_found)) ||
303 	    strncmp(vginfo->vgid, vgid_found, ID_LEN))
304 		return NULL;
305 
306 	return vginfo->fmt;
307 }
308 
309 struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
310 {
311 	struct lvmcache_vginfo *vginfo;
312 	char id[ID_LEN + 1] __attribute((aligned(8)));
313 
314 	if (!_vgid_hash || !vgid)
315 		return NULL;
316 
317 	/* vgid not necessarily NULL-terminated */
318 	strncpy(&id[0], vgid, ID_LEN);
319 	id[ID_LEN] = '\0';
320 
321 	if (!(vginfo = dm_hash_lookup(_vgid_hash, id)))
322 		return NULL;
323 
324 	return vginfo;
325 }
326 
327 const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid)
328 {
329 	struct lvmcache_vginfo *vginfo;
330 	const char *vgname = NULL;
331 
332 	if ((vginfo = vginfo_from_vgid(vgid)))
333 		vgname = vginfo->vgname;
334 
335 	if (mem && vgname)
336 		return dm_pool_strdup(mem, vgname);
337 
338 	return vgname;
339 }
340 
341 static int _info_is_valid(struct lvmcache_info *info)
342 {
343 	if (info->status & CACHE_INVALID)
344 		return 0;
345 
346 	/*
347 	 * The caller must hold the VG lock to manipulate metadata.
348 	 * In a cluster, remote nodes sometimes read metadata in the
349 	 * knowledge that the controlling node is holding the lock.
350 	 * So if the VG appears to be unlocked here, it should be safe
351 	 * to use the cached value.
352 	 */
353 	if (info->vginfo && !vgname_is_locked(info->vginfo->vgname))
354 		return 1;
355 
356 	if (!(info->status & CACHE_LOCKED))
357 		return 0;
358 
359 	return 1;
360 }
361 
362 static int _vginfo_is_valid(struct lvmcache_vginfo *vginfo)
363 {
364 	struct lvmcache_info *info;
365 
366 	/* Invalid if any info is invalid */
367 	dm_list_iterate_items(info, &vginfo->infos)
368 		if (!_info_is_valid(info))
369 			return 0;
370 
371 	return 1;
372 }
373 
374 /* vginfo is invalid if it does not contain at least one valid info */
375 static int _vginfo_is_invalid(struct lvmcache_vginfo *vginfo)
376 {
377 	struct lvmcache_info *info;
378 
379 	dm_list_iterate_items(info, &vginfo->infos)
380 		if (_info_is_valid(info))
381 			return 0;
382 
383 	return 1;
384 }
385 
386 /*
387  * If valid_only is set, data will only be returned if the cached data is
388  * known still to be valid.
389  */
390 struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only)
391 {
392 	struct lvmcache_info *info;
393 	char id[ID_LEN + 1] __attribute((aligned(8)));
394 
395 	if (!_pvid_hash || !pvid)
396 		return NULL;
397 
398 	strncpy(&id[0], pvid, ID_LEN);
399 	id[ID_LEN] = '\0';
400 
401 	if (!(info = dm_hash_lookup(_pvid_hash, id)))
402 		return NULL;
403 
404 	if (valid_only && !_info_is_valid(info))
405 		return NULL;
406 
407 	return info;
408 }
409 
410 static void _rescan_entry(struct lvmcache_info *info)
411 {
412 	struct label *label;
413 
414 	if (info->status & CACHE_INVALID)
415 		label_read(info->dev, &label, UINT64_C(0));
416 }
417 
418 static int _scan_invalid(void)
419 {
420 	dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _rescan_entry);
421 
422 	return 1;
423 }
424 
425 int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
426 {
427 	struct label *label;
428 	struct dev_iter *iter;
429 	struct device *dev;
430 	struct format_type *fmt;
431 
432 	int r = 0;
433 
434 	/* Avoid recursion when a PVID can't be found! */
435 	if (_scanning_in_progress)
436 		return 0;
437 
438 	_scanning_in_progress = 1;
439 
440 	if (!_vgname_hash && !lvmcache_init()) {
441 		log_error("Internal cache initialisation failed");
442 		goto out;
443 	}
444 
445 	if (_has_scanned && !full_scan) {
446 		r = _scan_invalid();
447 		goto out;
448 	}
449 
450 	if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1 : 0))) {
451 		log_error("dev_iter creation failed");
452 		goto out;
453 	}
454 
455 	while ((dev = dev_iter_get(iter)))
456 		label_read(dev, &label, UINT64_C(0));
457 
458 	dev_iter_destroy(iter);
459 
460 	_has_scanned = 1;
461 
462 	/* Perform any format-specific scanning e.g. text files */
463 	dm_list_iterate_items(fmt, &cmd->formats) {
464 		if (fmt->ops->scan && !fmt->ops->scan(fmt))
465 			goto out;
466 	}
467 
468 	r = 1;
469 
470       out:
471 	_scanning_in_progress = 0;
472 
473 	return r;
474 }
475 
476 struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
477 {
478 	struct lvmcache_vginfo *vginfo;
479 	struct volume_group *vg;
480 	struct format_instance *fid;
481 
482 	if (!vgid || !(vginfo = vginfo_from_vgid(vgid)) || !vginfo->vgmetadata)
483 		return NULL;
484 
485 	if (!_vginfo_is_valid(vginfo))
486 		return NULL;
487 
488 	/*
489 	 * Don't return cached data if either:
490 	 * (i)  precommitted metadata is requested but we don't have it cached
491 	 *      - caller should read it off disk;
492 	 * (ii) live metadata is requested but we have precommitted metadata cached
493 	 *      and no devices are suspended so caller may read it off disk.
494 	 *
495 	 * If live metadata is requested but we have precommitted metadata cached
496 	 * and devices are suspended, we assume this precommitted metadata has
497 	 * already been preloaded and committed so it's OK to return it as live.
498 	 * Note that we do not clear the PRECOMMITTED flag.
499 	 */
500 	if ((precommitted && !vginfo->precommitted) ||
501 	    (!precommitted && vginfo->precommitted && !memlock()))
502 		return NULL;
503 
504 	if (!(fid =  vginfo->fmt->ops->create_instance(vginfo->fmt,
505 						       vginfo->vgname,
506 						       vgid, NULL)))
507 		return_NULL;
508 
509 	if (!(vg = import_vg_from_buffer(vginfo->vgmetadata, fid)) ||
510 	    !vg_validate(vg)) {
511 		_free_cached_vgmetadata(vginfo);
512 		return_NULL;
513 	}
514 
515 	log_debug("Using cached %smetadata for VG %s.",
516 		  vginfo->precommitted ? "pre-committed" : "", vginfo->vgname);
517 
518 	return vg;
519 }
520 
521 struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
522 {
523 	struct dm_list *vgids;
524 	struct lvmcache_vginfo *vginfo;
525 
526 	lvmcache_label_scan(cmd, full_scan);
527 
528 	if (!(vgids = str_list_create(cmd->mem))) {
529 		log_error("vgids list allocation failed");
530 		return NULL;
531 	}
532 
533 	dm_list_iterate_items(vginfo, &_vginfos) {
534 		if (!str_list_add(cmd->mem, vgids,
535 				  dm_pool_strdup(cmd->mem, vginfo->vgid))) {
536 			log_error("strlist allocation failed");
537 			return NULL;
538 		}
539 	}
540 
541 	return vgids;
542 }
543 
544 struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
545 {
546 	struct dm_list *vgnames;
547 	struct lvmcache_vginfo *vginfo;
548 
549 	lvmcache_label_scan(cmd, full_scan);
550 
551 	if (!(vgnames = str_list_create(cmd->mem))) {
552 		log_error("vgnames list allocation failed");
553 		return NULL;
554 	}
555 
556 	dm_list_iterate_items(vginfo, &_vginfos) {
557 		if (!str_list_add(cmd->mem, vgnames,
558 				  dm_pool_strdup(cmd->mem, vginfo->vgname))) {
559 			log_error("strlist allocation failed");
560 			return NULL;
561 		}
562 	}
563 
564 	return vgnames;
565 }
566 
567 struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
568 				const char *vgid)
569 {
570 	struct dm_list *pvids;
571 	struct lvmcache_vginfo *vginfo;
572 	struct lvmcache_info *info;
573 
574 	if (!(pvids = str_list_create(cmd->mem))) {
575 		log_error("pvids list allocation failed");
576 		return NULL;
577 	}
578 
579 	if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
580 		return pvids;
581 
582 	dm_list_iterate_items(info, &vginfo->infos) {
583 		if (!str_list_add(cmd->mem, pvids,
584 				  dm_pool_strdup(cmd->mem, info->dev->pvid))) {
585 			log_error("strlist allocation failed");
586 			return NULL;
587 		}
588 	}
589 
590 	return pvids;
591 }
592 
593 struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
594 {
595 	struct label *label;
596 	struct lvmcache_info *info;
597 
598 	/* Already cached ? */
599 	if ((info = info_from_pvid((char *) pvid, 0))) {
600 		if (label_read(info->dev, &label, UINT64_C(0))) {
601 			info = (struct lvmcache_info *) label->info;
602 			if (id_equal(pvid, (struct id *) &info->dev->pvid))
603 				return info->dev;
604 		}
605 	}
606 
607 	lvmcache_label_scan(cmd, 0);
608 
609 	/* Try again */
610 	if ((info = info_from_pvid((char *) pvid, 0))) {
611 		if (label_read(info->dev, &label, UINT64_C(0))) {
612 			info = (struct lvmcache_info *) label->info;
613 			if (id_equal(pvid, (struct id *) &info->dev->pvid))
614 				return info->dev;
615 		}
616 	}
617 
618 	if (memlock())
619 		return NULL;
620 
621 	lvmcache_label_scan(cmd, 2);
622 
623 	/* Try again */
624 	if ((info = info_from_pvid((char *) pvid, 0))) {
625 		if (label_read(info->dev, &label, UINT64_C(0))) {
626 			info = (struct lvmcache_info *) label->info;
627 			if (id_equal(pvid, (struct id *) &info->dev->pvid))
628 				return info->dev;
629 		}
630 	}
631 
632 	return NULL;
633 }
634 
635 static int _free_vginfo(struct lvmcache_vginfo *vginfo)
636 {
637 	struct lvmcache_vginfo *primary_vginfo, *vginfo2;
638 	int r = 1;
639 
640 	_free_cached_vgmetadata(vginfo);
641 
642 	vginfo2 = primary_vginfo = vginfo_from_vgname(vginfo->vgname, NULL);
643 
644 	if (vginfo == primary_vginfo) {
645 		dm_hash_remove(_vgname_hash, vginfo->vgname);
646 		if (vginfo->next && !dm_hash_insert(_vgname_hash, vginfo->vgname,
647 						    vginfo->next)) {
648 			log_error("_vgname_hash re-insertion for %s failed",
649 				  vginfo->vgname);
650 			r = 0;
651 		}
652 	} else do
653 		if (vginfo2->next == vginfo) {
654 			vginfo2->next = vginfo->next;
655 			break;
656 		}
657  	while ((vginfo2 = primary_vginfo->next));
658 
659 	if (vginfo->vgname)
660 		dm_free(vginfo->vgname);
661 
662 	if (vginfo->creation_host)
663 		dm_free(vginfo->creation_host);
664 
665 	if (*vginfo->vgid && _vgid_hash &&
666 	    vginfo_from_vgid(vginfo->vgid) == vginfo)
667 		dm_hash_remove(_vgid_hash, vginfo->vgid);
668 
669 	dm_list_del(&vginfo->list);
670 
671 	dm_free(vginfo);
672 
673 	return r;
674 }
675 
676 /*
677  * vginfo must be info->vginfo unless info is NULL
678  */
679 static int _drop_vginfo(struct lvmcache_info *info, struct lvmcache_vginfo *vginfo)
680 {
681 	if (info)
682 		_vginfo_detach_info(info);
683 
684 	/* vginfo still referenced? */
685 	if (!vginfo || is_orphan_vg(vginfo->vgname) ||
686 	    !dm_list_empty(&vginfo->infos))
687 		return 1;
688 
689 	if (!_free_vginfo(vginfo))
690 		return_0;
691 
692 	return 1;
693 }
694 
695 /* Unused
696 void lvmcache_del(struct lvmcache_info *info)
697 {
698 	if (info->dev->pvid[0] && _pvid_hash)
699 		dm_hash_remove(_pvid_hash, info->dev->pvid);
700 
701 	_drop_vginfo(info, info->vginfo);
702 
703 	info->label->labeller->ops->destroy_label(info->label->labeller,
704 						info->label);
705 	dm_free(info);
706 
707 	return;
708 } */
709 
710 static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
711 {
712 	/*
713 	 * Nothing to do if already stored with same pvid.
714 	 */
715 	if (((dm_hash_lookup(_pvid_hash, pvid)) == info) &&
716 	    !strcmp(info->dev->pvid, pvid))
717 		return 1;
718 	if (*info->dev->pvid)
719 		dm_hash_remove(_pvid_hash, info->dev->pvid);
720 	strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid));
721 	if (!dm_hash_insert(_pvid_hash, pvid, info)) {
722 		log_error("_lvmcache_update: pvid insertion failed: %s", pvid);
723 		return 0;
724 	}
725 
726 	return 1;
727 }
728 
729 /*
730  * vginfo must be info->vginfo unless info is NULL (orphans)
731  */
732 static int _lvmcache_update_vgid(struct lvmcache_info *info,
733 				 struct lvmcache_vginfo *vginfo,
734 				 const char *vgid)
735 {
736 	if (!vgid || !vginfo ||
737 	    !strncmp(vginfo->vgid, vgid, ID_LEN))
738 		return 1;
739 
740 	if (vginfo && *vginfo->vgid)
741 		dm_hash_remove(_vgid_hash, vginfo->vgid);
742 	if (!vgid) {
743 		log_debug("lvmcache: %s: clearing VGID", info ? dev_name(info->dev) : vginfo->vgname);
744 		return 1;
745 	}
746 
747 	strncpy(vginfo->vgid, vgid, ID_LEN);
748 	vginfo->vgid[ID_LEN] = '\0';
749 	if (!dm_hash_insert(_vgid_hash, vginfo->vgid, vginfo)) {
750 		log_error("_lvmcache_update: vgid hash insertion failed: %s",
751 			  vginfo->vgid);
752 		return 0;
753 	}
754 
755 	if (!is_orphan_vg(vginfo->vgname))
756 		log_debug("lvmcache: %s: setting %s VGID to %s",
757 			  dev_name(info->dev), vginfo->vgname,
758 			  vginfo->vgid);
759 
760 	return 1;
761 }
762 
763 static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
764 			  uint32_t vgstatus, const char *creation_host,
765 			  struct lvmcache_vginfo *primary_vginfo)
766 {
767 	struct lvmcache_vginfo *last_vginfo = primary_vginfo;
768 	char uuid_primary[64] __attribute((aligned(8)));
769 	char uuid_new[64] __attribute((aligned(8)));
770 	int use_new = 0;
771 
772 	/* Pre-existing VG takes precedence. Unexported VG takes precedence. */
773 	if (primary_vginfo) {
774 		if (!id_write_format((const struct id *)vgid, uuid_new, sizeof(uuid_new)))
775 			return_0;
776 
777 		if (!id_write_format((const struct id *)&primary_vginfo->vgid, uuid_primary,
778 				     sizeof(uuid_primary)))
779 			return_0;
780 
781 		/*
782 		 * If   Primary not exported, new exported => keep
783 		 * Else Primary exported, new not exported => change
784 		 * Else Primary has hostname for this machine => keep
785 		 * Else Primary has no hostname, new has one => change
786 		 * Else New has hostname for this machine => change
787 		 * Else Keep primary.
788 		 */
789 		if (!(primary_vginfo->status & EXPORTED_VG) &&
790 		    (vgstatus & EXPORTED_VG))
791 			log_error("WARNING: Duplicate VG name %s: "
792 				  "Existing %s takes precedence over "
793 				  "exported %s", new_vginfo->vgname,
794 				  uuid_primary, uuid_new);
795 		else if ((primary_vginfo->status & EXPORTED_VG) &&
796 			   !(vgstatus & EXPORTED_VG)) {
797 			log_error("WARNING: Duplicate VG name %s: "
798 				  "%s takes precedence over exported %s",
799 				  new_vginfo->vgname, uuid_new,
800 				  uuid_primary);
801 			use_new = 1;
802 		} else if (primary_vginfo->creation_host &&
803 			   !strcmp(primary_vginfo->creation_host,
804 				   primary_vginfo->fmt->cmd->hostname))
805 			log_error("WARNING: Duplicate VG name %s: "
806 				  "Existing %s (created here) takes precedence "
807 				  "over %s", new_vginfo->vgname, uuid_primary,
808 				  uuid_new);
809 		else if (!primary_vginfo->creation_host && creation_host) {
810 			log_error("WARNING: Duplicate VG name %s: "
811 				  "%s (with creation_host) takes precedence over %s",
812 				  new_vginfo->vgname, uuid_new,
813 				  uuid_primary);
814 			use_new = 1;
815 		} else if (creation_host &&
816 			   !strcmp(creation_host,
817 				   primary_vginfo->fmt->cmd->hostname)) {
818 			log_error("WARNING: Duplicate VG name %s: "
819 				  "%s (created here) takes precedence over %s",
820 				  new_vginfo->vgname, uuid_new,
821 				  uuid_primary);
822 			use_new = 1;
823 		}
824 
825 		if (!use_new) {
826 			while (last_vginfo->next)
827 				last_vginfo = last_vginfo->next;
828 			last_vginfo->next = new_vginfo;
829 			return 1;
830 		}
831 
832 		dm_hash_remove(_vgname_hash, primary_vginfo->vgname);
833 	}
834 
835 	if (!dm_hash_insert(_vgname_hash, new_vginfo->vgname, new_vginfo)) {
836 		log_error("cache_update: vg hash insertion failed: %s",
837 		  	new_vginfo->vgname);
838 		return 0;
839 	}
840 
841 	if (primary_vginfo)
842 		new_vginfo->next = primary_vginfo;
843 
844 	return 1;
845 }
846 
847 static int _lvmcache_update_vgname(struct lvmcache_info *info,
848 				   const char *vgname, const char *vgid,
849 				   uint32_t vgstatus, const char *creation_host,
850 				   const struct format_type *fmt)
851 {
852 	struct lvmcache_vginfo *vginfo, *primary_vginfo, *orphan_vginfo;
853 	struct lvmcache_info *info2, *info3;
854 	char mdabuf[32];
855 	// struct lvmcache_vginfo  *old_vginfo, *next;
856 
857 	if (!vgname || (info && info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
858 		return 1;
859 
860 	/* Remove existing vginfo entry */
861 	if (info)
862 		_drop_vginfo(info, info->vginfo);
863 
864 	/* Get existing vginfo or create new one */
865 	if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
866 /*** FIXME - vginfo ends up duplicated instead of renamed.
867 		// Renaming?  This lookup fails.
868 		if ((vginfo = vginfo_from_vgid(vgid))) {
869 			next = vginfo->next;
870 			old_vginfo = vginfo_from_vgname(vginfo->vgname, NULL);
871 			if (old_vginfo == vginfo) {
872 				dm_hash_remove(_vgname_hash, old_vginfo->vgname);
873 				if (old_vginfo->next) {
874 					if (!dm_hash_insert(_vgname_hash, old_vginfo->vgname, old_vginfo->next)) {
875 						log_error("vg hash re-insertion failed: %s",
876 							  old_vginfo->vgname);
877 						return 0;
878 					}
879 				}
880 			} else do {
881 				if (old_vginfo->next == vginfo) {
882 					old_vginfo->next = vginfo->next;
883 					break;
884 				}
885 			} while ((old_vginfo = old_vginfo->next));
886 			vginfo->next = NULL;
887 
888 			dm_free(vginfo->vgname);
889 			if (!(vginfo->vgname = dm_strdup(vgname))) {
890 				log_error("cache vgname alloc failed for %s", vgname);
891 				return 0;
892 			}
893 
894 			// Rename so can assume new name does not already exist
895 			if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo->next)) {
896 				log_error("vg hash re-insertion failed: %s",
897 					  vginfo->vgname);
898 		      		return 0;
899 			}
900 		} else {
901 ***/
902 		if (!(vginfo = dm_malloc(sizeof(*vginfo)))) {
903 			log_error("lvmcache_update_vgname: list alloc failed");
904 			return 0;
905 		}
906 		memset(vginfo, 0, sizeof(*vginfo));
907 		if (!(vginfo->vgname = dm_strdup(vgname))) {
908 			dm_free(vginfo);
909 			log_error("cache vgname alloc failed for %s", vgname);
910 			return 0;
911 		}
912 		dm_list_init(&vginfo->infos);
913 
914 		/*
915 		 * If we're scanning and there's an invalidated entry, remove it.
916 		 * Otherwise we risk bogus warnings of duplicate VGs.
917 		 */
918 		while ((primary_vginfo = vginfo_from_vgname(vgname, NULL)) &&
919 		       _scanning_in_progress && _vginfo_is_invalid(primary_vginfo))
920 			dm_list_iterate_items_safe(info2, info3, &primary_vginfo->infos) {
921 				orphan_vginfo = vginfo_from_vgname(primary_vginfo->fmt->orphan_vg_name, NULL);
922 				_drop_vginfo(info2, primary_vginfo);
923 				_vginfo_attach_info(orphan_vginfo, info2);
924 				if (info2->mdas.n)
925 					sprintf(mdabuf, " with %u mdas",
926 						dm_list_size(&info2->mdas));
927 				else
928 					mdabuf[0] = '\0';
929 				log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
930 					  dev_name(info2->dev),
931 					  vgname, orphan_vginfo->vgid[0] ? " (" : "",
932 					  orphan_vginfo->vgid[0] ? orphan_vginfo->vgid : "",
933 					  orphan_vginfo->vgid[0] ? ")" : "", mdabuf);
934 		}
935 
936 		if (!_insert_vginfo(vginfo, vgid, vgstatus, creation_host,
937 				    primary_vginfo)) {
938 			dm_free(vginfo->vgname);
939 			dm_free(vginfo);
940 			return 0;
941 		}
942 		/* Ensure orphans appear last on list_iterate */
943 		if (is_orphan_vg(vgname))
944 			dm_list_add(&_vginfos, &vginfo->list);
945 		else
946 			dm_list_add_h(&_vginfos, &vginfo->list);
947 /***
948 		}
949 ***/
950 	}
951 
952 	if (info)
953 		_vginfo_attach_info(vginfo, info);
954 	else if (!_lvmcache_update_vgid(NULL, vginfo, vgid)) /* Orphans */
955 		return_0;
956 
957 	_update_cache_vginfo_lock_state(vginfo, vgname_is_locked(vgname));
958 
959 	/* FIXME Check consistency of list! */
960 	vginfo->fmt = fmt;
961 
962 	if (info) {
963 		if (info->mdas.n)
964 			sprintf(mdabuf, " with %u mdas", dm_list_size(&info->mdas));
965 		else
966 			mdabuf[0] = '\0';
967 		log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
968 			  dev_name(info->dev),
969 			  vgname, vginfo->vgid[0] ? " (" : "",
970 			  vginfo->vgid[0] ? vginfo->vgid : "",
971 			  vginfo->vgid[0] ? ")" : "", mdabuf);
972 	} else
973 		log_debug("lvmcache: initialised VG %s", vgname);
974 
975 	return 1;
976 }
977 
978 static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus,
979 				     const char *creation_host)
980 {
981 	if (!info || !info->vginfo)
982 		return 1;
983 
984 	if ((info->vginfo->status & EXPORTED_VG) != (vgstatus & EXPORTED_VG))
985 		log_debug("lvmcache: %s: VG %s %s exported",
986 			  dev_name(info->dev), info->vginfo->vgname,
987 			  vgstatus & EXPORTED_VG ? "now" : "no longer");
988 
989 	info->vginfo->status = vgstatus;
990 
991 	if (!creation_host)
992 		return 1;
993 
994 	if (info->vginfo->creation_host && !strcmp(creation_host,
995 						   info->vginfo->creation_host))
996 		return 1;
997 
998 	if (info->vginfo->creation_host)
999 		dm_free(info->vginfo->creation_host);
1000 
1001 	if (!(info->vginfo->creation_host = dm_strdup(creation_host))) {
1002 		log_error("cache creation host alloc failed for %s",
1003 			  creation_host);
1004 		return 0;
1005 	}
1006 
1007 	log_debug("lvmcache: %s: VG %s: Set creation host to %s.",
1008 		  dev_name(info->dev), info->vginfo->vgname, creation_host);
1009 
1010 	return 1;
1011 }
1012 
1013 int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
1014 {
1015 	if (!_lock_hash && !lvmcache_init()) {
1016 		log_error("Internal cache initialisation failed");
1017 		return 0;
1018 	}
1019 
1020 	return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
1021 }
1022 
1023 int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
1024 				  const char *vgname, const char *vgid,
1025 				  uint32_t vgstatus, const char *creation_host)
1026 {
1027 	if (!vgname && !info->vginfo) {
1028 		log_error("Internal error: NULL vgname handed to cache");
1029 		/* FIXME Remove this */
1030 		vgname = info->fmt->orphan_vg_name;
1031 		vgid = vgname;
1032 	}
1033 
1034 	/* If PV without mdas is already in a real VG, don't make it orphan */
1035 	if (is_orphan_vg(vgname) && info->vginfo && !dm_list_size(&info->mdas) &&
1036 	    !is_orphan_vg(info->vginfo->vgname) && memlock())
1037 		return 1;
1038 
1039 	/* If moving PV from orphan to real VG, always mark it valid */
1040 	if (!is_orphan_vg(vgname))
1041 		info->status &= ~CACHE_INVALID;
1042 
1043 	if (!_lvmcache_update_vgname(info, vgname, vgid, vgstatus,
1044 				     creation_host, info->fmt) ||
1045 	    !_lvmcache_update_vgid(info, info->vginfo, vgid) ||
1046 	    !_lvmcache_update_vgstatus(info, vgstatus, creation_host))
1047 		return_0;
1048 
1049 	return 1;
1050 }
1051 
1052 int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
1053 {
1054 	struct pv_list *pvl;
1055 	struct lvmcache_info *info;
1056 	struct lvmcache_vginfo *vginfo;
1057 	char pvid_s[ID_LEN + 1] __attribute((aligned(8)));
1058 
1059 	pvid_s[sizeof(pvid_s) - 1] = '\0';
1060 
1061 	dm_list_iterate_items(pvl, &vg->pvs) {
1062 		strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
1063 		/* FIXME Could pvl->pv->dev->pvid ever be different? */
1064 		if ((info = info_from_pvid(pvid_s, 0)) &&
1065 		    !lvmcache_update_vgname_and_id(info, vg->name,
1066 						   (char *) &vg->id,
1067 						   vg->status, NULL))
1068 			return_0;
1069 	}
1070 
1071 	/* store text representation of vg to cache */
1072 	if (vg->cmd->current_settings.cache_vgmetadata &&
1073 	    (vginfo = vginfo_from_vgname(vg->name, NULL)))
1074 		_store_metadata(vginfo, vg, precommitted);
1075 
1076 	return 1;
1077 }
1078 
1079 struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
1080 				   struct device *dev,
1081 				   const char *vgname, const char *vgid,
1082 				   uint32_t vgstatus)
1083 {
1084 	struct label *label;
1085 	struct lvmcache_info *existing, *info;
1086 	char pvid_s[ID_LEN + 1] __attribute((aligned(8)));
1087 
1088 	if (!_vgname_hash && !lvmcache_init()) {
1089 		log_error("Internal cache initialisation failed");
1090 		return NULL;
1091 	}
1092 
1093 	strncpy(pvid_s, pvid, sizeof(pvid_s));
1094 	pvid_s[sizeof(pvid_s) - 1] = '\0';
1095 
1096 	if (!(existing = info_from_pvid(pvid_s, 0)) &&
1097 	    !(existing = info_from_pvid(dev->pvid, 0))) {
1098 		if (!(label = label_create(labeller)))
1099 			return_NULL;
1100 		if (!(info = dm_malloc(sizeof(*info)))) {
1101 			log_error("lvmcache_info allocation failed");
1102 			label_destroy(label);
1103 			return NULL;
1104 		}
1105 		memset(info, 0, sizeof(*info));
1106 
1107 		label->info = info;
1108 		info->label = label;
1109 		dm_list_init(&info->list);
1110 		info->dev = dev;
1111 	} else {
1112 		if (existing->dev != dev) {
1113 			/* Is the existing entry a duplicate pvid e.g. md ? */
1114 			if (MAJOR(existing->dev->dev) == md_major() &&
1115 			    MAJOR(dev->dev) != md_major()) {
1116 				log_very_verbose("Ignoring duplicate PV %s on "
1117 						 "%s - using md %s",
1118 						 pvid, dev_name(dev),
1119 						 dev_name(existing->dev));
1120 				return NULL;
1121 			} else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
1122 				   !dm_is_dm_major(MAJOR(dev->dev))) {
1123 				log_very_verbose("Ignoring duplicate PV %s on "
1124 						 "%s - using dm %s",
1125 						 pvid, dev_name(dev),
1126 						 dev_name(existing->dev));
1127 				return NULL;
1128 			} else if (MAJOR(existing->dev->dev) != md_major() &&
1129 				   MAJOR(dev->dev) == md_major())
1130 				log_very_verbose("Duplicate PV %s on %s - "
1131 						 "using md %s", pvid,
1132 						 dev_name(existing->dev),
1133 						 dev_name(dev));
1134 			else if (!dm_is_dm_major(MAJOR(existing->dev->dev)) &&
1135 				 dm_is_dm_major(MAJOR(dev->dev)))
1136 				log_very_verbose("Duplicate PV %s on %s - "
1137 						 "using dm %s", pvid,
1138 						 dev_name(existing->dev),
1139 						 dev_name(dev));
1140 			/* FIXME If both dm, check dependencies */
1141 			//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
1142 				 //dm_is_dm_major(MAJOR(dev->dev)))
1143 				 //
1144 			else if (!strcmp(pvid_s, existing->dev->pvid))
1145 				log_error("Found duplicate PV %s: using %s not "
1146 					  "%s", pvid, dev_name(dev),
1147 					  dev_name(existing->dev));
1148 		}
1149 		if (strcmp(pvid_s, existing->dev->pvid))
1150 			log_debug("Updating pvid cache to %s (%s) from %s (%s)",
1151 				  pvid_s, dev_name(dev),
1152 				  existing->dev->pvid, dev_name(existing->dev));
1153 		/* Switch over to new preferred device */
1154 		existing->dev = dev;
1155 		info = existing;
1156 		/* Has labeller changed? */
1157 		if (info->label->labeller != labeller) {
1158 			label_destroy(info->label);
1159 			if (!(info->label = label_create(labeller)))
1160 				/* FIXME leaves info without label! */
1161 				return_NULL;
1162 			info->label->info = info;
1163 		}
1164 		label = info->label;
1165 	}
1166 
1167 	info->fmt = (const struct format_type *) labeller->private;
1168 	info->status |= CACHE_INVALID;
1169 
1170 	if (!_lvmcache_update_pvid(info, pvid_s)) {
1171 		if (!existing) {
1172 			dm_free(info);
1173 			label_destroy(label);
1174 		}
1175 		return NULL;
1176 	}
1177 
1178 	if (!lvmcache_update_vgname_and_id(info, vgname, vgid, vgstatus, NULL)) {
1179 		if (!existing) {
1180 			dm_hash_remove(_pvid_hash, pvid_s);
1181 			strcpy(info->dev->pvid, "");
1182 			dm_free(info);
1183 			label_destroy(label);
1184 		}
1185 		return NULL;
1186 	}
1187 
1188 	return info;
1189 }
1190 
1191 static void _lvmcache_destroy_entry(struct lvmcache_info *info)
1192 {
1193 	_vginfo_detach_info(info);
1194 	strcpy(info->dev->pvid, "");
1195 	label_destroy(info->label);
1196 	dm_free(info);
1197 }
1198 
1199 static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
1200 {
1201 	struct lvmcache_vginfo *next;
1202 
1203 	do {
1204 		next = vginfo->next;
1205 		if (!_free_vginfo(vginfo))
1206 			stack;
1207 	} while ((vginfo = next));
1208 }
1209 
1210 static void _lvmcache_destroy_lockname(struct dm_hash_node *n)
1211 {
1212 	char *vgname;
1213 
1214 	if (!dm_hash_get_data(_lock_hash, n))
1215 		return;
1216 
1217 	vgname = dm_hash_get_key(_lock_hash, n);
1218 
1219 	if (!strcmp(vgname, VG_GLOBAL))
1220 		_vg_global_lock_held = 1;
1221 	else
1222 		log_error("Internal error: Volume Group %s was not unlocked",
1223 			  dm_hash_get_key(_lock_hash, n));
1224 }
1225 
1226 void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans)
1227 {
1228 	struct dm_hash_node *n;
1229 	log_verbose("Wiping internal VG cache");
1230 
1231 	_has_scanned = 0;
1232 
1233 	if (_vgid_hash) {
1234 		dm_hash_destroy(_vgid_hash);
1235 		_vgid_hash = NULL;
1236 	}
1237 
1238 	if (_pvid_hash) {
1239 		dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _lvmcache_destroy_entry);
1240 		dm_hash_destroy(_pvid_hash);
1241 		_pvid_hash = NULL;
1242 	}
1243 
1244 	if (_vgname_hash) {
1245 		dm_hash_iter(_vgname_hash,
1246 			  (dm_hash_iterate_fn) _lvmcache_destroy_vgnamelist);
1247 		dm_hash_destroy(_vgname_hash);
1248 		_vgname_hash = NULL;
1249 	}
1250 
1251 	if (_lock_hash) {
1252 		dm_hash_iterate(n, _lock_hash)
1253 			_lvmcache_destroy_lockname(n);
1254 		dm_hash_destroy(_lock_hash);
1255 		_lock_hash = NULL;
1256 	}
1257 
1258 	if (!dm_list_empty(&_vginfos))
1259 		log_error("Internal error: _vginfos list should be empty");
1260 	dm_list_init(&_vginfos);
1261 
1262 	if (retain_orphans)
1263 		init_lvmcache_orphans(cmd);
1264 }
1265