summaryrefslogtreecommitdiff
path: root/netfs/fuse
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2019-09-23 19:33:42 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2019-09-24 23:13:15 +0100
commitc4cc5b556ce79e55fda1dd1e4a46bc23448306fb (patch)
tree12877c0fb921b059fce5a9c24130b208e64cd173 /netfs/fuse
parentAdd option terminator to test run command lines (diff)
downloadnetfs-c4cc5b556ce79e55fda1dd1e4a46bc23448306fb.tar.bz2
netfs-c4cc5b556ce79e55fda1dd1e4a46bc23448306fb.tar.xz
netfs-c4cc5b556ce79e55fda1dd1e4a46bc23448306fb.zip
Fuse separation
First swing at separating the fuse library interface with the fuse operations
Diffstat (limited to 'netfs/fuse')
-rw-r--r--netfs/fuse/fuseApp.cpp65
-rw-r--r--netfs/fuse/fuseApp.h21
-rw-r--r--netfs/fuse/fuseAppBase.cpp47
-rw-r--r--netfs/fuse/fuseAppBase.h47
-rw-r--r--netfs/fuse/netfs.cpp45
5 files changed, 92 insertions, 133 deletions
diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp
index ef1ca7f..aaec9bd 100644
--- a/netfs/fuse/fuseApp.cpp
+++ b/netfs/fuse/fuseApp.cpp
@@ -14,12 +14,22 @@ namespace AdHoc {
template class CallCacheable<struct stat, std::string>;
}
-NetFS::FuseApp::FuseApp(Ice::StringSeq a) :
- iceArgs(std::move(a)),
+NetFS::FuseApp::FuseApp(Ice::StringSeq && a) :
+ ic(Ice::initialize(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()
@@ -65,25 +75,12 @@ NetFS::FuseApp::~FuseApp()
}
}
-NetFS::Client::ConfigurationPtr
-NetFS::FuseApp::ReadConfiguration(const std::filesystem::path & path) const
-{
- auto s = Slicer::FileDeserializerFactory::createNew(path.extension().string(), path);
- return Slicer::DeserializeAnyWith<NetFS::Client::ConfigurationPtr>(s);
-}
-
-void *
-NetFS::FuseApp::init(struct fuse_conn_info *)
-{
- ic = Ice::initialize(iceArgs);
- fcr = configurator();
- return nullptr;
-}
-
NetFS::Client::ResourcePtr
-NetFS::FuseApp::configureFromFile(const std::string & configPath, const std::string & resourceName) const
+NetFS::FuseApp::configureFromFile(const std::filesystem::path & path, const std::string & resourceName) const
{
- return AdHoc::safeMapLookup<Client::ResourceNotFound>(ReadConfiguration(configPath)->Resources, resourceName);
+ auto s = Slicer::FileDeserializerFactory::createNew(path.extension().string(), path);
+ auto c = Slicer::DeserializeAnyWith<NetFS::Client::ConfigurationPtr>(s);
+ return AdHoc::safeMapLookup<Client::ResourceNotFound>(c->Resources, resourceName);
}
AdHocFormatter(IceEndpointFmt, "%? -h %? -p %?");
@@ -101,36 +98,6 @@ NetFS::FuseApp::configureFromUri(const std::string & uriString) const
return r;
}
-int
-NetFS::FuseApp::opt_parse(void *, const char * arg, int, struct fuse_args *)
-{
- if (strncmp(arg, "--Ice.", 6) == 0) {
- iceArgs.push_back(arg);
- return 0;
- }
- else if (strncmp(arg, "_netdev", 7) == 0) {
- return 0;
- }
- else if (arg[0] == '-') {
- return 1;
- }
- else if (!configurator) {
- if (strstr(arg, "://")) {
- configurator = std::bind(&NetFS::FuseApp::configureFromUri, this, arg);
- }
- else {
- const char * colon = strchr(arg, ':');
- configurator = std::bind(&NetFS::FuseApp::configureFromFile, this, std::string(arg, colon), colon + 1);
- }
- return 0;
- }
- else if (mountPoint.empty()) {
- mountPoint = arg;
- return 1;
- }
- return 1;
-}
-
void
NetFS::FuseApp::connectSession()
{
diff --git a/netfs/fuse/fuseApp.h b/netfs/fuse/fuseApp.h
index df342b6..5b5a8fa 100644
--- a/netfs/fuse/fuseApp.h
+++ b/netfs/fuse/fuseApp.h
@@ -16,7 +16,7 @@
#include <boost/icl/interval_map.hpp>
namespace NetFS {
- class DLL_PUBLIC FuseApp : public FuseAppBase {
+ class DLL_PUBLIC FuseApp : public FuseAppBaseT<FuseApp> {
private:
class OpenDir {
public:
@@ -49,15 +49,12 @@ namespace NetFS {
typedef std::map<int, OpenFilePtr> OpenFiles;
public:
- FuseApp(Ice::StringSeq);
+ FuseApp(Ice::StringSeq &&);
~FuseApp();
- private:
- void * init (struct fuse_conn_info * info) override;
- int opt_parse(void *, const char * arg, int key, struct fuse_args *) override;
-
+ protected:
void connectSession();
- void connectToService();
+ virtual void connectToService();
void connectToVolume();
void connectHandles();
void verifyConnection();
@@ -100,13 +97,10 @@ namespace NetFS {
virtual struct fuse_context * fuse_get_context() = 0;
protected:
- typedef std::function<Client::ResourcePtr()> Configurator;
- Configurator configurator;
- virtual NetFS::Client::ConfigurationPtr ReadConfiguration(const std::filesystem::path &) const;
- virtual NetFS::Client::ResourcePtr configureFromFile(const std::string &, const std::string &) const;
- virtual NetFS::Client::ResourcePtr configureFromUri(const std::string &) const;
+ NetFS::Client::ResourcePtr configureFromFile(const std::filesystem::path &, const std::string &) const;
+ NetFS::Client::ResourcePtr configureFromUri(const std::string &) const;
- private:
+ protected:
template<typename Handle, typename ... Params>
void setProxy(uint64_t & fh, const Params & ...);
template<typename Handle>
@@ -121,7 +115,6 @@ 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 01ec8e1..0b6a90e 100644
--- a/netfs/fuse/fuseAppBase.cpp
+++ b/netfs/fuse/fuseAppBase.cpp
@@ -5,22 +5,28 @@
#include <unistd.h>
#include <cstdlib>
#include <typeinfo>
+#include <boost/assert.hpp>
FuseAppBase * FuseAppBase::fuseApp;
+FuseAppBase::FuseAppBase()
+{
+ BOOST_ASSERT(!fuseApp);
+ BOOST_ASSERT(this);
+ fuseApp = this;
+}
+
+FuseAppBase::~FuseAppBase()
+{
+ BOOST_ASSERT(fuseApp);
+ fuseApp = nullptr;
+}
+
// LCOV_EXCL_START
// These are all excluded from coverage because it is impossible
// 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::opt_parse(void*, const char *, int, fuse_args*)
-{
- return 1;
-}
int FuseAppBase::access(const char *, int)
{
return -ENOSYS;
@@ -190,11 +196,8 @@ void FuseAppBase::log(int level, const char * message) const noexcept
void FuseAppBase::logf(int level, const char * fmt, ...) const noexcept
{
va_list args;
- // NOLINTNEXTLINE(hicpp-no-array-decay)
va_start(args, fmt);
- // NOLINTNEXTLINE(hicpp-no-array-decay)
vlogf(level, fmt, args);
- // NOLINTNEXTLINE(hicpp-no-array-decay)
va_end(args);
}
@@ -208,25 +211,3 @@ void FuseAppBase::beforeOperation()
{
}
-void * FuseAppBase::fuseInit (struct fuse_conn_info *conn)
-{
- return fuseApp->init(conn);
-}
-void FuseAppBase::fuseDestroy(void *)
-{
- delete fuseApp;
-}
-
-struct fuse_args
-FuseAppBase::runint(int argc, char ** argv)
-{
- std::array<fuse_opt, 1> fuse_opts {};
- fuseApp = this;
- struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
- if (fuse_opt_parse(&args, fuseApp, fuse_opts.data(),
- &internalHelper<decltype(&FuseAppBase::opt_parse), &FuseAppBase::opt_parse>) == -1) {
- exit(1);
- }
- return args;
-}
-
diff --git a/netfs/fuse/fuseAppBase.h b/netfs/fuse/fuseAppBase.h
index 2775c00..97810d2 100644
--- a/netfs/fuse/fuseAppBase.h
+++ b/netfs/fuse/fuseAppBase.h
@@ -15,9 +15,9 @@
class DLL_PUBLIC FuseAppBase {
public:
- virtual ~FuseAppBase() = default;
- virtual void * init (struct fuse_conn_info * info);
- virtual int opt_parse(void *, const char * arg, int key, struct fuse_args *);
+ FuseAppBase();
+ virtual ~FuseAppBase();
+
virtual int access(const char *, int);
virtual int chmod(const char *, mode_t);
virtual int chown(const char *, uid_t, gid_t);
@@ -64,18 +64,19 @@ class DLL_PUBLIC FuseAppBase {
void logf(int level, const char * fmt, ...) const throw() __attribute__ ((__format__ (__printf__, 3, 4)));
virtual void vlogf(int level, const char * fmt, va_list) const throw() __attribute__ ((__format__ (__printf__, 3, 0))) = 0;
- virtual int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc) = 0;
- virtual int main(int, char **, const struct fuse_operations *) = 0;
+ mutable std::shared_mutex _lock;
+ protected:
+ static FuseAppBase * fuseApp;
+};
+template <typename FuseApp>
+class FuseAppBaseT : public FuseAppBase {
+ public:
#define GetHelper(func) getHelper<decltype(&FuseAppBase::func), decltype(&FuseApp::func), &FuseAppBase::func>(&FuseAppBase::func)
- template <typename FuseApp>
- static int run(int argc, char ** argv, FuseApp * fa)
- {
- auto args = fa->runint(argc, argv);
- struct fuse_operations operations = {
+ FuseAppBaseT() : operations({
GetHelper(getattr),
GetHelper(readlink),
- NULL, // getdir deprecated
+ nullptr, // getdir deprecated
GetHelper(mknod),
GetHelper(mkdir),
GetHelper(unlink),
@@ -86,7 +87,7 @@ class DLL_PUBLIC FuseAppBase {
GetHelper(chmod),
GetHelper(chown),
GetHelper(truncate),
- NULL, // utime deprecated
+ nullptr, // utime deprecated
GetHelper(open),
GetHelper(read),
GetHelper(write),
@@ -102,8 +103,8 @@ class DLL_PUBLIC FuseAppBase {
GetHelper(readdir),
GetHelper(releasedir),
GetHelper(fsyncdir),
- fuseInit,
- fuseDestroy,
+ nullptr, //fuseInit
+ nullptr, //fuseDestroy
GetHelper(access),
GetHelper(create),
GetHelper(ftruncate),
@@ -129,15 +130,14 @@ class DLL_PUBLIC FuseAppBase {
#endif
#endif
#endif
- };
- return fa->main(args.argc, args.argv, &operations);
+ })
+ {
}
- struct fuse_args runint(int, char **);
+#undef GetHelper
- private:
- static void * fuseInit(struct fuse_conn_info *conn);
- static void fuseDestroy(void *);
+ const struct fuse_operations operations;
+ private:
template <typename BFunc, typename IFunc, BFunc bfunc, typename ... Args>
static int(*getHelper(int(FuseAppBase::*)(Args...)))(Args...)
{
@@ -169,16 +169,13 @@ class DLL_PUBLIC FuseAppBase {
}
return nullptr;
}
+
+ protected:
template <typename Func, Func f, typename ... Args>
static int internalHelper(Args ... a)
{
return (fuseApp->*f)(a...);
}
-
- static FuseAppBase * fuseApp;
-
- protected:
- mutable std::shared_mutex _lock;
};
#endif
diff --git a/netfs/fuse/netfs.cpp b/netfs/fuse/netfs.cpp
index c21711c..14c3c93 100644
--- a/netfs/fuse/netfs.cpp
+++ b/netfs/fuse/netfs.cpp
@@ -1,10 +1,37 @@
#include "fuseApp.h"
#include <syslog.h>
-class FuseImpl : public NetFS::FuseApp {
+class FuseImpl : public fuse_args, public NetFS::FuseApp {
public:
- explicit FuseImpl(const Ice::StringSeq & a) :
- NetFS::FuseApp(a)
+ static int opt_parse(void * data, const char * arg, int, struct fuse_args *)
+ {
+ auto iceArgs = static_cast<Ice::StringSeq *>(data);
+ if (strncmp(arg, "--Ice.", 6) == 0) {
+ iceArgs->push_back(arg);
+ return 0;
+ }
+ else if (strncmp(arg, "_netdev", 7) == 0) {
+ return 0;
+ }
+ else if (arg[0] == '-') {
+ return 1;
+ }
+ else if (iceArgs->empty() || strncmp(iceArgs->front().c_str(), "--Ice.", 6) == 0) {
+ iceArgs->insert(iceArgs->begin(), arg);
+ return 0;
+ }
+ return 1;
+ }
+
+ FuseImpl(int c, char ** v) :
+ fuse_args(FUSE_ARGS_INIT(c, v)),
+ NetFS::FuseApp([this](){
+ Ice::StringSeq iceArgs;
+ if (fuse_opt_parse(this, &iceArgs, nullptr, opt_parse) == -1) {
+ exit(-1);
+ }
+ return iceArgs;
+ }())
{
openlog("netfs", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
}
@@ -24,15 +51,9 @@ class FuseImpl : public NetFS::FuseApp {
return ::fuse_get_context();
}
- // NOLINTNEXTLINE(modernize-avoid-c-arrays, hicpp-avoid-c-arrays)
- int fuse_opt_parse(struct fuse_args * args, void * data, const struct fuse_opt opts[], fuse_opt_proc_t proc) override
- {
- return ::fuse_opt_parse(args, data, opts, proc);
- }
-
- int main(int argc, char ** argv, const struct fuse_operations * ops) override
+ int run()
{
- return ::fuse_main(argc, argv, ops, this);
+ return ::fuse_main(argc, argv, &operations, this);
}
void vlogf(int priority, const char * fmt, va_list args) const noexcept override
@@ -44,6 +65,6 @@ class FuseImpl : public NetFS::FuseApp {
int
main(int argc, char* argv[])
{
- return FuseAppBase::run(argc, argv, new FuseImpl(Ice::argsToStringSeq(argc, argv)));
+ return FuseImpl(argc, argv).run();
}