From 80f7f6e0fdd7672a3bbb781b5edbc73c0699c539 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 Mar 2019 17:13:26 +0800 Subject: [PATCH 01/19] Remove VG lock ordering check Four commands lock two VGs at a time: - vgsplit and vgmerge already have their own logic to acquire the locks in the correct order. - vgimportclone and vgrename disable this ordering check. --- lib/cache/lvmcache.c | 66 ------------------------------------------- lib/cache/lvmcache.h | 1 - lib/locking/locking.c | 5 ---- tools/toollib.c | 8 ------ tools/vgimportclone.c | 4 --- tools/vgrename.c | 5 ---- 6 files changed, 89 deletions(-) diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 3e681a2..1a2e987 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -105,7 +105,6 @@ static int _has_scanned = 0; static int _vgs_locked = 0; static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */ static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */ -static int _suppress_lock_ordering = 0; int lvmcache_init(struct cmd_context *cmd) { @@ -547,71 +546,6 @@ void lvmcache_drop_metadata(const char *vgname, int drop_precommitted) _drop_metadata(vgname, drop_precommitted); } -/* - * Ensure vgname2 comes after vgname1 alphabetically. - * Orphan locks come last. - * VG_GLOBAL comes first. - */ -static int _vgname_order_correct(const char *vgname1, const char *vgname2) -{ - if (is_global_vg(vgname1)) - return 1; - - if (is_global_vg(vgname2)) - return 0; - - if (is_orphan_vg(vgname1)) - return 0; - - if (is_orphan_vg(vgname2)) - return 1; - - if (strcmp(vgname1, vgname2) < 0) - return 1; - - return 0; -} - -void lvmcache_lock_ordering(int enable) -{ - _suppress_lock_ordering = !enable; -} - -/* - * Ensure VG locks are acquired in alphabetical order. - */ -int lvmcache_verify_lock_order(const char *vgname) -{ - struct dm_hash_node *n; - const char *vgname2; - - if (_suppress_lock_ordering) - return 1; - - if (!_lock_hash) - return 1; - - dm_hash_iterate(n, _lock_hash) { - if (!dm_hash_get_data(_lock_hash, n)) - return_0; - - if (!(vgname2 = dm_hash_get_key(_lock_hash, n))) { - log_error(INTERNAL_ERROR "VG lock %s hits NULL.", - vgname); - return 0; - } - - if (!_vgname_order_correct(vgname2, vgname)) { - log_errno(EDEADLK, INTERNAL_ERROR "VG lock %s must " - "be requested before %s, not after.", - vgname, vgname2); - return 0; - } - } - - return 1; -} - void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unused))) { if (dm_hash_lookup(_lock_hash, vgname)) diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index bf976e9..e9e6932 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -87,7 +87,6 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted); void lvmcache_lock_vgname(const char *vgname, int read_only); void lvmcache_unlock_vgname(const char *vgname); -int lvmcache_verify_lock_order(const char *vgname); /* Queries */ const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd, const char *vgname, const char *vgid, unsigned revalidate_labels); diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 2584227..093dbbd 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -319,11 +319,6 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str /* Global VG_ORPHANS lock covers all orphan formats. */ if (is_orphan_vg(vol)) vol = VG_ORPHANS; - /* VG locks alphabetical, ORPHAN lock last */ - if ((lck_type != LCK_UNLOCK) && - !(flags & LCK_CACHE) && - !lvmcache_verify_lock_order(vol)) - return_0; if ((flags == LCK_VG_DROP_CACHE) || (strcmp(vol, VG_GLOBAL) && strcmp(vol, VG_SYNC_NAMES))) { diff --git a/tools/toollib.c b/tools/toollib.c index 01686b0..ce877cc 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -5514,14 +5514,6 @@ int pvcreate_each_device(struct cmd_context *cmd, dm_list_add(&pp->arg_devices, &pd->list); } - /* - * This function holds the orphans lock while reading VGs to look for - * devices. This means the orphans lock is held while VG locks are - * acquired, which is against lvmcache lock ordering rules, so disable - * the lvmcache lock ordering checks. - */ - lvmcache_lock_ordering(0); - /* * Clear the cache before acquiring the orphan lock. (Clearing the * cache with locks held is an error.) We want the orphan lock diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c index c4c5d4c..087078a 100644 --- a/tools/vgimportclone.c +++ b/tools/vgimportclone.c @@ -342,9 +342,6 @@ retry_name: log_debug("Changing VG %s to %s.", vp.old_vgname, vp.new_vgname); - /* We don't care if the new name comes before the old in lock order. */ - lvmcache_lock_ordering(0); - if (!lock_vol(cmd, vp.new_vgname, LCK_VG_WRITE, NULL)) { log_error("Can't get lock for new VG name %s", vp.new_vgname); goto out; @@ -363,7 +360,6 @@ out: unlock_vg(cmd, NULL, VG_GLOBAL); internal_filter_clear(); init_internal_filtering(0); - lvmcache_lock_ordering(1); destroy_processing_handle(cmd, handle); /* Enable lvmetad again if no duplicates are left. */ diff --git a/tools/vgrename.c b/tools/vgrename.c index 4f2a08b..bbc3087 100644 --- a/tools/vgrename.c +++ b/tools/vgrename.c @@ -99,13 +99,8 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name, * this uuid-for-name case. */ if (vp->lock_vg_old_first || vp->old_name_is_uuid) { - if (vp->old_name_is_uuid) - lvmcache_lock_ordering(0); - if (!_lock_new_vg_for_rename(cmd, vp->vg_name_new)) return ECMD_FAILED; - - lvmcache_lock_ordering(1); } dev_dir = cmd->dev_dir; -- 2.19.1