diff --git a/configure.ac b/configure.ac index e1b1932..a7d5085 100755 --- a/configure.ac +++ b/configure.ac @@ -308,19 +308,54 @@ AM_COND_IF([AWS4C_DIR],[ ]) -# Amazon S3 support [see also: --with-aws4c] -AC_ARG_WITH([S3], - [AS_HELP_STRING([--with-S3], - [support IO with Amazon S3 backend @<:@default=no@:>@])], + +# Amazon S3 support using the libs3 API +AC_ARG_WITH([S3-libs3], + [AS_HELP_STRING([--with-S3-libs3], + [support IO with Amazon libS3 @<:@default=no@:>@])], [], - [with_S3=no]) -AM_CONDITIONAL([USE_S3_AIORI], [test x$with_S3 = xyes]) -AM_COND_IF([USE_S3_AIORI],[ - AC_DEFINE([USE_S3_AIORI], [], [Build Amazon-S3 backend AIORI]) + [with_S3_libs3=no]) +AM_CONDITIONAL([USE_S3_LIBS3_AIORI], [test x$with_S3_libs3 = xyes]) +AM_COND_IF([USE_S3_LIBS3_AIORI],[ + AC_DEFINE([USE_S3_LIBS3_AIORI], [], [Build Amazon-S3 backend AIORI using libs3]) ]) err=0 -AS_IF([test "x$with_S3" != xno], [ +AS_IF([test "x$with_S3_libs3" != xno], [ + AC_MSG_NOTICE([beginning of S3-related checks]) + ORIG_CPPFLAGS=$CPPFLAGS + ORIG_LDFLAGS=$LDFLAGS + + AC_CHECK_HEADERS([libs3.h], [], [err=1]) + + # Autotools thinks searching for a library means I want it added to LIBS + ORIG_LIBS=$LIBS + AC_CHECK_LIB([s3], [S3_initialize], [], [err=1]) + LIBS=$ORIG_LIBS + + AC_MSG_NOTICE([end of S3-related checks]) + if test "$err" == 1; then + AC_MSG_FAILURE([S3 support is missing. dnl Make sure you have access to libs3. dnl]) + fi + + # restore user's values + CPPFLAGS=$ORIG_CPPFLAGS + LDFLAGS=$ORIG_LDFLAGS +]) + +# Amazon S3 support [see also: --with-aws4c] +AC_ARG_WITH([S3-4c], + [AS_HELP_STRING([--with-S3-4c], + [support IO with Amazon S3 backend @<:@default=no@:>@])], + [], + [with_S3_4c=no]) +AM_CONDITIONAL([USE_S3_4C_AIORI], [test x$with_S3_4c = xyes]) +AM_COND_IF([USE_S3_4C_AIORI],[ + AC_DEFINE([USE_S3_4C_AIORI], [], [Build Amazon-S3 backend AIORI using lib4c]) +]) + +err=0 +AS_IF([test "x$with_S3_4c" != xno], [ AC_MSG_NOTICE([beginning of S3-related checks]) # save user's values, while we use AC_CHECK_HEADERS with $AWS4C_DIR diff --git a/src/Makefile.am b/src/Makefile.am index 7cbd448..c718169 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,8 +90,8 @@ extraSOURCES += aiori-Gfarm.c extraLDADD += -lgfarm endif -if USE_S3_AIORI -extraSOURCES += aiori-S3.c +if USE_S3_4C_AIORI +extraSOURCES += aiori-S3-4c.c if AWS4C_DIR extraCPPFLAGS += $(AWS4C_CPPFLAGS) extraLDFLAGS += $(AWS4C_LDFLAGS) @@ -102,6 +102,11 @@ extraLDADD += -laws4c extraLDADD += -laws4c_extra endif +if USE_S3_LIBS3_AIORI +extraSOURCES += aiori-S3-libs3.c +extraLDADD += -ls3 +endif + if WITH_LUSTRE extraLDADD += -llustreapi endif diff --git a/src/aiori-S3.c b/src/aiori-S3-4c.c similarity index 99% rename from src/aiori-S3.c rename to src/aiori-S3-4c.c index 3999739..a1465b7 100755 --- a/src/aiori-S3.c +++ b/src/aiori-S3-4c.c @@ -130,7 +130,7 @@ const char* bucket_name = "ior"; # define IOR_CURL_NOCONTINUE 0x02 # define IOR_CURL_S3_EMC_EXT 0x04 /* allow EMC extensions to S3? */ -#ifdef USE_S3_AIORI +#ifdef USE_S3_4C_AIORI # include # include "aws4c.h" #else @@ -167,8 +167,8 @@ static int S3_check_params(IOR_param_t *); // "Pure S3" // N:1 writes use multi-part upload // N:N fails if "transfer-size" != "block-size" (because that requires "append") -ior_aiori_t s3_aiori = { - .name = "S3", +ior_aiori_t s3_4c_aiori = { + .name = "S3-4c", .name_legacy = NULL, .create = S3_Create, .open = S3_Open, diff --git a/src/aiori-S3-libs3.c b/src/aiori-S3-libs3.c new file mode 100644 index 0000000..5c9129f --- /dev/null +++ b/src/aiori-S3-libs3.c @@ -0,0 +1,199 @@ +/* +* S3 implementation using the newer libs3 +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "ior.h" +#include "aiori.h" +#include "utilities.h" + + +/************************** O P T I O N S *****************************/ +typedef struct { + uint64_t delay_creates; + uint64_t delay_xfer; + int delay_rank_0_only; +} dummy_options_t; + +static char * current = (char*) 1; + +static option_help * S3_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values){ + dummy_options_t * o = malloc(sizeof(dummy_options_t)); + if (init_values != NULL){ + memcpy(o, init_values, sizeof(dummy_options_t)); + }else{ + memset(o, 0, sizeof(dummy_options_t)); + } + + *init_backend_options = (aiori_mod_opt_t*) o; + + option_help h [] = { + {0, "dummy.delay-create", "Delay per create in usec", OPTION_OPTIONAL_ARGUMENT, 'l', & o->delay_creates}, + {0, "dummy.delay-xfer", "Delay per xfer in usec", OPTION_OPTIONAL_ARGUMENT, 'l', & o->delay_xfer}, + {0, "dummy.delay-only-rank0", "Delay only Rank0", OPTION_FLAG, 'd', & o->delay_rank_0_only}, + LAST_OPTION + }; + option_help * help = malloc(sizeof(h)); + memcpy(help, h, sizeof(h)); + return help; +} + +static int count_init = 0; + +static aiori_fd_t *S3_Create(char *testFileName, int iorflags, aiori_mod_opt_t * options) +{ + if(count_init <= 0){ + ERR("S3 missing initialization in create\n"); + } + if(verbose > 4){ + fprintf(out_logfile, "S3 create: %s = %p\n", testFileName, current); + } + dummy_options_t * o = (dummy_options_t*) options; + if (o->delay_creates){ + if (! o->delay_rank_0_only || (o->delay_rank_0_only && rank == 0)){ + struct timespec wait = { o->delay_creates / 1000 / 1000, 1000l * (o->delay_creates % 1000000)}; + nanosleep( & wait, NULL); + } + } + return (aiori_fd_t*) current++; +} + +static aiori_fd_t *S3_Open(char *testFileName, int flags, aiori_mod_opt_t * options) +{ + if(count_init <= 0){ + ERR("S3 missing initialization in open\n"); + } + if(verbose > 4){ + fprintf(out_logfile, "S3 open: %s = %p\n", testFileName, current); + } + return (aiori_fd_t*) current++; +} + +static void S3_Fsync(aiori_fd_t *fd, aiori_mod_opt_t * options) +{ + if(verbose > 4){ + fprintf(out_logfile, "S3 fsync %p\n", fd); + } +} + + +static void S3_Sync(aiori_mod_opt_t * options) +{ +} + +static void S3_Close(aiori_fd_t *fd, aiori_mod_opt_t * options) +{ + if(verbose > 4){ + fprintf(out_logfile, "S3 close %p\n", fd); + } +} + +static void S3_Delete(char *testFileName, aiori_mod_opt_t * options) +{ + if(verbose > 4){ + fprintf(out_logfile, "S3 delete: %s\n", testFileName); + } +} + +static char * S3_getVersion() +{ + return "0.5"; +} + +static IOR_offset_t S3_GetFileSize(aiori_mod_opt_t * options, char *testFileName) +{ + if(verbose > 4){ + fprintf(out_logfile, "S3 getFileSize: %s\n", testFileName); + } + return 0; +} + +static IOR_offset_t S3_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer, IOR_offset_t length, IOR_offset_t offset, aiori_mod_opt_t * options){ + if(verbose > 4){ + fprintf(out_logfile, "S3 xfer: %p\n", file); + } + dummy_options_t * o = (dummy_options_t*) options; + if (o->delay_xfer){ + if (! o->delay_rank_0_only || (o->delay_rank_0_only && rank == 0)){ + struct timespec wait = {o->delay_xfer / 1000 / 1000, 1000l * (o->delay_xfer % 1000000)}; + nanosleep( & wait, NULL); + } + } + return length; +} + +static int S3_statfs (const char * path, ior_aiori_statfs_t * stat, aiori_mod_opt_t * options){ + stat->f_bsize = 1; + stat->f_blocks = 1; + stat->f_bfree = 1; + stat->f_bavail = 1; + stat->f_files = 1; + stat->f_ffree = 1; + return 0; +} + +static int S3_mkdir (const char *path, mode_t mode, aiori_mod_opt_t * options){ + return 0; +} + +static int S3_rmdir (const char *path, aiori_mod_opt_t * options){ + return 0; +} + +static int S3_access (const char *path, int mode, aiori_mod_opt_t * options){ + return 0; +} + +static int S3_stat (const char *path, struct stat *buf, aiori_mod_opt_t * options){ + return 0; +} + +static int S3_check_params(aiori_mod_opt_t * options){ + return 0; +} + +static void S3_init(aiori_mod_opt_t * options){ + WARN("S3 initialized"); + count_init++; +} + +static void S3_final(aiori_mod_opt_t * options){ + WARN("S3 finalized"); + if(count_init <= 0){ + ERR("S3 invalid finalization\n"); + } + count_init--; +} + + +ior_aiori_t S3_libS3_aiori = { + .name = "S3-libs3", + .name_legacy = NULL, + .create = S3_Create, + .open = S3_Open, + .xfer = S3_Xfer, + .close = S3_Close, + .delete = S3_Delete, + .get_version = S3_getVersion, + .fsync = S3_Fsync, + .get_file_size = S3_GetFileSize, + .statfs = S3_statfs, + .mkdir = S3_mkdir, + .rmdir = S3_rmdir, + .access = S3_access, + .stat = S3_stat, + .initialize = S3_init, + .finalize = S3_final, + .get_options = S3_options, + .check_params = S3_check_params, + .sync = S3_Sync, + .enable_mdtest = true +}; diff --git a/src/aiori.c b/src/aiori.c index 303f367..7b0c160 100644 --- a/src/aiori.c +++ b/src/aiori.c @@ -68,8 +68,11 @@ ior_aiori_t *available_aiori[] = { #ifdef USE_MMAP_AIORI &mmap_aiori, #endif -#ifdef USE_S3_AIORI - &s3_aiori, +#ifdef USE_S3_LIBS3_AIORI + &S3_libS3_aiori, +#endif +#ifdef USE_S3_4C_AIORI + &s3_4c_aiori, &s3_plus_aiori, &s3_emc_aiori, #endif diff --git a/src/aiori.h b/src/aiori.h index f7205e0..6b185d7 100755 --- a/src/aiori.h +++ b/src/aiori.h @@ -130,7 +130,8 @@ extern ior_aiori_t ncmpi_aiori; extern ior_aiori_t posix_aiori; extern ior_aiori_t pmdk_aiori; extern ior_aiori_t mmap_aiori; -extern ior_aiori_t s3_aiori; +extern ior_aiori_t S3_libS3_aiori; +extern ior_aiori_t s3_4c_aiori; extern ior_aiori_t s3_plus_aiori; extern ior_aiori_t s3_emc_aiori; extern ior_aiori_t rados_aiori;