/** * Test whether a certain element is already in use. If not yet * in use, reserve it. * * @param array Pointer to array (IN) * @param index Index of element to be tested (IN) * @param value New value to be set at element index (IN) * * @return true/false True if element could be reserved * False if element could not be reserved (e.g.in use). * * In contrary to array_set, this function does not allow to overwrite * a value, unless the previous value is NULL ( equiv. to free ). */ bool pmix_pointer_array_test_and_set_item (pmix_pointer_array_t *table, int index, void *value) { assert(table != NULL); assert(index >= 0); #if 0 pmix_output(0,"pmix_pointer_array_test_and_set_item: IN: " " table %p (size %ld, lowest free %ld, number free %ld)" " addr[%d] = %p\n", table, table->size, table->lowest_free, table->number_free, index, table->addr[index]); #endif /* expand table if required to set a specific index */ if ( index < table->size && table->addr[index] != NULL ) { /* This element is already in use */ return false; } /* Do we need to grow the table? */ if (table->size <= index) { if (!grow_table(table, (((index / TABLE_GROW) + 1) * TABLE_GROW), index)) { return false; } } /* * allow a specific index to be changed. */ table->addr[index] = value; table->number_free--; /* Reset lowest_free if required */ if ( index == table->lowest_free ) { int i; table->lowest_free = table->size; for ( i=index; i<table->size; i++) { if ( NULL == table->addr[i] ){ table->lowest_free = i; break; } } } #if 0 pmix_output(0,"pmix_pointer_array_test_and_set_item: OUT: " " table %p (size %ld, lowest free %ld, number free %ld)" " addr[%d] = %p\n", table, table->size, table->lowest_free, table->number_free, index, table->addr[index]); #endif return true; }
int main(int argc, char **argv) { pmix_status_t rc; pmix_proc_t myproc; pmix_info_t *info; size_t ninfo; /* init us */ if (PMIX_SUCCESS != (rc = PMIx_tool_init(&myproc, NULL, 0))) { fprintf(stderr, "PMIx_tool_init failed: %d\n", rc); exit(rc); } pmix_output(0, "Tool ns %s rank %d: Running", myproc.nspace, myproc.rank); /* query something */ ninfo = 2; PMIX_INFO_CREATE(info, ninfo); (void)strncpy(info[0].key, "foobar", PMIX_MAX_KEYLEN); (void)strncpy(info[1].key, "spastic", PMIX_MAX_KEYLEN); if (PMIX_SUCCESS != (rc = PMIx_Query_info(info, ninfo))) { pmix_output(0, "Client ns %s rank %d: PMIx_Query_info failed: %d", myproc.nspace, myproc.rank, rc); goto done; } if (0 != strncmp(info[0].key, "foobar", PMIX_MAX_KEYLEN)) { pmix_output(0, "Client ns %s rank %d: PMIx_Query_info key[0] wrong: %s vs foobar", myproc.nspace, myproc.rank, info[0].key); } if (0 != strncmp(info[1].key, "spastic", PMIX_MAX_KEYLEN)) { pmix_output(0, "Client ns %s rank %d: PMIx_Query_info key[0] wrong: %s vs spastic", myproc.nspace, myproc.rank, info[1].key); } if (PMIX_STRING != info[0].value.type) { pmix_output(0, "Client ns %s rank %d: PMIx_Query_info key[0] wrong type: %d vs %d", myproc.nspace, myproc.rank, info[0].value.type, PMIX_STRING); } if (PMIX_STRING != info[1].value.type) { pmix_output(0, "Client ns %s rank %d: PMIx_Query_info key[1] wrong type: %d vs %d", myproc.nspace, myproc.rank, info[1].value.type, PMIX_STRING); } if (0 != strcmp(info[0].value.data.string, "0")) { pmix_output(0, "Client ns %s rank %d: PMIx_Query_info key[0] wrong value: %s vs 0", myproc.nspace, myproc.rank, info[1].value.data.string); } if (0 != strcmp(info[1].value.data.string, "1")) { pmix_output(0, "Client ns %s rank %d: PMIx_Query_info key[1] wrong value: %s vs 1", myproc.nspace, myproc.rank, info[1].value.data.string); } PMIX_INFO_FREE(info, ninfo); done: /* finalize us */ pmix_output(0, "Client ns %s rank %d: Finalizing", myproc.nspace, myproc.rank); if (PMIX_SUCCESS != (rc = PMIx_Finalize(NULL, 0))) { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize failed: %d\n", myproc.nspace, myproc.rank, rc); } else { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize successfully completed\n", myproc.nspace, myproc.rank); } fflush(stderr); return(rc); }
char* pmix_net_get_hostname(const struct sockaddr *addr) { char *name = get_hostname_buffer(); int error; socklen_t addrlen; char *p; if (NULL == name) { pmix_output(0, "pmix_sockaddr2str: malloc() failed\n"); return NULL; } memset(name, 0, sizeof(*name)); switch (addr->sa_family) { case AF_INET: addrlen = sizeof (struct sockaddr_in); break; case AF_INET6: #if defined( __NetBSD__) /* hotfix for netbsd: on my netbsd machine, getnameinfo returns an unkown error code. */ if(NULL == inet_ntop(AF_INET6, &((struct sockaddr_in6*) addr)->sin6_addr, name, NI_MAXHOST)) { pmix_output(0, "pmix_sockaddr2str failed with error code %d", errno); free(name); return NULL; } return name; #else addrlen = sizeof (struct sockaddr_in6); #endif break; default: free(name); return NULL; } error = getnameinfo(addr, addrlen, name, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (error) { int err = errno; pmix_output (0, "pmix_sockaddr2str failed:%s (return code %i)\n", gai_strerror(err), error); free (name); return NULL; } /* strip any trailing % data as it isn't pertinent */ if (NULL != (p = strrchr(name, '%'))) { *p = '\0'; } return name; }
static void notification_fn(pmix_status_t status, pmix_proc_t procs[], size_t nprocs, pmix_info_t info[], size_t ninfo) { pmix_output(0, "Client %s:%d NOTIFIED with status %d", myproc.nspace, myproc.rank, status); completed = true; }
static pmix_status_t pmix_bfrops_base_unpack_buffer(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, void *dst, int32_t *num_vals, pmix_data_type_t type) { pmix_status_t rc; pmix_data_type_t local_type; pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output, "pmix_bfrops_base_unpack_buffer( %p, %p, %lu, %d )\n", (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); /** Unpack the declared data type */ if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { if (PMIX_SUCCESS != (rc = pmix_bfrop_get_data_type(regtypes, buffer, &local_type))) { PMIX_ERROR_LOG(rc); return rc; } /* if the data types don't match, then return an error */ if (type != local_type) { pmix_output(0, "PMIX bfrop:unpack: got type %d when expecting type %d", local_type, type); return PMIX_ERR_PACK_MISMATCH; } } PMIX_BFROPS_UNPACK_TYPE(rc, buffer, dst, num_vals, type, regtypes); return rc; }
pmix_status_t pmix_bfrop_unpack_buffer(pmix_buffer_t *buffer, void *dst, int32_t *num_vals, pmix_data_type_t type) { pmix_status_t rc; pmix_data_type_t local_type; pmix_bfrop_type_info_t *info; pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_buffer( %p, %p, %lu, %d )\n", (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); /** Unpack the declared data type */ if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { if (PMIX_SUCCESS != (rc = pmix_bfrop_get_data_type(buffer, &local_type))) { return rc; } /* if the data types don't match, then return an error */ if (type != local_type) { pmix_output(0, "PMIX bfrop:unpack: got type %d when expecting type %d", local_type, type); return PMIX_ERR_PACK_MISMATCH; } } /* Lookup the unpack function for this type and call it */ if (NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&pmix_bfrop_types, type))) { return PMIX_ERR_UNPACK_FAILURE; } return info->odti_unpack_fn(buffer, dst, num_vals, type); }
/** * Returns true if the given address is a public IPv4 address. */ bool pmix_net_addr_isipv4public(const struct sockaddr *addr) { switch (addr->sa_family) { case AF_INET6: return false; case AF_INET: { const struct sockaddr_in *inaddr = (struct sockaddr_in*) addr; int i; if( NULL == private_ipv4 ) { return true; } for( i = 0; private_ipv4[i].addr != 0; i++ ) { if( private_ipv4[i].addr == (inaddr->sin_addr.s_addr & pmix_net_prefix2netmask(private_ipv4[i].netmask_bits)) ) return false; } } return true; default: pmix_output (0, "unhandled sa_family %d passed to pmix_net_addr_isipv4public\n", addr->sa_family); } return false; }
bool pmix_net_islocalhost(const struct sockaddr *addr) { switch (addr->sa_family) { case AF_INET: { const struct sockaddr_in *inaddr = (struct sockaddr_in*) addr; /* if it's in the 127. domain, it shouldn't be routed (0x7f == 127) */ if (0x7F000000 == (0x7F000000 & ntohl(inaddr->sin_addr.s_addr))) { return true; } return false; } break; case AF_INET6: { const struct sockaddr_in6 *inaddr = (struct sockaddr_in6*) addr; if (IN6_IS_ADDR_LOOPBACK (&inaddr->sin6_addr)) { return true; /* Bug, FIXME: check for 127.0.0.1/8 */ } return false; } break; default: pmix_output(0, "unhandled sa_family %d passed to pmix_net_islocalhost", addr->sa_family); return false; break; } }
static void opcbfunc(pmix_status_t status, void *cbdata) { bool *active = (bool*)cbdata; pmix_output(0, "%s:%d completed fence_nb", myproc.nspace, myproc.rank); *active = false; }
/* * A blocking send on a non-blocking socket. Used to send the small amount of connection * information that identifies the peers endpoint. */ pmix_status_t pmix_usock_send_blocking(int sd, char *ptr, size_t size) { size_t cnt = 0; int retval; pmix_output_verbose(8, pmix_globals.debug_output, "send blocking of %"PRIsize_t" bytes to socket %d", size, sd ); while (cnt < size) { retval = send(sd, (char*)ptr+cnt, size-cnt, 0); if (retval < 0) { if (EAGAIN == pmix_socket_errno || EWOULDBLOCK == pmix_socket_errno) { /* just cycle and let it try again */ pmix_output_verbose(8, pmix_globals.debug_output, "blocking_send received error %d:%s from remote - cycling", pmix_socket_errno, strerror(pmix_socket_errno)); continue; } if (pmix_socket_errno != EINTR) { pmix_output(8, "usock_peer_send_blocking: send() to socket %d failed: %s (%d)\n", sd, strerror(pmix_socket_errno), pmix_socket_errno); return PMIX_ERR_UNREACH; } continue; } cnt += retval; } pmix_output_verbose(8, pmix_globals.debug_output, "blocking send complete to socket %d", sd); return PMIX_SUCCESS; }
static void errhandler_reg_callbk (pmix_status_t status, int errhandler_ref, void *cbdata) { pmix_output(0, "Client: ERRHANDLER REGISTRATION CALLBACK CALLED WITH STATUS %d, ref=%d", status, errhandler_ref); }
int pmix_usock_set_blocking(int sd) { int flags; /* setup the socket as non-blocking */ if ((flags = fcntl(sd, F_GETFL, 0)) < 0) { pmix_output(0, "usock_peer_connect: fcntl(F_GETFL) failed: %s (%d)\n", strerror(pmix_socket_errno), pmix_socket_errno); } else { flags &= ~(O_NONBLOCK); if(fcntl(sd, F_SETFL, flags) < 0) pmix_output(0, "usock_peer_connect: fcntl(F_SETFL) failed: %s (%d)\n", strerror(pmix_socket_errno), pmix_socket_errno); } return PMIX_SUCCESS; }
static void errhandler_reg_callbk(pmix_status_t status, size_t errhandler_ref, void *cbdata) { volatile bool *active = (volatile bool*)cbdata; pmix_output(0, "Client: ERRHANDLER REGISTRATION CALLBACK CALLED WITH STATUS %d, ref=%lu", status, (unsigned long)errhandler_ref); *active = false; }
int pmix_compress_bzip_compress_nb(char * fname, char **cname, char **postfix, pid_t *child_pid) { char **argv = NULL; char * base_fname = NULL; char * dir_fname = NULL; int status; bool is_dir; is_dir = is_directory(fname); *child_pid = fork(); if( *child_pid == 0 ) { /* Child */ char * cmd; dir_fname = pmix_dirname(fname); base_fname = pmix_basename(fname); chdir(dir_fname); if( is_dir ) { pmix_asprintf(cname, "%s.tar.bz2", base_fname); pmix_asprintf(&cmd, "tar -jcf %s %s", *cname, base_fname); } else { pmix_asprintf(cname, "%s.bz2", base_fname); pmix_asprintf(&cmd, "bzip2 %s", base_fname); } pmix_output_verbose(10, mca_compress_bzip_component.super.output_handle, "compress:bzip: compress_nb(%s -> [%s])", fname, *cname); pmix_output_verbose(10, mca_compress_bzip_component.super.output_handle, "compress:bzip: compress_nb() command [%s]", cmd); argv = pmix_argv_split(cmd, ' '); status = execvp(argv[0], argv); pmix_output(0, "compress:bzip: compress_nb: Failed to exec child [%s] status = %d\n", cmd, status); exit(PMIX_ERROR); } else if( *child_pid > 0 ) { if( is_dir ) { *postfix = strdup(".tar.bz2"); } else { *postfix = strdup(".bz2"); } pmix_asprintf(cname, "%s%s", fname, *postfix); } else { return PMIX_ERROR; } return PMIX_SUCCESS; }
/** * Set the value of the dynamic array at a specified location. * * * @param table Pointer to pmix_pointer_array_t object (IN) * @param ptr Pointer to be added to table (IN) * * @return Error code * * Assumption: NULL element is free element. */ pmix_status_t pmix_pointer_array_set_item(pmix_pointer_array_t *table, int index, void * value) { assert(table != NULL); /* expand table if required to set a specific index */ if (table->size <= index) { if (!grow_table(table, ((index / TABLE_GROW) + 1) * TABLE_GROW, index)) { return PMIX_ERROR; } } /* mark element as free, if NULL element */ if( NULL == value ) { if (index < table->lowest_free) { table->lowest_free = index; } if( NULL != table->addr[index] ) { table->number_free++; } } else { if (NULL == table->addr[index]) { table->number_free--; } /* Reset lowest_free if required */ if ( index == table->lowest_free ) { int i; table->lowest_free = table->size; for ( i=index + 1; i<table->size; i++) { if ( NULL == table->addr[i] ){ table->lowest_free = i; break; } } } } table->addr[index] = value; #if 0 pmix_output(0,"pmix_pointer_array_set_item: OUT: " " table %p (size %ld, lowest free %ld, number free %ld)" " addr[%d] = %p\n", table, table->size, table->lowest_free, table->number_free, index, table->addr[index]); #endif return PMIX_SUCCESS; }
/* * PMIX_VALUE */ pmix_status_t pmix_bfrops_base_unpack_val(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, pmix_value_t *val) { int m; pmix_status_t ret = PMIX_SUCCESS; m = 1; switch (val->type) { case PMIX_UNDEF: break; case PMIX_PROC: /* this field is now a pointer, so we must allocate storage for it */ PMIX_PROC_CREATE(val->data.proc, m); if (NULL == val->data.proc) { return PMIX_ERR_NOMEM; } PMIX_BFROPS_UNPACK_TYPE(ret, buffer, val->data.proc, &m, PMIX_PROC, regtypes); break; case PMIX_PROC_INFO: /* this is now a pointer, so allocate storage for it */ PMIX_PROC_INFO_CREATE(val->data.pinfo, 1); if (NULL == val->data.pinfo) { return PMIX_ERR_NOMEM; } PMIX_BFROPS_UNPACK_TYPE(ret, buffer, val->data.pinfo, &m, PMIX_PROC_INFO, regtypes); break; case PMIX_DATA_ARRAY: /* this is now a pointer, so allocate storage for it */ val->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); if (NULL == val->data.darray) { return PMIX_ERR_NOMEM; } PMIX_BFROPS_UNPACK_TYPE(ret, buffer, val->data.darray, &m, PMIX_DATA_ARRAY, regtypes); break; case PMIX_COORD: val->data.coord = (pmix_coord_t*)malloc(sizeof(pmix_coord_t)); if (NULL == val->data.coord) { return PMIX_ERR_NOMEM; } PMIX_BFROPS_UNPACK_TYPE(ret, buffer, val->data.coord, &m, PMIX_COORD, regtypes); return ret; default: PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &val->data, &m, val->type, regtypes); if (PMIX_ERR_UNKNOWN_DATA_TYPE == ret) { pmix_output(0, "UNPACK-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)val->type); } } return ret; }
/* compare function for pmix_value_t*/ bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1) { bool rc = false; switch (p->type) { case PMIX_BOOL: rc = (p->data.flag == p1->data.flag); break; case PMIX_BYTE: rc = (p->data.byte == p1->data.byte); break; case PMIX_SIZE: rc = (p->data.size == p1->data.size); break; case PMIX_INT: rc = (p->data.integer == p1->data.integer); break; case PMIX_INT8: rc = (p->data.int8 == p1->data.int8); break; case PMIX_INT16: rc = (p->data.int16 == p1->data.int16); break; case PMIX_INT32: rc = (p->data.int32 == p1->data.int32); break; case PMIX_INT64: rc = (p->data.int64 == p1->data.int64); break; case PMIX_UINT: rc = (p->data.uint == p1->data.uint); break; case PMIX_UINT8: rc = (p->data.uint8 == p1->data.int8); break; case PMIX_UINT16: rc = (p->data.uint16 == p1->data.uint16); break; case PMIX_UINT32: rc = (p->data.uint32 == p1->data.uint32); break; case PMIX_UINT64: rc = (p->data.uint64 == p1->data.uint64); break; case PMIX_STRING: rc = strcmp(p->data.string, p1->data.string); break; default: pmix_output(0, "COMPARE-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)p->type); } return rc; }
static void notification_fn(size_t evhdlr_registration_id, pmix_status_t status, const pmix_proc_t *source, pmix_info_t info[], size_t ninfo, pmix_info_t results[], size_t nresults, pmix_event_notification_cbfunc_fn_t cbfunc, void *cbdata) { pmix_output(0, "Client %s:%d NOTIFIED with status %s", myproc.nspace, myproc.rank, PMIx_Error_string(status)); if (NULL != cbfunc) { cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata); } completed = true; }
int pmix_net_init(void) { char **args, *arg; uint32_t a, b, c, d, bits, addr; int i, count, found_bad = 0; args = pmix_argv_split(pmix_net_private_ipv4, ';'); if( NULL != args ) { count = pmix_argv_count(args); private_ipv4 = (private_ipv4_t*)malloc( (count + 1) * sizeof(private_ipv4_t)); if( NULL == private_ipv4 ) { pmix_output(0, "Unable to allocate memory for the private addresses array" ); pmix_argv_free(args); goto do_local_init; } for( i = 0; i < count; i++ ) { arg = args[i]; (void)sscanf( arg, "%u.%u.%u.%u/%u", &a, &b, &c, &d, &bits ); if( (a > 255) || (b > 255) || (c > 255) || (d > 255) || (bits > 32) ) { if (0 == found_bad) { pmix_show_help("help-pmix-runtime.txt", "malformed net_private_ipv4", true, args[i]); found_bad = 1; } continue; } addr = (a << 24) | (b << 16) | (c << 8) | d; private_ipv4[i].addr = htonl(addr); private_ipv4[i].netmask_bits = bits; } private_ipv4[i].addr = 0; private_ipv4[i].netmask_bits = 0; pmix_argv_free(args); } do_local_init: return pmix_tsd_key_create(&hostname_tsd_key, hostname_cleanup); }
static pmix_status_t send_bytes(int sd, char **buf, size_t *remain) { pmix_status_t ret = PMIX_SUCCESS; int rc; char *ptr = *buf; while (0 < *remain) { rc = write(sd, ptr, *remain); if (rc < 0) { if (pmix_socket_errno == EINTR) { continue; } else if (pmix_socket_errno == EAGAIN) { /* tell the caller to keep this message on active, * but let the event lib cycle so other messages * can progress while this socket is busy */ ret = PMIX_ERR_RESOURCE_BUSY; goto exit; } else if (pmix_socket_errno == EWOULDBLOCK) { /* tell the caller to keep this message on active, * but let the event lib cycle so other messages * can progress while this socket is busy */ ret = PMIX_ERR_WOULD_BLOCK; goto exit; } /* we hit an error and cannot progress this message */ pmix_output(0, "pmix_usock_msg_send_bytes: write failed: %s (%d) [sd = %d]", strerror(pmix_socket_errno), pmix_socket_errno, sd); ret = PMIX_ERR_COMM_FAILURE; goto exit; } /* update location */ (*remain) -= rc; ptr += rc; } /* we sent the full data block */ exit: *buf = ptr; return ret; }
static void valcbfunc(pmix_status_t status, pmix_value_t *val, void *cbdata) { char *key = (char*)cbdata; if (PMIX_SUCCESS == status) { if (NULL != strstr(key, "local")) { if (PMIX_UINT64 != val->type) { pmix_output(0, "%s:%d: PMIx_Get_nb Key %s returned wrong type: %d", myproc.nspace, myproc.rank, key, val->type); goto done; } if (1234 != val->data.uint64) { pmix_output(0, "%s:%d: PMIx_Get_nb Key %s returned wrong value: %d", myproc.nspace, myproc.rank, key, (int)val->data.uint64); goto done; } } else if (NULL != strstr(key, "remote")) { if (PMIX_STRING != val->type) { pmix_output(0, "%s:%d: PMIx_Get_nb Key %s returned wrong type: %d", myproc.nspace, myproc.rank, key, val->type); goto done; } if (0 != strcmp(val->data.string, "1234")) { pmix_output(0, "%s:%d: PMIx_Get_nb Key %s returned wrong value: %s", myproc.nspace, myproc.rank, key, val->data.string); goto done; } } else { pmix_output(0, "%s:%d PMIx_Get_nb returned wrong key: %s", myproc.nspace, myproc.rank, key); goto done; } pmix_output(0, "%s:%d PMIx_Get_nb Key %s returned correctly", myproc.nspace, myproc.rank, key); } else { pmix_output(0, "%s:%d PMIx_Get_nb Key %s failed", myproc.nspace, myproc.rank, key); } done: free(key); getcount++; }
/* COPY FUNCTIONS FOR GENERIC PMIX TYPES */ int pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) { pmix_info_t *p1, *s1; /* copy the right field */ p->type = src->type; switch (src->type) { case PMIX_BOOL: p->data.flag = src->data.flag; break; case PMIX_BYTE: p->data.byte = src->data.byte; break; case PMIX_STRING: if (NULL != src->data.string) { p->data.string = strdup(src->data.string); } else { p->data.string = NULL; } break; case PMIX_SIZE: p->data.size = src->data.size; break; case PMIX_PID: p->data.pid = src->data.pid; break; case PMIX_INT: /* to avoid alignment issues */ memcpy(&p->data.integer, &src->data.integer, sizeof(int)); break; case PMIX_INT8: p->data.int8 = src->data.int8; break; case PMIX_INT16: /* to avoid alignment issues */ memcpy(&p->data.int16, &src->data.int16, 2); break; case PMIX_INT32: /* to avoid alignment issues */ memcpy(&p->data.int32, &src->data.int32, 4); break; case PMIX_INT64: /* to avoid alignment issues */ memcpy(&p->data.int64, &src->data.int64, 8); break; case PMIX_UINT: /* to avoid alignment issues */ memcpy(&p->data.uint, &src->data.uint, sizeof(unsigned int)); break; case PMIX_UINT8: p->data.uint8 = src->data.uint8; break; case PMIX_UINT16: /* to avoid alignment issues */ memcpy(&p->data.uint16, &src->data.uint16, 2); break; case PMIX_UINT32: /* to avoid alignment issues */ memcpy(&p->data.uint32, &src->data.uint32, 4); break; case PMIX_UINT64: /* to avoid alignment issues */ memcpy(&p->data.uint64, &src->data.uint64, 8); break; case PMIX_FLOAT: p->data.fval = src->data.fval; break; case PMIX_DOUBLE: p->data.dval = src->data.dval; break; case PMIX_TIMEVAL: p->data.tv.tv_sec = src->data.tv.tv_sec; p->data.tv.tv_usec = src->data.tv.tv_usec; break; case PMIX_INFO_ARRAY: p->data.array.size = src->data.array.size; if (0 < src->data.array.size) { p->data.array.array = (struct pmix_info_t*)malloc(src->data.array.size * sizeof(pmix_info_t)); p1 = (pmix_info_t*)p->data.array.array; s1 = (pmix_info_t*)src->data.array.array; memcpy(p1, s1, src->data.array.size * sizeof(pmix_info_t)); } break; case PMIX_BYTE_OBJECT: if (NULL != src->data.bo.bytes && 0 < src->data.bo.size) { p->data.bo.bytes = malloc(src->data.bo.size); memcpy(p->data.bo.bytes, src->data.bo.bytes, src->data.bo.size); p->data.bo.size = src->data.bo.size; } else { p->data.bo.bytes = NULL; p->data.bo.size = 0; } break; default: pmix_output(0, "COPY-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)src->type); return PMIX_ERROR; } return PMIX_SUCCESS; }
/* PACK FUNCTIONS FOR GENERIC PMIX TYPES */ static int pack_val(pmix_buffer_t *buffer, pmix_value_t *p) { int ret; switch (p->type) { case PMIX_BOOL: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.flag, 1, PMIX_BOOL))) { return ret; } break; case PMIX_BYTE: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.byte, 1, PMIX_BYTE))) { return ret; } break; case PMIX_STRING: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.string, 1, PMIX_STRING))) { return ret; } break; case PMIX_SIZE: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.size, 1, PMIX_SIZE))) { return ret; } break; case PMIX_PID: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.pid, 1, PMIX_PID))) { return ret; } break; case PMIX_INT: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.integer, 1, PMIX_INT))) { return ret; } break; case PMIX_INT8: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.int8, 1, PMIX_INT8))) { return ret; } break; case PMIX_INT16: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.int16, 1, PMIX_INT16))) { return ret; } break; case PMIX_INT32: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.int32, 1, PMIX_INT32))) { return ret; } break; case PMIX_INT64: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.int64, 1, PMIX_INT64))) { return ret; } break; case PMIX_UINT: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.uint, 1, PMIX_UINT))) { return ret; } break; case PMIX_UINT8: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.uint8, 1, PMIX_UINT8))) { return ret; } break; case PMIX_UINT16: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.uint16, 1, PMIX_UINT16))) { return ret; } break; case PMIX_UINT32: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.uint32, 1, PMIX_UINT32))) { return ret; } break; case PMIX_UINT64: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.uint64, 1, PMIX_UINT64))) { return ret; } break; case PMIX_FLOAT: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.fval, 1, PMIX_FLOAT))) { return ret; } break; case PMIX_DOUBLE: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.dval, 1, PMIX_DOUBLE))) { return ret; } break; case PMIX_TIMEVAL: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.tv, 1, PMIX_TIMEVAL))) { return ret; } break; case PMIX_STATUS: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.status, 1, PMIX_STATUS))) { return ret; } break; case PMIX_INFO_ARRAY: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.array, 1, PMIX_INFO_ARRAY))) { return ret; } break; case PMIX_BYTE_OBJECT: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.bo, 1, PMIX_BYTE_OBJECT))) { return ret; } break; default: pmix_output(0, "PACK-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)p->type); return PMIX_ERROR; } return PMIX_SUCCESS; }
/* PACK FUNCTIONS FOR GENERIC PMIX TYPES */ static pmix_status_t pack_val(pmix_buffer_t *buffer, pmix_value_t *p) { pmix_status_t ret; pmix_info_array_t array; switch (p->type) { case PMIX_BOOL: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.flag, 1, PMIX_BOOL))) { return ret; } break; case PMIX_BYTE: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.byte, 1, PMIX_BYTE))) { return ret; } break; case PMIX_STRING: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.string, 1, PMIX_STRING))) { return ret; } break; case PMIX_SIZE: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.size, 1, PMIX_SIZE))) { return ret; } break; case PMIX_PID: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.pid, 1, PMIX_PID))) { return ret; } break; case PMIX_INT: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.integer, 1, PMIX_INT))) { return ret; } break; case PMIX_INT8: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.int8, 1, PMIX_INT8))) { return ret; } break; case PMIX_INT16: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.int16, 1, PMIX_INT16))) { return ret; } break; case PMIX_INT32: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.int32, 1, PMIX_INT32))) { return ret; } break; case PMIX_INT64: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.int64, 1, PMIX_INT64))) { return ret; } break; case PMIX_UINT: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.uint, 1, PMIX_UINT))) { return ret; } break; case PMIX_UINT8: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.uint8, 1, PMIX_UINT8))) { return ret; } break; case PMIX_UINT16: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.uint16, 1, PMIX_UINT16))) { return ret; } break; case PMIX_UINT32: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.uint32, 1, PMIX_UINT32))) { return ret; } break; case PMIX_UINT64: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.uint64, 1, PMIX_UINT64))) { return ret; } break; case PMIX_FLOAT: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.fval, 1, PMIX_FLOAT))) { return ret; } break; case PMIX_DOUBLE: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.dval, 1, PMIX_DOUBLE))) { return ret; } break; case PMIX_TIMEVAL: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.tv, 1, PMIX_TIMEVAL))) { return ret; } break; case PMIX_INFO_ARRAY: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, p->data.array, 1, PMIX_INFO_ARRAY))) { return ret; } break; case PMIX_BYTE_OBJECT: if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &p->data.bo, 1, PMIX_BYTE_OBJECT))) { return ret; } break; case PMIX_DATA_ARRAY: /* must convert this to an in info array for v1.2 */ if (PMIX_INFO != p->data.darray->type) { return PMIX_ERR_NOT_SUPPORTED; } array.size = p->data.darray->size; array.array = (pmix_info_t*)p->data.darray->array; if (PMIX_SUCCESS != (ret = pmix12_bfrop_pack_buffer(buffer, &array, 1, PMIX_INFO_ARRAY))) { return ret; } break; default: pmix_output(0, "PACK-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)p->type); return PMIX_ERROR; } return PMIX_SUCCESS; }
void pmix_usock_recv_handler(int sd, short flags, void *cbdata) { pmix_status_t rc; pmix_peer_t *peer = (pmix_peer_t*)cbdata; pmix_ptl_recv_t *msg = NULL; /* acquire the object */ PMIX_ACQUIRE_OBJECT(peer); pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:recv:handler called with peer %s:%d", (NULL == peer) ? "NULL" : peer->info->pname.nspace, (NULL == peer) ? PMIX_RANK_UNDEF : peer->info->pname.rank); if (NULL == peer) { return; } /* allocate a new message and setup for recv */ if (NULL == peer->recv_msg) { pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:recv:handler allocate new recv msg"); peer->recv_msg = PMIX_NEW(pmix_ptl_recv_t); if (NULL == peer->recv_msg) { pmix_output(0, "usock_recv_handler: unable to allocate recv message\n"); goto err_close; } PMIX_RETAIN(peer); peer->recv_msg->peer = peer; // provide a handle back to the peer object /* start by reading the header */ peer->recv_msg->rdptr = (char*)&peer->recv_msg->hdr; peer->recv_msg->rdbytes = sizeof(pmix_usock_hdr_t); } msg = peer->recv_msg; msg->sd = sd; /* if the header hasn't been completely read, read it */ if (!msg->hdr_recvd) { pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:recv:handler read hdr on socket %d", peer->sd); if (PMIX_SUCCESS == (rc = read_bytes(peer->sd, &msg->rdptr, &msg->rdbytes))) { /* completed reading the header */ peer->recv_msg->hdr_recvd = true; pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "RECVD MSG FOR TAG %d SIZE %d", (int)peer->recv_msg->hdr.tag, (int)peer->recv_msg->hdr.nbytes); /* if this is a zero-byte message, then we are done */ if (0 == peer->recv_msg->hdr.nbytes) { pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "RECVD ZERO-BYTE MESSAGE FROM %s:%d for tag %d", peer->info->pname.nspace, peer->info->pname.rank, peer->recv_msg->hdr.tag); peer->recv_msg->data = NULL; // make sure peer->recv_msg->rdptr = NULL; peer->recv_msg->rdbytes = 0; /* post it for delivery */ PMIX_ACTIVATE_POST_MSG(peer->recv_msg); peer->recv_msg = NULL; PMIX_POST_OBJECT(peer); return; } else { pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:recv:handler allocate data region of size %lu", (unsigned long)peer->recv_msg->hdr.nbytes); /* allocate the data region */ peer->recv_msg->data = (char*)malloc(peer->recv_msg->hdr.nbytes); memset(peer->recv_msg->data, 0, peer->recv_msg->hdr.nbytes); /* point to it */ peer->recv_msg->rdptr = peer->recv_msg->data; peer->recv_msg->rdbytes = peer->recv_msg->hdr.nbytes; } /* fall thru and attempt to read the data */ } else if (PMIX_ERR_RESOURCE_BUSY == rc || PMIX_ERR_WOULD_BLOCK == rc) { /* exit this event and let the event lib progress */ return; } else { /* the remote peer closed the connection - report that condition * and let the caller know */ pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "pmix_usock_msg_recv: peer closed connection"); goto err_close; } } if (peer->recv_msg->hdr_recvd) { /* continue to read the data block - we start from * wherever we left off, which could be at the * beginning or somewhere in the message */ if (PMIX_SUCCESS == (rc = read_bytes(peer->sd, &msg->rdptr, &msg->rdbytes))) { /* we recvd all of the message */ pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "RECVD COMPLETE MESSAGE FROM SERVER OF %d BYTES FOR TAG %d ON PEER SOCKET %d", (int)peer->recv_msg->hdr.nbytes, peer->recv_msg->hdr.tag, peer->sd); /* post it for delivery */ PMIX_ACTIVATE_POST_MSG(peer->recv_msg); peer->recv_msg = NULL; /* ensure we post the modified peer object before another thread * picks it back up */ PMIX_POST_OBJECT(peer); return; } else if (PMIX_ERR_RESOURCE_BUSY == rc || PMIX_ERR_WOULD_BLOCK == rc) { /* exit this event and let the event lib progress */ /* ensure we post the modified peer object before another thread * picks it back up */ PMIX_POST_OBJECT(peer); return; } else { /* the remote peer closed the connection - report that condition * and let the caller know */ pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "pmix_usock_msg_recv: peer closed connection"); goto err_close; } } /* success */ return; err_close: /* stop all events */ if (peer->recv_ev_active) { pmix_event_del(&peer->recv_event); peer->recv_ev_active = false; } if (peer->send_ev_active) { pmix_event_del(&peer->send_event); peer->send_ev_active = false; } if (NULL != peer->recv_msg) { PMIX_RELEASE(peer->recv_msg); peer->recv_msg = NULL; } pmix_ptl_base_lost_connection(peer, PMIX_ERR_UNREACH); /* ensure we post the modified peer object before another thread * picks it back up */ PMIX_POST_OBJECT(peer); }
/* * A file descriptor is available/ready for send. Check the state * of the socket and take the appropriate action. */ void pmix_usock_send_handler(int sd, short flags, void *cbdata) { pmix_peer_t *peer = (pmix_peer_t*)cbdata; pmix_ptl_send_t *msg = peer->send_msg; pmix_status_t rc; uint32_t nbytes; /* acquire the object */ PMIX_ACQUIRE_OBJECT(peer); pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "%s:%d usock:send_handler SENDING TO PEER %s:%d tag %u with %s msg", pmix_globals.myid.nspace, pmix_globals.myid.rank, peer->info->pname.nspace, peer->info->pname.rank, (NULL == msg) ? UINT_MAX : msg->hdr.tag, (NULL == msg) ? "NULL" : "NON-NULL"); if (NULL != msg) { if (!msg->hdr_sent) { if (PMIX_PROC_IS_SERVER(pmix_globals.mypeer)) { /* we have to convert the header back to host-byte order */ msg->hdr.pindex = ntohl(msg->hdr.pindex); msg->hdr.tag = ntohl(msg->hdr.tag); nbytes = msg->hdr.nbytes; msg->hdr.nbytes = ntohl(nbytes); } pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:send_handler SENDING HEADER WITH MSG IDX %d TAG %d SIZE %lu", msg->hdr.pindex, msg->hdr.tag, (unsigned long)msg->hdr.nbytes); if (PMIX_SUCCESS == (rc = send_bytes(peer->sd, &msg->sdptr, &msg->sdbytes))) { /* header is completely sent */ pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:send_handler HEADER SENT"); msg->hdr_sent = true; /* setup to send the data */ if (NULL == msg->data) { /* this was a zero-byte msg - nothing more to do */ PMIX_RELEASE(msg); peer->send_msg = NULL; goto next; } else { /* send the data as a single block */ msg->sdptr = msg->data->base_ptr; msg->sdbytes = msg->hdr.nbytes; } /* fall thru and let the send progress */ } else if (PMIX_ERR_RESOURCE_BUSY == rc || PMIX_ERR_WOULD_BLOCK == rc) { /* exit this event and let the event lib progress */ pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:send_handler RES BUSY OR WOULD BLOCK"); if (PMIX_PROC_IS_SERVER(pmix_globals.mypeer)) { /* have to convert back again so we are correct when we re-enter */ msg->hdr.pindex = htonl(msg->hdr.pindex); msg->hdr.tag = htonl(msg->hdr.tag); nbytes = msg->hdr.nbytes; msg->hdr.nbytes = htonl(nbytes); } /* ensure we post the modified peer object before another thread * picks it back up */ PMIX_POST_OBJECT(peer); return; } else { // report the error event_del(&peer->send_event); peer->send_ev_active = false; PMIX_RELEASE(msg); peer->send_msg = NULL; pmix_ptl_base_lost_connection(peer, rc); /* ensure we post the modified peer object before another thread * picks it back up */ PMIX_POST_OBJECT(peer); return; } } if (msg->hdr_sent) { pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:send_handler SENDING BODY OF MSG"); if (PMIX_SUCCESS == (rc = send_bytes(peer->sd, &msg->sdptr, &msg->sdbytes))) { // message is complete pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:send_handler BODY SENT"); PMIX_RELEASE(msg); peer->send_msg = NULL; } else if (PMIX_ERR_RESOURCE_BUSY == rc || PMIX_ERR_WOULD_BLOCK == rc) { /* exit this event and let the event lib progress */ pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "usock:send_handler RES BUSY OR WOULD BLOCK"); /* ensure we post the modified peer object before another thread * picks it back up */ PMIX_POST_OBJECT(peer); return; } else { // report the error pmix_output(0, "pmix_usock_peer_send_handler: unable to send message ON SOCKET %d", peer->sd); pmix_event_del(&peer->send_event); peer->send_ev_active = false; PMIX_RELEASE(msg); peer->send_msg = NULL; pmix_ptl_base_lost_connection(peer, rc); /* ensure we post the modified peer object before another thread * picks it back up */ PMIX_POST_OBJECT(peer); return; } } next: /* if current message completed - progress any pending sends by * moving the next in the queue into the "on-deck" position. Note * that this doesn't mean we send the message right now - we will * wait for another send_event to fire before doing so. This gives * us a chance to service any pending recvs. */ peer->send_msg = (pmix_ptl_send_t*) pmix_list_remove_first(&peer->send_queue); } /* if nothing else to do unregister for send event notifications */ if (NULL == peer->send_msg && peer->send_ev_active) { pmix_event_del(&peer->send_event); peer->send_ev_active = false; } /* ensure we post the modified peer object before another thread * picks it back up */ PMIX_POST_OBJECT(peer); }
/* Xfer FUNCTIONS FOR GENERIC PMIX TYPES */ pmix_status_t pmix_bfrops_base_value_xfer(pmix_value_t *p, pmix_value_t *src) { /* copy the right field */ p->type = src->type; switch (src->type) { case PMIX_UNDEF: break; case PMIX_BOOL: p->data.flag = src->data.flag; break; case PMIX_BYTE: p->data.byte = src->data.byte; break; case PMIX_STRING: if (NULL != src->data.string) { p->data.string = strdup(src->data.string); } else { p->data.string = NULL; } break; case PMIX_SIZE: p->data.size = src->data.size; break; case PMIX_PID: p->data.pid = src->data.pid; break; case PMIX_INT: /* to avoid alignment issues */ memcpy(&p->data.integer, &src->data.integer, sizeof(int)); break; case PMIX_INT8: p->data.int8 = src->data.int8; break; case PMIX_INT16: /* to avoid alignment issues */ memcpy(&p->data.int16, &src->data.int16, 2); break; case PMIX_INT32: /* to avoid alignment issues */ memcpy(&p->data.int32, &src->data.int32, 4); break; case PMIX_INT64: /* to avoid alignment issues */ memcpy(&p->data.int64, &src->data.int64, 8); break; case PMIX_UINT: /* to avoid alignment issues */ memcpy(&p->data.uint, &src->data.uint, sizeof(unsigned int)); break; case PMIX_UINT8: p->data.uint8 = src->data.uint8; break; case PMIX_UINT16: /* to avoid alignment issues */ memcpy(&p->data.uint16, &src->data.uint16, 2); break; case PMIX_UINT32: /* to avoid alignment issues */ memcpy(&p->data.uint32, &src->data.uint32, 4); break; case PMIX_UINT64: /* to avoid alignment issues */ memcpy(&p->data.uint64, &src->data.uint64, 8); break; case PMIX_FLOAT: p->data.fval = src->data.fval; break; case PMIX_DOUBLE: p->data.dval = src->data.dval; break; case PMIX_TIMEVAL: memcpy(&p->data.tv, &src->data.tv, sizeof(struct timeval)); break; case PMIX_TIME: memcpy(&p->data.time, &src->data.time, sizeof(time_t)); break; case PMIX_STATUS: memcpy(&p->data.status, &src->data.status, sizeof(pmix_status_t)); break; case PMIX_PROC: PMIX_PROC_CREATE(p->data.proc, 1); if (NULL == p->data.proc) { return PMIX_ERR_NOMEM; } memcpy(p->data.proc, src->data.proc, sizeof(pmix_proc_t)); break; case PMIX_PROC_RANK: memcpy(&p->data.rank, &src->data.rank, sizeof(pmix_rank_t)); break; case PMIX_BYTE_OBJECT: case PMIX_COMPRESSED_STRING: memset(&p->data.bo, 0, sizeof(pmix_byte_object_t)); if (NULL != src->data.bo.bytes && 0 < src->data.bo.size) { p->data.bo.bytes = malloc(src->data.bo.size); memcpy(p->data.bo.bytes, src->data.bo.bytes, src->data.bo.size); p->data.bo.size = src->data.bo.size; } else { p->data.bo.bytes = NULL; p->data.bo.size = 0; } break; case PMIX_PERSIST: memcpy(&p->data.persist, &src->data.persist, sizeof(pmix_persistence_t)); break; case PMIX_SCOPE: memcpy(&p->data.scope, &src->data.scope, sizeof(pmix_scope_t)); break; case PMIX_DATA_RANGE: memcpy(&p->data.range, &src->data.range, sizeof(pmix_data_range_t)); break; case PMIX_PROC_STATE: memcpy(&p->data.state, &src->data.state, sizeof(pmix_proc_state_t)); break; case PMIX_PROC_INFO: return pmix_bfrops_base_copy_pinfo(&p->data.pinfo, src->data.pinfo, PMIX_PROC_INFO); case PMIX_DATA_ARRAY: return pmix_bfrops_base_copy_darray(&p->data.darray, src->data.darray, PMIX_DATA_ARRAY); case PMIX_POINTER: p->data.ptr = src->data.ptr; break; case PMIX_ENVAR: PMIX_ENVAR_CONSTRUCT(&p->data.envar); if (NULL != src->data.envar.envar) { p->data.envar.envar = strdup(src->data.envar.envar); } if (NULL != src->data.envar.value) { p->data.envar.value = strdup(src->data.envar.value); } p->data.envar.separator = src->data.envar.separator; break; default: pmix_output(0, "PMIX-XFER-VALUE: UNSUPPORTED TYPE %d", (int)src->type); return PMIX_ERROR; } return PMIX_SUCCESS; }
/* compare function for pmix_value_t */ pmix_value_cmp_t pmix_bfrops_base_value_cmp(pmix_value_t *p, pmix_value_t *p1) { pmix_value_cmp_t rc = PMIX_VALUE1_GREATER; int ret; if (p->type != p1->type) { return rc; } switch (p->type) { case PMIX_UNDEF: rc = PMIX_EQUAL; break; case PMIX_BOOL: if (p->data.flag == p1->data.flag) { rc = PMIX_EQUAL; } break; case PMIX_BYTE: if (p->data.byte == p1->data.byte) { rc = PMIX_EQUAL; } break; case PMIX_SIZE: if (p->data.size == p1->data.size) { rc = PMIX_EQUAL; } break; case PMIX_INT: if (p->data.integer == p1->data.integer) { rc = PMIX_EQUAL; } break; case PMIX_INT8: if (p->data.int8 == p1->data.int8) { rc = PMIX_EQUAL; } break; case PMIX_INT16: if (p->data.int16 == p1->data.int16) { rc = PMIX_EQUAL; } break; case PMIX_INT32: if (p->data.int32 == p1->data.int32) { rc = PMIX_EQUAL; } break; case PMIX_INT64: if (p->data.int64 == p1->data.int64) { rc = PMIX_EQUAL; } break; case PMIX_UINT: if (p->data.uint == p1->data.uint) { rc = PMIX_EQUAL; } break; case PMIX_UINT8: if (p->data.uint8 == p1->data.int8) { rc = PMIX_EQUAL; } break; case PMIX_UINT16: if (p->data.uint16 == p1->data.uint16) { rc = PMIX_EQUAL; } break; case PMIX_UINT32: if (p->data.uint32 == p1->data.uint32) { rc = PMIX_EQUAL; } break; case PMIX_UINT64: if (p->data.uint64 == p1->data.uint64) { rc = PMIX_EQUAL; } break; case PMIX_STRING: if (0 == strcmp(p->data.string, p1->data.string)) { rc = PMIX_EQUAL; } break; case PMIX_COMPRESSED_STRING: if (p->data.bo.size > p1->data.bo.size) { return PMIX_VALUE2_GREATER; } else { return PMIX_VALUE1_GREATER; } break; case PMIX_STATUS: if (p->data.status == p1->data.status) { rc = PMIX_EQUAL; } break; case PMIX_ENVAR: if (NULL != p->data.envar.envar) { if (NULL == p1->data.envar.envar) { return PMIX_VALUE1_GREATER; } ret = strcmp(p->data.envar.envar, p1->data.envar.envar); if (ret < 0) { return PMIX_VALUE2_GREATER; } else if (0 < ret) { return PMIX_VALUE1_GREATER; } } else if (NULL != p1->data.envar.envar) { /* we know value1->envar had to be NULL */ return PMIX_VALUE2_GREATER; } /* if both are NULL or are equal, then check value */ if (NULL != p->data.envar.value) { if (NULL == p1->data.envar.value) { return PMIX_VALUE1_GREATER; } ret = strcmp(p->data.envar.value, p1->data.envar.value); if (ret < 0) { return PMIX_VALUE2_GREATER; } else if (0 < ret) { return PMIX_VALUE1_GREATER; } } else if (NULL != p1->data.envar.value) { /* we know value1->value had to be NULL */ return PMIX_VALUE2_GREATER; } /* finally, check separator */ if (p->data.envar.separator < p1->data.envar.separator) { return PMIX_VALUE2_GREATER; } if (p1->data.envar.separator < p->data.envar.separator) { return PMIX_VALUE1_GREATER; } rc = PMIX_EQUAL; break; default: pmix_output(0, "COMPARE-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)p->type); } return rc; }
/* configure using getifaddrs(3) */ static int if_solaris_ipv6_open(void) { int i; int sd; int error; uint16_t kindex; struct lifnum lifnum; struct lifconf lifconf; struct lifreq *lifreq, lifquery; sd = socket (AF_INET6, SOCK_DGRAM, 0); if (sd < 0) { pmix_output (0, "pmix_ifinit: unable to open IPv6 socket\n"); return PMIX_ERROR; } /* we only ask for IPv6; IPv4 discovery has already been done */ lifnum.lifn_family = AF_INET6; lifnum.lifn_flags = 0; lifnum.lifn_count = 0; /* get the number of interfaces in the system */ error = ioctl (sd, SIOCGLIFNUM, &lifnum); if (error < 0) { pmix_output (0, "pmix_ifinit: ioctl SIOCGLIFNUM failed with errno=%d\n", errno); return PMIX_ERROR; } memset (&lifconf, 0, sizeof (struct lifconf)); memset (&lifquery, 0, sizeof (struct lifreq)); lifconf.lifc_family = AF_INET6; lifconf.lifc_flags = 0; lifconf.lifc_len = lifnum.lifn_count * sizeof (struct lifreq) * 2; lifconf.lifc_buf = malloc (lifconf.lifc_len); if (NULL == lifconf.lifc_buf) { pmix_output (0, "pmix_ifinit: IPv6 discovery: malloc() failed\n"); return PMIX_ERR_OUT_OF_RESOURCE; } memset (lifconf.lifc_buf, 0, lifconf.lifc_len); error = ioctl (sd, SIOCGLIFCONF, &lifconf); if (error < 0) { pmix_output (0, "pmix_ifinit: IPv6 SIOCGLIFCONF failed with errno=%d\n", errno); } for (i = 0; i + sizeof (struct lifreq) <= lifconf.lifc_len; i += sizeof (*lifreq)) { lifreq = (struct lifreq *)((caddr_t)lifconf.lifc_buf + i); pmix_strncpy (lifquery.lifr_name, lifreq->lifr_name, sizeof (lifquery.lifr_name)-1); /* lookup kernel index */ error = ioctl (sd, SIOCGLIFINDEX, &lifquery); if (error < 0) { pmix_output (0, "pmix_ifinit: SIOCGLIFINDEX failed with errno=%d\n", errno); return PMIX_ERROR; } kindex = lifquery.lifr_index; /* lookup interface flags */ error = ioctl (sd, SIOCGLIFFLAGS, &lifquery); if (error < 0) { pmix_output (0, "pmix_ifinit: SIOCGLIFFLAGS failed with errno=%d\n", errno); return PMIX_ERROR; } if (AF_INET6 == lifreq->lifr_addr.ss_family) { struct sockaddr_in6* my_addr = (struct sockaddr_in6*) &lifreq->lifr_addr; /* we surely want to check for sin6_scope_id, but Solaris does not set it correctly, so we have to look for global scope. For now, global is anything which is neither loopback nor link local. Bug, FIXME: site-local, multicast, ... missing Check for 2000::/3? */ if ( (!pmix_if_retain_loopback && !IN6_IS_ADDR_LOOPBACK (&my_addr->sin6_addr)) && (! IN6_IS_ADDR_LINKLOCAL (&my_addr->sin6_addr))) { /* create interface for newly found address */ pmix_pif_t *intf; intf = PMIX_NEW(pmix_pif_t); if (NULL == intf) { pmix_output (0, "pmix_ifinit: unable to allocate %d bytes\n", sizeof (pmix_pif_t)); return PMIX_ERR_OUT_OF_RESOURCE; } intf->af_family = AF_INET6; pmix_strncpy (intf->if_name, lifreq->lifr_name, IF_NAMESIZE-1); intf->if_index = pmix_list_get_size(&pmix_if_list)+1; memcpy(&intf->if_addr, my_addr, sizeof (*my_addr)); intf->if_mask = 64; /* lifrq flags are uint64_t */ intf->if_flags = (uint32_t)(0x00000000ffffffff) & lifquery.lifr_flags; /* append to list */ pmix_list_append (&pmix_if_list, &(intf->super)); } } } /* for */ if (NULL != lifconf.lifc_buf) { free (lifconf.lifc_buf); } return PMIX_SUCCESS; }
int main(int argc, char **argv) { int rc; pmix_value_t value; pmix_value_t *val = &value; char *tmp; pmix_proc_t proc; uint32_t n, num_gets; bool active; /* init us */ if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Init failed: %d", myproc.nspace, myproc.rank, rc); exit(0); } pmix_output(0, "Client ns %s rank %d: Running", myproc.nspace, myproc.rank); /* get our universe size */ (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN); proc.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_UNIV_SIZE, NULL, 0, &val))) { pmix_output(0, "Client ns %s rank %d: PMIx_Get universe size failed: %d", myproc.nspace, myproc.rank, rc); goto done; } nprocs = val->data.uint32; PMIX_VALUE_RELEASE(val); pmix_output(0, "Client %s:%d universe size %d", myproc.nspace, myproc.rank, nprocs); /* put a few values */ (void)asprintf(&tmp, "%s-%d-internal", myproc.nspace, myproc.rank); value.type = PMIX_UINT32; value.data.uint32 = 1234; if (PMIX_SUCCESS != (rc = PMIx_Store_internal(&myproc, tmp, &value))) { pmix_output(0, "Client ns %s rank %d: PMIx_Store_internal failed: %d", myproc.nspace, myproc.rank, rc); goto done; } (void)asprintf(&tmp, "%s-%d-local", myproc.nspace, myproc.rank); value.type = PMIX_UINT64; value.data.uint64 = 1234; if (PMIX_SUCCESS != (rc = PMIx_Put(PMIX_LOCAL, tmp, &value))) { pmix_output(0, "Client ns %s rank %d: PMIx_Put internal failed: %d", myproc.nspace, myproc.rank, rc); goto done; } (void)asprintf(&tmp, "%s-%d-remote", myproc.nspace, myproc.rank); value.type = PMIX_STRING; value.data.string = "1234"; if (PMIX_SUCCESS != (rc = PMIx_Put(PMIX_REMOTE, tmp, &value))) { pmix_output(0, "Client ns %s rank %d: PMIx_Put internal failed: %d", myproc.nspace, myproc.rank, rc); goto done; } /* introduce a delay by one rank so we can check what happens * if a "get" is received prior to data being provided */ if (0 == myproc.rank) { sleep(2); } /* commit the data to the server */ if (PMIX_SUCCESS != (rc = PMIx_Commit())) { pmix_output(0, "Client ns %s rank %d: PMIx_Commit failed: %d", myproc.nspace, myproc.rank, rc); goto done; } /* call fence_nb, but don't return any data */ PMIX_PROC_CONSTRUCT(&proc); (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN); proc.rank = PMIX_RANK_WILDCARD; active = true; if (PMIX_SUCCESS != (rc = PMIx_Fence_nb(&proc, 1, NULL, 0, opcbfunc, &active))) { pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); goto done; } /* get the committed data - ask for someone who doesn't exist as well */ num_gets = 0; for (n=0; n < nprocs; n++) { (void)asprintf(&tmp, "%s-%d-local", myproc.nspace, n); proc.rank = n; if (PMIX_SUCCESS != (rc = PMIx_Get_nb(&proc, tmp, NULL, 0, valcbfunc, tmp))) { pmix_output(0, "Client ns %s rank %d: PMIx_Get %s failed: %d", myproc.nspace, n, tmp, rc); goto done; } ++num_gets; (void)asprintf(&tmp, "%s-%d-remote", myproc.nspace, n); if (PMIX_SUCCESS != (rc = PMIx_Get_nb(&proc, tmp, NULL, 0, valcbfunc, tmp))) { pmix_output(0, "Client ns %s rank %d: PMIx_Get %s failed: %d", myproc.nspace, n, tmp, rc); goto done; } ++num_gets; } /* wait for the first fence to finish */ PMIX_WAIT_FOR_COMPLETION(active); /* wait for all my "get" calls to complete */ while (getcount < num_gets) { struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 100000; nanosleep(&ts, NULL); } /* call fence again so everyone waits before leaving */ proc.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); goto done; } done: /* finalize us */ pmix_output(0, "Client ns %s rank %d: Finalizing", myproc.nspace, myproc.rank); if (PMIX_SUCCESS != (rc = PMIx_Finalize(NULL, 0))) { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize failed: %d\n", myproc.nspace, myproc.rank, rc); } else { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize successfully completed\n", myproc.nspace, myproc.rank); } fflush(stderr); return(0); }