From 5780e0d6b8fb5c4269d224b865365a1c59afd38b Mon Sep 17 00:00:00 2001 From: randomdan Date: Thu, 20 Mar 2014 21:07:25 +0000 Subject: Modularized interfaces for netfs --- netfs/Jamfile.jam | 93 +-------------- netfs/daemon.cpp | 163 -------------------------- netfs/daemon.h | 82 ------------- netfs/daemon/Jamfile.jam | 31 +++++ netfs/daemon/daemon.cpp | 73 ++++++++++++ netfs/daemon/daemon.h | 39 +++++++ netfs/daemon/daemonConfig.cpp | 52 +++++++++ netfs/daemon/daemonConfig.h | 48 ++++++++ netfs/daemon/daemonDirectory.cpp | 41 +++++++ netfs/daemon/daemonDirectory.h | 22 ++++ netfs/daemon/daemonFile.cpp | 75 ++++++++++++ netfs/daemon/daemonFile.h | 28 +++++ netfs/daemon/daemonService.cpp | 21 ++++ netfs/daemon/daemonService.h | 18 +++ netfs/daemon/daemonVolume.cpp | 243 +++++++++++++++++++++++++++++++++++++++ netfs/daemon/daemonVolume.h | 47 ++++++++ netfs/daemon/pch.hpp | 13 +++ netfs/daemonConfig.cpp | 52 --------- netfs/daemonConfig.h | 48 -------- netfs/daemonDirs.cpp | 91 --------------- netfs/daemonFileSystem.cpp | 12 -- netfs/daemonFileSystem.h | 50 -------- netfs/daemonFiles.cpp | 170 --------------------------- netfs/daemonMisc.cpp | 157 ------------------------- netfs/daemonModule.cpp | 8 -- netfs/daemonModule.h | 14 --- netfs/daemonService.cpp | 22 ---- netfs/daemonService.h | 18 --- netfs/daemonSystem.cpp | 33 ------ netfs/entCache.cpp | 84 -------------- netfs/entCache.h | 37 ------ netfs/fuse.cpp | 120 ------------------- netfs/fuse.h | 113 ------------------ netfs/fuse/Jamfile.jam | 33 ++++++ netfs/fuse/fuse.cpp | 148 ++++++++++++++++++++++++ netfs/fuse/fuse.h | 117 +++++++++++++++++++ netfs/fuse/fuseConfig.cpp | 29 +++++ netfs/fuse/fuseConfig.h | 34 ++++++ netfs/fuse/fuseDirs.cpp | 103 +++++++++++++++++ netfs/fuse/fuseFiles.cpp | 155 +++++++++++++++++++++++++ netfs/fuse/fuseMisc.cpp | 110 ++++++++++++++++++ netfs/fuse/fuseSystem.cpp | 16 +++ netfs/fuse/pch.hpp | 13 +++ netfs/fuseConfig.cpp | 29 ----- netfs/fuseConfig.h | 34 ------ netfs/fuseDirs.cpp | 97 ---------------- netfs/fuseFiles.cpp | 162 -------------------------- netfs/fuseMisc.cpp | 122 -------------------- netfs/fuseSystem.cpp | 26 ----- netfs/guidmap.h | 64 ----------- netfs/ice/Jamfile.jam | 16 +++ netfs/ice/directory.ice | 17 +++ netfs/ice/exceptions.ice | 18 +++ netfs/ice/file.ice | 22 ++++ netfs/ice/service.ice | 16 +++ netfs/ice/typeConvert.cpp | 70 +++++++++++ netfs/ice/typeConvert.h | 29 +++++ netfs/ice/types.ice | 46 ++++++++ netfs/ice/volume.ice | 42 +++++++ netfs/lib/Jamfile.jam | 21 ++++ netfs/lib/entCache.cpp | 82 +++++++++++++ netfs/lib/entCache.h | 37 ++++++ netfs/lib/guidmap.h | 64 +++++++++++ netfs/lib/pch.hpp | 21 ++++ netfs/netfsComms.ice | 85 -------------- netfs/pchCommon.hpp | 25 ---- netfs/pchDaemon.hpp | 13 --- netfs/pchFuse.hpp | 14 --- 68 files changed, 2012 insertions(+), 2036 deletions(-) delete mode 100644 netfs/daemon.cpp delete mode 100644 netfs/daemon.h create mode 100644 netfs/daemon/Jamfile.jam create mode 100644 netfs/daemon/daemon.cpp create mode 100644 netfs/daemon/daemon.h create mode 100644 netfs/daemon/daemonConfig.cpp create mode 100644 netfs/daemon/daemonConfig.h create mode 100644 netfs/daemon/daemonDirectory.cpp create mode 100644 netfs/daemon/daemonDirectory.h create mode 100644 netfs/daemon/daemonFile.cpp create mode 100644 netfs/daemon/daemonFile.h create mode 100644 netfs/daemon/daemonService.cpp create mode 100644 netfs/daemon/daemonService.h create mode 100644 netfs/daemon/daemonVolume.cpp create mode 100644 netfs/daemon/daemonVolume.h create mode 100644 netfs/daemon/pch.hpp delete mode 100644 netfs/daemonConfig.cpp delete mode 100644 netfs/daemonConfig.h delete mode 100644 netfs/daemonDirs.cpp delete mode 100644 netfs/daemonFileSystem.cpp delete mode 100644 netfs/daemonFileSystem.h delete mode 100644 netfs/daemonFiles.cpp delete mode 100644 netfs/daemonMisc.cpp delete mode 100644 netfs/daemonModule.cpp delete mode 100644 netfs/daemonModule.h delete mode 100644 netfs/daemonService.cpp delete mode 100644 netfs/daemonService.h delete mode 100644 netfs/daemonSystem.cpp delete mode 100644 netfs/entCache.cpp delete mode 100644 netfs/entCache.h delete mode 100644 netfs/fuse.cpp delete mode 100644 netfs/fuse.h create mode 100644 netfs/fuse/Jamfile.jam create mode 100644 netfs/fuse/fuse.cpp create mode 100644 netfs/fuse/fuse.h create mode 100644 netfs/fuse/fuseConfig.cpp create mode 100644 netfs/fuse/fuseConfig.h create mode 100644 netfs/fuse/fuseDirs.cpp create mode 100644 netfs/fuse/fuseFiles.cpp create mode 100644 netfs/fuse/fuseMisc.cpp create mode 100644 netfs/fuse/fuseSystem.cpp create mode 100644 netfs/fuse/pch.hpp delete mode 100644 netfs/fuseConfig.cpp delete mode 100644 netfs/fuseConfig.h delete mode 100644 netfs/fuseDirs.cpp delete mode 100644 netfs/fuseFiles.cpp delete mode 100644 netfs/fuseMisc.cpp delete mode 100644 netfs/fuseSystem.cpp delete mode 100644 netfs/guidmap.h create mode 100644 netfs/ice/Jamfile.jam create mode 100644 netfs/ice/directory.ice create mode 100644 netfs/ice/exceptions.ice create mode 100644 netfs/ice/file.ice create mode 100644 netfs/ice/service.ice create mode 100644 netfs/ice/typeConvert.cpp create mode 100644 netfs/ice/typeConvert.h create mode 100644 netfs/ice/types.ice create mode 100644 netfs/ice/volume.ice create mode 100644 netfs/lib/Jamfile.jam create mode 100644 netfs/lib/entCache.cpp create mode 100644 netfs/lib/entCache.h create mode 100644 netfs/lib/guidmap.h create mode 100644 netfs/lib/pch.hpp delete mode 100644 netfs/netfsComms.ice delete mode 100644 netfs/pchCommon.hpp delete mode 100644 netfs/pchDaemon.hpp delete mode 100644 netfs/pchFuse.hpp diff --git a/netfs/Jamfile.jam b/netfs/Jamfile.jam index 7ed27fa..3bfc849 100644 --- a/netfs/Jamfile.jam +++ b/netfs/Jamfile.jam @@ -15,97 +15,8 @@ lib IceBox : : IceBox ; lib pthread : : pthread ; lib fuse : : fuse ; -lib netfsComms : - netfsComms.ice : - Ice - IceUtil - pthread - ; - -lib netfsCommon : - pchCommon - entCache.cpp ../libmisc/xml.cpp : - _FILE_OFFSET_BITS=64 - ../libmisc - libxml2 - netfsComms - boost_thread - boost_system - Ice - IceUtil - ; - -cpp-pch pchFuse : pchCommon pchFuse.hpp : - _FILE_OFFSET_BITS=64 - ../libmisc - ../libfusepp - netfsComms - netfsComms - boost_thread - fuse - Ice - libxml2 - ; - -cpp-pch pchDaemon : pchCommon pchDaemon.hpp : - _FILE_OFFSET_BITS=64 - ../libmisc - netfsComms - netfsComms - boost_thread - Ice - libxml2 - ; - -cpp-pch pchCommon : pchCommon.hpp : - _FILE_OFFSET_BITS=64 - ../libmisc - netfsComms - netfsComms - boost_thread - fuse - Ice - libxml2 - ; - -exe netfs : - pchFuse - [ glob fuse*.cpp ] - [ glob ../libfusepp/fuse*.cpp ] - : - _FILE_OFFSET_BITS=64 - ../libmisc - ../libfusepp - netfsComms - netfsComms - netfsCommon - boost_thread - boost_system - fuse - Ice - IceUtil - pthread - libxml2 - ; - -lib netfsd : - pchDaemon - [ glob daemon*.cpp ] - : - _FILE_OFFSET_BITS=64 - ../libmisc - netfsComms - netfsComms - netfsCommon - boost_random - boost_thread - boost_filesystem - boost_system - Ice - IceUtil - IceBox - libxml2 - ; +build-project daemon ; +build-project fuse ; explicit install ; package.install install : : netfs : netfsd ; diff --git a/netfs/daemon.cpp b/netfs/daemon.cpp deleted file mode 100644 index 65b9d4e..0000000 --- a/netfs/daemon.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include "pchDaemon.hpp" -#include -#include -#include -#include "daemon.h" -#include "daemonConfig.h" -#include "daemonFileSystem.h" -#include "daemonService.h" - -int16_t -makeHostID() -{ - char buf[128]; - gethostname(buf, sizeof(buf)); - boost::crc_basic<16> crc_ccitt1( 0x1021, 0xFFFF, 0, false, false ); - crc_ccitt1.process_bytes(buf, sizeof(buf)); - return crc_ccitt1.checksum(); -} - -// name = NetFSDaemonAdapter -void -NetFSDaemon::start(const std::string & name, const Ice::CommunicatorPtr & ic, const Ice::StringSeq&) -{ - Ice::PropertiesPtr props = ic->getProperties(); - dc = DaemonConfig::Load(props->getProperty("NetFSD.ConfigPath")); - dgs = new DaemonGlobalState(dc); - - int16_t hostseed = makeHostID(); - adapter = ic->createObjectAdapterWithEndpoints(name, dc->self->iceEndpoint); - adapter->add(new FileSystemServer(dgs), ic->stringToIdentity("FileSystem")); - adapter->add(new ServiceServer(hostseed, dgs), ic->stringToIdentity("Service")); - adapter->activate(); -} - -void -NetFSDaemon::stop() -{ - adapter->deactivate(); -} - -extern "C" { - IceBox::Service * - createNetFSDaemon(Ice::CommunicatorPtr) - { - return new NetFSDaemon(); - } -} - -DaemonGlobalState::DaemonGlobalState(DaemonConfigPtr c) : - config(c) -{ -} - -DaemonGlobalState::NSP -DaemonGlobalState::newSession(int16_t hostseed, const std::string & ex) -{ - boost::lock_guard lg(lock); - DaemonConfig::ExportMap::iterator e = config->exports.find(ex); - if (e == config->exports.end()) { - throw NetFSComms::ConfigError(); - } - SP s = new Session(hostseed, e->second); - while (Ice::Long tok = random()) { - if (sessions.find(tok) == sessions.end()) { - sessions[tok] = s; - return NSP(tok, s); - } - } - throw NetFSComms::AuthError(); -} - -DaemonGlobalState::SP -DaemonGlobalState::getSession(Ice::Long tok) const -{ - boost::lock_guard lg(lock); - Sessions::const_iterator s = sessions.find(tok); - if (s != sessions.end()) { - return s->second; - } - throw NetFSComms::AuthError(); -} - -void -DaemonGlobalState::endSession(Ice::Long tok) -{ - boost::lock_guard lg(lock); - sessions.erase(tok); -} - -DaemonGlobalState::Session::Session(int16_t hostseed, DaemonConfig::ExportPtr ex) : - dirs(hostseed), - files(hostseed), - exportCfg(ex) -{ -} - -DaemonGlobalState::Session::~Session() -{ -} - -SessionPtr::SessionPtr(boost::intrusive_ptr s, bool lock) : - ptr(s), - doUnlock(lock) -{ - if (lock) { - ptr->lock.lock(); - } -} - -SessionPtr::~SessionPtr() -{ - if (doUnlock) { - ptr->lock.unlock(); - } -} - -void -SessionPtr::lock() const -{ - ptr->lock.lock(); - doUnlock = true; -} - -void -SessionPtr::unlock() const -{ - ptr->lock.unlock(); - doUnlock = false; -} - -DaemonGlobalState::Session * -SessionPtr::operator->() const -{ - return ptr.get(); -} - -TempPrivs::TempPrivs(uid_t u, gid_t g) : - myu(u), oldu(geteuid()), - myg(g), oldg(getegid()) -{ - if (setegid(myg)) - throw NetFSComms::SystemError(errno); - if (seteuid(myu)) - throw NetFSComms::SystemError(errno); -} - -TempPrivs::TempPrivs(const NetFSComms::ReqEnv & re, const UserEntCache * uec, const GroupEntCache * gec) : - myu(uec->getID(re.user)), oldu(geteuid()), - myg(gec->getID(re.grp)), oldg(getegid()) -{ - if (setegid(myg)) - throw NetFSComms::SystemError(errno); - if (seteuid(myu)) - throw NetFSComms::SystemError(errno); -} - -TempPrivs::~TempPrivs() -{ - if (seteuid(oldu)) - throw NetFSComms::SystemError(errno); - if (setegid(oldg)) - throw NetFSComms::SystemError(errno); -} diff --git a/netfs/daemon.h b/netfs/daemon.h deleted file mode 100644 index 1f4fc64..0000000 --- a/netfs/daemon.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef DAEMON_H -#define DAEMON_H - -#include -#include -#include -#include -#include -#include -#include "daemonConfig.h" -#include "netfsComms.h" -#include "entCache.h" -#include "guidmap.h" -#include - -class DaemonGlobalState : public IntrusivePtrBase { - public: - DaemonGlobalState(DaemonConfigPtr c); - class Session : public IntrusivePtrBase { - public: - Session(int16_t hostseed, DaemonConfig::ExportPtr exportCfg); - ~Session(); - - GUIDMapImpl dirs; - GUIDMapImpl files; - - boost::mutex lock; - DaemonConfig::ExportPtr exportCfg; - }; - - typedef boost::intrusive_ptr SP; - typedef boost::tuple NSP; - NSP newSession(int16_t hostseed, const std::string & ex); - SP getSession(Ice::Long tok) const; - void endSession(Ice::Long tok); - - const DaemonConfigPtr config; - private: - typedef std::map Sessions; - Sessions sessions; - mutable boost::mutex lock; - boost::random_device random; -}; -typedef boost::intrusive_ptr DaemonGlobalStatePtr; - -class NetFSDaemon : public IceBox::Service { - public: - virtual void start(const std::string&, const Ice::CommunicatorPtr&, const Ice::StringSeq&); - virtual void stop(); - private: - Ice::ObjectAdapterPtr adapter; - DaemonConfigPtr dc; - DaemonGlobalStatePtr dgs; -}; - -class SessionPtr { - public: - SessionPtr(boost::intrusive_ptr ptr, bool lock); - ~SessionPtr(); - - DaemonGlobalState::Session * operator->() const; - - void lock() const; - void unlock() const; - private: - const boost::intrusive_ptr ptr; - mutable bool doUnlock; -}; - -class TempPrivs { - public: - TempPrivs(uid_t u, gid_t g); - TempPrivs(const NetFSComms::ReqEnv & re, const UserEntCache * uec, const GroupEntCache * gec); - virtual ~TempPrivs(); - - private: - const uid_t myu, oldu; - const gid_t myg, oldg; -}; - -#endif - diff --git a/netfs/daemon/Jamfile.jam b/netfs/daemon/Jamfile.jam new file mode 100644 index 0000000..1ea5dca --- /dev/null +++ b/netfs/daemon/Jamfile.jam @@ -0,0 +1,31 @@ +cpp-pch pch : pch.hpp : + _FILE_OFFSET_BITS=64 + ../../libmisc + ../ice//netfsComms + ../ice//netfsComms + ../lib//netfsCommon + ..//boost_thread + ..//Ice + ..//libxml2 + ; + +lib netfsd : + pch + [ glob *.cpp ] + : + _FILE_OFFSET_BITS=64 + ../libmisc + ../ice//netfsComms + ../ice//netfsComms + ../lib//netfsCommon + ..//boost_random + ..//boost_thread + ..//boost_filesystem + ..//boost_system + ..//Ice + ..//IceUtil + ..//IceBox + ..//libxml2 + ; + + diff --git a/netfs/daemon/daemon.cpp b/netfs/daemon/daemon.cpp new file mode 100644 index 0000000..0cbe2ad --- /dev/null +++ b/netfs/daemon/daemon.cpp @@ -0,0 +1,73 @@ +#include "pch.hpp" +#include +#include +#include +#include "daemon.h" +#include "daemonConfig.h" +#include "daemonService.h" +#include "daemonVolume.h" + +int16_t +makeHostID() +{ + char buf[128]; + gethostname(buf, sizeof(buf)); + boost::crc_basic<16> crc_ccitt1( 0x1021, 0xFFFF, 0, false, false ); + crc_ccitt1.process_bytes(buf, sizeof(buf)); + return crc_ccitt1.checksum(); +} + +// name = NetFSDaemonAdapter +void +NetFSDaemon::start(const std::string & name, const Ice::CommunicatorPtr & ic, const Ice::StringSeq&) +{ + Ice::PropertiesPtr props = ic->getProperties(); + dc = DaemonConfig::Load(props->getProperty("NetFSD.ConfigPath")); + + int16_t hostseed = makeHostID(); + adapter = ic->createObjectAdapterWithEndpoints(name, dc->self->iceEndpoint); + adapter->add(new ServiceServer(hostseed, dc), ic->stringToIdentity("Service")); + adapter->activate(); +} + +void +NetFSDaemon::stop() +{ + adapter->deactivate(); +} + +extern "C" { + IceBox::Service * + createNetFSDaemon(Ice::CommunicatorPtr) + { + return new NetFSDaemon(); + } +} + +TempPrivs::TempPrivs(uid_t u, gid_t g) : + myu(u), oldu(geteuid()), + myg(g), oldg(getegid()) +{ + if (setegid(myg)) + throw NetFS::SystemError(errno); + if (seteuid(myu)) + throw NetFS::SystemError(errno); +} + +TempPrivs::TempPrivs(const NetFS::ReqEnv & re, const UserEntCache * uec, const GroupEntCache * gec) : + myu(uec->getID(re.user)), oldu(geteuid()), + myg(gec->getID(re.grp)), oldg(getegid()) +{ + if (setegid(myg)) + throw NetFS::SystemError(errno); + if (seteuid(myu)) + throw NetFS::SystemError(errno); +} + +TempPrivs::~TempPrivs() +{ + if (seteuid(oldu)) + throw NetFS::SystemError(errno); + if (setegid(oldg)) + throw NetFS::SystemError(errno); +} diff --git a/netfs/daemon/daemon.h b/netfs/daemon/daemon.h new file mode 100644 index 0000000..385dbb3 --- /dev/null +++ b/netfs/daemon/daemon.h @@ -0,0 +1,39 @@ +#ifndef DAEMON_H +#define DAEMON_H + +#include +#include +#include +#include +#include +#include +#include "daemonConfig.h" +#include +#include +#include +#include "guidmap.h" +#include + +class NetFSDaemon : public IceBox::Service { + public: + virtual void start(const std::string&, const Ice::CommunicatorPtr&, const Ice::StringSeq&); + virtual void stop(); + + private: + Ice::ObjectAdapterPtr adapter; + DaemonConfigPtr dc; +}; + +class TempPrivs { + public: + TempPrivs(uid_t u, gid_t g); + TempPrivs(const NetFS::ReqEnv & re, const UserEntCache * uec, const GroupEntCache * gec); + virtual ~TempPrivs(); + + private: + const uid_t myu, oldu; + const gid_t myg, oldg; +}; + +#endif + diff --git a/netfs/daemon/daemonConfig.cpp b/netfs/daemon/daemonConfig.cpp new file mode 100644 index 0000000..7f171eb --- /dev/null +++ b/netfs/daemon/daemonConfig.cpp @@ -0,0 +1,52 @@ +#include "pch.hpp" +#include "daemonConfig.h" +#include + +std::string +myHostname() +{ + char buf[128]; + gethostname(buf, sizeof(buf)); + return buf; +} + +DaemonConfigPtr +DaemonConfig::Load(const std::string & path) +{ + xmlDoc * doc = xmlReadFile(path.c_str(), NULL, 0); + DaemonConfigPtr dc = new DaemonConfig(doc->children); + xmlFreeDoc(doc); + return dc; +} + +DaemonConfig::DaemonConfig(xmlNodePtr conf) +{ + foreachxml(hos, xmlGetNode(conf, "hosts"), "host") { + HostPtr h = new Host(hos); + hosts[h->name] = h; + if (h->self) { + self = h; + } + } + foreachxml(exp, xmlGetNode(conf, "exports"), "export") { + ExportPtr e = new Export(exp, hosts); + exports[e->name] = e; + } +} + +DaemonConfig::Export::Export(xmlNodePtr exp, const HostMap & hosts) : + root(xmlGetNodeValue(exp, "root")), + name(xmlGetNodeValue(exp, "name")) +{ + foreachxml(rep, xmlGetNode(exp, "replicate"), "name") { + replicate.insert(hosts.find(xmlGetNodeValue(rep))->second); + } +} + +DaemonConfig::Host::Host(xmlNodePtr hos) : + iceEndpoint(xmlGetNodeValue(hos, "endpoint")), + name(xmlGetNodeValue(hos, "name")), + self(name == myHostname()) +{ +} + diff --git a/netfs/daemon/daemonConfig.h b/netfs/daemon/daemonConfig.h new file mode 100644 index 0000000..f27aedb --- /dev/null +++ b/netfs/daemon/daemonConfig.h @@ -0,0 +1,48 @@ +#ifndef DAEMONCONFIG_H +#define DAEMONCONFIG_H + +#include +#include +#include +#include +#include +#include +#include "xml.h" + +class DaemonConfig : public virtual IntrusivePtrBase { + public: + class Host : public virtual IntrusivePtrBase { + public: + Host(xmlNodePtr); + + std::string iceEndpoint; + std::string name; + bool self; + }; + typedef boost::intrusive_ptr HostPtr; + typedef std::map HostMap; + typedef std::set HostSet; + + class Export : public virtual IntrusivePtrBase { + public: + Export(xmlNodePtr, const HostMap &); + + boost::filesystem::path root; + std::string name; + HostSet replicate; + }; + typedef boost::intrusive_ptr ExportPtr; + typedef std::map ExportMap; + + DaemonConfig(xmlNodePtr); + static boost::intrusive_ptr Load(const std::string & path); + + + ExportMap exports; + HostMap hosts; + HostPtr self; +}; +typedef boost::intrusive_ptr DaemonConfigPtr; + +#endif + diff --git a/netfs/daemon/daemonDirectory.cpp b/netfs/daemon/daemonDirectory.cpp new file mode 100644 index 0000000..f679653 --- /dev/null +++ b/netfs/daemon/daemonDirectory.cpp @@ -0,0 +1,41 @@ +#include "pch.hpp" +#include +#include +#include +#include +#include +#include "daemonDirectory.h" + +DirectoryServer::DirectoryServer(DIR * d) : + od(d) +{ +} + +DirectoryServer::~DirectoryServer() +{ +} + +void +DirectoryServer::close(const Ice::Current & ice) +{ + errno = 0; + if (::closedir(od) != 0) { + throw NetFS::SystemError(errno); + } + ice.adapter->remove(ice.id); +} + +NetFS::NameList +DirectoryServer::readdir(const Ice::Current&) +{ + errno = 0; + NetFS::NameList list; + while (dirent * d = ::readdir(od)) { + if (errno) { + throw NetFS::SystemError(errno); + } + list.push_back(d->d_name); + } + return list; +} + diff --git a/netfs/daemon/daemonDirectory.h b/netfs/daemon/daemonDirectory.h new file mode 100644 index 0000000..c1ef3c6 --- /dev/null +++ b/netfs/daemon/daemonDirectory.h @@ -0,0 +1,22 @@ +#ifndef DAEMONDIRECTORY_H +#define DAEMONDIRECTORY_H + +#include +#include "entCache.h" + +class DirectoryServer : public NetFS::Directory { + public: + DirectoryServer(DIR * od); + virtual ~DirectoryServer(); + + virtual void close(const Ice::Current&) override; + virtual NetFS::NameList readdir(const Ice::Current&) override; + + private: + DIR * od; +}; + +#endif + + + diff --git a/netfs/daemon/daemonFile.cpp b/netfs/daemon/daemonFile.cpp new file mode 100644 index 0000000..0b94787 --- /dev/null +++ b/netfs/daemon/daemonFile.cpp @@ -0,0 +1,75 @@ +#include "pch.hpp" +#include +#include +#include +#include +#include +#include "daemonFile.h" + +FileServer::FileServer(int f) : + fd(f) +{ +} + +FileServer::~FileServer() +{ +} + +void +FileServer::ftruncate(const NetFS::ReqEnv & re, Ice::Long size, const Ice::Current&) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + if (::ftruncate(fd, size) != 0) { + throw NetFS::SystemError(errno); + } +} + +NetFS::Attr +FileServer::fgetattr(const NetFS::ReqEnv & re, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + struct stat s; + if (::fstat(fd, &s) != 0) { + throw NetFS::SystemError(errno); + } + NetFS::Attr a; + a << StatSource { s, boost::bind(&UserEntCache::getName, &uentries, _1), boost::bind(&GroupEntCache::getName, &gentries, _1) }; + return a; +} + +void +FileServer::close(const Ice::Current & ice) +{ + errno = 0; + if (::close(fd) != 0) { + throw NetFS::SystemError(errno); + } + ice.adapter->remove(ice.id); +} + +NetFS::Buffer +FileServer::read(Ice::Long offset, Ice::Long size, const Ice::Current&) +{ + NetFS::Buffer buf; + buf.resize(size); + errno = 0; + int r = pread(fd, &buf[0], size, offset); + if (r == -1) { + throw NetFS::SystemError(errno); + } + else if (r != size) { + buf.resize(r); + } + return buf; +} + +void +FileServer::write(Ice::Long offset, Ice::Long size, const NetFS::Buffer & data, const Ice::Current&) +{ + errno = 0; + if (pwrite(fd, &data.front(), size, offset) != size) { + throw NetFS::SystemError(errno); + } +} + diff --git a/netfs/daemon/daemonFile.h b/netfs/daemon/daemonFile.h new file mode 100644 index 0000000..9f170e4 --- /dev/null +++ b/netfs/daemon/daemonFile.h @@ -0,0 +1,28 @@ +#ifndef DAEMONFILE_H +#define DAEMONFILE_H + +#include +#include "entCache.h" + +class FileServer : public NetFS::File { + public: + FileServer(int fd); + virtual ~FileServer(); + + virtual void close(const Ice::Current&) override; + virtual void ftruncate(const NetFS::ReqEnv &, Ice::Long size, const Ice::Current&) override; + virtual NetFS::Attr fgetattr(const NetFS::ReqEnv &, const Ice::Current&) override; + + virtual NetFS::Buffer read(Ice::Long offset, Ice::Long size, const Ice::Current&) override; + virtual void write(Ice::Long offset, Ice::Long size, const NetFS::Buffer & data, const Ice::Current&) override; + + private: + const int fd; + + UserEntCache uentries; + GroupEntCache gentries; +}; + +#endif + + diff --git a/netfs/daemon/daemonService.cpp b/netfs/daemon/daemonService.cpp new file mode 100644 index 0000000..024e5a5 --- /dev/null +++ b/netfs/daemon/daemonService.cpp @@ -0,0 +1,21 @@ +#include "pch.hpp" +#include "daemonService.h" +#include "daemonVolume.h" + +ServiceServer::ServiceServer(int16_t hs, DaemonConfigPtr c) : + config(c), + hostseed(hs) +{ +} + +NetFS::VolumePrx +ServiceServer::connect(const std::string & share, const std::string &, const Ice::Current & ice) +{ + //boost::lock_guard lg(lock); + DaemonConfig::ExportMap::iterator e = config->exports.find(share); + if (e == config->exports.end()) { + throw NetFS::ConfigError(); + } + return NetFS::VolumePrx::checkedCast(ice.adapter->addWithUUID(new VolumeServer(e->second->root))); +} + diff --git a/netfs/daemon/daemonService.h b/netfs/daemon/daemonService.h new file mode 100644 index 0000000..5618c84 --- /dev/null +++ b/netfs/daemon/daemonService.h @@ -0,0 +1,18 @@ +#ifndef DAEMONSERVICE_H +#define DAEMONSERVICE_H + +#include + +class ServiceServer : public NetFS::Service { + public: + ServiceServer(int16_t hostseed, DaemonConfigPtr c); + + virtual NetFS::VolumePrx connect(const std::string & share, const std::string & auth, const Ice::Current&) override; + + private: + DaemonConfigPtr config; + const int16_t hostseed; +}; + +#endif + diff --git a/netfs/daemon/daemonVolume.cpp b/netfs/daemon/daemonVolume.cpp new file mode 100644 index 0000000..b87958b --- /dev/null +++ b/netfs/daemon/daemonVolume.cpp @@ -0,0 +1,243 @@ +#include "pch.hpp" +#include +#include +#include +#include +#include +#include +#include +#include "daemonVolume.h" +#include "daemonFile.h" +#include "daemonDirectory.h" + +extern std::map files; + +VolumeServer::VolumeServer(const boost::filesystem::path & r) : + root(r) +{ +} + +VolumeServer::~VolumeServer() +{ +} + +void +VolumeServer::disconnect(const Ice::Current & ice) +{ + ice.adapter->remove(ice.id); +} + +Ice::Int +VolumeServer::access(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + boost::filesystem::path p = root / path; + return ::access(p.string().c_str(), mode); +} + +NetFS::Attr +VolumeServer::getattr(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + struct stat s; + boost::filesystem::path p = root / path; + if (::lstat(p.string().c_str(), &s) != 0) { + throw NetFS::SystemError(errno); + } + NetFS::Attr a; + a << StatSource { s, boost::bind(&UserEntCache::getName, &uentries, _1), boost::bind(&GroupEntCache::getName, &gentries, _1) }; + return a; +} + +void +VolumeServer::symlink(const NetFS::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path2; + if (::symlink(path1.c_str(), p.string().c_str()) != 0) { + throw NetFS::SystemError(errno); + } +} + +void +VolumeServer::link(const NetFS::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p1 = root / path1; + boost::filesystem::path p2 = root / path2; + if (::link(p1.string().c_str(), p2.string().c_str()) != 0) { + throw NetFS::SystemError(errno); + } +} + +void +VolumeServer::rename(const NetFS::ReqEnv & re, const std::string & from, const std::string & to, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path f = root / from; + boost::filesystem::path t = root / to; + if (::rename(f.string().c_str(), t.string().c_str()) != 0) { + throw NetFS::SystemError(errno); + } +} + +std::string +VolumeServer::readlink(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + char buf[PATH_MAX]; + boost::filesystem::path p = root / path; + ssize_t rc = ::readlink(p.string().c_str(), buf, PATH_MAX); + if (rc == -1) { + throw NetFS::SystemError(errno); + } + return std::string(buf, rc); +} + +void +VolumeServer::chmod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + if (::chmod(p.string().c_str(), mode) != 0) { + throw NetFS::SystemError(errno); + } +} + +void +VolumeServer::chown(const NetFS::ReqEnv & re, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current &) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + if (::lchown(p.string().c_str(), uid, gid) != 0) { + throw NetFS::SystemError(errno); + } +} + +void +VolumeServer::utimens(const NetFS::ReqEnv & re, const std::string & path, + Ice::Long s0, Ice::Long ns0, Ice::Long s1, Ice::Long ns1, const Ice::Current&) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + struct timespec times[2]; + times[0].tv_sec = s0; + times[0].tv_nsec = ns0; + times[1].tv_sec = s1; + times[1].tv_nsec = ns1; + boost::filesystem::path p = root / path; + if (::utimensat(0, p.string().c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { + throw NetFS::SystemError(errno); + } +} + +NetFS::VFS +VolumeServer::statfs(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + struct statvfs s; + boost::filesystem::path p = root / path; + if (::statvfs(p.string().c_str(), &s) != 0) { + throw NetFS::SystemError(errno); + } + NetFS::VFS t; + t << s; + return t; +} + +void +VolumeServer::truncate(const NetFS::ReqEnv & re, const std::string & path, Ice::Long size, const Ice::Current&) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + if (::truncate(p.string().c_str(), size) != 0) { + throw NetFS::SystemError(errno); + } +} + +void +VolumeServer::unlink(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + if (::unlink(p.string().c_str()) != 0) { + throw NetFS::SystemError(errno); + } +} + +NetFS::ReadOnlyFilePrx +VolumeServer::openReadOnly(const NetFS::ReqEnv & re, const std::string & path, Ice::Int flags, const Ice::Current & ice) +{ + return open(re, path, flags, ice); +} + +NetFS::FilePrx +VolumeServer::open(const NetFS::ReqEnv & re, const std::string & path, Ice::Int flags, const Ice::Current & ice) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + int fd = ::open(p.string().c_str(), flags); + if (fd == -1) { + throw NetFS::SystemError(errno); + } + return NetFS::FilePrx::checkedCast(ice.adapter->addWithUUID(new FileServer(fd))); +} + +NetFS::FilePrx +VolumeServer::create(const NetFS::ReqEnv & re, const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current & ice) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + int fd = ::open(p.string().c_str(), O_CREAT | flags, mode); + if (fd == -1) { + throw NetFS::SystemError(errno); + } + return NetFS::FilePrx::checkedCast(ice.adapter->addWithUUID(new FileServer(fd))); +} + +NetFS::DirectoryPrx +VolumeServer::opendir(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current & ice) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + DIR * od = ::opendir(p.string().c_str()); + if (!od) { + throw NetFS::SystemError(errno); + } + return NetFS::DirectoryPrx::checkedCast(ice.adapter->addWithUUID(new DirectoryServer(od))); +} + +void +VolumeServer::mkdir(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current&) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + if (::mkdir(p.string().c_str(), mode) != 0) { + throw NetFS::SystemError(errno); + } +} + +void +VolumeServer::rmdir(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&) +{ + TempPrivs tp(re, &uentries, &gentries); + errno = 0; + boost::filesystem::path p = root / path; + if (::rmdir(p.string().c_str()) != 0) { + throw NetFS::SystemError(errno); + } +} + diff --git a/netfs/daemon/daemonVolume.h b/netfs/daemon/daemonVolume.h new file mode 100644 index 0000000..e8a5b72 --- /dev/null +++ b/netfs/daemon/daemonVolume.h @@ -0,0 +1,47 @@ +#ifndef DAEMONVOLUME_H +#define DAEMONVOLUME_H + +#include +#include "entCache.h" + +class VolumeServer : public NetFS::Volume { + public: + VolumeServer(const boost::filesystem::path & root); + virtual ~VolumeServer(); + + virtual NetFS::DirectoryPrx opendir(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&) override; + + virtual void mkdir(const NetFS::ReqEnv &, const std::string & path, Ice::Int id, const Ice::Current&) override; + virtual void rmdir(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&) override; + + virtual void truncate(const NetFS::ReqEnv &, const std::string & path, Ice::Long size, const Ice::Current&) override; + + virtual void unlink(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&) override; + + virtual NetFS::FilePrx open(const NetFS::ReqEnv &, const std::string & path, Ice::Int flags, const Ice::Current&) override; + virtual NetFS::ReadOnlyFilePrx openReadOnly(const NetFS::ReqEnv &, const std::string & path, Ice::Int flags, const Ice::Current&) override; + virtual NetFS::FilePrx create(const NetFS::ReqEnv &, const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current&) override; + + virtual NetFS::VFS statfs(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&) override; + + virtual Ice::Int access(const NetFS::ReqEnv &, const std::string & path, Ice::Int mode, const Ice::Current&) override; + virtual NetFS::Attr getattr(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&) override; + virtual void symlink(const NetFS::ReqEnv &, const std::string & path1, const std::string & path2, const Ice::Current&) override; + virtual void link(const NetFS::ReqEnv &, const std::string & path1, const std::string & path2, const Ice::Current&) override; + virtual void rename(const NetFS::ReqEnv &, const std::string & path1, const std::string & path2, const Ice::Current&) override; + virtual std::string readlink(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&) override; + virtual void chmod(const NetFS::ReqEnv &, const std::string & path, Ice::Int mode, const Ice::Current&) override; + virtual void chown(const NetFS::ReqEnv &, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current&) override; + virtual void utimens(const NetFS::ReqEnv &, const std::string & path, Ice::Long, Ice::Long, Ice::Long, Ice::Long, const Ice::Current&) override; + + virtual void disconnect(const Ice::Current&) override; + + private: + const boost::filesystem::path root; + + UserEntCache uentries; + GroupEntCache gentries; +}; + +#endif + diff --git a/netfs/daemon/pch.hpp b/netfs/daemon/pch.hpp new file mode 100644 index 0000000..3229655 --- /dev/null +++ b/netfs/daemon/pch.hpp @@ -0,0 +1,13 @@ +#ifdef BOOST_BUILD_PCH_ENABLED +#ifndef NETFS_DAEMON_PCH +#define NETFS_DAEMON_PCH + +#include "../lib/pch.hpp" +#include +#include "daemon.h" +#include + +#endif +#endif + + diff --git a/netfs/daemonConfig.cpp b/netfs/daemonConfig.cpp deleted file mode 100644 index 0d05c44..0000000 --- a/netfs/daemonConfig.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "pchDaemon.hpp" -#include "daemonConfig.h" -#include - -std::string -myHostname() -{ - char buf[128]; - gethostname(buf, sizeof(buf)); - return buf; -} - -DaemonConfigPtr -DaemonConfig::Load(const std::string & path) -{ - xmlDoc * doc = xmlReadFile(path.c_str(), NULL, 0); - DaemonConfigPtr dc = new DaemonConfig(doc->children); - xmlFreeDoc(doc); - return dc; -} - -DaemonConfig::DaemonConfig(xmlNodePtr conf) -{ - foreachxml(hos, xmlGetNode(conf, "hosts"), "host") { - HostPtr h = new Host(hos); - hosts[h->name] = h; - if (h->self) { - self = h; - } - } - foreachxml(exp, xmlGetNode(conf, "exports"), "export") { - ExportPtr e = new Export(exp, hosts); - exports[e->name] = e; - } -} - -DaemonConfig::Export::Export(xmlNodePtr exp, const HostMap & hosts) : - root(xmlGetNodeValue(exp, "root")), - name(xmlGetNodeValue(exp, "name")) -{ - foreachxml(rep, xmlGetNode(exp, "replicate"), "name") { - replicate.insert(hosts.find(xmlGetNodeValue(rep))->second); - } -} - -DaemonConfig::Host::Host(xmlNodePtr hos) : - iceEndpoint(xmlGetNodeValue(hos, "endpoint")), - name(xmlGetNodeValue(hos, "name")), - self(name == myHostname()) -{ -} - diff --git a/netfs/daemonConfig.h b/netfs/daemonConfig.h deleted file mode 100644 index f27aedb..0000000 --- a/netfs/daemonConfig.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef DAEMONCONFIG_H -#define DAEMONCONFIG_H - -#include -#include -#include -#include -#include -#include -#include "xml.h" - -class DaemonConfig : public virtual IntrusivePtrBase { - public: - class Host : public virtual IntrusivePtrBase { - public: - Host(xmlNodePtr); - - std::string iceEndpoint; - std::string name; - bool self; - }; - typedef boost::intrusive_ptr HostPtr; - typedef std::map HostMap; - typedef std::set HostSet; - - class Export : public virtual IntrusivePtrBase { - public: - Export(xmlNodePtr, const HostMap &); - - boost::filesystem::path root; - std::string name; - HostSet replicate; - }; - typedef boost::intrusive_ptr ExportPtr; - typedef std::map ExportMap; - - DaemonConfig(xmlNodePtr); - static boost::intrusive_ptr Load(const std::string & path); - - - ExportMap exports; - HostMap hosts; - HostPtr self; -}; -typedef boost::intrusive_ptr DaemonConfigPtr; - -#endif - diff --git a/netfs/daemonDirs.cpp b/netfs/daemonDirs.cpp deleted file mode 100644 index 1fb3965..0000000 --- a/netfs/daemonDirs.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "pchDaemon.hpp" -#include -#include -#include -#include -#include -#include "daemonFileSystem.h" - -Ice::Int -FileSystemServer::opendir(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - DIR * od = ::opendir(p.string().c_str()); - if (!od) { - throw NetFSComms::SystemError(errno); - } - //s.replicatedRequest = true; - return sess->dirs.store(od); -} - -void -FileSystemServer::closedir(Ice::Long tok, Ice::Int id, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(tok), false); - try { - errno = 0; - if (::closedir(sess->dirs.get(id)) != 0) { - throw NetFSComms::SystemError(errno); - } - sess->dirs.remove(id); - } - catch (GUIDMap::NotFound) { - throw NetFSComms::SystemError(EBADF); - } - //s.replicatedRequest = true; -} - -NetFSComms::NameList -FileSystemServer::readdir(Ice::Long tok, Ice::Int id, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(tok), false); - try { - errno = 0; - dirent * d; - NetFSComms::NameList list; - DIR * dir = sess->dirs.get(id); - while ((d = ::readdir(dir))) { - if (errno) { - throw NetFSComms::SystemError(errno); - } - list.push_back(d->d_name); - } - return list; - } - catch (GUIDMap::NotFound) { - throw NetFSComms::SystemError(EBADF); - } -} - -void -FileSystemServer::mkdir(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::mkdir(p.string().c_str(), mode) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - -void -FileSystemServer::rmdir(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::rmdir(p.string().c_str()) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - diff --git a/netfs/daemonFileSystem.cpp b/netfs/daemonFileSystem.cpp deleted file mode 100644 index f0d3546..0000000 --- a/netfs/daemonFileSystem.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "pchDaemon.hpp" -#include "daemonFileSystem.h" - -FileSystemServer::FileSystemServer(DaemonGlobalStatePtr dgs) : - DaemonModule(dgs) -{ -} - -FileSystemServer::~FileSystemServer() -{ -} - diff --git a/netfs/daemonFileSystem.h b/netfs/daemonFileSystem.h deleted file mode 100644 index 2950f79..0000000 --- a/netfs/daemonFileSystem.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef DAEMONFILESYSTEM_H -#define DAEMONFILESYSTEM_H - -#include "netfsComms.h" -#include "daemonModule.h" -#include "entCache.h" -#include - -class FileSystemServer : public DaemonModule, public NetFSComms::FileSystem { - public: - FileSystemServer(DaemonGlobalStatePtr dgs); - virtual ~FileSystemServer(); - - virtual Ice::Int opendir(const NetFSComms::ReqEnv &, const std::string & path, const Ice::Current&); - virtual void closedir(Ice::Long tok, Ice::Int id, const Ice::Current&); - virtual NetFSComms::NameList readdir(Ice::Long tok, Ice::Int id, const Ice::Current&); - - virtual void mkdir(const NetFSComms::ReqEnv &, const std::string & path, Ice::Int id, const Ice::Current&); - virtual void rmdir(const NetFSComms::ReqEnv &, const std::string & path, const Ice::Current&); - - virtual void truncate(const NetFSComms::ReqEnv &, const std::string & path, Ice::Long size, const Ice::Current&); - virtual void ftruncate(const NetFSComms::ReqEnv &, Ice::Int id, Ice::Long size, const Ice::Current&); - virtual NetFSComms::Attr fgetattr(const NetFSComms::ReqEnv &, Ice::Int id, const Ice::Current&); - - virtual void unlink(const NetFSComms::ReqEnv &, const std::string & path, const Ice::Current&); - - virtual Ice::Int open(const NetFSComms::ReqEnv &, const std::string & path, Ice::Int flags, const Ice::Current&); - virtual Ice::Int create(const NetFSComms::ReqEnv &, const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current&); - virtual void close(Ice::Long tok, Ice::Int id, const Ice::Current&); - virtual NetFSComms::Buffer read(Ice::Long tok, Ice::Int id, Ice::Long offset, Ice::Long size, const Ice::Current&); - virtual void write(Ice::Long tok, Ice::Int id, Ice::Long offset, Ice::Long size, const NetFSComms::Buffer & data, const Ice::Current&); - - virtual NetFSComms::VFS statfs(const NetFSComms::ReqEnv &, const std::string & path, const Ice::Current&); - - virtual Ice::Int access(const NetFSComms::ReqEnv &, const std::string & path, Ice::Int mode, const Ice::Current&); - virtual NetFSComms::Attr getattr(const NetFSComms::ReqEnv &, const std::string & path, const Ice::Current&); - virtual void symlink(const NetFSComms::ReqEnv &, const std::string & path1, const std::string & path2, const Ice::Current&); - virtual void link(const NetFSComms::ReqEnv &, const std::string & path1, const std::string & path2, const Ice::Current&); - virtual void rename(const NetFSComms::ReqEnv &, const std::string & path1, const std::string & path2, const Ice::Current&); - virtual std::string readlink(const NetFSComms::ReqEnv &, const std::string & path, const Ice::Current&); - virtual void chmod(const NetFSComms::ReqEnv &, const std::string & path, Ice::Int mode, const Ice::Current&); - virtual void chown(const NetFSComms::ReqEnv &, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current&); - virtual void utimens(const NetFSComms::ReqEnv &, const std::string & path, Ice::Long, Ice::Long, Ice::Long, Ice::Long, const Ice::Current&); - private: - UserEntCache uentries; - GroupEntCache gentries; -}; - -#endif - diff --git a/netfs/daemonFiles.cpp b/netfs/daemonFiles.cpp deleted file mode 100644 index 75d9058..0000000 --- a/netfs/daemonFiles.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "pchDaemon.hpp" -#include -#include -#include -#include -#include "daemonFileSystem.h" - -void -FileSystemServer::truncate(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Long size, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::truncate(p.string().c_str(), size) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - -void -FileSystemServer::ftruncate(const NetFSComms::ReqEnv & re, Ice::Int id, Ice::Long size, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), false); - TempPrivs tp(re, &uentries, &gentries); - try { - errno = 0; - if (::ftruncate(sess->files.get(id), size) != 0) { - throw NetFSComms::SystemError(errno); - } - } - catch (GUIDMap::NotFound) { - throw NetFSComms::SystemError(EBADF); - } - // s.replicatedRequest = true; -} - -NetFSComms::Attr -FileSystemServer::fgetattr(const NetFSComms::ReqEnv & re, Ice::Int id, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), false); - TempPrivs tp(re, &uentries, &gentries); - try { - struct stat s; - if (::fstat(sess->files.get(id), &s) != 0) { - throw NetFSComms::SystemError(errno); - } - NetFSComms::Attr a; - a.dev = s.st_dev; - a.inode = s.st_ino; - a.mode = s.st_mode; - a.links = s.st_nlink; - a.uid = uentries.getName(s.st_uid); - a.gid = gentries.getName(s.st_gid); - a.rdev = s.st_rdev; - a.size = s.st_size; - a.blockSize = s.st_blksize; - a.blocks = s.st_blocks; - a.atime = s.st_atime; - a.mtime = s.st_mtime; - a.ctime = s.st_ctime; - return a; - } - catch (GUIDMap::NotFound) { - throw NetFSComms::SystemError(EBADF); - } -} - -void -FileSystemServer::unlink(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::unlink(p.string().c_str()) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - -Ice::Int -FileSystemServer::open(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int flags, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - int fd = ::open(p.string().c_str(), flags); - if (fd == -1) { - throw NetFSComms::SystemError(errno); - } - //s.replicatedRequest = true; - return sess->files.store(fd); -} - -Ice::Int -FileSystemServer::create(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - int fd = ::open(p.string().c_str(), O_CREAT | flags, mode); - if (fd == -1) { - throw NetFSComms::SystemError(errno); - } - //s.replicatedRequest = true; - return sess->files.store(fd); -} - -void -FileSystemServer::close(Ice::Long tok, Ice::Int id, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(tok), false); - try { - errno = 0; - if (::close(sess->files.get(id)) != 0) { - throw NetFSComms::SystemError(errno); - } - sess->files.remove(id); - // s.replicatedRequest = true; - } - catch (GUIDMap::NotFound) { - throw NetFSComms::SystemError(EBADF); - } -} - -NetFSComms::Buffer -FileSystemServer::read(Ice::Long tok, Ice::Int id, Ice::Long offset, Ice::Long size, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(tok), false); - try { - NetFSComms::Buffer buf; - buf.resize(size); - errno = 0; - int r = pread(sess->files.get(id), &buf[0], size, offset); - if (r == -1) { - throw NetFSComms::SystemError(errno); - } - else if (r != size) { - buf.resize(r); - } - return buf; - } - catch (GUIDMap::NotFound) { - throw NetFSComms::SystemError(EBADF); - } -} - -void -FileSystemServer::write(Ice::Long tok, Ice::Int id, Ice::Long offset, Ice::Long size, const NetFSComms::Buffer & data, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(tok), false); - try { - errno = 0; - if (pwrite(sess->files.get(id), &data[0], size, offset) != size) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; - } - catch (GUIDMap::NotFound) { - throw NetFSComms::SystemError(EBADF); - } -} - diff --git a/netfs/daemonMisc.cpp b/netfs/daemonMisc.cpp deleted file mode 100644 index e548606..0000000 --- a/netfs/daemonMisc.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "pchDaemon.hpp" -#include -#include -#include -#include -#include -#include -#include "daemonFileSystem.h" - -extern std::map files; - -Ice::Int -FileSystemServer::access(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - return ::access(p.string().c_str(), mode); -} - -NetFSComms::Attr -FileSystemServer::getattr(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - struct stat s; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::lstat(p.string().c_str(), &s) != 0) { - throw NetFSComms::SystemError(errno); - } - NetFSComms::Attr a; - a.dev = s.st_dev; - a.inode = s.st_ino; - a.mode = s.st_mode; - a.links = s.st_nlink; - a.uid = uentries.getName(s.st_uid); - a.gid = gentries.getName(s.st_gid); - a.rdev = s.st_rdev; - a.size = s.st_size; - a.blockSize = s.st_blksize; - a.blocks = s.st_blocks; - a.atime = s.st_atime; - a.mtime = s.st_mtime; - a.ctime = s.st_ctime; - return a; -} - -void -FileSystemServer::symlink(const NetFSComms::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path2; - sess.unlock(); - if (::symlink(path1.c_str(), p.string().c_str()) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - -void -FileSystemServer::link(const NetFSComms::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p1 = sess->exportCfg->root / path1; - boost::filesystem::path p2 = sess->exportCfg->root / path2; - sess.unlock(); - if (::link(p1.string().c_str(), p2.string().c_str()) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - -void -FileSystemServer::rename(const NetFSComms::ReqEnv & re, const std::string & from, const std::string & to, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path f = sess->exportCfg->root / from; - boost::filesystem::path t = sess->exportCfg->root / to; - sess.unlock(); - if (::rename(f.string().c_str(), t.string().c_str()) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - -std::string -FileSystemServer::readlink(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - char buf[PATH_MAX]; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - ssize_t rc = ::readlink(p.string().c_str(), buf, PATH_MAX); - if (rc == -1) { - throw NetFSComms::SystemError(errno); - } - return std::string(buf, rc); -} - -void -FileSystemServer::chmod(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::chmod(p.string().c_str(), mode) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - -void -FileSystemServer::chown(const NetFSComms::ReqEnv & re, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current &) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::lchown(p.string().c_str(), uid, gid) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - -void -FileSystemServer::utimens(const NetFSComms::ReqEnv & re, const std::string & path, - Ice::Long s0, Ice::Long ns0, Ice::Long s1, Ice::Long ns1, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - struct timespec times[2]; - times[0].tv_sec = s0; - times[0].tv_nsec = ns0; - times[1].tv_sec = s1; - times[1].tv_nsec = ns1; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::utimensat(0, p.string().c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { - throw NetFSComms::SystemError(errno); - } - // s.replicatedRequest = true; -} - diff --git a/netfs/daemonModule.cpp b/netfs/daemonModule.cpp deleted file mode 100644 index 8be108c..0000000 --- a/netfs/daemonModule.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "pchDaemon.hpp" -#include "daemonModule.h" - -DaemonModule::DaemonModule(DaemonGlobalStatePtr d) : - dgs(d) -{ -} - diff --git a/netfs/daemonModule.h b/netfs/daemonModule.h deleted file mode 100644 index 7525e74..0000000 --- a/netfs/daemonModule.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef DAEMONMODULE_H -#define DAEMONMODULE_H - -#include "daemon.h" - -class DaemonModule { - protected: - DaemonModule(DaemonGlobalStatePtr dgs); - - DaemonGlobalStatePtr dgs; -}; - -#endif - diff --git a/netfs/daemonService.cpp b/netfs/daemonService.cpp deleted file mode 100644 index bb13fbc..0000000 --- a/netfs/daemonService.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "pchDaemon.hpp" -#include "daemonService.h" - -ServiceServer::ServiceServer(int16_t hs, DaemonGlobalStatePtr dgs) : - DaemonModule(dgs), - hostseed(hs) -{ -} - -Ice::Long -ServiceServer::connect(const std::string & share, const std::string &, const Ice::Current &) -{ - DaemonGlobalState::NSP s = dgs->newSession(hostseed, share); - return s.get<0>(); -} - -void -ServiceServer::disconnect(Ice::Long tok, const Ice::Current &) -{ - dgs->endSession(tok); -} - diff --git a/netfs/daemonService.h b/netfs/daemonService.h deleted file mode 100644 index 067e4a5..0000000 --- a/netfs/daemonService.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef DAEMONSERVICE_H -#define DAEMONSERVICE_H - -#include "netfsComms.h" -#include "daemonModule.h" - -class ServiceServer : public DaemonModule, public NetFSComms::Service { - public: - ServiceServer(int16_t hostseed, DaemonGlobalStatePtr dgs); - - virtual Ice::Long connect(const std::string & share, const std::string & auth, const Ice::Current&); - virtual void disconnect(Ice::Long tok, const Ice::Current&); - private: - const int16_t hostseed; -}; - -#endif - diff --git a/netfs/daemonSystem.cpp b/netfs/daemonSystem.cpp deleted file mode 100644 index 1f683d6..0000000 --- a/netfs/daemonSystem.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "pchDaemon.hpp" -#include -#include -#include -#include "daemonFileSystem.h" - -NetFSComms::VFS -FileSystemServer::statfs(const NetFSComms::ReqEnv & re, const std::string & path, const Ice::Current&) -{ - SessionPtr sess(dgs->getSession(re.tok), true); - TempPrivs tp(re, &uentries, &gentries); - errno = 0; - struct statvfs s; - boost::filesystem::path p = sess->exportCfg->root / path; - sess.unlock(); - if (::statvfs(p.string().c_str(), &s) != 0) { - throw NetFSComms::SystemError(errno); - } - NetFSComms::VFS t; - t.blockSize = s.f_bsize; - t.fragmentSize = s.f_frsize; - t.blocks = s.f_blocks; - t.freeBlocks = s.f_bfree; - t.availBlocks = s.f_bavail; - t.files = s.f_files; - t.freeFiles = s.f_ffree; - t.availFiles = s.f_favail; - t.FSID = s.f_fsid; - t.flags = s.f_flag; - t.maxNameLen = s.f_namemax; - return t; -} - diff --git a/netfs/entCache.cpp b/netfs/entCache.cpp deleted file mode 100644 index d79de29..0000000 --- a/netfs/entCache.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "pchCommon.hpp" -#include "entCache.h" -#include - -#define LOCK boost::unique_lock _lck(lock) -#define SLOCK boost::shared_lock _lck(lock) - -template -EntCache::EntCache() -{ -} - -template -EntCache::~EntCache() -{ -} - -template -const id_t & -EntCache::getID(const name_t & u) const -{ - { - SLOCK; - typename IDs::right_map::const_iterator cu = idcache.right.find(u); - if (cu != idcache.right.end()) { - return cu->second; - } - } - fillCache(); - SLOCK; - typename IDs::right_map::const_iterator cu = idcache.right.find(u); - if (cu != idcache.right.end()) { - return cu->second; - } - throw NetFSComms::SystemError(EPERM); -} - -template -const name_t & -EntCache::getName(const id_t & u) const -{ - { - SLOCK; - typename IDs::left_map::const_iterator cu = idcache.left.find(u); - if (cu != idcache.left.end()) { - return cu->second; - } - } - fillCache(); - SLOCK; - typename IDs::left_map::const_iterator cu = idcache.left.find(u); - if (cu != idcache.left.end()) { - return cu->second; - } - throw NetFSComms::SystemError(EPERM); -} - -template class EntCache; -void -UserEntCache::fillCache() const -{ - LOCK; - setpwent(); - idcache.clear(); - while (struct passwd * pwp = getpwent()) { - idcache.insert(boost::bimap::value_type(pwp->pw_uid, pwp->pw_name)); - } - endpwent(); -} - -void -GroupEntCache::fillCache() const -{ - LOCK; - setgrent(); - idcache.clear(); - while (struct group * grpp = getgrent()) { - idcache.insert(boost::bimap::value_type(grpp->gr_gid, grpp->gr_name)); - } - endgrent(); -} - - - diff --git a/netfs/entCache.h b/netfs/entCache.h deleted file mode 100644 index c16cd0b..0000000 --- a/netfs/entCache.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef ENTCACHE_H -#define ENTCACHE_H - -#include -#include -#include -#include -#include - -template -class EntCache { - public: - EntCache(); - virtual ~EntCache(); - - const id_t & getID(const name_t & ) const; - const name_t & getName(const id_t &) const; - - protected: - virtual void fillCache() const = 0; - typedef boost::bimap IDs; - mutable IDs idcache; - mutable boost::shared_mutex lock; -}; - -class UserEntCache : public EntCache { - private: - void fillCache() const; -}; - -class GroupEntCache : public EntCache { - private: - void fillCache() const; -}; - -#endif - diff --git a/netfs/fuse.cpp b/netfs/fuse.cpp deleted file mode 100644 index 057daa0..0000000 --- a/netfs/fuse.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "pchFuse.hpp" -#include -#include -#include "fuse.h" - -NetFS::ReqEnv::ReqEnv(const NetFS * netfs) -{ - struct fuse_context * c = fuse_get_context(); - tok = netfs->authtok; - user = netfs->uentries.getName(c->uid); - grp = netfs->gentries.getName(c->gid); -} - -NetFS::NetFS(int & argc, char ** argv) : - _argc(argc), - _argv(argv), - authtok(0), - openFileID(0) -{ -} - -NetFS::~NetFS() -{ - if (authtok) { - service->disconnect(authtok); - } - if (ic) { - ic->destroy(); - } -} - -void * -NetFS::init(struct fuse_conn_info *) -{ - ic = Ice::initialize(_argc, _argv); - fc = FuseConfig::Load(configPath); - return NULL; -} - -int -NetFS::opt_parse(void *, const char * arg, int, struct fuse_args *) -{ - if (strncmp(arg, "--Ice.", 6) == 0) { - return 0; - } - else if (arg[0] == '-') { - return 1; - } - else if (exportName.empty()) { - const char * colon = strchr(arg, ':'); - exportName = colon + 1; - configPath.assign(arg, colon); - return 0; - } - else if (mountPoint.empty()) { - mountPoint = arg; - return 1; - } - return 1; -} - -void -NetFS::connect() -{ - LOCK; - connect_nl(); -} -void -NetFS::connect_nl() -{ - authtok = service->connect(exportName, "bar"); - BOOST_FOREACH(const OpenFiles::value_type & of, openFiles) { - of.second->remoteID = filesystem->open(reqEnv(), of.second->path, of.second->flags); - } - BOOST_FOREACH(const OpenDirs::value_type & of, openDirs) { - of.second->remoteID = filesystem->opendir(reqEnv(), of.second->path); - } -} - -int -NetFS::onError(const std::exception & e) throw() -{ - if (dynamic_cast(&e)) { - // I've become unauthenticated... reauthenticate - connect_nl(); - return 0; - } - return FuseAppBase::onError(e); -} - -NetFS::ReqEnv -NetFS::reqEnv() -{ - LOCK; - if (!service || !filesystem) { - FuseConfig::ExportPtr e = fc->exports[exportName]; - const std::string & ep = *e->endpoints.begin(); - - service = NetFSComms::ServicePrx::checkedCast(ic->stringToProxy("Service:" + ep)); - if (!service) { - throw "Invalid service proxy"; - } - - filesystem = NetFSComms::FileSystemPrx::checkedCast(ic->stringToProxy("FileSystem:" + ep)); - if (!filesystem) { - throw "Invalid filesystem proxy"; - } - } - if (authtok == 0) { - connect_nl(); - } - return ReqEnv(this); -} - -int -main(int argc, char* argv[]) -{ - return FuseAppBase::run(argc, argv, new NetFS(argc, argv)); -} - diff --git a/netfs/fuse.h b/netfs/fuse.h deleted file mode 100644 index 4a0abfd..0000000 --- a/netfs/fuse.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef FUSE_H -#define FUSE_H - -#include -#include -#include "netfsComms.h" -#include "fuseapp.h" -#include "fuseConfig.h" -#include "entCache.h" -#include "intrusivePtrBase.h" - -#define LOCK boost::unique_lock _lck(_lock) - -class NetFS : public FuseAppBase -{ - private: - class ReqEnv : public NetFSComms::ReqEnv { - public: - ReqEnv(const NetFS *); - }; - - class OpenDir : public IntrusivePtrBase { - public: - OpenDir(Ice::Int remoteID, const std::string & path); - - Ice::Int remoteID; - const std::string path; - }; - typedef boost::intrusive_ptr OpenDirPtr; - typedef std::map OpenDirs; - - class OpenFile : public IntrusivePtrBase { - public: - OpenFile(Ice::Int remoteID, const std::string & path, int flags); - - Ice::Int remoteID; - const std::string path; - const int flags; - }; - typedef boost::intrusive_ptr OpenFilePtr; - typedef std::map OpenFiles; - - public: - NetFS(int & argc, char ** argv); - ~NetFS(); - private: - void * init (struct fuse_conn_info * info); - int opt_parse(void *, const char * arg, int key, struct fuse_args *); - void connect(); - void connect_nl(); - public: - // misc - int access(const char * p, int a); - int getattr(const char * p, struct stat * s); - int fgetattr(const char *, struct stat *, struct fuse_file_info *); - int chmod(const char *, mode_t); - int chown(const char *, uid_t, gid_t); - int link(const char *, const char *); - int readlink(const char *, char *, size_t); - int rename(const char *, const char *); - int symlink(const char *, const char *); - int unlink(const char *); - int utimens(const char *, const struct timespec tv[2]); - // dirs - int opendir(const char * p, struct fuse_file_info * fi); - int releasedir(const char *, struct fuse_file_info * fi); - int readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi); - int mkdir(const char *, mode_t); - int rmdir(const char *); - // files - int open(const char * p, struct fuse_file_info * fi); - int create(const char *, mode_t, struct fuse_file_info *); - int release(const char *, struct fuse_file_info * fi); - int read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi); - int write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi); - int truncate(const char *, off_t); - int ftruncate(const char *, off_t, struct fuse_file_info *); - // fs - int statfs(const char *, struct statvfs *); - // stuff - int onError(const std::exception & err) throw(); - private: - int getNextFileID(); - Ice::Int getRemoteIDforFile(int localID) const; - int getNextDirID(); - Ice::Int getRemoteIDforDir(int localID) const; - - ReqEnv reqEnv(); - - int & _argc; - char ** _argv; - Ice::CommunicatorPtr ic; - FuseConfigPtr fc; - mutable boost::mutex _lock; - - NetFSComms::FileSystemPrx filesystem; - NetFSComms::ServicePrx service; - - mutable Ice::Long authtok; - - std::string mountPoint; - std::string exportName; - std::string configPath; - - UserEntCache uentries; - GroupEntCache gentries; - OpenDirs openDirs; - int openDirID; - OpenFiles openFiles; - int openFileID; -}; - -#endif diff --git a/netfs/fuse/Jamfile.jam b/netfs/fuse/Jamfile.jam new file mode 100644 index 0000000..873f67c --- /dev/null +++ b/netfs/fuse/Jamfile.jam @@ -0,0 +1,33 @@ +cpp-pch pch : pch.hpp : + _FILE_OFFSET_BITS=64 + ../../libmisc + ../../libfusepp + ../ice//netfsComms + ../ice//netfsComms + ..//boost_thread + ..//fuse + ..//Ice + ..//libxml2 + ; + + +exe netfs : + pch + [ glob *.cpp ] + [ glob ../../libfusepp/fuse*.cpp ] + : + _FILE_OFFSET_BITS=64 + ../../libmisc + ../../libfusepp + ../ice//netfsComms + ../ice//netfsComms + ../lib//netfsCommon + ..//boost_thread + ..//boost_system + ..//fuse + ..//Ice + ..//IceUtil + ..//pthread + ..//libxml2 + ; + diff --git a/netfs/fuse/fuse.cpp b/netfs/fuse/fuse.cpp new file mode 100644 index 0000000..e221cfd --- /dev/null +++ b/netfs/fuse/fuse.cpp @@ -0,0 +1,148 @@ +#include "pch.hpp" +#include +#include +#include "fuse.h" + +NetFS::FuseApp::FuseApp(int & argc, char ** argv) : + _argc(argc), + _argv(argv), + openDirID(0), + openFileID(0) +{ +} + +NetFS::FuseApp::~FuseApp() +{ + volume->disconnect(); + if (ic) { + ic->destroy(); + } +} + +void * +NetFS::FuseApp::init(struct fuse_conn_info *) +{ + ic = Ice::initialize(_argc, _argv); + fc = FuseConfig::Load(configPath); + return NULL; +} + +int +NetFS::FuseApp::opt_parse(void *, const char * arg, int, struct fuse_args *) +{ + if (strncmp(arg, "--Ice.", 6) == 0) { + return 0; + } + else if (arg[0] == '-') { + return 1; + } + else if (exportName.empty()) { + const char * colon = strchr(arg, ':'); + exportName = colon + 1; + configPath.assign(arg, colon); + return 0; + } + else if (mountPoint.empty()) { + mountPoint = arg; + return 1; + } + return 1; +} + +void +NetFS::FuseApp::connectToService() +{ + if (!service) { + LOCK; + FuseConfig::ExportPtr e = fc->exports[exportName]; + const std::string & ep = *e->endpoints.begin(); + + service = NetFS::ServicePrx::checkedCast(ic->stringToProxy("Service:" + ep)); + if (!service) { + throw "Invalid service proxy"; + } + } +} + +void +NetFS::FuseApp::connectToVolume() +{ + if (!volume) { + volume = service->connect(exportName, "bar"); + if (!volume) { + throw "Invalid filesystem proxy"; + } + } +} + +void +NetFS::FuseApp::connectHandles() +{ + BOOST_FOREACH(const OpenFiles::value_type & of, openFiles) { + try { + of.second->remote->ice_ping(); + } + catch (const Ice::ObjectNotExistException &) { + of.second->remote = volume->open(reqEnv(), of.second->path, of.second->flags); + } + } + BOOST_FOREACH(const OpenDirs::value_type & of, openDirs) { + try { + of.second->remote->ice_ping(); + } + catch (const Ice::ObjectNotExistException &) { + of.second->remote = volume->opendir(reqEnv(), of.second->path); + } + } +} + +void +NetFS::FuseApp::verifyConnection() +{ + LOCK; + if (service) { + try { + service->ice_ping(); + } + catch (const Ice::Exception &) { + service = NULL; + } + } + if (volume) { + try { + volume->ice_ping(); + } + catch (const Ice::Exception &) { + volume = NULL; + } + } +} + +int +NetFS::FuseApp::onError(const std::exception & e) throw() +{ + if (dynamic_cast(&e)) { + verifyConnection(); + connectToService(); + connectToVolume(); + connectHandles(); + return 0; + } + return FuseAppBase::onError(e); +} + +NetFS::ReqEnv +NetFS::FuseApp::reqEnv() +{ + connectToService(); + connectToVolume(); + struct fuse_context * c = fuse_get_context(); + return { uentries.getName(c->uid), gentries.getName(c->gid) }; +} + +int +main(int argc, char* argv[]) +{ + return FuseAppBase::run(argc, argv, new NetFS::FuseApp(argc, argv)); +} + diff --git a/netfs/fuse/fuse.h b/netfs/fuse/fuse.h new file mode 100644 index 0000000..033d7fa --- /dev/null +++ b/netfs/fuse/fuse.h @@ -0,0 +1,117 @@ +#ifndef FUSE_H +#define FUSE_H + +#include +#include +#include +#include "fuseapp.h" +#include "fuseConfig.h" +#include "entCache.h" +#include "intrusivePtrBase.h" + +#define LOCK boost::unique_lock _lck(_lock) +#define SLOCK boost::shared_lock _lck(_lock) + +namespace NetFS { + class FuseApp : public FuseAppBase { + private: + class OpenDir : public IntrusivePtrBase { + public: + OpenDir(DirectoryPrx remote, const std::string & path); + + DirectoryPrx remote; + const std::string path; + }; + typedef boost::intrusive_ptr OpenDirPtr; + typedef std::map OpenDirs; + + class OpenFile : public IntrusivePtrBase { + public: + OpenFile(FilePrx remote, const std::string & path, int flags); + + FilePrx remote; + const std::string path; + const int flags; + }; + typedef boost::intrusive_ptr OpenFilePtr; + typedef std::map OpenFiles; + + public: + FuseApp(int & argc, char ** argv); + ~FuseApp(); + + private: + void * init (struct fuse_conn_info * info); + int opt_parse(void *, const char * arg, int key, struct fuse_args *); + + void connectToService(); + void connectToVolume(); + void connectHandles(); + void verifyConnection(); + + public: + // misc + int access(const char * p, int a); + int getattr(const char * p, struct stat * s); + int fgetattr(const char *, struct stat *, struct fuse_file_info *); + int chmod(const char *, mode_t); + int chown(const char *, uid_t, gid_t); + int link(const char *, const char *); + int readlink(const char *, char *, size_t); + int rename(const char *, const char *); + int symlink(const char *, const char *); + int unlink(const char *); + int utimens(const char *, const struct timespec tv[2]); + // dirs + int opendir(const char * p, struct fuse_file_info * fi); + int releasedir(const char *, struct fuse_file_info * fi); + int readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi); + int mkdir(const char *, mode_t); + int rmdir(const char *); + // files + int open(const char * p, struct fuse_file_info * fi); + int create(const char *, mode_t, struct fuse_file_info *); + int release(const char *, struct fuse_file_info * fi); + int read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi); + int write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi); + int truncate(const char *, off_t); + int ftruncate(const char *, off_t, struct fuse_file_info *); + // fs + int statfs(const char *, struct statvfs *); + // stuff + int onError(const std::exception & err) throw(); + + private: + void setProxy(OpenFilePtr, uint64_t & fh); + OpenFilePtr getFileProxy(uint64_t localID) const; + void clearFileProxy(uint64_t localID); + + void setProxy(OpenDirPtr, uint64_t & fh); + OpenDirPtr getDirProxy(uint64_t localID) const; + void clearDirProxy(uint64_t localID); + + ReqEnv reqEnv(); + + int & _argc; + char ** _argv; + Ice::CommunicatorPtr ic; + FuseConfigPtr fc; + mutable boost::shared_mutex _lock; + + NetFS::VolumePrx volume; + NetFS::ServicePrx service; + + std::string mountPoint; + std::string exportName; + std::string configPath; + + UserEntCache uentries; + GroupEntCache gentries; + OpenDirs openDirs; + int openDirID; + OpenFiles openFiles; + int openFileID; + }; +} + +#endif diff --git a/netfs/fuse/fuseConfig.cpp b/netfs/fuse/fuseConfig.cpp new file mode 100644 index 0000000..168550e --- /dev/null +++ b/netfs/fuse/fuseConfig.cpp @@ -0,0 +1,29 @@ +#include "pch.hpp" +#include "fuseConfig.h" +#include + +FuseConfigPtr +FuseConfig::Load(const std::string & path) +{ + xmlDoc * doc = xmlReadFile(path.c_str(), NULL, 0); + FuseConfigPtr dc = new FuseConfig(doc->children); + xmlFreeDoc(doc); + return dc; +} + +FuseConfig::FuseConfig(xmlNodePtr conf) +{ + foreachxml(exp, xmlGetNode(conf, "exports"), "export") { + ExportPtr e = new Export(exp); + exports[e->name] = e; + } +} + +FuseConfig::Export::Export(xmlNodePtr conf) : + name(xmlGetNodeValue(conf, "name")) +{ + foreachxml(ep, xmlGetNode(conf, "endpoints"), "endpoint") { + endpoints.insert(xmlGetNodeValue(ep)); + } +} + diff --git a/netfs/fuse/fuseConfig.h b/netfs/fuse/fuseConfig.h new file mode 100644 index 0000000..f33c8f7 --- /dev/null +++ b/netfs/fuse/fuseConfig.h @@ -0,0 +1,34 @@ +#ifndef FUSECONFIG_H +#define FUSECONFIG_H + +#include +#include +#include +#include +#include +#include "xml.h" + +class FuseConfig : public virtual IntrusivePtrBase { + public: + class Export; + typedef boost::intrusive_ptr ExportPtr; + typedef std::map ExportMap; + class Export : public virtual IntrusivePtrBase { + public: + typedef std::set Endpoints; + Export(xmlNodePtr); + + std::string name; + Endpoints endpoints; + }; + + FuseConfig(xmlNodePtr); + static boost::intrusive_ptr Load(const std::string & path); + + ExportMap exports; +}; +typedef boost::intrusive_ptr FuseConfigPtr; + +#endif + + diff --git a/netfs/fuse/fuseDirs.cpp b/netfs/fuse/fuseDirs.cpp new file mode 100644 index 0000000..fac70a6 --- /dev/null +++ b/netfs/fuse/fuseDirs.cpp @@ -0,0 +1,103 @@ +#include "pch.hpp" +#include "fuse.h" +#include "misc.h" + +NetFS::FuseApp::OpenDir::OpenDir(DirectoryPrx r, const std::string & p) : + remote(r), + path(p) +{ +} + +void +NetFS::FuseApp::setProxy(OpenDirPtr od, uint64_t & fh) +{ + LOCK; + while (openDirs.find(fh = ++openDirID) != openDirs.end()) ; + openDirs.insert({ fh, od }); +} + +NetFS::FuseApp::OpenDirPtr +NetFS::FuseApp::getDirProxy(uint64_t localID) const +{ + SLOCK; + OpenDirs::const_iterator i = openDirs.find(localID); + if (i != openDirs.end()) { + return i->second; + } + throw NetFS::SystemError(EBADF); +} + +void +NetFS::FuseApp::clearDirProxy(uint64_t localID) +{ + LOCK; + openDirs.erase(localID); +} + +int +NetFS::FuseApp::opendir(const char * p, struct fuse_file_info * fi) +{ + try { + auto remote = volume->opendir(reqEnv(), p); + setProxy(new OpenDir(remote, p), fi->fh); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::releasedir(const char *, struct fuse_file_info * fi) +{ + try { + auto remote = getDirProxy(fi->fh)->remote; + remote->close(); + clearDirProxy(fi->fh); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi) +{ + try { + auto remote = getDirProxy(fi->fh)->remote; + NetFS::NameList ds = remote->readdir(); + BOOST_FOREACH(const auto & e, ds) { + filler(buf, e.c_str(), NULL, 0); + } + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::mkdir(const char * p, mode_t m) +{ + try { + volume->mkdir(reqEnv(), p, m); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::rmdir(const char * p) +{ + try { + volume->rmdir(reqEnv(), p); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp new file mode 100644 index 0000000..4a96e51 --- /dev/null +++ b/netfs/fuse/fuseFiles.cpp @@ -0,0 +1,155 @@ +#include "pch.hpp" +#include +#include +#include "fuse.h" + +NetFS::FuseApp::OpenFile::OpenFile(FilePrx r, const std::string & p, int f) : + remote(r), + path(p), + flags(f) +{ +} + +void +NetFS::FuseApp::setProxy(OpenFilePtr of, uint64_t & fh) +{ + LOCK; + while (openFiles.find(fh = ++openFileID) != openFiles.end()) ; + openFiles.insert({ fh, of }); +} + +NetFS::FuseApp::OpenFilePtr +NetFS::FuseApp::getFileProxy(uint64_t localID) const +{ + SLOCK; + OpenFiles::const_iterator i = openFiles.find(localID); + if (i != openFiles.end()) { + return i->second; + } + throw NetFS::SystemError(EBADF); +} + +void +NetFS::FuseApp::clearFileProxy(uint64_t localID) +{ + LOCK; + openFiles.erase(localID); +} + +int +NetFS::FuseApp::open(const char * p, struct fuse_file_info * fi) +{ + try { + auto remote = volume->open(reqEnv(), p, fi->flags); + setProxy(new OpenFile(remote, p, fi->flags), fi->fh); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::create(const char * p, mode_t m, struct fuse_file_info * fi) +{ + try { + auto remote = volume->create(reqEnv(), p, fi->flags, m); + setProxy(new OpenFile(remote, p, fi->flags), fi->fh); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::release(const char *, struct fuse_file_info * fi) +{ + try { + auto remote = getFileProxy(fi->fh)->remote; + remote->close(); + clearFileProxy(fi->fh); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) +{ + try { + auto remote = getFileProxy(fi->fh)->remote; + NetFS::Buffer data = remote->read(o, s); + memcpy(buf, &data.front(), data.size()); + return data.size(); + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) +{ + try { + auto remote = getFileProxy(fi->fh)->remote; + remote->write(o, s, NetFS::Buffer(buf, buf + s)); + return s; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::truncate(const char * p, off_t o) +{ + try { + volume->truncate(reqEnv(), p, o); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::ftruncate(const char *, off_t o, fuse_file_info * fi) +{ + try { + auto remote = getFileProxy(fi->fh)->remote; + remote->ftruncate(reqEnv(), o); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::fgetattr(const char *, struct stat * s, fuse_file_info * fi) +{ + try { + auto remote = getFileProxy(fi->fh)->remote; + *s << AttrSource { remote->fgetattr(reqEnv()), boost::bind(&UserEntCache::getID, &uentries, _1), boost::bind(&GroupEntCache::getID, &gentries, _1) }; + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::unlink(const char * p) +{ + try { + volume->unlink(reqEnv(), p); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + diff --git a/netfs/fuse/fuseMisc.cpp b/netfs/fuse/fuseMisc.cpp new file mode 100644 index 0000000..568cf52 --- /dev/null +++ b/netfs/fuse/fuseMisc.cpp @@ -0,0 +1,110 @@ +#include "pch.hpp" +#include "fuse.h" +#include +#include + +int +NetFS::FuseApp::access(const char * p, int a) +{ + return -volume->access(reqEnv(), p, a); +} + +int +NetFS::FuseApp::getattr(const char * p, struct stat * s) +{ + try { + *s << AttrSource { volume->getattr(reqEnv(), p), boost::bind(&UserEntCache::getID, &uentries, _1), boost::bind(&GroupEntCache::getID, &gentries, _1) }; + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::chmod(const char * p, mode_t m) +{ + try { + volume->chmod(reqEnv(), p, m); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::chown(const char * p, uid_t u, gid_t g) +{ + try { + volume->chown(reqEnv(), p, u, g); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::link(const char * p1, const char * p2) +{ + try { + volume->link(reqEnv(), p1, p2); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::symlink(const char * p1, const char * p2) +{ + try { + volume->symlink(reqEnv(), p1, p2); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::readlink(const char * p, char * p2, size_t s) +{ + try { + std::string l = volume->readlink(reqEnv(), p); + l.copy(p2, s); + p2[l.length()] = '\0'; + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::rename(const char * p1, const char * p2) +{ + try { + volume->rename(reqEnv(), p1, p2); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + +int +NetFS::FuseApp::utimens(const char * path, const struct timespec times[2]) +{ + try { + volume->utimens(reqEnv(), path, + times[0].tv_sec, times[0].tv_nsec, times[1].tv_sec, times[1].tv_nsec); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + diff --git a/netfs/fuse/fuseSystem.cpp b/netfs/fuse/fuseSystem.cpp new file mode 100644 index 0000000..0b29d86 --- /dev/null +++ b/netfs/fuse/fuseSystem.cpp @@ -0,0 +1,16 @@ +#include "pch.hpp" +#include +#include "fuse.h" + +int +NetFS::FuseApp::statfs(const char * p, struct statvfs * vfs) +{ + try { + *vfs << volume->statfs(reqEnv(), p); + return 0; + } + catch (NetFS::SystemError & e) { + return -e.syserrno; + } +} + diff --git a/netfs/fuse/pch.hpp b/netfs/fuse/pch.hpp new file mode 100644 index 0000000..7cb79ed --- /dev/null +++ b/netfs/fuse/pch.hpp @@ -0,0 +1,13 @@ +#ifdef BOOST_BUILD_PCH_ENABLED +#ifndef NETFS_FUSE_PCH +#define NETFS_FUSE_PCH + +#include "../lib/pch.hpp" +#include "../../libfusepp/fuseapp.h" +#include + +#endif +#endif + + + diff --git a/netfs/fuseConfig.cpp b/netfs/fuseConfig.cpp deleted file mode 100644 index 4030738..0000000 --- a/netfs/fuseConfig.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "pchFuse.hpp" -#include "fuseConfig.h" -#include - -FuseConfigPtr -FuseConfig::Load(const std::string & path) -{ - xmlDoc * doc = xmlReadFile(path.c_str(), NULL, 0); - FuseConfigPtr dc = new FuseConfig(doc->children); - xmlFreeDoc(doc); - return dc; -} - -FuseConfig::FuseConfig(xmlNodePtr conf) -{ - foreachxml(exp, xmlGetNode(conf, "exports"), "export") { - ExportPtr e = new Export(exp); - exports[e->name] = e; - } -} - -FuseConfig::Export::Export(xmlNodePtr conf) : - name(xmlGetNodeValue(conf, "name")) -{ - foreachxml(ep, xmlGetNode(conf, "endpoints"), "endpoint") { - endpoints.insert(xmlGetNodeValue(ep)); - } -} - diff --git a/netfs/fuseConfig.h b/netfs/fuseConfig.h deleted file mode 100644 index f33c8f7..0000000 --- a/netfs/fuseConfig.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef FUSECONFIG_H -#define FUSECONFIG_H - -#include -#include -#include -#include -#include -#include "xml.h" - -class FuseConfig : public virtual IntrusivePtrBase { - public: - class Export; - typedef boost::intrusive_ptr ExportPtr; - typedef std::map ExportMap; - class Export : public virtual IntrusivePtrBase { - public: - typedef std::set Endpoints; - Export(xmlNodePtr); - - std::string name; - Endpoints endpoints; - }; - - FuseConfig(xmlNodePtr); - static boost::intrusive_ptr Load(const std::string & path); - - ExportMap exports; -}; -typedef boost::intrusive_ptr FuseConfigPtr; - -#endif - - diff --git a/netfs/fuseDirs.cpp b/netfs/fuseDirs.cpp deleted file mode 100644 index 28b8363..0000000 --- a/netfs/fuseDirs.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "pchFuse.hpp" -#include "fuse.h" -#include "misc.h" - -NetFS::OpenDir::OpenDir(Ice::Int rid, const std::string & p) : - remoteID(rid), - path(p) -{ -} - -int -NetFS::getNextDirID() -{ - LOCK; - while (openDirs.find(++openDirID) != openDirs.end()) ; - return openDirID; -} - -Ice::Int -NetFS::getRemoteIDforDir(int localID) const -{ - LOCK; - OpenDirs::const_iterator i = openDirs.find(localID); - if (i != openDirs.end()) { - return i->second->remoteID; - } - throw NetFSComms::SystemError(EBADF); -} - -int -NetFS::opendir(const char * p, struct fuse_file_info * fi) -{ - try { - Ice::Int remoteID = filesystem->opendir(reqEnv(), p); - fi->fh = getNextDirID(); - LOCK; - openDirs[fi->fh] = new OpenDir(remoteID, p); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::releasedir(const char *, struct fuse_file_info * fi) -{ - try { - filesystem->closedir(authtok, getRemoteIDforDir(fi->fh)); - LOCK; - openDirs.erase(fi->fh); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi) -{ - try { - NetFSComms::NameList ds = filesystem->readdir(authtok, getRemoteIDforDir(fi->fh)); - for (NetFSComms::NameList::const_iterator e = ds.begin(); e != ds.end(); e++) { - filler(buf, e->c_str(), NULL, 0); - } - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::mkdir(const char * p, mode_t m) -{ - try { - filesystem->mkdir(reqEnv(), p, m); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::rmdir(const char * p) -{ - try { - filesystem->rmdir(reqEnv(), p); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - diff --git a/netfs/fuseFiles.cpp b/netfs/fuseFiles.cpp deleted file mode 100644 index 40709bd..0000000 --- a/netfs/fuseFiles.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "pchFuse.hpp" -#include -#include "fuse.h" - -NetFS::OpenFile::OpenFile(Ice::Int rid, const std::string & p, int f) : - remoteID(rid), - path(p), - flags(f) -{ -} - -int -NetFS::getNextFileID() -{ - LOCK; - while (openFiles.find(++openFileID) != openFiles.end()) ; - return openFileID; -} - -Ice::Int -NetFS::getRemoteIDforFile(int localID) const -{ - LOCK; - OpenFiles::const_iterator i = openFiles.find(localID); - if (i != openFiles.end()) { - return i->second->remoteID; - } - throw NetFSComms::SystemError(EBADF); -} - -int -NetFS::open(const char * p, struct fuse_file_info * fi) -{ - try { - Ice::Int remoteID = filesystem->open(reqEnv(), p, fi->flags); - fi->fh = getNextFileID(); - LOCK; - openFiles[fi->fh] = new OpenFile(remoteID, p, fi->flags); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::create(const char * p, mode_t m, struct fuse_file_info * fi) -{ - try { - Ice::Int remoteID = filesystem->create(reqEnv(), p, fi->flags, m); - fi->fh = getNextFileID(); - LOCK; - openFiles[fi->fh] = new OpenFile(remoteID, p, fi->flags); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::release(const char *, struct fuse_file_info * fi) -{ - try { - filesystem->close(authtok, getRemoteIDforFile(fi->fh)); - LOCK; - openFiles.erase(fi->fh); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) -{ - try { - NetFSComms::Buffer data = filesystem->read(authtok, getRemoteIDforFile(fi->fh), o, s); - for (NetFSComms::Buffer::const_iterator i = data.begin(); i != data.end(); i++, buf++) { - *buf = *i; - } - return data.size(); - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) -{ - try { - filesystem->write(authtok, getRemoteIDforFile(fi->fh), o, s, NetFSComms::Buffer(buf, buf + s)); - return s; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::truncate(const char * p, off_t o) -{ - try { - filesystem->truncate(reqEnv(), p, o); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::ftruncate(const char *, off_t o, fuse_file_info * fi) -{ - try { - filesystem->ftruncate(reqEnv(), getRemoteIDforFile(fi->fh), o); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::fgetattr(const char *, struct stat * s, fuse_file_info * fi) -{ - try { - NetFSComms::Attr a = filesystem->fgetattr(reqEnv(), getRemoteIDforFile(fi->fh)); - s->st_dev = a.dev; - s->st_ino = a.inode; - s->st_mode = a.mode; - s->st_nlink = a.links; - s->st_uid = uentries.getID(a.uid); - s->st_gid = gentries.getID(a.gid); - s->st_rdev = a.rdev; - s->st_size = a.size; - s->st_blksize = a.blockSize; - s->st_blocks = a.blocks; - s->st_atime = a.atime; - s->st_mtime = a.mtime; - s->st_ctime = a.ctime; - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::unlink(const char * p) -{ - try { - filesystem->unlink(reqEnv(), p); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - diff --git a/netfs/fuseMisc.cpp b/netfs/fuseMisc.cpp deleted file mode 100644 index 2cb79c0..0000000 --- a/netfs/fuseMisc.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "pchFuse.hpp" -#include "fuse.h" -#include - -int -NetFS::access(const char * p, int a) -{ - return -filesystem->access(reqEnv(), p, a); -} - -int -NetFS::getattr(const char * p, struct stat * s) -{ - try { - NetFSComms::Attr a = filesystem->getattr(reqEnv(), p); - s->st_dev = a.dev; - s->st_ino = a.inode; - s->st_mode = a.mode; - s->st_nlink = a.links; - s->st_uid = uentries.getID(a.uid); - s->st_gid = gentries.getID(a.gid); - s->st_rdev = a.rdev; - s->st_size = a.size; - s->st_blksize = a.blockSize; - s->st_blocks = a.blocks; - s->st_atime = a.atime; - s->st_mtime = a.mtime; - s->st_ctime = a.ctime; - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::chmod(const char * p, mode_t m) -{ - try { - filesystem->chmod(reqEnv(), p, m); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::chown(const char * p, uid_t u, gid_t g) -{ - try { - filesystem->chown(reqEnv(), p, u, g); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::link(const char * p1, const char * p2) -{ - try { - filesystem->link(reqEnv(), p1, p2); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::symlink(const char * p1, const char * p2) -{ - try { - filesystem->symlink(reqEnv(), p1, p2); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::readlink(const char * p, char * p2, size_t s) -{ - try { - std::string l = filesystem->readlink(reqEnv(), p); - l.copy(p2, s); - p2[l.length()] = '\0'; - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::rename(const char * p1, const char * p2) -{ - try { - filesystem->rename(reqEnv(), p1, p2); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - -int -NetFS::utimens(const char * path, const struct timespec times[2]) -{ - try { - filesystem->utimens(reqEnv(), path, - times[0].tv_sec, times[0].tv_nsec, times[1].tv_sec, times[1].tv_nsec); - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - diff --git a/netfs/fuseSystem.cpp b/netfs/fuseSystem.cpp deleted file mode 100644 index bcb9c79..0000000 --- a/netfs/fuseSystem.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "pchFuse.hpp" -#include "fuse.h" - -int -NetFS::statfs(const char * p, struct statvfs * vfs) -{ - try { - NetFSComms::VFS v = filesystem->statfs(reqEnv(), p); - vfs->f_bsize = v.blockSize; - vfs->f_frsize = v.fragmentSize; - vfs->f_blocks = v.blocks; - vfs->f_bfree = v.freeBlocks; - vfs->f_bavail = v.availBlocks; - vfs->f_files = v.files; - vfs->f_ffree = v.freeFiles; - vfs->f_favail = v.availFiles; - vfs->f_fsid = v.FSID; - vfs->f_flag = v.flags; - vfs->f_namemax = v.maxNameLen; - return 0; - } - catch (NetFSComms::SystemError & e) { - return -e.syserrno; - } -} - diff --git a/netfs/guidmap.h b/netfs/guidmap.h deleted file mode 100644 index b550b30..0000000 --- a/netfs/guidmap.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef GUIDMAP_H -#define GUIDMAP_H - -#include -#include -#include -#include - -class GUIDMap { - public: - class NotFound : public std::exception { }; - protected: - GUIDMap(int16_t s) : seed(int32_t(s) << 16) { - } - virtual ~GUIDMap() { - } - mutable boost::shared_mutex lock; - int32_t seed; - int16_t key; -}; -template -class GUIDMapImpl : public GUIDMap { - public: - typedef std::map Storage; - GUIDMapImpl(int16_t s) : GUIDMap(s) { - } - ~GUIDMapImpl() { - BOOST_FOREACH(typename Storage::value_type v, storage) { - ValueDeleter(v.second); - } - } - - int32_t store(const Value & value) { - boost::unique_lock l(lock); - int32_t newKey = (seed + ++key); - while (storage.find(newKey) != storage.end()) { - newKey = (seed + ++key); - } - storage.insert(std::pair(newKey, value)); - return newKey; - } - void remove(int32_t key) { - boost::unique_lock l(lock); - storage.erase(key); - } - Value get(int32_t key) const { - boost::shared_lock l(lock); - typename Storage::const_iterator i = storage.find(key); - if (i != storage.end()) { - return i->second; - } - throw NotFound(); - } - bool contains(int32_t key) const { - boost::shared_lock l(lock); - return (storage.find(key) != storage.end()); - } - - private: - Storage storage; -}; - -#endif - diff --git a/netfs/ice/Jamfile.jam b/netfs/ice/Jamfile.jam new file mode 100644 index 0000000..a227478 --- /dev/null +++ b/netfs/ice/Jamfile.jam @@ -0,0 +1,16 @@ +lib Ice ; +lib IceUtil ; +lib pthread ; + +lib netfsComms : + [ glob *.cpp *.ice ] : + Ice + IceUtil + pthread + : : + . + Ice + IceUtil + pthread + ; + diff --git a/netfs/ice/directory.ice b/netfs/ice/directory.ice new file mode 100644 index 0000000..7468503 --- /dev/null +++ b/netfs/ice/directory.ice @@ -0,0 +1,17 @@ +#ifndef _DIRECTORY +#define _DIRECTORY + +#include "exceptions.ice" +#include "types.ice" + +module NetFS { + interface Directory { + void close() throws AuthError, SystemError; + + idempotent NameList readdir() throws AuthError, SystemError; + }; + +}; + +#endif + diff --git a/netfs/ice/exceptions.ice b/netfs/ice/exceptions.ice new file mode 100644 index 0000000..9d5b970 --- /dev/null +++ b/netfs/ice/exceptions.ice @@ -0,0 +1,18 @@ +#ifndef _EXCEPTIONS +#define _EXCEPTIONS + +module NetFS { + // Exceptions + exception SystemError { + int syserrno; + }; + + exception AuthError { + }; + + exception ConfigError { + }; +}; + +#endif + diff --git a/netfs/ice/file.ice b/netfs/ice/file.ice new file mode 100644 index 0000000..bbfb2d5 --- /dev/null +++ b/netfs/ice/file.ice @@ -0,0 +1,22 @@ +#ifndef _FILES +#define _FILES + +#include "exceptions.ice" +#include "types.ice" + +module NetFS { + interface ReadOnlyFile { + void close() throws AuthError, SystemError; + + idempotent Attr fgetattr(ReqEnv env) throws AuthError, SystemError; + idempotent Buffer read(long offset, long size) throws AuthError, SystemError; + }; + + interface File extends ReadOnlyFile { + idempotent void ftruncate(ReqEnv env, long size) throws AuthError, SystemError; + idempotent void write(long offset, long size, Buffer data) throws AuthError, SystemError; + }; +}; + +#endif + diff --git a/netfs/ice/service.ice b/netfs/ice/service.ice new file mode 100644 index 0000000..d691ae2 --- /dev/null +++ b/netfs/ice/service.ice @@ -0,0 +1,16 @@ +#ifndef _SERVICE +#define _SERVICE + +#include "exceptions.ice" +#include "types.ice" +#include "volume.ice" + +module NetFS { + interface Service { + // NameList volumes() throws ConfigError; + Volume * connect(string volume, string auth) throws AuthError, ConfigError; + }; +}; + +#endif + diff --git a/netfs/ice/typeConvert.cpp b/netfs/ice/typeConvert.cpp new file mode 100644 index 0000000..538b894 --- /dev/null +++ b/netfs/ice/typeConvert.cpp @@ -0,0 +1,70 @@ +#include "typeConvert.h" + +void +operator<<(struct stat & s, const AttrSource & a) +{ + s.st_dev = a.attr.dev; + s.st_ino = a.attr.inode; + s.st_mode = a.attr.mode; + s.st_nlink = a.attr.links; + s.st_uid = a.user(a.attr.uid); + s.st_gid = a.group(a.attr.gid); + s.st_rdev = a.attr.rdev; + s.st_size = a.attr.size; + s.st_blksize = a.attr.blockSize; + s.st_blocks = a.attr.blocks; + s.st_atime = a.attr.atime; + s.st_mtime = a.attr.mtime; + s.st_ctime = a.attr.ctime; +} + +void +operator<<(struct statvfs & vfs, const NetFS::VFS & v) +{ + vfs.f_bsize = v.blockSize; + vfs.f_frsize = v.fragmentSize; + vfs.f_blocks = v.blocks; + vfs.f_bfree = v.freeBlocks; + vfs.f_bavail = v.availBlocks; + vfs.f_files = v.files; + vfs.f_ffree = v.freeFiles; + vfs.f_favail = v.availFiles; + vfs.f_fsid = v.FSID; + vfs.f_flag = v.flags; + vfs.f_namemax = v.maxNameLen; +} + +void +operator<<(NetFS::Attr & a, const struct StatSource & s) +{ + a.dev = s.stat.st_dev; + a.inode = s.stat.st_ino; + a.mode = s.stat.st_mode; + a.links = s.stat.st_nlink; + a.uid = s.user(s.stat.st_uid); + a.gid = s.group(s.stat.st_gid); + a.rdev = s.stat.st_rdev; + a.size = s.stat.st_size; + a.blockSize = s.stat.st_blksize; + a.blocks = s.stat.st_blocks; + a.atime = s.stat.st_atime; + a.mtime = s.stat.st_mtime; + a.ctime = s.stat.st_ctime; +} + +void +operator<<(NetFS::VFS & t, const struct statvfs & s) +{ + t.blockSize = s.f_bsize; + t.fragmentSize = s.f_frsize; + t.blocks = s.f_blocks; + t.freeBlocks = s.f_bfree; + t.availBlocks = s.f_bavail; + t.files = s.f_files; + t.freeFiles = s.f_ffree; + t.availFiles = s.f_favail; + t.FSID = s.f_fsid; + t.flags = s.f_flag; + t.maxNameLen = s.f_namemax; +} + diff --git a/netfs/ice/typeConvert.h b/netfs/ice/typeConvert.h new file mode 100644 index 0000000..dd56a3f --- /dev/null +++ b/netfs/ice/typeConvert.h @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +typedef boost::function UserIdLookup; +typedef boost::function GroupIdLookup; + +typedef boost::function UserNameLookup; +typedef boost::function GroupNameLookup; + +struct AttrSource { + const NetFS::Attr & attr; + const UserIdLookup & user; + const GroupIdLookup & group; +}; + +struct StatSource { + const struct stat & stat; + const UserNameLookup & user; + const GroupNameLookup & group; +}; + +void operator<<(struct stat &, const AttrSource &); +void operator<<(struct statvfs &, const NetFS::VFS &); + +void operator<<(NetFS::Attr &, const struct StatSource &); +void operator<<(NetFS::VFS &, const struct statvfs &); + diff --git a/netfs/ice/types.ice b/netfs/ice/types.ice new file mode 100644 index 0000000..74f48ce --- /dev/null +++ b/netfs/ice/types.ice @@ -0,0 +1,46 @@ +#ifndef _TYPES +#define _TYPES + +module NetFS { + struct VFS { + long blockSize; + long fragmentSize; + long blocks; + long freeBlocks; + long availBlocks; + long files; + long freeFiles; + long availFiles; + long FSID; + long flags; + long maxNameLen; + }; + + struct Attr { + int dev; + long inode; + int mode; + int links; + string uid; + string gid; + int rdev; + long size; + long blockSize; + long blocks; + long atime; + long mtime; + long ctime; + }; + + struct ReqEnv { + string user; + string grp; + }; + + sequence Buffer; + + sequence NameList; +}; + +#endif + diff --git a/netfs/ice/volume.ice b/netfs/ice/volume.ice new file mode 100644 index 0000000..7b0e3e0 --- /dev/null +++ b/netfs/ice/volume.ice @@ -0,0 +1,42 @@ +#ifndef _VOLUME +#define _VOLUME + +#include "exceptions.ice" +#include "types.ice" +#include "file.ice" +#include "directory.ice" + +module NetFS { + interface ReadOnlyVolume { + void disconnect() throws AuthError; + + ReadOnlyFile * openReadOnly(ReqEnv env, string path, int flags) throws AuthError, SystemError; + Directory * opendir(ReqEnv env, string path) throws AuthError, SystemError; + + idempotent VFS statfs(ReqEnv env, string path) throws AuthError, SystemError; + idempotent int access(ReqEnv env, string path, int mode) throws AuthError, SystemError; + idempotent Attr getattr(ReqEnv env, string path) throws AuthError, SystemError; + idempotent string readlink(ReqEnv env, string path) throws AuthError, SystemError; + }; + + interface Volume extends ReadOnlyVolume { + File * open(ReqEnv env, string path, int flags) throws AuthError, SystemError; + File * create(ReqEnv env, string path, int flags, int mode) throws AuthError, SystemError; + + idempotent void truncate(ReqEnv env, string path, long size) throws AuthError, SystemError; + void unlink(ReqEnv env, string path) throws AuthError, SystemError; + + void mkdir(ReqEnv env, string path, int mode) throws AuthError, SystemError; + void rmdir(ReqEnv env, string path) throws AuthError, SystemError; + + void symlink(ReqEnv env, string path1, string path2) throws AuthError, SystemError; + void link(ReqEnv env, string path1, string path2) throws AuthError, SystemError; + void rename(ReqEnv env, string from, string to) throws AuthError, SystemError; + idempotent void chmod(ReqEnv env, string path, int mode) throws AuthError, SystemError; + idempotent void chown(ReqEnv env, string path, int uid, int gid) throws AuthError, SystemError; + idempotent void utimens(ReqEnv env, string path, long atime, long atimens, long mtime, long mtimens) throws AuthError, SystemError; + }; +}; + +#endif + diff --git a/netfs/lib/Jamfile.jam b/netfs/lib/Jamfile.jam new file mode 100644 index 0000000..bf6dd1a --- /dev/null +++ b/netfs/lib/Jamfile.jam @@ -0,0 +1,21 @@ +cpp-pch pch : pch.hpp : + _FILE_OFFSET_BITS=64 + ../../libmisc + ; + +lib netfsCommon : + pch + [ glob *.cpp ] + ../../libmisc/xml.cpp : + _FILE_OFFSET_BITS=64 + ../../libmisc + ..//boost_system + ..//boost_thread + ..//libxml2 + ../ice//netfsComms + ../ice//netfsComms + : : + . + ../../libmisc + ; + diff --git a/netfs/lib/entCache.cpp b/netfs/lib/entCache.cpp new file mode 100644 index 0000000..7dee1e6 --- /dev/null +++ b/netfs/lib/entCache.cpp @@ -0,0 +1,82 @@ +#include "pch.hpp" +#include "entCache.h" +#include + +#define LOCK boost::unique_lock _lck(lock) +#define SLOCK boost::shared_lock _lck(lock) + +template +EntCache::EntCache() +{ +} + +template +EntCache::~EntCache() +{ +} + +template +const id_t & +EntCache::getID(const name_t & u) const +{ + { + SLOCK; + typename IDs::right_map::const_iterator cu = idcache.right.find(u); + if (cu != idcache.right.end()) { + return cu->second; + } + } + fillCache(); + SLOCK; + typename IDs::right_map::const_iterator cu = idcache.right.find(u); + if (cu != idcache.right.end()) { + return cu->second; + } + throw NetFS::SystemError(EPERM); +} + +template +const name_t & +EntCache::getName(const id_t & u) const +{ + { + SLOCK; + typename IDs::left_map::const_iterator cu = idcache.left.find(u); + if (cu != idcache.left.end()) { + return cu->second; + } + } + fillCache(); + SLOCK; + typename IDs::left_map::const_iterator cu = idcache.left.find(u); + if (cu != idcache.left.end()) { + return cu->second; + } + throw NetFS::SystemError(EPERM); +} + +template class EntCache; +void +UserEntCache::fillCache() const +{ + LOCK; + setpwent(); + idcache.clear(); + while (struct passwd * pwp = getpwent()) { + idcache.insert(boost::bimap::value_type(pwp->pw_uid, pwp->pw_name)); + } + endpwent(); +} + +void +GroupEntCache::fillCache() const +{ + LOCK; + setgrent(); + idcache.clear(); + while (struct group * grpp = getgrent()) { + idcache.insert(boost::bimap::value_type(grpp->gr_gid, grpp->gr_name)); + } + endgrent(); +} + diff --git a/netfs/lib/entCache.h b/netfs/lib/entCache.h new file mode 100644 index 0000000..c16cd0b --- /dev/null +++ b/netfs/lib/entCache.h @@ -0,0 +1,37 @@ +#ifndef ENTCACHE_H +#define ENTCACHE_H + +#include +#include +#include +#include +#include + +template +class EntCache { + public: + EntCache(); + virtual ~EntCache(); + + const id_t & getID(const name_t & ) const; + const name_t & getName(const id_t &) const; + + protected: + virtual void fillCache() const = 0; + typedef boost::bimap IDs; + mutable IDs idcache; + mutable boost::shared_mutex lock; +}; + +class UserEntCache : public EntCache { + private: + void fillCache() const; +}; + +class GroupEntCache : public EntCache { + private: + void fillCache() const; +}; + +#endif + diff --git a/netfs/lib/guidmap.h b/netfs/lib/guidmap.h new file mode 100644 index 0000000..b550b30 --- /dev/null +++ b/netfs/lib/guidmap.h @@ -0,0 +1,64 @@ +#ifndef GUIDMAP_H +#define GUIDMAP_H + +#include +#include +#include +#include + +class GUIDMap { + public: + class NotFound : public std::exception { }; + protected: + GUIDMap(int16_t s) : seed(int32_t(s) << 16) { + } + virtual ~GUIDMap() { + } + mutable boost::shared_mutex lock; + int32_t seed; + int16_t key; +}; +template +class GUIDMapImpl : public GUIDMap { + public: + typedef std::map Storage; + GUIDMapImpl(int16_t s) : GUIDMap(s) { + } + ~GUIDMapImpl() { + BOOST_FOREACH(typename Storage::value_type v, storage) { + ValueDeleter(v.second); + } + } + + int32_t store(const Value & value) { + boost::unique_lock l(lock); + int32_t newKey = (seed + ++key); + while (storage.find(newKey) != storage.end()) { + newKey = (seed + ++key); + } + storage.insert(std::pair(newKey, value)); + return newKey; + } + void remove(int32_t key) { + boost::unique_lock l(lock); + storage.erase(key); + } + Value get(int32_t key) const { + boost::shared_lock l(lock); + typename Storage::const_iterator i = storage.find(key); + if (i != storage.end()) { + return i->second; + } + throw NotFound(); + } + bool contains(int32_t key) const { + boost::shared_lock l(lock); + return (storage.find(key) != storage.end()); + } + + private: + Storage storage; +}; + +#endif + diff --git a/netfs/lib/pch.hpp b/netfs/lib/pch.hpp new file mode 100644 index 0000000..e5ee5d7 --- /dev/null +++ b/netfs/lib/pch.hpp @@ -0,0 +1,21 @@ +#ifdef BOOST_BUILD_PCH_ENABLED +#ifndef NETFS_PCH +#define NETFS_PCH + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif +#endif + diff --git a/netfs/netfsComms.ice b/netfs/netfsComms.ice deleted file mode 100644 index 44f983a..0000000 --- a/netfs/netfsComms.ice +++ /dev/null @@ -1,85 +0,0 @@ -module NetFSComms { - // Exceptions - exception SystemError { - int syserrno; - }; - exception AuthError { - }; - exception ConfigError { - }; - // Types - struct VFS { - long blockSize; - long fragmentSize; - long blocks; - long freeBlocks; - long availBlocks; - long files; - long freeFiles; - long availFiles; - long FSID; - long flags; - long maxNameLen; - }; - struct Attr { - int dev; - long inode; - int mode; - int links; - string uid; - string gid; - int rdev; - long size; - long blockSize; - long blocks; - long atime; - long mtime; - long ctime; - }; - struct ReqEnv { - string user; - string grp; - long tok; - }; - sequence Buffer; - sequence NameList; - // Interfaces - interface FileSystem { - idempotent void truncate(ReqEnv env, string path, long size) throws AuthError, SystemError; - idempotent void ftruncate(ReqEnv env, int id, long size) throws AuthError, SystemError; - idempotent Attr fgetattr(ReqEnv env, int id) throws AuthError, SystemError; - - void unlink(ReqEnv env, string path) throws AuthError, SystemError; - - int open(ReqEnv env, string path, int flags) throws AuthError, SystemError; - int create(ReqEnv env, string path, int flags, int mode) throws AuthError, SystemError; - void close(long tok, int id) throws AuthError, SystemError; - - idempotent Buffer read(long tok, int id, long offset, long size) throws AuthError, SystemError; - idempotent void write(long tok, int id, long offset, long size, Buffer data) throws AuthError, SystemError; - - int opendir(ReqEnv env, string path) throws AuthError, SystemError; - void closedir(long tok, int id) throws AuthError, SystemError; - idempotent NameList readdir(long tok, int id) throws AuthError, SystemError; - - void mkdir(ReqEnv env, string path, int mode) throws AuthError, SystemError; - void rmdir(ReqEnv env, string path) throws AuthError, SystemError; - - idempotent VFS statfs(ReqEnv env, string path) throws AuthError, SystemError; - - idempotent int access(ReqEnv env, string path, int mode) throws AuthError, SystemError; - idempotent Attr getattr(ReqEnv env, string path) throws AuthError, SystemError; - void symlink(ReqEnv env, string path1, string path2) throws AuthError, SystemError; - void link(ReqEnv env, string path1, string path2) throws AuthError, SystemError; - void rename(ReqEnv env, string from, string to) throws AuthError, SystemError; - idempotent string readlink(ReqEnv env, string path) throws AuthError, SystemError; - idempotent void chmod(ReqEnv env, string path, int mode) throws AuthError, SystemError; - idempotent void chown(ReqEnv env, string path, int uid, int gid) throws AuthError, SystemError; - idempotent void utimens(ReqEnv env, string path, long atime, long atimens, long mtime, long mtimens) throws AuthError, SystemError; - }; - interface Service { - long connect(string volume, string auth) throws AuthError, ConfigError; - void disconnect(long tok) throws AuthError; - }; -}; - diff --git a/netfs/pchCommon.hpp b/netfs/pchCommon.hpp deleted file mode 100644 index 5d4270b..0000000 --- a/netfs/pchCommon.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef BOOST_BUILD_PCH_ENABLED -#ifndef NETFS_PCH -#define NETFS_PCH - -#include -#include -#include -#include -#include -#include -#include "entCache.h" -#include -#include "guidmap.h" -#include -#include -#include -#include "netfsComms.h" -#include -#include -#include -#include "xml.h" - -#endif -#endif - diff --git a/netfs/pchDaemon.hpp b/netfs/pchDaemon.hpp deleted file mode 100644 index cece5cb..0000000 --- a/netfs/pchDaemon.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifdef BOOST_BUILD_PCH_ENABLED -#ifndef NETFS_DAEMON_PCH -#define NETFS_DAEMON_PCH - -#include "pchCommon.hpp" -#include -#include "daemon.h" -#include - -#endif -#endif - - diff --git a/netfs/pchFuse.hpp b/netfs/pchFuse.hpp deleted file mode 100644 index d563b57..0000000 --- a/netfs/pchFuse.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef BOOST_BUILD_PCH_ENABLED -#ifndef NETFS_FUSE_PCH -#define NETFS_FUSE_PCH - -#include "pchCommon.hpp" -#include "fuseapp.h" -#include "fuseConfig.h" -#include - -#endif -#endif - - - -- cgit v1.2.3