mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +03:00
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.
This commit is contained in:
parent
1c9b36618e
commit
2037476008
@ -338,7 +338,7 @@ int sync_local_dev_names(struct cmd_context* cmd)
|
|||||||
* an explicitly acquired ex global lock to sh in process_each.
|
* 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;
|
uint32_t flags = 0;
|
||||||
int ret;
|
int ret;
|
||||||
@ -346,6 +346,9 @@ static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert)
|
|||||||
if (convert)
|
if (convert)
|
||||||
flags |= LCK_CONVERT;
|
flags |= LCK_CONVERT;
|
||||||
|
|
||||||
|
if (nonblock)
|
||||||
|
flags |= LCK_NONBLOCK;
|
||||||
|
|
||||||
if (!strcmp(mode, "ex")) {
|
if (!strcmp(mode, "ex")) {
|
||||||
flags |= LCK_WRITE;
|
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)
|
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)
|
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"))
|
if (cmd->lockf_global_ex && !strcmp(mode, "ex"))
|
||||||
return 1;
|
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)
|
int lock_global(struct cmd_context *cmd, const char *mode)
|
||||||
|
@ -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(struct cmd_context *cmd, const char *mode);
|
||||||
int lockf_global_convert(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(struct cmd_context *cmd, const char *mode);
|
||||||
int lock_global_convert(struct cmd_context *cmd, const char *mode);
|
int lock_global_convert(struct cmd_context *cmd, const char *mode);
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ static int _do_write_priority_flock(const char *file, int *fd, int operation, ui
|
|||||||
strcpy(file_aux, file);
|
strcpy(file_aux, file);
|
||||||
strcat(file_aux, AUX_LOCK_SUFFIX);
|
strcat(file_aux, AUX_LOCK_SUFFIX);
|
||||||
|
|
||||||
if ((r = _do_flock(file_aux, &fd_aux, LOCK_EX, 0))) {
|
if ((r = _do_flock(file_aux, &fd_aux, LOCK_EX, nonblock))) {
|
||||||
if (operation == LOCK_EX) {
|
if (operation == LOCK_EX) {
|
||||||
r = _do_flock(file, fd, operation, nonblock);
|
r = _do_flock(file, fd, operation, nonblock);
|
||||||
_undo_flock(file_aux, fd_aux);
|
_undo_flock(file_aux, fd_aux);
|
||||||
|
@ -5577,10 +5577,11 @@ int pvcreate_each_device(struct cmd_context *cmd,
|
|||||||
* Reacquire the lock that was released above before waiting, then
|
* Reacquire the lock that was released above before waiting, then
|
||||||
* check again that the devices can still be used. If the second loop
|
* check again that the devices can still be used. If the second loop
|
||||||
* finds them changed, or can't find them any more, then they aren't
|
* finds them changed, or can't find them any more, then they aren't
|
||||||
* used.
|
* used. Use a non-blocking request when reacquiring to avoid
|
||||||
|
* potential deadlock since this is not the normal locking sequence.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!lockf_global(cmd, "ex")) {
|
if (!lockf_global_nonblock(cmd, "ex")) {
|
||||||
log_error("Failed to reacquire global lock after prompt.");
|
log_error("Failed to reacquire global lock after prompt.");
|
||||||
goto_out;
|
goto_out;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user