diff options
author | David Teigland <teigland@redhat.com> | 2019-11-26 14:34:43 -0600 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2019-11-26 14:34:43 -0600 |
commit | 2037476008ea42e79388a407355c7f285656a5d9 (patch) | |
tree | 306bc5b1a4f0b10338c55b4c5f9b7240a3c282c0 /lib/locking | |
parent | 1c9b36618ec8357350ed4d83c807ae0bf27a12be (diff) | |
download | lvm2-2037476008ea42e79388a407355c7f285656a5d9.tar.gz |
pvcreate,pvremove: fix reacquiring global lock after prompt
When pvcreate/pvremove prompt the user, they first release
the global lock, then acquire it again after the prompt,
to avoid blocking other commands while waiting for a user
response. This release/reacquire changes the locking
order with respect to the hints flock (and potentially other
locks). So, to avoid deadlock, use a nonblocking request
when reacquiring the global lock.
Diffstat (limited to 'lib/locking')
-rw-r--r-- | lib/locking/locking.c | 14 | ||||
-rw-r--r-- | lib/locking/locking.h | 1 |
2 files changed, 12 insertions, 3 deletions
diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 3058a8ba0..65ff8c221 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -338,7 +338,7 @@ int sync_local_dev_names(struct cmd_context* cmd) * an explicitly acquired ex global lock to sh in process_each. */ -static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert) +static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert, int nonblock) { uint32_t flags = 0; int ret; @@ -346,6 +346,9 @@ static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert) if (convert) flags |= LCK_CONVERT; + if (nonblock) + flags |= LCK_NONBLOCK; + if (!strcmp(mode, "ex")) { flags |= LCK_WRITE; @@ -379,7 +382,7 @@ static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert) int lockf_global(struct cmd_context *cmd, const char *mode) { - return _lockf_global(cmd, mode, 0); + return _lockf_global(cmd, mode, 0, 0); } int lockf_global_convert(struct cmd_context *cmd, const char *mode) @@ -388,7 +391,12 @@ int lockf_global_convert(struct cmd_context *cmd, const char *mode) if (cmd->lockf_global_ex && !strcmp(mode, "ex")) return 1; - return _lockf_global(cmd, mode, 1); + return _lockf_global(cmd, mode, 1, 0); +} + +int lockf_global_nonblock(struct cmd_context *cmd, const char *mode) +{ + return _lockf_global(cmd, mode, 0, 1); } int lock_global(struct cmd_context *cmd, const char *mode) diff --git a/lib/locking/locking.h b/lib/locking/locking.h index 746667a9b..3e8ae6f0c 100644 --- a/lib/locking/locking.h +++ b/lib/locking/locking.h @@ -75,6 +75,7 @@ int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusiv int lockf_global(struct cmd_context *cmd, const char *mode); int lockf_global_convert(struct cmd_context *cmd, const char *mode); +int lockf_global_nonblock(struct cmd_context *cmd, const char *mode); int lock_global(struct cmd_context *cmd, const char *mode); int lock_global_convert(struct cmd_context *cmd, const char *mode); |