diff options
author | randomdan <randomdan@localhost> | 2014-03-20 21:07:25 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2014-03-20 21:07:25 +0000 |
commit | 5780e0d6b8fb5c4269d224b865365a1c59afd38b (patch) | |
tree | 2fdef12c4a975d2b412b78d75654db6fab471379 | |
parent | Fix slice scanner and split .ice files back into logical blocks (diff) | |
download | netfs-5780e0d6b8fb5c4269d224b865365a1c59afd38b.tar.bz2 netfs-5780e0d6b8fb5c4269d224b865365a1c59afd38b.tar.xz netfs-5780e0d6b8fb5c4269d224b865365a1c59afd38b.zip |
Modularized interfaces for netfs
58 files changed, 1628 insertions, 1652 deletions
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 : : <name>IceBox ; lib pthread : : <name>pthread ; lib fuse : : <name>fuse ; -lib netfsComms : - netfsComms.ice : - <library>Ice - <library>IceUtil - <library>pthread - ; - -lib netfsCommon : - pchCommon - entCache.cpp ../libmisc/xml.cpp : - <define>_FILE_OFFSET_BITS=64 - <include>../libmisc - <library>libxml2 - <library>netfsComms - <library>boost_thread - <library>boost_system - <library>Ice - <library>IceUtil - ; - -cpp-pch pchFuse : pchCommon pchFuse.hpp : - <define>_FILE_OFFSET_BITS=64 - <include>../libmisc - <include>../libfusepp - <implicit-dependency>netfsComms - <library>netfsComms - <library>boost_thread - <library>fuse - <library>Ice - <library>libxml2 - ; - -cpp-pch pchDaemon : pchCommon pchDaemon.hpp : - <define>_FILE_OFFSET_BITS=64 - <include>../libmisc - <implicit-dependency>netfsComms - <library>netfsComms - <library>boost_thread - <library>Ice - <library>libxml2 - ; - -cpp-pch pchCommon : pchCommon.hpp : - <define>_FILE_OFFSET_BITS=64 - <include>../libmisc - <implicit-dependency>netfsComms - <library>netfsComms - <library>boost_thread - <library>fuse - <library>Ice - <library>libxml2 - ; - -exe netfs : - pchFuse - [ glob fuse*.cpp ] - [ glob ../libfusepp/fuse*.cpp ] - : - <define>_FILE_OFFSET_BITS=64 - <include>../libmisc - <include>../libfusepp - <implicit-dependency>netfsComms - <library>netfsComms - <library>netfsCommon - <library>boost_thread - <library>boost_system - <library>fuse - <library>Ice - <library>IceUtil - <library>pthread - <library>libxml2 - ; - -lib netfsd : - pchDaemon - [ glob daemon*.cpp ] - : - <define>_FILE_OFFSET_BITS=64 - <include>../libmisc - <implicit-dependency>netfsComms - <library>netfsComms - <library>netfsCommon - <library>boost_random - <library>boost_thread - <library>boost_filesystem - <library>boost_system - <library>Ice - <library>IceUtil - <library>IceBox - <library>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 <Ice/Ice.h> -#include <boost/foreach.hpp> -#include <boost/crc.hpp> -#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<boost::mutex> 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<boost::mutex> 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<boost::mutex> 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<DaemonGlobalState::Session> 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 <Ice/Ice.h> -#include <IceBox/IceBox.h> -#include <boost/thread/locks.hpp> -#include <boost/thread/mutex.hpp> -#include <boost/tuple/tuple.hpp> -#include <boost/nondet_random.hpp> -#include "daemonConfig.h" -#include "netfsComms.h" -#include "entCache.h" -#include "guidmap.h" -#include <dirent.h> - -class DaemonGlobalState : public IntrusivePtrBase { - public: - DaemonGlobalState(DaemonConfigPtr c); - class Session : public IntrusivePtrBase { - public: - Session(int16_t hostseed, DaemonConfig::ExportPtr exportCfg); - ~Session(); - - GUIDMapImpl<DIR*, closedir> dirs; - GUIDMapImpl<int, close> files; - - boost::mutex lock; - DaemonConfig::ExportPtr exportCfg; - }; - - typedef boost::intrusive_ptr<Session> SP; - typedef boost::tuple<Ice::Long, SP> 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<Ice::Long, SP> Sessions; - Sessions sessions; - mutable boost::mutex lock; - boost::random_device random; -}; -typedef boost::intrusive_ptr<DaemonGlobalState> 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<DaemonGlobalState::Session> ptr, bool lock); - ~SessionPtr(); - - DaemonGlobalState::Session * operator->() const; - - void lock() const; - void unlock() const; - private: - const boost::intrusive_ptr<DaemonGlobalState::Session> 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 : + <define>_FILE_OFFSET_BITS=64 + <include>../../libmisc + <implicit-dependency>../ice//netfsComms + <library>../ice//netfsComms + <library>../lib//netfsCommon + <library>..//boost_thread + <library>..//Ice + <library>..//libxml2 + ; + +lib netfsd : + pch + [ glob *.cpp ] + : + <define>_FILE_OFFSET_BITS=64 + <include>../libmisc + <implicit-dependency>../ice//netfsComms + <library>../ice//netfsComms + <library>../lib//netfsCommon + <library>..//boost_random + <library>..//boost_thread + <library>..//boost_filesystem + <library>..//boost_system + <library>..//Ice + <library>..//IceUtil + <library>..//IceBox + <library>..//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 <Ice/Ice.h> +#include <boost/foreach.hpp> +#include <boost/crc.hpp> +#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 <Ice/Ice.h> +#include <IceBox/IceBox.h> +#include <boost/thread/locks.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/tuple/tuple.hpp> +#include <boost/nondet_random.hpp> +#include "daemonConfig.h" +#include <types.h> +#include <volume.h> +#include <entCache.h> +#include "guidmap.h" +#include <dirent.h> + +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/daemonConfig.cpp b/netfs/daemon/daemonConfig.cpp index 0d05c44..7f171eb 100644 --- a/netfs/daemonConfig.cpp +++ b/netfs/daemon/daemonConfig.cpp @@ -1,4 +1,4 @@ -#include "pchDaemon.hpp" +#include "pch.hpp" #include "daemonConfig.h" #include <string.h> diff --git a/netfs/daemonConfig.h b/netfs/daemon/daemonConfig.h index f27aedb..f27aedb 100644 --- a/netfs/daemonConfig.h +++ b/netfs/daemon/daemonConfig.h 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 <dirent.h> +#include <errno.h> +#include <map> +#include <sys/stat.h> +#include <sys/types.h> +#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 <directory.h> +#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 <errno.h> +#include <map> +#include <fcntl.h> +#include <typeConvert.h> +#include <sys/stat.h> +#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 <file.h> +#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<boost::mutex> 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 <service.h> + +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 <errno.h> +#include <map> +#include <unistd.h> +#include <sys/stat.h> +#include <limits.h> +#include <fcntl.h> +#include <typeConvert.h> +#include "daemonVolume.h" +#include "daemonFile.h" +#include "daemonDirectory.h" + +extern std::map<Ice::Int, int> 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 <volume.h> +#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/pchDaemon.hpp b/netfs/daemon/pch.hpp index cece5cb..3229655 100644 --- a/netfs/pchDaemon.hpp +++ b/netfs/daemon/pch.hpp @@ -2,7 +2,7 @@ #ifndef NETFS_DAEMON_PCH #define NETFS_DAEMON_PCH -#include "pchCommon.hpp" +#include "../lib/pch.hpp" #include <boost/filesystem/path.hpp> #include "daemon.h" #include <IceBox/IceBox.h> 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 <dirent.h> -#include <errno.h> -#include <map> -#include <sys/stat.h> -#include <sys/types.h> -#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 <dirent.h> - -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 <errno.h> -#include <map> -#include <fcntl.h> -#include <sys/stat.h> -#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 <errno.h> -#include <map> -#include <unistd.h> -#include <sys/stat.h> -#include <limits.h> -#include <fcntl.h> -#include "daemonFileSystem.h" - -extern std::map<Ice::Int, int> 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 <errno.h> -#include <sys/statvfs.h> -#include <sys/vfs.h> -#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/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 <string.h> -#include <boost/foreach.hpp> -#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<const NetFSComms::AuthError *>(&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 <boost/thread/mutex.hpp> -#include <Ice/Ice.h> -#include "netfsComms.h" -#include "fuseapp.h" -#include "fuseConfig.h" -#include "entCache.h" -#include "intrusivePtrBase.h" - -#define LOCK boost::unique_lock<boost::mutex> _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<OpenDir> OpenDirPtr; - typedef std::map<int, OpenDirPtr> 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<OpenFile> OpenFilePtr; - typedef std::map<int, OpenFilePtr> 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 : + <define>_FILE_OFFSET_BITS=64 + <include>../../libmisc + <include>../../libfusepp + <implicit-dependency>../ice//netfsComms + <library>../ice//netfsComms + <library>..//boost_thread + <library>..//fuse + <library>..//Ice + <library>..//libxml2 + ; + + +exe netfs : + pch + [ glob *.cpp ] + [ glob ../../libfusepp/fuse*.cpp ] + : + <define>_FILE_OFFSET_BITS=64 + <include>../../libmisc + <include>../../libfusepp + <implicit-dependency>../ice//netfsComms + <library>../ice//netfsComms + <library>../lib//netfsCommon + <library>..//boost_thread + <library>..//boost_system + <library>..//fuse + <library>..//Ice + <library>..//IceUtil + <library>..//pthread + <library>..//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 <string.h> +#include <boost/foreach.hpp> +#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<const Ice::ObjectNotExistException *>(&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 <boost/thread/shared_mutex.hpp> +#include <Ice/Ice.h> +#include <service.h> +#include "fuseapp.h" +#include "fuseConfig.h" +#include "entCache.h" +#include "intrusivePtrBase.h" + +#define LOCK boost::unique_lock<boost::shared_mutex> _lck(_lock) +#define SLOCK boost::shared_lock<boost::shared_mutex> _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<OpenDir> OpenDirPtr; + typedef std::map<int, OpenDirPtr> 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<OpenFile> OpenFilePtr; + typedef std::map<int, OpenFilePtr> 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/fuseConfig.cpp b/netfs/fuse/fuseConfig.cpp index 4030738..168550e 100644 --- a/netfs/fuseConfig.cpp +++ b/netfs/fuse/fuseConfig.cpp @@ -1,4 +1,4 @@ -#include "pchFuse.hpp" +#include "pch.hpp" #include "fuseConfig.h" #include <string.h> diff --git a/netfs/fuseConfig.h b/netfs/fuse/fuseConfig.h index f33c8f7..f33c8f7 100644 --- a/netfs/fuseConfig.h +++ b/netfs/fuse/fuseConfig.h 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 <string.h> +#include <typeConvert.h> +#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 <string.h> +#include <typeConvert.h> + +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 <typeConvert.h> +#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/pchFuse.hpp b/netfs/fuse/pch.hpp index d563b57..7cb79ed 100644 --- a/netfs/pchFuse.hpp +++ b/netfs/fuse/pch.hpp @@ -2,9 +2,8 @@ #ifndef NETFS_FUSE_PCH #define NETFS_FUSE_PCH -#include "pchCommon.hpp" -#include "fuseapp.h" -#include "fuseConfig.h" +#include "../lib/pch.hpp" +#include "../../libfusepp/fuseapp.h" #include <fuse.h> #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 <string.h> -#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 <string.h> - -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/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 ] : + <library>Ice + <library>IceUtil + <library>pthread + : : + <include>. + <library>Ice + <library>IceUtil + <library>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 <types.h> +#include <sys/stat.h> +#include <sys/statvfs.h> +#include <boost/function.hpp> + +typedef boost::function<uid_t(const std::string &)> UserIdLookup; +typedef boost::function<gid_t(const std::string &)> GroupIdLookup; + +typedef boost::function<std::string(uid_t)> UserNameLookup; +typedef boost::function<std::string(gid_t)> 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<byte> Buffer; + + sequence<string> 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 : + <define>_FILE_OFFSET_BITS=64 + <include>../../libmisc + ; + +lib netfsCommon : + pch + [ glob *.cpp ] + ../../libmisc/xml.cpp : + <define>_FILE_OFFSET_BITS=64 + <include>../../libmisc + <library>..//boost_system + <library>..//boost_thread + <library>..//libxml2 + <library>../ice//netfsComms + <implicit-dependency>../ice//netfsComms + : : + <include>. + <include>../../libmisc + ; + diff --git a/netfs/entCache.cpp b/netfs/lib/entCache.cpp index d79de29..7dee1e6 100644 --- a/netfs/entCache.cpp +++ b/netfs/lib/entCache.cpp @@ -1,6 +1,6 @@ -#include "pchCommon.hpp" +#include "pch.hpp" #include "entCache.h" -#include <netfsComms.h> +#include <exceptions.h> #define LOCK boost::unique_lock<boost::shared_mutex> _lck(lock) #define SLOCK boost::shared_lock<boost::shared_mutex> _lck(lock) @@ -32,7 +32,7 @@ EntCache<id_t, name_t>::getID(const name_t & u) const if (cu != idcache.right.end()) { return cu->second; } - throw NetFSComms::SystemError(EPERM); + throw NetFS::SystemError(EPERM); } template<class id_t, class name_t> @@ -52,7 +52,7 @@ EntCache<id_t, name_t>::getName(const id_t & u) const if (cu != idcache.left.end()) { return cu->second; } - throw NetFSComms::SystemError(EPERM); + throw NetFS::SystemError(EPERM); } template class EntCache<uid_t, std::string>; @@ -80,5 +80,3 @@ GroupEntCache::fillCache() const endgrent(); } - - diff --git a/netfs/entCache.h b/netfs/lib/entCache.h index c16cd0b..c16cd0b 100644 --- a/netfs/entCache.h +++ b/netfs/lib/entCache.h diff --git a/netfs/guidmap.h b/netfs/lib/guidmap.h index b550b30..b550b30 100644 --- a/netfs/guidmap.h +++ b/netfs/lib/guidmap.h diff --git a/netfs/pchCommon.hpp b/netfs/lib/pch.hpp index 5d4270b..e5ee5d7 100644 --- a/netfs/pchCommon.hpp +++ b/netfs/lib/pch.hpp @@ -8,17 +8,13 @@ #include <boost/thread/mutex.hpp> #include <boost/thread/shared_mutex.hpp> #include <boost/tuple/tuple.hpp> -#include "entCache.h" #include <exception> -#include "guidmap.h" #include <Ice/Ice.h> #include <intrusivePtrBase.h> #include <map> -#include "netfsComms.h" #include <set> #include <string> #include <typeinfo> -#include "xml.h" #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<byte> Buffer; - sequence<string> 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; - }; -}; - |