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
This commit is contained in:
Adam Simpkins 2016-12-15 12:34:39 -08:00 committed by Facebook Github Bot
parent 3fedd393a7
commit 970159aa5c
8 changed files with 73 additions and 67 deletions

View File

@ -65,14 +65,14 @@ namespace facebook {
namespace eden {
EdenServer::EdenServer(
StringPiece edenDir,
StringPiece systemConfigDir,
StringPiece configPath,
StringPiece rocksPath)
: edenDir_(AbsolutePath(edenDir)),
AbsolutePathPiece edenDir,
AbsolutePathPiece systemConfigDir,
AbsolutePathPiece configPath,
AbsolutePathPiece rocksPath)
: edenDir_(edenDir),
systemConfigDir_(systemConfigDir),
configPath_(configPath),
rocksPath_(rocksPath.str()) {}
rocksPath_(rocksPath) {}
EdenServer::~EdenServer() {
// Stop all of the mount points.

View File

@ -53,10 +53,10 @@ class EdenServer {
using DirstateMap = folly::StringKeyedMap<std::shared_ptr<Dirstate>>;
EdenServer(
folly::StringPiece edenDir,
folly::StringPiece systemConfigDir,
folly::StringPiece configPath,
folly::StringPiece rocksPath);
AbsolutePathPiece edenDir,
AbsolutePathPiece systemConfigDir,
AbsolutePathPiece configPath,
AbsolutePathPiece rocksPath);
virtual ~EdenServer();
void run();
@ -138,7 +138,7 @@ class EdenServer {
AbsolutePath edenDir_;
AbsolutePath systemConfigDir_;
AbsolutePath configPath_;
std::string rocksPath_;
AbsolutePath rocksPath_;
folly::File lockFile_;
folly::Synchronized<std::shared_ptr<ConfigData>> configData_;
std::shared_ptr<EdenServiceHandler> handler_;

View File

@ -122,41 +122,39 @@ int main(int argc, char **argv) {
fprintf(stderr, "error: the --edenDir argument is required\n");
return EX_USAGE;
}
auto edenDir = canonicalPath(FLAGS_edenDir);
auto systemConfigDir = FLAGS_systemConfigDir.empty()
? AbsolutePath{"/etc/eden/config.d"}
: canonicalPath(FLAGS_systemConfigDir);
auto rocksPath = FLAGS_rocksPath.empty()
? edenDir + RelativePathPiece{"storage/rocks-db"}
: canonicalPath(FLAGS_rocksPath);
std::string systemConfigDir = FLAGS_systemConfigDir;
if (systemConfigDir.empty()) {
systemConfigDir = "/etc/eden/config.d";
}
std::string configPath = FLAGS_configPath;
if (configPath.empty()) {
std::string configPathStr = FLAGS_configPath;
if (configPathStr.empty()) {
auto homeDir = getenv("HOME");
if (homeDir) {
configPath = homeDir;
configPathStr = homeDir;
} else {
struct passwd pwd;
struct passwd* result;
char buf[1024];
if (getpwuid_r(getuid(), &pwd, buf, sizeof(buf), &result) == 0) {
if (result != nullptr) {
configPath = pwd.pw_dir;
configPathStr = pwd.pw_dir;
}
}
}
if (configPath.empty()) {
if (configPathStr.empty()) {
fprintf(
stderr,
"error: the --configPath argument was not specified and no $HOME\
directory could be found for this user\n");
"error: the --configPath argument was not specified and no "
"$HOME directory could be found for this user\n");
return EX_USAGE;
}
configPath.append("/.edenrc");
}
std::string rocksPath = FLAGS_rocksPath;
if (rocksPath.empty()) {
rocksPath = FLAGS_edenDir + "/storage/rocks-db";
configPathStr.append("/.edenrc");
}
auto configPath = canonicalPath(configPathStr);
// Set the FUSE_THREAD_STACK environment variable.
// Do this early on before we spawn any other threads, since setenv()
@ -167,7 +165,7 @@ directory could be found for this user\n");
1);
// Run the eden server
EdenServer server(FLAGS_edenDir, systemConfigDir, configPath, rocksPath);
EdenServer server(edenDir, systemConfigDir, configPath, rocksPath);
server.run();
LOG(INFO) << "edenfs performing orderly shutdown";

View File

@ -129,8 +129,8 @@ rocksdb::Slice _createSlice(folly::ByteRange bytes) {
namespace facebook {
namespace eden {
LocalStore::LocalStore(StringPiece pathToRocksDb)
: db_(createRocksDb(pathToRocksDb)) {}
LocalStore::LocalStore(AbsolutePathPiece pathToRocksDb)
: db_(createRocksDb(pathToRocksDb.stringPiece())) {}
LocalStore::~LocalStore() {
#ifdef FOLLY_SANITIZE_ADDRESS

View File

@ -12,6 +12,7 @@
#include <folly/Range.h>
#include <memory>
#include "eden/fs/store/BlobMetadata.h"
#include "eden/utils/PathFuncs.h"
namespace folly {
template <typename T>
@ -45,7 +46,7 @@ class Tree;
*/
class LocalStore {
public:
explicit LocalStore(folly::StringPiece pathToRocksDb);
explicit LocalStore(AbsolutePathPiece pathToRocksDb);
virtual ~LocalStore();
/**

View File

@ -15,10 +15,13 @@
#include "HgImporter.h"
#include "eden/fs/store/LocalStore.h"
#include "eden/utils/PathFuncs.h"
DEFINE_string(edenDir, "", "The path to the .eden directory");
DEFINE_string(rev, "", "The revision ID to import");
using namespace facebook::eden;
int main(int argc, char* argv[]) {
folly::init(&argc, &argv);
@ -31,15 +34,16 @@ int main(int argc, char* argv[]) {
fprintf(stderr, "error: --edenDir must be specified\n");
return EX_USAGE;
}
auto rocksPath = FLAGS_edenDir + "/storage/rocks-db";
auto rocksPath =
canonicalPath(FLAGS_edenDir) + RelativePathPiece{"storage/rocks-db"};
std::string revName = FLAGS_rev;
if (revName.empty()) {
revName = ".";
}
facebook::eden::LocalStore store(rocksPath);
facebook::eden::HgImporter importer(repoPath, &store);
LocalStore store(rocksPath);
HgImporter importer(repoPath, &store);
auto rootHash = importer.importManifest(revName);
printf("Imported root tree: %s\n", rootHash.toString().c_str());

View File

@ -21,18 +21,30 @@
#include "eden/fs/store/StoreResult.h"
using namespace facebook::eden;
using TempDir = folly::test::TemporaryDirectory;
using facebook::eden::Hash;
using folly::IOBuf;
using folly::StringPiece;
using folly::test::TemporaryDirectory;
using folly::unhexlify;
using std::string;
TEST(LocalStore, testReadAndWriteBlob) {
TempDir tmp;
LocalStore store(tmp.path().string());
class LocalStoreTest : public ::testing::Test {
protected:
void SetUp() override {
testDir_ = std::make_unique<TemporaryDirectory>("eden_test");
auto path = AbsolutePathPiece{testDir_->path().string()};
store_ = std::make_unique<LocalStore>(path);
}
void TearDown() override {
testDir_.reset();
}
std::unique_ptr<TemporaryDirectory> testDir_;
std::unique_ptr<LocalStore> store_;
};
TEST_F(LocalStoreTest, testReadAndWriteBlob) {
Hash hash("3a8f8eb91101860fd8484154885838bf322964d0");
StringPiece contents("{\n \"breakConfig\": true\n}\n");
@ -40,34 +52,28 @@ TEST(LocalStore, testReadAndWriteBlob) {
auto sha1 = Hash::sha1(&buf);
auto inBlob = Blob{hash, std::move(buf)};
store.putBlob(hash, &inBlob);
store_->putBlob(hash, &inBlob);
auto outBlob = store.getBlob(hash);
auto outBlob = store_->getBlob(hash);
EXPECT_EQ(hash, outBlob->getHash());
EXPECT_EQ(
contents, outBlob->getContents().clone()->moveToFbString().toStdString());
EXPECT_EQ(sha1, store.getSha1ForBlob(hash));
auto retreivedMetadata = store.getBlobMetadata(hash);
EXPECT_EQ(sha1, store_->getSha1ForBlob(hash));
auto retreivedMetadata = store_->getBlobMetadata(hash);
ASSERT_TRUE(retreivedMetadata.hasValue());
EXPECT_EQ(sha1, retreivedMetadata.value().sha1);
EXPECT_EQ(contents.size(), retreivedMetadata.value().size);
}
TEST(LocalStore, testReadNonexistent) {
TempDir tmp;
LocalStore store(tmp.path().string());
TEST_F(LocalStoreTest, testReadNonexistent) {
Hash hash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
EXPECT_TRUE(nullptr == store.getBlob(hash));
auto retreivedMetadata = store.getBlobMetadata(hash);
EXPECT_TRUE(nullptr == store_->getBlob(hash));
auto retreivedMetadata = store_->getBlobMetadata(hash);
EXPECT_FALSE(retreivedMetadata.hasValue());
}
TEST(LocalStore, testReadsAndWriteTree) {
TempDir tmp;
LocalStore store(tmp.path().string());
TEST_F(LocalStoreTest, testReadsAndWriteTree) {
Hash hash(folly::StringPiece{"8e073e366ed82de6465d1209d3f07da7eebabb93"});
auto gitTreeObject = folly::to<string>(
@ -106,8 +112,8 @@ TEST(LocalStore, testReadsAndWriteTree) {
string("100644 xdebug.ini\x00", 18),
unhexlify("9ed5bbccd1b9b0077561d14c0130dc086ab27e04"));
store.put(hash.getBytes(), folly::StringPiece{gitTreeObject});
auto tree = store.getTree(hash);
store_->put(hash.getBytes(), folly::StringPiece{gitTreeObject});
auto tree = store_->getTree(hash);
EXPECT_EQ(Hash("8e073e366ed82de6465d1209d3f07da7eebabb93"), tree->getHash());
EXPECT_EQ(11, tree->getTreeEntries().size());
@ -120,22 +126,19 @@ TEST(LocalStore, testReadsAndWriteTree) {
EXPECT_EQ(0b0110, readmeEntry.getOwnerPermissions());
}
TEST(LocalStore, testGetResult) {
TempDir tmp;
LocalStore store(tmp.path().string());
TEST_F(LocalStoreTest, testGetResult) {
StringPiece key1 = "foo";
StringPiece key2 = "bar";
EXPECT_FALSE(store.get(key1).isValid());
EXPECT_FALSE(store.get(key2).isValid());
EXPECT_FALSE(store_->get(key1).isValid());
EXPECT_FALSE(store_->get(key2).isValid());
store.put(key1, StringPiece{"hello world"});
auto result1 = store.get(key1);
store_->put(key1, StringPiece{"hello world"});
auto result1 = store_->get(key1);
ASSERT_TRUE(result1.isValid());
EXPECT_EQ("hello world", result1.piece());
auto result2 = store.get(key2);
auto result2 = store_->get(key2);
EXPECT_FALSE(result2.isValid());
EXPECT_THROW(result2.piece(), std::domain_error);
}

View File

@ -70,7 +70,7 @@ unique_ptr<TestMount> TestMountBuilder::build() {
AbsolutePath testDirPath{testDir->path().string()};
auto pathToRocksDb = testDirPath + PathComponentPiece("rocksdb");
auto localStore = make_shared<LocalStore>(pathToRocksDb.stringPiece());
auto localStore = make_shared<LocalStore>(pathToRocksDb);
shared_ptr<BackingStore> backingStore =
make_shared<TestBackingStore>(localStore);
unique_ptr<ObjectStore> objectStore =