Re: tramp (2.7.0-pre HEAD/dc0839de9b3654837ec8f5e66d187319b9eecd6f); bracktrace when saving modified remote file

Michael Albinus <[email protected]>
Newsgroups gmane.emacs.tramp
Message-ID <[email protected]>
Gregor Zattler <[email protected]> writes:

Hi Gregor,

> When I saved a modified buffer to it*'s associated
> remote file (via ssh on an Univention Corporate Server
> (debian/buster)), the file was saved but I got a
> backtrace, see below.
>
> I tried to reproduce (modify, save) with tramp-verbose
> set to 9 but no problem occured.

Well, this is a problem with Tramp for a long time. Tramp keeps a
connection to the remote host (say an ssh connection). Whenever Tramp
needs to know something, it sends a command over the connection, and
reads the reply.

This works fine when everything is serialized. But there are
asynchronous Emacs events which could trigger a new remote command while
another command is still waiting for the response. This cannot work,
because once a response arrives, Tramp wouldn't know which command is
waiting for what response.

Tramp has tried to fix this. It suppresses timers while waitng for a
response. Timers are the most likely trouble-shooter in this game.

Obviously, there are still cases where it doesn't work as expected. Like here.

> Here is the backtrace and further info (I redacted one
> directory name)

Lets' condense the backtrace to the relevant calls.

--8<---------------cut here---------------start------------->8---
> Debugger entered--Lisp error: (remote-file-error "Forbidden reentrant call of Tramp")
>   signal(remote-file-error ("Forbidden reentrant call of Tramp"))
>   tramp-send-command((tramp-file-name "ssh" "root" nil "fs2" nil "/data/projekte/Projekte/XXXXXXXXXXXX/Aufgaben/" nil) "test -r /data/projekte/Projekte/XXXXXXXXXXXX/Aufga...")
>   tramp-sh-handle-file-readable-p("/ssh:root@fs2:/data/projekte/Projekte/XXXXXXXXXXXX...")
>   dired-buffer-stale-p(t)
>   auto-revert-buffer(#<buffer Aufgaben>)
>   timer-event-handler([t 25836 43972 364989 5 auto-revert-buffers nil nil 762000 nil])
--8<---------------cut here---------------end--------------->8---

--8<---------------cut here---------------start------------->8---
>   accept-process-output(#<process *tramp/ssh root@fs2*> 0 nil t)
>   tramp-send-command((tramp-file-name "ssh" "root" nil "fs2" nil "/data/projekte/Projekte/XXXXXXXXXXXX/Aufgaben/" nil) "test -e /data/projekte/Projekte/XXXXXXXXXXXX/Aufga...")
>   file-exists-p("/ssh:root@fs2:/data/projekte/Projekte/XXXXXXXXXXXX...")
>   insert-directory("/ssh:root@fs2:/data/projekte/Projekte/XXXXXXXXXXXX..." "-altrF --group-directories-first --block-size='1" nil t)
>   dired-revert(ignore-auto dont-ask)
>   revert-buffer(ignore-auto dont-ask preserve-modes)
>   auto-revert-handler()
>   file-notify-handle-event((file-notify (#<process inotifywait> (delete) ".#MDMunattended--Antwortfile-Win11.txt") file-notify-callback))
>   tramp-sh-inotifywait-process-filter(#<process inotifywait> "/data/projekte/Projekte/XXXXXXXXXXXX/Aufgaben/ MOD...")
--8<---------------cut here---------------end--------------->8---

The lower block shows a file-notify event '(#<process inotifywait>
(delete) ".#xxx")'. This is a file lock which is deleted, because the
corresponding file was written. This calls up to "test -e
/data/projekte/Projekte/XXXXXXXXXXXX/Aufga..."  (checking, whether the
directory still exists, before inserting the changed contents in the
dired buffer. Everything normal.

But while it waits for the response, a timer has started (also in the
auto-revert cosmos) which wants to send "test -r
/data/projekte/Projekte/XXXXXXXXXXXX/Aufga..."  (checking, whether a
file is readable. Since the first command didn't finish yet, Tramp has
signalled it. Boom.

Obviously, Tramp didn't try hard enough to suppress timers. I've pushed
the appended patch to the repositories. Could you please observe next
days, whether the situation has been changed? Thanks.

> HTH, Gregor

Best regards, Michael.
(unnamed) (text/x-patch, 575 B)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 9d555c5621b..b34d3ff6695 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -5615,7 +5615,8 @@ tramp-accept-process-output
 	     (v (process-get proc 'tramp-vector)))
     (dolist (p (delq proc (process-list)))
       (when (tramp-file-name-equal-p v (process-get p 'tramp-vector))
-	(with-local-quit (accept-process-output p 0 nil t)))))
+	(with-tramp-suspended-timers
+	  (with-local-quit (accept-process-output p 0 nil t))))))

   (with-current-buffer (process-buffer proc)
     (let ((inhibit-read-only t)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.