From a09145a371b2ad5e3751aa26a7dfd052ee24130d Mon Sep 17 00:00:00 2001 From: randomdan Date: Tue, 16 Nov 2010 23:16:54 +0000 Subject: Create opening-host-unique IDs for directories and files suitable for global replication --- netfs/daemon.cpp | 30 ++++++++----- netfs/daemon.h | 13 +++--- netfs/daemonDirs.cpp | 42 ++++++++++-------- netfs/daemonFiles.cpp | 116 ++++++++++++++++++++++++++---------------------- netfs/daemonService.cpp | 7 +-- netfs/daemonService.h | 5 ++- netfs/guidmap.h | 64 ++++++++++++++++++++++++++ 7 files changed, 179 insertions(+), 98 deletions(-) create mode 100644 netfs/guidmap.h 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 #include +#include #include "daemon.h" #include "daemonConfig.h" #include "daemonFileSystem.h" #include "daemonService.h" +int16_t +makeHostID() +{ + char buf[128]; + gethostname(buf, sizeof(buf)); + boost::crc_basic<16> crc_ccitt1( 0x1021, 0xFFFF, 0, false, false ); + crc_ccitt1.process_bytes(buf, sizeof(buf)); + return crc_ccitt1.checksum(); +} + // name = NetFSDaemonAdapter void NetFSDaemon::start(const std::string & name, const Ice::CommunicatorPtr & ic, const Ice::StringSeq&) @@ -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 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 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 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 Dirs; - Dirs dirs; - int fileNo; - typedef std::map Files; - Files files; + GUIDMapImpl dirs; + GUIDMapImpl files; boost::mutex lock; DaemonConfig::ExportPtr exportCfg; @@ -33,7 +30,7 @@ class DaemonGlobalState : public IntrusivePtrBase { typedef boost::intrusive_ptr SP; typedef boost::tuple 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 +#include +#include +#include + +class GUIDMap { + public: + class NotFound : public std::exception { }; + protected: + GUIDMap(int16_t s) : seed(int32_t(s) << 16) { + } + virtual ~GUIDMap() { + } + mutable boost::shared_mutex lock; + int32_t seed; + int16_t key; +}; +template +class GUIDMapImpl : public GUIDMap { + public: + typedef std::map Storage; + GUIDMapImpl(int16_t s) : GUIDMap(s) { + } + ~GUIDMapImpl() { + BOOST_FOREACH(typename Storage::value_type v, storage) { + ValueDeleter(v.second); + } + } + + int32_t store(const Value & value) { + boost::unique_lock l(lock); + int32_t newKey = (seed + ++key); + while (storage.find(newKey) != storage.end()) { + newKey = (seed + ++key); + } + storage.insert(std::pair(newKey, value)); + return newKey; + } + void remove(int32_t key) { + boost::unique_lock l(lock); + storage.erase(key); + } + Value get(int32_t key) const { + boost::shared_lock l(lock); + typename Storage::const_iterator i = storage.find(key); + if (i != storage.end()) { + return i->second; + } + throw NotFound(); + } + bool contains(int32_t key) const { + boost::shared_lock l(lock); + return (storage.find(key) != storage.end()); + } + + private: + Storage storage; +}; + +#endif + -- cgit v1.2.3