Commit Graph

287 Commits

Author SHA1 Message Date
Puneet Kaushik
1e94122c0b Win: Porting eden/service to Windows with fb-thrift
Reviewed By: strager

Differential Revision: D10225935

fbshipit-source-id: 5c571229e243b8fcabb9db8a6e15e1c66423edaf
2018-10-22 20:27:26 -07:00
Lee Howes
de464bd163 then to thenValue and thenTry
Summary: Convert then to thenValue or thenTry as appropriate.

Reviewed By: Orvid

Differential Revision: D10413847

fbshipit-source-id: 834756c2bcb4722fbe3729ce54aece0482b0a7ff
2018-10-22 20:27:25 -07:00
Wez Furlong
da904dd4a5 make mononoke tier configurable
Summary: This was previously hard coded and making it configurable is operationally desirable.

Reviewed By: chadaustin

Differential Revision: D10298279

fbshipit-source-id: 124c3fa319c44aacb3d17ef6e380e9dec49db8be
2018-10-10 14:47:08 -07:00
Chad Austin
bf85e7ea15 propagate bind mount errors
Summary:
This explains why some people ended up with broken bind mounts. If
bind mount creation ever failed, eden start would silently ignore the
error, leaving buck-out as a mutable directory in the Eden overlay
itself.

Reviewed By: wez, strager

Differential Revision: D10118612

fbshipit-source-id: ce99df4216f6815c24dc8283e55a9a30d58d29a1
2018-10-09 16:39:45 -07:00
Chad Austin
b2d0f9eefd disallow undefined symbols in the eden server library
Summary:
The eden server library used to rely on a symbol being defined by the
executable that linked it. Pass runServer as a parameter to
EdenServer::run to allow us to leave undefined_symbols=False in the
library rule.

Reviewed By: wez

Differential Revision: D10246972

fbshipit-source-id: d4c47e58947a2d57c4163134db2455fe9c815344
2018-10-09 10:02:55 -07:00
Chad Austin
59ad0c2ac8 store the file handle -> InodeNumber map in the FileHandleMap
Summary: Eliminate the need to look up an InodeNumber from a FileHandle. Instead, simply preserve the mapping when it's created.

Reviewed By: wez

Differential Revision: D10187120

fbshipit-source-id: dc47f7776294871ff2398f33c31bd85d240ead50
2018-10-08 11:13:38 -07:00
Chad Austin
598b471442 Disable automatic background unloading until we've fixed the InodeMap crash
Summary:
In D6766900, we turned on automatic background inode
unloading. However, there's a bug somewhere in InodeMap or the loading
sequence that causes occasional crashes for users, so turn it back off
for now.

Reviewed By: pkaush

Differential Revision: D10114443

fbshipit-source-id: fd35fd31b5731aa9bf26004fca8aa73930bb2344
2018-09-28 16:51:32 -07:00
Chad Austin
bf8970752d despam periodic unload log and make it useful
Summary:
Previously, Eden would log `UnloadInodeScheduler Unloading Free
Inodes` every 10 minutes. Now it only logs if it actually unloads an
inode for a mount.

Reviewed By: strager

Differential Revision: D9999029

fbshipit-source-id: f01d0e7b1341bef230bcb5a327c31ffc8e3aeb2c
2018-09-25 17:51:41 -07:00
Lee Howes
e8e25257cf Future<T>::then Future<T>::then() -> Future<T>::thenValue or thenTry.
Summary:
Part of the larger project to modify Future<T>::then to be r-value qualified and use Future<T>::thenTry or Future<T>::thenValue.

The goal is to disambiguate folly::Future and to improve type and lifetime safety of Future and its methods.

Codemod:
  future<T>.then(callable with operator()(not-a-try)) to future<T>.thenValue(callable with operator()(not-a-try)).
  future<T>.then(callable with operator()()) to future<T>.thenValue(callable with operator()(auto&&)).
  future<T>.then(callable with operator()(auto)) to future<T>.thenValue(callable with operator()(auto)).
  future<T>.then(callable with operator()(folly::Try<T>)) to future<T>.thenTry(callable)

Reviewed By: Orvid

Differential Revision: D9819578

fbshipit-source-id: f9e31f47354c041ecbf0a90953cbe50ebfda6adc
2018-09-14 17:10:57 -07: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
Chad Austin
d4d3102892 enable the periodic inode unload job
Summary:
Every 10 minutes, unload any inodes that have not been accessed within
6 hours.  This work helps keep Eden's memory usage from growing to O(repo) over
time.

Reviewed By: wez

Differential Revision: D6766900

fbshipit-source-id: af4af8fe12e5f43ce90f26578fa9bd534f124085
2018-09-04 12:23:19 -07:00
Adam Simpkins
66186a6c00 make sure we set O_CLOEXEC on the lock file
Summary:
Open the lock file with O_CLOEXEC so that the `hg_import_helper.py`
subprocesses do not inherit the lock file.

Reviewed By: wez

Differential Revision: D9553355

fbshipit-source-id: b7024e9637bc52ef9a8a01cff60df00d8617a839
2018-08-29 17:23:02 -07:00
Lee Howes
2cc00ea5de Future<T>::then Future<T>::then(not-try-task) -> Future<T>::thenValue(task).
Summary:
Overall plan to modify Future<T>::then to be r-value qualified and use Future<T>::thenTry or Future<T>::thenValue.

The goal is to disambiguate folly::Future and to improve type and lifetime safety of Future and its methods.

Codemod:
 * future<T>.then(callable with operator()(not-a-try)) to future<T>.thenValue(callable with operator()(not-a-try)).
 * future<T>.then(callable with operator()()) to future<T>.thenValue(callable with operator()(auto&&)).
 * future<T>.then(callable with operator()(auto)) to future<T>.thenValue(callable with operator()(auto)).

Reviewed By: yfeldblum

Differential Revision: D9523023

fbshipit-source-id: b59a5fd4b155a3d9c2c85d157c436399627a856b
2018-08-28 10:09:08 -07:00
Zeyi Fan
96c7bb1c5f read use-mononoke and client-certificate in edenfs
Summary: This commit let `HgImporter` pick up configuration values from `EdenConfig`.

Reviewed By: chadaustin

Differential Revision: D9346293

fbshipit-source-id: cb63f7d13a86058e9bf076eddb52212560a64cb1
2018-08-20 11:22:14 -07:00
Lee Howes
69d8203162 Future<T>::then 6/n: Future<T>::then() & -> Future<T>::then() &&.
Summary:
Overall plan to modify Future<T>::then to be r-value qualified and use Future<T>::thenTry or Future<T>::thenValue.

The goal is to disambiguate folly::Future and to improve type and lifetime safety of Future and its methods.

6/n: Codemod rvalue-future<T>.then(...) to rvalue-future<T>.then(...).

Reviewed By: yfeldblum

Differential Revision: D9152002

fbshipit-source-id: 166475c1dcafb29a11154cbfbdf7e2e1feaf745b
2018-08-03 23:36:16 -07:00
Eamonn Kent
d39ca39b85 EdenMount should load/use ignore file list from configuration
Summary:
[Eden] EdenMount should make use of EdenConfig in order to determine the user and system ignore files to load.

This commit does the following:
- adds EdenConfig to ServerState that gets passed to the MountPoint.
- removes hard-coded system ignore settings.
- allows the ignore files to be updated in the user and system config.
- has the diff context loaded with actual ignore file contents.
- adds the FileChangeMonitor class to efficiently (throttled) identify when file changes have occured and reload as necessary.

Reviewed By: simpkins

Differential Revision: D8876214

fbshipit-source-id: d2697c130d3d4960c7f645ace226e5ce6b772048
2018-07-30 17:20:45 -07:00
Lee Howes
2b4e4f861e Future<T>::then 1/n: Future<T>::then(try-task) -> Future<T>::thenTry(task).
Summary:
Overall plan to modify Future<T>::then to be r-value qualified and use
Future<T>::thenTry or Future<T>::thenValue.

1/n: Codemod rvalue-future<T>.then(callable with operator()(Try<T>)) to rvalue-future<T>.thenTry(callable with operator()(Try<T>)).

Reviewed By: simpkins

Differential Revision: D8961903

fbshipit-source-id: ff17b7833d240c221197cdf0bf914b8a39f80b07
2018-07-23 18:51:38 -07:00
Aaryaman Sagar
d2a15f5aff Remove const from shutdownSubscribers() and stop()
Summary:
The methods were marked const when they were actually mutating the inner
objects, this was working because the pointed to objects were referenced via
`shared_ptr` handles

Reviewed By: yfeldblum

Differential Revision: D8851578

fbshipit-source-id: 4ca49390daf46f5c8681149da4d1e9eeab5aacb5
2018-07-16 16:10:38 -07:00
Eamonn Kent
601c5ea1e5 Support loading of system wide and users eden config files
Summary:
This commit focuses on the following functionality:
    - Eden configuration should have reasonable default values.
    - Eden should allow configuration to be specified in various manners: default, cli, user and system configuration files.
    - Configuration values should have the following precedence (hi to low): cli,
      user config, system config, default.
    - A light-weight mechanism is required to detect and update configuration changes.

Reviewed By: simpkins

Differential Revision: D8594297

fbshipit-source-id: ed195212669b18b450a1eae359e4d23905beadb4
2018-07-09 16:54:11 -07:00
Adam Simpkins
3f99298e67 teach edenfs to create directories it needs
Summary:
Update the C++ edenfs code to ensure that the .eden and
.eden/storage/rocks-db directories exist, rather than requiring the python CLI
code create these directories as part of `eden start`

Reviewed By: strager

Differential Revision: D8508488

fbshipit-source-id: 358521b4f5eed1d19bf37903900ca50718e2c35c
2018-06-26 12:07:08 -07:00
Adam Simpkins
0253ff3d52 have edenfs daemonize itself by default
Summary:
This updates edenfs to be able to daemonize itself, and moves the
daemonization logic from the python CLI code into C++.

The main benefit of this is that we can now do a better job of reporting
messages to the user during start-up.  We can log around potentially slow
operations (opening the RocksDB local store), and we can print messages
directly to the user if startup fails.  Previously most failure messages would
go only to the eden log and would not be printed to the user's terminal.

This also fixes some issues where stdin and stdout were not closed properly
when daemonization was performed by the CLI.  sudo needed access to these file
descriptors in case it needed to prompt for a password, and it would then hold
the descriptors open until edenfs exited.

Reviewed By: wez

Differential Revision: D8373672

fbshipit-source-id: 3272bff2208596f41d26e479c82c700d6c1efe11
2018-06-26 12:07:07 -07:00
Eamonn Kent
935e3bdb2f Multiply vmRSS bytes by 1024
Summary:
We calculate vmRSS bytes on linux systems by parsing the /proc/self/status
file. The value in that file is in kB so we need to convert it to bytes.

Reviewed By: chadaustin

Differential Revision: D8549009

fbshipit-source-id: 88b18543cb561372dc5eee84293e79fddca8efcb
2018-06-20 15:06:40 -07:00
Eamonn Kent
8821a6fe66 Support reporting of additional statistics
Summary:
Expand the data we collect in fb 303 collector. Currently we extract data from
procprint it is only reliable for a day (or so).

Here we add:

- memory vm rss bytes (from /proc/self/status)
- memory private bytes (from /proc/self/smaps)

Reviewed By: chadaustin

Differential Revision: D8380917

fbshipit-source-id: dca6fac7af44321c7a6615edb0fde0cb7c8827d0
2018-06-20 09:06:16 -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
Adam Simpkins
dc84937e0b update PrivHelper to support detaching from an EventBase
Summary:
Add a PrivHelper::detachEventBase() method, and rename PrivHelper::start() to
attachEventBase().

This makes it possible to detach a running PrivHelper from its EventBase and
re-attach it to an EventBase later to restart it.  This will be useful in
upcoming diffs to allow performing calls to the PrivHelper before the main
thrift server EventBase has started.

Reviewed By: wez

Differential Revision: D8212777

fbshipit-source-id: d5a9bf672afa8b16e53201ac747d77337e1cc307
2018-06-18 17:22:18 -07:00
Adam Simpkins
011cc21e52 update privhelper code to use the UnixSocket helper class
Summary:
This updates the privhelper code to use the UnixSocket class for performing
I/O.  This reduces the number of separate implementations of code we have for
sending file descriptors across Unix domain sockets, and also makes the
privhelper APIs non-blocking.

This will make it easier to clean up some of the initialization ordering in
the future.  It will also make it easier to send file descriptors to the
privhelper server, instead of just receiving them.  This may be helpful for
passing a file descriptor to use for logging to the privhelper process, which
will make it easier to fork the privhelper before logging redirection has
occurred.

Reviewed By: bolinfest

Differential Revision: D8053422

fbshipit-source-id: 1f8fdf22afc797eead0213be1352ea530762140d
2018-06-11 18:32:25 -07:00
Adam Simpkins
5305edefc1 update PrivHelper APIs to return Futures
Summary:
Up until now all of the privhelper APIs have been blocking calls.  This
changes the privhelper functions to return Futures, and updates all users of
these APIs to be able to handle the results using Futures.

One benefit of this change is that all existing mount points are remounted in
parallel now during startup, rather than being mounted serially.  The old code
performed a blocking `get()` call on the future returned by
`EdenServer::mount()`.

The privhelper calls themselves are still blocking for now--they block until
complete and always return completed Future objects.  I will update the
privhelper code in a subsequent diff to actually make it asynchronous.

Reviewed By: bolinfest

Differential Revision: D8053421

fbshipit-source-id: 342d38697f67518f6ca96a37c12dd9812ddb151d
2018-06-11 18:32:25 -07:00
Chad Austin
74de9c13a8 recover from a commit2tree entry existing without the corresponding tree
Summary:
When testing D8108649 I accidentally deleted all of my trees
but didn't delete my commit2tree mapping. This diff allows Eden to
recover from that situation.

Reviewed By: wez

Differential Revision: D8108728

fbshipit-source-id: 94a9393294ca259303026c297683dac4b3ecfac4
2018-06-06 14:36:32 -07:00
Sergey Zhupanov
419a57b1bc Enabled additional compiler warnings in Eden.
Summary:
1. Enabled a number of additional C++ compiler warnings in Eden.
2. Fixed warnings-turned-errors that resulted from this change.

Reviewed By: simpkins

Differential Revision: D8132543

fbshipit-source-id: 2290ffaaab55024d582e29201a1bcaa1152e6b3e
2018-06-01 11:39:01 -07:00
Orvid King
5e124cc05f Change calls from collectAll to collectAllSemiFuture
Summary: We are changing `folly::collectAll` to return `SemiFuture` rather than `Future` and this is needed as an interim step. After all calls to `collectAll` are changed to `collectAllSemiFuture`, we'll be renaming it back to `collectAll`.

Reviewed By: yfeldblum

Differential Revision: D8157548

fbshipit-source-id: 27b768ac7ff0d6572bde57f01601045a1fd5d5e5
2018-05-26 14:01:37 -07:00
Chad Austin
72be488e3d add convenient operator literals for the various path piece types
Summary:
I got tired of typing PathComponentPiece{"..."} in tests so here are
some operator literals.

Reviewed By: simpkins

Differential Revision: D7956732

fbshipit-source-id: 85d9f3fd725853a54da9e70fc659bd7eb9e0862c
2018-05-11 14:52:07 -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
Adam Simpkins
0195e0f6f0 ensure that the ServerState object outlives all EdenMounts
Summary:
This updates the code to store ServerState using a shared_ptr rather than
having it be an inlined member variable of EdenServer.

Previously EdenMount objects contained a raw pointer to the ServerState, with
the reasoning that the EdenServer object should outlive the EdenMount objects.
It turns out that this is not quite true in practice--EdenMount::destroy() will
normally be called before the EdenServer is destroyed, but this may not
actually destroy the EdenMount object immediately.

This fixes a race condition in the FuseTest.initMount() test that could cause
this test to occasionally fail when run on a heavily loaded system.

Reviewed By: chadaustin

Differential Revision: D7720509

fbshipit-source-id: 056ff5985587c8d8c32c11d17ba637ebd7598677
2018-04-23 13:53:48 -07:00
Adam Simpkins
c8921d0218 remove alternate EDEN_HAS_COMMON_STATS code paths
Summary:
Remove the EDEN_HAS_COMMON_STATS checks now that the common/stats stubs have
the required APIs needed by Eden.

Reviewed By: wez

Differential Revision: D7479593

fbshipit-source-id: cc3db50288bfea7aefd6c91391ab800628b7978f
2018-04-10 12:19:17 -07:00
Adam Simpkins
8be175e361 split up unmountAll() into separate takeover vs non-takeover functions
Summary:
Split up unmountAll() into two separate methods for the takeover vs
non-takeover code paths.  The logic for these two situations is fairly
different, and they have different return types.  Keeping them separate makes
it a bit easier to understand these two separate code paths.

In the future we may also want to update this code further so it can transfer
mounts to the new process as soon as each mount is done shutting down, which
would make these code paths diverge further.

Reviewed By: chadaustin

Differential Revision: D7504363

fbshipit-source-id: 50d19b9a660f791b69f3f5f99f3943040e6af368
2018-04-04 20:01:51 -07:00
Chad Austin
f80dd19454 add a graceful takeover method to TestMount
Summary: Now we can write unit tests for takeover. :)

Reviewed By: simpkins

Differential Revision: D7345419

fbshipit-source-id: 05741dab65016c59109bf190c83be2f676a6141d
2018-03-23 15:06:22 -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
2b2f7436f2 update EdenServer to handle unmounted mounts during takeover
Summary:
As of D7300847 the FuseChannel code will now return the FUSE FD as a closed
File object if the mount was unmounted, even if a takeover stop was requested.
This updates the EdenServer code to deal with the fact that it might receive a
closed FD even during a takeover.  The correct behavior is to simply skip this
mount when building the takeover state to pass to the new process.

This is a somewhat minimal change to fix up this bit of the code.  It would
probably be nice to continue simplifying this logic in the future.

Reviewed By: wez

Differential Revision: D7300877

fbshipit-source-id: c2f617449e155e4b42784ac42ec3aaa378e3288b
2018-03-16 17:39:13 -07:00
Chad Austin
a6b37d7a5d Verify inode numbers are consistent for unmaterialized objects across daemon
Summary:
A little integration test verifying inode numbers remain consistent
after graceful restart.

Reviewed By: simpkins

Differential Revision: D7304778

fbshipit-source-id: 96321d56c68c0e328f3c53ca7c1e3ac64f3a6f8e
2018-03-16 14:56:35 -07:00
Adam Simpkins
ac35979de3 move the clock to ServerState
Summary:
Make ServerState also store the clock as a member variable.  This moves more
server-wide state into the ServerState class, and allows us to eliminate
another argument to the EdenMount constructor.

Reviewed By: chadaustin

Differential Revision: D7297832

fbshipit-source-id: 2a063d67752f46686987390b3faefb304455568a
2018-03-16 12:35:19 -07:00
Adam Simpkins
89b0607f0f move the main thread pool to ServerState
Summary:
Move the EdenCPUThreadPool from EdenServer to ServerState.

This ensures that all EdenMount objects always have a thread pool.  Previously
most unit tests were creating an EdenMount without a thread pool set, but the
FileInode code and TreeInode code could end up wanting to use the thread pool
even if no FuseChannel is running.

Reviewed By: chadaustin

Differential Revision: D7297828

fbshipit-source-id: 9861b3439cd091afe31fa13f449aa14656983318
2018-03-16 12:35:19 -07:00
Chad Austin
053bec97ac Eliminate InodeMap::load and require that the takeover state be passed into initialize
Summary: Cleaning up the takeover initialization code for EdenMount and InodeMap.

Reviewed By: simpkins

Differential Revision: D7294419

fbshipit-source-id: 58506f04259bb1017e6cd2e80e40e5820de6200f
2018-03-15 17:48:27 -07:00
Chad Austin
20dc41871b Make it clearer that SerializedInodeMap is a byproduct of takeover shutdown
Summary:
Instead of having a rule that save() must be called after
InodeMap::shutdown, just have InodeMap::shutdown return the
SerializedInodeMap if it's desired.

Reviewed By: simpkins

Differential Revision: D7292773

fbshipit-source-id: 2ba35fc729e19af122fe5d6c5a3287ad6b8af946
2018-03-15 17:48:27 -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
Chad Austin
ab39bcc10f decouple inode allocation initialization from the rest of InodeMap
Summary:
If the root TreeInode wants to allocate inode numbers, the inode
allocator must be initialized first.  But complete InodeMap
initialization requires the root TreeInode.  So split this into two
parts.

Also, I changed the inode allocator to a single atomic increment instead
of a lock acquisiton.

Finally, the extra assertions in this diff uncovered what looks like a
bug in the takeover logic where nextInodeNumber_ could end up being
smaller than the value in the takeover data, since the max inode
number from the overlay was assigned after loading from takeover data.

Reviewed By: simpkins

Differential Revision: D7107706

fbshipit-source-id: ec43cc81c11d709261598739c622609b372433a2
2018-03-07 23:11:49 -08:00
Chad Austin
34f78baa21 make it annoying to use InodeNumber as an integer
Summary:
I'm seeing test failures that I have not yet understood and I
thought they might be caused by an implicit conversion from
fusell::InodeNumber to bool.  Well, they're not, but this is how I
discovered that.  I'm not sure I want to land this change, but I'm
going to leave it around until I figure out what's happening with my
other diffs.

Reviewed By: simpkins

Differential Revision: D7077635

fbshipit-source-id: 50bf67026d2d0da0220c4709e3db24d841960f4b
2018-02-27 12:44:41 -08:00
Wez Furlong
eaeaf8f23c add SqliteLocalStore
Summary:
Adds a SQLite storage implementation and makes it the
default engine for integration tests; this requires fewer resources
to run and the integration tests thus run faster and more reliably.

In the future we may add a configuration option to remember the
storage engine that was used as it is currently not "safe" to switch
from one to the other because the hgproxyhash data cannot be
recreated without re-importing a revision.

Reviewed By: simpkins

Differential Revision: D6919456

fbshipit-source-id: 3afbfafb190cca0e3c797cd9b7cd051768575a8c
2018-02-08 20:06:55 -08:00
Adam Simpkins
70b75b4164 rename EdenServer::state_ to runState_
Summary:
Rename the existing `state_` variable to `runState_` to help distinguish it
from the new `serverState_` variable.

The information in `runState_` is all related to whether the EdenServer object
is starting, shutting down, or running normally.

Reviewed By: wez

Differential Revision: D6929864

fbshipit-source-id: ad7af381a8a291b12db9308668c7616ebd9b7f39
2018-02-08 19:36:03 -08:00
Adam Simpkins
fe1c35f781 move the privhelper APIs into a PrivHelper class
Summary:
Move all of the privhelper functionality into a PrivHelper class.  The
ServerState object now stores the PrivHelper object to use, rather than having
a global singleton.

This will make it easier to stub out the PrivHelper functionality during unit
tests.

Reviewed By: wez

Differential Revision: D6929862

fbshipit-source-id: e3edcb0a03ba9afdf34554cb961fd74557cdd6e3
2018-02-08 19:36:03 -08:00
Adam Simpkins
fd2aa6a596 remove the --thrift_address command line flag
Summary:
Drop the --thrift_address flag, and always create the thrift socket using a
fixed name under the `.eden` directory.  The location of the `.eden` directory
is still configurable with the `--edenDir` argument.

There isn't really much benefit to making the socket path be configurable
separately from the .eden directory path, and it adds to the code complexity.
For instance, while you can tell eden to listen on a TCP socket instead of a
Unix domain socket, that functionality has been broken since D4637285
introduced a `CHECK()` statement that crashes the code when using a TCP socket.

Reviewed By: wez

Differential Revision: D6929863

fbshipit-source-id: ee5f7341d01d3ce522cae936ef3c133bba3f18f7
2018-02-08 19:36:03 -08:00
Adam Simpkins
265b17d188 add a new ServerState class to store process-wide state
Summary:
Add a new ServerState class to store process-wide state that is shared across
multiple mounts.  Up until now we have passed around the shared state data as
separate variables.

This is intentionally separate from the existing EdenServer class to allow unit
tests to create EdenMount objects without an EdenServer object.

Reviewed By: wez

Differential Revision: D6929861

fbshipit-source-id: 5f22efb6d79dfd70031be1dc37f494c2ad8af902
2018-02-08 16:43:22 -08:00
Wez Furlong
a0fb6d9d05 split RocksDbLocalStore out from LocalStore
Summary:
This enables dropping in alternative implementations
of LocalStore and adds a MemoryLocalStore implementation for
use in our tests.

This diff doesn't change the default storage option for the
eden server.  I'll look at adding such an option in a follow up diff.

Reviewed By: chadaustin

Differential Revision: D6910413

fbshipit-source-id: 018bf04e0bff101e1f0ab35e8580ca2a2622e5ef
2018-02-07 11:54:16 -08:00
Chad Austin
697eb8a6fd run clang-format across eden
Summary:
```
find . \( -iname '*.cpp' -o -iname '*.h' \) -exec arc lint --apply-patches {} +
```

Differential Revision: D6820436

fbshipit-source-id: 173c0e3b5c023c1c9276f34e17d732f1dd161892
2018-01-26 11:20:31 -08:00
Chad Austin
adce4eba1e fix determining which inodes can be unloaded
Summary:
I'm not sure what was wrong with the old code, but I
simplified and clarified all of the time math and now `eden debug
unload` behaves as I'd expect it should.

Reviewed By: simpkins

Differential Revision: D6764962

fbshipit-source-id: 3ed359d4ab4652e95d1538a0982c24185999351c
2018-01-24 15:29:16 -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
Wez Furlong
9bb3db9ee4 stop journal subscribers prior to shutting down thrift
Summary:
This avoids the long delay and the `Cpp2Worker.cpp:281] Failed to join
outstanding requests.` message from showing up in the eden logs during shutdown
and graceful restart.

Reviewed By: chadaustin

Differential Revision: D6693117

fbshipit-source-id: 3c56314f288a596264cddae0d8bbab66ab19e9fe
2018-01-10 13:13:50 -08:00
Wez Furlong
530346887d split EdenMount::{create,initialize} -> safer takeover mounting
Summary:
Previously, `EdenMount::create` would implicitly call
`EdenMount::initialize` which would load the root inode and the `.eden` magical
directory.  That's fine for the fresh mount case, but in the case of the
graceful restart we need to take the opportunity to apply the `InodeMap`
from the old process before we start muddying its state.

This diff breaks out the `initialize` method from the `create` method and
makes the mount code call it after potentially loading the `InodeMap` from
the takeover data.

In addition, this diff removes the the `root->loadMaterializedChildren()`
call from the mount initialization code.  It is no longer required to do
this eagerly and it makes things simpler and our memory profile a little
smaller to defer this (I haven't measured how much that impacts things).

Reviewed By: simpkins

Differential Revision: D6691182

fbshipit-source-id: 52033a6d64105b658314a919f69dbfcd4eea242b
2018-01-10 13:13:50 -08:00
Wez Furlong
7daecf237d refactor mount/takeover code into a single flow
Summary:
This removes the duplicated logic and makes it a little
bit easier to follow the initialization sequence.

It doesn't change the behavior, just moves some code around.

Reviewed By: simpkins

Differential Revision: D6691180

fbshipit-source-id: 2068dbe56ebe9a6136d69689997aec8dedd32be0
2018-01-10 13:13:50 -08:00
Wez Furlong
c82616c564 refactor takeoverAll() -> unmountAll()
Summary:
This is the "simple" threading through of a `doTakeover`
flag and the return of `Optional<TakeoverData>` in the unmount code.

Reviewed By: simpkins

Differential Revision: D6691181

fbshipit-source-id: 4a384787783c16085f2e9964964023ba07cefca3
2018-01-09 22:23:12 -08:00
Wez Furlong
014789b4ca open file handles now survive graceful restart
Summary:
I'm so-so on a bit of the implementation here, but it works!

I had to change the `takeoverPromise` from the `pair<fuseDevice, connInfo>`
to a new helper struct because we now have three distinct pieces of data
to pass out of EdenMount to build up the overall TakeoverData.

The key change in this diff is that we have to release all of the file handles
we're maintaining in the `FileHandleMap` prior to shutting down the `InodeMap`,
otherwise the `InodeMap` will never complete (it waits for all inodes to be
unreferenced, and that cannot happen while there are open file handles).  I've
made the `FileHandleMap` serialization and clearing contingent on performing a
takeover shutdown because that feels like the safest thing to do wrt. not
losing any pending writes.

Reviewed By: simpkins

Differential Revision: D6672437

fbshipit-source-id: 7b1f0f8e7ff09dbed850c7737383ecdf1e5ff0c7
2018-01-09 22:23:11 -08:00
Wez Furlong
490e6adcf5 inform PrivHelper of takeover; graceful restarts now work!
Summary:
This is the key portion that makes the graceful restart
function.  This diff connects almost all of the moving pieces together;
it informs the priv helper about the takeover mount and transfers
the InodeMap information into the new generation of the eden server.

It doesn't yet load the fileHandleMap (will tackle that in a follow up diff)

Reviewed By: simpkins

Differential Revision: D6670903

fbshipit-source-id: 1770d99eb1477440a6c1deed83b0da55b9c1bbe4
2018-01-09 22:23:10 -08:00
Wez Furlong
ef214c6c4f serialize the InodeMap
Summary:
this isn't how we really want to do this long term, it's
just the most expedient short term implementation.

This diff provides an implementation of the `InodeMap::save()` which
was previously a stub method; the new implementation returns a thrift
structure that encompasses the unloaded inodes in the map, and adds
a corresponding load() method that performs the reverse transformation.

The struct is serialized into the Takeover data.

This diff doesn't hook up the real serialized data to EdenServer; that will happen
in a follow-on diff.

The way that we actually want to handle this longer term is to store the
`numFuseReferences` field into the overlay file on disk, but to do so we
will need to add a mountGeneration field alongside it and ensure that we
always write out the correct information at the correct times.  In addition,
we'd need to add equivalent data to TreeInode::Entry and add accessors that
safely return the correct values in the correct situations.

In the interest of getting something working, I've just dumped this code in
here.

I've also placed the thrift structure for this in `fuse/handlemap.thrift`;
this is a slight layering violation but one that feels "OK" in light of
the imminent refactor of the Takeover data struct to be its own thrift
struct anyway.

Reviewed By: simpkins

Differential Revision: D6670904

fbshipit-source-id: 11a0918954c741935c587e46fcb0e38849010de1
2018-01-09 22:23:10 -08:00
Wez Furlong
65b2d3c4b1 serialize FileHandleMap into TakeoverData
Summary:
This puts the data into the takeover information during takeover
shutdown, but doesn't do anything to pull it out again (that will be in a follow on diff).

The serialization stuff could be done a little bit more efficiently (since we
will perform an extra thrift serialization step just to compute the length, and
repeat it again later), but we're planning on replacing this with thrift
serializing soon, once simpkins diff stack lands, so I'm not losing sleep over
it.

Reviewed By: simpkins

Differential Revision: D6668846

fbshipit-source-id: e6d01428bd506a9e93b427db499770fce0a0983a
2018-01-09 22:23:08 -08:00
Wez Furlong
1c2a4c3f93 add client configuration path to TakeoverData
Summary:
This fulfils a TODO but doesn't do anything useful
with that data at this time.

Reviewed By: simpkins

Differential Revision: D6552750

fbshipit-source-id: 0c441fd0c2ab43785b4d98c4ca6ff643a20629e0
2018-01-09 22:23:07 -08:00
Wez Furlong
8689b37221 connect the fuse device information to the takeover data
Summary:
This adds some plumbing to thread the fuse device descriptor and
negotiated capabilities through to the takeover code.

I initially wanted to just make the
unmount future yield the device descriptor, but since that uses
`SharedPromise` it is not compatible with a move-only type like
`folly:File`, so I added an optional promise to deal with just that.

I'm also populating the takeover mount information (path, bind mounts)
for each mount point.

Reviewed By: simpkins

Differential Revision: D6494509

fbshipit-source-id: a90684292dc1d8e06ce2c0721eadd8d393377f33
2018-01-09 22:23:04 -08:00
Wez Furlong
6ff492d11c remove dep on libfuse
Summary:
This serves a few purposes:

1. We can avoid some conditional code inside eden if we know that
   we have a specific fuse_kernel.h header implementation.
2. We don't have to figure out a way to propagate the kernel
   capabilities through the graceful restart process.
3. libfuse3 removed the channel/session hooks that we've been
   using thus far to interject ourselves for mounting and
   graceful restarting, so we were already effectively the
   walking dead here.
4. We're now able to take advtange of the latest aspects of
   the fuse kernel interface without being tied to the implementation
   of libfuse2 or libfuse3.  We're interested in the readdirplus
   functionality and will look at enabling that in a future diff.

This may make some things slightly harder for the more immediate
macOS port but I belive that we're in a much better place overall.

This diff is relatively mechanical and sadly is (unavoidably) large.

The main aspects of this diff are:

1. The `fuse_ino_t` type was provided by libfuse so we needed to
   replace it with our own definition.  This has decent penetration
   throughout the codebase.
2. The confusing `fuse_file_info` type that was multi-purpose and
   had fields that were sometimes *in* parameters and sometimes *out*
   parameters has been removed and replaced with a simpler *flags*
   parameter that corresponds to the `open(2)` flags parameter.
   The *out* portions are subsumed by existing file handle metadata
   methods.
3. The fuse parameters returned from variations of the `LOOKUP` opcode
   now return the fuse kernel type for this directly.  I suspect
   that we may need to introduce a compatibility type when we revisit
   the macOS port, but this at least makes this diff slightly simpler.
   You'll notice that some field and symbol name prefixes vary as
   a result of this.
4. Similarly for `setattr`, libfuse separated the kernel data into
   two parameters that were a little awkward to use; we're now just
   passing the kernel data through and this, IMO, makes the interface
   slightly more understandable.
5. The bulk of the code from `Dispatcher.cpp` that shimmed the
   libfuse callbacks into the C++ virtual methods has been removed
   and replaced by a `switch` statement based dispatcher in
   `FuseChannel`.   I'm not married to this being `switch` based
   and may revise this to be driven by an `unordered_map` of
   opcode -> dispatcher method defined in `FuseChannel`.  Regardless,
   `Dispatcher.cpp` is now much slimmer and should be easier to
   replace by rolling it together into `EdenDispatcher.cpp` in
   the future should we desire to do so.
6. This diff disables dispatching `poll` and `ioctl` calls.  We
   didn't make use of them and their interfaces are a bit fiddly.
7. `INTERRUPT` is also disabled here.  I will re-enable it in
   a follow-up diff where I can also revise how we track outstanding
   requests for graceful shutdown.
8. I've imported `fuse_kernel.h` from libfuse.  This is included
   under the permissive 2-clause BSD license that it allows for
   exactly this integration purpose.

Reviewed By: simpkins

Differential Revision: D6576472

fbshipit-source-id: 7cb088af5e06fe27bf22a1bed295c18c17d8006c
2018-01-02 16:36:16 -08:00
Adam Simpkins
f42c51c6eb remove the --rocksPath command line flag
Summary:
The RocksDB location is relative to the .eden directory.  Given that the
location of the .eden directory can be controlled from the command line it
doesn't seem worthwhile to make the RocksDB location independently controllable
too.

Reviewed By: chadaustin

Differential Revision: D6527495

fbshipit-source-id: dab8c22f3f1a74de908ea33d0b20c4115c28ce31
2017-12-14 12:41:47 -08:00
Chad Austin
2f22a9f534 introduce a type representing the unbounded eden cpu pool
Summary:
Add EdenCPUThreadPool and UnboundedQueueThreadPool types to make it clearer
that it's always okay for prefetch, deferred diff entry, and hg import to
shuttle work back to the main thread pool.

This diff changes no behavior - it just makes some invariants explicit.

Reviewed By: wez, simpkins

Differential Revision: D6504117

fbshipit-source-id: 3400ad55c00b3719ecba31807fd992442f622cd9
2017-12-12 12:35:35 -08:00
Chad Austin
5eaddd7921 Make sure shutdown() errors propagate to unmount() waiters
Summary: Use SharedPromise::setFuture to make sure errors propagate.

Reviewed By: simpkins

Differential Revision: D6515818

fbshipit-source-id: dee95bccdc086a040ead08e60373cbc7daa4db3f
2017-12-11 18:16:05 -08:00
Chad Austin
e19939cf15 fix crash when too many tasks are put on the eden thread pool
Summary:
Use an unbounded queue for edenfs's main thread pool.  This fixes a
crash where DeferredDiffEntry multigets a batch of trees and pushes
the completion callbacks back onto the server thread pool.  If the
server thread pool is bounded and throws when the queue is full, then
the import fails.

There is a slight performance hit relative to LifoSemMPMCQueue but
hopefully it isn't a big deal.  An unbounded lock-free queue would be
nicer.

Reviewed By: simpkins

Differential Revision: D6490979

fbshipit-source-id: bc55dd6526f0ceb9d8b5e43a1a275250a9838aca
2017-12-05 17:52:04 -08:00
Chad Austin
f91ae520b2 introduce a Clock seam for testability
Summary:
Introduce a Clock seam.  This will allow us to write tests around
ctime, mtime, and atime logic.

Reviewed By: wez

Differential Revision: D6392543

fbshipit-source-id: 1721d76d2364b135b4ef5c078ef60f7f8526259e
2017-12-05 10:06:48 -08:00
Adam Simpkins
7d98d9cfc4 define constants for several files in the .eden directory
Summary:
Define constants at the top of EdenServer.cpp for the names of the main lock
file, the thrift socket, and the takeover socket.

Reviewed By: bolinfest

Differential Revision: D6295040

fbshipit-source-id: 8605840a50c84bc89b798123d1063bbb11ff2502
2017-11-20 11:35:50 -08:00
Adam Simpkins
e64baf16db add a --takeover flag to allow graceful takeover
Summary:
This begins implementing the "client-side" portion of graceful takeover in
edenfs.  When the --takeover flag is specified, if edenfs finds that another
edenfs process is already running it will attempt to gracefully take over its
mount points rather than exiting with an error.

This does not yet actually take over the mount points themselves--it still
sends dummy mount information during shutdown, and does not use this data
during startup.  However, we do perform takeover of the eden lock file and the
thrift server socket.

Reviewed By: bolinfest

Differential Revision: D6038944

fbshipit-source-id: 42406a0559367cec79af088b4ca84c22de3f3ef3
2017-11-20 11:35:49 -08:00
Adam Simpkins
649b4e3ecb send the thrift server socket during graceful takeover
Summary:
Update the TakeoverData to also include the thrift server socket.
Also update EdenServer to set this field when performing a takeover
shutdown.

Reviewed By: bolinfest

Differential Revision: D6038945

fbshipit-source-id: 725faa431b3b55d617ef645c8a7eae080e4fe066
2017-11-19 15:47:30 -08:00
Adam Simpkins
532e42cb87 update EdenServer to implement TakeoverHandler
Summary:
Update EdenServer to implement the TakeoverHandler API, and to exit after
sending the mount point takeover data.  The actual shutdown logic itself is not
implemented yet--this just sends dummy data for now.  However, this does serve
as a proof of concept that the TakeoverServer and TakeoverClient code functions
as desired.

Reviewed By: bolinfest

Differential Revision: D6018180

fbshipit-source-id: c19581928926a46b767f1ee5c1761381e5055fa9
2017-11-19 15:47:25 -08:00
Michael Bolin
019f456fab Change the contents and format for the edenrc file under ~/local/.eden.
Summary:
The headline changes of this revision are:

- Changes the format of the config file from INI to TOML
  (the `edenrc` file under `~/local/.eden` has been replaced
  with `config.toml`). This revision includes logic for automatically
  performing the migration when Eden is restarted.
- Inlines data from `/etc/eden/config.d` into the TOML file.

Historically, the `edenrc` file for a client would contain the
name of the "configuration alias" defined in a config file like
`~/.edenrc` or `/etc/eden/config.d/00-defaults`. When Eden
loaded a client, it would have to first read the `edenrc` and
then reconstitute the rest of the client configuration by
looking up the alias in the set of config files that were used to
create the client in the first place.

This changes things so that all of the data that was being
cross-referenced is now inlined in the client's config file.
This makes loading a config considerably simpler at the cost
of no longer being able to change the config for multiple clients
that were cloned from the same configuration alias in one place.
It was questionable whether being able to modify a client from
a foreign config after it was created was a safe thing to do, anyway.

Eliminating the need for a historic link to the configuration alias
will make it easier to support running `eden clone` on an arbitrary
local Hg or Git repo. So long as `eden clone` can extract enough
information from the local repo to create an appropriate config file
for the new Eden client, there is no need for a configuration alias
to exist a priori.

Since we were already changing the data in the config file, this
seemed like an appropriate time to make the switch from INI to
TOML, as this was something we wanted to do, anyway.
In testing, I discovered a discrepancy between how boost's
`boost::property_tree::ptree` and Python's `ConfigParser` handled
the following section heading:

```
[repository ZtmpZsillyZeden-clone.LIkh32]
```

Apparently `hasSection("repository ZtmpZsillyZeden-clone.LIkh32")`
in boost would fail to find this section. Because
[[https://stackoverflow.com/questions/13109506/are-hyphens-allowed-in-section-definitions-in-ini-files | there is no spec for INI]],
it is not that surprising that boost and `ConfigParser` do not 100% agree
on what they accept. Moving to TOML means we have a configuration
language with the following desirable properties:

- It has a formal spec, unlike INI. This is important because there are parsers
  in a wide range of programming languages that, in theory, accept a consistent
  input language.
- It is reasonable for humans to write, as it supports comments, unlike JSON.
- It supports nested structures, like maps and arrays, without going crazy
  on the input language it supports, unlike YAML.

Eden now depends on the following third-party TOML parsers:
* C++ https://github.com/skystrife/cpptoml
* Python https://github.com/uiri/toml

This revision also changes the organization of `~/local/.eden` slightly. For now,
there is still a `config.json` file, but the values are no longer hashes of the realpath
of the mount. Instead, we take the basename of the realpath and use that as the
name of the directory under `~/local/.eden/clients`. If there is a naming collision, we
add the first available integral suffix. Using the basename makes it easier to
navigate the `~/local/.eden/clients` directory.

Although the `edenrc` file under `~/local/.eden/clients` has been switched from INI
to TOML, the other Eden config files (`~/.edenrc` and `/etc/eden/config.d/*`) still use
INI. Migrating those to TOML will be done in a future revision.

Note this revision allowed us to eliminate `facebook::eden::InterpolatedPropertyTree`
as well as a number of uses of boost due to the elimination of
`ClientConfig::loadConfigData()` in the C++ code. Because `ClientConfig`
no longer does interpolation, a bit of `ClientConfigTest` was deleted as part of
this revision because it is no longer relevant.

Reviewed By: wez

Differential Revision: D6310325

fbshipit-source-id: 2548149c064cdf8e78a3b3ce6fe667ff70f94f84
2017-11-16 13:23:27 -08:00
Chad Austin
385a94a69f Use a pool of HgImporter workers
Summary:
Have HgBackingStore hold multiple HgImporters in its own thread pool. Incoming
requests are processed by threads in the thread pool.

Reviewed By: wez

Differential Revision: D6265043

fbshipit-source-id: b2d4f345b772f296c5335a7fbcadfce1d93245fd
2017-11-15 09:49:48 -08:00
Michael Bolin
e8d25ee211 Move the post-clone step from C++ to Python.
Summary:
Moving the post-clone step out of C++ makes it so that
`ClientConfig` in C++ no longer knows about `hooks` and requires
`RepoConfig` to know about `hooks`. This helps us reduce
`ClientConfig`'s dependency on `ConfigData`, as my next step
is to move the remaining information that `ClientConfig` gets from
`ConfigData` directly into the client's `edenrc` file under
`~/local/.eden`.

Reviewed By: chadaustin

Differential Revision: D6310544

fbshipit-source-id: dec7a21281ab49e0416b8872757970a4eff2d943
2017-11-14 14:06:25 -08:00
Scott Michelson
0431efa7f8 remove all setMaxConnections calls
Summary:
This setting is bad for a few reasons

1) there is no correct value; rejecting connections is typically something you want to do when under pressure, which no fixed number of connections can indicate
2) it's not discoverable when it trips, and pretty much always confuses people
3) the effect is generally not better than the thing it is theoretically supposed to prevent, when it trips, servers crash and exhibit other weird behaviors; I don't think I've ever seen a situation where I thought this was needed, and I've seen many were it created problems where none would have existed.

About a year ago, I removed almost all calls to this; however, I left some behind since they were slightly harder to clean up or had unique flag names. Since then, 2 things have happened

1) more copypasta instances have cropped up
2) More people have run into issues with this flag, notably up2x recently

This removes all calls except one (realtime Pylon has some somewhat more complex config here, I'll need to talk to them). This is somewhat aggressive; some of the calls are totally safe to remove, as they're either copypasted or set it to 0 or some absurdly high number. Others are less obvious. I've decided to adopt a door-in-the-face strategy here and see if anyone tells me I should be more conservative

I couldn't delete all the flags; these ones are in use

zdb_thrift_max_connection
thrift2_max_connections (commerce ranker)
max_connections (a bunch of places)
maxConnections (presence)

I'll need a separate diff/set of diffs to delete those

Reviewed By: eduardo-elizondo, yfeldblum

Differential Revision: D6182563

fbshipit-source-id: e778edd9da582f4ca90a902621cb49f1e04ca26e
2017-11-09 12:18:50 -08:00
Adam Simpkins
c0e048148e log around opening the RocksDB local store
Summary:
Opening the RocksDB store can take a long time if there is a fair amount of
data in the store.  In my current .eden directory I have around 10GB of data in
the local store, and it takes RocksDB nearly 60 seconds to open the database.

These log messages help provide a little more information about what edenfs is
doing during this startup delay.

Reviewed By: bolinfest

Differential Revision: D6263603

fbshipit-source-id: a0945aa1cc020b95944b365b17869756dcc27407
2017-11-07 14:17:37 -08:00
Michael Bolin
5d738193e5 Store Hg dirstate data in Hg instead of Eden.
Summary:
This is a major change to how we manage the dirstate in Eden's Hg extension.

Previously, the dirstate information was stored under `$EDEN_CONFIG_DIR`,
which is Eden's private storage. Any time the Mercurial extension wanted to
read or write the dirstate, it had to make a Thrift request to Eden to do so on
its behalf. The upside is that Eden could answer dirstate-related questions
independently of the Python code.

This was sufficiently different than how Mercurial's default dirstate worked
that our subclass, `eden_dirstate`, had to override quite a bit of behavior.
Failing to manage the `.hg/dirstate` file in a way similar to the way Mercurial
does has exposed some "unofficial contracts" that Mercurial has. For example,
tools like Nuclide rely on changes to the `.hg/dirstate` file as a heuristic to
determine when to invalidate its internal caches for Mercurial data.

Today, Mercurial has a well-factored `dirstatemap` abstraction that is primarily
responsible for the transactions with the dirstate's data. With this split, we can
focus on putting most of our customizations in our `eden_dirstate_map` subclass
while our `eden_dirstate` class has to override fewer methods. Because the
data is managed through the `.hg/dirstate` file, transaction logic in Mercurial that
relies on renaming/copying that file will work out-of-the-box. This change
also reduces the number of Thrift calls the Mercurial extension has to make
for operations like `hg status` or `hg add`.

In this revision, we introduce our own binary format for the `.hg/dirstate` file.
The logic to read and write this file is in `eden/py/dirstate.py`. After the first
40 bytes, which are used for the parent hashes, the next four bytes are
reserved for a version number for the file format so we can manage file format
changes going forward.

Admittedly one downside of this change is that it is a breaking change.
Ideally, users should commit all of their local changes in their existing mounts,
shutdown Eden, delete the old mounts, restart Eden, and re-clone.

In the end, this change deletes a number of Mercurial-specific code and Thrift
APIs from Eden. This is a better separation of concerns that makes Eden more
SCM-agnostic. For example, this change removes `Dirstate.cpp` and
`DirstatePersistance.cpp`, replacing them with the much simpler and more
general `Differ.cpp`. The Mercurial-specific logic from `Dirstate.cpp` that turned
a diff into an `hg status` now lives in the Mercurial extension in
`EdenThriftClient.getStatus()`, which is much more appropriate.

Note that this reverts the changes that were recently introduced in D6116105:
we now need to intercept `localrepo.localrepository.dirstate` once again.

Reviewed By: simpkins

Differential Revision: D6179950

fbshipit-source-id: 5b78904909b669c9cc606e2fe1fd118ef6eaab95
2017-11-06 19:56:49 -08:00
Chad Austin
e5984e48d5 Revert D5067763: [eden] Use a pool of HgImporter workers
Summary:
D5067763 introduced a potential deadlock.  The issue is that all of the FUSE threads were blocked
on the HgImporter thread pool, which completes its futures back on serverEventThread_.  The
FUSE threads were blocked on Future::get() in ensureDataLoaded().

Eventually, the right fix is some combination of eliminating ensureDataLoaded() and
replacing it with an explicitly-asynchronous API.

Reviewed By: bolinfest

Differential Revision: D6212858

fbshipit-source-id: 42b17d3e20a200f26b87588784edb5ee51e96a4a
2017-11-01 14:55:45 -07:00
Stepan Palamarchuk
2e7804cc3e Remove more unused flags
Summary:
Thess flags are not used (neither in code, nor passed in on command line). List of flags that are getting killed:
thriftMaxNumMessagesInQueue
max_queue_message_num
thrift_max_unprocessed_message
thrift_set_max_num_messages_in_queue
decorator_thriftSetMaxNumMessagesInQueue
atlas_pinger_imps_thriftSetMaxNumMessagesInQueue
tesseract_ocr_max_queue_msgs_per_thread
max_msgs_in_queue
max_num_messages_in_queue
maxNumMessagesInQueue
thrift_max_messages
thrift_queue_len
max_accepts_in_pipe
max_pending_connections_per_io_thread
thriftMaxNumPendingConnectionsPerWorker
lookup_thriftSetMaxNumMessagesInQueue
thriftSetMaxNumPendingConnectionsPerWorker
max_queue_msgs_per_thread
ds_thrift_max_num_messages_in_queue
zdb_thrift_max_num_messages_in_queue
update_control_proxy_queue_length
safety_enforcer_proxy_queue_length
maxRequestsInQueue
max_num_messages_in_pipe

Reviewed By: yfeldblum

Differential Revision: D6143500

fbshipit-source-id: 541507d50100817590b91cdd48e39a29e7c465ea
2017-10-25 08:18:10 -07:00
Chad Austin
03396f30f7 Use a pool of HgImporter workers
Summary:
Have HgBackingStore hold multiple HgImporters in its own thread pool. Incoming
requests are processed by threads in the thread pool.

Reviewed By: wez

Differential Revision: D5067763

fbshipit-source-id: d666b1026455d13442367673010b5934ff4cdb48
2017-10-24 10:45:33 -07:00
Stepan Palamarchuk
e0227f8c4e Remove call-sites to ThriftServer::setMaxNumPendingConnectionsPerWorker()
Summary:
While debugging SRProxy issue I found a bug in ThriftServer initialization (more details in D6115379), due to that bug we always have accept queue of 1k and the value passed to `setMaxNumPendingConnectionsPerWorker` is ignored, thus making all call sites bogus.

We have ~350 calls to this function in fbcode, all of them pass random numbers such as 50, 100, 50k, etc. I’m removing all of them before landing the fix for Thrift to avoid causing production issues.

Unfortunately almost every such caller has a gflag for it (that are usually have confusing names, e.g. FLAGS_thriftSetMaxNumMessagesInQueue). I’m not touching these gflags, because they may be used in different configs and removing them would cause breakages.

Reviewed By: yfeldblum

Differential Revision: D6129569

fbshipit-source-id: 1550b5073bac42d0c6fb7bdffa1835bf523609c8
2017-10-23 19:32:03 -07:00
Michael Bolin
2c46c59ad6 Write the PID to the lockfile and update eden health to use it.
Summary:
We have encountered cases where `eden health` reported
`"edenfs not healthy: edenfs not running"` even though the `edenfs` process is
still running. Because the existing implementation of `eden health` bases its
health check on the output of a `getStatus()` Thrift call, it will erroneously
report `"edenfs not running"` even if Eden is running but its Thrift server is
not running. This type of false negative could occur if `edenfs` has shutdown
the Thrift server, but not the rest of the process (quite possibly, its
shutdown is blocked on calls to `umount2()`).

This is further problematic because `eden daemon` checks `eden health`
before attempting to start the daemon. If it gets a false negative, then
`eden daemon` will forge ahead, trying to launch a new instance of the daemon,
but it will fail with a nasty error like the following:

```
I1017 11:59:25.188414 3064499 main.cpp:81] Starting edenfs.  UID=5256, GID=100, PID=3064499
terminate called after throwing an instance of 'std::runtime_error'
  what():  another instance of Eden appears to be running for /home/mbolin/local/.eden
*** Aborted at 1508266765 (Unix time, try 'date -d 1508266765') ***
*** Signal 6 (SIGABRT) (0x1488002ec2b3) received by PID 3064499 (pthread TID 0x7fd0d3787d40) (linux TID 3064499) (maybe from PID 30644
99, UID 5256), stack trace: ***
    @ 000000000290d3cd folly::symbolizer::(anonymous namespace)::signalHandler(int, siginfo_t*, void*)
    @ 00007fd0d133cacf (unknown)
    @ 00007fd0d093e7c8 __GI_raise
    @ 00007fd0d0940590 __GI_abort
    @ 00007fd0d1dfeecc __gnu_cxx::__verbose_terminate_handler()
    @ 00007fd0d1dfcdc5 __cxxabiv1::__terminate(void (*)())
    @ 00007fd0d1dfce10 std::terminate()
    @ 00007fd0d1dfd090 __cxa_throw
    @ 00000000015fe8ca facebook::eden::EdenServer::acquireEdenLock()
    @ 000000000160f27b facebook::eden::EdenServer::prepare()
    @ 00000000016107d5 facebook::eden::EdenServer::run()
    @ 000000000042c4ee main
    @ 00007fd0d0929857 __libc_start_main
    @ 0000000000548ad8 _start
Aborted
```

By providing more accurate information to `eden daemon`, if the user tries to
run it while the daemon is already running, they will get a more polite error
like the following:

```
error: edenfs is already running (pid 274205)
```

This revision addresses this issue by writing the PID of `edenfs` in the
lockfile. It updated the implementation of `eden health` to use the PID in the
lockfile to assess the health of Eden if the call to `getStatus()` fails. It
does this by running:

```
ps -p PID -o comm=
```

and applying some heuristics on the output to assess whether the command
associated with that process is the `edenfs` command. If it is, then
`eden health` reports the status as `STOPPED` whereas previously it would report
it as `DEAD`.

Reviewed By: wez

Differential Revision: D6086473

fbshipit-source-id: 825421a6818b56ddd7deea257a92c070c2232bdd
2017-10-18 11:29:43 -07:00
Michael Bolin
288d599fb3 Set flags to use default values for Thrift until we have a reason to do otherwise.
Summary:
Our existing values for these resources appear to be too conservative for
massively parallel builds. Although we expected Eden to behave more like a small
application, there are times when it has to be able to respond more like a
well-provisioned service (particularly during the parse phase of a large Buck
build).

Reviewed By: simpkins

Differential Revision: D6075340

fbshipit-source-id: 7c26e9b0f785358968430527115c63c6d8cdedc8
2017-10-18 11:29:43 -07:00
Chad Austin
24c0fe9e8f prefetch inode contents when they're looked up
Reviewed By: wez

Differential Revision: D5817915

fbshipit-source-id: 3820f635cc6251ae5e13a4e214ba66df25ab6687
2017-09-19 11:10:11 -07:00
Wez Furlong
8135820893 EdenServiceHandler::mountImpl -> EdenServer::mount
Summary:
Following on from D5798659, this diff pulls the mount flow into
EdenServer.  Previously the flow of control would bounce back and forth between
the EdenServiceHandler and EdenServer and this made it (IMO) more difficult to
follow and understand where to add things into the flow.

Now `EdenServer::mount` is the main entry point for the mounting flow.

I've simplified the stat registration and broken that out into helper methods
to avoid cluttering up the mount logic.

Reviewed By: bolinfest

Differential Revision: D5806393

fbshipit-source-id: 7c858a2a580332ce82c2600e9dc3537af1d734d1
2017-09-13 08:42:22 -07:00
Wez Furlong
fab0c4071c centralize the post-mount functionality
Summary:
This moves the bind mounting and post-clone script running
functionality to methods of the EdenMount class and makes the whole
mount flow return a `Future<>`.  The higher level goal is to make it
easier to see where and how we want to tweak this flow to support
graceful restart.

This is mostly straight forward but care is required to avoid deadlocks; there
are two scenarios:

  # We fulfill the fuse start promise in the context of the fuse thread that is
  handling the fuse initialization packet before it has signalled to the kernel
  that it has come up.  This can be solved by using `via(mainEventBase_)`, but...
  # When remounting all the mounts on startup, we're running in the
  `mainEventBase_` thread so the simplistic solution to 1. would cause us to
  deadlock on startup (visible in the remount integration tests).

So to avoid this, we shunt the completion of the future via a CPU pool.

Also worth noting: the way we were setting up the global CPU pool with
wangle wasn't correct; it takes a weak reference to the pool which was
then getting destroyed when our prepare method returned.  It just happened
to work for us in the facebook specific build because something else was
setting up a different CPU executor.

I've reconciled this by just setting up a thread pool of our own and
using that explicitly.

Reviewed By: bolinfest

Differential Revision: D5798659

fbshipit-source-id: f1c48730f283f6962f6cd706c02d82ea2952e369
2017-09-13 08:42:21 -07:00
Wez Furlong
fe1a376e0f migrate functionScheduler to eventBase timer
Summary:
This is reasonably straightforward, although a little
more fiddly than I'd hoped because the timer wheel stuff doesn't
offer a convenient way to set up a recurring timer.

I've also made the inode unloading code get run globally for all
mounts; it was previously scheduling one timer per mount point.
This nets out the same; the function scheduler was just a single
thread anyway, so there is no change in the level of concurrency.
I believe that this tidies up the unload counter too; it looked
like we'd set the counter to be the result of the last mount
point that we processed rather than the aggregate of all mounts.

Having the unload timer be associated with the server rather
than the mount points means that we don't have to do anything
special to coordinate with the timer management when the mount
point is being torn down.

Reviewed By: bolinfest

Differential Revision: D5792938

fbshipit-source-id: 1a14bb7b7f4952139e684fe6b52f64bd1ba70dd0
2017-09-13 08:42:21 -07:00
Wez Furlong
1e679a2400 remove stale TODO comment
Summary: This looks like it ended up getting done together with the original diff

Reviewed By: simpkins

Differential Revision: D5796901

fbshipit-source-id: 24ab05c50b13a37eefe903de5fd3f2dac3d462da
2017-09-08 19:25:34 -07:00
Wez Furlong
d910ab6594 unify state and fuseStatus in EdenMount
Summary:
After performing the dumb merge of EdenMount and MountPoint in
the prior commit, this one tidies up the state tracking and the interface
by which clients of the object can be notified of state changes.

I've introduced two Promises; the first of these can be used to wait
for the fuse mount to come up or error out.  It logically replaces
the cond wait in the `start` method and is exposed to the caller
as a Future, allowing them to wait and react to the outcome.

The second of the promises is associated with the fuse thread pool
winding down.  The attached future can be extracted and used by the
client of the EdenMount class.  This future yields the fuse device
descriptor which we can then choose to pass on during graceful
restart or simply close.  In the current integration, since we ignore
the result of that future, the handle is implicitly closed.

These promises allow us to remove the reference cycle that we had with the
`onStop` function and to potentially make the mount/unmount sequence more
async.

Reviewed By: bolinfest

Differential Revision: D5778214

fbshipit-source-id: 00b293009b7251ddd8bfb10795a115188e97aa3a
2017-09-08 19:25:34 -07:00
Wez Furlong
3da68e5adc dumb merge of MountPoint into EdenMount
Summary:
This is a mechanical and dumb move of the code from MountPoint
and into the EdenMount class.

Of note, it doesn't merge together the two different state/status fields
into a unified thing; that will be tackled in a follow on diff.

Reviewed By: bolinfest

Differential Revision: D5778212

fbshipit-source-id: 6e91a90a5cc760429d87a475ec12f81b93f87be0
2017-09-08 19:25:34 -07:00
Wez Furlong
467c417ccb re-organize the fuse Channel and Session code
Summary:
The higher level goal is to make it easier to deal
with the graceful restart scenario.

This diff removes the SessionDeleter class and effectively renames
the Channel class to FuseChannel.  The FuseChannel represents
the channel to the kernel; it can be constructed from a fuse
device descriptor that has been obtained either from the privhelper
at mount time, or from the graceful restart procedure.  Importantly
for graceful restart, it is possible to move the fuse device
descriptor out of the FuseChannel so that it can be transferred
to a new eden process.

The graceful restart procedure requires a bit more control over
the lifecycle of the fuse event loop so this diff also takes over
managing the thread pool for the worker threads.  The threads
are owned by the MountPoint class which continues to be responsible
for starting and stopping the fuse session and notifying EdenServer
when it has finished.  A nice side effect of this change is that
we can remove a couple of inelegant aspects of the integration;
the stack size env var stuff and the redundant extra thread
to wait for the loop to finish.

I opted to expose the dispatcher ops struct via an `extern` to
simplify the code in the MountPoint class and avoid adding special
interfaces for passing the ops around; they're constant anyway
so this doesn't feel especially egregious.

Reviewed By: bolinfest

Differential Revision: D5751521

fbshipit-source-id: 5ba4fff48f3efb31a809adfc7787555711f649c9
2017-09-08 19:25:34 -07:00
Adam Simpkins
25c7041589 add an EdenServer::getMainEventBase() method
Summary: Add a method to get the EventBase used to drive the main thread.

Reviewed By: wez

Differential Revision: D5750054

fbshipit-source-id: ad2eba021a6200ed28e39a60b16d90aabfaee5b4
2017-08-31 19:05:23 -07:00
Adam Simpkins
15c3de2dc1 add an EdenServer::run() method
Summary:
This moves logic for running the server from main.cpp into the EdenServer
class.

This will make it easier to refactor some of the start-up and running process
in the future, and makes EdenServer the owner of this entire workflow.  This
will help as we start splitting the startup code into two separate code paths:
one for a new, fresh start, and one for graceful restart taking over mounts
from an existing eden process.

Reviewed By: bolinfest

Differential Revision: D5732656

fbshipit-source-id: 63f05eb1105078764f4e4931d770416dd5f6d6dc
2017-08-30 13:50:08 -07:00
Jyothsna Konisa
8fb37c1ada Diagnostic tool to report Stat information of EdenFs
Summary:
Added new tool to report stat information of EdenFs like fuse counters, Memory counters, latencies, Inode status for all the mount points etc.

eden stat : Prints the general information about eden like list of mount points, loaded unloaded and materialized inodes in each mount point. Also this reports how well periodic unload job is doing by reporting the number of unloaded inodes by periodic job.

eden stat io : Prints how many number of calls made to a system call in Edenfs.

eden stat memory : returns the memory stat for edenfs.

eden stat latency : reports the latencies of system calls in Edenfs.

Reviewed By: bolinfest

Differential Revision: D5660345

fbshipit-source-id: 97a1c2b83a6d8df0cd1b82c4d54b52d7ebd126bd
2017-08-25 12:49:35 -07:00
Jyothsna Konisa
43f27195b6 Modification of unloadChildrenNow
Summary: Modified `TreeInode::unloadChildrenNow` such that inodes are unloaded whose age is greater than a specific age.

Reviewed By: simpkins

Differential Revision: D5526137

fbshipit-source-id: 91e2364d55e31befedcf43d98c26467e1a472ef9
2017-08-18 14:20:43 -07:00
Adam Simpkins
abacbf38ec fix thread-local stats flushing
Summary:
Update the EdenServer code to correctly aggregate the thread local stats data
from all threads.  Previously it only aggregated stats from the
FunctionScheduler thread that it was running in.  This thread never updates any
stats, so it never had any actual stats data.

This also adds a thrift call to trigger stats flushing immediately.  This can
be called from integration tests to ensure that they get up-to-date stats
information.

Reviewed By: bolinfest

Differential Revision: D5657267

fbshipit-source-id: 060a24c00a19568b09ae8795477d73a3baab9a3c
2017-08-18 11:50:56 -07:00
Adam Simpkins
66ed1cd727 use folly::Synchronized to manage the mount point map
Summary:
Update EdenServer to use folly::Synchronized for managing access to the
mountPoints_ map, instead of using a separate standalone mutex.  This simply
makes it slightly harder to accidentally access the mount point map without
holding the lock correctly.

Reviewed By: bolinfest, wez

Differential Revision: D5541315

fbshipit-source-id: 094a941a3b8177aed4a75b91a998494f4c33fe8c
2017-08-02 17:42:49 -07:00
Adam Simpkins
4949aada7f fix EdenServer::unmount() to fully wait for mount point cleanup
Summary:
This fixes EdenServer::unmount() to actually wait for all EdenMount cleanup
to complete, and fixes unmountAll() to return a Future that correctly waits for
all mount points to be cleaned up.

Previously `unmount()` waited for the mount point to be unmounted from the
kernel, but did not wait for EdenMount shutdown to complete.  Previously
EdenMount shutdown was not triggered until the last reference to the
shared_ptr<EdenMount> was released.  This often happened in the FUSE channel
thread that triggered the mountFinished() call--it would still hold a
reference to this pointer, and would not release it until after
mountFinished() returns.  As a result, when the main thread was shutting down,
`main()` would call `unmountAll()`, and then return soon after it completed.
Some FUSE channel threads may still be running at this point, still performing
`EdenMount` shutdown while the main thread was exiting.  This could result in
crashes and deadlocks as shutdown tried to access objects already destroyed by
the main thread.

With this change `EdenMount::shutdown()` is triggered explicitly during
`mountFinished()`, and `unmount()` will not complete until this finishes.
The `EdenMount` object may still exist at this point, and could still be
deleted by the FUSE channel thread, but the deletion now only requires freeing
the memory and does not require accessing other data that may have been cleaned
up by the main thread.

We should still clean up the FUSE channel thread handling in the future, to
make sure these threads are joined before the main thread exits.  However, that
cleanup can wait until a separate diff.  Ideally I would like to move more of
the mount and unmount logic from EdenServer and EdenServiceHandler and put that
code in EdenMount instead.

Reviewed By: bolinfest

Differential Revision: D5541318

fbshipit-source-id: 470332478357a85c314bc40458373cb0f827f62b
2017-08-02 17:07:19 -07:00
Adam Simpkins
7a7e32090f wait for the unload inodes function to finish when unmounting
Summary:
When cleaning up an unmounted EdenMount, cancel the periodic unload inodes
function before we remove the mount from the mountPoints_ map and signal other
threads that it has been removed via mountPointsCV_.  Also use
FunctionScheduler::cancelAndWait() to make sure that we wait for the function
to complete if it was currently in the middle of being run.

Reviewed By: bolinfest

Differential Revision: D5541316

fbshipit-source-id: 46046f59746b5f283a5d4af94159b5c122d43d0d
2017-08-01 20:53:09 -07:00
Jyothsna Konisa
638615b542 periodic job to unload inodes
Summary:
Added `EdenServer::unloadInodesScheduler_` to schedule unloading inodes on timely basis.
new function will be added to the function scheduler on each mount, so each mount point can be have different start delay and different frequency.

Reviewed By: simpkins

Differential Revision: D5501036

fbshipit-source-id: 238b9cb5747a2358c65a1508095ad672bdf87ffc
2017-07-31 20:52:35 -07:00
Jyothsna Konisa
f0587420a2 Race condition Fix on overlay lock during unmount
Summary:
Some test cases are crashing once in a whiled due to a race condition on lock over overlay directory.

when a mount point is unmounted, `EdenServer::mountFinished` called on `umount` where destruction of `EdenMount` object for the mount point happens. When a remount is called before the destruction of `EdenMount` a race condition is occuring on the lock of overlay directory as the undestructed `EdenMount` still holds the lock on overlay and the newly created `EdenMount` tries to grab a lock on overly.

Made the `EdenServer::unmount` asynchronous which waits for a promise that is set in `EdenServer::mountFinished`.

Reviewed By: simpkins

Differential Revision: D5515740

fbshipit-source-id: 5cbfddf13fe00c2cb1b63a6be6353e9b84fbd569
2017-07-31 20:52:35 -07:00
Adam Simpkins
dbe029d83d exit gracefully on SIGTERM and SIGINT
Summary:
Update EdenServer to catch SIGTERM and SIGINT, and to stop gracefully on these
signals.

Reviewed By: wez

Differential Revision: D5315323

fbshipit-source-id: 16611190c8d522a78cf6b624d97d4f7ecc478f96
2017-06-26 19:34:55 -07:00
Adam Simpkins
8893b0d694 use AbsolutePathPiece for repository path arguments
Summary:
Update HgBackingStore and GitBackingStore to accept the repository path as an
AbsolutePathPiece rather than as a plain StringPiece.

Reviewed By: bolinfest

Differential Revision: D5309172

fbshipit-source-id: aca4818c3add11d07ece796298f6175ca4fb1448
2017-06-23 15:23:32 -07:00
Adam Simpkins
b0d1e57975 update logging statements to use folly logging APIs
Summary:
Update eden to log via the new folly logging APIs rather than with glog.

This adds a new --logging flag that takes a logging configuration string.
By default we set the log level to INFO for all eden logs, and WARNING for
everything else.  (I suspect we may eventually want to run with some
high-priority debug logs enabled for some or all of eden, but this seems like a
reasonable default to start with.)

Reviewed By: wez

Differential Revision: D5290783

fbshipit-source-id: 14183489c48c96613e2aca0f513bfa82fd9798c7
2017-06-22 13:50:13 -07:00
Adam Simpkins
67a756de93 avoid multiple builds of the eden server library
Summary:
This tweaks the main.cpp and EdenServer.cpp code so that we can avoid having
separate internal and open source builds of the eden/fs/service:server library.

Only one small function is different between the two builds.  This updates the
code so that this function is only used from main.cpp, instead of being used
inside EdenServer.cpp.

Reviewed By: wez

Differential Revision: D4889721

fbshipit-source-id: 97abda92c36752516fb8a8e73b4cf50580db8d79
2017-04-14 11:39:02 -07:00
Adam Simpkins
a6ae3edab9 move eden/utils and eden/fuse into eden/fs
Summary:
This change makes it so that all of the C++ code related to the edenfs daemon
is now contained in the eden/fs subdirectory.

Reviewed By: bolinfest, wez

Differential Revision: D4889053

fbshipit-source-id: d0bd4774cc0bdb5d1d6b6f47d716ecae52391f37
2017-04-14 11:39:02 -07:00
Adam Simpkins
5eb692d345 update EdenServer::getMount() to throw on error
Summary:
Previously EdenServer::getMount() returned a null pointer if the path did not
refer to a known mount point.  However, most of the thrift APIs using this
method never checked if the return value was null, which could allow any thrift
client to crash edenfs.

This updates getMount() to throw if the path is not found, and never return
null.

Reviewed By: bolinfest

Differential Revision: D4760527

fbshipit-source-id: 6cd9a1e3bc0a0a220d7f5fa518d497d37f245eff
2017-04-03 15:50:32 -07:00
Wez Furlong
4235784907 add .eden "magic" dir
Summary:
It's not really magic because we don't have a virtual directory
inode base any more.  Instead, we mkdir and populate it at mount time.

What is slightly magical about it is that we give it some special powers:

* We know the inode number of the eden dir and prevent unlink operations
  on it or inside it.
* The .eden dir is present in the contents of the root inode and will
  show up when that directory is `readdir`'d
* When resolving a child of a TreeInode by name, we know to return the
  magic `.eden` inode number.  This means that it is possible to `stat`
  and consume the `.eden` directory from any directory inside the eden
  mount, even though it won't show up in `readdir` for those child dirs.

The contents of the `.eden` dir are:

* `socket` - a symlink back to the unix domain socket that our thrift
  server is listening on.  This means that it is a simple
  `readlink(".eden/socket")` operation to discover both whether a directory
  is part of an eden mount and how to talk to the server.

* `root` - a symlink back to the root of this eden mount.  This allows
  using `readlink(".eden/root")` as a simple 1-step operation to find
  the root of an eden mount, and avoids needing to walk up directory
  by directory as is the common pattern for locating `.hg` or `.git`
  dirs.

Reviewed By: simpkins

Differential Revision: D4637285

fbshipit-source-id: 0eabf98b29144acccef5c83bd367493399dc55bb
2017-03-24 23:07:42 -07:00
Adam Simpkins
b48fad3547 make sure edenfs does not exit successfully if privhelper crashes
Summary:
Update the edenfs main function to check the exit code of the privhelper
process, and to exit with EX_SOFTWARE rather than EX_OK if the privhelper did
not exit with status 0.

This will ensure that our integration tests always catch crashes in the
privhelper process.  Previously we could catch errors that happened before the
privhelper socket was closed, but if the privhelper server crashed during
cleanup we never noticed the error.

Reviewed By: bolinfest

Differential Revision: D4728006

fbshipit-source-id: 2c478612e5fabec90438b28b9c76a3343f561655
2017-03-21 13:05:57 -07:00
Adam Simpkins
ff7b05831f don't hang the privhelper forever waiting for bind unmounts
Summary:
Update PrivHelperServer::bindUnmount() to give up after 2 seconds instead of
possibly looping forever.

Also fix the unmount code in the eden process to rethrow the original exception
as-is.  Previously it was re-throwing it as a std::exception, losing the
exception details.

I think there are still other bugs here in this unmount code--it repeatedly
hangs for me on unmount.  (I believe it is trying to unmount things that aren't
actually bind mounts.)  However, I'll look into fixing those in a separate
diff.

Reviewed By: wez

Differential Revision: D4547711

fbshipit-source-id: af6bce0262e8314361450874ef998ebf7ad590e3
2017-02-15 16:56:29 -08:00
Wez Furlong
4829dfe319 change systemConfigDir to etcEdenDir
Summary:
While testing with the fb-eden rpm installed, I hit some integration
test failures.  These were caused by the integration tests picking up the
default post-clone hook configuration.

This diff changes our existing `systemConfigDir` option (which defaults to
`/etc/eden/config.d`) to `etcEdenDir` (which defaults to `/etc/eden`) and
adjusts the code that consumed `systemConfigDir` to construct the effective
value by computing `etcEdenDir + "config.d"`.

Doing this allows us to also default the `repoHooks` path to be
`etcEdenDir + "hooks"` rather than just hard coding `/etc/eden/hooks`.

The result of this is that our integration tests will now pass when `fb-eden`
is installed, because they override the `etcEdenDir` option and isolate their
`edenfs` processes from the globally installed configuration.

Reviewed By: bolinfest

Differential Revision: D4446321

fbshipit-source-id: 524fdb2f386fdf16dce42dce7661d07e13c0f0e7
2017-01-23 23:54:38 -08:00
Adam Simpkins
251da81f36 update all copyright statements to "2016-present"
Summary:
Update copyright statements to "2016-present".  This makes our updated lint
rules happy and complies with the recommended license header statement.

Reviewed By: wez, bolinfest

Differential Revision: D4433594

fbshipit-source-id: e9ecb1c1fc66e4ec49c1f046c6a98d425b13bc27
2017-01-20 22:03:02 -08:00
Adam Simpkins
970159aa5c normalize path arguments
Summary:
This updates the EdenServer and LocalStore classes to require more arguments be
passed in as AbsolutePath arguments rather than just plain strings.

This updates the main program to process path arguments using canonicalPath().

Reviewed By: bolinfest

Differential Revision: D4332273

fbshipit-source-id: 3d235a767963b11129c3897ad027ad761b6dae50
2016-12-15 13:02:38 -08:00
Adam Simpkins
fc202f81e5 add new Future-based APIs to ObjectStore
Summary:
Update the ObjectStore and BackingStore classes to have APIs that return
folly::Future objects, rather than blocking until the requested data is loaded.

For now most users still call the blocking versions of getBlob() and getTree().
Furthermore, all of the Future-based implementations actually still block
until the data is ready.  I will update the code to use these new APIs in
future diffs, and then deprecate the non-future based versions.

Reviewed By: bolinfest

Differential Revision: D4318055

fbshipit-source-id: a250c23b418e69b597a4c6a95dbe80c56da5c53b
2016-12-13 18:12:21 -08:00
Michael Bolin
b078392a9c Add Thrift endpoints for Hg dirstate.
Summary:
This also introduces the change where the `EdenMount` creates
and takes ownership of the `Dirstate`.

To clean some of this up, I had to expose a `getEdenDir()` method on `EdenServer`
that returns an `AbsolutePathPiece`. This was previously stored internally as a
`std::string`, so I had to clean up a bunch of path construction that was using `edenDir_`.

Reviewed By: simpkins

Differential Revision: D4123763

fbshipit-source-id: 270b182521c1a84bb054832f4b5f92af849d67e4
2016-11-26 12:01:41 -08:00
Andrii Korotkov
8f94770d20 Rename thrift methods from NWorker/NPoolThreads to NumIOWorker/NumCPUWorkerThreads for all remaining directories
Summary:
Use new, less confusing names for mentioned thrift methods.

Codemod with 'Yes to All'. Reverted changes in thrift/

Reviewed By: yfeldblum

Differential Revision: D4076812

fbshipit-source-id: 4962ec0aead1f6a45efc1ac7fc2778f39c72e1d0
2016-11-04 15:31:04 -07:00
Michael Bolin
7a05213f34 New Thrift endpoint: getBindMounts(mountPoint).
Summary:
Buck needs this API so that it knows which paths under a project
root it should exclude when deciding whether it can ask Eden for its
SHA-1 or if it must compute it on its own.

Reviewed By: simpkins

Differential Revision: D3840658

fbshipit-source-id: 5eddc0bef423d3b3ee165d2a4b0bbf193f94f61a
2016-09-12 18:29:15 -07:00
Wez Furlong
96d6684947 eden: fix data race on shutdown
Summary:
We can't allow ~EdenServer to delete the memory until we're sure that
the other threads are done.  To ensure that, we need to notify the condition
variable while the aux thread still holds the lock.  This makes sure that the
thread destroying the EdenServer waits for the aux thread to release the lock
before we check the predicate and proceed to deleting the memory.

```
SUMMARY  ThreadSanitizer: data race /
/common/concurrency/Event.cpp:107 in facebook::common::concurrency::Event::set() const
==================
I0909 14:51:18.543072 4147554 main.cpp:173] edenfs performing orderly shutdown
I0909 14:51:18.555794 4148654 Channel.cpp:177] session completed
I0909 14:51:18.556011 4148654 EdenServer.cpp:192] mount point "/tmp/eden_test.0ostuc90/mounts/main" stopped
==================
WARNING: ThreadSanitizer: data race (pid=4147554)
  Write of size 8 at 0x7fff9e182d90 by main thread:
    #0 pthread_cond_destroy <null> (edenfs+0x00000007671a)
    #1 facebook::eden::EdenServer::~EdenServer() /
/eden/fs/service/EdenServer.cpp:93 (libeden_fs_service_server.so+0x0000000b96cd)
    #2 main /
/eden/fs/service/main.cpp:176 (edenfs+0x000000018515)

  Previous read of size 8 at 0x7fff9e182d90 by thread T73:
    #0 pthread_cond_broadcast <null> (edenfs+0x0000000765b7)
    #1 __gthread_cond_broadcast /home/engshare/third-party2/libgcc/4.9.x/src/gcc-4_9/x86_64-facebook-linux/libstdc++-v3/include/x86_64-facebook-linux/bits/gthr-default.h:852 (libstdc++.so.6+0x0000000e14f8)
    #2 std::condition_variable::notify_all() /home/engshare/third-party2/libgcc/4.9.x/src/gcc-4_9/x86_64-facebook-linux/libstdc++-v3/src/c++11/../../../.././libstdc++-v3/src/c++11/condition_variable.cc:72 (libstdc
++.so.6+0x0000000e14f8)
    #3 facebook::eden::EdenServer::mount(std::shared_ptr<facebook::eden::EdenMount>, std::unique_ptr<facebook::eden::ClientConfig, std::default_delete<facebook::eden::ClientConfig> >)::$_0::operator()() const /
/
/eden/fs/service/EdenServer.cpp:145 (libeden_fs_service_server.so+0x0000000bcdb5)
    #4 std::_Function_handler<void (), facebook::eden::EdenServer::mount(std::shared_ptr<facebook::eden::EdenMount>, std::unique_ptr<facebook::eden::ClientConfig, std::default_delete<facebook::eden::ClientConfig>
>)::$_0>::_M_invoke(std::_Any_data const&) /
/third-party-buck/gcc-4.9-glibc-2.20-fb/build/libgcc/include/c++/trunk/functional:2039 (libeden_fs_service_server.so+0x0000000bcab0)
    #5 std::function<void ()>::operator()() const /
/third-party-buck/gcc-4.9-glibc-2.20-fb/build/libgcc/include/c++/trunk/functional:2439 (libeden_fuse_fusell.so+0x00000020fbb9)
    #6 facebook::eden::fusell::MountPoint::start(bool, std::function<void ()> const&)::$_0::operator()() const /
/eden/fuse/MountPoint.cpp:69 (libeden_fuse_fusell.so+0x000000237447
)
    #7 void std::_Bind_simple<facebook::eden::fusell::MountPoint::start(bool, std::function<void ()> const&)::$_0 ()>::_M_invoke<>(std::_Index_tuple<>) /
/third-party-buck/gcc-4.9-
glibc-2.20-fb/build/libgcc/include/c++/trunk/functional:1699 (libeden_fuse_fusell.so+0x000000237048)
    #8 std::_Bind_simple<facebook::eden::fusell::MountPoint::start(bool, std::function<void ()> const&)::$_0 ()>::operator()() /
/third-party-buck/gcc-4.9-glibc-2.20-fb/build/libgc
c/include/c++/trunk/functional:1688 (libeden_fuse_fusell.so+0x000000236ff8)
    #9 std:🧵:_Impl<std::_Bind_simple<facebook::eden::fusell::MountPoint::start(bool, std::function<void ()> const&)::$_0 ()> >::_M_run() /
/third-party-buck/gcc-4.9-glibc-2.
20-fb/build/libgcc/include/c++/trunk/thread:115 (libeden_fuse_fusell.so+0x000000236d8c)
    #10 execute_native_thread_routine /home/engshare/third-party2/libgcc/4.9.x/src/gcc-4_9/x86_64-facebook-linux/libstdc++-v3/src/c++11/../../../.././libstdc++-v3/src/c++11/thread.cc:84 (libstdc++.so.6+0x0000000e6
ec0)
```

Reviewed By: simpkins

Differential Revision: D3844846

fbshipit-source-id: 545474bc1aff8621dbeb487dcd6b54c82828ff3b
2016-09-09 16:57:57 -07:00
Caren Thomas
1e5d3c4d4c have daemon remount on start up
Summary: Currently, all existing mount path are unmounted on 'eden shutdown' but are not remounted again after a subsequent 'eden daemon' call, though they appear as mounted when 'eden list' is called. These changes fix this behavior and have the daemon remount the paths that had been mounted before shutdown was called.

Reviewed By: simpkins

Differential Revision: D3580793

fbshipit-source-id: d03beafc20db4bd01662dd7f198a5ab8859b8e3d
2016-08-05 12:50:32 -07:00
Caren Thomas
bed0de5a95 load config data on start-up
Summary:
Load the config data when eden server is started so that it doesn't need to be re-loaded every time a mount is done. The normal use case for eden will not see that many changes to the config data (users adding repositories themselves is expected to be minimal) so this new logic will be more efficient overall.

Currently, the config data IS reloaded before use every time but this is because there is currently no way to reload the config data if any files are modified on disk. I am looking into how to do this now, and this feature will soon be updated to this diff so configData_ does not need to be constantly reloaded.

Reviewed By: simpkins

Differential Revision: D3580777

fbshipit-source-id: 5e23f51e4aab815e9812750617446dcb7e5483cb
2016-08-05 12:50:31 -07:00
Caren Thomas
670297fa88 add ClientConfig method that compiles repository data
Summary: Restructure the current logic used for loading the config data into a ClientConfig object. Rather than having loadFromClientDirectory iterate through all the config files and parse them to find the necessary information, abstract that logic out into a new method that compiles all of the relevant data so that all loadFromClientDirectory has to do is pull out the needed information. Since this change separates the two steps, this will make it easier to move the first step of compiling config information outside of ClientConfig - the goal here is to have the eden server load all of the config data at start up and cache it in memory so that it doesn't need to be done every time a ClientConfig object is created, and this change is an intermediate step.

Reviewed By: simpkins

Differential Revision: D3580757

fbshipit-source-id: c340a0fe715856066a554238249574f8177bc4d7
2016-08-05 12:50:29 -07:00
Caren Thomas
90cfd27c37 add configPath_ field to EdenServer
Summary:
Include a configPath_ field for EdenServer that holds the path of the user ~/.edenrc config file. The server needs the data from this user config file in order to perform mounts and currently, the path to the home directory is passed via the CLI to the mount command as a field inside the MountInfo struct in order to get the file. As per discussion in D3498567, including the home directory inside the MountInfo struct is logically a bit disjointed, and this change would no longer require the home directory to be passed to the server via MountInfo.

This restructuring also sets up eden for a future change - having the server remount existing mount points on start-up is now possible from the inside. Before this change, mounting anything had to be done via the CLI since the home directory had to be passed in from the outside. This meant that remounting the existing mount points on start up could only be done if Eden was run in the background - running in the foreground would require manual remounting of all existing mount points. Now that the server has access to the config file's path, remounting can be done without any prompting from the CLI in both cases.

Reviewed By: simpkins

Differential Revision: D3580737

fbshipit-source-id: 46667ccd130b470a3a8a9e9aa08e5ec8e8b90336
2016-07-26 10:16:16 -07:00
Adam Simpkins
8db5e56c87 fix shutdown data races
Summary:
Make sure mount points are completely stopped before destroying the EdenServer
object.  Previously the EdenServer was destroyed with the MountPoints still
running the fuse channels in background threads.  When the privileged helper
process unmounted them, fuse requests from the kernel could arrive and access
memory that had already been destroyed.

Reviewed By: wez

Differential Revision: D3458898

fbshipit-source-id: 365bca716ff0f8315b66af92effeb8c6dc574ce1
2016-06-30 21:00:46 -07:00
Adam Simpkins
ed58335598 minor refactoring of integration tests
Summary:
This moves all of the test library code into a lib/ subdirectory, just to help
distinguish tests from utility code.

This also changes the test so that we no longer pack the eden CLI and daemon
binaries into the python archives.  This results in very large archives when
building in dbg and opt modes, and isn't really necessary.  Instead
edenclient.py simply finds the CLI and daemon binaries relative to the test
binary.  We pass in an EDENFS_SUFFIX variable to tell it which flavor of the
daemon to use.

Additionally, this changes the tests to run with python 3.

Reviewed By: bolinfest

Differential Revision: D3449013

fbshipit-source-id: 82533137090325766a52cd067aa97dd8391ae088
2016-06-20 13:40:02 -07:00
Adam Simpkins
eae8ee41e9 start adding an HgBackingStore implementation
Summary:
This adds an HgBackingStore implementation which can load tree data from a
mercurial repository.  Blob loading is not implemented yet, but will come in a
separate diff.

This also adds a minimal GitBackingStore class.  The GitBackingStore has nearly
no functionality, but is needed to keep the existing git functionality working.

Reviewed By: bolinfest

Differential Revision: D3409743

fbshipit-source-id: dbebf53e9de08bd1469e489baa48b84cbf889511
2016-06-13 15:16:30 -07:00
Adam Simpkins
d9be0757b8 add a BackingStore API
Summary:
Add the basic BackingStore interface, plus a NullBackingStore implementation
that always returns null.  This updates the ObjectStore to query the
BackingStore if data is not found in the LocalStore.

Additionally, this updates EdenServer to manage the BackingStore objects.  It
maintains a map of the BackingStore objects created for each known repository.

Reviewed By: bolinfest

Differential Revision: D3409602

fbshipit-source-id: 2920dc4c24ee1ec37efb542f058d0d121ceb5532
2016-06-13 15:16:29 -07:00
Michael Bolin
11169bcf95 Add an eden shutdown command.
Summary:
This revision introduces two complementary changes:
* `eden daemon` no longer runs in the foreground.
* There is now an `eden shutdown` command to kill the daemon.

When `shutdown` is called, it tells the Thrift server to shutdown.
In turn, this causes `EdenServer::runThriftServer()` to exit,
which causes `EdenServer::run()` to exit.

Reviewed By: simpkins

Differential Revision: D3402347

fbshipit-source-id: 80032ba53eb69b3f69bef9d7cd169f93500c833c
2016-06-10 14:16:09 -07:00
Caren Thomas
1117f21e19 handle unmount through privhelper process
Summary:
PrivHelper serializes messages and sends it over to PrivHelperServer who verifies that mount point exists, cleans up bind mounts for the FUSE mount, and undoes FUSE mount.

Some repeated code in this diff since I was unsure on the protocol for that - let me know if/where I should generalize functions to avoid this.

Reviewed By: simpkins

Differential Revision: D3361955

fbshipit-source-id: a7324fb9660912d6c2b753e15b1fa6061c0d5261
2016-05-31 13:17:03 -07:00
Caren Thomas
203be051a1 add unmount parser and wrapper functions
Summary: Updated python CLI to include subparser for unmount command and added wrapper functions that hand over execution to privhelper process. Unmount currently requires client_name at the command line.

Reviewed By: simpkins

Differential Revision: D3359517

fbshipit-source-id: ff05e90bcdb96ecad63f37634c69dbeef429c90f
2016-05-27 17:41:07 -07:00
Michael Bolin
d6d5d6c695 Set up bind mounts for a client when mounting it.
Summary:
This adds a new API to `PrivHelper`: `privilegedBindMount()`.
Similar to `privilegedFuseMount()`, this sends a message to the privileged helper,
which is running as `root`, so it can set up the specified bind mount.
The changes in the `privhelper` directory parrot what was done to support `privilegedFuseMount()`.

Now, once the primary mount for a client is created, any bind mounts listed in the
config for the client are set up. This logic is introduced in `EdenServer.cpp`.

Reviewed By: simpkins

Differential Revision: D3296660

fbshipit-source-id: 61296f35e5c3a6f232a1c17e0f296dd5d3b5ec06
2016-05-23 21:33:20 -07:00
Adam Simpkins
53e821eb23 add an EdenMount class
Summary:
Add a new class to serve as a single location where we can store all
information about a single eden mount point.  Currently this contains the
MountPoint, LocalStore, and Overlay objects.  This allows the TreeInode class
to just store a single pointer to the EdenMount, rather than having to track
these three objects separately.

In the future we could consider also keeping a copy of the ClientConfig in the
EdenMount object, but I haven't done that for now.

Reviewed By: bolinfest

Differential Revision: D3321355

fbshipit-source-id: 8a39bb49822ca8e90c88b2a834b59230d2f91435
2016-05-20 10:34:07 -07:00
Facebook Github Bot 5
2eeea32117 Initial commit
fbshipit-source-id: 2bcefbd0cd127cc5ea982e074ea6819d7aac3d7a
2016-05-12 14:09:13 -07:00