diff --git a/opal/dss/dss_load_unload.c b/opal/dss/dss_load_unload.c index 52ca03af79..1b375997cc 100644 --- a/opal/dss/dss_load_unload.c +++ b/opal/dss/dss_load_unload.c @@ -49,19 +49,30 @@ int opal_dss_unload(opal_buffer_t *buffer, void **payload, return OPAL_SUCCESS; } + /* if nothing has been unpacked, we can pass the entire + * region back and protect it - no need to copy. This is + * an optimization */ + if (buffer->unpack_ptr == buffer->base_ptr) { + *payload = buffer->base_ptr; + *bytes_used = buffer->bytes_used; + buffer->base_ptr = NULL; + buffer->unpack_ptr = NULL; + buffer->pack_ptr = NULL; + buffer->bytes_used = 0; + return OPAL_SUCCESS; + } + /* okay, we have something to provide - pass it back */ *bytes_used = buffer->bytes_used - (buffer->unpack_ptr - buffer->base_ptr); if (0 == (*bytes_used)) { *payload = NULL; } else { - *payload = buffer->unpack_ptr; + /* we cannot just set the pointer as it might be + * partway in a malloc'd region */ + *payload = (void*)malloc(*bytes_used); + memcpy(*payload, buffer->unpack_ptr, *bytes_used); } - /* dereference everything in buffer */ - buffer->base_ptr = NULL; - buffer->pack_ptr = buffer->unpack_ptr = NULL; - buffer->bytes_allocated = buffer->bytes_used = 0; - /* All done */ return OPAL_SUCCESS; diff --git a/opal/mca/pmix/pmix1xx/pmix/src/server/pmix_server_ops.c b/opal/mca/pmix/pmix1xx/pmix/src/server/pmix_server_ops.c index 1037e5d5ea..e76c557b38 100644 --- a/opal/mca/pmix/pmix1xx/pmix/src/server/pmix_server_ops.c +++ b/opal/mca/pmix/pmix1xx/pmix/src/server/pmix_server_ops.c @@ -857,7 +857,10 @@ static void _process_dmdx_reply(int fd, short args, void *cbdata) kp->key = strdup("modex"); PMIX_VALUE_CREATE(kp->value, 1); kp->value->type = PMIX_BYTE_OBJECT; - kp->value->data.bo.bytes = (char*)caddy->data; + /* we don't know if the host is going to save this data + * or not, so we have to copy it */ + kp->value->data.bo.bytes = (char*)malloc(caddy->ndata); + memcpy(kp->value->data.bo.bytes, caddy->data, caddy->ndata); kp->value->data.bo.size = caddy->ndata; /* store it in the appropriate hash */ if (PMIX_SUCCESS != (rc = pmix_hash_store(&nptr->server->remote, caddy->lcd->proc.rank, kp))) { diff --git a/orte/orted/pmix/pmix_server.c b/orte/orted/pmix/pmix_server.c index f35f4251d2..953145d9aa 100644 --- a/orte/orted/pmix/pmix_server.c +++ b/orte/orted/pmix/pmix_server.c @@ -537,7 +537,10 @@ static void pmix_server_dmdx_resp(int status, orte_process_name_t* sender, } /* unload the remainder of the buffer */ - opal_dss.unload(buffer, (void**)&data, &ndata); + if (OPAL_SUCCESS != (rc = opal_dss.unload(buffer, (void**)&data, &ndata))) { + ORTE_ERROR_LOG(rc); + return; + } /* if we got something, store the blobs locally so we can * meet any further requests without doing a remote fetch. @@ -565,9 +568,6 @@ static void pmix_server_dmdx_resp(int status, orte_process_name_t* sender, } OBJ_RELEASE(req); } - if (NULL != data) { - free(data); - } } static void opcon(orte_pmix_server_op_caddy_t *p)