diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c index 75dd9f2ac..7e85016d0 100644 --- a/lib/locking/lvmlockd.c +++ b/lib/locking/lvmlockd.c @@ -2808,9 +2808,28 @@ int lockd_lv(struct cmd_context *cmd, struct logical_volume *lv, return 0; } + if (!_lvmlockd_connected && !strcmp(def_mode, "un")) { + log_debug("Skip LV unlock: no lvmlockd"); + return 1; + } + if (!_lvmlockd_connected) return 0; + /* + * This addresses the specific case of: vgchange -an vg + * when vg is a shared VG that is not started. Without + * this check, the command will try and fail to unlock + * every LV, which is wasted effort if the lockspace is + * not started, especially with many LVs in the VG. + * The command still attempts to deactivate the LVs, + * which it should in case they are active for some reason. + */ + if (lv->vg->lockd_not_started && !strcmp(def_mode, "un")) { + log_debug("Skip LV unlock: no lockspace"); + return 1; + } + if (lv_is_thin_type(lv)) return _lockd_lv_thin(cmd, lv, def_mode, flags); diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index c120297e6..d21df54c5 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -3862,6 +3862,9 @@ static int _access_vg_lock_type(struct cmd_context *cmd, struct volume_group *vg return 0; } + if (lockd_state & (LDST_FAIL_NOLS | LDST_FAIL_STARTING)) + vg->lockd_not_started = 1; + log_warn("Reading VG %s without a lock.", vg->name); return 1; } diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h index 96ab6a0b2..ae79e6162 100644 --- a/lib/metadata/vg.h +++ b/lib/metadata/vg.h @@ -42,6 +42,7 @@ struct volume_group { struct lvmcache_vginfo *vginfo; uint32_t seqno; /* Metadata sequence number */ unsigned skip_validate_lock_args : 1; + unsigned lockd_not_started : 1; unsigned needs_backup : 1; unsigned needs_write_and_commit : 1; uint32_t write_count; /* count the number of vg_write calls */