2016-05-12 23:43:17 +03:00
|
|
|
/*
|
2017-01-21 09:02:33 +03:00
|
|
|
* Copyright (c) 2016-present, Facebook, Inc.
|
2016-05-12 23:43:17 +03:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
2016-07-09 12:40:45 +03:00
|
|
|
|
|
|
|
#include <folly/Conv.h>
|
2017-03-31 21:23:02 +03:00
|
|
|
#include <folly/experimental/FunctionScheduler.h>
|
2017-06-22 23:39:57 +03:00
|
|
|
#include <folly/experimental/logging/Init.h>
|
|
|
|
#include <folly/experimental/logging/xlog.h>
|
2016-05-12 23:43:17 +03:00
|
|
|
#include <folly/init/Init.h>
|
|
|
|
#include <gflags/gflags.h>
|
2016-07-26 20:15:43 +03:00
|
|
|
#include <pwd.h>
|
2016-05-12 23:43:17 +03:00
|
|
|
#include <sysexits.h>
|
|
|
|
#include "EdenServer.h"
|
2017-04-14 21:31:48 +03:00
|
|
|
#include "eden/fs/fuse/privhelper/PrivHelper.h"
|
2017-07-28 05:23:39 +03:00
|
|
|
#include "eden/fs/fuse/privhelper/UserInfo.h"
|
2016-05-12 23:43:17 +03:00
|
|
|
|
|
|
|
DEFINE_bool(allowRoot, false, "Allow running eden directly as root");
|
|
|
|
DEFINE_string(edenDir, "", "The path to the .eden directory");
|
2016-08-05 22:49:21 +03:00
|
|
|
DEFINE_string(
|
2017-01-24 10:52:46 +03:00
|
|
|
etcEdenDir,
|
|
|
|
"/etc/eden",
|
2016-08-05 22:49:21 +03:00
|
|
|
"The directory holding all system configuration files");
|
2016-07-26 20:15:43 +03:00
|
|
|
DEFINE_string(configPath, "", "The path of the ~/.edenrc config file");
|
2016-05-12 23:43:17 +03:00
|
|
|
|
2017-08-23 07:22:46 +03:00
|
|
|
// The logging configuration parameter. We default to DBG2 for everything in
|
2017-06-22 23:39:57 +03:00
|
|
|
// eden, and WARNING for all other categories.
|
2017-08-23 07:22:46 +03:00
|
|
|
DEFINE_string(logging, ".=WARNING,eden=DBG2", "Logging configuration");
|
2017-06-22 23:39:57 +03:00
|
|
|
|
2016-05-12 23:43:17 +03:00
|
|
|
using namespace facebook::eden::fusell;
|
|
|
|
using namespace facebook::eden;
|
|
|
|
|
2017-11-04 01:58:04 +03:00
|
|
|
int main(int argc, char** argv) {
|
2016-05-12 23:43:17 +03:00
|
|
|
// Make sure to run this before any flag values are read.
|
|
|
|
folly::init(&argc, &argv);
|
|
|
|
|
|
|
|
// Determine the desired user and group ID.
|
|
|
|
if (geteuid() != 0) {
|
|
|
|
fprintf(stderr, "error: edenfs must be started as root\n");
|
|
|
|
return EX_NOPERM;
|
|
|
|
}
|
2017-07-28 05:23:39 +03:00
|
|
|
|
|
|
|
auto identity = UserInfo::lookup();
|
|
|
|
if (identity.getUid() == 0 && !FLAGS_allowRoot) {
|
2016-05-12 23:43:17 +03:00
|
|
|
fprintf(
|
|
|
|
stderr,
|
|
|
|
"error: you appear to be running eden as root, "
|
|
|
|
"rather than using\n"
|
|
|
|
"sudo or a setuid binary. This is normally undesirable.\n"
|
|
|
|
"Pass in the --allowRoot flag if you really mean to run "
|
|
|
|
"eden as root.\n");
|
|
|
|
return EX_USAGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set some default glog settings, to be applied unless overridden on the
|
|
|
|
// command line
|
2017-03-09 09:13:38 +03:00
|
|
|
gflags::SetCommandLineOptionWithMode(
|
|
|
|
"logtostderr", "1", gflags::SET_FLAGS_DEFAULT);
|
|
|
|
gflags::SetCommandLineOptionWithMode(
|
|
|
|
"minloglevel", "0", gflags::SET_FLAGS_DEFAULT);
|
2016-05-12 23:43:17 +03:00
|
|
|
|
|
|
|
// Fork the privhelper process, then drop privileges in the main process.
|
|
|
|
// This should be done as early as possible, so that everything else we do
|
|
|
|
// runs only with normal user privileges.
|
|
|
|
//
|
|
|
|
// (It might be better to do this even before calling folly::init() and
|
|
|
|
// parsing command line arguments. The downside would be that we then
|
|
|
|
// shouldn't really use glog in the privhelper process, since it won't have
|
|
|
|
// been set up and configured based on the command line flags.)
|
2017-07-28 05:23:41 +03:00
|
|
|
fusell::startPrivHelper(identity);
|
|
|
|
identity.dropPrivileges();
|
2017-06-22 23:39:57 +03:00
|
|
|
|
2017-12-02 03:53:51 +03:00
|
|
|
folly::initLogging(FLAGS_logging);
|
2017-06-22 23:39:57 +03:00
|
|
|
|
2017-07-28 05:23:39 +03:00
|
|
|
XLOG(INFO) << "Starting edenfs. UID=" << identity.getUid()
|
|
|
|
<< ", GID=" << identity.getGid() << ", PID=" << getpid();
|
2016-05-12 23:43:17 +03:00
|
|
|
|
|
|
|
if (FLAGS_edenDir.empty()) {
|
|
|
|
fprintf(stderr, "error: the --edenDir argument is required\n");
|
|
|
|
return EX_USAGE;
|
|
|
|
}
|
2017-12-14 23:35:19 +03:00
|
|
|
// We require edenDir to already exist, so use realpath() to resolve it.
|
|
|
|
auto edenDir = facebook::eden::realpath(FLAGS_edenDir);
|
|
|
|
|
|
|
|
// It's okay if the etcEdenDir and configPath don't exist, so use
|
|
|
|
// normalizeBestEffort() to try resolving symlinks in these paths but don't
|
|
|
|
// fail if they don't exist.
|
|
|
|
auto etcEdenDir = normalizeBestEffort(FLAGS_etcEdenDir);
|
2016-12-15 23:34:39 +03:00
|
|
|
|
2017-07-28 05:23:39 +03:00
|
|
|
AbsolutePath configPath;
|
2016-12-15 23:34:39 +03:00
|
|
|
std::string configPathStr = FLAGS_configPath;
|
|
|
|
if (configPathStr.empty()) {
|
2017-07-28 05:23:39 +03:00
|
|
|
configPath = identity.getHomeDirectory() + PathComponentPiece{".edenrc"};
|
|
|
|
} else {
|
2017-12-14 23:35:19 +03:00
|
|
|
configPath = normalizeBestEffort(configPathStr);
|
2016-05-12 23:43:17 +03:00
|
|
|
}
|
|
|
|
|
2017-12-14 23:35:17 +03:00
|
|
|
EdenServer server(edenDir, etcEdenDir, configPath);
|
2017-08-30 23:43:39 +03:00
|
|
|
server.run();
|
2016-05-12 23:43:17 +03:00
|
|
|
return EX_OK;
|
|
|
|
}
|