Imported Upstream version 1.5.1

This commit is contained in:
Mario Fetka
2020-09-22 02:25:22 +02:00
commit 434d6067d9
2103 changed files with 928962 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_ASYNC_WRITE_BUFFER_H_
#define CPP_INCLUDE_LIBXTREEMFS_ASYNC_WRITE_BUFFER_H_
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <string>
namespace xtreemfs {
namespace pbrpc {
class writeRequest;
} // namespace pbrpc
class FileHandleImplementation;
class XCapHandler;
struct AsyncWriteBuffer {
/** Possible states of this object. */
enum State {
PENDING,
FAILED,
SUCCEEDED
};
/**
* @remark Ownership of write_request is transferred to this object.
*/
AsyncWriteBuffer(xtreemfs::pbrpc::writeRequest* write_request,
const char* data,
size_t data_length,
FileHandleImplementation* file_handle,
XCapHandler* xcap_handler);
/**
* @remark Ownership of write_request is transferred to this object.
*/
AsyncWriteBuffer(xtreemfs::pbrpc::writeRequest* write_request,
const char* data,
size_t data_length,
FileHandleImplementation* file_handle,
XCapHandler* xcap_handler,
const std::string& osd_uuid);
~AsyncWriteBuffer();
/** Additional information of the write request. */
xtreemfs::pbrpc::writeRequest* write_request;
/** Actual payload of the write request. */
char* data;
/** Length of the payload. */
size_t data_length;
/** FileHandle which did receive the Write() command. */
FileHandleImplementation* file_handle;
/** XCapHandler, used to update the XCap in case of retries. */
XCapHandler* xcap_handler_;
/** Set to false if the member "osd_uuid" is used instead of the FileInfo's
* osd_uuid_iterator in order to determine the OSD to be used. */
bool use_uuid_iterator;
/** UUID of the OSD which was used for the last retry or if use_uuid_iterator
* is false, this variable is initialized to the OSD to be used. */
std::string osd_uuid;
/** Resolved UUID */
std::string service_address;
/** Current state of the object. */
State state_;
/** Retry count.*/
int retry_count_;
/** Time when the request was sent */
boost::posix_time::ptime request_sent_time;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_ASYNC_WRITE_BUFFER_H_

View File

@@ -0,0 +1,300 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_ASYNC_WRITE_HANDLER_H_
#define CPP_INCLUDE_LIBXTREEMFS_ASYNC_WRITE_HANDLER_H_
#include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp>
#include <list>
#include "libxtreemfs/execute_sync_request.h"
#include "libxtreemfs/options.h"
#include "rpc/callback_interface.h"
#include "util/synchronized_queue.h"
namespace xtreemfs {
struct AsyncWriteBuffer;
class FileInfo;
class UUIDResolver;
class UUIDIterator;
namespace pbrpc {
class OSDServiceClient;
class OSDWriteResponse;
} // namespace pbrpc
class AsyncWriteHandler
: public xtreemfs::rpc::CallbackInterface<
xtreemfs::pbrpc::OSDWriteResponse> {
public:
struct CallbackEntry {
/**
* @remark Ownerships of response_message, data and error are transferred.
*/
CallbackEntry(AsyncWriteHandler* handler,
xtreemfs::pbrpc::OSDWriteResponse* response_message,
char* data,
uint32_t data_length,
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error,
void* context)
: handler_(handler),
response_message_(response_message),
data_(data),
data_length_(data_length),
error_(error),
context_(context) {}
AsyncWriteHandler* handler_;
xtreemfs::pbrpc::OSDWriteResponse* response_message_;
char* data_;
uint32_t data_length_;
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error_;
void* context_;
};
AsyncWriteHandler(
FileInfo* file_info,
UUIDIterator* uuid_iterator,
UUIDResolver* uuid_resolver,
xtreemfs::pbrpc::OSDServiceClient* osd_service_client,
const xtreemfs::pbrpc::Auth& auth_bogus,
const xtreemfs::pbrpc::UserCredentials& user_credentials_bogus,
const Options& volume_options,
util::SynchronizedQueue<CallbackEntry>& callback_queue_);
~AsyncWriteHandler();
/** Adds write_buffer to the list of pending writes and sends it to the OSD
* specified by write_buffer->uuid_iterator (or write_buffer->osd_uuid if
* write_buffer->use_uuid_iterator is false).
*
* Blocks if the number of pending bytes exceeds the maximum write-ahead
* or WaitForPendingWrites{NonBlocking}() was called beforehand.
*/
void Write(AsyncWriteBuffer* write_buffer);
/** Blocks until state changes back to IDLE and prevents allowing new writes.
* by blocking further Write() calls. */
void WaitForPendingWrites();
/** If waiting for pending writes would block, it returns true and adds
* the parameters to the list waiting_observers_ and calls notify_one()
* on condition_variable once state_ changed back to IDLE. */
bool WaitForPendingWritesNonBlocking(boost::condition* condition_variable,
bool* wait_completed,
boost::mutex* wait_completed_mutex);
/** This static method runs in its own thread and does the real callback
* handling to avoid load and blocking on the RPC thread. */
static void ProcessCallbacks(util::SynchronizedQueue<CallbackEntry>& callback_queue);
private:
/** Possible states of this object. */
enum State {
IDLE,
WRITES_PENDING,
HAS_FAILED_WRITES,
FINALLY_FAILED
};
/** Contains information about observer who has to be notified once all
* currently pending writes have finished. */
struct WaitForCompletionObserver {
WaitForCompletionObserver(boost::condition* condition_variable,
bool* wait_completed,
boost::mutex* wait_completed_mutex)
: condition_variable(condition_variable),
wait_completed(wait_completed),
wait_completed_mutex(wait_completed_mutex) {
assert(condition_variable && wait_completed && wait_completed_mutex);
}
boost::condition* condition_variable;
bool* wait_completed;
boost::mutex* wait_completed_mutex;
};
/** Implements callback for an async write request. This method just enqueues
* data. The actual handling of the callback is done by another thread via
* HandleCallback(). */
virtual void CallFinished(xtreemfs::pbrpc::OSDWriteResponse* response_message,
char* data,
uint32_t data_length,
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error,
void* context);
/** Implements callback handling for an async write request. This method is
* called for all queued callbacks in a separate thread.*/
void HandleCallback(xtreemfs::pbrpc::OSDWriteResponse* response_message,
char* data,
uint32_t data_length,
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error,
void* context);
/** Helper function which adds "write_buffer" to the list writes_in_flight_,
* increases the number of pending bytes and takes care of state changes.
*
* @remark Ownership is not transferred to the caller.
* @remark Requires a lock on mutex_.
*/
void IncreasePendingBytesHelper(AsyncWriteBuffer* write_buffer,
boost::mutex::scoped_lock* lock);
/** Helper function reduces the number of pending bytes and takes care
* of state changes.
* Depending on "delete_buffer" the buffer is deleted or not (which implies
* DeleteBufferHelper must be called later).
*
* @remark Ownership of "write_buffer" is transferred to the caller.
* @remark Requires a lock on mutex_.
*/
void DecreasePendingBytesHelper(AsyncWriteBuffer* write_buffer,
boost::mutex::scoped_lock* lock,
bool delete_buffer);
/** Helper function which removes all leading elements which were flagged
* as successfully sent from writes_in_flight_ and deletes them.
*
* @remark Requires a lock on mutex_.
*/
void DeleteBufferHelper(boost::mutex::scoped_lock* lock);
/** Helper to enter the FINALLY_FAILED state in a thread-safe way. CleanUp
* is done automatically when the last expected Callback arrives.
*/
void FailFinallyHelper();
/** This helper method is used to clean up after the AsyncWriteHandler
* reaches the finally failed state. So all write buffers are deleted,
* and waiting threads are notified.
*/
void CleanUp(boost::mutex::scoped_lock* lock);
/** This method is used to repeat failed writes which already are in the list
* of writes in flight. It bypasses the writeahead limitations.
*/
void ReWrite(AsyncWriteBuffer* write_buffer,
boost::mutex::scoped_lock* lock);
/** Common code, used by Write and ReWrite.
* Pay attention to the locking semantics:
* In case of a write (is_rewrite == false), WriteCommon() expects to be
* called from an unlocked context. In case of a rewrite, the opposite
* applies.
*/
void WriteCommon(AsyncWriteBuffer* write_buffer,
boost::mutex::scoped_lock* lock,
bool is_rewrite);
/** Calls notify_one() on all observers in waiting_observers_, frees each
* element in the list and clears the list afterwards.
*
* @remark Requires a lock on mutex_.
*/
void NotifyWaitingObserversAndClearAll(boost::mutex::scoped_lock* lock);
/** Use this when modifying the object. */
boost::mutex mutex_;
/** State of this object. */
State state_;
/** List of pending writes. */
std::list<AsyncWriteBuffer*> writes_in_flight_;
/** Number of pending bytes. */
int pending_bytes_;
/** Number of pending write requests
* NOTE: this does not equal writes_in_flight_.size(), since it also contains
* successfully sent entries which must be kept for consistent retries in
* case of failure. */
int pending_writes_;
/** Set by WaitForPendingWrites{NonBlocking}() to true if there are
* temporarily no new async writes allowed and will be set to false again
* once the state IDLE is reached. */
bool writing_paused_;
/** Used to notify blocked WaitForPendingWrites() callers for the state change
* back to IDLE. */
boost::condition all_pending_writes_did_complete_;
/** Number of threads blocked by WaitForPendingWrites() waiting on
* all_pending_writes_did_complete_ for a state change back to IDLE.
*
* This does not include the number of waiting threads which did call
* WaitForPendingWritesNonBlocking(). Therefore, see "waiting_observers_".
* The total number of all waiting threads is:
* waiting_blocking_threads_count_ + waiting_observers_.size()
*/
int waiting_blocking_threads_count_;
/** Used to notify blocked Write() callers that the number of pending bytes
* has decreased. */
boost::condition pending_bytes_were_decreased_;
/** List of WaitForPendingWritesNonBlocking() observers (specified by their
* boost::condition variable and their bool value which will be set to true
* if the state changed back to IDLE). */
std::list<WaitForCompletionObserver*> waiting_observers_;
/** FileInfo object to which this AsyncWriteHandler does belong. Accessed for
* file size updates. */
FileInfo* file_info_;
/** Pointer to the UUIDIterator of the FileInfo object. */
UUIDIterator* uuid_iterator_;
/** Required for resolving UUIDs to addresses. */
UUIDResolver* uuid_resolver_;
/** Options (Max retries, ...) used when resolving UUIDs. */
RPCOptions uuid_resolver_options_;
/** Client which is used to send out the writes. */
xtreemfs::pbrpc::OSDServiceClient* osd_service_client_;
/** Auth needed for ServiceClients. Always set to AUTH_NONE by Volume. */
const xtreemfs::pbrpc::Auth& auth_bogus_;
/** For same reason needed as auth_bogus_. Always set to user "xtreemfs". */
const xtreemfs::pbrpc::UserCredentials& user_credentials_bogus_;
const Options& volume_options_;
/** Maximum number in bytes which may be pending. */
const int max_writeahead_;
/** Maximum number of pending write requests. */
const int max_requests_;
/** Maximum number of attempts a write will be tried. */
const int max_write_tries_;
/** True after the first redirct, set back to false on error resolution */
bool redirected_;
/** Set to true in when redirected is set true for the first time. The retries
* wont be delayed if true. */
bool fast_redirect_;
/** A copy of the worst error which was detected. It determines the error
* handling. */
xtreemfs::pbrpc::RPCHeader::ErrorResponse worst_error_;
/** The write buffer to whom the worst_error_ belongs. */
AsyncWriteBuffer* worst_write_buffer_;
/** Used by CallFinished (enqueue) */
util::SynchronizedQueue<CallbackEntry>& callback_queue_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_ASYNC_WRITE_HANDLER_H_

View File

@@ -0,0 +1,192 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_CLIENT_H_
#define CPP_INCLUDE_LIBXTREEMFS_CLIENT_H_
#include <list>
#include <string>
#include "libxtreemfs/typedefs.h"
#include "pbrpc/RPC.pb.h"
#include "xtreemfs/MRC.pb.h"
namespace xtreemfs {
class UUIDIterator;
namespace rpc {
class SSLOptions;
} // namespace rpc
class Options;
class UUIDResolver;
class Volume;
/**
* Provides methods to open, close, create, delete and list volumes and to
* instantiate a new client object, to start and shutdown a Client object.
*/
class Client {
public:
/** Available client implementations which are allowed by CreateClient(). */
enum ClientImplementationType {
kDefaultClient
};
/** Returns an instance of the default Client implementation.
* @param dir_service_addresses List of DIR replicas
* @param user_credentials Name and Groups of the user.
* @param ssl_options NULL if no SSL is used.
* @param options Has to contain loglevel string and logfile path.
*/
static Client* CreateClient(
const ServiceAddresses& dir_service_addresses,
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const xtreemfs::rpc::SSLOptions* ssl_options,
const Options& options);
/** Returns an instance of the chosen Client implementation. */
static Client* CreateClient(
const ServiceAddresses& dir_service_addresses,
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const xtreemfs::rpc::SSLOptions* ssl_options,
const Options& options,
ClientImplementationType type);
virtual ~Client() {}
/** Initialize a client.
*
* @remark Make sure initialize_logger was called before. */
virtual void Start() = 0;
/** A shutdown of a client will close all open volumes and block until all
* threads have exited.
*
* @throws OpenFileHandlesLeftException
*/
virtual void Shutdown() = 0;
/** Open a volume and use the returned class to access it.
* @remark Ownership is NOT transferred to the caller. Instead
* Volume->Close() has to be called to destroy the object.
*
* @throws AddressToUUIDNotFoundException
* @throws UnknownAddressSchemeException
* @throws VolumeNotFoundException
*/
virtual xtreemfs::Volume* OpenVolume(
const std::string& volume_name,
const xtreemfs::rpc::SSLOptions* ssl_options,
const Options& options) = 0;
// TODO(mberlin): Also provide a method which accepts a list of MRC addresses.
/** Creates a volume on the MRC at mrc_address using certain default values (
* POSIX access policy type, striping size = 128k and width = 1 (i.e. no
* striping), mode = 777 and owner username and groupname retrieved from the
* user_credentials.
*
* @param mrc_address One or several addresses of the form "hostname:port".
* @param auth Authentication data, e.g. of type AUTH_PASSWORD.
* @param user_credentials Username and groups of the user who executes
* CreateVolume(). Not checked so far?
* @param volume_name Name of the new volume.
*
* @throws IOException
* @throws PosixErrorException
*/
void CreateVolume(
const ServiceAddresses& mrc_address,
const xtreemfs::pbrpc::Auth& auth,
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& volume_name);
// TODO(mberlin): Also provide a method which accepts a list of MRC addresses.
/** Creates a volume on the MRC at mrc_address.
*
* @param mrc_address String of the form "hostname:port".
* @param auth Authentication data, e.g. of type AUTH_PASSWORD.
* @param user_credentials Username and groups of the user who executes
* CreateVolume().
* @param volume_name Name of the new volume.
* @param mode Mode of the volume's root directory (in octal
* representation (e.g. 511), not decimal (777)).
* @param owner_username Name of the owner user.
* @param owner_groupname Name of the owner group.
* @param access_policy_type Access policy type (Null, Posix, Volume, ...).
* @param default_striping_policy_type Only RAID0 so far.
* @param default_stripe_size Size of an object on the OSD (in kBytes).
* @param default_stripe_width Number of OSDs objects of a file are striped
* across.
* @param volume_attributes Reference to a list of key-value pairs of volume
* attributes which will bet set at creation time
* of the volume.
*
* @throws IOException
* @throws PosixErrorException
*/
virtual void CreateVolume(
const ServiceAddresses& mrc_address,
const xtreemfs::pbrpc::Auth& auth,
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& volume_name,
int mode,
const std::string& owner_username,
const std::string& owner_groupname,
const xtreemfs::pbrpc::AccessControlPolicyType& access_policy_type,
long quota,
const xtreemfs::pbrpc::StripingPolicyType& default_striping_policy_type,
int default_stripe_size,
int default_stripe_width,
const std::list<xtreemfs::pbrpc::KeyValuePair*>& volume_attributes) = 0;
// TODO(mberlin): Also provide a method which accepts a list of MRC addresses.
/** Deletes the volume "volume_name" at the MRC "mrc_address".
*
* @param mrc_address String of the form "hostname:port".
* @param auth Authentication data, e.g. of type AUTH_PASSWORD.
* @param user_credentials Username and groups of the user who executes
* CreateVolume().
* @param volume_name Name of the volume to be deleted.
*
* @throws IOException
* @throws PosixErrorException
*/
virtual void DeleteVolume(
const ServiceAddresses& mrc_address,
const xtreemfs::pbrpc::Auth& auth,
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& volume_name) = 0;
/** Returns the available volumes on a MRC.
*
* @param mrc_addresses ServiceAddresses object which
* contains MRC addresses of the
* form "hostname:port".
* @param auth Authentication data, e.g. of type AUTH_PASSWORD.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
*
* @remark Ownership of the return value is transferred to the caller. */
virtual xtreemfs::pbrpc::Volumes* ListVolumes(
const ServiceAddresses& mrc_addresses,
const xtreemfs::pbrpc::Auth& auth) = 0;
/** Resolves the address (ip-address:port) for a given UUID.
*
* @throws AddressToUUIDNotFoundException
* @throws UnknownAddressSchemeException
*/
virtual std::string UUIDToAddress(const std::string& uuid) = 0;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_CLIENT_H_

View File

@@ -0,0 +1,184 @@
/*
* Copyright (c) 2011-2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_CLIENT_IMPLEMENTATION_H_
#define CPP_INCLUDE_LIBXTREEMFS_CLIENT_IMPLEMENTATION_H_
#include <boost/scoped_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <gtest/gtest_prod.h>
#include <list>
#include <string>
#include "libxtreemfs/client.h"
#include "libxtreemfs/uuid_cache.h"
#include "libxtreemfs/simple_uuid_iterator.h"
#include "libxtreemfs/typedefs.h"
#include "libxtreemfs/uuid_resolver.h"
#include "util/synchronized_queue.h"
#include "libxtreemfs/async_write_handler.h"
namespace boost {
class thread;
} // namespace boost
namespace xtreemfs {
class Options;
class UUIDIterator;
class Vivaldi;
class Volume;
class VolumeImplementation;
namespace pbrpc {
class DIRServiceClient;
class OSDServiceClient;
} // namespace pbrpc
namespace rpc {
class Client;
class SSLOptions;
class ClientTestFastLingerTimeout_LingerTests_Test; // see FRIEND_TEST @bottom.
class ClientTestFastLingerTimeoutConnectTimeout_LingerTests_Test;
} // namespace rpc
class DIRUUIDResolver : public UUIDResolver {
public:
DIRUUIDResolver(
const ServiceAddresses& dir_service_addresses,
const pbrpc::UserCredentials& user_credentials,
const Options& options);
void Initialize(rpc::Client* network_client);
virtual void UUIDToAddress(const std::string& uuid, std::string* address);
virtual void UUIDToAddressWithOptions(const std::string& uuid,
std::string* address,
const RPCOptions& options);
virtual void VolumeNameToMRCUUID(const std::string& volume_name,
std::string* uuid);
virtual void VolumeNameToMRCUUID(const std::string& volume_name,
SimpleUUIDIterator* uuid_iterator);
private:
SimpleUUIDIterator dir_service_addresses_;
/** The auth_type of this object will always be set to AUTH_NONE. */
// TODO(mberlin): change this when the DIR service supports real auth.
pbrpc::Auth dir_service_auth_;
/** These credentials will be used for messages to the DIR service. */
const pbrpc::UserCredentials dir_service_user_credentials_;
/** A DIRServiceClient is a wrapper for an RPC Client. */
boost::scoped_ptr<pbrpc::DIRServiceClient> dir_service_client_;
/** Caches service UUIDs -> (address, port, TTL). */
UUIDCache uuid_cache_;
/** Options class which contains the log_level string and logfile path. */
const Options& options_;
};
/**
* Default Implementation of the XtreemFS C++ client interfaces.
*/
class ClientImplementation : public Client {
public:
ClientImplementation(
const ServiceAddresses& dir_service_addresses,
const pbrpc::UserCredentials& user_credentials,
const rpc::SSLOptions* ssl_options,
const Options& options);
virtual ~ClientImplementation();
virtual void Start();
virtual void Shutdown();
virtual Volume* OpenVolume(
const std::string& volume_name,
const rpc::SSLOptions* ssl_options,
const Options& options);
virtual void CloseVolume(xtreemfs::Volume* volume);
virtual void CreateVolume(
const ServiceAddresses& mrc_address,
const pbrpc::Auth& auth,
const pbrpc::UserCredentials& user_credentials,
const std::string& volume_name,
int mode,
const std::string& owner_username,
const std::string& owner_groupname,
const pbrpc::AccessControlPolicyType& access_policy,
long volume_quota,
const pbrpc::StripingPolicyType& default_striping_policy_type,
int default_stripe_size,
int default_stripe_width,
const std::list<pbrpc::KeyValuePair*>& volume_attributes);
virtual void DeleteVolume(
const ServiceAddresses& mrc_address,
const pbrpc::Auth& auth,
const pbrpc::UserCredentials& user_credentials,
const std::string& volume_name);
virtual pbrpc::Volumes* ListVolumes(
const ServiceAddresses& mrc_addresses,
const pbrpc::Auth& auth);
virtual UUIDResolver* GetUUIDResolver();
virtual std::string UUIDToAddress(const std::string& uuid);
const pbrpc::VivaldiCoordinates& GetVivaldiCoordinates() const;
util::SynchronizedQueue<AsyncWriteHandler::CallbackEntry>& GetAsyncWriteCallbackQueue();
private:
/** True if Shutdown() was executed. */
bool was_shutdown_;
/** Auth of type AUTH_NONE which is required for most operations which do not
* check the authentication data (except Create, Delete, ListVolume(s)). */
xtreemfs::pbrpc::Auth auth_bogus_;
/** Options class which contains the log_level string and logfile path. */
const xtreemfs::Options& options_;
std::list<VolumeImplementation*> list_open_volumes_;
boost::mutex list_open_volumes_mutex_;
const rpc::SSLOptions* dir_service_ssl_options_;
/** The RPC Client processes requests from a queue and executes callbacks in
* its thread. */
boost::scoped_ptr<rpc::Client> network_client_;
boost::scoped_ptr<boost::thread> network_client_thread_;
DIRUUIDResolver uuid_resolver_;
/** Random, non-persistent UUID to distinguish locks of different clients. */
std::string client_uuid_;
/** Vivaldi thread, periodically updates vivaldi-coordinates. */
boost::scoped_ptr<boost::thread> vivaldi_thread_;
boost::scoped_ptr<Vivaldi> vivaldi_;
boost::scoped_ptr<pbrpc::OSDServiceClient> osd_service_client_;
/** Thread that handles the callbacks for asynchronous writes. */
boost::scoped_ptr<boost::thread> async_write_callback_thread_;
/** Holds the Callbacks enqueued be CallFinished() (producer). They are
* processed by ProcessCallbacks(consumer), running in its own thread. */
util::SynchronizedQueue<AsyncWriteHandler::CallbackEntry> async_write_callback_queue_;
FRIEND_TEST(rpc::ClientTestFastLingerTimeout, LingerTests);
FRIEND_TEST(rpc::ClientTestFastLingerTimeoutConnectTimeout, LingerTests);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_CLIENT_IMPLEMENTATION_H_

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_CONTAINER_UUID_ITERATOR_H_
#define CPP_INCLUDE_LIBXTREEMFS_CONTAINER_UUID_ITERATOR_H_
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <gtest/gtest_prod.h>
#include <list>
#include <string>
#include "libxtreemfs/uuid_item.h"
#include "libxtreemfs/uuid_iterator.h"
#include "libxtreemfs/uuid_container.h"
namespace xtreemfs {
/** This class is a UUIDIterator that does not own its UUIDItems. Instead it
* references a subset of UUIDItems stored in a UUIDContainer. The iterator
* is initialized on construction and does not change during its lifetime.
* The main use-case of this class is the OSD-addressing in a striped setup.
* Such a setup can include multiple replicas, each with a different striping
* configuration. So each object can have its individual list of OSDs over all
* replicas. This list is needed in order to support redirection and automatic
* fail-over. ContainerUUIDIterator stores this list. The UUIDContainer is
* stored as a shared pointer at each UUIDIterator to ensure UUIDItems remain
* valid as long as the UUIDIterator exists. */
class ContainerUUIDIterator : public UUIDIterator {
public:
/** This ctor initializes the iterator from a given UUIDContainer and a
* vector of offsets. The offsets specify indices in the two-dimensional
* container. */
ContainerUUIDIterator(boost::shared_ptr<UUIDContainer> uuid_container,
std::vector<size_t> offsets)
: uuid_container_(uuid_container) {
uuid_container_->FillUUIDIterator(this, offsets);
}
virtual void SetCurrentUUID(const std::string& uuid);
private:
/** Reference to the container, this iterator and its UUIDs are derived from.
* The container has to outlast every iterator and thus has to use a smart
* pointer with reference counting.
*/
boost::shared_ptr<UUIDContainer> uuid_container_;
// UUIDContainer is a friend of this class
friend void UUIDContainer::FillUUIDIterator(
ContainerUUIDIterator* uuid_iterator, std::vector<size_t> offsets);
// the following is for testing
template<class T> friend struct UUIDAdder;
template<class T> friend UUIDIterator* CreateUUIDIterator();
/** Only for testing and UUIDContainer */
ContainerUUIDIterator() {}
/** Only for testing and UUIDContainer */
virtual void Clear();
/** Add an existing UUIDItem. Ownership is NOT transferred.
* It can only be called by UUIDContainer::GetUUIDIterator, hence the
* friend-declaration above. */
void AddUUIDItem(UUIDItem* uuid);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_CONTAINER_UUID_ITERATOR_H_

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_CALLBACK_EXECUTE_SYNC_REQUEST_H_
#define CPP_INCLUDE_LIBXTREEMFS_CALLBACK_EXECUTE_SYNC_REQUEST_H_
#include <boost/function.hpp>
#include <string>
namespace xtreemfs {
namespace rpc {
class ClientRequestCallbackInterface;
class SyncCallbackBase;
} // namespace rpc
namespace pbrpc {
class XCap;
} // namespace pbrpc
class UUIDIterator;
class UUIDResolver;
class Options;
class XCapHandler;
class RPCOptions {
public:
typedef boost::function0<int> WasInterruptedCallback;
RPCOptions(int max_retries,
int retry_delay_s,
bool delay_last_attempt,
WasInterruptedCallback was_interrupted_cb)
: max_retries_(max_retries),
retry_delay_s_(retry_delay_s),
delay_last_attempt_(delay_last_attempt),
was_interrupted_cb_(was_interrupted_cb) {}
RPCOptions(int max_retries,
int retry_delay_s,
WasInterruptedCallback was_interrupted_cb)
: max_retries_(max_retries),
retry_delay_s_(retry_delay_s),
delay_last_attempt_(false),
was_interrupted_cb_(was_interrupted_cb) {}
int max_retries() const {
return max_retries_;
}
int retry_delay_s() const {
return retry_delay_s_;
}
bool delay_last_attempt() const {
return delay_last_attempt_;
}
WasInterruptedCallback was_interrupted_cb() const {
return was_interrupted_cb_;
}
private:
int max_retries_;
int retry_delay_s_;
bool delay_last_attempt_;
WasInterruptedCallback was_interrupted_cb_;
};
/** Retries to execute the synchronous request "sync_function" up to "options.
* max_tries" times and may get interrupted. The "uuid_iterator" object is used
* to retrieve UUIDs or mark them as failed.
* If uuid_iterator_has_addresses=true, the resolving of the UUID is skipped
* and the string retrieved by uuid_iterator->GetUUID() is used as address.
* (in this case uuid_resolver may be NULL).
*
* The parameter delay_last_attempt should be set true, if this method is
* called with max_tries = 1 and one does the looping over the retries on its
* own (for instance in FileHandleImplementation::AcquireLock). If set to false
* this method would return immediately after the _last_ try and the caller would
* have to ensure the delay of options.retry_delay_s on its own.
*
* Ownership of arguments is NOT transferred.
*
*/
rpc::SyncCallbackBase* ExecuteSyncRequest(
boost::function<rpc::SyncCallbackBase* (const std::string&)> sync_function,
UUIDIterator* uuid_iterator,
UUIDResolver* uuid_resolver,
const RPCOptions& options,
bool uuid_iterator_has_addresses,
XCapHandler* xcap_handler,
xtreemfs::pbrpc::XCap* xcap_in_req);
/** Executes the request without delaying the last try and no xcap handler. */
rpc::SyncCallbackBase* ExecuteSyncRequest(
boost::function<rpc::SyncCallbackBase* (const std::string&)> sync_function,
UUIDIterator* uuid_iterator,
UUIDResolver* uuid_resolver,
const RPCOptions& options);
/** Executes the request without a xcap handler. */
rpc::SyncCallbackBase* ExecuteSyncRequest(
boost::function<rpc::SyncCallbackBase* (const std::string&)> sync_function,
UUIDIterator* uuid_iterator,
UUIDResolver* uuid_resolver,
const RPCOptions& options,
bool uuid_iterator_has_addresses);
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_CALLBACK_EXECUTE_SYNC_REQUEST_H_

View File

@@ -0,0 +1,249 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_FILE_HANDLE_H_
#define CPP_INCLUDE_LIBXTREEMFS_FILE_HANDLE_H_
#include <stdint.h>
namespace xtreemfs {
namespace pbrpc {
class Lock;
class Stat;
class UserCredentials;
} // namespace pbrpc
class FileHandle {
public:
virtual ~FileHandle() {}
/** Read from a file 'count' bytes starting at 'offset' into 'buf'.
*
* @param buf[out] Buffer to be filled with read data.
* @param count Number of requested bytes.
* @param offset Offset in bytes.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @return Number of bytes read.
*/
virtual int Read(
char *buf,
size_t count,
int64_t offset) = 0;
/** Write to a file 'count' bytes at file offset 'offset' from 'buf'.
*
* @attention If asynchronous writes are enabled (which is the default
* unless the file was opened with O_SYNC or async writes
* were disabled globally), no possible write errors can be
* returned as Write() does return immediately after putting
* the write request into the send queue instead of waiting
* until the result was received.
* In this case, only after calling Flush() or Close() occurred
* write errors are returned to the user.
*
* @param buf[in] Buffer which contains data to be written.
* @param count Number of bytes to be written from buf.
* @param offset Offset in bytes.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @return Number of bytes written (see @attention above).
*/
virtual int Write(
const char *buf,
size_t count,
int64_t offset) = 0;
/** Flushes pending writes and file size updates (corresponds to a fsync()
* system call).
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void Flush() = 0;
/** Truncates the file to "new_file_size_ bytes".
*
* @param user_credentials Name and Groups of the user.
* @param new_file_size New size of the file.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
**/
virtual void Truncate(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
int64_t new_file_size) = 0;
/** Retrieve the attributes of this file and writes the result in "stat".
*
* @param user_credentials Name and Groups of the user.
* @param stat Pointer to Stat which will be overwritten.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void GetAttr(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
xtreemfs::pbrpc::Stat* stat) = 0;
/** Sets a lock on the specified file region and returns the resulting Lock
* object.
*
* If the acquisition of the lock fails, PosixErrorException will be thrown
* and posix_errno() will return POSIX_ERROR_EAGAIN.
*
* @param process_id ID of the process to which the lock belongs.
* @param offset Start of the region to be locked in the file.
* @param length Length of the region.
* @param exclusive shared/read lock (false) or write/exclusive (true)?
* @param wait_for_lock if true, blocks until lock acquired.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @remark Ownership is transferred to the caller.
*/
virtual xtreemfs::pbrpc::Lock* AcquireLock(
int process_id,
uint64_t offset,
uint64_t length,
bool exclusive,
bool wait_for_lock) = 0;
/** Checks if the requested lock does not result in conflicts. If true, the
* returned Lock object contains the requested 'process_id' in 'client_pid',
* otherwise the Lock object is a copy of the conflicting lock.
*
* @param process_id ID of the process to which the lock belongs.
* @param offset Start of the region to be locked in the file.
* @param length Length of the region.
* @param exclusive shared/read lock (false) or write/exclusive (true)?
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @remark Ownership is transferred to the caller.
*/
virtual xtreemfs::pbrpc::Lock* CheckLock(
int process_id,
uint64_t offset,
uint64_t length,
bool exclusive) = 0;
/** Releases "lock".
*
* @param process_id ID of the process to which the lock belongs.
* @param offset Start of the region to be locked in the file.
* @param length Length of the region.
* @param exclusive shared/read lock (false) or write/exclusive (true)?
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void ReleaseLock(
int process_id,
uint64_t offset,
uint64_t length,
bool exclusive) = 0;
/** Releases "lock" (parameters given in Lock object).
*
* @param lock Lock to be released.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void ReleaseLock(
const xtreemfs::pbrpc::Lock& lock) = 0;
/** Releases the lock possibly hold by "process_id". Use this before closing
* a file to ensure POSIX semantics:
*
* "All locks associated with a file for a given process shall be removed
* when a file descriptor for that file is closed by that process or the
* process holding that file descriptor terminates."
* (http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html)
*
* @param process_id ID of the process whose lock shall be released.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void ReleaseLockOfProcess(int process_id) = 0;
/** Triggers the replication of the replica on the OSD with the UUID
* "osd_uuid" if the replica is a full replica (and not a partial one).
*
* The Replica had to be added beforehand and "osd_uuid" has to be included
* in the XlocSet of the file.
*
* @param user_credentials Name and Groups of the user.
* @param osd_uuid UUID of the OSD where the replica is located.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
* @throws UUIDNotInXlocSetException
*/
virtual void PingReplica(
const std::string& osd_uuid) = 0;
/** Closes the open file handle (flushing any pending data).
*
* @attention The libxtreemfs implementation does NOT count the number of
* pending operations. Make sure that there're no pending
* operations on the FileHandle before you Close() it.
*
* @attention Please execute ReleaseLockOfProcess() first if there're multiple
* open file handles for the same file and you want to ensure the
* POSIX semantics that with the close of a file handle the lock
* (XtreemFS allows only one per tuple (client UUID, Process ID))
* of the process will be closed.
* If you do not care about this, you don't have to release any
* locks on your own as all locks will be automatically released if
* the last open file handle of a file will be closed.
*
* @throws AddressToUUIDNotFoundException
* @throws FileInfoNotFoundException
* @throws FileHandleNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void Close() = 0;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_FILE_HANDLE_H_

View File

@@ -0,0 +1,384 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_FILE_HANDLE_IMPLEMENTATION_H_
#define CPP_INCLUDE_LIBXTREEMFS_FILE_HANDLE_IMPLEMENTATION_H_
#include <stdint.h>
#include <boost/function.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest_prod.h>
#include <map>
#include <string>
#include "pbrpc/RPC.pb.h"
#include "rpc/callback_interface.h"
#include "xtreemfs/GlobalTypes.pb.h"
#include "xtreemfs/MRC.pb.h"
#include "libxtreemfs/client_implementation.h"
#include "libxtreemfs/file_handle.h"
#include "libxtreemfs/interrupt.h"
#include "libxtreemfs/xcap_handler.h"
namespace xtreemfs {
namespace rpc {
class SyncCallbackBase;
} // namespace rpc
namespace pbrpc {
class FileCredentials;
class Lock;
class MRCServiceClient;
class OSDServiceClient;
class readRequest;
class writeRequest;
} // namespace pbrpc
class FileInfo;
class ObjectCache;
class Options;
class StripeTranslator;
class UUIDIterator;
class UUIDResolver;
class Volume;
class XCapManager;
class XCapManager :
public rpc::CallbackInterface<xtreemfs::pbrpc::XCap>,
public XCapHandler {
public:
XCapManager(
const xtreemfs::pbrpc::XCap& xcap,
pbrpc::MRCServiceClient* mrc_service_client,
UUIDResolver* uuid_resolver,
UUIDIterator* mrc_uuid_iterator,
const pbrpc::Auth& auth_bogus,
const pbrpc::UserCredentials& user_credentials_bogus);
/** Renew xcap_ asynchronously. */
void RenewXCapAsync(const RPCOptions& options);
/** Blocks until the callback has completed (if an XCapRenewal is pending). */
void WaitForPendingXCapRenewal();
/** XCapHandler: Get current capability.*/
virtual void GetXCap(xtreemfs::pbrpc::XCap* xcap);
/** Update the capability with the provided one. */
void SetXCap(const xtreemfs::pbrpc::XCap& xcap);
/** Get the file id from the capability. */
uint64_t GetFileId();
private:
/** Implements callback for an async xtreemfs_renew_capability request. */
virtual void CallFinished(xtreemfs::pbrpc::XCap* new_xcap,
char* data,
uint32_t data_length,
pbrpc::RPCHeader::ErrorResponse* error,
void* context);
/** Any modification to the object must obtain a lock first. */
boost::mutex mutex_;
/** Capabilitiy for the file, used to authorize against services */
xtreemfs::pbrpc::XCap xcap_;
/** True if there is an outstanding xcap_renew callback. */
bool xcap_renewal_pending_;
/** Used to wait for pending XCap renewal callbacks. */
boost::condition xcap_renewal_pending_cond_;
/** UUIDIterator of the MRC. */
pbrpc::MRCServiceClient* mrc_service_client_;
UUIDResolver* uuid_resolver_;
UUIDIterator* mrc_uuid_iterator_;
/** Auth needed for ServiceClients. Always set to AUTH_NONE by Volume. */
const pbrpc::Auth auth_bogus_;
/** For same reason needed as auth_bogus_. Always set to user "xtreemfs". */
const pbrpc::UserCredentials user_credentials_bogus_;
};
/** Default implementation of the FileHandle Interface. */
class FileHandleImplementation
: public FileHandle,
public XCapHandler,
public rpc::CallbackInterface<pbrpc::timestampResponse> {
public:
FileHandleImplementation(
ClientImplementation* client,
const std::string& client_uuid,
FileInfo* file_info,
const pbrpc::XCap& xcap,
UUIDIterator* mrc_uuid_iterator,
UUIDIterator* osd_uuid_iterator,
UUIDResolver* uuid_resolver,
pbrpc::MRCServiceClient* mrc_service_client,
pbrpc::OSDServiceClient* osd_service_client,
const std::map<pbrpc::StripingPolicyType,
StripeTranslator*>& stripe_translators,
bool async_writes_enabled,
ObjectCache* object_cache, // owned by the caller
const Options& options,
const pbrpc::Auth& auth_bogus,
const pbrpc::UserCredentials& user_credentials_bogus);
virtual ~FileHandleImplementation();
virtual int Read(char *buf, size_t count, int64_t offset);
virtual int Write(const char *buf, size_t count, int64_t offset);
virtual void Flush();
virtual void Truncate(
const pbrpc::UserCredentials& user_credentials,
int64_t new_file_size);
/** Used by Truncate() and Volume->OpenFile() to truncate the file to
* "new_file_size" on the OSD and update the file size at the MRC.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
**/
void TruncatePhaseTwoAndThree(int64_t new_file_size);
virtual void GetAttr(
const pbrpc::UserCredentials& user_credentials,
pbrpc::Stat* stat);
virtual xtreemfs::pbrpc::Lock* AcquireLock(
int process_id,
uint64_t offset,
uint64_t length,
bool exclusive,
bool wait_for_lock);
virtual xtreemfs::pbrpc::Lock* CheckLock(
int process_id,
uint64_t offset,
uint64_t length,
bool exclusive);
virtual void ReleaseLock(
int process_id,
uint64_t offset,
uint64_t length,
bool exclusive);
/** Also used by FileInfo object to free active locks. */
void ReleaseLock(const pbrpc::Lock& lock);
virtual void ReleaseLockOfProcess(int process_id);
virtual void PingReplica(const std::string& osd_uuid);
virtual void Close();
/** Returns the StripingPolicy object for a given type (e.g. Raid0).
*
* @remark Ownership is NOT transferred to the caller.
*/
const StripeTranslator* GetStripeTranslator(
pbrpc::StripingPolicyType type);
/** Sets async_writes_failed_ to true. */
void MarkAsyncWritesAsFailed();
/** Thread-safe check if async_writes_failed_ */
bool DidAsyncWritesFail();
/** Thread-safe check and throw if async_writes_failed_ */
void ThrowIfAsyncWritesFailed();
/** Sends pending file size updates synchronous (needed for flush/close).
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
void WriteBackFileSize(const pbrpc::OSDWriteResponse& owr,
bool close_file);
/** Sends osd_write_response_for_async_write_back_ asynchronously. */
void WriteBackFileSizeAsync(const RPCOptions& options);
/** Overwrites the current osd_write_response_ with "owr". */
void set_osd_write_response_for_async_write_back(
const pbrpc::OSDWriteResponse& owr);
/** Wait for all asyncronous operations to finish */
void WaitForAsyncOperations();
/** Execute period tasks */
void ExecutePeriodTasks(const RPCOptions& options);
/** XCapHandler: Get current capability. */
virtual void GetXCap(xtreemfs::pbrpc::XCap* xcap);
private:
/**
* Execute the operation and check on invalid view exceptions.
* If the operation was executed with an outdated, the view
* will be renewed and the operation retried.
*/
template<typename T>
T ExecuteViewCheckedOperation(boost::function<T()> operation);
/** Renew the xLocSet synchronously. */
void RenewXLocSet();
/** Implements callback for an async xtreemfs_update_file_size request. */
virtual void CallFinished(
pbrpc::timestampResponse* response_message,
char* data,
uint32_t data_length,
pbrpc::RPCHeader::ErrorResponse* error,
void* context);
/** Same as Flush(), takes special actions if called by Close(). */
void Flush(bool close_file);
/** Actual implementation of Flush(). */
void DoFlush(bool close_file);
/** Actual implementation of Read(). */
int DoRead(
char *buf,
size_t count,
int64_t offset);
/** Read data from the OSD. Objects owned by the caller. */
int ReadFromOSD(
UUIDIterator* uuid_iterator,
const pbrpc::FileCredentials& file_credentials,
int object_no,
char* buffer,
int offset_in_object,
int bytes_to_read);
/** Actual implementation of Write(). */
int DoWrite(
const char *buf,
size_t count,
int64_t offset);
/** Write data to the OSD. Objects owned by the caller. */
void WriteToOSD(
UUIDIterator* uuid_iterator,
const pbrpc::FileCredentials& file_credentials,
int object_no,
int offset_in_object,
const char* buffer,
int bytes_to_write);
/** Acutal implementation of TruncatePhaseTwoAndThree(). */
void DoTruncatePhaseTwoAndThree(int64_t new_file_size);
/** Actual implementation of AcquireLock(). */
xtreemfs::pbrpc::Lock* DoAcquireLock(
int process_id,
uint64_t offset,
uint64_t length,
bool exclusive,
bool wait_for_lock);
/** Actual implementation of CheckLock(). */
xtreemfs::pbrpc::Lock* DoCheckLock(
int process_id,
uint64_t offset,
uint64_t length,
bool exclusive);
/** Actual implementation of ReleaseLock(). */
void DoReleaseLock(const pbrpc::Lock& lock);
/** Actual implementation of PingReplica(). */
void DoPingReplica(const std::string& osd_uuid);
/** Any modification to the object must obtain a lock first. */
boost::mutex mutex_;
/** Reference to Client which did open this volume. */
ClientImplementation* client_;
/** UUID of the Client (needed to distinguish Locks of different clients). */
const std::string& client_uuid_;
/** UUIDIterator of the MRC. */
UUIDIterator* mrc_uuid_iterator_;
/** UUIDIterator which contains the UUIDs of all replicas. */
UUIDIterator* osd_uuid_iterator_;
/** Needed to resolve UUIDs. */
UUIDResolver* uuid_resolver_;
/** Multiple FileHandle may refer to the same File and therefore unique file
* properties (e.g. Path, FileId, XlocSet) are stored in a FileInfo object. */
FileInfo* file_info_;
// TODO(mberlin): Add flags member.
/** Contains a file size update which has to be written back (or NULL). */
boost::scoped_ptr<pbrpc::OSDWriteResponse>
osd_write_response_for_async_write_back_;
/** Pointer to object owned by VolumeImplemention */
pbrpc::MRCServiceClient* mrc_service_client_;
/** Pointer to object owned by VolumeImplemention */
pbrpc::OSDServiceClient* osd_service_client_;
const std::map<pbrpc::StripingPolicyType,
StripeTranslator*>& stripe_translators_;
/** Set to true if async writes (max requests > 0, no O_SYNC) are enabled. */
const bool async_writes_enabled_;
/** Set to true if an async write of this file_handle failed. If true, this
* file_handle is broken and no further writes/reads/truncates are possible.
*/
bool async_writes_failed_;
/** The object cache, or NULL if not enabled. */
ObjectCache* object_cache_;
const Options& volume_options_;
/** Auth needed for ServiceClients. Always set to AUTH_NONE by Volume. */
const pbrpc::Auth& auth_bogus_;
/** For same reason needed as auth_bogus_. Always set to user "xtreemfs". */
const pbrpc::UserCredentials& user_credentials_bogus_;
XCapManager xcap_manager_;
FRIEND_TEST(VolumeImplementationTestFastPeriodicFileSizeUpdate,
WorkingPendingFileSizeUpdates);
FRIEND_TEST(VolumeImplementationTest, FileSizeUpdateAfterFlush);
FRIEND_TEST(VolumeImplementationTestFastPeriodicFileSizeUpdate,
FileSizeUpdateAfterFlushWaitsForPendingUpdates);
FRIEND_TEST(VolumeImplementationTestFastPeriodicXCapRenewal,
WorkingXCapRenewal);
FRIEND_TEST(VolumeImplementationTest, FilesLockingReleaseNonExistantLock);
FRIEND_TEST(VolumeImplementationTest, FilesLockingReleaseExistantLock);
FRIEND_TEST(VolumeImplementationTest, FilesLockingLastCloseReleasesAllLocks);
FRIEND_TEST(VolumeImplementationTest, FilesLockingReleaseLockOfProcess);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_FILE_HANDLE_IMPLEMENTATION_H_

View File

@@ -0,0 +1,348 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_FILE_INFO_H_
#define CPP_INCLUDE_LIBXTREEMFS_FILE_INFO_H_
#include <stdint.h>
#include <boost/optional.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp>
#include <gtest/gtest_prod.h>
#include <list>
#include <map>
#include <string>
#include "libxtreemfs/async_write_handler.h"
#include "libxtreemfs/client_implementation.h"
#include "libxtreemfs/object_cache.h"
#include "libxtreemfs/simple_uuid_iterator.h"
#include "libxtreemfs/uuid_container.h"
#include "xtreemfs/GlobalTypes.pb.h"
namespace xtreemfs {
class FileHandleImplementation;
class VolumeImplementation;
namespace pbrpc {
class Lock;
class Stat;
class UserCredentials;
} // namespace pbrpc
/** Different states regarding osd_write_response_ and its write back. */
enum FilesizeUpdateStatus {
kClean, kDirty, kDirtyAndAsyncPending, kDirtyAndSyncPending
};
class FileInfo {
public:
FileInfo(ClientImplementation* client,
VolumeImplementation* volume,
uint64_t file_id,
const std::string& path,
bool replicate_on_close,
const xtreemfs::pbrpc::XLocSet& xlocset,
const std::string& client_uuid);
~FileInfo();
/** Returns a new FileHandle object to which xcap belongs.
*
* @remark Ownership is transferred to the caller.
*/
FileHandleImplementation* CreateFileHandle(const xtreemfs::pbrpc::XCap& xcap,
bool async_writes_enabled);
/** See CreateFileHandle(xcap). Does not add file_handle to list of open
* file handles if used_for_pending_filesize_update=true.
*
* This function will be used if a FileHandle was solely created to
* asynchronously write back a dirty file size update (osd_write_response_).
*
* @remark Ownership is transferred to the caller.
*/
FileHandleImplementation* CreateFileHandle(
const xtreemfs::pbrpc::XCap& xcap,
bool async_writes_enabled,
bool used_for_pending_filesize_update);
/** Deregisters a closed FileHandle. Called by FileHandle::Close(). */
void CloseFileHandle(FileHandleImplementation* file_handle);
/** Decreases the reference count and returns the current value. */
int DecreaseReferenceCount();
/** Copies osd_write_response_ into response if not NULL. */
void GetOSDWriteResponse(xtreemfs::pbrpc::OSDWriteResponse* response);
/** Writes path_ to path. */
void GetPath(std::string* path);
/** Changes path_ to new_path if path_ == path. */
void RenamePath(const std::string& path, const std::string& new_path);
/** Compares "response" against the current "osd_write_response_". Returns
* true if response is newer and assigns "response" to "osd_write_response_".
*
* If successful, a new file handle will be created and xcap is required to
* send the osd_write_response to the MRC in the background.
*
* @remark Ownership of response is transferred to this object if this
* method returns true. */
bool TryToUpdateOSDWriteResponse(xtreemfs::pbrpc::OSDWriteResponse* response,
const xtreemfs::pbrpc::XCap& xcap);
/** Merge into a possibly outdated Stat object (e.g. from the StatCache) the
* current file size and truncate_epoch from a stored OSDWriteResponse. */
void MergeStatAndOSDWriteResponse(xtreemfs::pbrpc::Stat* stat);
/** Sends pending file size updates to the MRC asynchronously. */
void WriteBackFileSizeAsync(const RPCOptions& options);
/** Renews xcap of all file handles of this file asynchronously. */
void RenewXCapsAsync(const RPCOptions& options);
/** Releases all locks of process_id using file_handle to issue
* ReleaseLock(). */
void ReleaseLockOfProcess(FileHandleImplementation* file_handle,
int process_id);
/** Uses file_handle to release all known local locks. */
void ReleaseAllLocks(FileHandleImplementation* file_handle);
/** Blocks until all asynchronous file size updates are completed. */
void WaitForPendingFileSizeUpdates();
/** Called by the file size update callback of FileHandle. */
void AsyncFileSizeUpdateResponseHandler(
const xtreemfs::pbrpc::OSDWriteResponse& owr,
FileHandleImplementation* file_handle,
bool success);
/** Passes FileHandle::GetAttr() through to Volume. */
void GetAttr(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
xtreemfs::pbrpc::Stat* stat);
/** Compares "lock" against list of active locks.
*
* Sets conflict_found to true and copies the conflicting, active lock into
* "conflicting_lock".
* If no conflict was found, "lock_for_pid_cached" is set to true if there
* exists already a lock for lock.client_pid(). Additionally,
* "cached_lock_for_pid_equal" will be set to true, lock is equal to the lock
* active for this pid. */
void CheckLock(const xtreemfs::pbrpc::Lock& lock,
xtreemfs::pbrpc::Lock* conflicting_lock,
bool* lock_for_pid_cached,
bool* cached_lock_for_pid_equal,
bool* conflict_found);
/** Returns true if a lock for "process_id" is known. */
bool CheckIfProcessHasLocks(int process_id);
/** Add a copy of "lock" to list of active locks. */
void PutLock(const xtreemfs::pbrpc::Lock& lock);
/** Remove locks equal to "lock" from list of active locks. */
void DelLock(const xtreemfs::pbrpc::Lock& lock);
/** Flushes pending async writes and file size updates. */
void Flush(FileHandleImplementation* file_handle);
/** Same as Flush(), takes special actions if called by FileHandle::Close().*/
void Flush(FileHandleImplementation* file_handle, bool close_file);
/** Flushes a pending file size update. */
void FlushPendingFileSizeUpdate(FileHandleImplementation* file_handle);
/** Calls async_write_handler_.Write().
*
* @remark Ownership of write_buffer is transferred to caller.
*/
void AsyncWrite(AsyncWriteBuffer* write_buffer);
/** Calls async_write_handler_.WaitForPendingWrites() (resulting in blocking
* until all pending async writes are finished).
*/
void WaitForPendingAsyncWrites();
/** Returns result of async_write_handler_.WaitForPendingWritesNonBlocking().
*
* @remark Ownership is not transferred to the caller.
*/
bool WaitForPendingAsyncWritesNonBlocking(
boost::condition* condition_variable,
bool* wait_completed,
boost::mutex* wait_completed_mutex);
void UpdateXLocSetAndRest(const xtreemfs::pbrpc::XLocSet& new_xlocset,
bool replicate_on_close);
void UpdateXLocSetAndRest(const xtreemfs::pbrpc::XLocSet& new_xlocset);
/** Copies the XlocSet into new_xlocset. */
void GetXLocSet(xtreemfs::pbrpc::XLocSet* new_xlocset);
/** Copies the XlocSet into new_xlocset
* and returns the corresponding UUIDContainer.
* The UUIDcontainer is just valid for the associated XLocSet.
*/
boost::shared_ptr<UUIDContainer> GetXLocSetAndUUIDContainer(
xtreemfs::pbrpc::XLocSet* new_xlocset);
/** Non-recursive scoped lock which is used to prevent concurrent XLocSet
* renewals from multiple FileHandles associated to the same FileInfo.
*
* @see FileHandleImplementation::RenewXLocSet
*/
class XLocSetRenewalLock {
private:
boost::mutex& m_;
public:
XLocSetRenewalLock(FileInfo* file_info) :
m_(file_info->xlocset_renewal_mutex_) {
m_.lock();
}
~XLocSetRenewalLock() {
m_.unlock();
}
};
private:
/** Same as FlushPendingFileSizeUpdate(), takes special actions if called by Close(). */
void FlushPendingFileSizeUpdate(FileHandleImplementation* file_handle,
bool close_file);
/** See WaitForPendingFileSizeUpdates(). */
void WaitForPendingFileSizeUpdatesHelper(boost::mutex::scoped_lock* lock);
/** Reference to Client which did open this volume. */
ClientImplementation* client_;
/** Volume which did open this file. */
VolumeImplementation* volume_;
/** XtreemFS File ID of this file (does never change). */
uint64_t file_id_;
/** Path of the File, used for debug output and writing back the
* OSDWriteResponse to the MetadataCache. */
std::string path_;
/** Extracted from the FileHandle's XCap: true if an explicit close() has to
* be send to the MRC in order to trigger the on close replication. */
bool replicate_on_close_;
/** Number of file handles which hold a pointer on this object. */
int reference_count_;
/** Use this to protect reference_count_ and path_. */
boost::mutex mutex_;
/** List of corresponding OSDs. */
xtreemfs::pbrpc::XLocSet xlocset_;
/** UUIDIterator which contains the head OSD UUIDs of all replicas.
* It is used for non-striped files. */
SimpleUUIDIterator osd_uuid_iterator_;
/** This UUIDContainer contains all OSD UUIDs for all replicas and is
* constructed from the xlocset_ passed to this class on construction.
* It is used to construct a custom ContainerUUIDIterator on the fly when
* accessing striped files.
* It is managed by a smart pointer, because it has to outlast every
* ContainerUUIDIterator derived from it.
* */
boost::shared_ptr<UUIDContainer> osd_uuid_container_;
/** Use this to protect xlocset_ and replicate_on_close_. */
boost::mutex xlocset_mutex_;
/** Use this to protect xlocset_ renewals. */
boost::mutex xlocset_renewal_mutex_;
/** List of active locks (acts as a cache). The OSD allows only one lock per
* (client UUID, PID) tuple. */
std::map<unsigned int, xtreemfs::pbrpc::Lock*> active_locks_;
/** Use this to protect active_locks_. */
boost::mutex active_locks_mutex_;
/** Random UUID of this client to distinguish them while locking. */
const std::string& client_uuid_;
/** List of open FileHandles for this file. */
std::list<FileHandleImplementation*> open_file_handles_;
/** Use this to protect open_file_handles_. */
boost::mutex open_file_handles_mutex_;
/** List of open FileHandles which solely exist to propagate a pending
* file size update (a OSDWriteResponse object) to the MRC.
*
* This extra list is needed to distinguish between the regular file handles
* (see open_file_handles_) and the ones used for file size updates.
* The intersection of both lists is empty.
*/
std::list<FileHandleImplementation*> pending_filesize_updates_;
/** Pending file size update after a write() operation, may be NULL.
*
* If osd_write_response_ != NULL, the file_size and truncate_epoch of the
* referenced OSDWriteResponse have to be respected, e.g. when answering
* a GetAttr request.
* When all file handles to a file are closed, the information of the
* stored osd_write_response_ will be merged back into the metadata cache.
* This osd_write_response_ also corresponds to the "maximum" of all known
* OSDWriteReponses. The maximum has the highest truncate_epoch, or if equal
* compared to another response, the higher size_in_bytes value.
*/
boost::scoped_ptr<xtreemfs::pbrpc::OSDWriteResponse> osd_write_response_;
/** Denotes the state of the stored osd_write_response_ object. */
FilesizeUpdateStatus osd_write_response_status_;
/** XCap required to send an OSDWriteResponse to the MRC. */
xtreemfs::pbrpc::XCap osd_write_response_xcap_;
/** Always lock to access osd_write_response_, osd_write_response_status_,
* osd_write_response_xcap_ or pending_filesize_updates_. */
boost::mutex osd_write_response_mutex_;
/** Used by NotifyFileSizeUpdateCompletition() to notify waiting threads. */
boost::condition osd_write_response_cond_;
/** Proceeds async writes, handles the callbacks and provides a
* WaitForPendingWrites() method for barrier operations like read. */
AsyncWriteHandler async_write_handler_;
/** A cache for objects of this file. Maybe NULL in which case the
* cache is disabled. */
boost::scoped_ptr<ObjectCache> object_cache_;
FRIEND_TEST(VolumeImplementationTestFastPeriodicFileSizeUpdate,
WorkingPendingFileSizeUpdates);
FRIEND_TEST(VolumeImplementationTest, FileSizeUpdateAfterFlush);
FRIEND_TEST(VolumeImplementationTestFastPeriodicFileSizeUpdate,
FileSizeUpdateAfterFlushWaitsForPendingUpdates);
FRIEND_TEST(VolumeImplementationTest, FilesLockingReleaseNonExistantLock);
FRIEND_TEST(VolumeImplementationTest, FilesLockingReleaseExistantLock);
FRIEND_TEST(VolumeImplementationTest, FilesLockingLastCloseReleasesAllLocks);
FRIEND_TEST(VolumeImplementationTest, FilesLockingReleaseLockOfProcess);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_FILE_INFO_H_

View File

@@ -0,0 +1,153 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_HELPER_H_
#define CPP_INCLUDE_LIBXTREEMFS_HELPER_H_
#include <stdint.h>
#include <boost/unordered_set.hpp>
#include <string>
#include "xtreemfs/GlobalTypes.pb.h"
#include <libxtreemfs/execute_sync_request.h>
#ifdef __linux__
#include <ifaddrs.h>
#endif // __linux__
namespace xtreemfs {
namespace pbrpc {
class Lock;
class OSDWriteResponse;
class Stat;
class XCap;
class XLocSet;
} // namespace pbrpc
/** Returns -1, 0 or 1 if "new_response" is less than, equal or greater than
* "current_response" in "XtreemFS terms".
*
* Those terms are:
* - two responses are equal if their truncate_epoch and file size are equal.
* - a response is greater if a) its truncate epoch is higher OR
* b) if both truncate epochs are equal and its
* file size is higher. */
int CompareOSDWriteResponses(
const xtreemfs::pbrpc::OSDWriteResponse* new_response,
const xtreemfs::pbrpc::OSDWriteResponse* current_response);
uint64_t ExtractFileIdFromXCap(const xtreemfs::pbrpc::XCap& xcap);
/** Same as dirname(): Returns the path to the parent directory of a path. */
std::string ResolveParentDirectory(const std::string& path);
/** Same as basename(): Returns the last component of a path. */
std::string GetBasename(const std::string& path);
/** Concatenates a given directory and file and returns the correct full path to
* the file. */
std::string ConcatenatePath(const std::string& directory,
const std::string& file);
/** Returns the OSD UUID for the given replica and the given block within the
* striping pattern.
*
* @param xlocs List of replicas.
* @param replica_index Index of the replica in the XlocSet (starting from 0).
* @param stripe_index Index of the OSD in the striping pattern (where 0 is the
* head OSD).
* @return returns string("") if there is no OSD available.
*/
std::string GetOSDUUIDFromXlocSet(const xtreemfs::pbrpc::XLocSet& xlocs,
uint32_t replica_index,
uint32_t stripe_index);
/** Returns UUID of the head OSD (block = 0) of the first replica (r = 0). */
std::string GetOSDUUIDFromXlocSet(const xtreemfs::pbrpc::XLocSet& xlocs);
/** Convert StripePolicyType to string */
std::string StripePolicyTypeToString(xtreemfs::pbrpc::StripingPolicyType policy);
/** Generates a random UUID (needed to distinguish clients for locks). */
void GenerateVersion4UUID(std::string* result);
/** Sets all required members of a Stat object to 0 or "". */
void InitializeStat(xtreemfs::pbrpc::Stat* stat);
/** Returns true if both locks aren't NULL and all members are identical. */
bool CheckIfLocksAreEqual(const xtreemfs::pbrpc::Lock& lock1,
const xtreemfs::pbrpc::Lock& lock2);
/** Returns true if lock2 conflicts with lock1. */
bool CheckIfLocksDoConflict(const xtreemfs::pbrpc::Lock& lock1,
const xtreemfs::pbrpc::Lock& lock2);
/** Tests if string is a numeric (positive) value. */
bool CheckIfUnsignedInteger(const std::string& string);
/** Adapter to create RPCOptions from an Options object */
RPCOptions RPCOptionsFromOptions(const Options& options);
#ifdef __APPLE__
/** Returns the MacOSX Kernel Version (8 = Tiger, 9 = Leopard, 10 = Snow Leopard). */
int GetMacOSXKernelVersion();
#endif // __APPLE__
#ifdef WIN32
/** Convert a Windows Multibyte string (e.g. a path or username) into
* an UTF8 string and returns it.
*/
std::string ConvertWindowsToUTF8(const wchar_t* windows_string);
/** Convert a Windows Multibyte string (e.g. a path or username) into
* an UTF8 string and stores it in utf8_string.
*/
void ConvertWindowsToUTF8(const wchar_t* windows_string,
std::string* utf8_string);
/** Convert an UTF8 string (e.g. a path or username) into
* a Windows Multibyte string.
*
* @param buffer_size Size, including the null character.
*/
void ConvertUTF8ToWindows(const std::string& utf8,
wchar_t* buf,
int buffer_size);
void ConvertUTF8ToWindows(const std::string& utf8, std::wstring* win);
std::wstring ConvertUTF8ToWindows(const std::string& utf8);
#endif // WIN32
/** Returns the set of available networks (for each local network interface).
*
* Each entry has the form "<network address>/<prefix length>".
*
* Currently, only Linux is supported. For other OS, the list is empty.
*/
boost::unordered_set<std::string> GetNetworks();
/** Returns for the "struct ifaddrs" the network prefix (e.g. 127.0.0.1/8).
*
* @throws XtreemFSException if the conversion fails.
*/
#ifdef __linux__
std::string GetNetworkStringUnix(const struct ifaddrs* ifaddr);
#endif // __linux__
/**
* Parses human-readable byte numbers to byte counts
*/
long parseByteNumber(std::string byte_number);
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_HELPER_H_

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2012 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_INTERRUPT_H_
#define CPP_INCLUDE_LIBXTREEMFS_INTERRUPT_H_
#include <stdint.h>
#include <boost/function.hpp>
namespace xtreemfs {
typedef boost::function0<int> InterruptedCallback;
/** Aggregates helper functions which check for an interrupted request or are
* responsible for the delay between two request execution attempts. */
class Interruptibilizer {
public:
static bool WasInterrupted(InterruptedCallback cb);
/** Wrapper for boost::thread::sleep which checks for interruptions by
* the signal handler.
*
* @remarks this function contains a boost::thread interruption point and
* thus might throw boost::thread_interrupted.
*/
static void SleepInterruptible(int64_t rel_time_ms, InterruptedCallback cb);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_INTERRUPT_H_

View File

@@ -0,0 +1,198 @@
/*
* Copyright (c) 2010-2011 by Patrick Schaefer, Zuse Institute Berlin
* 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_METADATA_CACHE_H_
#define CPP_INCLUDE_LIBXTREEMFS_METADATA_CACHE_H_
#include <stdint.h>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/thread/mutex.hpp>
#include <string>
#include "libxtreemfs/metadata_cache_entry.h"
#include "xtreemfs/MRC.pb.h"
namespace xtreemfs {
namespace pbrpc {
class OSDWriteResponse;
}
class MetadataCache {
public:
enum GetStatResult { kStatCached, kPathDoesntExist, kStatNotCached };
// Tags needed to address the different indexes.
struct IndexList {};
struct IndexMap {};
struct IndexHash {};
typedef boost::multi_index_container<
MetadataCacheEntry*,
boost::multi_index::indexed_by<
// list-like: Order
boost::multi_index::sequenced<
boost::multi_index::tag<IndexList> >,
// map-like: Sort entries by path for InvalidatePrefix().
boost::multi_index::ordered_unique<
boost::multi_index::tag<IndexMap>,
boost::multi_index::member<
MetadataCacheEntry,
std::string,
&MetadataCacheEntry::path> >,
// unordered_map-like: Hash based access for fast Get* calls.
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexHash>,
boost::multi_index::member<
MetadataCacheEntry,
std::string,
&MetadataCacheEntry::path> >
>
> Cache;
typedef Cache::index<IndexList>::type by_list;
typedef Cache::index<IndexMap>::type by_map;
typedef Cache::index<IndexHash>::type by_hash;
MetadataCache(uint64_t size, uint64_t ttl_s);
/** Frees all MetadataCacheEntry objects. */
~MetadataCache();
/** Removes MetadataCacheEntry for path from cache_. */
void Invalidate(const std::string& path);
/** Removes MetadataCacheEntry for path and any objects matching path+"/". */
void InvalidatePrefix(const std::string& path);
/** Renames path to new_path and any object's path matching path+"/". */
void RenamePrefix(const std::string& path, const std::string& new_path);
/** Returns true if there is a Stat object for path in cache and fills stat.*/
GetStatResult GetStat(const std::string& path, xtreemfs::pbrpc::Stat* stat);
/** Stores/updates stat in cache for path. */
void UpdateStat(const std::string& path, const xtreemfs::pbrpc::Stat& stat);
/** Updates timestamp of the cached stat object.
* Values for to_set: SETATTR_ATIME, SETATTR_MTIME, SETATTR_CTIME
*/
void UpdateStatTime(const std::string& path,
uint64_t timestamp,
xtreemfs::pbrpc::Setattrs to_set);
/** Updates the attributes given in "stat" and selected by "to_set". */
void UpdateStatAttributes(const std::string& path,
const xtreemfs::pbrpc::Stat& stat,
xtreemfs::pbrpc::Setattrs to_set);
/** Returns the set of attributes which divert from the cached stat entry. */
xtreemfs::pbrpc::Setattrs SimulateSetStatAttributes(
const std::string& path,
const xtreemfs::pbrpc::Stat& stat,
xtreemfs::pbrpc::Setattrs to_set);
/** Updates file size and truncate epoch from an OSDWriteResponse. */
void UpdateStatFromOSDWriteResponse(
const std::string& path,
const xtreemfs::pbrpc::OSDWriteResponse& response);
/** Returns a DirectoryEntries object (if it's found for "path") limited to
* entries starting from "offset" up to "count" (or the maximum)S.
*
* @remark Ownership is transferred to the caller.
*/
xtreemfs::pbrpc::DirectoryEntries* GetDirEntries(const std::string& path,
uint64_t offset,
uint32_t count);
/** Invalidates the stat entry stored for "path". */
void InvalidateStat(const std::string& path);
/** Stores/updates DirectoryEntries in cache for path.
*
* @note This implementation assumes that dir_entries is always complete,
* i.e. it must be guaranteed that it contains all entries.*/
void UpdateDirEntries(const std::string& path,
const xtreemfs::pbrpc::DirectoryEntries& dir_entries);
/** Removes "entry_name" from the cached directory "path_to_directory". */
void InvalidateDirEntry(const std::string& path_to_directory,
const std::string& entry_name);
/** Remove cached DirectoryEntries in cache for path. */
void InvalidateDirEntries(const std::string& path);
/** Writes value for an XAttribute with "name" stored for "path" in "value".
* Returns true if found, false otherwise. */
bool GetXAttr(const std::string& path,
const std::string& name,
std::string* value,
bool* xattrs_cached);
/** Stores the size of a value (string length) of an XAttribute "name" cached
* for "path" in "size". */
bool GetXAttrSize(const std::string& path,
const std::string& name,
int* size,
bool* xattrs_cached);
/** Get all extended attributes cached for "path".
*
* @remark Ownership is transferred to the caller.
*/
xtreemfs::pbrpc::listxattrResponse* GetXAttrs(const std::string& path);
/** Updates the "value" for the attribute "name" of "path" if the list of
* attributes for "path" is already cached.
*
* @remark This function does not extend the TTL of the xattr list. */
void UpdateXAttr(const std::string& path,
const std::string& name,
const std::string& value);
/** Stores/updates XAttrs in cache for path.
*
* @note This implementation assumes that the list of extended attributes is
* always complete.*/
void UpdateXAttrs(const std::string& path,
const xtreemfs::pbrpc::listxattrResponse& xattrs);
/** Removes "name" from the list of extended attributes cached for "path". */
void InvalidateXAttr(const std::string& path, const std::string& name);
/** Remove cached XAttrs in cache for path. */
void InvalidateXAttrs(const std::string& path);
/** Returns the current number of elements. */
uint64_t Size();
/** Returns the maximum number of elements. */
uint64_t Capacity() { return size_; }
private:
/** Evicts first n oldest entries from cache_. */
void EvictUnmutexed(int n);
bool enabled;
uint64_t size_;
uint64_t ttl_s_;
boost::mutex mutex_;
Cache cache_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_METADATA_CACHE_H_

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_METADATA_CACHE_ENTRY_H_
#define CPP_INCLUDE_LIBXTREEMFS_METADATA_CACHE_ENTRY_H_
#include <stdint.h>
#include <string>
namespace xtreemfs {
namespace pbrpc {
class DirectoryEntries;
class Stat;
class listxattrResponse;
}
class MetadataCacheEntry {
public:
MetadataCacheEntry();
~MetadataCacheEntry();
std::string path;
xtreemfs::pbrpc::DirectoryEntries* dir_entries;
uint64_t dir_entries_timeout_s;
xtreemfs::pbrpc::Stat* stat;
uint64_t stat_timeout_s;
xtreemfs::pbrpc::listxattrResponse* xattrs;
uint64_t xattrs_timeout_s;
/** Always the maximum of all three timeouts. */
uint64_t timeout_s;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_METADATA_CACHE_ENTRY_H_

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2013 by Felix Hupfeld.
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_OBJECT_CACHE_H_
#define CPP_INCLUDE_LIBXTREEMFS_OBJECT_CACHE_H_
#include <stdint.h>
#include <boost/scoped_array.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/function.hpp>
#include <deque>
#include <map>
#include "util/annotations.h"
namespace boost {
class condition_variable;
}
namespace xtreemfs {
/** These are injected functions that provide object read and write
* functionality for complete objects. */
typedef boost::function<int (int object_no, char* data)>
ObjectReaderFunction;
typedef boost::function<void (int object_no, const char* data, int size)>
ObjectWriterFunction;
class CachedObject {
public:
/** Create the object in ReadPending state. */
CachedObject(int object_no, int object_size);
~CachedObject();
/** Flush data and free memory. */
void FlushAndErase(const ObjectWriterFunction& writer)
LOCKS_EXCLUDED(mutex_);
/** Free memory without flushing to storage. */
void Drop() LOCKS_EXCLUDED(mutex_);
int Read(int offset_in_object,
char* buffer,
int bytes_to_read,
const ObjectReaderFunction& reader)
LOCKS_EXCLUDED(mutex_);
void Write(int offset_in_object,
const char* buffer,
int bytes_to_write,
const ObjectReaderFunction& reader)
LOCKS_EXCLUDED(mutex_);
void Flush(const ObjectWriterFunction& writer)
LOCKS_EXCLUDED(mutex_);
void Truncate(int new_object_size)
LOCKS_EXCLUDED(mutex_);
uint64_t last_access()
LOCKS_EXCLUDED(mutex_);
bool is_dirty()
LOCKS_EXCLUDED(mutex_);
bool has_data()
LOCKS_EXCLUDED(mutex_);
private:
/** Caller must hold mutex_ */
void DropLocked() EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void ReadInternal(boost::unique_lock<boost::mutex>& lock,
const ObjectReaderFunction& reader)
EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void WriteObjectToOSD(const ObjectWriterFunction& writer)
EXCLUSIVE_LOCKS_REQUIRED(mutex_);
/** Mutex that protects all non const data member. */
boost::mutex mutex_;
std::deque<boost::condition_variable*> read_queue_
GUARDED_BY(mutex_);
const int object_no_;
const int object_size_;
/** Our buffer, always object_size_ large. */
boost::scoped_array<char> data_ GUARDED_BY(mutex_);
/** The last object has fewer bytes than object_size_. If data has not been
fetched from the OSD yet, actual_size is -1.
*/
int actual_size_ GUARDED_BY(mutex_);
/** Data is dirty and must be written back. */
bool is_dirty_ GUARDED_BY(mutex_);
/** Timestamp of last access, for LRU expunge policy. */
uint64_t last_access_ GUARDED_BY(mutex_);
/** Reading the data has failed */
bool read_has_failed_ GUARDED_BY(mutex_);
};
class ObjectCache {
public:
ObjectCache(size_t max_objects, int object_size);
~ObjectCache();
/** Read within a specific object */
int Read(int object_no, int offset_in_object,
char* buffer, int bytes_to_read,
const ObjectReaderFunction& reader,
const ObjectWriterFunction& writer)
LOCKS_EXCLUDED(mutex_);
/** Write within a specific object */
void Write(int object_no, int offset_in_object,
const char* buffer, int bytes_to_write,
const ObjectReaderFunction& reader,
const ObjectWriterFunction& writer)
LOCKS_EXCLUDED(mutex_);
void Flush(const ObjectWriterFunction& writer)
LOCKS_EXCLUDED(mutex_);
void Truncate(int64_t new_size)
LOCKS_EXCLUDED(mutex_);
int object_size() const;
private:
CachedObject* LookupObject(int object_no,
const ObjectWriterFunction& writer)
LOCKS_EXCLUDED(mutex_);
void EvictObjects(const ObjectWriterFunction& writer)
EXCLUSIVE_LOCKS_REQUIRED(mutex_);
/** Protects all non-const members of this class. */
boost::mutex mutex_;
/** Map of object number to cached object. */
typedef std::map<int64_t, CachedObject*> Cache;
Cache cache_ GUARDED_BY(mutex_);
/** Maximum number of objects to cache. */
const size_t max_objects_;
const int object_size_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_OBJECT_CACHE_H_

View File

@@ -0,0 +1,326 @@
/*
* Copyright (c) 2010-2011 by Patrick Schaefer, Zuse Institute Berlin
* 2011-2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_OPTIONS_H_
#define CPP_INCLUDE_LIBXTREEMFS_OPTIONS_H_
#include <stdint.h>
#include <boost/function.hpp>
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
#include <vector>
#include "libxtreemfs/typedefs.h"
#include "libxtreemfs/user_mapping.h"
namespace xtreemfs {
namespace rpc {
class SSLOptions;
} // namespace rpc
enum XtreemFSServiceType {
kDIR, kMRC
};
class Options {
public:
/** Query function which returns 1 when the request was interrupted.
*
* @note the boost::function typedef could be replaced with
* typedef int (*query_function)(void);
* which would also works without changes, but would not support
* functor objects
*/
typedef boost::function0<int> CheckIfInterruptedQueryFunction;
/** Sets the default values. */
Options();
virtual ~Options() {}
/** Generates boost::program_options description texts. */
void GenerateProgramOptionsDescriptions();
/** Set options parsed from command line.
*
* However, it does not set dir_volume_url and does not call
* ParseVolumeAndDir().
*
* @throws InvalidCommandLineParametersException
* @throws InvalidURLException */
std::vector<std::string> ParseCommandLine(int argc, char** argv);
/** Extract volume name and dir service address from dir_volume_url. */
void ParseURL(XtreemFSServiceType service_type);
/** Outputs usage of the command line parameters of all options. */
virtual std::string ShowCommandLineHelp();
/** Outputs usage of the command line parameters of volume creation
* relevant options. */
std::string ShowCommandLineHelpVolumeCreationAndDeletion();
/** Outputs usage of the command line parameters of volume deletion/listing
* relevant options. */
std::string ShowCommandLineHelpVolumeListing();
/** Returns the version string and prepends "component". */
std::string ShowVersion(const std::string& component);
/** Returns true if required SSL options are set. */
bool SSLEnabled() const;
/** Creates a new SSLOptions object based on the value of the members:
* - ssl_pem_key_path
* - ssl_pem_cert_path
* - ssl_pem_key_pass
* - ssl_pem_trusted_certs_path
* - ssl_pkcs12_path
* - ssl_pkcs12_pass
* - grid_ssl || protocol
* - verify_certificates
* - ignore_verify_errors
* - ssl_method
*
* @remark Ownership is transferred to caller. May be NULL.
*/
xtreemfs::rpc::SSLOptions* GenerateSSLOptions() const;
// Version information.
std::string version_string;
// XtreemFS URL Options.
/** URL to the Volume.
*
* Format:[pbrpc://]service-hostname[:port](,[pbrpc://]service-hostname2[:port])*[/volume_name]. // NOLINT
*
* Depending on the type of operation the service-hostname has to point to the
* DIR (to open/"mount" a volume) or the MRC (create/delete/list volumes).
* Depending on this type, the default port differs (DIR: 32638; MRC: 32636).
*/
std::string xtreemfs_url;
/** Usually extracted from xtreemfs_url (Form: ip-address:port).
*
* Depending on the application, it may contain the addresses of DIR replicas
* (e.g., mount.xtreemfs) or MRC replicas (e.g., mkfs.xtreemfs). */
ServiceAddresses service_addresses;
/** Usually extracted from xtreemfs_url. */
std::string volume_name;
/** Usually extracted from xtreemfs_url. */
std::string protocol;
/** Mount point on local system (set by ParseCommandLine()). */
std::string mount_point;
// General options.
/** Log level as string (EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG). */
std::string log_level_string;
/** If not empty, the output will be logged to a file. */
std::string log_file_path;
/** True, if "-h" was specified. */
bool show_help;
/** True, if argc == 1 was at ParseCommandLine(). */
bool empty_arguments_list;
/** True, if -V/--version was specified and the version will be shown only .*/
bool show_version;
// Optimizations.
/** Maximum number of entries of the StatCache */
uint64_t metadata_cache_size;
/** Time to live for MetadataCache entries. */
uint64_t metadata_cache_ttl_s;
/** Enable asynchronous writes */
bool enable_async_writes;
/** Maximum number of pending async write requests per file. */
int async_writes_max_requests;
/** Maximum write request size per async write. Should be equal to the lowest
* upper bound in the system (e.g. an object size, or the FUSE limit). */
int async_writes_max_request_size_kb;
/** Number of retrieved entries per readdir request. */
int readdir_chunk_size;
/** True, if atime requests are enabled in Fuse/not ignored by the library. */
bool enable_atime;
/** Cached objects per file. A value <= 0 disables the object cache. */
int object_cache_size;
// Error Handling options.
/** How often shall a failed operation get retried? */
int max_tries;
/** How often shall a failed read operation get retried? */
int max_read_tries;
/** How often shall a failed write operation get retried? */
int max_write_tries;
/** How often shall a view be tried to renewed? */
int max_view_renewals;
/** How long to wait after a failed request at least? */
int retry_delay_s;
/** Maximum time until a connection attempt will be aborted. */
int32_t connect_timeout_s;
/** Maximum time until a request will be aborted and the response returned. */
int32_t request_timeout_s;
/** The RPC Client closes connections after "linger_timeout_s" time of
* inactivity. */
int32_t linger_timeout_s;
#ifdef HAS_OPENSSL
// SSL options.
std::string ssl_pem_cert_path;
std::string ssl_pem_key_path;
std::string ssl_pem_key_pass;
std::string ssl_pem_trusted_certs_path;
std::string ssl_pkcs12_path;
std::string ssl_pkcs12_pass;
/** True, if the XtreemFS Grid-SSL Mode (only SSL handshake, no encryption of
* data itself) shall be used. */
bool grid_ssl;
/** True if certificates shall be verified. */
bool ssl_verify_certificates;
/** List of openssl verify error codes to ignore during verification and
* accept anyway. Only used when ssl_verify_certificates = true. */
std::vector<int> ssl_ignore_verify_errors;
/** SSL version that this client should accept. */
std::string ssl_method_string;
#endif // HAS_OPENSSL
// Grid Support options.
/** True if the Globus user mapping shall be used. */
bool grid_auth_mode_globus;
/** True if the Unicore user mapping shall be used. */
bool grid_auth_mode_unicore;
/** Location of the gridmap file. */
std::string grid_gridmap_location;
/** Default Location of the Globus gridmap file. */
std::string grid_gridmap_location_default_globus;
/** Default Location of the Unicore gridmap file. */
std::string grid_gridmap_location_default_unicore;
/** Periodic interval after which the gridmap file will be reloaded. */
int grid_gridmap_reload_interval_m;
// Vivaldi Options
/** Enables the vivaldi coordinate calculation for the client. */
bool vivaldi_enable;
/** Enables sending the coordinates to the DIR after each recalculation. This
* is only needed to add the clients to the vivaldi visualization at the cost
* of some additional traffic between client and DIR.") */
bool vivaldi_enable_dir_updates;
/** The file where the vivaldi coordinates should be saved after each
* recalculation. */
std::string vivaldi_filename;
/** The interval between coordinate recalculations. Also see
* vivaldi_recalculation_epsilon_s. */
int vivaldi_recalculation_interval_s;
/** The recalculation interval will be randomly chosen from
* vivaldi_recalculation_inverval_s +/- vivaldi_recalculation_epsilon_s */
int vivaldi_recalculation_epsilon_s;
/** Number of coordinate recalculations before updating the list of OSDs. */
int vivaldi_max_iterations_before_updating;
/** Maximal number of retries when requesting coordinates from another
* vivaldi node. */
int vivaldi_max_request_retries;
// Advanced XtreemFS options.
/** Interval for periodic file size updates in seconds. */
int periodic_file_size_updates_interval_s;
/** Interval for periodic xcap renewal in seconds. */
int periodic_xcap_renewal_interval_s;
/** Skewness of the Zipf distribution used for vivaldi OSD selection */
double vivaldi_zipf_generator_skew;
/** May contain all previous options in key=value pair lists. */
std::vector<std::string> alternative_options_list;
// Internal options, not available from the command line interface.
/** If not NULL, called to find out if request was interrupted. */
CheckIfInterruptedQueryFunction was_interrupted_function;
// NOTE: Deprecated options are no longer needed as members
// Additional User mapping.
/** Type of the UserMapping used to translate between local/global names. */
UserMapping::UserMappingType additional_user_mapping_type;
private:
/** Reads password from stdin and stores it in 'password'. */
void ReadPasswordFromStdin(const std::string& msg, std::string* password);
/** This functor template can be used as argument for the notifier() method
* of boost::options. It is specifically used to create a warning whenever
* a deprecated option is used, but is not limited to that purpose.
* The CreateMsgOptionHandler function template can be used to instantiate it
* without explicit template type specification. Instead the type inferred
* from the value given by the corresponding member variable.
*/
template<typename T>
class MsgOptionHandler {
public:
typedef void result_type;
MsgOptionHandler(std::string msg)
: msg_(msg) { }
void operator()(const T& value) {
std::cerr << "Warning: Deprecated option used: " << msg_ << std::endl;
}
private:
const std::string msg_;
};
/** See MsgOptionHandler */
template<typename T>
MsgOptionHandler<T> CreateMsgOptionHandler(const T&, std::string msg) {
return MsgOptionHandler<T>(msg);
}
// Sums of options.
/** Contains all boost program options, needed for parsing. */
boost::program_options::options_description all_descriptions_;
/** Contains descriptions of all visible options (no advanced and
* deprecated options). Used by ShowCommandLineHelp().*/
boost::program_options::options_description visible_descriptions_;
/** Set to true if GenerateProgramOptionsDescriptions() was executed. */
bool all_descriptions_initialized_;
// Options itself.
/** Description of general options (Logging, help). */
boost::program_options::options_description general_;
/** Description of options which improve performance. */
boost::program_options::options_description optimizations_;
/** Description of timeout options etc. */
boost::program_options::options_description error_handling_;
#ifdef HAS_OPENSSL
/** Description of SSL related options. */
boost::program_options::options_description ssl_options_;
#endif // HAS_OPENSSL
/** Description of options of the Grid support. */
boost::program_options::options_description grid_options_;
/** Description of the Vivaldi options */
boost::program_options::options_description vivaldi_options_;
// Hidden options.
/** Description of options of the Grid support. */
boost::program_options::options_description xtreemfs_advanced_options_;
/** Deprecated options which are kept to ensure backward compatibility. */
boost::program_options::options_description deprecated_options_;
/** Specify all previous options in key=value pair lists. */
boost::program_options::options_description alternative_options_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_OPTIONS_H_

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2011-2012 by Michael Berlin, Zuse Institute Berlin
* 2010-2011 by Patrick Schaefer, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_PBRPC_URL_H_
#define CPP_INCLUDE_LIBXTREEMFS_PBRPC_URL_H_
#include <stdint.h>
#include <boost/lexical_cast.hpp>
#include <list>
#include <string>
#include "libxtreemfs/typedefs.h"
namespace xtreemfs {
class PBRPCURL {
public:
PBRPCURL();
/** Parses the URL of the form [scheme://]host[:port][/volume].
*
* Multiple entries of "[scheme://]host[:port]" can be given as comma
* separated list e.g., the following URL would also be valid:
*
* [scheme://]host0[:port],[scheme://]host1[:port][/volume]
*
* @throws InvalidURLException
*/
void ParseURL(const std::string& url,
const std::string& default_scheme,
const uint16_t default_port);
const std::string& scheme() const {
return scheme_;
}
const std::string& volume() const {
return volume_;
}
ServiceAddresses GetAddresses() const;
static const std::string& GetSchemePBRPC() {
static const std::string SCHEME_PBRPC_STRING = "pbrpc";
return SCHEME_PBRPC_STRING;
}
static const std::string& GetSchemePBRPCS() {
static const std::string SCHEME_PBRPCS_STRING = "pbrpcs";
return SCHEME_PBRPCS_STRING;
}
static const std::string& GetSchemePBRPCG() {
static const std::string SCHEME_PBRPCG_STRING = "pbrpcg";
return SCHEME_PBRPCG_STRING;
}
static const std::string GetSchemePBRPCU() {
static const std::string SCHEME_PBRPCU_STRING = "pbrpcu";
return SCHEME_PBRPCU_STRING;
}
private:
/** List of servers (hostnames only) */
typedef std::list<std::string> ServerList;
/** List of ports */
typedef std::list<uint16_t> PortList;
std::string scheme_;
/** List of all parsed server's hostnames. Ports are stored in ports_ */
ServerList servers_;
/** Ports for the hostnames in servers. Server and ports with the same list
* position belong together. */
PortList ports_;
std::string volume_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_PBRPC_URL_H_

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
* 2012 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_SIMPLE_UUID_ITERATOR_H_
#define CPP_INCLUDE_LIBXTREEMFS_SIMPLE_UUID_ITERATOR_H_
#include <boost/thread/mutex.hpp>
#include <gtest/gtest_prod.h>
#include <list>
#include <string>
#include "libxtreemfs/uuid_item.h"
#include "libxtreemfs/uuid_iterator.h"
#include "libxtreemfs/uuid_container.h"
#include "xtreemfs/GlobalTypes.pb.h"
namespace xtreemfs {
class SimpleUUIDIterator : public UUIDIterator {
public:
SimpleUUIDIterator() {};
SimpleUUIDIterator(const xtreemfs::pbrpc::XLocSet& xlocs);
virtual ~SimpleUUIDIterator();
virtual void SetCurrentUUID(const std::string& uuid);
virtual void Clear();
/** Appends "uuid" to the list of UUIDs. Does not change the current UUID. */
virtual void AddUUID(const std::string& uuid);
/** Clear the list and add the head OSD UUIDs of all replicas from the xLocSet. */
virtual void ClearAndGetOSDUUIDsFromXlocSet(const xtreemfs::pbrpc::XLocSet& xlocs);
FRIEND_TEST(SimpleUUIDIteratorTest, ConcurrentSetAndMarkAsFailed);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_SIMPLE_UUID_ITERATOR_H_

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_STRIPE_TRANSLATOR_H_
#define CPP_INCLUDE_LIBXTREEMFS_STRIPE_TRANSLATOR_H_
#include <stdint.h>
#include <list>
#include <vector>
#include "xtreemfs/GlobalTypes.pb.h"
namespace xtreemfs {
class ReadOperation {
public:
typedef std::vector<size_t> OSDOffsetContainer;
ReadOperation(size_t _obj_number, OSDOffsetContainer _osd_offsets,
size_t _req_size, size_t _req_offset,
char *_data)
: obj_number(_obj_number), osd_offsets(_osd_offsets),
req_size(_req_size), req_offset(_req_offset),
data(_data) {
};
size_t obj_number;
OSDOffsetContainer osd_offsets;
size_t req_size;
size_t req_offset;
char *data;
};
class WriteOperation {
public:
typedef std::vector<size_t> OSDOffsetContainer;
WriteOperation(size_t _obj_number, OSDOffsetContainer _osd_offsets,
size_t _req_size, size_t _req_offset,
const char *_data)
: obj_number(_obj_number), osd_offsets(_osd_offsets),
req_size(_req_size), req_offset(_req_offset),
data(_data) {
};
size_t obj_number;
OSDOffsetContainer osd_offsets;
size_t req_size;
size_t req_offset;
const char *data;
};
class StripeTranslator {
public:
typedef std::list<const xtreemfs::pbrpc::StripingPolicy*> PolicyContainer;
virtual ~StripeTranslator() {}
virtual void TranslateWriteRequest(
const char *buf,
size_t size,
int64_t offset,
PolicyContainer policies,
std::vector<WriteOperation>* operations) const = 0;
virtual void TranslateReadRequest(
char *buf,
size_t size,
int64_t offset,
PolicyContainer policies,
std::vector<ReadOperation>* operations) const = 0;
};
class StripeTranslatorRaid0 : public StripeTranslator {
public:
virtual void TranslateWriteRequest(
const char *buf,
size_t size,
int64_t offset,
PolicyContainer policies,
std::vector<WriteOperation>* operations) const;
virtual void TranslateReadRequest(
char *buf,
size_t size,
int64_t offset,
PolicyContainer policies,
std::vector<ReadOperation>* operations) const;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_STRIPE_TRANSLATOR_H_

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_H_
#define CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_H_
#include <boost/scoped_ptr.hpp>
#include "libxtreemfs/user_mapping.h"
namespace xtreemfs {
namespace pbrpc {
class UserCredentials;
} // namespace pbrpc
/**
* Allows to retrieve the UserCredentials for the current system user.
* Additionally, a UserMapping can be registered to transform local usernames
* and groupnames e.g., convert a local username into a global name.
*/
class SystemUserMapping {
public:
/** Returns a SystemSystemUserMapping for the current plattform.
*
* Currently only Windows and Unix (suitable for Linux, MacOSX, Solaris)
* SystemUserMapping implementations are available.
*
* @remark Ownership is transferred to the caller.
*/
static SystemUserMapping* GetSystemUserMapping();
virtual ~SystemUserMapping() {}
/** Fills "user_credentials" with the user and group names of the current
* system user. */
virtual void GetUserCredentialsForCurrentUser(
xtreemfs::pbrpc::UserCredentials* user_credentials) = 0;
/** Register an additional user mapping to transform user and group names
* before returning them to the system or XtreemFS.
*
* @attention The implementation of this function is not required to be
* thread-safe i.e., register an additional user mapping before
* making the system user mapping available to multiple threads.
*
* @remark Ownership is transferred to the caller.
*/
void RegisterAdditionalUserMapping(UserMapping* mapping);
/** Executes the Start() method of the registered additional user mapping. */
void StartAdditionalUserMapping();
/** Executes the Stop() method of the registered additional user mapping. */
void StopAdditionalUserMapping();
protected:
/** Used for custom transformation between local and global names. */
boost::scoped_ptr<UserMapping> additional_user_mapping_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_H_

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2011-2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_UNIX_H_
#define CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_UNIX_H_
#ifndef WIN32
#include <list>
#include <string>
#include "libxtreemfs/system_user_mapping.h"
namespace xtreemfs {
class SystemUserMappingUnix : public SystemUserMapping {
public:
SystemUserMappingUnix() {}
virtual void GetUserCredentialsForCurrentUser(
xtreemfs::pbrpc::UserCredentials* user_credentials);
std::string UIDToUsername(uid_t uid);
uid_t UsernameToUID(const std::string& username);
std::string GIDToGroupname(gid_t gid);
gid_t GroupnameToGID(const std::string& groupname);
void GetGroupnames(uid_t uid,
gid_t gid,
pid_t pid,
std::list<std::string>* groupnames);
};
} // namespace xtreemfs
#endif // !WIN32
#endif // CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_UNIX_H_

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2011-2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_WINDOWS_H_
#define CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_WINDOWS_H_
#include "libxtreemfs/system_user_mapping.h"
namespace xtreemfs {
class SystemUserMappingWindows : public SystemUserMapping {
public:
SystemUserMappingWindows() {}
virtual void GetUserCredentialsForCurrentUser(
xtreemfs::pbrpc::UserCredentials* user_credentials);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_SYSTEM_USER_MAPPING_WINDOWS_H_

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_TYPEDEFS_H_
#define CPP_INCLUDE_LIBXTREEMFS_TYPEDEFS_H_
#include <vector>
#include <string>
namespace xtreemfs {
/** This file contains typedefs which are used by different classes.
* @file
*/
/** List of network addresses. Addresses have the form "hostname:port". */
class ServiceAddresses {
public:
ServiceAddresses() {}
ServiceAddresses(const char* address) {
addresses_.push_back(address);
}
ServiceAddresses(const std::string& address) {
addresses_.push_back(address);
}
explicit ServiceAddresses(const std::vector<std::string>& addresses) {
addresses_ = addresses;
}
void Add(const std::string& address) {
addresses_.push_back(address);
}
typedef std::vector<std::string> Addresses;
Addresses GetAddresses() const {
return addresses_;
}
bool empty() const {
return addresses_.empty();
}
size_t size() const {
return addresses_.size();
}
bool IsAddressList() const {
return addresses_.size() > 1;
}
private:
Addresses addresses_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_TYPEDEFS_H_

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2010-2011 by Patrick Schaefer, Zuse Institute Berlin
* 2011-2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_H_
#define CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_H_
#include <sys/types.h>
#include <list>
#include <string>
namespace xtreemfs {
namespace pbrpc {
class UserCredentials;
} // namespace pbrpc
class Options;
/** Allows to specify a transformation between local user and group names and
* its global counterparts stored in XtreemFS. */
class UserMapping {
public:
/** Available UserMappings which are allowed by CreateUserMapping(). */
enum UserMappingType {
kNone, kUnicore, kGlobus
};
/** Returns an instance of the chosen UserMapping.
*
* @param type Type of the user mapping to be created.
* @param options Options object which has to contain additional members
* depending on the constructor of the user mapping.
*/
static UserMapping* CreateUserMapping(UserMappingType type,
const Options& options);
/** Returns CreateUserMapping(type, options) whereas options is a
* default Options object. */
static UserMapping* CreateUserMapping(UserMappingType type);
virtual ~UserMapping() {}
/** Has to be called after creating a UserMapping object and can be used to
* start a needed thread. */
virtual void Start() = 0;
/** Has to be called before the deletion of a UserMapping object and can be
* used to stop a created threads. */
virtual void Stop() = 0;
virtual void LocalToGlobalUsername(const std::string& username_local,
std::string* username_global) = 0;
virtual void LocalToGlobalGroupname(const std::string& groupname_local,
std::string* groupname_global) = 0;
virtual void GlobalToLocalUsername(const std::string& username_global,
std::string* username_local) = 0;
virtual void GlobalToLocalGroupname(const std::string& groupname_global,
std::string* groupname_local) = 0;
/** Retrieve the list of known group names based on the local username. */
virtual void GetGroupnames(
const std::string& username_local,
xtreemfs::pbrpc::UserCredentials* user_credentials) = 0;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_H_

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2011-2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_H_
#define CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_H_
#include <sys/types.h>
#include <boost/bimap.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <list>
#include <map>
#include <string>
#include "libxtreemfs/user_mapping.h"
namespace xtreemfs {
class UserMappingGridmap : public UserMapping {
public:
UserMappingGridmap(const std::string& gridmap_file,
int gridmap_reload_interval_s);
virtual void Start();
virtual void Stop();
virtual void LocalToGlobalUsername(const std::string& username_local,
std::string* username_global);
virtual void LocalToGlobalGroupname(const std::string& groupname_local,
std::string* groupname_global);
virtual void GlobalToLocalUsername(const std::string& username_global,
std::string* username_local);
virtual void GlobalToLocalGroupname(const std::string& groupname_local,
std::string* groupname_global);
virtual void GetGroupnames(
const std::string& username_local,
xtreemfs::pbrpc::UserCredentials* user_credentials);
protected:
/** Parses the file gridmap_file_ and stores the information in the maps
* dn_username_ and dn_groupname_. */
virtual void ReadGridmapFile() = 0;
/** Stores dn, user and extracts the groups (all entries starting with OU=)
* from the dn-string.
*
* This is a helper function provided for ReadGridMapFile implementations. */
void Store(std::string dn,
std::string users,
std::string user_seperator,
boost::bimap< std::string, std::string > &new_username,
std::multimap< std::string, std::string > &new_groupname);
/** Accessor for derived classes. */
inline std::string gridmap_file() {
return gridmap_file_;
}
/** Contains the mappings DN <-> Username. */
boost::bimap< std::string, std::string > dn_username;
/** Contains the mappings DN <-> OU whereas multiple DN entries may exist. */
std::multimap< std::string, std::string > dn_groupname;
/** Use this when accessing the maps dn_username_ or dn_groupname_. */
boost::mutex mutex;
private:
/** Executed in an extra thread at intervals of the length
* gridmap_reload_interval_s_. The thread has to be started and stopped with
* Start() and Stop() after the creation and before the deletion of this
* object.
*
* The thread checks the modification time of the gridmap file to decide if
* the file shall be reloaded.
*/
void PeriodicGridmapFileReload();
/** Looks up a username in the mapfile and returns the DN if found, else "".*/
std::string UsernameToDN(const std::string& username);
/** Looks up a DN in the mapfile and returns the username if found, else "".*/
std::string DNToUsername(const std::string& dn);
/** Adds OUs as groups from the DN. */
void DNToOUs(const std::string& dn,
xtreemfs::pbrpc::UserCredentials* user_credentials);
/** Path to grid map file which will be periodically re-read. */
std::string gridmap_file_;
/** Thread which reloads the gridmap file. */
boost::scoped_ptr<boost::thread> monitor_thread_;
/** Interval at which the gridmap file will be periodically reread.
*
* @remarks Start() and Stop() have to be executed to start and stop the
* thread responsible for the periodic reread. */
int gridmap_reload_interval_s_;
/** Last time the gridmap file was modified. If changed, fill be reloaded. */
time_t date_;
/** Last known size of gridmap file. If changed, fill be reloaded. */
off_t size_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_H_

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2011-2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_GLOBUS_H_
#define CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_GLOBUS_H_
#include <string>
#include "libxtreemfs/user_mapping_gridmap.h"
namespace xtreemfs {
class UserMappingGridmapGlobus : public UserMappingGridmap {
public:
UserMappingGridmapGlobus(const std::string& gridmap_file,
int gridmap_reload_interval_s);
protected:
virtual void ReadGridmapFile();
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_GLOBUS_H_

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2010-2011 by Patrick Schaefer, Zuse Institute Berlin
* 2011-2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_UNICORE_H_
#define CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_UNICORE_H_
#include <boost/bimap.hpp>
#include <fstream>
#include <string>
#include <map>
#include "libxtreemfs/user_mapping_gridmap.h"
namespace xtreemfs {
class UserMappingGridmapUnicore : public UserMappingGridmap {
public:
UserMappingGridmapUnicore(const std::string& gridmap_file,
int gridmap_reload_interval_s);
protected:
virtual void ReadGridmapFile();
/** Parses the unicore gridmap-file for version < 6. */
void ReadGridmapFileUnicore(
std::ifstream &in,
boost::bimap< std::string, std::string > &new_username,
std::multimap< std::string, std::string > &new_groupname);
/** Parses the unicore gridmap-file for version 6. */
void ReadGridmapFileUnicore6(
std::ifstream &in,
boost::bimap< std::string, std::string > &new_username,
std::multimap< std::string, std::string > &new_groupname);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_GRIDMAP_UNICORE_H_

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_UNIX_H_
#define CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_UNIX_H_
#include <list>
#include <string>
#include "libxtreemfs/user_mapping.h"
namespace xtreemfs {
class UserMappingUnix : public UserMapping {
public:
UserMappingUnix() {}
#ifndef WIN32
/** Left unimplemented. */
virtual void Start() {}
/** Left unimplemented. */
virtual void Stop() {}
virtual std::string UIDToUsername(uid_t uid);
virtual uid_t UsernameToUID(const std::string& username);
virtual std::string GIDToGroupname(gid_t gid);
virtual gid_t GroupnameToGID(const std::string& groupname);
virtual void GetGroupnames(uid_t uid,
gid_t gid,
pid_t pid,
std::list<std::string>* groupnames);
#endif // !WIN32
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_USER_MAPPING_UNIX_H_

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2009-2011 by Patrick Schaefer, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_UUID_CACHE_H_
#define CPP_INCLUDE_LIBXTREEMFS_UUID_CACHE_H_
#include <stdint.h>
#include <boost/thread/mutex.hpp>
#include <map>
#include <string>
namespace xtreemfs {
class UUIDCache {
public:
void update(const std::string& uuid, const std::string& address,
const uint32_t port, const time_t timeout);
std::string get(const std::string& uuid);
private:
struct UUIDMapping {
std::string uuid;
std::string address;
uint32_t port;
time_t timeout;
};
std::map<std::string, UUIDMapping > cache_;
boost::mutex mutex_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_UUID_CACHE_H_

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2012 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_UUID_CONTAINER_H_
#define CPP_INCLUDE_LIBXTREEMFS_UUID_CONTAINER_H_
#include <boost/thread/mutex.hpp>
#include <gtest/gtest_prod.h>
#include <list>
#include <string>
#include <vector>
#include "libxtreemfs/uuid_item.h"
#include "xtreemfs/GlobalTypes.pb.h"
namespace xtreemfs {
class ContainerUUIDIterator;
/** This class stores a list of all UUIDs of a striped replica and is used to
* construct ContainerUUIDIterators for a specific stripe index.
* It also manages the failure-state of the stored UUIDs. */
class UUIDContainer {
public:
UUIDContainer(const xtreemfs::pbrpc::XLocSet& xlocs);
~UUIDContainer();
private:
typedef std::vector<UUIDItem*> InnerContainer;
typedef std::vector<UUIDItem*>::iterator InnerIterator;
typedef std::vector<InnerContainer> Container;
typedef std::vector<InnerContainer>::iterator Iterator;
void GetOSDUUIDsFromXlocSet(const xtreemfs::pbrpc::XLocSet& xlocs);
/** Fills the given uuid_iterator with the UUIDs corresponding to the
* given offsets. This is private because it is only called by
* ContainerUUIDIterator's ctor. */
void FillUUIDIterator(ContainerUUIDIterator* uuid_iterator,
std::vector<size_t> offsets);
/** Obtain a lock on this when accessing uuids_ */
boost::mutex mutex_;
/** List of List of UUIDs. */
Container uuids_;
/** This is needed to only allow ContainerUUIDIterator to call
* FillUUIDIterator. A more strict friend statement which would only
* declare ContainerUUIDIterator's ctor does not work due to circular
* include dependencies.
*/
friend class ContainerUUIDIterator;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_UUID_CONTAINER_H_

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2012 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_UUID_ITEM_H_
#define CPP_INCLUDE_LIBXTREEMFS_UUID_ITEM_H_
#include <stdint.h>
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/version.hpp>
#include <string>
#if (BOOST_VERSION < 104800)
using boost::interprocess::detail::atomic_read32;
using boost::interprocess::detail::atomic_write32;
#else
using boost::interprocess::ipcdetail::atomic_read32;
using boost::interprocess::ipcdetail::atomic_write32;
#endif // BOOST_VERSION < 104800
namespace xtreemfs {
/** Entry object per UUID in list of UUIDs. */
class UUIDItem {
public:
UUIDItem(const std::string& add_uuid)
: uuid(add_uuid),
marked_as_failed(0) {}
bool IsFailed() {
return atomic_read32(&marked_as_failed) > 0;
}
void MarkAsFailed() {
atomic_write32(&marked_as_failed, 1);
}
void Reset() {
atomic_write32(&marked_as_failed, 0);
};
const std::string uuid;
private:
uint32_t marked_as_failed;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_UUID_ITEM_H_

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_UUID_ITERATOR_H_
#define CPP_INCLUDE_LIBXTREEMFS_UUID_ITERATOR_H_
#include <boost/thread/mutex.hpp>
#include <gtest/gtest_prod.h>
#include <list>
#include <string>
#include "libxtreemfs/uuid_item.h"
#include "libxtreemfs/uuid_container.h"
namespace xtreemfs {
/** Stores a list of all UUIDs of a replicated service and allows to iterate
* through them.
*
* If an UUID was marked as failed and this is the current UUID, the next
* call of GetUUID() will return another available, not as failed marked,
* UUID.
*
* If the last UUID in the list is marked as failed, the status of all entries
* will be reset and the current UUID is set to the first in the list.
*
* Additionally, it is allowed to set the current UUID to a specific one,
* regardless of its current state. This is needed in case a service did
* redirect a request to another UUID.
*/
class UUIDIterator {
public:
UUIDIterator();
virtual ~UUIDIterator();
/** Get the current UUID (by default the first in the list).
*
* @throws UUIDIteratorListIsEmpyException
*/
virtual void GetUUID(std::string* result);
/** Marks "uuid" as failed. Use this function to advance to the next in the
* list. */
virtual void MarkUUIDAsFailed(const std::string& uuid);
/** Sets "uuid" as current UUID. If uuid was not found in the list of UUIDs,
* it will be added to the UUIDIterator. */
virtual void SetCurrentUUID(const std::string& uuid) = 0;
/** Clear the list. */
virtual void Clear() = 0;
/** Returns the list of UUIDs and their status. */
virtual std::string DebugString();
protected:
/** Obtain a lock on this when accessing uuids_ or current_uuid_. */
boost::mutex mutex_;
/** Current UUID (advanced if entries are marked as failed).
*
* Please note: "Lists have the important property that insertion and splicing
* do not invalidate iterators to list elements [...]"
* (http://www.sgi.com/tech/stl/List.html)
*/
std::list<UUIDItem*>::iterator current_uuid_;
/** List of UUIDs. */
std::list<UUIDItem*> uuids_;
template<typename T>
FRIEND_TEST(UUIDIteratorTest, ResetAfterEndOfList);
template<typename T>
FRIEND_TEST(UUIDIteratorTest, SetCurrentUUID);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_UUID_ITERATOR_H_

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_UUID_RESOLVER_H_
#define CPP_INCLUDE_LIBXTREEMFS_UUID_RESOLVER_H_
#include <string>
namespace xtreemfs {
class RPCOptions;
class SimpleUUIDIterator;
/** Abstract base class which defines the interface to resolve UUIDs from the
* DIR service. */
class UUIDResolver {
public:
virtual ~UUIDResolver() {}
/** Resolves the address (ip-address:port) for a given UUID.
*
* @throws AddressToUUIDNotFoundException
* @throws UnknownAddressSchemeException
*/
virtual void UUIDToAddress(const std::string& uuid, std::string* address) = 0;
/** Resolves the address (ip-address:port) for a given UUID, using "options".
*
* @throws AddressToUUIDNotFoundException
* @throws UnknownAddressSchemeException
*/
virtual void UUIDToAddressWithOptions(const std::string& uuid,
std::string* address,
const RPCOptions& options) = 0;
/** Resolves the UUID for a given volume name.
*
* @throws VolumeNotFoundException
*/
virtual void VolumeNameToMRCUUID(const std::string& volume_name,
std::string* mrc_uuid) = 0;
/** Resolves the list of UUIDs of the MRC replicas and adds them to the
* uuid_iterator object.
*
* @throws VolumeNotFoundException
*/
virtual void VolumeNameToMRCUUID(const std::string& volume_name,
SimpleUUIDIterator* uuid_iterator) = 0;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_UUID_RESOLVER_H_

View File

@@ -0,0 +1,13 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_VERSION_MANAGEMENT_H_
#define CPP_INCLUDE_LIBXTREEMFS_VERSION_MANAGEMENT_H_
#define XTREEMFS_VERSION_STRING "1.5.1 (Wonderful Waffles)"
#endif // CPP_INCLUDE_LIBXTREEMFS_VERSION_MANAGEMENT_H_

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2009 Juan Gonzalez de Benito,
* 2011 Bjoern Kolbeck (Zuse Institute Berlin),
* 2012 Matthias Noack (Zuse Institute Berlin)
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_VIVALDI_H_
#define CPP_INCLUDE_LIBXTREEMFS_VIVALDI_H_
#include <boost/scoped_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <list>
#include <string>
#include "libxtreemfs/options.h"
#include "libxtreemfs/vivaldi_node.h"
#include "xtreemfs/GlobalTypes.pb.h"
namespace xtreemfs {
namespace pbrpc {
class DIRServiceClient;
class OSDServiceClient;
} // namespace pbrpc
namespace rpc {
class Client;
} // namespace rpc
class SimpleUUIDIterator;
class UUIDResolver;
class KnownOSD {
public:
KnownOSD(const std::string& uuid,
const xtreemfs::pbrpc::VivaldiCoordinates& coordinates)
: uuid(uuid),
coordinates(coordinates) {
}
bool operator==(const KnownOSD& other) {
return (uuid == other.uuid) &&
(coordinates.local_error() == other.coordinates.local_error()) &&
(coordinates.x_coordinate() == other.coordinates.x_coordinate()) &&
(coordinates.y_coordinate() == other.coordinates.y_coordinate());
}
pbrpc::VivaldiCoordinates* GetCoordinates() {
return &coordinates;
}
const std::string& GetUUID() {
return uuid;
}
void SetCoordinates(const pbrpc::VivaldiCoordinates& new_coords) {
coordinates = new_coords;
}
private:
std::string uuid;
pbrpc::VivaldiCoordinates coordinates;
};
class Vivaldi {
public:
/**
* @remarks Ownership is not transferred.
*/
Vivaldi(const ServiceAddresses& dir_addresses,
UUIDResolver* uuid_resolver,
const Options& options);
void Initialize(rpc::Client* network_client);
void Run();
const xtreemfs::pbrpc::VivaldiCoordinates& GetVivaldiCoordinates() const;
private:
bool UpdateKnownOSDs(std::list<KnownOSD>* updated_osds,
const VivaldiNode& own_node);
boost::scoped_ptr<pbrpc::DIRServiceClient> dir_client_;
boost::scoped_ptr<pbrpc::OSDServiceClient> osd_client_;
boost::scoped_ptr<SimpleUUIDIterator> dir_service_addresses_;
UUIDResolver* uuid_resolver_;
/** Shallow copy of the Client's options, with disabled retry and interrupt
* functionality. */
Options vivaldi_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(). */
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 "xtreems".
*
* @remark Cannot be set to const because it's modified inside the
* constructor VolumeImplementation(). */
pbrpc::UserCredentials user_credentials_bogus_;
/** Mutex to serialise concurrent read and write access to
* my_vivaldi_coordinates_. */
mutable boost::mutex coordinate_mutex_;
pbrpc::VivaldiCoordinates my_vivaldi_coordinates_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_VIVALDI_H_

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2009 Juan Gonzalez de Benito.
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_VIVALDI_NODE_H_
#define CPP_INCLUDE_LIBXTREEMFS_VIVALDI_NODE_H_
#include <stdint.h>
#include <string>
#include "pbrpc/RPC.pb.h"
#include "xtreemfs/GlobalTypes.pb.h"
#define CONSTANT_E 0.10
#define CONSTANT_C 0.25
#define MAX_MOVEMENT_RATIO 0.10
/*
* If the client contacts an OSD which has not started recalculating its position
* yet (and therefore has no information about the space) it just trusts it partially.
* Next value is used to reduce the magnitude of the proposed movement.
*/
#define WEIGHT_IF_OSD_UNINITIALIZED 0.1
namespace xtreemfs {
class VivaldiNode {
public:
explicit VivaldiNode(
const xtreemfs::pbrpc::VivaldiCoordinates& nodeCoordinates)
: ownCoordinates(nodeCoordinates) {
}
const xtreemfs::pbrpc::VivaldiCoordinates* GetCoordinates() const;
bool RecalculatePosition(
const xtreemfs::pbrpc::VivaldiCoordinates& coordinatesJ,
uint64_t measuredRTT,
bool forceRecalculation);
static double CalculateDistance(xtreemfs::pbrpc::VivaldiCoordinates coordA,
const xtreemfs::pbrpc::VivaldiCoordinates& coordB);
private:
static void MultiplyValueCoordinates(
xtreemfs::pbrpc::VivaldiCoordinates* coord,
double value);
static void AddCoordinates(xtreemfs::pbrpc::VivaldiCoordinates* coordA,
const xtreemfs::pbrpc::VivaldiCoordinates& coordB);
static void SubtractCoordinates(xtreemfs::pbrpc::VivaldiCoordinates* coordA,
const xtreemfs::pbrpc::VivaldiCoordinates& coordB);
static double ScalarProductCoordinates(
const xtreemfs::pbrpc::VivaldiCoordinates& coordA,
const xtreemfs::pbrpc::VivaldiCoordinates& coordB);
static double MagnitudeCoordinates(
const xtreemfs::pbrpc::VivaldiCoordinates& coordA);
static bool GetUnitaryCoordinates(xtreemfs::pbrpc::VivaldiCoordinates* coord);
static void ModifyCoordinatesRandomly(
xtreemfs::pbrpc::VivaldiCoordinates* coord);
xtreemfs::pbrpc::VivaldiCoordinates ownCoordinates;
};
class OutputUtils {
public:
static void StringToCoordinates(const std::string& str,
xtreemfs::pbrpc::VivaldiCoordinates &vc);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_VIVALDI_NODE_H_

View File

@@ -0,0 +1,523 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_VOLUME_H_
#define CPP_INCLUDE_LIBXTREEMFS_VOLUME_H_
#include <stdint.h>
#include <list>
#include <string>
#include "pbrpc/RPC.pb.h"
#include "xtreemfs/GlobalTypes.pb.h"
#include "xtreemfs/MRC.pb.h"
namespace xtreemfs {
class FileHandle;
/*
* A Volume object corresponds to a mounted XtreemFS volume and defines
* the available functions to access the file system.
*/
class Volume {
public:
virtual ~Volume() {}
/** Closes the Volume.
*
* @throws OpenFileHandlesLeftException
*/
virtual void Close() = 0;
/** Returns information about the volume (e.g. used/free space).
*
* @param user_credentials Name and Groups of the user.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @remark Ownership is transferred to the caller.
*/
virtual xtreemfs::pbrpc::StatVFS* StatFS(
const xtreemfs::pbrpc::UserCredentials& user_credentials) = 0;
/** Resolves the symbolic link at "path" and returns it in "link_target_path".
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the symbolic link.
* @param link_target_path[out] String where to store the result.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void ReadLink(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
std::string* link_target_path) = 0;
/** Creates a symbolic link pointing to "target_path" at "link_path".
*
* @param user_credentials Name and Groups of the user.
* @param target_path Path to the target.
* @param link_path Path to the symbolic link.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void Symlink(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& target_path,
const std::string& link_path) = 0;
/** Creates a hard link pointing to "target_path" at "link_path".
*
* @param user_credentials Name and Groups of the user.
* @param target_path Path to the target.
* @param link_path Path to the hard link.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void Link(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& target_path,
const std::string& link_path) = 0;
/** Tests if the subject described by "user_credentials" is allowed to access
* "path" as specified by "flags". "flags" is a bit mask which may contain
* the values ACCESS_FLAGS_{F_OK,R_OK,W_OK,X_OK}.
*
* Throws a PosixErrorException if not allowed.
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param flags Open flags as specified in xtreemfs::pbrpc::SYSTEM_V_FCNTL.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void Access(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const xtreemfs::pbrpc::ACCESS_FLAGS flags) = 0;
/** Opens a file and returns the pointer to a FileHandle object.
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file.
* @param flags Open flags as specified in xtreemfs::pbrpc::SYSTEM_V_FCNTL.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @remark Ownership is NOT transferred to the caller. Instead
* FileHandle->Close() has to be called to destroy the object.
*/
virtual FileHandle* OpenFile(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const xtreemfs::pbrpc::SYSTEM_V_FCNTL flags) = 0;
/** Same as previous OpenFile() except for the additional mode parameter,
* which sets the permissions for the file in case SYSTEM_V_FCNTL_H_O_CREAT
* is specified as flag and the file will be created.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual FileHandle* OpenFile(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const xtreemfs::pbrpc::SYSTEM_V_FCNTL flags,
uint32_t mode) = 0;
/** Same as previous OpenFile() except for the additional parameter
* "attributes" which also stores Windows FileAttributes on the MRC
* when creating a file. See the MSDN article "File Attribute Constants" for
* the list of possible * values e.g., here: http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117%28v=vs.85%29.aspx // NOLINT
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
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) = 0;
/** Truncates the file to "new_file_size_ bytes.
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file.
* @param new_file_size New size of file.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void Truncate(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
off_t new_file_size) = 0;
/** Retrieve the attributes of a file and writes the result in "stat".
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param stat[out] Result of the operation will be stored here.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void GetAttr(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
xtreemfs::pbrpc::Stat* stat) = 0;
/** Retrieve the attributes of a file and writes the result in "stat".
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param ignore_metadata_cache If true, do not use the cached value.
* The cache will be updated, though.
* @param stat[out] Result of the operation will be stored here.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void GetAttr(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
bool ignore_metadata_cache,
xtreemfs::pbrpc::Stat* stat) = 0;
/** Sets the attributes given by "stat" and specified in "to_set".
*
* @note If the mode, uid or gid is changed, the ctime of the file will be
* updated according to POSIX semantics.
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param stat Stat object with attributes which will be set.
* @param to_set Bitmask which defines which attributes to set.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void SetAttr(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const xtreemfs::pbrpc::Stat& stat,
xtreemfs::pbrpc::Setattrs to_set) = 0;
/** Remove the file at "path" (deletes the entry at the MRC and all objects
* on one OSD).
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void Unlink(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path) = 0;
/** Rename a file or directory "path" to "new_path".
*
* @param user_credentials Name and Groups of the user.
* @param path Old path.
* @param new_path New path.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
* */
virtual void Rename(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const std::string& new_path) = 0;
/** Creates a directory with the modes "mode".
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the new directory.
* @param mode Permissions of the new directory.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void MakeDirectory(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
unsigned int mode) = 0;
/** Removes the directory at "path" which has to be empty.
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the directory to be removed.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void DeleteDirectory(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path) = 0;
/** Appends the list of requested directory entries to "dir_entries".
*
* There does not exist something like OpenDir and CloseDir. Instead one can
* limit the number of requested entries (count) and specify the offset.
*
* DirectoryEntries will contain the names of the entries and, if not disabled
* by "names_only", a Stat object for every entry.
*
* @remark Even if names_only is set to false, an entry does _not_ need to
* contain a stat buffer. Always check with entries(i).has_stbuf()
* if the i'th entry does have a stat buffer before accessing it.
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the directory.
* @param offset Index of first requested entry.
* @param count Number of requested entries.
* @param names_only If set to true, the Stat object of every entry will be
* omitted.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @remark Ownership is transferred to the caller.
*/
virtual xtreemfs::pbrpc::DirectoryEntries* ReadDir(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
uint64_t offset,
uint32_t count,
bool names_only) = 0;
/** Returns the list of extended attributes stored for "path" (Entries may
* be cached).
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @remark Ownership is transferred to the caller.
*/
virtual xtreemfs::pbrpc::listxattrResponse* ListXAttrs(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path) = 0;
/** Returns the list of extended attributes stored for "path" (Set "use_cache"
* to false to make sure no cached entries are returned).
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param use_cache Set to false to fetch the attributes from the MRC.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @remark Ownership is transferred to the caller.
*/
virtual xtreemfs::pbrpc::listxattrResponse* ListXAttrs(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
bool use_cache) = 0;
/** Sets the extended attribute "name" of "path" to "value".
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param name Name of the extended attribute.
* @param value Value of the extended attribute.
* @param flags May be 1 (= XATTR_CREATE) or 2 (= XATTR_REPLACE).
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
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) = 0;
/** Writes value for an XAttribute with "name" stored for "path" in "value".
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param name Name of the extended attribute.
* @param value[out] Will contain the content of the extended attribute.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @return true if the attribute was found.
*/
virtual bool GetXAttr(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const std::string& name,
std::string* value) = 0;
/** Writes the size of a value (string size without null-termination) of an
* XAttribute "name" stored for "path" in "size".
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param name Name of the extended attribute.
* @param size[out] Will contain the size of the extended attribute.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*
* @return true if the attribute was found.
*/
virtual bool GetXAttrSize(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const std::string& name,
int* size) = 0;
/** Removes the extended attribute "name", stored for "path".
*
* @param user_credentials Name and Groups of the user.
* @param path Path to the file/directory.
* @param name Name of the extended attribute.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void RemoveXAttr(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const std::string& name) = 0;
/** Adds a new replica for the file at "path" and triggers the replication of
* this replica if it's a full replica.
*
* @param user_credentials Username and groups of the user.
* @param path Path to the file.
* @param new_replica Description of the new replica to be added.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* */
virtual void AddReplica(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const xtreemfs::pbrpc::Replica& new_replica) = 0;
/** Return the list of replicas of the file at "path".
*
* @param user_credentials Username and groups of the user.
* @param path Path to the file.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
*
* @remark Ownership is transferred to the caller.
*/
virtual xtreemfs::pbrpc::Replicas* ListReplicas(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path) = 0;
/** Removes the replica of file at "path" located on the OSD with the UUID
* "osd_uuid" (which has to be the head OSD in case of striping).
*
* @param user_credentials Username and groups of the user.
* @param path Path to the file.
* @param osd_uuid UUID of the OSD from which the replica will be
* deleted.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
virtual void RemoveReplica(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
const std::string& osd_uuid) = 0;
/** Adds all available OSDs where the file (described by "path") can be
* placed to "list_of_osd_uuids"
*
* @param user_credentials Username and groups of the user.
* @param path Path to the file.
* @param number_of_osds Number of OSDs required in a valid group. This
* is only relevant for grouping and will be
* ignored by filtering and sorting policies.
* @param list_of_osd_uuids[out] List of strings to which the UUIDs will be
* appended.
*
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
*/
virtual void GetSuitableOSDs(
const xtreemfs::pbrpc::UserCredentials& user_credentials,
const std::string& path,
int number_of_osds,
std::list<std::string>* list_of_osd_uuids) = 0;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_VOLUME_H_

View File

@@ -0,0 +1,406 @@
/*
* 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 <stdint.h>
#include <boost/scoped_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <gtest/gtest_prod.h>
#include <list>
#include <map>
#include <string>
#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<std::string>* 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<xtreemfs::pbrpc::StripingPolicyType,
StripeTranslator*>& 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<UUIDIterator> 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<xtreemfs::rpc::Client> network_client_;
boost::scoped_ptr<boost::thread> network_client_thread_;
/** An MRCServiceClient is a wrapper for an RPC Client. */
boost::scoped_ptr<xtreemfs::pbrpc::MRCServiceClient> mrc_service_client_;
/** A OSDServiceClient is a wrapper for an RPC Client. */
boost::scoped_ptr<xtreemfs::pbrpc::OSDServiceClient> osd_service_client_;
/** Maps file_id -> FileInfo* for every open file. */
std::map<uint64_t, FileInfo*> 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<xtreemfs::pbrpc::StripingPolicyType,
StripeTranslator*> stripe_translators_;
/** Periodically renews the XCap of every FileHandle before it expires. */
boost::scoped_ptr<boost::thread> xcap_renewal_thread_;
/** Periodically writes back pending file sizes updates to the MRC service. */
boost::scoped_ptr<boost::thread> filesize_writeback_thread_;
FRIEND_TEST(VolumeImplementationTest,
StatCacheCorrectlyUpdatedAfterRenameWriteAndClose);
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_VOLUME_IMPLEMENTATION_H_

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_XCAP_HANDLER_H_
#define CPP_INCLUDE_LIBXTREEMFS_XCAP_HANDLER_H_
namespace xtreemfs {
namespace pbrpc {
class XCap;
} // namespace pbrpc
/** An interface which allows to retrieve the latest XCap. */
class XCapHandler {
public:
virtual ~XCapHandler() {}
/** Update "outdated_xcap" with latest XCap. */
virtual void GetXCap(xtreemfs::pbrpc::XCap* outdated_xcap) = 0;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_XCAP_HANDLER_H_

View File

@@ -0,0 +1,153 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LIBXTREEMFS_XTREEMFS_EXCEPTION_H_
#define CPP_INCLUDE_LIBXTREEMFS_XTREEMFS_EXCEPTION_H_
#include <stdint.h>
#include <boost/lexical_cast.hpp>
#include <stdexcept>
#include <string>
#include "pbrpc/RPC.pb.h"
namespace xtreemfs {
class XtreemFSException : public std::runtime_error {
public:
explicit XtreemFSException(const std::string& msg)
: std::runtime_error(msg) {}
};
class PosixErrorException : public XtreemFSException {
public:
PosixErrorException(xtreemfs::pbrpc::POSIXErrno posix_errno,
const std::string& msg)
: XtreemFSException(msg),
posix_errno_(posix_errno) {}
xtreemfs::pbrpc::POSIXErrno posix_errno() const { return posix_errno_; }
private:
xtreemfs::pbrpc::POSIXErrno posix_errno_;
};
/** Will be thrown, if there was an IO_ERROR in the RPC Client on the client
* side. */
class IOException : public XtreemFSException {
public:
IOException() : XtreemFSException("IOError occurred.") {}
explicit IOException(const std::string& msg)
: XtreemFSException(msg) {}
};
/** Will be thrown if the server did return an INTERNAL_SERVER_ERROR. */
class InternalServerErrorException : public XtreemFSException {
public:
InternalServerErrorException()
: XtreemFSException("Internal Server Error received.") {}
explicit InternalServerErrorException(const std::string& msg)
: XtreemFSException(msg) {}
};
/** Thrown if FileInfo for given file_id was not found in OpenFileTable.
*
* Every FileHandle does reference a FileInfo object where per-file properties
* are stored. This exception should never occur as it means there was no
* FileInfo for the FileHandle.
*/
class FileInfoNotFoundException : public XtreemFSException {
public:
explicit FileInfoNotFoundException(uint64_t file_id)
: XtreemFSException("The FileInfo object was not found in the OpenFileTable"
" for the FileId: " + boost::lexical_cast<std::string>(file_id)) {}
};
/** Thrown if FileHandle for given file_id was not found in FileHandleList. */
class FileHandleNotFoundException : public XtreemFSException {
public:
explicit FileHandleNotFoundException()
: XtreemFSException("The FileHandle object was not found in the "
"FileHandleList") {}
};
class AddressToUUIDNotFoundException : public XtreemFSException {
public:
explicit AddressToUUIDNotFoundException(const std::string& uuid)
: XtreemFSException("Address for UUID not found: " + uuid) {}
};
class VolumeNotFoundException : public XtreemFSException {
public:
explicit VolumeNotFoundException(const std::string& volume_name)
: XtreemFSException("Volume not found: " + volume_name) {}
};
class OpenFileHandlesLeftException : public XtreemFSException {
public:
OpenFileHandlesLeftException() : XtreemFSException("There are remaining open "
"FileHandles which have to be closed first.") {}
};
/** Thrown if the DIR Service did return a AddressMapping which is not known. */
class UnknownAddressSchemeException : public XtreemFSException {
public:
explicit UnknownAddressSchemeException(const std::string& msg)
: XtreemFSException(msg) {}
};
/** Thrown if a given UUID was not found in the xlocset of a file. */
class UUIDNotInXlocSetException : public XtreemFSException {
public:
explicit UUIDNotInXlocSetException(const std::string& msg)
: XtreemFSException(msg) {}
};
/** Thrown if there was an operation on an UUIDIterator requested which could
* not be fulfilled, e.g. retrieve a UUID, because the list of UUIDs of the
* UUIDIterator was empty. */
class UUIDIteratorListIsEmpyException : public XtreemFSException {
public:
explicit UUIDIteratorListIsEmpyException(const std::string& msg)
: XtreemFSException(msg) {}
};
/** Thrown if there was an empty replicas list in an XlocSet. */
class EmptyReplicaListInXlocSet : public XtreemFSException {
public:
explicit EmptyReplicaListInXlocSet(const std::string& msg)
: XtreemFSException(msg) {}
};
/** Thrown if there was no head OSD for a replica listed in an XlocSet. */
class NoHeadOSDInXlocSet : public XtreemFSException {
public:
explicit NoHeadOSDInXlocSet(const std::string& msg)
: XtreemFSException(msg) {}
};
/** Thrown if the given URL was not parsed correctly. */
class InvalidURLException : public XtreemFSException {
public:
explicit InvalidURLException(const std::string& msg)
: XtreemFSException(msg) {}
};
class InvalidCommandLineParametersException : public XtreemFSException {
public:
explicit InvalidCommandLineParametersException(const std::string& msg)
: XtreemFSException(msg) {}
};
class InvalidViewException : public XtreemFSException {
public:
explicit InvalidViewException(const std::string& msg)
: XtreemFSException(msg) {}
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LIBXTREEMFS_XTREEMFS_EXCEPTION_H_