diff options
| -rw-r--r-- | netfs/daemon.cpp | 30 | ||||
| -rw-r--r-- | netfs/daemon.h | 13 | ||||
| -rw-r--r-- | netfs/daemonDirs.cpp | 42 | ||||
| -rw-r--r-- | netfs/daemonFiles.cpp | 116 | ||||
| -rw-r--r-- | netfs/daemonService.cpp | 7 | ||||
| -rw-r--r-- | netfs/daemonService.h | 5 | ||||
| -rw-r--r-- | netfs/guidmap.h | 64 | 
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 + | 
