1212
1313#include < fb303/FollyLoggingHandler.h>
1414#include < fb303/TFunctionStatHandler.h>
15+ #include < fmt/format.h>
1516#include < folly/Conv.h>
1617#include < folly/MapUtil.h>
1718#include < folly/executors/FunctionScheduler.h>
@@ -102,6 +103,10 @@ std::optional<bool> checkIsRootMountNamespace() {
102103 return std::nullopt ;
103104}
104105
106+ // Helper macro to convert optional to string for logging
107+ #define OPT_TO_STRING (opt ) \
108+ ((opt).has_value() ? folly::to<std::string>(*(opt)) : " nullopt" )
109+
105110std::optional<std::string> readCgroup () {
106111 std::string contents;
107112 if (folly::readFile (" /proc/self/cgroup" , contents)) {
@@ -398,17 +403,14 @@ int runEdenMain(EdenMain&& main, int argc, char** argv) {
398403 daemonPidNamespace = getNamespaceInode (" /proc/self/ns/pid" );
399404 isDaemonInRootMountNamespace = checkIsRootMountNamespace ();
400405 }
401- (void )isPrivhelperInRootMountNamespace;
402- (void )privhelperPidNamespace;
403406#else
404407 std::optional<uint64_t > daemonMountNamespace;
405408 std::optional<uint64_t > daemonPidNamespace;
406409 std::optional<std::string> cgroupInfo;
407410 std::optional<bool > isDaemonInRootMountNamespace;
408411 std::optional<bool > isPrivhelperInRootMountNamespace;
412+ std::optional<uint64_t > privhelperMountNamespace;
409413 std::optional<uint64_t > privhelperPidNamespace;
410- (void )isPrivhelperInRootMountNamespace;
411- (void )privhelperPidNamespace;
412414#endif
413415
414416 std::vector<std::string> originalCommandLine{argv, argv + argc};
@@ -511,6 +513,39 @@ int runEdenMain(EdenMain&& main, int argc, char** argv) {
511513 daemonPid, daemonMemoryPriority.value ());
512514 }
513515
516+ #ifdef __linux__
517+ XLOGF (
518+ DBG2,
519+ " Namespace detection: daemon(mnt={}, pid={}), privhelper(mnt={}, pid={}), "
520+ " rootMountNsInode={}, isDaemonInRootMountNamespace={}, "
521+ " isPrivhelperInRootMountNamespace={}" ,
522+ OPT_TO_STRING (daemonMountNamespace),
523+ OPT_TO_STRING (daemonPidNamespace),
524+ OPT_TO_STRING (privhelperMountNamespace),
525+ OPT_TO_STRING (privhelperPidNamespace),
526+ OPT_TO_STRING (rootMountNsInode),
527+ OPT_TO_STRING (isDaemonInRootMountNamespace),
528+ OPT_TO_STRING (isPrivhelperInRootMountNamespace));
529+
530+ if (edenConfig->requireRootMountNamespace .getValue ()) {
531+ // To avoid disruption, we assume that the daemon and privhelper are in
532+ // the root mount namespace unless we can prove otherwise.
533+ bool daemonInRootNs = isDaemonInRootMountNamespace.value_or (true );
534+ bool privhelperInRootNs = isPrivhelperInRootMountNamespace.value_or (true );
535+
536+ if (!daemonInRootNs || !privhelperInRootNs) {
537+ auto errorMsg = fmt::format (
538+ " EdenFS cannot start: daemon in root mount namespace = {}, "
539+ " privhelper in root mount namespace = {}.\n To allow this "
540+ " behavior, set core.require-root-mount-namespace config to false" ,
541+ daemonInRootNs,
542+ privhelperInRootNs);
543+ XLOG (ERR, errorMsg);
544+ startupLogger->exitUnsuccessfully (kExitCodeError , errorMsg);
545+ }
546+ }
547+ #endif // __linux__
548+
514549 server.emplace (
515550 std::move (originalCommandLine),
516551 std::move (identity),
@@ -538,7 +573,10 @@ int runEdenMain(EdenMain&& main, int argc, char** argv) {
538573 false /* success*/ ,
539574 daemonMountNamespace,
540575 daemonPidNamespace,
576+ privhelperMountNamespace,
577+ privhelperPidNamespace,
541578 isDaemonInRootMountNamespace,
579+ isPrivhelperInRootMountNamespace,
542580 cgroupInfo});
543581 }
544582 startupLogger->exitUnsuccessfully (
@@ -573,7 +611,10 @@ int runEdenMain(EdenMain&& main, int argc, char** argv) {
573611 takeover = FLAGS_takeover,
574612 daemonMountNamespace,
575613 daemonPidNamespace,
614+ privhelperMountNamespace,
615+ privhelperPidNamespace,
576616 isDaemonInRootMountNamespace,
617+ isPrivhelperInRootMountNamespace,
577618 cgroupInfo,
578619 &server] {
579620 // This value is slightly different from `startTimeInSeconds`
@@ -592,7 +633,10 @@ int runEdenMain(EdenMain&& main, int argc, char** argv) {
592633 true /* success*/ ,
593634 daemonMountNamespace,
594635 daemonPidNamespace,
636+ privhelperMountNamespace,
637+ privhelperPidNamespace,
595638 isDaemonInRootMountNamespace,
639+ isPrivhelperInRootMountNamespace,
596640 cgroupInfo});
597641
598642#ifndef _WIN32
0 commit comments