haiwen/seafile-client

Failed to connect to named pipe: All pipe instances are busy

DymOK93 opened this issue · 1 comments

The problem arises from a race condition between the creation of two named pipe instances in SeafileRpcClient::connectDaemon() and the creation of the daemon thread.

  1. Client creates a pipe instance for kSeafileRpcService.
  2. The daemon main worker is trying to spawns a new thread and may stuck in the kernel for some considerable time (for example, due to antivirus or EDR activity, or simply under heavy load)
  3. The client sees that the connection is successful and creates a second instance of the same pipe for kSeafileThreadedRpcService.
  4. If the time the worker daemon spends in the kernel exceeds 1-2ms (experimental), the client is very likely to get ERROR_PIPE_BUSY from CreateFile().
  5. In this case, the client writes to the log "Failed to connect to named pipe: All pipe instances are busy." and closes the instance from p.1.
  6. Now daemon has spawned a new thread and trying to read the pipe, but pipe is already closed.
  7. pipe_read_n() returns 0 for ERROR_BROKEN_PIPE so the daemon thread silently terminates.
    Then the situation repeats up to 20 * 16 times in total, after which the client exits with an error.

The bug was already mentioned (but not actually fixed) in #1284.

My solution is similar to the Named Pipe Client example on the Microsoft website: using WaitNamedPipe() if CreateFile() fails with ERROR_PIPE_BUSY.

Thank you for the nice patch! It's been merged.