24 #include <sys/types.h> 31 #include <gurt/common.h> 32 #include <gurt/hash.h> 40 #if defined(DAOS_API_VERSION_MAJOR) && defined(DAOS_API_VERSION_MINOR) 41 #define CHECK_DAOS_API_VERSION(major, minor) \ 42 ((DAOS_API_VERSION_MAJOR > (major)) \ 43 || (DAOS_API_VERSION_MAJOR == (major) && DAOS_API_VERSION_MINOR >= (minor))) 45 #define CHECK_DAOS_API_VERSION(major, minor) 0 83 if (init_values !=
NULL) {
100 {0,
"dfs.destroy",
"Destroy DFS container on finalize",
OPTION_FLAG,
'd', &o->
destroy},
105 memcpy(help, h,
sizeof(h));
156 .enable_mdtest =
true,
162 #define DCHECK(rc, format, ...) \ 167 fprintf(stderr, "ERROR (%s:%d): %d: %d: " \ 168 format"\n", __FILE__, __LINE__, rank, _rc, \ 175 #define INFO(level, format, ...) \ 177 if (verbose >= level) \ 178 printf("[%d] "format"\n", rank, ##__VA_ARGS__); \ 181 #define DERR(format, ...) \ 183 fprintf(stderr, format"\n", ##__VA_ARGS__); \ 200 ERR(
"Invalid pool or container options\n");
215 key_cmp(
struct d_hash_table *htable, d_list_t *rlink,
216 const void *key,
unsigned int ksize)
220 return (strcmp(hdl->
name, (
const char *)key) == 0);
224 rec_free(
struct d_hash_table *htable, d_list_t *rlink)
228 dfs_release(hdl->
oh);
239 rec_hash(
struct d_hash_table *htable, d_list_t *rlink)
243 return d_hash_string_u32(hdl->
name, strlen(hdl->
name));
260 global.iov_buf =
NULL;
261 global.iov_buf_len = 0;
268 rc = daos_pool_local2global(
poh, &global);
270 rc = daos_cont_local2global(
coh, &global);
272 rc = dfs_local2global(
dfs, &global);
273 DCHECK(rc,
"Failed to get global handle size");
277 "Failed to bcast global handle buffer size");
279 global.iov_len = global.iov_buf_len;
280 global.iov_buf = malloc(global.iov_buf_len);
281 if (global.iov_buf ==
NULL)
282 ERR(
"Failed to allocate global handle buffer");
286 rc = daos_pool_local2global(
poh, &global);
288 rc = daos_cont_local2global(
coh, &global);
290 rc = dfs_local2global(
dfs, &global);
291 DCHECK(rc,
"Failed to create global handle");
295 "Failed to bcast global pool handle");
299 rc = daos_pool_global2local(global, &
poh);
301 rc = daos_cont_global2local(
poh, global, &
coh);
303 rc = dfs_global2local(
poh,
coh, 0, global, &
dfs);
304 DCHECK(rc,
"Failed to get local handle");
309 free(global.iov_buf);
319 char *cont_name =
NULL;
322 if (path ==
NULL || _obj_name ==
NULL || _cont_name ==
NULL)
337 fname = basename(f1);
338 cont_name = dirname(f2);
340 if (cont_name[0] !=
'/') {
344 ptr = realpath(cont_name, buf);
350 cont_name = strdup(ptr);
351 if (cont_name ==
NULL) {
355 *_cont_name = cont_name;
357 *_cont_name = strdup(cont_name);
358 if (*_cont_name ==
NULL) {
364 *_obj_name = strdup(fname);
365 if (*_obj_name ==
NULL) {
384 global.iov_buf =
NULL;
385 global.iov_buf_len = 0;
389 rc = dfs_obj_local2global(
dfs, *file, &global);
390 DCHECK(rc,
"Failed to get global handle size");
394 "Failed to bcast global handle buffer size");
396 global.iov_len = global.iov_buf_len;
397 global.iov_buf = malloc(global.iov_buf_len);
398 if (global.iov_buf ==
NULL)
399 ERR(
"Failed to allocate global handle buffer");
402 rc = dfs_obj_local2global(
dfs, *file, &global);
403 DCHECK(rc,
"Failed to create global handle");
407 "Failed to bcast global pool handle");
410 rc = dfs_obj_global2local(
dfs, 0, global, file);
411 DCHECK(rc,
"Failed to get local handle");
416 free(global.iov_buf);
426 size_t len = strlen(name);
435 rc = dfs_lookup(
dfs, name, O_RDWR, &oh, mode,
NULL);
439 if (mode && !S_ISDIR(*mode))
446 strncpy(hdl->
name, name, len);
451 fprintf(stderr,
"Failed to insert dir handle in hashtable\n");
452 dfs_release(hdl->
oh);
464 bool pool_connect, cont_create, cont_open, dfs_mounted;
470 pool_connect = cont_create = cont_open = dfs_mounted =
true;
475 DERR(
"Invalid DAOS object class: %s\n", o->
oclass);
491 pool_connect = cont_create = cont_open = dfs_mounted =
false;
494 DCHECK(rc,
"Failed to initialize daos");
499 DERR(
"Invalid DAOS object class: %s\n", o->
oclass);
508 rc = d_hash_table_create(D_HASH_FT_EPHEMERAL | D_HASH_FT_NOLOCK | D_HASH_FT_LRU,
510 DCHECK(rc,
"Failed to initialize dir hashtable");
513 daos_pool_info_t pool_info;
514 daos_cont_info_t co_info;
519 #if CHECK_DAOS_API_VERSION(1, 4) 520 rc = daos_pool_connect(o->
pool, o->
group, DAOS_PC_RW, &
poh, &pool_info,
NULL);
521 DCHECK(rc,
"Failed to connect to pool %s", o->
pool);
524 rc = daos_cont_open(
poh, o->
cont, DAOS_COO_RW, &
coh, &co_info,
NULL);
528 rc = uuid_parse(o->
pool, pool_uuid);
529 DCHECK(rc,
"Failed to parse 'Pool uuid': %s", o->
pool);
530 rc = uuid_parse(o->
cont, co_uuid);
531 DCHECK(rc,
"Failed to parse 'Cont uuid': %s", o->
cont);
533 rc = daos_pool_connect(pool_uuid, o->
group, DAOS_PC_RW, &
poh, &pool_info,
NULL);
534 DCHECK(rc,
"Failed to connect to pool %s", o->
pool);
537 rc = daos_cont_open(
poh, co_uuid, DAOS_COO_RW, &
coh, &co_info,
NULL);
540 if (rc == -DER_NONEXIST) {
542 #if CHECK_DAOS_API_VERSION(1, 4) 543 if (uuid_parse(o->
cont, co_uuid) != 0)
551 DCHECK(rc,
"Failed to create container");
554 DCHECK(rc,
"Failed to create container");
559 DCHECK(rc,
"Failed to mount DFS namespace");
572 DCHECK(rc,
"Failed to set DFS Prefix");
581 if (cont_create &&
rank == 0) {
582 #if CHECK_DAOS_API_VERSION(1, 4) 585 daos_cont_destroy(
poh, co_uuid, 1,
NULL);
589 daos_pool_disconnect(
poh,
NULL);
594 ERR(
"Failed to initialize DAOS DFS driver");
614 d_list_t *rlink =
NULL;
623 DCHECK(rc,
"Failed to destroy DFS hash");
626 rc = dfs_umount(
dfs);
627 DCHECK(rc,
"Failed to umount DFS namespace");
630 rc = daos_cont_close(
coh,
NULL);
631 DCHECK(rc,
"Failed to close container %s (%d)", o->
cont, rc);
637 #if CHECK_DAOS_API_VERSION(1, 4) 641 uuid_parse(o->
cont, uuid);
642 rc = daos_cont_destroy(
poh, uuid, 1,
NULL);
644 DCHECK(rc,
"Failed to destroy container %s", o->
cont);
647 MPI_Bcast(&rc, 1, MPI_INT, 0,
testComm);
650 DCHECK(rc,
"Failed to destroy container %s (%d)", o->
cont, rc);
657 rc = daos_pool_disconnect(
poh,
NULL);
658 DCHECK(rc,
"Failed to disconnect from pool");
666 DCHECK(rc,
"Failed to finalize DAOS");
688 dfs_obj_t *obj =
NULL, *parent =
NULL;
694 DCHECK(rc,
"Failed to parse path %s", testFileName);
698 mode = S_IFREG | mode;
700 fd_oflag |= O_CREAT | O_RDWR | O_EXCL;
704 DERR(
"Failed to lookup parent: %s", dir_name);
706 rc = dfs_open(
dfs, parent, name, mode, fd_oflag,
708 DCHECK(rc,
"dfs_open() of %s Failed", name);
713 DCHECK(rc,
"global open of %s Failed", name);
732 dfs_obj_t *obj =
NULL, *parent =
NULL;
738 mode = S_IFREG | flags;
741 DCHECK(rc,
"Failed to parse path %s", testFileName);
748 DERR(
"Failed to lookup parent: %s", dir_name);
752 DCHECK(rc,
"dfs_open() of %s Failed", name);
757 DCHECK(rc,
"global open of %s Failed", name);
777 long long remaining = (
long long)length;
778 char *ptr = (
char *)buffer;
783 obj = (dfs_obj_t *)file;
785 while (remaining > 0) {
792 d_iov_set(&iov, (
void *)ptr, remaining);
796 if (access ==
WRITE) {
797 rc = dfs_write(
dfs, obj, &sgl, off,
NULL);
799 ERRF(
"dfs_write(%p, %lld) failed (%d): %s\n",
800 (
void*)ptr, remaining, rc, strerror(rc));
803 rc = dfs_read(
dfs, obj, &sgl, off, &ret,
NULL);
805 ERRF(
"dfs_read(%p, %lld) failed (%d): %s\n",
806 (
void*)ptr, remaining, rc, strerror(rc));
808 ERRF(
"dfs_read(%p, %lld) returned EOF prematurely",
809 (
void*)ptr, remaining);
812 if (ret < remaining) {
816 ERR(
"too many retries -- aborting");
820 assert(ret <= remaining);
857 dfs_release((dfs_obj_t *)fd);
867 dfs_obj_t *parent =
NULL;
871 DCHECK(rc,
"Failed to parse path %s", testFileName);
878 DERR(
"Failed to lookup parent: %s", dir_name);
880 rc = dfs_remove(
dfs, parent, name,
false,
NULL);
881 DCHECK(rc,
"Failed to remove path %s", testFileName);
891 static char ver[1024] = {};
893 sprintf(ver,
"%s",
"DAOS");
909 comm = MPI_COMM_SELF;
915 rc = dfs_lookup(
dfs, testFileName, O_RDONLY, &obj,
NULL,
NULL);
917 fprintf(stderr,
"dfs_lookup() of %s Failed (%d)", testFileName, rc);
921 rc = dfs_get_size(
dfs, obj, &fsize);
928 rc = MPI_Bcast(&fsize, 1, MPI_UINT64_T, 0, comm);
939 daos_pool_info_t info = {.pi_bits = DPI_SPACE};
943 DCHECK(rc,
"Failed to query pool");
945 sfs->
f_blocks = info.pi_space.ps_space.s_total[DAOS_MEDIA_SCM]
946 + info.pi_space.ps_space.s_total[DAOS_MEDIA_NVME];
947 sfs->
f_bfree = info.pi_space.ps_space.s_free[DAOS_MEDIA_SCM]
948 + info.pi_space.ps_space.s_free[DAOS_MEDIA_NVME];
963 dfs_obj_t *parent =
NULL;
968 DCHECK(rc,
"Failed to parse path %s", path);
976 DERR(
"Failed to lookup parent: %s", dir_name);
993 dfs_obj_t *old_parent =
NULL, *new_parent =
NULL;
994 char *old_name =
NULL, *old_dir_name =
NULL;
995 char *new_name =
NULL, *new_dir_name =
NULL;
999 DCHECK(rc,
"Failed to parse path %s", oldfile);
1000 assert(old_dir_name);
1004 DCHECK(rc,
"Failed to parse path %s", newfile);
1005 assert(new_dir_name);
1009 if (old_parent ==
NULL)
1010 DERR(
"Failed to lookup parent: %s", old_dir_name);
1013 if (new_parent ==
NULL)
1014 DERR(
"Failed to lookup parent: %s", new_dir_name);
1016 rc = dfs_move(
dfs, old_parent, old_name, new_parent, new_name,
NULL);
1035 dfs_obj_t *parent =
NULL;
1040 DCHECK(rc,
"Failed to parse path %s", path);
1047 DERR(
"Failed to lookup parent: %s", dir_name);
1049 rc = dfs_remove(
dfs, parent, name,
false,
NULL);
1064 dfs_obj_t *parent =
NULL;
1065 dfs_obj_t *obj =
NULL;
1070 DCHECK(rc,
"Failed to parse path %s", path);
1077 DERR(
"Failed to lookup parent: %s", dir_name);
1079 if (strcmp(name,
"/") == 0) {
1084 rc = dfs_access(
dfs, parent, name, mode);
1099 dfs_obj_t *parent =
NULL;
1104 DCHECK(rc,
"Failed to parse path %s", path);
1111 DERR(
"Failed to lookup parent: %s", dir_name);
1113 rc = dfs_stat(
dfs, parent, name, buf);
static void rec_free(struct d_hash_table *htable, d_list_t *rlink)
static struct aiori_dir_hdl * hdl_obj(d_list_t *rlink)
#define DCHECK(rc, format,...)
struct benchmark_options o
static bool rec_decref(struct d_hash_table *htable, d_list_t *rlink)
static struct d_hash_table * aiori_dfs_hash
static int parse_filename(const char *path, char **_obj_name, char **_cont_name)
static d_hash_table_ops_t hdl_hash_ops
static IOR_offset_t DFS_Xfer(int, aiori_fd_t *, IOR_size_t *, IOR_offset_t, IOR_offset_t, aiori_mod_opt_t *)
static aiori_fd_t * DFS_Create(char *, int, aiori_mod_opt_t *)
#define MPI_CHECK(MPI_STATUS, MSG)
static int DFS_Access(const char *, int, aiori_mod_opt_t *)
static void DFS_Finalize(aiori_mod_opt_t *)
#define INFO(level, format,...)
static aiori_xfer_hint_t * hints
static option_help options[]
static int DFS_Rename(const char *, const char *, aiori_mod_opt_t *)
static void DFS_Sync(aiori_mod_opt_t *)
static daos_oclass_id_t dir_oclass
static IOR_offset_t DFS_GetFileSize(aiori_mod_opt_t *, char *)
static int DFS_Mkdir(const char *, mode_t, aiori_mod_opt_t *)
static void DFS_init_xfer_options(aiori_xfer_hint_t *)
static option_help * DFS_options(aiori_mod_opt_t **init_backend_options, aiori_mod_opt_t *init_values)
static void DFS_Delete(char *, aiori_mod_opt_t *)
static daos_oclass_id_t objectClass
static uint32_t rec_hash(struct d_hash_table *htable, d_list_t *rlink)
static char * DFS_GetVersion()
static void DFS_Close(aiori_fd_t *, aiori_mod_opt_t *)
static int DFS_Statfs(const char *, ior_aiori_statfs_t *, aiori_mod_opt_t *)
static dfs_obj_t * lookup_insert_dir(const char *name, mode_t *mode)
static int HandleDistribute(enum handleType type)
static int DFS_Stat(const char *, struct stat *, aiori_mod_opt_t *)
static void DFS_Fsync(aiori_fd_t *, aiori_mod_opt_t *)
static void DFS_Init(aiori_mod_opt_t *)
static aiori_fd_t * DFS_Open(char *, int, aiori_mod_opt_t *)
static int share_file_handle(dfs_obj_t **file, MPI_Comm comm)
static int dfs_init_count
long long int IOR_offset_t
static int DFS_Rmdir(const char *, aiori_mod_opt_t *)
static bool key_cmp(struct d_hash_table *htable, d_list_t *rlink, const void *key, unsigned int ksize)
static int DFS_check_params(aiori_mod_opt_t *)