From d55f8e4651a46ccefdf0facf3315262b6957385c Mon Sep 17 00:00:00 2001 From: Xiaowei Lu Date: Wed, 12 Feb 2025 18:49:34 -0800 Subject: [PATCH] Add methods for privHelper client to interact with fam Summary: ## This Diff Defined two methods: startFam and stopFam for privHelper client. These methods will be called directly by serviceHandler upon receiving the Thrift requests. ## Context File Access Monitor(FAM) is a tool to monitor file system access, aiming to find out EdenFS crawlers. The tool will be implemented after the toolchain is ready. Before that, we are going to use [this third-party binary](https://github.com/objective-see/FileMonitor). This diff stack focuses on integrating the binary into Eden package and spawn a process from privHelper because of the required privileged permission. Reviewed By: jdelliot Differential Revision: D69340304 fbshipit-source-id: 815423a1d38ea9af6bcd74d481e60f6299a5baf8 --- eden/fs/privhelper/PrivHelper.h | 19 ++++++++++ eden/fs/privhelper/PrivHelperImpl.cpp | 49 ++++++++++++++++++++++++++ eden/fs/testharness/FakePrivHelper.cpp | 14 ++++++++ eden/fs/testharness/FakePrivHelper.h | 6 ++++ 4 files changed, 88 insertions(+) diff --git a/eden/fs/privhelper/PrivHelper.h b/eden/fs/privhelper/PrivHelper.h index 62fe4108bfbba..f18cf1f16f6de 100644 --- a/eden/fs/privhelper/PrivHelper.h +++ b/eden/fs/privhelper/PrivHelper.h @@ -187,6 +187,25 @@ class PrivHelper { */ FOLLY_NODISCARD virtual folly::Future getServerPid() = 0; + /** + * Start File Access Monitor(FAM). + * + * @param paths A list of paths to be monitored by FAM. + * @param outputPath The path to the output file. + * @return pid of the started FAM process + */ + FOLLY_NODISCARD virtual folly::Future startFam( + const std::vector& paths, + const std::string& tmpOutputPath, + const std::string& specifiedOutputPath, + const bool shouldUpload) = 0; + + /** + * Stop File Access Monitor(FAM). + */ + FOLLY_NODISCARD virtual folly::Future + stopFam() = 0; + /** * setLogFileBlocking() is a wrapper around setLogFile() that blocks until * the call has completed. diff --git a/eden/fs/privhelper/PrivHelperImpl.cpp b/eden/fs/privhelper/PrivHelperImpl.cpp index 5229723ea14e3..26b3deca1fe29 100644 --- a/eden/fs/privhelper/PrivHelperImpl.cpp +++ b/eden/fs/privhelper/PrivHelperImpl.cpp @@ -126,6 +126,12 @@ class PrivHelperClientImpl : public PrivHelper, std::chrono::nanoseconds duration) override; Future setUseEdenFs(bool useEdenFs) override; Future getServerPid() override; + Future startFam( + const std::vector& paths, + const std::string& tmpOutputPath, + const std::string& specifiedOutputPath, + const bool shouldUpload) override; + Future stopFam() override; int stop() override; int getRawClientFd() const override { auto state = state_.rlock(); @@ -588,6 +594,37 @@ Future PrivHelperClientImpl::getServerPid() { }); } +Future PrivHelperClientImpl::startFam( + const std::vector& paths, + const std::string& tmpOutputPath, + const std::string& specifiedOutputPath, + const bool shouldUpload) { + auto xid = getNextXid(); + auto request = PrivHelperConn::serializeStartFamRequest( + xid, paths, tmpOutputPath, specifiedOutputPath, shouldUpload); + + return sendAndRecv(xid, std::move(request)) + .thenValue([](UnixSocket::Message&& response) { + return PrivHelperConn::parseStartFamResponse(response); + }); +} + +Future PrivHelperClientImpl::stopFam() { + auto xid = getNextXid(); + auto request = PrivHelperConn::serializeStopFamRequest(xid); + + return sendAndRecv(xid, std::move(request)) + .thenValue([&](UnixSocket::Message&& response) { + StopFileAccessMonitorResponse stopResponse{}; + PrivHelperConn::parseStopFamResponse( + response, + stopResponse.tmpOutputPath, + stopResponse.specifiedOutputPath, + stopResponse.shouldUpload); + return stopResponse; + }); +} + int PrivHelperClientImpl::stop() { const auto result = cleanup(); if (result.hasError()) { @@ -880,6 +917,18 @@ class StubPrivHelper final : public PrivHelper { return -1; } + folly::Future startFam( + const std::vector& paths, + const std::string& tmpOutputPath, + const std::string& specifiedOutputPath, + const bool shouldUpload) override { + NOT_IMPLEMENTED(); + } + + folly::Future stopFam() override { + NOT_IMPLEMENTED(); + } + int stop() override { return 0; } diff --git a/eden/fs/testharness/FakePrivHelper.cpp b/eden/fs/testharness/FakePrivHelper.cpp index 22a9c48641d2f..e2e8af7bec0f5 100644 --- a/eden/fs/testharness/FakePrivHelper.cpp +++ b/eden/fs/testharness/FakePrivHelper.cpp @@ -177,4 +177,18 @@ folly::Future FakePrivHelper::getServerPid() { return -1; } +folly::Future FakePrivHelper::startFam( + const std::vector& /* paths */, + const std::string& /* tmpOutputPath */, + const std::string& /* specifiedOutputPath */, + const bool /* shouldUpload */) { + return makeFuture( + runtime_error("FakePrivHelper::startFam() not implemented")); +} + +folly::Future FakePrivHelper::stopFam() { + return makeFuture( + runtime_error("FakePrivHelper::stopFam() not implemented")); +} + } // namespace facebook::eden diff --git a/eden/fs/testharness/FakePrivHelper.h b/eden/fs/testharness/FakePrivHelper.h index 245451d7e22de..1806b4e6f596b 100644 --- a/eden/fs/testharness/FakePrivHelper.h +++ b/eden/fs/testharness/FakePrivHelper.h @@ -74,6 +74,12 @@ class FakePrivHelper final : public PrivHelper { std::chrono::nanoseconds duration) override; folly::Future setUseEdenFs(bool useEdenFs) override; folly::Future getServerPid() override; + folly::Future startFam( + const std::vector& paths, + const std::string& tmpOutputPath, + const std::string& specifiedOutputPath, + const bool shouldUpload) override; + folly::Future stopFam() override; int stop() override; int getRawClientFd() const override { return -1;