From dc42985674f560a9a76b886f56d6b8f5138b69ab Mon Sep 17 00:00:00 2001
From: Joseph Schuchart <schuchart@hlrs.de>
Date: Sat, 2 Jan 2021 22:55:19 +0100
Subject: [PATCH] Have opal_info_get return opal_cstring_t object

The key and info strings are now stored as opal_cstring_t objects so
returning them works by incrementing their reference count. The
caller is responsible for releasing the objects eventually. This avoids
many unnecessary string copy operations, which are now only required if
the string is to be modified (e.g., passed to strtok).

Signed-off-by: Joseph Schuchart <schuchart@icl.utk.edu>
---
 ompi/dpm/dpm.c                                | 286 +++++++-----
 ompi/info/info.c                              |  12 +-
 ompi/info/info.h                              |   6 +-
 ompi/mca/coll/base/coll_base_comm_select.c    |   7 +-
 ompi/mca/coll/han/coll_han_module.c           |   6 +-
 .../mca/common/ompio/common_ompio_file_open.c |   9 +-
 .../mca/common/ompio/common_ompio_file_view.c |  34 +-
 ompi/mca/fs/gpfs/fs_gpfs_file_set_info.c      |  67 +--
 ompi/mca/fs/lustre/fs_lustre_file_open.c      |  12 +-
 ompi/mca/fs/pvfs2/fs_pvfs2_file_open.c        |  12 +-
 .../mca/osc/portals4/osc_portals4_component.c |  55 +--
 .../sharedfp/individual/sharedfp_individual.c |   9 +-
 ompi/mpi/c/alloc_mem.c                        |  13 +-
 ompi/mpi/c/info_get.c                         |   9 +-
 ompi/mpi/c/info_get_nthkey.c                  |   8 +-
 ompi/mpi/c/lookup_name.c                      |   9 +-
 ompi/mpi/c/publish_name.c                     |  20 +-
 ompi/mpi/c/unpublish_name.c                   |   9 +-
 ompi/mpi/fortran/base/fortran_base_strings.h  |   2 +-
 ompi/mpi/fortran/base/strings.c               |   2 +-
 ompi/mpi/fortran/mpif-h/info_get_f.c          |  22 +-
 ompi/mpi/fortran/mpif-h/info_get_nthkey_f.c   |  17 +-
 opal/util/info.c                              | 416 ++++++++----------
 opal/util/info.h                              |  85 ++--
 opal/util/info_subscriber.c                   |  73 +--
 25 files changed, 609 insertions(+), 591 deletions(-)

diff --git a/ompi/dpm/dpm.c b/ompi/dpm/dpm.c
index 63d1e22000..c568316844 100644
--- a/ompi/dpm/dpm.c
+++ b/ompi/dpm/dpm.c
@@ -654,7 +654,7 @@ static dpm_conflicts_t bindto_modifiers[] = {
     {.name = ""}
 };
 
-static int check_modifiers(char *modifier, char **checks, dpm_conflicts_t *conflicts)
+static int check_modifiers(const char *modifier, char **checks, dpm_conflicts_t *conflicts)
 {
     int n, m, k;
 
@@ -674,10 +674,10 @@ static int check_modifiers(char *modifier, char **checks, dpm_conflicts_t *confl
 }
 
 static int dpm_convert(opal_list_t *infos,
-                       char *infokey,
-                       char *option,
-                       char *directive,
-                       char *modifier,
+                       const char *infokey,
+                       const char *option,
+                       const char *directive,
+                       const char *modifier,
                        bool deprecated)
 {
     opal_info_item_t *iptr;
@@ -745,6 +745,7 @@ static int dpm_convert(opal_list_t *infos,
                         /* we have a conflict */
                         opal_asprintf(&ptr, "  Option %s\n  Conflicting modifiers \"%s %s\"", option, infokey, modifier);
 #if PMIX_NUMERIC_VERSION >= 0x00040000
+                        /* TODO: this triggers a const warning :/ */
                         attr = PMIx_Get_attribute_string(option);
 #else
                         attr = option;
@@ -805,14 +806,7 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
     int rc, i, j;
     int have_wdir=0;
     int flag=0;
-    char cwd[OPAL_PATH_MAX];
-    char host[OPAL_MAX_INFO_VAL];  /*** should define OMPI_HOST_MAX ***/
-    char init_errh[OPAL_MAX_INFO_VAL];
-    char prefix[OPAL_MAX_INFO_VAL];
-    char stdin_target[OPAL_MAX_INFO_VAL];
-    char params[OPAL_MAX_INFO_VAL];
-    char mapper[OPAL_MAX_INFO_VAL];
-    char slot_list[OPAL_MAX_INFO_VAL];
+    opal_cstring_t *info_str;
     uint32_t ui32;
     bool personality = false;
     char *tmp;
@@ -908,33 +902,36 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
         if ( array_of_info != NULL && array_of_info[i] != MPI_INFO_NULL ) {
 
             /* check for personality - this is a job-level key */
-            ompi_info_get (array_of_info[i], "personality", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "personality", &info_str, &flag);
             if ( flag ) {
                 /* deprecate --> PMIX_PERSONALITY */
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "personality", "PMIX_PERSONALITY");
                 personality = true;
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PERSONALITY, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PERSONALITY, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_PERSONALITY", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_PERSONALITY", &info_str, &flag);
             if ( flag ) {
                 personality = true;
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PERSONALITY, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PERSONALITY, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_PERSONALITY");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 personality = true;
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PERSONALITY, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PERSONALITY, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
@@ -943,68 +940,75 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
              * MPI standard ch. 10.3.4 */
 
             /* check for 'host' */
-            ompi_info_get (array_of_info[i], "host", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "host", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_HOST, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_HOST, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
-                opal_argv_append_nosize(&dash_host, host);
+                opal_argv_append_nosize(&dash_host, info_str->string);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_HOST", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_HOST", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_HOST, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_HOST, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
-                opal_argv_append_nosize(&dash_host, host);
+                opal_argv_append_nosize(&dash_host, info_str->string);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_HOST");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_HOST, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_HOST, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
-                opal_argv_append_nosize(&dash_host, host);
+                opal_argv_append_nosize(&dash_host, info_str->string);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
 
             /* check for 'wdir' */
-            ompi_info_get (array_of_info[i], "wdir", sizeof(cwd) - 1, cwd, &flag);
+            ompi_info_get (array_of_info[i], "wdir", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_WDIR, cwd, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_WDIR, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 have_wdir = 1;
             }
-            ompi_info_get (array_of_info[i], "PMIX_WDIR", sizeof(cwd) - 1, cwd, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_WDIR", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_WDIR, cwd, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_WDIR, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 have_wdir = 1;
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_WDIR");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(cwd) - 1, cwd, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_WDIR, cwd, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_WDIR, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 have_wdir = 1;
                 continue;
             }
 #endif
 
             /* check for 'mpi_initial_errhandler' */
-            ompi_info_get (array_of_info[i], "mpi_initial_errhandler", sizeof(init_errh) - 1, init_errh, &flag);
+            ompi_info_get (array_of_info[i], "mpi_initial_errhandler", &info_str, &flag);
             if ( flag ) {
                 /* this is set as an environment because it must be available
                  * before pmix_init */
-                opal_setenv("OMPI_MCA_mpi_initial_errhandler", init_errh, true, &app->env);
+                opal_setenv("OMPI_MCA_mpi_initial_errhandler", info_str->string, true, &app->env);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 
@@ -1018,108 +1022,119 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
              * deprecated in the non-prefixed form */
 
             /* check for 'hostfile' */
-            ompi_info_get (array_of_info[i], "hostfile", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "hostfile", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_HOSTFILE, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_HOSTFILE, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
-                opal_argv_append_nosize(&hostfiles, host);
+                opal_argv_append_nosize(&hostfiles, info_str->string);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_HOSTFILE", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_HOSTFILE", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_HOSTFILE, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_HOSTFILE, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
-                opal_argv_append_nosize(&hostfiles, host);
+                opal_argv_append_nosize(&hostfiles, info_str->string);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_HOSTFILE");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_HOSTFILE, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_HOSTFILE, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
-                opal_argv_append_nosize(&hostfiles, host);
+                opal_argv_append_nosize(&hostfiles, info_str->string);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
 
             /* check for 'add-hostfile' */
-            ompi_info_get (array_of_info[i], "add-hostfile", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "add-hostfile", &info_str, &flag);
             if ( flag ) {
                 /* deprecate --> PMIX_ADD_HOSTFILE */
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "add-hostfile", "PMIX_ADD_HOSTFILE");
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOSTFILE, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOSTFILE, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_ADD_HOSTFILE", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_ADD_HOSTFILE", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOSTFILE, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOSTFILE, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_ADD_HOSTFILE");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOSTFILE, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOSTFILE, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
 
             /* check for 'add-host' */
-            ompi_info_get (array_of_info[i], "add-host", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "add-host", &info_str, &flag);
             if ( flag ) {
                 /* deprecate --> PMIX_ADD_HOST */
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "add-host", "PMIX_ADD_HOST");
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOST, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOST, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_ADD_HOST", sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_ADD_HOST", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOST, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOST, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_ADD_HOST");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(host) - 1, host, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOST, host, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_ADD_HOST, info_str->string, PMIX_STRING);
                 opal_list_append(&app_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
 
             /* check for env */
-            ompi_info_get (array_of_info[i], "env", sizeof(host)-1, host, &flag);
+            ompi_info_get (array_of_info[i], "env", &info_str, &flag);
             if ( flag ) {
                 /* deprecate --> PMIX_ENVAR */
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "env", "PMIX_ENVAR");
-                envars = opal_argv_split(host, '\n');
+                envars = opal_argv_split(info_str->string, '\n');
+                OBJ_RELEASE(info_str);
                 for (j=0; NULL != envars[j]; j++) {
                     opal_argv_append_nosize(&app->env, envars[j]);
                 }
                 opal_argv_free(envars);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_ENVAR", sizeof(host)-1, host, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_ENVAR", &info_str, &flag);
             if ( flag ) {
-                envars = opal_argv_split(host, '\n');
+                envars = opal_argv_split(info_str->string, '\n');
+                OBJ_RELEASE(info_str);
                 for (j=0; NULL != envars[j]; j++) {
                     opal_argv_append_nosize(&app->env, envars[j]);
                 }
@@ -1128,9 +1143,10 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_ENVAR");
-            ompi_info_get (array_of_info[i], "PMIX_ENVAR", sizeof(host)-1, host, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_ENVAR", &info_str, &flag);
             if ( flag ) {
-                envars = opal_argv_split(host, '\n');
+                envars = opal_argv_split(info_str->string, '\n');
+                OBJ_RELEASE(info_str);
                 for (j=0; NULL != envars[j]; j++) {
                     opal_argv_append_nosize(&app->env, envars[j]);
                 }
@@ -1144,59 +1160,65 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
              *
              * This is a job-level key
              */
-            ompi_info_get (array_of_info[i], "ompi_prefix", sizeof(prefix) - 1, prefix, &flag);
+            ompi_info_get (array_of_info[i], "ompi_prefix", &info_str, &flag);
             if ( flag ) {
                 /* deprecate --> PMIX_PREFIX */
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "ompi_prefix", "PMIX_PREFIX");
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PREFIX, prefix, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PREFIX, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_PREFIX", sizeof(prefix) - 1, prefix, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_PREFIX", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PREFIX, prefix, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PREFIX, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_PREFIX");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(prefix) - 1, prefix, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PREFIX, prefix, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PREFIX, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
 
             /* check for 'mapper' - a job-level key */
-            ompi_info_get(array_of_info[i], "mapper", sizeof(mapper) - 1, mapper, &flag);
+            ompi_info_get(array_of_info[i], "mapper", &info_str, &flag);
             if ( flag ) {
                 /* deprecate --> PMIX_MAPPER */
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "mapper", "PMIX_MAPPER");
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_MAPPER, mapper, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_MAPPER, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get(array_of_info[i], "PMIX_MAPPER", sizeof(mapper) - 1, mapper, &flag);
+            ompi_info_get(array_of_info[i], "PMIX_MAPPER", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_MAPPER, mapper, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_MAPPER, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_MAPPER");
-            ompi_info_get(array_of_info[i], checkkey, sizeof(mapper) - 1, mapper, &flag);
+            ompi_info_get(array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_MAPPER, mapper, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_MAPPER, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
@@ -1222,11 +1244,12 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
             }
 
             /* check for 'npernode' and 'ppr' - job-level key */
-            ompi_info_get (array_of_info[i], "npernode", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get (array_of_info[i], "npernode", &info_str, &flag);
             if ( flag ) {
-                opal_asprintf(&tmp, "PPR:%s:NODE", slot_list);
+                opal_asprintf(&tmp, "PPR:%s:NODE", info_str->string);
                 rc = dpm_convert(&job_info, "npernode", PMIX_MAPBY, tmp, NULL, true);
                 free(tmp);
+                OBJ_RELEASE(info_str);
                 if (OMPI_SUCCESS != rc) {
                     OPAL_LIST_DESTRUCT(&job_info);
                     OPAL_LIST_DESTRUCT(&app_info);
@@ -1242,10 +1265,11 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
                 }
                 continue;
             }
-            ompi_info_get (array_of_info[i], "pernode", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get (array_of_info[i], "pernode", &info_str, &flag);
             if ( flag ) {
                 rc = dpm_convert(&job_info, "pernode", PMIX_MAPBY, "PPR:1:NODE", NULL, true);
                 free(tmp);
+                OBJ_RELEASE(info_str);
                 if (OMPI_SUCCESS != rc) {
                     OPAL_LIST_DESTRUCT(&job_info);
                     OPAL_LIST_DESTRUCT(&app_info);
@@ -1261,11 +1285,11 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
                 }
                 continue;
             }
-            ompi_info_get (array_of_info[i], "ppr", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get (array_of_info[i], "ppr", &info_str, &flag);
             if ( flag ) {
                 /* must have correct syntax with two colons */
-                if (NULL == (tmp = strchr(slot_list, ':'))) {
-                    opal_show_help("help-dpm.txt", "bad-ppr", true, slot_list);
+                if (NULL == (tmp = strchr(info_str->string, ':'))) {
+                    opal_show_help("help-dpm.txt", "bad-ppr", true, info_str->string);
                     OPAL_LIST_DESTRUCT(&job_info);
                     OPAL_LIST_DESTRUCT(&app_info);
                     PMIX_APP_FREE(apps, scount);
@@ -1276,11 +1300,12 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
                     if (NULL != dash_host) {
                         opal_argv_free(dash_host);
                     }
+                    OBJ_RELEASE(info_str);
                     return MPI_ERR_SPAWN;
                 }
                 ++tmp; // step over first colon
                 if (NULL == strchr(tmp, ':')) {
-                    opal_show_help("help-dpm.txt", "bad-ppr", true, slot_list);
+                    opal_show_help("help-dpm.txt", "bad-ppr", true, info_str->string);
                     OPAL_LIST_DESTRUCT(&job_info);
                     OPAL_LIST_DESTRUCT(&app_info);
                     PMIX_APP_FREE(apps, scount);
@@ -1291,10 +1316,12 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
                     if (NULL != dash_host) {
                         opal_argv_free(dash_host);
                     }
+                    OBJ_RELEASE(info_str);
                     return MPI_ERR_SPAWN;
                 }
-                rc = dpm_convert(&job_info, "ppr", PMIX_MAPBY, slot_list, NULL, true);
+                rc = dpm_convert(&job_info, "ppr", PMIX_MAPBY, info_str->string, NULL, true);
                 free(tmp);
+                OBJ_RELEASE(info_str);
                 if (OMPI_SUCCESS != rc) {
                     OPAL_LIST_DESTRUCT(&job_info);
                     OPAL_LIST_DESTRUCT(&app_info);
@@ -1312,10 +1339,11 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
             }
 
             /* check for 'map_by' - job-level key */
-            ompi_info_get(array_of_info[i], "map_by", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], "map_by", &info_str, &flag);
             if ( flag ) {
-                rc = dpm_convert(&job_info, "map_by", PMIX_MAPBY, slot_list, NULL, false);
+                rc = dpm_convert(&job_info, "map_by", PMIX_MAPBY, info_str->string, NULL, false);
                 free(tmp);
+                OBJ_RELEASE(info_str);
                 if (OMPI_SUCCESS != rc) {
                     OPAL_LIST_DESTRUCT(&job_info);
                     OPAL_LIST_DESTRUCT(&app_info);
@@ -1331,29 +1359,32 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
                 }
                 continue;
             }
-            ompi_info_get(array_of_info[i], "PMIX_MAPBY", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], "PMIX_MAPBY", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_MAPBY, slot_list, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_MAPBY, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_MAPBY");
-            ompi_info_get(array_of_info[i], checkkey, sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_MAPBY, slot_list, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_MAPBY, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
 
             /* check for 'rank_by' - job-level key */
-            ompi_info_get(array_of_info[i], "rank_by", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], "rank_by", &info_str, &flag);
             if ( flag ) {
-                rc = dpm_convert(&job_info, "rank_by", PMIX_RANKBY, slot_list, NULL, false);
+                rc = dpm_convert(&job_info, "rank_by", PMIX_RANKBY, info_str->string, NULL, false);
                 free(tmp);
+                OBJ_RELEASE(info_str);
                 if (OMPI_SUCCESS != rc) {
                     OPAL_LIST_DESTRUCT(&job_info);
                     OPAL_LIST_DESTRUCT(&app_info);
@@ -1363,29 +1394,32 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
                 }
                 continue;
             }
-            ompi_info_get(array_of_info[i], "PMIX_RANKBY", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], "PMIX_RANKBY", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_RANKBY, slot_list, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_RANKBY, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_RANKBY");
-            ompi_info_get(array_of_info[i], checkkey, sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_RANKBY, slot_list, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_RANKBY, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
 
             /* check for 'bind_to' - job-level key */
-            ompi_info_get(array_of_info[i], "bind_to", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], "bind_to", &info_str, &flag);
             if ( flag ) {
-                rc = dpm_convert(&job_info, "bind_to", PMIX_BINDTO, slot_list, NULL, false);
+                rc = dpm_convert(&job_info, "bind_to", PMIX_BINDTO, info_str->string, NULL, false);
                 free(tmp);
+                OBJ_RELEASE(info_str);
                 if (OMPI_SUCCESS != rc) {
                     OPAL_LIST_DESTRUCT(&job_info);
                     OPAL_LIST_DESTRUCT(&app_info);
@@ -1395,20 +1429,22 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
                 }
                 continue;
             }
-            ompi_info_get(array_of_info[i], "PMIX_BINDTO", sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], "PMIX_BINDTO", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_BINDTO, slot_list, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_BINDTO, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_BINDTO");
-            ompi_info_get(array_of_info[i], checkkey, sizeof(slot_list) - 1, slot_list, &flag);
+            ompi_info_get(array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_BINDTO, slot_list, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_BINDTO, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
@@ -1443,30 +1479,33 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
 #endif
 
             /* check for 'preload_files' - job-level key */
-            ompi_info_get (array_of_info[i], "ompi_preload_files", sizeof(cwd) - 1, cwd, &flag);
+            ompi_info_get (array_of_info[i], "ompi_preload_files", &info_str, &flag);
             if ( flag ) {
                 /* deprecate --> PMIX_PRELOAD_FILES */
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "ompi_preload_files", "PMIX_PRELOAD_FILES");
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PRELOAD_FILES, cwd, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PRELOAD_FILES, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_PRELOAD_FILES", sizeof(cwd) - 1, cwd, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_PRELOAD_FILES", &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PRELOAD_FILES, cwd, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PRELOAD_FILES, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_PRELOAD_FILES");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(cwd) - 1, cwd, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
                 info = OBJ_NEW(opal_info_item_t);
-                PMIX_INFO_LOAD(&info->info, PMIX_PRELOAD_FILES, cwd, PMIX_STRING);
+                PMIX_INFO_LOAD(&info->info, PMIX_PRELOAD_FILES, info_str->string, PMIX_STRING);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
@@ -1482,61 +1521,65 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
             }
 
             /* see if this is an MCA param that the user wants applied to the child job */
-            ompi_info_get (array_of_info[i], "ompi_param", sizeof(params) - 1, params, &flag);
+            ompi_info_get (array_of_info[i], "ompi_param", &info_str, &flag);
             if ( flag ) {
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "ompi_param", "PMIX_ENVAR");
-                opal_argv_append_unique_nosize(&app->env, params, true);
+                opal_argv_append_unique_nosize(&app->env, info_str->string, true);
+                OBJ_RELEASE(info_str);
             }
 
             /* see if user specified what to do with stdin - defaults to
              * not forwarding stdin to child processes - job-level key
              */
-            ompi_info_get (array_of_info[i], "ompi_stdin_target", sizeof(stdin_target) - 1, stdin_target, &flag);
+            ompi_info_get (array_of_info[i], "ompi_stdin_target", &info_str, &flag);
             if ( flag ) {
                 /* deprecate --> PMIX_STDIN_TGT */
                 opal_show_help("help-dpm.txt", "deprecated-converted", true,
                                 "ompi_stdin_target", "PMIX_STDIN_TGT");
-                if (0 == strcmp(stdin_target, "all")) {
+                if (0 == strcmp(info_str->string, "all")) {
                     ui32 = OPAL_VPID_WILDCARD;
-                } else if (0 == strcmp(stdin_target, "none")) {
+                } else if (0 == strcmp(info_str->string, "none")) {
                     ui32 = OPAL_VPID_INVALID;
                 } else {
-                    ui32 = strtoul(stdin_target, NULL, 10);
+                    ui32 = strtoul(info_str->string, NULL, 10);
                 }
                 info = OBJ_NEW(opal_info_item_t);
                 PMIX_INFO_LOAD(&info->info, PMIX_STDIN_TGT, &ui32, PMIX_UINT32);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
-            ompi_info_get (array_of_info[i], "PMIX_STDIN_TGT", sizeof(stdin_target) - 1, stdin_target, &flag);
+            ompi_info_get (array_of_info[i], "PMIX_STDIN_TGT", &info_str, &flag);
             if ( flag ) {
-                if (0 == strcmp(stdin_target, "all")) {
+                if (0 == strcmp(info_str->string, "all")) {
                     ui32 = OPAL_VPID_WILDCARD;
-                } else if (0 == strcmp(stdin_target, "none")) {
+                } else if (0 == strcmp(info_str->string, "none")) {
                     ui32 = OPAL_VPID_INVALID;
                 } else {
-                    ui32 = strtoul(stdin_target, NULL, 10);
+                    ui32 = strtoul(info_str->string, NULL, 10);
                 }
                 info = OBJ_NEW(opal_info_item_t);
                 PMIX_INFO_LOAD(&info->info, PMIX_STDIN_TGT, &ui32, PMIX_UINT32);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #if PMIX_NUMERIC_VERSION >= 0x00040000
             checkkey = PMIx_Get_attribute_string("PMIX_STDIN_TGT");
-            ompi_info_get (array_of_info[i], checkkey, sizeof(stdin_target) - 1, stdin_target, &flag);
+            ompi_info_get (array_of_info[i], checkkey, &info_str, &flag);
             if ( flag ) {
-                if (0 == strcmp(stdin_target, "all")) {
+                if (0 == strcmp(info_str->string, "all")) {
                     ui32 = OPAL_VPID_WILDCARD;
-                } else if (0 == strcmp(stdin_target, "none")) {
+                } else if (0 == strcmp(info_str->string, "none")) {
                     ui32 = OPAL_VPID_INVALID;
                 } else {
-                    ui32 = strtoul(stdin_target, NULL, 10);
+                    ui32 = strtoul(info_str->string, NULL, 10);
                 }
                 info = OBJ_NEW(opal_info_item_t);
                 PMIX_INFO_LOAD(&info->info, PMIX_STDIN_TGT, &ui32, PMIX_UINT32);
                 opal_list_append(&job_info, &info->super);
+                OBJ_RELEASE(info_str);
                 continue;
             }
 #endif
@@ -1546,6 +1589,7 @@ int ompi_dpm_spawn(int count, const char *array_of_commands[],
          * executable, we assume the current working directory
          */
         if ( !have_wdir ) {
+            char cwd[OPAL_PATH_MAX];
             if (OMPI_SUCCESS != (rc = opal_getcwd(cwd, OPAL_PATH_MAX))) {
                 OMPI_ERROR_LOG(rc);
                 PMIX_APP_FREE(apps, (size_t)count);
diff --git a/ompi/info/info.c b/ompi/info/info.c
index ba51bdc2d3..6785fde5df 100644
--- a/ompi/info/info.c
+++ b/ompi/info/info.c
@@ -224,10 +224,10 @@ int ompi_info_set_value_enum (ompi_info_t *info, const char *key, int value,
 {
     return opal_info_set_value_enum (&(info->super), key, value, var_enum);
 }
-int ompi_info_get (ompi_info_t *info, const char *key, int valuelen,
-                   char *value, int *flag)
+int ompi_info_get (ompi_info_t *info, const char *key,
+                   opal_cstring_t **value, int *flag)
 {
-    return opal_info_get (&(info->super), key, valuelen, value, flag);
+    return opal_info_get (&(info->super), key, value, flag);
 }
 int ompi_info_get_value_enum (ompi_info_t *info, const char *key, int *value,
                               int default_value, mca_base_var_enum_t *var_enum,
@@ -247,7 +247,7 @@ int ompi_info_get_valuelen (ompi_info_t *info, const char *key, int *valuelen,
 {
     return opal_info_get_valuelen (&(info->super), key, valuelen, flag);
 }
-int ompi_info_get_nthkey (ompi_info_t *info, int n, char *key) {
+int ompi_info_get_nthkey (ompi_info_t *info, int n, opal_cstring_t **key) {
     return opal_info_get_nthkey (&(info->super), n, key);
 }
 int ompi_info_get_nkeys(ompi_info_t *info, int *nkeys)
@@ -304,8 +304,8 @@ int ompi_mpiinfo_finalize(void)
                          item = opal_list_get_next(item)) {
                         entry = (opal_info_entry_t *) item;
                         opal_output(0, "WARNING:   key=\"%s\", value=\"%s\"",
-                                    entry->ie_key,
-                                    NULL != entry->ie_value ? entry->ie_value : "(null)");
+                                    entry->ie_key->string,
+                                    NULL != entry->ie_value ? entry->ie_value->string : "(null)");
                         found = true;
                     }
                 }
diff --git a/ompi/info/info.h b/ompi/info/info.h
index 8b5a861de8..4fffe6df14 100644
--- a/ompi/info/info.h
+++ b/ompi/info/info.h
@@ -130,8 +130,8 @@ OMPI_DECLSPEC int ompi_info_get_value_enum (ompi_info_t *info, const char *key,
 /**
  * ompi_info_foo() wrapper around various opal_info_foo() calls
  */
-OMPI_DECLSPEC int ompi_info_get (ompi_info_t *info, const char *key, int valuelen,
-                                 char *value, int *flag);
+OMPI_DECLSPEC int ompi_info_get (ompi_info_t *info, const char *key,
+                                 opal_cstring_t **value, int *flag);
 /**
  * ompi_info_foo() wrapper around various opal_info_foo() calls
  */
@@ -144,7 +144,7 @@ OMPI_DECLSPEC int ompi_info_get_valuelen (ompi_info_t *info, const char *key, in
 /**
  * ompi_info_foo() wrapper around various opal_info_foo() calls
  */
-OMPI_DECLSPEC int ompi_info_get_nthkey (ompi_info_t *info, int n, char *key);
+OMPI_DECLSPEC int ompi_info_get_nthkey (ompi_info_t *info, int n, opal_cstring_t **key);
 /**
  * ompi_info_foo() wrapper around various opal_info_foo() calls
  */
diff --git a/ompi/mca/coll/base/coll_base_comm_select.c b/ompi/mca/coll/base/coll_base_comm_select.c
index c8932bf4d5..fcdb8649eb 100644
--- a/ompi/mca/coll/base/coll_base_comm_select.c
+++ b/ompi/mca/coll/base/coll_base_comm_select.c
@@ -348,7 +348,6 @@ static opal_list_t *check_components(opal_list_t * components,
     mca_coll_base_module_t *module;
     opal_list_t *selectable;
     mca_coll_base_avail_coll_t *avail;
-    char info_val[OPAL_MAX_INFO_VAL+1];
     char **coll_argv = NULL, **coll_exclude = NULL, **coll_include = NULL;
 
     /* Check if this communicator comes with restrictions on the collective modules
@@ -360,12 +359,14 @@ static opal_list_t *check_components(opal_list_t * components,
      * force a change in the component priority.
      */
     if( NULL != comm->super.s_info) {
+        opal_cstring_t *info_str;
         opal_info_get(comm->super.s_info, "ompi_comm_coll_preference",
-                      sizeof(info_val), info_val, &flag);
+                      &info_str, &flag);
         if( !flag ) {
             goto proceed_to_select;
         }
-        coll_argv = opal_argv_split(info_val, ',');
+        coll_argv = opal_argv_split(info_str->string, ',');
+        OBJ_RELEASE(info_str);
         if(NULL == coll_argv) {
             goto proceed_to_select;
         }
diff --git a/ompi/mca/coll/han/coll_han_module.c b/ompi/mca/coll/han/coll_han_module.c
index f926e4de1a..99b02e1869 100644
--- a/ompi/mca/coll/han/coll_han_module.c
+++ b/ompi/mca/coll/han/coll_han_module.c
@@ -225,15 +225,17 @@ mca_coll_han_comm_query(struct ompi_communicator_t * comm, int *priority)
         char info_val[OPAL_MAX_INFO_VAL+1];
 
         /* Get the info value disaqualifying coll components */
+        opal_cstring_t *info_str;
         opal_info_get(comm->super.s_info, "ompi_comm_coll_han_topo_level",
-                      sizeof(info_val), info_val, &flag);
+                      &info_str, &flag);
 
         if (flag) {
-            if (0 == strcmp(info_val, "INTER_NODE")) {
+            if (0 == strcmp(info_str->string, "INTER_NODE")) {
                 han_module->topologic_level = INTER_NODE;
             } else {
                 han_module->topologic_level = INTRA_NODE;
             }
+            OBJ_RELEASE(info_str);
         }
     }
 
diff --git a/ompi/mca/common/ompio/common_ompio_file_open.c b/ompi/mca/common/ompio/common_ompio_file_open.c
index 778bd0365f..b2d27d148e 100644
--- a/ompi/mca/common/ompio/common_ompio_file_open.c
+++ b/ompi/mca/common/ompio/common_ompio_file_open.c
@@ -415,7 +415,7 @@ int mca_common_ompio_set_file_defaults (ompio_file_t *fh)
 {
 
    if (NULL != fh) {
-       char char_stripe[MPI_MAX_INFO_VAL];
+       opal_cstring_t *stripe_str;
        ompi_datatype_t *types[2];
        int blocklen[2] = {1, 1};
        ptrdiff_t d[2], base;
@@ -426,11 +426,12 @@ int mca_common_ompio_set_file_defaults (ompio_file_t *fh)
        fh->f_flags = 0;
        
        fh->f_bytes_per_agg = OMPIO_MCA_GET(fh, bytes_per_agg);
-       opal_info_get (fh->f_info, "cb_buffer_size", MPI_MAX_INFO_VAL, char_stripe, &flag);
+       opal_info_get (fh->f_info, "cb_buffer_size", &stripe_str, &flag);
        if ( flag ) {
            /* Info object trumps mca parameter value */
-           sscanf ( char_stripe, "%d", &fh->f_bytes_per_agg  );
-           OMPIO_MCA_PRINT_INFO(fh, "cb_buffer_size", char_stripe, "");
+           sscanf ( stripe_str->string, "%d", &fh->f_bytes_per_agg  );
+           OMPIO_MCA_PRINT_INFO(fh, "cb_buffer_size", stripe_str->string, "");
+           OBJ_RELEASE(stripe_str);
        }
 
        fh->f_atomicity = 0;
diff --git a/ompi/mca/common/ompio/common_ompio_file_view.c b/ompi/mca/common/ompio/common_ompio_file_view.c
index a1800192e9..c32b50347a 100644
--- a/ompi/mca/common/ompio/common_ompio_file_view.c
+++ b/ompi/mca/common/ompio/common_ompio_file_view.c
@@ -220,19 +220,21 @@ int mca_common_ompio_set_view (ompio_file_t *fh,
        }
     }
 
-    char char_stripe[MPI_MAX_INFO_VAL];
+    opal_cstring_t *stripe_str;
     /* Check the info object set during File_open */
-    opal_info_get (fh->f_info, "cb_nodes", MPI_MAX_INFO_VAL, char_stripe, &flag);
+    opal_info_get (fh->f_info, "cb_nodes", &stripe_str, &flag);
     if ( flag ) {
-        sscanf ( char_stripe, "%d", &num_cb_nodes );
-        OMPIO_MCA_PRINT_INFO(fh, "cb_nodes", char_stripe, "");
+        sscanf ( stripe_str->string, "%d", &num_cb_nodes );
+        OMPIO_MCA_PRINT_INFO(fh, "cb_nodes", stripe_str->string, "");
+        OBJ_RELEASE(stripe_str);
     }
     else {
         /* Check the info object set during file_set_view */
-        opal_info_get (info, "cb_nodes", MPI_MAX_INFO_VAL, char_stripe, &flag);
+        opal_info_get (info, "cb_nodes", &stripe_str, &flag);
         if ( flag ) {
-            sscanf ( char_stripe, "%d", &num_cb_nodes );
-            OMPIO_MCA_PRINT_INFO(fh, "cb_nodes", char_stripe, "");
+            sscanf ( stripe_str->string, "%d", &num_cb_nodes );
+            OMPIO_MCA_PRINT_INFO(fh, "cb_nodes", stripe_str->string, "");
+            OBJ_RELEASE(stripe_str);
         }
     }
         
@@ -323,23 +325,25 @@ int mca_common_ompio_set_view (ompio_file_t *fh,
     }
 
     bool info_is_set=false;
-    opal_info_get (fh->f_info, "collective_buffering", MPI_MAX_INFO_VAL, char_stripe, &flag);
+    opal_info_get (fh->f_info, "collective_buffering", &stripe_str, &flag);
     if ( flag ) {
-        if ( strncmp ( char_stripe, "false", sizeof("true") )){
+        if ( strncmp ( stripe_str->string, "false", sizeof("true") )){
             info_is_set = true;
-            OMPIO_MCA_PRINT_INFO(fh, "collective_buffering", char_stripe, "enforcing using individual fcoll component");
+            OMPIO_MCA_PRINT_INFO(fh, "collective_buffering", stripe_str->string, "enforcing using individual fcoll component");
         } else {
-            OMPIO_MCA_PRINT_INFO(fh, "collective_buffering", char_stripe, "");
+            OMPIO_MCA_PRINT_INFO(fh, "collective_buffering", stripe_str->string, "");
         }
+        OBJ_RELEASE(stripe_str);
     } else {
-        opal_info_get (info, "collective_buffering", MPI_MAX_INFO_VAL, char_stripe, &flag);
+        opal_info_get (info, "collective_buffering", &stripe_str, &flag);
         if ( flag ) {
-            if ( strncmp ( char_stripe, "false", sizeof("true") )){
+            if ( strncmp ( stripe_str->string, "false", sizeof("true") )){
                 info_is_set = true;
-                OMPIO_MCA_PRINT_INFO(fh, "collective_buffering", char_stripe, "enforcing using individual fcoll component");
+                OMPIO_MCA_PRINT_INFO(fh, "collective_buffering", stripe_str->string, "enforcing using individual fcoll component");
             } else {
-                OMPIO_MCA_PRINT_INFO(fh, "collective_buffering", char_stripe, "");
+                OMPIO_MCA_PRINT_INFO(fh, "collective_buffering", stripe_str->string, "");
             }
+            OBJ_RELEASE(stripe_str);
         }
     }
 
diff --git a/ompi/mca/fs/gpfs/fs_gpfs_file_set_info.c b/ompi/mca/fs/gpfs/fs_gpfs_file_set_info.c
index f9e04fdc8c..04c74ffa6d 100644
--- a/ompi/mca/fs/gpfs/fs_gpfs_file_set_info.c
+++ b/ompi/mca/fs/gpfs/fs_gpfs_file_set_info.c
@@ -44,9 +44,9 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
 {
     int rc = 0;
     int flag;
-    int valueLen = MPI_MAX_INFO_VAL;
-    char value[MPI_MAX_INFO_VAL + 1];
+    opal_cstring_t *info_str;
     char gpfsHintsKey[50];
+    bool info_bool;
     const char* split = ",";
     char* token;
     int ret = OMPI_SUCCESS;
@@ -163,9 +163,9 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
     */
 
     strcpy(gpfsHintsKey, "useSIOXLib");
-    ompi_info_get(info_selected, gpfsHintsKey, valueLen, value, &flag);
+    ompi_info_get_bool(info_selected, gpfsHintsKey, &info_bool, &flag);
     if (flag) {
-        if(strcmp(value, "true") == 0) {
+        if(info_bool) {
             //using the SIOX lib and the I/O pattern selection
             ret = mca_fs_gpfs_io_selection(fh, info, info_selected);
             if (ret != OMPI_SUCCESS)
@@ -179,10 +179,10 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
 
     //Setting GPFS Hint - gpfsAccessRange
     strcpy(gpfsHintsKey, "gpfsAccessRange");
-    ompi_info_get(info_selected, gpfsHintsKey, valueLen, value, &flag);
+    ompi_info_get(info_selected, gpfsHintsKey, &info_str, &flag);
     if (flag) {
         opal_output(ompi_fs_base_framework.framework_output,
-                    "GPFS Access Range is set: %s: %s\n", gpfsHintsKey, value);
+                    "GPFS Access Range is set: %s: %s\n", gpfsHintsKey, info_str->string);
         gpfs_hint_AccessRange.gpfsFcntlHeader.totalLength = sizeof(gpfs_hint_AccessRange);
         gpfs_hint_AccessRange.gpfsFcntlHeader.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
         gpfs_hint_AccessRange.gpfsFcntlHeader.fcntlReserved = 0;
@@ -190,12 +190,15 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
         gpfs_hint_AccessRange.gpfsAccessRange.structLen =
                 sizeof(gpfs_hint_AccessRange.gpfsAccessRange);
         gpfs_hint_AccessRange.gpfsAccessRange.structType = GPFS_ACCESS_RANGE;
-        token = strtok(value, split);
+        char *info_str_dup = strdup(info_str->string);
+        OBJ_RELEASE(info_str);
+        token = strtok(info_str_dup, split);
         gpfs_hint_AccessRange.gpfsAccessRange.start = atol(token);
         token = strtok(NULL, split);
         gpfs_hint_AccessRange.gpfsAccessRange.length = atol(token);
         token = strtok(NULL, split);
         gpfs_hint_AccessRange.gpfsAccessRange.isWrite = atoi(token);
+        free(info_str_dup);
 
         rc = gpfs_fcntl(gpfs_file_handle, &gpfs_hint_AccessRange);
         if (rc != 0) {
@@ -209,10 +212,10 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
 
     //Setting GPFS Hint - gpfsFreeRange
     strcpy(gpfsHintsKey, "gpfsFreeRange");
-    ompi_info_get(info_selected, gpfsHintsKey, valueLen, value, &flag);
+    ompi_info_get(info_selected, gpfsHintsKey, &info_str, &flag);
     if (flag) {
         opal_output(ompi_fs_base_framework.framework_output,
-                    "GPFS Free Range is set: %s: %s\n", gpfsHintsKey, value);
+                    "GPFS Free Range is set: %s: %s\n", gpfsHintsKey, info_str->string);
         gpfs_hint_FreeRange.gpfsFcntlHeader.totalLength = sizeof(gpfs_hint_FreeRange);
         gpfs_hint_FreeRange.gpfsFcntlHeader.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
         gpfs_hint_FreeRange.gpfsFcntlHeader.fcntlReserved = 0;
@@ -220,10 +223,13 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
         gpfs_hint_FreeRange.gpfsFreeRange.structLen =
                 sizeof(gpfs_hint_FreeRange.gpfsFreeRange);
         gpfs_hint_FreeRange.gpfsFreeRange.structType = GPFS_FREE_RANGE;
-        token = strtok(value, split);
+        char *info_str_dup = strdup(info_str->string);
+        OBJ_RELEASE(info_str);
+        token = strtok(info_str_dup, split);
         gpfs_hint_FreeRange.gpfsFreeRange.start = atol(token);
         token = strtok(NULL, split);
         gpfs_hint_FreeRange.gpfsFreeRange.length = atol(token);
+        free(info_str_dup);
 
         rc = gpfs_fcntl(gpfs_file_handle, &gpfs_hint_FreeRange);
         if (rc != 0) {
@@ -241,10 +247,10 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
 
     //Setting GPFS Hint - gpfsClearFileCache
     strcpy(gpfsHintsKey, "gpfsClearFileCache");
-    ompi_info_get(info_selected, gpfsHintsKey, valueLen, value, &flag);
-    if (flag & (strcmp(value, "true") == 0)) {
+    ompi_info_get_bool(info_selected, gpfsHintsKey, &info_bool, &flag);
+    if (flag && info_bool) {
         opal_output(ompi_fs_base_framework.framework_output,
-                    "GPFS Clear File Cache is set: %s: %s\n", gpfsHintsKey, value);
+                    "GPFS Clear File Cache is set: %s\n", gpfsHintsKey);
         gpfs_hint_ClearFileCache.gpfsFcntlHeader.totalLength = sizeof(gpfs_hint_ClearFileCache);
         gpfs_hint_ClearFileCache.gpfsFcntlHeader.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
         gpfs_hint_ClearFileCache.gpfsFcntlHeader.fcntlReserved = 0;
@@ -265,10 +271,10 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
 
     //Setting GPFS Hint - gpfsCancelHints
     strcpy(gpfsHintsKey, "gpfsCancelHints");
-    ompi_info_get(info_selected, gpfsHintsKey, valueLen, value, &flag);
-    if (flag & (strcmp(value, "true") == 0)) {
+    ompi_info_get_bool(info_selected, gpfsHintsKey, &info_bool, &flag);
+    if (flag && info_bool) {
         opal_output(ompi_fs_base_framework.framework_output,
-                    "GPFS Cancel Hints is set: %s: %s\n", gpfsHintsKey, value);
+                    "GPFS Cancel Hints is set: %s\n", gpfsHintsKey);
         gpfs_hint_CancelHints.gpfsFcntlHeader.totalLength = sizeof(gpfs_hint_CancelHints);
         gpfs_hint_CancelHints.gpfsFcntlHeader.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
         gpfs_hint_CancelHints.gpfsFcntlHeader.fcntlReserved = 0;
@@ -289,10 +295,10 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
 
     //Setting GPFS Hint - gpfsSetReplication
     strcpy(gpfsHintsKey, "gpfsSetReplication");
-    ompi_info_get(info_selected, gpfsHintsKey, valueLen, value, &flag);
+    ompi_info_get(info_selected, gpfsHintsKey, &info_str, &flag);
     if (flag) {
         opal_output(ompi_fs_base_framework.framework_output,
-                    "GPFS Set Replication is set: %s: %s\n", gpfsHintsKey, value);
+                    "GPFS Set Replication is set: %s: %s\n", gpfsHintsKey, info_str->string);
         gpfs_hint_SetReplication.gpfsFcntlHeader.totalLength = sizeof(gpfs_hint_SetReplication);
         gpfs_hint_SetReplication.gpfsFcntlHeader.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
         gpfs_hint_SetReplication.gpfsFcntlHeader.fcntlReserved = 0;
@@ -300,12 +306,15 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
         gpfs_hint_SetReplication.gpfsSetReplication.structLen =
                 sizeof(gpfs_hint_SetReplication.gpfsSetReplication);
         gpfs_hint_SetReplication.gpfsSetReplication.structType = GPFS_FCNTL_SET_REPLICATION;
-        token = strtok(value, split);
+        char *info_str_dup = strdup(info_str->string);
+        OBJ_RELEASE(info_str);
+        token = strtok(info_str_dup, split);
         gpfs_hint_SetReplication.gpfsSetReplication.metadataReplicas = atoi(token);
         gpfs_hint_SetReplication.gpfsSetReplication.maxMetadataReplicas = atoi(token);
         gpfs_hint_SetReplication.gpfsSetReplication.dataReplicas = atoi(token);
         gpfs_hint_SetReplication.gpfsSetReplication.maxDataReplicas = atoi(token);
         gpfs_hint_SetReplication.gpfsSetReplication.reserved = 0;
+        free(info_str_dup);
 
         rc = gpfs_fcntl(gpfs_file_handle, &gpfs_hint_SetReplication);
         if (rc != 0) {
@@ -322,18 +331,21 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
 
     //Setting GPFS Hint - gpfsByteRange
     strcpy(gpfsHintsKey, "gpfsByteRange");
-    ompi_info_get(info_selected, gpfsHintsKey, valueLen, value, &flag);
+    ompi_info_get(info_selected, gpfsHintsKey, &info_str, &flag);
     if (flag) {
         opal_output(ompi_fs_base_framework.framework_output,
-                    "GPFS Byte Range is set: %s: %s\n", gpfsHintsKey, value);
+                    "GPFS Byte Range is set: %s: %s\n", gpfsHintsKey, info_str->string);
         gpfs_hint_ByteRange.gpfsFcntlHeader.totalLength = sizeof(gpfs_hint_ByteRange);
         gpfs_hint_ByteRange.gpfsFcntlHeader.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
         gpfs_hint_ByteRange.gpfsFcntlHeader.fcntlReserved = 0;
 
-        token = strtok(value, split);
+        char *info_str_dup = strdup(info_str->string);
+        OBJ_RELEASE(info_str);
+        token = strtok(info_str_dup, split);
         gpfs_hint_ByteRange.gpfsByteRange.startOffset = atol(token);
-        token = strtok(value, split);
+        token = strtok(NULL, split);
         gpfs_hint_ByteRange.gpfsByteRange.numOfBlks = atol(token);
+        free(info_str_dup);
 
         rc = gpfs_fcntl(gpfs_file_handle, &gpfs_hint_ByteRange);
         if (rc != 0) {
@@ -347,10 +359,10 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
 
     //Setting GPFS Hint - gpfsRestripeData
     strcpy(gpfsHintsKey, "gpfsRestripeData");
-    ompi_info_get(info_selected, gpfsHintsKey, valueLen, value, &flag);
+    ompi_info_get(info_selected, gpfsHintsKey, &info_str, &flag);
     if (flag) {
         opal_output(ompi_fs_base_framework.framework_output,
-                    "GPFS Restripe Data is set: %s: %s\n", gpfsHintsKey, value);
+                    "GPFS Restripe Data is set: %s: %s\n", gpfsHintsKey, info_str->string);
         gpfs_hint_RestripeData.gpfsFcntlHeader.totalLength = sizeof(gpfs_hint_RestripeData);
         gpfs_hint_RestripeData.gpfsFcntlHeader.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
         gpfs_hint_RestripeData.gpfsFcntlHeader.fcntlReserved = 0;
@@ -358,10 +370,13 @@ int mca_fs_gpfs_file_set_info(ompio_file_t *fh, struct ompi_info_t *info)
         gpfs_hint_RestripeData.gpfsRestripeData.structLen =
                 sizeof(gpfs_hint_RestripeData.gpfsRestripeData);
         gpfs_hint_RestripeData.gpfsRestripeData.structType = GPFS_FCNTL_RESTRIPE_DATA;
-        token = strtok(value, split);
+        char *info_str_dup = strdup(info_str->string);
+        OBJ_RELEASE(info_str);
+        token = strtok(info_str_dup, split);
         gpfs_hint_RestripeData.gpfsRestripeData.options = atoi(token);
         gpfs_hint_RestripeData.gpfsRestripeData.reserved1 = 0;
         gpfs_hint_RestripeData.gpfsRestripeData.reserved2 = 0;
+        free(info_str_dup);
 
         rc = gpfs_fcntl(gpfs_file_handle, &gpfs_hint_RestripeData);
         if (rc != 0) {
diff --git a/ompi/mca/fs/lustre/fs_lustre_file_open.c b/ompi/mca/fs/lustre/fs_lustre_file_open.c
index 3a0e1c049b..64c3014050 100644
--- a/ompi/mca/fs/lustre/fs_lustre_file_open.c
+++ b/ompi/mca/fs/lustre/fs_lustre_file_open.c
@@ -69,21 +69,23 @@ mca_fs_lustre_file_open (struct ompi_communicator_t *comm,
     int flag;
     int fs_lustre_stripe_size = -1;
     int fs_lustre_stripe_width = -1;
-    char char_stripe[MPI_MAX_INFO_KEY];
+    opal_cstring_t *stripe_str;
 
     struct lov_user_md *lump=NULL;
 
     perm = mca_fs_base_get_file_perm(fh);
     amode = mca_fs_base_get_file_amode(fh->f_rank, access_mode);
 
-    opal_info_get (info, "stripe_size", MPI_MAX_INFO_VAL, char_stripe, &flag);
+    opal_info_get (info, "stripe_size", &stripe_str, &flag);
     if ( flag ) {
-        sscanf ( char_stripe, "%d", &fs_lustre_stripe_size );
+        sscanf ( stripe_str->string, "%d", &fs_lustre_stripe_size );
+        OBJ_RELEASE(stripe_str);
     }
 
-    opal_info_get (info, "stripe_width", MPI_MAX_INFO_VAL, char_stripe, &flag);
+    opal_info_get (info, "stripe_width", &stripe_str, &flag);
     if ( flag ) {
-        sscanf ( char_stripe, "%d", &fs_lustre_stripe_width );
+        sscanf ( stripe_str->string, "%d", &fs_lustre_stripe_width );
+        OBJ_RELEASE(stripe_str);
     }
 
     if (fs_lustre_stripe_size < 0) {
diff --git a/ompi/mca/fs/pvfs2/fs_pvfs2_file_open.c b/ompi/mca/fs/pvfs2/fs_pvfs2_file_open.c
index cfc9acb591..827959c1e5 100644
--- a/ompi/mca/fs/pvfs2/fs_pvfs2_file_open.c
+++ b/ompi/mca/fs/pvfs2/fs_pvfs2_file_open.c
@@ -74,7 +74,7 @@ mca_fs_pvfs2_file_open (struct ompi_communicator_t *comm,
     struct ompi_datatype_t *types[2] = {&ompi_mpi_int.dt, &ompi_mpi_byte.dt};
     int lens[2] = {1, sizeof(PVFS_object_ref)};
     ptrdiff_t offsets[2];
-    char char_stripe[MPI_MAX_INFO_KEY];
+    opal_cstring_t *stripe_str;
     int flag;
     int fs_pvfs2_stripe_size = -1;
     int fs_pvfs2_stripe_width = -1;
@@ -109,14 +109,16 @@ mca_fs_pvfs2_file_open (struct ompi_communicator_t *comm,
        update mca_fs_pvfs2_stripe_width and mca_fs_pvfs2_stripe_size
        before calling fake_an_open() */
 
-    opal_info_get (info, "stripe_size", MPI_MAX_INFO_VAL, char_stripe, &flag);
+    opal_info_get (info, "stripe_size", &stripe_str, &flag);
     if ( flag ) {
-        sscanf ( char_stripe, "%d", &fs_pvfs2_stripe_size );
+        sscanf ( stripe_str->string, "%d", &fs_pvfs2_stripe_size );
+        OBJ_RELEASE(stripe_str);
     }
 
-    opal_info_get (info, "stripe_width", MPI_MAX_INFO_VAL, char_stripe, &flag);
+    opal_info_get (info, "stripe_width", &stripe_str, &flag);
     if ( flag ) {
-        sscanf ( char_stripe, "%d", &fs_pvfs2_stripe_width );
+        sscanf ( stripe_str->string, "%d", &fs_pvfs2_stripe_width );
+        OBJ_RELEASE(stripe_str);
     }
 
     if (fs_pvfs2_stripe_size < 0) {
diff --git a/ompi/mca/osc/portals4/osc_portals4_component.c b/ompi/mca/osc/portals4/osc_portals4_component.c
index f914831252..293885eb88 100644
--- a/ompi/mca/osc/portals4/osc_portals4_component.c
+++ b/ompi/mca/osc/portals4/osc_portals4_component.c
@@ -109,28 +109,11 @@ ompi_osc_portals4_module_t ompi_osc_portals4_module_template = {
 static bool
 check_config_value_bool(char *key, opal_info_t *info)
 {
-    char *value_string;
-    int value_len, ret, flag, param;
+    int ret, flag, param;
     const bool *flag_value;
     bool result;
-
-    ret = opal_info_get_valuelen(info, key, &value_len, &flag);
-    if (OMPI_SUCCESS != ret) goto info_not_found;
-    if (flag == 0) goto info_not_found;
-    value_len++;
-
-    value_string = (char*)malloc(sizeof(char) * value_len + 1); /* Should malloc 1 char for NUL-termination */
-    if (NULL == value_string) goto info_not_found;
-
-    ret = opal_info_get(info, key, value_len, value_string, &flag);
-    if (OMPI_SUCCESS != ret) {
-        free(value_string);
-        goto info_not_found;
-    }
-    assert(flag != 0);
-    ret = opal_info_value_to_bool(value_string, &result);
-    free(value_string);
-    if (OMPI_SUCCESS != ret) goto info_not_found;
+    ret = opal_info_get_bool(info, key, &result, &flag);
+    if (OMPI_SUCCESS != ret || !flag) goto info_not_found;
     return result;
 
  info_not_found:
@@ -147,37 +130,31 @@ check_config_value_bool(char *key, opal_info_t *info)
 static bool
 check_config_value_equal(char *key, opal_info_t *info, char *value)
 {
-    char *value_string;
-    int value_len, ret, flag, param;
-    const bool *flag_value;
+    int ret, flag, param;
+    const char *mca_value;
     bool result = false;
+    opal_cstring_t *value_string;
 
-    ret = opal_info_get_valuelen(info, key, &value_len, &flag);
-    if (OMPI_SUCCESS != ret) goto info_not_found;
-    if (flag == 0) goto info_not_found;
-    value_len++;
-
-    value_string = (char*)malloc(sizeof(char) * value_len + 1); /* Should malloc 1 char for NUL-termination */
-    if (NULL == value_string) goto info_not_found;
-
-    ret = opal_info_get(info, key, value_len, value_string, &flag);
-    if (OMPI_SUCCESS != ret) {
-        free(value_string);
+    ret = opal_info_get(info, key, &value_string, &flag);
+    if (OMPI_SUCCESS != ret || !flag) {
         goto info_not_found;
     }
-    assert(flag != 0);
-    if (0 == strcmp(value_string, value)) result = true;
-    free(value_string);
+    if (0 == strcmp(value_string->string, value)) {
+        result = true;
+    }
+    OBJ_RELEASE(value_string);
     return result;
 
  info_not_found:
     param = mca_base_var_find("ompi", "osc", "portals4", key);
     if (0 > param) return false;
 
-    ret = mca_base_var_get_value(param, &flag_value, NULL, NULL);
+    ret = mca_base_var_get_value(param, &mca_value, NULL, NULL);
     if (OMPI_SUCCESS != ret) return false;
 
-    if (0 == strcmp(value_string, value)) result = true;
+    if (0 == strcmp(mca_value, value)) {
+        result = true;
+    }
 
     return result;
 }
diff --git a/ompi/mca/sharedfp/individual/sharedfp_individual.c b/ompi/mca/sharedfp/individual/sharedfp_individual.c
index 2d66e20197..f827f472e9 100644
--- a/ompi/mca/sharedfp/individual/sharedfp_individual.c
+++ b/ompi/mca/sharedfp/individual/sharedfp_individual.c
@@ -77,8 +77,7 @@ struct mca_sharedfp_base_module_1_0_0_t * mca_sharedfp_individual_component_file
     bool relaxed_order_flag=false;
     opal_info_t *info;
     int flag;
-    int valuelen;
-    char value[MPI_MAX_INFO_VAL+1];
+    opal_cstring_t *info_str;
     *priority = 0;
 
     /*test, and update priority*/
@@ -105,16 +104,16 @@ struct mca_sharedfp_base_module_1_0_0_t * mca_sharedfp_individual_component_file
     /* 2. Did the user specify MPI_INFO relaxed ordering flag? */
     info = fh->f_info;
     if ( info != &(MPI_INFO_NULL->super) ){
-        valuelen = MPI_MAX_INFO_VAL;
-        opal_info_get ( info,"OMPIO_SHAREDFP_RELAXED_ORDERING", valuelen, value, &flag);
+        opal_info_get ( info,"OMPIO_SHAREDFP_RELAXED_ORDERING", &info_str, &flag);
         if ( flag ) {
            if ( mca_sharedfp_individual_verbose ) {
                 opal_output(ompi_sharedfp_base_framework.framework_output,
                         "mca_sharedfp_individual_component_file_query: "
-                        "OMPIO_SHAREDFP_RELAXED_ORDERING=%s\n",value);
+                        "OMPIO_SHAREDFP_RELAXED_ORDERING=%s\n", info_str->string);
 	    }
             /* flag - Returns true if key defined, false if not (boolean). */
             relaxed_order_flag=true;
+            OBJ_RELEASE(info_str);
         }
         else {
             if ( mca_sharedfp_individual_verbose ) {
diff --git a/ompi/mpi/c/alloc_mem.c b/ompi/mpi/c/alloc_mem.c
index 44f7f5e39d..28942fbbba 100644
--- a/ompi/mpi/c/alloc_mem.c
+++ b/ompi/mpi/c/alloc_mem.c
@@ -46,8 +46,8 @@ static const char FUNC_NAME[] = "MPI_Alloc_mem";
 
 int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr)
 {
-    char info_value[MPI_MAX_INFO_VAL + 1];
-    char *mpool_hints = NULL;
+    opal_cstring_t *info_str = NULL;
+    const char *mpool_hints = NULL;
 
     if (MPI_PARAM_CHECK) {
         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
@@ -74,14 +74,19 @@ int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr)
 
     if (MPI_INFO_NULL != info) {
         int flag;
-        (void) ompi_info_get (info, "mpool_hints", MPI_MAX_INFO_VAL, info_value, &flag);
+        (void) ompi_info_get (info, "mpool_hints", &info_str, &flag);
         if (flag) {
-            mpool_hints = info_value;
+            mpool_hints = info_str->string;
         }
     }
 
     *((void **) baseptr) = mca_mpool_base_alloc ((size_t) size, (struct opal_info_t*)info,
                                                  mpool_hints);
+
+    if (NULL != info_str) {
+        OBJ_RELEASE(info_str);
+    }
+
     if (NULL == *((void **) baseptr)) {
         return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_NO_MEM,
                                       FUNC_NAME);
diff --git a/ompi/mpi/c/info_get.c b/ompi/mpi/c/info_get.c
index b8e8566c76..4b4da55f60 100644
--- a/ompi/mpi/c/info_get.c
+++ b/ompi/mpi/c/info_get.c
@@ -29,6 +29,7 @@
 #include "ompi/communicator/communicator.h"
 #include "ompi/errhandler/errhandler.h"
 #include "ompi/info/info.h"
+#include "opal/util/string_copy.h"
 #include <stdlib.h>
 #include <string.h>
 
@@ -65,6 +66,7 @@ int MPI_Info_get(MPI_Info info, const char *key, int valuelen,
 {
     int err;
     int key_length;
+    opal_cstring_t *info_str;
 
     /*
      * Simple function. All we need to do is search for the value
@@ -99,6 +101,11 @@ int MPI_Info_get(MPI_Info info, const char *key, int valuelen,
         }
     }
 
-    err = ompi_info_get(info, key, valuelen, value, flag);
+    err = ompi_info_get(info, key, &info_str, flag);
+    if (*flag) {
+        opal_string_copy(value, info_str->string, valuelen+1);
+        OBJ_RELEASE(info_str);
+    }
+
     OMPI_ERRHANDLER_NOHANDLE_RETURN(err, err, FUNC_NAME);
 }
diff --git a/ompi/mpi/c/info_get_nthkey.c b/ompi/mpi/c/info_get_nthkey.c
index 412664f054..0007bf8367 100644
--- a/ompi/mpi/c/info_get_nthkey.c
+++ b/ompi/mpi/c/info_get_nthkey.c
@@ -25,6 +25,7 @@
 #include "ompi/communicator/communicator.h"
 #include "ompi/errhandler/errhandler.h"
 #include "ompi/info/info.h"
+#include "opal/util/string_copy.h"
 #include <string.h>
 
 #if OMPI_BUILD_MPI_PROFILING
@@ -89,6 +90,11 @@ int MPI_Info_get_nthkey(MPI_Info info, int n, char *key)
 
     /* Everything seems alright. Call the back end key copy */
 
-    err = ompi_info_get_nthkey (info, n, key);
+    opal_cstring_t *key_str = NULL;
+    err = ompi_info_get_nthkey (info, n, &key_str);
+    if (NULL != key_str) {
+        opal_string_copy(key, key_str->string, MPI_MAX_INFO_KEY);
+        OBJ_RELEASE(key);
+    }
     OMPI_ERRHANDLER_NOHANDLE_RETURN(err, err, FUNC_NAME);
 }
diff --git a/ompi/mpi/c/lookup_name.c b/ompi/mpi/c/lookup_name.c
index 7415ad88cf..0633d05a90 100644
--- a/ompi/mpi/c/lookup_name.c
+++ b/ompi/mpi/c/lookup_name.c
@@ -48,7 +48,6 @@ static const char FUNC_NAME[] = "MPI_Lookup_name";
 
 int MPI_Lookup_name(const char *service_name, MPI_Info info, char *port_name)
 {
-    char range[OPAL_MAX_INFO_VAL];
     int flag=0, ret;
     pmix_status_t rc;
     pmix_pdata_t pdat;
@@ -75,17 +74,19 @@ int MPI_Lookup_name(const char *service_name, MPI_Info info, char *port_name)
     /* OMPI supports info keys to pass the range to
      * be searched for the given key */
     if (MPI_INFO_NULL != info) {
-        ompi_info_get (info, "range", sizeof(range) - 1, range, &flag);
+        opal_cstring_t *info_str;
+        ompi_info_get (info, "range", &info_str, &flag);
         if (flag) {
-            if (0 == strcmp(range, "nspace")) {
+            if (0 == strcmp(info_str->string, "nspace")) {
                 rng = PMIX_RANGE_NAMESPACE;  // share only with procs in same nspace
-            } else if (0 == strcmp(range, "session")) {
+            } else if (0 == strcmp(info_str->string, "session")) {
                 rng = PMIX_RANGE_SESSION; // share only with procs in same session
             } else {
                 /* unrecognized scope */
                 return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_ARG,
                                             FUNC_NAME);
             }
+            OBJ_RELEASE(info_str);
         }
     }
     PMIX_INFO_LOAD(&pinfo, PMIX_RANGE, &rng, PMIX_DATA_RANGE);
diff --git a/ompi/mpi/c/publish_name.c b/ompi/mpi/c/publish_name.c
index be930aa82d..73c95ab9e0 100644
--- a/ompi/mpi/c/publish_name.c
+++ b/ompi/mpi/c/publish_name.c
@@ -49,7 +49,7 @@ int MPI_Publish_name(const char *service_name, MPI_Info info,
                      const char *port_name)
 {
     int ret;
-    char range[OPAL_MAX_INFO_VAL];
+    opal_cstring_t *info_str;
     int flag=0;
     pmix_status_t rc;
     pmix_info_t pinfo[3];
@@ -76,33 +76,35 @@ int MPI_Publish_name(const char *service_name, MPI_Info info,
     /* OMPI supports info keys to pass the range and persistence to
      * be used for the given key */
     if (MPI_INFO_NULL != info) {
-        ompi_info_get (info, "range", sizeof(range) - 1, range, &flag);
+        ompi_info_get (info, "range", &info_str, &flag);
         if (flag) {
-            if (0 == strcmp(range, "nspace")) {
+            if (0 == strcmp(info_str->string, "nspace")) {
                 rng = PMIX_RANGE_NAMESPACE;  // share only with procs in same nspace
-            } else if (0 == strcmp(range, "session")) {
+            } else if (0 == strcmp(info_str->string, "session")) {
                 rng = PMIX_RANGE_SESSION; // share only with procs in same session
             } else {
                 /* unrecognized scope */
                 return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_ARG,
                                             FUNC_NAME);
             }
+            OBJ_RELEASE(info_str);
         }
-        ompi_info_get (info, "persistence", sizeof(range) - 1, range, &flag);
+        ompi_info_get (info, "persistence", &info_str, &flag);
         if (flag) {
-            if (0 == strcmp(range, "indef")) {
+            if (0 == strcmp(info_str->string, "indef")) {
                 pers = PMIX_PERSIST_INDEF;   // retain until specifically deleted
-            } else if (0 == strcmp(range, "proc")) {
+            } else if (0 == strcmp(info_str->string, "proc")) {
                 pers = PMIX_PERSIST_PROC;    // retain until publishing process terminates
-            } else if (0 == strcmp(range, "app")) {
+            } else if (0 == strcmp(info_str->string, "app")) {
                 pers = PMIX_PERSIST_APP;     // retain until application terminates
-            } else if (0 == strcmp(range, "session")) {
+            } else if (0 == strcmp(info_str->string, "session")) {
                 pers = PMIX_PERSIST_SESSION; // retain until session/allocation terminates
             } else {
                 /* unrecognized persistence */
                 return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_ARG,
                                             FUNC_NAME);
             }
+            OBJ_RELEASE(info_str);
         }
     }
 
diff --git a/ompi/mpi/c/unpublish_name.c b/ompi/mpi/c/unpublish_name.c
index db03e70c39..800853df0d 100644
--- a/ompi/mpi/c/unpublish_name.c
+++ b/ompi/mpi/c/unpublish_name.c
@@ -50,7 +50,7 @@ int MPI_Unpublish_name(const char *service_name, MPI_Info info,
                        const char *port_name)
 {
     int ret;
-    char range[OPAL_MAX_INFO_VAL];
+    opal_cstring_t *info_str;
     int flag=0;
     pmix_status_t rc;
     pmix_info_t pinfo;
@@ -77,17 +77,18 @@ int MPI_Unpublish_name(const char *service_name, MPI_Info info,
     /* OMPI supports info keys to pass the range to
      * be searched for the given key */
     if (MPI_INFO_NULL != info) {
-        ompi_info_get (info, "range", sizeof(range) - 1, range, &flag);
+        ompi_info_get (info, "range", &info_str, &flag);
         if (flag) {
-            if (0 == strcmp(range, "nspace")) {
+            if (0 == strcmp(info_str->string, "nspace")) {
                 rng = PMIX_RANGE_NAMESPACE;  // share only with procs in same nspace
-            } else if (0 == strcmp(range, "session")) {
+            } else if (0 == strcmp(info_str->string, "session")) {
                 rng = PMIX_RANGE_SESSION; // share only with procs in same session
             } else {
                 /* unrecognized scope */
                 return OMPI_ERRHANDLER_NOHANDLE_INVOKE(MPI_ERR_ARG,
                                             FUNC_NAME);
             }
+            OBJ_RELEASE(info_str);
         }
     }
 
diff --git a/ompi/mpi/fortran/base/fortran_base_strings.h b/ompi/mpi/fortran/base/fortran_base_strings.h
index c1e4f7513e..f6bfb6da5b 100644
--- a/ompi/mpi/fortran/base/fortran_base_strings.h
+++ b/ompi/mpi/fortran/base/fortran_base_strings.h
@@ -55,7 +55,7 @@ BEGIN_C_DECLS
      * convert C strings to fortran strings.  It is assumed that the
      * fortran string is already allocated and has a length of len.
      */
-    OMPI_DECLSPEC int ompi_fortran_string_c2f(char *cstr, char *fstr, int len);
+    OMPI_DECLSPEC int ompi_fortran_string_c2f(const char* cstr, char* fstr, int len);
 
     /**
      * Convert an array of Fortran strings that are terminated with a
diff --git a/ompi/mpi/fortran/base/strings.c b/ompi/mpi/fortran/base/strings.c
index 95645a1d90..5bbd96d5ee 100644
--- a/ompi/mpi/fortran/base/strings.c
+++ b/ompi/mpi/fortran/base/strings.c
@@ -90,7 +90,7 @@ int ompi_fortran_string_f2c(char *fstr, int len, char **cstr)
  * shorter string, or reading a shorter record, automatically pads the
  * rest of the string with blanks."
  */
-int ompi_fortran_string_c2f(char *cstr, char *fstr, int len)
+int ompi_fortran_string_c2f(const char *cstr, char *fstr, int len)
 {
     int i;
 
diff --git a/ompi/mpi/fortran/mpif-h/info_get_f.c b/ompi/mpi/fortran/mpif-h/info_get_f.c
index a1b479b08e..d9d6b4ac85 100644
--- a/ompi/mpi/fortran/mpif-h/info_get_f.c
+++ b/ompi/mpi/fortran/mpif-h/info_get_f.c
@@ -82,8 +82,9 @@ void ompi_info_get_f(MPI_Fint *info, char *key, MPI_Fint *valuelen,
 {
     int c_ierr, ret;
     MPI_Info c_info;
-    char *c_key = NULL, c_value[MPI_MAX_INFO_VAL + 1];
+    char *c_key = NULL;
     OMPI_LOGICAL_NAME_DECL(flag);
+    opal_cstring_t *info_str;
 
     if (OMPI_SUCCESS != (ret = ompi_fortran_string_f2c(key, key_len, &c_key))) {
         c_ierr = OMPI_ERRHANDLER_NOHANDLE_INVOKE(ret, FUNC_NAME);
@@ -92,10 +93,8 @@ void ompi_info_get_f(MPI_Fint *info, char *key, MPI_Fint *valuelen,
     }
     c_info = PMPI_Info_f2c(*info);
 
-    c_ierr = PMPI_Info_get(c_info, c_key,
-                          OMPI_FINT_2_INT(*valuelen),
-                          c_value,
-                          OMPI_LOGICAL_SINGLE_NAME_CONVERT(flag));
+    c_ierr = ompi_info_get(c_info, c_key, &info_str,
+                           OMPI_LOGICAL_SINGLE_NAME_CONVERT(flag));
     if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr);
 
     if (MPI_SUCCESS == c_ierr) {
@@ -107,12 +106,13 @@ void ompi_info_get_f(MPI_Fint *info, char *key, MPI_Fint *valuelen,
            Fortran compilers have TRUE == 1).  Note: use the full
            length of the Fortran string, not *valuelen.  See comment
            in ompi/mpi/fortran/base/strings.c. */
-        if (*flag && OMPI_SUCCESS !=
-            (ret = ompi_fortran_string_c2f(c_value, value, value_len))) {
-            c_ierr = OMPI_ERRHANDLER_NOHANDLE_INVOKE(ret, FUNC_NAME);
-            if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr);
-            free(c_key);
-            return;
+        if (*flag) {
+            if (OMPI_SUCCESS !=
+                (ret = ompi_fortran_string_c2f(info_str->string, value, value_len))) {
+                c_ierr = OMPI_ERRHANDLER_NOHANDLE_INVOKE(ret, FUNC_NAME);
+                if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr);
+            }
+            OBJ_RELEASE(info_str);
         }
     }
 
diff --git a/ompi/mpi/fortran/mpif-h/info_get_nthkey_f.c b/ompi/mpi/fortran/mpif-h/info_get_nthkey_f.c
index 2e93f50afe..db5223ae2d 100644
--- a/ompi/mpi/fortran/mpif-h/info_get_nthkey_f.c
+++ b/ompi/mpi/fortran/mpif-h/info_get_nthkey_f.c
@@ -81,18 +81,19 @@ void ompi_info_get_nthkey_f(MPI_Fint *info, MPI_Fint *n, char *key,
 {
     int c_ierr, ret;
     MPI_Info c_info;
-    char c_key[MPI_MAX_INFO_KEY + 1];
+    opal_cstring_t *key_str;
 
     c_info = PMPI_Info_f2c(*info);
 
-    c_ierr = PMPI_Info_get_nthkey(c_info,
-                                 OMPI_FINT_2_INT(*n),
-                                 c_key);
+    c_ierr = ompi_info_get_nthkey(c_info, OMPI_FINT_2_INT(*n), &key_str);
     if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr);
 
-    if (OMPI_SUCCESS != (ret = ompi_fortran_string_c2f(c_key, key, key_len))) {
-        c_ierr = OMPI_ERRHANDLER_NOHANDLE_INVOKE(ret, FUNC_NAME);
-        if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr);
-        return;
+    if (NULL != key_str) {
+        if (OMPI_SUCCESS != (ret = ompi_fortran_string_c2f(key_str->string, key, key_len))) {
+            c_ierr = OMPI_ERRHANDLER_NOHANDLE_INVOKE(ret, FUNC_NAME);
+            if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr);
+        }
+        OBJ_RELEASE(key_str);
     }
+
 }
diff --git a/opal/util/info.c b/opal/util/info.c
index e77384ea98..cf2379c8b3 100644
--- a/opal/util/info.c
+++ b/opal/util/info.c
@@ -77,76 +77,108 @@ OBJ_CLASS_INSTANCE(opal_info_entry_t,
  */
 int opal_info_dup (opal_info_t *info, opal_info_t **newinfo)
 {
-    int err;
     opal_info_entry_t *iterator;
 
     OPAL_THREAD_LOCK(info->i_lock);
     OPAL_LIST_FOREACH(iterator, &info->super, opal_info_entry_t) {
-        err = opal_info_set(*newinfo, iterator->ie_key, iterator->ie_value);
-        if (OPAL_SUCCESS != err) {
-            OPAL_THREAD_UNLOCK(info->i_lock);
-            return err;
-        }
+        /* create a new info entry and retain the string objects */
+        opal_info_entry_t *newentry = OBJ_NEW(opal_info_entry_t);
+        newentry->ie_key = iterator->ie_key;
+        OBJ_RETAIN(iterator->ie_key);
+        newentry->ie_value = iterator->ie_value;
+        OBJ_RETAIN(iterator->ie_value);
      }
     OPAL_THREAD_UNLOCK(info->i_lock);
     return OPAL_SUCCESS;
 }
 
-static void opal_info_get_nolock (opal_info_t *info, const char *key, int valuelen,
-                                 char *value, int *flag)
+static void opal_info_get_nolock (opal_info_t *info, const char *key,
+                                  opal_cstring_t **value, int *flag)
 {
     opal_info_entry_t *search;
 
     search = info_find_key (info, key);
     if (NULL == search){
         *flag = 0;
-    } else if (value && valuelen) {
+    } else {
         /*
-         * We have found the element, so we can return the value
-         * Set the flag and value
-         */
+        * We have found the element, so we can return the value
+        * Set the flag and value
+        */
         *flag = 1;
-        // Note: we copy exactly (valuelen) characters, because that's
-        // what the caller asked for.  Don't use opal_string_copy()
-        // here, because that will guarantee to \0-terminate what is
-        // copied (i.e., potentially copy (valuelen-1) chars and then
-        // an additional \0).  Instead: copy over exactly (valuelen)
-        // characters, and if that's not \0-terminated, then so be it.
-        memcpy(value, search->ie_value, valuelen);
+        if (NULL != value) {
+            OBJ_RETAIN(search->ie_value);
+            *value = search->ie_value;
+        }
     }
 }
 
-static int opal_info_set_nolock (opal_info_t *info, const char *key, const char *value)
+static int opal_info_set_cstring_nolock (opal_info_t *info, const char *key, opal_cstring_t *value)
 {
-    char *new_value;
-    opal_info_entry_t *new_info;
     opal_info_entry_t *old_info;
 
-    new_value = strdup(value);
-    if (NULL == new_value) {
-      return OPAL_ERR_OUT_OF_RESOURCE;
+    old_info = info_find_key (info, key);
+    if (NULL != old_info) {
+        /*
+         * key already exists. remove the value associated with it
+         */
+        OBJ_RELEASE(old_info->ie_value);
+        OBJ_RETAIN(value);
+        old_info->ie_value = value;
+    } else {
+        opal_info_entry_t *new_info;
+        new_info = OBJ_NEW(opal_info_entry_t);
+        if (NULL == new_info) {
+            return OPAL_ERR_OUT_OF_RESOURCE;
+        }
+        opal_cstring_t *key_str = opal_cstring_create(key);
+        new_info->ie_key = key_str;
+        OBJ_RETAIN(value);
+        new_info->ie_value = value;
+        opal_list_append (&(info->super), (opal_list_item_t *) new_info);
     }
+    return OPAL_SUCCESS;
+}
+
+
+static int opal_info_set_nolock (opal_info_t *info, const char *key, const char *value)
+{
+    opal_info_entry_t *old_info;
 
     old_info = info_find_key (info, key);
     if (NULL != old_info) {
         /*
-         * key already exists. remove the value associated with it
+         * key already exists, check whether it is the same
          */
-        free(old_info->ie_value);
-        old_info->ie_value = new_value;
+        size_t value_len = strlen(value);
+        if (old_info->ie_value->length == value_len
+            && 0 == strcmp(old_info->ie_value->string, value)) {
+            return OPAL_SUCCESS;
+        }
+        /* value is different so replace it */
+        OBJ_RELEASE(old_info->ie_value);
+        old_info->ie_value = opal_cstring_create_l(value, value_len);
+        if (NULL == old_info->ie_value) {
+            OBJ_RELEASE(old_info);
+            return OPAL_ERR_OUT_OF_RESOURCE;
+        }
     } else {
+        opal_info_entry_t *new_info;
         new_info = OBJ_NEW(opal_info_entry_t);
         if (NULL == new_info) {
-            free(new_value);
-            OPAL_THREAD_UNLOCK(info->i_lock);
             return OPAL_ERR_OUT_OF_RESOURCE;
         }
-        opal_string_copy (new_info->ie_key, key, OPAL_MAX_INFO_KEY);
-        new_info->ie_value = new_value;
+        new_info->ie_key = opal_cstring_create(key);
+        new_info->ie_value = opal_cstring_create(value);
+        if (NULL == new_info->ie_key || NULL == new_info->ie_value) {
+            OBJ_RELEASE(new_info);
+            return OPAL_ERR_OUT_OF_RESOURCE;
+        }
         opal_list_append (&(info->super), (opal_list_item_t *) new_info);
     }
     return OPAL_SUCCESS;
 }
+
 /*
  * An object's info can be set, but those settings can be modified by
  * system callbacks. When those callbacks happen, we save a "__IN_<key>"/"val"
@@ -165,95 +197,95 @@ int opal_info_dup_mode (opal_info_t *info, opal_info_t **newinfo,
 {
     int err, flag;
     opal_info_entry_t *iterator;
-    char savedkey[OPAL_MAX_INFO_KEY + 1]; // iterator->ie_key has this as its size
-    char savedval[OPAL_MAX_INFO_VAL];
-    char *valptr, *pkey;
+
+    const char *pkey;
     int is_IN_key;
     int exists_IN_key, exists_reg_key;
 
     OPAL_THREAD_LOCK(info->i_lock);
     OPAL_LIST_FOREACH(iterator, &info->super, opal_info_entry_t) {
-// If we see an __IN_<key> key but no <key>, decide what to do based on mode.
-// If we see an __IN_<key> and a <key>, skip since it'll be handled when
-// we process <key>.
-         is_IN_key = 0;
-         exists_IN_key = 0;
-         exists_reg_key = 0;
-         pkey = iterator->ie_key;
-         if (0 == strncmp(iterator->ie_key, OPAL_INFO_SAVE_PREFIX,
-             strlen(OPAL_INFO_SAVE_PREFIX)))
+        // If we see an __IN_<key> key but no <key>, decide what to do based on mode.
+        // If we see an __IN_<key> and a <key>, skip since it'll be handled when
+        // we process <key>.
+        is_IN_key = 0;
+        exists_IN_key = 0;
+        exists_reg_key = 0;
+        pkey = iterator->ie_key->string;
+        opal_cstring_t *savedval = NULL;
+        opal_cstring_t *valstr = NULL;
+        if (0 == strncmp(iterator->ie_key->string, OPAL_INFO_SAVE_PREFIX,
+                         strlen(OPAL_INFO_SAVE_PREFIX)))
         {
-             pkey += strlen(OPAL_INFO_SAVE_PREFIX);
-
-             is_IN_key = 1;
-             exists_IN_key = 1;
-             opal_info_get_nolock (info, pkey, 0, NULL, &flag);
-             if (flag) {
-                 exists_reg_key = 1;
-             }
-         } else {
-             is_IN_key = 0;
-             exists_reg_key = 1;
-
-// see if there is an __IN_<key> for the current <key>
-             if (strlen(OPAL_INFO_SAVE_PREFIX) + strlen(pkey) < OPAL_MAX_INFO_KEY) {
-                 snprintf(savedkey, OPAL_MAX_INFO_KEY+1,
-                     OPAL_INFO_SAVE_PREFIX "%s", pkey);
-// (the prefix macro is a string, so the unreadable part above is a string concatenation)
-                 opal_info_get_nolock (info, savedkey, OPAL_MAX_INFO_VAL,
-                                       savedval, &flag);
-             } else {
-                 flag = 0;
-             }
-             if (flag) {
-                 exists_IN_key = 1;
-             }
-         }
+            pkey += strlen(OPAL_INFO_SAVE_PREFIX);
+
+            is_IN_key = 1;
+            exists_IN_key = 1;
+            opal_info_get_nolock (info, pkey, NULL, &flag);
+            if (flag) {
+                exists_reg_key = 1;
+            }
+        } else {
+            is_IN_key = 0;
+            exists_reg_key = 1;
+
+            // see if there is an __IN_<key> for the current <key>
+            if (strlen(OPAL_INFO_SAVE_PREFIX) + strlen(pkey) < OPAL_MAX_INFO_KEY) {
+                char savedkey[OPAL_MAX_INFO_KEY + 1]; // iterator->ie_key has this as its size
+                snprintf(savedkey, OPAL_MAX_INFO_KEY+1, OPAL_INFO_SAVE_PREFIX "%s", pkey);
+                // (the prefix macro is a string, so the unreadable part above is a string concatenation)
+                opal_info_get_nolock (info, savedkey, &savedval, &flag);
+                // release savedval, it remains valid as long we're holding the lock
+                OBJ_RELEASE(savedval);
+                exists_IN_key = 1;
+            } else {
+                flag = 0;
+            }
+        }
 
-         if (is_IN_key) {
-             if (exists_reg_key) {
-// we're processing __IN_<key> and there exists a <key> so we'll handle it then
-                 continue;
-             } else {
-// we're processing __IN_<key> and no <key> exists
-// this would mean <key> was set by the user but ignored by the system
-// so base our behavior on the omit_ignored
-                 if (!omit_ignored) {
-                     err = opal_info_set_nolock(*newinfo, pkey, iterator->ie_value);
-                     if (OPAL_SUCCESS != err) {
-                         OPAL_THREAD_UNLOCK(info->i_lock);
-                         return err;
-                     }
-                 }
-             }
-         } else {
-             valptr = 0;
-             if (!exists_IN_key) {
-// we're processing <key> and no __IN_<key> <key> exists
-// this would mean it's a system setting, not something that came from the user
-                 if (include_system_extras) {
-                     valptr = iterator->ie_value;
-                 }
-             } else {
-// we're processing <key> and __IN_<key> also exists
-// pick which value to use
-                 if (!show_modifications) {
-                     valptr = savedval;
-                 } else {
-                     valptr = iterator->ie_value;
-                 }
-             }
-             if (valptr) {
-                 err = opal_info_set_nolock(*newinfo, pkey, valptr);
-                 if (OPAL_SUCCESS != err) {
-                     OPAL_THREAD_UNLOCK(info->i_lock);
-                     return err;
-                 }
-             }
-         }
-     }
-     OPAL_THREAD_UNLOCK(info->i_lock);
-     return OPAL_SUCCESS;
+        if (is_IN_key) {
+            if (exists_reg_key) {
+                // we're processing __IN_<key> and there exists a <key> so we'll handle it then
+                continue;
+            } else {
+                // we're processing __IN_<key> and no <key> exists
+                // this would mean <key> was set by the user but ignored by the system
+                // so base our behavior on the omit_ignored
+                if (!omit_ignored) {
+                    err = opal_info_set_cstring_nolock(*newinfo, pkey, iterator->ie_value);
+                    if (OPAL_SUCCESS != err) {
+                        OPAL_THREAD_UNLOCK(info->i_lock);
+                        return err;
+                    }
+                }
+            }
+        } else {
+            if (!exists_IN_key) {
+                // we're processing <key> and no __IN_<key> <key> exists
+                // this would mean it's a system setting, not something that came from the user
+                if (include_system_extras) {
+                    valstr = iterator->ie_value;
+                }
+            } else {
+                // we're processing <key> and __IN_<key> also exists
+                // pick which value to use
+                if (!show_modifications) {
+                    valstr = savedval;
+                } else {
+                    valstr = iterator->ie_value;
+                }
+            }
+            if (NULL != valstr) {
+                err = opal_info_set_cstring_nolock(*newinfo, pkey, valstr);
+                /* NOTE: we have not retained valstr so don't release here after using it */
+                if (OPAL_SUCCESS != err) {
+                    OPAL_THREAD_UNLOCK(info->i_lock);
+                    return err;
+                }
+            }
+        }
+    }
+    OPAL_THREAD_UNLOCK(info->i_lock);
+    return OPAL_SUCCESS;
 }
 
 /*
@@ -278,6 +310,16 @@ int opal_info_set (opal_info_t *info, const char *key, const char *value)
     return ret;
 }
 
+int opal_info_set_cstring (opal_info_t *info, const char *key, opal_cstring_t *value)
+{
+    int ret;
+
+    OPAL_THREAD_LOCK(info->i_lock);
+    ret = opal_info_set_cstring_nolock(info, key, value);
+    OPAL_THREAD_UNLOCK(info->i_lock);
+    return ret;
+}
+
 
 int opal_info_set_value_enum (opal_info_t *info, const char *key, int value,
                               mca_base_var_enum_t *var_enum)
@@ -297,11 +339,11 @@ int opal_info_set_value_enum (opal_info_t *info, const char *key, int value,
 /*
  * Get a value from an info
  */
-int opal_info_get (opal_info_t *info, const char *key, int valuelen,
-                   char *value, int *flag)
+int opal_info_get (opal_info_t *info, const char *key,
+                   opal_cstring_t  **value, int *flag)
 {
     OPAL_THREAD_LOCK(info->i_lock);
-    opal_info_get_nolock(info, key, valuelen, value, flag);
+    opal_info_get_nolock(info, key, value, flag);
     OPAL_THREAD_UNLOCK(info->i_lock);
     return OPAL_SUCCESS;
 }
@@ -310,25 +352,17 @@ int opal_info_get_value_enum (opal_info_t *info, const char *key, int *value,
                               int default_value, mca_base_var_enum_t *var_enum,
                               int *flag)
 {
-    opal_info_entry_t *search;
     int ret;
+    opal_cstring_t *str;
 
     *value = default_value;
 
-    OPAL_THREAD_LOCK(info->i_lock);
-    search = info_find_key (info, key);
-    if (NULL == search){
-        OPAL_THREAD_UNLOCK(info->i_lock);
-        *flag = 0;
-        return OPAL_SUCCESS;
-    }
-
-    /* we found a mathing key. pass the string value to the enumerator and
-     * return */
-    *flag = 1;
+    ret = opal_info_get(info, key, &str, flag);
 
-    ret = var_enum->value_from_string (var_enum, search->ie_value, value);
-    OPAL_THREAD_UNLOCK(info->i_lock);
+    if (*flag) {
+        ret = var_enum->value_from_string (var_enum, str->string, value);
+        OBJ_RELEASE(str);
+    }
 
     return ret;
 }
@@ -340,47 +374,16 @@ int opal_info_get_value_enum (opal_info_t *info, const char *key, int *value,
  */
 int opal_info_get_bool(opal_info_t *info, const char *key, bool *value, int *flag)
 {
-    char str[256];
+    int ret;
+    opal_cstring_t *str;
 
-    str[sizeof(str) - 1] = '\0';
-    opal_info_get(info, key, sizeof(str) - 1, str, flag);
+    ret = opal_info_get(info, key, &str, flag);
     if (*flag) {
-        *value = opal_str_to_bool(str);
+        ret = opal_cstring_to_bool(str, value);
+        OBJ_RELEASE(str);
     }
 
-    return OPAL_SUCCESS;
-}
-
-
-bool
-opal_str_to_bool(char *str)
-{
-    bool result = false;
-    char *ptr;
-
-    /* Trim whitespace */
-    ptr = str + strlen(str) - 1;
-    while (ptr >= str && isspace(*ptr)) {
-        *ptr = '\0';
-        --ptr;
-    }
-    ptr = str;
-    while (ptr < str + strlen(str) - 1 && *ptr != '\0' &&
-           isspace(*ptr)) {
-        ++ptr;
-    }
-    if ('\0' != *ptr) {
-        if (isdigit(*ptr)) {
-            result = (bool) atoi(ptr);
-        } else if (0 == strcasecmp(ptr, "yes") ||
-                   0 == strcasecmp(ptr, "true")) {
-            result = true;
-        } else if (0 != strcasecmp(ptr, "no") &&
-                   0 != strcasecmp(ptr, "false")) {
-            /* RHC unrecognized value -- print a warning? */
-        }
-    }
-    return result;
+    return ret;
 }
 
 /*
@@ -428,7 +431,7 @@ int opal_info_get_valuelen (opal_info_t *info, const char *key, int *valuelen,
          * Set the flag, value_length and value
          */
          *flag = 1;
-         *valuelen = strlen(search->ie_value);
+         *valuelen = search->ie_value->length;
     }
     OPAL_THREAD_UNLOCK(info->i_lock);
     return OPAL_SUCCESS;
@@ -438,7 +441,7 @@ int opal_info_get_valuelen (opal_info_t *info, const char *key, int *valuelen,
 /*
  * Get the nth key
  */
-int opal_info_get_nthkey (opal_info_t *info, int n, char *key)
+int opal_info_get_nthkey (opal_info_t *info, int n, opal_cstring_t **key)
 {
     opal_info_entry_t *iterator;
 
@@ -456,12 +459,8 @@ int opal_info_get_nthkey (opal_info_t *info, int n, char *key)
              return OPAL_ERR_BAD_PARAM;
          }
     }
-    /*
-     * iterator is of the type opal_list_item_t. We have to
-     * cast it to opal_info_entry_t before we can use it to
-     * access the value
-     */
-    opal_string_copy(key, iterator->ie_key, OPAL_MAX_INFO_KEY);
+    OBJ_RETAIN(iterator->ie_key);
+    *key = iterator->ie_key;
     OPAL_THREAD_UNLOCK(info->i_lock);
     return OPAL_SUCCESS;
 }
@@ -507,15 +506,21 @@ static void info_destructor(opal_info_t *info)
  */
 static void info_entry_constructor(opal_info_entry_t *entry)
 {
-    memset(entry->ie_key, 0, sizeof(entry->ie_key));
-    entry->ie_key[OPAL_MAX_INFO_KEY] = 0;
+    entry->ie_key = NULL;
+    entry->ie_value = NULL;
 }
 
 
 static void info_entry_destructor(opal_info_entry_t *entry)
 {
+    if (NULL != entry->ie_key) {
+        OBJ_RELEASE(entry->ie_key);
+        entry->ie_key = NULL;
+    }
+
     if (NULL != entry->ie_value) {
-        free(entry->ie_value);
+        OBJ_RELEASE(entry->ie_value);
+        entry->ie_value = NULL;
     }
 }
 
@@ -537,60 +542,9 @@ static opal_info_entry_t *info_find_key (opal_info_t *info, const char *key)
      * and NULL is returned
      */
     OPAL_LIST_FOREACH(iterator, &info->super, opal_info_entry_t) {
-        if (0 == strcmp(key, iterator->ie_key)) {
+        if (0 == strcmp(key, iterator->ie_key->string)) {
             return iterator;
         }
     }
     return NULL;
 }
-
-
-int
-opal_info_value_to_int(char *value, int *interp)
-{
-    long tmp;
-    char *endp;
-
-    if (NULL == value || '\0' == value[0]) return OPAL_ERR_BAD_PARAM;
-
-    errno = 0;
-    tmp = strtol(value, &endp, 10);
-    /* we found something not a number */
-    if (*endp != '\0') return OPAL_ERR_BAD_PARAM;
-    /* underflow */
-    if (tmp == 0 && errno == EINVAL) return OPAL_ERR_BAD_PARAM;
-
-    *interp = (int) tmp;
-
-    return OPAL_SUCCESS;
-}
-
-
-int
-opal_info_value_to_bool(char *value, bool *interp)
-{
-    int tmp;
-
-    /* idiot case */
-    if (NULL == value || NULL == interp) return OPAL_ERR_BAD_PARAM;
-
-    /* is it true / false? */
-    if (0 == strcmp(value, "true")) {
-        *interp = true;
-        return OPAL_SUCCESS;
-    } else if (0 == strcmp(value, "false")) {
-        *interp = false;
-        return OPAL_SUCCESS;
-
-    /* is it a number? */
-    } else if (OPAL_SUCCESS == opal_info_value_to_int(value, &tmp)) {
-        if (tmp == 0) {
-            *interp = false;
-        } else {
-            *interp = true;
-        }
-        return OPAL_SUCCESS;
-    }
-
-    return OPAL_ERR_BAD_PARAM;
-}
diff --git a/opal/util/info.h b/opal/util/info.h
index 8521d765f3..53f3b7e35d 100644
--- a/opal/util/info.h
+++ b/opal/util/info.h
@@ -28,6 +28,7 @@
 
 #include <string.h>
 
+#include "opal/class/opal_cstring.h"
 #include "opal/class/opal_list.h"
 #include "opal/class/opal_pointer_array.h"
 #include "opal/mca/threads/mutex.h"
@@ -63,12 +64,11 @@ extern opal_pointer_array_t ompi_info_f_to_c_table;
  * type. It contains (key,value) pairs
  */
 struct opal_info_entry_t {
-    opal_list_item_t super; /**< required for opal_list_t type */
-    char *ie_value; /**< value part of the (key, value) pair.
-                  * Maximum length is MPI_MAX_INFO_VAL */
-    char ie_key[OPAL_MAX_INFO_KEY + 1]; /**< "key" part of the (key, value)
-                                     * pair */
+    opal_list_item_t super;  /**< required for opal_list_t type */
+    opal_cstring_t *ie_value; /**< value part of the (key, value) pair. */
+    opal_cstring_t *ie_key;   /**< "key" part of the (key, value) pair */
 };
+
 /**
  * \internal
  * Convenience typedef
@@ -104,7 +104,7 @@ int opal_mpiinfo_init(void*);
  *   Not only will the (key, value) pairs be duplicated, the order
  *   of keys will be the same in 'newinfo' as it is in 'info'.  When
  *   an info object is no longer being used, it should be freed with
- *   'MPI_Info_free'.
+ *   \c opal_info_free.
  */
 int opal_info_dup (opal_info_t *info, opal_info_t **newinfo);
 
@@ -152,6 +152,21 @@ int opal_info_dup_mpistandard (opal_info_t *info, opal_info_t **newinfo);
  */
 OPAL_DECLSPEC int opal_info_set (opal_info_t *info, const char *key, const char *value);
 
+/**
+ * Set a new key,value pair on info.
+ *
+ * @param info pointer to opal_info_t object
+ * @param key pointer to the new key string
+ * @param value pointer to the new value string object
+ *
+ * @retval OPAL_SUCCESS upon success
+ * @retval OPAL_ERR_OUT_OF_RESOURCE if out of memory
+ *
+ * The \c value string object will be retained and can be safely released if necessary
+ * by the caller.
+ */
+OPAL_DECLSPEC int opal_info_set_cstring (opal_info_t *info, const char *key, opal_cstring_t *value);
+
 /**
  * Set a new key,value pair from a variable enumerator.
  *
@@ -232,18 +247,19 @@ OPAL_DECLSPEC int opal_info_get_value_enum (opal_info_t *info, const char *key,
  *
  *   @param info Pointer to opal_info_t object
  *   @param key null-terminated character string of the index key
- *   @param valuelen maximum length of 'value' (integer)
- *   @param value null-terminated character string of the value
+ *   @param string null-terminated character string of the value
  *   @param flag true (1) if 'key' defined on 'info', false (0) if not
  *               (logical)
  *
  *   @retval OPAL_SUCCESS
  *
- *   In C and C++, 'valuelen' should be one less than the allocated
- *   space to allow for for the null terminator.
+ *   The \c string pointer will only be set if the key is found, i.e., if \c flag
+ *   is set to \c true. It is the caller's responsibility to decremenet the
+ *   reference count of the \c string object by calling \c OBJ_RELEASE on it
+ *   once the object is not needed any more.
  */
-OPAL_DECLSPEC int opal_info_get (opal_info_t *info, const char *key, int valuelen,
-                                 char *value, int *flag);
+OPAL_DECLSPEC int opal_info_get (opal_info_t *info, const char *key,
+                                 opal_cstring_t **string, int *flag);
 
 /**
  * Delete a (key,value) pair from "info"
@@ -276,49 +292,20 @@ OPAL_DECLSPEC int opal_info_get_valuelen (opal_info_t *info, const char *key, in
                                           int *flag);
 
 /**
- *   opal_info_get_nthkey - Get a key indexed by integer from an 'MPI_Info' o
+ *   opal_info_get_nthkey - Get a key indexed by integer from an info object
  *
  *   @param info Pointer to opal_info_t object
  *   @param n index of key to retrieve (integer)
- *   @param key character string of at least 'MPI_MAX_INFO_KEY' characters
+ *   @param key output opal_cstring_t object, set if the n'th key exists
  *
  *   @retval OPAL_SUCCESS
  *   @retval OPAL_ERR_BAD_PARAM
- */
-int opal_info_get_nthkey (opal_info_t *info, int n, char *key);
-
-/**
- * Convert value string to boolean
  *
- * Convert value string \c value into a boolean, using the
- * interpretation rules specified in MPI-2 Section 4.10.  The
- * strings "true", "false", and integer numbers can be converted
- * into booleans.  All others will return \c OMPI_ERR_BAD_PARAM
- *
- * @param value Value string for info key to interpret
- * @param interp returned interpretation of the value key
- *
- * @retval OPAL_SUCCESS string was successfully interpreted
- * @retval OPAL_ERR_BAD_PARAM string was not able to be interpreted
+ *   It is the caller's responsibility to decremenet the reference count of the
+ *   \c key string by calling \c OBJ_RELEASE on it once the object is not needed
+ *   any more.
  */
-OPAL_DECLSPEC int opal_info_value_to_bool(char *value, bool *interp);
-
-/**
- * Convert value string to integer
- *
- * Convert value string \c value into a integer, using the
- * interpretation rules specified in MPI-2 Section 4.10.
- * All others will return \c OPAL_ERR_BAD_PARAM
- *
- * @param value Value string for info key to interpret
- * @param interp returned interpretation of the value key
- *
- * @retval OPAL_SUCCESS string was successfully interpreted
- * @retval OPAL_ERR_BAD_PARAM string was not able to be interpreted
- */
-int opal_info_value_to_int(char *value, int *interp);
-
-END_C_DECLS
+int opal_info_get_nthkey (opal_info_t *info, int n, opal_cstring_t **key);
 
 /**
  * Get the number of keys defined on on an MPI_Info object
@@ -334,6 +321,8 @@ opal_info_get_nkeys(opal_info_t *info, int *nkeys)
     return OPAL_SUCCESS;
 }
 
-bool opal_str_to_bool(char*);
+
+END_C_DECLS
+
 
 #endif /* OPAL_INFO_H */
diff --git a/opal/util/info_subscriber.c b/opal/util/info_subscriber.c
index 7c5491434c..36fd53d67b 100644
--- a/opal/util/info_subscriber.c
+++ b/opal/util/info_subscriber.c
@@ -37,13 +37,14 @@
 #include <sys/utsname.h>
 #endif
 #include <assert.h>
+#include <string.h>
 
 #include "opal/util/argv.h"
 #include "opal/util/opal_getcwd.h"
 #include "opal/util/output.h"
 #include "opal/util/info_subscriber.h"
 
-static char* opal_infosubscribe_inform_subscribers(opal_infosubscriber_t * object, char *key, char *new_value, int *found_callback);
+static const char* opal_infosubscribe_inform_subscribers(opal_infosubscriber_t * object, const char *key, const char *new_value, int *found_callback);
 static void infosubscriber_construct(opal_infosubscriber_t *obj);
 static void infosubscriber_destruct(opal_infosubscriber_t *obj);
 
@@ -55,7 +56,7 @@ typedef struct opal_callback_list_t opal_callback_list_t;
 
 struct opal_callback_list_item_t {
     opal_list_item_t super;
-    char *default_value;
+    opal_cstring_t *default_value;
     opal_key_interest_callback_t *callback;
 };
 typedef struct opal_callback_list_item_t opal_callback_list_item_t;
@@ -104,16 +105,16 @@ static void infosubscriber_destruct(opal_infosubscriber_t *obj) {
 
 static void opal_callback_list_item_destruct(opal_callback_list_item_t *obj) {
     if (obj->default_value) {
-        free(obj->default_value); // came from a strdup()
+        OBJ_RELEASE(obj->default_value);
     }
 }
 
-static char* opal_infosubscribe_inform_subscribers(opal_infosubscriber_t *object, char *key, char *new_value, int *found_callback)
+static const char* opal_infosubscribe_inform_subscribers(opal_infosubscriber_t *object, const char *key, const char *new_value, int *found_callback)
 {
     opal_hash_table_t *table = &object->s_subscriber_table;
     opal_list_t *list = NULL;
     opal_callback_list_item_t *item;
-    char *updated_value = NULL;
+    const char *updated_value = NULL;
 
     if (found_callback) { *found_callback = 0; }
 /*
@@ -191,7 +192,7 @@ opal_infosubscribe_testregister(opal_infosubscriber_t *object)
             if (list) {
                 OPAL_LIST_FOREACH(item, list, opal_callback_list_item_t) {
                     if (0 ==
-                        strcmp(item->default_value, testing_initialvals[i])
+                        strcmp(item->default_value->string, testing_initialvals[i])
                         &&
                         item->callback == testing_callbacks[i])
                     {
@@ -225,7 +226,7 @@ opal_infosubscribe_testregister(opal_infosubscriber_t *object)
             OPAL_LIST_FOREACH(item1, list, opal_callback_list_item_t) {
                 OPAL_LIST_FOREACH(item2, list, opal_callback_list_item_t) {
                     if (0 ==
-                        strcmp(item1->default_value, item2->default_value)
+                        strcmp(item1->default_value->string, item2->default_value->string)
                         &&
                         item1->callback == item2->callback)
                     {
@@ -255,7 +256,7 @@ opal_infosubscribe_testregister(opal_infosubscriber_t *object)
 // The last argument indicates whether to overwrite a previous
 // __IN_<key> or not.
 static int
-save_original_key_val(opal_info_t *info, char *key, char *val, int overwrite)
+save_original_key_val(opal_info_t *info, const char *key, opal_cstring_t *val, int overwrite)
 {
     char modkey[OPAL_MAX_INFO_KEY];
     int flag, err;
@@ -267,9 +268,9 @@ save_original_key_val(opal_info_t *info, char *key, char *val, int overwrite)
             OPAL_INFO_SAVE_PREFIX "%s", key);
 // (the prefix macro is a string, so the unreadable part above is a string concatenation)
         flag = 0;
-        opal_info_get(info, modkey, 0, NULL, &flag);
+        opal_info_get(info, modkey, 0, &flag);
         if (!flag || overwrite) {
-            err = opal_info_set(info, modkey, val);
+            err = opal_info_set_cstring(info, modkey, val);
             if (OPAL_SUCCESS != err) {
                 return err;
             }
@@ -291,7 +292,7 @@ opal_infosubscribe_change_info(opal_infosubscriber_t *object, opal_info_t *new_i
 {
     int err;
     opal_info_entry_t *iterator;
-    char *updated_value;
+    const char *updated_value;
 
     /* for each key/value in new info, let subscribers know of new value */
     int found_callback;
@@ -302,27 +303,36 @@ opal_infosubscribe_change_info(opal_infosubscriber_t *object, opal_info_t *new_i
 
     if (NULL != new_info) {
     OPAL_LIST_FOREACH(iterator, &new_info->super, opal_info_entry_t) {
-
-        updated_value = opal_infosubscribe_inform_subscribers(object, iterator->ie_key, iterator->ie_value, &found_callback);
+        opal_cstring_t *value_str, *key_str;
+        value_str = iterator->ie_value;
+        OBJ_RETAIN(value_str);
+        key_str = iterator->ie_key;
+        OBJ_RETAIN(key_str);
+
+        updated_value = opal_infosubscribe_inform_subscribers(object, iterator->ie_key->string,
+                                                              iterator->ie_value->string, &found_callback);
         if (updated_value) {
-            err = opal_info_set(object->s_info, iterator->ie_key, updated_value);
+            err = opal_info_set(object->s_info, iterator->ie_key->string, updated_value);
         } else {
 // This path would happen if there was no callback for this key,
 // or if there was a callback and it returned null. One way the
 // setting was unrecognized the other way it was recognized and ignored,
 // either way it shouldn't be set, which we'll ensure with an unset
 // in case a previous value exists.
-            err = opal_info_delete(object->s_info, iterator->ie_key);
+            err = opal_info_delete(object->s_info, iterator->ie_key->string);
             err = OPAL_SUCCESS; // we don't care if the key was found or not
         }
         if (OPAL_SUCCESS != err) {
+            OBJ_RELEASE(value_str);
+            OBJ_RELEASE(key_str);
             return err;
         }
 // Save the original at "__IN_<key>":"original"
 // And if multiple set-info calls happen, the last would be the most relevant
 // to save, so overwrite a previously saved value if there is one.
-        save_original_key_val(object->s_info,
-            iterator->ie_key, iterator->ie_value, 1);
+        save_original_key_val(object->s_info, key_str->string, value_str, 1);
+        OBJ_RELEASE(value_str);
+        OBJ_RELEASE(key_str);
     }}
 
     return OPAL_SUCCESS;
@@ -346,7 +356,7 @@ opal_infosubscribe_change_info(opal_infosubscriber_t *object, opal_info_t *new_i
 // to me this might be required if the strings become more dynamic than the
 // simple true/false values seen in the current code. It'll be an easy change,
 // callback() is only used two places.
-int opal_infosubscribe_subscribe(opal_infosubscriber_t *object, char *key, char *value, opal_key_interest_callback_t *callback)
+int opal_infosubscribe_subscribe(opal_infosubscriber_t *object, const char *key, const char *value, opal_key_interest_callback_t *callback)
 {
     opal_list_t *list = NULL;
     opal_hash_table_t *table = &object->s_subscriber_table;
@@ -363,7 +373,6 @@ int opal_infosubscribe_subscribe(opal_infosubscriber_t *object, char *key, char
         exit(1);
 #else
         opal_output(0, "The \"%s\" MPI info key almost certainly will not work properly.  You should inform an Open MPI developer about this.", key);
-        key[max_len] = '\0';
 #endif
     }
 
@@ -374,14 +383,10 @@ int opal_infosubscribe_subscribe(opal_infosubscriber_t *object, char *key, char
             list = OBJ_NEW(opal_list_t);
             opal_hash_table_set_value_ptr(table, key, strlen(key), list);
         }
-
+        opal_cstring_t *value_str = opal_cstring_create(value);
         callback_list_item = OBJ_NEW(opal_callback_list_item_t);
         callback_list_item->callback = callback;
-        if (value) {
-            callback_list_item->default_value = strdup(value);
-        } else {
-            callback_list_item->default_value = NULL;
-        }
+        callback_list_item->default_value = value_str;
 
         opal_list_append(list, (opal_list_item_t*) callback_list_item);
 
@@ -398,17 +403,17 @@ int opal_infosubscribe_subscribe(opal_infosubscriber_t *object, char *key, char
         }
 // - is there a value already associated with key in this obj's info:
 //   to use in the callback()
-        char *buffer = malloc(OPAL_MAX_INFO_VAL+1); // (+1 shouldn't be needed)
-        char *val = value; // start as default value
+        opal_cstring_t *val;
         int flag = 0;
-        char *updated_value;
+        const char *updated_value;
         int err;
-        opal_info_get(object->s_info, key, OPAL_MAX_INFO_VAL, buffer, &flag);
-        if (flag) {
-            val = buffer; // become info value if this key was in info
+        opal_info_get(object->s_info, key, &val, &flag);
+        if (!flag) {
+            val = value_str; // fall back to default string
+            OBJ_RETAIN(val);
         }
 // - callback() and modify the val in info
-        updated_value = callback(object, key, val);
+        updated_value = callback(object, key, val->string);
         if (updated_value) {
             err = opal_info_set(object->s_info, key, updated_value);
         } else {
@@ -416,7 +421,7 @@ int opal_infosubscribe_subscribe(opal_infosubscriber_t *object, char *key, char
             err = OPAL_SUCCESS; // we don't care if the key was found or not
         }
         if (OPAL_SUCCESS != err) {
-            free(buffer);
+            OBJ_RELEASE(val);
             return err;
         }
 // - save the previous val under key __IN_*
@@ -428,7 +433,7 @@ int opal_infosubscribe_subscribe(opal_infosubscriber_t *object, char *key, char
 //   up if the user queries later with get_info.
         save_original_key_val(object->s_info, key, val, 0);
 
-        free(buffer);
+        OBJ_RELEASE(val);
     } else {
 /*
  * TODO: This should not happen
-- 
GitLab