Skip to content

The socket API connection is never re-established after the client goes away #56

Description

@Ebrathul

SocketThread connects to the socket API once, at startup
(socketthread.cpp, connect() around line 118). There is no path anywhere in
the class that dials again. Once that connection is gone, the mount stays up but
can no longer hydrate anything, for as long as it exists.

In the intended architecture the client owns the mount lifecycle, so a clean
client restart tears the mount down and brings it back. The problem is the case
where it does not: if the client crashes, or is killed, or exits without
unmounting, what is left behind is a mount that looks completely healthy —
findmnt shows it, ls and stat work, hydrated files still read — and that
fails every open of a dehydrated placeholder from then on.

Observed

Killing the client under a live mount and starting a new one on the same socket
path. The new client accepts no connection, because nothing dials it:

write: Bad file descriptor
Failed to send msg 25: V2/HYDRATE_FILE
open Failed job 25 ./test.pdf     -> EIO, immediately, and for every open after

The failure itself is well-behaved: EIO straight away, no hang, no partial
file, no corruption. It is the permanence that is the problem, and the fact that
nothing about the mount indicates it has become useless.

On main specifically

socketSendMsg() calls close(_socket) on a failed write but does not set
_socket to -1, so subsequent sends write to a closed descriptor — which the
kernel may by then have reused for something else. #54 changes that to -1 and
publishes the send failure as an explicit failed state, which is what produced
the clean EIO above. Neither version reconnects.

Why I am not sending a patch

There are at least three defensible answers and the choice is yours:

  1. Redial with backoff. The mount survives a client restart. Costs a
    reconnect loop and a decision about what to do with hydrations in flight.
  2. Exit and unmount when the connection drops. The mount disappears with the
    client that owns it, which matches the lifecycle model in INTEGRATION.md.
    Blunt, but it never leaves a mount that silently cannot work.
  3. Keep failing, but say so. Report it through a state the client or the
    user can see, rather than only in the log of a daemon nobody is reading.

I would rather report this accurately than pick one for you.

Environment

Linux 7.1.8 (CachyOS), libfuse 3.18.2, main at 525d8c6 and the #54 branch at
0096111 — both behave the same way in this respect.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions