From 3e9e3e52e693e27cd3b23cf266f1041753cbc9d5 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 28 Sep 2019 14:15:52 +0100 Subject: Ice initialize must occur after any forking --- netfs/fuse/fuseApp.cpp | 31 ++++++++++++++++++++----------- netfs/fuse/fuseApp.h | 3 +++ netfs/fuse/fuseAppBase.cpp | 4 ++++ netfs/fuse/fuseAppBase.h | 17 +++++++++++++++-- netfs/unittests/Jamfile.jam | 1 + netfs/unittests/mockFuse.cpp | 3 +++ 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp index aaec9bd..1db9690 100644 --- a/netfs/fuse/fuseApp.cpp +++ b/netfs/fuse/fuseApp.cpp @@ -15,21 +15,11 @@ namespace AdHoc { } NetFS::FuseApp::FuseApp(Ice::StringSeq && a) : - ic(Ice::initialize(a)), + iceArgs(std::move(a)), sessionOpened(false), openHandleId(0), converter(userLookup, groupLookup) { - if (!a.empty()) { - const auto & arg = a.front(); - if (arg.find("://") != std::string::npos) { - fcr = configureFromUri(arg); - } - else if (auto colon = arg.find(':'); colon != std::string::npos) { - fcr = configureFromFile(arg.substr(0, colon), arg.substr(colon + 1)); - } - } - BOOST_ASSERT(fcr); } NetFS::FuseApp::~FuseApp() @@ -75,6 +65,25 @@ NetFS::FuseApp::~FuseApp() } } +void * +NetFS::FuseApp::init(struct fuse_conn_info *) +{ + BOOST_ASSERT(!ic); + ic = Ice::initialize(iceArgs); + BOOST_ASSERT(ic); + if (!iceArgs.empty()) { + const auto & arg = iceArgs.front(); + if (arg.find("://") != std::string::npos) { + fcr = configureFromUri(arg); + } + else if (auto colon = arg.find(':'); colon != std::string::npos) { + fcr = configureFromFile(arg.substr(0, colon), arg.substr(colon + 1)); + } + } + BOOST_ASSERT(fcr); + return this; +} + NetFS::Client::ResourcePtr NetFS::FuseApp::configureFromFile(const std::filesystem::path & path, const std::string & resourceName) const { diff --git a/netfs/fuse/fuseApp.h b/netfs/fuse/fuseApp.h index 5b5a8fa..d44960c 100644 --- a/netfs/fuse/fuseApp.h +++ b/netfs/fuse/fuseApp.h @@ -60,6 +60,8 @@ namespace NetFS { void verifyConnection(); public: + // lifecycle + void * init (struct fuse_conn_info * info) override; // misc int access(const char * p, int a) override; int getattr(const char * p, struct stat * s) override; @@ -115,6 +117,7 @@ namespace NetFS { ReqEnv reqEnv(); + Ice::StringSeq iceArgs; Ice::CommunicatorPtr ic; Client::ResourcePtr fcr; mutable std::shared_mutex _proxymaplock; diff --git a/netfs/fuse/fuseAppBase.cpp b/netfs/fuse/fuseAppBase.cpp index 0b6a90e..68bc170 100644 --- a/netfs/fuse/fuseAppBase.cpp +++ b/netfs/fuse/fuseAppBase.cpp @@ -27,6 +27,10 @@ FuseAppBase::~FuseAppBase() // to call them in a realistic manner. They exist only as the default // implementation of the function which is never passed to libfuse // unless it is overridden. +void * FuseAppBase::init(fuse_conn_info*) +{ + return nullptr; +} int FuseAppBase::access(const char *, int) { return -ENOSYS; diff --git a/netfs/fuse/fuseAppBase.h b/netfs/fuse/fuseAppBase.h index 97810d2..5de3a41 100644 --- a/netfs/fuse/fuseAppBase.h +++ b/netfs/fuse/fuseAppBase.h @@ -18,6 +18,7 @@ class DLL_PUBLIC FuseAppBase { FuseAppBase(); virtual ~FuseAppBase(); + virtual void * init (struct fuse_conn_info * info); virtual int access(const char *, int); virtual int chmod(const char *, mode_t); virtual int chown(const char *, uid_t, gid_t); @@ -72,6 +73,7 @@ class DLL_PUBLIC FuseAppBase { template class FuseAppBaseT : public FuseAppBase { public: +#define GetIntHelper(func) getInternalHelper(&FuseAppBase::func) #define GetHelper(func) getHelper(&FuseAppBase::func) FuseAppBaseT() : operations({ GetHelper(getattr), @@ -103,7 +105,7 @@ class FuseAppBaseT : public FuseAppBase { GetHelper(readdir), GetHelper(releasedir), GetHelper(fsyncdir), - nullptr, //fuseInit + GetIntHelper(init), nullptr, //fuseDestroy GetHelper(access), GetHelper(create), @@ -134,12 +136,23 @@ class FuseAppBaseT : public FuseAppBase { { } #undef GetHelper +#undef GetIntHelper const struct fuse_operations operations; private: + template + constexpr static Rtn(*getInternalHelper(Rtn(FuseAppBase::*)(Args...)))(Args...) + { + if constexpr (!std::is_same::value) { + return [](Args ... a) { + return (fuseApp->*bfunc)(a...); + }; + } + return nullptr; + } template - static int(*getHelper(int(FuseAppBase::*)(Args...)))(Args...) + constexpr static int(*getHelper(int(FuseAppBase::*)(Args...)))(Args...) { if constexpr (!std::is_same::value) { return [](Args ... a) { diff --git a/netfs/unittests/Jamfile.jam b/netfs/unittests/Jamfile.jam index 3102e4c..20c15c7 100644 --- a/netfs/unittests/Jamfile.jam +++ b/netfs/unittests/Jamfile.jam @@ -67,6 +67,7 @@ run testEdgeCases.cpp testMocks : testEdgeCases ; +# explicit testFuse ; run testFuse.cpp : -- : defaultDaemon.xml diff --git a/netfs/unittests/mockFuse.cpp b/netfs/unittests/mockFuse.cpp index fd93388..b00c4c2 100644 --- a/netfs/unittests/mockFuse.cpp +++ b/netfs/unittests/mockFuse.cpp @@ -45,5 +45,8 @@ FuseMockHost::FuseMockHost(std::string ep, const Ice::StringSeq & a) : app(std::make_unique(std::move(ep), a)), fuse(&app->operations) { + if (app->operations.init) { + app->operations.init(nullptr); + } } -- cgit v1.2.3