@@ -308,6 +308,9 @@ int daos_parse_path(
308308 } else {
309309 strncpy (path , dattr .da_rel_path , path_len );
310310 }
311+ } else if (strncmp (path , "daos:" , 5 ) == 0 ) {
312+ /* Actual error, since we expect a daos path */
313+ rc = -1 ;
311314 } else {
312315 /* If basename does not exist yet then duns_resolve_path will fail even
313316 * if dirname is a UNS path */
@@ -354,9 +357,6 @@ int daos_parse_path(
354357 snprintf (* pool_str , DAOS_PROP_LABEL_MAX_LEN + 1 , "%s" , dattr .da_pool );
355358 snprintf (* cont_str , DAOS_PROP_LABEL_MAX_LEN + 1 , "%s" , dattr .da_cont );
356359 strncpy (path , dattr .da_rel_path , path_len );
357- } else if (strncmp (path , "daos:" , 5 ) == 0 ) {
358- /* Actual error, since we expect a daos path */
359- rc = -1 ;
360360 } else {
361361 /* We didn't parse a daos path,
362362 * but we weren't necessarily looking for one */
@@ -450,7 +450,7 @@ static int daos_set_paths(
450450 return rc ;
451451}
452452
453- static int daos_get_cont_type (
453+ static int mfu_daos_get_cont_type (
454454 daos_handle_t coh ,
455455 enum daos_cont_props * type )
456456{
@@ -516,7 +516,7 @@ static int daos_check_cont_status(daos_handle_t coh, bool *status_healthy)
516516 * Try to set the file type based on the container type,
517517 * using api as a guide.
518518 */
519- static int daos_set_api_cont_type (
519+ static int mfu_daos_set_api_cont_type (
520520 mfu_file_t * mfu_file ,
521521 enum daos_cont_props cont_type ,
522522 daos_api_t api )
@@ -1013,7 +1013,7 @@ void daos_bcast_handle(
10131013}
10141014
10151015/* connect to DAOS pool, and then open container */
1016- int daos_connect (
1016+ int mfu_daos_connect (
10171017 int rank ,
10181018 daos_args_t * da ,
10191019 char (* pool )[],
@@ -1022,7 +1022,9 @@ int daos_connect(
10221022 daos_handle_t * coh ,
10231023 bool force_serialize ,
10241024 bool connect_pool ,
1025+ unsigned int pool_connect_flags ,
10251026 bool create_cont ,
1027+ unsigned int cont_open_flags ,
10261028 bool require_new_cont ,
10271029 bool preserve ,
10281030 mfu_file_t * mfu_src_file ,
@@ -1059,12 +1061,12 @@ int daos_connect(
10591061 }
10601062#endif
10611063 /* Connect to DAOS pool */
1062- if (connect_pool ) {
1064+ if (connect_pool && ! daos_handle_is_valid ( * poh ) ) {
10631065 daos_pool_info_t pool_info = {0 };
10641066#if DAOS_API_VERSION_MAJOR < 1
1065- rc = daos_pool_connect (* pool , NULL , NULL , DAOS_PC_RW , poh , & pool_info , NULL );
1067+ rc = daos_pool_connect (* pool , NULL , NULL , pool_connect_flags , poh , & pool_info , NULL );
10661068#else
1067- rc = daos_pool_connect (* pool , NULL , DAOS_PC_RW , poh , & pool_info , NULL );
1069+ rc = daos_pool_connect (* pool , NULL , pool_connect_flags , poh , & pool_info , NULL );
10681070#endif
10691071 if (rc != 0 ) {
10701072 MFU_LOG (MFU_LOG_ERR , "Failed to connect to pool: " DF_RC , DP_RC (rc ));
@@ -1082,9 +1084,9 @@ int daos_connect(
10821084 * not generated */
10831085 char cont_str [130 ];
10841086 uuid_unparse (da -> dst_cont_uuid , cont_str );
1085- rc = daos_cont_open (* poh , cont_str , DAOS_COO_RW , coh , & co_info , NULL );
1087+ rc = daos_cont_open (* poh , cont_str , cont_open_flags , coh , & co_info , NULL );
10861088 } else {
1087- rc = daos_cont_open (* poh , * cont , DAOS_COO_RW , coh , & co_info , NULL );
1089+ rc = daos_cont_open (* poh , * cont , cont_open_flags , coh , & co_info , NULL );
10881090 }
10891091 if (rc != 0 ) {
10901092 if (rc != - DER_NONEXIST || !create_cont ) {
@@ -1146,7 +1148,7 @@ int daos_connect(
11461148 /* if nothing is passed in for destination a uuid is always
11471149 * generated unless user passed one in, destination container
11481150 * labels are not generated */
1149- rc = dfs_cont_create (* poh , da -> dst_cont_uuid , & attr , NULL , NULL );
1151+ rc = dfs_cont_create (* poh , & da -> dst_cont_uuid , & attr , NULL , NULL );
11501152 }
11511153 if (rc != 0 ) {
11521154 MFU_LOG (MFU_LOG_ERR , "Failed to create container: (%d %s)" , rc , strerror (rc ));
@@ -1156,7 +1158,7 @@ int daos_connect(
11561158 if (dst_cont_passed && !is_uuid ) {
11571159 rc = daos_cont_create_with_label (* poh , * cont , props , & da -> dst_cont_uuid , NULL );
11581160 } else {
1159- rc = daos_cont_create (* poh , da -> dst_cont_uuid , props , NULL );
1161+ rc = daos_cont_create (* poh , & da -> dst_cont_uuid , props , NULL );
11601162 }
11611163 if (rc != 0 ) {
11621164 MFU_LOG (MFU_LOG_ERR , "Failed to create container: " DF_RC , DP_RC (rc ));
@@ -1174,11 +1176,11 @@ int daos_connect(
11741176
11751177 /* try to open it again */
11761178 if (dst_cont_passed && !is_uuid ) {
1177- rc = daos_cont_open (* poh , * cont , DAOS_COO_RW , coh , & co_info , NULL );
1179+ rc = daos_cont_open (* poh , * cont , cont_open_flags , coh , & co_info , NULL );
11781180 } else {
11791181 char cont_str [130 ];
11801182 uuid_unparse (da -> dst_cont_uuid , cont_str );
1181- rc = daos_cont_open (* poh , cont_str , DAOS_COO_RW , coh , & co_info , NULL );
1183+ rc = daos_cont_open (* poh , cont_str , cont_open_flags , coh , & co_info , NULL );
11821184 }
11831185 if (rc != 0 ) {
11841186 MFU_LOG (MFU_LOG_ERR , "Failed to open container: " DF_RC , DP_RC (rc ));
@@ -1554,8 +1556,7 @@ int daos_setup(
15541556 }
15551557
15561558 /* Make sure there weren't any errors before continuing.
1557- * Since daos_connect has a collective broadcast.
1558- * we have to make sure same_pool below is valid. */
1559+ * Since mfu_daos_connect has a collective broadcast. */
15591560 if (daos_any_error (rank , local_daos_error , flag_daos_args )) {
15601561 tmp_rc = daos_fini ();
15611562 return 1 ;
@@ -1569,10 +1570,16 @@ int daos_setup(
15691570 bool have_src_cont = strlen (da -> src_cont ) > 0 ? true : false;
15701571 bool have_dst_pool = strlen (da -> dst_pool ) > 0 ? true : false;
15711572
1572- /* Check if containers are in the same pool */
1573- bool same_pool = (strcmp (da -> src_pool , da -> dst_pool ) == 0 );
1573+ /* Need W on destination pools for creating a container */
1574+ unsigned int src_pool_connect_flags = DAOS_PC_RO ;
1575+ unsigned int dst_pool_connect_flags = DAOS_PC_RW ;
1576+
1577+ /* For POSIX containers, the source only needs read, but the destination needs read and write.
1578+ * For DAOS (object-level), both containers need read and write.
1579+ * Open the source with RO first, then elevate to RW if needed below. */
1580+ unsigned int src_cont_open_flags = DAOS_COO_RO ;
1581+ unsigned int dst_cont_open_flags = DAOS_COO_RW ;
15741582
1575- bool connect_pool = true;
15761583 bool create_cont = false;
15771584 bool require_new_cont = false;
15781585 bool preserve = false;
@@ -1587,28 +1594,52 @@ int daos_setup(
15871594 local_daos_error = true;
15881595 goto out ;
15891596 }
1590- tmp_rc = daos_connect (rank , da , & da -> src_pool , & da -> src_cont ,
1591- & da -> src_poh , & da -> src_coh , false,
1592- connect_pool , create_cont , require_new_cont ,
1593- preserve , mfu_src_file , dst_cont_passed );
1597+ tmp_rc = mfu_daos_connect (rank , da , & da -> src_pool , & da -> src_cont ,
1598+ & da -> src_poh , & da -> src_coh , false,
1599+ true, src_pool_connect_flags , create_cont , src_cont_open_flags , require_new_cont ,
1600+ preserve , mfu_src_file , dst_cont_passed );
15941601 if (tmp_rc != 0 ) {
1595- /* tmp_rc from daos_connect is collective */
1602+ /* tmp_rc from mfu_daos_connect is collective */
15961603 local_daos_error = true;
15971604 goto out ;
15981605 }
15991606 /* Get the container type */
1600- tmp_rc = daos_get_cont_type (da -> src_coh , & da -> src_cont_type );
1607+ tmp_rc = mfu_daos_get_cont_type (da -> src_coh , & da -> src_cont_type );
16011608 if (tmp_rc != 0 ) {
16021609 /* ideally, this should be the same for each process */
16031610 local_daos_error = true;
16041611 goto out ;
16051612 }
16061613 /* Set the src api based on the container type */
1607- tmp_rc = daos_set_api_cont_type (mfu_src_file , da -> src_cont_type , da -> api );
1614+ tmp_rc = mfu_daos_set_api_cont_type (mfu_src_file , da -> src_cont_type , da -> api );
16081615 if (tmp_rc != 0 ) {
16091616 local_daos_error = true;
16101617 goto out ;
16111618 }
1619+ /* If using the DAOS API, we need to elevate permissions to RW for creating a snapshot */
1620+ if (mfu_src_file -> type == DAOS ) {
1621+ MPI_Barrier (MPI_COMM_WORLD );
1622+
1623+ tmp_rc = daos_cont_close (da -> src_coh , NULL );
1624+ if (tmp_rc != 0 ) {
1625+ local_daos_error = true;
1626+ goto out ;
1627+ }
1628+ da -> src_coh = DAOS_HDL_INVAL ;
1629+
1630+ /* Re-open with RW */
1631+ src_cont_open_flags = DAOS_COO_RW ;
1632+ tmp_rc = mfu_daos_connect (rank , da , & da -> src_pool , & da -> src_cont ,
1633+ & da -> src_poh , & da -> src_coh , false,
1634+ true, src_pool_connect_flags , create_cont , src_cont_open_flags , require_new_cont ,
1635+ preserve , mfu_src_file , dst_cont_passed );
1636+ if (tmp_rc != 0 ) {
1637+ /* tmp_rc from mfu_daos_connect is collective */
1638+ local_daos_error = true;
1639+ goto out ;
1640+ }
1641+ }
1642+
16121643 /* Sanity check before we create a new container */
16131644 if (da -> src_cont_type != DAOS_PROP_CO_LAYOUT_POSIX ) {
16141645 if (strcmp (da -> src_path , "/" ) != 0 ) {
@@ -1622,7 +1653,7 @@ int daos_setup(
16221653 }
16231654
16241655 /* If we're using the DAOS API, the destination container cannot
1625- * exist already, unless overriden by allow_exist_dst_cont. */
1656+ * exist already, unless overridden by allow_exist_dst_cont. */
16261657 if (mfu_src_file -> type != POSIX && mfu_src_file -> type != DFS && !da -> allow_exist_dst_cont ) {
16271658 require_new_cont = true;
16281659 }
@@ -1646,11 +1677,11 @@ int daos_setup(
16461677 create_cont = true;
16471678 /* do check that src is POSIX and since dst has a pool,
16481679 * then the dst *should* always be DFS, but this is not set
1649- * on the destintaion until after daos_connect is called, and
1680+ * on the destintaion until after mfu_daos_connect is called, and
16501681 * we should read the properties *before* the container is
16511682 * created. We do not have the destination container type
16521683 * here yet which is why extra check is used then passed
1653- * to daos_connect */
1684+ * to mfu_daos_connect */
16541685 if (da -> daos_preserve ) {
16551686 if (mfu_src_file -> type == POSIX ) {
16561687 preserve = true;
@@ -1662,34 +1693,25 @@ int daos_setup(
16621693 goto out ;
16631694 }
16641695 }
1665- if (same_pool ) {
1666- connect_pool = false;
1667- tmp_rc = daos_connect (rank , da , & da -> dst_pool , & da -> dst_cont ,
1668- & da -> src_poh , & da -> dst_coh , false,
1669- connect_pool , create_cont , require_new_cont ,
1670- preserve , mfu_src_file , dst_cont_passed );
1671- } else {
1672- connect_pool = true;
1673- tmp_rc = daos_connect (rank , da , & da -> dst_pool , & da -> dst_cont ,
1696+ tmp_rc = mfu_daos_connect (rank , da , & da -> dst_pool , & da -> dst_cont ,
16741697 & da -> dst_poh , & da -> dst_coh , false,
1675- connect_pool , create_cont , require_new_cont ,
1676- preserve , mfu_src_file , dst_cont_passed );
1677- }
1698+ true, dst_pool_connect_flags , create_cont , dst_cont_open_flags ,
1699+ require_new_cont , preserve , mfu_src_file , dst_cont_passed );
16781700 if (tmp_rc != 0 ) {
1679- /* tmp_rc from daos_connect is collective */
1701+ /* tmp_rc from mfu_daos_connect is collective */
16801702 local_daos_error = true;
16811703 goto out ;
16821704 }
16831705 /* Get the container type */
1684- tmp_rc = daos_get_cont_type (da -> dst_coh , & da -> dst_cont_type );
1706+ tmp_rc = mfu_daos_get_cont_type (da -> dst_coh , & da -> dst_cont_type );
16851707 if (tmp_rc != 0 ) {
16861708 /* ideally, this should be the same for each process */
16871709 local_daos_error = true;
16881710 goto out ;
16891711 }
16901712 if (have_dst ) {
16911713 /* Set the dst api based on the container type */
1692- tmp_rc = daos_set_api_cont_type (mfu_dst_file , da -> dst_cont_type , da -> api );
1714+ tmp_rc = mfu_daos_set_api_cont_type (mfu_dst_file , da -> dst_cont_type , da -> api );
16931715 if (tmp_rc != 0 ) {
16941716 local_daos_error = true;
16951717 goto out ;
@@ -1716,11 +1738,7 @@ int daos_setup(
17161738 if (have_dst ) {
17171739 /* Mount destination DFS container */
17181740 if (mfu_dst_file -> type == DFS ) {
1719- if (same_pool ) {
1720- tmp_rc = mfu_dfs_mount (mfu_dst_file , & da -> src_poh , & da -> dst_coh );
1721- } else {
1722- tmp_rc = mfu_dfs_mount (mfu_dst_file , & da -> dst_poh , & da -> dst_coh );
1723- }
1741+ tmp_rc = mfu_dfs_mount (mfu_dst_file , & da -> dst_poh , & da -> dst_coh );
17241742 if (tmp_rc != 0 ) {
17251743 local_daos_error = true;
17261744 goto out ;
@@ -1767,8 +1785,6 @@ int daos_cleanup(
17671785 int rank ;
17681786 MPI_Comm_rank (MPI_COMM_WORLD , & rank );
17691787
1770- bool same_pool = (strcmp (da -> src_pool , da -> dst_pool ) == 0 );
1771-
17721788 /* Destroy source snapshot */
17731789 if (rank == 0 && da -> src_epc != 0 ) {
17741790 tmp_rc = mfu_daos_destroy_snap (da -> src_coh , da -> src_epc );
@@ -1837,7 +1853,7 @@ int daos_cleanup(
18371853 }
18381854
18391855 /* Close destination pool */
1840- if (daos_handle_is_valid (da -> dst_poh ) && ! same_pool ) {
1856+ if (daos_handle_is_valid (da -> dst_poh )) {
18411857 tmp_rc = daos_pool_disconnect (da -> dst_poh , NULL );
18421858 if (tmp_rc != 0 ) {
18431859 MFU_LOG (MFU_LOG_ERR , "Failed to disconnect from destination pool " DF_RC , DP_RC (tmp_rc ));
0 commit comments