summaryrefslogtreecommitdiff
path: root/netfs/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'netfs/daemon')
-rw-r--r--netfs/daemon/Jamfile.jam31
-rw-r--r--netfs/daemon/daemon.cpp73
-rw-r--r--netfs/daemon/daemon.h39
-rw-r--r--netfs/daemon/daemonConfig.cpp52
-rw-r--r--netfs/daemon/daemonConfig.h48
-rw-r--r--netfs/daemon/daemonDirectory.cpp41
-rw-r--r--netfs/daemon/daemonDirectory.h22
-rw-r--r--netfs/daemon/daemonFile.cpp75
-rw-r--r--netfs/daemon/daemonFile.h28
-rw-r--r--netfs/daemon/daemonService.cpp21
-rw-r--r--netfs/daemon/daemonService.h18
-rw-r--r--netfs/daemon/daemonVolume.cpp243
-rw-r--r--netfs/daemon/daemonVolume.h47
-rw-r--r--netfs/daemon/pch.hpp13
14 files changed, 751 insertions, 0 deletions
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/daemon/daemonConfig.cpp b/netfs/daemon/daemonConfig.cpp
new file mode 100644
index 0000000..7f171eb
--- /dev/null
+++ b/netfs/daemon/daemonConfig.cpp
@@ -0,0 +1,52 @@
+#include "pch.hpp"
+#include "daemonConfig.h"
+#include <string.h>
+
+std::string
+myHostname()
+{
+ char buf[128];
+ gethostname(buf, sizeof(buf));
+ return buf;
+}
+
+DaemonConfigPtr
+DaemonConfig::Load(const std::string & path)
+{
+ xmlDoc * doc = xmlReadFile(path.c_str(), NULL, 0);
+ DaemonConfigPtr dc = new DaemonConfig(doc->children);
+ xmlFreeDoc(doc);
+ return dc;
+}
+
+DaemonConfig::DaemonConfig(xmlNodePtr conf)
+{
+ foreachxml(hos, xmlGetNode(conf, "hosts"), "host") {
+ HostPtr h = new Host(hos);
+ hosts[h->name] = h;
+ if (h->self) {
+ self = h;
+ }
+ }
+ foreachxml(exp, xmlGetNode(conf, "exports"), "export") {
+ ExportPtr e = new Export(exp, hosts);
+ exports[e->name] = e;
+ }
+}
+
+DaemonConfig::Export::Export(xmlNodePtr exp, const HostMap & hosts) :
+ root(xmlGetNodeValue(exp, "root")),
+ name(xmlGetNodeValue(exp, "name"))
+{
+ foreachxml(rep, xmlGetNode(exp, "replicate"), "name") {
+ replicate.insert(hosts.find(xmlGetNodeValue(rep))->second);
+ }
+}
+
+DaemonConfig::Host::Host(xmlNodePtr hos) :
+ iceEndpoint(xmlGetNodeValue(hos, "endpoint")),
+ name(xmlGetNodeValue(hos, "name")),
+ self(name == myHostname())
+{
+}
+
diff --git a/netfs/daemon/daemonConfig.h b/netfs/daemon/daemonConfig.h
new file mode 100644
index 0000000..f27aedb
--- /dev/null
+++ b/netfs/daemon/daemonConfig.h
@@ -0,0 +1,48 @@
+#ifndef DAEMONCONFIG_H
+#define DAEMONCONFIG_H
+
+#include <string>
+#include <map>
+#include <set>
+#include <intrusivePtrBase.h>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/filesystem/path.hpp>
+#include "xml.h"
+
+class DaemonConfig : public virtual IntrusivePtrBase {
+ public:
+ class Host : public virtual IntrusivePtrBase {
+ public:
+ Host(xmlNodePtr);
+
+ std::string iceEndpoint;
+ std::string name;
+ bool self;
+ };
+ typedef boost::intrusive_ptr<Host> HostPtr;
+ typedef std::map<std::string, HostPtr> HostMap;
+ typedef std::set<HostPtr> HostSet;
+
+ class Export : public virtual IntrusivePtrBase {
+ public:
+ Export(xmlNodePtr, const HostMap &);
+
+ boost::filesystem::path root;
+ std::string name;
+ HostSet replicate;
+ };
+ typedef boost::intrusive_ptr<Export> ExportPtr;
+ typedef std::map<std::string, ExportPtr> ExportMap;
+
+ DaemonConfig(xmlNodePtr);
+ static boost::intrusive_ptr<DaemonConfig> Load(const std::string & path);
+
+
+ ExportMap exports;
+ HostMap hosts;
+ HostPtr self;
+};
+typedef boost::intrusive_ptr<DaemonConfig> DaemonConfigPtr;
+
+#endif
+
diff --git a/netfs/daemon/daemonDirectory.cpp b/netfs/daemon/daemonDirectory.cpp
new file mode 100644
index 0000000..f679653
--- /dev/null
+++ b/netfs/daemon/daemonDirectory.cpp
@@ -0,0 +1,41 @@
+#include "pch.hpp"
+#include <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/daemon/pch.hpp b/netfs/daemon/pch.hpp
new file mode 100644
index 0000000..3229655
--- /dev/null
+++ b/netfs/daemon/pch.hpp
@@ -0,0 +1,13 @@
+#ifdef BOOST_BUILD_PCH_ENABLED
+#ifndef NETFS_DAEMON_PCH
+#define NETFS_DAEMON_PCH
+
+#include "../lib/pch.hpp"
+#include <boost/filesystem/path.hpp>
+#include "daemon.h"
+#include <IceBox/IceBox.h>
+
+#endif
+#endif
+
+