diff --git a/src/aiori-DFS.c b/src/aiori-DFS.c index 6f0c07b..f22bbbd 100755 --- a/src/aiori-DFS.c +++ b/src/aiori-DFS.c @@ -6,6 +6,14 @@ * Copyright (c) 2003, The Regents of the University of California * * See the file COPYRIGHT for a complete copyright notice and license. * * * +* Copyright (C) 2018 Intel Corporation +* +* GOVERNMENT LICENSE RIGHTS-OPEN SOURCE SOFTWARE +* The Government's rights to use, modify, reproduce, release, perform, display, +* or disclose this software are subject to the terms of the Apache License as +* provided in Contract No. 8F-30005. +* Any reproduction of computer software, computer software documentation, or +* portions thereof marked with this legend must also reproduce the markings. ******************************************************************************** * * Implement of abstract I/O interface for DFS. @@ -70,10 +78,11 @@ parse_filename(const char *path, char **_obj_name, char **_cont_name) cont_name = dirname(f2); if (cont_name[0] == '.' || cont_name[0] != '/') { - char *cwd; + char cwd[1024]; + + if (getcwd(cwd, 1024) == NULL) + D_GOTO(out, rc = -ENOMEM); - //getcwd(cwd, 1024); - cwd = strdup("/"); if (strcmp(cont_name, ".") == 0) { cont_name = strdup(cwd); if (cont_name == NULL) @@ -130,6 +139,8 @@ static int DFS_Stat (const char *, struct stat *, IOR_param_t *); static int DFS_Mkdir (const char *, mode_t, IOR_param_t *); static int DFS_Rmdir (const char *, IOR_param_t *); static int DFS_Access (const char *, int, IOR_param_t *); +static int DFS_Init(IOR_param_t *param); +static int DFS_Finalize(IOR_param_t *param); /************************** D E C L A R A T I O N S ***************************/ @@ -148,85 +159,122 @@ ior_aiori_t dfs_aiori = { .rmdir = DFS_Rmdir, .access = DFS_Access, .stat = DFS_Stat, + .init = DFS_Init, + .finalize = DFS_Finalize, }; /***************************** F U N C T I O N S ******************************/ -int -dfs_init(void) { - char *pool_str, *svcl_str, *group_str; +static int +DFS_Init(IOR_param_t *param) { uuid_t pool_uuid, co_uuid; daos_pool_info_t pool_info; daos_cont_info_t co_info; d_rank_list_t *svcl = NULL; + bool cont_created = false; int rc; - + + if (uuid_parse(param->daosPool, pool_uuid) < 0) { + fprintf(stderr, "Invalid pool uuid\n"); + return -1; + } + + if (uuid_parse(param->daosCont, co_uuid) < 0) { + fprintf(stderr, "Invalid pool uuid\n"); + return -1; + } + + svcl = daos_rank_list_parse(param->daosPoolSvc, ":"); + if (svcl == NULL) { + fprintf(stderr, "Invalid pool service rank list\n"); + return -1; + } + + printf("Pool uuid = %s, SVCL = %s\n", param->daosPool, + param->daosPoolSvc); + + printf("DFS Container namespace uuid = %s\n", param->daosCont); + rc = daos_init(); if (rc) { fprintf(stderr, "daos_init() failed with %d\n", rc); return rc; } - pool_str = getenv("DAOS_POOL"); - if (!pool_str) { - fprintf(stderr, "missing pool uuid\n"); - return -1; - } - if (uuid_parse(pool_str, pool_uuid) < 0) { - fprintf(stderr, "Invalid pool uuid\n"); - return -1; - } - - svcl_str = getenv("DAOS_SVCL"); - if (!svcl_str) { - fprintf(stderr, "missing pool service rank list\n"); - return -1; - } - svcl = daos_rank_list_parse(svcl_str, ":"); - if (svcl == NULL) { - fprintf(stderr, "Invalid pool service rank list\n"); - return -1; - } - - group_str = getenv("DAOS_GROUP"); - /** Connect to DAOS pool */ - rc = daos_pool_connect(pool_uuid, group_str, svcl, DAOS_PC_RW, - &poh, &pool_info, NULL); + rc = daos_pool_connect(pool_uuid, + strlen(param->daosGroup) ? param->daosGroup : NULL, + svcl, DAOS_PC_RW, &poh, &pool_info, NULL); if (rc < 0) { - fprintf(stderr, "Failed to connect to pool %s %s (%d)\n", - pool_str, svcl_str, rc); - return -1; + fprintf(stderr, "Failed to connect to pool (%d)\n", rc); + goto err_daos; } - uuid_generate(co_uuid); - rc = daos_cont_create(poh, co_uuid, NULL); + rc = daos_cont_open(poh, co_uuid, DAOS_COO_RW, &coh, &co_info, NULL); + /* If NOEXIST we create it */ + if (rc == -DER_NONEXIST) { + printf("Creating DFS Container ...\n"); + rc = daos_cont_create(poh, co_uuid, NULL); + if (rc == 0) { + cont_created = true; + rc = daos_cont_open(poh, co_uuid, DAOS_COO_RW, &coh, + &co_info, NULL); + } + } if (rc) { fprintf(stderr, "Failed to create container (%d)\n", rc); - return -1; + goto err_pool; } - rc = daos_cont_open(poh, co_uuid, DAOS_COO_RW, &coh, &co_info, NULL); - if (rc) { - fprintf(stderr, "Failed to open container (%d)\n", rc); - return -1; - } - - rc = dfs_mount(poh, coh, &dfs); + rc = dfs_mount(poh, coh, O_RDWR, &dfs); if (rc) { fprintf(stderr, "dfs_mount failed (%d)\n", rc); - return -1; + goto err_cont; } +out: + daos_rank_list_free(svcl); return rc; +err_cont: + daos_cont_close(coh, NULL); +err_pool: + if (cont_created) + daos_cont_destroy(poh, co_uuid, 1, NULL); + daos_pool_disconnect(poh, NULL); +err_daos: + daos_fini(); + goto out; } -int dfs_finalize(void) +int +DFS_Finalize(IOR_param_t *param) { - dfs_umount(dfs); - daos_cont_close(coh, NULL); + int rc; + + rc = dfs_umount(dfs, true); + if (rc) { + fprintf(stderr, "dfs_umount() failed (%d)\n", rc); + return -1; + } + + rc = daos_cont_close(coh, NULL); + if (rc) { + fprintf(stderr, "daos_cont_close() failed (%d)\n", rc); + return -1; + } + daos_pool_disconnect(poh, NULL); - daos_fini(); + if (rc) { + fprintf(stderr, "daos_pool_disconnect() failed (%d)\n", rc); + return -1; + } + + rc = daos_fini(); + if (rc) { + fprintf(stderr, "daos_fini() failed (%d)\n", rc); + return -1; + } + return 0; } @@ -238,11 +286,14 @@ DFS_Create(char *testFileName, IOR_param_t *param) { char *name = NULL, *dir_name = NULL; dfs_obj_t *obj = NULL, *parent = NULL; - mode_t pmode; + mode_t pmode, mode; int fd_oflag = 0; int rc; + assert(param); + fd_oflag |= O_CREAT | O_RDWR; + mode = S_IFREG | param->mode; rc = parse_filename(testFileName, &name, &dir_name); if (rc) @@ -255,8 +306,8 @@ DFS_Create(char *testFileName, IOR_param_t *param) if (rc || !S_ISDIR(pmode)) goto out; - mode_t mode = S_IFREG | param->mode; - rc = dfs_open(dfs, parent, name, mode, fd_oflag, NULL, &obj); + rc = dfs_open(dfs, parent, name, mode, fd_oflag, DAOS_OC_LARGE_RW, + NULL, &obj); if (rc) goto out; @@ -274,7 +325,8 @@ out: /* * Open a file through the DFS interface. */ -static void *DFS_Open(char *testFileName, IOR_param_t *param) +static void * +DFS_Open(char *testFileName, IOR_param_t *param) { char *name = NULL, *dir_name = NULL; dfs_obj_t *obj = NULL, *parent = NULL; @@ -295,7 +347,7 @@ static void *DFS_Open(char *testFileName, IOR_param_t *param) if (rc || !S_ISDIR(pmode)) goto out; - rc = dfs_open(dfs, parent, name, S_IFREG, fd_oflag, NULL, &obj); + rc = dfs_open(dfs, parent, name, S_IFREG, fd_oflag, 0, NULL, &obj); if (rc) goto out; @@ -369,15 +421,18 @@ DFS_Xfer(int access, void *file, IOR_size_t *buffer, IOR_offset_t length, /* * Perform fsync(). */ -static void DFS_Fsync(void *fd, IOR_param_t * param) +static void +DFS_Fsync(void *fd, IOR_param_t * param) { + dfs_sync(dfs); return; } /* * Close a file through the DFS interface. */ -static void DFS_Close(void *fd, IOR_param_t * param) +static void +DFS_Close(void *fd, IOR_param_t * param) { dfs_release((dfs_obj_t *)fd); } @@ -385,7 +440,8 @@ static void DFS_Close(void *fd, IOR_param_t * param) /* * Delete a file through the DFS interface. */ -static void DFS_Delete(char *testFileName, IOR_param_t * param) +static void +DFS_Delete(char *testFileName, IOR_param_t * param) { char *name = NULL, *dir_name = NULL; dfs_obj_t *parent = NULL; @@ -419,7 +475,8 @@ out: /* * Determine api version. */ -static void DFS_SetVersion(IOR_param_t * test) +static void +DFS_SetVersion(IOR_param_t * test) { strcpy(test->apiVersion, test->api); } @@ -427,8 +484,8 @@ static void DFS_SetVersion(IOR_param_t * test) /* * Use DFS stat() to return aggregate file size. */ -static IOR_offset_t DFS_GetFileSize(IOR_param_t * test, MPI_Comm testComm, - char *testFileName) +static IOR_offset_t +DFS_GetFileSize(IOR_param_t * test, MPI_Comm testComm, char *testFileName) { dfs_obj_t *obj; daos_size_t fsize, tmpMin, tmpMax, tmpSum; @@ -475,7 +532,7 @@ DFS_Statfs(const char *path, ior_aiori_statfs_t *sfs, IOR_param_t * param) } static int -DFS_Mkdir (const char *path, mode_t mode, IOR_param_t * param) +DFS_Mkdir(const char *path, mode_t mode, IOR_param_t * param) { dfs_obj_t *parent = NULL; mode_t pmode; @@ -504,11 +561,13 @@ out: free(dir_name); if (parent) dfs_release(parent); + if (rc) + return -1; return rc; } static int -DFS_Rmdir (const char *path, IOR_param_t * param) +DFS_Rmdir(const char *path, IOR_param_t * param) { dfs_obj_t *parent = NULL; mode_t pmode; @@ -537,11 +596,13 @@ out: free(dir_name); if (parent) dfs_release(parent); + if (rc) + return -1; return rc; } static int -DFS_Access (const char *path, int mode, IOR_param_t * param) +DFS_Access(const char *path, int mode, IOR_param_t * param) { dfs_obj_t *parent = NULL; mode_t pmode; @@ -578,11 +639,13 @@ out: free(dir_name); if (parent) dfs_release(parent); + if (rc) + return -1; return rc; } static int -DFS_Stat (const char *path, struct stat *buf, IOR_param_t * param) +DFS_Stat(const char *path, struct stat *buf, IOR_param_t * param) { dfs_obj_t *parent = NULL; mode_t pmode; @@ -611,5 +674,7 @@ out: free(dir_name); if (parent) dfs_release(parent); + if (rc) + return -1; return rc; } diff --git a/src/aiori.h b/src/aiori.h index 9e5695e..b2c4818 100755 --- a/src/aiori.h +++ b/src/aiori.h @@ -77,6 +77,8 @@ typedef struct ior_aiori { int (*rmdir) (const char *path, IOR_param_t * param); int (*access) (const char *path, int mode, IOR_param_t * param); int (*stat) (const char *path, struct stat *buf, IOR_param_t * param); + int (*init)(IOR_param_t *); + int (*finalize)(IOR_param_t *); } ior_aiori_t; extern ior_aiori_t hdf5_aiori; @@ -94,9 +96,6 @@ const ior_aiori_t *aiori_select (const char *api); int aiori_count (void); const char *aiori_default (void); -int dfs_init(void); -int dfs_finalize(void); - IOR_offset_t MPIIO_GetFileSize(IOR_param_t * test, MPI_Comm testComm, char *testFileName); diff --git a/src/ior.c b/src/ior.c index e4dc03b..aa64436 100755 --- a/src/ior.c +++ b/src/ior.c @@ -2037,10 +2037,10 @@ static void TestIoSys(IOR_test_t *test) /* bind I/O calls to specific API */ AioriBind(params->api, params); -#ifdef USE_DFS_AIORI - if (strcmp(params->api, "DFS") == 0) - dfs_init(); -#endif + /* initialize API session */ + if (backend->init != NULL) + if (backend->init(params) != 0) + ERR("Could not init backend"); /* show test setup */ if (rank == 0 && verbose >= VERBOSE_0) @@ -2312,13 +2312,12 @@ static void TestIoSys(IOR_test_t *test) free(timer[i]); } + /* finalize API session */ + if (backend->finalize != NULL) + backend->finalize(params); + /* Sync with the tasks that did not participate in this test */ MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error"); - -#ifdef USE_DFS_AIORI - if (strcmp(params->api, "DFS") == 0) - dfs_finalize(); -#endif } /* diff --git a/src/ior.h b/src/ior.h index ce1b4ec..31b962a 100755 --- a/src/ior.h +++ b/src/ior.h @@ -213,6 +213,12 @@ typedef struct int beegfs_numTargets; /* number storage targets to use */ int beegfs_chunkSize; /* srtipe pattern for new files */ + /* daos variables */ + char daosGroup[MAX_STR]; /* group name */ + char daosPool[37]; /* pool UUID */ + char daosPoolSvc[MAX_STR]; /* pool service ranks */ + char daosCont[37]; /* Container UUID */ + int id; /* test's unique ID */ int intraTestBarriers; /* barriers between open/op and op/close */ } IOR_param_t; diff --git a/src/mdtest.c b/src/mdtest.c index 3245c47..b95211d 100644 --- a/src/mdtest.c +++ b/src/mdtest.c @@ -1801,6 +1801,59 @@ void create_remove_directory_tree(int create, } } +/* + * Set flags from commandline string/value pairs. + */ +static void +DecodeDirective(char *line, IOR_param_t *params) +{ + char option[MAX_STR]; + char value[MAX_STR]; + int rc; + + rc = sscanf(line, " %[^=# \t\r\n] = %[^# \t\r\n] ", option, value); + if (rc != 2 && rank == 0) { + fprintf(stdout, "Syntax error in configuration options: %s\n", + line); + MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); + } + + if (strcasecmp(option, "daospool") == 0) { + strcpy(params->daosPool, value); + } else if (strcasecmp(option, "daospoolsvc") == 0) { + strcpy(params->daosPoolSvc, value); + } else if (strcasecmp(option, "daosgroup") == 0) { + strcpy(params->daosGroup, value); + } else if (strcasecmp(option, "daoscont") == 0) { + strcpy(params->daosCont, value); + } + else { + if (rank == 0) + fprintf(stdout, "Unrecognized parameter \"%s\"\n", + option); + MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); + } +} + +/* + * Parse a single line, which may contain multiple comma-seperated directives + */ +static void +ParseLine(char *line, IOR_param_t * test) +{ + char *start, *end; + + start = line; + do { + end = strchr(start, ','); + if (end != NULL) + *end = '\0'; + DecodeDirective(start, test); + start = end + 1; + } while (end != NULL); + +} + int main(int argc, char **argv) { int i, j, k, c; int nodeCount; @@ -1853,7 +1906,7 @@ int main(int argc, char **argv) { /* Parse command line options */ while (1) { - c = getopt(argc, argv, "a:b:BcCd:De:Ef:Fhi:I:l:Ln:N:p:rR::s:StTuvV:w:yz:"); + c = getopt(argc, argv, "a:b:BcCd:De:Ef:Fhi:I:l:Ln:N:O:p:rR::s:StTuvV:w:yz:"); if (c == -1) { break; } @@ -1898,6 +1951,9 @@ int main(int argc, char **argv) { //items = atoi(optarg); break; case 'N': nstride = atoi(optarg); break; + case 'O': + ParseLine(optarg, ¶m); + break; case 'p': pre_delay = atoi(optarg); break; case 'r': @@ -1936,11 +1992,6 @@ int main(int argc, char **argv) { } } -#ifdef USE_DFS_AIORI - if (strcmp(backend_name, "DFS") == 0) - dfs_init(); -#endif - if (!create_only && !stat_only && !read_only && !remove_only) { create_only = stat_only = read_only = remove_only = 1; if (( rank == 0 ) && ( verbose >= 1 )) { @@ -2082,6 +2133,11 @@ int main(int argc, char **argv) { FAIL("Could not find suitable backend to use"); } + /* initialize API session */ + if (backend->init != NULL) + if (backend->init(¶m) != 0) + FAIL("Could not init backend"); + /* if directory does not exist, create it */ if ((rank < path_count) && backend->access(testdirpath, F_OK, ¶m) != 0) { if (backend->mkdir(testdirpath, DIRMODE, ¶m) != 0) { @@ -2090,16 +2146,20 @@ int main(int argc, char **argv) { } /* display disk usage */ - if (verbose >= 3 && rank == 0) { - printf( "V-3: main (before display_freespace): testdirpath is \"%s\"\n", testdirpath ); - fflush( stdout ); - } + if (strcmp(backend->name, "DFS")) { + if (verbose >= 3 && rank == 0) { + printf( "V-3: main (before display_freespace): testdirpath is \"%s\"\n", + testdirpath ); + fflush( stdout ); + } - if (rank == 0) display_freespace(testdirpath); + if (rank == 0) display_freespace(testdirpath); - if (verbose >= 3 && rank == 0) { - printf( "V-3: main (after display_freespace): testdirpath is \"%s\"\n", testdirpath ); - fflush( stdout ); + if (verbose >= 3 && rank == 0) { + printf( "V-3: main (after display_freespace): testdirpath is \"%s\"\n", + testdirpath ); + fflush( stdout ); + } } if (rank == 0) { @@ -2416,10 +2476,9 @@ int main(int argc, char **argv) { free(rand_array); } -#ifdef USE_DFS_AIORI - if (strcmp(backend_name, "DFS") == 0) - dfs_finalize(); -#endif + /* finalize API session */ + if (backend->finalize != NULL) + backend->finalize(¶m); MPI_Finalize(); exit(0); diff --git a/src/parse_options.c b/src/parse_options.c index cfa388a..1126559 100755 --- a/src/parse_options.c +++ b/src/parse_options.c @@ -327,7 +327,14 @@ void DecodeDirective(char *line, IOR_param_t *params) RecalculateExpectedFileSize(params); } else if (strcasecmp(option, "summaryalways") == 0) { params->summary_every_test = atoi(value); - } else { + } else if (strcasecmp(option, "daospool") == 0) { + strcpy(params->daosPool, value); + } else if (strcasecmp(option, "daospoolsvc") == 0) { + strcpy(params->daosPoolSvc, value); + } else if (strcasecmp(option, "daosgroup") == 0) { + strcpy(params->daosGroup, value); + } + else { if (rank == 0) fprintf(stdout, "Unrecognized parameter \"%s\"\n", option);