/* * Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ #ifndef CPP_INCLUDE_LIBXTREEMFS_VOLUME_IMPLEMENTATION_H_ #define CPP_INCLUDE_LIBXTREEMFS_VOLUME_IMPLEMENTATION_H_ #include "libxtreemfs/volume.h" #include #include #include #include #include #include #include #include "libxtreemfs/execute_sync_request.h" #include "libxtreemfs/metadata_cache.h" #include "libxtreemfs/options.h" #include "libxtreemfs/uuid_iterator.h" #include "rpc/sync_callback.h" namespace boost { class thread; } // namespace boost namespace xtreemfs { namespace pbrpc { class MRCServiceClient; class OSDServiceClient; } // namespace pbrpc namespace rpc { class Client; class SSLOptions; } // namespace rpc class ClientImplementation; class FileHandleImplementation; class FileInfo; class StripeTranslator; class UUIDResolver; /** * Default implementation of an XtreemFS volume. */ class VolumeImplementation : public Volume { public: /** * @remark Ownership of mrc_uuid_iterator is transferred to this object. */ VolumeImplementation( ClientImplementation* client, const std::string& client_uuid, UUIDIterator* mrc_uuid_iterator, const std::string& volume_name, const xtreemfs::rpc::SSLOptions* ssl_options, const Options& options); virtual ~VolumeImplementation(); virtual void Close(); virtual xtreemfs::pbrpc::StatVFS* StatFS( const xtreemfs::pbrpc::UserCredentials& user_credentials); virtual void ReadLink( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, std::string* link_target_path); virtual void Symlink( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& target_path, const std::string& link_path); virtual void Link( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& target_path, const std::string& link_path); virtual void Access( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const xtreemfs::pbrpc::ACCESS_FLAGS flags); virtual FileHandle* OpenFile( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const xtreemfs::pbrpc::SYSTEM_V_FCNTL flags); virtual FileHandle* OpenFile( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const xtreemfs::pbrpc::SYSTEM_V_FCNTL flags, uint32_t mode); virtual FileHandle* OpenFile( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const xtreemfs::pbrpc::SYSTEM_V_FCNTL flags, uint32_t mode, uint32_t attributes); /** Used by Volume->Truncate(). Otherwise truncate_new_file_size = 0. */ FileHandle* OpenFileWithTruncateSize( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const xtreemfs::pbrpc::SYSTEM_V_FCNTL flags, uint32_t mode, uint32_t attributes, int truncate_new_file_size); virtual void Truncate( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, off_t new_file_size); virtual void GetAttr( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, xtreemfs::pbrpc::Stat* stat); virtual void GetAttr( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, bool ignore_metadata_cache, xtreemfs::pbrpc::Stat* stat); /** If file_info is unknown and set to NULL, GetFileInfo(path) is used. */ void GetAttr( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, bool ignore_metadata_cache, xtreemfs::pbrpc::Stat* stat_buffer, FileInfo* file_info); virtual void SetAttr( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const xtreemfs::pbrpc::Stat& stat, xtreemfs::pbrpc::Setattrs to_set); virtual void Unlink( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path); /** Issue an unlink at the head OSD of every replica given in fc.xlocs(). */ void UnlinkAtOSD( const xtreemfs::pbrpc::FileCredentials& fc, const std::string& path); virtual void Rename( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const std::string& new_path); virtual void MakeDirectory( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, unsigned int mode); virtual void DeleteDirectory( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path); virtual xtreemfs::pbrpc::DirectoryEntries* ReadDir( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, uint64_t offset, uint32_t count, bool names_only); virtual xtreemfs::pbrpc::listxattrResponse* ListXAttrs( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path); virtual xtreemfs::pbrpc::listxattrResponse* ListXAttrs( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, bool use_cache); virtual void SetXAttr( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const std::string& name, const std::string& value, xtreemfs::pbrpc::XATTR_FLAGS flags); virtual bool GetXAttr( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const std::string& name, std::string* value); virtual bool GetXAttrSize( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const std::string& name, int* size); virtual void RemoveXAttr( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const std::string& name); virtual void AddReplica( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const xtreemfs::pbrpc::Replica& new_replica); virtual xtreemfs::pbrpc::Replicas* ListReplicas( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path); virtual void RemoveReplica( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, const std::string& osd_uuid); virtual void GetSuitableOSDs( const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, int number_of_osds, std::list* list_of_osd_uuids); /** Starts the network client of the volume and its wrappers MRCServiceClient * and OSDServiceClient. */ void Start(); /** Shuts down threads, called by ClientImplementation::Shutdown(). */ void CloseInternal(); /** Called by FileHandle.Close() to remove file_handle from the list. */ void CloseFile(uint64_t file_id, FileInfo* file_info, FileHandleImplementation* file_handle); const std::string& client_uuid() { return client_uuid_; } /** * @remark Ownership is NOT transferred to the caller. */ UUIDIterator* mrc_uuid_iterator() { return mrc_uuid_iterator_.get(); } /** * @remark Ownership is NOT transferred to the caller. */ UUIDResolver* uuid_resolver() { return uuid_resolver_; } /** * @remark Ownership is NOT transferred to the caller. */ xtreemfs::pbrpc::MRCServiceClient* mrc_service_client() { return mrc_service_client_.get(); } /** * @remark Ownership is NOT transferred to the caller. */ xtreemfs::pbrpc::OSDServiceClient* osd_service_client() { return osd_service_client_.get(); } const Options& volume_options() { return volume_options_; } const xtreemfs::pbrpc::Auth& auth_bogus() { return auth_bogus_; } const xtreemfs::pbrpc::UserCredentials& user_credentials_bogus() { return user_credentials_bogus_; } const std::map& stripe_translators() { return stripe_translators_; } private: /** Retrieves the stat object for file at "path" from MRC or cache. * Does not query any open file for pending file size updates nor lock the * open_file_table_. * * @remark Ownership of stat_buffer is not transferred to the caller. */ void GetAttrHelper(const xtreemfs::pbrpc::UserCredentials& user_credentials, const std::string& path, bool ignore_metadata_cache, xtreemfs::pbrpc::Stat* stat_buffer); /** Obtain or create a new FileInfo object in the open_file_table_ * * @remark Ownership is NOT transferred to the caller. The object will be * deleted by DecreaseFileInfoReferenceCount() if no further * FileHandle references it. */ FileInfo* GetFileInfoOrCreateUnmutexed( uint64_t file_id, const std::string& path, bool replicate_on_close, const xtreemfs::pbrpc::XLocSet& xlocset); /** Deregisters file_id from open_file_table_. */ void RemoveFileInfoUnmutexed(uint64_t file_id, FileInfo* file_info); /** Renew the XCap of every FileHandle before it does expire. */ void PeriodicXCapRenewal(); /** Write back file_sizes of every FileInfo object in open_file_table_. */ void PeriodicFileSizeUpdate(); /** Reference to Client which did open this volume. */ ClientImplementation* client_; /** UUID Resolver (usually points to the client_) */ UUIDResolver* uuid_resolver_; /** UUID of the Client (needed to distinguish Locks of different clients). */ const std::string& client_uuid_; /** UUID Iterator which contains the UUIDs of all MRC replicas of this * volume. */ boost::scoped_ptr mrc_uuid_iterator_; /** Name of the corresponding Volume. */ const std::string volume_name_; /** SSL options used for connections to the MRC and OSDs. */ const xtreemfs::rpc::SSLOptions* volume_ssl_options_; /** libxtreemfs Options object which includes all program options */ const Options& volume_options_; /** Disabled retry and interrupt functionality. */ RPCOptions periodic_threads_options_; /** The PBRPC protocol requires an Auth & UserCredentials object in every * request. However there are many operations which do not check the content * of this operation and therefore we use bogus objects then. * auth_bogus_ will always be set to the type AUTH_NONE. * * @remark Cannot be set to const because it's modified inside the * constructor VolumeImplementation(). */ xtreemfs::pbrpc::Auth auth_bogus_; /** The PBRPC protocol requires an Auth & UserCredentials object in every * request. However there are many operations which do not check the content * of this operation and therefore we use bogus objects then. * user_credentials_bogus will only contain a user "xtreemfs". * * @remark Cannot be set to const because it's modified inside the * constructor VolumeImplementation(). */ xtreemfs::pbrpc::UserCredentials user_credentials_bogus_; /** The RPC Client processes requests from a queue and executes callbacks in * its thread. */ boost::scoped_ptr network_client_; boost::scoped_ptr network_client_thread_; /** An MRCServiceClient is a wrapper for an RPC Client. */ boost::scoped_ptr mrc_service_client_; /** A OSDServiceClient is a wrapper for an RPC Client. */ boost::scoped_ptr osd_service_client_; /** Maps file_id -> FileInfo* for every open file. */ std::map open_file_table_; /** * @attention If a function uses open_file_table_mutex_ and * file_handle_list_mutex_, file_handle_list_mutex_ has to be * locked first to avoid a deadlock. */ boost::mutex open_file_table_mutex_; /** Metadata cache (stat, dir_entries, xattrs) by path. */ MetadataCache metadata_cache_; /** Available Striping policies. */ std::map stripe_translators_; /** Periodically renews the XCap of every FileHandle before it expires. */ boost::scoped_ptr xcap_renewal_thread_; /** Periodically writes back pending file sizes updates to the MRC service. */ boost::scoped_ptr filesize_writeback_thread_; FRIEND_TEST(VolumeImplementationTest, StatCacheCorrectlyUpdatedAfterRenameWriteAndClose); }; } // namespace xtreemfs #endif // CPP_INCLUDE_LIBXTREEMFS_VOLUME_IMPLEMENTATION_H_