summaryrefslogtreecommitdiff
path: root/lib/locking
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2019-11-26 14:34:43 -0600
committerDavid Teigland <teigland@redhat.com>2019-11-26 14:34:43 -0600
commit2037476008ea42e79388a407355c7f285656a5d9 (patch)
tree306bc5b1a4f0b10338c55b4c5f9b7240a3c282c0 /lib/locking
parent1c9b36618ec8357350ed4d83c807ae0bf27a12be (diff)
downloadlvm2-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.c14
-rw-r--r--lib/locking/locking.h1
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);