Commit Graph

34 Commits

Author SHA1 Message Date
Chad Austin
f6fcff3151 move strace logging into FuseChannel
Summary:
Instead of logging in the Dispatcher, move strace logging to
FuseChannel where it can be standardized for all FUSE request types.

Reviewed By: wez

Differential Revision: D24035838

fbshipit-source-id: c84d8c27b62f9944e2d26a35a7ed7bbbeeb5bf0e
2020-10-20 09:34:03 -07:00
Chad Austin
f663d81b6a use TraceBus in FuseChannel
Summary: Migrate FuseChannel outstanding request tracking to the TraceBus's background thread.

Reviewed By: kmancini

Differential Revision: D23773955

fbshipit-source-id: 5137437e6526cf4e995f60144e5ecbe392245719
2020-10-07 22:23:36 -07:00
Xavier Deguillard
ce44616cb3 fuse: cleanup some include of RequestData
Summary:
None of these were used, let's remove them.

ps: I thought we had a system to detect unused headers and lint about them?

Reviewed By: chadaustin

Differential Revision: D23465783

fbshipit-source-id: c21a34c9838db29f4fd0057d3be4e0fcb527cd6d
2020-09-02 12:15:48 -07:00
Chad Austin
61e738cd84 use enumValue instead of static_cast<int>
Summary:
Where appropriate, replace uses of `static_cast<int>` with
`enumValue`.

Reviewed By: simpkins

Differential Revision: D20975196

fbshipit-source-id: 581643366ea7eda5d1961238b0693cf45c4eec94
2020-04-28 18:59:34 -07:00
Chad Austin
65c93484e2 rename tracing to telemetry
Summary: Tracing was not an accurate name for what this directory had become. So rename it to telemetry.

Reviewed By: wez

Differential Revision: D17923303

fbshipit-source-id: fca07e8447d9b9b3ea5d860809a2d377e3c4f9f2
2019-10-15 13:39:41 -07:00
Chad Austin
8cac2bfe6a Remove dead includes in eden
Reviewed By: wez

Differential Revision: D17877514

fbshipit-source-id: e7f8ed8364bdb7a77f293cbdf4b48e8f15e64c30
2019-10-11 16:45:01 -07:00
Andres Suarez
fbdb46f5cb Tidy up license headers
Reviewed By: chadaustin

Differential Revision: D17872966

fbshipit-source-id: cd60a364a2146f0dadbeca693b1d4a5d7c97ff63
2019-10-11 05:28:23 -07:00
Adam Simpkins
aa5e6c7295 update license headers in C++ files
Summary:
Update the copyright & license headers in C++ files to reflect the
relicensing to GPLv2

Reviewed By: wez

Differential Revision: D15487078

fbshipit-source-id: 19f24c933a64ecad0d3a692d0f8d2a38b4194b1d
2019-06-19 17:02:45 -07:00
Matt Glazar
11195c2b0b Rename ThreadLocalEdenStats to EdenStats
Summary:
I'm confused by the naming of EdenThreadStats and ThreadLocalEdenStats. For example, when I see "ThreadLocalEdenStats", I think that such objects can only be accessed by one thread. That's definitely not what "ThreadLocalEdenStats" means!

I think the following naming scheme makes more sense:

* **EdenThreadStats**: Statistics which are updated by one thread. Currently called EdenThreadStats.
* **EdenStats**: Statistics for all threads. Provides access to EdenThreadStats. Currently called ThreadLocalEdenStats.

Implement my preferred scheme: rename ThreadLocalEdenStats to EdenStats.

This diff should not change behavior.

Note: Prior to D14822274, EdenThreadStats was called EdenStats.

Reviewed By: simpkins

Differential Revision: D14822271

fbshipit-source-id: bd20179b1010588e3fc16dc9ed0657d458606f16
2019-04-14 20:45:16 -07:00
Matt Glazar
d9e4eabc9d Move EdenStats into eden/fs/tracing/
Summary:
I want to use EdenStats in eden/fs/store/. EdenStats currently lives in eden/fs/fuse/, and making eden/fs/store/ depend upon eden/fs/fuse/ is confusing. (It's also confusing that some code in eden/fs/fuse/ is used on Windows.)

Reorganize the code: move EdenStats into eden/fs/tracing/.

This diff should not change behavior.

Reviewed By: chadaustin

Differential Revision: D14677337

fbshipit-source-id: af26d214bcc3a9919920fbd4e59e6098fe4e3834
2019-04-01 17:41:57 -07:00
Matt Glazar
201fef1c2e Create exception type for FUSE unmount-during-init
Summary:
FuseChannel::initialize throws runtime_error when the FUSE connection is interrupted. I want EdenMount::startFuse to handle unexpected-unmount errors from FuseChannel::initialize, but catching runtime_error would catch unrelated errors too.

When the FUSE connection is interrupted during initialization, make FuseChannel throw FuseDeviceUnmountedDuringInitialization instead of runtime_error.

Reviewed By: chadaustin

Differential Revision: D14077848

fbshipit-source-id: ed7b7d370a83ed1a9c36a443d8bb06ba940dc032
2019-03-11 20:48:27 -07:00
Chad Austin
4f532889d1 reenable ProcessNameCache
Summary:
Now that the deadlock in ProcessNameCache has been fixed, bring it
back.

Reviewed By: strager

Differential Revision: D13742965

fbshipit-source-id: f407105e06b9954766bdb48ef1303e2003c07284
2019-01-24 15:45:29 -08:00
Matt Glazar
e9f5639b1f Make ProcessNameCache optional for ProcessAccessLog
Summary:
To mitigate a deadlock, I want to make ProcessAccessLog not access /proc/. Allow this by making ProcessNameCache optional.

This diff should not change behavior.

Reviewed By: simpkins

Differential Revision: D13540948

fbshipit-source-id: 4c5d68c972c04122de1d2414084debfec078dd4c
2018-12-21 15:43:51 -08:00
Chad Austin
e88177a2f3 count FUSE accesses by process ID
Summary: Begin tracking pids passed into FUSE in the ProcessAccessLog.

Reviewed By: strager

Differential Revision: D9595795

fbshipit-source-id: 02e5fefebcd0de860274409ba6258f14fa050b55
2018-09-10 13:52:51 -07:00
Lewis Baker
34b48e102d Fix data race in Eden fuse driver handling of FUSE_INTERRUPT
Summary:
Fixed a data race in Eden's `FuseChannel` implementation that could cause a crash if a `FUSE_INTERRUPT` request was concurrently on a different thread while a first thread was still launching the original request.

Modified `FakeFuse` to use `SOCK_SEQPACKET` instead of `SOCK_STREAM` so that tests can submit several requests in a pipelined fashion without having to first wait until the previous request was received. This requires the `recvResponse()` function to first read the header with `MSG_PEEK` to determine the response size and then subsequently read the entire message atomically to avoid reading a truncated message.

Added a new unit-test that exercises the `FUSE_INTERRUPT` race condition by sending a series of alternating `FUSE_LOOKUP`/`FUSE_INTERRUPT` requests.

Reviewed By: simpkins

Differential Revision: D9023654

fbshipit-source-id: 0eb44669ea8c4f58cf4313adf6ceb11098115a70
2018-07-27 14:36:42 -07:00
Adam Simpkins
4442ab5e54 increase the timeouts in FuseChannelTest to 1 second
Summary:
Many of the tests in FuseChannelTest.cpp perform blocking waits on Futures.
Previously they used a 100ms timeout.  This could sometimes result in flaky
test failures if the system was under heavy CPU load.  Bumping up the timeout
to 1 second appears to avoid this issue.

Reviewed By: lewissbaker

Differential Revision: D9024730

fbshipit-source-id: 7af78c61008c6b4c1e5e130b3d37b2f3ac787a01
2018-07-26 21:21:36 -07:00
Marshall Cline
af39582cc8 use rvalue-qual Future::get(...)
Summary:
This is part of "the great r-valuification of folly::Future":

* This is something we should do for safety in general.
* Context: `Future::get(...)` means both `Future::get()` and `Future::get(Duration)`
* Using lvalue-qualified `Future::get(...)` has caused some failures around D7840699 since lvalue-qualification hides that operation's move-out semantics - leads to some use of future operations that are really not correct, but are not obviously incorrect.
* Problems with `Future::get(...) &`: it moves-out the result but doesn't invalidate the Future - the Future remains (technically) valid even though it actually is partially moved-out. Callers can subsequently access that moved-out result via things like `future.get(...)`, `future.result()`, `future.value()`, etc. - these access an already-moved-out result which is/can be surprising.
* Reasons `Future::get(...) &&` is better: its semantics are more obvious and user-testable. It moves-out the Future, leaving it with `future.valid() == false`.

Reviewed By: LeeHowes

Differential Revision: D8756764

fbshipit-source-id: 5c75c79cebcec77658a3a4605087716e969a376d
2018-07-09 08:51:43 -07:00
Marshall Cline
9825a9fd3f modernize Future::get(): 4/n = codemod to std::move for non-ptr exprs
Summary:
Codemod non-pointer expressions:
   - expr.get() ==> std::move(expr).get()
   - expr.get(dur) ==> std::move(expr).get(dur)
when expr is not already an xvalue.

Reviewed By: yfeldblum

Differential Revision: D8429621

fbshipit-source-id: 87dea0749509d7083f14be93505ffff14ae8d464
2018-06-19 23:21:11 -07:00
Yedidya Feldblum
c811669c95 In Futures Core, destroy context when destroying callback
Summary:
[Folly] In Futures Core, destroy context when destroying callback since they basically go together.

Also removes expectations in an Eden FS test case which affirm the old behavior, along with a TODO to remove the expectations once the affirmed behavior is fixed.

Reviewed By: marshallcline

Differential Revision: D8347040

fbshipit-source-id: ed9fec932ad1e0aa1e40675cf70081d19bbe4325
2018-06-13 01:38:10 -07:00
Chad Austin
22e46cfe74 standardize on std::chrono_literals
Summary:
This is not at all clear from cppreference.com, but per
https://www.youtube.com/watch?v=dTeKf5Oek2c, it sounds to me like
recommended practice is to either:

`using namespace std::chrono_literals` (or string_literals or
whatever) to pull in a focused set of literals.

or

`using namespace std::literals` to pull in all standard literals.

or

`using namespace std` to pull in everything.

`using namespace std::literals::chrono_literals` is unnecessarily
verbose.

Adopt those standards in Eden.

Reviewed By: simpkins

Differential Revision: D8060944

fbshipit-source-id: 4d9dd4329698b7ff5e5c81b5b28780ca4d81a2a1
2018-05-18 16:51:15 -07:00
Adam Simpkins
8e3c09a99a move folly/experimental/logging to folly/logging/
Summary:
Promote the folly logging code out of the experimental subdirectory.
We have been using this for several months in a few projects and are pretty
happy with it so far.

After moving it out of the experimental/ subdirectory I plan to update
folly::Init() to automatically support configuring it via a `--logging` command
line flag (similar to the initialization it already does today for glog).

Reviewed By: yfeldblum, chadaustin

Differential Revision: D7755455

fbshipit-source-id: 052db34c97f7516728f7cbb1a5ad959def2f6efb
2018-04-30 21:29:29 -07:00
Puneet Kaushik
a7f99f7f2c Added thrift request to report outstanding FUSE calls
Summary:
Added a thrift call to return the outstanding FUSE requests.
Cli will call the thrift and print the output.
Added a unit test to test getOutstandingRequests().

Reviewed By: simpkins

Differential Revision: D7314584

fbshipit-source-id: 420790405babdb734f598e19719b487096ec53ca
2018-03-20 10:25:49 -07:00
Adam Simpkins
bfcf4c574a remove the fusell namespace
Summary: Move everything in the `facebook::eden::fusell` namespace to `facebook::eden`

Reviewed By: chadaustin

Differential Revision: D7314458

fbshipit-source-id: db56d3e5fb898235e1376ac76077cf780d9b4698
2018-03-19 17:01:52 -07:00
Adam Simpkins
bbf0407287 record the FUSE version reported by the kernel
Summary:
Previously the FuseChannel code unconditionally set `connInfo_.major` and
`connInfo_.minor` to the FUSE version that it supports, rather than the FUSE
version supported by the kernel it is talking to.

This does not appear to be the intended behavior, given that in several other
location it checks the value of `connInfo_->minor` to see if particular
features are supported.

Reviewed By: wez

Differential Revision: D7300845

fbshipit-source-id: 1f5946134037b2cbe03a8b86241acaa401c21ffa
2018-03-16 17:39:13 -07:00
Adam Simpkins
1c46d4c9e1 have FuseChannel return its FD in the completion future
Summary:
Remove the `FuseChannel::stealFuseDevice()` method, and instead change the
session completion future to return the FUSE device FD if it is still valid.

This ensures we only extract the FUSE device when it is still valid: if an
unmount event is being processed by a FUSE worker thread simultaneously with a
call to `FuseChannel::takeoverStop()` the session completion future will return
an empty `folly::File` since the FUSE device has been shut down.

This also helps clarify the synchronization semantics around modification to
the `fuseDevice_` member variable.

Reviewed By: wez

Differential Revision: D7300847

fbshipit-source-id: 02ced8fc9d24e7cd526d911782949d0bfbf0e5a7
2018-03-16 17:39:13 -07:00
Adam Simpkins
8eff641bf3 prevent FuseChannel from being destroyed with outstanding requests
Summary:
The FuseChannel destructor previously could be invoked while there are still
outstanding requests, which would cause problems when responses were generated
for these requests.

This makes the FuseChannel destructor private, requiring users to always
allocate FuseChannel objects on the heap and destroy them using a destroy()
method.  The destroy() method still blocks waiting for the FUSE worker threads
to exit, but if there are still outstanding FUSE requests it defers the
deletion of the FuseChannel until they are complete.

The EdenMount class currently couldn't ever destroy FuseChannel objects with
outstanding requests, since it waits for the completion future to fire before
invoking the destructor.  Fixing this behavior is mostly for correctness of the
FuseChannel API and for the benefit of our unit tests.

Reviewed By: chadaustin

Differential Revision: D7297829

fbshipit-source-id: 643d1332be84a1f25ee30ba2a2ea3515806f00ef
2018-03-16 12:35:19 -07:00
Adam Simpkins
c5f4ea6f8b update FuseChannel::initialize() to return the completion future
Summary:
Remove the `FuseChannel::getSessionCompleteFuture()` method and instead have
`initialize()` and `initializeFromTakeover()` return the `Future` that can be
used to wait on session completion.

This makes it explicit from an API perspective that this session completion
future will only be invoked if initialization is successful.  It also
eliminates the possibility of anyone calling getSessionCompleteFuture() more
than once.

I also changed the session completion future to use a folly::SemiFuture rather
than a folly::Future, to make it explicit that callers generally should not
execute their callback inline in the same thread where the SemiFuture is
fulfilled.

Reviewed By: chadaustin

Differential Revision: D7297835

fbshipit-source-id: 3a1157951f0738f1692833ed5e875c3e9c6d6d69
2018-03-16 12:35:19 -07:00
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
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