* 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;
if (convert)
flags |= LCK_CONVERT;
+ if (nonblock)
+ flags |= LCK_NONBLOCK;
+
if (!strcmp(mode, "ex")) {
flags |= LCK_WRITE;
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)
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)
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);
strcpy(file_aux, file);
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) {
r = _do_flock(file, fd, operation, nonblock);
_undo_flock(file_aux, fd_aux);
* Reacquire the lock that was released above before waiting, then
* 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
- * 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.");
goto_out;
}