diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 156cb0db2..84ad4decd 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -11,6 +11,7 @@ #include "lvm-string.h" #include "activate.h" #include "toolcontext.h" +#include "memlock.h" #include #include @@ -62,6 +63,24 @@ static void _unblock_signals(void) return; } +static void _lock_memory(int flags) +{ + if (!(_locking.flags & LCK_PRE_MEMLOCK)) + return; + + if ((flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_SUSPEND) + memlock_inc(); +} + +static void _unlock_memory(int flags) +{ + if (!(_locking.flags & LCK_PRE_MEMLOCK)) + return; + + if ((flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_RESUME) + memlock_dec(); +} + void reset_locking(void) { int was_locked = _vg_lock_count; @@ -176,13 +195,16 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname) static int _lock_vol(struct cmd_context *cmd, const char *resource, int flags) { _block_signals(flags); + _lock_memory(flags); if (!(_locking.lock_resource(cmd, resource, flags))) { + _unlock_memory(flags); _unblock_signals(); return 0; } _update_vg_lock_count(flags); + _unlock_memory(flags); _unblock_signals(); return 1; @@ -221,6 +243,42 @@ int lock_vol(struct cmd_context *cmd, const char *vol, int flags) return 1; } +/* Unlock list of LVs */ +int unlock_lvs(struct cmd_context *cmd, struct list *lvs) +{ + struct list *lvh; + struct logical_volume *lv; + + list_iterate(lvh, lvs) { + lv = list_item(lvh, struct lv_list)->lv; + unlock_lv(cmd, lv->lvid.s); + } + + return 1; +} + +/* Lock a list of LVs */ +int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags) +{ + struct list *lvh; + struct logical_volume *lv; + + list_iterate(lvh, lvs) { + lv = list_item(lvh, struct lv_list)->lv; + if (!lock_vol(cmd, lv->lvid.s, flags)) { + log_error("Failed to suspend %s", lv->name); + list_uniterate(lvh, lvs, lvh) { + lv = list_item(lvh, struct lv_list)->lv; + unlock_lv(cmd, lv->lvid.s); + } + + return 0; + } + } + + return 1; +} + int vg_write_lock_held(void) { return _vg_write_lock_held; diff --git a/lib/locking/locking.h b/lib/locking/locking.h index 0dced7f52..ff6c6e0a2 100644 --- a/lib/locking/locking.h +++ b/lib/locking/locking.h @@ -71,3 +71,8 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname); #define unlock_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_UNLOCK) #define unlock_vg(cmd, vol) lock_vol(cmd, vol, LCK_VG_UNLOCK) + +/* Process list of LVs */ +int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags); +int unlock_lvs(struct cmd_context *cmd, struct list *lvs); + diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index a8ab3210d..47c5e6afd 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -731,42 +731,6 @@ int lv_remove(struct volume_group *vg, struct logical_volume *lv) return 1; } -/* Unlock list of LVs */ -int unlock_lvs(struct cmd_context *cmd, struct list *lvs) -{ - struct list *lvh; - struct logical_volume *lv; - - list_iterate(lvh, lvs) { - lv = list_item(lvh, struct lv_list)->lv; - unlock_lv(cmd, lv->lvid.s); - } - - return 1; -} - -/* Lock a list of LVs */ -int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags) -{ - struct list *lvh; - struct logical_volume *lv; - - list_iterate(lvh, lvs) { - lv = list_item(lvh, struct lv_list)->lv; - if (!lock_vol(cmd, lv->lvid.s, flags)) { - log_error("Failed to lock %s", lv->name); - list_uniterate(lvh, lvs, lvh) { - lv = list_item(lvh, struct lv_list)->lv; - unlock_lv(cmd, lv->lvid.s); - } - - return 0; - } - } - - return 1; -} - uint32_t find_free_lvnum(struct logical_volume *lv) { int lvnum_used[MAX_RESTRICTED_LVS + 1]; diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index e2f633229..91e35c705 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -426,10 +426,6 @@ int lv_extend_mirror(struct format_instance *fid, uint32_t extents, struct list *allocatable_pvs, uint32_t status); -/* Lock list of LVs */ -int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags); -int unlock_lvs(struct cmd_context *cmd, struct list *lvs); - /* lv must be part of vg->lvs */ int lv_remove(struct volume_group *vg, struct logical_volume *lv);