From ec21d961629bd64eea694ccb3220c2a4591ff84c Mon Sep 17 00:00:00 2001 From: randomdan Date: Wed, 20 Oct 2010 23:31:13 +0000 Subject: Commit WTD basic FS works --- netfs/Jamfile.jam | 13 +++-- netfs/client.xml | 18 +++++++ netfs/daemon.cpp | 126 ++++++++++++++++++++++++++++++++++++------------ netfs/daemon.h | 57 ++++++++++++++++++++-- netfs/daemon.xml | 18 +++---- netfs/daemonConfig.cpp | 18 +++++-- netfs/daemonConfig.h | 4 +- netfs/daemonDirs.cpp | 38 ++++++++------- netfs/daemonDirs.h | 12 ++--- netfs/daemonFiles.cpp | 68 ++++++++++++++------------ netfs/daemonFiles.h | 20 ++++---- netfs/daemonMisc.cpp | 34 ++++++++----- netfs/daemonMisc.h | 16 +++--- netfs/daemonModule.cpp | 3 +- netfs/daemonModule.h | 2 + netfs/daemonService.cpp | 20 ++++++++ netfs/daemonService.h | 17 +++++++ netfs/daemonSystem.cpp | 5 +- netfs/daemonSystem.h | 2 +- netfs/etc/daemon.xml | 16 ++++++ netfs/fuse.cpp | 49 +++++++++++++++++-- netfs/fuse.h | 8 +++ netfs/fuseConfig.cpp | 28 +++++++++++ netfs/fuseConfig.h | 34 +++++++++++++ netfs/fuseDirs.cpp | 10 ++-- netfs/fuseFiles.cpp | 18 +++---- netfs/fuseMisc.cpp | 16 +++--- netfs/fuseSystem.cpp | 2 +- netfs/fuseapp.cpp | 2 + netfs/netfsComms.ice | 52 +++++++++++--------- 30 files changed, 530 insertions(+), 196 deletions(-) create mode 100644 netfs/client.xml create mode 100644 netfs/daemonService.cpp create mode 100644 netfs/daemonService.h create mode 100644 netfs/etc/daemon.xml create mode 100644 netfs/fuseConfig.cpp create mode 100644 netfs/fuseConfig.h diff --git a/netfs/Jamfile.jam b/netfs/Jamfile.jam index 6868fdb..6be0b63 100644 --- a/netfs/Jamfile.jam +++ b/netfs/Jamfile.jam @@ -1,4 +1,5 @@ using gcc ; +import package ; import type : register ; import generators : register-standard ; @@ -11,6 +12,7 @@ alias fuse : : : : lib boost_regex : : boost_regex ; lib boost_filesystem : : boost_filesystem ; +lib boost_random : : boost_random ; lib Ice : : Ice ; import type ; @@ -78,25 +80,26 @@ lib netfsComms : ; exe netfs : - libxmlpp [ glob fuse*.cpp ] : ../libmisc//misc netfsComms netfsComms - boost_regex fuse Ice ; -exe netfsd : - libxmlpp +lib netfsd : [ glob daemon*.cpp ] : ../libmisc//misc netfsComms netfsComms - boost_regex + boost_random boost_filesystem Ice ; + +explicit install ; +package.install install : : netfs : netfsd ; + diff --git a/netfs/client.xml b/netfs/client.xml new file mode 100644 index 0000000..9eab8fc --- /dev/null +++ b/netfs/client.xml @@ -0,0 +1,18 @@ + + + + + portage + + tcp -p 4000 -h localhost + + + + store + + tcp -p 4000 -h defiant + + + + + diff --git a/netfs/daemon.cpp b/netfs/daemon.cpp index 65388e5..30ff806 100644 --- a/netfs/daemon.cpp +++ b/netfs/daemon.cpp @@ -1,45 +1,111 @@ #include +#include #include "daemon.h" #include "daemonConfig.h" #include "daemonDirs.h" #include "daemonFiles.h" #include "daemonMisc.h" #include "daemonSystem.h" +#include "daemonService.h" -int main(int argc, char* argv[]) -{ - DaemonConfigPtr dc = DaemonConfig::Load("daemon.xml"); - DaemonGlobalStatePtr dgs = new DaemonGlobalState(dc); - - Ice::CommunicatorPtr ic; - try { - ic = Ice::initialize(argc, argv); - Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints("NetFSDaemonAdapter", "default -p 10000"); - adapter->add(new FileServer(dgs), ic->stringToIdentity("Files")); - adapter->add(new DirsServer(dgs), ic->stringToIdentity("Dirs")); - adapter->add(new MiscServer(dgs), ic->stringToIdentity("Misc")); - adapter->add(new SystemServer(dgs), ic->stringToIdentity("System")); - adapter->activate(); - ic->waitForShutdown(); - } - catch (const Ice::Exception& e) { - std::cerr << e << std::endl; - return 1; +// 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); + + adapter = ic->createObjectAdapterWithEndpoints(name, dc->self->iceEndpoint); + adapter->add(new FileServer(dgs), ic->stringToIdentity("Files")); + adapter->add(new DirsServer(dgs), ic->stringToIdentity("Dirs")); + adapter->add(new MiscServer(dgs), ic->stringToIdentity("Misc")); + adapter->add(new SystemServer(dgs), ic->stringToIdentity("System")); + adapter->add(new ServiceServer(dgs), ic->stringToIdentity("Service")); + adapter->activate(); +} + +void +NetFSDaemon::stop() +{ + adapter->deactivate(); +} + +extern "C" { + IceBox::Service * + createNetFSDaemon(Ice::CommunicatorPtr communicator) + { + return new NetFSDaemon(); } - catch (const char* msg) { - std::cerr << msg << std::endl; - return 1; +} + +DaemonGlobalState::DaemonGlobalState(DaemonConfigPtr c) : + config(c) +{ +} + +DaemonGlobalState::NSP +DaemonGlobalState::newSession(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(); } - if (ic) { - try { - ic->destroy(); - } - catch (const Ice::Exception& e) { - std::cerr << e << std::endl; - return 1; + SP s = new Session(e->second); + while (Ice::Long tok = random()) { + if (sessions.find(tok) == sessions.end()) { + sessions[tok] = s; + return NSP(tok, s); } } + throw NetFSComms::AuthError(); +} - return 0; +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(DaemonConfig::ExportPtr ex) : + dirNo(0), + fileNo(0), + exportCfg(ex) +{ +} + +DaemonGlobalState::Session::~Session() +{ + BOOST_FOREACH(Dirs::value_type d, dirs) { + closedir(d.second); + } + BOOST_FOREACH(Files::value_type f, files) { + close(f.second); + } +} + +SessionPtr::SessionPtr(boost::intrusive_ptr s) : + ptr(s), + lg(s->lock) +{ +} + +DaemonGlobalState::Session * +SessionPtr::operator->() +{ + return ptr.get(); } diff --git a/netfs/daemon.h b/netfs/daemon.h index 7dd6d63..892a1f7 100644 --- a/netfs/daemon.h +++ b/netfs/daemon.h @@ -1,18 +1,67 @@ #ifndef DAEMON_H #define DAEMON_H +#include +#include +#include +#include +#include +#include #include "daemonConfig.h" +#include class DaemonGlobalState : public IntrusivePtrBase { public: - DaemonGlobalState(DaemonConfigPtr c) : - config(c) - { - } + DaemonGlobalState(DaemonConfigPtr c); + class Session : public IntrusivePtrBase { + public: + Session(DaemonConfig::ExportPtr exportCfg); + ~Session(); + + int dirNo; + typedef std::map Dirs; + Dirs dirs; + int fileNo; + typedef std::map Files; + Files files; + + boost::mutex lock; + DaemonConfig::ExportPtr exportCfg; + }; + + typedef boost::intrusive_ptr SP; + typedef boost::tuple NSP; + NSP newSession(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); + DaemonGlobalState::Session * operator->(); + private: + boost::intrusive_ptr ptr; + boost::lock_guard lg; +}; + #endif diff --git a/netfs/daemon.xml b/netfs/daemon.xml index 72d4ad6..5e1ef0c 100644 --- a/netfs/daemon.xml +++ b/netfs/daemon.xml @@ -1,22 +1,22 @@ + - true - 4000 - akira.random.lan + tcp -p 4000 + akira - 4000 - vmware2.random.lan + tcp -p 4000 + riogrande - test - /tmp/netfsTest + portage + /usr/portage - akira.random.lan - vmware2.random.lan + akira + vmware2 diff --git a/netfs/daemonConfig.cpp b/netfs/daemonConfig.cpp index ad3621d..f0810f7 100644 --- a/netfs/daemonConfig.cpp +++ b/netfs/daemonConfig.cpp @@ -1,10 +1,18 @@ #include "daemonConfig.h" #include +std::string +myHostname() +{ + char buf[128]; + gethostname(buf, sizeof(buf)); + return buf; +} + DaemonConfigPtr -DaemonConfig::Load(const char * path) +DaemonConfig::Load(const std::string & path) { - xmlDoc * doc = xmlReadFile(path, NULL, 0); + xmlDoc * doc = xmlReadFile(path.c_str(), NULL, 0); DaemonConfigPtr dc = new DaemonConfig(doc->children); xmlFreeDoc(doc); return dc; @@ -12,7 +20,7 @@ DaemonConfig::Load(const char * path) DaemonConfig::DaemonConfig(xmlNodePtr conf) { - foreachxml(hos, xmlGetNode(conf, "hosts"), "hosts") { + foreachxml(hos, xmlGetNode(conf, "hosts"), "host") { HostPtr h = new Host(hos); hosts[h->name] = h; if (h->self) { @@ -35,9 +43,9 @@ DaemonConfig::Export::Export(xmlNodePtr exp, const HostMap & hosts) : } DaemonConfig::Host::Host(xmlNodePtr hos) : - tcpPort(xmlGetNodeValue(hos, "tcpPort")), + iceEndpoint(xmlGetNodeValue(hos, "endpoint")), name(xmlGetNodeValue(hos, "name")), - self(strcmp(xmlGetNodeValue(hos, "self", "false"), "true") == 0) + self(name == myHostname()) { } diff --git a/netfs/daemonConfig.h b/netfs/daemonConfig.h index a27f686..f27aedb 100644 --- a/netfs/daemonConfig.h +++ b/netfs/daemonConfig.h @@ -15,7 +15,7 @@ class DaemonConfig : public virtual IntrusivePtrBase { public: Host(xmlNodePtr); - std::string tcpPort; + std::string iceEndpoint; std::string name; bool self; }; @@ -35,7 +35,7 @@ class DaemonConfig : public virtual IntrusivePtrBase { typedef std::map ExportMap; DaemonConfig(xmlNodePtr); - static boost::intrusive_ptr Load(const char * path); + static boost::intrusive_ptr Load(const std::string & path); ExportMap exports; diff --git a/netfs/daemonDirs.cpp b/netfs/daemonDirs.cpp index 3833e8c..c24dd9f 100644 --- a/netfs/daemonDirs.cpp +++ b/netfs/daemonDirs.cpp @@ -6,48 +6,50 @@ #include "daemonDirs.h" DirsServer::DirsServer(DaemonGlobalStatePtr dgs) : - DaemonModule(dgs), - dirNo(0) + DaemonModule(dgs) { } Ice::Int -DirsServer::opendir(const std::string & path, const Ice::Current&) +DirsServer::opendir(Ice::Long tok, const std::string & path, const Ice::Current&) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - DIR * od = ::opendir(path.c_str()); + DIR * od = ::opendir((sess->exportCfg->root / path).string().c_str()); if (!od) { throw NetFSComms::SystemError(errno); } - dirs[++dirNo] = od; + sess->dirs[++sess->dirNo] = od; //s.replicatedRequest = true; - return dirNo; + return sess->dirNo; } void -DirsServer::closedir(Ice::Int id, const Ice::Current&) +DirsServer::closedir(Ice::Long tok, Ice::Int id, const Ice::Current&) { - if (dirs.find(id) == dirs.end()) { + SessionPtr sess(dgs->getSession(tok)); + if (sess->dirs.find(id) == sess->dirs.end()) { throw NetFSComms::SystemError(EBADF); } errno = 0; - if (::closedir(dirs[id]) != 0) { + if (::closedir(sess->dirs[id]) != 0) { throw NetFSComms::SystemError(errno); } - dirs.erase(id); + sess->dirs.erase(id); //s.replicatedRequest = true; } NetFSComms::NameList -DirsServer::readdir(Ice::Int id, const Ice::Current&) +DirsServer::readdir(Ice::Long tok, Ice::Int id, const Ice::Current&) { - if (dirs.find(id) == dirs.end()) { + SessionPtr sess(dgs->getSession(tok)); + if (sess->dirs.find(id) == sess->dirs.end()) { throw NetFSComms::SystemError(EBADF); } errno = 0; dirent * d; NetFSComms::NameList list; - while ((d = ::readdir(dirs[id]))) { + while ((d = ::readdir(sess->dirs[id]))) { if (errno) { throw NetFSComms::SystemError(errno); } @@ -57,20 +59,22 @@ DirsServer::readdir(Ice::Int id, const Ice::Current&) } void -DirsServer::mkdir(const std::string & path, Ice::Int mode, const Ice::Current&) +DirsServer::mkdir(Ice::Long tok, const std::string & path, Ice::Int mode, const Ice::Current&) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - if (::mkdir(path.c_str(), mode) != 0) { + if (::mkdir((sess->exportCfg->root / path).string().c_str(), mode) != 0) { throw NetFSComms::SystemError(errno); } // s.replicatedRequest = true; } void -DirsServer::rmdir(const std::string & path, const Ice::Current&) +DirsServer::rmdir(Ice::Long tok, const std::string & path, const Ice::Current&) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - if (::rmdir(path.c_str()) != 0) { + if (::rmdir((sess->exportCfg->root / path).string().c_str()) != 0) { throw NetFSComms::SystemError(errno); } // s.replicatedRequest = true; diff --git a/netfs/daemonDirs.h b/netfs/daemonDirs.h index dfd04fb..1d5e2b5 100644 --- a/netfs/daemonDirs.h +++ b/netfs/daemonDirs.h @@ -9,16 +9,14 @@ class DirsServer : public DaemonModule, public NetFSComms::Dirs { public: DirsServer(DaemonGlobalStatePtr dgs); - virtual Ice::Int opendir(const std::string & path, const Ice::Current&); - virtual void closedir(Ice::Int id, const Ice::Current&); - virtual NetFSComms::NameList readdir(Ice::Int id, const Ice::Current&); + virtual Ice::Int opendir(Ice::Long tok, 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 std::string & path, Ice::Int id, const Ice::Current&); - virtual void rmdir(const std::string & path, const Ice::Current&); + virtual void mkdir(Ice::Long tok, const std::string & path, Ice::Int id, const Ice::Current&); + virtual void rmdir(Ice::Long tok, const std::string & path, const Ice::Current&); private: - int dirNo; - std::map dirs; }; #endif diff --git a/netfs/daemonFiles.cpp b/netfs/daemonFiles.cpp index f447a20..826f7be 100644 --- a/netfs/daemonFiles.cpp +++ b/netfs/daemonFiles.cpp @@ -5,42 +5,44 @@ #include "daemonFiles.h" FileServer::FileServer(DaemonGlobalStatePtr dgs) : - DaemonModule(dgs), - fileNo(0) + DaemonModule(dgs) { } void -FileServer::truncate(const std::string & path, Ice::Long size, const Ice::Current&) +FileServer::truncate(Ice::Long tok, const std::string & path, Ice::Long size, const Ice::Current&) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - if (::truncate(path.c_str(), size) != 0) { + if (::truncate((sess->exportCfg->root / path).string().c_str(), size) != 0) { throw NetFSComms::SystemError(errno); } // s.replicatedRequest = true; } void -FileServer::ftruncate(Ice::Int id, Ice::Long size, const Ice::Current&) +FileServer::ftruncate(Ice::Long tok, Ice::Int id, Ice::Long size, const Ice::Current&) { - if (files.find(id) == files.end()) { + SessionPtr sess(dgs->getSession(tok)); + if (sess->files.find(id) == sess->files.end()) { throw NetFSComms::SystemError(EBADF); } errno = 0; - if (::ftruncate(files[id], size) != 0) { + if (::ftruncate(sess->files[id], size) != 0) { throw NetFSComms::SystemError(errno); } // s.replicatedRequest = true; } NetFSComms::Attr -FileServer::fgetattr(Ice::Int id, const Ice::Current &) +FileServer::fgetattr(Ice::Long tok, Ice::Int id, const Ice::Current &) { - if (files.find(id) == files.end()) { + SessionPtr sess(dgs->getSession(tok)); + if (sess->files.find(id) == sess->files.end()) { throw NetFSComms::SystemError(EBADF); } struct stat s; - if (::fstat(files[id], &s) != 0) { + if (::fstat(sess->files[id], &s) != 0) { throw NetFSComms::SystemError(errno); } NetFSComms::Attr a; @@ -61,65 +63,70 @@ FileServer::fgetattr(Ice::Int id, const Ice::Current &) } void -FileServer::unlink(const std::string & path, const Ice::Current&) +FileServer::unlink(Ice::Long tok, const std::string & path, const Ice::Current&) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - if (::unlink(path.c_str()) != 0) { + if (::unlink((sess->exportCfg->root / path).string().c_str()) != 0) { throw NetFSComms::SystemError(errno); } // s.replicatedRequest = true; } Ice::Int -FileServer::open(const std::string & path, Ice::Int flags, const Ice::Current&) +FileServer::open(Ice::Long tok, const std::string & path, Ice::Int flags, const Ice::Current&) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - int fd = ::open(path.c_str(), flags); + int fd = ::open((sess->exportCfg->root / path).string().c_str(), flags); if (fd == -1) { throw NetFSComms::SystemError(errno); } - files[++fileNo] = fd; + sess->files[++sess->fileNo] = fd; //s.replicatedRequest = true; - return fileNo; + return sess->fileNo; } Ice::Int -FileServer::create(const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current&) +FileServer::create(Ice::Long tok, const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current&) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - int fd = ::open(path.c_str(), O_CREAT | flags, mode); + int fd = ::open((sess->exportCfg->root / path).string().c_str(), O_CREAT | flags, mode); if (fd == -1) { throw NetFSComms::SystemError(errno); } - files[++fileNo] = fd; + sess->files[++sess->fileNo] = fd; //s.replicatedRequest = true; - return fileNo; + return sess->fileNo; } void -FileServer::close(Ice::Int id, const Ice::Current&) +FileServer::close(Ice::Long tok, Ice::Int id, const Ice::Current&) { - if (files.find(id) == files.end()) { + SessionPtr sess(dgs->getSession(tok)); + if (sess->files.find(id) == sess->files.end()) { throw NetFSComms::SystemError(EBADF); } errno = 0; - if (::close(files[id]) != 0) { + if (::close(sess->files[id]) != 0) { throw NetFSComms::SystemError(errno); } - files.erase(id); + sess->files.erase(id); // s.replicatedRequest = true; } NetFSComms::Buffer -FileServer::read(Ice::Int id, Ice::Long offset, Ice::Long size, const Ice::Current&) +FileServer::read(Ice::Long tok, Ice::Int id, Ice::Long offset, Ice::Long size, const Ice::Current&) { - if (files.find(id) == files.end()) { + SessionPtr sess(dgs->getSession(tok)); + if (sess->files.find(id) == sess->files.end()) { throw NetFSComms::SystemError(EBADF); } NetFSComms::Buffer buf; buf.resize(size); errno = 0; - int r = pread(files[id], &buf[0], size, offset); + int r = pread(sess->files[id], &buf[0], size, offset); if (r == -1) { throw NetFSComms::SystemError(errno); } @@ -130,13 +137,14 @@ FileServer::read(Ice::Int id, Ice::Long offset, Ice::Long size, const Ice::Curre } void -FileServer::write(Ice::Int id, Ice::Long offset, Ice::Long size, const NetFSComms::Buffer & data, const Ice::Current&) +FileServer::write(Ice::Long tok, Ice::Int id, Ice::Long offset, Ice::Long size, const NetFSComms::Buffer & data, const Ice::Current&) { - if (files.find(id) == files.end()) { + SessionPtr sess(dgs->getSession(tok)); + if (sess->files.find(id) == sess->files.end()) { throw NetFSComms::SystemError(EBADF); } errno = 0; - if (pwrite(files[id], &data[0], size, offset) != size) { + if (pwrite(sess->files[id], &data[0], size, offset) != size) { throw NetFSComms::SystemError(errno); } // s.replicatedRequest = true; diff --git a/netfs/daemonFiles.h b/netfs/daemonFiles.h index 1ba844c..be3de2d 100644 --- a/netfs/daemonFiles.h +++ b/netfs/daemonFiles.h @@ -8,21 +8,19 @@ class FileServer : public DaemonModule, public NetFSComms::Files { public: FileServer(DaemonGlobalStatePtr dgs); - virtual void truncate(const std::string & path, Ice::Long size, const Ice::Current&); - virtual void ftruncate(Ice::Int id, Ice::Long size, const Ice::Current&); - virtual NetFSComms::Attr fgetattr(Ice::Int id, const Ice::Current&); + virtual void truncate(Ice::Long tok, const std::string & path, Ice::Long size, const Ice::Current&); + virtual void ftruncate(Ice::Long tok, Ice::Int id, Ice::Long size, const Ice::Current&); + virtual NetFSComms::Attr fgetattr(Ice::Long tok, Ice::Int id, const Ice::Current&); - virtual void unlink(const std::string & path, const Ice::Current&); + virtual void unlink(Ice::Long tok, const std::string & path, const Ice::Current&); - virtual Ice::Int open(const std::string & path, Ice::Int flags, const Ice::Current&); - virtual Ice::Int create(const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current&); - virtual void close(Ice::Int id, const Ice::Current&); - virtual NetFSComms::Buffer read(Ice::Int id, Ice::Long offset, Ice::Long size, const Ice::Current&); - virtual void write(Ice::Int id, Ice::Long offset, Ice::Long size, const NetFSComms::Buffer & data, const Ice::Current&); + virtual Ice::Int open(Ice::Long tok, const std::string & path, Ice::Int flags, const Ice::Current&); + virtual Ice::Int create(Ice::Long tok, 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&); private: - int fileNo; - std::map files; }; #endif diff --git a/netfs/daemonMisc.cpp b/netfs/daemonMisc.cpp index 9327fad..4fa6eaf 100644 --- a/netfs/daemonMisc.cpp +++ b/netfs/daemonMisc.cpp @@ -13,16 +13,18 @@ MiscServer::MiscServer(DaemonGlobalStatePtr dgs) : } Ice::Int -MiscServer::access(const std::string & path, Ice::Int mode, const Ice::Current &) +MiscServer::access(Ice::Long tok, const std::string & path, Ice::Int mode, const Ice::Current &) { - return ::access(path.c_str(), mode); + SessionPtr sess(dgs->getSession(tok)); + return ::access((sess->exportCfg->root / path).string().c_str(), mode); } NetFSComms::Attr -MiscServer::getattr(const std::string & path, const Ice::Current &) +MiscServer::getattr(Ice::Long tok, const std::string & path, const Ice::Current &) { + SessionPtr sess(dgs->getSession(tok)); struct stat s; - if (::stat(path.c_str(), &s) != 0) { + if (::stat((sess->exportCfg->root / path).string().c_str(), &s) != 0) { throw NetFSComms::SystemError(errno); } NetFSComms::Attr a; @@ -43,8 +45,9 @@ MiscServer::getattr(const std::string & path, const Ice::Current &) } void -MiscServer::symlink(const std::string & path1, const std::string & path2, const Ice::Current &) +MiscServer::symlink(Ice::Long tok, const std::string & path1, const std::string & path2, const Ice::Current &) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; if (::symlink(path1.c_str(), path2.c_str()) != 0) { throw NetFSComms::SystemError(errno); @@ -53,8 +56,9 @@ MiscServer::symlink(const std::string & path1, const std::string & path2, const } void -MiscServer::link(const std::string & path1, const std::string & path2, const Ice::Current &) +MiscServer::link(Ice::Long tok, const std::string & path1, const std::string & path2, const Ice::Current &) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; if (::link(path1.c_str(), path2.c_str()) != 0) { throw NetFSComms::SystemError(errno); @@ -63,8 +67,9 @@ MiscServer::link(const std::string & path1, const std::string & path2, const Ice } void -MiscServer::rename(const std::string & from, const std::string & to, const Ice::Current &) +MiscServer::rename(Ice::Long tok, const std::string & from, const std::string & to, const Ice::Current &) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; if (::rename(from.c_str(), to.c_str()) != 0) { throw NetFSComms::SystemError(errno); @@ -73,11 +78,12 @@ MiscServer::rename(const std::string & from, const std::string & to, const Ice:: } std::string -MiscServer::readlink(const std::string & path, const Ice::Current &) +MiscServer::readlink(Ice::Long tok, const std::string & path, const Ice::Current &) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; char buf[PATH_MAX]; - ssize_t rc = ::readlink(path.c_str(), buf, PATH_MAX); + ssize_t rc = ::readlink((sess->exportCfg->root / path).string().c_str(), buf, PATH_MAX); if (rc == -1) { throw NetFSComms::SystemError(errno); } @@ -85,20 +91,22 @@ MiscServer::readlink(const std::string & path, const Ice::Current &) } void -MiscServer::chmod(const std::string & path, Ice::Int mode, const Ice::Current &) +MiscServer::chmod(Ice::Long tok, const std::string & path, Ice::Int mode, const Ice::Current &) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - if (::chmod(path.c_str(), mode) != 0) { + if (::chmod((sess->exportCfg->root / path).string().c_str(), mode) != 0) { throw NetFSComms::SystemError(errno); } // s.replicatedRequest = true; } void -MiscServer::chown(const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current &) +MiscServer::chown(Ice::Long tok, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current &) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; - if (::chown(path.c_str(), uid, gid) != 0) { + if (::chown((sess->exportCfg->root / path).string().c_str(), uid, gid) != 0) { throw NetFSComms::SystemError(errno); } // s.replicatedRequest = true; diff --git a/netfs/daemonMisc.h b/netfs/daemonMisc.h index 69223f5..3682baf 100644 --- a/netfs/daemonMisc.h +++ b/netfs/daemonMisc.h @@ -8,14 +8,14 @@ class MiscServer : public DaemonModule, public NetFSComms::Misc { public: MiscServer(DaemonGlobalStatePtr dgs); - virtual Ice::Int access(const std::string & path, Ice::Int mode, const Ice::Current&); - virtual NetFSComms::Attr getattr(const std::string & path, const Ice::Current&); - virtual void symlink(const std::string & path1, const std::string & path2, const Ice::Current&); - virtual void link(const std::string & path1, const std::string & path2, const Ice::Current&); - virtual void rename(const std::string & path1, const std::string & path2, const Ice::Current&); - virtual std::string readlink(const std::string & path, const Ice::Current&); - virtual void chmod(const std::string & path, Ice::Int mode, const Ice::Current&); - virtual void chown(const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current&); + virtual Ice::Int access(Ice::Long tok, const std::string & path, Ice::Int mode, const Ice::Current&); + virtual NetFSComms::Attr getattr(Ice::Long tok, const std::string & path, const Ice::Current&); + virtual void symlink(Ice::Long tok, const std::string & path1, const std::string & path2, const Ice::Current&); + virtual void link(Ice::Long tok, const std::string & path1, const std::string & path2, const Ice::Current&); + virtual void rename(Ice::Long tok, const std::string & path1, const std::string & path2, const Ice::Current&); + virtual std::string readlink(Ice::Long tok, const std::string & path, const Ice::Current&); + virtual void chmod(Ice::Long tok, const std::string & path, Ice::Int mode, const Ice::Current&); + virtual void chown(Ice::Long tok, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current&); }; #endif diff --git a/netfs/daemonModule.cpp b/netfs/daemonModule.cpp index e0f59bd..bb9f1f0 100644 --- a/netfs/daemonModule.cpp +++ b/netfs/daemonModule.cpp @@ -1,6 +1,7 @@ #include "daemonModule.h" -DaemonModule::DaemonModule(DaemonGlobalStatePtr dgs) +DaemonModule::DaemonModule(DaemonGlobalStatePtr d) : + dgs(d) { } diff --git a/netfs/daemonModule.h b/netfs/daemonModule.h index 5d2123c..7525e74 100644 --- a/netfs/daemonModule.h +++ b/netfs/daemonModule.h @@ -6,6 +6,8 @@ class DaemonModule { protected: DaemonModule(DaemonGlobalStatePtr dgs); + + DaemonGlobalStatePtr dgs; }; #endif diff --git a/netfs/daemonService.cpp b/netfs/daemonService.cpp new file mode 100644 index 0000000..ce3d70c --- /dev/null +++ b/netfs/daemonService.cpp @@ -0,0 +1,20 @@ +#include "daemonService.h" + +ServiceServer::ServiceServer(DaemonGlobalStatePtr dgs) : + DaemonModule(dgs) +{ +} + +Ice::Long +ServiceServer::connect(const std::string & share, const std::string & auth, const Ice::Current &) +{ + DaemonGlobalState::NSP s = dgs->newSession(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 new file mode 100644 index 0000000..e1a7d7f --- /dev/null +++ b/netfs/daemonService.h @@ -0,0 +1,17 @@ +#ifndef DAEMONSERVICE_H +#define DAEMONSERVICE_H + +#include "netfsComms.h" +#include "daemonModule.h" + +class ServiceServer : public DaemonModule, public NetFSComms::Service { + public: + ServiceServer(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&); +}; + +#endif + + diff --git a/netfs/daemonSystem.cpp b/netfs/daemonSystem.cpp index 9690fc4..fa9cb1d 100644 --- a/netfs/daemonSystem.cpp +++ b/netfs/daemonSystem.cpp @@ -9,11 +9,12 @@ SystemServer::SystemServer(DaemonGlobalStatePtr dgs) : } NetFSComms::VFS -SystemServer::statfs(const std::string & path, const Ice::Current&) +SystemServer::statfs(Ice::Long tok, const std::string & path, const Ice::Current&) { + SessionPtr sess(dgs->getSession(tok)); errno = 0; struct statvfs s; - if (::statvfs(path.c_str(), &s) != 0) { + if (::statvfs((sess->exportCfg->root / path).string().c_str(), &s) != 0) { throw NetFSComms::SystemError(errno); } NetFSComms::VFS t; diff --git a/netfs/daemonSystem.h b/netfs/daemonSystem.h index 3d5f2be..48670fc 100644 --- a/netfs/daemonSystem.h +++ b/netfs/daemonSystem.h @@ -8,7 +8,7 @@ class SystemServer : public DaemonModule, public NetFSComms::System { public: SystemServer(DaemonGlobalStatePtr dgs); - virtual NetFSComms::VFS statfs(const std::string & path, const Ice::Current&); + virtual NetFSComms::VFS statfs(Ice::Long tok, const std::string & path, const Ice::Current&); }; #endif diff --git a/netfs/etc/daemon.xml b/netfs/etc/daemon.xml new file mode 100644 index 0000000..03e2c2a --- /dev/null +++ b/netfs/etc/daemon.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/netfs/fuse.cpp b/netfs/fuse.cpp index 36ace17..daaf788 100644 --- a/netfs/fuse.cpp +++ b/netfs/fuse.cpp @@ -6,6 +6,7 @@ #include #include #include "fuse.h" +#include "fuseConfig.h" static FuseAppBase * fuseApp; @@ -69,29 +70,67 @@ static void fuseDestroy(void * x) delete (App*)x; } +int +NetFS::opt_parse(void *, const char * arg, int key, struct fuse_args *) +{ + puts(arg); + if (arg[0] == '-') { + return 1; + } + else if (exportName.empty()) { + exportName = arg; + return 0; + } + else if (mountPoint.empty()) { + mountPoint = arg; + return 1; + } + return 1; +} + NetFS::NetFS(int & argc, char ** argv) : - ic(Ice::initialize(argc, argv)) + ic(Ice::initialize(argc, argv)), + authtok(0) { - files = NetFSComms::FilesPrx::checkedCast(ic->stringToProxy("Files:default -p 10000")); +} + +void * +NetFS::init(struct fuse_conn_info *) +{ + puts(exportName.c_str()); + FuseConfigPtr fc = FuseConfig::Load("client.xml"); + 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"; + } + files = NetFSComms::FilesPrx::checkedCast(ic->stringToProxy("Files:" + ep)); if (!files) { throw "Invalid files proxy"; } - dirs = NetFSComms::DirsPrx::checkedCast(ic->stringToProxy("Dirs:default -p 10000")); + dirs = NetFSComms::DirsPrx::checkedCast(ic->stringToProxy("Dirs:" + ep)); if (!dirs) { throw "Invalid directories proxy"; } - misc = NetFSComms::MiscPrx::checkedCast(ic->stringToProxy("Misc:default -p 10000")); + misc = NetFSComms::MiscPrx::checkedCast(ic->stringToProxy("Misc:" + ep)); if (!misc) { throw "Invalid misc proxy"; } - system = NetFSComms::SystemPrx::checkedCast(ic->stringToProxy("System:default -p 10000")); + system = NetFSComms::SystemPrx::checkedCast(ic->stringToProxy("System:" + ep)); if (!files) { throw "Invalid system proxy"; } + authtok = service->connect(exportName, "bar"); + return NULL; } NetFS::~NetFS() { + if (authtok) { + service->disconnect(authtok); + } if (ic) { ic->destroy(); } diff --git a/netfs/fuse.h b/netfs/fuse.h index 74374d5..707b368 100644 --- a/netfs/fuse.h +++ b/netfs/fuse.h @@ -11,6 +11,8 @@ class NetFS : public FuseAppBase 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 *); // misc int access(const char * p, int a); int getattr(const char * p, struct stat * s); @@ -46,6 +48,12 @@ class NetFS : public FuseAppBase NetFSComms::DirsPrx dirs; NetFSComms::MiscPrx misc; NetFSComms::SystemPrx system; + NetFSComms::ServicePrx service; + + Ice::Long authtok; + + std::string mountPoint; + std::string exportName; }; #endif diff --git a/netfs/fuseConfig.cpp b/netfs/fuseConfig.cpp new file mode 100644 index 0000000..26ee6a1 --- /dev/null +++ b/netfs/fuseConfig.cpp @@ -0,0 +1,28 @@ +#include "fuseConfig.h" +#include + +FuseConfigPtr +FuseConfig::Load(const char * path) +{ + xmlDoc * doc = xmlReadFile(path, 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 new file mode 100644 index 0000000..5416360 --- /dev/null +++ b/netfs/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 char * path); + + ExportMap exports; +}; +typedef boost::intrusive_ptr FuseConfigPtr; + +#endif + + diff --git a/netfs/fuseDirs.cpp b/netfs/fuseDirs.cpp index 846f1de..9d3861e 100644 --- a/netfs/fuseDirs.cpp +++ b/netfs/fuseDirs.cpp @@ -5,7 +5,7 @@ int NetFS::opendir(const char * p, struct fuse_file_info * fi) { try { - fi->fh = dirs->opendir(p); + fi->fh = dirs->opendir(authtok, p); return 0; } catch (NetFSComms::SystemError & e) { @@ -17,7 +17,7 @@ int NetFS::releasedir(const char *, struct fuse_file_info * fi) { try { - dirs->closedir(fi->fh); + dirs->closedir(authtok, fi->fh); return 0; } catch (NetFSComms::SystemError & e) { @@ -29,7 +29,7 @@ int NetFS::readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi) { try { - NetFSComms::NameList ds = dirs->readdir(fi->fh); + NetFSComms::NameList ds = dirs->readdir(authtok, fi->fh); for (NetFSComms::NameList::const_iterator e = ds.begin(); e != ds.end(); e++) { filler(buf, e->c_str(), NULL, 0); } @@ -44,7 +44,7 @@ int NetFS::mkdir(const char * p, mode_t m) { try { - dirs->mkdir(p, m); + dirs->mkdir(authtok, p, m); return 0; } catch (NetFSComms::SystemError & e) { @@ -55,7 +55,7 @@ int NetFS::rmdir(const char * p) { try { - dirs->rmdir(p); + dirs->rmdir(authtok, p); return 0; } catch (NetFSComms::SystemError & e) { diff --git a/netfs/fuseFiles.cpp b/netfs/fuseFiles.cpp index 430b411..5eb3bd5 100644 --- a/netfs/fuseFiles.cpp +++ b/netfs/fuseFiles.cpp @@ -5,7 +5,7 @@ int NetFS::open(const char * p, struct fuse_file_info * fi) { try { - fi->fh = files->open(p, fi->flags); + fi->fh = files->open(authtok, p, fi->flags); return 0; } catch (NetFSComms::SystemError & e) { @@ -17,7 +17,7 @@ int NetFS::create(const char * p, mode_t m, struct fuse_file_info * fi) { try { - fi->fh = files->create(p, 0, m); + fi->fh = files->create(authtok, p, 0, m); return 0; } catch (NetFSComms::SystemError & e) { @@ -29,7 +29,7 @@ int NetFS::release(const char *, struct fuse_file_info * fi) { try { - files->close(fi->fh); + files->close(authtok, fi->fh); return 0; } catch (NetFSComms::SystemError & e) { @@ -41,7 +41,7 @@ int NetFS::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) { try { - NetFSComms::Buffer data = files->read(fi->fh, o, s); + NetFSComms::Buffer data = files->read(authtok, fi->fh, o, s); for (NetFSComms::Buffer::const_iterator i = data.begin(); i != data.end(); i++, buf++) { *buf = *i; } @@ -57,7 +57,7 @@ NetFS::write(const char *, const char * buf, size_t s, off_t o, struct fuse_file { try { NetFSComms::Buffer data(buf, buf + s); - files->write(fi->fh, o, s, data); + files->write(authtok, fi->fh, o, s, data); return s; } catch (NetFSComms::SystemError & e) { @@ -69,7 +69,7 @@ int NetFS::truncate(const char * p, off_t o) { try { - files->truncate(p, o); + files->truncate(authtok, p, o); return 0; } catch (NetFSComms::SystemError & e) { @@ -81,7 +81,7 @@ int NetFS::ftruncate(const char *, off_t o, fuse_file_info * fi) { try { - files->ftruncate(fi->fh, o); + files->ftruncate(authtok, fi->fh, o); return 0; } catch (NetFSComms::SystemError & e) { @@ -93,7 +93,7 @@ int NetFS::fgetattr(const char *, struct stat * s, fuse_file_info * fi) { try { - NetFSComms::Attr a = files->fgetattr(fi->fh); + NetFSComms::Attr a = files->fgetattr(authtok, fi->fh); s->st_dev = a.dev; s->st_ino = a.inode; s->st_mode = a.mode; @@ -118,7 +118,7 @@ int NetFS::unlink(const char * p) { try { - files->unlink(p); + files->unlink(authtok, p); return 0; } catch (NetFSComms::SystemError & e) { diff --git a/netfs/fuseMisc.cpp b/netfs/fuseMisc.cpp index 4b3a4bf..52350e1 100644 --- a/netfs/fuseMisc.cpp +++ b/netfs/fuseMisc.cpp @@ -4,13 +4,13 @@ int NetFS::access(const char * p, int a) { - return -misc->access(p, a); + return -misc->access(authtok, p, a); } int NetFS::getattr(const char * p, struct stat * s) { try { - NetFSComms::Attr a = misc->getattr(p); + NetFSComms::Attr a = misc->getattr(authtok, p); s->st_dev = a.dev; s->st_ino = a.inode; s->st_mode = a.mode; @@ -35,7 +35,7 @@ int NetFS::chmod(const char * p, mode_t m) { try { - misc->chmod(p, m); + misc->chmod(authtok, p, m); return 0; } catch (NetFSComms::SystemError & e) { @@ -47,7 +47,7 @@ int NetFS::chown(const char * p, uid_t u, gid_t g) { try { - misc->chown(p, u, g); + misc->chown(authtok, p, u, g); return 0; } catch (NetFSComms::SystemError & e) { @@ -59,7 +59,7 @@ int NetFS::link(const char * p1, const char * p2) { try { - misc->link(p1, p2); + misc->link(authtok, p1, p2); return 0; } catch (NetFSComms::SystemError & e) { @@ -71,7 +71,7 @@ int NetFS::symlink(const char * p1, const char * p2) { try { - misc->symlink(p1, p2); + misc->symlink(authtok, p1, p2); return 0; } catch (NetFSComms::SystemError & e) { @@ -83,7 +83,7 @@ int NetFS::readlink(const char * p, char * p2, size_t s) { try { - std::string l = misc->readlink(p); + std::string l = misc->readlink(authtok, p); l.copy(p2, s); p2[s] = '\0'; return 0; @@ -97,7 +97,7 @@ int NetFS::rename(const char * p1, const char * p2) { try { - misc->rename(p1, p2); + misc->rename(authtok, p1, p2); return 0; } catch (NetFSComms::SystemError & e) { diff --git a/netfs/fuseSystem.cpp b/netfs/fuseSystem.cpp index 050eaa4..5cdc462 100644 --- a/netfs/fuseSystem.cpp +++ b/netfs/fuseSystem.cpp @@ -4,7 +4,7 @@ int NetFS::statfs(const char * p, struct statvfs * vfs) { try { - NetFSComms::VFS v = system->statfs(p); + NetFSComms::VFS v = system->statfs(authtok, p); vfs->f_bsize = v.blockSize; vfs->f_frsize = v.fragmentSize; vfs->f_blocks = v.blocks; diff --git a/netfs/fuseapp.cpp b/netfs/fuseapp.cpp index b46d3ad..976bc1e 100644 --- a/netfs/fuseapp.cpp +++ b/netfs/fuseapp.cpp @@ -1,5 +1,6 @@ #include "fuseapp.h" #include +#include FuseAppBase::FuseAppBase() { @@ -13,6 +14,7 @@ void * FuseAppBase::init(fuse_conn_info*) } int FuseAppBase::opt_parse(void*, const char *, int, fuse_args*) { + puts("default"); return 1; } int FuseAppBase::access(const char *, int) diff --git a/netfs/netfsComms.ice b/netfs/netfsComms.ice index 1fcfaf1..058412a 100644 --- a/netfs/netfsComms.ice +++ b/netfs/netfsComms.ice @@ -3,6 +3,10 @@ module NetFSComms { exception SystemError { int syserrno; }; + exception AuthError { + }; + exception ConfigError { + }; // Types struct VFS { long blockSize; @@ -36,41 +40,43 @@ module NetFSComms { sequence NameList; // Interfaces interface Files { - void truncate(string path, long size); - void ftruncate(int id, long size); - Attr fgetattr(int id); + idempotent void truncate(long tok, string path, long size) throws AuthError, SystemError; + idempotent void ftruncate(long tok, int id, long size) throws AuthError, SystemError; + idempotent Attr fgetattr(long tok, int id) throws AuthError, SystemError; - void unlink(string path); + void unlink(long tok, string path) throws AuthError, SystemError; - int open(string path, int flags); - int create(string path, int flags, int mode); - void close(int id); + int open(long tok, string path, int flags) throws AuthError, SystemError; + int create(long tok, string path, int flags, int mode) throws AuthError, SystemError; + void close(long tok, int id) throws AuthError, SystemError; - Buffer read(int id, long offset, long size); - void write(int id, long offset, long size, Buffer data); + 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; }; interface Dirs { - int opendir(string path) throws SystemError; - void closedir(int id) throws SystemError; - NameList readdir(int id) throws SystemError; + int opendir(long tok, 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(string path, int mode) throws SystemError; - void rmdir(string path) throws SystemError; + void mkdir(long tok, string path, int mode) throws AuthError, SystemError; + void rmdir(long tok, string path) throws AuthError, SystemError; }; interface System { - VFS statfs(string path); + idempotent VFS statfs(long tok, string path) throws AuthError, SystemError; }; interface Misc { - int access(string path, int mode); - Attr getattr(string path); - void symlink(string path1, string path2); - void link(string path1, string path2); - void rename(string from, string to); - string readlink(string path); - void chmod(string path, int mode); - void chown(string path, int uid, int gid); + idempotent int access(long tok, string path, int mode) throws AuthError, SystemError; + idempotent Attr getattr(long tok, string path) throws AuthError, SystemError; + void symlink(long tok, string path1, string path2) throws AuthError, SystemError; + void link(long tok, string path1, string path2) throws AuthError, SystemError; + void rename(long tok, string from, string to) throws AuthError, SystemError; + idempotent string readlink(long tok, string path) throws AuthError, SystemError; + idempotent void chmod(long tok, string path, int mode) throws AuthError, SystemError; + idempotent void chown(long tok, string path, int uid, int gid) throws AuthError, SystemError; }; interface Service { + long connect(string volume, string auth) throws AuthError, ConfigError; + void disconnect(long tok) throws AuthError; }; }; -- cgit v1.2.3