summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2010-11-16 23:16:54 +0000
committerrandomdan <randomdan@localhost>2010-11-16 23:16:54 +0000
commita09145a371b2ad5e3751aa26a7dfd052ee24130d (patch)
tree2e3069b4faaa3fc862f65ffb61afefe435192d6f
parentAdd missing Boost threads library to daemon library (diff)
downloadnetfs-a09145a371b2ad5e3751aa26a7dfd052ee24130d.tar.bz2
netfs-a09145a371b2ad5e3751aa26a7dfd052ee24130d.tar.xz
netfs-a09145a371b2ad5e3751aa26a7dfd052ee24130d.zip
Create opening-host-unique IDs for directories and files suitable for global replication
-rw-r--r--netfs/daemon.cpp30
-rw-r--r--netfs/daemon.h13
-rw-r--r--netfs/daemonDirs.cpp42
-rw-r--r--netfs/daemonFiles.cpp116
-rw-r--r--netfs/daemonService.cpp7
-rw-r--r--netfs/daemonService.h5
-rw-r--r--netfs/guidmap.h64
7 files changed, 179 insertions, 98 deletions
diff --git a/netfs/daemon.cpp b/netfs/daemon.cpp
index 522f19f..3c8fdcc 100644
--- a/netfs/daemon.cpp
+++ b/netfs/daemon.cpp
@@ -1,10 +1,21 @@
#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&)
@@ -13,9 +24,10 @@ NetFSDaemon::start(const std::string & name, const Ice::CommunicatorPtr & ic, co
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(dgs), ic->stringToIdentity("Service"));
+ adapter->add(new ServiceServer(hostseed, dgs), ic->stringToIdentity("Service"));
adapter->activate();
}
@@ -39,14 +51,14 @@ DaemonGlobalState::DaemonGlobalState(DaemonConfigPtr c) :
}
DaemonGlobalState::NSP
-DaemonGlobalState::newSession(const std::string & ex)
+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(e->second);
+ SP s = new Session(hostseed, e->second);
while (Ice::Long tok = random()) {
if (sessions.find(tok) == sessions.end()) {
sessions[tok] = s;
@@ -74,21 +86,15 @@ DaemonGlobalState::endSession(Ice::Long tok)
sessions.erase(tok);
}
-DaemonGlobalState::Session::Session(DaemonConfig::ExportPtr ex) :
- dirNo(0),
- fileNo(0),
+DaemonGlobalState::Session::Session(int16_t hostseed, DaemonConfig::ExportPtr ex) :
+ dirs(hostseed),
+ files(hostseed),
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<DaemonGlobalState::Session> s) :
diff --git a/netfs/daemon.h b/netfs/daemon.h
index d24353b..f3499c0 100644
--- a/netfs/daemon.h
+++ b/netfs/daemon.h
@@ -10,6 +10,7 @@
#include "daemonConfig.h"
#include "netfsComms.h"
#include "entCache.h"
+#include "guidmap.h"
#include <dirent.h>
class DaemonGlobalState : public IntrusivePtrBase {
@@ -17,15 +18,11 @@ class DaemonGlobalState : public IntrusivePtrBase {
DaemonGlobalState(DaemonConfigPtr c);
class Session : public IntrusivePtrBase {
public:
- Session(DaemonConfig::ExportPtr exportCfg);
+ Session(int16_t hostseed, DaemonConfig::ExportPtr exportCfg);
~Session();
- int dirNo;
- typedef std::map<Ice::Int, DIR*> Dirs;
- Dirs dirs;
- int fileNo;
- typedef std::map<Ice::Int, int> Files;
- Files files;
+ GUIDMapImpl<DIR*, closedir> dirs;
+ GUIDMapImpl<int, close> files;
boost::mutex lock;
DaemonConfig::ExportPtr exportCfg;
@@ -33,7 +30,7 @@ class DaemonGlobalState : public IntrusivePtrBase {
typedef boost::intrusive_ptr<Session> SP;
typedef boost::tuple<Ice::Long, SP> NSP;
- NSP newSession(const std::string & ex);
+ NSP newSession(int16_t hostseed, const std::string & ex);
SP getSession(Ice::Long tok) const;
void endSession(Ice::Long tok);
diff --git a/netfs/daemonDirs.cpp b/netfs/daemonDirs.cpp
index 37f2a5c..01d976b 100644
--- a/netfs/daemonDirs.cpp
+++ b/netfs/daemonDirs.cpp
@@ -15,23 +15,24 @@ FileSystemServer::opendir(const NetFSComms::ReqEnv & re, const std::string & pat
if (!od) {
throw NetFSComms::SystemError(errno);
}
- sess->dirs[++sess->dirNo] = od;
//s.replicatedRequest = true;
- return sess->dirNo;
+ return sess->dirs.store(od);
}
void
FileSystemServer::closedir(Ice::Long tok, Ice::Int id, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(tok));
- if (sess->dirs.find(id) == sess->dirs.end()) {
- throw NetFSComms::SystemError(EBADF);
+ try {
+ errno = 0;
+ if (::closedir(sess->dirs.get(id)) != 0) {
+ throw NetFSComms::SystemError(errno);
+ }
+ sess->dirs.remove(id);
}
- errno = 0;
- if (::closedir(sess->dirs[id]) != 0) {
- throw NetFSComms::SystemError(errno);
+ catch (GUIDMap::NotFound) {
+ throw NetFSComms::SystemError(EBADF);
}
- sess->dirs.erase(id);
//s.replicatedRequest = true;
}
@@ -39,19 +40,22 @@ NetFSComms::NameList
FileSystemServer::readdir(Ice::Long tok, Ice::Int id, const Ice::Current&)
{
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(sess->dirs[id]))) {
- if (errno) {
- throw NetFSComms::SystemError(errno);
+ 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);
}
- list.push_back(d->d_name);
+ return list;
+ }
+ catch (GUIDMap::NotFound) {
+ throw NetFSComms::SystemError(EBADF);
}
- return list;
}
void
diff --git a/netfs/daemonFiles.cpp b/netfs/daemonFiles.cpp
index aef3239..2686f20 100644
--- a/netfs/daemonFiles.cpp
+++ b/netfs/daemonFiles.cpp
@@ -21,12 +21,14 @@ FileSystemServer::ftruncate(const NetFSComms::ReqEnv & re, Ice::Int id, Ice::Lon
{
SessionPtr sess(dgs->getSession(re.tok));
TempPrivs tp(re, &uentries, &gentries);
- if (sess->files.find(id) == sess->files.end()) {
- throw NetFSComms::SystemError(EBADF);
+ try {
+ errno = 0;
+ if (::ftruncate(sess->files.get(id), size) != 0) {
+ throw NetFSComms::SystemError(errno);
+ }
}
- errno = 0;
- if (::ftruncate(sess->files[id], size) != 0) {
- throw NetFSComms::SystemError(errno);
+ catch (GUIDMap::NotFound) {
+ throw NetFSComms::SystemError(EBADF);
}
// s.replicatedRequest = true;
}
@@ -36,28 +38,30 @@ FileSystemServer::fgetattr(const NetFSComms::ReqEnv & re, Ice::Int id, const Ice
{
SessionPtr sess(dgs->getSession(re.tok));
TempPrivs tp(re, &uentries, &gentries);
- if (sess->files.find(id) == sess->files.end()) {
- throw NetFSComms::SystemError(EBADF);
+ 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;
}
- struct stat s;
- if (::fstat(sess->files[id], &s) != 0) {
- throw NetFSComms::SystemError(errno);
+ catch (GUIDMap::NotFound) {
+ throw NetFSComms::SystemError(EBADF);
}
- 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
@@ -82,9 +86,8 @@ FileSystemServer::open(const NetFSComms::ReqEnv & re, const std::string & path,
if (fd == -1) {
throw NetFSComms::SystemError(errno);
}
- sess->files[++sess->fileNo] = fd;
//s.replicatedRequest = true;
- return sess->fileNo;
+ return sess->files.store(fd);
}
Ice::Int
@@ -97,57 +100,62 @@ FileSystemServer::create(const NetFSComms::ReqEnv & re, const std::string & path
if (fd == -1) {
throw NetFSComms::SystemError(errno);
}
- sess->files[++sess->fileNo] = fd;
//s.replicatedRequest = true;
- return sess->fileNo;
+ return sess->files.store(fd);
}
void
FileSystemServer::close(Ice::Long tok, Ice::Int id, const Ice::Current&)
{
SessionPtr sess(dgs->getSession(tok));
- if (sess->files.find(id) == sess->files.end()) {
- throw NetFSComms::SystemError(EBADF);
+ try {
+ errno = 0;
+ if (::close(sess->files.get(id)) != 0) {
+ throw NetFSComms::SystemError(errno);
+ }
+ sess->files.remove(id);
+ // s.replicatedRequest = true;
}
- errno = 0;
- if (::close(sess->files[id]) != 0) {
- throw NetFSComms::SystemError(errno);
+ catch (GUIDMap::NotFound) {
+ throw NetFSComms::SystemError(EBADF);
}
- sess->files.erase(id);
- // s.replicatedRequest = true;
}
NetFSComms::Buffer
FileSystemServer::read(Ice::Long tok, Ice::Int id, Ice::Long offset, Ice::Long size, const Ice::Current&)
{
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(sess->files[id], &buf[0], size, offset);
- if (r == -1) {
- throw NetFSComms::SystemError(errno);
+ 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;
}
- else if (r != size) {
- buf.resize(r);
+ catch (GUIDMap::NotFound) {
+ throw NetFSComms::SystemError(EBADF);
}
- return buf;
}
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));
- if (sess->files.find(id) == sess->files.end()) {
- throw NetFSComms::SystemError(EBADF);
+ try {
+ errno = 0;
+ if (pwrite(sess->files.get(id), &data[0], size, offset) != size) {
+ throw NetFSComms::SystemError(errno);
+ }
+ // s.replicatedRequest = true;
}
- errno = 0;
- if (pwrite(sess->files[id], &data[0], size, offset) != size) {
- throw NetFSComms::SystemError(errno);
+ catch (GUIDMap::NotFound) {
+ throw NetFSComms::SystemError(EBADF);
}
- // s.replicatedRequest = true;
}
diff --git a/netfs/daemonService.cpp b/netfs/daemonService.cpp
index ce3d70c..04ff9da 100644
--- a/netfs/daemonService.cpp
+++ b/netfs/daemonService.cpp
@@ -1,14 +1,15 @@
#include "daemonService.h"
-ServiceServer::ServiceServer(DaemonGlobalStatePtr dgs) :
- DaemonModule(dgs)
+ServiceServer::ServiceServer(int16_t hs, DaemonGlobalStatePtr dgs) :
+ DaemonModule(dgs),
+ hostseed(hs)
{
}
Ice::Long
ServiceServer::connect(const std::string & share, const std::string & auth, const Ice::Current &)
{
- DaemonGlobalState::NSP s = dgs->newSession(share);
+ DaemonGlobalState::NSP s = dgs->newSession(hostseed, share);
return s.get<0>();
}
diff --git a/netfs/daemonService.h b/netfs/daemonService.h
index e1a7d7f..067e4a5 100644
--- a/netfs/daemonService.h
+++ b/netfs/daemonService.h
@@ -6,12 +6,13 @@
class ServiceServer : public DaemonModule, public NetFSComms::Service {
public:
- ServiceServer(DaemonGlobalStatePtr dgs);
+ 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/guidmap.h b/netfs/guidmap.h
new file mode 100644
index 0000000..b550b30
--- /dev/null
+++ b/netfs/guidmap.h
@@ -0,0 +1,64 @@
+#ifndef GUIDMAP_H
+#define GUIDMAP_H
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/foreach.hpp>
+#include <map>
+
+class GUIDMap {
+ public:
+ class NotFound : public std::exception { };
+ protected:
+ GUIDMap(int16_t s) : seed(int32_t(s) << 16) {
+ }
+ virtual ~GUIDMap() {
+ }
+ mutable boost::shared_mutex lock;
+ int32_t seed;
+ int16_t key;
+};
+template<class Value, int ValueDeleter(Value)>
+class GUIDMapImpl : public GUIDMap {
+ public:
+ typedef std::map<int32_t, const Value> Storage;
+ GUIDMapImpl(int16_t s) : GUIDMap(s) {
+ }
+ ~GUIDMapImpl() {
+ BOOST_FOREACH(typename Storage::value_type v, storage) {
+ ValueDeleter(v.second);
+ }
+ }
+
+ int32_t store(const Value & value) {
+ boost::unique_lock<boost::shared_mutex> l(lock);
+ int32_t newKey = (seed + ++key);
+ while (storage.find(newKey) != storage.end()) {
+ newKey = (seed + ++key);
+ }
+ storage.insert(std::pair<int32_t, const Value>(newKey, value));
+ return newKey;
+ }
+ void remove(int32_t key) {
+ boost::unique_lock<boost::shared_mutex> l(lock);
+ storage.erase(key);
+ }
+ Value get(int32_t key) const {
+ boost::shared_lock<boost::shared_mutex> l(lock);
+ typename Storage::const_iterator i = storage.find(key);
+ if (i != storage.end()) {
+ return i->second;
+ }
+ throw NotFound();
+ }
+ bool contains(int32_t key) const {
+ boost::shared_lock<boost::shared_mutex> l(lock);
+ return (storage.find(key) != storage.end());
+ }
+
+ private:
+ Storage storage;
+};
+
+#endif
+