Michael Albinus <[email protected]> writes:

Hi Stephen,

>>>   > Two Emacs processes accessing the same remote host can confuse each 
>>> other:
>>>   >    . open an sshfs file in Emacs 1
>>>   >    . open an sshfs file in Emacs 2 on the same remote host
>>>   >    . cleanup-all in Emacs 1
>>>   >    . try to access file again in Emacs 2 - fails: No such file or 
>>> directory
>>>
>>>   Yes, you can always shoot yourself in the foot. It might be possible to
>>>   check this case, but is it really worth the effort?
>>
>> I do not need this fixed.  Tramp sshfs is very useful to me as-is.  But I
>> wonder if in general it would be good for Tramp to be robust against dying
>> network connections.
>
> There are also other connection types which will suffer from two Emacs
> sessions in parallel. No need to fix this.
>
> However, it is is different if a network connection is dying. I will
> work on this scenario next days.

I have prepared a patch for this, see appended. Could you pls test?

There is a new defconst `tramp-fuse-mount-timeout', which defines the
time period how often it is checked whether an fuse volume is still
mounted. I didn't want to perform the check every time the volume is
accessed, this would result in severe performance penalties.

The initial value of the defconst is derived from
`remote-file-name-inhibit-cache' (10 seconds). Like that variable, it
could also be nil (never check the mount) or t (always check the mount).

I'm kind of undecided whether this shall be a defcustom, but somehow I
have the feeling it would be over-engineering. The defconst is there
just in case ...

>>  < Stephen

Best regards, Michael.

diff --git a/lisp/tramp-fuse.el b/lisp/tramp-fuse.el
index d2bac2d0..bb80cafe 100644
--- a/lisp/tramp-fuse.el
+++ b/lisp/tramp-fuse.el
@@ -156,19 +156,24 @@
 	(tramp-file-name-host-port vec))
        tramp-compat-temporary-file-directory)))

+(defconst tramp-fuse-mount-timeout
+  (eval (car (get 'remote-file-name-inhibit-cache 'standard-value)) t)
+  "Time period to check whether the mount point still exists.
+It has the same meaning as `remote-file-name-inhibit-cache'.")
+
 (defun tramp-fuse-mounted-p (vec)
   "Check, whether fuse volume determined by VEC is mounted."
-  (when (tramp-get-connection-process vec)
+  (let ((remote-file-name-inhibit-cache tramp-fuse-mount-timeout))
     ;; We cannot use `with-connection-property', because we don't want
-    ;; to cache a nil result.
-    (or (tramp-get-connection-property
-         (tramp-get-connection-process vec) "mounted" nil)
+    ;; to cache a nil result.  We use file property "/" in order to
+    ;; apply a timeout, for regular recheck.
+    (or (tramp-get-file-property vec "/" "mounted" nil)
         (let* ((default-directory tramp-compat-temporary-file-directory)
                (command (format "mount -t fuse.%s" (tramp-file-name-method vec)))
 	       (mount (shell-command-to-string command)))
           (tramp-message vec 6 "%s\n%s" command mount)
-          (tramp-set-connection-property
-           (tramp-get-connection-process vec) "mounted"
+          (tramp-set-file-property
+	   vec "/" "mounted"
            (when (string-match
 	          (format
                    "^\\(%s\\)\\s-" (regexp-quote (tramp-fuse-mount-spec vec)))
@@ -191,8 +196,7 @@
 	 (mount-point (tramp-fuse-mount-point vec))
          (command (format "%s -u %s" (tramp-fuse-get-fusermount) mount-point)))
     (tramp-message vec 6 "%s\n%s" command (shell-command-to-string command))
-    (tramp-flush-connection-property
-     (tramp-get-connection-process vec) "mounted")
+    (tramp-flush-file-property "/" "mounted")
     (setq tramp-fuse-mount-points
 	  (delete (tramp-file-name-unify vec) tramp-fuse-mount-points))
     ;; Give the caches a chance to expire.
diff --git a/lisp/tramp-sshfs.el b/lisp/tramp-sshfs.el
index 2be0485f..1bd4c5dc 100644
--- a/lisp/tramp-sshfs.el
+++ b/lisp/tramp-sshfs.el
@@ -349,31 +349,31 @@ connection if a previous connection has died for some reason."
       (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds)))

       ;; Set connection-local variables.
-      (tramp-set-connection-local-variables vec)
-
-      ;; Create directory.
-      (unless (file-directory-p (tramp-fuse-mount-point vec))
-	(make-directory (tramp-fuse-mount-point vec) 'parents))
-
-      (unless
-	  (or (tramp-fuse-mounted-p vec)
-	      (with-temp-buffer
-		(zerop
-		 (apply
-		  #'tramp-call-process
-		  vec tramp-sshfs-program nil t nil
-		  (tramp-fuse-mount-spec vec)
-		  (tramp-fuse-mount-point vec)
-		  (tramp-expand-args
-		   vec 'tramp-mount-args
-		   ?p (or (tramp-file-name-port vec) "")))))
-	  (tramp-error
-	   vec 'file-error "Error mounting %s" (tramp-fuse-mount-spec vec))))
-
-      ;; Mark it as connected.
-      (add-to-list 'tramp-fuse-mount-points (tramp-file-name-unify vec))
-      (tramp-set-connection-property
-       (tramp-get-connection-process vec) "connected" t)))
+      (tramp-set-connection-local-variables vec)))
+
+  ;; Create directory.
+  (unless (file-directory-p (tramp-fuse-mount-point vec))
+    (make-directory (tramp-fuse-mount-point vec) 'parents))
+
+  (unless
+      (or (tramp-fuse-mounted-p vec)
+	  (with-temp-buffer
+	    (zerop
+	     (apply
+	      #'tramp-call-process
+	      vec tramp-sshfs-program nil t nil
+	      (tramp-fuse-mount-spec vec)
+	      (tramp-fuse-mount-point vec)
+	      (tramp-expand-args
+	       vec 'tramp-mount-args
+	       ?p (or (tramp-file-name-port vec) ""))))))
+    (tramp-error
+     vec 'file-error "Error mounting %s" (tramp-fuse-mount-spec vec)))
+
+  ;; Mark it as connected.
+  (add-to-list 'tramp-fuse-mount-points (tramp-file-name-unify vec))
+  (tramp-set-connection-property
+   (tramp-get-connection-process vec) "connected" t)

   ;; In `tramp-check-cached-permissions', the connection properties
   ;; "{uid,gid}-{integer,string}" are used.  We set them to proper values.

Reply via email to