Commit Graph

12 Commits

Author SHA1 Message Date
Adam Simpkins
fdecf19d91 update FuseChannel to signal the session complete future immediately
Summary:
This changes FuseChannel to fulfill the session complete future immediately in
the thread where it finishes.  This may occur inside a FUSE worker thread.
It is now up to the caller to use `via()` if they want their callback to run in
a separate thread.

This simplifies the FuseChannel code and also addresses a crash that occurs in
the unit tests sometimes: If the FuseChannel destructor is invoked without
explicitly invoking the FuseChannel, it would schedule the session complete
promise to be fulfilled in a separate EventBase thread.  However, the promise
may then have already been destroyed by the time it can run in the EventBase
thread.

There are still additional synchronization issues to fix in the FuseChannel
tests, but this resolves one problem.

Reviewed By: chadaustin

Differential Revision: D7282001

fbshipit-source-id: be64d3ef6a0e664ed7a2cf93a549acc140184095
2018-03-15 13:48:45 -07:00
Adam Simpkins
1a9f74b940 fix a race between FuseChannel::startWorkerThreads() and the destructor
Summary:
Update FuseChannel::startWorkerThreads() to return without doing anything if
runState_ indicates that the FuseChannel is currently stopping.

This addresses a race betwen startWorkerThreads() and the destructor.  If the
destructor is invoked in parallel with startWorkerThreads() the destructor can
grab the state_ lock and clear out the workerThreads list first.  This then
causes problems when startWorkerThreads() runs and adds new threads to the
workerThreads list, which then never get joined.

Reviewed By: wez

Differential Revision: D7253574

fbshipit-source-id: f2cac11f1e71e1a14e3f020368152e0f2948c625
2018-03-13 18:30:49 -07:00
Adam Simpkins
d622eb481d allow stopping FuseChannel during initialization
Summary:
Update FuseChannel::readInitPacket() to honor `runState_` and stop if it is
changed to indicate that the channel is stopping.  Previously the init worker
thread would always wait until it received an INIT packet or an error on the
FUSE channel.

This also refactors the `readInitPacket()` code slightly mainly to to reduce
the level of indentation.

Reviewed By: wez

Differential Revision: D7253575

fbshipit-source-id: 7f27698947b629daecd9cd4ddffb6e6a921ce41e
2018-03-13 18:30:49 -07:00
Adam Simpkins
9bb25beab3 update FuseChannel to record the reason why we stopped
Summary:
Update the FuseChannel code to keep track of why it is stopping, and to return
this data in the session complete future.

This is mainly just available for diagnostic reasons, and at the moment nothing
is using this outside of the unit tests.

Reviewed By: wez

Differential Revision: D7253573

fbshipit-source-id: 0c7e5b8bd9c3c1de3788918c2257c06d4fe0a90c
2018-03-13 18:30:49 -07:00
Adam Simpkins
fef4a43da7 restructure FuseChannel initialization and synchronization
Summary:
- Update FuseChannel::initializate() to not require an Executor.  Rather than
  performing initialization using the supplied Executor, it simply starts one
  worker thread first and performs initialization there.
- Change the API semantics slightly so that the session complete future is
  invoked only if initialization succeeds.  Previously the session complete
  future could be invoked if initialization failed as well.
- Replace the activeThreads counter with a stoppedThreads counter to determine
  when the session complete future should be invoked.  The previous
  activeThreads behavior was somewhat racy, since the activeThreads counter was
  incremented inside each worker thread, but most places that checked it did
  not wait to ensure that all worker threads had successfully incremented it
  yet.

Reviewed By: chadaustin

Differential Revision: D7243910

fbshipit-source-id: 93b3465509bd9bf6fa90ea097e70dac3193172f9
2018-03-13 13:29:03 -07:00
Adam Simpkins
1b441aa0b4 split up FUSE initialization for fresh start vs takeover
Summary:
Split up the FuseChannel and EdenMount APIs for starting a brand new FUSE
channel vs taking over an existing channel.

These operations are somewhat different as initializing a new FUSE channel
requires performing a negotiation with the kernel that will not complete
immediately.  Therefore these APIs return a Future object.  Taking over an
existing FUSE channel is always an immediate operation, and therefor does not
need to return a Future object.

Reviewed By: chadaustin

Differential Revision: D7241997

fbshipit-source-id: 22780f2df76b2d554ab2a4043b6425fa7a4e9c94
2018-03-12 21:28:50 -07:00
Adam Simpkins
81aa1a31a4 make sure we ignore SIGPIPE in unit tests
Summary:
Ensure that we ignore SIGPIPE in unit tests.  The
`FuseChannel::requestSessionExit()` function sends SIGPIPE to its worker
threads, and expects this to wake up the worker threads if they are stuck
inside a read() call.

In normal program builds folly/Subprocess.cpp causes SIGPIPE to be ignored on
startup.  However, Subprocess.cpp is not necessarily linked into all of our
unit tests.  I haven't tracked down exactly why, but SIGPIPE in the unit tests
seems to kill the entire process only in opt-ubsan builds.

In the future we probably should clean up how requestSessionExit() triggers its
worker threads to exit: the current code is still potentially racy, since the
worker threads could receive the SIGPIPE just after checking `sessionFinished_`
and before calling `read()`, in which case they may go back to sleep rather
than exiting.  However for now this should be a simple fix to get the tests
passing in all build modes.

Reviewed By: wez

Differential Revision: D7224370

fbshipit-source-id: a56fe3331fc5aa6a49ccbe6b0678b479a44ffc07
2018-03-12 11:46:20 -07:00
Adam Simpkins
d5e3d5dd63 add initial test code for FUSE channel communication
Summary:
This adds a FakeFuse class to simulate a FUSE connection to the kernel, but
that is actually communicating with our userspace test harness code.  This also
adds a FakePrivHelper class which implements the PrivHelper interface but
returns FakeFuse connections rather than real FUSE connections to the kernel.

This will enable us to write unit tests that exercise more of the FUSE and
EdenMount logic, and will also enable us to test error conditions and ordering
behaviors that are difficult to reliably reproduce with a real FUSE mount.

This also includes some very basic tests using this new code.  The code in
fuse/test/FuseChannelTest.cpp creates a FuseChannel using a FakeFuse object,
and the code in inodes/test/FuseTest.cpp creates a full EdenMount object using
FakePrivHelper and FakeFuse.  The tests are pretty similar for now, and only
exercise the FUSE initialization code.  I will expand these tests in subsequent
diffs.

Reviewed By: wez

Differential Revision: D7050826

fbshipit-source-id: 4f82375d65664ca3a5a228a577caa4d1d47454fe
2018-02-27 22:57:09 -08:00
Adam Simpkins
21d2b6c46d Remove TARGETS files
Summary:
This removes the TARGETS files from the eden github repository.  The
open source buck build has been failing for several months, since buck
removed support for the thrift_library() rule.

I will potentially take a stab at adding CMake build support for Eden
at some point in the future.

Reviewed By: chadaustin

Differential Revision: D6893233

fbshipit-source-id: e6023094a807cf481ac49998c6f21b213be6c288
2018-02-20 19:57:45 -08:00
Sergey Zhupanov
ea2994c045 Misc cleanup of cpp files in eden/fs/fuse/
Summary: Misc cleanup (mainly constification).

Reviewed By: simpkins

Differential Revision: D6720987

fbshipit-source-id: c9c719fce93d413857c48c61e0c920319e865209
2018-01-17 13:41:19 -08:00
Philip Jameson
8604b8f5b0 Migrate TARGETS files from @/ to //
Summary:
This is a codemod to change from using @/ to // in basic cases.
- TARGETS files with lines starting with @/ (but excluding @/third-party:
- autodeps lines in source and TARGETS files ( (dep|manual)=@/ ), excluding @/third-party
- Targets in string macros

The only thing left of the old format should be @/third-party:foo:bar

drop-conflicts

Reviewed By: ttsugriy

Differential Revision: D6605465

fbshipit-source-id: ae50de2e1edb3f97c0b839d4021f38d77b7ab64c
2017-12-20 16:57:41 -08:00
Chad Austin
8a6d0592f7 allow returning the open file handle before the load/materialize completes
Summary:
There's no technical reason to block an open() request until the data
load / materialization returns.  This change returns immediately from
open() and then waits if necessary in a subsequent write() call.

Reviewed By: wez

Differential Revision: D6391486

fbshipit-source-id: 862f87e3c3a0d760bacb0f8ca7acc479037fec2f
2017-12-05 11:21:26 -08:00