From c6097935d5be4c3750b9bf9167783ad28158905b Mon Sep 17 00:00:00 2001
From: Dana Robinson <derobins@hdfgroup.org>
Date: Mon, 20 Apr 2020 17:38:45 -0700
Subject: Separated VFD and VOL parameters in tools.

---
 tools/lib/h5tools.c                | 335 ++++++++++++++++++-------------------
 tools/lib/h5tools.h                |  33 ++--
 tools/libtest/h5tools_test_utils.c |   9 +-
 tools/src/h5dump/h5dump.c          |  16 +-
 tools/src/h5ls/h5ls.c              |  14 +-
 tools/src/h5repack/h5repack_main.c |  12 +-
 tools/src/h5stat/h5stat.c          |  14 +-
 7 files changed, 215 insertions(+), 218 deletions(-)

diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c
index 2f641d0..cc51e2c 100644
--- a/tools/lib/h5tools.c
+++ b/tools/lib/h5tools.c
@@ -434,138 +434,126 @@ h5tools_set_error_file(const char *fname, int is_bin)
 }
 
 /*-------------------------------------------------------------------------
- * Function: h5tools_set_vfd_fapl
+ * Function: h5tools_set_fapl_vfd
  *
  * Purpose:  Given a VFL driver name, sets the appropriate driver on the
  *           specified FAPL.
  *
- * TODO:     Add handling for Windows VFD.
- *
  * Return:   positive - succeeded
  *           negative - failed
  *-------------------------------------------------------------------------
  */
 static herr_t
-h5tools_set_vfd_fapl(hid_t fapl, h5tools_fapl_info_t *fapl_info)
+h5tools_set_fapl_vfd(hid_t fapl_id, h5tools_vfd_info_t *vfd_info)
 {
     herr_t ret_value = SUCCEED;
 
-    switch (fapl_info->type) {
-        /* Currently, only retrieving a VFD by name is supported */
-        case VFD_BY_NAME:
-            /* Determine which driver the user wants to open the file with */
-            if (!HDstrcmp(fapl_info->u.name, drivernames[SEC2_VFD_IDX])) {
-                /* SEC2 Driver */
-                if (H5Pset_fapl_sec2(fapl) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_sec2 failed");
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[DIRECT_VFD_IDX])) {
+    /* Determine which driver the user wants to open the file with */
+    if (!HDstrcmp(vfd_info->name, drivernames[SEC2_VFD_IDX])) {
+        /* SEC2 Driver */
+        if (H5Pset_fapl_sec2(fapl_id) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_sec2 failed");
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[DIRECT_VFD_IDX])) {
 #ifdef H5_HAVE_DIRECT
-                /* Direct Driver */
-                if (H5Pset_fapl_direct(fapl, 1024, 4096, 8 * 4096) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_direct failed");
+        /* Direct Driver */
+        if (H5Pset_fapl_direct(fapl_id, 1024, 4096, 8 * 4096) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_direct failed");
 #else
-                H5TOOLS_GOTO_ERROR(FAIL, "Direct VFD is not enabled");
+        H5TOOLS_GOTO_ERROR(FAIL, "Direct VFD is not enabled");
 #endif
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[LOG_VFD_IDX])) {
-                unsigned long long log_flags = H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC;
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[LOG_VFD_IDX])) {
+        unsigned long long log_flags = H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC;
 
-                /* Log Driver */
-                if (H5Pset_fapl_log(fapl, NULL, log_flags, (size_t) 0) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_sec2 failed");
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[WINDOWS_VFD_IDX])) {
+        /* Log Driver */
+        if (H5Pset_fapl_log(fapl_id, NULL, log_flags, (size_t) 0) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_log failed");
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[WINDOWS_VFD_IDX])) {
 #ifdef H5_HAVE_WINDOWS
-
+        /* There is no Windows VFD - use SEC2 */
+        if (H5Pset_fapl_sec2(fapl_id) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_sec2 failed");
 #else
-                H5TOOLS_GOTO_ERROR(FAIL, "Windows VFD is not enabled");
+        H5TOOLS_GOTO_ERROR(FAIL, "Windows VFD is not enabled");
 #endif
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[STDIO_VFD_IDX])) {
-                /* Stdio Driver */
-                if (H5Pset_fapl_stdio(fapl) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_stdio failed");
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[CORE_VFD_IDX])) {
-                /* Core Driver */
-                if (H5Pset_fapl_core(fapl, (size_t) H5_MB, TRUE) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_stdio failed");
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[FAMILY_VFD_IDX])) {
-                /* FAMILY Driver */
-
-                /* Set member size to be 0 to indicate the current first member size
-                 * is the member size.
-                 */
-                if (H5Pset_fapl_family(fapl, (hsize_t) 0, H5P_DEFAULT) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_family failed");
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[SPLIT_VFD_IDX])) {
-                /* SPLIT Driver */
-                if (H5Pset_fapl_split(fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_split failed");
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[MULTI_VFD_IDX])) {
-                /* MULTI Driver */
-                if (H5Pset_fapl_multi(fapl, NULL, NULL, NULL, NULL, TRUE) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_multi failed");
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[MPIO_VFD_IDX])) {
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[STDIO_VFD_IDX])) {
+        /* Stdio Driver */
+        if (H5Pset_fapl_stdio(fapl_id) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_stdio failed");
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[CORE_VFD_IDX])) {
+        /* Core Driver */
+        if (H5Pset_fapl_core(fapl_id, (size_t) H5_MB, TRUE) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_core failed");
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[FAMILY_VFD_IDX])) {
+        /* FAMILY Driver */
+        /* Set member size to be 0 to indicate the current first member size
+         * is the member size.
+         */
+        if (H5Pset_fapl_family(fapl_id, (hsize_t) 0, H5P_DEFAULT) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_family failed");
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[SPLIT_VFD_IDX])) {
+        /* SPLIT Driver */
+        if (H5Pset_fapl_split(fapl_id, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_split failed");
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[MULTI_VFD_IDX])) {
+        /* MULTI Driver */
+        if (H5Pset_fapl_multi(fapl_id, NULL, NULL, NULL, NULL, TRUE) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_multi failed");
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[MPIO_VFD_IDX])) {
 #ifdef H5_HAVE_PARALLEL
-                int mpi_initialized, mpi_finalized;
+        int mpi_initialized, mpi_finalized;
 
-                /* MPI-I/O Driver */
+        /* MPI-I/O Driver */
 
-                /* check if MPI is available. */
-                MPI_Initialized(&mpi_initialized);
-                MPI_Finalized(&mpi_finalized);
+        /* check if MPI is available. */
+        MPI_Initialized(&mpi_initialized);
+        MPI_Finalized(&mpi_finalized);
 
-                if (mpi_initialized && !mpi_finalized) {
-                    if (H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0)
-                        H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_mpio failed");
-                } /* end if */
+        if (mpi_initialized && !mpi_finalized) {
+            if (H5Pset_fapl_mpio(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL) < 0)
+                H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_mpio failed");
+        }
 #else
-                H5TOOLS_GOTO_ERROR(FAIL, "MPI-I/O VFD is not enabled");
+        H5TOOLS_GOTO_ERROR(FAIL, "MPI-I/O VFD is not enabled");
 #endif /* H5_HAVE_PARALLEL */
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[ROS3_VFD_IDX])) {
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[ROS3_VFD_IDX])) {
 #ifdef H5_HAVE_ROS3_VFD
-                if (!fapl_info->info_string)
-                    H5TOOLS_GOTO_ERROR(FAIL, "Read-only S3 VFD info is invalid");
-                if (H5Pset_fapl_ros3(fapl, (H5FD_ros3_fapl_t *)fapl_info->info_string) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_ros3() failed");
+        if (!vfd_info->info)
+            H5TOOLS_GOTO_ERROR(FAIL, "Read-only S3 VFD info is invalid");
+        if (H5Pset_fapl_ros3(fapl_id, (H5FD_ros3_fapl_t *)vfd_info->info) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_ros3() failed");
 #else
-                H5TOOLS_GOTO_ERROR(FAIL, "Read-only S3 VFD is not enabled");
+        H5TOOLS_GOTO_ERROR(FAIL, "Read-only S3 VFD is not enabled");
 #endif
-            }
-            else if (!HDstrcmp(fapl_info->u.name, drivernames[HDFS_VFD_IDX])) {
+    }
+    else if (!HDstrcmp(vfd_info->name, drivernames[HDFS_VFD_IDX])) {
 #ifdef H5_HAVE_LIBHDFS
-                if (!fapl_info->info_string)
-                    H5TOOLS_GOTO_ERROR(FAIL, "HDFS VFD info is invalid");
-                if (H5Pset_fapl_hdfs(fapl, (H5FD_hdfs_fapl_t *)fapl_info->info_string) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_hdfs() failed");
+        if (!vfd_info->info)
+            H5TOOLS_GOTO_ERROR(FAIL, "HDFS VFD info is invalid");
+        if (H5Pset_fapl_hdfs(fapl_id, (H5FD_hdfs_fapl_t *)vfd_info->info) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "H5Pset_fapl_hdfs() failed");
 #else
-                H5TOOLS_GOTO_ERROR(FAIL, "The HDFS VFD is not enabled");
+        H5TOOLS_GOTO_ERROR(FAIL, "The HDFS VFD is not enabled");
 #endif
-            }
-            else
-                H5TOOLS_GOTO_ERROR(FAIL, "invalid VFD name");
-
-            break;
-
-        case VOL_BY_NAME:
-        case VOL_BY_VALUE:
-        default:
-            H5TOOLS_GOTO_ERROR(FAIL, "invalid VFD retrieval type");
     }
+    else
+        H5TOOLS_GOTO_ERROR(FAIL, "invalid VFD name");
 
 done:
     return ret_value;
 }
 
 /*-------------------------------------------------------------------------
- * Function: h5tools_set_vol_fapl
+ * Function: h5tools_set_fapl_vol
  *
  * Purpose:  Given a VOL connector name or ID, sets the appropriate
  *           connector on the specified FAPL.
@@ -575,83 +563,86 @@ done:
  *-------------------------------------------------------------------------
  */
 static herr_t
-h5tools_set_vol_fapl(hid_t fapl_id, h5tools_fapl_info_t *fapl_info)
+h5tools_set_fapl_vol(hid_t fapl_id, h5tools_vol_info_t *vol_info)
 {
     htri_t connector_is_registered;
     hid_t  connector_id = H5I_INVALID_HID;
-    void *vol_info = NULL;
+    void *connector_info = NULL;
     herr_t ret_value = SUCCEED;
 
-    switch (fapl_info->type) {
+    switch (vol_info->type) {
         case VOL_BY_NAME:
             /* Retrieve VOL connector by name */
-            if ((connector_is_registered = H5VLis_connector_registered_by_name(fapl_info->u.name)) < 0)
+            if ((connector_is_registered = H5VLis_connector_registered_by_name(vol_info->u.name)) < 0)
                 H5TOOLS_GOTO_ERROR(FAIL, "can't check if VOL connector is registered");
             if (connector_is_registered) {
-                if ((connector_id = H5VLget_connector_id_by_name(fapl_info->u.name)) < 0)
+                if ((connector_id = H5VLget_connector_id_by_name(vol_info->u.name)) < 0)
                     H5TOOLS_GOTO_ERROR(FAIL, "can't get VOL connector ID");
             }
             else {
-                /* Check for VOL connectors that ship with the library */
-                if (!HDstrcmp(fapl_info->u.name, H5VL_NATIVE_NAME)) {
+                /* Check for VOL connectors that ship with the library, then try
+                 * registering by name if that fails.
+                */
+                if (!HDstrcmp(vol_info->u.name, H5VL_NATIVE_NAME)) {
                     connector_id = H5VL_NATIVE;
                 }
-                else if (!HDstrcmp(fapl_info->u.name, H5VL_PASSTHRU_NAME)) {
+                else if (!HDstrcmp(vol_info->u.name, H5VL_PASSTHRU_NAME)) {
                     connector_id = H5VL_PASSTHRU;
                 }
                 else {
-                    if ((connector_id = H5VLregister_connector_by_name(fapl_info->u.name, H5P_DEFAULT)) < 0)
+                    /* NOTE: Not being able to pass in a VIPL may be a limitation for some
+                     * connectors.
+                     */
+                    if ((connector_id = H5VLregister_connector_by_name(vol_info->u.name, H5P_DEFAULT)) < 0)
                         H5TOOLS_GOTO_ERROR(FAIL, "can't register VOL connector");
                 }
             }
 
-            /* Convert the info string */
-            if (fapl_info->info_string)
-                if (H5VLconnector_str_to_info(fapl_info->info_string, connector_id, &vol_info) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "can't get VOL info from string");
-
             break;
 
         case VOL_BY_VALUE:
             /* Retrieve VOL connector by ID */
-            if ((connector_is_registered = H5VLis_connector_registered_by_value(fapl_info->u.value)) < 0)
+            if ((connector_is_registered = H5VLis_connector_registered_by_value(vol_info->u.value)) < 0)
                 H5TOOLS_GOTO_ERROR(FAIL, "can't check if VOL connector is registered");
             if (connector_is_registered) {
-                if ((connector_id = H5VLget_connector_id_by_value(fapl_info->u.value)) < 0)
+                if ((connector_id = H5VLget_connector_id_by_value(vol_info->u.value)) < 0)
                     H5TOOLS_GOTO_ERROR(FAIL, "can't get VOL connector ID");
             }
             else {
                 /* Check for VOL connectors that ship with the library */
-                if (fapl_info->u.value == H5VL_NATIVE_VALUE) {
+                if (vol_info->u.value == H5VL_NATIVE_VALUE) {
                     connector_id = H5VL_NATIVE;
                 }
-                else if (fapl_info->u.value == H5VL_PASSTHRU_VALUE) {
+                else if (vol_info->u.value == H5VL_PASSTHRU_VALUE) {
                     connector_id = H5VL_PASSTHRU;
                 }
                 else {
-                    if ((connector_id = H5VLregister_connector_by_value(fapl_info->u.value, H5P_DEFAULT)) < 0)
+                    /* NOTE: Not being able to pass in a VIPL may be a limitation for some
+                     * connectors.
+                     */
+                    if ((connector_id = H5VLregister_connector_by_value(vol_info->u.value, H5P_DEFAULT)) < 0)
                         H5TOOLS_GOTO_ERROR(FAIL, "can't register VOL connector");
                 }
             }
 
-            /* Convert the info string */
-            if (fapl_info->info_string)
-                if (H5VLconnector_str_to_info(fapl_info->info_string, connector_id, &vol_info) < 0)
-                    H5TOOLS_GOTO_ERROR(FAIL, "can't get VOL info from string");
-
             break;
 
-        case VFD_BY_NAME:
         default:
             H5TOOLS_GOTO_ERROR(FAIL, "invalid VOL retrieval type");
     }
 
-    if (H5Pset_vol(fapl_id, connector_id, vol_info) < 0)
+    /* Convert the info string, if provided */
+    if (vol_info->info_string)
+        if (H5VLconnector_str_to_info(vol_info->info_string, connector_id, &connector_info) < 0)
+            H5TOOLS_GOTO_ERROR(FAIL, "can't get VOL connector info from string");
+
+    /* Set the VOL connector on the fapl */
+    if (H5Pset_vol(fapl_id, connector_id, connector_info) < 0)
         H5TOOLS_GOTO_ERROR(FAIL, "can't set VOL connector on FAPL");
 
 done:
-    if (vol_info)
-        if (H5VLfree_connector_info(connector_id, vol_info))
+    if (connector_info)
+        if (H5VLfree_connector_info(connector_id, connector_info))
             H5TOOLS_ERROR(FAIL, "failed to free VOL connector-specific info");
 
     if (ret_value < 0) {
@@ -665,45 +656,43 @@ done:
 /*-------------------------------------------------------------------------
  * Function: h5tools_get_fapl
  *
- * Purpose:  Get a FAPL for a given VFL driver name, VOL connector name
- *           or VOL connector ID.
+ * Purpose:  Copies an input fapl and then sets a VOL and/or a VFD on it.
+ *
+ *           The returned fapl must be closed by the caller.
  *
  * Return:   positive - succeeded
  *           negative - failed
  *-------------------------------------------------------------------------
  */
 hid_t
-h5tools_get_fapl(hid_t prev_fapl_id, h5tools_fapl_info_t *fapl_info)
+h5tools_get_fapl(hid_t prev_fapl_id, h5tools_vol_info_t *vol_info,
+    h5tools_vfd_info_t *vfd_info)
 {
     hid_t new_fapl_id = H5I_INVALID_HID;
     hid_t ret_value = H5I_INVALID_HID;
 
     if (prev_fapl_id < 0)
         H5TOOLS_GOTO_ERROR(FAIL, "invalid FAPL");
-    if (!fapl_info)
-        H5TOOLS_GOTO_ERROR(FAIL, "invalid FAPL retrieval info");
 
-    /* Make a copy of the FAPL if necessary, or create a FAPL if
-     * H5P_DEFAULT is specified. */
+    /* Make a copy of the FAPL or create one if H5P_DEFAULT is specified. */
     if (H5P_DEFAULT == prev_fapl_id) {
         if ((new_fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
             H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "H5Pcreate failed");
-    } /* end if */
+    }
     else {
         if ((new_fapl_id = H5Pcopy(prev_fapl_id)) < 0)
             H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "H5Pcopy failed");
     }
 
-    if (VFD_BY_NAME == fapl_info->type) {
-        if (h5tools_set_vfd_fapl(new_fapl_id, fapl_info) < 0)
-            H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to set VFD on FAPL");
-    }
-    else if (VOL_BY_NAME == fapl_info->type || VOL_BY_VALUE == fapl_info->type) {
-        if (h5tools_set_vol_fapl(new_fapl_id, fapl_info) < 0)
+    /* Set non-default VOL connector, if requested */
+    if (vol_info)
+        if (h5tools_set_fapl_vol(new_fapl_id, vol_info) < 0)
             H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to set VOL on FAPL");
-    }
-    else
-        H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "invalid FAPL retrieval type");
+
+    /* Set non-default virtual file driver, if requested */
+    if (vfd_info)
+        if (h5tools_set_fapl_vfd(new_fapl_id, vfd_info) < 0)
+            H5TOOLS_GOTO_ERROR(H5I_INVALID_HID, "failed to set VFD on FAPL");
 
     ret_value = new_fapl_id;
 
@@ -851,13 +840,12 @@ done:
  *-------------------------------------------------------------------------
  */
 hid_t
-h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, hbool_t use_specific_driver,
+h5tools_fopen(const char *fname, unsigned flags, hid_t fapl_id, hbool_t use_specific_driver,
     char *drivername, size_t drivername_size)
 {
     hid_t    fid = H5I_INVALID_HID;
-    hid_t    tmp_vol_fapl = H5I_INVALID_HID;
-    hid_t    tmp_vfd_fapl = H5I_INVALID_HID;
-    hid_t    used_fapl = H5I_INVALID_HID;
+    hid_t    tmp_fapl_id = H5I_INVALID_HID;
+    hid_t    used_fapl_id = H5I_INVALID_HID;
     unsigned volnum, drivernum;
     hid_t    ret_value = H5I_INVALID_HID;
 
@@ -872,17 +860,17 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, hbool_t use_specifi
 
     /* Allow error stack display if --enable-error-stack has optional arg number */
     if (enable_error_stack > 1) {
-        fid = H5Fopen(fname, flags, fapl);
+        fid = H5Fopen(fname, flags, fapl_id);
     }
     else {
         H5E_BEGIN_TRY {
-            fid = H5Fopen(fname, flags, fapl);
+            fid = H5Fopen(fname, flags, fapl_id);
         } H5E_END_TRY;
     }
 
     /* If we succeeded in opening the file, we're done. */
     if (fid >= 0) {
-        used_fapl = fapl;
+        used_fapl_id = fapl_id;
         H5TOOLS_GOTO_DONE(fid);
     }
 
@@ -900,18 +888,16 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, hbool_t use_specifi
      * connector being looked at, also try using each of the available VFL drivers.
      */
     for (volnum = 0; volnum < NUM_VOLS; volnum++) {
-        h5tools_fapl_info_t vol_info;
+        h5tools_vol_info_t vol_info;
 
         vol_info.type           = VOL_BY_NAME;
         vol_info.info_string    = NULL;
         vol_info.u.name         = volnames[volnum];
 
-        /* Get a FAPL for the current VOL connector */
-        if ((tmp_vol_fapl = h5tools_get_fapl(fapl, &vol_info)) < 0)
-            continue;
-
         /* TODO: For now, we have no way of determining if an arbitrary
-         * VOL connector is native-terminal. */
+         * VOL connector is native-terminal so we only try VFDs with the
+         * actual native VOL connector.
+         */
         if (NATIVE_VOL_IDX == volnum) {
             /*
              * If using the native VOL connector, or a VOL connector which has the
@@ -919,7 +905,7 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, hbool_t use_specifi
              * VFL drivers as well.
              */
             for (drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) {
-                h5tools_fapl_info_t vfd_info;
+                h5tools_vfd_info_t vfd_info;
 
                 /* Skip the log VFD as it prints out to standard out
                  * and is fundamentally SEC2 anyway.
@@ -927,34 +913,41 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, hbool_t use_specifi
                 if (drivernum == LOG_VFD_IDX)
                     continue;
 
-                vfd_info.type           = VFD_BY_NAME;
-                vfd_info.info_string    = NULL;
-                vfd_info.u.name         = drivernames[drivernum];
+                vfd_info.info           = NULL;
+                vfd_info.name           = drivernames[drivernum];
 
-                /* Using the current VOL FAPL as a base, get the correct FAPL for the given VFL driver */
-                if ((tmp_vfd_fapl = h5tools_get_fapl(tmp_vol_fapl, &vfd_info)) < 0)
+                /* Get a fapl reflecting the selected VOL connector and VFD */
+                if ((tmp_fapl_id = h5tools_get_fapl(fapl_id, &vol_info, &vfd_info)) < 0)
                     continue;
 
-                if ((fid = h5tools_fopen(fname, flags, tmp_vfd_fapl, TRUE, drivername, drivername_size)) >= 0) {
-                    used_fapl = tmp_vfd_fapl;
+                /* Can we open the file with this combo? */
+                if ((fid = h5tools_fopen(fname, flags, tmp_fapl_id, TRUE, drivername, drivername_size)) >= 0) {
+                    used_fapl_id = tmp_fapl_id;
                     H5TOOLS_GOTO_DONE(fid);
                 }
                 else {
-                    /* Close the temporary VFD FAPL */
-                    H5Pclose(tmp_vfd_fapl);
-                    tmp_vfd_fapl = H5I_INVALID_HID;
+                    /* Close the temporary fapl */
+                    H5Pclose(tmp_fapl_id);
+                    tmp_fapl_id = H5I_INVALID_HID;
                 }
             }
         }
         else {
-            if ((fid = h5tools_fopen(fname, flags, tmp_vol_fapl, TRUE, drivername, drivername_size)) >= 0) {
-                used_fapl = tmp_vol_fapl;
+            /* NOT the native VOL connector */
+
+            /* Get a FAPL for the current VOL connector */
+            if ((tmp_fapl_id = h5tools_get_fapl(fapl_id, &vol_info, NULL)) < 0)
+                continue;
+
+            /* Can we open the file with this connector? */
+            if ((fid = h5tools_fopen(fname, flags, tmp_fapl_id, TRUE, drivername, drivername_size)) >= 0) {
+                used_fapl_id = tmp_fapl_id;
                 H5TOOLS_GOTO_DONE(fid);
             }
             else {
                 /* Close the temporary VOL FAPL */
-                H5Pclose(tmp_vol_fapl);
-                tmp_vol_fapl = H5I_INVALID_HID;
+                H5Pclose(tmp_fapl_id);
+                tmp_fapl_id = H5I_INVALID_HID;
             }
         }
     }
@@ -965,13 +958,11 @@ h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, hbool_t use_specifi
 done:
     /* Save the driver name if using a native-terminal VOL connector */
     if (drivername && drivername_size && ret_value >= 0)
-        if (used_fapl >= 0 && h5tools_get_vfd_name(used_fapl, drivername, drivername_size) < 0)
+        if (used_fapl_id >= 0 && h5tools_get_vfd_name(used_fapl_id, drivername, drivername_size) < 0)
             H5TOOLS_ERROR(H5I_INVALID_HID, "failed to retrieve name of VFD used to open file");
 
-    if (tmp_vfd_fapl >= 0)
-        H5Pclose(tmp_vfd_fapl);
-    if (tmp_vol_fapl >= 0)
-        H5Pclose(tmp_vol_fapl);
+    if (tmp_fapl_id >= 0)
+        H5Pclose(tmp_fapl_id);
 
     return ret_value;
 }
diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h
index b931dc8..2b6fffb 100644
--- a/tools/lib/h5tools.h
+++ b/tools/lib/h5tools.h
@@ -539,24 +539,36 @@ typedef struct h5tools_context_t {
     int display_char;                 /* */
 } h5tools_context_t;
 
+/* VOL and VFD info structs used to set the file access property
+ * lists in the tools.
+ */
+
 typedef enum {
-    VFD_BY_NAME,
     VOL_BY_NAME,
     VOL_BY_VALUE
-} h5tools_fapl_info_type_t;
+} h5tools_vol_info_type_t;
 
-typedef struct h5tools_fapl_info_t {
-    h5tools_fapl_info_type_t type;
+typedef struct h5tools_vol_info_t {
+    h5tools_vol_info_type_t type;
 
-    /* Pointer to information to be passed to the driver/connector for its setup */
+    /* Pointer to information string to be passed to the connector for its setup */
     const char *info_string;
 
-    /* Field specifying either the driver's/connector's name or ID */
+    /* Field specifying either the connector's name or value (ID) */
     union {
-        const char          *name;      /* VOL and VFD */
-        H5VL_class_value_t  value;      /* VOL only */
+        const char          *name;
+        H5VL_class_value_t  value;
     } u;
-} h5tools_fapl_info_t;
+} h5tools_vol_info_t;
+
+typedef struct h5tools_vfd_info_t {
+
+    /* Pointer to information to be passed to the driver for its setup */
+    const void *info;
+
+    /* Name of the VFD */
+    const char *name;
+} h5tools_vfd_info_t;
 
 H5TOOLS_DLLVAR const char *volnames[];
 H5TOOLS_DLLVAR const char *drivernames[];
@@ -637,7 +649,8 @@ H5TOOLS_DLL int     h5tools_set_attr_output_file(const char *fname, int is_bin);
 H5TOOLS_DLL int     h5tools_set_input_file(const char *fname, int is_bin);
 H5TOOLS_DLL int     h5tools_set_output_file(const char *fname, int is_bin);
 H5TOOLS_DLL int     h5tools_set_error_file(const char *fname, int is_bin);
-H5TOOLS_DLL hid_t   h5tools_get_fapl(hid_t prev_fapl_id, h5tools_fapl_info_t *fapl_info);
+H5TOOLS_DLL hid_t   h5tools_get_fapl(hid_t prev_fapl_id, h5tools_vol_info_t *vol_info,
+                        h5tools_vfd_info_t *vfd_info);
 H5TOOLS_DLL herr_t  h5tools_get_vfd_name(hid_t fapl_id, char *drivername, size_t drivername_size);
 H5TOOLS_DLL hid_t   h5tools_fopen(const char *fname, unsigned flags, hid_t fapl,
                             hbool_t use_specific_driver, char *drivername, size_t drivername_size);
diff --git a/tools/libtest/h5tools_test_utils.c b/tools/libtest/h5tools_test_utils.c
index aecd3f5..12360a7 100644
--- a/tools/libtest/h5tools_test_utils.c
+++ b/tools/libtest/h5tools_test_utils.c
@@ -1148,7 +1148,7 @@ test_set_configured_fapl(void)
     TESTING("programmatic fapl set");
 
     for (i = 0; i < n_cases; i++) {
-        h5tools_fapl_info_t fapl_info;
+        h5tools_vfd_info_t vfd_info;
         hid_t result;
         testcase C = cases[i];
 
@@ -1171,10 +1171,9 @@ test_set_configured_fapl(void)
 #endif /* UTIL_TEST_DEBUG */
 
         /* test */
-        fapl_info.type = VFD_BY_NAME;
-        fapl_info.info_string = C.conf_fa;
-        fapl_info.u.name = C.vfdname;
-        result = h5tools_get_fapl(H5P_DEFAULT, &fapl_info);
+        vfd_info.info = C.conf_fa;
+        vfd_info.name = C.vfdname;
+        result = h5tools_get_fapl(H5P_DEFAULT, NULL, &vfd_info);
         if (C.expected == 0)
             JSVERIFY( result, H5I_INVALID_HID, C.message)
         else
diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c
index 3de6454..d292b75 100644
--- a/tools/src/h5dump/h5dump.c
+++ b/tools/src/h5dump/h5dump.c
@@ -870,7 +870,7 @@ parse_command_line(int argc, const char *argv[])
     }
 
     /* this will be plenty big enough to hold the info */
-    if((hand = (struct handler_t *)HDcalloc((size_t)argc, sizeof(struct handler_t)))==NULL) {
+    if((hand = (struct handler_t *)HDcalloc((size_t)argc, sizeof(struct handler_t))) == NULL) {
         goto error;
     }
 
@@ -1415,16 +1415,14 @@ main(int argc, const char *argv[])
     h5trav_set_index(sort_by, sort_order);
 
     if (driver != NULL) {
-        h5tools_fapl_info_t fapl_info;
+        h5tools_vfd_info_t vfd_info;
 
-        /* Currently, only retrieval of VFDs is supported. */
-        fapl_info.type          = VFD_BY_NAME;
-        fapl_info.info_string   = NULL;
-        fapl_info.u.name        = driver;
+        vfd_info.info       = NULL;
+        vfd_info.name       = driver;
 
         if (!HDstrcmp(driver, drivernames[ROS3_VFD_IDX])) {
 #ifdef H5_HAVE_ROS3_VFD
-            fapl_info.info_string = (void *)&ros3_fa;
+            vfd_info.info = (void *)&ros3_fa;
 #else
             error_msg("Read-Only S3 VFD not enabled.\n");
             h5tools_setstatus(EXIT_FAILURE);
@@ -1433,7 +1431,7 @@ main(int argc, const char *argv[])
         }
         else if (!HDstrcmp(driver, drivernames[HDFS_VFD_IDX])) {
 #ifdef H5_HAVE_LIBHDFS
-            fapl_info.info_string = (void *)&hdfs_fa;
+            vfd_info.info = (void *)&hdfs_fa;
 #else
             error_msg("The HDFS VFD is not enabled.\n");
             h5tools_setstatus(EXIT_FAILURE);
@@ -1441,7 +1439,7 @@ main(int argc, const char *argv[])
 #endif
         }
 
-        if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, &fapl_info)) < 0) {
+        if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, NULL, &vfd_info)) < 0) {
             error_msg("unable to create FAPL for file access\n");
             h5tools_setstatus(EXIT_FAILURE);
             goto done;
diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c
index 9fc91f1..3036ae9 100644
--- a/tools/src/h5ls/h5ls.c
+++ b/tools/src/h5ls/h5ls.c
@@ -3148,16 +3148,14 @@ main(int argc, const char *argv[])
     }
 
     if (preferred_driver) {
-        h5tools_fapl_info_t fapl_info;
+        h5tools_vfd_info_t vfd_info;
 
-        /* Currently, only retrieval of VFDs is supported. */
-        fapl_info.type          = VFD_BY_NAME;
-        fapl_info.info_string   = NULL;
-        fapl_info.u.name        = preferred_driver;
+        vfd_info.info       = NULL;
+        vfd_info.name       = preferred_driver;
 
         if (!HDstrcmp(preferred_driver, drivernames[ROS3_VFD_IDX])) {
 #ifdef H5_HAVE_ROS3_VFD
-            fapl_info.info_string = (void *)&ros3_fa;
+            vfd_info.info = (void *)&ros3_fa;
 #else
             HDfprintf(rawerrorstream, "Error: Read-Only S3 VFD is not enabled\n\n");
             leave(EXIT_FAILURE);
@@ -3165,14 +3163,14 @@ main(int argc, const char *argv[])
         }
         else if (!HDstrcmp(preferred_driver, drivernames[HDFS_VFD_IDX])) {
 #ifdef H5_HAVE_LIBHDFS
-            fapl_info.info_string = (void *)&hdfs_fa;
+            vfd_info.info = (void *)&hdfs_fa;
 #else
             HDfprintf(rawerrorstream, "Error: The HDFS VFD is not enabled\n\n");
             leave(EXIT_FAILURE);
 #endif
         }
 
-        if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, &fapl_info)) < 0) {
+        if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, NULL, &vfd_info)) < 0) {
             HDfprintf(rawerrorstream, "Error: Unable to create FAPL for file access\n\n");
             leave(EXIT_FAILURE);
         }
diff --git a/tools/src/h5repack/h5repack_main.c b/tools/src/h5repack/h5repack_main.c
index 03da8d9..d54827f 100644
--- a/tools/src/h5repack/h5repack_main.c
+++ b/tools/src/h5repack/h5repack_main.c
@@ -432,16 +432,16 @@ set_sort_order(const char *form)
 static
 int parse_command_line(int argc, const char **argv, pack_opt_t* options)
 {
-    h5tools_fapl_info_t in_vol_info;
-    h5tools_fapl_info_t out_vol_info;
+    h5tools_vol_info_t in_vol_info;
+    h5tools_vol_info_t out_vol_info;
     hbool_t custom_in_fapl = FALSE;
     hbool_t custom_out_fapl = FALSE;
     hid_t tmp_fapl = H5I_INVALID_HID;
     int bound, opt;
     int ret_value = 0;
 
-    HDmemset(&in_vol_info, 0, sizeof(h5tools_fapl_info_t));
-    HDmemset(&out_vol_info, 0, sizeof(h5tools_fapl_info_t));
+    HDmemset(&in_vol_info, 0, sizeof(h5tools_vol_info_t));
+    HDmemset(&out_vol_info, 0, sizeof(h5tools_vol_info_t));
 
     /* parse command line options */
     while (EOF != (opt = get_option(argc, argv, s_opts, l_opts))) {
@@ -747,7 +747,7 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options)
 
     /* Setup FAPL for input and output file accesses */
     if (custom_in_fapl) {
-        if ((tmp_fapl = h5tools_get_fapl(options->fin_fapl, &in_vol_info)) < 0) {
+        if ((tmp_fapl = h5tools_get_fapl(options->fin_fapl, &in_vol_info, NULL)) < 0) {
             error_msg("failed to setup FAPL for input file\n");
             h5tools_setstatus(EXIT_FAILURE);
             ret_value = -1;
@@ -767,7 +767,7 @@ int parse_command_line(int argc, const char **argv, pack_opt_t* options)
     }
 
     if (custom_out_fapl) {
-        if ((tmp_fapl = h5tools_get_fapl(options->fout_fapl, &out_vol_info)) < 0) {
+        if ((tmp_fapl = h5tools_get_fapl(options->fout_fapl, &out_vol_info, NULL)) < 0) {
             error_msg("failed to setup FAPL for output file\n");
             h5tools_setstatus(EXIT_FAILURE);
             ret_value = -1;
diff --git a/tools/src/h5stat/h5stat.c b/tools/src/h5stat/h5stat.c
index bebe443..fb3d50d7 100644
--- a/tools/src/h5stat/h5stat.c
+++ b/tools/src/h5stat/h5stat.c
@@ -1813,16 +1813,14 @@ main(int argc, const char *argv[])
         goto done;
 
     if (drivername) {
-        h5tools_fapl_info_t fapl_info;
+        h5tools_vfd_info_t vfd_info;
 
-        /* Currently, only retrieval of VFDs is supported. */
-        fapl_info.type          = VFD_BY_NAME;
-        fapl_info.info_string   = NULL;
-        fapl_info.u.name        = drivername;
+        vfd_info.info       = NULL;
+        vfd_info.name       = drivername;
 
         if (!HDstrcmp(drivername, drivernames[ROS3_VFD_IDX])) {
 #ifdef H5_HAVE_ROS3_VFD
-            fapl_info.info_string = (void *)&ros3_fa;
+            vfd_info.info = (void *)&ros3_fa;
 #else
             error_msg("Read-Only S3 VFD not enabled.\n");
             goto done;
@@ -1830,14 +1828,14 @@ main(int argc, const char *argv[])
         }
         else if (!HDstrcmp(drivername, drivernames[HDFS_VFD_IDX])) {
 #ifdef H5_HAVE_LIBHDFS
-            fapl_info.info_string = (void *)&hdfs_fa;
+            vfd_info.info = (void *)&hdfs_fa;
 #else
             error_msg("HDFS VFD not enabled.\n");
             goto done;
 #endif
         }
 
-        if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, &fapl_info)) < 0) {
+        if ((fapl_id = h5tools_get_fapl(H5P_DEFAULT, NULL, &vfd_info)) < 0) {
             error_msg("Unable to create FAPL for file access\n");
             goto done;
         }
-- 
cgit v0.12