4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
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.
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
20 #include "toolcontext.h"
21 #include "dev-cache.h"
25 #include "filter-persistent.h"
28 #include "format-text.h"
29 #include "format_pool.h"
32 static struct dm_hash_table
*_pvid_hash
= NULL
;
33 static struct dm_hash_table
*_vgid_hash
= NULL
;
34 static struct dm_hash_table
*_vgname_hash
= NULL
;
35 static struct dm_hash_table
*_lock_hash
= NULL
;
36 static struct dm_list _vginfos
;
37 static int _scanning_in_progress
= 0;
38 static int _has_scanned
= 0;
39 static int _vgs_locked
= 0;
40 static int _vg_global_lock_held
= 0; /* Global lock held when cache wiped? */
42 int lvmcache_init(void)
44 dm_list_init(&_vginfos
);
46 if (!(_vgname_hash
= dm_hash_create(128)))
49 if (!(_vgid_hash
= dm_hash_create(128)))
52 if (!(_pvid_hash
= dm_hash_create(128)))
55 if (!(_lock_hash
= dm_hash_create(128)))
59 * Reinitialising the cache clears the internal record of
60 * which locks are held. The global lock can be held during
61 * this operation so its state must be restored afterwards.
63 if (_vg_global_lock_held
) {
64 lvmcache_lock_vgname(VG_GLOBAL
, 0);
65 _vg_global_lock_held
= 0;
71 /* Volume Group metadata cache functions */
72 static void _free_cached_vgmetadata(struct lvmcache_vginfo
*vginfo
)
74 if (!vginfo
|| !vginfo
->vgmetadata
)
77 dm_free(vginfo
->vgmetadata
);
79 vginfo
->vgmetadata
= NULL
;
81 log_debug("Metadata cache: VG %s wiped.", vginfo
->vgname
);
85 * Cache VG metadata against the vginfo with matching vgid.
87 static void _store_metadata(struct volume_group
*vg
, unsigned precommitted
)
89 char uuid
[64] __attribute((aligned(8)));
90 struct lvmcache_vginfo
*vginfo
;
93 if (!(vginfo
= vginfo_from_vgid((const char *)&vg
->id
))) {
98 if (vginfo
->vgmetadata
)
99 _free_cached_vgmetadata(vginfo
);
101 if (!(size
= export_vg_to_buffer(vg
, &vginfo
->vgmetadata
))) {
106 vginfo
->precommitted
= precommitted
;
108 if (!id_write_format((const struct id
*)vginfo
->vgid
, uuid
, sizeof(uuid
))) {
113 log_debug("Metadata cache: VG %s (%s) stored (%d bytes%s).",
114 vginfo
->vgname
, uuid
, size
,
115 precommitted
? ", precommitted" : "");
118 static void _update_cache_info_lock_state(struct lvmcache_info
*info
,
120 int *cached_vgmetadata_valid
)
122 int was_locked
= (info
->status
& CACHE_LOCKED
) ? 1 : 0;
125 * Cache becomes invalid whenever lock state changes unless
126 * exclusive VG_GLOBAL is held (i.e. while scanning).
128 if (!vgname_is_locked(VG_GLOBAL
) && (was_locked
!= locked
)) {
129 info
->status
|= CACHE_INVALID
;
130 *cached_vgmetadata_valid
= 0;
134 info
->status
|= CACHE_LOCKED
;
136 info
->status
&= ~CACHE_LOCKED
;
139 static void _update_cache_vginfo_lock_state(struct lvmcache_vginfo
*vginfo
,
142 struct lvmcache_info
*info
;
143 int cached_vgmetadata_valid
= 1;
145 dm_list_iterate_items(info
, &vginfo
->infos
)
146 _update_cache_info_lock_state(info
, locked
,
147 &cached_vgmetadata_valid
);
149 if (!cached_vgmetadata_valid
)
150 _free_cached_vgmetadata(vginfo
);
153 static void _update_cache_lock_state(const char *vgname
, int locked
)
155 struct lvmcache_vginfo
*vginfo
;
157 if (!(vginfo
= vginfo_from_vgname(vgname
, NULL
)))
160 _update_cache_vginfo_lock_state(vginfo
, locked
);
163 static void _drop_metadata(const char *vgname
)
165 struct lvmcache_vginfo
*vginfo
;
166 struct lvmcache_info
*info
;
168 if (!(vginfo
= vginfo_from_vgname(vgname
, NULL
)))
172 * Invalidate cached PV labels.
173 * If cached precommitted metadata exists that means we
174 * already invalidated the PV labels (before caching it)
175 * and we must not do it again.
178 if (!vginfo
->precommitted
)
179 dm_list_iterate_items(info
, &vginfo
->infos
)
180 info
->status
|= CACHE_INVALID
;
182 _free_cached_vgmetadata(vginfo
);
185 void lvmcache_drop_metadata(const char *vgname
)
187 /* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
188 if (!strcmp(vgname
, VG_ORPHANS
)) {
189 _drop_metadata(FMT_TEXT_ORPHAN_VG_NAME
);
190 _drop_metadata(FMT_LVM1_ORPHAN_VG_NAME
);
191 _drop_metadata(FMT_POOL_ORPHAN_VG_NAME
);
193 /* Indicate that PVs could now be missing from the cache */
194 init_full_scan_done(0);
195 } else if (!vgname_is_locked(VG_GLOBAL
))
196 _drop_metadata(vgname
);
200 * Ensure vgname2 comes after vgname1 alphabetically.
201 * Special VG names beginning with '#' don't count.
203 static int _vgname_order_correct(const char *vgname1
, const char *vgname2
)
205 if ((*vgname1
== '#') || (*vgname2
== '#'))
208 if (strcmp(vgname1
, vgname2
) < 0)
215 * Ensure VG locks are acquired in alphabetical order.
217 int lvmcache_verify_lock_order(const char *vgname
)
219 struct dm_hash_node
*n
;
225 dm_hash_iterate(n
, _lock_hash
) {
226 if (!dm_hash_get_data(_lock_hash
, n
))
229 vgname2
= dm_hash_get_key(_lock_hash
, n
);
231 if (!_vgname_order_correct(vgname2
, vgname
)) {
232 log_errno(EDEADLK
, "Internal error: VG lock %s must "
233 "be requested before %s, not after.",
242 void lvmcache_lock_vgname(const char *vgname
, int read_only
__attribute((unused
)))
244 if (!_lock_hash
&& !lvmcache_init()) {
245 log_error("Internal cache initialisation failed");
249 if (dm_hash_lookup(_lock_hash
, vgname
))
250 log_error("Internal error: Nested locking attempted on VG %s.",
253 if (!dm_hash_insert(_lock_hash
, vgname
, (void *) 1))
254 log_error("Cache locking failure for %s", vgname
);
256 _update_cache_lock_state(vgname
, 1);
258 if (strcmp(vgname
, VG_GLOBAL
))
262 int vgname_is_locked(const char *vgname
)
267 return dm_hash_lookup(_lock_hash
, vgname
) ? 1 : 0;
270 void lvmcache_unlock_vgname(const char *vgname
)
272 if (!dm_hash_lookup(_lock_hash
, vgname
))
273 log_error("Internal error: Attempt to unlock unlocked VG %s.",
276 _update_cache_lock_state(vgname
, 0);
278 dm_hash_remove(_lock_hash
, vgname
);
280 /* FIXME Do this per-VG */
281 if (strcmp(vgname
, VG_GLOBAL
) && !--_vgs_locked
)
290 static void _vginfo_attach_info(struct lvmcache_vginfo
*vginfo
,
291 struct lvmcache_info
*info
)
296 info
->vginfo
= vginfo
;
297 dm_list_add(&vginfo
->infos
, &info
->list
);
300 static void _vginfo_detach_info(struct lvmcache_info
*info
)
302 if (!dm_list_empty(&info
->list
)) {
303 dm_list_del(&info
->list
);
304 dm_list_init(&info
->list
);
310 /* If vgid supplied, require a match. */
311 struct lvmcache_vginfo
*vginfo_from_vgname(const char *vgname
, const char *vgid
)
313 struct lvmcache_vginfo
*vginfo
;
316 return vginfo_from_vgid(vgid
);
321 if (!(vginfo
= dm_hash_lookup(_vgname_hash
, vgname
)))
326 if (!strncmp(vgid
, vginfo
->vgid
, ID_LEN
))
328 while ((vginfo
= vginfo
->next
));
333 const struct format_type
*fmt_from_vgname(const char *vgname
, const char *vgid
)
335 struct lvmcache_vginfo
*vginfo
;
336 struct lvmcache_info
*info
;
338 struct dm_list
*devh
, *tmp
;
340 struct device_list
*devl
;
341 char vgid_found
[ID_LEN
+ 1] __attribute((aligned(8)));
343 if (!(vginfo
= vginfo_from_vgname(vgname
, vgid
)))
346 /* This function is normally called before reading metadata so
347 * we check cached labels here. Unfortunately vginfo is volatile. */
349 dm_list_iterate_items(info
, &vginfo
->infos
) {
350 if (!(devl
= dm_malloc(sizeof(*devl
)))) {
351 log_error("device_list element allocation failed");
354 devl
->dev
= info
->dev
;
355 dm_list_add(&devs
, &devl
->list
);
358 memcpy(vgid_found
, vginfo
->vgid
, sizeof(vgid_found
));
360 dm_list_iterate_safe(devh
, tmp
, &devs
) {
361 devl
= dm_list_item(devh
, struct device_list
);
362 label_read(devl
->dev
, &label
, UINT64_C(0));
363 dm_list_del(&devl
->list
);
367 /* If vginfo changed, caller needs to rescan */
368 if (!(vginfo
= vginfo_from_vgname(vgname
, vgid_found
)) ||
369 strncmp(vginfo
->vgid
, vgid_found
, ID_LEN
))
375 struct lvmcache_vginfo
*vginfo_from_vgid(const char *vgid
)
377 struct lvmcache_vginfo
*vginfo
;
378 char id
[ID_LEN
+ 1] __attribute((aligned(8)));
380 if (!_vgid_hash
|| !vgid
)
383 /* vgid not necessarily NULL-terminated */
384 strncpy(&id
[0], vgid
, ID_LEN
);
387 if (!(vginfo
= dm_hash_lookup(_vgid_hash
, id
)))
393 const char *vgname_from_vgid(struct dm_pool
*mem
, const char *vgid
)
395 struct lvmcache_vginfo
*vginfo
;
396 const char *vgname
= NULL
;
398 if ((vginfo
= vginfo_from_vgid(vgid
)))
399 vgname
= vginfo
->vgname
;
402 return dm_pool_strdup(mem
, vgname
);
407 static int _info_is_valid(struct lvmcache_info
*info
)
409 if (info
->status
& CACHE_INVALID
)
413 * The caller must hold the VG lock to manipulate metadata.
414 * In a cluster, remote nodes sometimes read metadata in the
415 * knowledge that the controlling node is holding the lock.
416 * So if the VG appears to be unlocked here, it should be safe
417 * to use the cached value.
419 if (info
->vginfo
&& !vgname_is_locked(info
->vginfo
->vgname
))
422 if (!(info
->status
& CACHE_LOCKED
))
428 static int _vginfo_is_valid(struct lvmcache_vginfo
*vginfo
)
430 struct lvmcache_info
*info
;
432 /* Invalid if any info is invalid */
433 dm_list_iterate_items(info
, &vginfo
->infos
)
434 if (!_info_is_valid(info
))
440 /* vginfo is invalid if it does not contain at least one valid info */
441 static int _vginfo_is_invalid(struct lvmcache_vginfo
*vginfo
)
443 struct lvmcache_info
*info
;
445 dm_list_iterate_items(info
, &vginfo
->infos
)
446 if (_info_is_valid(info
))
453 * If valid_only is set, data will only be returned if the cached data is
454 * known still to be valid.
456 struct lvmcache_info
*info_from_pvid(const char *pvid
, int valid_only
)
458 struct lvmcache_info
*info
;
459 char id
[ID_LEN
+ 1] __attribute((aligned(8)));
461 if (!_pvid_hash
|| !pvid
)
464 strncpy(&id
[0], pvid
, ID_LEN
);
467 if (!(info
= dm_hash_lookup(_pvid_hash
, id
)))
470 if (valid_only
&& !_info_is_valid(info
))
476 static void _rescan_entry(struct lvmcache_info
*info
)
480 if (info
->status
& CACHE_INVALID
)
481 label_read(info
->dev
, &label
, UINT64_C(0));
484 static int _scan_invalid(void)
486 dm_hash_iter(_pvid_hash
, (dm_hash_iterate_fn
) _rescan_entry
);
491 int lvmcache_label_scan(struct cmd_context
*cmd
, int full_scan
)
494 struct dev_iter
*iter
;
496 struct format_type
*fmt
;
500 /* Avoid recursion when a PVID can't be found! */
501 if (_scanning_in_progress
)
504 _scanning_in_progress
= 1;
506 if (!_vgname_hash
&& !lvmcache_init()) {
507 log_error("Internal cache initialisation failed");
511 if (_has_scanned
&& !full_scan
) {
516 if (full_scan
== 2 && !refresh_filters(cmd
)) {
517 log_error("refresh filters failed");
521 if (!(iter
= dev_iter_create(cmd
->filter
, (full_scan
== 2) ? 1 : 0))) {
522 log_error("dev_iter creation failed");
526 while ((dev
= dev_iter_get(iter
)))
527 label_read(dev
, &label
, UINT64_C(0));
529 dev_iter_destroy(iter
);
533 /* Perform any format-specific scanning e.g. text files */
534 dm_list_iterate_items(fmt
, &cmd
->formats
) {
535 if (fmt
->ops
->scan
&& !fmt
->ops
->scan(fmt
))
540 * If we are a long-lived process, write out the updated persistent
541 * device cache for the benefit of short-lived processes.
543 if (full_scan
== 2 && cmd
->is_long_lived
&& cmd
->dump_filter
)
544 persistent_filter_dump(cmd
->filter
);
549 _scanning_in_progress
= 0;
554 struct volume_group
*lvmcache_get_vg(const char *vgid
, unsigned precommitted
)
556 struct lvmcache_vginfo
*vginfo
;
557 struct volume_group
*vg
;
558 struct format_instance
*fid
;
560 if (!vgid
|| !(vginfo
= vginfo_from_vgid(vgid
)) || !vginfo
->vgmetadata
)
563 if (!_vginfo_is_valid(vginfo
))
567 * Don't return cached data if either:
568 * (i) precommitted metadata is requested but we don't have it cached
569 * - caller should read it off disk;
570 * (ii) live metadata is requested but we have precommitted metadata cached
571 * and no devices are suspended so caller may read it off disk.
573 * If live metadata is requested but we have precommitted metadata cached
574 * and devices are suspended, we assume this precommitted metadata has
575 * already been preloaded and committed so it's OK to return it as live.
576 * Note that we do not clear the PRECOMMITTED flag.
578 if ((precommitted
&& !vginfo
->precommitted
) ||
579 (!precommitted
&& vginfo
->precommitted
&& !memlock()))
582 if (!(fid
= vginfo
->fmt
->ops
->create_instance(vginfo
->fmt
,
587 if (!(vg
= import_vg_from_buffer(vginfo
->vgmetadata
, fid
)) ||
589 _free_cached_vgmetadata(vginfo
);
594 log_debug("Using cached %smetadata for VG %s.",
595 vginfo
->precommitted
? "pre-committed" : "", vginfo
->vgname
);
600 struct dm_list
*lvmcache_get_vgids(struct cmd_context
*cmd
, int full_scan
)
602 struct dm_list
*vgids
;
603 struct lvmcache_vginfo
*vginfo
;
605 lvmcache_label_scan(cmd
, full_scan
);
607 if (!(vgids
= str_list_create(cmd
->mem
))) {
608 log_error("vgids list allocation failed");
612 dm_list_iterate_items(vginfo
, &_vginfos
) {
613 if (!str_list_add(cmd
->mem
, vgids
,
614 dm_pool_strdup(cmd
->mem
, vginfo
->vgid
))) {
615 log_error("strlist allocation failed");
623 struct dm_list
*lvmcache_get_vgnames(struct cmd_context
*cmd
, int full_scan
)
625 struct dm_list
*vgnames
;
626 struct lvmcache_vginfo
*vginfo
;
628 lvmcache_label_scan(cmd
, full_scan
);
630 if (!(vgnames
= str_list_create(cmd
->mem
))) {
631 log_errno(ENOMEM
, "vgnames list allocation failed");
635 dm_list_iterate_items(vginfo
, &_vginfos
) {
636 if (!str_list_add(cmd
->mem
, vgnames
,
637 dm_pool_strdup(cmd
->mem
, vginfo
->vgname
))) {
638 log_errno(ENOMEM
, "strlist allocation failed");
646 struct dm_list
*lvmcache_get_pvids(struct cmd_context
*cmd
, const char *vgname
,
649 struct dm_list
*pvids
;
650 struct lvmcache_vginfo
*vginfo
;
651 struct lvmcache_info
*info
;
653 if (!(pvids
= str_list_create(cmd
->mem
))) {
654 log_error("pvids list allocation failed");
658 if (!(vginfo
= vginfo_from_vgname(vgname
, vgid
)))
661 dm_list_iterate_items(info
, &vginfo
->infos
) {
662 if (!str_list_add(cmd
->mem
, pvids
,
663 dm_pool_strdup(cmd
->mem
, info
->dev
->pvid
))) {
664 log_error("strlist allocation failed");
672 struct device
*device_from_pvid(struct cmd_context
*cmd
, struct id
*pvid
)
675 struct lvmcache_info
*info
;
677 /* Already cached ? */
678 if ((info
= info_from_pvid((char *) pvid
, 0))) {
679 if (label_read(info
->dev
, &label
, UINT64_C(0))) {
680 info
= (struct lvmcache_info
*) label
->info
;
681 if (id_equal(pvid
, (struct id
*) &info
->dev
->pvid
))
686 lvmcache_label_scan(cmd
, 0);
689 if ((info
= info_from_pvid((char *) pvid
, 0))) {
690 if (label_read(info
->dev
, &label
, UINT64_C(0))) {
691 info
= (struct lvmcache_info
*) label
->info
;
692 if (id_equal(pvid
, (struct id
*) &info
->dev
->pvid
))
700 lvmcache_label_scan(cmd
, 2);
703 if ((info
= info_from_pvid((char *) pvid
, 0))) {
704 if (label_read(info
->dev
, &label
, UINT64_C(0))) {
705 info
= (struct lvmcache_info
*) label
->info
;
706 if (id_equal(pvid
, (struct id
*) &info
->dev
->pvid
))
714 static int _free_vginfo(struct lvmcache_vginfo
*vginfo
)
716 struct lvmcache_vginfo
*primary_vginfo
, *vginfo2
;
719 _free_cached_vgmetadata(vginfo
);
721 vginfo2
= primary_vginfo
= vginfo_from_vgname(vginfo
->vgname
, NULL
);
723 if (vginfo
== primary_vginfo
) {
724 dm_hash_remove(_vgname_hash
, vginfo
->vgname
);
725 if (vginfo
->next
&& !dm_hash_insert(_vgname_hash
, vginfo
->vgname
,
727 log_error("_vgname_hash re-insertion for %s failed",
732 if (vginfo2
->next
== vginfo
) {
733 vginfo2
->next
= vginfo
->next
;
736 while ((vginfo2
= primary_vginfo
->next
));
739 dm_free(vginfo
->vgname
);
741 if (vginfo
->creation_host
)
742 dm_free(vginfo
->creation_host
);
744 if (*vginfo
->vgid
&& _vgid_hash
&&
745 vginfo_from_vgid(vginfo
->vgid
) == vginfo
)
746 dm_hash_remove(_vgid_hash
, vginfo
->vgid
);
748 dm_list_del(&vginfo
->list
);
756 * vginfo must be info->vginfo unless info is NULL
758 static int _drop_vginfo(struct lvmcache_info
*info
, struct lvmcache_vginfo
*vginfo
)
761 _vginfo_detach_info(info
);
763 /* vginfo still referenced? */
764 if (!vginfo
|| is_orphan_vg(vginfo
->vgname
) ||
765 !dm_list_empty(&vginfo
->infos
))
768 if (!_free_vginfo(vginfo
))
775 void lvmcache_del(struct lvmcache_info *info)
777 if (info->dev->pvid[0] && _pvid_hash)
778 dm_hash_remove(_pvid_hash, info->dev->pvid);
780 _drop_vginfo(info, info->vginfo);
782 info->label->labeller->ops->destroy_label(info->label->labeller,
789 static int _lvmcache_update_pvid(struct lvmcache_info
*info
, const char *pvid
)
792 * Nothing to do if already stored with same pvid.
794 if (((dm_hash_lookup(_pvid_hash
, pvid
)) == info
) &&
795 !strcmp(info
->dev
->pvid
, pvid
))
797 if (*info
->dev
->pvid
)
798 dm_hash_remove(_pvid_hash
, info
->dev
->pvid
);
799 strncpy(info
->dev
->pvid
, pvid
, sizeof(info
->dev
->pvid
));
800 if (!dm_hash_insert(_pvid_hash
, pvid
, info
)) {
801 log_error("_lvmcache_update: pvid insertion failed: %s", pvid
);
809 * vginfo must be info->vginfo unless info is NULL (orphans)
811 static int _lvmcache_update_vgid(struct lvmcache_info
*info
,
812 struct lvmcache_vginfo
*vginfo
,
815 if (!vgid
|| !vginfo
||
816 !strncmp(vginfo
->vgid
, vgid
, ID_LEN
))
819 if (vginfo
&& *vginfo
->vgid
)
820 dm_hash_remove(_vgid_hash
, vginfo
->vgid
);
822 log_debug("lvmcache: %s: clearing VGID", info
? dev_name(info
->dev
) : vginfo
->vgname
);
826 strncpy(vginfo
->vgid
, vgid
, ID_LEN
);
827 vginfo
->vgid
[ID_LEN
] = '\0';
828 if (!dm_hash_insert(_vgid_hash
, vginfo
->vgid
, vginfo
)) {
829 log_error("_lvmcache_update: vgid hash insertion failed: %s",
834 if (!is_orphan_vg(vginfo
->vgname
))
835 log_debug("lvmcache: %s: setting %s VGID to %s",
836 dev_name(info
->dev
), vginfo
->vgname
,
842 static int _insert_vginfo(struct lvmcache_vginfo
*new_vginfo
, const char *vgid
,
843 uint32_t vgstatus
, const char *creation_host
,
844 struct lvmcache_vginfo
*primary_vginfo
)
846 struct lvmcache_vginfo
*last_vginfo
= primary_vginfo
;
847 char uuid_primary
[64] __attribute((aligned(8)));
848 char uuid_new
[64] __attribute((aligned(8)));
851 /* Pre-existing VG takes precedence. Unexported VG takes precedence. */
852 if (primary_vginfo
) {
853 if (!id_write_format((const struct id
*)vgid
, uuid_new
, sizeof(uuid_new
)))
856 if (!id_write_format((const struct id
*)&primary_vginfo
->vgid
, uuid_primary
,
857 sizeof(uuid_primary
)))
861 * If Primary not exported, new exported => keep
862 * Else Primary exported, new not exported => change
863 * Else Primary has hostname for this machine => keep
864 * Else Primary has no hostname, new has one => change
865 * Else New has hostname for this machine => change
868 if (!(primary_vginfo
->status
& EXPORTED_VG
) &&
869 (vgstatus
& EXPORTED_VG
))
870 log_error("WARNING: Duplicate VG name %s: "
871 "Existing %s takes precedence over "
872 "exported %s", new_vginfo
->vgname
,
873 uuid_primary
, uuid_new
);
874 else if ((primary_vginfo
->status
& EXPORTED_VG
) &&
875 !(vgstatus
& EXPORTED_VG
)) {
876 log_error("WARNING: Duplicate VG name %s: "
877 "%s takes precedence over exported %s",
878 new_vginfo
->vgname
, uuid_new
,
881 } else if (primary_vginfo
->creation_host
&&
882 !strcmp(primary_vginfo
->creation_host
,
883 primary_vginfo
->fmt
->cmd
->hostname
))
884 log_error("WARNING: Duplicate VG name %s: "
885 "Existing %s (created here) takes precedence "
886 "over %s", new_vginfo
->vgname
, uuid_primary
,
888 else if (!primary_vginfo
->creation_host
&& creation_host
) {
889 log_error("WARNING: Duplicate VG name %s: "
890 "%s (with creation_host) takes precedence over %s",
891 new_vginfo
->vgname
, uuid_new
,
894 } else if (creation_host
&&
895 !strcmp(creation_host
,
896 primary_vginfo
->fmt
->cmd
->hostname
)) {
897 log_error("WARNING: Duplicate VG name %s: "
898 "%s (created here) takes precedence over %s",
899 new_vginfo
->vgname
, uuid_new
,
905 while (last_vginfo
->next
)
906 last_vginfo
= last_vginfo
->next
;
907 last_vginfo
->next
= new_vginfo
;
911 dm_hash_remove(_vgname_hash
, primary_vginfo
->vgname
);
914 if (!dm_hash_insert(_vgname_hash
, new_vginfo
->vgname
, new_vginfo
)) {
915 log_error("cache_update: vg hash insertion failed: %s",
921 new_vginfo
->next
= primary_vginfo
;
926 static int _lvmcache_update_vgname(struct lvmcache_info
*info
,
927 const char *vgname
, const char *vgid
,
928 uint32_t vgstatus
, const char *creation_host
,
929 const struct format_type
*fmt
)
931 struct lvmcache_vginfo
*vginfo
, *primary_vginfo
, *orphan_vginfo
;
932 struct lvmcache_info
*info2
, *info3
;
934 // struct lvmcache_vginfo *old_vginfo, *next;
936 if (!vgname
|| (info
&& info
->vginfo
&& !strcmp(info
->vginfo
->vgname
, vgname
)))
939 /* Remove existing vginfo entry */
941 _drop_vginfo(info
, info
->vginfo
);
943 /* Get existing vginfo or create new one */
944 if (!(vginfo
= vginfo_from_vgname(vgname
, vgid
))) {
945 /*** FIXME - vginfo ends up duplicated instead of renamed.
946 // Renaming? This lookup fails.
947 if ((vginfo = vginfo_from_vgid(vgid))) {
949 old_vginfo = vginfo_from_vgname(vginfo->vgname, NULL);
950 if (old_vginfo == vginfo) {
951 dm_hash_remove(_vgname_hash, old_vginfo->vgname);
952 if (old_vginfo->next) {
953 if (!dm_hash_insert(_vgname_hash, old_vginfo->vgname, old_vginfo->next)) {
954 log_error("vg hash re-insertion failed: %s",
960 if (old_vginfo->next == vginfo) {
961 old_vginfo->next = vginfo->next;
964 } while ((old_vginfo = old_vginfo->next));
967 dm_free(vginfo->vgname);
968 if (!(vginfo->vgname = dm_strdup(vgname))) {
969 log_error("cache vgname alloc failed for %s", vgname);
973 // Rename so can assume new name does not already exist
974 if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo->next)) {
975 log_error("vg hash re-insertion failed: %s",
981 if (!(vginfo
= dm_malloc(sizeof(*vginfo
)))) {
982 log_error("lvmcache_update_vgname: list alloc failed");
985 memset(vginfo
, 0, sizeof(*vginfo
));
986 if (!(vginfo
->vgname
= dm_strdup(vgname
))) {
988 log_error("cache vgname alloc failed for %s", vgname
);
991 dm_list_init(&vginfo
->infos
);
994 * If we're scanning and there's an invalidated entry, remove it.
995 * Otherwise we risk bogus warnings of duplicate VGs.
997 while ((primary_vginfo
= vginfo_from_vgname(vgname
, NULL
)) &&
998 _scanning_in_progress
&& _vginfo_is_invalid(primary_vginfo
))
999 dm_list_iterate_items_safe(info2
, info3
, &primary_vginfo
->infos
) {
1000 orphan_vginfo
= vginfo_from_vgname(primary_vginfo
->fmt
->orphan_vg_name
, NULL
);
1001 _drop_vginfo(info2
, primary_vginfo
);
1002 _vginfo_attach_info(orphan_vginfo
, info2
);
1004 sprintf(mdabuf
, " with %u mdas",
1005 dm_list_size(&info2
->mdas
));
1008 log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
1009 dev_name(info2
->dev
),
1010 vgname
, orphan_vginfo
->vgid
[0] ? " (" : "",
1011 orphan_vginfo
->vgid
[0] ? orphan_vginfo
->vgid
: "",
1012 orphan_vginfo
->vgid
[0] ? ")" : "", mdabuf
);
1015 if (!_insert_vginfo(vginfo
, vgid
, vgstatus
, creation_host
,
1017 dm_free(vginfo
->vgname
);
1021 /* Ensure orphans appear last on list_iterate */
1022 if (is_orphan_vg(vgname
))
1023 dm_list_add(&_vginfos
, &vginfo
->list
);
1025 dm_list_add_h(&_vginfos
, &vginfo
->list
);
1032 _vginfo_attach_info(vginfo
, info
);
1033 else if (!_lvmcache_update_vgid(NULL
, vginfo
, vgid
)) /* Orphans */
1036 _update_cache_vginfo_lock_state(vginfo
, vgname_is_locked(vgname
));
1038 /* FIXME Check consistency of list! */
1043 sprintf(mdabuf
, " with %u mdas", dm_list_size(&info
->mdas
));
1046 log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
1047 dev_name(info
->dev
),
1048 vgname
, vginfo
->vgid
[0] ? " (" : "",
1049 vginfo
->vgid
[0] ? vginfo
->vgid
: "",
1050 vginfo
->vgid
[0] ? ")" : "", mdabuf
);
1052 log_debug("lvmcache: initialised VG %s", vgname
);
1057 static int _lvmcache_update_vgstatus(struct lvmcache_info
*info
, uint32_t vgstatus
,
1058 const char *creation_host
)
1060 if (!info
|| !info
->vginfo
)
1063 if ((info
->vginfo
->status
& EXPORTED_VG
) != (vgstatus
& EXPORTED_VG
))
1064 log_debug("lvmcache: %s: VG %s %s exported",
1065 dev_name(info
->dev
), info
->vginfo
->vgname
,
1066 vgstatus
& EXPORTED_VG
? "now" : "no longer");
1068 info
->vginfo
->status
= vgstatus
;
1073 if (info
->vginfo
->creation_host
&& !strcmp(creation_host
,
1074 info
->vginfo
->creation_host
))
1077 if (info
->vginfo
->creation_host
)
1078 dm_free(info
->vginfo
->creation_host
);
1080 if (!(info
->vginfo
->creation_host
= dm_strdup(creation_host
))) {
1081 log_error("cache creation host alloc failed for %s",
1086 log_debug("lvmcache: %s: VG %s: Set creation host to %s.",
1087 dev_name(info
->dev
), info
->vginfo
->vgname
, creation_host
);
1092 int lvmcache_add_orphan_vginfo(const char *vgname
, struct format_type
*fmt
)
1094 if (!_lock_hash
&& !lvmcache_init()) {
1095 log_error("Internal cache initialisation failed");
1099 return _lvmcache_update_vgname(NULL
, vgname
, vgname
, 0, "", fmt
);
1102 int lvmcache_update_vgname_and_id(struct lvmcache_info
*info
,
1103 const char *vgname
, const char *vgid
,
1104 uint32_t vgstatus
, const char *creation_host
)
1106 if (!vgname
&& !info
->vginfo
) {
1107 log_error("Internal error: NULL vgname handed to cache");
1108 /* FIXME Remove this */
1109 vgname
= info
->fmt
->orphan_vg_name
;
1113 /* If PV without mdas is already in a real VG, don't make it orphan */
1114 if (is_orphan_vg(vgname
) && info
->vginfo
&& !dm_list_size(&info
->mdas
) &&
1115 !is_orphan_vg(info
->vginfo
->vgname
) && memlock())
1118 /* If moving PV from orphan to real VG, always mark it valid */
1119 if (!is_orphan_vg(vgname
))
1120 info
->status
&= ~CACHE_INVALID
;
1122 if (!_lvmcache_update_vgname(info
, vgname
, vgid
, vgstatus
,
1123 creation_host
, info
->fmt
) ||
1124 !_lvmcache_update_vgid(info
, info
->vginfo
, vgid
) ||
1125 !_lvmcache_update_vgstatus(info
, vgstatus
, creation_host
))
1131 int lvmcache_update_vg(struct volume_group
*vg
, unsigned precommitted
)
1133 struct pv_list
*pvl
;
1134 struct lvmcache_info
*info
;
1135 char pvid_s
[ID_LEN
+ 1] __attribute((aligned(8)));
1137 pvid_s
[sizeof(pvid_s
) - 1] = '\0';
1139 dm_list_iterate_items(pvl
, &vg
->pvs
) {
1140 strncpy(pvid_s
, (char *) &pvl
->pv
->id
, sizeof(pvid_s
) - 1);
1141 /* FIXME Could pvl->pv->dev->pvid ever be different? */
1142 if ((info
= info_from_pvid(pvid_s
, 0)) &&
1143 !lvmcache_update_vgname_and_id(info
, vg
->name
,
1149 /* store text representation of vg to cache */
1150 if (vg
->cmd
->current_settings
.cache_vgmetadata
)
1151 _store_metadata(vg
, precommitted
);
1156 struct lvmcache_info
*lvmcache_add(struct labeller
*labeller
, const char *pvid
,
1158 const char *vgname
, const char *vgid
,
1161 struct label
*label
;
1162 struct lvmcache_info
*existing
, *info
;
1163 char pvid_s
[ID_LEN
+ 1] __attribute((aligned(8)));
1165 if (!_vgname_hash
&& !lvmcache_init()) {
1166 log_error("Internal cache initialisation failed");
1170 strncpy(pvid_s
, pvid
, sizeof(pvid_s
));
1171 pvid_s
[sizeof(pvid_s
) - 1] = '\0';
1173 if (!(existing
= info_from_pvid(pvid_s
, 0)) &&
1174 !(existing
= info_from_pvid(dev
->pvid
, 0))) {
1175 if (!(label
= label_create(labeller
)))
1177 if (!(info
= dm_malloc(sizeof(*info
)))) {
1178 log_error("lvmcache_info allocation failed");
1179 label_destroy(label
);
1182 memset(info
, 0, sizeof(*info
));
1185 info
->label
= label
;
1186 dm_list_init(&info
->list
);
1189 if (existing
->dev
!= dev
) {
1190 /* Is the existing entry a duplicate pvid e.g. md ? */
1191 if (dev_subsystem_part_major(existing
->dev
) &&
1192 !dev_subsystem_part_major(dev
)) {
1193 log_very_verbose("Ignoring duplicate PV %s on "
1195 pvid
, dev_name(dev
),
1196 dev_subsystem_name(existing
->dev
),
1197 dev_name(existing
->dev
));
1199 } else if (dm_is_dm_major(MAJOR(existing
->dev
->dev
)) &&
1200 !dm_is_dm_major(MAJOR(dev
->dev
))) {
1201 log_very_verbose("Ignoring duplicate PV %s on "
1203 pvid
, dev_name(dev
),
1204 dev_name(existing
->dev
));
1206 } else if (!dev_subsystem_part_major(existing
->dev
) &&
1207 dev_subsystem_part_major(dev
))
1208 log_very_verbose("Duplicate PV %s on %s - "
1209 "using %s %s", pvid
,
1210 dev_name(existing
->dev
),
1211 dev_subsystem_name(existing
->dev
),
1213 else if (!dm_is_dm_major(MAJOR(existing
->dev
->dev
)) &&
1214 dm_is_dm_major(MAJOR(dev
->dev
)))
1215 log_very_verbose("Duplicate PV %s on %s - "
1216 "using dm %s", pvid
,
1217 dev_name(existing
->dev
),
1219 /* FIXME If both dm, check dependencies */
1220 //else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
1221 //dm_is_dm_major(MAJOR(dev->dev)))
1223 else if (!strcmp(pvid_s
, existing
->dev
->pvid
))
1224 log_error("Found duplicate PV %s: using %s not "
1225 "%s", pvid
, dev_name(dev
),
1226 dev_name(existing
->dev
));
1228 if (strcmp(pvid_s
, existing
->dev
->pvid
))
1229 log_debug("Updating pvid cache to %s (%s) from %s (%s)",
1230 pvid_s
, dev_name(dev
),
1231 existing
->dev
->pvid
, dev_name(existing
->dev
));
1232 /* Switch over to new preferred device */
1233 existing
->dev
= dev
;
1235 /* Has labeller changed? */
1236 if (info
->label
->labeller
!= labeller
) {
1237 label_destroy(info
->label
);
1238 if (!(info
->label
= label_create(labeller
)))
1239 /* FIXME leaves info without label! */
1241 info
->label
->info
= info
;
1243 label
= info
->label
;
1246 info
->fmt
= (const struct format_type
*) labeller
->private;
1247 info
->status
|= CACHE_INVALID
;
1249 if (!_lvmcache_update_pvid(info
, pvid_s
)) {
1252 label_destroy(label
);
1257 if (!lvmcache_update_vgname_and_id(info
, vgname
, vgid
, vgstatus
, NULL
)) {
1259 dm_hash_remove(_pvid_hash
, pvid_s
);
1260 strcpy(info
->dev
->pvid
, "");
1262 label_destroy(label
);
1270 static void _lvmcache_destroy_entry(struct lvmcache_info
*info
)
1272 _vginfo_detach_info(info
);
1273 strcpy(info
->dev
->pvid
, "");
1274 label_destroy(info
->label
);
1278 static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo
*vginfo
)
1280 struct lvmcache_vginfo
*next
;
1283 next
= vginfo
->next
;
1284 if (!_free_vginfo(vginfo
))
1286 } while ((vginfo
= next
));
1289 static void _lvmcache_destroy_lockname(struct dm_hash_node
*n
)
1293 if (!dm_hash_get_data(_lock_hash
, n
))
1296 vgname
= dm_hash_get_key(_lock_hash
, n
);
1298 if (!strcmp(vgname
, VG_GLOBAL
))
1299 _vg_global_lock_held
= 1;
1301 log_error("Internal error: Volume Group %s was not unlocked",
1302 dm_hash_get_key(_lock_hash
, n
));
1305 void lvmcache_destroy(struct cmd_context
*cmd
, int retain_orphans
)
1307 struct dm_hash_node
*n
;
1308 log_verbose("Wiping internal VG cache");
1313 dm_hash_destroy(_vgid_hash
);
1318 dm_hash_iter(_pvid_hash
, (dm_hash_iterate_fn
) _lvmcache_destroy_entry
);
1319 dm_hash_destroy(_pvid_hash
);
1324 dm_hash_iter(_vgname_hash
,
1325 (dm_hash_iterate_fn
) _lvmcache_destroy_vgnamelist
);
1326 dm_hash_destroy(_vgname_hash
);
1327 _vgname_hash
= NULL
;
1331 dm_hash_iterate(n
, _lock_hash
)
1332 _lvmcache_destroy_lockname(n
);
1333 dm_hash_destroy(_lock_hash
);
1337 if (!dm_list_empty(&_vginfos
))
1338 log_error("Internal error: _vginfos list should be empty");
1339 dm_list_init(&_vginfos
);
1342 init_lvmcache_orphans(cmd
);