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,274 @@
/*
* Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_
#define CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_
#define WIN32_LEAN_AND_MEAN
#include <windows.h> // required for CbFS.h
#include <boost/cstdint.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp>
#include <CbFS.h>
#include "xtfsutil/xtfsutil_server.h"
#include "xtreemfs/GlobalTypes.pb.h"
namespace xtreemfs {
namespace pbrpc {
class Stat;
} // namespace pbrpc
class CbFSOptions;
class Client;
class SystemUserMapping;
class CbFSAdapter {
public:
/** Replace "\" path separator by "/" and convert UTF-16 to UTF-8. */
static std::string WindowsPathToUTF8Unix(const wchar_t* from);
static void DebugPrintCreateFile(
LPCWSTR OperationType,
LPCTSTR FileName,
ACCESS_MASK DesiredAccess,
DWORD FileAttributes,
DWORD ShareMode,
PVOID FileHandleContext);
/** Creates a new instance of CbFSAdapter, but does not create any
* libxtreemfs Client yet.
*
* Use Start() to actually create the client and mount the volume given in
* options. May modify options.
*/
explicit CbFSAdapter(CbFSOptions* options);
~CbFSAdapter();
/** Create client, open volume and start needed threads. */
void Start();
/** Shutdown threads, close Volume and Client and blocks until all threads
* are stopped. */
void Stop();
/** Same as Stop(), but does not call cbfs_.UnmountMedia(). */
void StopWithoutUnmount();
void GetVolumeSize(CallbackFileSystem* Sender,
__int64* TotalNumberOfSectors,
__int64* NumberOfFreeSectors);
void GetVolumeLabel(CallbackFileSystem* Sender, LPTSTR VolumeLabel);
void GetVolumeId(CallbackFileSystem* Sender, PDWORD VolumeID);
void CreateFile(CallbackFileSystem* Sender,
LPCTSTR FileName,
ACCESS_MASK DesiredAccess,
DWORD FileAttributes,
DWORD ShareMode,
PVOID* FileHandleContext);
void OpenFile(CallbackFileSystem* Sender,
LPCTSTR FileName,
ACCESS_MASK DesiredAccess,
DWORD ShareMode,
PVOID* FileHandleContext);
void CloseFile(CallbackFileSystem* Sender,
CbFsFileInfo* FileInfo,
PVOID FileHandleContext);
void GetFileInfo(CallbackFileSystem* Sender,
LPCTSTR FileName,
LPBOOL FileExists,
PFILETIME CreationTime,
PFILETIME LastAccessTime,
PFILETIME LastWriteTime,
__int64* EndOfFile,
__int64* AllocationSize,
__int64* FileId,
PDWORD FileAttributes,
LPTSTR LongFileName OPTIONAL,
PWORD LongFileNameLength OPTIONAL);
void EnumerateDirectory(CallbackFileSystem* Sender,
CbFsFileInfo* DirectoryInfo,
PVOID* EnumerationContext,
LPCTSTR Mask,
INT Index,
BOOL Restart,
LPBOOL FileFound,
LPTSTR FileName,
PDWORD FileNameLength,
LPTSTR ShortFileName OPTIONAL,
PUCHAR ShortFileNameLength OPTIONAL,
PFILETIME CreationTime,
PFILETIME LastAccessTime,
PFILETIME LastWriteTime,
__int64* EndOfFile,
__int64* AllocationSize,
__int64* FileId,
PDWORD FileAttributes);
void CloseEnumeration(CallbackFileSystem* Sender,
CbFsFileInfo* DirectoryInfo,
PVOID EnumerationContext);
void SetAllocationSize(CallbackFileSystem* Sender,
CbFsFileInfo* FileInfo,
PVOID FileHandleContext,
__int64 AllocationSize);
void SetEndOfFile(CallbackFileSystem* Sender,
CbFsFileInfo* FileInfo,
PVOID FileHandleContext,
__int64 EndOfFile);
void SetFileAttributes(CallbackFileSystem* Sender,
CbFsFileInfo* FileInfo,
PVOID FileHandleContext,
PFILETIME CreationTime,
PFILETIME LastAccessTime,
PFILETIME LastWriteTime,
DWORD FileAttributes);
void CanFileBeDeleted(CallbackFileSystem* Sender,
CbFsFileInfo* FileInfo,
BOOL* CanBeDeleted);
void DeleteFile(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo);
void RenameOrMoveFile(CallbackFileSystem* Sender,
CbFsFileInfo* FileInfo,
LPCTSTR NewFileName);
void ReadFile(CallbackFileSystem* Sender,
CbFsFileInfo* FileInfo,
PVOID FileHandleContext,
__int64 Position,
PVOID Buffer,
DWORD BytesToRead,
PDWORD BytesRead);
void WriteFile(CallbackFileSystem* Sender,
CbFsFileInfo* FileInfo,
PVOID FileHandleContext,
__int64 Position,
PVOID Buffer,
DWORD BytesToWrite,
PDWORD BytesWritten);
void IsDirectoryEmpty(CallbackFileSystem* Sender,
LPWSTR FileName,
LPBOOL IsEmpty);
void StorageEjected(CallbackFileSystem* Sender);
/** Blocks until device was ejected by user. */
void WaitForEjection();
private:
static const DWORD kMaxFileNameLength = 32767;
static const size_t kMaxVolumeLabelLength = 32;
/** Print debug output to stdout. */
static void DbgPrint(LPCWSTR format, ...);
/** Output exception thrown by CBFS as string. */
static std::string ECBFSErrorToString(ECBFSError& e);
/** Maps XtreemFS return values to Windows specific ones. */
static int ConvertXtreemFSErrnoToWindows(
xtreemfs::pbrpc::POSIXErrno xtreemfs_errno);
/** Convert UNIX timestamp (in nanoseconds) to Windows time format. */
static void XtreemFSTimeToWinTime(uint64_t utime_ns,
DWORD* lower,
DWORD* upper);
/** Convert Windows timestamp to UNIX timestamp (in nanoseconds). */
static boost::uint64_t ConvertWinTimeToXtreemFSTime(DWORD lower,
DWORD upper);
/** Returns true if "stat" is a directory. */
static bool IsDirectory(const xtreemfs::pbrpc::Stat& stat);
/** Convert "desired_access", passed at Create and Open, to e.g., O_RDWR. */
static xtreemfs::pbrpc::SYSTEM_V_FCNTL ConvertFlagsWindowsToXtreemFS(
const ACCESS_MASK desired_access);
/** Provides the CBFS library the required license key. */
void SetRegistrationKey();
/** Returns true if "path" is a directory.
* @throws AddressToUUIDNotFoundException
* @throws IOException
* @throws PosixErrorException
* @throws UnknownAddressSchemeException
*/
bool IsDirectory(const std::string& path);
/** Same as GetFileInfo(), except that "path" is an UTF8 encoded UNIX path. */
void ConvertXtreemFSStatToCbFS(const xtreemfs::pbrpc::Stat& stat,
PFILETIME CreationTime,
PFILETIME LastAccessTime,
PFILETIME LastWriteTime,
__int64* EndOfFile,
__int64* AllocationSize,
__int64* FileId,
PDWORD FileAttributes,
LPTSTR LongFileName OPTIONAL,
PWORD LongFileNameLength OPTIONAL);
/** Contains all needed options to mount the requested volume. */
CbFSOptions* options_;
/** Volume Label generated from the given XtreemFS URL. */
std::wstring volume_label_;
/** The chosen UserMapping provides methods to translate between local and
* remote usernames and groups. */
boost::scoped_ptr<SystemUserMapping> system_user_mapping_;
/** Username and domain name of user executing the Dokan client. Will be used
* by all XtreemFS operations. */
xtreemfs::pbrpc::UserCredentials user_credentials_;
/** Created libxtreemfs Client. */
boost::scoped_ptr<Client> client_;
/** Opened libxtreemfs Volume. */
Volume* volume_;
/** Server for processing commands sent from the xtfsutil tool
via xctl files. */
XtfsUtilServer xctl_;
/** Callback Filesystem instance which provides a Windows user space
* file system interface. */
CallbackFileSystem cbfs_;
/** True if device was ejected by user. */
bool device_ejected_;
/** Guards device_ejected_. */
boost::mutex device_ejected_mutex_;
/** Used when waiting for a change of device_ejected_. */
boost::condition device_ejected_cond_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_CBFS_CBFS_ENUMERATION_CONTEXT_H_
#define CPP_INCLUDE_CBFS_CBFS_ENUMERATION_CONTEXT_H_
#include <boost/cstdint.hpp>
namespace xtreemfs {
namespace pbrpc {
class DirectoryEntries;
} // namespace pbrpc
struct CbFSEnumerationContext {
CbFSEnumerationContext();
~CbFSEnumerationContext();
/** Index in the complete directory listing where dir_entries starts. */
boost::uint64_t offset;
xtreemfs::pbrpc::DirectoryEntries* dir_entries;
/** Index of next entry which will be returned from dir_entries (starting from
* 0).
*
* @attention This is relative to dir_entries, not to the complete dir.
*/
int next_index;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_CBFS_CBFS_ENUMERATION_CONTEXT_H_

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_CBFS_CBFS_OPTIONS_H_
#define CPP_INCLUDE_CBFS_CBFS_OPTIONS_H_
#include "libxtreemfs/options.h"
#include <boost/program_options.hpp>
#include <string>
#include <vector>
namespace xtreemfs {
class CbFSOptions : public Options {
public:
/** Sets the default values. */
CbFSOptions();
/** Set options parsed from command line which must contain at least the URL
* to a XtreemFS volume and a mount point.
*
* Calls Options::ParseCommandLine() to parse general options.
*
* @throws InvalidCommandLineParametersException
* @throws InvalidURLException */
void ParseCommandLine(int argc, char** argv);
/** Shows only the minimal help text describing the usage of mount.xtreemfs.*/
std::string ShowCommandLineUsage();
/** Outputs usage of the command line parameters. */
virtual std::string ShowCommandLineHelp();
// CbFS options.
private:
/** Contains all available CbFS options and its descriptions. */
boost::program_options::options_description cbfs_descriptions_;
/** Brief help text if there are no command line arguments. */
std::string helptext_usage_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_CBFS_CBFS_OPTIONS_H_

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_FUSE_CACHED_DIRECTORY_ENTRIES_H_
#define CPP_INCLUDE_FUSE_CACHED_DIRECTORY_ENTRIES_H_
#include <stdint.h>
#include <boost/thread/mutex.hpp>
namespace xtreemfs {
namespace pbrpc {
class DirectoryEntries;
} // namespace pbrpc
struct CachedDirectoryEntries {
uint64_t offset;
xtreemfs::pbrpc::DirectoryEntries* dir_entries;
boost::mutex mutex;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_FUSE_CACHED_DIRECTORY_ENTRIES_H_

View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_FUSE_FUSE_ADAPTER_H_
#define CPP_INCLUDE_FUSE_FUSE_ADAPTER_H_
#include <sys/types.h>
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <boost/scoped_ptr.hpp>
#include <list>
#include <string>
#include "libxtreemfs/system_user_mapping_unix.h"
#include "xtfsutil/xtfsutil_server.h"
#include "xtreemfs/GlobalTypes.pb.h"
namespace xtreemfs {
class Client;
class FuseOptions;
class UserMapping;
class Volume;
namespace pbrpc {
class Stat;
class UserCredentials;
} // namespace pbrpc
/** Uses fuse_interrupted() to check if an operation was cancelled by the user
* and stops retrying to execute the request then.
*
* Always returns 0, if called from a non-Fuse thread. */
int CheckIfOperationInterrupted();
class FuseAdapter {
public:
/** Creates a new instance of FuseAdapter, but does not create any libxtreemfs
* Client yet.
*
* Use Start() to actually create the client and mount the volume given in
* options. May modify options.
*/
explicit FuseAdapter(FuseOptions* options);
~FuseAdapter();
/** Create client, open volume and start needed threads.
* @return Returns a list of additional "-o<option>" Fuse options which may be
* generated after processing the "options" parameter and have to be
* considered before starting Fuse.
* @remark Ownership of the list elements is transferred to the caller. */
void Start(std::list<char*>* required_fuse_options);
/** Shutdown threads, close Volume and Client and blocks until all threads are
* stopped. */
void Stop();
/** After successfully executing fuse_new, tell libxtreemfs to use
* fuse_interrupted() if a request was cancelled by the user. */
void SetInterruptQueryFunction() const;
void GenerateUserCredentials(
uid_t uid,
gid_t gid,
pid_t pid,
xtreemfs::pbrpc::UserCredentials* user_credentials);
/** Generate UserCredentials using information from fuse context or the
* current process (in that case set fuse_context to NULL). */
void GenerateUserCredentials(
struct fuse_context* fuse_context,
xtreemfs::pbrpc::UserCredentials* user_credentials);
/** Fill a Fuse stat object with information from an XtreemFS stat. */
void ConvertXtreemFSStatToFuse(const xtreemfs::pbrpc::Stat& xtreemfs_stat,
struct stat* fuse_stat);
/** Converts given UNIX file handle flags into XtreemFS symbols. */
xtreemfs::pbrpc::SYSTEM_V_FCNTL ConvertFlagsUnixToXtreemFS(int flags);
/** Converts from XtreemFS error codes to the system ones. */
int ConvertXtreemFSErrnoToFuse(xtreemfs::pbrpc::POSIXErrno xtreemfs_errno);
// Fuse operations as called by placeholder functions in fuse_operations.h. */
int statfs(const char *path, struct statvfs *statv);
int getattr(const char *path, struct stat *statbuf);
int getxattr(const char *path, const char *name, char *value, size_t size);
/** Creates CachedDirectoryEntries struct and let fi->fh point to it. */
int opendir(const char *path, struct fuse_file_info *fi);
/** Uses the Fuse readdir offset approach to handle readdir requests in chunks
* instead of one large request. */
int readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
struct fuse_file_info *fi);
/** Deletes CachedDirectoryEntries struct which is hold by fi->fh. */
int releasedir(const char *path, struct fuse_file_info *fi);
int utime(const char *path, struct utimbuf *ubuf);
int utimens(const char *path, const struct timespec tv[2]);
int create(const char *path, mode_t mode, struct fuse_file_info *fi);
int mknod(const char *path, mode_t mode, dev_t device);
int mkdir(const char *path, mode_t mode);
int open(const char *path, struct fuse_file_info *fi);
int truncate(const char *path, off_t newsize);
int ftruncate(const char *path, off_t offset, struct fuse_file_info *fi);
int write(const char *path, const char *buf, size_t size, off_t offset,
struct fuse_file_info *fi);
int flush(const char *path, struct fuse_file_info *fi);
int read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi);
int access(const char *path, int mask);
int unlink(const char *path);
int fgetattr(const char *path, struct stat *statbuf,
struct fuse_file_info *fi);
int release(const char *path, struct fuse_file_info *fi);
int readlink(const char *path, char *buf, size_t size);
int rmdir(const char *path);
int symlink(const char *path, const char *link);
int rename(const char *path, const char *newpath);
int link(const char *path, const char *newpath);
int chmod(const char *path, mode_t mode);
int chown(const char *path, uid_t uid, gid_t gid);
int setxattr(const char *path, const char *name, const char *value,
size_t size, int flags);
int listxattr(const char *path, char *list, size_t size);
int removexattr(const char *path, const char *name);
int lock(const char* path, struct fuse_file_info *fi, int cmd,
struct flock* flock);
private:
/** Contains all needed options to mount the requested volume. */
FuseOptions* options_;
/** Translates between local and remote usernames and groups. */
SystemUserMappingUnix system_user_mapping_;
/** Created libxtreemfs Client. */
boost::scoped_ptr<Client> client_;
/** Opened libxtreemfs Volume. */
Volume* volume_;
/** Server for processing commands sent from the xtfsutil tool
via xctl files. */
XtfsUtilServer xctl_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_FUSE_FUSE_ADAPTER_H_

View File

@@ -0,0 +1,106 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_FUSE_FUSE_OPERATIONS_H_
#define CPP_INCLUDE_FUSE_FUSE_OPERATIONS_H_
#include <sys/types.h>
#define FUSE_USE_VERSION 26
#include <fuse.h>
namespace xtreemfs {
class FuseAdapter;
}
/** Contains functions which are passed into fuse_operations struct.
* @file
*
* The functions in this file are merely placeholders which call the actual
* functions of the FuseAdapter instance pointed to by fuse_adapter.
*/
/** Points to the FuseAdapter instance created by mount.xtreemfs.cpp. */
extern xtreemfs::FuseAdapter* fuse_adapter;
extern "C" int xtreemfs_fuse_getattr(const char *path, struct stat *statbuf);
extern "C" int xtreemfs_fuse_readlink(const char *path, char *link,
size_t size);
extern "C" int xtreemfs_fuse_mknod(const char *path, mode_t mode, dev_t dev);
extern "C" int xtreemfs_fuse_mkdir(const char *path, mode_t mode);
extern "C" int xtreemfs_fuse_unlink(const char *path);
extern "C" int xtreemfs_fuse_rmdir(const char *path);
extern "C" int xtreemfs_fuse_symlink(const char *path, const char *link);
extern "C" int xtreemfs_fuse_rename(const char *path, const char *newpath);
extern "C" int xtreemfs_fuse_link(const char *path, const char *newpath);
extern "C" int xtreemfs_fuse_chmod(const char *path, mode_t mode);
extern "C" int xtreemfs_fuse_chown(const char *path, uid_t uid, gid_t gid);
extern "C" int xtreemfs_fuse_truncate(const char *path, off_t new_file_size);
extern "C" int xtreemfs_fuse_utime(const char *path, struct utimbuf *ubuf);
extern "C" int xtreemfs_fuse_lock(const char *, struct fuse_file_info *,
int cmd, struct flock *);
extern "C" int xtreemfs_fuse_utimens(const char *path,
const struct timespec tv[2]);
extern "C" int xtreemfs_fuse_open(const char *path, struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_read(const char *path, char *buf, size_t size,
off_t offset, struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_write(
const char *path,
const char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_statfs(const char *path, struct statvfs *statv);
extern "C" int xtreemfs_fuse_flush(const char *path, struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_release(const char *path,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_fsync(const char *path, int datasync,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_setxattr(
const char *path,
const char *name,
const char *value,
size_t size,
int flags
#ifdef __APPLE__
, uint32_t position
#endif
);
extern "C" int xtreemfs_fuse_getxattr(const char *path, const char *name,
char *value, size_t size
#ifdef __APPLE__
, uint32_t position
#endif
);
extern "C" int xtreemfs_fuse_listxattr(const char *path, char *list,
size_t size);
extern "C" int xtreemfs_fuse_removexattr(const char *path, const char *name);
extern "C" int xtreemfs_fuse_opendir(const char *path,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_readdir(
const char *path,
void *buf,
fuse_fill_dir_t filler,
off_t offset,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_releasedir(const char *path,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_fsyncdir(const char *path, int datasync,
struct fuse_file_info *fi);
extern "C" void *xtreemfs_fuse_init(struct fuse_conn_info *conn);
extern "C" void xtreemfs_fuse_destroy(void *userdata);
extern "C" int xtreemfs_fuse_access(const char *path, int mask);
extern "C" int xtreemfs_fuse_create(const char *path, mode_t mode,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_ftruncate(const char *path, off_t new_file_size,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_fgetattr(const char *path, struct stat *statbuf,
struct fuse_file_info *fi);
extern "C" int xtreemfs_fuse_lock(const char* path, struct fuse_file_info *fi,
int cmd, struct flock* flock_);
#endif // CPP_INCLUDE_FUSE_FUSE_OPERATIONS_H_

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_FUSE_FUSE_OPTIONS_H_
#define CPP_INCLUDE_FUSE_FUSE_OPTIONS_H_
#include "libxtreemfs/options.h"
#include <boost/program_options.hpp>
#include <string>
#include <vector>
namespace xtreemfs {
class FuseOptions : public Options {
public:
/** Sets the default values. */
FuseOptions();
/** Set options parsed from command line which must contain at least the URL
* to a XtreemFS volume and a mount point.
*
* Calls Options::ParseCommandLine() to parse general options.
*
* @throws InvalidCommandLineParametersException
* @throws InvalidURLException */
void ParseCommandLine(int argc, char** argv);
/** Shows only the minimal help text describing the usage of mount.xtreemfs.*/
std::string ShowCommandLineUsage();
/** Outputs usage of the command line parameters. */
virtual std::string ShowCommandLineHelp();
// Fuse options.
/** Execute extended attributes operations? */
bool enable_xattrs;
/** If -o default_permissions is passed to Fuse, there are no extra permission
* checks needed. */
bool use_fuse_permission_checks;
/** If requested by the user, do not pass -o default_permissions to Fuse. */
bool fuse_permission_checks_explicitly_disabled;
/** Run the adapter program in foreground or send it to background? */
bool foreground;
/** Fuse options specified by -o. */
std::vector<std::string> fuse_options;
#ifdef __APPLE__
/** Assumed (or if specified the set) timeout of a blocked operation after
* which MacFuse will on a) Tiger show a dialog if the user will still wait
* for the operation or b) >=Leopard just kill our Fuse implementation and
* call fuse_destroy.
*/
int daemon_timeout;
#endif // __APPLE__
private:
/** Contains all available Fuse options and its descriptions. */
boost::program_options::options_description fuse_descriptions_;
/** Brief help text if there are no command line arguments. */
std::string helptext_usage_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_FUSE_FUSE_OPTIONS_H_

View File

@@ -0,0 +1,249 @@
/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).
/// It is intented to be used with #include <json/json-forwards.h>
/// This header provides forward declaration for all JsonCpp types.
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////
/*
The JsonCpp library's source code, including accompanying documentation,
tests and demonstration applications, are licensed under the following
conditions...
The author (Baptiste Lepilleur) explicitly disclaims copyright in all
jurisdictions which recognize such a disclaimer. In such jurisdictions,
this software is released into the Public Domain.
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
released under the terms of the MIT License (see below).
In jurisdictions which recognize Public Domain property, the user of this
software may choose to accept it either as 1) Public Domain, 2) under the
conditions of the MIT License (see below), or 3) under the terms of dual
Public Domain/MIT License conditions described here, as they choose.
The MIT License is about as close to Public Domain as a license can get, and is
described in clear, concise terms at:
http://en.wikipedia.org/wiki/MIT_License
The full text of the MIT License follows:
========================================================================
Copyright (c) 2007-2010 Baptiste Lepilleur
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
========================================================================
(END LICENSE TEXT)
The MIT license is compatible with both the GPL and commercial
software, affording one all of the rights of Public Domain with the
minor nuisance of being required to keep the above copyright notice
and license text in the source code. Note also that by accepting the
Public Domain "license" you can re-license your copy using whatever
license you like.
*/
// //////////////////////////////////////////////////////////////////////
// End of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////
#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED
# define JSON_FORWARD_AMALGATED_H_INCLUDED
/// If defined, indicates that the source file is amalgated
/// to prevent private header inclusion.
#define JSON_IS_AMALGATED
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_CONFIG_H_INCLUDED
# define JSON_CONFIG_H_INCLUDED
/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1
/// If defined, indicates that json may leverage CppTL library
//# define JSON_USE_CPPTL 1
/// If defined, indicates that cpptl vector based map should be used instead of std::map
/// as Value container.
//# define JSON_USE_CPPTL_SMALLMAP 1
/// If defined, indicates that Json specific container should be used
/// (hash table & simple deque container with customizable allocator).
/// THIS FEATURE IS STILL EXPERIMENTAL! There is know bugs: See #3177332
//# define JSON_VALUE_USE_INTERNAL_MAP 1
/// Force usage of standard new/malloc based allocator instead of memory pool based allocator.
/// The memory pools allocator used optimization (initializing Value and ValueInternalLink
/// as if it was a POD) that may cause some validation tool to report errors.
/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined.
//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1
/// If defined, indicates that Json use exception to report invalid type manipulation
/// instead of C assert macro.
# define JSON_USE_EXCEPTION 1
/// If defined, indicates that the source file is amalgated
/// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgated header.
// #define JSON_IS_AMALGAMATION
# ifdef JSON_IN_CPPTL
# include <cpptl/config.h>
# ifndef JSON_USE_CPPTL
# define JSON_USE_CPPTL 1
# endif
# endif
# ifdef JSON_IN_CPPTL
# define JSON_API CPPTL_API
# elif defined(JSON_DLL_BUILD)
# define JSON_API __declspec(dllexport)
# elif defined(JSON_DLL)
# define JSON_API __declspec(dllimport)
# else
# define JSON_API
# endif
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for integer
// Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1
#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6
// Microsoft Visual Studio 6 only support conversion from __int64 to double
// (no conversion from unsigned __int64).
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6
#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
/// Indicates that the following function is deprecated.
# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#endif
#if !defined(JSONCPP_DEPRECATED)
# define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)
namespace Json {
typedef int Int;
typedef unsigned int UInt;
# if defined(JSON_NO_INT64)
typedef int LargestInt;
typedef unsigned int LargestUInt;
# undef JSON_HAS_INT64
# else // if defined(JSON_NO_INT64)
// For Microsoft Visual use specific types as long long is not supported
# if defined(_MSC_VER) // Microsoft Visual Studio
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
# else // if defined(_MSC_VER) // Other platforms, use long long
typedef long long int Int64;
typedef unsigned long long int UInt64;
# endif // if defined(_MSC_VER)
typedef Int64 LargestInt;
typedef UInt64 LargestUInt;
# define JSON_HAS_INT64
# endif // if defined(JSON_NO_INT64)
} // end namespace Json
#endif // JSON_CONFIG_H_INCLUDED
// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_FORWARDS_H_INCLUDED
# define JSON_FORWARDS_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
//# include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
namespace Json {
// writer.h
class FastWriter;
class StyledWriter;
// reader.h
class Reader;
// features.h
class Features;
// value.h
typedef unsigned int ArrayIndex;
class StaticString;
class Path;
class PathArgument;
class Value;
class ValueIteratorBase;
class ValueIterator;
class ValueConstIterator;
#ifdef JSON_VALUE_USE_INTERNAL_MAP
class ValueMapAllocator;
class ValueInternalLink;
class ValueInternalArray;
class ValueInternalMap;
#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
} // namespace Json
#endif // JSON_FORWARDS_H_INCLUDED
// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////
#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED

1856
cpp/include/json/json.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2014 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef PRELOAD_ENVIRONMENT_H_
#define PRELOAD_ENVIRONMENT_H_
#include <string>
#include <stdint.h>
#include <sys/types.h>
#include "libxtreemfs/system_user_mapping_unix.h"
#include "libxtreemfs/volume_implementation.h"
#include "ld_preload/open_file_table.h"
#include "ld_preload/path.h"
#include "ld_preload/preload_options.h"
namespace xtreemfs {
class Client;
class VolumeHandle;
}
class Environment {
public:
Environment();
~Environment();
//xtreemfs::Volume* GetVolume(const std::string& volume_name);
xtreemfs::Volume* GetVolume();
xtreemfs::SystemUserMappingUnix& GetSystemUserMapping();
xtreemfs::PreloadOptions options_;
xtreemfs::Client* client_;
xtreemfs::Volume* volume_;
std::string volume_name_;
/** Translates between local and remote usernames and groups. */
xtreemfs::SystemUserMappingUnix system_user_mapping_;
xtreemfs::pbrpc::UserCredentials user_creds_;
OpenFileTable open_file_table_;
};
#endif // PRELOAD_ENVIRONMENT_H_

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2014 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef PRELOAD_MISC_H_
#define PRELOAD_MISC_H_
#include <string>
#include <stdint.h>
#include <sys/types.h>
#include "libxtreemfs/pbrpc_url.h"
#include "xtreemfs/GlobalTypes.pb.h"
#include "ld_preload/environment.h"
#include "ld_preload/passthrough.h"
xtreemfs::pbrpc::SYSTEM_V_FCNTL ConvertFlagsUnixToXtreemFS(int flags);
int TranslateMode(const char* mode);
int ConvertXtreemFSErrnoToUnix(xtreemfs::pbrpc::POSIXErrno xtreemfs_errno);
template<class T>
void ConvertXtreemFSStatToUnix(const xtreemfs::pbrpc::Stat& xtreemfs_stat, T* unix_stat, xtreemfs::SystemUserMappingUnix& system_user_mapping) {
unix_stat->st_dev = xtreemfs_stat.dev();
unix_stat->st_blksize = 8 * 128 * 1024;
unix_stat->st_ino = xtreemfs_stat.ino(); // = fileId
unix_stat->st_mode = xtreemfs_stat.mode();
unix_stat->st_nlink = xtreemfs_stat.nlink();
// Map user- and groupnames.
unix_stat->st_uid = system_user_mapping.UsernameToUID(xtreemfs_stat.user_id());
unix_stat->st_gid = system_user_mapping.GroupnameToGID(xtreemfs_stat.group_id());
unix_stat->st_size = xtreemfs_stat.size();
#ifdef __linux
unix_stat->st_atim.tv_sec = xtreemfs_stat.atime_ns() / 1000000000;
unix_stat->st_atim.tv_nsec = xtreemfs_stat.atime_ns() % 1000000000;
unix_stat->st_mtim.tv_sec = xtreemfs_stat.mtime_ns() / 1000000000;
unix_stat->st_mtim.tv_nsec = xtreemfs_stat.mtime_ns() % 1000000000;
unix_stat->st_ctim.tv_sec = xtreemfs_stat.ctime_ns() / 1000000000;
unix_stat->st_ctim.tv_nsec = xtreemfs_stat.ctime_ns() % 1000000000;
#elif __APPLE__
unix_stat->st_atimespec.tv_sec = xtreemfs_stat.atime_ns() / 1000000000;
unix_stat->st_atimespec.tv_nsec = xtreemfs_stat.atime_ns() % 1000000000;
unix_stat->st_mtimespec.tv_sec = xtreemfs_stat.mtime_ns() / 1000000000;
unix_stat->st_mtimespec.tv_nsec = xtreemfs_stat.mtime_ns() % 1000000000;
unix_stat->st_ctimespec.tv_sec = xtreemfs_stat.ctime_ns() / 1000000000;
unix_stat->st_ctimespec.tv_nsec = xtreemfs_stat.ctime_ns() % 1000000000;
#endif
unix_stat->st_rdev = 0;
unix_stat->st_blocks = xtreemfs_stat.size() / 512;
}
#endif // PRELOAD_MISC_H_

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2014 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef PRELOAD_OPEN_FILE_TABLE_H_
#define PRELOAD_OPEN_FILE_TABLE_H_
#include <map>
#include <pthread.h>
#include <cstdio>
#include <stdint.h>
#include <boost/thread/mutex.hpp>
#include "libxtreemfs/file_handle.h"
namespace xtreemfs {
class Client;
class VolumeHandle;
}
class OpenFile {
public:
OpenFile(xtreemfs::FileHandle* fh);
void Initialise();
void Deinitialise();
int GetFileDescriptor();
xtreemfs::FileHandle* fh_;
uint64_t offset_;
private:
FILE * tmp_file_;
int tmp_file_fd_;
};
class OpenFileTable {
public:
OpenFileTable();
~OpenFileTable();
int Register(xtreemfs::FileHandle* handle);
void Unregister(int fd);
OpenFile Get(int fd);
int Set(int fd, xtreemfs::FileHandle* handle);
void SetOffset(int fd, uint64_t offset);
bool Has(int fd);
private:
boost::mutex mutex_;
typedef std::map<int, OpenFile> FileTable;
FileTable open_files_;// GUARDED_BY(mutex_);
FILE * tmp_file_;
int tmp_file_fd_;
int next_fd_;
};
#endif // PRELOAD_OPEN_FILE_TABLE_H_

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2014 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef PRELOAD_PASSTHROUGH_H_
#define PRELOAD_PASSTHROUGH_H_
#include <stdio.h>
#include <unistd.h>
typedef int (*funcptr_open)(const char*, int, int);
typedef int (*funcptr_close)(int);
typedef ssize_t (*funcptr_read)(int, void*, size_t);
typedef ssize_t (*funcptr_write)(int, const void*, size_t);
typedef ssize_t (*funcptr_pread)(int, void*, size_t, off_t);
typedef ssize_t (*funcptr_pwrite)(int, const void*, size_t, off_t);
typedef int (*funcptr_dup)(int);
typedef int (*funcptr_dup2)(int, int);
typedef off_t (*funcptr_lseek)(int, off_t, int);
typedef int (*funcptr_stat)(const char*, struct stat*);
typedef int (*funcptr_fstat)(int, struct stat*);
typedef int (*funcptr___xstat)(int, const char*, struct stat*);
typedef int (*funcptr___xstat64)(int, const char*, struct stat64*);
typedef int (*funcptr___fxstat)(int, int, struct stat*);
typedef int (*funcptr___fxstat64)(int, int, struct stat64*);
typedef int (*funcptr___lxstat)(int, const char*, struct stat*);
typedef int (*funcptr___lxstat64)(int, const char*, struct stat64*);
typedef FILE* (*funcptr_fopen)(const char*, const char*);
typedef int (*funcptr_truncate)(const char*, off_t);
typedef int (*funcptr_ftruncate)(int, off_t);
typedef int (*funcptr_setxattr)(const char*, const char*, const void*, size_t, int);
typedef int (*funcptr_fsetxattr)(int, const char*, const void*, size_t, int);
extern void* libc_open;
extern void* libc_close;
extern void* libc___close;
extern void* libc_pread;
extern void* libc_read;
extern void* libc_write;
extern void* libc_dup;
extern void* libc_dup2;
extern void* libc_lseek;
extern void* libc_stat;
extern void* libc_fstat;
extern void* libc___xstat;
extern void* libc___xstat64;
extern void* libc___fxstat;
extern void* libc___fxstat64;
extern void* libc___lxstat;
extern void* libc___lxstat64;
extern void* libc_fopen;
extern void* libc_truncate;
extern void* libc_ftruncate;
extern void* libattr_setxattr;
extern void* libattr_fsetxattr;
void initialize_passthrough_if_necessary();
#ifdef XTREEMFS_PRELOAD_QUIET
#define xprintf(...)
#else
#define xprintf(...) fprintf(xtreemfs_stdout() ? xtreemfs_stdout() : stdout, __VA_ARGS__)
#endif
FILE* xtreemfs_stdout();
#endif // PRELOAD_PASSTHROUGH_H_

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2014 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef PRELOAD_PATH_H_
#define PRELOAD_PATH_H_
#include <string>
class Path {
public:
Path(const char* pathname);
bool IsXtreemFS();
void Parse();
const char* GetXtreemFSPath();
static void SetXtreemFSPrefix(const std::string& prefix);
private:
static std::string& GetXtreemFSPrefix();
const char* pathname_;
const char* xtreemfs_path_;
};
#endif // PRELOAD_PATH_H_

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2014 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef PRELOAD_PRELOAD_H_
#define PRELOAD_PRELOAD_H_
#include <stdint.h>
#include <sys/types.h>
#include "ld_preload/environment.h"
bool overlay_initialized(bool toggle = false);
Environment* get_env();
bool is_xtreemfs_fd(int fd);
bool is_xtreemfs_path(const char *path);
int xtreemfs_open(const char* pathname, int flags, int mode);
int xtreemfs_close(int fd);
uint64_t xtreemfs_pread(int fd, void* buf, uint64_t nbyte, uint64_t offset);
uint64_t xtreemfs_read(int fd, void* buf, uint64_t nbyte);
uint64_t xtreemfs_write(int fd, const void* buf, uint64_t nbyte);
int xtreemfs_dup2(int oldfd, int newfd);
int xtreemfs_dup(int fd);
off_t xtreemfs_lseek(int fd, off_t offset, int mode);
int xtreemfs_stat(const char *path, struct stat *buf);
int xtreemfs_stat64(const char *pathname, struct stat64 *buf);
int xtreemfs_fstat(int fd, struct stat *buf);
int xtreemfs_fstat64(int fd, struct stat64 *buf);
int xtreemfs_setxattr(const char *pathname, const char *name, const void *value, size_t size, int flags);
int xtreemfs_fsetxattr(int fd, const char *name, const void *value, size_t size, int flags);
#endif // PRELOAD_PRELOAD_H_

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2014 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LD_PRELOAD_PRELOAD_OPTIONS_H_
#define CPP_INCLUDE_LD_PRELOAD_PRELOAD_OPTIONS_H_
#include "libxtreemfs/options.h"
#include <boost/program_options.hpp>
#include <string>
#include <vector>
namespace xtreemfs {
class PreloadOptions : public Options {
public:
/** Sets the default values. */
PreloadOptions();
/** Set options parsed from command line which must contain at least the URL
* to an XtreemFS volume.
*
* Calls Options::ParseCommandLine() to parse general options.
*
* @throws InvalidCommandLineParametersException
* @throws InvalidURLException */
void ParseCommandLine(int argc, char** argv);
/** Outputs usage of the command line parameters. */
virtual std::string ShowCommandLineHelp();
// TODO: add preload-specific options here
private:
/** Contains all available preload options and its descriptions. */
boost::program_options::options_description preload_descriptions_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LD_PRELOAD_PRELOAD_OPTIONS_H_

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_

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_LSFS_XTREEMFS_LSFS_OPTIONS_H_
#define CPP_INCLUDE_LSFS_XTREEMFS_LSFS_OPTIONS_H_
#include "libxtreemfs/options.h"
#include <boost/program_options.hpp>
#include <string>
#include "pbrpc/RPC.pb.h"
#include "xtreemfs/MRC.pb.h"
namespace xtreemfs {
class LsfsOptions : public Options {
public:
/** Sets the default values. */
LsfsOptions();
/** Set options parsed from command line which must contain at least the URL
* to a XtreemFS volume.
*
* Calls Options::ParseCommandLine() to parse general options.
*
* @throws InvalidCommandLineParametersException
* @throws InvalidURLException */
void ParseCommandLine(int argc, char** argv);
/** Shows only the minimal help text describing the usage of lsfs.xtreemfs.*/
std::string ShowCommandLineUsage();
/** Outputs usage of the command line parameters. */
virtual std::string ShowCommandLineHelp();
/** MRC admin_password as set in the MRC config. */
std::string admin_password;
/** The service_adresses of Options became service_address, so we can no
* longer use this option for the MRC address and need a new member.
*/
std::string mrc_service_address;
private:
/** Contains all available lsfs options and its descriptions. */
boost::program_options::options_description lsfs_descriptions_;
/** Brief help text if there are no command line arguments. */
std::string helptext_usage_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_LSFS_XTREEMFS_LSFS_OPTIONS_H_

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_MKFS_XTREEMFS_MKFS_OPTIONS_H_
#define CPP_INCLUDE_MKFS_XTREEMFS_MKFS_OPTIONS_H_
#include "libxtreemfs/options.h"
#include <boost/program_options.hpp>
#include <list>
#include <string>
#include "pbrpc/RPC.pb.h"
#include "xtreemfs/MRC.pb.h"
namespace xtreemfs {
class MkfsOptions : public Options {
public:
/** Sets the default values. */
MkfsOptions();
/** Frees memory of KeyValuePair objects created for the volume attributes. */
~MkfsOptions();
/** Set options parsed from command line which must contain at least the URL
* to a XtreemFS volume.
*
* Calls Options::ParseCommandLine() to parse general options.
*
* @throws InvalidCommandLineParametersException
* @throws InvalidURLException */
void ParseCommandLine(int argc, char** argv);
/** Shows only the minimal help text describing the usage of mkfs.xtreemfs.*/
std::string ShowCommandLineUsage();
/** Outputs usage of the command line parameters. */
virtual std::string ShowCommandLineHelp();
/** Converts an octal value (e.g. 777) to a decimal value (e.g. ). */
int OctalToDecimal(int octal);
/** MRC admin_password as set in the MRC config. */
std::string admin_password;
/** The service_adresses of Options became service_address, so we can no
* longer use this option for the MRC address and need a new member.
*/
std::string mrc_service_address;
// Volume options.
/** Permissions mode of "/".
*
* @attention This value is stored in decimal representation. On the other
* hand, it is assumed that the user does specify the value in octal
* representation at the command line. Therefore,
* ParseCommandLine() does convert it from octal to decimal.
*/
int volume_mode_decimal;
/** Volume mode in octal form as specified at the command line. */
int volume_mode_octal;
/** Quota of the volume*/
std::string volume_quota;
/** Name of the owner of the new volume. */
std::string owner_username;
/** Owning group of the new volume. */
std::string owner_groupname;
/** Enforced access control policy: NULL|POSIX|VOLUME. */
xtreemfs::pbrpc::AccessControlPolicyType access_policy_type;
/** Will be parsed by ParseCommandLine() to set access_policy_type. */
std::string access_policy_type_string;
/** Default striping policy for new files: NONE|RAID0. */
xtreemfs::pbrpc::StripingPolicyType default_striping_policy_type;
/** Will be parsed by ParseCommandLine() to set
* default_striping_policy_type. */
std::string default_striping_policy_type_string;
/** Default stripe size for new files (in kB). */
int default_stripe_size;
/** Default stripe width for new files (number of OSDs per replica). */
int default_stripe_width;
/** List of user defined volume attributes. */
std::list<xtreemfs::pbrpc::KeyValuePair*> volume_attributes;
/** Will be parsed by ParseCommandLine() to set volume_attributes. */
std::vector<std::string> volume_attributes_strings;
/** If true, chown_non_root=true will be added to the list of attributes. */
bool chown_non_root;
private:
/** Contains all available mkfs options and its descriptions. */
boost::program_options::options_description mkfs_descriptions_;
/** Brief help text if there are no command line arguments. */
std::string helptext_usage_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_MKFS_XTREEMFS_MKFS_OPTIONS_H_

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RMFS_XTREEMFS_RMFS_OPTIONS_H_
#define CPP_INCLUDE_RMFS_XTREEMFS_RMFS_OPTIONS_H_
#include "libxtreemfs/options.h"
#include <boost/program_options.hpp>
#include <string>
#include "pbrpc/RPC.pb.h"
#include "xtreemfs/MRC.pb.h"
namespace xtreemfs {
class RmfsOptions : public Options {
public:
/** Sets the default values. */
RmfsOptions();
/** Set options parsed from command line which must contain at least the URL
* to a XtreemFS volume.
*
* Calls Options::ParseCommandLine() to parse general options.
*
* @throws InvalidCommandLineParametersException
* @throws InvalidURLException */
void ParseCommandLine(int argc, char** argv);
/** Shows only the minimal help text describing the usage of rmfs.xtreemfs.*/
std::string ShowCommandLineUsage();
/** Outputs usage of the command line parameters. */
virtual std::string ShowCommandLineHelp();
/** MRC admin_password as set in the MRC config. */
std::string admin_password;
/** The service_adresses of Options became service_address, so we can no
* longer use this option for the MRC address and need a new member.
*/
std::string mrc_service_address;
/** If true, no questions will be asked. */
bool force;
private:
/** Contains all available rmfs options and its descriptions. */
boost::program_options::options_description rmfs_descriptions_;
/** Brief help text if there are no command line arguments. */
std::string helptext_usage_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_RMFS_XTREEMFS_RMFS_OPTIONS_H_

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_ABSTRACT_SOCKET_CHANNEL_H_
#define CPP_INCLUDE_RPC_ABSTRACT_SOCKET_CHANNEL_H_
#include <boost/function.hpp>
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#include <vector>
namespace xtreemfs {
namespace rpc {
typedef boost::function2<void, const boost::system::error_code&,
std::size_t> ReadWriteHandler;
typedef boost::function1<void, const boost::system::error_code&>
ConnectHandler;
class AbstractSocketChannel {
public:
virtual ~AbstractSocketChannel() {}
virtual void async_connect(
const boost::asio::ip::tcp::endpoint& peer_endpoint,
ConnectHandler handler) = 0;
virtual void async_read(
const std::vector<boost::asio::mutable_buffer>& buffers,
ReadWriteHandler handler) = 0;
virtual void async_read(
const boost::asio::mutable_buffers_1& buffer,
ReadWriteHandler handler) = 0;
virtual void async_write(
const std::vector<boost::asio::const_buffer> & buffers,
ReadWriteHandler handler) = 0;
virtual void close() = 0;
};
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_ABSTRACT_SOCKET_CHANNEL_H_

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_CALLBACK_INTERFACE_H_
#define CPP_INCLUDE_RPC_CALLBACK_INTERFACE_H_
#include <stdint.h>
#include "pbrpc/RPC.pb.h"
#include "rpc/client_request.h"
#include "rpc/client_request_callback_interface.h"
namespace xtreemfs {
namespace rpc {
template <class ReturnMessageType>
class CallbackInterface : public ClientRequestCallbackInterface {
public:
virtual ~CallbackInterface();
/** To be implemented callback function which will be called by
* RequestCompleted() as the response was received.
*
* @param response_message Pointer to the response message.
* @param data Response data or NULL.
* @param data_length Length of response data.
* @param error Error message or NULL if no error occurred.
*
* @remark Ownership of response_message, data and error is transferred to
* the caller.
*/
virtual void CallFinished(ReturnMessageType* response_message,
char* data,
uint32_t data_length,
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error,
void* context) = 0;
/** Executes CallFinished(), internal use only. */
virtual void RequestCompleted(ClientRequest* request);
};
template <class ReturnMessageType>
CallbackInterface<ReturnMessageType>::~CallbackInterface() {}
template <class ReturnMessageType>
void CallbackInterface<ReturnMessageType>::RequestCompleted(
ClientRequest* request) {
assert(request->resp_message() != NULL || request->error() != NULL);
CallFinished(dynamic_cast<ReturnMessageType*>(request->resp_message()),
request->resp_data(),
request->resp_data_len(),
request->error(),
request->context());
delete request;
}
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_CALLBACK_INTERFACE_H_

160
cpp/include/rpc/client.h Normal file
View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
* 2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_CLIENT_H_
#define CPP_INCLUDE_RPC_CLIENT_H_
#include <stdint.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/system/error_code.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/version.hpp>
#include <gtest/gtest_prod.h>
#include <queue>
#include <string>
#include "rpc/client_connection.h"
#include "rpc/client_request.h"
#include "rpc/ssl_options.h"
#ifdef HAS_OPENSSL
#include <boost/asio/ssl.hpp>
#endif // HAS_OPENSSL
#if (BOOST_VERSION / 100000 > 1) || (BOOST_VERSION / 100 % 1000 > 35)
#include <boost/unordered_map.hpp>
#else
#include <map>
#endif
namespace xtreemfs {
namespace rpc {
// Boost introduced unordered_map in version 1.36 but we need to support
// older versions for Debian 5.
// TODO(bjko): Remove this typedef when support for Debian 5 is dropped.
#if (BOOST_VERSION / 100000 > 1) || (BOOST_VERSION / 100 % 1000 > 35)
typedef boost::unordered_map<std::string, ClientConnection*> connection_map;
#else
typedef std::map<std::string, ClientConnection*> connection_map;
#endif
class Client {
public:
Client(int32_t connect_timeout_s,
int32_t request_timeout_s,
int32_t max_con_linger,
const SSLOptions* options);
virtual ~Client();
void run();
void shutdown();
void sendRequest(const std::string& address,
int32_t interface_id,
int32_t proc_id,
const xtreemfs::pbrpc::UserCredentials& userCreds,
const xtreemfs::pbrpc::Auth& auth,
const google::protobuf::Message* message,
const char* data,
int data_length,
google::protobuf::Message* response_message,
void* context,
ClientRequestCallbackInterface *callback);
private:
/** Helper function which aborts a ClientRequest with "error".
*
* @remarks Ownership of "request" is not transferred.
*/
void AbortClientRequest(ClientRequest* request, const std::string& error);
void handleTimeout(const boost::system::error_code& error);
void sendInternalRequest();
void ShutdownHandler();
FILE* create_and_open_temporary_ssl_file(std::string* filename_template,
const char* mode);
#ifdef HAS_OPENSSL
boost::asio::ssl::context_base::method string_to_ssl_method(
std::string method_string,
boost::asio::ssl::context_base::method default_method);
#endif // HAS_OPENSSL
boost::asio::io_service service_;
connection_map connections_;
/** Contains all pending requests which are uniquely identified by their
* call id.
*
* Requests to this table are added when sending them and removed by the
* handleTimeout() function and the callback processing.
*
* @remark All accesses to this object have to be executed in the context of
* service_ and therefore do not require further synchronization.
*/
request_map request_table_;
/** Guards access to requests_ and stopped_. */
boost::mutex requests_mutex_;
/** Global queue where all requests queue up before the required
* ClientConnection is available.
*
* Once a ClientRequest was removed from this queue, it will be added to the
* requests_table_ and the queue ClientConnection::requests_.
*/
std::queue<ClientRequest*> requests_;
/** True when the RPC client was stopped and no new requests are accepted. */
bool stopped_;
/** True when the RPC client was stopped, only accessed in the context of
* io_service::run. */
bool stopped_ioservice_only_;
uint32_t callid_counter_;
boost::asio::deadline_timer rq_timeout_timer_;
int32_t rq_timeout_s_;
int32_t connect_timeout_s_;
int32_t max_con_linger_;
#ifdef HAS_OPENSSL
std::string get_pem_password_callback() const;
std::string get_pkcs12_password_callback() const;
// For previous Boost versions the callback is not a member function (see below).
#if (BOOST_VERSION > 104601)
bool verify_certificate_callback(bool preverfied,
boost::asio::ssl::verify_context& context) const;
#endif
bool use_gridssl_;
const SSLOptions* ssl_options;
char* pemFileName;
char* certFileName;
char* trustedCAsFileName;
boost::asio::ssl::context* ssl_context_;
#endif // HAS_OPENSSL
FRIEND_TEST(ClientTestFastLingerTimeout, LingerTests);
FRIEND_TEST(ClientTestFastLingerTimeoutConnectTimeout, LingerTests);
};
// For newer Boost versions the callback is a member function (see above).
#if (BOOST_VERSION < 104700)
int verify_certificate_callback(int preverify_ok, X509_STORE_CTX *ctx);
#endif // BOOST_VERSION < 104700
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_CLIENT_H_

View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
* 2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_CLIENT_CONNECTION_H_
#define CPP_INCLUDE_RPC_CLIENT_CONNECTION_H_
#include <stdint.h>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/system/error_code.hpp>
#include <boost/version.hpp>
#include <queue>
#include <string>
#include "pbrpc/RPC.pb.h"
#include "rpc/abstract_socket_channel.h"
#include "rpc/client_request.h"
#include "rpc/record_marker.h"
#include "rpc/ssl_options.h"
#if (BOOST_VERSION / 100000 > 1) || (BOOST_VERSION / 100 % 1000 > 35)
#include <boost/unordered_map.hpp>
#else
#include <map>
#endif
namespace xtreemfs {
namespace rpc {
// Boost introduced unordered_map in version 1.36 but we need to support
// older versions for Debian 5.
// TODO(bjko): Remove this typedef when support for Debian 5 is dropped.
#if (BOOST_VERSION / 100000 > 1) || (BOOST_VERSION / 100 % 1000 > 35)
typedef boost::unordered_map<int32_t, ClientRequest*> request_map;
#else
typedef std::map<int32_t, ClientRequest*> request_map;
#endif
/** Created by xtreemfs::rpc::Client for every connection.
*
* This class contains the per-connection data.
*
* @remarks Special care has to be taken regarding the boost::asio callback
* functions. In particular, every callback must not access members
* when the error_code equals asio::error::operation_aborted.
* Additionally, no further actions must be taken when
* connection_state_ is set to CLOSED.
*/
class ClientConnection {
public:
struct PendingRequest {
PendingRequest(uint32_t call_id, ClientRequest* rq)
: call_id(call_id), rq(rq) {}
uint32_t call_id;
ClientRequest* rq;
};
ClientConnection(const std::string& server_name,
const std::string& port,
boost::asio::io_service& service,
request_map *request_table,
int32_t connect_timeout_s,
int32_t max_reconnect_interval_s
#ifdef HAS_OPENSSL
,bool use_gridssl,
boost::asio::ssl::context* ssl_context
#endif // HAS_OPENSSL
);
virtual ~ClientConnection();
void DoProcess();
void AddRequest(ClientRequest *request);
void Close(const std::string& error);
void SendError(xtreemfs::pbrpc::POSIXErrno posix_errno,
const std::string& error_message);
void Reset();
boost::posix_time::ptime last_used() const {
return last_used_;
}
std::string GetServerAddress() const {
return server_name_ + ":" + server_port_;
}
private:
enum State {
CONNECTING,
IDLE,
ACTIVE,
CLOSED,
WAIT_FOR_RECONNECT
};
RecordMarker *receive_marker_;
char *receive_hdr_, *receive_msg_, *receive_data_;
char *receive_marker_buffer_;
State connection_state_;
/** Queue of requests which have not been sent out yet. */
std::queue<PendingRequest> requests_;
ClientRequest* current_request_;
const std::string server_name_;
const std::string server_port_;
boost::asio::io_service &service_;
boost::asio::ip::tcp::resolver resolver_;
AbstractSocketChannel* socket_;
boost::asio::ip::tcp::endpoint* endpoint_;
/** Points to the Client's request_table_. */
request_map* request_table_;
boost::asio::deadline_timer timer_;
const int32_t connect_timeout_s_;
const int32_t max_reconnect_interval_s_;
boost::posix_time::ptime next_reconnect_at_;
boost::posix_time::ptime last_connect_was_at_;
int32_t reconnect_interval_s_;
boost::posix_time::ptime last_used_;
#ifdef HAS_OPENSSL
bool use_gridssl_;
boost::asio::ssl::context* ssl_context_;
#endif // HAS_OPENSSL
/** Deletes "socket".
*
* @remark Ownership of "socket" is transferred.
*/
void static DelayedSocketDeletionHandler(AbstractSocketChannel* socket);
void Connect();
void SendRequest();
void ReceiveRequest();
void PostResolve(const boost::system::error_code& err,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
void PostConnect(const boost::system::error_code& err,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
void OnConnectTimeout(const boost::system::error_code& err);
void PostReadMessage(const boost::system::error_code& err);
void PostReadRecordMarker(const boost::system::error_code& err);
void PostWrite(const boost::system::error_code& err,
std::size_t bytes_written);
void DeleteInternalBuffers();
void CreateChannel();
};
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_CLIENT_CONNECTION_H_

View File

@@ -0,0 +1,211 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
* 2012 by Michael Berlin, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_CLIENT_REQUEST_H_
#define CPP_INCLUDE_RPC_CLIENT_REQUEST_H_
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <stdint.h>
#include <string>
#include "include/Common.pb.h"
#include "pbrpc/RPC.pb.h"
namespace xtreemfs {
namespace rpc {
class ClientConnection;
class ClientRequest;
class ClientRequestCallbackInterface;
class RecordMarker;
class ClientRequest {
public:
static const int ERR_NOERR = 0;
ClientRequest(const std::string& address,
const uint32_t call_id,
const uint32_t interface_id,
const uint32_t proc_id,
const xtreemfs::pbrpc::UserCredentials& userCreds,
const xtreemfs::pbrpc::Auth& auth,
const google::protobuf::Message* request_message,
const char* request_data,
const int data_length,
google::protobuf::Message* response_message,
void *context,
ClientRequestCallbackInterface* callback);
virtual ~ClientRequest();
void ExecuteCallback();
void RequestSent();
/** Used by Client::handleTimeout() to find the respective ClientConnection.
*
* @remarks This object does not have the ownership of "client_connection_",
* so it does not get transferred.
*/
ClientConnection* client_connection() {
return client_connection_;
}
/**
* @remarks Ownership is not transferred. Instead, it's assumed that this
* ClientRequests exists as long as "client_connection".
*/
void set_client_connection(ClientConnection* client_connection) {
client_connection_ = client_connection;
}
void set_rq_data(const char* rq_data) {
this->rq_data_ = rq_data;
}
const char* rq_data() const {
return rq_data_;
}
void set_rq_hdr_msg(char* rq_hdr_msg) {
this->rq_hdr_msg_ = rq_hdr_msg;
}
char* rq_hdr_msg() const {
return rq_hdr_msg_;
}
void set_request_marker(RecordMarker* request_marker) {
this->request_marker_ = request_marker;
}
RecordMarker* request_marker() const {
return request_marker_;
}
void set_resp_data(char* resp_data) {
this->resp_data_ = resp_data;
}
char* resp_data() const {
return resp_data_;
}
void clear_resp_data() {
delete[] resp_data_;
resp_data_ = NULL;
resp_data_len_ = 0;
}
void set_resp_header(xtreemfs::pbrpc::RPCHeader* resp_header) {
this->resp_header_ = resp_header;
}
xtreemfs::pbrpc::RPCHeader* resp_header() const {
return resp_header_;
}
void set_address(std::string address) {
this->address_ = address_;
}
std::string address() const {
return address_;
}
uint32_t call_id() const {
return call_id_;
}
uint32_t interface_id() const {
return interface_id_;
}
uint32_t proc_id() const {
return proc_id_;
}
boost::posix_time::ptime time_sent() const {
return time_sent_;
}
google::protobuf::Message* resp_message() const {
return resp_message_;
}
void clear_resp_message() {
delete resp_message_;
resp_message_ = NULL;
}
void set_error(xtreemfs::pbrpc::RPCHeader::ErrorResponse* error) {
if (!error_) {
// Process first error only.
this->error_ = error;
} else {
delete error;
}
}
void clear_error() {
delete error_;
error_ = NULL;
}
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error() const {
return error_;
}
void* context() const {
return context_;
}
void set_resp_data_len(uint32_t resp_data_len_) {
this->resp_data_len_ = resp_data_len_;
}
uint32_t resp_data_len() const {
return resp_data_len_;
}
private:
/** Pointer to the ClientConnection which is responsible for this object. */
ClientConnection* client_connection_;
/** ID of the request to match received responses to sent requests. */
const uint32_t call_id_;
/** Type of interface (service) which will be contacted. */
const uint32_t interface_id_;
/** Number of the operation which will be executed. */
const uint32_t proc_id_;
void *context_;
ClientRequestCallbackInterface *callback_;
std::string address_;
boost::posix_time::ptime time_sent_;
bool callback_executed_;
/** Internal buffers (will be deleted with the object). */
RecordMarker *request_marker_;
char *rq_hdr_msg_;
/** Buffers which are passed to the callback. */
xtreemfs::pbrpc::RPCHeader::ErrorResponse *error_;
const char *rq_data_;
xtreemfs::pbrpc::RPCHeader *resp_header_;
google::protobuf::Message *resp_message_;
char *resp_data_;
uint32_t resp_data_len_;
void deleteInternalBuffers();
};
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_CLIENT_REQUEST_H_

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_CLIENT_REQUEST_CALLBACK_INTERFACE_H_
#define CPP_INCLUDE_RPC_CLIENT_REQUEST_CALLBACK_INTERFACE_H_
namespace xtreemfs {
namespace rpc {
class ClientRequest;
class ClientRequestCallbackInterface {
public:
virtual ~ClientRequestCallbackInterface() {}
virtual void RequestCompleted(ClientRequest* request) = 0;
};
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_CLIENT_REQUEST_CALLBACK_INTERFACE_H_

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_GRID_SSL_SOCKET_CHANNEL_H_
#define CPP_INCLUDE_RPC_GRID_SSL_SOCKET_CHANNEL_H_
#ifdef HAS_OPENSSL
#include <boost/system/error_code.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <vector>
#include "pbrpc/RPC.pb.h"
#include "rpc/abstract_socket_channel.h"
namespace xtreemfs {
namespace rpc {
class GridSSLSocketChannel : public AbstractSocketChannel {
public:
GridSSLSocketChannel(boost::asio::io_service& service,
boost::asio::ssl::context& context)
: ssl_stream_(service, context) {
}
virtual ~GridSSLSocketChannel() {
}
virtual void async_connect(
const boost::asio::ip::tcp::endpoint& peer_endpoint,
ConnectHandler handler) {
connect_handler_ = handler;
ssl_stream_.lowest_layer().async_connect(
peer_endpoint,
boost::bind(&GridSSLSocketChannel::internal_do_handshake,
this,
boost::asio::placeholders::error));
}
void internal_do_handshake(const boost::system::error_code& error) {
if (error) {
connect_handler_(error);
} else {
ssl_stream_.async_handshake(
boost::asio::ssl::stream<boost::asio::ip::tcp::socket>::client,
connect_handler_);
}
}
virtual void async_read(
const std::vector<boost::asio::mutable_buffer>& buffers,
ReadWriteHandler handler) {
boost::asio::async_read(ssl_stream_.next_layer(), buffers, handler);
}
virtual void async_read(
const boost::asio::mutable_buffers_1& buffer,
ReadWriteHandler handler) {
boost::asio::async_read(ssl_stream_.next_layer(), buffer, handler);
}
virtual void async_write(
const std::vector<boost::asio::const_buffer> & buffers,
ReadWriteHandler handler) {
boost::asio::async_write(ssl_stream_.next_layer(), buffers, handler);
}
virtual void close() {
boost::system::error_code ignored_error;
ssl_stream_.lowest_layer().shutdown(
boost::asio::ip::tcp::socket::shutdown_both,
ignored_error);
ssl_stream_.lowest_layer().close(ignored_error);
ssl_stream_.shutdown(ignored_error);
}
const char *ssl_tls_version() {
#if (BOOST_VERSION < 104700)
return SSL_get_version(ssl_stream_.impl()->ssl);
#else // BOOST_VERSION < 104700
return SSL_get_version(ssl_stream_.native_handle());
#endif // BOOST_VERSION < 104700
}
private:
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_stream_;
ConnectHandler connect_handler_;
};
} // namespace rpc
} // namespace xtreemfs
#endif // HAS_OPENSSL
#endif // CPP_INCLUDE_RPC_GRID_SSL_SOCKET_CHANNEL_H_

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_RECORD_MARKER_H_
#define CPP_INCLUDE_RPC_RECORD_MARKER_H_
#include <cstddef>
#include <stdint.h>
namespace xtreemfs {
namespace rpc {
class RecordMarker {
public:
RecordMarker(uint32_t header_len,
uint32_t message_len,
uint32_t data_len);
explicit RecordMarker(const char* buffer);
void serialize(char* buffer) const;
uint32_t data_len() const;
uint32_t message_len() const;
uint32_t header_len() const;
static std::size_t get_size() {
return sizeof(uint32_t) * 3;
}
private:
uint32_t header_len_;
uint32_t message_len_;
uint32_t data_len_;
};
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_RECORD_MARKER_H_

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_SSL_OPTIONS_H_
#define CPP_INCLUDE_RPC_SSL_OPTIONS_H_
#ifdef HAS_OPENSSL
#include <boost/asio/ssl.hpp>
#endif // HAS_OPENSSL
#include <algorithm> // std::find
#include <string>
#include <vector>
namespace xtreemfs {
namespace rpc {
class SSLOptions {
#ifdef HAS_OPENSSL
public:
SSLOptions(const std::string ssl_pem_path,
const std::string ssl_pem_cert_path,
const std::string ssl_pem_key_pass,
const std::string ssl_pem_trusted_certs_path,
const std::string ssl_pkcs12_path,
const std::string ssl_pkcs12_pass,
const boost::asio::ssl::context::file_format format,
const bool use_grid_ssl,
const bool ssl_verify_certificates,
const std::vector<int> ssl_ignore_verify_errors,
const std::string ssl_method_string)
: pem_file_name_(ssl_pem_path),
pem_file_pass_(ssl_pem_key_pass),
pem_cert_name_(ssl_pem_cert_path),
pem_trusted_certs_file_name_(ssl_pem_trusted_certs_path),
pkcs12_file_name_(ssl_pkcs12_path),
pkcs12_file_pass_(ssl_pkcs12_pass),
cert_format_(format),
use_grid_ssl_(use_grid_ssl),
verify_certificates_(ssl_verify_certificates),
ignore_verify_errors_(ssl_ignore_verify_errors),
ssl_method_string_(ssl_method_string) {}
virtual ~SSLOptions() {
}
std::string pem_file_name() const {
return pem_file_name_;
}
std::string pem_cert_name() const {
return pem_cert_name_;
}
std::string pem_file_password() const {
return pem_file_pass_;
}
std::string pem_trusted_certs_file_name() const {
return pem_trusted_certs_file_name_;
}
std::string pkcs12_file_name() const {
return pkcs12_file_name_;
}
std::string pkcs12_file_password() const {
return pkcs12_file_pass_;
}
boost::asio::ssl::context::file_format cert_format() const {
return cert_format_;
}
bool use_grid_ssl() const {
return use_grid_ssl_;
}
bool verify_certificates() const {
return verify_certificates_;
}
bool ignore_verify_error(int verify_error) const {
return std::find(ignore_verify_errors_.begin(),
ignore_verify_errors_.end(),
verify_error) != ignore_verify_errors_.end();
}
std::string ssl_method_string() const {
return ssl_method_string_;
}
private:
std::string pem_file_name_;
std::string pem_file_pass_;
std::string pem_cert_name_;
std::string pem_trusted_certs_file_name_;
std::string pkcs12_file_name_;
std::string pkcs12_file_pass_;
boost::asio::ssl::context::file_format cert_format_;
bool use_grid_ssl_;
bool verify_certificates_;
std::vector<int> ignore_verify_errors_;
std::string ssl_method_string_;
#endif // HAS_OPENSSL
};
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_SSL_OPTIONS_H_

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_SSL_SOCKET_CHANNEL_H_
#define CPP_INCLUDE_RPC_SSL_SOCKET_CHANNEL_H_
#ifdef HAS_OPENSSL
#include <boost/system/error_code.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <vector>
#include "pbrpc/RPC.pb.h"
#include "rpc/abstract_socket_channel.h"
namespace xtreemfs {
namespace rpc {
class SSLSocketChannel : public AbstractSocketChannel {
public:
SSLSocketChannel(boost::asio::io_service& service,
boost::asio::ssl::context& context)
: ssl_stream_(service, context) {
}
virtual ~SSLSocketChannel() {
}
virtual void async_connect(
const boost::asio::ip::tcp::endpoint& peer_endpoint,
ConnectHandler handler) {
connect_handler_ = handler;
ssl_stream_.lowest_layer().async_connect(
peer_endpoint,
boost::bind(&SSLSocketChannel::internal_do_handshake,
this,
boost::asio::placeholders::error));
}
void internal_do_handshake(const boost::system::error_code& error) {
if (error) {
connect_handler_(error);
} else {
ssl_stream_.async_handshake(
boost::asio::ssl::stream<boost::asio::ip::tcp::socket>::client,
connect_handler_);
}
}
virtual void async_read(
const std::vector<boost::asio::mutable_buffer>& buffers,
ReadWriteHandler handler) {
boost::asio::async_read(ssl_stream_, buffers, handler);
}
virtual void async_read(
const boost::asio::mutable_buffers_1& buffer,
ReadWriteHandler handler) {
boost::asio::async_read(ssl_stream_, buffer, handler);
}
virtual void async_write(
const std::vector<boost::asio::const_buffer> & buffers,
ReadWriteHandler handler) {
boost::asio::async_write(ssl_stream_, buffers, handler);
}
virtual void close() {
boost::system::error_code ignored_error;
ssl_stream_.lowest_layer().shutdown(
boost::asio::ip::tcp::socket::shutdown_both,
ignored_error);
ssl_stream_.lowest_layer().close(ignored_error);
ssl_stream_.shutdown(ignored_error);
}
const char *ssl_tls_version() {
#if (BOOST_VERSION < 104700)
return SSL_get_version(ssl_stream_.impl()->ssl);
#else // BOOST_VERSION < 104700
return SSL_get_version(ssl_stream_.native_handle());
#endif // BOOST_VERSION < 104700
}
private:
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_stream_;
ConnectHandler connect_handler_;
};
} // namespace rpc
} // namespace xtreemfs
#endif // HAS_OPENSSL
#endif // CPP_INCLUDE_RPC_SSL_SOCKET_CHANNEL_H_

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_SYNC_CALLBACK_H_
#define CPP_INCLUDE_RPC_SYNC_CALLBACK_H_
#include <boost/thread.hpp>
#include <stdint.h>
#include "pbrpc/RPC.pb.h"
#include "rpc/client_request_callback_interface.h"
namespace xtreemfs {
namespace rpc {
class ClientRequest;
class SyncCallbackBase : public ClientRequestCallbackInterface {
public:
SyncCallbackBase();
virtual ~SyncCallbackBase();
/**
* Returns if the rpc has finished (response was received or error).
* This operation does not block.
* @return true, if the RPC has finished
*/
bool HasFinished();
/**
* Returns true if the request has failed. Blocks until
* response is available.
* @return true if an error occurred
*/
bool HasFailed();
/**
* Returns a pointer to the error or NULL if the request was successful.
* Blocks until response is available.
* @return pointer to ErrorResponse, caller is responsible for deleting
* the object or calling deleteBuffers
*/
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error();
/**
* Returns a pointer to the response message. Blocks until response is
* available.
* @return pointer to response message, caller is responsible for
* deleting the object or calling deleteBuffers
*/
::google::protobuf::Message* response();
/**
* Returns the length of the response data or 0.
* Blocks until response is available.
* @return ength of the response data or 0
*/
uint32_t data_length();
/**
* Returns a pointer to the response data. Blocks until response
* is available.
* @return pointer to response data, caller is responsible for
* deleting[] the data or calling deleteBuffers
*/
char* data();
/**
* Deletes the response objects (message, response, data)
* This is not done automatically when the SyncCallback is deleted!
*/
void DeleteBuffers();
/** internal callback, ignore */
virtual void RequestCompleted(ClientRequest* rq);
private:
boost::mutex cond_lock_;
boost::condition_variable response_avail_;
ClientRequest* request_;
void WaitForResponse();
};
// TODO(hupfeld): update pbrpcgen to emit dynamic types.
template <class ReturnMessageType>
class SyncCallback : public SyncCallbackBase {};
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_SYNC_CALLBACK_H_

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_RPC_TCP_SOCKET_CHANNEL_H_
#define CPP_INCLUDE_RPC_TCP_SOCKET_CHANNEL_H_
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#include <vector>
#include "pbrpc/RPC.pb.h"
#include "rpc/abstract_socket_channel.h"
namespace xtreemfs {
namespace rpc {
class TCPSocketChannel : public AbstractSocketChannel {
public:
explicit TCPSocketChannel(boost::asio::io_service& service) {
socket_ = new boost::asio::ip::tcp::socket(service);
}
virtual ~TCPSocketChannel() {
delete socket_;
}
virtual void async_connect(
const boost::asio::ip::tcp::endpoint& peer_endpoint,
ConnectHandler handler) {
socket_->async_connect(peer_endpoint, handler);
}
virtual void async_read(
const std::vector<boost::asio::mutable_buffer>& buffers,
ReadWriteHandler handler) {
boost::asio::async_read(*socket_, buffers, handler);
}
virtual void async_read(
const boost::asio::mutable_buffers_1& buffer,
ReadWriteHandler handler) {
boost::asio::async_read(*socket_, buffer, handler);
}
virtual void async_write(
const std::vector<boost::asio::const_buffer> & buffers,
ReadWriteHandler handler) {
boost::asio::async_write(*socket_, buffers, handler);
}
virtual void close() {
boost::system::error_code ignored_error;
socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both,
ignored_error);
socket_->close(ignored_error);
}
protected:
boost::asio::ip::tcp::socket *socket_;
};
} // namespace rpc
} // namespace xtreemfs
#endif // CPP_INCLUDE_RPC_TCP_SOCKET_CHANNEL_H_

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2013 by Felix Hupfeld.
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifdef __clang__
// TODO(fhupfeld): add annotations to synchronization primitives.
// Taken from http://www.mail-archive.com/linuxkernelnewbies@googlegroups.com/msg01455.html.
#define GUARDED_BY(x) __attribute__ ((guarded_by(x)))
#define GUARDED_VAR __attribute__ ((guarded))
#define PT_GUARDED_BY(x) __attribute__ ((point_to_guarded_by(x)))
#define PT_GUARDED_VAR __attribute__ ((point_to_guarded))
#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
#define LOCKABLE __attribute__ ((lockable))
#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock(__VA_ARGS__)))
#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock(__VA_ARGS__)))
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock(__VA_ARGS__)))
#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock(__VA_ARGS__)))
#define UNLOCK_FUNCTION(...) __attribute__ ((unlock(__VA_ARGS__)))
#define LOCK_RETURNED(x) __attribute__ ((lock_returned(x)))
#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
#define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
#define SHARED_LOCKS_REQUIRED(...) __attribute__ ((shared_locks_required(__VA_ARGS__)))
#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
#else
#define GUARDED_BY(x)
#define GUARDED_VAR
#define PT_GUARDED_BY(x)
#define PT_GUARDED_VAR
#define ACQUIRED_AFTER(...)
#define ACQUIRED_BEFORE(...)
#define LOCKABLE
#define SCOPED_LOCKABLE
#define EXCLUSIVE_LOCK_FUNCTION(...)
#define SHARED_LOCK_FUNCTION(...)
#define EXCLUSIVE_TRYLOCK_FUNCTION(...)
#define SHARED_TRYLOCK_FUNCTION(...)
#define UNLOCK_FUNCTION(...)
#define LOCK_RETURNED(x)
#define LOCKS_EXCLUDED(...)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define SHARED_LOCKS_REQUIRED(...)
#define NO_THREAD_SAFETY_ANALYSIS
#endif

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_UTIL_ERROR_LOG_H_
#define CPP_INCLUDE_UTIL_ERROR_LOG_H_
#include "boost/thread.hpp"
#include <list>
#include <string>
namespace xtreemfs {
namespace util {
/**
* A simple class that stores the last max_entries
* error messages. Thread safe.
*/
class ErrorLog {
public:
static ErrorLog* error_log;
ErrorLog(int max_entries) : max_entries_(max_entries) {}
~ErrorLog() {}
void AppendError(const std::string& message) {
boost::mutex::scoped_lock lock(error_messages_mutex_);
if (error_messages_.size() == max_entries_) {
error_messages_.pop_front();
}
error_messages_.push_back(message);
}
std::list<std::string> error_messages() {
boost::mutex::scoped_lock lock(error_messages_mutex_);
return error_messages_;
}
private:
int max_entries_;
boost::mutex error_messages_mutex_;
std::list<std::string> error_messages_;
};
void initialize_error_log(int max_entries);
void shutdown_error_log();
} // namespace util
} // namespace xtreemfs
#endif // CPP_INCLUDE_UTIL_ERROR_LOG_H_

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_UTIL_LOGGING_H_
#define CPP_INCLUDE_UTIL_LOGGING_H_
#include <ostream>
#include <string>
namespace xtreemfs {
namespace util {
enum LogLevel {
LEVEL_EMERG = 0,
LEVEL_ALERT = 1,
LEVEL_CRIT = 2,
LEVEL_ERROR = 3,
LEVEL_WARN = 4,
LEVEL_NOTICE = 5,
LEVEL_INFO = 6,
LEVEL_DEBUG = 7
};
class Logging {
public:
static Logging* log;
explicit Logging(LogLevel level = LEVEL_ERROR);
Logging(LogLevel level, std::ostream* stream);
virtual ~Logging();
std::ostream& getLog(LogLevel level) {
return getLog(level, "?", 0);
}
std::ostream& getLog(LogLevel level, const char* file, int line);
bool loggingActive(LogLevel level);
private:
/** Log stream. */
std::ostream& log_stream_;
/** Contains the pointer to the stream which has to be freed by the shutdown
* method. */
std::ostream* log_file_stream_;
LogLevel level_;
char levelToChar(LogLevel level);
};
LogLevel stringToLevel(std::string stringLevel, LogLevel defaultLevel);
void initialize_logger(LogLevel level);
void initialize_logger(LogLevel level, std::string logfilePath);
void initialize_logger(std::string stringLevel,
std::string logfilePath,
LogLevel defaultLevel);
void shutdown_logger();
} // namespace util
} // namespace xtreemfs
#endif // CPP_INCLUDE_UTIL_LOGGING_H_

View File

@@ -0,0 +1,61 @@
/**
* Copyright (c) 2012 by Matthias Noack, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
* This specific file is based on an example found in this article:
* http://www.quantnet.com/cplusplus-multithreading-boost/
*/
#ifndef CPP_INCLUDE_UTIL_SYNCHRONIZED_QUEUE_H_
#define CPP_INCLUDE_UTIL_SYNCHRONIZED_QUEUE_H_
#include <boost/thread/thread.hpp>
#include <queue>
namespace xtreemfs {
namespace util {
/** Queue class that has thread synchronization. Intended to synchronize
* threads in a producer consumer scenario.*/
template <typename T>
class SynchronizedQueue {
public:
/** Add data to the queue and notify others. Never blocks. */
void Enqueue(const T& data) {
boost::mutex::scoped_lock lock(mutex_);
queue_.push(data);
// Notify others that data is ready
queue_not_empty_cond_.notify_one();
}
/** Get data from the queue. Blocks if no data is available. */
T Dequeue() {
boost::mutex::scoped_lock lock(mutex_);
// When there is no data, wait till someone fills it.
// Lock is automatically released in the wait and obtained
// again after the wait
while (queue_.size() == 0) {
queue_not_empty_cond_.wait(lock);
}
T result = queue_.front();
queue_.pop();
return result;
}
private:
/** STL queue for data storage. */
std::queue<T> queue_;
/** The mutex to synchronize queue access. */
boost::mutex mutex_;
/** The condition to wait for if the queue is empty. */
boost::condition_variable queue_not_empty_cond_;
};
} // namespace util
} // namespace xtreemfs
#endif

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2009 Juan Gonzalez de Benito.
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_UTIL_ZIPF_GENERATOR_H_
#define CPP_INCLUDE_UTIL_ZIPF_GENERATOR_H_
namespace xtreemfs {
namespace util {
class ZipfGenerator {
public:
/**
* Creates a new ZipfGenerator with the given skewness
* skew: Desired skewness
*/
explicit ZipfGenerator(const double skew);
/**
* Returns a number from [0,this.size)
*/
int next();
/**
* Modifies the rank of the generated indexes
*/
void set_size(const int new_size);
private:
/**
* Returns the probability (0.0,1.0) to choose a given index
*/
double get_probability(const int rank);
int size;
double skew;
double bottom;
};
} // namespace util
} // namespace xtreemfs
#endif // CPP_INCLUDE_UTIL_ZIPF_GENERATOR_H_

View File

@@ -0,0 +1,244 @@
/*
* Copyright (c) 2011 by Bjoern Kolbeck, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifndef CPP_INCLUDE_XTFSUTIL_XTFSUTIL_SERVER_H_
#define CPP_INCLUDE_XTFSUTIL_XTFSUTIL_SERVER_H_
#include <sys/types.h>
#include <sys/stat.h>
#include <boost/thread/mutex.hpp>
#include <map>
#include <string>
#include "json/json-forwards.h"
#include "pbrpc/RPC.pb.h"
#ifdef WIN32
typedef unsigned int uid_t;
typedef unsigned int gid_t;
#endif // WIN32
namespace xtreemfs {
class Client;
class Volume;
/** Handle for a xcntl pseudo file used to communicate with
* the xtfsutil server inside the client.
*/
class XCtlFile {
public:
XCtlFile() : in_use_(false), last_result_(), uid_(0), gid_(0) {}
void set_last_result(std::string _last_result) {
this->last_result_ = _last_result;
}
std::string last_result() const {
return last_result_;
}
void set_in_use(bool _in_use) {
this->in_use_ = _in_use;
}
bool in_use() const {
return in_use_;
}
void set_user(uid_t uid, gid_t gid) {
uid_ = uid;
gid_ = gid;
}
bool is_owner(uid_t uid, gid_t gid) {
// Always allow root to read all files.
// Required for APPLE.
return (uid == 0 && gid == 0)
|| (uid == uid_ && gid == gid_);
}
uid_t get_uid() const {
return uid_;
}
gid_t get_gid() const {
return gid_;
}
private:
/** True, if an operation is currently being executed for this file. */
volatile bool in_use_;
/** Result of last operation executed, encoded in JSON. */
std::string last_result_;
/** User who owns this file. */
uid_t uid_;
gid_t gid_;
};
/** part of the xtfsutil that runs in the client (FUSE...)
* and handles all requests from the xtfsutil tool.
* xtfsutil uses special files to communicate with the client
* commands are executed using write and results are obtained via read.
* A write will block until the operation has finished.
*/
class XtfsUtilServer {
public:
/** @param prefix is the path prefix used to identify xctl pseudo files. */
XtfsUtilServer(const std::string& prefix);
~XtfsUtilServer();
/** Sets the volume to be used. */
void set_volume(Volume* volume);
/** Sets the Client to be used. */
void set_client(Client* uuid_resolver);
/** Returns true, if the path points to a xctl pseudo file. */
bool checkXctlFile(const std::string& path);
/** Reads the last response into buf.
* @returns 0 on success, -1*errno otherwise.
*/
int read(uid_t uid,
gid_t gid,
const std::string& path,
char *buf,
size_t size,
off_t offset);
/** Parses and executes the command from buf.
* @returns 0 on success, -1*errno otherwise.
*/
int write(uid_t uid,
gid_t gid,
const xtreemfs::pbrpc::UserCredentials& uc,
const std::string& path,
const char* buf,
size_t size);
/** Stats a xctl pseudo file. */
int getattr(uid_t uid,
gid_t gid,
const std::string& path,
struct stat* st_buf);
/** Delets a xctl pseudo file. */
int unlink(uid_t uid,
gid_t gid,
const std::string& path);
/** Creates a xctl pseudo file. */
int create(uid_t uid,
gid_t gid,
const std::string& path);
private:
/** Retrieves the file from the internal map. Creates it if it doesn't exist
* and create is true.
* @returns the file or NULL if the file does not exist or is owned by another
* user.
*/
XCtlFile* FindFile(uid_t uid,
gid_t gid,
const std::string& path,
bool create);
/** Parses the input JSON and executes the operation.
* Stores the result in file.
*/
void ParseAndExecute(const xtreemfs::pbrpc::UserCredentials& uc,
const std::string& input_str,
XCtlFile* file);
/** Returns a list of errors. */
void OpGetErrors(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
/** Returns XtreemFS-specific attributes. */
void OpStat(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
/** Changes the default striping policy. Volumes only. */
void OpSetDefaultSP(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
/** Changes the default replication policy. Volumes only. */
void OpSetDefaultRP(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
/** Changes the OSD selection policy (OSP). Volume only. */
void OpSetOSP(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
/** Changes the Replica selection policy (RSP). Volume only. */
void OpSetRSP(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpSetReplicationPolicy(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpAddReplica(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpRemoveReplica(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpGetSuitableOSDs(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpSetPolicyAttr(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpListPolicyAttr(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpEnableDisableSnapshots(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpListSnapshots(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpCreateDeleteSnapshot(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpSetRemoveACL(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
void OpSetVolumeQuota(const xtreemfs::pbrpc::UserCredentials& uc,
const Json::Value& input,
Json::Value* output);
/** Mutex to protect xctl_files_. */
boost::mutex xctl_files_mutex_;
/** Map of xctl pseudo files. */
std::map<std::string, XCtlFile*> xctl_files_;
/** Path prefix. */
std::string prefix_;
/** Volume on which to execute operations. */
Volume* volume_;
/** Client to resolve UUIDs to addresses. */
Client* client_;
/** XAttr prefix used for Policy Attribute names by the MRC. */
const std::string xtreemfs_policies_prefix_;
};
} // namespace xtreemfs
#endif // CPP_INCLUDE_XTFSUTIL_XTFSUTIL_SERVER_H_