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