diff --git a/.gitignore b/.gitignore index 8138cd8055..9b462dbe3b 100644 --- a/.gitignore +++ b/.gitignore @@ -302,7 +302,11 @@ opal/mca/event/libevent*/libevent/libevent_pthreads.pc opal/mca/event/libevent*/libevent/include/event2/event-config.h opal/mca/hwloc/hwloc*/hwloc/include/hwloc/autogen/config.h +opal/mca/hwloc/hwloc*/hwloc/include/hwloc/autogen/config.h.in opal/mca/hwloc/hwloc*/hwloc/include/private/autogen/config.h +opal/mca/hwloc/hwloc*/hwloc/include/private/autogen/config.h.in +opal/mca/hwloc/base/static-components.h.new.extern +opal/mca/hwloc/base/static-components.h.new.struct opal/mca/installdirs/config/install_dirs.h @@ -310,8 +314,6 @@ opal/mca/pmix/pmix*/pmix/include/pmix/autogen/config.h opal/mca/pmix/pmix*/pmix/include/pmix/autogen/config.h.in opal/mca/pmix/pmix*/pmix/src/include/private/autogen/config.h.in opal/mca/pmix/pmix*/pmix/src/include/private/autogen/config.h -opal/mca/hwloc/base/static-components.h.new.extern -opal/mca/hwloc/base/static-components.h.new.struct opal/mca/pmix/pmix2x/pmix/src/include/frameworks.h opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pinstall_dirs.h opal/mca/pmix/pmix2x/pmix/config/autogen_found_items.m4 diff --git a/opal/mca/hwloc/hwloc2x/hwloc/include/private/autogen/config.h.in b/opal/mca/hwloc/hwloc2x/hwloc/include/private/autogen/config.h.in deleted file mode 100644 index f65a8be473..0000000000 --- a/opal/mca/hwloc/hwloc2x/hwloc/include/private/autogen/config.h.in +++ /dev/null @@ -1,728 +0,0 @@ -/* include/private/autogen/config.h.in. Generated from configure.ac by autoheader. */ - -/* -*- c -*- - * - * Copyright © 2009, 2011, 2012 CNRS, inria., Université Bordeaux All rights reserved. - * Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - * - * This file is automatically generated by configure. Edits will be lost - * the next time you run configure! - */ - -#ifndef HWLOC_CONFIGURE_H -#define HWLOC_CONFIGURE_H - - -/* Define to 1 if the system has the type `CACHE_DESCRIPTOR'. */ -#undef HAVE_CACHE_DESCRIPTOR - -/* Define to 1 if the system has the type `CACHE_RELATIONSHIP'. */ -#undef HAVE_CACHE_RELATIONSHIP - -/* Define to 1 if you have the `clock_gettime' function. */ -#undef HAVE_CLOCK_GETTIME - -/* Define to 1 if you have the `clz' function. */ -#undef HAVE_CLZ - -/* Define to 1 if you have the `clzl' function. */ -#undef HAVE_CLZL - -/* Define to 1 if you have the header file. */ -#undef HAVE_CL_CL_EXT_H - -/* Define to 1 if you have the `cpuset_setaffinity' function. */ -#undef HAVE_CPUSET_SETAFFINITY - -/* Define to 1 if you have the `cpuset_setid' function. */ -#undef HAVE_CPUSET_SETID - -/* Define to 1 if you have the header file. */ -#undef HAVE_CTYPE_H - -/* Define to 1 if we have -lcuda */ -#undef HAVE_CUDA - -/* Define to 1 if you have the header file. */ -#undef HAVE_CUDA_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_CUDA_RUNTIME_API_H - -/* Define to 1 if you have the declaration of `CL_DEVICE_TOPOLOGY_AMD', and to - 0 if you don't. */ -#undef HAVE_DECL_CL_DEVICE_TOPOLOGY_AMD - -/* Define to 1 if you have the declaration of `CTL_HW', and to 0 if you don't. - */ -#undef HAVE_DECL_CTL_HW - -/* Define to 1 if you have the declaration of `fabsf', and to 0 if you don't. - */ -#undef HAVE_DECL_FABSF - -/* Define to 1 if you have the declaration of `getexecname', and to 0 if you - don't. */ -#undef HAVE_DECL_GETEXECNAME - -/* Define to 1 if you have the declaration of `GetModuleFileName', and to 0 if - you don't. */ -#undef HAVE_DECL_GETMODULEFILENAME - -/* Define to 1 if you have the declaration of `getprogname', and to 0 if you - don't. */ -#undef HAVE_DECL_GETPROGNAME - -/* Define to 1 if you have the declaration of `HW_NCPU', and to 0 if you - don't. */ -#undef HAVE_DECL_HW_NCPU - -/* Define to 1 if you have the declaration of `lgrp_latency_cookie', and to 0 - if you don't. */ -#undef HAVE_DECL_LGRP_LATENCY_COOKIE - -/* Define to 1 if you have the declaration of - `nvmlDeviceGetMaxPcieLinkGeneration', and to 0 if you don't. */ -#undef HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION - -/* Define to 1 if you have the declaration of `pthread_getaffinity_np', and to - 0 if you don't. */ -#undef HAVE_DECL_PTHREAD_GETAFFINITY_NP - -/* Define to 1 if you have the declaration of `pthread_setaffinity_np', and to - 0 if you don't. */ -#undef HAVE_DECL_PTHREAD_SETAFFINITY_NP - -/* Embedded mode; just assume we do not have Valgrind support */ -#undef HAVE_DECL_RUNNING_ON_VALGRIND - -/* Define to 1 if you have the declaration of `snprintf', and to 0 if you - don't. */ -#undef HAVE_DECL_SNPRINTF - -/* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you - don't. */ -#undef HAVE_DECL_STRCASECMP - -/* Define to 1 if you have the declaration of `strtoull', and to 0 if you - don't. */ -#undef HAVE_DECL_STRTOULL - -/* Define to 1 if you have the declaration of `_putenv', and to 0 if you - don't. */ -#undef HAVE_DECL__PUTENV - -/* Define to 1 if you have the declaration of `_SC_LARGE_PAGESIZE', and to 0 - if you don't. */ -#undef HAVE_DECL__SC_LARGE_PAGESIZE - -/* Define to 1 if you have the declaration of `_SC_NPROCESSORS_CONF', and to 0 - if you don't. */ -#undef HAVE_DECL__SC_NPROCESSORS_CONF - -/* Define to 1 if you have the declaration of `_SC_NPROCESSORS_ONLN', and to 0 - if you don't. */ -#undef HAVE_DECL__SC_NPROCESSORS_ONLN - -/* Define to 1 if you have the declaration of `_SC_NPROC_CONF', and to 0 if - you don't. */ -#undef HAVE_DECL__SC_NPROC_CONF - -/* Define to 1 if you have the declaration of `_SC_NPROC_ONLN', and to 0 if - you don't. */ -#undef HAVE_DECL__SC_NPROC_ONLN - -/* Define to 1 if you have the declaration of `_SC_PAGESIZE', and to 0 if you - don't. */ -#undef HAVE_DECL__SC_PAGESIZE - -/* Define to 1 if you have the declaration of `_SC_PAGE_SIZE', and to 0 if you - don't. */ -#undef HAVE_DECL__SC_PAGE_SIZE - -/* Define to 1 if you have the declaration of `_strdup', and to 0 if you - don't. */ -#undef HAVE_DECL__STRDUP - -/* Define to 1 if you have the header file. */ -#undef HAVE_DIRENT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the `ffs' function. */ -#undef HAVE_FFS - -/* Define to 1 if you have the `ffsl' function. */ -#undef HAVE_FFSL - -/* Define to 1 if you have the `fls' function. */ -#undef HAVE_FLS - -/* Define to 1 if you have the `flsl' function. */ -#undef HAVE_FLSL - -/* Define to 1 if you have the `getpagesize' function. */ -#undef HAVE_GETPAGESIZE - -/* Define to 1 if the system has the type `GROUP_AFFINITY'. */ -#undef HAVE_GROUP_AFFINITY - -/* Define to 1 if the system has the type `GROUP_RELATIONSHIP'. */ -#undef HAVE_GROUP_RELATIONSHIP - -/* Define to 1 if you have the `host_info' function. */ -#undef HAVE_HOST_INFO - -/* Define to 1 if you have the header file. */ -#undef HAVE_INFINIBAND_VERBS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if the system has the type `KAFFINITY'. */ -#undef HAVE_KAFFINITY - -/* Define to 1 if you have the header file. */ -#undef HAVE_KSTAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LANGINFO_H - -/* Define to 1 if we have -lgdi32 */ -#undef HAVE_LIBGDI32 - -/* Define to 1 if we have -libverbs */ -#undef HAVE_LIBIBVERBS - -/* Define to 1 if we have -lkstat */ -#undef HAVE_LIBKSTAT - -/* Define to 1 if we have -llgrp */ -#undef HAVE_LIBLGRP - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBUDEV_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LOCALE_H - -/* Define to 1 if the system has the type `LOGICAL_PROCESSOR_RELATIONSHIP'. */ -#undef HAVE_LOGICAL_PROCESSOR_RELATIONSHIP - -/* Define to 1 if you have the header file. */ -#undef HAVE_MACH_MACH_HOST_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MACH_MACH_INIT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MALLOC_H - -/* Define to 1 if you have the `memalign' function. */ -#undef HAVE_MEMALIGN - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MPI_H - -/* Define to 1 if we have -lmyriexpress */ -#undef HAVE_MYRIEXPRESS - -/* Define to 1 if you have the header file. */ -#undef HAVE_MYRIEXPRESS_H - -/* Define to 1 if you have the `nl_langinfo' function. */ -#undef HAVE_NL_LANGINFO - -/* Define to 1 if the system has the type `NUMA_NODE_RELATIONSHIP'. */ -#undef HAVE_NUMA_NODE_RELATIONSHIP - -/* Define to 1 if you have the header file. */ -#undef HAVE_NVCTRL_NVCTRL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NVML_H - -/* Define to 1 if you have the `openat' function. */ -#undef HAVE_OPENAT - -/* Define to 1 if you have the header file. */ -#undef HAVE_PICL_H - -/* Define to 1 if you have the `posix_memalign' function. */ -#undef HAVE_POSIX_MEMALIGN - -/* Define to 1 if the system has the type `PROCESSOR_CACHE_TYPE'. */ -#undef HAVE_PROCESSOR_CACHE_TYPE - -/* Define to 1 if the system has the type `PROCESSOR_GROUP_INFO'. */ -#undef HAVE_PROCESSOR_GROUP_INFO - -/* Define to 1 if the system has the type `PROCESSOR_NUMBER'. */ -#undef HAVE_PROCESSOR_NUMBER - -/* Define to 1 if the system has the type `PROCESSOR_RELATIONSHIP'. */ -#undef HAVE_PROCESSOR_RELATIONSHIP - -/* Define to '1' if program_invocation_name is present and usable */ -#undef HAVE_PROGRAM_INVOCATION_NAME - -/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_BLOCK'. */ -#undef HAVE_PSAPI_WORKING_SET_EX_BLOCK - -/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_INFORMATION'. - */ -#undef HAVE_PSAPI_WORKING_SET_EX_INFORMATION - -/* Define to 1 if you have the header file. */ -#undef HAVE_PTHREAD_NP_H - -/* Define to 1 if the system has the type `pthread_t'. */ -#undef HAVE_PTHREAD_T - -/* Define to 1 if you have the `putwc' function. */ -#undef HAVE_PUTWC - -/* Define to 1 if the system has the type `RelationProcessorPackage'. */ -#undef HAVE_RELATIONPROCESSORPACKAGE - -/* Define to 1 if you have the `setlocale' function. */ -#undef HAVE_SETLOCALE - -/* Define to 1 if the system has the type `ssize_t'. */ -#undef HAVE_SSIZE_T - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `strftime' function. */ -#undef HAVE_STRFTIME - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strncasecmp' function. */ -#undef HAVE_STRNCASECMP - -/* Define to 1 if you have the `strtoull' function. */ -#undef HAVE_STRTOULL - -/* Define to '1' if sysctl is present and usable */ -#undef HAVE_SYSCTL - -/* Define to '1' if sysctlbyname is present and usable */ -#undef HAVE_SYSCTLBYNAME - -/* Define to 1 if the system has the type - `SYSTEM_LOGICAL_PROCESSOR_INFORMATION'. */ -#undef HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION - -/* Define to 1 if the system has the type - `SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX'. */ -#undef HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_CPUSET_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_LGRP_USER_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_MMAN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SYSCTL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UTSNAME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_TIME_H - -/* Define to 1 if you have the `uname' function. */ -#undef HAVE_UNAME - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `uselocale' function. */ -#undef HAVE_USELOCALE - -/* Define to 1 if you have the header file. */ -#undef HAVE_VALGRIND_VALGRIND_H - -/* Define to 1 if the system has the type `wchar_t'. */ -#undef HAVE_WCHAR_T - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_KEYSYM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XUTIL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_XLOCALE_H - -/* Define to '1' if __progname is present and usable */ -#undef HAVE___PROGNAME - -/* Define to 1 on AIX */ -#undef HWLOC_AIX_SYS - -/* Define to 1 on BlueGene/Q */ -#undef HWLOC_BGQ_SYS - -/* Whether C compiler supports symbol visibility or not */ -#undef HWLOC_C_HAVE_VISIBILITY - -/* Define to 1 on Darwin */ -#undef HWLOC_DARWIN_SYS - -/* Whether we are in debugging mode or not */ -#undef HWLOC_DEBUG - -/* Define to 1 on *FREEBSD */ -#undef HWLOC_FREEBSD_SYS - -/* Whether your compiler has __attribute__ or not */ -#undef HWLOC_HAVE_ATTRIBUTE - -/* Whether your compiler has __attribute__ aligned or not */ -#undef HWLOC_HAVE_ATTRIBUTE_ALIGNED - -/* Whether your compiler has __attribute__ always_inline or not */ -#undef HWLOC_HAVE_ATTRIBUTE_ALWAYS_INLINE - -/* Whether your compiler has __attribute__ cold or not */ -#undef HWLOC_HAVE_ATTRIBUTE_COLD - -/* Whether your compiler has __attribute__ const or not */ -#undef HWLOC_HAVE_ATTRIBUTE_CONST - -/* Whether your compiler has __attribute__ deprecated or not */ -#undef HWLOC_HAVE_ATTRIBUTE_DEPRECATED - -/* Whether your compiler has __attribute__ format or not */ -#undef HWLOC_HAVE_ATTRIBUTE_FORMAT - -/* Whether your compiler has __attribute__ hot or not */ -#undef HWLOC_HAVE_ATTRIBUTE_HOT - -/* Whether your compiler has __attribute__ malloc or not */ -#undef HWLOC_HAVE_ATTRIBUTE_MALLOC - -/* Whether your compiler has __attribute__ may_alias or not */ -#undef HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS - -/* Whether your compiler has __attribute__ nonnull or not */ -#undef HWLOC_HAVE_ATTRIBUTE_NONNULL - -/* Whether your compiler has __attribute__ noreturn or not */ -#undef HWLOC_HAVE_ATTRIBUTE_NORETURN - -/* Whether your compiler has __attribute__ no_instrument_function or not */ -#undef HWLOC_HAVE_ATTRIBUTE_NO_INSTRUMENT_FUNCTION - -/* Whether your compiler has __attribute__ packed or not */ -#undef HWLOC_HAVE_ATTRIBUTE_PACKED - -/* Whether your compiler has __attribute__ pure or not */ -#undef HWLOC_HAVE_ATTRIBUTE_PURE - -/* Whether your compiler has __attribute__ sentinel or not */ -#undef HWLOC_HAVE_ATTRIBUTE_SENTINEL - -/* Whether your compiler has __attribute__ unused or not */ -#undef HWLOC_HAVE_ATTRIBUTE_UNUSED - -/* Whether your compiler has __attribute__ warn unused result or not */ -#undef HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT - -/* Whether your compiler has __attribute__ weak alias or not */ -#undef HWLOC_HAVE_ATTRIBUTE_WEAK_ALIAS - -/* Define to 1 if your `ffs' function is known to be broken. */ -#undef HWLOC_HAVE_BROKEN_FFS - -/* Define to 1 if you have the `cairo' library. */ -#undef HWLOC_HAVE_CAIRO - -/* Define to 1 if you have the `clz' function. */ -#undef HWLOC_HAVE_CLZ - -/* Define to 1 if you have the `clzl' function. */ -#undef HWLOC_HAVE_CLZL - -/* Define to 1 if the CPU_SET macro works */ -#undef HWLOC_HAVE_CPU_SET - -/* Define to 1 if the CPU_SET_S macro works */ -#undef HWLOC_HAVE_CPU_SET_S - -/* Define to 1 if you have the `cudart' SDK. */ -#undef HWLOC_HAVE_CUDART - -/* Define to 1 if function `clz' is declared by system headers */ -#undef HWLOC_HAVE_DECL_CLZ - -/* Define to 1 if function `clzl' is declared by system headers */ -#undef HWLOC_HAVE_DECL_CLZL - -/* Define to 1 if function `ffs' is declared by system headers */ -#undef HWLOC_HAVE_DECL_FFS - -/* Define to 1 if function `ffsl' is declared by system headers */ -#undef HWLOC_HAVE_DECL_FFSL - -/* Define to 1 if function `fls' is declared by system headers */ -#undef HWLOC_HAVE_DECL_FLS - -/* Define to 1 if function `flsl' is declared by system headers */ -#undef HWLOC_HAVE_DECL_FLSL - -/* Define to 1 if function `strncasecmp' is declared by system headers */ -#undef HWLOC_HAVE_DECL_STRNCASECMP - -/* Define to 1 if you have the `ffs' function. */ -#undef HWLOC_HAVE_FFS - -/* Define to 1 if you have the `ffsl' function. */ -#undef HWLOC_HAVE_FFSL - -/* Define to 1 if you have the `fls' function. */ -#undef HWLOC_HAVE_FLS - -/* Define to 1 if you have the `flsl' function. */ -#undef HWLOC_HAVE_FLSL - -/* Define to 1 if you have the GL module components. */ -#undef HWLOC_HAVE_GL - -/* Define to 1 if you have a library providing the termcap interface */ -#undef HWLOC_HAVE_LIBTERMCAP - -/* Define to 1 if you have libudev. */ -#undef HWLOC_HAVE_LIBUDEV - -/* Define to 1 if you have the `libxml2' library. */ -#undef HWLOC_HAVE_LIBXML2 - -/* Define to 1 if building the Linux I/O component */ -#undef HWLOC_HAVE_LINUXIO - -/* Define to 1 if enabling Linux-specific PCI discovery in the Linux I/O - component */ -#undef HWLOC_HAVE_LINUXPCI - -/* Define to 1 if you have the `NVML' library. */ -#undef HWLOC_HAVE_NVML - -/* Define to 1 if glibc provides the old prototype (without length) of - sched_setaffinity() */ -#undef HWLOC_HAVE_OLD_SCHED_SETAFFINITY - -/* Define to 1 if you have the `OpenCL' library. */ -#undef HWLOC_HAVE_OPENCL - -/* Define to 1 if the hwloc library should support dynamically-loaded plugins - */ -#undef HWLOC_HAVE_PLUGINS - -/* `Define to 1 if you have pthread_getthrds_np' */ -#undef HWLOC_HAVE_PTHREAD_GETTHRDS_NP - -/* Define to 1 if pthread mutexes are available */ -#undef HWLOC_HAVE_PTHREAD_MUTEX - -/* Define to 1 if glibc provides a prototype of sched_setaffinity() */ -#undef HWLOC_HAVE_SCHED_SETAFFINITY - -/* Define to 1 if you have the header file. */ -#undef HWLOC_HAVE_STDINT_H - -/* Define to 1 if function `syscall' is available with 6 parameters */ -#undef HWLOC_HAVE_SYSCALL - -/* Define to 1 if you have the `windows.h' header. */ -#undef HWLOC_HAVE_WINDOWS_H - -/* Define to 1 if X11 headers including Xutil.h and keysym.h are available. */ -#undef HWLOC_HAVE_X11_KEYSYM - -/* Define to 1 if you have x86 cpuid */ -#undef HWLOC_HAVE_X86_CPUID - -/* Define to 1 on HP-UX */ -#undef HWLOC_HPUX_SYS - -/* Define to 1 on Irix */ -#undef HWLOC_IRIX_SYS - -/* Define to 1 on Linux */ -#undef HWLOC_LINUX_SYS - -/* Define to 1 on *NETBSD */ -#undef HWLOC_NETBSD_SYS - -/* The size of `unsigned int', as computed by sizeof */ -#undef HWLOC_SIZEOF_UNSIGNED_INT - -/* The size of `unsigned long', as computed by sizeof */ -#undef HWLOC_SIZEOF_UNSIGNED_LONG - -/* Define to 1 on Solaris */ -#undef HWLOC_SOLARIS_SYS - -/* The hwloc symbol prefix */ -#undef HWLOC_SYM_PREFIX - -/* The hwloc symbol prefix in all caps */ -#undef HWLOC_SYM_PREFIX_CAPS - -/* Whether we need to re-define all the hwloc public symbols or not */ -#undef HWLOC_SYM_TRANSFORM - -/* Define to 1 on unsupported systems */ -#undef HWLOC_UNSUPPORTED_SYS - -/* Define to 1 if ncurses works, preferred over curses */ -#undef HWLOC_USE_NCURSES - -/* The library version, always available, even in embedded mode, contrary to - VERSION */ -#undef HWLOC_VERSION - -/* Define to 1 on WINDOWS */ -#undef HWLOC_WIN_SYS - -/* Define to 1 on x86_32 */ -#undef HWLOC_X86_32_ARCH - -/* Define to 1 on x86_64 */ -#undef HWLOC_X86_64_ARCH - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR - -/* Define to 1 if scotch is netlocscotch is enabled */ -#undef NETLOC_SCOTCH - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* The size of `unsigned int', as computed by sizeof. */ -#undef SIZEOF_UNSIGNED_INT - -/* The size of `unsigned long', as computed by sizeof. */ -#undef SIZEOF_UNSIGNED_LONG - -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Enable extensions on HP-UX. */ -#ifndef _HPUX_SOURCE -# undef _HPUX_SOURCE -#endif - - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif - - -/* Version number of package */ -#undef VERSION - -/* Define to 1 if the X Window System is missing or not being used. */ -#undef X_DISPLAY_MISSING - -/* Are we building for HP-UX? */ -#undef _HPUX_SOURCE - -/* Define to 1 if on MINIX. */ -#undef _MINIX - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE - -/* Define this to the process ID type */ -#undef hwloc_pid_t - -/* Define this to the thread ID type */ -#undef hwloc_thread_t - - -#endif /* HWLOC_CONFIGURE_H */ - diff --git a/opal/mca/pmix/pmix2x/pmix/AUTHORS b/opal/mca/pmix/pmix2x/pmix/AUTHORS index 581a22ec73..98cfbbeb91 100644 --- a/opal/mca/pmix/pmix2x/pmix/AUTHORS +++ b/opal/mca/pmix/pmix2x/pmix/AUTHORS @@ -4,7 +4,7 @@ PMIx Authors The following cumulative list contains the names and GitHub IDs of all individuals who have committed code to the PMIx repository. -Email Name Affiliation(s) +GitHub ID Name Affiliation(s) ------------------------------- --------------------------- ------------------- alinask Elena Shipunova Mellanox annu13 Annapurna Dasari Intel diff --git a/opal/mca/pmix/pmix2x/pmix/INSTALL b/opal/mca/pmix/pmix2x/pmix/INSTALL index e1fc5e3f6d..08fdfe641f 100644 --- a/opal/mca/pmix/pmix2x/pmix/INSTALL +++ b/opal/mca/pmix/pmix2x/pmix/INSTALL @@ -21,10 +21,10 @@ For More Information ==================== This file is a *very* short overview of building and installing -the PMIx library. Much more information is available on the -PMIx web site (e.g., see the FAQ section): +the PMIx library. Much more information is available in the +FAQ section on the PMIx web site: - http://pmix.github.io/pmix/pmix + http://pmix.github.io/pmix/faq Developer Builds diff --git a/opal/mca/pmix/pmix2x/pmix/README b/opal/mca/pmix/pmix2x/pmix/README index 55b7c61f5e..6eaf57526f 100644 --- a/opal/mca/pmix/pmix2x/pmix/README +++ b/opal/mca/pmix/pmix2x/pmix/README @@ -15,7 +15,7 @@ Copyright (c) 2007 Myricom, Inc. All rights reserved. Copyright (c) 2008 IBM Corporation. All rights reserved. Copyright (c) 2010 Oak Ridge National Labs. All rights reserved. Copyright (c) 2011 University of Houston. All rights reserved. -Copyright (c) 2013-2015 Intel, Inc. All rights reserved +Copyright (c) 2013-2017 Intel, Inc. All rights reserved. $COPYRIGHT$ Additional copyrights may follow @@ -28,7 +28,7 @@ When submitting questions and problems, be sure to include as much extra information as possible. This web page details all the information that we request in order to provide assistance: - http://pmix.github.io/master/community/help/ + http://pmix.github.io/pmix/community/help/ The best way to report bugs, send comments, or ask questions is to sign up on the PMIx mailing list, which is hosted by GoogleGroups: @@ -48,7 +48,7 @@ Thanks for your time. More information is available in the PMIx FAQ: - http://pmix.github.io/master/faq/ + http://pmix.github.io/pmix/faq/ We are in early days, so please be patient - info will grow as questions are addressed. @@ -63,7 +63,7 @@ General notes - The majority of PMIx's documentation is here in this file, the included man pages, and on the web site FAQ - (http://pmix.github.io/master/faq). This will eventually be + (http://pmix.github.io/pmix/faq). This will eventually be supplemented with cohesive installation and user documentation files. - Systems that have been tested are: @@ -286,7 +286,7 @@ Common Questions Many common questions about building and using PMIx are answered on the FAQ: - http://pmix.github.io/master/faq/ + http://pmix.github.io/pmix/faq/ =========================================================================== @@ -300,7 +300,7 @@ When submitting questions and problems, be sure to include as much extra information as possible. This web page details all the information that we request in order to provide assistance: - http://pmix.github.io/master/community/help/ + http://pmix.github.io/pmix/community/help/ Questions and comments should generally be sent to the PMIx mailing list (pmix@googlegroups.com). Because of spam, only diff --git a/opal/mca/pmix/pmix2x/pmix/VERSION b/opal/mca/pmix/pmix2x/pmix/VERSION index 15236cc64b..d11ea2f1ed 100644 --- a/opal/mca/pmix/pmix2x/pmix/VERSION +++ b/opal/mca/pmix/pmix2x/pmix/VERSION @@ -13,8 +13,8 @@ # major, minor, and release are generally combined in the form # ... -major=3 -minor=0 +major=2 +minor=1 release=0 # greek is used for alpha or beta release tags. If it is non-empty, @@ -30,7 +30,7 @@ greek= # command, or with the date (if "git describe" fails) in the form of # "date". -repo_rev=gitaa26b56 +repo_rev=git4714f20 # If tarball_version is not empty, it is used as the version string in # the tarball filename, regardless of all other versions listed in @@ -44,7 +44,7 @@ tarball_version= # The date when this release was created -date="Jun 26, 2017" +date="Jul 20, 2017" # The shared library version of each of PMIx's public libraries. # These versions are maintained in accordance with the "Library diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_setup_libevent.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_setup_libevent.m4 index e8e62a914e..7643863965 100644 --- a/opal/mca/pmix/pmix2x/pmix/config/pmix_setup_libevent.m4 +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_setup_libevent.m4 @@ -3,6 +3,8 @@ # Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2013 Los Alamos National Security, LLC. All rights reserved. # Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2017 Research Organization for Information Science +# and Technology (RIST). All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -39,8 +41,11 @@ AC_DEFUN([_PMIX_LIBEVENT_EMBEDDED_MODE],[ AC_MSG_CHECKING([for libevent]) AC_MSG_RESULT([assumed available (embedded mode)]) - PMIX_EVENT_HEADER="$with_libevent_header" - PMIX_EVENT2_THREAD_HEADER="$with_libevent_header" + AS_IF([test -z "$with_libevent_header" || test "$with_libevent_header" = "yes"], + [PMIX_EVENT_HEADER="" + PMIX_EVENT2_THREAD_HEADER=""], + [PMIX_EVENT_HEADER="$with_libevent_header" + PMIX_EVENT2_THREAD_HEADER="$with_libevent_header"]) ]) diff --git a/opal/mca/pmix/pmix2x/pmix/configure.ac b/opal/mca/pmix/pmix2x/pmix/configure.ac index f8abb60d55..5bb1beaa07 100644 --- a/opal/mca/pmix/pmix2x/pmix/configure.ac +++ b/opal/mca/pmix/pmix2x/pmix/configure.ac @@ -55,6 +55,19 @@ AC_CONFIG_MACRO_DIR(./config) # because it twiddles random bits of autoconf PMIX_LOAD_PLATFORM +PMIX_TOP_BUILDDIR="`pwd`" +AC_SUBST(PMIX_TOP_BUILDDIR) +cd "$srcdir" +PMIX_TOP_SRCDIR="`pwd`" +AC_SUBST(PMIX_TOP_SRCDIR) +cd "$PMIX_TOP_BUILDDIR" + +AC_MSG_NOTICE([builddir: $PMIX_TOP_BUILDDIR]) +AC_MSG_NOTICE([srcdir: $PMIX_TOP_SRCDIR]) +if test "$PMIX_TOP_BUILDDIR" != "$PMIX_TOP_SRCDIR"; then + AC_MSG_NOTICE([Detected VPATH build]) +fi + # setup configure options (e.g., show_title and friends) PMIX_CONFIGURE_SETUP pmix_show_title "Configuring PMIx" diff --git a/opal/mca/pmix/pmix2x/pmix/examples/alloc.c b/opal/mca/pmix/pmix2x/pmix/examples/alloc.c index ab171ee142..f0cdf43a0e 100644 --- a/opal/mca/pmix/pmix2x/pmix/examples/alloc.c +++ b/opal/mca/pmix/pmix2x/pmix/examples/alloc.c @@ -208,7 +208,7 @@ int main(int argc, char **argv) * query the status of the allocation request */ usleep(10); PMIX_QUERY_CREATE(query, 1); - PMIX_ARGV_APPEND(query[0].keys, PMIX_QUERY_ALLOC_STATUS); + PMIX_ARGV_APPEND(rc, query[0].keys, PMIX_QUERY_ALLOC_STATUS); PMIX_INFO_CREATE(query[0].qualifiers, 1); PMIX_INFO_LOAD(&query[0].qualifiers[0], PMIX_ALLOC_ID, myallocation, PMIX_STRING); mydata.active = true; diff --git a/opal/mca/pmix/pmix2x/pmix/examples/debugger.c b/opal/mca/pmix/pmix2x/pmix/examples/debugger.c index 62bc8e593f..f2a23226cc 100644 --- a/opal/mca/pmix/pmix2x/pmix/examples/debugger.c +++ b/opal/mca/pmix/pmix2x/pmix/examples/debugger.c @@ -267,8 +267,8 @@ int main(int argc, char **argv) * so we know if the RM can stop-on-exec, or only supports stop-in-init */ nq = 1; PMIX_QUERY_CREATE(query, nq); - PMIX_ARGV_APPEND(query[0].keys, PMIX_QUERY_SPAWN_SUPPORT); - PMIX_ARGV_APPEND(query[0].keys, PMIX_QUERY_DEBUG_SUPPORT); + PMIX_ARGV_APPEND(rc, query[0].keys, PMIX_QUERY_SPAWN_SUPPORT); + PMIX_ARGV_APPEND(rc, query[0].keys, PMIX_QUERY_DEBUG_SUPPORT); /* setup the caddy to retrieve the data */ myquery_data.info = NULL; myquery_data.ninfo = 0; @@ -333,7 +333,7 @@ int main(int argc, char **argv) PMIX_APP_CREATE(app, napps); /* setup the executable */ app[0].cmd = strdup("client"); - PMIX_ARGV_APPEND(app[0].argv, "./client"); + PMIX_ARGV_APPEND(rc, app[0].argv, "./client"); getcwd(cwd, 1024); // point us to our current directory app[0].cwd = strdup(cwd); app[0].maxprocs = 2; @@ -359,7 +359,7 @@ int main(int argc, char **argv) /* setup the debugger */ PMIX_APP_CREATE(debugger, 1); debugger[0].cmd = strdup("./debuggerd"); - PMIX_ARGV_APPEND(debugger[0].argv, "./debuggerd"); + PMIX_ARGV_APPEND(rc, debugger[0].argv, "./debuggerd"); debugger[0].cwd = strdup(cwd); /* provide directives so the daemons go where we want, and * let the RM know these are debugger daemons */ diff --git a/opal/mca/pmix/pmix2x/pmix/examples/debuggerd.c b/opal/mca/pmix/pmix2x/pmix/examples/debuggerd.c index fa843fa137..5924dca717 100644 --- a/opal/mca/pmix/pmix2x/pmix/examples/debuggerd.c +++ b/opal/mca/pmix/pmix2x/pmix/examples/debuggerd.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. All rights reserved. * $COPYRIGHT$ * @@ -172,7 +172,7 @@ int main(int argc, char **argv) * our local target processes */ nq = 1; PMIX_QUERY_CREATE(query, nq); - PMIX_ARGV_APPEND(query[0].keys, PMIX_QUERY_LOCAL_PROC_TABLE); + PMIX_ARGV_APPEND(rc, query[0].keys, PMIX_QUERY_LOCAL_PROC_TABLE); query[0].nqual = 1; PMIX_INFO_CREATE(query[0].qualifiers, 1); PMIX_INFO_LOAD(&query[0].qualifiers[0], PMIX_NSPACE, val->data.string, PMIX_STRING); // the nspace we are enquiring about diff --git a/opal/mca/pmix/pmix2x/pmix/examples/server.c b/opal/mca/pmix/pmix2x/pmix/examples/server.c index 5a1ccaa885..72db59447c 100644 --- a/opal/mca/pmix/pmix2x/pmix/examples/server.c +++ b/opal/mca/pmix/pmix2x/pmix/examples/server.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -48,7 +49,6 @@ #include "src/util/output.h" #include "src/util/printf.h" #include "src/util/argv.h" -#include "src/buffer_ops/buffer_ops.h" static pmix_status_t connected(const pmix_proc_t *proc, void *server_object, pmix_op_cbfunc_t cbfunc, void *cbdata); diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix_common.h b/opal/mca/pmix/pmix2x/pmix/include/pmix_common.h index 5713517b43..95f8749936 100644 --- a/opal/mca/pmix/pmix2x/pmix/include/pmix_common.h +++ b/opal/mca/pmix/pmix2x/pmix/include/pmix_common.h @@ -4,7 +4,7 @@ * Copyright (c) 2016-2017 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. - * Copyright (c) 2016 Mellanox Technologies, Inc. + * Copyright (c) 2016-2017 Mellanox Technologies, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -154,6 +154,10 @@ typedef uint32_t pmix_rank_t; #define PMIX_TCP_DISABLE_IPV4 "pmix.tcp.disipv4" // (bool) true to disable IPv4 family #define PMIX_TCP_DISABLE_IPV6 "pmix.tcp.disipv6" // (bool) true to disable IPv6 family +/* attributes for GDS */ +#define PMIX_GDS_MODULE "pmix.gds.mod" // (char*) comma-delimited string of desired modules + + /* general proc-level attributes */ #define PMIX_CPUSET "pmix.cpuset" // (char*) hwloc bitmap applied to proc upon launch #define PMIX_CREDENTIAL "pmix.cred" // (char*) security credential assigned to proc @@ -184,7 +188,7 @@ typedef uint32_t pmix_rank_t; #define PMIX_NODE_LIST "pmix.nlist" // (char*) comma-delimited list of nodes running procs for the specified nspace #define PMIX_ALLOCATED_NODELIST "pmix.alist" // (char*) comma-delimited list of all nodes in this allocation regardless of - // whether or not they currently host procs. + // whether or not they currently host procs. #define PMIX_HOSTNAME "pmix.hname" // (char*) name of the host the specified proc is on #define PMIX_NODEID "pmix.nodeid" // (uint32_t) node identifier where the specified proc is located #define PMIX_LOCAL_PEERS "pmix.lpeers" // (char*) comma-delimited string of ranks on this node within the specified nspace @@ -219,8 +223,9 @@ typedef uint32_t pmix_rank_t; /* request-related info */ #define PMIX_COLLECT_DATA "pmix.collect" // (bool) collect data and return it at the end of the operation #define PMIX_TIMEOUT "pmix.timeout" // (int) time in sec before specified operation should time out (0 => infinite) -#define PMIX_IMMEDIATE "pmix.immediate" // (bool) specified operation should immediately return an error if requested - // data cannot be found - do not request it from the host RM +#define PMIX_IMMEDIATE "pmix.immediate" // (bool) specified operation should immediately return an error from the PMIx + // server if requested data cannot be found - do not request it from + // the host RM #define PMIX_WAIT "pmix.wait" // (int) caller requests that the server wait until at least the specified // #values are found (0 => all and is the default) #define PMIX_COLLECTIVE_ALGO "pmix.calgo" // (char*) comma-delimited list of algorithms to use for collective @@ -229,14 +234,15 @@ typedef uint32_t pmix_rank_t; #define PMIX_RANGE "pmix.range" // (pmix_data_range_t) value for calls to publish/lookup/unpublish or for // monitoring event notifications #define PMIX_PERSISTENCE "pmix.persist" // (pmix_persistence_t) value for calls to publish -#define PMIX_OPTIONAL "pmix.optional" // (bool) look only in the immediate data store for the requested value - do +#define PMIX_DATA_SCOPE "pmix.scope" // (pmix_scope_t) scope of the data to be found in a PMIx_Get call +#define PMIX_OPTIONAL "pmix.optional" // (bool) look only in the client's local data store for the requested value - do // not request data from the server if not found #define PMIX_EMBED_BARRIER "pmix.embed.barrier" // (bool) execute a blocking fence operation before executing the // specified operation /* attributes used by host server to pass data to the server convenience library - the * data will then be parsed and provided to the local clients */ -#define PMIX_PROC_DATA "pmix.pdata" // (pmix_value_array_t) starts with rank, then contains more data +#define PMIX_PROC_DATA "pmix.pdata" // (pmix_data_array_t) starts with rank, then contains more data #define PMIX_NODE_MAP "pmix.nmap" // (char*) regex of nodes containing procs for this job #define PMIX_PROC_MAP "pmix.pmap" // (char*) regex describing procs on each node within this job #define PMIX_ANL_MAP "pmix.anlmap" // (char*) process mapping in ANL notation (used in PMI-1/PMI-2) @@ -538,6 +544,7 @@ typedef int pmix_status_t; #define PMIX_ERR_JOB_TERMINATED (PMIX_ERR_OP_BASE - 15) #define PMIX_ERR_UPDATE_ENDPOINTS (PMIX_ERR_OP_BASE - 16) #define PMIX_MODEL_DECLARED (PMIX_ERR_OP_BASE - 17) +#define PMIX_GDS_ACTION_COMPLETE (PMIX_ERR_OP_BASE - 18) /* define a starting point for system error constants so * we avoid renumbering when making additions */ @@ -626,7 +633,7 @@ typedef uint16_t pmix_data_type_t; #define PMIX_DATA_TYPE_MAX 500 -/* define a scope for data "put" by PMI per the following: +/* define a scope for data "put" by PMIx per the following: * * PMI_LOCAL - the data is intended only for other application * processes on the same node. Data marked in this way @@ -642,6 +649,7 @@ typedef uint8_t pmix_scope_t; #define PMIX_LOCAL 1 // share to procs also on this node #define PMIX_REMOTE 2 // share with procs not on this node #define PMIX_GLOBAL 3 // share with all procs (local + remote) +#define PMIX_INTERNAL 4 // store data in the internal tables /* define a range for data "published" by PMI */ @@ -690,6 +698,23 @@ typedef struct pmix_byte_object { char *bytes; size_t size; } pmix_byte_object_t; +#define PMIX_BYTE_OBJECT_DESTRUCT(m) \ + do { \ + if (NULL != (m)->bytes) { \ + free((m)->bytes); \ + } \ + } while(0) + +#define PMIX_BYTE_OBJECT_FREE(m, n) \ + do { \ + size_t _n; \ + for (_n=0; _n < n; _n++) { \ + if (NULL != (m)[_n].bytes) { \ + free((m)[_n].bytes); \ + } \ + } \ + free((m)); \ + } while(0) /**** PMIX DATA BUFFER ****/ @@ -860,6 +885,7 @@ typedef struct pmix_value { pmix_proc_info_t *pinfo; pmix_data_array_t *darray; void *ptr; + pmix_alloc_directive_t adir; /**** DEPRECATED ****/ pmix_info_array_t *array; /********************/ @@ -987,18 +1013,36 @@ typedef struct pmix_value { /* expose some functions that are resolved in the * PMIx library, but part of a header that * includes internal functions - we don't - * want to expose the entire header here + * want to expose the entire header here. For + * consistency, we provide macro versions as well */ void pmix_value_load(pmix_value_t *v, const void *data, pmix_data_type_t type); +#define PMIX_VALUE_LOAD(v, d, t) \ + pmix_value_load((v), (d), (t)) + pmix_status_t pmix_value_xfer(pmix_value_t *kv, pmix_value_t *src); +#define PMIX_VALUE_XFER(r, v, s) \ + do { \ + if (NULL == (v)) { \ + (v) = (pmix_value_t*)malloc(sizeof(pmix_value_t)); \ + if (NULL == (v)) { \ + (r) = PMIX_ERR_NOMEM; \ + } else { \ + (r) = pmix_value_xfer((v), (s)); \ + } \ + } else { \ + (r) = pmix_value_xfer((v), (s)); \ + } \ + } while(0) + pmix_status_t pmix_argv_append_nosize(char ***argv, const char *arg); +#define PMIX_ARGV_APPEND(r, a, b) \ + (r) = pmix_argv_append_nosize(&(a), (b)) + pmix_status_t pmix_setenv(const char *name, const char *value, bool overwrite, char ***env); - -#define PMIX_ARGV_APPEND(a, b) \ - pmix_argv_append_nosize(&(a), (b)) -#define PMIX_SETENV(a, b, c) \ - pmix_setenv((a), (b), true, (c)) +#define PMIX_SETENV(r, a, b, c) \ + (r) = pmix_setenv((a), (b), true, (c)) /**** PMIX INFO STRUCT ****/ struct pmix_info_t { @@ -1052,6 +1096,28 @@ struct pmix_info_t { #define PMIX_INFO_OPTIONAL(m) \ (m)->flags &= ~PMIX_INFO_REQD; +#define PMIX_INFO_UNLOAD(r, v, l) \ + do { \ + pmix_info_t *_info; \ + size_t _n, _ninfo; \ + pmix_kval_t *_kv; \ + _info = (pmix_info_t*)(v)->data.darray->array; \ + _ninfo = (v)->data.darray->size; \ + for (_n = 0; _n < _ninfo; _n++){ \ + _kv = PMIX_NEW(pmix_kval_t); \ + if (NULL == _kv) { \ + (r) = PMIX_ERR_NOMEM; \ + break; \ + } \ + _kv->key = strdup(_info[_n].key); \ + PMIX_VALUE_XFER((r), _kv->value, &_info[_n].value);\ + if (PMIX_SUCCESS != (r)) { \ + PMIX_RELEASE(_kv); \ + break; \ + } \ + pmix_list_append((l), &_kv->super); \ + } \ + } while(0) /**** PMIX LOOKUP RETURN STRUCT ****/ typedef struct pmix_pdata { @@ -1105,6 +1171,17 @@ typedef struct pmix_pdata { } \ } while (0) +#define PMIX_PDATA_XFER(d, s) \ + do { \ + if (NULL != (d)) { \ + memset((d), 0, sizeof(pmix_pdata_t)); \ + (void)strncpy((d)->proc.nspace, (s)->proc.nspace, PMIX_MAX_NSLEN); \ + (d)->proc.rank = (s)->proc.rank; \ + (void)strncpy((d)->key, (s)->key, PMIX_MAX_KEYLEN); \ + pmix_value_xfer(&((d)->value), &((s)->value)); \ + } \ + } while (0) + /**** PMIX APP STRUCT ****/ typedef struct pmix_app { diff --git a/opal/mca/pmix/pmix2x/pmix/src/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/Makefile.am index 6337039084..4b7463ab5d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/Makefile.am @@ -86,11 +86,6 @@ include server/Makefile.include include runtime/Makefile.include include tool/Makefile.include include common/Makefile.include -include buffer_ops/Makefile.am -if WANT_DSTORE -include sm/Makefile.include -include dstore/Makefile.include -endif MAINTAINERCLEANFILES = Makefile.in config.h config.h.in DISTCLEANFILES = Makefile diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/atomic.h index 1ee246252a..8118f70a9f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/atomic.h +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/atomic.h @@ -47,8 +47,8 @@ /* ...or the v6-specific equivalent... */ #define PMIXMB() __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 5" : : : "memory") -#define PMIXRMB() MB() -#define PMIXWMB() MB() +#define PMIXRMB() PMIXMB() +#define PMIXWMB() PMIXMB() #else @@ -56,8 +56,8 @@ /* ...otherwise use the Linux kernel-provided barrier */ #define PMIXMB() (*((void (*)(void))(0xffff0fa0)))() -#define PMIXRMB() MB() -#define PMIXWMB() MB() +#define PMIXRMB() PMIXMB() +#define PMIXWMB() PMIXMB() #endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/internal.h b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/internal.h deleted file mode 100644 index 0eaa8b6ae3..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/internal.h +++ /dev/null @@ -1,538 +0,0 @@ -/* -*- C -*- - * - * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana - * University Research and Technology - * Corporation. All rights reserved. - * Copyright (c) 2004-2006 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. - * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, - * University of Stuttgart. All rights reserved. - * Copyright (c) 2004-2005 The Regents of the University of California. - * All rights reserved. - * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. - * Copyright (c) 2015 Research Organization for Information Science - * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - * - */ -#ifndef PMIX_BFROP_INTERNAL_H_ -#define PMIX_BFROP_INTERNAL_H_ - -#include - - -#ifdef HAVE_SYS_TIME_H -#include /* for struct timeval */ -#endif - -#include "src/class/pmix_pointer_array.h" - -#include "buffer_ops.h" - -#ifdef HAVE_STRING_H -#include -#endif - - BEGIN_C_DECLS - -/* - * The default starting chunk size - */ -#define PMIX_BFROP_DEFAULT_INITIAL_SIZE 2048 -/* - * The default threshold size when we switch from doubling the - * buffer size to addatively increasing it - */ -#define PMIX_BFROP_DEFAULT_THRESHOLD_SIZE 4096 - -/* - * Internal type corresponding to size_t. Do not use this in - * interface calls - use PMIX_SIZE instead. - */ -#if SIZEOF_SIZE_T == 1 -#define BFROP_TYPE_SIZE_T PMIX_UINT8 -#elif SIZEOF_SIZE_T == 2 -#define BFROP_TYPE_SIZE_T PMIX_UINT16 -#elif SIZEOF_SIZE_T == 4 -#define BFROP_TYPE_SIZE_T PMIX_UINT32 -#elif SIZEOF_SIZE_T == 8 -#define BFROP_TYPE_SIZE_T PMIX_UINT64 -#else -#error Unsupported size_t size! -#endif - -/* - * Internal type corresponding to bool. Do not use this in interface - * calls - use PMIX_BOOL instead. - */ -#if SIZEOF__BOOL == 1 -#define BFROP_TYPE_BOOL PMIX_UINT8 -#elif SIZEOF__BOOL == 2 -#define BFROP_TYPE_BOOL PMIX_UINT16 -#elif SIZEOF__BOOL == 4 -#define BFROP_TYPE_BOOL PMIX_UINT32 -#elif SIZEOF__BOOL == 8 -#define BFROP_TYPE_BOOL PMIX_UINT64 -#else -#error Unsupported bool size! -#endif - -/* - * Internal type corresponding to int and unsigned int. Do not use - * this in interface calls - use PMIX_INT / PMIX_UINT instead. - */ -#if SIZEOF_INT == 1 -#define BFROP_TYPE_INT PMIX_INT8 -#define BFROP_TYPE_UINT PMIX_UINT8 -#elif SIZEOF_INT == 2 -#define BFROP_TYPE_INT PMIX_INT16 -#define BFROP_TYPE_UINT PMIX_UINT16 -#elif SIZEOF_INT == 4 -#define BFROP_TYPE_INT PMIX_INT32 -#define BFROP_TYPE_UINT PMIX_UINT32 -#elif SIZEOF_INT == 8 -#define BFROP_TYPE_INT PMIX_INT64 -#define BFROP_TYPE_UINT PMIX_UINT64 -#else -#error Unsupported int size! -#endif - -/* - * Internal type corresponding to pid_t. Do not use this in interface - * calls - use PMIX_PID instead. - */ -#if SIZEOF_PID_T == 1 -#define BFROP_TYPE_PID_T PMIX_UINT8 -#elif SIZEOF_PID_T == 2 -#define BFROP_TYPE_PID_T PMIX_UINT16 -#elif SIZEOF_PID_T == 4 -#define BFROP_TYPE_PID_T PMIX_UINT32 -#elif SIZEOF_PID_T == 8 -#define BFROP_TYPE_PID_T PMIX_UINT64 -#else -#error Unsupported pid_t size! -#endif - -/* Unpack generic size macros */ -#define UNPACK_SIZE_MISMATCH(unpack_type, remote_type, ret) \ - do { \ - switch(remote_type) { \ - case PMIX_UINT8: \ - UNPACK_SIZE_MISMATCH_FOUND(unpack_type, uint8_t, remote_type); \ - break; \ - case PMIX_INT8: \ - UNPACK_SIZE_MISMATCH_FOUND(unpack_type, int8_t, remote_type); \ - break; \ - case PMIX_UINT16: \ - UNPACK_SIZE_MISMATCH_FOUND(unpack_type, uint16_t, remote_type); \ - break; \ - case PMIX_INT16: \ - UNPACK_SIZE_MISMATCH_FOUND(unpack_type, int16_t, remote_type); \ - break; \ - case PMIX_UINT32: \ - UNPACK_SIZE_MISMATCH_FOUND(unpack_type, uint32_t, remote_type); \ - break; \ - case PMIX_INT32: \ - UNPACK_SIZE_MISMATCH_FOUND(unpack_type, int32_t, remote_type); \ - break; \ - case PMIX_UINT64: \ - UNPACK_SIZE_MISMATCH_FOUND(unpack_type, uint64_t, remote_type); \ - break; \ - case PMIX_INT64: \ - UNPACK_SIZE_MISMATCH_FOUND(unpack_type, int64_t, remote_type); \ - break; \ - default: \ - ret = PMIX_ERR_NOT_FOUND; \ - } \ -} while (0) - -/* NOTE: do not need to deal with endianness here, as the unpacking of - the underling sender-side type will do that for us. Repeat: the - data in tmpbuf[] is already in host byte order. */ -#define UNPACK_SIZE_MISMATCH_FOUND(unpack_type, tmptype, tmpbfroptype) \ - do { \ - int32_t i; \ - tmptype *tmpbuf = (tmptype*)malloc(sizeof(tmptype) * (*num_vals)); \ - ret = pmix_bfrop_unpack_buffer(buffer, tmpbuf, num_vals, tmpbfroptype); \ - for (i = 0 ; i < *num_vals ; ++i) { \ - ((unpack_type*) dest)[i] = (unpack_type)(tmpbuf[i]); \ - } \ - free(tmpbuf); \ -} while (0) - - -/** - * Internal struct used for holding registered bfrop functions - */ - typedef struct { - pmix_object_t super; - /* type identifier */ - pmix_data_type_t odti_type; - /** Debugging string name */ - char *odti_name; - /** Pack function */ - pmix_bfrop_pack_fn_t odti_pack_fn; - /** Unpack function */ - pmix_bfrop_unpack_fn_t odti_unpack_fn; - /** copy function */ - pmix_bfrop_copy_fn_t odti_copy_fn; - /** print function */ - pmix_bfrop_print_fn_t odti_print_fn; -} pmix_bfrop_type_info_t; -PMIX_CLASS_DECLARATION(pmix_bfrop_type_info_t); - -/* - * globals needed within bfrop - */ - extern bool pmix_bfrop_initialized; - extern size_t pmix_bfrop_initial_size; - extern size_t pmix_bfrop_threshold_size; - extern pmix_pointer_array_t pmix_bfrop_types; - extern pmix_data_type_t pmix_bfrop_num_reg_types; - -/* macro for registering data types */ -#define PMIX_REGISTER_TYPE(n, t, p, u, c, pr) \ - do { \ - pmix_bfrop_type_info_t *_info; \ - _info = PMIX_NEW(pmix_bfrop_type_info_t); \ - _info->odti_name = strdup((n)); \ - _info->odti_type = (t); \ - _info->odti_pack_fn = (pmix_bfrop_pack_fn_t)(p); \ - _info->odti_unpack_fn = (pmix_bfrop_unpack_fn_t)(u); \ - _info->odti_copy_fn = (pmix_bfrop_copy_fn_t)(c) ; \ - _info->odti_print_fn = (pmix_bfrop_print_fn_t)(pr) ; \ - pmix_pointer_array_set_item(&pmix_bfrop_types, (t), _info); \ - ++pmix_bfrop_num_reg_types; \ -} while (0) - -/* - * Implementations of API functions - */ - -pmix_status_t pmix_bfrop_pack(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_unpack(pmix_buffer_t *buffer, void *dest, - int32_t *max_num_vals, - pmix_data_type_t type); - -pmix_status_t pmix_bfrop_copy(void **dest, void *src, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_print(char **output, char *prefix, void *src, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_copy_payload(pmix_buffer_t *dest, pmix_buffer_t *src); - -/* - * Specialized functions - */ -pmix_status_t pmix_bfrop_pack_buffer(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_unpack_buffer(pmix_buffer_t *buffer, void *dst, - int32_t *num_vals, pmix_data_type_t type); - -/* - * Internal pack functions - */ - -pmix_status_t pmix_bfrop_pack_bool(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_byte(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_string(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_sizet(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_pid(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_pack_int(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_int16(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_int32(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_datatype(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_int64(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_pack_float(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_double(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_time(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_timeval(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_time(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_status(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_value(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_proc(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_app(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_info(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_buf(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_kval(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_modex(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_persist(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_scope(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_range(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_cmd(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_infodirs(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_bo(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_pdata(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_ptr(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_pstate(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_pinfo(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_darray(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_query(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_rank(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_pack_alloc_directive(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -/**** DEPRECATED ****/ -pmix_status_t pmix_bfrop_pack_array(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type); -/********************/ - -/* - * Internal unpack functions - */ - pmix_status_t pmix_bfrop_unpack_bool(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_byte(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_string(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_sizet(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_pid(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - - pmix_status_t pmix_bfrop_unpack_int(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_int16(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_int32(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_datatype(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_int64(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - - pmix_status_t pmix_bfrop_unpack_float(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_double(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_timeval(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_time(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_status(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_value(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_proc(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_app(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_info(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_buf(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_kval(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_modex(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_persist(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_scope(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_range(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_cmd(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_infodirs(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_bo(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_pdata(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_ptr(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_pstate(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_pinfo(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); - pmix_status_t pmix_bfrop_unpack_darray(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_unpack_query(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_unpack_rank(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); -pmix_status_t pmix_bfrop_unpack_alloc_directive(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); -/**** DEPRECATED ****/ -pmix_status_t pmix_bfrop_unpack_array(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type); -/********************/ - -/* - * Internal copy functions - */ - -pmix_status_t pmix_bfrop_std_copy(void **dest, void *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_string(char **dest, char *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_value(pmix_value_t **dest, pmix_value_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_proc(pmix_proc_t **dest, pmix_proc_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_app(pmix_app_t **dest, pmix_app_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_info(pmix_info_t **dest, pmix_info_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_buf(pmix_buffer_t **dest, pmix_buffer_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_kval(pmix_kval_t **dest, pmix_kval_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_modex(pmix_modex_data_t **dest, pmix_modex_data_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_persist(pmix_persistence_t **dest, pmix_persistence_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_bo(pmix_byte_object_t **dest, pmix_byte_object_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_pdata(pmix_pdata_t **dest, pmix_pdata_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_pinfo(pmix_proc_info_t **dest, pmix_proc_info_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, pmix_data_array_t *src, - pmix_data_type_t type); -pmix_status_t pmix_bfrop_copy_query(pmix_query_t **dest, pmix_query_t *src, - pmix_data_type_t type); -/**** DEPRECATED ****/ -pmix_status_t pmix_bfrop_copy_array(pmix_info_array_t **dest, - pmix_info_array_t *src, - pmix_data_type_t type); - -/********************/ - -/* - * Internal print functions - */ -pmix_status_t pmix_bfrop_print_bool(char **output, char *prefix, bool *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_byte(char **output, char *prefix, uint8_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_string(char **output, char *prefix, char *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_size(char **output, char *prefix, size_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_pid(char **output, char *prefix, pid_t *src, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_print_int(char **output, char *prefix, int *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_int8(char **output, char *prefix, int8_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_int16(char **output, char *prefix, int16_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_int32(char **output, char *prefix, int32_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_int64(char **output, char *prefix, int64_t *src, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_print_uint(char **output, char *prefix, uint *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_uint8(char **output, char *prefix, uint8_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_uint16(char **output, char *prefix, uint16_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_uint32(char **output, char *prefix, uint32_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_uint64(char **output, char *prefix, uint64_t *src, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_print_float(char **output, char *prefix, float *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_double(char **output, char *prefix, double *src, pmix_data_type_t type); - -pmix_status_t pmix_bfrop_print_timeval(char **output, char *prefix, struct timeval *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_time(char **output, char *prefix, time_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_status(char **output, char *prefix, pmix_status_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_value(char **output, char *prefix, pmix_value_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_proc(char **output, char *prefix, - pmix_proc_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_app(char **output, char *prefix, - pmix_app_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_info(char **output, char *prefix, - pmix_info_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_buf(char **output, char *prefix, - pmix_buffer_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_kval(char **output, char *prefix, - pmix_kval_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_modex(char **output, char *prefix, - pmix_modex_data_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_persist(char **output, char *prefix, - pmix_persistence_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_scope(char **output, char *prefix, - pmix_scope_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_range(char **output, char *prefix, - pmix_data_range_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_cmd(char **output, char *prefix, - pmix_cmd_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_infodirs(char **output, char *prefix, - pmix_info_directives_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_bo(char **output, char *prefix, - pmix_byte_object_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_pdata(char **output, char *prefix, - pmix_pdata_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_ptr(char **output, char *prefix, - void *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_pstate(char **output, char *prefix, - pmix_proc_state_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_pinfo(char **output, char *prefix, - pmix_proc_info_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_darray(char **output, char *prefix, - pmix_data_array_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_query(char **output, char *prefix, - pmix_query_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_rank(char **output, char *prefix, - pmix_rank_t *src, pmix_data_type_t type); -pmix_status_t pmix_bfrop_print_alloc_directive(char **output, char *prefix, - pmix_alloc_directive_t *src, - pmix_data_type_t type); -/**** DEPRECATED ****/ -pmix_status_t pmix_bfrop_print_array(char **output, char *prefix, - pmix_info_array_t *src, - pmix_data_type_t type); -/********************/ - -/* - * Internal helper functions - */ - - char* pmix_bfrop_buffer_extend(pmix_buffer_t *bptr, size_t bytes_to_add); - - bool pmix_bfrop_too_small(pmix_buffer_t *buffer, size_t bytes_reqd); - - pmix_bfrop_type_info_t* pmix_bfrop_find_type(pmix_data_type_t type); - - pmix_status_t pmix_bfrop_store_data_type(pmix_buffer_t *buffer, pmix_data_type_t type); - - pmix_status_t pmix_bfrop_get_data_type(pmix_buffer_t *buffer, pmix_data_type_t *type); - - END_C_DECLS - -#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/internal_functions.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/internal_functions.c deleted file mode 100644 index d22333ffce..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/internal_functions.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana - * University Research and Technology - * Corporation. All rights reserved. - * Copyright (c) 2004-2006 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. - * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, - * University of Stuttgart. All rights reserved. - * Copyright (c) 2004-2005 The Regents of the University of California. - * All rights reserved. - * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. - * Copyright (c) 2017 Los Alamos National Security, LLC. All rights - * reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#include - - -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "src/class/pmix_pointer_array.h" - -#include "src/buffer_ops/internal.h" - -/** - * Internal function that resizes (expands) an inuse buffer if - * necessary. - */ -char* pmix_bfrop_buffer_extend(pmix_buffer_t *buffer, size_t bytes_to_add) -{ - size_t required, to_alloc; - size_t pack_offset, unpack_offset; - char *tmp; - - /* Check to see if we have enough space already */ - - if ((buffer->bytes_allocated - buffer->bytes_used) >= bytes_to_add) { - return buffer->pack_ptr; - } - - required = buffer->bytes_used + bytes_to_add; - if (required >= pmix_bfrop_threshold_size) { - to_alloc = (required + pmix_bfrop_threshold_size - 1) & ~(pmix_bfrop_threshold_size - 1); - } else { - to_alloc = buffer->bytes_allocated ? buffer->bytes_allocated : pmix_bfrop_initial_size; - while(to_alloc < required) { - to_alloc <<= 1; - } - } - - pack_offset = ((char*) buffer->pack_ptr) - ((char*) buffer->base_ptr); - unpack_offset = ((char*) buffer->unpack_ptr) - ((char*) buffer->base_ptr); - tmp = (char*)realloc(buffer->base_ptr, to_alloc); - if (NULL == tmp) { - return NULL; - } - - buffer->base_ptr = tmp; - - /* This memset is meant to keep valgrind happy. If possible it should be removed - * in the future. */ - memset(buffer->base_ptr + pack_offset, 0, to_alloc - buffer->bytes_allocated); - - buffer->pack_ptr = ((char*) buffer->base_ptr) + pack_offset; - buffer->unpack_ptr = ((char*) buffer->base_ptr) + unpack_offset; - buffer->bytes_allocated = to_alloc; - - /* All done */ - - return buffer->pack_ptr; -} - -/* - * Internal function that checks to see if the specified number of bytes - * remain in the buffer for unpacking - */ -bool pmix_bfrop_too_small(pmix_buffer_t *buffer, size_t bytes_reqd) -{ - size_t bytes_remaining_packed; - - if (buffer->pack_ptr < buffer->unpack_ptr) { - return true; - } - - bytes_remaining_packed = buffer->pack_ptr - buffer->unpack_ptr; - - if (bytes_remaining_packed < bytes_reqd) { - /* don't error log this - it could be that someone is trying to - * simply read until the buffer is empty - */ - return true; - } - - return false; -} - -pmix_status_t pmix_bfrop_store_data_type(pmix_buffer_t *buffer, pmix_data_type_t type) -{ - /* Lookup the pack function for the actual pmix_data_type type and call it */ - return pmix_bfrop_pack_datatype(buffer, &type, 1, PMIX_DATA_TYPE); -} - -pmix_status_t pmix_bfrop_get_data_type(pmix_buffer_t *buffer, pmix_data_type_t *type) -{ - int32_t cnt = 1; - - return pmix_bfrop_unpack_datatype(buffer, type, &cnt, PMIX_DATA_TYPE); -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c deleted file mode 100644 index 4745024554..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c +++ /dev/null @@ -1,755 +0,0 @@ -/* -*- Mode: C; c-basic-offset:4 ; -*- */ -/* - * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana - * University Research and Technology - * Corporation. All rights reserved. - * Copyright (c) 2004-2009 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. - * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, - * University of Stuttgart. All rights reserved. - * Copyright (c) 2004-2005 The Regents of the University of California. - * All rights reserved. - * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. - * Copyright (c) 2015 Research Organization for Information Science - * and Technology (RIST). All rights reserved. - * Copyright (c) 2016-2017 IBM Corporation. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ -/** @file: - * - */ -#include - -#include - -#ifdef HAVE_STRING_H -#include -#endif - -#include "src/util/argv.h" -#include "src/util/error.h" -#include "src/buffer_ops/internal.h" - -/** - * globals - */ -bool pmix_bfrop_initialized = false; -size_t pmix_bfrop_initial_size = 0; -size_t pmix_bfrop_threshold_size = 0; -pmix_pointer_array_t pmix_bfrop_types = {{0}}; -pmix_data_type_t pmix_bfrop_num_reg_types = PMIX_UNDEF; -static pmix_bfrop_buffer_type_t pmix_default_buf_type = PMIX_BFROP_BUFFER_NON_DESC; - -PMIX_EXPORT pmix_bfrop_t pmix_bfrop = { - pmix_bfrop_pack, - pmix_bfrop_unpack, - pmix_bfrop_copy, - pmix_bfrop_print, - pmix_bfrop_copy_payload, -}; - -/** - * Object constructors, destructors, and instantiations - */ -/** Value **/ -static void pmix_buffer_construct (pmix_buffer_t* buffer) -{ - /** set the default buffer type */ - buffer->type = pmix_default_buf_type; - - /* Make everything NULL to begin with */ - buffer->base_ptr = buffer->pack_ptr = buffer->unpack_ptr = NULL; - buffer->bytes_allocated = buffer->bytes_used = 0; -} - -static void pmix_buffer_destruct (pmix_buffer_t* buffer) -{ - if (NULL != buffer->base_ptr) { - free (buffer->base_ptr); - } -} - -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_buffer_t, - pmix_object_t, - pmix_buffer_construct, - pmix_buffer_destruct); - - -static void pmix_bfrop_type_info_construct(pmix_bfrop_type_info_t *obj) -{ - obj->odti_name = NULL; - obj->odti_pack_fn = NULL; - obj->odti_unpack_fn = NULL; - obj->odti_copy_fn = NULL; - obj->odti_print_fn = NULL; -} - -static void pmix_bfrop_type_info_destruct(pmix_bfrop_type_info_t *obj) -{ - if (NULL != obj->odti_name) { - free(obj->odti_name); - } -} - -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_bfrop_type_info_t, pmix_object_t, - pmix_bfrop_type_info_construct, - pmix_bfrop_type_info_destruct); - -static void kvcon(pmix_kval_t *k) -{ - k->key = NULL; - k->value = NULL; -} -static void kvdes(pmix_kval_t *k) -{ - if (NULL != k->key) { - free(k->key); - } - if (NULL != k->value) { - PMIX_VALUE_RELEASE(k->value); - } -} -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_kval_t, - pmix_list_item_t, - kvcon, kvdes); - -static void rcon(pmix_regex_range_t *p) -{ - p->start = 0; - p->cnt = 0; -} -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_regex_range_t, - pmix_list_item_t, - rcon, NULL); - -static void rvcon(pmix_regex_value_t *p) -{ - p->prefix = NULL; - p->suffix = NULL; - p->num_digits = 0; - PMIX_CONSTRUCT(&p->ranges, pmix_list_t); -} -static void rvdes(pmix_regex_value_t *p) -{ - if (NULL != p->prefix) { - free(p->prefix); - } - if (NULL != p->suffix) { - free(p->suffix); - } - PMIX_LIST_DESTRUCT(&p->ranges); -} -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_regex_value_t, - pmix_list_item_t, - rvcon, rvdes); - -PMIX_EXPORT pmix_status_t pmix_bfrop_open(void) -{ - pmix_status_t rc; - - if (pmix_bfrop_initialized) { - return PMIX_SUCCESS; - } - - /** set the default buffer type. If we are in debug mode, then we default - * to fully described buffers. Otherwise, we default to non-described for brevity - * and performance - */ -#if PMIX_ENABLE_DEBUG - pmix_default_buf_type = PMIX_BFROP_BUFFER_FULLY_DESC; -#else - pmix_default_buf_type = PMIX_BFROP_BUFFER_NON_DESC; -#endif - - /* Setup the types array */ - PMIX_CONSTRUCT(&pmix_bfrop_types, pmix_pointer_array_t); - if (PMIX_SUCCESS != (rc = pmix_pointer_array_init(&pmix_bfrop_types, 64, 255, 64))) { - return rc; - } - pmix_bfrop_num_reg_types = PMIX_UNDEF; - pmix_bfrop_threshold_size = PMIX_BFROP_DEFAULT_THRESHOLD_SIZE; - pmix_bfrop_initial_size = PMIX_BFROP_DEFAULT_INITIAL_SIZE; - - /* Register all the supported types */ - PMIX_REGISTER_TYPE("PMIX_BOOL", PMIX_BOOL, - pmix_bfrop_pack_bool, - pmix_bfrop_unpack_bool, - pmix_bfrop_std_copy, - pmix_bfrop_print_bool); - - PMIX_REGISTER_TYPE("PMIX_BYTE", PMIX_BYTE, - pmix_bfrop_pack_byte, - pmix_bfrop_unpack_byte, - pmix_bfrop_std_copy, - pmix_bfrop_print_byte); - - PMIX_REGISTER_TYPE("PMIX_STRING", PMIX_STRING, - pmix_bfrop_pack_string, - pmix_bfrop_unpack_string, - pmix_bfrop_copy_string, - pmix_bfrop_print_string); - - PMIX_REGISTER_TYPE("PMIX_SIZE", PMIX_SIZE, - pmix_bfrop_pack_sizet, - pmix_bfrop_unpack_sizet, - pmix_bfrop_std_copy, - pmix_bfrop_print_size); - - PMIX_REGISTER_TYPE("PMIX_PID", PMIX_PID, - pmix_bfrop_pack_pid, - pmix_bfrop_unpack_pid, - pmix_bfrop_std_copy, - pmix_bfrop_print_pid); - - PMIX_REGISTER_TYPE("PMIX_INT", PMIX_INT, - pmix_bfrop_pack_int, - pmix_bfrop_unpack_int, - pmix_bfrop_std_copy, - pmix_bfrop_print_int); - - PMIX_REGISTER_TYPE("PMIX_INT8", PMIX_INT8, - pmix_bfrop_pack_byte, - pmix_bfrop_unpack_byte, - pmix_bfrop_std_copy, - pmix_bfrop_print_int8); - - PMIX_REGISTER_TYPE("PMIX_INT16", PMIX_INT16, - pmix_bfrop_pack_int16, - pmix_bfrop_unpack_int16, - pmix_bfrop_std_copy, - pmix_bfrop_print_int16); - - PMIX_REGISTER_TYPE("PMIX_INT32", PMIX_INT32, - pmix_bfrop_pack_int32, - pmix_bfrop_unpack_int32, - pmix_bfrop_std_copy, - pmix_bfrop_print_int32); - - PMIX_REGISTER_TYPE("PMIX_INT64", PMIX_INT64, - pmix_bfrop_pack_int64, - pmix_bfrop_unpack_int64, - pmix_bfrop_std_copy, - pmix_bfrop_print_int64); - - PMIX_REGISTER_TYPE("PMIX_UINT", PMIX_UINT, - pmix_bfrop_pack_int, - pmix_bfrop_unpack_int, - pmix_bfrop_std_copy, - pmix_bfrop_print_uint); - - PMIX_REGISTER_TYPE("PMIX_UINT8", PMIX_UINT8, - pmix_bfrop_pack_byte, - pmix_bfrop_unpack_byte, - pmix_bfrop_std_copy, - pmix_bfrop_print_uint8); - - PMIX_REGISTER_TYPE("PMIX_UINT16", PMIX_UINT16, - pmix_bfrop_pack_int16, - pmix_bfrop_unpack_int16, - pmix_bfrop_std_copy, - pmix_bfrop_print_uint16); - - PMIX_REGISTER_TYPE("PMIX_UINT32", PMIX_UINT32, - pmix_bfrop_pack_int32, - pmix_bfrop_unpack_int32, - pmix_bfrop_std_copy, - pmix_bfrop_print_uint32); - - PMIX_REGISTER_TYPE("PMIX_UINT64", PMIX_UINT64, - pmix_bfrop_pack_int64, - pmix_bfrop_unpack_int64, - pmix_bfrop_std_copy, - pmix_bfrop_print_uint64); - - PMIX_REGISTER_TYPE("PMIX_FLOAT", PMIX_FLOAT, - pmix_bfrop_pack_float, - pmix_bfrop_unpack_float, - pmix_bfrop_std_copy, - pmix_bfrop_print_float); - - PMIX_REGISTER_TYPE("PMIX_DOUBLE", PMIX_DOUBLE, - pmix_bfrop_pack_double, - pmix_bfrop_unpack_double, - pmix_bfrop_std_copy, - pmix_bfrop_print_double); - - PMIX_REGISTER_TYPE("PMIX_TIMEVAL", PMIX_TIMEVAL, - pmix_bfrop_pack_timeval, - pmix_bfrop_unpack_timeval, - pmix_bfrop_std_copy, - pmix_bfrop_print_timeval); - - PMIX_REGISTER_TYPE("PMIX_TIME", PMIX_TIME, - pmix_bfrop_pack_time, - pmix_bfrop_unpack_time, - pmix_bfrop_std_copy, - pmix_bfrop_print_time); - - PMIX_REGISTER_TYPE("PMIX_STATUS", PMIX_STATUS, - pmix_bfrop_pack_status, - pmix_bfrop_unpack_status, - pmix_bfrop_std_copy, - pmix_bfrop_print_status); - - PMIX_REGISTER_TYPE("PMIX_VALUE", PMIX_VALUE, - pmix_bfrop_pack_value, - pmix_bfrop_unpack_value, - pmix_bfrop_copy_value, - pmix_bfrop_print_value); - - PMIX_REGISTER_TYPE("PMIX_PROC", PMIX_PROC, - pmix_bfrop_pack_proc, - pmix_bfrop_unpack_proc, - pmix_bfrop_copy_proc, - pmix_bfrop_print_proc); - - PMIX_REGISTER_TYPE("PMIX_APP", PMIX_APP, - pmix_bfrop_pack_app, - pmix_bfrop_unpack_app, - pmix_bfrop_copy_app, - pmix_bfrop_print_app); - - PMIX_REGISTER_TYPE("PMIX_INFO", PMIX_INFO, - pmix_bfrop_pack_info, - pmix_bfrop_unpack_info, - pmix_bfrop_copy_info, - pmix_bfrop_print_info); - - PMIX_REGISTER_TYPE("PMIX_PDATA", PMIX_PDATA, - pmix_bfrop_pack_pdata, - pmix_bfrop_unpack_pdata, - pmix_bfrop_copy_pdata, - pmix_bfrop_print_pdata); - - PMIX_REGISTER_TYPE("PMIX_BUFFER", PMIX_BUFFER, - pmix_bfrop_pack_buf, - pmix_bfrop_unpack_buf, - pmix_bfrop_copy_buf, - pmix_bfrop_print_buf); - - PMIX_REGISTER_TYPE("PMIX_BYTE_OBJECT", PMIX_BYTE_OBJECT, - pmix_bfrop_pack_bo, - pmix_bfrop_unpack_bo, - pmix_bfrop_copy_bo, - pmix_bfrop_print_bo); - - PMIX_REGISTER_TYPE("PMIX_KVAL", PMIX_KVAL, - pmix_bfrop_pack_kval, - pmix_bfrop_unpack_kval, - pmix_bfrop_copy_kval, - pmix_bfrop_print_kval); - - PMIX_REGISTER_TYPE("PMIX_MODEX", PMIX_MODEX, - pmix_bfrop_pack_modex, - pmix_bfrop_unpack_modex, - pmix_bfrop_copy_modex, - pmix_bfrop_print_modex); - - PMIX_REGISTER_TYPE("PMIX_PERSIST", PMIX_PERSIST, - pmix_bfrop_pack_persist, - pmix_bfrop_unpack_persist, - pmix_bfrop_std_copy, - pmix_bfrop_print_persist); - - PMIX_REGISTER_TYPE("PMIX_POINTER", PMIX_POINTER, - pmix_bfrop_pack_ptr, - pmix_bfrop_unpack_ptr, - pmix_bfrop_std_copy, - pmix_bfrop_print_ptr); - - PMIX_REGISTER_TYPE("PMIX_SCOPE", PMIX_SCOPE, - pmix_bfrop_pack_scope, - pmix_bfrop_unpack_scope, - pmix_bfrop_std_copy, - pmix_bfrop_print_scope); - - PMIX_REGISTER_TYPE("PMIX_DATA_RANGE", PMIX_DATA_RANGE, - pmix_bfrop_pack_range, - pmix_bfrop_unpack_range, - pmix_bfrop_std_copy, - pmix_bfrop_print_range); - - PMIX_REGISTER_TYPE("PMIX_COMMAND", PMIX_COMMAND, - pmix_bfrop_pack_cmd, - pmix_bfrop_unpack_cmd, - pmix_bfrop_std_copy, - pmix_bfrop_print_cmd); - - PMIX_REGISTER_TYPE("PMIX_INFO_DIRECTIVES", PMIX_INFO_DIRECTIVES, - pmix_bfrop_pack_infodirs, - pmix_bfrop_unpack_infodirs, - pmix_bfrop_std_copy, - pmix_bfrop_print_infodirs); - - PMIX_REGISTER_TYPE("PMIX_PROC_STATE", PMIX_PROC_STATE, - pmix_bfrop_pack_pstate, - pmix_bfrop_unpack_pstate, - pmix_bfrop_std_copy, - pmix_bfrop_print_pstate); - - PMIX_REGISTER_TYPE("PMIX_PROC_INFO", PMIX_PROC_INFO, - pmix_bfrop_pack_pinfo, - pmix_bfrop_unpack_pinfo, - pmix_bfrop_copy_pinfo, - pmix_bfrop_print_pinfo); - - PMIX_REGISTER_TYPE("PMIX_DATA_ARRAY", PMIX_DATA_ARRAY, - pmix_bfrop_pack_darray, - pmix_bfrop_unpack_darray, - pmix_bfrop_copy_darray, - pmix_bfrop_print_darray); - - PMIX_REGISTER_TYPE("PMIX_PROC_RANK", PMIX_PROC_RANK, - pmix_bfrop_pack_rank, - pmix_bfrop_unpack_rank, - pmix_bfrop_std_copy, - pmix_bfrop_print_rank); - - PMIX_REGISTER_TYPE("PMIX_QUERY", PMIX_QUERY, - pmix_bfrop_pack_query, - pmix_bfrop_unpack_query, - pmix_bfrop_copy_query, - pmix_bfrop_print_query); - - PMIX_REGISTER_TYPE("PMIX_COMPRESSED_STRING", - PMIX_COMPRESSED_STRING, - pmix_bfrop_pack_bo, - pmix_bfrop_unpack_bo, - pmix_bfrop_copy_bo, - pmix_bfrop_print_bo); - - PMIX_REGISTER_TYPE("PMIX_ALLOC_DIRECTIVE", - PMIX_ALLOC_DIRECTIVE, - pmix_bfrop_pack_alloc_directive, - pmix_bfrop_unpack_alloc_directive, - pmix_bfrop_std_copy, - pmix_bfrop_print_alloc_directive); - - /**** DEPRECATED ****/ - PMIX_REGISTER_TYPE("PMIX_INFO_ARRAY", PMIX_INFO_ARRAY, - pmix_bfrop_pack_array, - pmix_bfrop_unpack_array, - pmix_bfrop_copy_array, - pmix_bfrop_print_array); - /********************/ - - /* All done */ - pmix_bfrop_initialized = true; - return PMIX_SUCCESS; -} - - -PMIX_EXPORT pmix_status_t pmix_bfrop_close(void) -{ - int32_t i; - - if (!pmix_bfrop_initialized) { - return PMIX_SUCCESS; - } - pmix_bfrop_initialized = false; - - for (i = 0 ; i < pmix_pointer_array_get_size(&pmix_bfrop_types) ; ++i) { - pmix_bfrop_type_info_t *info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&pmix_bfrop_types, i); - if (NULL != info) { - pmix_pointer_array_set_item(&pmix_bfrop_types, i, NULL); - PMIX_RELEASE(info); - } - } - - PMIX_DESTRUCT(&pmix_bfrop_types); - - return PMIX_SUCCESS; -} - -/**** UTILITY SUPPORT ****/ -PMIX_EXPORT void pmix_value_load(pmix_value_t *v, - const void *data, - pmix_data_type_t type) -{ - pmix_byte_object_t *bo; - pmix_proc_info_t *pi; - - v->type = type; - if (NULL == data) { - /* just set the fields to zero */ - memset(&v->data, 0, sizeof(v->data)); - if (PMIX_BOOL == type) { - v->data.flag = true; // existence of the attribute indicates true unless specified different - } - } else { - switch(type) { - case PMIX_UNDEF: - break; - case PMIX_BOOL: - memcpy(&(v->data.flag), data, 1); - break; - case PMIX_BYTE: - memcpy(&(v->data.byte), data, 1); - break; - case PMIX_STRING: - v->data.string = strdup(data); - break; - case PMIX_SIZE: - memcpy(&(v->data.size), data, sizeof(size_t)); - break; - case PMIX_PID: - memcpy(&(v->data.pid), data, sizeof(pid_t)); - break; - case PMIX_INT: - memcpy(&(v->data.integer), data, sizeof(int)); - break; - case PMIX_INT8: - memcpy(&(v->data.int8), data, 1); - break; - case PMIX_INT16: - memcpy(&(v->data.int16), data, 2); - break; - case PMIX_INT32: - memcpy(&(v->data.int32), data, 4); - break; - case PMIX_INT64: - memcpy(&(v->data.int64), data, 8); - break; - case PMIX_UINT: - memcpy(&(v->data.uint), data, sizeof(int)); - break; - case PMIX_UINT8: - memcpy(&(v->data.uint8), data, 1); - break; - case PMIX_UINT16: - memcpy(&(v->data.uint16), data, 2); - break; - case PMIX_UINT32: - memcpy(&(v->data.uint32), data, 4); - break; - case PMIX_UINT64: - memcpy(&(v->data.uint64), data, 8); - break; - case PMIX_FLOAT: - memcpy(&(v->data.fval), data, sizeof(float)); - break; - case PMIX_DOUBLE: - memcpy(&(v->data.dval), data, sizeof(double)); - break; - case PMIX_TIMEVAL: - memcpy(&(v->data.tv), data, sizeof(struct timeval)); - break; - case PMIX_TIME: - memcpy(&(v->data.time), data, sizeof(time_t)); - break; - case PMIX_STATUS: - memcpy(&(v->data.status), data, sizeof(pmix_status_t)); - break; - case PMIX_PROC_RANK: - memcpy(&(v->data.rank), data, sizeof(pmix_rank_t)); - break; - case PMIX_PROC: - PMIX_PROC_CREATE(v->data.proc, 1); - if (NULL == v->data.proc) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - return; - } - memcpy(v->data.proc, data, sizeof(pmix_proc_t)); - break; - case PMIX_BYTE_OBJECT: - bo = (pmix_byte_object_t*)data; - v->data.bo.bytes = bo->bytes; - memcpy(&(v->data.bo.size), &bo->size, sizeof(size_t)); - break; - case PMIX_PERSIST: - memcpy(&(v->data.persist), data, sizeof(pmix_persistence_t)); - break; - case PMIX_SCOPE: - memcpy(&(v->data.scope), data, sizeof(pmix_scope_t)); - break; - case PMIX_DATA_RANGE: - memcpy(&(v->data.range), data, sizeof(pmix_data_range_t)); - break; - case PMIX_PROC_STATE: - memcpy(&(v->data.state), data, sizeof(pmix_proc_state_t)); - break; - case PMIX_PROC_INFO: - PMIX_PROC_INFO_CREATE(v->data.pinfo, 1); - if (NULL == v->data.pinfo) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - return; - } - pi = (pmix_proc_info_t*)data; - memcpy(&(v->data.pinfo->proc), &pi->proc, sizeof(pmix_proc_t)); - if (NULL != pi->hostname) { - v->data.pinfo->hostname = strdup(pi->hostname); - } - if (NULL != pi->executable_name) { - v->data.pinfo->executable_name = strdup(pi->executable_name); - } - memcpy(&(v->data.pinfo->pid), &pi->pid, sizeof(pid_t)); - memcpy(&(v->data.pinfo->exit_code), &pi->exit_code, sizeof(int)); - break; - case PMIX_POINTER: - memcpy(&(v->data.ptr), data, sizeof(void*)); - break; - default: - /* silence warnings */ - PMIX_ERROR_LOG(PMIX_ERR_UNKNOWN_DATA_TYPE); - break; - } - } -} - -pmix_status_t pmix_value_unload(pmix_value_t *kv, void **data, - size_t *sz, pmix_data_type_t type) -{ - pmix_status_t rc; - pmix_proc_t *pc; - - rc = PMIX_SUCCESS; - if (type != kv->type) { - rc = PMIX_ERR_TYPE_MISMATCH; - } else if (NULL == data || - (NULL == *data && PMIX_STRING != type && PMIX_BYTE_OBJECT != type)) { - rc = PMIX_ERR_BAD_PARAM; - } else { - switch(type) { - case PMIX_UNDEF: - rc = PMIX_ERR_UNKNOWN_DATA_TYPE; - break; - case PMIX_BOOL: - memcpy(*data, &(kv->data.flag), 1); - *sz = 1; - break; - case PMIX_BYTE: - memcpy(*data, &(kv->data.byte), 1); - *sz = 1; - break; - case PMIX_STRING: - if (NULL != kv->data.string) { - *data = strdup(kv->data.string); - *sz = strlen(kv->data.string); - } - break; - case PMIX_SIZE: - memcpy(*data, &(kv->data.size), sizeof(size_t)); - *sz = sizeof(size_t); - break; - case PMIX_PID: - memcpy(*data, &(kv->data.pid), sizeof(pid_t)); - *sz = sizeof(pid_t); - break; - case PMIX_INT: - memcpy(*data, &(kv->data.integer), sizeof(int)); - *sz = sizeof(int); - break; - case PMIX_INT8: - memcpy(*data, &(kv->data.int8), 1); - *sz = 1; - break; - case PMIX_INT16: - memcpy(*data, &(kv->data.int16), 2); - *sz = 2; - break; - case PMIX_INT32: - memcpy(*data, &(kv->data.int32), 4); - *sz = 4; - break; - case PMIX_INT64: - memcpy(*data, &(kv->data.int64), 8); - *sz = 8; - break; - case PMIX_UINT: - memcpy(*data, &(kv->data.uint), sizeof(int)); - *sz = sizeof(int); - break; - case PMIX_UINT8: - memcpy(*data, &(kv->data.uint8), 1); - *sz = 1; - break; - case PMIX_UINT16: - memcpy(*data, &(kv->data.uint16), 2); - *sz = 2; - break; - case PMIX_UINT32: - memcpy(*data, &(kv->data.uint32), 4); - *sz = 4; - break; - case PMIX_UINT64: - memcpy(*data, &(kv->data.uint64), 8); - *sz = 8; - break; - case PMIX_FLOAT: - memcpy(*data, &(kv->data.fval), sizeof(float)); - *sz = sizeof(float); - break; - case PMIX_DOUBLE: - memcpy(*data, &(kv->data.dval), sizeof(double)); - *sz = sizeof(double); - break; - case PMIX_TIMEVAL: - memcpy(*data, &(kv->data.tv), sizeof(struct timeval)); - *sz = sizeof(struct timeval); - break; - case PMIX_TIME: - memcpy(*data, &(kv->data.time), sizeof(time_t)); - *sz = sizeof(time_t); - break; - case PMIX_STATUS: - memcpy(*data, &(kv->data.status), sizeof(pmix_status_t)); - *sz = sizeof(pmix_status_t); - break; - case PMIX_PROC_RANK: - memcpy(*data, &(kv->data.rank), sizeof(pmix_rank_t)); - *sz = sizeof(pmix_rank_t); - break; - case PMIX_PROC: - PMIX_PROC_CREATE(pc, 1); - if (NULL == pc) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - rc = PMIX_ERR_NOMEM; - break; - } - memcpy(pc, kv->data.proc, sizeof(pmix_proc_t)); - *sz = sizeof(pmix_proc_t); - *data = pc; - break; - case PMIX_BYTE_OBJECT: - if (NULL != kv->data.bo.bytes && 0 < kv->data.bo.size) { - *data = kv->data.bo.bytes; - *sz = kv->data.bo.size; - } else { - *data = NULL; - *sz = 0; - } - break; - case PMIX_PERSIST: - memcpy(*data, &(kv->data.persist), sizeof(pmix_persistence_t)); - *sz = sizeof(pmix_persistence_t); - break; - case PMIX_SCOPE: - memcpy(*data, &(kv->data.scope), sizeof(pmix_scope_t)); - *sz = sizeof(pmix_scope_t); - break; - case PMIX_DATA_RANGE: - memcpy(*data, &(kv->data.range), sizeof(pmix_data_range_t)); - *sz = sizeof(pmix_data_range_t); - break; - case PMIX_PROC_STATE: - memcpy(*data, &(kv->data.state), sizeof(pmix_proc_state_t)); - *sz = sizeof(pmix_proc_state_t); - break; - case PMIX_POINTER: - memcpy(*data, &(kv->data.ptr), sizeof(void*)); - *sz = sizeof(void*); - break; - default: - /* silence warnings */ - rc = PMIX_ERROR; - break; - } - } - return rc; -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/pack.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/pack.c deleted file mode 100644 index 000be85c5b..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/pack.c +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana - * University Research and Technology - * Corporation. All rights reserved. - * Copyright (c) 2004-2007 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. - * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, - * University of Stuttgart. All rights reserved. - * Copyright (c) 2004-2005 The Regents of the University of California. - * All rights reserved. - * Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. - * Copyright (c) 2015 Research Organization for Information Science - * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Mellanox Technologies, Inc. - * All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#include - -#include - -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#include "src/util/argv.h" -#include "src/util/error.h" -#include "src/util/output.h" -#include "src/buffer_ops/internal.h" - -pmix_status_t pmix_bfrop_pack(pmix_buffer_t *buffer, - const void *src, int32_t num_vals, - pmix_data_type_t type) - { - pmix_status_t rc; - - /* check for error */ - if (NULL == buffer) { - return PMIX_ERR_BAD_PARAM; - } - - /* Pack the number of values */ - if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { - if (PMIX_SUCCESS != (rc = pmix_bfrop_store_data_type(buffer, PMIX_INT32))) { - return rc; - } - } - if (PMIX_SUCCESS != (rc = pmix_bfrop_pack_int32(buffer, &num_vals, 1, PMIX_INT32))) { - return rc; - } - - /* Pack the value(s) */ - return pmix_bfrop_pack_buffer(buffer, src, num_vals, type); -} - -pmix_status_t pmix_bfrop_pack_buffer(pmix_buffer_t *buffer, - const void *src, int32_t num_vals, - pmix_data_type_t type) -{ - pmix_status_t rc; - pmix_bfrop_type_info_t *info; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_pack_buffer( %p, %p, %lu, %d )\n", - (void*)buffer, src, (long unsigned int)num_vals, (int)type); - - /* Pack the declared data type */ - if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { - if (PMIX_SUCCESS != (rc = pmix_bfrop_store_data_type(buffer, type))) { - return rc; - } - } - - /* Lookup the pack 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_PACK_FAILURE; - } - - return info->odti_pack_fn(buffer, src, num_vals, type); -} - - -/* PACK FUNCTIONS FOR GENERIC SYSTEM TYPES */ - -/* - * BOOL - */ -pmix_status_t pmix_bfrop_pack_bool(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - uint8_t *dst; - int32_t i; - bool *s = (bool*)src; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_pack_bool * %d\n", num_vals); - /* check to see if buffer needs extending */ - if (NULL == (dst = (uint8_t*)pmix_bfrop_buffer_extend(buffer, num_vals))) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - - /* store the data */ - for (i=0; i < num_vals; i++) { - if (s[i]) { - dst[i] = 1; - } else { - dst[i] = 0; - } - } - - /* update buffer pointers */ - buffer->pack_ptr += num_vals; - buffer->bytes_used += num_vals; - - return PMIX_SUCCESS; -} - -/* - * INT - */ -pmix_status_t pmix_bfrop_pack_int(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - pmix_status_t ret; - - /* System types need to always be described so we can properly - unpack them */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, BFROP_TYPE_INT))) { - return ret; - } - - /* Turn around and pack the real type */ - return pmix_bfrop_pack_buffer(buffer, src, num_vals, BFROP_TYPE_INT); -} - -/* - * SIZE_T - */ -pmix_status_t pmix_bfrop_pack_sizet(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - pmix_status_t ret; - - /* System types need to always be described so we can properly - unpack them. */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, BFROP_TYPE_SIZE_T))) { - return ret; - } - - return pmix_bfrop_pack_buffer(buffer, src, num_vals, BFROP_TYPE_SIZE_T); -} - -/* - * PID_T - */ -pmix_status_t pmix_bfrop_pack_pid(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - pmix_status_t ret; - - /* System types need to always be described so we can properly - unpack them. */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, BFROP_TYPE_PID_T))) { - return ret; - } - - /* Turn around and pack the real type */ - return pmix_bfrop_pack_buffer(buffer, src, num_vals, BFROP_TYPE_PID_T); -} - - -/* PACK FUNCTIONS FOR NON-GENERIC SYSTEM TYPES */ - -/* - * BYTE, CHAR, INT8 - */ -pmix_status_t pmix_bfrop_pack_byte(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - char *dst; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_pack_byte * %d\n", num_vals); - /* check to see if buffer needs extending */ - if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, num_vals))) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - - /* store the data */ - memcpy(dst, src, num_vals); - - /* update buffer pointers */ - buffer->pack_ptr += num_vals; - buffer->bytes_used += num_vals; - - return PMIX_SUCCESS; -} - -/* - * INT16 - */ -pmix_status_t pmix_bfrop_pack_int16(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - int32_t i; - uint16_t tmp, *srctmp = (uint16_t*) src; - char *dst; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_pack_int16 * %d\n", num_vals); - /* check to see if buffer needs extending */ - if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, num_vals*sizeof(tmp)))) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - - for (i = 0; i < num_vals; ++i) { - tmp = pmix_htons(srctmp[i]); - memcpy(dst, &tmp, sizeof(tmp)); - dst += sizeof(tmp); - } - buffer->pack_ptr += num_vals * sizeof(tmp); - buffer->bytes_used += num_vals * sizeof(tmp); - - return PMIX_SUCCESS; -} - -/* - * INT32 - */ -pmix_status_t pmix_bfrop_pack_int32(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - int32_t i; - uint32_t tmp, *srctmp = (uint32_t*) src; - char *dst; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_pack_int32 * %d\n", num_vals); - /* check to see if buffer needs extending */ - if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, num_vals*sizeof(tmp)))) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - - for (i = 0; i < num_vals; ++i) { - tmp = htonl(srctmp[i]); - memcpy(dst, &tmp, sizeof(tmp)); - dst += sizeof(tmp); - } - buffer->pack_ptr += num_vals * sizeof(tmp); - buffer->bytes_used += num_vals * sizeof(tmp); - - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_datatype(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_int16(buffer, src, num_vals, type); -} - -/* - * INT64 - */ -pmix_status_t pmix_bfrop_pack_int64(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - int32_t i; - uint64_t tmp, tmp2; - char *dst; - size_t bytes_packed = num_vals * sizeof(tmp); - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_pack_int64 * %d\n", num_vals); - /* check to see if buffer needs extending */ - if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, bytes_packed))) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - - for (i = 0; i < num_vals; ++i) { - memcpy(&tmp2, (char *)src+i*sizeof(uint64_t), sizeof(uint64_t)); - tmp = pmix_hton64(tmp2); - memcpy(dst, &tmp, sizeof(tmp)); - dst += sizeof(tmp); - } - buffer->pack_ptr += bytes_packed; - buffer->bytes_used += bytes_packed; - - return PMIX_SUCCESS; -} - -/* - * STRING - */ -pmix_status_t pmix_bfrop_pack_string(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - pmix_status_t ret = PMIX_SUCCESS; - int32_t i, len; - char **ssrc = (char**) src; - - for (i = 0; i < num_vals; ++i) { - if (NULL == ssrc[i]) { /* got zero-length string/NULL pointer - store NULL */ - len = 0; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int32(buffer, &len, 1, PMIX_INT32))) { - return ret; - } - } else { - len = (int32_t)strlen(ssrc[i]) + 1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int32(buffer, &len, 1, PMIX_INT32))) { - return ret; - } - if (PMIX_SUCCESS != (ret = - pmix_bfrop_pack_byte(buffer, ssrc[i], len, PMIX_BYTE))) { - return ret; - } -} -} - -return PMIX_SUCCESS; -} - -/* FLOAT */ -pmix_status_t pmix_bfrop_pack_float(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_status_t ret = PMIX_SUCCESS; - int32_t i; - float *ssrc = (float*)src; - char *convert; - - for (i = 0; i < num_vals; ++i) { - if (0 > asprintf(&convert, "%f", ssrc[i])) { - return PMIX_ERR_NOMEM; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &convert, 1, PMIX_STRING))) { - free(convert); - return ret; - } - free(convert); - } - - return PMIX_SUCCESS; -} - -/* DOUBLE */ -pmix_status_t pmix_bfrop_pack_double(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_status_t ret = PMIX_SUCCESS; - int32_t i; - double *ssrc = (double*)src; - char *convert; - - for (i = 0; i < num_vals; ++i) { - if (0 > asprintf(&convert, "%f", ssrc[i])) { - return PMIX_ERR_NOMEM; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &convert, 1, PMIX_STRING))) { - free(convert); - return ret; - } - free(convert); - } - - return PMIX_SUCCESS; -} - -/* TIMEVAL */ -pmix_status_t pmix_bfrop_pack_timeval(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - int64_t tmp[2]; - pmix_status_t ret = PMIX_SUCCESS; - int32_t i; - struct timeval *ssrc = (struct timeval *)src; - - for (i = 0; i < num_vals; ++i) { - tmp[0] = (int64_t)ssrc[i].tv_sec; - tmp[1] = (int64_t)ssrc[i].tv_usec; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int64(buffer, tmp, 2, PMIX_INT64))) { - return ret; - } - } - - return PMIX_SUCCESS; -} - -/* TIME */ -pmix_status_t pmix_bfrop_pack_time(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_status_t ret = PMIX_SUCCESS; - int32_t i; - time_t *ssrc = (time_t *)src; - uint64_t ui64; - - /* time_t is a system-dependent size, so cast it - * to uint64_t as a generic safe size - */ - for (i = 0; i < num_vals; ++i) { - ui64 = (uint64_t)ssrc[i]; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int64(buffer, &ui64, 1, PMIX_UINT64))) { - return ret; - } - } - - return PMIX_SUCCESS; -} - -/* STATUS */ -pmix_status_t pmix_bfrop_pack_status(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_status_t ret = PMIX_SUCCESS; - int32_t i; - pmix_status_t *ssrc = (pmix_status_t *)src; - int32_t status; - - for (i = 0; i < num_vals; ++i) { - status = (int32_t)ssrc[i]; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int32(buffer, &status, 1, PMIX_INT32))) { - return ret; - } - } - - 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; - - switch (p->type) { - case PMIX_UNDEF: - break; - 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_TIME: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.time, 1, PMIX_TIME))) { - 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_PROC: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, p->data.proc, 1, PMIX_PROC))) { - return ret; - } - break; - case PMIX_PROC_RANK: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.rank, 1, PMIX_PROC_RANK))) { - return ret; - } - break; - case PMIX_BYTE_OBJECT: - case PMIX_COMPRESSED_STRING: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.bo, 1, PMIX_BYTE_OBJECT))) { - return ret; - } - break; - case PMIX_PERSIST: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.persist, 1, PMIX_PERSIST))) { - return ret; - } - break; - case PMIX_POINTER: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.ptr, 1, PMIX_POINTER))) { - return ret; - } - break; - case PMIX_SCOPE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.scope, 1, PMIX_SCOPE))) { - return ret; - } - break; - case PMIX_DATA_RANGE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.range, 1, PMIX_DATA_RANGE))) { - return ret; - } - break; - case PMIX_PROC_STATE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.state, 1, PMIX_PROC_STATE))) { - return ret; - } - break; - case PMIX_PROC_INFO: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, p->data.pinfo, 1, PMIX_PROC_INFO))) { - return ret; - } - break; - case PMIX_DATA_ARRAY: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, p->data.darray, 1, PMIX_DATA_ARRAY))) { - return ret; - } - break; - case PMIX_QUERY: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, p->data.darray, 1, PMIX_QUERY))) { - return ret; - } - break; - /**** DEPRECATED ****/ - case PMIX_INFO_ARRAY: - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, p->data.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; -} - -/* - * PMIX_VALUE - */ - pmix_status_t pmix_bfrop_pack_value(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) - { - pmix_value_t *ptr; - int32_t i; - pmix_status_t ret; - - ptr = (pmix_value_t *) src; - - for (i = 0; i < num_vals; ++i) { - /* pack the type */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, ptr[i].type))) { - return ret; - } - /* now pack the right field */ - if (PMIX_SUCCESS != (ret = pack_val(buffer, &ptr[i]))) { - return ret; - } - } - - return PMIX_SUCCESS; -} - - -pmix_status_t pmix_bfrop_pack_info(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_info_t *info; - int32_t i; - pmix_status_t ret; - char *foo; - - info = (pmix_info_t *) src; - - for (i = 0; i < num_vals; ++i) { - /* pack key */ - foo = info[i].key; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &foo, 1, PMIX_STRING))) { - return ret; - } - /* pack info directives flag */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_infodirs(buffer, &info[i].flags, 1, PMIX_INFO_DIRECTIVES))) { - return ret; - } - /* pack the type */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int(buffer, &info[i].value.type, 1, PMIX_INT))) { - return ret; - } - /* pack value */ - if (PMIX_SUCCESS != (ret = pack_val(buffer, &info[i].value))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_pdata(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_pdata_t *pdata; - int32_t i; - pmix_status_t ret; - char *foo; - - pdata = (pmix_pdata_t *) src; - - for (i = 0; i < num_vals; ++i) { - /* pack the proc */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_proc(buffer, &pdata[i].proc, 1, PMIX_PROC))) { - return ret; - } - /* pack key */ - foo = pdata[i].key; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &foo, 1, PMIX_STRING))) { - return ret; - } - /* pack the type */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int(buffer, &pdata[i].value.type, 1, PMIX_INT))) { - return ret; - } - /* pack value */ - if (PMIX_SUCCESS != (ret = pack_val(buffer, &pdata[i].value))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_buf(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_buffer_t **ptr; - int32_t i; - pmix_status_t ret; - - ptr = (pmix_buffer_t **) src; - - for (i = 0; i < num_vals; ++i) { - /* pack the number of bytes */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_sizet(buffer, &ptr[i]->bytes_used, 1, PMIX_SIZE))) { - return ret; - } - /* pack the bytes */ - if (0 < ptr[i]->bytes_used) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_byte(buffer, ptr[i]->base_ptr, ptr[i]->bytes_used, PMIX_BYTE))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_proc(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_proc_t *proc; - int32_t i; - pmix_status_t ret; - - proc = (pmix_proc_t *) src; - - for (i = 0; i < num_vals; ++i) { - char *ptr = proc[i].nspace; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &ptr, 1, PMIX_STRING))) { - return ret; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_rank(buffer, &proc[i].rank, 1, PMIX_PROC_RANK))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_app(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_app_t *app; - int32_t i, j, nvals; - pmix_status_t ret; - - app = (pmix_app_t *) src; - - for (i = 0; i < num_vals; ++i) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &app[i].cmd, 1, PMIX_STRING))) { - return ret; - } - /* argv */ - nvals = pmix_argv_count(app[i].argv); - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int(buffer, &nvals, 1, PMIX_INT32))) { - return ret; - } - for (j=0; j < nvals; j++) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &app[i].argv[j], 1, PMIX_STRING))) { - return ret; - } - } - /* env */ - nvals = pmix_argv_count(app[i].env); - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int32(buffer, &nvals, 1, PMIX_INT32))) { - return ret; - } - for (j=0; j < nvals; j++) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &app[i].env[j], 1, PMIX_STRING))) { - return ret; - } - } - /* cwd */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &app[i].cwd, 1, PMIX_STRING))) { - return ret; - } - /* maxprocs */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int(buffer, &app[i].maxprocs, 1, PMIX_INT))) { - return ret; - } - /* info array */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_sizet(buffer, &app[i].ninfo, 1, PMIX_SIZE))) { - return ret; - } - if (0 < app[i].ninfo) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_info(buffer, app[i].info, app[i].ninfo, PMIX_INFO))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - - -pmix_status_t pmix_bfrop_pack_kval(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_kval_t *ptr; - int32_t i; - pmix_status_t ret; - char *st; - - ptr = (pmix_kval_t *) src; - - for (i = 0; i < num_vals; ++i) { - /* pack the key */ - st = ptr[i].key; - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &st, 1, PMIX_STRING))) { - return ret; - } - /* pack the value */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_value(buffer, ptr[i].value, 1, PMIX_VALUE))) { - return ret; - } - } - - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_modex(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_modex_data_t *ptr; - int32_t i; - pmix_status_t ret; - - ptr = (pmix_modex_data_t *) src; - - for (i = 0; i < num_vals; ++i) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_sizet(buffer, &ptr[i].size, 1, PMIX_SIZE))) { - return ret; - } - if( 0 < ptr[i].size){ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_byte(buffer, ptr[i].blob, ptr[i].size, PMIX_UINT8))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_persist(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_byte(buffer, src, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_pack_scope(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_byte(buffer, src, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_pack_range(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_byte(buffer, src, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_pack_cmd(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_byte(buffer, src, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_pack_infodirs(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_int32(buffer, src, num_vals, PMIX_UINT32); -} - -pmix_status_t pmix_bfrop_pack_bo(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_status_t ret; - int i; - pmix_byte_object_t *bo; - - bo = (pmix_byte_object_t*)src; - for (i=0; i < num_vals; i++) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_sizet(buffer, &bo[i].size, 1, PMIX_SIZE))) { - return ret; - } - if (0 < bo[i].size) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_byte(buffer, bo[i].bytes, bo[i].size, PMIX_BYTE))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_ptr(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - uint8_t foo=1; - /* it obviously makes no sense to pack a pointer and - * send it somewhere else, so we just pack a sentinel */ - return pmix_bfrop_pack_byte(buffer, &foo, 1, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_pack_pstate(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_byte(buffer, src, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_pack_pinfo(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_proc_info_t *pinfo = (pmix_proc_info_t*)src; - pmix_status_t ret; - int32_t i; - - for (i=0; i < num_vals; i++) { - /* pack the proc identifier */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_proc(buffer, &pinfo[i].proc, 1, PMIX_PROC))) { - return ret; - } - /* pack the hostname and exec */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &pinfo[i].hostname, 1, PMIX_STRING))) { - return ret; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &pinfo[i].executable_name, 1, PMIX_STRING))) { - return ret; - } - /* pack the pid and state */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_pid(buffer, &pinfo[i].pid, 1, PMIX_PID))) { - return ret; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_pstate(buffer, &pinfo[i].state, 1, PMIX_PROC_STATE))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_darray(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_data_array_t *p = (pmix_data_array_t*)src; - pmix_status_t ret; - int32_t i; - - for (i=0; i < num_vals; i++) { - /* pack the actual type in the array */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_datatype(buffer, &p[i].type, 1, PMIX_DATA_TYPE))) { - return ret; - } - /* pack the number of array elements */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_sizet(buffer, &p[i].size, 1, PMIX_SIZE))) { - return ret; - } - if (0 == p[i].size || PMIX_UNDEF == p[i].type) { - /* nothing left to do */ - continue; - } - /* pack the actual elements */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, p[i].array, p[i].size, p[i].type))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_rank(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_int32(buffer, src, num_vals, PMIX_UINT32); -} - -pmix_status_t pmix_bfrop_pack_query(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_query_t *pq = (pmix_query_t*)src; - pmix_status_t ret; - int32_t i; - int32_t nkeys; - - for (i=0; i < num_vals; i++) { - /* pack the number of keys */ - nkeys = pmix_argv_count(pq[i].keys); - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int32(buffer, &nkeys, 1, PMIX_INT32))) { - return ret; - } - if (0 < nkeys) { - /* pack the keys */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, pq[i].keys, nkeys, PMIX_STRING))) { - return ret; - } - } - /* pack the number of qualifiers */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_sizet(buffer, &pq[i].nqual, 1, PMIX_SIZE))) { - return ret; - } - if (0 < pq[i].nqual) { - /* pack any provided qualifiers */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_info(buffer, pq[i].qualifiers, pq[i].nqual, PMIX_INFO))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_pack_alloc_directive(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_pack_byte(buffer, src, num_vals, PMIX_UINT8); -} - - -/**** DEPRECATED ****/ -pmix_status_t pmix_bfrop_pack_array(pmix_buffer_t *buffer, const void *src, - int32_t num_vals, pmix_data_type_t type) -{ - pmix_info_array_t *ptr; - int32_t i; - pmix_status_t ret; - - ptr = (pmix_info_array_t *) src; - - for (i = 0; i < num_vals; ++i) { - /* pack the size */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_sizet(buffer, &ptr[i].size, 1, PMIX_SIZE))) { - return ret; - } - if (0 < ptr[i].size) { - /* pack the values */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_info(buffer, ptr[i].array, ptr[i].size, PMIX_INFO))) { - return ret; - } - } - } - - return PMIX_SUCCESS; -} -/********************/ diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/types.h b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/types.h deleted file mode 100644 index c48a30b8b5..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/types.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- C -*- - * - * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana - * University Research and Technology - * Corporation. All rights reserved. - * Copyright (c) 2004-2006 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. - * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, - * University of Stuttgart. All rights reserved. - * Copyright (c) 2004-2005 The Regents of the University of California. - * All rights reserved. - * Copyright (c) 2007-2011 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ -/** - * @file - * - * Buffer management types. - */ - -#ifndef PMIX_BFROP_TYPES_H_ -#define PMIX_BFROP_TYPES_H_ - -#include - - -#include "src/class/pmix_object.h" -#include "src/class/pmix_pointer_array.h" -#include "src/class/pmix_list.h" -#include - -BEGIN_C_DECLS - -/* define the results values for comparisons so we can change them in only one place */ -#define PMIX_VALUE1_GREATER +1 -#define PMIX_VALUE2_GREATER -1 -#define PMIX_EQUAL 0 - -/** - * buffer type - */ -enum pmix_bfrop_buffer_type_t { - PMIX_BFROP_BUFFER_NON_DESC = 0x00, - PMIX_BFROP_BUFFER_FULLY_DESC = 0x01 -}; - -typedef enum pmix_bfrop_buffer_type_t pmix_bfrop_buffer_type_t; - -#define PMIX_BFROP_BUFFER_TYPE_HTON(h); -#define PMIX_BFROP_BUFFER_TYPE_NTOH(h); - -/** - * Structure for holding a buffer */ -typedef struct { - /** First member must be the object's parent */ - pmix_object_t parent; - /** type of buffer */ - pmix_bfrop_buffer_type_t type; - /** Start of my memory */ - char *base_ptr; - /** Where the next data will be packed to (within the allocated - memory starting at base_ptr) */ - char *pack_ptr; - /** Where the next data will be unpacked from (within the - allocated memory starting as base_ptr) */ - char *unpack_ptr; - - /** Number of bytes allocated (starting at base_ptr) */ - size_t bytes_allocated; - /** Number of bytes used by the buffer (i.e., amount of data -- - including overhead -- packed in the buffer) */ - size_t bytes_used; -} pmix_buffer_t; -PMIX_CLASS_DECLARATION (pmix_buffer_t); - -/* these classes are required by the regex code shared - * between the client and server implementations - it - * is put here so that both can access these objects */ -typedef struct { - pmix_list_item_t super; - int start; - int cnt; -} pmix_regex_range_t; -PMIX_CLASS_DECLARATION(pmix_regex_range_t); - -typedef struct { - /* list object */ - pmix_list_item_t super; - char *prefix; - char *suffix; - int num_digits; - pmix_list_t ranges; -} pmix_regex_value_t; -PMIX_CLASS_DECLARATION(pmix_regex_value_t); - -END_C_DECLS - -#endif /* PMIX_BFROP_TYPES_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/unpack.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/unpack.c deleted file mode 100644 index 8296f8f7ce..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/unpack.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* - * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana - * University Research and Technology - * Corporation. All rights reserved. - * Copyright (c) 2004-2006 The University of Tennessee and The University - * of Tennessee Research Foundation. All rights - * reserved. - * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, - * University of Stuttgart. All rights reserved. - * Copyright (c) 2004-2005 The Regents of the University of California. - * All rights reserved. - * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. - * Copyright (c) 2015 Research Organization for Information Science - * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Mellanox Technologies, Inc. - * All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#include - -#include - -#include "src/util/argv.h" -#include "src/util/error.h" -#include "src/util/output.h" -#include "src/buffer_ops/types.h" -#include "src/buffer_ops/internal.h" - -pmix_status_t pmix_bfrop_unpack(pmix_buffer_t *buffer, - void *dst, int32_t *num_vals, - pmix_data_type_t type) - { - pmix_status_t rc, ret; - int32_t local_num, n=1; - pmix_data_type_t local_type; - - /* check for error */ - if (NULL == buffer || NULL == dst || NULL == num_vals) { - return PMIX_ERR_BAD_PARAM; - } - - /* if user provides a zero for num_vals, then there is no storage allocated - * so return an appropriate error - */ - if (0 == *num_vals) { - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack: inadequate space ( %p, %p, %lu, %d )\n", - (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); - return PMIX_ERR_UNPACK_INADEQUATE_SPACE; - } - - /** Unpack the declared number of values - * REMINDER: it is possible that the buffer is corrupted and that - * the BFROP will *think* there is a proper int32_t variable at the - * beginning of the unpack region - but that the value is bogus (e.g., just - * a byte field in a string array that so happens to have a value that - * matches the int32_t data type flag). Therefore, this error check is - * NOT completely safe. This is true for ALL unpack functions, not just - * int32_t as used here. - */ - if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { - if (PMIX_SUCCESS != (rc = pmix_bfrop_get_data_type(buffer, &local_type))) { - *num_vals = 0; - /* don't error log here as the user may be unpacking past - * the end of the buffer, which isn't necessarily an error */ - return rc; - } - if (PMIX_INT32 != local_type) { /* if the length wasn't first, then error */ - *num_vals = 0; - return PMIX_ERR_UNPACK_FAILURE; - } - } - - n=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop_unpack_int32(buffer, &local_num, &n, PMIX_INT32))) { - *num_vals = 0; - /* don't error log here as the user may be unpacking past - * the end of the buffer, which isn't necessarily an error */ - return rc; - } - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack: found %d values for %d provided storage", - local_num, *num_vals); - - /** if the storage provided is inadequate, set things up - * to unpack as much as we can and to return an error code - * indicating that everything was not unpacked - the buffer - * is left in a state where it can not be further unpacked. - */ - if (local_num > *num_vals) { - local_num = *num_vals; - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack: inadequate space ( %p, %p, %lu, %d )\n", - (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); - ret = PMIX_ERR_UNPACK_INADEQUATE_SPACE; - } else { /** enough or more than enough storage */ - *num_vals = local_num; /** let the user know how many we actually unpacked */ - ret = PMIX_SUCCESS; - } - - /** Unpack the value(s) */ - if (PMIX_SUCCESS != (rc = pmix_bfrop_unpack_buffer(buffer, dst, &local_num, type))) { - *num_vals = 0; - ret = rc; - } - - return ret; -} - -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); -} - - -/* UNPACK GENERIC SYSTEM TYPES */ - -/* - * BOOL - */ -pmix_status_t pmix_bfrop_unpack_bool(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) - { - int32_t i; - uint8_t *src; - bool *dst; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_bool * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, *num_vals)) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - src = (uint8_t*)buffer->unpack_ptr; - dst = (bool*)dest; - - for (i=0; i < *num_vals; i++) { - if (src[i]) { - dst[i] = true; - } else { - dst[i] = false; - } - } - - /* update buffer pointer */ - buffer->unpack_ptr += *num_vals; - - return PMIX_SUCCESS; -} - -/* - * INT - */ -pmix_status_t pmix_bfrop_unpack_int(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) - { - pmix_status_t ret; - pmix_data_type_t remote_type; - - if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &remote_type))) { - return ret; - } - - if (remote_type == BFROP_TYPE_INT) { - /* fast path it if the sizes are the same */ - /* Turn around and unpack the real type */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, dest, num_vals, BFROP_TYPE_INT))) { - } - } else { - /* slow path - types are different sizes */ - UNPACK_SIZE_MISMATCH(int, remote_type, ret); - } - - return ret; -} - -/* - * SIZE_T - */ -pmix_status_t pmix_bfrop_unpack_sizet(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) - { - pmix_status_t ret; - pmix_data_type_t remote_type; - - if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &remote_type))) { - return ret; - } - - if (remote_type == BFROP_TYPE_SIZE_T) { - /* fast path it if the sizes are the same */ - /* Turn around and unpack the real type */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, dest, num_vals, BFROP_TYPE_SIZE_T))) { - } - } else { - /* slow path - types are different sizes */ - UNPACK_SIZE_MISMATCH(size_t, remote_type, ret); - } - - return ret; -} - -/* - * PID_T - */ -pmix_status_t pmix_bfrop_unpack_pid(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) - { - pmix_status_t ret; - pmix_data_type_t remote_type; - - if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &remote_type))) { - return ret; - } - - if (remote_type == BFROP_TYPE_PID_T) { - /* fast path it if the sizes are the same */ - /* Turn around and unpack the real type */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, dest, num_vals, BFROP_TYPE_PID_T))) { - } - } else { - /* slow path - types are different sizes */ - UNPACK_SIZE_MISMATCH(pid_t, remote_type, ret); - } - - return ret; -} - - -/* UNPACK FUNCTIONS FOR NON-GENERIC SYSTEM TYPES */ - -/* - * BYTE, CHAR, INT8 - */ -pmix_status_t pmix_bfrop_unpack_byte(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) - { - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_byte * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, *num_vals)) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - memcpy(dest, buffer->unpack_ptr, *num_vals); - - /* update buffer pointer */ - buffer->unpack_ptr += *num_vals; - - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_int16(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - int32_t i; - uint16_t tmp, *desttmp = (uint16_t*) dest; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_int16 * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - for (i = 0; i < (*num_vals); ++i) { - memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) ); - tmp = pmix_ntohs(tmp); - memcpy(&desttmp[i], &tmp, sizeof(tmp)); - buffer->unpack_ptr += sizeof(tmp); - } - - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_int32(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - int32_t i; - uint32_t tmp, *desttmp = (uint32_t*) dest; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_int32 * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - for (i = 0; i < (*num_vals); ++i) { - memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) ); - tmp = ntohl(tmp); - memcpy(&desttmp[i], &tmp, sizeof(tmp)); - buffer->unpack_ptr += sizeof(tmp); - } - - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_datatype(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_int16(buffer, dest, num_vals, type); -} - -pmix_status_t pmix_bfrop_unpack_int64(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - int32_t i; - uint64_t tmp, *desttmp = (uint64_t*) dest; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_int64 * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - for (i = 0; i < (*num_vals); ++i) { - memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) ); - tmp = pmix_ntoh64(tmp); - memcpy(&desttmp[i], &tmp, sizeof(tmp)); - buffer->unpack_ptr += sizeof(tmp); - } - - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_string(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_status_t ret; - int32_t i, len, n=1; - char **sdest = (char**) dest; - - for (i = 0; i < (*num_vals); ++i) { - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int32(buffer, &len, &n, PMIX_INT32))) { - return ret; - } - if (0 == len) { /* zero-length string - unpack the NULL */ - sdest[i] = NULL; - } else { - sdest[i] = (char*)malloc(len); - if (NULL == sdest[i]) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_byte(buffer, sdest[i], &len, PMIX_BYTE))) { - return ret; - } - } - } - - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_float(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - int32_t i, n; - float *desttmp = (float*) dest, tmp; - pmix_status_t ret; - char *convert; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_float * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(float))) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - for (i = 0; i < (*num_vals); ++i) { - n=1; - convert = NULL; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &convert, &n, PMIX_STRING))) { - return ret; - } - if (NULL != convert) { - tmp = strtof(convert, NULL); - memcpy(&desttmp[i], &tmp, sizeof(tmp)); - free(convert); - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_double(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - int32_t i, n; - double *desttmp = (double*) dest, tmp; - pmix_status_t ret; - char *convert; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_double * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(double))) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - for (i = 0; i < (*num_vals); ++i) { - n=1; - convert = NULL; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &convert, &n, PMIX_STRING))) { - return ret; - } - if (NULL != convert) { - tmp = strtod(convert, NULL); - memcpy(&desttmp[i], &tmp, sizeof(tmp)); - free(convert); - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_timeval(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - int32_t i, n; - int64_t tmp[2]; - struct timeval *desttmp = (struct timeval *) dest, tt; - pmix_status_t ret; - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_timeval * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(struct timeval))) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - for (i = 0; i < (*num_vals); ++i) { - n=2; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int64(buffer, tmp, &n, PMIX_INT64))) { - return ret; - } - tt.tv_sec = tmp[0]; - tt.tv_usec = tmp[1]; - memcpy(&desttmp[i], &tt, sizeof(tt)); - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_time(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - int32_t i, n; - time_t *desttmp = (time_t *) dest, tmp; - pmix_status_t ret; - uint64_t ui64; - - /* time_t is a system-dependent size, so cast it - * to uint64_t as a generic safe size - */ - - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_time * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, (*num_vals)*(sizeof(uint64_t)))) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - for (i = 0; i < (*num_vals); ++i) { - n=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int64(buffer, &ui64, &n, PMIX_UINT64))) { - return ret; - } - tmp = (time_t)ui64; - memcpy(&desttmp[i], &tmp, sizeof(tmp)); - } - return PMIX_SUCCESS; -} - - -pmix_status_t pmix_bfrop_unpack_status(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_status * %d\n", (int)*num_vals); - /* check to see if there's enough data in buffer */ - if (pmix_bfrop_too_small(buffer, (*num_vals)*(sizeof(pmix_status_t)))) { - return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; - } - - /* unpack the data */ - return pmix_bfrop_unpack_int32(buffer, dest, num_vals, PMIX_INT32); -} - - -/* UNPACK FUNCTIONS FOR GENERIC PMIX TYPES */ - -/* - * PMIX_VALUE - */ - static pmix_status_t unpack_val(pmix_buffer_t *buffer, pmix_value_t *val) - { - int32_t m; - pmix_status_t ret; - - m = 1; - switch (val->type) { - case PMIX_UNDEF: - break; - case PMIX_BOOL: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.flag, &m, PMIX_BOOL))) { - return ret; - } - break; - case PMIX_BYTE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.byte, &m, PMIX_BYTE))) { - return ret; - } - break; - case PMIX_STRING: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.string, &m, PMIX_STRING))) { - return ret; - } - break; - case PMIX_SIZE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.size, &m, PMIX_SIZE))) { - return ret; - } - break; - case PMIX_PID: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.pid, &m, PMIX_PID))) { - return ret; - } - break; - case PMIX_INT: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.integer, &m, PMIX_INT))) { - return ret; - } - break; - case PMIX_INT8: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int8, &m, PMIX_INT8))) { - return ret; - } - break; - case PMIX_INT16: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int16, &m, PMIX_INT16))) { - return ret; - } - break; - case PMIX_INT32: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int32, &m, PMIX_INT32))) { - return ret; - } - break; - case PMIX_INT64: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.int64, &m, PMIX_INT64))) { - return ret; - } - break; - case PMIX_UINT: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint, &m, PMIX_UINT))) { - return ret; - } - break; - case PMIX_UINT8: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint8, &m, PMIX_UINT8))) { - return ret; - } - break; - case PMIX_UINT16: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint16, &m, PMIX_UINT16))) { - return ret; - } - break; - case PMIX_UINT32: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint32, &m, PMIX_UINT32))) { - return ret; - } - break; - case PMIX_UINT64: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.uint64, &m, PMIX_UINT64))) { - return ret; - } - break; - case PMIX_FLOAT: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.fval, &m, PMIX_FLOAT))) { - return ret; - } - break; - case PMIX_DOUBLE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.dval, &m, PMIX_DOUBLE))) { - return ret; - } - break; - case PMIX_TIMEVAL: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.tv, &m, PMIX_TIMEVAL))) { - return ret; - } - break; - case PMIX_TIME: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.time, &m, PMIX_TIME))) { - return ret; - } - break; - case PMIX_STATUS: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.status, &m, PMIX_STATUS))) { - return ret; - } - 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; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.proc, &m, PMIX_PROC))) { - return ret; - } - break; - case PMIX_PROC_RANK: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.rank, &m, PMIX_PROC_RANK))) { - return ret; - } - break; - case PMIX_BYTE_OBJECT: - case PMIX_COMPRESSED_STRING: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.bo, &m, PMIX_BYTE_OBJECT))) { - return ret; - } - break; - case PMIX_PERSIST: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.proc, &m, PMIX_PROC))) { - return ret; - } - break; - case PMIX_POINTER: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.ptr, &m, PMIX_POINTER))) { - return ret; - } - break; - case PMIX_SCOPE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.scope, &m, PMIX_SCOPE))) { - return ret; - } - break; - case PMIX_DATA_RANGE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.range, &m, PMIX_DATA_RANGE))) { - return ret; - } - break; - case PMIX_PROC_STATE: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.state, &m, PMIX_PROC_STATE))) { - return ret; - } - 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; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.pinfo, &m, PMIX_PROC_INFO))) { - return ret; - } - 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; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.darray, &m, PMIX_DATA_ARRAY))) { - return ret; - } - break; - case PMIX_QUERY: - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.darray, &m, PMIX_QUERY))) { - return ret; - } - break; - /**** DEPRECATED ****/ - case PMIX_INFO_ARRAY: - /* this field is now a pointer, so we must allocate storage for it */ - val->data.array = (pmix_info_array_t*)malloc(sizeof(pmix_info_array_t)); - if (NULL == val->data.array) { - return PMIX_ERR_NOMEM; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, val->data.array, &m, PMIX_INFO_ARRAY))) { - return ret; - } - break; - /********************/ - default: - pmix_output(0, "UNPACK-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)val->type); - return PMIX_ERROR; - } - - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_value(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_value_t *ptr; - int32_t i, n; - pmix_status_t ret; - - ptr = (pmix_value_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - /* unpack the type */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &ptr[i].type))) { - return ret; - } - /* unpack value */ - if (PMIX_SUCCESS != (ret = unpack_val(buffer, &ptr[i])) ) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_info(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_info_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - char *tmp; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d info", *num_vals); - - ptr = (pmix_info_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - memset(ptr[i].key, 0, sizeof(ptr[i].key)); - memset(&ptr[i].value, 0, sizeof(pmix_value_t)); - /* unpack key */ - m=1; - tmp = NULL; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { - PMIX_ERROR_LOG(ret); - return ret; - } - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - (void)strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN); - free(tmp); - /* unpack the flags */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_infodirs(buffer, &ptr[i].flags, &m, PMIX_INFO_DIRECTIVES))) { - PMIX_ERROR_LOG(ret); - return ret; - } - /* unpack value - since the value structure is statically-defined - * instead of a pointer in this struct, we directly unpack it to - * avoid the malloc */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int(buffer, &ptr[i].value.type, &m, PMIX_INT))) { - PMIX_ERROR_LOG(ret); - return ret; - } - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: info type %d", ptr[i].value.type); - m=1; - if (PMIX_SUCCESS != (ret = unpack_val(buffer, &ptr[i].value))) { - PMIX_ERROR_LOG(ret); - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_pdata(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_pdata_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - char *tmp; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d pdata", *num_vals); - - ptr = (pmix_pdata_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - PMIX_PDATA_CONSTRUCT(&ptr[i]); - /* unpack the proc */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_proc(buffer, &ptr[i].proc, &m, PMIX_PROC))) { - return ret; - } - /* unpack key */ - m=1; - tmp = NULL; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { - return ret; - } - if (NULL == tmp) { - return PMIX_ERROR; - } - (void)strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN); - free(tmp); - /* unpack value - since the value structure is statically-defined - * instead of a pointer in this struct, we directly unpack it to - * avoid the malloc */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int(buffer, &ptr[i].value.type, &m, PMIX_INT))) { - return ret; - } - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: pdata type %d", ptr[i].value.type); - m=1; - if (PMIX_SUCCESS != (ret = unpack_val(buffer, &ptr[i].value))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_buf(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_buffer_t **ptr; - int32_t i, n, m; - pmix_status_t ret; - size_t nbytes; - - ptr = (pmix_buffer_t **) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - /* allocate the new object */ - ptr[i] = PMIX_NEW(pmix_buffer_t); - if (NULL == ptr[i]) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - /* unpack the number of bytes */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &nbytes, &m, PMIX_SIZE))) { - return ret; - } - m = nbytes; - /* setup the buffer's data region */ - if (0 < nbytes) { - ptr[i]->base_ptr = (char*)malloc(nbytes); - /* unpack the bytes */ - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_byte(buffer, ptr[i]->base_ptr, &m, PMIX_BYTE))) { - return ret; - } - } - ptr[i]->pack_ptr = ptr[i]->base_ptr + m; - ptr[i]->unpack_ptr = ptr[i]->base_ptr; - ptr[i]->bytes_allocated = nbytes; - ptr[i]->bytes_used = m; - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_proc(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_proc_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - char *tmp; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d procs", *num_vals); - - ptr = (pmix_proc_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: init proc[%d]", i); - memset(&ptr[i], 0, sizeof(pmix_proc_t)); - /* unpack nspace */ - m=1; - tmp = NULL; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { - return ret; - } - if (NULL == tmp) { - return PMIX_ERROR; - } - (void)strncpy(ptr[i].nspace, tmp, PMIX_MAX_NSLEN); - free(tmp); - /* unpack the rank */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_rank(buffer, &ptr[i].rank, &m, PMIX_PROC_RANK))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_app(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_app_t *ptr; - int32_t i, k, n, m; - pmix_status_t ret; - int32_t nval; - char *tmp; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d apps", *num_vals); - - ptr = (pmix_app_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - /* initialize the fields */ - PMIX_APP_CONSTRUCT(&ptr[i]); - /* unpack cmd */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &ptr[i].cmd, &m, PMIX_STRING))) { - return ret; - } - /* unpack argc */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int(buffer, &nval, &m, PMIX_INT32))) { - return ret; - } - /* unpack argv */ - for (k=0; k < nval; k++) { - m=1; - tmp = NULL; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { - return ret; - } - if (NULL == tmp) { - return PMIX_ERROR; - } - pmix_argv_append_nosize(&ptr[i].argv, tmp); - free(tmp); - } - /* unpack env */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int32(buffer, &nval, &m, PMIX_INT32))) { - return ret; - } - for (k=0; k < nval; k++) { - m=1; - tmp = NULL; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { - return ret; - } - if (NULL == tmp) { - return PMIX_ERROR; - } - pmix_argv_append_nosize(&ptr[i].env, tmp); - free(tmp); - } - /* unpack cwd */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &ptr[i].cwd, &m, PMIX_STRING))) { - return ret; - } - /* unpack maxprocs */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int(buffer, &ptr[i].maxprocs, &m, PMIX_INT))) { - return ret; - } - /* unpack info array */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &ptr[i].ninfo, &m, PMIX_SIZE))) { - return ret; - } - if (0 < ptr[i].ninfo) { - PMIX_INFO_CREATE(ptr[i].info, ptr[i].ninfo); - m = ptr[i].ninfo; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_info(buffer, ptr[i].info, &m, PMIX_INFO))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_kval(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_kval_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d kvals", *num_vals); - - ptr = (pmix_kval_t*) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - PMIX_CONSTRUCT(&ptr[i], pmix_kval_t); - /* unpack the key */ - m = 1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &ptr[i].key, &m, PMIX_STRING))) { - PMIX_ERROR_LOG(ret); - return ret; - } - /* allocate the space */ - ptr[i].value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); - /* unpack the value */ - m = 1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_value(buffer, ptr[i].value, &m, PMIX_VALUE))) { - PMIX_ERROR_LOG(ret); - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_modex(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_modex_data_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d modex", *num_vals); - - ptr = (pmix_modex_data_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - memset(&ptr[i], 0, sizeof(pmix_modex_data_t)); - /* unpack the number of bytes */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { - return ret; - } - if (0 < ptr[i].size) { - ptr[i].blob = (uint8_t*)malloc(ptr[i].size * sizeof(uint8_t)); - m=ptr[i].size; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_byte(buffer, ptr[i].blob, &m, PMIX_UINT8))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_persist(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_unpack_scope(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_unpack_range(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_unpack_cmd(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_unpack_infodirs(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_int32(buffer, dest, num_vals, PMIX_UINT32); -} - -pmix_status_t pmix_bfrop_unpack_bo(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_byte_object_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d byte_object", *num_vals); - - ptr = (pmix_byte_object_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - memset(&ptr[i], 0, sizeof(pmix_byte_object_t)); - /* unpack the number of bytes */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { - return ret; - } - if (0 < ptr[i].size) { - ptr[i].bytes = (char*)malloc(ptr[i].size * sizeof(char)); - m=ptr[i].size; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_byte(buffer, ptr[i].bytes, &m, PMIX_BYTE))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_ptr(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - uint8_t foo=1; - int32_t cnt=1; - - /* it obviously makes no sense to pack a pointer and - * send it somewhere else, so we just unpack the sentinel */ - return pmix_bfrop_unpack_byte(buffer, &foo, &cnt, PMIX_UINT8); -} - -pmix_status_t pmix_bfrop_unpack_pstate(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); -} - - -pmix_status_t pmix_bfrop_unpack_pinfo(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_proc_info_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d pinfo", *num_vals); - - ptr = (pmix_proc_info_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - PMIX_PROC_INFO_CONSTRUCT(&ptr[i]); - /* unpack the proc */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_proc(buffer, &ptr[i].proc, &m, PMIX_PROC))) { - return ret; - } - /* unpack the hostname */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &ptr[i].hostname, &m, PMIX_STRING))) { - return ret; - } - /* unpack the executable */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &ptr[i].executable_name, &m, PMIX_STRING))) { - return ret; - } - /* unpack pid */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_pid(buffer, &ptr[i].pid, &m, PMIX_PID))) { - return ret; - } - /* unpack state */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_pstate(buffer, &ptr[i].state, &m, PMIX_PROC_STATE))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_darray(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_data_array_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - size_t nbytes; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d data arrays", *num_vals); - - ptr = (pmix_data_array_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - memset(&ptr[i], 0, sizeof(pmix_data_array_t)); - /* unpack the type */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_datatype(buffer, &ptr[i].type, &m, PMIX_DATA_TYPE))) { - return ret; - } - /* unpack the number of array elements */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { - return ret; - } - if (0 == ptr[i].size || PMIX_UNDEF == ptr[i].type) { - /* nothing else to do */ - continue; - } - /* allocate storage for the array and unpack the array elements */ - m = ptr[i].size; - switch(ptr[i].type) { - case PMIX_BOOL: - nbytes = sizeof(bool); - break; - case PMIX_BYTE: - case PMIX_INT8: - case PMIX_UINT8: - nbytes = sizeof(int8_t); - break; - case PMIX_INT16: - case PMIX_UINT16: - nbytes = sizeof(int16_t); - break; - case PMIX_INT32: - case PMIX_UINT32: - nbytes = sizeof(int32_t); - break; - case PMIX_INT64: - case PMIX_UINT64: - nbytes = sizeof(int64_t); - break; - case PMIX_STRING: - nbytes = sizeof(char*); - break; - case PMIX_SIZE: - nbytes = sizeof(size_t); - break; - case PMIX_PID: - nbytes = sizeof(pid_t); - break; - case PMIX_INT: - case PMIX_UINT: - nbytes = sizeof(int); - break; - case PMIX_FLOAT: - nbytes = sizeof(float); - break; - case PMIX_DOUBLE: - nbytes = sizeof(double); - break; - case PMIX_TIMEVAL: - nbytes = sizeof(struct timeval); - break; - case PMIX_TIME: - nbytes = sizeof(time_t); - break; - case PMIX_STATUS: - nbytes = sizeof(pmix_status_t); - break; - case PMIX_INFO: - nbytes = sizeof(pmix_info_t); - break; - case PMIX_PROC: - nbytes = sizeof(pmix_proc_t); - break; - case PMIX_BYTE_OBJECT: - case PMIX_COMPRESSED_STRING: - nbytes = sizeof(pmix_byte_object_t); - break; - case PMIX_PERSIST: - nbytes = sizeof(pmix_persistence_t); - break; - case PMIX_SCOPE: - nbytes = sizeof(pmix_scope_t); - break; - case PMIX_DATA_RANGE: - nbytes = sizeof(pmix_data_range_t); - break; - case PMIX_PROC_STATE: - nbytes = sizeof(pmix_proc_state_t); - break; - case PMIX_PROC_INFO: - nbytes = sizeof(pmix_proc_info_t); - break; - case PMIX_QUERY: - nbytes = sizeof(pmix_query_t); - default: - return PMIX_ERR_NOT_SUPPORTED; - } - if (NULL == (ptr[i].array = malloc(m * nbytes))) { - return PMIX_ERR_NOMEM; - } - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, ptr[i].array, &m, ptr[i].type))) { - return ret; - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_rank(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_int32(buffer, dest, num_vals, PMIX_UINT32); -} - -pmix_status_t pmix_bfrop_unpack_query(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_query_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - int32_t nkeys; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d queries", *num_vals); - - ptr = (pmix_query_t *) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - PMIX_QUERY_CONSTRUCT(&ptr[i]); - /* unpack the number of keys */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int32(buffer, &nkeys, &m, PMIX_INT32))) { - return ret; - } - if (0 < nkeys) { - /* unpack the keys */ - if (NULL == (ptr[i].keys = (char**)calloc(nkeys+1, sizeof(char*)))) { - return PMIX_ERR_NOMEM; - } - /* unpack keys */ - m=nkeys; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, ptr[i].keys, &m, PMIX_STRING))) { - return ret; - } - } - /* unpack the number of qualifiers */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &ptr[i].nqual, &m, PMIX_SIZE))) { - return ret; - } - if (0 < ptr[i].nqual) { - /* unpack the qualifiers */ - PMIX_INFO_CREATE(ptr[i].qualifiers, ptr[i].nqual); - m = ptr[i].nqual; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_info(buffer, ptr[i].qualifiers, &m, PMIX_INFO))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_unpack_alloc_directive(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - return pmix_bfrop_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); -} - - -/**** DEPRECATED ****/ -pmix_status_t pmix_bfrop_unpack_array(pmix_buffer_t *buffer, void *dest, - int32_t *num_vals, pmix_data_type_t type) -{ - pmix_info_array_t *ptr; - int32_t i, n, m; - pmix_status_t ret; - - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: %d info arrays", *num_vals); - - ptr = (pmix_info_array_t*) dest; - n = *num_vals; - - for (i = 0; i < n; ++i) { - pmix_output_verbose(20, pmix_globals.debug_output, - "pmix_bfrop_unpack: init array[%d]", i); - memset(&ptr[i], 0, sizeof(pmix_info_array_t)); - /* unpack the size of this array */ - m=1; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { - return ret; - } - if (0 < ptr[i].size) { - ptr[i].array = (pmix_info_t*)malloc(ptr[i].size * sizeof(pmix_info_t)); - m=ptr[i].size; - if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_value(buffer, ptr[i].array, &m, PMIX_INFO))) { - return ret; - } - } - } - return PMIX_SUCCESS; -} -/********************/ diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/class/Makefile.include index 904995173d..80eb146f91 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/class/Makefile.include @@ -10,7 +10,7 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hash_table.c b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hash_table.c index ead33aecfa..7dc218e22f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hash_table.c +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hash_table.c @@ -11,7 +11,7 @@ * All rights reserved. * Copyright (c) 2014-2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2014-2015 Intel, Inc. All rights reserved + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hash_table.h b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hash_table.h index c27d9878c0..bef483e7a2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hash_table.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hash_table.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015-2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.c b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.c index 933c5bcd5a..ea0eb96c2b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.c +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.c @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Voltaire All rights reserved. - * Copyright (c) 2013-2015 Intel, Inc. All rights reserved + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.h b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.h index 4d8a195bb3..bd5a89e1e4 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.h @@ -13,7 +13,7 @@ * Copyright (c) 2007 Voltaire All rights reserved. * Copyright (c) 2013 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2013-2015 Intel, Inc. All rights reserved + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.c b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.c index ba911e578f..6dffa57139 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.c +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -224,4 +224,3 @@ static void expand_array(void) classes[i] = NULL; } } - diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_ring_buffer.c b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_ring_buffer.c index e578a4e22b..ce54f62d29 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_ring_buffer.c +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_ring_buffer.c @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_ring_buffer.h b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_ring_buffer.h index 8e8d236bd6..47e51088af 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_ring_buffer.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_ring_buffer.h @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.c b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.c index f46e494c38..31c19c15c4 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.c +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -64,4 +64,3 @@ int pmix_value_array_set_size(pmix_value_array_t* array, size_t size) array->array_size = size; return PMIX_SUCCESS; } - diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.h b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.h index 1b10a5e79a..35910e8d25 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmi1.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmi1.c index 9a4e1acd0a..b56df7d25e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmi1.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmi1.c @@ -1,6 +1,6 @@ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2014 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. @@ -34,7 +34,7 @@ #define ANL_MAPPING "PMI_process_mapping" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmi2.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmi2.c index 97d1939c0f..300af1d937 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmi2.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmi2.c @@ -1,6 +1,6 @@ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. @@ -30,7 +30,7 @@ #include #include -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c index 3bf71848cd..2e67e40819 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c @@ -5,7 +5,7 @@ * and Technology (RIST). All rights reserved. * Copyright (c) 2014 Artem Y. Polyakov . * All rights reserved. - * Copyright (c) 2016 Mellanox Technologies, Inc. + * Copyright (c) 2016-2017 Mellanox Technologies, Inc. * All rights reserved. * Copyright (c) 2016-2017 IBM Corporation. All rights reserved. * $COPYRIGHT$ @@ -61,7 +61,6 @@ static const char pmix_version_string[] = PMIX_VERSION; #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" #include "src/event/pmix_event.h" #include "src/util/argv.h" #include "src/util/compress.h" @@ -71,17 +70,13 @@ static const char pmix_version_string[] = PMIX_VERSION; #include "src/runtime/pmix_progress_threads.h" #include "src/runtime/pmix_rte.h" #include "src/threads/threads.h" -#include "src/mca/ptl/ptl.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/gds/base/base.h" +#include "src/mca/preg/preg.h" +#include "src/mca/ptl/base/base.h" #include "src/include/pmix_globals.h" -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -#include "src/dstore/pmix_dstore.h" -#endif /* PMIX_ENABLE_DSTORE */ -#ifdef HAVE_ZLIB_H -#include -#endif #include "pmix_client_ops.h" -#include "src/include/pmix_jobdata.h" #define PMIX_MAX_RETRIES 10 @@ -107,43 +102,67 @@ static void pmix_client_notify_recv(struct pmix_peer_t *peer, /* start the local notification chain */ chain = PMIX_NEW(pmix_event_chain_t); + if (NULL == chain) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return; + } chain->final_cbfunc = _notify_complete; chain->final_cbdata = chain; cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cmd, &cnt, PMIX_CMD))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &cmd, &cnt, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); + PMIX_RELEASE(chain); goto error; } /* unpack the status */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &chain->status, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &chain->status, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); + PMIX_RELEASE(chain); goto error; } /* unpack the source of the event */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &chain->source, &cnt, PMIX_PROC))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &chain->source, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); + PMIX_RELEASE(chain); goto error; } /* unpack the info that might have been provided */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); + PMIX_RELEASE(chain); goto error; } /* we always leave space for a callback object */ chain->ninfo = ninfo + 1; PMIX_INFO_CREATE(chain->info, chain->ninfo); + if (NULL == chain->info) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + PMIX_RELEASE(chain); + return; + } if (0 < ninfo) { cnt = ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, chain->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, chain->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); + PMIX_RELEASE(chain); goto error; } } @@ -162,6 +181,10 @@ static void pmix_client_notify_recv(struct pmix_peer_t *peer, pmix_output_verbose(2, pmix_globals.debug_output, "pmix:client_notify_recv - unpack error status =%d, calling def errhandler", rc); chain = PMIX_NEW(pmix_event_chain_t); + if (NULL == chain) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return; + } chain->status = rc; pmix_invoke_local_event_hdlr(chain); } @@ -191,22 +214,21 @@ static void job_data(struct pmix_peer_t *pr, int32_t cnt = 1; pmix_cb_t *cb = (pmix_cb_t*)cbdata; - /* unpack the nspace - we don't really need it, but have to - * unpack it to maintain sequence */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &nspace, &cnt, PMIX_STRING))) { + /* unpack the nspace - should be same as our own */ + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &nspace, &cnt, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); cb->status = PMIX_ERROR; PMIX_POST_OBJECT(cb); PMIX_WAKEUP_THREAD(&cb->lock); return; } - assert(NULL != nspace); - free(nspace); /* decode it */ -#if !(defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1)) - pmix_job_data_htable_store(pmix_globals.myid.nspace, buf); -#endif + PMIX_GDS_STORE_JOB_INFO(cb->status, + pmix_client_globals.myserver, + nspace, buf); cb->status = PMIX_SUCCESS; PMIX_POST_OBJECT(cb); PMIX_WAKEUP_THREAD(&cb->lock); @@ -321,10 +343,8 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, pmix_info_t ginfo; pmix_value_t *val = NULL; pmix_lock_t reglock; - - if (NULL == proc) { - return PMIX_ERR_BAD_PARAM; - } + size_t n; + bool found; PMIX_ACQUIRE_THREAD(&pmix_global_lock); @@ -368,6 +388,21 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_NOMEM; } + pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_nspace_t); + if (NULL == pmix_client_globals.myserver->nptr) { + PMIX_RELEASE(pmix_client_globals.myserver); + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_NOMEM; + } + pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); + if (NULL == pmix_client_globals.myserver->info) { + PMIX_RELEASE(pmix_client_globals.myserver); + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_NOMEM; + } + /* construct the global notification ring buffer */ + PMIX_CONSTRUCT(&pmix_globals.notifications, pmix_ring_buffer_t); + pmix_ring_buffer_init(&pmix_globals.notifications, 256); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: init called"); @@ -382,9 +417,14 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, (void)strncpy(proc->nspace, evar, PMIX_MAX_NSLEN); } (void)strncpy(pmix_globals.myid.nspace, evar, PMIX_MAX_NSLEN); + /* create a pmix_nspace_t object for our peer */ nsptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(nsptr->nspace, evar, PMIX_MAX_NSLEN); - pmix_list_append(&pmix_globals.nspaces, &nsptr->super); + if (NULL == nsptr){ + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_NOMEM; + } + nsptr->nspace = strdup(evar); + pmix_globals.mypeer->nptr = nsptr; /* we also require our rank */ if (NULL == (evar = getenv("PMIX_RANK"))) { @@ -397,39 +437,108 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, proc->rank = pmix_globals.myid.rank; } pmix_globals.pindex = -1; + /* setup a rank_info object for us */ + pmix_globals.mypeer->info = PMIX_NEW(pmix_rank_info_t); + if (NULL == pmix_globals.mypeer->info) { + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_NOMEM; + } + pmix_globals.mypeer->info->pname.nspace = strdup(proc->nspace); + pmix_globals.mypeer->info->pname.rank = proc->rank; + + /* select our bfrops compat module - the selection will be based + * on the corresponding envars that should have been passed + * to us at launch */ + evar = getenv("PMIX_BFROPS_MODE"); + pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module(evar); + if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) { + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_INIT; + } + /* the server will be using the same */ + pmix_client_globals.myserver->nptr->compat.bfrops = pmix_globals.mypeer->nptr->compat.bfrops; + + /* set the buffer type - the selection will be based + * on the corresponding envars that should have been passed + * to us at launch */ + evar = getenv("PMIX_BFROP_BUFFER_TYPE"); + if (NULL == evar) { + /* just set to our default */ + pmix_globals.mypeer->nptr->compat.type = pmix_bfrops_globals.default_type; + } else if (0 == strcmp(evar, "PMIX_BFROP_BUFFER_FULLY_DESC")) { + pmix_globals.mypeer->nptr->compat.type = PMIX_BFROP_BUFFER_FULLY_DESC; + } else { + pmix_globals.mypeer->nptr->compat.type = PMIX_BFROP_BUFFER_NON_DESC; + } + /* the server will be using the same */ + pmix_client_globals.myserver->nptr->compat.type = pmix_globals.mypeer->nptr->compat.type; + /* select our psec compat module - the selection will be based * on the corresponding envars that should have been passed * to us at launch */ evar = getenv("PMIX_SECURITY_MODE"); - if (PMIX_SUCCESS != (rc = pmix_psec.assign_module(pmix_globals.mypeer, evar))) { + pmix_globals.mypeer->nptr->compat.psec = pmix_psec_base_assign_module(evar); + if (NULL == pmix_globals.mypeer->nptr->compat.psec) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_INIT; } /* the server will be using the same */ - pmix_client_globals.myserver->compat.psec = pmix_globals.mypeer->compat.psec; + pmix_client_globals.myserver->nptr->compat.psec = pmix_globals.mypeer->nptr->compat.psec; - /* setup the shared memory support */ -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (PMIX_SUCCESS != (rc = pmix_dstore_init(NULL, 0))) { + /* select the gds compat module we will use to interact with + * our server- the selection will be based + * on the corresponding envars that should have been passed + * to us at launch */ + evar = getenv("PMIX_GDS_MODULE"); + PMIX_INFO_LOAD(&ginfo, PMIX_GDS_MODULE, evar, PMIX_STRING); + pmix_client_globals.myserver->nptr->compat.gds = pmix_gds_base_assign_module(&ginfo, 1); + if (NULL == pmix_client_globals.myserver->nptr->compat.gds) { + PMIX_INFO_DESTRUCT(&ginfo); PMIX_RELEASE_THREAD(&pmix_global_lock); - return PMIX_ERR_DATA_VALUE_NOT_FOUND; + return PMIX_ERR_INIT; } -#endif /* PMIX_ENABLE_DSTORE */ + PMIX_INFO_DESTRUCT(&ginfo); + /* now select a GDS module for our own internal use - the user may + * have passed down a directive for this purpose. If they did, then + * use it. Otherwise, we want the "hash" module */ + found = false; + if (info != NULL) { + for (n=0; n < ninfo; n++) { + if (0 == strncmp(info[n].key, PMIX_GDS_MODULE, PMIX_MAX_KEYLEN)) { + PMIX_INFO_LOAD(&ginfo, PMIX_GDS_MODULE, info[n].value.data.string, PMIX_STRING); + found = true; + break; + } + } + } + if (!found) { + PMIX_INFO_LOAD(&ginfo, PMIX_GDS_MODULE, "hash", PMIX_STRING); + } + pmix_globals.mypeer->nptr->compat.gds = pmix_gds_base_assign_module(&ginfo, 1); + if (NULL == pmix_globals.mypeer->nptr->compat.gds) { + PMIX_INFO_DESTRUCT(&ginfo); + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_INIT; + } + PMIX_INFO_DESTRUCT(&ginfo); /* connect to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.connect_to_peer(pmix_client_globals.myserver, info, ninfo))){ + rc = pmix_ptl_base_connect_to_peer((struct pmix_peer_t*)pmix_client_globals.myserver, info, ninfo); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; } /* mark that we are using the same module as used for the server */ - pmix_globals.mypeer->compat.ptl = pmix_client_globals.myserver->compat.ptl; + pmix_globals.mypeer->nptr->compat.ptl = pmix_client_globals.myserver->nptr->compat.ptl; /* send a request for our job info - we do this as a non-blocking * transaction because some systems cannot handle very large * blocking operations and error out if we try them. */ req = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(req, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + req, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(req); PMIX_RELEASE_THREAD(&pmix_global_lock); @@ -437,8 +546,9 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, } /* send to the server */ PMIX_CONSTRUCT(&cb, pmix_cb_t); - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, req, job_data, (void*)&cb))){ - PMIX_DESTRUCT(&cb); + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + req, job_data, (void*)&cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; } @@ -577,9 +687,12 @@ PMIX_EXPORT pmix_status_t PMIx_Finalize(const pmix_info_t info[], size_t ninfo) * server that we are normally terminating */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); + PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; } @@ -597,8 +710,10 @@ PMIX_EXPORT pmix_status_t PMIx_Finalize(const pmix_info_t info[], size_t ninfo) PMIX_POST_OBJECT(&tev); pmix_event_add(&tev.ev, &tv); /* send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, - finwait_cbfunc, (void*)&tev))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, finwait_cbfunc, (void*)&tev); + if (PMIX_SUCCESS != rc) { + PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; } @@ -622,13 +737,6 @@ PMIX_EXPORT pmix_status_t PMIx_Finalize(const pmix_info_t info[], size_t ninfo) (void)pmix_progress_thread_pause(NULL); } -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (0 > (rc = pmix_dstore_nspace_del(pmix_globals.myid.nspace))) { - PMIX_ERROR_LOG(rc); - return rc; - } -#endif - PMIX_LIST_DESTRUCT(&pmix_client_globals.pending_requests); if (0 <= pmix_client_globals.myserver->sd) { @@ -672,32 +780,42 @@ PMIX_EXPORT pmix_status_t PMIx_Abort(int flag, const char msg[], /* create a buffer to hold the message */ bfr = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(bfr, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + bfr, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(bfr); return rc; } /* pack the status flag */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(bfr, &flag, 1, PMIX_STATUS))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + bfr, &flag, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(bfr); return rc; } /* pack the string message - a NULL is okay */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(bfr, &msg, 1, PMIX_STRING))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + bfr, &msg, 1, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(bfr); return rc; } /* pack the number of procs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(bfr, &nprocs, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + bfr, &nprocs, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(bfr); return rc; } /* pack any provided procs */ if (0 < nprocs) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(bfr, procs, 1, PMIX_PROC))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + bfr, procs, nprocs, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(bfr); return rc; @@ -706,8 +824,10 @@ PMIX_EXPORT pmix_status_t PMIx_Abort(int flag, const char msg[], /* send to the server */ PMIX_CONSTRUCT_LOCK(®lock); - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, bfr, - wait_cbfunc, (void*)®lock))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, bfr, + wait_cbfunc, (void*)®lock); + if (PMIX_SUCCESS != rc) { + PMIX_DESTRUCT_LOCK(®lock); return rc; } @@ -722,7 +842,6 @@ static void _putfn(int sd, short args, void *cbdata) pmix_cb_t *cb = (pmix_cb_t*)cbdata; pmix_status_t rc; pmix_kval_t *kv = NULL; - pmix_nspace_t *ns; uint8_t *tmp; size_t len; @@ -754,52 +873,29 @@ static void _putfn(int sd, short args, void *cbdata) kv->value->data.bo.size = len; rc = PMIX_SUCCESS; } else { - rc = pmix_value_xfer(kv->value, cb->value); + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, + kv->value, cb->value); } } else { - rc = pmix_value_xfer(kv->value, cb->value); + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, + kv->value, cb->value); } if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto done; } - /* put it in our own modex hash table in case something - * internal to us wants it - our nsrecord is always - * first on the list */ - if (NULL == (ns = (pmix_nspace_t*)pmix_list_get_first(&pmix_globals.nspaces))) { - /* shouldn't be possible */ - goto done; - } - if (PMIX_SUCCESS != (rc = pmix_hash_store(&ns->modex, pmix_globals.myid.rank, kv))) { + /* store it */ + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + cb->scope, kv); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); } - /* pack the cache that matches the scope - global scope needs - * to go into both local and remote caches */ - if (PMIX_LOCAL == cb->scope || PMIX_GLOBAL == cb->scope) { - if (NULL == pmix_globals.cache_local) { - pmix_globals.cache_local = PMIX_NEW(pmix_buffer_t); - } - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix: put %s data for key %s in local cache", - cb->key, (PMIX_GLOBAL == cb->scope) ? "global" : "local"); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(pmix_globals.cache_local, kv, 1, PMIX_KVAL))) { - PMIX_ERROR_LOG(rc); - } - } - - if (PMIX_REMOTE == cb->scope || PMIX_GLOBAL == cb->scope) { - if (NULL == pmix_globals.cache_remote) { - pmix_globals.cache_remote = PMIX_NEW(pmix_buffer_t); - } - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix: put %s data for key %s in remote cache", - cb->key, (PMIX_GLOBAL == cb->scope) ? "global" : "remote"); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(pmix_globals.cache_remote, kv, 1, PMIX_KVAL))) { - PMIX_ERROR_LOG(rc); - } - } + /* mark that fresh values have been stored so we know + * to commit them later */ + pmix_globals.commits_pending = true; done: if (NULL != kv) { @@ -849,59 +945,131 @@ static void _commitfn(int sd, short args, void *cbdata) pmix_cb_t *cb = (pmix_cb_t*)cbdata; pmix_status_t rc; pmix_scope_t scope; - pmix_buffer_t *msgout; + pmix_buffer_t *msgout, bkt; pmix_cmd_t cmd=PMIX_COMMIT_CMD; + pmix_kval_t *kv, *kvn; /* need to acquire the cb object from its originating thread */ PMIX_ACQUIRE_OBJECT(cb); msgout = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msgout, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msgout, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msgout); - goto done; + goto error; } /* if we haven't already done it, ensure we have committed our values */ - if (NULL != pmix_globals.cache_local) { + if (pmix_globals.commits_pending) { + /* fetch and pack the local values */ scope = PMIX_LOCAL; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msgout, &scope, 1, PMIX_SCOPE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msgout, &scope, 1, PMIX_SCOPE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msgout); - goto done; + goto error; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msgout, &pmix_globals.cache_local, 1, PMIX_BUFFER))) { + /* allow the GDS module to pass us this info + * as a local connection as this data would + * only go to another local client */ + cb->proc = &pmix_globals.myid; + cb->scope = scope; + cb->copy = false; + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, cb); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msgout); - goto done; + goto error; } - PMIX_RELEASE(pmix_globals.cache_local); - } - if (NULL != pmix_globals.cache_remote) { + + PMIX_CONSTRUCT(&bkt, pmix_buffer_t); + PMIX_LIST_FOREACH_SAFE(kv, kvn, &cb->kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + &bkt, kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&bkt); + PMIX_RELEASE(msgout); + goto error; + } + pmix_list_remove_item(&cb->kvs, &kv->super); + PMIX_RELEASE(kv); + } + /* now pack the result */ + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msgout, &bkt, 1, PMIX_BUFFER); + PMIX_DESTRUCT(&bkt); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(msgout); + goto error; + } + + /* fetch and pack the remote values */ scope = PMIX_REMOTE; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msgout, &scope, 1, PMIX_SCOPE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msgout, &scope, 1, PMIX_SCOPE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msgout); - goto done; + goto error; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msgout, &pmix_globals.cache_remote, 1, PMIX_BUFFER))) { + /* we need real copies here as this data will + * go to remote procs - so a connection will + * not suffice */ + cb->proc = &pmix_globals.myid; + cb->scope = scope; + cb->copy = true; + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, cb); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msgout); - goto done; + goto error; } - PMIX_RELEASE(pmix_globals.cache_remote); + + PMIX_CONSTRUCT(&bkt, pmix_buffer_t); + PMIX_LIST_FOREACH_SAFE(kv, kvn, &cb->kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + &bkt, kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&bkt); + PMIX_RELEASE(msgout); + goto error; + } + pmix_list_remove_item(&cb->kvs, &kv->super); + PMIX_RELEASE(kv); + } + /* now pack the result */ + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msgout, &bkt, 1, PMIX_BUFFER); + PMIX_DESTRUCT(&bkt); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(msgout); + goto error; + } + + /* record that all committed data to-date has been sent */ + pmix_globals.commits_pending = false; } /* always send, even if we have nothing to contribute, so the server knows * that we contributed whatever we had */ - if (PMIX_SUCCESS == (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msgout, - wait_cbfunc, (void*)&cb->lock))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, msgout, + wait_cbfunc, (void*)&cb->lock); + if (PMIX_SUCCESS == rc) { + /* we should wait for the callback, so don't + * modify the active flag */ cb->pstatus = PMIX_SUCCESS; return; } - done: + error: cb->pstatus = rc; /* post the data so the receiving thread can acquire it */ PMIX_POST_OBJECT(cb); @@ -943,86 +1111,11 @@ static void _commitfn(int sd, short args, void *cbdata) return rc; } -static void _peersfn(int sd, short args, void *cbdata) -{ - pmix_cb_t *cb = (pmix_cb_t*)cbdata; - pmix_status_t rc; - char **nsprocs=NULL, **nsps=NULL, **tmp; -#if !(defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1)) - pmix_nspace_t *nsptr; - pmix_nrec_t *nptr; -#endif - size_t i; - - /* need to acquire the cb object from its originating thread */ - PMIX_ACQUIRE_OBJECT(cb); - - /* cycle across our known nspaces */ - tmp = NULL; -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (PMIX_SUCCESS == (rc = pmix_dstore_fetch(cb->nspace, PMIX_RANK_WILDCARD, - cb->key, &cb->value))) { - - tmp = pmix_argv_split(cb->value->data.string, ','); - for (i=0; NULL != tmp[i]; i++) { - pmix_argv_append_nosize(&nsps, cb->nspace); - pmix_argv_append_nosize(&nsprocs, tmp[i]); - } - pmix_argv_free(tmp); - tmp = NULL; - } -#else - PMIX_LIST_FOREACH(nsptr, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strncmp(nsptr->nspace, cb->nspace, PMIX_MAX_NSLEN)) { - /* cycle across the nodes in this nspace */ - PMIX_LIST_FOREACH(nptr, &nsptr->nodes, pmix_nrec_t) { - if (0 == strcmp(cb->key, nptr->name)) { - /* add the contribution from this node */ - tmp = pmix_argv_split(nptr->procs, ','); - for (i=0; NULL != tmp[i]; i++) { - pmix_argv_append_nosize(&nsps, nsptr->nspace); - pmix_argv_append_nosize(&nsprocs, tmp[i]); - } - pmix_argv_free(tmp); - tmp = NULL; - } - } - } - } -#endif - if (0 == (i = pmix_argv_count(nsps))) { - /* we don't know this nspace */ - rc = PMIX_ERR_NOT_FOUND; - goto done; - } - - /* create the required storage */ - PMIX_PROC_CREATE(cb->procs, i); - cb->nvals = pmix_argv_count(nsps); - - /* transfer the data */ - for (i=0; NULL != nsps[i]; i++) { - (void)strncpy(cb->procs[i].nspace, nsps[i], PMIX_MAX_NSLEN); - cb->procs[i].rank = strtol(nsprocs[i], NULL, 10); - } - pmix_argv_free(nsps); - pmix_argv_free(nsprocs); - rc = PMIX_SUCCESS; - - done: - cb->pstatus = rc; - /* post the data so the receiving thread can acquire it */ - PMIX_POST_OBJECT(cb); - PMIX_WAKEUP_THREAD(&cb->lock); -} - +/* need to thread-shift this request */ PMIX_EXPORT pmix_status_t PMIx_Resolve_peers(const char *nodename, const char *nspace, pmix_proc_t **procs, size_t *nprocs) { - pmix_cb_t *cb; - pmix_status_t rc; - PMIX_ACQUIRE_THREAD(&pmix_global_lock); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); @@ -1030,69 +1123,16 @@ PMIX_EXPORT pmix_status_t PMIx_Resolve_peers(const char *nodename, } PMIX_RELEASE_THREAD(&pmix_global_lock); - /* create a callback object */ - cb = PMIX_NEW(pmix_cb_t); - cb->key = (char*)nodename; - if (NULL != nspace) { - (void)strncpy(cb->nspace, nspace, PMIX_MAX_NSLEN); - } + /* set default */ + *procs = NULL; + *nprocs = 0; - /* pass this into the event library for thread protection */ - PMIX_THREADSHIFT(cb, _peersfn); - - /* wait for the result */ - PMIX_WAIT_THREAD(&cb->lock); - rc = cb->pstatus; - /* transfer the result */ - *procs = cb->procs; - *nprocs = cb->nvals; - - /* cleanup */ - PMIX_RELEASE(cb); - - return rc; -} - -static void _nodesfn(int sd, short args, void *cbdata) -{ - pmix_cb_t *cb = (pmix_cb_t*)cbdata; - pmix_status_t rc; - char **tmp; - pmix_nspace_t *nsptr; - pmix_nrec_t *nptr; - - /* need to acquire the cb object from its originating thread */ - PMIX_ACQUIRE_OBJECT(cb); - - /* cycle across our known nspaces */ - tmp = NULL; - PMIX_LIST_FOREACH(nsptr, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strncmp(nsptr->nspace, cb->nspace, PMIX_MAX_NSLEN)) { - /* cycle across the nodes in this nspace */ - PMIX_LIST_FOREACH(nptr, &nsptr->nodes, pmix_nrec_t) { - pmix_argv_append_unique_nosize(&tmp, nptr->name, false); - } - } - } - if (NULL == tmp) { - rc = PMIX_ERR_NOT_FOUND; - } else { - cb->key = pmix_argv_join(tmp, ','); - pmix_argv_free(tmp); - rc = PMIX_SUCCESS; - } - - cb->pstatus = rc; - /* post the data so the receiving thread can acquire it */ - PMIX_POST_OBJECT(cb); - PMIX_WAKEUP_THREAD(&cb->lock); + return pmix_preg.resolve_peers(nodename, nspace, procs, nprocs); } +/* need to thread-shift this request */ PMIX_EXPORT pmix_status_t PMIx_Resolve_nodes(const char *nspace, char **nodelist) { - pmix_cb_t *cb; - pmix_status_t rc; - PMIX_ACQUIRE_THREAD(&pmix_global_lock); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); @@ -1100,20 +1140,8 @@ PMIX_EXPORT pmix_status_t PMIx_Resolve_nodes(const char *nspace, char **nodelist } PMIX_RELEASE_THREAD(&pmix_global_lock); - /* create a callback object */ - cb = PMIX_NEW(pmix_cb_t); - if (NULL != nspace) { - (void)strncpy(cb->nspace, nspace, PMIX_MAX_NSLEN); - } + /* set default */ + *nodelist = NULL; - /* pass this into the event library for thread protection */ - PMIX_THREADSHIFT(cb, _nodesfn); - - /* wait for the result */ - PMIX_WAIT_THREAD(&cb->lock); - rc = cb->pstatus; - *nodelist = cb->key; - PMIX_RELEASE(cb); - - return rc; + return pmix_preg.resolve_nodes(nspace, nodelist); } diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_connect.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_connect.c index 50864d7fbc..0d8765680f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_connect.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_connect.c @@ -47,16 +47,15 @@ #include PMIX_EVENT_HEADER #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" #include "src/threads/threads.h" - +#include "src/mca/gds/gds.h" #include "src/mca/ptl/ptl.h" #include "pmix_client_ops.h" -#include "src/include/pmix_jobdata.h" /* callback for wait completion */ static void wait_cbfunc(struct pmix_peer_t *pr, @@ -65,7 +64,7 @@ static void wait_cbfunc(struct pmix_peer_t *pr, static void op_cbfunc(pmix_status_t status, void *cbdata); PMIX_EXPORT pmix_status_t PMIx_Connect(const pmix_proc_t procs[], size_t nprocs, - const pmix_info_t info[], size_t ninfo) + const pmix_info_t info[], size_t ninfo) { pmix_status_t rc; pmix_cb_t *cb; @@ -142,29 +141,39 @@ PMIX_EXPORT pmix_status_t PMIx_Connect_nb(const pmix_proc_t procs[], size_t npro msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack the number of procs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &nprocs, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &nprocs, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, procs, nprocs, PMIX_PROC))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, procs, nprocs, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack the info structs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -175,11 +184,13 @@ PMIX_EXPORT pmix_status_t PMIx_Connect_nb(const pmix_proc_t procs[], size_t npro * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); - cb->op_cbfunc = cbfunc; + cb->cbfunc.opfn = cbfunc; cb->cbdata = cbdata; /* push the message into our event base to send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, wait_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, wait_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } @@ -260,29 +271,39 @@ PMIX_EXPORT pmix_status_t PMIx_Disconnect_nb(const pmix_proc_t procs[], size_t n msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack the number of procs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &nprocs, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &nprocs, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, procs, nprocs, PMIX_PROC))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, procs, nprocs, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack the info structs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -293,11 +314,13 @@ PMIX_EXPORT pmix_status_t PMIx_Disconnect_nb(const pmix_proc_t procs[], size_t n * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); - cb->op_cbfunc = cbfunc; + cb->cbfunc.opfn = cbfunc; cb->cbdata = cbdata; /* push the message into our event base to send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, wait_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, wait_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } @@ -317,43 +340,65 @@ static void wait_cbfunc(struct pmix_peer_t *pr, pmix_status_t ret; int32_t cnt; char *nspace; - pmix_buffer_t *bptr; + pmix_buffer_t bkt; + pmix_byte_object_t bo; pmix_output_verbose(2, pmix_globals.debug_output, "pmix:client recv callback activated with %d bytes", (NULL == buf) ? -1 : (int)buf->bytes_used); + if (NULL == buf) { + ret = PMIX_ERR_BAD_PARAM; + goto report; + } + /* unpack the returned status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ret, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &ret, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); ret = rc; } /* connect has to also pass back data from all nspace's involved in - * the operation, including our own. Each will come as a buffer */ + * the operation, including our own. Each will come as a byte object */ cnt = 1; - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(buf, &bptr, &cnt, PMIX_BUFFER))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &bo, &cnt, PMIX_BYTE_OBJECT); + while (PMIX_SUCCESS == rc) { + /* load it for unpacking */ + PMIX_CONSTRUCT(&bkt, pmix_buffer_t); + PMIX_LOAD_BUFFER(pmix_client_globals.myserver, &bkt, bo.bytes, bo.size); + /* unpack the nspace for this blob */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(bptr, &nspace, &cnt, PMIX_STRING))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &bkt, &nspace, &cnt, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); - PMIX_RELEASE(bptr); + PMIX_DESTRUCT(&bkt); continue; } /* extract and process any proc-related info for this nspace */ -#if !(defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1)) - pmix_job_data_htable_store(nspace, bptr); -#endif + PMIX_GDS_STORE_JOB_INFO(rc, pmix_globals.mypeer, nspace, &bkt); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + } free(nspace); - PMIX_RELEASE(bptr); - } + PMIX_DESTRUCT(&bkt); + /* get the next one */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &bo, &cnt, PMIX_BYTE_OBJECT); + } if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { PMIX_ERROR_LOG(rc); ret = rc; } - if (NULL != cb->op_cbfunc) { - cb->op_cbfunc(ret, cb->cbdata); + report: + if (NULL != cb->cbfunc.opfn) { + cb->cbfunc.opfn(ret, cb->cbdata); } PMIX_RELEASE(cb); } diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_fence.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_fence.c index 72ccdef295..61fb73a637 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_fence.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_fence.c @@ -47,7 +47,7 @@ #include PMIX_EVENT_HEADER #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/hash.h" @@ -96,6 +96,7 @@ PMIX_EXPORT pmix_status_t PMIx_Fence(const pmix_proc_t procs[], size_t nprocs, /* push the message into our event base to send to the server */ if (PMIX_SUCCESS != (rc = PMIx_Fence_nb(procs, nprocs, info, ninfo, op_cbfunc, cb))) { + PMIX_ERROR_LOG(rc); PMIX_RELEASE(cb); return rc; } @@ -165,11 +166,13 @@ PMIX_EXPORT pmix_status_t PMIx_Fence_nb(const pmix_proc_t procs[], size_t nprocs * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); - cb->op_cbfunc = cbfunc; + cb->cbfunc.opfn = cbfunc; cb->cbdata = cbdata; /* push the message into our event base to send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, wait_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, wait_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } @@ -187,7 +190,9 @@ static pmix_status_t unpack_return(pmix_buffer_t *data) /* unpack the status code */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(data, &ret, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + data, &ret, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } @@ -203,29 +208,39 @@ static pmix_status_t pack_fence(pmix_buffer_t *msg, pmix_cmd_t cmd, pmix_status_t rc; /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack the number of procs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &nprocs, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &nprocs, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack any provided procs - must always be at least one (our own) */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, procs, nprocs, PMIX_PROC))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, procs, nprocs, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack the number of info */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack any provided info - may be NULL */ if (NULL != info && 0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } @@ -250,8 +265,8 @@ static void wait_cbfunc(struct pmix_peer_t *pr, pmix_ptl_hdr_t *hdr, rc = unpack_return(buf); /* if a callback was provided, execute it */ - if (NULL != cb->op_cbfunc) { - cb->op_cbfunc(rc, cb->cbdata); + if (NULL != cb->cbfunc.opfn) { + cb->cbfunc.opfn(rc, cb->cbdata); } PMIX_RELEASE(cb); } diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_get.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_get.c index 928eb721f5..196bc14667 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_get.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_get.c @@ -24,7 +24,6 @@ #include #include "src/include/pmix_globals.h" -#include "src/include/pmix_jobdata.h" #ifdef HAVE_STRING_H #include @@ -52,20 +51,17 @@ #include PMIX_EVENT_HEADER #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/threads/threads.h" #include "src/util/argv.h" #include "src/util/compress.h" #include "src/util/error.h" #include "src/util/hash.h" #include "src/util/output.h" +#include "src/mca/gds/gds.h" #include "src/mca/ptl/ptl.h" -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -#include "src/dstore/pmix_dstore.h" -#endif /* PMIX_ENABLE_DSTORE */ #include "pmix_client_ops.h" -#include "src/include/pmix_jobdata.h" static pmix_buffer_t* _pack_get(char *nspace, pmix_rank_t rank, const pmix_info_t info[], size_t ninfo, @@ -107,11 +103,13 @@ PMIX_EXPORT pmix_status_t PMIx_Get(const pmix_proc_t *proc, const char key[], /* wait for the data to return */ PMIX_WAIT_THREAD(&cb->lock); rc = cb->status; - *val = cb->value; + if (NULL != val) { + *val = cb->value; + } PMIX_RELEASE(cb); pmix_output_verbose(2, pmix_globals.debug_output, - "pmix:client get completed %d", rc); + "pmix:client get completed"); return rc; } @@ -174,14 +172,14 @@ PMIX_EXPORT pmix_status_t PMIx_Get_nb(const pmix_proc_t *proc, const char *key, "pmix: get_nb value for proc %s:%u key %s", nm, rank, (NULL == key) ? "NULL" : key); - /* thread-shift so we can check global objects */ + /* threadshift this request so we can access global structures */ cb = PMIX_NEW(pmix_cb_t); - (void)strncpy(cb->nspace, nm, PMIX_MAX_NSLEN); - cb->rank = rank; + cb->pname.nspace = strdup(nm); + cb->pname.rank = rank; cb->key = (char*)key; cb->info = (pmix_info_t*)info; cb->ninfo = ninfo; - cb->value_cbfunc = cbfunc; + cb->cbfunc.valuefn = cbfunc; cb->cbdata = cbdata; PMIX_THREADSHIFT(cb, _getnbfn); @@ -196,7 +194,9 @@ static void _value_cbfunc(pmix_status_t status, pmix_value_t *kv, void *cbdata) PMIX_ACQUIRE_OBJECT(cb); cb->status = status; if (PMIX_SUCCESS == status) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.copy((void**)&cb->value, kv, PMIX_VALUE))) { + PMIX_BFROPS_COPY(rc, pmix_client_globals.myserver, + (void**)&cb->value, kv, PMIX_VALUE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); } } @@ -205,8 +205,8 @@ static void _value_cbfunc(pmix_status_t status, pmix_value_t *kv, void *cbdata) } static pmix_buffer_t* _pack_get(char *nspace, pmix_rank_t rank, - const pmix_info_t info[], size_t ninfo, - pmix_cmd_t cmd) + const pmix_info_t info[], size_t ninfo, + pmix_cmd_t cmd) { pmix_buffer_t *msg; pmix_status_t rc; @@ -214,31 +214,41 @@ static pmix_buffer_t* _pack_get(char *nspace, pmix_rank_t rank, /* nope - see if we can get it */ msg = PMIX_NEW(pmix_buffer_t); /* pack the get cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return NULL; } /* pack the request information - we'll get the entire blob * for this proc, so we don't need to pass the key */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &nspace, 1, PMIX_STRING))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &nspace, 1, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return NULL; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &rank, 1, PMIX_PROC_RANK))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &rank, 1, PMIX_PROC_RANK); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return NULL; } /* pack the number of info structs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return NULL; } if (0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return NULL; @@ -247,6 +257,7 @@ static pmix_buffer_t* _pack_get(char *nspace, pmix_rank_t rank, return msg; } + /* this callback is coming from the ptl recv, and thus * is occurring inside of our progress thread - hence, no * need to thread shift */ @@ -259,12 +270,8 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr, pmix_status_t rc, ret; pmix_value_t *val = NULL; int32_t cnt; - pmix_nspace_t *ns, *nptr; - pmix_rank_t rank; -#if (PMIX_ENABLE_DSTORE != 1) - pmix_rank_t cur_rank; -#endif - char *tmp; + pmix_proc_t proc; + pmix_kval_t *kv; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: get_nb callback recvd"); @@ -274,210 +281,120 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr, PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); return; } - /* cache the rank */ - rank = cb->rank; + /* cache the proc id */ + (void)strncpy(proc.nspace, cb->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = cb->pname.rank; /* unpack the status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ret, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &ret, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); + pmix_list_remove_item(&pmix_client_globals.pending_requests, &cb->super); + PMIX_RELEASE(cb); return; } - /* look up the nspace object for this proc */ - nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strncmp(cb->nspace, ns->nspace, PMIX_MAX_NSLEN)) { - nptr = ns; - break; - } - } - if (NULL == nptr) { - /* new nspace - setup a record for it */ - nptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(nptr->nspace, cb->nspace, PMIX_MAX_NSLEN); - pmix_list_append(&pmix_globals.nspaces, &nptr->super); - } - if (PMIX_SUCCESS != ret) { goto done; } - -#if (defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1)) - if (PMIX_SUCCESS != (rc = pmix_dstore_fetch(nptr->nspace, cb->rank, cb->key, &val))){ - /* DO NOT error log this status - it is perfectly okay - * for a key not to be found */ + PMIX_GDS_ACCEPT_KVS_RESP(rc, pmix_client_globals.myserver, buf); + if (PMIX_SUCCESS != rc) { goto done; } -#else - /* we received the entire blob for this process, so - * unpack and store it in the modex - this could consist - * of buffers from multiple scopes */ - cur_rank = rank; - cnt = 1; - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(buf, &cur_rank, &cnt, PMIX_PROC_RANK))) { - pmix_kval_t *cur_kval; - pmix_buffer_t *bptr; - cnt = 1; - if (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(buf, &bptr, &cnt, PMIX_BUFFER))) { - /* if the rank is WILDCARD, then this is an nspace blob */ - if (PMIX_RANK_WILDCARD == cur_rank) { - char *nspace; - /* unpack the nspace - we don't really need it, but have to - * unpack it to maintain sequence */ - cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(bptr, &nspace, &cnt, PMIX_STRING))) { - PMIX_ERROR_LOG(rc); - return; - } - free(nspace); - pmix_job_data_htable_store(cb->nspace, bptr); - - /* Check if the key is in this blob */ - - pmix_hash_fetch(&nptr->internal, cb->rank, cb->key, &val); - - } else { - cnt = 1; - cur_kval = PMIX_NEW(pmix_kval_t); - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(bptr, cur_kval, &cnt, PMIX_KVAL))) { - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix: unpacked key %s", cur_kval->key); - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nptr->modex, cur_rank, cur_kval))) { - PMIX_ERROR_LOG(rc); - } - if (NULL != cb->key && 0 == strcmp(cb->key, cur_kval->key)) { - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix: found requested value"); - if (PMIX_SUCCESS != (rc = pmix_bfrop.copy((void**)&val, cur_kval->value, PMIX_VALUE))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(cur_kval); - val = NULL; - goto done; - } - } - PMIX_RELEASE(cur_kval); // maintain acctg - hash_store does a retain - cnt = 1; - cur_kval = PMIX_NEW(pmix_kval_t); - } - cnt = 1; - PMIX_RELEASE(cur_kval); - } - } - PMIX_RELEASE(bptr); // free's the data region - if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc && - PMIX_SUCCESS != rc) { - PMIX_ERROR_LOG(rc); - rc = PMIX_ERR_SILENT; // avoid error-logging twice - break; - } - } - if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc && - PMIX_SUCCESS != rc) { - PMIX_ERROR_LOG(rc); - } else { - rc = PMIX_SUCCESS; - } -#endif /* PMIX_ENABLE_DSTORE */ - -done: - /* if a callback was provided, execute it */ - if (NULL != cb && NULL != cb->value_cbfunc) { - if (NULL == val) { - rc = PMIX_ERR_NOT_FOUND; - } else { - /* if this is a compressed string, then uncompress it */ - if (PMIX_COMPRESSED_STRING == val->type) { - pmix_util_uncompress_string(&tmp, (uint8_t*)val->data.bo.bytes, val->data.bo.size); - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - rc = PMIX_ERR_NOMEM; - PMIX_VALUE_RELEASE(val); + done: + /* now search any pending requests (including the one this was in + * response to) to see if they can be met. Note that this function + * will only be called if the user requested a specific key - we + * don't support calls to "get" for a NULL key */ + PMIX_LIST_FOREACH_SAFE(cb, cb2, &pmix_client_globals.pending_requests, pmix_cb_t) { + if (0 == strncmp(proc.nspace, cb->pname.nspace, PMIX_MAX_NSLEN) && + cb->pname.rank == proc.rank) { + /* we have the data for this proc - see if we can find the key */ + cb->proc = &proc; + cb->scope = PMIX_SCOPE_UNDEF; + /* fetch the data from server peer module - since it is passing + * it back to the user, we need a copy of it */ + cb->copy = true; + PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, cb); + if (PMIX_SUCCESS == rc) { + if (1 != pmix_list_get_size(&cb->kvs)) { + rc = PMIX_ERR_INVALID_VAL; val = NULL; } else { - PMIX_VALUE_DESTRUCT(val); - PMIX_VAL_ASSIGN(val, string, tmp); + kv = (pmix_kval_t*)pmix_list_remove_first(&cb->kvs); + val = kv->value; + kv->value = NULL; // protect the value + PMIX_RELEASE(kv); } } - } - cb->value_cbfunc(rc, val, cb->cbdata); - } - if (NULL != val) { - PMIX_VALUE_RELEASE(val); - } - /* we obviously processed this one, so remove it from the - * list of pending requests */ - pmix_list_remove_item(&pmix_client_globals.pending_requests, &cb->super); - PMIX_RELEASE(cb); - - /* now search any pending requests to see if they can be met */ - PMIX_LIST_FOREACH_SAFE(cb, cb2, &pmix_client_globals.pending_requests, pmix_cb_t) { - if (0 == strncmp(nptr->nspace, cb->nspace, PMIX_MAX_NSLEN) && cb->rank == rank) { - /* we have the data - see if we can find the key */ - val = NULL; -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - rc = pmix_dstore_fetch(nptr->nspace, rank, cb->key, &val); -#else - rc = pmix_hash_fetch(&nptr->modex, rank, cb->key, &val); -#endif /* PMIX_ENABLE_DSTORE */ - cb->value_cbfunc(rc, val, cb->cbdata); - if (NULL != val) { - PMIX_VALUE_RELEASE(val); - } + cb->cbfunc.valuefn(rc, val, cb->cbdata); pmix_list_remove_item(&pmix_client_globals.pending_requests, &cb->super); PMIX_RELEASE(cb); } } } -static pmix_status_t process_val(pmix_value_t *val, - size_t *num_vals, - pmix_pointer_array_t *results) +static void timeout(int fd, short flags, void *cbdata) { - pmix_info_t *info; - size_t n, nsize, nvals; - pmix_status_t rc; + pmix_cb_t *cb = (pmix_cb_t*)cbdata; + /* let them know that we timed out */ + cb->cbfunc.valuefn(PMIX_ERR_TIMEOUT, NULL, cb->cbdata); + cb->timer_running = false; + + /* remove this request */ + pmix_list_remove_item(&pmix_client_globals.pending_requests, &cb->super); + PMIX_RELEASE(cb); +} + +static pmix_status_t process_values(pmix_value_t **v, pmix_cb_t *cb) +{ + pmix_list_t *kvs = &cb->kvs; + pmix_kval_t *kv; + pmix_value_t *val; + pmix_info_t *info; + size_t ninfo, n; + + if (NULL != cb->key && 1 == pmix_list_get_size(kvs)) { + kv = (pmix_kval_t*)pmix_list_get_first(kvs); + *v = kv->value; + kv->value = NULL; // protect the value + return PMIX_SUCCESS; + } + /* we will return the data as an array of pmix_info_t + * in the kvs pmix_value_t */ + val = (pmix_value_t*)malloc(sizeof(pmix_value_t)); if (NULL == val) { - /* this is an error */ - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - return PMIX_ERR_BAD_PARAM; + return PMIX_ERR_NOMEM; } - /* since we didn't provide them with a key, the hash function - * must return the results in the pmix_data_array field of the - * value */ - /* must account for the deprecated pmix_info_array_t */ - if (PMIX_DATA_ARRAY != val->type && - PMIX_INFO_ARRAY != val->type) { - /* this is an error */ - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - return PMIX_ERR_BAD_PARAM; + val->type = PMIX_DATA_ARRAY; + val->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); + if (NULL == val->data.darray) { + PMIX_VALUE_RELEASE(val); + return PMIX_ERR_NOMEM; } - /* save the results */ - if (PMIX_DATA_ARRAY == val->type) { - info = (pmix_info_t*)val->data.darray->array; - nsize = val->data.darray->size; - } else { - info = (pmix_info_t*)val->data.array->array; - nsize = val->data.array->size; + val->data.darray->type = PMIX_INFO; + val->data.darray->size = 0; + val->data.darray->array = NULL; + ninfo = pmix_list_get_size(kvs); + PMIX_INFO_CREATE(info, ninfo); + if (NULL == info) { + PMIX_VALUE_RELEASE(val); + return PMIX_ERR_NOMEM; } - nvals = 0; - for (n=0; n < nsize; n++) { - if (0 > (rc = pmix_pointer_array_add(results, &info[n]))) { - return rc; - } - ++nvals; + /* copy the list elements */ + n=0; + PMIX_LIST_FOREACH(kv, kvs, pmix_kval_t) { + (void)strncpy(info[n].key, kv->key, PMIX_MAX_KEYLEN); + pmix_value_xfer(&info[n].value, kv->value); + ++n; } - if (PMIX_DATA_ARRAY == val->type) { - val->data.darray->array = NULL; // protect the data - val->data.darray->size = 0; - } else { - val->data.array->array = NULL; - val->data.array->size = 0; - } - /* increment the number of values */ - (*num_vals) += nvals; + val->data.darray->size = ninfo; + val->data.darray->array = info; + *v = val; return PMIX_SUCCESS; } @@ -487,267 +404,146 @@ static void _getnbfn(int fd, short flags, void *cbdata) pmix_cb_t *cbret; pmix_buffer_t *msg; pmix_value_t *val = NULL; - pmix_info_t *info, *iptr; - pmix_pointer_array_t results; pmix_status_t rc; - pmix_nspace_t *ns, *nptr; - size_t n, nvals; + size_t n; char *tmp; - bool my_nspace = false, my_rank = false; + pmix_proc_t proc; + bool optional = false; + struct timeval tv; /* cb was passed to us from another thread - acquire it */ PMIX_ACQUIRE_OBJECT(cb); pmix_output_verbose(2, pmix_globals.debug_output, - "pmix: getnbfn value for proc %s:%d key %s", - cb->nspace, cb->rank, + "pmix: getnbfn value for proc %s:%u key %s", + cb->pname.nspace, cb->pname.rank, (NULL == cb->key) ? "NULL" : cb->key); - /* find the nspace object */ - nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strcmp(cb->nspace, ns->nspace)) { - nptr = ns; - break; - } - } - if (NULL == nptr) { - /* we are asking for info about a new nspace - give us - * a chance to learn about it from the server. If the - * server has never heard of it, the server will return - * an error */ - nptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(nptr->nspace, cb->nspace, PMIX_MAX_NSLEN); - pmix_list_append(&pmix_globals.nspaces, &nptr->super); - /* there is no point in looking for data in this nspace - * object, so let's just go generate the request */ - goto request; - } + /* set the proc object identifier */ + (void)strncpy(proc.nspace, cb->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = cb->pname.rank; - /* The NULL==key scenario only pertains to cases where legacy - * PMI methods are being employed. In this case, we have to check - * both the job-data and the modex tables. If we don't yet have - * the modex data, then we are going to have to go get it. So let's - * check that case first */ - if (NULL == cb->key) { - PMIX_CONSTRUCT(&results, pmix_pointer_array_t); - pmix_pointer_array_init(&results, 2, INT_MAX, 1); - nvals = 0; - /* if the rank is WILDCARD, then they want all the job-level info, - * so no need to check the modex */ - if (PMIX_RANK_WILDCARD != cb->rank) { - rc = PMIX_ERR_NOT_FOUND; -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - /* my own data is in the hash table, so don't bother looking - * in the dstore if that is what they want */ - if (pmix_globals.myid.rank != cb->rank) { - if (PMIX_SUCCESS == (rc = pmix_dstore_fetch(nptr->nspace, cb->rank, NULL, &val))) { - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix_get[%d]: value retrieved from dstore", __LINE__); - if (PMIX_SUCCESS != (rc = process_val(val, &nvals, &results))) { - cb->value_cbfunc(rc, NULL, cb->cbdata); - /* cleanup */ - if (NULL != val) { - PMIX_VALUE_RELEASE(val); - } - PMIX_RELEASE(cb); - return; - } + /* scan the incoming directives */ + if (NULL != cb->info) { + for (n=0; n < cb->ninfo; n++) { + if (0 == strncmp(cb->info[n].key, PMIX_OPTIONAL, PMIX_MAX_KEYLEN)) { + if (PMIX_UNDEF == cb->info[n].value.type || + cb->info[n].value.data.flag) { + optional = true; } - } -#endif /* PMIX_ENABLE_DSTORE */ - if (PMIX_SUCCESS != rc) { - /* if the user was asking about themselves, or we aren't using the dstore, - * then we need to check the hash table */ - if (PMIX_SUCCESS == (rc = pmix_hash_fetch(&nptr->modex, cb->rank, NULL, &val))) { - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix_get[%d]: value retrieved from hash", __LINE__); - if (PMIX_SUCCESS != (rc = process_val(val, &nvals, &results))) { - cb->value_cbfunc(rc, NULL, cb->cbdata); - /* cleanup */ - if (NULL != val) { - PMIX_VALUE_RELEASE(val); - } - PMIX_RELEASE(cb); - return; - } - PMIX_VALUE_RELEASE(val); + } else if (0 == strncmp(cb->info[n].key, PMIX_TIMEOUT, PMIX_MAX_KEYLEN)) { + /* set a timer to kick us out if we don't + * have an answer within their window */ + if (0 < cb->info[n].value.data.integer) { + tv.tv_sec = cb->info[n].value.data.integer; + tv.tv_usec = 0; + pmix_event_evtimer_set(pmix_globals.evbase, &cb->ev, + timeout, cb); + pmix_event_evtimer_add(&cb->ev, &tv); + cb->timer_running = true; } - } - if (PMIX_SUCCESS != rc) { - /* if we didn't find a modex for this rank, then we need - * to go get it. Thus, the caller wants -all- information for - * the specified rank, not just the job-level info. */ - goto request; + } else if (0 == strncmp(cb->info[n].key, PMIX_DATA_SCOPE, PMIX_MAX_KEYLEN)) { + cb->scope = cb->info[n].value.data.scope; } } - /* now get any data from the job-level info */ - if (PMIX_SUCCESS == (rc = pmix_hash_fetch(&nptr->internal, PMIX_RANK_WILDCARD, NULL, &val))) { - if (PMIX_SUCCESS != (rc = process_val(val, &nvals, &results))) { - cb->value_cbfunc(rc, NULL, cb->cbdata); - /* cleanup */ - if (NULL != val) { - PMIX_VALUE_RELEASE(val); - } - PMIX_RELEASE(cb); - return; - } - PMIX_VALUE_RELEASE(val); - } - /* now let's package up the results */ - PMIX_VALUE_CREATE(val, 1); - val->type = PMIX_DATA_ARRAY; - val->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); - if (NULL == val->data.darray) { - PMIX_VALUE_RELEASE(val); - cb->value_cbfunc(PMIX_ERR_NOMEM, NULL, cb->cbdata); - return; - } - val->data.darray->type = PMIX_INFO; - val->data.darray->size = nvals; - PMIX_INFO_CREATE(iptr, nvals); - val->data.darray->array = (void*)iptr; - for (n=0; n < (size_t)results.size && n < nvals; n++) { - if (NULL != (info = (pmix_info_t*)pmix_pointer_array_get_item(&results, n))) { - (void)strncpy(iptr[n].key, info->key, PMIX_MAX_KEYLEN); - /* if this is a compressed string, then uncompress it */ - if (PMIX_COMPRESSED_STRING == info->value.type) { - iptr[n].value.type = PMIX_STRING; - pmix_util_uncompress_string(&iptr[n].value.data.string, - (uint8_t*)info->value.data.bo.bytes, - info->value.data.bo.size); - if (NULL == iptr[n].value.data.string) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - } - } else { - pmix_value_xfer(&iptr[n].value, &info->value); - } - PMIX_INFO_DESTRUCT(info); - } - } - /* done with results array */ - PMIX_DESTRUCT(&results); - /* return the result to the caller - they are responsible for releasing it */ - cb->value_cbfunc(PMIX_SUCCESS, val, cb->cbdata); - PMIX_RELEASE(cb); - return; } /* check the internal storage first */ - rc = pmix_hash_fetch(&nptr->internal, cb->rank, cb->key, &val); - if(PMIX_SUCCESS == rc) { + cb->proc = &proc; + cb->copy = true; + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, cb); + if (PMIX_SUCCESS == rc) { + rc = process_values(&val, cb); goto respond; } - my_nspace = (0 == strncmp(cb->nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN)); - my_rank = (pmix_globals.myid.rank == cb->rank); - - /* if the key starts from "pmix", then they are looking for data - * that was provided at startup */ - if (0 == strncmp(cb->key, "pmix", 4)) { -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - /* if this is a dstore - check there */ - rc = pmix_dstore_fetch(cb->nspace, cb->rank, cb->key, &val); -#endif - if( PMIX_SUCCESS != rc && !my_nspace ){ - /* we are asking about the job-level info from another - * namespace. It seems that we don't have it - go and - * ask server - */ + /* if the key is NULL or starts with "pmix", then they are looking + * for data that was provided by the server at startup */ + if (NULL == cb->key || 0 == strncmp(cb->key, "pmix", 4)) { + cb->proc = &proc; + /* fetch the data from my server's module - since we are passing + * it back to the user, we need a copy of it */ + cb->copy = true; + PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, cb); + if (PMIX_SUCCESS != rc) { + if (0 != strncmp(cb->pname.nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN)) { + /* we are asking about the job-level info from another + * namespace. It seems that we don't have it - go and + * ask server + */ + goto request; + } else { + /* we should have had this info, so respond with the error */ + goto respond; + } + } + rc = process_values(&val, cb); + goto respond; + } else { + cb->proc = &proc; + cb->copy = true; + PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, cb); + if (PMIX_SUCCESS != rc) { + val = NULL; goto request; } - /* we supposed to already have all local namespace data */ - goto respond; + /* return whatever we found */ + rc = process_values(&val, cb); } - /* if we were asked about this rank */ - if ( my_nspace && my_rank ){ - /* if we asking the data about this rank - check local hash table. - * All the data passed through PMIx_Put settle down there - * if there is nothing there - it's nothing else we can do - */ - rc = pmix_hash_fetch(&nptr->modex, pmix_globals.myid.rank, cb->key, &val); - if( PMIX_SUCCESS != rc ){ - rc = PMIX_ERR_NOT_FOUND; - } - goto respond; + respond: + /* if a callback was provided, execute it */ + if (NULL != cb->cbfunc.valuefn) { + if (NULL != val) { + /* if this is a compressed string, then uncompress it */ + if (PMIX_COMPRESSED_STRING == val->type) { + pmix_util_uncompress_string(&tmp, (uint8_t*)val->data.bo.bytes, val->data.bo.size); + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + rc = PMIX_ERR_NOMEM; + PMIX_VALUE_RELEASE(val); + val = NULL; + } else { + PMIX_VALUE_DESTRUCT(val); + PMIX_VAL_ASSIGN(val, string, tmp); + } + } + } + cb->cbfunc.valuefn(rc, val, cb->cbdata); } - - /* otherwise, the data must be something they "put" */ -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - rc = PMIX_ERR_PROC_ENTRY_NOT_FOUND; - /* if rank is undefined - check local table first */ - if ( my_nspace && (PMIX_RANK_UNDEF == cb->rank)){ - /* if we asking about undefined process - check local hash table first - * local rank may have submitted this key. */ - rc = pmix_hash_fetch(&nptr->modex, pmix_globals.myid.rank, cb->key, &val); - } - /* try to take it from dstore */ - if( PMIX_ERR_PROC_ENTRY_NOT_FOUND == rc ){ - /* Two option possible here: - - we asking the key from UNDEF process and local proc - haven't pushed this data - - we askin the key from the particular process which is not us. - */ - rc = pmix_dstore_fetch(nptr->nspace, cb->rank, cb->key, &val); - } -#else - rc = pmix_hash_fetch(&nptr->modex, cb->rank, cb->key, &val); -#endif /* PMIX_ENABLE_DSTORE */ - - if ( PMIX_SUCCESS == rc ) { - goto respond; - } else if ( PMIX_ERR_PROC_ENTRY_NOT_FOUND == rc ){ - goto request; - }else if (PMIX_ERR_NOT_FOUND == rc) { - /* we have the modex data from this proc, but didn't find the key - * the user requested. It's possible someone pushed something since - * we got this data, so let's ask the server for an update. However, - * we do have to protect against an infinite loop! */ - if (cb->checked) { - goto respond; - } - pmix_output_verbose(2, pmix_globals.debug_output, - "Unable to locally satisfy request for key=%s for rank = %d, namespace = %s", - cb->key, cb->rank, cb->nspace); - cb->checked = true; // flag that we are going to check this again - goto request; - } else if (PMIX_ERR_PROC_ENTRY_NOT_FOUND != rc) { - /* errors are fatal */ - goto respond; + if (NULL != val) { + PMIX_VALUE_RELEASE(val); } + PMIX_RELEASE(cb); + return; request: /* if we got here, then we don't have the data for this proc. If we * are a server, or we are a client and not connected, then there is * nothing more we can do */ - if (PMIX_PROC_IS_SERVER || - (!PMIX_PROC_IS_SERVER && !pmix_globals.connected)) { + if (PMIX_PROC_SERVER == pmix_globals.proc_type || + (PMIX_PROC_SERVER != pmix_globals.proc_type && !pmix_globals.connected)) { rc = PMIX_ERR_NOT_FOUND; goto respond; } /* we also have to check the user's directives to see if they do not want * us to attempt to retrieve it from the server */ - for (n=0; n < cb->ninfo; n++) { - if ((0 == strcmp(cb->info[n].key, PMIX_OPTIONAL) || (0 == strcmp(cb->info[n].key, PMIX_IMMEDIATE))) && - (PMIX_UNDEF == cb->info[n].value.type || cb->info[n].value.data.flag)) { - /* they don't want us to try and retrieve it */ - pmix_output_verbose(2, pmix_globals.debug_output, - "PMIx_Get key=%s for rank = %d, namespace = %s was not found - request was optional", - cb->key, cb->rank, cb->nspace); - rc = PMIX_ERR_NOT_FOUND; - val = NULL; - goto respond; - } + if (optional) { + /* they don't want us to try and retrieve it */ + pmix_output_verbose(2, pmix_globals.debug_output, + "PMIx_Get key=%s for rank = %u, namespace = %s was not found - request was optional", + cb->key, cb->pname.rank, cb->pname.nspace); + rc = PMIX_ERR_NOT_FOUND; + goto respond; } /* see if we already have a request in place with the server for data from * this nspace:rank. If we do, then no need to ask again as the * request will return _all_ data from that proc */ PMIX_LIST_FOREACH(cbret, &pmix_client_globals.pending_requests, pmix_cb_t) { - if (0 == strncmp(cbret->nspace, cb->nspace, PMIX_MAX_NSLEN) && - cbret->rank == cb->rank) { + if (0 == strncmp(cbret->pname.nspace, cb->pname.nspace, PMIX_MAX_NSLEN) && + cbret->pname.rank == cb->pname.rank) { /* we do have a pending request, but we still need to track this * outstanding request so we can satisfy it once the data is returned */ pmix_list_append(&pmix_client_globals.pending_requests, &cb->super); @@ -757,7 +553,7 @@ static void _getnbfn(int fd, short flags, void *cbdata) /* we don't have a pending request, so let's create one - don't worry * about packing the key as we return everything from that proc */ - msg = _pack_get(cb->nspace, cb->rank, cb->info, cb->ninfo, PMIX_GETNB_CMD); + msg = _pack_get(cb->pname.nspace, cb->pname.rank, cb->info, cb->ninfo, PMIX_GETNB_CMD); if (NULL == msg) { rc = PMIX_ERROR; goto respond; @@ -766,12 +562,13 @@ static void _getnbfn(int fd, short flags, void *cbdata) pmix_output_verbose(2, pmix_globals.debug_output, "%s:%d REQUESTING DATA FROM SERVER FOR %s:%d KEY %s", pmix_globals.myid.nspace, pmix_globals.myid.rank, - cb->nspace, cb->rank, cb->key); + cb->pname.nspace, cb->pname.rank, cb->key); /* track the callback object */ pmix_list_append(&pmix_client_globals.pending_requests, &cb->super); /* send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, _getnb_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, msg, _getnb_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { pmix_list_remove_item(&pmix_client_globals.pending_requests, &cb->super); rc = PMIX_ERROR; goto respond; @@ -780,30 +577,4 @@ static void _getnbfn(int fd, short flags, void *cbdata) * written out before we return */ PMIX_POST_OBJECT(cb); return; - - respond: - /* if a callback was provided, execute it */ - if (NULL != cb->value_cbfunc) { - if (NULL != val) { - /* if this is a compressed string, then uncompress it */ - if (PMIX_COMPRESSED_STRING == val->type) { - pmix_util_uncompress_string(&tmp, (uint8_t*)val->data.bo.bytes, val->data.bo.size); - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - rc = PMIX_ERR_NOMEM; - PMIX_VALUE_RELEASE(val); - val = NULL; - } else { - PMIX_VALUE_DESTRUCT(val); - PMIX_VAL_ASSIGN(val, string, tmp); - } - } - } - cb->value_cbfunc(rc, val, cb->cbdata); - } - if (NULL != val) { - PMIX_VALUE_RELEASE(val); - } - PMIX_RELEASE(cb); - return; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_ops.h b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_ops.h index ecf979572c..159d0a1603 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_ops.h +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_ops.h @@ -13,9 +13,9 @@ #include -#include "src/buffer_ops/buffer_ops.h" -#include "src/class/pmix_hash_table.h" #include "src/threads/threads.h" +#include "src/class/pmix_list.h" +#include "src/include/pmix_globals.h" BEGIN_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_pub.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_pub.c index 6981c96e1e..c76ff28e7d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_pub.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_pub.c @@ -47,8 +47,8 @@ #include PMIX_EVENT_HEADER #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" #include "src/threads/threads.h" +#include "src/mca/bfrops/bfrops.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" @@ -141,40 +141,52 @@ PMIX_EXPORT pmix_status_t PMIx_Publish_nb(const pmix_info_t info[], size_t ninfo /* create the publish cmd */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack our effective userid - will be used to constrain lookup */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &pmix_globals.uid, 1, PMIX_UINT32))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &pmix_globals.uid, 1, PMIX_UINT32); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pass the number of info structs - needed on remote end so * space can be malloc'd for the values */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } - /* pack the info structs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(msg); - return rc; + if (0 < ninfo) { + /* pack the info structs */ + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(msg); + return rc; + } } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); - cb->op_cbfunc = cbfunc; + cb->cbfunc.opfn = cbfunc; cb->cbdata = cbdata; /* push the message into our event base to send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, wait_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, wait_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } @@ -256,7 +268,7 @@ PMIX_EXPORT pmix_status_t PMIx_Lookup_nb(char **keys, PMIX_ACQUIRE_THREAD(&pmix_global_lock); pmix_output_verbose(2, pmix_globals.debug_output, - "pmix: lookup called"); + "pmix: lookup_nb called"); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); @@ -278,27 +290,35 @@ PMIX_EXPORT pmix_status_t PMIx_Lookup_nb(char **keys, /* create the lookup cmd */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack our effective userid - will be used to constrain lookup */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &pmix_globals.uid, 1, PMIX_UINT32))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &pmix_globals.uid, 1, PMIX_UINT32); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the keys */ nkeys = pmix_argv_count(keys); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &nkeys, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &nkeys, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < nkeys) { for (n=0; n < nkeys; n++) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &keys[n], 1, PMIX_STRING))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &keys[n], 1, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -307,27 +327,35 @@ PMIX_EXPORT pmix_status_t PMIx_Lookup_nb(char **keys, } /* pass the number of info structs - needed on remote end so * space can be malloc'd for the values */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } - /* pack the info structs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(msg); - return rc; + if (0 < ninfo) { + /* pack the info structs */ + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(msg); + return rc; + } } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); - cb->lookup_cbfunc = cbfunc; + cb->cbfunc.lookupfn = cbfunc; cb->cbdata = cbdata; /* send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, wait_lookup_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, wait_lookup_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } @@ -408,27 +436,35 @@ PMIX_EXPORT pmix_status_t PMIx_Unpublish_nb(char **keys, /* create the unpublish cmd */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack our effective userid - will be used to constrain lookup */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &pmix_globals.uid, 1, PMIX_UINT32))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &pmix_globals.uid, 1, PMIX_UINT32); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the number of keys */ i = pmix_argv_count(keys); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &i, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &i, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < i) { for (j=0; j < i; j++) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &keys[j], 1, PMIX_STRING))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &keys[j], 1, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -437,25 +473,33 @@ PMIX_EXPORT pmix_status_t PMIx_Unpublish_nb(char **keys, } /* pass the number of info structs - needed on remote end so * space can be malloc'd for the values */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } - /* pack the info structs */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(msg); - return rc; + if (0 < ninfo) { + /* pack the info structs */ + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(msg); + return rc; + } } /* create a callback object */ cb = PMIX_NEW(pmix_cb_t); - cb->op_cbfunc = cbfunc; + cb->cbfunc.opfn = cbfunc; cb->cbdata = cbdata; /* send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, wait_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, wait_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } @@ -478,13 +522,22 @@ static void wait_cbfunc(struct pmix_peer_t *pr, "pmix:client recv callback activated with %d bytes", (NULL == buf) ? -1 : (int)buf->bytes_used); + if (NULL == buf) { + rc = PMIX_ERR_BAD_PARAM; + goto report; + } + /* unpack the returned status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ret, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &ret, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); } - if (NULL != cb->op_cbfunc) { - cb->op_cbfunc(rc, cb->cbdata); + + report: + if (NULL != cb->cbfunc.opfn) { + cb->cbfunc.opfn(rc, cb->cbdata); } PMIX_RELEASE(cb); } @@ -505,8 +558,8 @@ static void wait_lookup_cbfunc(struct pmix_peer_t *pr, pmix_cb_t *cb = (pmix_cb_t*)cbdata; pmix_status_t rc, ret; int32_t cnt; - pmix_pdata_t *pdata; - size_t ndata; + pmix_pdata_t *pdata = NULL; + size_t ndata = 0; PMIX_ACQUIRE_OBJECT(cb); @@ -514,11 +567,15 @@ static void wait_lookup_cbfunc(struct pmix_peer_t *pr, "pmix:client recv callback activated with %d bytes", (NULL == buf) ? -1 : (int)buf->bytes_used); - if (NULL == cb->lookup_cbfunc) { + if (NULL == cb->cbfunc.lookupfn) { /* nothing we can do with this */ PMIX_RELEASE(cb); return; } + if (NULL == buf) { + rc = PMIX_ERR_BAD_PARAM; + goto report; + } /* set the defaults */ pdata = NULL; @@ -526,13 +583,15 @@ static void wait_lookup_cbfunc(struct pmix_peer_t *pr, /* unpack the returned status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ret, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &ret, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); ret = rc; } if (PMIX_SUCCESS != ret) { - if (NULL != cb->lookup_cbfunc) { - cb->lookup_cbfunc(ret, NULL, 0, cb->cbdata); + if (NULL != cb->cbfunc.lookupfn) { + cb->cbfunc.lookupfn(ret, NULL, 0, cb->cbdata); } PMIX_RELEASE(cb); return; @@ -540,7 +599,9 @@ static void wait_lookup_cbfunc(struct pmix_peer_t *pr, /* unpack the number of returned values */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ndata, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &ndata, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(cb); return; @@ -550,19 +611,24 @@ static void wait_lookup_cbfunc(struct pmix_peer_t *pr, PMIX_PDATA_CREATE(pdata, ndata); cnt = ndata; /* unpack the returned values into the pdata array */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, pdata, &cnt, PMIX_PDATA))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, pdata, &cnt, PMIX_PDATA); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } } - if (NULL != cb->lookup_cbfunc) { - cb->lookup_cbfunc(rc, pdata, ndata, cb->cbdata); + report: + if (NULL != cb->cbfunc.lookupfn) { + cb->cbfunc.lookupfn(rc, pdata, ndata, cb->cbdata); } cleanup: /* cleanup */ - PMIX_PDATA_FREE(pdata, ndata); + if (NULL != pdata) { + PMIX_PDATA_FREE(pdata, ndata); + } PMIX_RELEASE(cb); } @@ -585,7 +651,7 @@ static void lookup_cbfunc(pmix_status_t status, pmix_pdata_t pdata[], size_t nda (void)strncpy(tgt[j].proc.nspace, pdata[i].proc.nspace, PMIX_MAX_NSLEN); tgt[j].proc.rank = pdata[i].proc.rank; /* transfer the value to the pmix_info_t */ - pmix_value_xfer(&tgt[j].value, &pdata[i].value); + PMIX_BFROPS_VALUE_XFER(cb->status, pmix_client_globals.myserver, &tgt[j].value, &pdata[i].value); break; } } diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_spawn.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_spawn.c index a7842c5ffb..9059145377 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_spawn.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_spawn.c @@ -47,15 +47,15 @@ #include PMIX_EVENT_HEADER #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" #include "src/threads/threads.h" +#include "src/mca/bfrops/bfrops.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" +#include "src/mca/gds/gds.h" #include "src/mca/ptl/ptl.h" #include "pmix_client_ops.h" -#include "src/include/pmix_jobdata.h" static void wait_cbfunc(struct pmix_peer_t *pr, pmix_ptl_hdr_t *hdr, @@ -104,7 +104,7 @@ PMIX_EXPORT pmix_status_t PMIx_Spawn(const pmix_info_t job_info[], size_t ninfo, PMIX_WAIT_THREAD(&cb->lock); rc = cb->status; if (NULL != nspace) { - (void)strncpy(nspace, cb->nspace, PMIX_MAX_NSLEN); + (void)strncpy(nspace, cb->pname.nspace, PMIX_MAX_NSLEN); } PMIX_RELEASE(cb); @@ -139,20 +139,26 @@ PMIX_EXPORT pmix_status_t PMIx_Spawn_nb(const pmix_info_t job_info[], size_t nin msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the job-level directives */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, job_info, ninfo, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, job_info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -160,28 +166,34 @@ PMIX_EXPORT pmix_status_t PMIx_Spawn_nb(const pmix_info_t job_info[], size_t nin } /* pack the apps */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &napps, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &napps, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < napps) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, apps, napps, PMIX_APP))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(msg); - return rc; - } + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, apps, napps, PMIX_APP); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(msg); + return rc; + } } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); - cb->spawn_cbfunc = cbfunc; + cb->cbfunc.spawnfn = cbfunc; cb->cbdata = cbdata; /* push the message into our event base to send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, wait_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, wait_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } @@ -209,16 +221,25 @@ static void wait_cbfunc(struct pmix_peer_t *pr, /* init */ memset(nspace, 0, PMIX_MAX_NSLEN+1); + if (NULL == buf) { + ret = PMIX_ERR_BAD_PARAM; + goto report; + } + /* unpack the returned status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ret, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &ret, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); ret = rc; } if (PMIX_SUCCESS == ret) { /* unpack the namespace */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &n2, &cnt, PMIX_STRING))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &n2, &cnt, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); ret = rc; } @@ -226,19 +247,21 @@ static void wait_cbfunc(struct pmix_peer_t *pr, "pmix:client recv '%s'", n2); if (NULL != n2) { + /* protect length */ (void)strncpy(nspace, n2, PMIX_MAX_NSLEN); -#if !(defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1)) - /* extract and process any proc-related info for this nspace */ - pmix_job_data_htable_store(nspace, buf); -#endif free(n2); + PMIX_GDS_STORE_JOB_INFO(rc, pmix_globals.mypeer, nspace, buf); + /* extract and process any job-related info for this nspace */ + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + } } } - if (NULL != cb->spawn_cbfunc) { - cb->spawn_cbfunc(ret, nspace, cb->cbdata); + report: + if (NULL != cb->cbfunc.spawnfn) { + cb->cbfunc.spawnfn(ret, nspace, cb->cbdata); } - cb->cbdata = NULL; PMIX_RELEASE(cb); } @@ -249,7 +272,7 @@ static void spawn_cbfunc(pmix_status_t status, char nspace[], void *cbdata) PMIX_ACQUIRE_OBJECT(cb); cb->status = status; if (NULL != nspace) { - (void)strncpy(cb->nspace, nspace, PMIX_MAX_NSLEN); + cb->pname.nspace = strdup(nspace); } PMIX_POST_OBJECT(cb); PMIX_WAKEUP_THREAD(&cb->lock); diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.include index e8b9a46a62..dda109eb69 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.include @@ -13,6 +13,5 @@ sources += \ common/pmix_query.c \ common/pmix_strings.c \ common/pmix_log.c \ - common/pmix_jobdata.c \ common/pmix_control.c \ common/pmix_data.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_control.c b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_control.c index cf2f546f77..1ce8d05952 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_control.c +++ b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_control.c @@ -25,7 +25,7 @@ #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/mca/ptl/ptl.h" #include "src/client/pmix_client_ops.h" @@ -60,7 +60,8 @@ static void query_cbfunc(struct pmix_peer_t *peer, /* unpack the status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &results->status, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &results->status, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto complete; } @@ -70,14 +71,16 @@ static void query_cbfunc(struct pmix_peer_t *peer, /* unpack any returned data */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &results->ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &results->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto complete; } if (0 < results->ninfo) { PMIX_INFO_CREATE(results->info, results->ninfo); cnt = results->ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, results->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, results->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto complete; } @@ -138,14 +141,18 @@ PMIX_EXPORT pmix_status_t PMIx_Job_control_nb(const pmix_proc_t targets[], size_ /* if we are a client, then relay this request to the server */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the number of targets */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ntargets, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ntargets, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -154,7 +161,9 @@ PMIX_EXPORT pmix_status_t PMIx_Job_control_nb(const pmix_proc_t targets[], size_ * is to be done against all members of our nspace */ if (0 < ntargets) { /* pack the targets */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, targets, ntargets, PMIX_PROC))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, targets, ntargets, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -162,13 +171,17 @@ PMIX_EXPORT pmix_status_t PMIx_Job_control_nb(const pmix_proc_t targets[], size_ } /* pack the directives */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ndirs, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ndirs, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < ndirs) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, directives, ndirs, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, directives, ndirs, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -183,7 +196,9 @@ PMIX_EXPORT pmix_status_t PMIx_Job_control_nb(const pmix_proc_t targets[], size_ cb->cbdata = cbdata; /* push the message into our event base to send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, query_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, query_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } @@ -234,34 +249,44 @@ PMIX_EXPORT pmix_status_t PMIx_Process_monitor_nb(const pmix_info_t *monitor, pm /* if we are a client, then relay this request to the server */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the monitor */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, monitor, 1, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, monitor, 1, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the error */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &error, 1, PMIX_STATUS))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &error, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the directives */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ndirs, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ndirs, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < ndirs) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, directives, ndirs, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, directives, ndirs, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -276,7 +301,9 @@ PMIX_EXPORT pmix_status_t PMIx_Process_monitor_nb(const pmix_info_t *monitor, pm cb->cbdata = cbdata; /* push the message into our event base to send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, query_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, query_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_data.c b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_data.c index a10f4057cc..69263a556b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_data.c +++ b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_data.c @@ -34,7 +34,8 @@ #include #include -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" +#include "src/include/pmix_globals.h" #define PMIX_EMBED_DATA_BUFFER(b, db) \ do { \ @@ -78,7 +79,8 @@ PMIX_EXPORT pmix_status_t PMIx_Data_pack(pmix_data_buffer_t *buffer, PMIX_EMBED_DATA_BUFFER(&buf, buffer); /* pack the value */ - rc = pmix_bfrop.pack(&buf, src, num_vals, type); + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, + &buf, src, num_vals, type); /* extract the data buffer - the pointers may have changed */ PMIX_EXTRACT_DATA_BUFFER(&buf, buffer); @@ -102,7 +104,8 @@ PMIX_EXPORT pmix_status_t PMIx_Data_unpack(pmix_data_buffer_t *buffer, void *des PMIX_EMBED_DATA_BUFFER(&buf, buffer); /* unpack the value */ - rc = pmix_bfrop.unpack(&buf, dest, max_num_values, type); + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, + &buf, dest, max_num_values, type); /* extract the data buffer - the pointers may have changed */ PMIX_EXTRACT_DATA_BUFFER(&buf, buffer); @@ -117,7 +120,8 @@ PMIX_EXPORT pmix_status_t PMIx_Data_copy(void **dest, void *src, pmix_status_t rc; /* copy the value */ - rc = pmix_bfrop.copy(dest, src, type); + PMIX_BFROPS_COPY(rc, pmix_globals.mypeer, + dest, src, type); return rc; } @@ -128,7 +132,8 @@ PMIX_EXPORT pmix_status_t PMIx_Data_print(char **output, char *prefix, pmix_status_t rc; /* print the value */ - rc = pmix_bfrop.print(output, prefix, src, type); + PMIX_BFROPS_PRINT(rc, pmix_globals.mypeer, + output, prefix, src, type); return rc; } @@ -148,7 +153,8 @@ PMIX_EXPORT pmix_status_t PMIx_Data_copy_payload(pmix_data_buffer_t *dest, PMIX_EMBED_DATA_BUFFER(&buf2, src); /* copy payload */ - rc = pmix_bfrop.copy_payload(&buf1, &buf2); + PMIX_BFROPS_COPY_PAYLOAD(rc, pmix_globals.mypeer, + &buf1, &buf2); /* extract the dest data buffer - the pointers may have changed */ PMIX_EXTRACT_DATA_BUFFER(&buf1, dest); diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_jobdata.c b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_jobdata.c deleted file mode 100644 index 4ca58d6acf..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_jobdata.c +++ /dev/null @@ -1,415 +0,0 @@ -/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ -/* - * Copyright (c) 2016-2017 Mellanox Technologies, Inc. - * All rights reserved. - * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ -#include -#include -#include -#include "src/include/pmix_globals.h" -#include "src/client/pmix_client_ops.h" -#include "src/class/pmix_value_array.h" -#include "src/util/error.h" -#include "src/buffer_ops/internal.h" -#include "src/util/argv.h" -#include "src/util/compress.h" -#include "src/util/hash.h" -#include "src/util/show_help.h" -#include "src/runtime/pmix_rte.h" -#include "src/include/pmix_jobdata.h" - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -#include "src/dstore/pmix_dstore.h" -#endif - -static inline int _add_key_for_rank(pmix_rank_t rank, pmix_kval_t *kv, void *cbdata); -static inline pmix_status_t _job_data_store(const char *nspace, void *cbdata); - - -static inline int _add_key_for_rank(pmix_rank_t rank, pmix_kval_t *kv, void *cbdata) -{ - pmix_job_data_caddy_t *cb = (pmix_job_data_caddy_t*)(cbdata); - pmix_status_t rc = PMIX_SUCCESS; -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - uint32_t i, size; - pmix_buffer_t *tmp = NULL; - pmix_rank_t cur_rank; - - if (NULL != cb->dstore_fn) { - /* rank WILDCARD contained in the 0 item */ - cur_rank = PMIX_RANK_WILDCARD == rank ? 0 : rank + 1; - size = (uint32_t)pmix_value_array_get_size(cb->bufs); - - if ((cur_rank + 1) <= size) { - tmp = &(PMIX_VALUE_ARRAY_GET_ITEM(cb->bufs, pmix_buffer_t, cur_rank)); - pmix_bfrop.pack(tmp, kv, 1, PMIX_KVAL); - return rc; - } - if (PMIX_SUCCESS != (rc = pmix_value_array_set_size(cb->bufs, cur_rank + 1))) { - PMIX_ERROR_LOG(rc); - return rc; - } - for (i = size; i < (cur_rank + 1); i++) { - tmp = &(PMIX_VALUE_ARRAY_GET_ITEM(cb->bufs, pmix_buffer_t, i)); - PMIX_CONSTRUCT(tmp, pmix_buffer_t); - } - pmix_bfrop.pack(tmp, kv, 1, PMIX_KVAL); - } -#endif - if (cb->hstore_fn) { - if (PMIX_SUCCESS != (rc = cb->hstore_fn(&cb->nsptr->internal, rank, kv))) { - PMIX_ERROR_LOG(rc); - } - } - return rc; -} - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -static inline int _rank_key_dstore_store(void *cbdata) -{ - int rc = PMIX_SUCCESS; - uint32_t i, size; - pmix_buffer_t *tmp; - pmix_job_data_caddy_t *cb = (pmix_job_data_caddy_t*)cbdata; - pmix_rank_t rank; - pmix_kval_t *kv = NULL; - bool flag = true; - - if (NULL == cb->bufs) { - rc = PMIX_ERR_BAD_PARAM; - PMIX_ERROR_LOG(rc); - goto exit; - } - kv = PMIX_NEW(pmix_kval_t); - kv->key = strdup("jobinfo"); - PMIX_VALUE_CREATE(kv->value, 1); - kv->value->type = PMIX_BYTE_OBJECT; - - size = pmix_value_array_get_size(cb->bufs); - for (i = 0; i < size; i++) { - tmp = &(PMIX_VALUE_ARRAY_GET_ITEM(cb->bufs, pmix_buffer_t, i)); - rank = 0 == i ? PMIX_RANK_WILDCARD : i - 1; - PMIX_UNLOAD_BUFFER(tmp, kv->value->data.bo.bytes, kv->value->data.bo.size); - if (NULL == kv->value->data.bo.bytes) { - if (flag && !pmix_suppress_missing_data_warning) { - /* this occurs if the host RM did _not_ provide us with - * data for every process in the job, in non-compliance - * with the PMIx standard. Warn the user that their job - * may not scale as desired, and give them a way to turn - * that warning off in case the RM just can't do it */ - pmix_show_help("help-pmix-runtime.txt", "missingdata", true); - /* only show this once */ - flag = false; - } - } else { - if (PMIX_SUCCESS != (rc = cb->dstore_fn(cb->nsptr->nspace, rank, kv))) { - PMIX_ERROR_LOG(rc); - goto exit; - } - } - } - -exit: - if (NULL != kv) { - PMIX_RELEASE(kv); - } - return rc; -} -#endif - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -pmix_status_t pmix_job_data_dstore_store(const char *nspace, pmix_buffer_t *bptr) -{ - pmix_job_data_caddy_t *cd = PMIX_NEW(pmix_job_data_caddy_t); - - cd->job_data = bptr; - cd->dstore_fn = pmix_dstore_store; - - return _job_data_store(nspace, cd); -} -#endif - -pmix_status_t pmix_job_data_htable_store(const char *nspace, pmix_buffer_t *bptr) -{ - pmix_job_data_caddy_t *cb = PMIX_NEW(pmix_job_data_caddy_t); - - cb->job_data = bptr; - cb->hstore_fn = pmix_hash_store; - - return _job_data_store(nspace, cb); -} - -static inline pmix_status_t _job_data_store(const char *nspace, void *cbdata) -{ - pmix_buffer_t *job_data = ((pmix_job_data_caddy_t*)(cbdata))->job_data; - pmix_job_data_caddy_t *cb = (pmix_job_data_caddy_t*)(cbdata); - pmix_status_t rc = PMIX_SUCCESS; - pmix_nspace_t *nsptr = NULL, *nsptr2 = NULL; - pmix_kval_t *kptr, *kp2, kv; - int32_t cnt; - size_t nnodes, len; - uint32_t i; -#if !(defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1)) - uint32_t j; -#endif - pmix_nrec_t *nrec, *nr2; - char **procs = NULL; - uint8_t *tmp; - pmix_byte_object_t *bo; - pmix_buffer_t buf2; - int rank; - char *proc_type_str = PMIX_PROC_SERVER == pmix_globals.proc_type ? - "server" : "client"; - - pmix_output_verbose(10, pmix_globals.debug_output, - "[%s:%d] pmix:%s pmix_jobdata_store %s", - pmix_globals.myid.nspace, pmix_globals.myid.rank, - proc_type_str, nspace); - - /* check buf data */ - if ((NULL == job_data) || (0 == job_data->bytes_used)) { - rc = PMIX_ERR_BAD_PARAM; - PMIX_ERROR_LOG(rc); - return rc; - } - - PMIX_LIST_FOREACH(nsptr2, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strcmp(nsptr2->nspace, nspace)) { - nsptr = nsptr2; - break; - } - } - if (NULL == nsptr) { - /* we don't know this nspace - add it */ - nsptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(nsptr->nspace, nspace, PMIX_MAX_NSLEN); - pmix_list_append(&pmix_globals.nspaces, &nsptr->super); - } - cb->nsptr = nsptr; - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (NULL == (cb->bufs = PMIX_NEW(pmix_value_array_t))) { - rc = PMIX_ERR_OUT_OF_RESOURCE; - PMIX_ERROR_LOG(rc); - goto exit; - } - if (PMIX_SUCCESS != (rc = pmix_value_array_init(cb->bufs, sizeof(pmix_buffer_t)))) { - PMIX_ERROR_LOG(rc); - goto exit; - } -#endif - cnt = 1; - kptr = PMIX_NEW(pmix_kval_t); - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(job_data, kptr, &cnt, PMIX_KVAL))) - { - if (0 == strcmp(kptr->key, PMIX_PROC_BLOB)) { - bo = &(kptr->value->data.bo); - PMIX_CONSTRUCT(&buf2, pmix_buffer_t); - PMIX_LOAD_BUFFER(&buf2, bo->bytes, bo->size); - /* start by unpacking the rank */ - cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(&buf2, &rank, &cnt, PMIX_PROC_RANK))) { - PMIX_ERROR_LOG(rc); - PMIX_DESTRUCT(&buf2); - goto exit; - } - kp2 = PMIX_NEW(pmix_kval_t); - kp2->key = strdup(PMIX_RANK); - PMIX_VALUE_CREATE(kp2->value, 1); - kp2->value->type = PMIX_PROC_RANK; - kp2->value->data.rank = rank; - if (PMIX_SUCCESS != (rc = _add_key_for_rank(rank, kp2, cb))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(kp2); - PMIX_DESTRUCT(&buf2); - goto exit; - } - PMIX_RELEASE(kp2); // maintain accounting - cnt = 1; - kp2 = PMIX_NEW(pmix_kval_t); - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(&buf2, kp2, &cnt, PMIX_KVAL))) { - /* if the value contains a string that is longer than the - * limit, then compress it */ - if (PMIX_STRING_SIZE_CHECK(kp2->value)) { - if (pmix_util_compress_string(kp2->value->data.string, &tmp, &len)) { - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - rc = PMIX_ERR_NOMEM; - goto exit; - } - kp2->value->type = PMIX_COMPRESSED_STRING; - free(kp2->value->data.string); - kp2->value->data.bo.bytes = (char*)tmp; - kp2->value->data.bo.size = len; - } - } - /* this is data provided by a job-level exchange, so store it - * in the job-level data hash_table */ - if (PMIX_SUCCESS != (rc = _add_key_for_rank(rank, kp2, cb))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(kp2); - PMIX_DESTRUCT(&buf2); - goto exit; - } - PMIX_RELEASE(kp2); // maintain accounting - kp2 = PMIX_NEW(pmix_kval_t); - } - /* cleanup */ - PMIX_DESTRUCT(&buf2); // releases the original kptr data - PMIX_RELEASE(kp2); - } else if (0 == strcmp(kptr->key, PMIX_MAP_BLOB)) { - /* transfer the byte object for unpacking */ - bo = &(kptr->value->data.bo); - PMIX_CONSTRUCT(&buf2, pmix_buffer_t); - PMIX_LOAD_BUFFER(&buf2, bo->bytes, bo->size); - /* start by unpacking the number of nodes */ - cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(&buf2, &nnodes, &cnt, PMIX_SIZE))) { - PMIX_ERROR_LOG(rc); - PMIX_DESTRUCT(&buf2); - goto exit; - } - /* unpack the list of procs on each node */ - for (i=0; i < nnodes; i++) { - cnt = 1; - PMIX_CONSTRUCT(&kv, pmix_kval_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(&buf2, &kv, &cnt, PMIX_KVAL))) { - PMIX_ERROR_LOG(rc); - PMIX_DESTRUCT(&buf2); - PMIX_DESTRUCT(&kv); - goto exit; - } - /* the name of the node is in the key, and the value is - * a comma-delimited list of procs on that node. See if we already - * have this node */ - nrec = NULL; - PMIX_LIST_FOREACH(nr2, &nsptr->nodes, pmix_nrec_t) { - if (0 == strcmp(nr2->name, kv.key)) { - nrec = nr2; - break; - } - } - if (NULL == nrec) { - /* Create a node record and store that list */ - nrec = PMIX_NEW(pmix_nrec_t); - if (NULL == nrec) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - PMIX_DESTRUCT(&buf2); - PMIX_DESTRUCT(&kv); - goto exit; - } - nrec->name = strdup(kv.key); - pmix_list_append(&nsptr->nodes, &nrec->super); - } else { - /* refresh the list */ - if (NULL != nrec->procs) { - free(nrec->procs); - } - } - nrec->procs = strdup(kv.value->data.string); - /* split the list of procs so we can store their - * individual location data */ -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (PMIX_SUCCESS != (rc = _add_key_for_rank(PMIX_RANK_WILDCARD, &kv, cb))) { - PMIX_ERROR_LOG(rc); - PMIX_DESTRUCT(&kv); - PMIX_DESTRUCT(&buf2); - pmix_argv_free(procs); - goto exit; - } -#else - procs = pmix_argv_split(nrec->procs, ','); - for (j=0; NULL != procs[j]; j++) { - /* store the hostname for each proc - again, this is - * data obtained via a job-level exchange, so store it - * in the job-level data hash_table */ - kp2 = PMIX_NEW(pmix_kval_t); - kp2->key = strdup(PMIX_HOSTNAME); - kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); - kp2->value->type = PMIX_STRING; - kp2->value->data.string = strdup(nrec->name); - rank = strtol(procs[j], NULL, 10); - if (PMIX_SUCCESS != (rc = _add_key_for_rank(rank, kp2, cb))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(kp2); - PMIX_DESTRUCT(&kv); - PMIX_DESTRUCT(&buf2); - pmix_argv_free(procs); - goto exit; - } - PMIX_RELEASE(kp2); - } - pmix_argv_free(procs); -#endif - PMIX_DESTRUCT(&kv); - } - /* cleanup */ - PMIX_DESTRUCT(&buf2); - } else { - /* if the value contains a string that is longer than the - * limit, then compress it */ - if (PMIX_STRING_SIZE_CHECK(kptr->value)) { - if (pmix_util_compress_string(kptr->value->data.string, &tmp, &len)) { - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - rc = PMIX_ERR_NOMEM; - goto exit; - } - kptr->value->type = PMIX_COMPRESSED_STRING; - free(kptr->value->data.string); - kptr->value->data.bo.bytes = (char*)tmp; - kptr->value->data.bo.size = len; - } - } - if (PMIX_SUCCESS != (rc = _add_key_for_rank(PMIX_RANK_WILDCARD, kptr, cb))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(kptr); - goto exit; - } - } - PMIX_RELEASE(kptr); - kptr = PMIX_NEW(pmix_kval_t); - cnt = 1; - } - /* need to release the leftover kptr */ - PMIX_RELEASE(kptr); - - if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { - PMIX_ERROR_LOG(rc); - goto exit; - } - rc = PMIX_SUCCESS; - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (NULL != cb->dstore_fn) { - if (PMIX_SUCCESS != (rc = _rank_key_dstore_store(cbdata))) { - PMIX_ERROR_LOG(rc); - goto exit; - } - } -#endif -exit: -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (NULL != cb->bufs) { - size_t size = pmix_value_array_get_size(cb->bufs); - size_t i; - for (i = 0; i < size; i++) { - pmix_buffer_t *tmp = &(PMIX_VALUE_ARRAY_GET_ITEM(cb->bufs, pmix_buffer_t, i)); - PMIX_DESTRUCT(tmp); - } - PMIX_RELEASE(cb->bufs); - } -#endif - PMIX_RELEASE(cb); - - /* reset buf unpack ptr */ - job_data->unpack_ptr = job_data->base_ptr; - - return rc; -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_log.c b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_log.c index 92ea30189e..85eae9492e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_log.c +++ b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_log.c @@ -25,7 +25,7 @@ #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/mca/ptl/ptl.h" #include "src/client/pmix_client_ops.h" @@ -42,7 +42,8 @@ static void log_cbfunc(struct pmix_peer_t *peer, /* unpack the return status */ m=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &status, &m, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &status, &m, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { status = rc; } @@ -91,7 +92,7 @@ PMIX_EXPORT pmix_status_t PMIx_Log_nb(const pmix_info_t data[], size_t ndata, return PMIX_ERR_NOT_SUPPORTED; } pmix_output_verbose(2, pmix_globals.debug_output, - "pmix:query handed to RM"); + "pmix:log handed to RM"); pmix_host_server.log(&pmix_globals.myid, data, ndata, directives, ndirs, cbfunc, cbdata); @@ -102,32 +103,42 @@ PMIX_EXPORT pmix_status_t PMIx_Log_nb(const pmix_info_t data[], size_t ndata, cd->cbfunc.opcbfn = cbfunc; cd->cbdata = cbdata; msg = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); PMIX_RELEASE(cd); return rc; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ndata, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ndata, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); PMIX_RELEASE(cd); return rc; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, data, ndata, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, data, ndata, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); PMIX_RELEASE(cd); return rc; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ndirs, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ndirs, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); PMIX_RELEASE(cd); return rc; } if (0 < ndirs) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, data, ndata, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, directives, ndirs, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); PMIX_RELEASE(cd); @@ -136,8 +147,11 @@ PMIX_EXPORT pmix_status_t PMIx_Log_nb(const pmix_info_t data[], size_t ndata, } pmix_output_verbose(2, pmix_globals.debug_output, - "pmix:query sending to server"); - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, log_cbfunc, (void*)cd))){ + "pmix:log sending to server"); + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, log_cbfunc, (void*)cd); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); PMIX_RELEASE(cd); } } diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_query.c b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_query.c index 5eec3f79c7..2e6d1b1d2a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_query.c +++ b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_query.c @@ -1,6 +1,6 @@ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* - * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. * All rights reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. @@ -25,7 +25,7 @@ #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/mca/ptl/ptl.h" #include "src/client/pmix_client_ops.h" @@ -60,7 +60,8 @@ static void query_cbfunc(struct pmix_peer_t *peer, /* unpack the status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &results->status, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &results->status, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto complete; } @@ -70,14 +71,16 @@ static void query_cbfunc(struct pmix_peer_t *peer, /* unpack any returned data */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &results->ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &results->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto complete; } if (0 < results->ninfo) { PMIX_INFO_CREATE(results->info, results->ninfo); cnt = results->ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, results->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, results->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto complete; } @@ -142,19 +145,25 @@ PMIX_EXPORT pmix_status_t PMIx_Query_info_nb(pmix_query_t queries[], size_t nque cd->cbfunc = cbfunc; cd->cbdata = cbdata; msg = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); PMIX_RELEASE(cd); return rc; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &nqueries, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &nqueries, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); PMIX_RELEASE(cd); return rc; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, queries, nqueries, PMIX_QUERY))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, queries, nqueries, PMIX_QUERY); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); PMIX_RELEASE(cd); @@ -162,7 +171,9 @@ PMIX_EXPORT pmix_status_t PMIx_Query_info_nb(pmix_query_t queries[], size_t nque } pmix_output_verbose(2, pmix_globals.debug_output, "pmix:query sending to server"); - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, query_cbfunc, (void*)cd))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, query_cbfunc, (void*)cd); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(cd); } } @@ -210,27 +221,35 @@ PMIX_EXPORT pmix_status_t PMIx_Allocation_request_nb(pmix_alloc_directive_t dire msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the directive */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &directive, 1, PMIX_ALLOC_DIRECTIVE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &directive, 1, PMIX_ALLOC_DIRECTIVE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the info */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -245,7 +264,9 @@ PMIX_EXPORT pmix_status_t PMIx_Allocation_request_nb(pmix_alloc_directive_t dire cb->cbdata = cbdata; /* push the message into our event base to send to the server */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, query_cbfunc, (void*)cb))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, query_cbfunc, (void*)cb); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); PMIX_RELEASE(cb); } diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_strings.c b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_strings.c index 301c980620..98e6609d8d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_strings.c +++ b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_strings.c @@ -34,7 +34,6 @@ #include #include -#include "src/buffer_ops/internal.h" #include "src/include/pmix_globals.h" PMIX_EXPORT const char* PMIx_Proc_state_string(pmix_proc_state_t state) @@ -98,6 +97,8 @@ PMIX_EXPORT const char* PMIx_Scope_string(pmix_scope_t scope) return "SHARE ON REMOTE NODES ONLY"; case PMIX_GLOBAL: return "SHARE ACROSS ALL NODES"; + case PMIX_INTERNAL: + return "STORE INTERNALLY"; default: return "UNKNOWN SCOPE"; } @@ -209,16 +210,3 @@ PMIX_EXPORT const char* pmix_command_string(pmix_cmd_t cmd) return "UNKNOWN"; } } - -PMIX_EXPORT const char* PMIx_Data_type_string(pmix_data_type_t type) -{ - pmix_bfrop_type_info_t *info; - - if (NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&pmix_bfrop_types, type))) { - return "UNKNOWN"; - } - if (NULL == info->odti_name) { - return "UNKNOWN"; - } - return info->odti_name; -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/dstore/Makefile.include deleted file mode 100644 index a317230d07..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/Makefile.include +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2015-2016 Mellanox Technologies, Inc. -# All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ - - -headers += \ - dstore/pmix_dstore.h \ - dstore/pmix_esh.h - -sources += \ - dstore/pmix_dstore.c \ - dstore/pmix_esh.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.c b/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.c deleted file mode 100644 index 1c0af9c947..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016 Mellanox Technologies, Inc. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#include -#include -#include "src/include/pmix_globals.h" - -#include "pmix_dstore.h" -#include "pmix_esh.h" - - -/* - * Array of all possible DSTOREs - */ - -/**** ENSURE THE FOLLOWING VALUE IS AT LEAST AS - **** LARGE AS THE TOTAL NUMBER OF SUPPORTED SPCs - **** IN THE ARRAY BELOW - */ - -static pmix_dstore_base_module_t *all[] = { - &pmix_dstore_esh_module, - - /* Always end the array with a NULL */ - NULL -}; - -pmix_dstore_base_module_t pmix_dstore = {0}; - -int pmix_dstore_init(pmix_info_t info[], size_t ninfo) -{ - pmix_dstore = *all[0]; - - if (!pmix_dstore.init) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_dstore.init(info, ninfo); -} - -void pmix_dstore_finalize(void) -{ - if (!pmix_dstore.finalize) { - return ; - } - - pmix_dstore.finalize(); - - return ; -} - -int pmix_dstore_store(const char *nspace, pmix_rank_t rank, pmix_kval_t *kv) -{ - if (!pmix_dstore.store) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_dstore.store(nspace, rank, kv); -} - -int pmix_dstore_fetch(const char *nspace, pmix_rank_t rank, - const char *key, pmix_value_t **kvs) -{ - if (!pmix_dstore.fetch) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_dstore.fetch(nspace, rank, key, kvs); -} - -int pmix_dstore_patch_env(const char *nspace, char ***env) -{ - if (!pmix_dstore.patch_env) { - return PMIX_ERR_NOT_SUPPORTED; - } - return pmix_dstore.patch_env(nspace, env); -} - -int pmix_dstore_nspace_add(const char *nspace, pmix_info_t info[], size_t ninfo) -{ - if (!pmix_dstore.nspace_add) { - return PMIX_ERR_NOT_SUPPORTED; - } - return pmix_dstore.nspace_add(nspace, info, ninfo); -} - -int pmix_dstore_nspace_del(const char *nspace) -{ - if (!pmix_dstore.nspace_del) { - return PMIX_ERR_NOT_SUPPORTED; - } - return pmix_dstore.nspace_del(nspace); -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.h b/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.h deleted file mode 100644 index 5ec75a6b92..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016 Mellanox Technologies, Inc. - * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#ifndef PMIX_DSTORE_H -#define PMIX_DSTORE_H - -#include - - -#include -#include "src/buffer_ops/buffer_ops.h" - - -BEGIN_C_DECLS - - -int pmix_dstore_init(pmix_info_t info[], size_t ninfo); -void pmix_dstore_finalize(void); -int pmix_dstore_store(const char *nspace, pmix_rank_t rank, pmix_kval_t *kv); - -/* - * Return codes: - * - PMIX_ERR_BAD_PARAM - bad parameters - can't proceed. - * - PMIX_ERR_FATAL - fatal error - * - PMIX_ERR_NOT_FOUND - we have the BLOB for the process but the - * requested key wasn't found there - * - PMIX_ERR_PROC_ENTRY_NOT_FOUND - the BLOB for the process wasn't - * found - need to request it from the server. - */ -int pmix_dstore_fetch(const char *nspace, pmix_rank_t rank, - const char *key, pmix_value_t **kvs); -int pmix_dstore_patch_env(const char *nspace, char ***env); -int pmix_dstore_nspace_add(const char *nspace, pmix_info_t info[], size_t ninfo); -int pmix_dstore_nspace_del(const char *nspace); - -/** - * Initialize the module. Returns an error if the module cannot - * run, success if it can and wants to be used. - */ -typedef int (*pmix_dstore_base_module_init_fn_t)(pmix_info_t info[], size_t ninfo); - -/** - * Finalize the module. Tear down any allocated storage, disconnect - * from any system support. - */ -typedef int (*pmix_dstore_base_module_fini_fn_t)(void); - -/** -* store key/value pair in datastore. -* -* @param nspace namespace string -* -* @param rank rank. -* -* @param kv key/value pair. -* -* @return PMIX_SUCCESS on success. -*/ -typedef int (*pmix_dstore_base_module_store_fn_t)(const char *nspace, - pmix_rank_t rank, - pmix_kval_t *kv); - -/** -* fetch value in datastore. -* -* @param nspace namespace string -* -* @param rank rank. -* -* @param key key. -* -* @return kvs(key/value pair) and PMIX_SUCCESS on success. -*/ -typedef int (*pmix_dstore_base_module_fetch_fn_t)(const char *nspace, - pmix_rank_t rank, - const char *key, - pmix_value_t **kvs); - -/** -* get base dstore path. -* -* @param nspace namespace string -* -* @param rank rank. -* -* @return PMIX_SUCCESS on success. -*/ -typedef int (*pmix_dstore_base_module_proc_patch_env_fn_t)(const char *nspace, char ***env); - -/** -* get base dstore path. -* -* @param nspace namespace string -* -* @param rank rank. -* -* @return PMIX_SUCCESS on success. -*/ -typedef int (*pmix_dstore_base_module_add_nspace_fn_t)(const char *nspace, - pmix_info_t info[], - size_t ninfo); - -/** -* finalize nspace. -* -* @param nspace namespace string -* -* @return PMIX_SUCCESS on success. -*/ -typedef int (*pmix_dstore_base_module_del_nspace_fn_t)(const char *nspace); - -/** -* structure for dstore modules -*/ -typedef struct { - const char *name; - pmix_dstore_base_module_init_fn_t init; - pmix_dstore_base_module_fini_fn_t finalize; - pmix_dstore_base_module_store_fn_t store; - pmix_dstore_base_module_fetch_fn_t fetch; - pmix_dstore_base_module_proc_patch_env_fn_t patch_env; - pmix_dstore_base_module_add_nspace_fn_t nspace_add; - pmix_dstore_base_module_del_nspace_fn_t nspace_del; - -} pmix_dstore_base_module_t; - -END_C_DECLS - -#endif /* PMIX_DSTORE_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.include index 2f970896a4..78ceaa4e30 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.include @@ -1,6 +1,6 @@ # -*- makefile -*- # -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h index 715289f503..3e45197a41 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h +++ b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h @@ -147,9 +147,9 @@ void pmix_event_timeout_cb(int fd, short flags, void *arg); ch->status = (e); \ ch->range = (r); \ (void)strncpy(ch->source.nspace, \ - (p)->info->nptr->nspace, \ + (p)->nptr->nspace, \ PMIX_MAX_NSLEN); \ - ch->source.rank = (p)->info->rank; \ + ch->source.rank = (p)->info->pname.rank; \ ch->ninfo = 2; \ ch->final_cbfunc = (f); \ ch->final_cbdata = ch; \ @@ -169,8 +169,8 @@ void pmix_event_timeout_cb(int fd, short flags, void *arg); pmix_event_add(&ch->ev, &pmix_globals.event_window); \ } else { \ /* add this peer to the array of sources */ \ - (void)strncpy(proc.nspace, (p)->info->nptr->nspace, PMIX_MAX_NSLEN); \ - proc.rank = (p)->info->rank; \ + (void)strncpy(proc.nspace, (p)->nptr->nspace, PMIX_MAX_NSLEN); \ + proc.rank = (p)->info->pname.rank; \ ninfo = ch->ninfo + 1; \ PMIX_INFO_CREATE(info, ninfo); \ /* must keep the hdlr name and return object at the end, so prepend */ \ diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_notification.c b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_notification.c index 27b1ed7826..7f55460fae 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_notification.c +++ b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_notification.c @@ -22,6 +22,7 @@ #include "src/util/error.h" #include "src/util/output.h" +#include "src/mca/bfrops/bfrops.h" #include "src/client/pmix_client_ops.h" #include "src/server/pmix_server_ops.h" #include "src/include/pmix_globals.h" @@ -88,13 +89,14 @@ static void notify_event_cbfunc(struct pmix_peer_t *pr, pmix_ptl_hdr_t *hdr, pmix_cb_t *cb = (pmix_cb_t*)cbdata; /* unpack the status */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ret, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pr, buf, &ret, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); ret = rc; } /* do the cback */ - if (NULL != cb->op_cbfunc) { - cb->op_cbfunc(ret, cb->cbdata); + if (NULL != cb->cbfunc.opfn) { + cb->cbfunc.opfn(ret, cb->cbdata); } PMIX_RELEASE(cb); } @@ -124,29 +126,34 @@ static pmix_status_t notify_server_of_event(pmix_status_t status, msg = PMIX_NEW(pmix_buffer_t); /* pack the command */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } /* pack the status */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &status, 1, PMIX_STATUS))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, &status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } /* no need to pack the source as it is us */ /* pack the range */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &range, 1, PMIX_DATA_RANGE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, &range, 1, PMIX_DATA_RANGE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } /* pack the info */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } if (0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } @@ -231,13 +238,14 @@ static pmix_status_t notify_server_of_event(pmix_status_t status, * server will _not_ send this notification back to us, * so we handle it locally */ cb = PMIX_NEW(pmix_cb_t); - cb->op_cbfunc = cbfunc; + cb->cbfunc.opfn = cbfunc; cb->cbdata = cbdata; /* send to the server */ pmix_output_verbose(2, pmix_globals.debug_output, "client: notifying server %s:%d - sending", pmix_globals.myid.nspace, pmix_globals.myid.rank); - rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, notify_event_cbfunc, cb); + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, + msg, notify_event_cbfunc, cb); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(cb); @@ -721,6 +729,7 @@ void pmix_invoke_local_event_hdlr(pmix_event_chain_t *chain) } /* if we got here, then nothing was found */ + complete: /* we still have to call their final callback */ if (NULL != chain->final_cbfunc) { @@ -783,12 +792,15 @@ static void _notify_client_event(int sd, short args, void *cbdata) pmix_event_chain_t *chain; size_t n; bool matched, holdcd; + pmix_buffer_t *bfr; + pmix_cmd_t cmd = PMIX_NOTIFY_CMD; + pmix_status_t rc; /* need to acquire the object from its originating thread */ PMIX_ACQUIRE_OBJECT(cd); pmix_output_verbose(2, pmix_globals.debug_output, - "pmix_server: _notify_error notifying clients of error %s", + "pmix_server: _notify_client_event notifying clients of event %s", PMIx_Error_string(cd->status)); /* we cannot know if everyone who wants this notice has had a chance @@ -814,19 +826,19 @@ static void _notify_client_event(int sd, short args, void *cbdata) /* if this client was the source of the event, then * don't send it back as they will have processed it * when they generated it */ - if (0 == strncmp(cd->source.nspace, pr->peer->info->nptr->nspace, PMIX_MAX_NSLEN) && - cd->source.rank == pr->peer->info->rank) { + if (0 == strncmp(cd->source.nspace, pr->peer->info->pname.nspace, PMIX_MAX_NSLEN) && + cd->source.rank == pr->peer->info->pname.rank) { continue; } /* if we were given specific targets, check if this is one */ if (NULL != cd->targets) { matched = false; for (n=0; n < cd->ntargets; n++) { - if (0 != strncmp(pr->peer->info->nptr->nspace, cd->targets[n].nspace, PMIX_MAX_NSLEN)) { + if (0 != strncmp(pr->peer->info->pname.nspace, cd->targets[n].nspace, PMIX_MAX_NSLEN)) { continue; } if (PMIX_RANK_WILDCARD == cd->targets[n].rank || - pr->peer->info->rank == cd->targets[n].rank) { + pr->peer->info->pname.rank == cd->targets[n].rank) { matched = true; break; } @@ -837,10 +849,53 @@ static void _notify_client_event(int sd, short args, void *cbdata) } } pmix_output_verbose(2, pmix_globals.debug_output, - "pmix_server: notifying client %s:%d", - pr->peer->info->nptr->nspace, pr->peer->info->rank); - PMIX_RETAIN(cd->buf); - PMIX_SERVER_QUEUE_REPLY(pr->peer, 0, cd->buf); + "pmix_server: notifying client %s:%u", + pr->peer->info->pname.nspace, pr->peer->info->pname.rank); + bfr = PMIX_NEW(pmix_buffer_t); + if (NULL == bfr) { + continue; + } + /* pack the command */ + PMIX_BFROPS_PACK(rc, pr->peer, bfr, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(bfr); + continue; + } + + /* pack the status */ + PMIX_BFROPS_PACK(rc, pr->peer, bfr, &cd->status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(bfr); + continue; + } + + /* pack the source */ + PMIX_BFROPS_PACK(rc, pr->peer, bfr, &cd->source, 1, PMIX_PROC); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(bfr); + continue; + } + + /* pack any info */ + PMIX_BFROPS_PACK(rc, pr->peer, bfr, &cd->ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(bfr); + continue; + } + + if (0 < cd->ninfo) { + PMIX_BFROPS_PACK(rc, pr->peer, bfr, cd->info, cd->ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(bfr); + continue; + } + } + PMIX_SERVER_QUEUE_REPLY(pr->peer, 0, bfr); } } } @@ -909,8 +964,6 @@ pmix_status_t pmix_server_notify_client_of_event(pmix_status_t status, pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_notify_caddy_t *cd; - pmix_cmd_t cmd = PMIX_NOTIFY_CMD; - pmix_status_t rc; size_t n; pmix_output_verbose(2, pmix_globals.debug_output, @@ -927,6 +980,8 @@ pmix_status_t pmix_server_notify_client_of_event(pmix_status_t status, cd->source.rank = source->rank; } cd->range = range; + cd->info = info; + cd->ninfo = ninfo; /* check for directives */ if (NULL != info) { @@ -972,42 +1027,6 @@ pmix_status_t pmix_server_notify_client_of_event(pmix_status_t status, } } - /* pack the command */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(cd->buf, &cmd, 1, PMIX_CMD))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(cd); - return rc; - } - - /* pack the status */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(cd->buf, &status, 1, PMIX_STATUS))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(cd); - return rc; - } - - /* pack the source */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(cd->buf, source, 1, PMIX_PROC))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(cd); - return rc; - } - - /* pack any info */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(cd->buf, &ninfo, 1, PMIX_SIZE))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(cd); - return rc; - } - - if (0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(cd->buf, info, ninfo, PMIX_INFO))) { - PMIX_ERROR_LOG(rc); - PMIX_RELEASE(cd); - return rc; - } - } - /* track the eventual callback info */ cd->cbfunc = cbfunc; cd->cbdata = cbdata; diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_registration.c b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_registration.c index 21fcc38130..c5a41689ee 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_registration.c +++ b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_registration.c @@ -23,6 +23,7 @@ #include "src/client/pmix_client_ops.h" #include "src/server/pmix_server_ops.h" #include "src/include/pmix_globals.h" +#include "src/mca/bfrops/bfrops.h" #include "src/event/pmix_event.h" typedef struct { @@ -84,7 +85,8 @@ static void regevents_cbfunc(struct pmix_peer_t *peer, pmix_ptl_hdr_t *hdr, /* unpack the status code */ cnt = 1; - if ((PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ret, &cnt, PMIX_STATUS))) || + PMIX_BFROPS_UNPACK(rc, peer, buf, &ret, &cnt, PMIX_STATUS); + if ((PMIX_SUCCESS != rc) || (PMIX_SUCCESS != ret)) { PMIX_ERROR_LOG(rc); /* remove the err handler and call the error handler reg completion callback fn.*/ @@ -176,36 +178,41 @@ static pmix_status_t _send_to_server(pmix_rshift_caddy_t *rcd) msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* pack the number of codes */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cd->ncodes, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, &cd->ncodes, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } - /* pack any provided codes - may be NULL */ - if (NULL != cd->codes && 0 < cd->ncodes) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, cd->codes, cd->ncodes, PMIX_STATUS))) { + /* pack any provided codes */ + if (0 < cd->ncodes) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, cd->codes, cd->ncodes, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } } /* pack the number of info */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &rcd->ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, &rcd->ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } - /* pack any provided info - may be NULL */ - if (NULL != rcd->info && 0 < rcd->ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, rcd->info, rcd->ninfo, PMIX_INFO))) { + /* pack any provided info */ + if (0 < rcd->ninfo) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, msg, rcd->info, rcd->ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } } - rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, regevents_cbfunc, rcd); + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, msg, regevents_cbfunc, rcd); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); @@ -280,7 +287,10 @@ static pmix_status_t _add_hdlr(pmix_rshift_caddy_t *cd, pmix_list_t *xfer) n=0; PMIX_LIST_FOREACH(ixfer, xfer, pmix_info_caddy_t) { (void)strncpy(cd2->info[n].key, ixfer->info[n].key, PMIX_MAX_KEYLEN); - pmix_value_load(&cd2->info[n].value, &ixfer->info[n].value.data, ixfer->info[n].value.type); + PMIX_BFROPS_VALUE_LOAD(pmix_client_globals.myserver, + &cd2->info[n].value, + &ixfer->info[n].value.data, + ixfer->info[n].value.type); ++n; } } @@ -815,7 +825,9 @@ static void dereg_event_hdlr(int sd, short args, void *cbdata) * to remove my registration */ if (!PMIX_PROC_IS_SERVER) { msg = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); goto cleanup; } @@ -836,7 +848,9 @@ static void dereg_event_hdlr(int sd, short args, void *cbdata) if (NULL == ev->codes) { if (0 == pmix_list_get_size(&pmix_globals.events.default_events)) { /* tell the server to dereg our default handler */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &wildcard, 1, PMIX_STATUS))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &wildcard, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); goto cleanup; } @@ -850,7 +864,9 @@ static void dereg_event_hdlr(int sd, short args, void *cbdata) if (0 == active->nregs) { pmix_list_remove_item(&pmix_globals.events.actives, &active->super); /* tell the server to dereg this code */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &active->code, 1, PMIX_STATUS))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &active->code, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(active); PMIX_RELEASE(msg); goto cleanup; @@ -881,7 +897,9 @@ static void dereg_event_hdlr(int sd, short args, void *cbdata) /* if there are no more default handlers registered, tell * the server to dereg the default handler */ if (0 == pmix_list_get_size(&pmix_globals.events.default_events)) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &wildcard, 1, PMIX_STATUS))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &wildcard, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(msg); goto cleanup; } @@ -904,7 +922,9 @@ static void dereg_event_hdlr(int sd, short args, void *cbdata) pmix_list_remove_item(&pmix_globals.events.actives, &active->super); if (NULL != msg) { /* tell the server to dereg this code */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &active->code, 1, PMIX_STATUS))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &active->code, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(active); PMIX_RELEASE(msg); goto cleanup; @@ -933,7 +953,9 @@ static void dereg_event_hdlr(int sd, short args, void *cbdata) pmix_list_remove_item(&pmix_globals.events.actives, &active->super); if (NULL != msg) { /* tell the server to dereg this code */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &active->code, 1, PMIX_STATUS))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &active->code, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_RELEASE(active); PMIX_RELEASE(msg); goto cleanup; @@ -958,7 +980,7 @@ static void dereg_event_hdlr(int sd, short args, void *cbdata) report: if (NULL != msg) { /* send to the server */ - rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, NULL, NULL); + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, msg, NULL, NULL); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); } diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/include/Makefile.include index af34f84b4d..b66386e861 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/include/Makefile.include @@ -10,7 +10,7 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2007-2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # @@ -37,8 +37,7 @@ headers += \ include/prefetch.h \ include/types.h \ include/pmix_config_top.h \ - include/pmix_config_bottom.h \ - include/pmix_jobdata.h + include/pmix_config_bottom.h endif ! PMIX_EMBEDDED_MODE diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/align.h b/opal/mca/pmix/pmix2x/pmix/src/include/align.h index e55c303603..77658918f0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/align.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/align.h @@ -12,6 +12,7 @@ * Copyright (c) 2006 Voltaire All rights reserved. * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. * + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/hash_string.h b/opal/mca/pmix/pmix2x/pmix/src/include/hash_string.h index a079f793ca..a3ba48e1f2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/hash_string.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/hash_string.h @@ -2,6 +2,7 @@ * Copyright (c) 2004-2007 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_bottom.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_bottom.h index ecf6d03feb..3f8a91a38d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_bottom.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_bottom.h @@ -13,7 +13,7 @@ * Copyright (c) 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2013 Mellanox Technologies, Inc. * All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. * $COPYRIGHT$ * diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_top.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_top.h index 725a6c7c36..d157391077 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_top.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_top.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2011 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2013-2015 Intel, Inc. All rights reserved + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. * $COPYRIGHT$ * diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c index 85882d3e2f..5044e8e4eb 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c @@ -37,7 +37,7 @@ #include #include PMIX_EVENT_HEADER -#include "src/buffer_ops/types.h" +#include "src/mca/bfrops/bfrops_types.h" #include "src/class/pmix_hash_table.h" #include "src/class/pmix_list.h" #include "src/threads/threads.h" @@ -48,49 +48,86 @@ pmix_lock_t pmix_global_lock = { .active = false }; -static void cbcon(pmix_cb_t *p) -{ - PMIX_CONSTRUCT_LOCK(&p->lock); - p->checked = false; - PMIX_CONSTRUCT(&p->data, pmix_buffer_t); - p->cbfunc = NULL; - p->op_cbfunc = NULL; - p->value_cbfunc = NULL; - p->lookup_cbfunc = NULL; - p->spawn_cbfunc = NULL; - p->cbdata = NULL; - memset(p->nspace, 0, PMIX_MAX_NSLEN+1); - p->rank = -1; - p->key = NULL; - p->value = NULL; - p->procs = NULL; - p->info = NULL; - p->ninfo = 0; - p->nvals = 0; -} -static void cbdes(pmix_cb_t *p) -{ - PMIX_DESTRUCT_LOCK(&p->lock); - PMIX_DESTRUCT(&p->data); -} -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_cb_t, +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_namelist_t, pmix_list_item_t, - cbcon, cbdes); + NULL, NULL); + +static void nscon(pmix_nspace_t *p) +{ + p->nspace = NULL; + p->nlocalprocs = 0; + p->all_registered = false; + p->jobinfo = NULL; + p->njobinfo = 0; + p->jobbkt = NULL; + p->ndelivered = 0; + PMIX_CONSTRUCT(&p->ranks, pmix_list_t); + memset(&p->compat, 0, sizeof(p->compat)); +} +static void nsdes(pmix_nspace_t *p) +{ + if (NULL != p->nspace) { + free(p->nspace); + } + if (NULL != p->jobinfo) { + PMIX_INFO_FREE(p->jobinfo, p->njobinfo); + } + if (NULL != p->jobbkt) { + PMIX_RELEASE(p->jobbkt); + } + PMIX_LIST_DESTRUCT(&p->ranks); +} +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_nspace_t, + pmix_list_item_t, + nscon, nsdes); + +static void ncdcon(pmix_nspace_caddy_t *p) +{ + p->ns = NULL; +} +static void ncddes(pmix_nspace_caddy_t *p) +{ + if (NULL != p->ns) { + PMIX_RELEASE(p->ns); + } +} +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_nspace_caddy_t, + pmix_list_item_t, + ncdcon, ncddes); + +static void info_con(pmix_rank_info_t *info) +{ + info->peerid = -1; + info->gid = info->uid = 0; + info->pname.nspace = NULL; + info->pname.rank = PMIX_RANK_UNDEF; + info->modex_recvd = false; + info->proc_cnt = 0; + info->server_object = NULL; +} +static void info_des(pmix_rank_info_t *info) +{ + if (NULL != info->pname.nspace) { + free(info->pname.nspace); + } +} +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_rank_info_t, + pmix_list_item_t, + info_con, info_des); static void pcon(pmix_peer_t *p) { p->finalized = false; p->info = NULL; p->proc_cnt = 0; - p->server_object = NULL; p->index = 0; p->sd = -1; + p->finalized = false; p->send_ev_active = false; p->recv_ev_active = false; PMIX_CONSTRUCT(&p->send_queue, pmix_list_t); p->send_msg = NULL; p->recv_msg = NULL; - memset(&p->compat, 0, sizeof(p->compat)); } static void pdes(pmix_peer_t *p) { @@ -120,120 +157,16 @@ PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_peer_t, pmix_object_t, pcon, pdes); -static void nscon(pmix_nspace_t *p) -{ - memset(p->nspace, 0, PMIX_MAX_NSLEN); - PMIX_CONSTRUCT(&p->nodes, pmix_list_t); - PMIX_CONSTRUCT(&p->internal, pmix_hash_table_t); - pmix_hash_table_init(&p->internal, 16); - PMIX_CONSTRUCT(&p->modex, pmix_hash_table_t); - pmix_hash_table_init(&p->modex, 256); - p->server = NULL; -} -static void nsdes(pmix_nspace_t *p) -{ - uint64_t key; - pmix_object_t *obj; - - PMIX_LIST_DESTRUCT(&p->nodes); - PMIX_HASH_TABLE_FOREACH(key, uint64, obj, &p->internal) { - if (NULL != obj) { - PMIX_RELEASE(obj); - } - } - PMIX_DESTRUCT(&p->internal); - PMIX_HASH_TABLE_FOREACH(key, uint64, obj, &p->modex) { - if (NULL != obj) { - PMIX_RELEASE(obj); - } - } - PMIX_DESTRUCT(&p->modex); - if (NULL != p->server) { - PMIX_RELEASE(p->server); - } -} -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_nspace_t, - pmix_list_item_t, - nscon, nsdes); - -static void ncon(pmix_nrec_t *p) -{ - p->name = NULL; - p->procs = NULL; -} -static void ndes(pmix_nrec_t *p) -{ - if (NULL != p->name) { - free(p->name); - } - if (NULL != p->procs) { - free(p->procs); - } -} -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_nrec_t, - pmix_list_item_t, - ncon, ndes); - -static void sncon(pmix_server_nspace_t *p) -{ - p->nlocalprocs = 0; - p->all_registered = false; - PMIX_CONSTRUCT(&p->job_info, pmix_buffer_t); - PMIX_CONSTRUCT(&p->ranks, pmix_list_t); - PMIX_CONSTRUCT(&p->mylocal, pmix_hash_table_t); - pmix_hash_table_init(&p->mylocal, 16); - PMIX_CONSTRUCT(&p->myremote, pmix_hash_table_t); - pmix_hash_table_init(&p->myremote, 16); - PMIX_CONSTRUCT(&p->remote, pmix_hash_table_t); - pmix_hash_table_init(&p->remote, 256); -} -static void sndes(pmix_server_nspace_t *p) -{ - uint64_t key; - pmix_peer_t * peer; - PMIX_DESTRUCT(&p->job_info); - PMIX_LIST_DESTRUCT(&p->ranks); - PMIX_HASH_TABLE_FOREACH(key, uint64, peer, &p->mylocal) { - PMIX_RELEASE(peer); - } - PMIX_DESTRUCT(&p->mylocal); - PMIX_HASH_TABLE_FOREACH(key, uint64, peer, &p->myremote) { - PMIX_RELEASE(peer); - } - PMIX_DESTRUCT(&p->myremote); - PMIX_DESTRUCT(&p->remote); -} -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_server_nspace_t, - pmix_object_t, - sncon, sndes); - -static void info_con(pmix_rank_info_t *info) -{ - info->gid = info->uid = 0; - info->nptr = NULL; - info->rank = PMIX_RANK_WILDCARD; - info->modex_recvd = false; - info->proc_cnt = 0; - info->server_object = NULL; -} -static void info_des(pmix_rank_info_t *info) -{ - if (NULL!= info->nptr) { - PMIX_RELEASE(info->nptr); - } -} -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_rank_info_t, - pmix_list_item_t, - info_con, info_des); - static void scon(pmix_shift_caddy_t *p) { PMIX_CONSTRUCT_LOCK(&p->lock); p->codes = NULL; p->ncodes = 0; - p->nspace = NULL; + p->pname.nspace = NULL; + p->pname.rank = PMIX_RANK_UNDEF; p->data = NULL; p->ndata = 0; + p->key = NULL; p->info = NULL; p->ninfo = 0; p->directives = NULL; @@ -251,6 +184,9 @@ static void scon(pmix_shift_caddy_t *p) static void scdes(pmix_shift_caddy_t *p) { PMIX_DESTRUCT_LOCK(&p->lock); + if (NULL != p->pname.nspace) { + free(p->pname.nspace); + } if (NULL != p->kv) { PMIX_RELEASE(p->kv); } @@ -259,6 +195,42 @@ PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_shift_caddy_t, pmix_object_t, scon, scdes); +static void cbcon(pmix_cb_t *p) +{ + PMIX_CONSTRUCT_LOCK(&p->lock); + p->checked = false; + PMIX_CONSTRUCT(&p->data, pmix_buffer_t); + p->cbfunc.ptlfn = NULL; + p->cbdata = NULL; + p->pname.nspace = NULL; + p->pname.rank = PMIX_RANK_UNDEF; + p->scope = PMIX_SCOPE_UNDEF; + p->key = NULL; + p->value = NULL; + p->procs = NULL; + p->nprocs = 0; + p->info = NULL; + p->ninfo = 0; + p->nvals = 0; + PMIX_CONSTRUCT(&p->kvs, pmix_list_t); + p->copy = false; + p->timer_running = false; +} +static void cbdes(pmix_cb_t *p) +{ + if (p->timer_running) { + pmix_event_del(&p->ev); + } + if (NULL != p->pname.nspace) { + free(p->pname.nspace); + } + PMIX_DESTRUCT(&p->data); + PMIX_LIST_DESTRUCT(&p->kvs); +} +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_cb_t, + pmix_list_item_t, + cbcon, cbdes); + PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_info_caddy_t, pmix_list_item_t, NULL, NULL); @@ -283,18 +255,3 @@ static void qdes(pmix_query_caddy_t *p) PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_query_caddy_t, pmix_object_t, qcon, qdes); - -static void jdcon(pmix_job_data_caddy_t *p) -{ - p->nsptr = NULL; - p->job_data = NULL; - p->dstore_fn = NULL; - p->hstore_fn = NULL; -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - p->bufs = NULL; -#endif -} - -PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_job_data_caddy_t, - pmix_object_t, - jdcon, NULL); diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h index 5cf9886a5f..7fdb68cd02 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h @@ -33,12 +33,14 @@ #include -#include "src/buffer_ops/types.h" +#include "src/mca/bfrops/bfrops.h" #include "src/class/pmix_hash_table.h" #include "src/class/pmix_list.h" #include "src/class/pmix_ring_buffer.h" #include "src/event/pmix_event.h" #include "src/threads/threads.h" + +#include "src/mca/gds/gds.h" #include "src/mca/psec/psec.h" #include "src/mca/ptl/ptl.h" @@ -49,34 +51,47 @@ BEGIN_C_DECLS #define PMIX_MAX_ERR_CONSTANT INT_MIN -/**** ENUM DEFINITIONS ****/ +/* define an internal-only process name that has + * a dynamically-sized nspace field to save memory */ +typedef struct { + char *nspace; + pmix_rank_t rank; +} pmix_name_t; + +/* define an internal-only object for creating + * lists of names */ +typedef struct { + pmix_list_item_t super; + pmix_name_t *pname; +} pmix_namelist_t; +PMIX_CLASS_DECLARATION(pmix_namelist_t); + /* define a command type for communicating to the * pmix server */ +typedef uint32_t pmix_cmd_t; #define PMIX_CMD PMIX_UINT32 /* define some commands */ -typedef enum { - PMIX_REQ_CMD, - PMIX_ABORT_CMD, - PMIX_COMMIT_CMD, - PMIX_FENCENB_CMD, - PMIX_GETNB_CMD, - PMIX_FINALIZE_CMD, - PMIX_PUBLISHNB_CMD, - PMIX_LOOKUPNB_CMD, - PMIX_UNPUBLISHNB_CMD, - PMIX_SPAWNNB_CMD, - PMIX_CONNECTNB_CMD, - PMIX_DISCONNECTNB_CMD, - PMIX_NOTIFY_CMD, - PMIX_REGEVENTS_CMD, - PMIX_DEREGEVENTS_CMD, - PMIX_QUERY_CMD, - PMIX_LOG_CMD, - PMIX_ALLOC_CMD, - PMIX_JOB_CONTROL_CMD, - PMIX_MONITOR_CMD -} pmix_cmd_t; +#define PMIX_REQ_CMD 0 +#define PMIX_ABORT_CMD 1 +#define PMIX_COMMIT_CMD 2 +#define PMIX_FENCENB_CMD 3 +#define PMIX_GETNB_CMD 4 +#define PMIX_FINALIZE_CMD 5 +#define PMIX_PUBLISHNB_CMD 6 +#define PMIX_LOOKUPNB_CMD 7 +#define PMIX_UNPUBLISHNB_CMD 8 +#define PMIX_SPAWNNB_CMD 9 +#define PMIX_CONNECTNB_CMD 10 +#define PMIX_DISCONNECTNB_CMD 11 +#define PMIX_NOTIFY_CMD 12 +#define PMIX_REGEVENTS_CMD 13 +#define PMIX_DEREGEVENTS_CMD 14 +#define PMIX_QUERY_CMD 15 +#define PMIX_LOG_CMD 16 +#define PMIX_ALLOC_CMD 17 +#define PMIX_JOB_CONTROL_CMD 18 +#define PMIX_MONITOR_CMD 19 /* provide a "pretty-print" function for cmds */ const char* pmix_command_string(pmix_cmd_t cmd); @@ -104,47 +119,52 @@ typedef enum { #define PMIX_PROC_IS_TOOL (PMIX_PROC_TOOL == pmix_globals.proc_type) -/* internally used object for transferring data - * to/from the server and for storing in the - * hash tables */ +/**** PEER STRUCTURES ****/ + +/* clients can only talk to their server, and servers are + * assumed to all have the same personality. Thus, each + * process only needs to track a single set of personality + * modules. All interactions between a client and its local + * server, or between servers, are done thru these modules */ +typedef struct pmix_personality_t { + pmix_bfrop_buffer_type_t type; + pmix_bfrops_module_t *bfrops; + pmix_psec_module_t *psec; + pmix_ptl_module_t *ptl; + pmix_gds_base_module_t *gds; +} pmix_personality_t; + +/* objects used by servers for tracking active nspaces */ typedef struct { pmix_list_item_t super; - char *key; - pmix_value_t *value; -} pmix_kval_t; -PMIX_CLASS_DECLARATION(pmix_kval_t); - -// forward declaration -struct pmix_peer_t; - -/**** PEER STRUCTURES ****/ -/* objects for tracking active nspaces */ -typedef struct { - pmix_object_t super; + char *nspace; size_t nlocalprocs; bool all_registered; // all local ranks have been defined - pmix_buffer_t job_info; // packed copy of the job-level info to be delivered to each proc + pmix_info_t *jobinfo; // copy of the job-level info to be delivered to each proc + size_t njobinfo; + pmix_buffer_t *jobbkt; // packed version of jobinfo + size_t ndelivered; // count of #local clients that have received the jobinfo pmix_list_t ranks; // list of pmix_rank_info_t for connection support of my clients - pmix_hash_table_t mylocal; // hash_table for storing data PUT with local/global scope by my clients - pmix_hash_table_t myremote; // hash_table for storing data PUT with remote/global scope by my clients - pmix_hash_table_t remote; // hash_table for storing data PUT with remote/global scope recvd from remote clients via modex -} pmix_server_nspace_t; -PMIX_CLASS_DECLARATION(pmix_server_nspace_t); - -typedef struct { - pmix_list_item_t super; - char nspace[PMIX_MAX_NSLEN+1]; - pmix_list_t nodes; // list of pmix_nrec_t nodes that house procs in this nspace - pmix_hash_table_t internal; // hash_table for storing job-level/internal data related to this nspace - pmix_hash_table_t modex; // hash_table of received modex data - pmix_server_nspace_t *server; // isolate these so the client doesn't instantiate them + /* all members of an nspace are required to have the + * same personality, but it can differ between nspaces. + * Since servers may support clients from multiple nspaces, + * track their respective compatibility modules here */ + pmix_personality_t compat; } pmix_nspace_t; PMIX_CLASS_DECLARATION(pmix_nspace_t); +/* define a caddy for quickly creating a list of pmix_nspace_t + * objects for local, dedicated purposes */ +typedef struct { + pmix_list_item_t super; + pmix_nspace_t *ns; +} pmix_nspace_caddy_t; +PMIX_CLASS_DECLARATION(pmix_nspace_caddy_t); + typedef struct pmix_rank_info_t { pmix_list_item_t super; - pmix_nspace_t *nptr; - pmix_rank_t rank; + int peerid; // peer object index into the local clients array on the server + pmix_name_t pname; uid_t uid; gid_t gid; bool modex_recvd; @@ -153,13 +173,6 @@ typedef struct pmix_rank_info_t { } pmix_rank_info_t; PMIX_CLASS_DECLARATION(pmix_rank_info_t); -/* define a structure for holding personality pointers - * to plugins for cross-version support */ -typedef struct pmix_personality_t { - pmix_psec_module_t *psec; - pmix_ptl_module_t *ptl; -} pmix_personality_t; - /* object for tracking peers - each peer can have multiple * connections. This can occur if the initial app executes * a fork/exec, and the child initiates its own connection @@ -167,12 +180,12 @@ typedef struct pmix_personality_t { * by the socket, not the process nspace/rank */ typedef struct pmix_peer_t { pmix_object_t super; - bool finalized; + pmix_nspace_t *nptr; // point to the nspace object for this process pmix_rank_info_t *info; int proc_cnt; - void *server_object; - int index; + int index; // index into the local clients array on the server int sd; + bool finalized; // peer has called finalize pmix_event_t send_event; /**< registration with event thread for send events */ bool send_ev_active; pmix_event_t recv_event; /**< registration with event thread for recv events */ @@ -180,33 +193,17 @@ typedef struct pmix_peer_t { pmix_list_t send_queue; /**< list of messages to send */ pmix_ptl_send_t *send_msg; /**< current send in progress */ pmix_ptl_recv_t *recv_msg; /**< current recv in progress */ - pmix_personality_t compat; } pmix_peer_t; PMIX_CLASS_DECLARATION(pmix_peer_t); -typedef struct { - pmix_list_item_t super; - char *name; // name of the node - char *procs; // comma-separated list of proc ranks on that node -} pmix_nrec_t; -PMIX_CLASS_DECLARATION(pmix_nrec_t); - /* define an object for moving a send - * request into the server's event base */ -typedef struct { - pmix_object_t super; - int sd; -} pmix_snd_caddy_t; -PMIX_CLASS_DECLARATION(pmix_snd_caddy_t); - -/* define an object for moving a send - * request into the server's event base */ + * request into the server's event base + * - instanced in pmix_server_ops.c */ typedef struct { pmix_list_item_t super; pmix_ptl_hdr_t hdr; pmix_peer_t *peer; - pmix_snd_caddy_t snd; } pmix_server_caddy_t; PMIX_CLASS_DECLARATION(pmix_server_caddy_t); @@ -228,16 +225,19 @@ typedef struct { } pmix_query_caddy_t; PMIX_CLASS_DECLARATION(pmix_query_caddy_t); -/* define a tracker for collective operations */ +/* define a tracker for collective operations + * - instanced in pmix_server_ops.c */ typedef struct { pmix_list_item_t super; pmix_cmd_t type; + bool hybrid; // true if participating procs are from more than one nspace pmix_proc_t *pcs; // copy of the original array of participants size_t npcs; // number of procs in the array pmix_lock_t lock; // flag for waiting for completion bool def_complete; // all local procs have been registered and the trk definition is complete - pmix_list_t ranks; // list of pmix_rank_info_t of the local participants pmix_list_t local_cbs; // list of pmix_server_caddy_t for sending result to the local participants + // Note: there may be multiple entries for a given proc if that proc + // has fork/exec'd clones that are also participating uint32_t nlocal; // number of local participants uint32_t local_cnt; // number of local participants who have contributed pmix_info_t *info; // array of info structs @@ -248,24 +248,6 @@ typedef struct { } pmix_server_trkr_t; PMIX_CLASS_DECLARATION(pmix_server_trkr_t); -typedef int (*pmix_store_dstor_cbfunc_t)(const char *nsname, - pmix_rank_t rank, pmix_kval_t *kv); -typedef int (*pmix_store_hash_cbfunc_t)(pmix_hash_table_t *table, - pmix_rank_t rank, pmix_kval_t *kv); - -typedef struct { - pmix_object_t super; - pmix_nspace_t *nsptr; - pmix_buffer_t *job_data; - pmix_store_dstor_cbfunc_t dstore_fn; - pmix_store_hash_cbfunc_t hstore_fn; -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - /* array of buffers per rank */ - pmix_value_array_t *bufs; -#endif -} pmix_job_data_caddy_t; -PMIX_CLASS_DECLARATION(pmix_job_data_caddy_t); - /**** THREAD-RELATED ****/ /* define a caddy for thread-shifting operations */ typedef struct { @@ -275,8 +257,7 @@ PMIX_CLASS_DECLARATION(pmix_job_data_caddy_t); pmix_status_t status; pmix_status_t *codes; size_t ncodes; - const char *nspace; - pmix_rank_t rank; + pmix_name_t pname; const char *data; size_t ndata; const char *key; @@ -295,7 +276,7 @@ PMIX_CLASS_DECLARATION(pmix_job_data_caddy_t); pmix_evhdlr_reg_cbfunc_t evregcbfn; pmix_op_cbfunc_t opcbfn; pmix_evhdlr_reg_cbfunc_t errregcbfn; - }cbfunc; + } cbfunc; void *cbdata; size_t ref; } pmix_shift_caddy_t; @@ -311,22 +292,28 @@ typedef struct { pmix_status_t pstatus; pmix_scope_t scope; pmix_buffer_t data; - pmix_ptl_cbfunc_t cbfunc; - pmix_op_cbfunc_t op_cbfunc; - pmix_value_cbfunc_t value_cbfunc; - pmix_lookup_cbfunc_t lookup_cbfunc; - pmix_spawn_cbfunc_t spawn_cbfunc; - pmix_evhdlr_reg_cbfunc_t errreg_cbfunc; + union { + pmix_ptl_cbfunc_t ptlfn; + pmix_op_cbfunc_t opfn; + pmix_value_cbfunc_t valuefn; + pmix_lookup_cbfunc_t lookupfn; + pmix_spawn_cbfunc_t spawnfn; + pmix_evhdlr_reg_cbfunc_t errregfn; + } cbfunc; size_t errhandler_ref; void *cbdata; - char nspace[PMIX_MAX_NSLEN+1]; - pmix_rank_t rank; + pmix_name_t pname; char *key; pmix_value_t *value; + pmix_proc_t *proc; pmix_proc_t *procs; + size_t nprocs; pmix_info_t *info; size_t ninfo; size_t nvals; + pmix_list_t kvs; + bool copy; + bool timer_running; } pmix_cb_t; PMIX_CLASS_DECLARATION(pmix_cb_t); @@ -376,7 +363,7 @@ PMIX_CLASS_DECLARATION(pmix_notify_caddy_t); /**** GLOBAL STORAGE ****/ /* define a global construct that includes values that must be shared - * between various parts of the code library. Both the client + * between various parts of the code library. The client, tool, * and server libraries must instance this structure */ typedef struct { int init_cntr; // #times someone called Init - #times called Finalize @@ -391,12 +378,17 @@ typedef struct { int debug_output; pmix_events_t events; // my event handler registrations. bool connected; - pmix_list_t nspaces; // list of pmix_nspace_t for the nspaces we know about - pmix_buffer_t *cache_local; // data PUT by me to local scope - pmix_buffer_t *cache_remote; // data PUT by me to remote scope + bool commits_pending; struct timeval event_window; pmix_list_t cached_events; // events waiting in the window prior to processing pmix_ring_buffer_t notifications; // ring buffer of pending notifications + /* processes also need a place where they can store + * their own internal data - e.g., data provided by + * the user via the store_internal interface, as well + * as caching their own data obtained thru the "put" + * interface so that other parts of the process can + * look them up */ + pmix_gds_base_module_t *mygds; } pmix_globals_t; diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_jobdata.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_jobdata.h deleted file mode 100644 index f8a61a656f..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_jobdata.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016 Mellanox Technologies, Inc. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#ifndef PMIX_JOBDATA_H -#define PMIX_JOBDATA_H - -#include - -#include "src/buffer_ops/buffer_ops.h" -#include "src/class/pmix_hash_table.h" - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -pmix_status_t pmix_job_data_dstore_store(const char *nspace, pmix_buffer_t *bptr); -#endif -pmix_status_t pmix_job_data_htable_store(const char *nspace, pmix_buffer_t *bptr); - -#endif // PMIX_JOBDATA_H diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_socket_errno.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_socket_errno.h index 2b7ecb506c..aeb9d2e007 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_socket_errno.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_socket_errno.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/mca/Makefile.include index 67f92a9207..fe943ad61f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/Makefile.include @@ -10,7 +10,7 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/base/Makefile.am index 948d687eed..3e27f92ad0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/Makefile.am @@ -10,6 +10,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2010-2016 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h index 0554431d7b..d70dc33e34 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h @@ -15,7 +15,7 @@ * reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-base.txt b/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-base.txt index c0b8251076..c12f28df5a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-base.txt +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-base.txt @@ -11,6 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2008-2014 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-var.txt b/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-var.txt index b306c31ff9..886e73f588 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-var.txt +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-var.txt @@ -13,6 +13,7 @@ # Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2013 Los Alamos National Security, LLC. All rights # reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_close.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_close.c index f42c2f038f..4b028ad536 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_close.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_close.c @@ -13,7 +13,7 @@ * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_compare.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_compare.c index e4c9507069..8f1fed5e56 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_compare.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_compare.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -149,4 +149,3 @@ char * pmix_mca_base_component_to_string(const pmix_mca_base_component_t *a) { } return str; } - diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_find.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_find.c index 981511ee5a..9fb63381be 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_find.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_find.c @@ -16,7 +16,7 @@ * and Technology (RIST). All rights reserved. * Copyright (c) 2014-2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.c index de1c735e64..ccf730e698 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.c @@ -15,7 +15,7 @@ * reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.h b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.h index 38d6f464db..23978bea0b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.h @@ -13,7 +13,7 @@ * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_close.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_close.c index 22d757a0ae..a8ae7b2c56 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_close.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_close.c @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2013-2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_open.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_open.c index 63aa9f1997..dbde228e56 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_open.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_open.c @@ -14,7 +14,7 @@ * Copyright (c) 2011-2015 Los Alamos National Security, LLC. * All rights reserved. * Copyright (c) 2014 Hochschule Esslingen. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_register.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_register.c index fc53b411cd..be73c59116 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_register.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_register.c @@ -13,7 +13,7 @@ * Copyright (c) 2008-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011-2015 Los Alamos National Security, LLC. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_select.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_select.c index b039bf66c2..805305941c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_select.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_select.c @@ -5,7 +5,7 @@ * Corporation. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.c index 3e0ddfa57e..2097a25db2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.c @@ -3,7 +3,7 @@ * Copyright (c) 2012-2015 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.h b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.h index d62c589f40..79d8b0a049 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.h @@ -2,7 +2,7 @@ /* * Copyright (c) 2012-2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_list.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_list.c index 1d5f8b6fcd..b16fde371b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_list.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_list.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_open.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_open.c index 72b387ce1f..3fc024bf4e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_open.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_open.c @@ -13,7 +13,7 @@ * Copyright (c) 2011 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_parse_paramfile.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_parse_paramfile.c index 12785f22d5..4504f48f2c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_parse_paramfile.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_parse_paramfile.c @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2013 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.c index b5bb281b68..ab674cc0f8 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.c @@ -13,7 +13,7 @@ * Copyright (c) 2008-2013 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2012-2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.h b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.h index fbe0bcaee4..bbf93c4831 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.h @@ -13,7 +13,7 @@ * Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2012-2016 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.c index 8cef65e83c..beda836b36 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.c @@ -13,7 +13,7 @@ * Copyright (c) 2008-2013 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2012-2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.h b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.h index bd43c7840a..1be058d05b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.h @@ -13,7 +13,7 @@ * Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2012-2013 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_vari.h b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_vari.h index e2bd97b1e2..8170d6d184 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_vari.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_vari.h @@ -13,7 +13,7 @@ * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2012-2013 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/Makefile.am new file mode 100644 index 0000000000..bce928db11 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/Makefile.am @@ -0,0 +1,44 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_CPPFLAGS = $(LTDLINCL) + +# main library setup +noinst_LTLIBRARIES = libmca_bfrops.la +libmca_bfrops_la_SOURCES = + +# local files +headers = bfrops.h bfrops_types.h +sources = + +# Conditionally install the header files +if WANT_INSTALL_HEADERS +pmixdir = $(pmixincludedir)/$(subdir) +nobase_pmix_HEADERS = $(headers) +endif + +include base/Makefile.include + +libmca_bfrops_la_SOURCES += $(headers) $(sources) + +distclean-local: + rm -f base/static-components.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/Makefile.include new file mode 100644 index 0000000000..4cfa81965d --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/Makefile.include @@ -0,0 +1,37 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from +# src/Makefile.am + +headers += \ + base/base.h + +sources += \ + base/bfrop_base_frame.c \ + base/bfrop_base_fns.c \ + base/bfrop_base_select.c \ + base/bfrop_base_copy.c \ + base/bfrop_base_pack.c \ + base/bfrop_base_print.c \ + base/bfrop_base_unpack.c \ + base/bfrop_base_stubs.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/base.h new file mode 100644 index 0000000000..76bab62c35 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/base.h @@ -0,0 +1,626 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ +#ifndef PMIX_BFROP_BASE_H_ +#define PMIX_BFROP_BASE_H_ + +#include + + +#ifdef HAVE_SYS_TIME_H +#include /* for struct timeval */ +#endif +#ifdef HAVE_STRING_H +#include +#endif + +#include "src/class/pmix_pointer_array.h" +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_framework.h" +#include "src/include/pmix_globals.h" +#include "src/mca/bfrops/bfrops.h" + + + BEGIN_C_DECLS + +/* + * MCA Framework + */ + PMIX_EXPORT extern pmix_mca_base_framework_t pmix_bfrops_base_framework; +/** + * BFROP select function + * + * Cycle across available components and construct the list + * of active modules + */ + PMIX_EXPORT pmix_status_t pmix_bfrop_base_select(void); + +/** + * Track an active component / module + */ +struct pmix_bfrops_base_active_module_t { + pmix_list_item_t super; + pmix_status_t pri; + pmix_bfrops_module_t *module; + pmix_bfrops_base_component_t *component; +}; +typedef struct pmix_bfrops_base_active_module_t pmix_bfrops_base_active_module_t; +PMIX_CLASS_DECLARATION(pmix_bfrops_base_active_module_t); + + +/* framework globals */ +struct pmix_bfrops_globals_t { + pmix_list_t actives; + bool initialized; + size_t initial_size; + size_t threshold_size; + pmix_bfrop_buffer_type_t default_type; +}; +typedef struct pmix_bfrops_globals_t pmix_bfrops_globals_t; + +PMIX_EXPORT extern pmix_bfrops_globals_t pmix_bfrops_globals; + +/* + * The default starting chunk size + */ +#define PMIX_BFROP_DEFAULT_INITIAL_SIZE 128 +/* + * The default threshold size when we switch from doubling the + * buffer size to additively increasing it + */ +#define PMIX_BFROP_DEFAULT_THRESHOLD_SIZE 1024 + +/* + * Internal type corresponding to size_t. Do not use this in + * interface calls - use PMIX_SIZE instead. + */ +#if SIZEOF_SIZE_T == 1 +#define BFROP_TYPE_SIZE_T PMIX_UINT8 +#elif SIZEOF_SIZE_T == 2 +#define BFROP_TYPE_SIZE_T PMIX_UINT16 +#elif SIZEOF_SIZE_T == 4 +#define BFROP_TYPE_SIZE_T PMIX_UINT32 +#elif SIZEOF_SIZE_T == 8 +#define BFROP_TYPE_SIZE_T PMIX_UINT64 +#else +#error Unsupported size_t size! +#endif + +/* + * Internal type corresponding to bool. Do not use this in interface + * calls - use PMIX_BOOL instead. + */ +#if SIZEOF__BOOL == 1 +#define BFROP_TYPE_BOOL PMIX_UINT8 +#elif SIZEOF__BOOL == 2 +#define BFROP_TYPE_BOOL PMIX_UINT16 +#elif SIZEOF__BOOL == 4 +#define BFROP_TYPE_BOOL PMIX_UINT32 +#elif SIZEOF__BOOL == 8 +#define BFROP_TYPE_BOOL PMIX_UINT64 +#else +#error Unsupported bool size! +#endif + +/* + * Internal type corresponding to int and unsigned int. Do not use + * this in interface calls - use PMIX_INT / PMIX_UINT instead. + */ +#if SIZEOF_INT == 1 +#define BFROP_TYPE_INT PMIX_INT8 +#define BFROP_TYPE_UINT PMIX_UINT8 +#elif SIZEOF_INT == 2 +#define BFROP_TYPE_INT PMIX_INT16 +#define BFROP_TYPE_UINT PMIX_UINT16 +#elif SIZEOF_INT == 4 +#define BFROP_TYPE_INT PMIX_INT32 +#define BFROP_TYPE_UINT PMIX_UINT32 +#elif SIZEOF_INT == 8 +#define BFROP_TYPE_INT PMIX_INT64 +#define BFROP_TYPE_UINT PMIX_UINT64 +#else +#error Unsupported INT size! +#endif + +/* + * Internal type corresponding to pid_t. Do not use this in interface + * calls - use PMIX_PID instead. + */ +#if SIZEOF_PID_T == 1 +#define BFROP_TYPE_PID_T PMIX_UINT8 +#elif SIZEOF_PID_T == 2 +#define BFROP_TYPE_PID_T PMIX_UINT16 +#elif SIZEOF_PID_T == 4 +#define BFROP_TYPE_PID_T PMIX_UINT32 +#elif SIZEOF_PID_T == 8 +#define BFROP_TYPE_PID_T PMIX_UINT64 +#else +#error Unsupported pid_t size! +#endif + + +/** + * Internal struct used for holding registered bfrop functions + */ + typedef struct { + pmix_object_t super; + /* type identifier */ + pmix_data_type_t odti_type; + /** Debugging string name */ + char *odti_name; + /** Pack function */ + pmix_bfrop_pack_fn_t odti_pack_fn; + /** Unpack function */ + pmix_bfrop_unpack_fn_t odti_unpack_fn; + /** copy function */ + pmix_bfrop_copy_fn_t odti_copy_fn; + /** prpmix_status_t function */ + pmix_bfrop_print_fn_t odti_print_fn; +} pmix_bfrop_type_info_t; +PMIX_CLASS_DECLARATION(pmix_bfrop_type_info_t); + +/* macro for registering data types - overwrite an existing + * duplicate one based on type name */ +#define PMIX_REGISTER_TYPE(n, t, p, u, c, pr, arr) \ + do { \ + pmix_bfrop_type_info_t *_info; \ + _info = PMIX_NEW(pmix_bfrop_type_info_t); \ + _info->odti_name = strdup((n)); \ + _info->odti_type = (t); \ + _info->odti_pack_fn = (pmix_bfrop_pack_fn_t)(p); \ + _info->odti_unpack_fn = (pmix_bfrop_unpack_fn_t)(u); \ + _info->odti_copy_fn = (pmix_bfrop_copy_fn_t)(c) ; \ + _info->odti_print_fn = (pmix_bfrop_print_fn_t)(pr) ; \ + pmix_pointer_array_set_item((arr), (t), _info); \ +} while (0) + +/* API Stub functions */ +PMIX_EXPORT char* pmix_bfrops_stub_get_available_modules(void); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_assign_module(struct pmix_peer_t *peer, + const char *version); +PMIX_EXPORT pmix_buffer_t* pmix_bfrops_stub_create_buffer(struct pmix_peer_t *pr); +PMIX_EXPORT void pmix_bfrops_construct_buffer(struct pmix_peer_t *pr, + pmix_buffer_t *buf); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_pack(struct pmix_peer_t *peer, + pmix_buffer_t *buffer, + const void *src, + int32_t num_values, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_unpack(struct pmix_peer_t *peer, + pmix_buffer_t *buffer, void *dest, + int32_t *max_num_values, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_copy(struct pmix_peer_t *peer, + void **dest, void *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_print(struct pmix_peer_t *peer, + char **output, char *prefix, + void *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_copy_payload(struct pmix_peer_t *peer, + pmix_buffer_t *dest, + pmix_buffer_t *src); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_value_xfer(struct pmix_peer_t *peer, + pmix_value_t *dest, + pmix_value_t *src); +PMIX_EXPORT void pmix_bfrops_stub_value_load(struct pmix_peer_t *peer, + pmix_value_t *v, void *data, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_value_unload(struct pmix_peer_t *peer, + pmix_value_t *kv, + void **data, size_t *sz); +PMIX_EXPORT pmix_value_cmp_t pmix_bfrops_stub_value_cmp(struct pmix_peer_t *peer, + pmix_value_t *p1, pmix_value_t *p2); +PMIX_EXPORT pmix_status_t pmix_bfrops_stub_register_type(struct pmix_peer_t *peer, + const char *name, pmix_data_type_t type, + pmix_bfrop_pack_fn_t pack, + pmix_bfrop_unpack_fn_t unpack, + pmix_bfrop_copy_fn_t copy, + pmix_bfrop_print_fn_t print); + +/* data type string function */ +PMIX_EXPORT const char* pmix_bfrops_base_data_type_string(pmix_pointer_array_t *regtypes, + pmix_data_type_t type); + +/* + * "Standard" pack functions + */ +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack(pmix_pointer_array_t *regtypes, + pmix_buffer_t *buffer, + const void *src, int num_vals, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_buffer(pmix_pointer_array_t *regtypes, + pmix_buffer_t *buffer, + const void *src, int32_t num_vals, + pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_bool(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_int(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_sizet(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_byte(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_string(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_pid(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_int16(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_int32(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_int64(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_string(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_float(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_double(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_timeval(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_time(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_status(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_buf(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_bo(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_proc(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_value(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_info(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_pdata(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_app(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_kval(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_array(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_modex(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_persist(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_datatype(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_ptr(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_scope(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_range(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_cmd(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_info_directives(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_pstate(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_pinfo(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_darray(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_rank(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_query(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_val(pmix_buffer_t *buffer, + pmix_value_t *p); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_pack_alloc_directive(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type); + +/* +* "Standard" unpack functions +*/ +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack(pmix_pointer_array_t *regtypes, + pmix_buffer_t *buffer, + void *dst, int32_t *num_vals, + pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_bool(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_byte(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_string(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_int(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_sizet(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_pid(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_int16(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_int32(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_datatype(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_int64(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_float(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_double(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_timeval(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_time(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_status(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_val(pmix_buffer_t *buffer, + pmix_value_t *val); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_value(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_info(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_pdata(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_buf(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_proc(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_app(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_kval(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_modex(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_persist(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_bo(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_ptr(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_scope(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_range(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_cmd(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_info_directives(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_datatype(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_pstate(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_pinfo(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_darray(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_rank(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_query(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_alloc_directive(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +/**** DEPRECATED ****/ +PMIX_EXPORT pmix_status_t pmix_bfrops_base_unpack_array(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); + +/* +* "Standard" copy functions +*/ +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy(pmix_pointer_array_t *regtypes, + void **dest, void *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_payload(pmix_buffer_t *dest, + pmix_buffer_t *src); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_std_copy(void **dest, void *src, + pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_string(char **dest, char *src, + pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_value(pmix_value_t **dest, + pmix_value_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_array(pmix_info_array_t **dest, + pmix_info_array_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_proc(pmix_proc_t **dest, + pmix_proc_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_app(pmix_app_t **dest, + pmix_app_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_info(pmix_info_t **dest, + pmix_info_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_buf(pmix_buffer_t **dest, + pmix_buffer_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_kval(pmix_kval_t **dest, + pmix_kval_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_modex(pmix_modex_data_t **dest, + pmix_modex_data_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrop_base_copy_persist(pmix_persistence_t **dest, + pmix_persistence_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_bo(pmix_byte_object_t **dest, + pmix_byte_object_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_pdata(pmix_pdata_t **dest, + pmix_pdata_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_pinfo(pmix_proc_info_t **dest, + pmix_proc_info_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_darray(pmix_data_array_t **dest, + pmix_data_array_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_query(pmix_query_t **dest, + pmix_query_t *src, + pmix_data_type_t type); +/**** DEPRECATED ****/ +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_array(pmix_info_array_t **dest, + pmix_info_array_t *src, + pmix_data_type_t type); + +/* +* "Standard" print functions +*/ +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print(pmix_pointer_array_t *regtypes, + char **output, char *prefix, + void *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_bool(char **output, char *prefix, + bool *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_byte(char **output, char *prefix, + uint8_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_string(char **output, char *prefix, + char *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_size(char **output, char *prefix, + size_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_pid(char **output, char *prefix, + pid_t *src, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_int(char **output, char *prefix, + int *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_int8(char **output, char *prefix, + int8_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_int16(char **output, char *prefix, + int16_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_int32(char **output, char *prefix, + int32_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_int64(char **output, char *prefix, + int64_t *src, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_uint(char **output, char *prefix, + uint *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_uint8(char **output, char *prefix, + uint8_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_uint16(char **output, char *prefix, + uint16_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_uint32(char **output, char *prefix, + uint32_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_uint64(char **output, char *prefix, + uint64_t *src, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_float(char **output, char *prefix, + float *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_double(char **output, char *prefix, + double *src, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_timeval(char **output, char *prefix, + struct timeval *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_time(char **output, char *prefix, + time_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_status(char **output, char *prefix, + pmix_status_t *src, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_value(char **output, char *prefix, + pmix_value_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_array(char **output, char *prefix, + pmix_info_array_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_proc(char **output, char *prefix, + pmix_proc_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_app(char **output, char *prefix, + pmix_app_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_info(char **output, char *prefix, + pmix_info_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_buf(char **output, char *prefix, + pmix_buffer_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_kval(char **output, char *prefix, + pmix_kval_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_modex(char **output, char *prefix, + pmix_modex_data_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_persist(char **output, char *prefix, + pmix_persistence_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_bo(char **output, char *prefix, + pmix_byte_object_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_pdata(char **output, char *prefix, + pmix_pdata_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_ptr(char **output, char *prefix, + void *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_scope(char **output, char *prefix, + pmix_scope_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_range(char **output, char *prefix, + pmix_data_range_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_cmd(char **output, char *prefix, + pmix_cmd_t *src, pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_info_directives(char **output, char *prefix, + pmix_info_directives_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_datatype(char **output, char *prefix, + pmix_data_type_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_pstate(char **output, char *prefix, + pmix_proc_state_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_pinfo(char **output, char *prefix, + pmix_proc_info_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_darray(char **output, char *prefix, + pmix_data_array_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_query(char **output, char *prefix, + pmix_query_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_rank(char **output, char *prefix, + pmix_rank_t *src, + pmix_data_type_t type); +PMIX_EXPORT pmix_status_t pmix_bfrops_base_print_alloc_directive(char **output, char *prefix, + pmix_alloc_directive_t *src, + pmix_data_type_t type); + +/* + * Common helper functions + */ + +PMIX_EXPORT char* pmix_bfrop_buffer_extend(pmix_buffer_t *bptr, size_t bytes_to_add); + +PMIX_EXPORT bool pmix_bfrop_too_small(pmix_buffer_t *buffer, size_t bytes_reqd); + +PMIX_EXPORT pmix_bfrop_type_info_t* pmix_bfrop_find_type(pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrop_store_data_type(pmix_buffer_t *buffer, pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrop_get_data_type(pmix_buffer_t *buffer, pmix_data_type_t *type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_copy_payload(pmix_buffer_t *dest, + pmix_buffer_t *src); + +PMIX_EXPORT void pmix_bfrops_base_value_load(pmix_value_t *v, const void *data, + pmix_data_type_t type); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_value_unload(pmix_value_t *kv, + void **data, + size_t *sz); + +PMIX_EXPORT pmix_status_t pmix_bfrops_base_value_xfer(pmix_value_t *p, + pmix_value_t *src); + +PMIX_EXPORT pmix_value_cmp_t pmix_bfrops_base_value_cmp(pmix_value_t *p, + pmix_value_t *p1); + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_copy.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_copy.c new file mode 100644 index 0000000000..978647f669 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_copy.c @@ -0,0 +1,871 @@ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + + +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/util/output.h" +#include "src/include/pmix_globals.h" + +#include "src/mca/bfrops/base/base.h" + +pmix_status_t pmix_bfrops_base_copy(pmix_pointer_array_t *regtypes, + void **dest, void *src, + pmix_data_type_t type) +{ + pmix_bfrop_type_info_t *info; + + /* check for error */ + if (NULL == dest || NULL == src) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + return PMIX_ERR_BAD_PARAM; + } + + /* Lookup the copy function for this type and call it */ + if (NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(regtypes, type))) { + PMIX_ERROR_LOG(PMIX_ERR_UNKNOWN_DATA_TYPE); + return PMIX_ERR_UNKNOWN_DATA_TYPE; + } + + return info->odti_copy_fn(dest, src, type); +} + +pmix_status_t pmix_bfrops_base_copy_payload(pmix_buffer_t *dest, + pmix_buffer_t *src) +{ + size_t to_copy = 0; + char *ptr; + + /* deal with buffer type */ + if (NULL == dest->base_ptr){ + /* destination buffer is empty - derive src buffer type */ + dest->type = src->type; + } else if (dest->type != src->type) { + /* buffer types mismatch */ + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + return PMIX_ERR_BAD_PARAM; + } + + to_copy = src->pack_ptr - src->unpack_ptr; + if (NULL == (ptr = pmix_bfrop_buffer_extend(dest, to_copy))) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + return PMIX_ERR_OUT_OF_RESOURCE; + } + memcpy(ptr,src->unpack_ptr, to_copy); + dest->bytes_used += to_copy; + dest->pack_ptr += to_copy; + return PMIX_SUCCESS; +} + + +/* + * STANDARD COPY FUNCTION - WORKS FOR EVERYTHING NON-STRUCTURED + */ +pmix_status_t pmix_bfrops_base_std_copy(void **dest, void *src, + pmix_data_type_t type) +{ + size_t datasize; + uint8_t *val = NULL; + + switch(type) { + case PMIX_BOOL: + datasize = sizeof(bool); + break; + + case PMIX_INT: + case PMIX_UINT: + datasize = sizeof(int); + break; + + case PMIX_SIZE: + datasize = sizeof(size_t); + break; + + case PMIX_PID: + datasize = sizeof(pid_t); + break; + + case PMIX_BYTE: + case PMIX_INT8: + case PMIX_UINT8: + datasize = 1; + break; + + case PMIX_INT16: + case PMIX_UINT16: + datasize = 2; + break; + + case PMIX_INT32: + case PMIX_UINT32: + datasize = 4; + break; + + case PMIX_INT64: + case PMIX_UINT64: + datasize = 8; + break; + + case PMIX_FLOAT: + datasize = sizeof(float); + break; + + case PMIX_TIMEVAL: + datasize = sizeof(struct timeval); + break; + + case PMIX_TIME: + datasize = sizeof(time_t); + break; + + case PMIX_STATUS: + datasize = sizeof(pmix_status_t); + break; + + case PMIX_PROC_RANK: + datasize = sizeof(pmix_rank_t); + break; + + case PMIX_PERSIST: + datasize = sizeof(pmix_persistence_t); + break; + + case PMIX_POINTER: + datasize = sizeof(char*); + break; + + case PMIX_SCOPE: + datasize = sizeof(pmix_scope_t); + break; + + case PMIX_DATA_RANGE: + datasize = sizeof(pmix_data_range_t); + break; + + case PMIX_COMMAND: + datasize = sizeof(pmix_cmd_t); + break; + + case PMIX_INFO_DIRECTIVES: + datasize = sizeof(pmix_info_directives_t); + break; + + case PMIX_PROC_STATE: + datasize = sizeof(pmix_proc_state_t); + break; + + case PMIX_ALLOC_DIRECTIVE: + datasize = sizeof(pmix_alloc_directive_t); + break; + + default: + return PMIX_ERR_UNKNOWN_DATA_TYPE; + } + + val = (uint8_t*)malloc(datasize); + if (NULL == val) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + memcpy(val, src, datasize); + *dest = val; + + return PMIX_SUCCESS; +} + +/* COPY FUNCTIONS FOR NON-STANDARD SYSTEM TYPES */ + +/* + * STRING + */ + pmix_status_t pmix_bfrops_base_copy_string(char **dest, char *src, + pmix_data_type_t type) +{ + if (NULL == src) { /* got zero-length string/NULL pointer - store NULL */ + *dest = NULL; + } else { + *dest = strdup(src); + } + + return PMIX_SUCCESS; +} + +/* PMIX_VALUE */ +pmix_status_t pmix_bfrops_base_copy_value(pmix_value_t **dest, + pmix_value_t *src, + pmix_data_type_t type) +{ + pmix_value_t *p; + + /* create the new object */ + *dest = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == *dest) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + p = *dest; + + /* copy the type */ + p->type = src->type; + /* copy the data */ + return pmix_bfrops_base_value_xfer(p, src); +} + +pmix_status_t pmix_bfrops_base_copy_info(pmix_info_t **dest, + pmix_info_t *src, + pmix_data_type_t type) +{ + *dest = (pmix_info_t*)malloc(sizeof(pmix_info_t)); + (void)strncpy((*dest)->key, src->key, PMIX_MAX_KEYLEN); + (*dest)->flags = src->flags; + return pmix_bfrops_base_value_xfer(&(*dest)->value, &src->value); +} + +pmix_status_t pmix_bfrops_base_copy_buf(pmix_buffer_t **dest, + pmix_buffer_t *src, + pmix_data_type_t type) +{ + *dest = PMIX_NEW(pmix_buffer_t); + pmix_bfrops_base_copy_payload(*dest, src); + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_copy_app(pmix_app_t **dest, + pmix_app_t *src, + pmix_data_type_t type) +{ + size_t j; + + *dest = (pmix_app_t*)malloc(sizeof(pmix_app_t)); + (*dest)->cmd = strdup(src->cmd); + (*dest)->argv = pmix_argv_copy(src->argv); + (*dest)->env = pmix_argv_copy(src->env); + if (NULL != src->cwd) { + (*dest)->cwd = strdup(src->cwd); + } + (*dest)->maxprocs = src->maxprocs; + (*dest)->ninfo = src->ninfo; + (*dest)->info = (pmix_info_t*)malloc(src->ninfo * sizeof(pmix_info_t)); + for (j=0; j < src->ninfo; j++) { + (void)strncpy((*dest)->info[j].key, src->info[j].key, PMIX_MAX_KEYLEN); + pmix_value_xfer(&(*dest)->info[j].value, &src->info[j].value); + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_copy_kval(pmix_kval_t **dest, + pmix_kval_t *src, + pmix_data_type_t type) +{ + pmix_kval_t *p; + + /* create the new object */ + *dest = PMIX_NEW(pmix_kval_t); + if (NULL == *dest) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + p = *dest; + + /* copy the type */ + p->value->type = src->value->type; + /* copy the data */ + return pmix_bfrops_base_value_xfer(p->value, src->value); +} + +pmix_status_t pmix_bfrops_base_copy_proc(pmix_proc_t **dest, + pmix_proc_t *src, + pmix_data_type_t type) +{ + *dest = (pmix_proc_t*)malloc(sizeof(pmix_proc_t)); + if (NULL == *dest) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + (void)strncpy((*dest)->nspace, src->nspace, PMIX_MAX_NSLEN); + (*dest)->rank = src->rank; + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_copy_modex(pmix_modex_data_t **dest, + pmix_modex_data_t *src, + pmix_data_type_t type) +{ + *dest = (pmix_modex_data_t*)malloc(sizeof(pmix_modex_data_t)); + if (NULL == *dest) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + (*dest)->blob = NULL; + (*dest)->size = 0; + if (NULL != src->blob) { + (*dest)->blob = (uint8_t*)malloc(src->size * sizeof(uint8_t)); + if (NULL == (*dest)->blob) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + memcpy((*dest)->blob, src->blob, src->size * sizeof(uint8_t)); + (*dest)->size = src->size; + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrop_base_copy_persist(pmix_persistence_t **dest, + pmix_persistence_t *src, + pmix_data_type_t type) +{ + *dest = (pmix_persistence_t*)malloc(sizeof(pmix_persistence_t)); + if (NULL == *dest) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + memcpy(*dest, src, sizeof(pmix_persistence_t)); + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_copy_bo(pmix_byte_object_t **dest, + pmix_byte_object_t *src, + pmix_data_type_t type) +{ + *dest = (pmix_byte_object_t*)malloc(sizeof(pmix_byte_object_t)); + if (NULL == *dest) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + (*dest)->bytes = (char*)malloc(src->size); + memcpy((*dest)->bytes, src->bytes, src->size); + (*dest)->size = src->size; + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_copy_pdata(pmix_pdata_t **dest, + pmix_pdata_t *src, + pmix_data_type_t type) +{ + *dest = (pmix_pdata_t*)malloc(sizeof(pmix_pdata_t)); + (void)strncpy((*dest)->proc.nspace, src->proc.nspace, PMIX_MAX_NSLEN); + (*dest)->proc.rank = src->proc.rank; + (void)strncpy((*dest)->key, src->key, PMIX_MAX_KEYLEN); + return pmix_bfrops_base_value_xfer(&(*dest)->value, &src->value); +} + +pmix_status_t pmix_bfrops_base_copy_pinfo(pmix_proc_info_t **dest, + pmix_proc_info_t *src, + pmix_data_type_t type) +{ + *dest = (pmix_proc_info_t*)malloc(sizeof(pmix_proc_info_t)); + (void)strncpy((*dest)->proc.nspace, src->proc.nspace, PMIX_MAX_NSLEN); + (*dest)->proc.rank = src->proc.rank; + if (NULL != src->hostname) { + (*dest)->hostname = strdup(src->hostname); + } + if (NULL != src->executable_name) { + (*dest)->executable_name = strdup(src->executable_name); + } + (*dest)->pid = src->pid; + (*dest)->exit_code = src->exit_code; + (*dest)->state = src->state; + return PMIX_SUCCESS; +} + +/* the pmix_data_array_t is a little different in that it + * is an array of values, and so we cannot just copy one + * value at a time. So handle all value types here */ +pmix_status_t pmix_bfrops_base_copy_darray(pmix_data_array_t **dest, + pmix_data_array_t *src, + pmix_data_type_t type) +{ + pmix_data_array_t *p; + size_t n, m; + pmix_status_t rc; + char **prarray, **strarray; + pmix_value_t *pv, *sv; + pmix_app_t *pa, *sa; + pmix_info_t *p1, *s1; + pmix_pdata_t *pd, *sd; + pmix_buffer_t *pb, *sb; + pmix_byte_object_t *pbo, *sbo; + pmix_kval_t *pk, *sk; + pmix_modex_data_t *pm, *sm; + pmix_proc_info_t *pi, *si; + pmix_query_t *pq, *sq; + + p = (pmix_data_array_t*)calloc(1, sizeof(pmix_data_array_t)); + if (NULL == p) { + return PMIX_ERR_NOMEM; + } + p->type = src->type; + p->size = src->size; + /* process based on type of array element */ + switch (src->type) { + p->type = src->type; + p->size = src->size; + if (0 == p->size || NULL == src->array) { + p->array = NULL; + p->size = 0; + break; + } + case PMIX_UINT8: + case PMIX_INT8: + case PMIX_BYTE: + p->array = (char*)malloc(src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size); + break; + case PMIX_UINT16: + case PMIX_INT16: + p->array = (char*)malloc(src->size * sizeof(uint16_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(uint16_t)); + break; + case PMIX_UINT32: + case PMIX_INT32: + p->array = (char*)malloc(src->size * sizeof(uint32_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(uint32_t)); + break; + case PMIX_UINT64: + case PMIX_INT64: + p->array = (char*)malloc(src->size * sizeof(uint64_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(uint64_t)); + break; + case PMIX_BOOL: + p->array = (char*)malloc(src->size * sizeof(bool)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(bool)); + break; + case PMIX_SIZE: + p->array = (char*)malloc(src->size * sizeof(size_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(size_t)); + break; + case PMIX_PID: + p->array = (char*)malloc(src->size * sizeof(pid_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pid_t)); + break; + case PMIX_STRING: + p->array = (char**)malloc(src->size * sizeof(char*)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + prarray = (char**)p->array; + strarray = (char**)src->array; + for (n=0; n < src->size; n++) { + if (NULL != strarray[n]) { + prarray[n] = strdup(strarray[n]); + } + } + break; + case PMIX_INT: + case PMIX_UINT: + p->array = (char*)malloc(src->size * sizeof(int)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(int)); + break; + case PMIX_FLOAT: + p->array = (char*)malloc(src->size * sizeof(float)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(float)); + break; + case PMIX_DOUBLE: + p->array = (char*)malloc(src->size * sizeof(double)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(double)); + break; + case PMIX_TIMEVAL: + p->array = (struct timeval*)malloc(src->size * sizeof(struct timeval)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(struct timeval)); + break; + case PMIX_TIME: + p->array = (time_t*)malloc(src->size * sizeof(time_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(time_t)); + break; + case PMIX_STATUS: + p->array = (pmix_status_t*)malloc(src->size * sizeof(pmix_status_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pmix_status_t)); + break; + case PMIX_VALUE: + PMIX_VALUE_CREATE(p->array, src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pv = (pmix_value_t*)p->array; + sv = (pmix_value_t*)src->array; + for (n=0; n < src->size; n++) { + if (PMIX_SUCCESS != (rc = pmix_bfrops_base_value_xfer(&pv[n], &sv[n]))) { + PMIX_VALUE_FREE(pv, src->size); + free(p); + return rc; + } + } + break; + case PMIX_PROC: + PMIX_PROC_CREATE(p->array, src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pmix_proc_t)); + break; + case PMIX_PROC_RANK: + p->array = (char*)malloc(src->size * sizeof(pmix_rank_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pmix_proc_t)); + break; + case PMIX_APP: + PMIX_APP_CREATE(p->array, src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pa = (pmix_app_t*)p->array; + sa = (pmix_app_t*)src->array; + for (n=0; n < src->size; n++) { + if (NULL != sa[n].cmd) { + pa[n].cmd = strdup(sa[n].cmd); + } + if (NULL != sa[n].argv) { + pa[n].argv = pmix_argv_copy(sa[n].argv); + } + if (NULL != sa[n].env) { + pa[n].env = pmix_argv_copy(sa[n].env); + } + if (NULL != sa[n].cwd) { + pa[n].cwd = strdup(sa[n].cwd); + } + pa[n].maxprocs = sa[n].maxprocs; + if (0 < sa[n].ninfo && NULL != sa[n].info) { + PMIX_INFO_CREATE(pa[n].info, sa[n].ninfo); + if (NULL == pa[n].info) { + PMIX_APP_FREE(pa, p->size); + free(p); + return PMIX_ERR_NOMEM; + } + pa[n].ninfo = sa[n].ninfo; + for (m=0; m < pa[n].ninfo; m++) { + PMIX_INFO_XFER(&pa[n].info[m], &sa[n].info[m]); + } + } + } + break; + case PMIX_INFO: + PMIX_INFO_CREATE(p->array, src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + p1 = (pmix_info_t*)p->array; + s1 = (pmix_info_t*)src->array; + for (n=0; n < src->size; n++) { + PMIX_INFO_LOAD(&p1[n], s1[n].key, &s1[n].value.data.flag, s1[n].value.type); + } + break; + case PMIX_PDATA: + PMIX_PDATA_CREATE(p->array, src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pd = (pmix_pdata_t*)p->array; + sd = (pmix_pdata_t*)src->array; + for (n=0; n < src->size; n++) { + PMIX_PDATA_LOAD(&pd[n], &sd[n].proc, sd[n].key, &sd[n].value.data.flag, sd[n].value.type); + } + break; + case PMIX_BUFFER: + p->array = (pmix_buffer_t*)malloc(src->size * sizeof(pmix_buffer_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pb = (pmix_buffer_t*)p->array; + sb = (pmix_buffer_t*)src->array; + for (n=0; n < src->size; n++) { + PMIX_CONSTRUCT(&pb[n], pmix_buffer_t); + pmix_bfrops_base_copy_payload(&pb[n], &sb[n]); + } + break; + case PMIX_BYTE_OBJECT: + case PMIX_COMPRESSED_STRING: + p->array = (pmix_byte_object_t*)malloc(src->size * sizeof(pmix_byte_object_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pbo = (pmix_byte_object_t*)p->array; + sbo = (pmix_byte_object_t*)src->array; + for (n=0; n < src->size; n++) { + if (NULL != sbo[n].bytes && 0 < sbo[n].size) { + pbo[n].size = sbo[n].size; + pbo[n].bytes = (char*)malloc(pbo[n].size); + memcpy(pbo[n].bytes, sbo[n].bytes, pbo[n].size); + } else { + pbo[n].bytes = NULL; + pbo[n].size = 0; + } + } + break; + case PMIX_KVAL: + p->array = (pmix_kval_t*)calloc(src->size , sizeof(pmix_kval_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pk = (pmix_kval_t*)p->array; + sk = (pmix_kval_t*)src->array; + for (n=0; n < src->size; n++) { + if (NULL != sk[n].key) { + pk[n].key = strdup(sk[n].key); + } + if (NULL != sk[n].value) { + PMIX_VALUE_CREATE(pk[n].value, 1); + if (NULL == pk[n].value) { + PMIX_VALUE_FREE(pk[n].value, 1); + free(p); + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (rc = pmix_bfrops_base_value_xfer(pk[n].value, sk[n].value))) { + PMIX_VALUE_FREE(pk[n].value, 1); + free(p); + return rc; + } + } + } + break; + case PMIX_MODEX: + PMIX_MODEX_CREATE(p->array, src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pm = (pmix_modex_data_t*)p->array; + sm = (pmix_modex_data_t*)src->array; + for (n=0; n < src->size; n++) { + memcpy(&pm[n], &sm[n], sizeof(pmix_modex_data_t)); + if (NULL != sm[n].blob && 0 < sm[n].size) { + pm[n].blob = (uint8_t*)malloc(sm[n].size); + if (NULL == pm[n].blob) { + PMIX_MODEX_FREE(pm, src->size); + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(pm[n].blob, sm[n].blob, sm[n].size); + pm[n].size = sm[n].size; + } else { + pm[n].blob = NULL; + pm[n].size = 0; + } + } + break; + case PMIX_PERSIST: + p->array = (pmix_persistence_t*)malloc(src->size * sizeof(pmix_persistence_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pmix_persistence_t)); + break; + case PMIX_POINTER: + p->array = (char**)malloc(src->size * sizeof(char*)); + prarray = (char**)p->array; + strarray = (char**)src->array; + for (n=0; n < src->size; n++) { + prarray[n] = strarray[n]; + } + break; + case PMIX_SCOPE: + p->array = (pmix_scope_t*)malloc(src->size * sizeof(pmix_scope_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pmix_scope_t)); + break; + case PMIX_DATA_RANGE: + p->array = (pmix_data_range_t*)malloc(src->size * sizeof(pmix_data_range_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pmix_data_range_t)); + break; + case PMIX_COMMAND: + p->array = (pmix_cmd_t*)malloc(src->size * sizeof(pmix_cmd_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pmix_cmd_t)); + break; + case PMIX_INFO_DIRECTIVES: + p->array = (pmix_info_directives_t*)malloc(src->size * sizeof(pmix_info_directives_t)); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + memcpy(p->array, src->array, src->size * sizeof(pmix_info_directives_t)); + break; + case PMIX_PROC_INFO: + PMIX_PROC_INFO_CREATE(p->array, src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pi = (pmix_proc_info_t*)p->array; + si = (pmix_proc_info_t*)src->array; + for (n=0; n < src->size; n++) { + memcpy(&pi[n].proc, &si[n].proc, sizeof(pmix_proc_t)); + if (NULL != si[n].hostname) { + pi[n].hostname = strdup(si[n].hostname); + } else { + pi[n].hostname = NULL; + } + if (NULL != si[n].executable_name) { + pi[n].executable_name = strdup(si[n].executable_name); + } else { + pi[n].executable_name = NULL; + } + pi[n].pid = si[n].pid; + pi[n].exit_code = si[n].exit_code; + pi[n].state = si[n].state; + } + break; + case PMIX_DATA_ARRAY: + free(p); + return PMIX_ERR_NOT_SUPPORTED; // don't support iterative arrays + case PMIX_QUERY: + PMIX_QUERY_CREATE(p->array, src->size); + if (NULL == p->array) { + free(p); + return PMIX_ERR_NOMEM; + } + pq = (pmix_query_t*)p->array; + sq = (pmix_query_t*)src->array; + for (n=0; n < src->size; n++) { + if (NULL != sq[n].keys) { + pq[n].keys = pmix_argv_copy(sq[n].keys); + } + if (NULL != sq[n].qualifiers && 0 < sq[n].nqual) { + PMIX_INFO_CREATE(pq[n].qualifiers, sq[n].nqual); + if (NULL == pq[n].qualifiers) { + PMIX_INFO_FREE(pq[n].qualifiers, sq[n].nqual); + free(p); + return PMIX_ERR_NOMEM; + } + for (m=0; m < sq[n].nqual; m++) { + PMIX_INFO_XFER(&pq[n].qualifiers[m], &sq[n].qualifiers[m]); + } + pq[n].nqual = sq[n].nqual; + } else { + pq[n].qualifiers = NULL; + pq[n].nqual = 0; + } + } + break; + default: + free(p); + return PMIX_ERR_UNKNOWN_DATA_TYPE; + } + + (*dest) = p; + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_copy_query(pmix_query_t **dest, + pmix_query_t *src, + pmix_data_type_t type) +{ + pmix_status_t rc; + + *dest = (pmix_query_t*)malloc(sizeof(pmix_query_t)); + if (NULL != src->keys) { + (*dest)->keys = pmix_argv_copy(src->keys); + } + (*dest)->nqual = src->nqual; + if (NULL != src->qualifiers) { + if (PMIX_SUCCESS != (rc = pmix_bfrops_base_copy_info(&((*dest)->qualifiers), src->qualifiers, PMIX_INFO))) { + free(*dest); + return rc; + } + } + return PMIX_SUCCESS; +} + +/**** DEPRECATED ****/ +pmix_status_t pmix_bfrops_base_copy_array(pmix_info_array_t **dest, + pmix_info_array_t *src, + pmix_data_type_t type) +{ + pmix_info_t *d1, *s1; + + *dest = (pmix_info_array_t*)malloc(sizeof(pmix_info_array_t)); + (*dest)->size = src->size; + (*dest)->array = (pmix_info_t*)malloc(src->size * sizeof(pmix_info_t)); + d1 = (pmix_info_t*)(*dest)->array; + s1 = (pmix_info_t*)src->array; + memcpy(d1, s1, src->size * sizeof(pmix_info_t)); + return PMIX_SUCCESS; +} +/*******************/ diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/copy.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_fns.c similarity index 50% rename from opal/mca/pmix/pmix2x/pmix/src/buffer_ops/copy.c rename to opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_fns.c index b65d6944b4..8108b84880 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/copy.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_fns.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2006 The University of Tennessee and The University @@ -9,10 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. - * Copyright (c) 2015 Research Organization for Information Science - * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -23,195 +20,304 @@ #include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + #include "src/util/argv.h" #include "src/util/error.h" -#include "src/util/output.h" -#include "src/buffer_ops/buffer_ops.h" -#include "src/buffer_ops/internal.h" +#include "src/include/pmix_globals.h" - pmix_status_t pmix_bfrop_copy(void **dest, void *src, pmix_data_type_t type) +#include "src/mca/bfrops/base/base.h" + +/* define two public functions */ +PMIX_EXPORT void pmix_value_load(pmix_value_t *v, const void *data, + pmix_data_type_t type) { - pmix_bfrop_type_info_t *info; - - /* check for error */ - if (NULL == dest) { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - return PMIX_ERR_BAD_PARAM; - } - if (NULL == src) { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - return PMIX_ERR_BAD_PARAM; - } - - /* Lookup the copy function for this type and call it */ - - if (NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&pmix_bfrop_types, type))) { - PMIX_ERROR_LOG(PMIX_ERR_UNKNOWN_DATA_TYPE); - return PMIX_ERR_UNKNOWN_DATA_TYPE; - } - - return info->odti_copy_fn(dest, src, type); + pmix_bfrops_base_value_load(v, data, type); } -pmix_status_t pmix_bfrop_copy_payload(pmix_buffer_t *dest, pmix_buffer_t *src) +PMIX_EXPORT pmix_status_t pmix_value_xfer(pmix_value_t *dest, + pmix_value_t *src) { - size_t to_copy = 0; - char *ptr; - /* deal with buffer type */ - if( NULL == dest->base_ptr ){ - /* destination buffer is empty - derive src buffer type */ - dest->type = src->type; - } else if( dest->type != src->type ){ - /* buffer types mismatch */ - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - return PMIX_ERR_BAD_PARAM; - } - - to_copy = src->pack_ptr - src->unpack_ptr; - if( NULL == (ptr = pmix_bfrop_buffer_extend(dest, to_copy)) ){ - PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); - return PMIX_ERR_OUT_OF_RESOURCE; - } - memcpy(ptr,src->unpack_ptr, to_copy); - dest->bytes_used += to_copy; - dest->pack_ptr += to_copy; - return PMIX_SUCCESS; + return pmix_bfrops_base_value_xfer(dest, src); } - -/* - * STANDARD COPY FUNCTION - WORKS FOR EVERYTHING NON-STRUCTURED - */ - pmix_status_t pmix_bfrop_std_copy(void **dest, void *src, pmix_data_type_t type) +void pmix_bfrops_base_value_load(pmix_value_t *v, const void *data, + pmix_data_type_t type) { - size_t datasize; - uint8_t *val = NULL; + pmix_byte_object_t *bo; + pmix_proc_info_t *pi; - switch(type) { - case PMIX_BOOL: - datasize = sizeof(bool); - break; - - case PMIX_INT: - case PMIX_UINT: - datasize = sizeof(int); - break; - - case PMIX_SIZE: - datasize = sizeof(size_t); - break; - - case PMIX_PID: - datasize = sizeof(pid_t); - break; - - case PMIX_BYTE: - case PMIX_INT8: - case PMIX_UINT8: - datasize = 1; - break; - - case PMIX_INT16: - case PMIX_UINT16: - datasize = 2; - break; - - case PMIX_INT32: - case PMIX_UINT32: - datasize = 4; - break; - - case PMIX_INT64: - case PMIX_UINT64: - datasize = 8; - break; - - case PMIX_FLOAT: - datasize = sizeof(float); - break; - - case PMIX_TIMEVAL: - datasize = sizeof(struct timeval); - break; - - case PMIX_TIME: - datasize = sizeof(time_t); - break; - - case PMIX_STATUS: - datasize = sizeof(pmix_status_t); - break; - - case PMIX_PROC_RANK: - datasize = sizeof(pmix_rank_t); - break; - - case PMIX_PERSIST: - datasize = sizeof(pmix_persistence_t); - break; - - case PMIX_POINTER: - datasize = sizeof(char*); - break; - - case PMIX_SCOPE: - datasize = sizeof(pmix_scope_t); - break; - - case PMIX_DATA_RANGE: - datasize = sizeof(pmix_data_range_t); - break; - - case PMIX_COMMAND: - datasize = sizeof(pmix_cmd_t); - break; - - case PMIX_INFO_DIRECTIVES: - datasize = sizeof(pmix_info_directives_t); - break; - - case PMIX_PROC_STATE: - datasize = sizeof(pmix_proc_state_t); - break; - - case PMIX_ALLOC_DIRECTIVE: - datasize = sizeof(pmix_alloc_directive_t); - break; - - default: - return PMIX_ERR_UNKNOWN_DATA_TYPE; - } - - val = (uint8_t*)malloc(datasize); - if (NULL == val) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - - memcpy(val, src, datasize); - *dest = val; - - return PMIX_SUCCESS; -} - -/* COPY FUNCTIONS FOR NON-STANDARD SYSTEM TYPES */ - -/* - * STRING - */ - pmix_status_t pmix_bfrop_copy_string(char **dest, char *src, pmix_data_type_t type) -{ - if (NULL == src) { /* got zero-length string/NULL pointer - store NULL */ - *dest = NULL; + v->type = type; + if (NULL == data) { + /* just set the fields to zero */ + memset(&v->data, 0, sizeof(v->data)); + if (PMIX_BOOL == type) { + v->data.flag = true; // existence of the attribute indicates true unless specified different + } } else { - *dest = strdup(src); + switch(type) { + case PMIX_UNDEF: + break; + case PMIX_BOOL: + memcpy(&(v->data.flag), data, 1); + break; + case PMIX_BYTE: + memcpy(&(v->data.byte), data, 1); + break; + case PMIX_STRING: + v->data.string = strdup(data); + break; + case PMIX_SIZE: + memcpy(&(v->data.size), data, sizeof(size_t)); + break; + case PMIX_PID: + memcpy(&(v->data.pid), data, sizeof(pid_t)); + break; + case PMIX_INT: + memcpy(&(v->data.integer), data, sizeof(int)); + break; + case PMIX_INT8: + memcpy(&(v->data.int8), data, 1); + break; + case PMIX_INT16: + memcpy(&(v->data.int16), data, 2); + break; + case PMIX_INT32: + memcpy(&(v->data.int32), data, 4); + break; + case PMIX_INT64: + memcpy(&(v->data.int64), data, 8); + break; + case PMIX_UINT: + memcpy(&(v->data.uint), data, sizeof(int)); + break; + case PMIX_UINT8: + memcpy(&(v->data.uint8), data, 1); + break; + case PMIX_UINT16: + memcpy(&(v->data.uint16), data, 2); + break; + case PMIX_UINT32: + memcpy(&(v->data.uint32), data, 4); + break; + case PMIX_UINT64: + memcpy(&(v->data.uint64), data, 8); + break; + case PMIX_FLOAT: + memcpy(&(v->data.fval), data, sizeof(float)); + break; + case PMIX_DOUBLE: + memcpy(&(v->data.dval), data, sizeof(double)); + break; + case PMIX_TIMEVAL: + memcpy(&(v->data.tv), data, sizeof(struct timeval)); + break; + case PMIX_TIME: + memcpy(&(v->data.time), data, sizeof(time_t)); + break; + case PMIX_STATUS: + memcpy(&(v->data.status), data, sizeof(pmix_status_t)); + break; + case PMIX_PROC_RANK: + memcpy(&(v->data.rank), data, sizeof(pmix_rank_t)); + break; + case PMIX_PROC: + PMIX_PROC_CREATE(v->data.proc, 1); + if (NULL == v->data.proc) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return; + } + memcpy(v->data.proc, data, sizeof(pmix_proc_t)); + break; + case PMIX_BYTE_OBJECT: + bo = (pmix_byte_object_t*)data; + v->data.bo.bytes = (char*)malloc(bo->size); + if (NULL == v->data.bo.bytes) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return; + } + memcpy(v->data.bo.bytes, bo->bytes, bo->size); + memcpy(&(v->data.bo.size), &bo->size, sizeof(size_t)); + break; + case PMIX_PERSIST: + memcpy(&(v->data.persist), data, sizeof(pmix_persistence_t)); + break; + case PMIX_SCOPE: + memcpy(&(v->data.scope), data, sizeof(pmix_scope_t)); + break; + case PMIX_DATA_RANGE: + memcpy(&(v->data.range), data, sizeof(pmix_data_range_t)); + break; + case PMIX_PROC_STATE: + memcpy(&(v->data.state), data, sizeof(pmix_proc_state_t)); + break; + case PMIX_PROC_INFO: + PMIX_PROC_INFO_CREATE(v->data.pinfo, 1); + if (NULL == v->data.pinfo) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return; + } + pi = (pmix_proc_info_t*)data; + memcpy(&(v->data.pinfo->proc), &pi->proc, sizeof(pmix_proc_t)); + if (NULL != pi->hostname) { + v->data.pinfo->hostname = strdup(pi->hostname); + } + if (NULL != pi->executable_name) { + v->data.pinfo->executable_name = strdup(pi->executable_name); + } + memcpy(&(v->data.pinfo->pid), &pi->pid, sizeof(pid_t)); + memcpy(&(v->data.pinfo->exit_code), &pi->exit_code, sizeof(int)); + break; + case PMIX_POINTER: + memcpy(&(v->data.ptr), data, sizeof(void*)); + break; + default: + /* silence warnings */ + break; + } } - - return PMIX_SUCCESS; + return; } -/* compare function for pmix_value_t */ -bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1) + +pmix_status_t pmix_bfrops_base_value_unload(pmix_value_t *kv, + void **data, + size_t *sz) { - bool rc = false; + pmix_status_t rc; + + rc = PMIX_SUCCESS; + if (NULL == data || + (NULL == *data && PMIX_STRING != kv->type && PMIX_BYTE_OBJECT != kv->type)) { + rc = PMIX_ERR_BAD_PARAM; + } else { + switch(kv->type) { + case PMIX_UNDEF: + rc = PMIX_ERR_UNKNOWN_DATA_TYPE; + break; + case PMIX_BOOL: + memcpy(*data, &(kv->data.flag), 1); + *sz = 1; + break; + case PMIX_BYTE: + memcpy(*data, &(kv->data.byte), 1); + *sz = 1; + break; + case PMIX_STRING: + if (NULL != kv->data.string) { + *data = strdup(kv->data.string); + *sz = strlen(kv->data.string); + } + break; + case PMIX_SIZE: + memcpy(*data, &(kv->data.size), sizeof(size_t)); + *sz = sizeof(size_t); + break; + case PMIX_PID: + memcpy(*data, &(kv->data.pid), sizeof(pid_t)); + *sz = sizeof(pid_t); + break; + case PMIX_INT: + memcpy(*data, &(kv->data.integer), sizeof(int)); + *sz = sizeof(int); + break; + case PMIX_INT8: + memcpy(*data, &(kv->data.int8), 1); + *sz = 1; + break; + case PMIX_INT16: + memcpy(*data, &(kv->data.int16), 2); + *sz = 2; + break; + case PMIX_INT32: + memcpy(*data, &(kv->data.int32), 4); + *sz = 4; + break; + case PMIX_INT64: + memcpy(*data, &(kv->data.int64), 8); + *sz = 8; + break; + case PMIX_UINT: + memcpy(*data, &(kv->data.uint), sizeof(int)); + *sz = sizeof(int); + break; + case PMIX_UINT8: + memcpy(*data, &(kv->data.uint8), 1); + *sz = 1; + break; + case PMIX_UINT16: + memcpy(*data, &(kv->data.uint16), 2); + *sz = 2; + break; + case PMIX_UINT32: + memcpy(*data, &(kv->data.uint32), 4); + *sz = 4; + break; + case PMIX_UINT64: + memcpy(*data, &(kv->data.uint64), 8); + *sz = 8; + break; + case PMIX_FLOAT: + memcpy(*data, &(kv->data.fval), sizeof(float)); + *sz = sizeof(float); + break; + case PMIX_DOUBLE: + memcpy(*data, &(kv->data.dval), sizeof(double)); + *sz = sizeof(double); + break; + case PMIX_TIMEVAL: + memcpy(*data, &(kv->data.tv), sizeof(struct timeval)); + *sz = sizeof(struct timeval); + break; + case PMIX_TIME: + memcpy(*data, &(kv->data.time), sizeof(time_t)); + *sz = sizeof(time_t); + break; + case PMIX_BYTE_OBJECT: + if (NULL != kv->data.bo.bytes && 0 < kv->data.bo.size) { + *data = kv->data.bo.bytes; + *sz = kv->data.bo.size; + } else { + *data = NULL; + *sz = 0; + } + break; + case PMIX_PERSIST: + memcpy(*data, &(kv->data.persist), sizeof(pmix_persistence_t)); + *sz = sizeof(pmix_persistence_t); + break; + case PMIX_SCOPE: + memcpy(*data, &(kv->data.scope), sizeof(pmix_scope_t)); + *sz = sizeof(pmix_scope_t); + break; + case PMIX_DATA_RANGE: + memcpy(*data, &(kv->data.range), sizeof(pmix_data_range_t)); + *sz = sizeof(pmix_data_range_t); + break; + case PMIX_PROC_STATE: + memcpy(*data, &(kv->data.state), sizeof(pmix_proc_state_t)); + *sz = sizeof(pmix_proc_state_t); + break; + case PMIX_POINTER: + memcpy(*data, &(kv->data.ptr), sizeof(void*)); + *sz = sizeof(void*); + break; + default: + /* silence warnings */ + rc = PMIX_ERROR; + break; + } + } + return rc; +} + +/* 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; if (p->type != p1->type) { return rc; @@ -219,49 +325,77 @@ bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1) switch (p->type) { case PMIX_UNDEF: - rc = true; + rc = PMIX_EQUAL; break; case PMIX_BOOL: - rc = (p->data.flag == p1->data.flag); + if (p->data.flag == p1->data.flag) { + rc = PMIX_EQUAL; + } break; case PMIX_BYTE: - rc = (p->data.byte == p1->data.byte); + if (p->data.byte == p1->data.byte) { + rc = PMIX_EQUAL; + } break; case PMIX_SIZE: - rc = (p->data.size == p1->data.size); + if (p->data.size == p1->data.size) { + rc = PMIX_EQUAL; + } break; case PMIX_INT: - rc = (p->data.integer == p1->data.integer); + if (p->data.integer == p1->data.integer) { + rc = PMIX_EQUAL; + } break; case PMIX_INT8: - rc = (p->data.int8 == p1->data.int8); + if (p->data.int8 == p1->data.int8) { + rc = PMIX_EQUAL; + } break; case PMIX_INT16: - rc = (p->data.int16 == p1->data.int16); + if (p->data.int16 == p1->data.int16) { + rc = PMIX_EQUAL; + } break; case PMIX_INT32: - rc = (p->data.int32 == p1->data.int32); + if (p->data.int32 == p1->data.int32) { + rc = PMIX_EQUAL; + } break; case PMIX_INT64: - rc = (p->data.int64 == p1->data.int64); + if (p->data.int64 == p1->data.int64) { + rc = PMIX_EQUAL; + } break; case PMIX_UINT: - rc = (p->data.uint == p1->data.uint); + if (p->data.uint == p1->data.uint) { + rc = PMIX_EQUAL; + } break; case PMIX_UINT8: - rc = (p->data.uint8 == p1->data.int8); + if (p->data.uint8 == p1->data.int8) { + rc = PMIX_EQUAL; + } break; case PMIX_UINT16: - rc = (p->data.uint16 == p1->data.uint16); + if (p->data.uint16 == p1->data.uint16) { + rc = PMIX_EQUAL; + } break; case PMIX_UINT32: - rc = (p->data.uint32 == p1->data.uint32); + if (p->data.uint32 == p1->data.uint32) { + rc = PMIX_EQUAL; + } break; case PMIX_UINT64: - rc = (p->data.uint64 == p1->data.uint64); + if (p->data.uint64 == p1->data.uint64) { + rc = PMIX_EQUAL; + } break; case PMIX_STRING: - rc = strcmp(p->data.string, p1->data.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) { @@ -270,17 +404,19 @@ bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1) return true; } case PMIX_STATUS: - rc = (p->data.status == p1->data.status); + if (p->data.status == p1->data.status) { + rc = PMIX_EQUAL; + } break; default: pmix_output(0, "COMPARE-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)p->type); } return rc; } -/* COPY FUNCTIONS FOR GENERIC PMIX TYPES - we - * are not allocating memory and so we cannot - * use the regular copy functions */ -PMIX_EXPORT pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) + +/* Xfer FUNCTIONS FOR GENERIC PMIX TYPES */ +pmix_status_t pmix_bfrops_base_value_xfer(pmix_value_t *p, + pmix_value_t *src) { size_t n, m; pmix_status_t rc; @@ -596,7 +732,7 @@ PMIX_EXPORT pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) p1 = (pmix_info_t*)p->data.darray->array; s1 = (pmix_info_t*)src->data.darray->array; for (n=0; n < src->data.darray->size; n++) { - PMIX_INFO_LOAD(&p1[n], s1[n].key, &s1[n].value.data.flag, s1[n].value.type); + PMIX_INFO_XFER(&p1[n], &s1[n]); } break; case PMIX_PDATA: @@ -607,7 +743,7 @@ PMIX_EXPORT pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) pd = (pmix_pdata_t*)p->data.darray->array; sd = (pmix_pdata_t*)src->data.darray->array; for (n=0; n < src->data.darray->size; n++) { - PMIX_PDATA_LOAD(&pd[n], &sd[n].proc, sd[n].key, &sd[n].value.data.flag, sd[n].value.type); + PMIX_PDATA_XFER(&pd[n], &sd[n]); } break; case PMIX_BUFFER: @@ -619,7 +755,7 @@ PMIX_EXPORT pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) sb = (pmix_buffer_t*)src->data.darray->array; for (n=0; n < src->data.darray->size; n++) { PMIX_CONSTRUCT(&pb[n], pmix_buffer_t); - pmix_bfrop.copy_payload(&pb[n], &sb[n]); + pmix_bfrops_base_copy_payload(&pb[n], &sb[n]); } break; case PMIX_BYTE_OBJECT: @@ -757,6 +893,7 @@ PMIX_EXPORT pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) } break; case PMIX_DATA_ARRAY: + PMIX_ERROR_LOG(PMIX_ERR_NOT_SUPPORTED); return PMIX_ERR_NOT_SUPPORTED; // don't support iterative arrays case PMIX_QUERY: PMIX_QUERY_CREATE(p->data.darray->array, src->data.darray->size); @@ -803,663 +940,144 @@ PMIX_EXPORT pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) p1 = (pmix_info_t*)p->data.array->array; s1 = (pmix_info_t*)src->data.array->array; for (n=0; n < src->data.darray->size; n++) { - PMIX_INFO_LOAD(&p1[n], s1[n].key, &s1[n].value.data.flag, s1[n].value.type); + PMIX_INFO_XFER(&p1[n], &s1[n]); } } break; /********************/ default: - pmix_output(0, "COPY-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)src->type); + pmix_output(0, "XFER-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)src->type); + assert(0); return PMIX_ERROR; } return PMIX_SUCCESS; } -/* PMIX_VALUE */ -pmix_status_t pmix_bfrop_copy_value(pmix_value_t **dest, pmix_value_t *src, - pmix_data_type_t type) -{ - pmix_value_t *p; - /* create the new object */ - *dest = (pmix_value_t*)malloc(sizeof(pmix_value_t)); - if (NULL == *dest) { - return PMIX_ERR_OUT_OF_RESOURCE; +/** + * Internal function that resizes (expands) an inuse buffer if + * necessary. + */ +char* pmix_bfrop_buffer_extend(pmix_buffer_t *buffer, size_t bytes_to_add) +{ + size_t required, to_alloc; + size_t pack_offset, unpack_offset; + + /* Check to see if we have enough space already */ + + + if ((buffer->bytes_allocated - buffer->bytes_used) >= bytes_to_add) { + return buffer->pack_ptr; } - p = *dest; - /* copy the type */ - p->type = src->type; - /* copy the data */ - return pmix_value_xfer(p, src); -} - -pmix_status_t pmix_bfrop_copy_info(pmix_info_t **dest, pmix_info_t *src, - pmix_data_type_t type) -{ - *dest = (pmix_info_t*)malloc(sizeof(pmix_info_t)); - (void)strncpy((*dest)->key, src->key, PMIX_MAX_KEYLEN); - (*dest)->flags = src->flags; - return pmix_value_xfer(&(*dest)->value, &src->value); -} - -pmix_status_t pmix_bfrop_copy_buf(pmix_buffer_t **dest, pmix_buffer_t *src, - pmix_data_type_t type) -{ - *dest = PMIX_NEW(pmix_buffer_t); - pmix_bfrop.copy_payload(*dest, src); - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_copy_app(pmix_app_t **dest, pmix_app_t *src, - pmix_data_type_t type) -{ - size_t j; - - *dest = (pmix_app_t*)malloc(sizeof(pmix_app_t)); - (*dest)->cmd = strdup(src->cmd); - (*dest)->argv = pmix_argv_copy(src->argv); - (*dest)->env = pmix_argv_copy(src->env); - if (NULL != src->cwd) { - (*dest)->cwd = strdup(src->cwd); - } - (*dest)->maxprocs = src->maxprocs; - (*dest)->ninfo = src->ninfo; - (*dest)->info = (pmix_info_t*)malloc(src->ninfo * sizeof(pmix_info_t)); - for (j=0; j < src->ninfo; j++) { - (void)strncpy((*dest)->info[j].key, src->info[j].key, PMIX_MAX_KEYLEN); - pmix_value_xfer(&(*dest)->info[j].value, &src->info[j].value); - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_copy_kval(pmix_kval_t **dest, pmix_kval_t *src, - pmix_data_type_t type) -{ - pmix_kval_t *p; - - /* create the new object */ - *dest = PMIX_NEW(pmix_kval_t); - if (NULL == *dest) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - p = *dest; - - /* copy the type */ - p->value->type = src->value->type; - /* copy the data */ - return pmix_value_xfer(p->value, src->value); -} - -pmix_status_t pmix_bfrop_copy_proc(pmix_proc_t **dest, pmix_proc_t *src, - pmix_data_type_t type) -{ - *dest = (pmix_proc_t*)malloc(sizeof(pmix_proc_t)); - if (NULL == *dest) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - (void)strncpy((*dest)->nspace, src->nspace, PMIX_MAX_NSLEN); - (*dest)->rank = src->rank; - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_copy_modex(pmix_modex_data_t **dest, pmix_modex_data_t *src, - pmix_data_type_t type) -{ - *dest = (pmix_modex_data_t*)malloc(sizeof(pmix_modex_data_t)); - if (NULL == *dest) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - (*dest)->blob = NULL; - (*dest)->size = 0; - if (NULL != src->blob) { - (*dest)->blob = (uint8_t*)malloc(src->size * sizeof(uint8_t)); - if (NULL == (*dest)->blob) { - return PMIX_ERR_OUT_OF_RESOURCE; + required = buffer->bytes_used + bytes_to_add; + if (required >= pmix_bfrops_globals.threshold_size) { + to_alloc = ((required + pmix_bfrops_globals.threshold_size - 1) + / pmix_bfrops_globals.threshold_size) * pmix_bfrops_globals.threshold_size; + } else { + to_alloc = buffer->bytes_allocated; + if (0 == to_alloc) { + to_alloc = pmix_bfrops_globals.initial_size; } - memcpy((*dest)->blob, src->blob, src->size * sizeof(uint8_t)); - (*dest)->size = src->size; - } - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_copy_persist(pmix_persistence_t **dest, pmix_persistence_t *src, - pmix_data_type_t type) -{ - *dest = (pmix_persistence_t*)malloc(sizeof(pmix_persistence_t)); - if (NULL == *dest) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - memcpy(*dest, src, sizeof(pmix_persistence_t)); - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_copy_bo(pmix_byte_object_t **dest, pmix_byte_object_t *src, - pmix_data_type_t type) -{ - *dest = (pmix_byte_object_t*)malloc(sizeof(pmix_byte_object_t)); - if (NULL == *dest) { - return PMIX_ERR_OUT_OF_RESOURCE; - } - (*dest)->bytes = (char*)malloc(src->size); - memcpy((*dest)->bytes, src->bytes, src->size); - (*dest)->size = src->size; - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_copy_pdata(pmix_pdata_t **dest, pmix_pdata_t *src, - pmix_data_type_t type) -{ - *dest = (pmix_pdata_t*)malloc(sizeof(pmix_pdata_t)); - (void)strncpy((*dest)->proc.nspace, src->proc.nspace, PMIX_MAX_NSLEN); - (*dest)->proc.rank = src->proc.rank; - (void)strncpy((*dest)->key, src->key, PMIX_MAX_KEYLEN); - return pmix_value_xfer(&(*dest)->value, &src->value); -} - -pmix_status_t pmix_bfrop_copy_pinfo(pmix_proc_info_t **dest, pmix_proc_info_t *src, - pmix_data_type_t type) -{ - *dest = (pmix_proc_info_t*)malloc(sizeof(pmix_proc_info_t)); - (void)strncpy((*dest)->proc.nspace, src->proc.nspace, PMIX_MAX_NSLEN); - (*dest)->proc.rank = src->proc.rank; - if (NULL != src->hostname) { - (*dest)->hostname = strdup(src->hostname); - } - if (NULL != src->executable_name) { - (*dest)->executable_name = strdup(src->executable_name); - } - (*dest)->pid = src->pid; - (*dest)->exit_code = src->exit_code; - (*dest)->state = src->state; - return PMIX_SUCCESS; -} - -/* the pmix_data_array_t is a little different in that it - * is an array of values, and so we cannot just copy one - * value at a time. So handle all value types here */ -pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, - pmix_data_array_t *src, - pmix_data_type_t type) -{ - pmix_data_array_t *p; - size_t n, m; - pmix_status_t rc; - char **prarray, **strarray; - pmix_value_t *pv, *sv; - pmix_app_t *pa, *sa; - pmix_info_t *p1, *s1; - pmix_pdata_t *pd, *sd; - pmix_buffer_t *pb, *sb; - pmix_byte_object_t *pbo, *sbo; - pmix_kval_t *pk, *sk; - pmix_modex_data_t *pm, *sm; - pmix_proc_info_t *pi, *si; - pmix_query_t *pq, *sq; - - p = (pmix_data_array_t*)calloc(1, sizeof(pmix_data_array_t)); - if (NULL == p) { - return PMIX_ERR_NOMEM; - } - p->type = src->type; - p->size = src->size; - /* process based on type of array element */ - switch (src->type) { - p->type = src->type; - p->size = src->size; - if (0 == p->size || NULL == src->array) { - p->array = NULL; - p->size = 0; - break; - } - case PMIX_UINT8: - case PMIX_INT8: - case PMIX_BYTE: - p->array = (char*)malloc(src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size); - break; - case PMIX_UINT16: - case PMIX_INT16: - p->array = (char*)malloc(src->size * sizeof(uint16_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(uint16_t)); - break; - case PMIX_UINT32: - case PMIX_INT32: - p->array = (char*)malloc(src->size * sizeof(uint32_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(uint32_t)); - break; - case PMIX_UINT64: - case PMIX_INT64: - p->array = (char*)malloc(src->size * sizeof(uint64_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(uint64_t)); - break; - case PMIX_BOOL: - p->array = (char*)malloc(src->size * sizeof(bool)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(bool)); - break; - case PMIX_SIZE: - p->array = (char*)malloc(src->size * sizeof(size_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(size_t)); - break; - case PMIX_PID: - p->array = (char*)malloc(src->size * sizeof(pid_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pid_t)); - break; - case PMIX_STRING: - p->array = (char**)malloc(src->size * sizeof(char*)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - prarray = (char**)p->array; - strarray = (char**)src->array; - for (n=0; n < src->size; n++) { - if (NULL != strarray[n]) { - prarray[n] = strdup(strarray[n]); - } - } - break; - case PMIX_INT: - case PMIX_UINT: - p->array = (char*)malloc(src->size * sizeof(int)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(int)); - break; - case PMIX_FLOAT: - p->array = (char*)malloc(src->size * sizeof(float)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(float)); - break; - case PMIX_DOUBLE: - p->array = (char*)malloc(src->size * sizeof(double)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(double)); - break; - case PMIX_TIMEVAL: - p->array = (struct timeval*)malloc(src->size * sizeof(struct timeval)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(struct timeval)); - break; - case PMIX_TIME: - p->array = (time_t*)malloc(src->size * sizeof(time_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(time_t)); - break; - case PMIX_STATUS: - p->array = (pmix_status_t*)malloc(src->size * sizeof(pmix_status_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pmix_status_t)); - break; - case PMIX_VALUE: - PMIX_VALUE_CREATE(p->array, src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pv = (pmix_value_t*)p->array; - sv = (pmix_value_t*)src->array; - for (n=0; n < src->size; n++) { - if (PMIX_SUCCESS != (rc = pmix_value_xfer(&pv[n], &sv[n]))) { - PMIX_VALUE_FREE(pv, src->size); - free(p); - return rc; - } - } - break; - case PMIX_PROC: - PMIX_PROC_CREATE(p->array, src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pmix_proc_t)); - break; - case PMIX_PROC_RANK: - p->array = (char*)malloc(src->size * sizeof(pmix_rank_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pmix_proc_t)); - break; - case PMIX_APP: - PMIX_APP_CREATE(p->array, src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pa = (pmix_app_t*)p->array; - sa = (pmix_app_t*)src->array; - for (n=0; n < src->size; n++) { - if (NULL != sa[n].cmd) { - pa[n].cmd = strdup(sa[n].cmd); - } - if (NULL != sa[n].argv) { - pa[n].argv = pmix_argv_copy(sa[n].argv); - } - if (NULL != sa[n].env) { - pa[n].env = pmix_argv_copy(sa[n].env); - } - if (NULL != sa[n].cwd) { - pa[n].cwd = strdup(sa[n].cwd); - } - pa[n].maxprocs = sa[n].maxprocs; - if (0 < sa[n].ninfo && NULL != sa[n].info) { - PMIX_INFO_CREATE(pa[n].info, sa[n].ninfo); - if (NULL == pa[n].info) { - PMIX_APP_FREE(pa, p->size); - free(p); - return PMIX_ERR_NOMEM; - } - pa[n].ninfo = sa[n].ninfo; - for (m=0; m < pa[n].ninfo; m++) { - PMIX_INFO_XFER(&pa[n].info[m], &sa[n].info[m]); - } - } - } - break; - case PMIX_INFO: - PMIX_INFO_CREATE(p->array, src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - p1 = (pmix_info_t*)p->array; - s1 = (pmix_info_t*)src->array; - for (n=0; n < src->size; n++) { - PMIX_INFO_LOAD(&p1[n], s1[n].key, &s1[n].value.data.flag, s1[n].value.type); - } - break; - case PMIX_PDATA: - PMIX_PDATA_CREATE(p->array, src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pd = (pmix_pdata_t*)p->array; - sd = (pmix_pdata_t*)src->array; - for (n=0; n < src->size; n++) { - PMIX_PDATA_LOAD(&pd[n], &sd[n].proc, sd[n].key, &sd[n].value.data, sd[n].value.type); - } - break; - case PMIX_BUFFER: - p->array = (pmix_buffer_t*)malloc(src->size * sizeof(pmix_buffer_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pb = (pmix_buffer_t*)p->array; - sb = (pmix_buffer_t*)src->array; - for (n=0; n < src->size; n++) { - PMIX_CONSTRUCT(&pb[n], pmix_buffer_t); - pmix_bfrop.copy_payload(&pb[n], &sb[n]); - } - break; - case PMIX_BYTE_OBJECT: - case PMIX_COMPRESSED_STRING: - p->array = (pmix_byte_object_t*)malloc(src->size * sizeof(pmix_byte_object_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pbo = (pmix_byte_object_t*)p->array; - sbo = (pmix_byte_object_t*)src->array; - for (n=0; n < src->size; n++) { - if (NULL != sbo[n].bytes && 0 < sbo[n].size) { - pbo[n].size = sbo[n].size; - pbo[n].bytes = (char*)malloc(pbo[n].size); - memcpy(pbo[n].bytes, sbo[n].bytes, pbo[n].size); - } else { - pbo[n].bytes = NULL; - pbo[n].size = 0; - } - } - break; - case PMIX_KVAL: - p->array = (pmix_kval_t*)calloc(src->size , sizeof(pmix_kval_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pk = (pmix_kval_t*)p->array; - sk = (pmix_kval_t*)src->array; - for (n=0; n < src->size; n++) { - if (NULL != sk[n].key) { - pk[n].key = strdup(sk[n].key); - } - if (NULL != sk[n].value) { - PMIX_VALUE_CREATE(pk[n].value, 1); - if (NULL == pk[n].value) { - PMIX_VALUE_FREE(pk[n].value, 1); - free(p); - return PMIX_ERR_NOMEM; - } - if (PMIX_SUCCESS != (rc = pmix_value_xfer(pk[n].value, sk[n].value))) { - PMIX_VALUE_FREE(pk[n].value, 1); - free(p); - return rc; - } - } - } - break; - case PMIX_MODEX: - PMIX_MODEX_CREATE(p->array, src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pm = (pmix_modex_data_t*)p->array; - sm = (pmix_modex_data_t*)src->array; - for (n=0; n < src->size; n++) { - memcpy(&pm[n], &sm[n], sizeof(pmix_modex_data_t)); - if (NULL != sm[n].blob && 0 < sm[n].size) { - pm[n].blob = (uint8_t*)malloc(sm[n].size); - if (NULL == pm[n].blob) { - PMIX_MODEX_FREE(pm, src->size); - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(pm[n].blob, sm[n].blob, sm[n].size); - pm[n].size = sm[n].size; - } else { - pm[n].blob = NULL; - pm[n].size = 0; - } - } - break; - case PMIX_PERSIST: - p->array = (pmix_persistence_t*)malloc(src->size * sizeof(pmix_persistence_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pmix_persistence_t)); - break; - case PMIX_POINTER: - p->array = (char**)malloc(src->size * sizeof(char*)); - prarray = (char**)p->array; - strarray = (char**)src->array; - for (n=0; n < src->size; n++) { - prarray[n] = strarray[n]; - } - break; - case PMIX_SCOPE: - p->array = (pmix_scope_t*)malloc(src->size * sizeof(pmix_scope_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pmix_scope_t)); - break; - case PMIX_DATA_RANGE: - p->array = (pmix_data_range_t*)malloc(src->size * sizeof(pmix_data_range_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pmix_data_range_t)); - break; - case PMIX_COMMAND: - p->array = (pmix_cmd_t*)malloc(src->size * sizeof(pmix_cmd_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pmix_cmd_t)); - break; - case PMIX_INFO_DIRECTIVES: - p->array = (pmix_info_directives_t*)malloc(src->size * sizeof(pmix_info_directives_t)); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - memcpy(p->array, src->array, src->size * sizeof(pmix_info_directives_t)); - break; - case PMIX_PROC_INFO: - PMIX_PROC_INFO_CREATE(p->array, src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pi = (pmix_proc_info_t*)p->array; - si = (pmix_proc_info_t*)src->array; - for (n=0; n < src->size; n++) { - memcpy(&pi[n].proc, &si[n].proc, sizeof(pmix_proc_t)); - if (NULL != si[n].hostname) { - pi[n].hostname = strdup(si[n].hostname); - } else { - pi[n].hostname = NULL; - } - if (NULL != si[n].executable_name) { - pi[n].executable_name = strdup(si[n].executable_name); - } else { - pi[n].executable_name = NULL; - } - pi[n].pid = si[n].pid; - pi[n].exit_code = si[n].exit_code; - pi[n].state = si[n].state; - } - break; - case PMIX_DATA_ARRAY: - free(p); - return PMIX_ERR_NOT_SUPPORTED; // don't support iterative arrays - case PMIX_QUERY: - PMIX_QUERY_CREATE(p->array, src->size); - if (NULL == p->array) { - free(p); - return PMIX_ERR_NOMEM; - } - pq = (pmix_query_t*)p->array; - sq = (pmix_query_t*)src->array; - for (n=0; n < src->size; n++) { - if (NULL != sq[n].keys) { - pq[n].keys = pmix_argv_copy(sq[n].keys); - } - if (NULL != sq[n].qualifiers && 0 < sq[n].nqual) { - PMIX_INFO_CREATE(pq[n].qualifiers, sq[n].nqual); - if (NULL == pq[n].qualifiers) { - PMIX_INFO_FREE(pq[n].qualifiers, sq[n].nqual); - free(p); - return PMIX_ERR_NOMEM; - } - for (m=0; m < sq[n].nqual; m++) { - PMIX_INFO_XFER(&pq[n].qualifiers[m], &sq[n].qualifiers[m]); - } - pq[n].nqual = sq[n].nqual; - } else { - pq[n].qualifiers = NULL; - pq[n].nqual = 0; - } - } - break; - default: - free(p); - return PMIX_ERR_UNKNOWN_DATA_TYPE; - } - - (*dest) = p; - return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_copy_query(pmix_query_t **dest, - pmix_query_t *src, - pmix_data_type_t type) -{ - pmix_status_t rc; - - *dest = (pmix_query_t*)malloc(sizeof(pmix_query_t)); - if (NULL != src->keys) { - (*dest)->keys = pmix_argv_copy(src->keys); - } - (*dest)->nqual = src->nqual; - if (NULL != src->qualifiers) { - if (PMIX_SUCCESS != (rc = pmix_bfrop_copy_info(&((*dest)->qualifiers), src->qualifiers, PMIX_INFO))) { - free(*dest); - return rc; + while (to_alloc < required) { + to_alloc <<= 1; } } - return PMIX_SUCCESS; + + if (NULL != buffer->base_ptr) { + pack_offset = ((char*) buffer->pack_ptr) - ((char*) buffer->base_ptr); + unpack_offset = ((char*) buffer->unpack_ptr) - + ((char*) buffer->base_ptr); + buffer->base_ptr = (char*)realloc(buffer->base_ptr, to_alloc); + memset(buffer->base_ptr + pack_offset, 0, to_alloc - buffer->bytes_allocated); + } else { + pack_offset = 0; + unpack_offset = 0; + buffer->bytes_used = 0; + buffer->base_ptr = (char*)malloc(to_alloc); + memset(buffer->base_ptr, 0, to_alloc); + } + + if (NULL == buffer->base_ptr) { + return NULL; + } + buffer->pack_ptr = ((char*) buffer->base_ptr) + pack_offset; + buffer->unpack_ptr = ((char*) buffer->base_ptr) + unpack_offset; + buffer->bytes_allocated = to_alloc; + + /* All done */ + return buffer->pack_ptr; } -/**** DEPRECATED ****/ -pmix_status_t pmix_bfrop_copy_array(pmix_info_array_t **dest, - pmix_info_array_t *src, - pmix_data_type_t type) +/* + * Internal function that checks to see if the specified number of bytes + * remain in the buffer for unpacking + */ +bool pmix_bfrop_too_small(pmix_buffer_t *buffer, size_t bytes_reqd) { - pmix_info_t *d1, *s1; + size_t bytes_remaining_packed; + + if (buffer->pack_ptr < buffer->unpack_ptr) { + return true; + } + + bytes_remaining_packed = buffer->pack_ptr - buffer->unpack_ptr; + + if (bytes_remaining_packed < bytes_reqd) { + /* don't error log this - it could be that someone is trying to + * simply read until the buffer is empty + */ + return true; + } + + return false; +} + +pmix_status_t pmix_bfrop_store_data_type(pmix_buffer_t *buffer, pmix_data_type_t type) +{ + uint16_t tmp; + char *dst; + + /* check to see if buffer needs extending */ + if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, sizeof(tmp)))) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + tmp = pmix_htons(type); + memcpy(dst, &tmp, sizeof(tmp)); + buffer->pack_ptr += sizeof(tmp); + buffer->bytes_used += sizeof(tmp); - *dest = (pmix_info_array_t*)malloc(sizeof(pmix_info_array_t)); - (*dest)->size = src->size; - (*dest)->array = (pmix_info_t*)malloc(src->size * sizeof(pmix_info_t)); - d1 = (pmix_info_t*)(*dest)->array; - s1 = (pmix_info_t*)src->array; - memcpy(d1, s1, src->size * sizeof(pmix_info_t)); return PMIX_SUCCESS; } -/*******************/ + +pmix_status_t pmix_bfrop_get_data_type(pmix_buffer_t *buffer, pmix_data_type_t *type) +{ + uint16_t tmp; + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, sizeof(tmp))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + memcpy(&tmp, buffer->unpack_ptr, sizeof(tmp)); + tmp = pmix_ntohs(tmp); + memcpy(type, &tmp, sizeof(tmp)); + buffer->unpack_ptr += sizeof(tmp); + + return PMIX_SUCCESS; +} + +const char* pmix_bfrops_base_data_type_string(pmix_pointer_array_t *regtypes, + pmix_data_type_t type) +{ + pmix_bfrop_type_info_t *info; + + /* Lookup the object for this type and call it */ + if (NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(regtypes, type))) { + return NULL; + } + + return info->odti_name; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_frame.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_frame.c new file mode 100644 index 0000000000..bf2f0eb5f8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_frame.c @@ -0,0 +1,184 @@ +/* -*- Mode: C; c-basic-offset:4 ; -*- */ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2009 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** @file: + * + */ +#include + +#include + +#ifdef HAVE_STRING_H +#include +#endif + +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_var.h" +#include "src/mca/base/pmix_mca_base_framework.h" +#include "src/class/pmix_list.h" +#include "src/mca/bfrops/base/base.h" + +/* + * The following file was created by configure. It contains extern + * statements and the definition of an array of pointers to each + * component's public mca_base_component_t struct. + */ + +#include "src/mca/bfrops/base/static-components.h" + +/* Instantiate the global vars */ +pmix_bfrops_globals_t pmix_bfrops_globals = {{{0}}}; + +static int pmix_bfrop_register(pmix_mca_base_register_flag_t flags) +{ + pmix_bfrops_globals.initial_size = PMIX_BFROP_DEFAULT_INITIAL_SIZE; + pmix_mca_base_var_register("pmix", "bfrops", "base", "initial_size", + "Initial size of a buffer", + PMIX_MCA_BASE_VAR_TYPE_SIZE_T, NULL, 0, 0, + PMIX_INFO_LVL_2, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, + &pmix_bfrops_globals.initial_size); + + pmix_bfrops_globals.threshold_size = PMIX_BFROP_DEFAULT_THRESHOLD_SIZE; + pmix_mca_base_var_register("pmix", "bfrops", "base", "threshold_size", + "Size at which we switch from extending a buffer by doubling to extending by a smaller value", + PMIX_MCA_BASE_VAR_TYPE_SIZE_T, NULL, 0, 0, + PMIX_INFO_LVL_2, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, + &pmix_bfrops_globals.threshold_size); + +#if PMIX_ENABLE_DEBUG + pmix_bfrops_globals.default_type = PMIX_BFROP_BUFFER_FULLY_DESC; +#else + pmix_bfrops_globals.default_type = PMIX_BFROP_BUFFER_NON_DESC; +#endif + pmix_mca_base_var_register("pmix", "bfrops", "base", "default_type", + "Default type for buffers", + PMIX_MCA_BASE_VAR_TYPE_INT, NULL, 0, 0, + PMIX_INFO_LVL_2, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, + &pmix_bfrops_globals.default_type); + return PMIX_SUCCESS; +} + +static pmix_status_t pmix_bfrop_close(void) +{ + if (!pmix_bfrops_globals.initialized) { + return PMIX_SUCCESS; + } + pmix_bfrops_globals.initialized = false; + + /* the components will cleanup when closed */ + PMIX_DESTRUCT(&pmix_bfrops_globals.actives); + + return pmix_mca_base_framework_components_close(&pmix_bfrops_base_framework, NULL); +} + +static pmix_status_t pmix_bfrop_open(pmix_mca_base_open_flag_t flags) +{ + /* initialize globals */ + pmix_bfrops_globals.initialized = true; + PMIX_CONSTRUCT(&pmix_bfrops_globals.actives, pmix_list_t); + + /* Open up all available components */ + return pmix_mca_base_framework_components_open(&pmix_bfrops_base_framework, flags); +} + +PMIX_MCA_BASE_FRAMEWORK_DECLARE(pmix, bfrops, "PMIx Buffer Operations", + pmix_bfrop_register, pmix_bfrop_open, pmix_bfrop_close, + mca_bfrops_base_static_components, 0); + +static void moddes(pmix_bfrops_base_active_module_t *p) +{ + if (NULL != p->module->finalize) { + p->module->finalize(); + } +} +PMIX_CLASS_INSTANCE(pmix_bfrops_base_active_module_t, + pmix_list_item_t, + NULL, moddes); + +/** + * Object constructors, destructors, and instantiations + */ +/** Value **/ +static void pmix_buffer_construct (pmix_buffer_t* buffer) +{ + /** set the default buffer type */ + buffer->type = PMIX_BFROP_BUFFER_UNDEF; + + /* Make everything NULL to begin with */ + buffer->base_ptr = buffer->pack_ptr = buffer->unpack_ptr = NULL; + buffer->bytes_allocated = buffer->bytes_used = 0; +} + +static void pmix_buffer_destruct (pmix_buffer_t* buffer) +{ + if (NULL != buffer->base_ptr) { + free (buffer->base_ptr); + } +} + +PMIX_CLASS_INSTANCE(pmix_buffer_t, + pmix_object_t, + pmix_buffer_construct, + pmix_buffer_destruct); + + +static void pmix_bfrop_type_info_construct(pmix_bfrop_type_info_t *obj) +{ + obj->odti_name = NULL; + obj->odti_pack_fn = NULL; + obj->odti_unpack_fn = NULL; + obj->odti_copy_fn = NULL; + obj->odti_print_fn = NULL; +} + +static void pmix_bfrop_type_info_destruct(pmix_bfrop_type_info_t *obj) +{ + if (NULL != obj->odti_name) { + free(obj->odti_name); + } +} + +PMIX_CLASS_INSTANCE(pmix_bfrop_type_info_t, pmix_object_t, + pmix_bfrop_type_info_construct, + pmix_bfrop_type_info_destruct); + +static void kvcon(pmix_kval_t *k) +{ + k->key = NULL; + k->value = NULL; +} +static void kvdes(pmix_kval_t *k) +{ + if (NULL != k->key) { + free(k->key); + } + if (NULL != k->value) { + PMIX_VALUE_RELEASE(k->value); + } +} +PMIX_CLASS_INSTANCE(pmix_kval_t, + pmix_list_item_t, + kvcon, kvdes); diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_pack.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_pack.c new file mode 100644 index 0000000000..9047db5ed4 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_pack.c @@ -0,0 +1,1255 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/class/pmix_pointer_array.h" +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/util/output.h" +#include "src/include/pmix_globals.h" + +#include "src/mca/bfrops/base/base.h" + + +pmix_status_t pmix_bfrops_base_pack(pmix_pointer_array_t *regtypes, + pmix_buffer_t *buffer, + const void *src, int num_vals, + pmix_data_type_t type) +{ + pmix_status_t rc; + + /* check for error */ + if (NULL == buffer || NULL == src) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + return PMIX_ERR_BAD_PARAM; + } + + /* Pack the number of values */ + if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { + if (PMIX_SUCCESS != (rc = pmix_bfrop_store_data_type(buffer, PMIX_INT32))) { + return rc; + } + } + if (PMIX_SUCCESS != (rc = pmix_bfrops_base_pack_int32(buffer, &num_vals, 1, PMIX_INT32))) { + return rc; + } + + /* Pack the value(s) */ + return pmix_bfrops_base_pack_buffer(regtypes, buffer, src, num_vals, type); +} + + +pmix_status_t pmix_bfrops_base_pack_buffer(pmix_pointer_array_t *regtypes, + pmix_buffer_t *buffer, + const void *src, int32_t num_vals, + pmix_data_type_t type) +{ + pmix_status_t rc; + pmix_bfrop_type_info_t *info; + + pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrops_base_pack_buffer( %p, %p, %lu, %d )\n", + (void*)buffer, src, (long unsigned int)num_vals, (int)type); + + /* Pack the declared data type */ + if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { + if (PMIX_SUCCESS != (rc = pmix_bfrop_store_data_type(buffer, type))) { + return rc; + } + } + + /* Lookup the pack function for this type and call it */ + if (NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(regtypes, type))) { + PMIX_ERROR_LOG(PMIX_ERR_UNKNOWN_DATA_TYPE); + return PMIX_ERR_UNKNOWN_DATA_TYPE; + } + + return info->odti_pack_fn(buffer, src, num_vals, type); +} + +static pmix_status_t pack_gentype(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + switch(type) { + case PMIX_INT8: + case PMIX_UINT8: + return pmix_bfrops_base_pack_byte(buffer, src, num_vals, type); + break; + + case PMIX_INT16: + case PMIX_UINT16: + return pmix_bfrops_base_pack_int16(buffer, src, num_vals, type); + break; + + case PMIX_INT32: + case PMIX_UINT32: + return pmix_bfrops_base_pack_int32(buffer, src, num_vals, type); + break; + + case PMIX_INT64: + case PMIX_UINT64: + return pmix_bfrops_base_pack_int64(buffer, src, num_vals, type); + break; + + default: + return PMIX_ERR_UNKNOWN_DATA_TYPE; + } +} + +/* PACK FUNCTIONS FOR GENERIC SYSTEM TYPES */ + +/* + * BOOL + */ + pmix_status_t pmix_bfrops_base_pack_bool(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) + { + uint8_t *dst; + int32_t i; + bool *s = (bool*)src; + + pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrops_base_pack_bool * %d\n", num_vals); + + /* check to see if buffer needs extending */ + if (NULL == (dst = (uint8_t*)pmix_bfrop_buffer_extend(buffer, num_vals))) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + /* store the data */ + for (i=0; i < num_vals; i++) { + if (s[i]) { + dst[i] = 1; + } else { + dst[i] = 0; + } + } + + /* update buffer pointers */ + buffer->pack_ptr += num_vals; + buffer->bytes_used += num_vals; + + return PMIX_SUCCESS; +} + +/* + * INT + */ +pmix_status_t pmix_bfrops_base_pack_int(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_status_t ret; + + /* System types need to always be described so we can properly + unpack them */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, BFROP_TYPE_INT))) { + return ret; + } + + /* Turn around and pack the real type */ + return pack_gentype(buffer, src, num_vals, BFROP_TYPE_INT); +} + +/* + * SIZE_T + */ +pmix_status_t pmix_bfrops_base_pack_sizet(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int ret; + + /* System types need to always be described so we can properly + unpack them. */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, BFROP_TYPE_SIZE_T))) { + return ret; + } + + return pack_gentype(buffer, src, num_vals, BFROP_TYPE_SIZE_T); +} + +/* + * PID_T + */ +pmix_status_t pmix_bfrops_base_pack_pid(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int ret; + + /* System types need to always be described so we can properly + unpack them. */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, BFROP_TYPE_PID_T))) { + return ret; + } + + /* Turn around and pack the real type */ + return pack_gentype(buffer, src, num_vals, BFROP_TYPE_PID_T); +} + + +/* + * BYTE, CHAR, INT8 + */ +pmix_status_t pmix_bfrops_base_pack_byte(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + char *dst; + + pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrops_base_pack_byte * %d\n", num_vals); + + /* check to see if buffer needs extending */ + if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, num_vals))) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + /* store the data */ + memcpy(dst, src, num_vals); + + /* update buffer pointers */ + buffer->pack_ptr += num_vals; + buffer->bytes_used += num_vals; + + return PMIX_SUCCESS; +} + +/* + * INT16 + */ +pmix_status_t pmix_bfrops_base_pack_int16(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int32_t i; + uint16_t tmp, *srctmp = (uint16_t*) src; + char *dst; + + pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrops_base_pack_int16 * %d\n", num_vals); + + /* check to see if buffer needs extending */ + if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, num_vals*sizeof(tmp)))) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + for (i = 0; i < num_vals; ++i) { + tmp = pmix_htons(srctmp[i]); + memcpy(dst, &tmp, sizeof(tmp)); + dst += sizeof(tmp); + } + buffer->pack_ptr += num_vals * sizeof(tmp); + buffer->bytes_used += num_vals * sizeof(tmp); + + return PMIX_SUCCESS; +} + +/* + * INT32 + */ +pmix_status_t pmix_bfrops_base_pack_int32(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int32_t i; + uint32_t tmp, *srctmp = (uint32_t*) src; + char *dst; + + pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrops_base_pack_int32 * %d\n", num_vals); + + /* check to see if buffer needs extending */ + if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, num_vals*sizeof(tmp)))) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + for (i = 0; i < num_vals; ++i) { + tmp = htonl(srctmp[i]); + memcpy(dst, &tmp, sizeof(tmp)); + dst += sizeof(tmp); + } + buffer->pack_ptr += num_vals * sizeof(tmp); + buffer->bytes_used += num_vals * sizeof(tmp); + + return PMIX_SUCCESS; +} + +/* + * INT64 + */ +pmix_status_t pmix_bfrops_base_pack_int64(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int32_t i; + uint64_t tmp, tmp2; + char *dst; + size_t bytes_packed = num_vals * sizeof(tmp); + + pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrops_base_pack_int64 * %d\n", num_vals); + + /* check to see if buffer needs extending */ + if (NULL == (dst = pmix_bfrop_buffer_extend(buffer, bytes_packed))) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + for (i = 0; i < num_vals; ++i) { + memcpy(&tmp2, (char *)src+i*sizeof(uint64_t), sizeof(uint64_t)); + tmp = pmix_hton64(tmp2); + memcpy(dst, &tmp, sizeof(tmp)); + dst += sizeof(tmp); + } + buffer->pack_ptr += bytes_packed; + buffer->bytes_used += bytes_packed; + + return PMIX_SUCCESS; +} + +/* + * STRING + */ +pmix_status_t pmix_bfrops_base_pack_string(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int ret = PMIX_SUCCESS; + int32_t i, len; + char **ssrc = (char**) src; + + for (i = 0; i < num_vals; ++i) { + if (NULL == ssrc[i]) { /* got zero-length string/NULL pointer - store NULL */ + len = 0; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, &len, 1, PMIX_INT32))) { + return ret; + } + } else { + len = (int32_t)strlen(ssrc[i]) + 1; // retain the NULL terminator + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, &len, 1, PMIX_INT32))) { + return ret; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, ssrc[i], len, PMIX_BYTE))) { + return ret; + } + } + } +return ret; +} + +/* FLOAT */ +pmix_status_t pmix_bfrops_base_pack_float(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int ret = PMIX_SUCCESS; + int32_t i; + float *ssrc = (float*)src; + char *convert; + + for (i = 0; i < num_vals; ++i) { + asprintf(&convert, "%f", ssrc[i]); + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &convert, 1, PMIX_STRING))) { + free(convert); + return ret; + } + free(convert); + } + + return PMIX_SUCCESS; +} + +/* DOUBLE */ +pmix_status_t pmix_bfrops_base_pack_double(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int ret = PMIX_SUCCESS; + int32_t i; + double *ssrc = (double*)src; + char *convert; + + for (i = 0; i < num_vals; ++i) { + asprintf(&convert, "%f", ssrc[i]); + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &convert, 1, PMIX_STRING))) { + free(convert); + return ret; + } + free(convert); + } + + return PMIX_SUCCESS; +} + +/* TIMEVAL */ +pmix_status_t pmix_bfrops_base_pack_timeval(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int64_t tmp[2]; + int ret = PMIX_SUCCESS; + int32_t i; + struct timeval *ssrc = (struct timeval *)src; + + for (i = 0; i < num_vals; ++i) { + tmp[0] = (int64_t)ssrc[i].tv_sec; + tmp[1] = (int64_t)ssrc[i].tv_usec; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int64(buffer, tmp, 2, PMIX_INT64))) { + return ret; + } + } + + return PMIX_SUCCESS; +} + +/* TIME */ +pmix_status_t pmix_bfrops_base_pack_time(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int ret = PMIX_SUCCESS; + int32_t i; + time_t *ssrc = (time_t *)src; + uint64_t ui64; + + /* time_t is a system-dependent size, so cast it + * to uint64_t as a generic safe size + */ + for (i = 0; i < num_vals; ++i) { + ui64 = (uint64_t)ssrc[i]; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int64(buffer, &ui64, 1, PMIX_UINT64))) { + return ret; + } + } + + return PMIX_SUCCESS; +} + +/* STATUS */ +pmix_status_t pmix_bfrops_base_pack_status(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int ret = PMIX_SUCCESS; + int32_t i; + pmix_status_t *ssrc = (pmix_status_t *)src; + int32_t status; + + for (i = 0; i < num_vals; ++i) { + status = (int32_t)ssrc[i]; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, &status, 1, PMIX_INT32))) { + return ret; + } + } + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_buf(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_buffer_t *ptr; + int32_t i; + int ret; + + ptr = (pmix_buffer_t *) src; + + for (i = 0; i < num_vals; ++i) { + /* pack the type of buffer */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, &ptr[i].type, 1, PMIX_BYTE))) { + return ret; + } + /* pack the number of bytes */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, &ptr[i].bytes_used, 1, PMIX_SIZE))) { + return ret; + } + /* pack the bytes */ + if (0 < ptr[i].bytes_used) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, ptr[i].base_ptr, ptr[i].bytes_used, PMIX_BYTE))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_bo(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + int ret; + int i; + pmix_byte_object_t *bo; + + bo = (pmix_byte_object_t*)src; + for (i=0; i < num_vals; i++) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, &bo[i].size, 1, PMIX_SIZE))) { + return ret; + } + if (0 < bo[i].size) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, bo[i].bytes, bo[i].size, PMIX_BYTE))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_proc(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_proc_t *proc; + int32_t i; + int ret; + + proc = (pmix_proc_t *) src; + + for (i = 0; i < num_vals; ++i) { + char *ptr = proc[i].nspace; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &ptr, 1, PMIX_STRING))) { + return ret; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_rank(buffer, &proc[i].rank, 1, PMIX_PROC_RANK))) { + return ret; + } + } + return PMIX_SUCCESS; +} + + +/* PMIX_VALUE */ +pmix_status_t pmix_bfrops_base_pack_value(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_value_t *ptr; + int32_t i; + int ret; + + ptr = (pmix_value_t *) src; + + for (i = 0; i < num_vals; ++i) { + /* pack the type */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, ptr[i].type))) { + return ret; + } + /* now pack the right field */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_val(buffer, &ptr[i]))) { + return ret; + } + } + + return PMIX_SUCCESS; +} + + +pmix_status_t pmix_bfrops_base_pack_info(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_info_t *info; + int32_t i; + int ret; + char *foo; + + info = (pmix_info_t *) src; + + for (i = 0; i < num_vals; ++i) { + /* pack key */ + foo = info[i].key; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &foo, 1, PMIX_STRING))) { + return ret; + } + /* pack info directives */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_info_directives(buffer, &info[i].flags, 1, PMIX_INFO_DIRECTIVES))) { + return ret; + } + /* pack the type */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, info[i].value.type))) { + return ret; + } + /* pack value */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_val(buffer, &info[i].value))) { + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_pdata(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_pdata_t *pdata; + int32_t i; + int ret; + char *foo; + + pdata = (pmix_pdata_t *) src; + + for (i = 0; i < num_vals; ++i) { + /* pack the proc */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_proc(buffer, &pdata[i].proc, 1, PMIX_PROC))) { + return ret; + } + /* pack key */ + foo = pdata[i].key; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &foo, 1, PMIX_STRING))) { + PMIX_ERROR_LOG(ret); + return ret; + } + /* pack the type */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, pdata[i].value.type))) { + PMIX_ERROR_LOG(ret); + return ret; + } + /* pack value */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_val(buffer, &pdata[i].value))) { + PMIX_ERROR_LOG(ret); + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_app(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_app_t *app; + int32_t i, j, nvals; + int ret; + + app = (pmix_app_t *) src; + + for (i = 0; i < num_vals; ++i) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &app[i].cmd, 1, PMIX_STRING))) { + return ret; + } + /* argv */ + nvals = pmix_argv_count(app[i].argv); + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int(buffer, &nvals, 1, PMIX_INT32))) { + return ret; + } + for (j=0; j < nvals; j++) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &app[i].argv[j], 1, PMIX_STRING))) { + return ret; + } + } + /* env */ + nvals = pmix_argv_count(app[i].env); + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, &nvals, 1, PMIX_INT32))) { + return ret; + } + for (j=0; j < nvals; j++) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &app[i].env[j], 1, PMIX_STRING))) { + return ret; + } + } + /* cwd */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &app[i].cwd, 1, PMIX_STRING))) { + return ret; + } + /* maxprocs */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int(buffer, &app[i].maxprocs, 1, PMIX_INT))) { + return ret; + } + /* info array */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, &app[i].ninfo, 1, PMIX_SIZE))) { + return ret; + } + if (0 < app[i].ninfo) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_info(buffer, app[i].info, app[i].ninfo, PMIX_INFO))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + + +pmix_status_t pmix_bfrops_base_pack_kval(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_kval_t *ptr; + int32_t i; + int ret; + + ptr = (pmix_kval_t *) src; + + for (i = 0; i < num_vals; ++i) { + /* pack the key */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &ptr[i].key, 1, PMIX_STRING))) { + return ret; + } + /* pack the value */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_value(buffer, ptr[i].value, 1, PMIX_VALUE))) { + return ret; + } + } + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_modex(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_modex_data_t *ptr; + int32_t i; + int ret; + + ptr = (pmix_modex_data_t *) src; + + for (i = 0; i < num_vals; ++i) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, &ptr[i].size, 1, PMIX_SIZE))) { + return ret; + } + if( 0 < ptr[i].size){ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, ptr[i].blob, ptr[i].size, PMIX_UINT8))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_persist(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_byte(buffer, src, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_pack_datatype(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_int16(buffer, src, num_vals, type); +} + + +pmix_status_t pmix_bfrops_base_pack_ptr(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + uint8_t foo=1; + /* it obviously makes no sense to pack a pointer and + * send it somewhere else, so we just pack a sentinel */ + return pmix_bfrops_base_pack_byte(buffer, &foo, 1, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_pack_scope(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_byte(buffer, src, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_pack_range(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_byte(buffer, src, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_pack_cmd(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_byte(buffer, src, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_pack_info_directives(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_int32(buffer, src, num_vals, PMIX_UINT32); +} + +pmix_status_t pmix_bfrops_base_pack_pstate(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_byte(buffer, src, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_pack_pinfo(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_proc_info_t *pinfo = (pmix_proc_info_t*)src; + pmix_status_t ret; + int32_t i; + + for (i=0; i < num_vals; i++) { + /* pack the proc identifier */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_proc(buffer, &pinfo[i].proc, 1, PMIX_PROC))) { + return ret; + } + /* pack the hostname and exec */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &pinfo[i].hostname, 1, PMIX_STRING))) { + return ret; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &pinfo[i].executable_name, 1, PMIX_STRING))) { + return ret; + } + /* pack the pid and state */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_pid(buffer, &pinfo[i].pid, 1, PMIX_PID))) { + return ret; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_pstate(buffer, &pinfo[i].state, 1, PMIX_PROC_STATE))) { + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_darray(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_data_array_t *p = (pmix_data_array_t*)src; + pmix_status_t ret; + int32_t i; + + for (i=0; i < num_vals; i++) { + /* pack the actual type in the array */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_store_data_type(buffer, p[i].type))) { + return ret; + } + /* pack the number of array elements */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, &p[i].size, 1, PMIX_SIZE))) { + return ret; + } + if (0 == p[i].size || PMIX_UNDEF == p[i].type) { + /* nothing left to do */ + continue; + } + /* pack the actual elements - have to do this the hard way */ + switch(p[i].type) { + case PMIX_UNDEF: + break; + case PMIX_BOOL: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_bool(buffer, p[i].array, p[i].size, PMIX_BOOL))) { + return ret; + } + break; + case PMIX_BYTE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, p[i].array, p[i].size, PMIX_BYTE))) { + return ret; + } + break; + case PMIX_STRING: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, p[i].array, p[i].size, PMIX_STRING))) { + return ret; + } + break; + case PMIX_SIZE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, p[i].array, p[i].size, PMIX_SIZE))) { + return ret; + } + break; + case PMIX_PID: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_pid(buffer, p[i].array, p[i].size, PMIX_PID))) { + return ret; + } + break; + case PMIX_INT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int(buffer, p[i].array, p[i].size, PMIX_INT))) { + return ret; + } + break; + case PMIX_INT8: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, p[i].array, p[i].size, PMIX_INT8))) { + return ret; + } + break; + case PMIX_INT16: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int16(buffer, p[i].array, p[i].size, PMIX_INT16))) { + return ret; + } + break; + case PMIX_INT32: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, p[i].array, p[i].size, PMIX_INT32))) { + return ret; + } + break; + case PMIX_INT64: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int64(buffer, p[i].array, p[i].size, PMIX_INT64))) { + return ret; + } + break; + case PMIX_UINT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int(buffer, p[i].array, p[i].size, PMIX_UINT))) { + return ret; + } + break; + case PMIX_UINT8: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, p[i].array, p[i].size, PMIX_UINT8))) { + return ret; + } + break; + case PMIX_UINT16: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int16(buffer, p[i].array, p[i].size, PMIX_UINT16))) { + return ret; + } + break; + case PMIX_UINT32: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, p[i].array, p[i].size, PMIX_UINT32))) { + return ret; + } + break; + case PMIX_UINT64: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int64(buffer, p[i].array, p[i].size, PMIX_UINT64))) { + return ret; + } + break; + case PMIX_FLOAT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_float(buffer, p[i].array, p[i].size, PMIX_FLOAT))) { + return ret; + } + break; + case PMIX_DOUBLE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_double(buffer, p[i].array, p[i].size, PMIX_DOUBLE))) { + return ret; + } + break; + case PMIX_TIMEVAL: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_timeval(buffer, p[i].array, p[i].size, PMIX_TIMEVAL))) { + return ret; + } + break; + case PMIX_TIME: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_time(buffer, p[i].array, p[i].size, PMIX_TIME))) { + return ret; + } + break; + case PMIX_STATUS: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_status(buffer, p[i].array, p[i].size, PMIX_STATUS))) { + return ret; + } + break; + case PMIX_INFO: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_info(buffer, p[i].array, p[i].size, PMIX_INFO))) { + return ret; + } + break; + case PMIX_PROC: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_proc(buffer, p[i].array, p[i].size, PMIX_PROC))) { + return ret; + } + break; + case PMIX_PROC_RANK: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_rank(buffer, p[i].array, p[i].size, PMIX_PROC_RANK))) { + return ret; + } + break; + case PMIX_BYTE_OBJECT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_bo(buffer, p[i].array, p[i].size, PMIX_BYTE_OBJECT))) { + return ret; + } + break; + case PMIX_PERSIST: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_persist(buffer, p[i].array, p[i].size, PMIX_PERSIST))) { + return ret; + } + break; + case PMIX_POINTER: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_ptr(buffer, p[i].array, p[i].size, PMIX_POINTER))) { + return ret; + } + break; + case PMIX_SCOPE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_scope(buffer, p[i].array, p[i].size, PMIX_SCOPE))) { + return ret; + } + break; + case PMIX_DATA_RANGE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_range(buffer, p[i].array, p[i].size, PMIX_DATA_RANGE))) { + return ret; + } + break; + case PMIX_PROC_STATE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_pstate(buffer, p[i].array, p[i].size, PMIX_PROC_STATE))) { + return ret; + } + break; + case PMIX_PROC_INFO: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_pinfo(buffer, p[i].array, p[i].size, PMIX_PROC_INFO))) { + return ret; + } + break; + case PMIX_DATA_ARRAY: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_darray(buffer, p[i].array, p[i].size, PMIX_DATA_ARRAY))) { + return ret; + } + break; + case PMIX_QUERY: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_query(buffer, p[i].array, p[i].size, PMIX_QUERY))) { + return ret; + } + break; + case PMIX_ALLOC_DIRECTIVE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_alloc_directive(buffer, p[i].array, p[i].size, PMIX_ALLOC_DIRECTIVE))) { + return ret; + } + break; + /**** DEPRECATED ****/ + case PMIX_INFO_ARRAY: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_array(buffer, p[i].array, p[i].size, PMIX_INFO_ARRAY))) { + return ret; + } + break; + /********************/ + default: + pmix_output(0, "PACK-PMIX-VALUE[%s:%d]: UNSUPPORTED TYPE %d", + __FILE__, __LINE__, (int)p[i].type); + return PMIX_ERROR; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_rank(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_int32(buffer, src, num_vals, PMIX_UINT32); +} + +pmix_status_t pmix_bfrops_base_pack_query(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_query_t *pq = (pmix_query_t*)src; + pmix_status_t ret; + int32_t i; + int32_t nkeys; + + for (i=0; i < num_vals; i++) { + /* pack the number of keys */ + nkeys = pmix_argv_count(pq[i].keys); + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, &nkeys, 1, PMIX_INT32))) { + return ret; + } + if (0 < nkeys) { + /* pack the keys */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, pq[i].keys, nkeys, PMIX_STRING))) { + return ret; + } + } + /* pack the number of qualifiers */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, &pq[i].nqual, 1, PMIX_SIZE))) { + return ret; + } + if (0 < pq[i].nqual) { + /* pack any provided qualifiers */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_info(buffer, pq[i].qualifiers, pq[i].nqual, PMIX_INFO))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + + +/********************/ +/* PACK FUNCTIONS FOR VALUE TYPES */ +pmix_status_t pmix_bfrops_base_pack_val(pmix_buffer_t *buffer, + pmix_value_t *p) +{ + pmix_status_t ret; + + switch (p->type) { + case PMIX_UNDEF: + break; + case PMIX_BOOL: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_bool(buffer, &p->data.flag, 1, PMIX_BOOL))) { + return ret; + } + break; + case PMIX_BYTE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, &p->data.byte, 1, PMIX_BYTE))) { + return ret; + } + break; + case PMIX_STRING: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_string(buffer, &p->data.string, 1, PMIX_STRING))) { + return ret; + } + break; + case PMIX_SIZE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, &p->data.size, 1, PMIX_SIZE))) { + return ret; + } + break; + case PMIX_PID: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_pid(buffer, &p->data.pid, 1, PMIX_PID))) { + return ret; + } + break; + case PMIX_INT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int(buffer, &p->data.integer, 1, PMIX_INT))) { + return ret; + } + break; + case PMIX_INT8: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, &p->data.int8, 1, PMIX_INT8))) { + return ret; + } + break; + case PMIX_INT16: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int16(buffer, &p->data.int16, 1, PMIX_INT16))) { + return ret; + } + break; + case PMIX_INT32: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, &p->data.int32, 1, PMIX_INT32))) { + return ret; + } + break; + case PMIX_INT64: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int64(buffer, &p->data.int64, 1, PMIX_INT64))) { + return ret; + } + break; + case PMIX_UINT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int(buffer, &p->data.uint, 1, PMIX_UINT))) { + return ret; + } + break; + case PMIX_UINT8: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_byte(buffer, &p->data.uint8, 1, PMIX_UINT8))) { + return ret; + } + break; + case PMIX_UINT16: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int16(buffer, &p->data.uint16, 1, PMIX_UINT16))) { + return ret; + } + break; + case PMIX_UINT32: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int32(buffer, &p->data.uint32, 1, PMIX_UINT32))) { + return ret; + } + break; + case PMIX_UINT64: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_int64(buffer, &p->data.uint64, 1, PMIX_UINT64))) { + return ret; + } + break; + case PMIX_FLOAT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_float(buffer, &p->data.fval, 1, PMIX_FLOAT))) { + return ret; + } + break; + case PMIX_DOUBLE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_double(buffer, &p->data.dval, 1, PMIX_DOUBLE))) { + return ret; + } + break; + case PMIX_TIMEVAL: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_timeval(buffer, &p->data.tv, 1, PMIX_TIMEVAL))) { + return ret; + } + break; + case PMIX_TIME: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_time(buffer, &p->data.time, 1, PMIX_TIME))) { + return ret; + } + break; + case PMIX_STATUS: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_status(buffer, &p->data.status, 1, PMIX_STATUS))) { + return ret; + } + break; + case PMIX_PROC: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_proc(buffer, p->data.proc, 1, PMIX_PROC))) { + return ret; + } + break; + case PMIX_PROC_RANK: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_rank(buffer, &p->data.rank, 1, PMIX_PROC_RANK))) { + return ret; + } + break; + case PMIX_BYTE_OBJECT: + case PMIX_COMPRESSED_STRING: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_bo(buffer, &p->data.bo, 1, PMIX_BYTE_OBJECT))) { + return ret; + } + break; + case PMIX_PERSIST: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_persist(buffer, &p->data.persist, 1, PMIX_PERSIST))) { + return ret; + } + break; + case PMIX_POINTER: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_ptr(buffer, &p->data.ptr, 1, PMIX_POINTER))) { + return ret; + } + break; + case PMIX_SCOPE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_scope(buffer, &p->data.scope, 1, PMIX_SCOPE))) { + return ret; + } + break; + case PMIX_DATA_RANGE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_range(buffer, &p->data.range, 1, PMIX_DATA_RANGE))) { + return ret; + } + break; + case PMIX_PROC_STATE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_pstate(buffer, &p->data.state, 1, PMIX_PROC_STATE))) { + return ret; + } + break; + case PMIX_PROC_INFO: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_pinfo(buffer, p->data.pinfo, 1, PMIX_PROC_INFO))) { + return ret; + } + break; + case PMIX_DATA_ARRAY: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_darray(buffer, p->data.darray, 1, PMIX_DATA_ARRAY))) { + return ret; + } + break; + case PMIX_ALLOC_DIRECTIVE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_alloc_directive(buffer, &p->data.adir, 1, PMIX_ALLOC_DIRECTIVE))) { + return ret; + } + break; + /**** DEPRECATED ****/ + case PMIX_INFO_ARRAY: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_array(buffer, p->data.array, 1, PMIX_INFO_ARRAY))) { + return ret; + } + break; + /********************/ + default: + pmix_output(0, "PACK-PMIX-VALUE[%s:%d]: UNSUPPORTED TYPE %d", + __FILE__, __LINE__, (int)p->type); + return PMIX_ERROR; + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_pack_alloc_directive(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_pack_byte(buffer, src, num_vals, PMIX_UINT8); +} + + +/**** DEPRECATED ****/ +pmix_status_t pmix_bfrops_base_pack_array(pmix_buffer_t *buffer, const void *src, + int32_t num_vals, pmix_data_type_t type) +{ + pmix_info_array_t *ptr; + int32_t i; + pmix_status_t ret; + + ptr = (pmix_info_array_t *) src; + + for (i = 0; i < num_vals; ++i) { + /* pack the size */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_sizet(buffer, &ptr[i].size, 1, PMIX_SIZE))) { + return ret; + } + if (0 < ptr[i].size) { + /* pack the values */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_pack_info(buffer, ptr[i].array, ptr[i].size, PMIX_INFO))) { + return ret; + } + } + } + + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/print.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_print.c similarity index 57% rename from opal/mca/pmix/pmix2x/pmix/src/buffer_ops/print.c rename to opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_print.c index e126bb1a91..c22ada53f9 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/print.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_print.c @@ -13,7 +13,7 @@ * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. * All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -31,21 +31,24 @@ #endif #include "src/util/error.h" -#include "src/include/pmix_globals.h" -#include "src/buffer_ops/internal.h" - pmix_status_t pmix_bfrop_print(char **output, char *prefix, void *src, pmix_data_type_t type) - { +#include "src/include/pmix_globals.h" +#include "src/mca/bfrops/base/base.h" + +pmix_status_t pmix_bfrops_base_print(pmix_pointer_array_t *regtypes, + char **output, char *prefix, + void *src, pmix_data_type_t type) +{ pmix_bfrop_type_info_t *info; /* check for error */ - if (NULL == output) { + if (NULL == output || NULL == src) { return PMIX_ERR_BAD_PARAM; } /* Lookup the print function for this type and call it */ - if(NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&pmix_bfrop_types, type))) { + if(NULL == (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(regtypes, type))) { return PMIX_ERR_UNKNOWN_DATA_TYPE; } @@ -55,43 +58,8 @@ /* * STANDARD PRINT FUNCTIONS FOR SYSTEM TYPES */ - pmix_status_t pmix_bfrop_print_bool(char **output, char *prefix, bool *src, pmix_data_type_t type) - { - char *prefx; - - /* deal with NULL prefix */ - if (NULL == prefix) { - if (0 > asprintf(&prefx, " ")) { - return PMIX_ERR_NOMEM; - } - } - else { - prefx = prefix; - } - - /* if src is NULL, just print data type and return */ - if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_BOOL\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } - if (prefx != prefix) { - free(prefx); - } - return PMIX_SUCCESS; - } - - if (0 > asprintf(output, "%sData type: PMIX_BOOL\tValue: %s", prefix, - (*src) ? "TRUE" : "FALSE")) { - return PMIX_ERR_NOMEM; -} -if (prefx != prefix) { - free(prefx); -} - -return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_print_byte(char **output, char *prefix, uint8_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_bool(char **output, char *prefix, + bool *src, pmix_data_type_t type) { char *prefx; @@ -106,18 +74,15 @@ pmix_status_t pmix_bfrop_print_byte(char **output, char *prefix, uint8_t *src, p /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_BYTE\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_BOOL\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_BYTE\tValue: %x", prefix, *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_BOOL\tValue: %s", prefix, + (*src) ? "TRUE" : "FALSE"); if (prefx != prefix) { free(prefx); } @@ -125,7 +90,8 @@ pmix_status_t pmix_bfrop_print_byte(char **output, char *prefix, uint8_t *src, p return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_string(char **output, char *prefix, char *src, pmix_data_type_t type) +int pmix_bfrops_base_print_byte(char **output, char *prefix, + uint8_t *src, pmix_data_type_t type) { char *prefx; @@ -140,18 +106,14 @@ pmix_status_t pmix_bfrop_print_string(char **output, char *prefix, char *src, pm /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_STRING\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_BYTE\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_STRING\tValue: %s", prefx, src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_BYTE\tValue: %x", prefix, *src); if (prefx != prefix) { free(prefx); } @@ -159,7 +121,8 @@ pmix_status_t pmix_bfrop_print_string(char **output, char *prefix, char *src, pm return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_size(char **output, char *prefix, size_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_string(char **output, char *prefix, + char *src, pmix_data_type_t type) { char *prefx; @@ -174,18 +137,14 @@ pmix_status_t pmix_bfrop_print_size(char **output, char *prefix, size_t *src, pm /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_SIZE\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_STRING\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_SIZE\tValue: %lu", prefx, (unsigned long) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_STRING\tValue: %s", prefx, src); if (prefx != prefix) { free(prefx); } @@ -193,7 +152,8 @@ pmix_status_t pmix_bfrop_print_size(char **output, char *prefix, size_t *src, pm return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_pid(char **output, char *prefix, pid_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_size(char **output, char *prefix, + size_t *src, pmix_data_type_t type) { char *prefx; @@ -208,25 +168,23 @@ pmix_status_t pmix_bfrop_print_pid(char **output, char *prefix, pid_t *src, pmix /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_PID\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_SIZE\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_PID\tValue: %lu", prefx, (unsigned long) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_SIZE\tValue: %lu", prefx, (unsigned long) *src); if (prefx != prefix) { free(prefx); } + return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_int(char **output, char *prefix, int *src, pmix_data_type_t type) +int pmix_bfrops_base_print_pid(char **output, char *prefix, + pid_t *src, pmix_data_type_t type) { char *prefx; @@ -241,26 +199,22 @@ pmix_status_t pmix_bfrop_print_int(char **output, char *prefix, int *src, pmix_d /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_INT\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_PID\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_INT\tValue: %ld", prefx, (long) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_PID\tValue: %lu", prefx, (unsigned long) *src); if (prefx != prefix) { free(prefx); } - return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_uint(char **output, char *prefix, uint *src, pmix_data_type_t type) +int pmix_bfrops_base_print_int(char **output, char *prefix, + int *src, pmix_data_type_t type) { char *prefx; @@ -275,18 +229,14 @@ pmix_status_t pmix_bfrop_print_uint(char **output, char *prefix, uint *src, pmix /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_UINT\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_UINT\tValue: %lu", prefx, (unsigned long) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT\tValue: %ld", prefx, (long) *src); if (prefx != prefix) { free(prefx); } @@ -294,7 +244,8 @@ pmix_status_t pmix_bfrop_print_uint(char **output, char *prefix, uint *src, pmix return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_uint8(char **output, char *prefix, uint8_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_uint(char **output, char *prefix, + uint *src, pmix_data_type_t type) { char *prefx; @@ -309,18 +260,14 @@ pmix_status_t pmix_bfrop_print_uint8(char **output, char *prefix, uint8_t *src, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_UINT8\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_UINT8\tValue: %u", prefx, (unsigned int) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT\tValue: %lu", prefx, (unsigned long) *src); if (prefx != prefix) { free(prefx); } @@ -328,7 +275,8 @@ pmix_status_t pmix_bfrop_print_uint8(char **output, char *prefix, uint8_t *src, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_uint16(char **output, char *prefix, uint16_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_uint8(char **output, char *prefix, + uint8_t *src, pmix_data_type_t type) { char *prefx; @@ -343,18 +291,14 @@ pmix_status_t pmix_bfrop_print_uint16(char **output, char *prefix, uint16_t *src /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_UINT16\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT8\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_UINT16\tValue: %u", prefx, (unsigned int) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT8\tValue: %u", prefx, (unsigned int) *src); if (prefx != prefix) { free(prefx); } @@ -362,8 +306,8 @@ pmix_status_t pmix_bfrop_print_uint16(char **output, char *prefix, uint16_t *src return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_uint32(char **output, char *prefix, - uint32_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_uint16(char **output, char *prefix, + uint16_t *src, pmix_data_type_t type) { char *prefx; @@ -378,18 +322,14 @@ pmix_status_t pmix_bfrop_print_uint32(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_UINT32\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT16\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_UINT32\tValue: %u", prefx, (unsigned int) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT16\tValue: %u", prefx, (unsigned int) *src); if (prefx != prefix) { free(prefx); } @@ -397,8 +337,8 @@ pmix_status_t pmix_bfrop_print_uint32(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_int8(char **output, char *prefix, - int8_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_uint32(char **output, char *prefix, + uint32_t *src, pmix_data_type_t type) { char *prefx; @@ -413,18 +353,14 @@ pmix_status_t pmix_bfrop_print_int8(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_INT8\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT32\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_INT8\tValue: %d", prefx, (int) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT32\tValue: %u", prefx, (unsigned int) *src); if (prefx != prefix) { free(prefx); } @@ -432,8 +368,8 @@ pmix_status_t pmix_bfrop_print_int8(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_int16(char **output, char *prefix, - int16_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_int8(char **output, char *prefix, + int8_t *src, pmix_data_type_t type) { char *prefx; @@ -448,18 +384,14 @@ pmix_status_t pmix_bfrop_print_int16(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_INT16\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT8\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_INT16\tValue: %d", prefx, (int) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT8\tValue: %d", prefx, (int) *src); if (prefx != prefix) { free(prefx); } @@ -467,7 +399,8 @@ pmix_status_t pmix_bfrop_print_int16(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_int32(char **output, char *prefix, int32_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_int16(char **output, char *prefix, + int16_t *src, pmix_data_type_t type) { char *prefx; @@ -482,27 +415,23 @@ pmix_status_t pmix_bfrop_print_int32(char **output, char *prefix, int32_t *src, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_INT32\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT16\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_INT32\tValue: %d", prefx, (int) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT16\tValue: %d", prefx, (int) *src); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_uint64(char **output, char *prefix, - uint64_t *src, - pmix_data_type_t type) + +int pmix_bfrops_base_print_int32(char **output, char *prefix, + int32_t *src, pmix_data_type_t type) { char *prefx; @@ -517,28 +446,23 @@ pmix_status_t pmix_bfrop_print_uint64(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_UINT64\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT32\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_UINT64\tValue: %lu", prefx, (unsigned long) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT32\tValue: %d", prefx, (int) *src); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - -pmix_status_t pmix_bfrop_print_int64(char **output, char *prefix, - int64_t *src, - pmix_data_type_t type) +int pmix_bfrops_base_print_uint64(char **output, char *prefix, + uint64_t *src, + pmix_data_type_t type) { char *prefx; @@ -553,18 +477,14 @@ pmix_status_t pmix_bfrop_print_int64(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_INT64\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT64\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_INT64\tValue: %ld", prefx, (long) *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_UINT64\tValue: %lu", prefx, (unsigned long) *src); if (prefx != prefix) { free(prefx); } @@ -572,8 +492,9 @@ pmix_status_t pmix_bfrop_print_int64(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_float(char **output, char *prefix, - float *src, pmix_data_type_t type) +int pmix_bfrops_base_print_int64(char **output, char *prefix, + int64_t *src, + pmix_data_type_t type) { char *prefx; @@ -588,18 +509,14 @@ pmix_status_t pmix_bfrop_print_float(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_FLOAT\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT64\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_FLOAT\tValue: %f", prefx, *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_INT64\tValue: %ld", prefx, (long) *src); if (prefx != prefix) { free(prefx); } @@ -607,8 +524,8 @@ pmix_status_t pmix_bfrop_print_float(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_double(char **output, char *prefix, - double *src, pmix_data_type_t type) +int pmix_bfrops_base_print_float(char **output, char *prefix, + float *src, pmix_data_type_t type) { char *prefx; @@ -623,18 +540,14 @@ pmix_status_t pmix_bfrop_print_double(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_DOUBLE\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_FLOAT\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_DOUBLE\tValue: %f", prefx, *src)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_FLOAT\tValue: %f", prefx, *src); if (prefx != prefix) { free(prefx); } @@ -642,8 +555,39 @@ pmix_status_t pmix_bfrop_print_double(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_time(char **output, char *prefix, - time_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_double(char **output, char *prefix, + double *src, pmix_data_type_t type) +{ + char *prefx; + + /* deal with NULL prefix */ + if (NULL == prefix) { + if (0 > asprintf(&prefx, " ")) { + return PMIX_ERR_NOMEM; + } + } else { + prefx = prefix; + } + + /* if src is NULL, just print data type and return */ + if (NULL == src) { + asprintf(output, "%sData type: PMIX_DOUBLE\tValue: NULL pointer", prefx); + if (prefx != prefix) { + free(prefx); + } + return PMIX_SUCCESS; + } + + asprintf(output, "%sData type: PMIX_DOUBLE\tValue: %f", prefx, *src); + if (prefx != prefix) { + free(prefx); + } + + return PMIX_SUCCESS; +} + +int pmix_bfrops_base_print_time(char **output, char *prefix, + time_t *src, pmix_data_type_t type) { char *prefx; char *t; @@ -659,9 +603,7 @@ pmix_status_t pmix_bfrop_print_time(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_TIME\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_TIME\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } @@ -671,9 +613,7 @@ pmix_status_t pmix_bfrop_print_time(char **output, char *prefix, t = ctime(src); t[strlen(t)-1] = '\0'; // remove trailing newline - if (0 > asprintf(output, "%sData type: PMIX_TIME\tValue: %s", prefx, t)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_TIME\tValue: %s", prefx, t); if (prefx != prefix) { free(prefx); } @@ -681,8 +621,8 @@ pmix_status_t pmix_bfrop_print_time(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_timeval(char **output, char *prefix, - struct timeval *src, pmix_data_type_t type) +int pmix_bfrops_base_print_timeval(char **output, char *prefix, + struct timeval *src, pmix_data_type_t type) { char *prefx; @@ -697,28 +637,24 @@ pmix_status_t pmix_bfrop_print_timeval(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_TIMEVAL\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_TIMEVAL\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_TIMEVAL\tValue: %ld.%06ld", prefx, - (long)src->tv_sec, (long)src->tv_usec)) { - return PMIX_ERR_NOMEM; -} -if (prefx != prefix) { - free(prefx); + asprintf(output, "%sData type: PMIX_TIMEVAL\tValue: %ld.%06ld", prefx, + (long)src->tv_sec, (long)src->tv_usec); + if (prefx != prefix) { + free(prefx); + } + + return PMIX_SUCCESS; } -return PMIX_SUCCESS; -} - -pmix_status_t pmix_bfrop_print_status(char **output, char *prefix, - pmix_status_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_status(char **output, char *prefix, + pmix_status_t *src, pmix_data_type_t type) { char *prefx; @@ -733,18 +669,14 @@ pmix_status_t pmix_bfrop_print_status(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_STATUS\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_STATUS\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_STATUS\tValue: %s", prefx, PMIx_Error_string(*src))) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_STATUS\tValue: %s", prefx, PMIx_Error_string(*src)); if (prefx != prefix) { free(prefx); } @@ -758,26 +690,19 @@ pmix_status_t pmix_bfrop_print_status(char **output, char *prefix, /* * PMIX_VALUE */ - pmix_status_t pmix_bfrop_print_value(char **output, char *prefix, - pmix_value_t *src, pmix_data_type_t type) + int pmix_bfrops_base_print_value(char **output, char *prefix, + pmix_value_t *src, pmix_data_type_t type) { char *prefx; int rc; /* deal with NULL prefix */ - if (NULL == prefix) { - if (0 > asprintf(&prefx, " ")) { - return PMIX_ERR_NOMEM; - } - } else { - prefx = prefix; - } + if (NULL == prefix) asprintf(&prefx, " "); + else prefx = prefix; /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_VALUE\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_VALUE\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } @@ -786,195 +711,182 @@ pmix_status_t pmix_bfrop_print_status(char **output, char *prefix, switch (src->type) { case PMIX_UNDEF: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UNDEF", prefx); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UNDEF", prefx); + break; case PMIX_BYTE: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_BYTE\tValue: %x", - prefx, src->data.byte); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_BYTE\tValue: %x", + prefx, src->data.byte); + break; case PMIX_STRING: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_STRING\tValue: %s", - prefx, src->data.string); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_STRING\tValue: %s", + prefx, src->data.string); + break; case PMIX_SIZE: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_SIZE\tValue: %lu", - prefx, (unsigned long)src->data.size); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_SIZE\tValue: %lu", + prefx, (unsigned long)src->data.size); + break; case PMIX_PID: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PID\tValue: %lu", - prefx, (unsigned long)src->data.pid); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PID\tValue: %lu", + prefx, (unsigned long)src->data.pid); + break; case PMIX_INT: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT\tValue: %d", - prefx, src->data.integer); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT\tValue: %d", + prefx, src->data.integer); + break; case PMIX_INT8: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT8\tValue: %d", - prefx, (int)src->data.int8); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT8\tValue: %d", + prefx, (int)src->data.int8); + break; case PMIX_INT16: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT16\tValue: %d", - prefx, (int)src->data.int16); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT16\tValue: %d", + prefx, (int)src->data.int16); + break; case PMIX_INT32: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT32\tValue: %d", - prefx, src->data.int32); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT32\tValue: %d", + prefx, src->data.int32); + break; case PMIX_INT64: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT64\tValue: %ld", - prefx, (long)src->data.int64); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_INT64\tValue: %ld", + prefx, (long)src->data.int64); + break; case PMIX_UINT: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT\tValue: %u", - prefx, src->data.uint); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT\tValue: %u", + prefx, src->data.uint); + break; case PMIX_UINT8: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT8\tValue: %u", - prefx, (unsigned int)src->data.uint8); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT8\tValue: %u", + prefx, (unsigned int)src->data.uint8); + break; case PMIX_UINT16: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT16\tValue: %u", - prefx, (unsigned int)src->data.uint16); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT16\tValue: %u", + prefx, (unsigned int)src->data.uint16); + break; case PMIX_UINT32: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT32\tValue: %u", - prefx, src->data.uint32); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT32\tValue: %u", + prefx, src->data.uint32); + break; case PMIX_UINT64: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT64\tValue: %lu", - prefx, (unsigned long)src->data.uint64); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_UINT64\tValue: %lu", + prefx, (unsigned long)src->data.uint64); + break; case PMIX_FLOAT: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_FLOAT\tValue: %f", - prefx, src->data.fval); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_FLOAT\tValue: %f", + prefx, src->data.fval); + break; case PMIX_DOUBLE: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_DOUBLE\tValue: %f", - prefx, src->data.dval); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_DOUBLE\tValue: %f", + prefx, src->data.dval); + break; case PMIX_TIMEVAL: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_TIMEVAL\tValue: %ld.%06ld", prefx, - (long)src->data.tv.tv_sec, (long)src->data.tv.tv_usec); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_TIMEVAL\tValue: %ld.%06ld", prefx, + (long)src->data.tv.tv_sec, (long)src->data.tv.tv_usec); + break; case PMIX_TIME: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_TIME\tValue: %s", prefx, - ctime(&src->data.time)); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_TIME\tValue: %ld", prefx, + (long)src->data.time); + break; case PMIX_STATUS: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_STATUS\tValue: %s", prefx, - PMIx_Error_string(src->data.status)); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_STATUS\tValue: %s", prefx, + PMIx_Error_string(src->data.status)); + break; case PMIX_PROC: - if (NULL == src->data.proc) { - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PROC\tNULL", prefx); - } else { - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PROC\t%s:%lu", - prefx, src->data.proc->nspace, (unsigned long)src->data.proc->rank); - } - break; + if (NULL == src->data.proc) { + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PROC\tNULL", prefx); + } else { + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PROC\t%s:%lu", + prefx, src->data.proc->nspace, (unsigned long)src->data.proc->rank); + } + break; case PMIX_BYTE_OBJECT: - rc = asprintf(output, "%sPMIX_VALUE: Data type: BYTE_OBJECT\tSIZE: %ld", - prefx, (long)src->data.bo.size); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: BYTE_OBJECT\tSIZE: %ld", + prefx, (long)src->data.bo.size); + break; case PMIX_PERSIST: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PERSIST\tValue: %s", - prefx, PMIx_Persistence_string(src->data.persist)); + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PERSIST\tValue: %d", + prefx, (int)src->data.persist); break; case PMIX_SCOPE: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_SCOPE\tValue: %s", - prefx, PMIx_Scope_string(src->data.scope)); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_SCOPE\tValue: %d", + prefx, (int)src->data.scope); + break; case PMIX_DATA_RANGE: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_DATA_RANGE\tValue: %s", - prefx, PMIx_Data_range_string(src->data.range)); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_DATA_RANGE\tValue: %d", + prefx, (int)src->data.range); + break; case PMIX_PROC_STATE: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_STATE\tValue: %s", - prefx, PMIx_Proc_state_string(src->data.state)); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_STATE\tValue: %d", + prefx, (int)src->data.state); + break; case PMIX_PROC_INFO: - rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PROC_INFO\tProc: %s:%lu\n%s\tHost: %s\tExecutable: %s\tPid: %lu", - prefx, src->data.pinfo->proc.nspace, (unsigned long)src->data.pinfo->proc.rank, - prefx, src->data.pinfo->hostname, src->data.pinfo->executable_name, - (unsigned long)src->data.pinfo->pid); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: PMIX_PROC_INFO\tValue: %s:%lu", + prefx, src->data.proc->nspace, (unsigned long)src->data.proc->rank); + break; case PMIX_DATA_ARRAY: - rc = asprintf(output, "%sPMIX_VALUE: Data type: DATA_ARRAY\tARRAY SIZE: %ld", - prefx, (long)src->data.darray->size); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: DATA_ARRAY\tARRAY SIZE: %ld", + prefx, (long)src->data.darray->size); + break; /**** DEPRECATED ****/ case PMIX_INFO_ARRAY: - rc = asprintf(output, "%sPMIX_VALUE: Data type: INFO_ARRAY\tARRAY SIZE: %ld", - prefx, (long)src->data.array->size); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: INFO_ARRAY\tARRAY SIZE: %ld", + prefx, (long)src->data.array->size); + break; /********************/ default: - rc = asprintf(output, "%sPMIX_VALUE: Data type: UNKNOWN\tValue: UNPRINTABLE", prefx); - break; + rc = asprintf(output, "%sPMIX_VALUE: Data type: UNKNOWN\tValue: UNPRINTABLE", prefx); + break; } if (prefx != prefix) { free(prefx); } - if (0 > rc) { - return PMIX_ERR_NOMEM; - } - return PMIX_SUCCESS; + return rc; } -pmix_status_t pmix_bfrop_print_info(char **output, char *prefix, - pmix_info_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_info(char **output, char *prefix, + pmix_info_t *src, pmix_data_type_t type) { - char *tmp; - int rc; + char *tmp=NULL, *tmp2=NULL; - pmix_bfrop_print_value(&tmp, NULL, &src->value, PMIX_VALUE); - rc = asprintf(output, "%sKEY: %s DIRECTIVES: %0x %s", prefix, src->key, - src->flags, (NULL == tmp) ? "PMIX_VALUE: NULL" : tmp); - if (NULL != tmp) { - free(tmp); - } - if (0 > rc) { - return PMIX_ERR_NOMEM; - } + pmix_bfrops_base_print_value(&tmp, NULL, &src->value, PMIX_VALUE); + pmix_bfrops_base_print_info_directives(&tmp2, NULL, &src->flags, PMIX_INFO_DIRECTIVES); + asprintf(output, "%sKEY: %s\n%s\t%s\n%s\t%s", prefix, src->key, + prefix, tmp2, prefix, tmp); + free(tmp); + free(tmp2); return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_pdata(char **output, char *prefix, - pmix_pdata_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_pdata(char **output, char *prefix, + pmix_pdata_t *src, pmix_data_type_t type) { char *tmp1, *tmp2; - int rc; - pmix_bfrop_print_proc(&tmp1, NULL, &src->proc, PMIX_PROC); - pmix_bfrop_print_value(&tmp2, NULL, &src->value, PMIX_VALUE); - rc = asprintf(output, "%s %s KEY: %s %s", prefix, tmp1, src->key, - (NULL == tmp2) ? "NULL" : tmp2); + pmix_bfrops_base_print_proc(&tmp1, NULL, &src->proc, PMIX_PROC); + pmix_bfrops_base_print_value(&tmp2, NULL, &src->value, PMIX_VALUE); + asprintf(output, "%s %s KEY: %s %s", prefix, tmp1, src->key, + (NULL == tmp2) ? "NULL" : tmp2); if (NULL != tmp1) { free(tmp1); } if (NULL != tmp2) { free(tmp2); } - if (0 > rc) { - return PMIX_ERR_NOMEM; - } return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_buf(char **output, char *prefix, - pmix_buffer_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_buf(char **output, char *prefix, + pmix_buffer_t *src, pmix_data_type_t type) { return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_app(char **output, char *prefix, - pmix_app_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_app(char **output, char *prefix, + pmix_app_t *src, pmix_data_type_t type) { return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_proc(char **output, char *prefix, - pmix_proc_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_proc(char **output, char *prefix, + pmix_proc_t *src, pmix_data_type_t type) { char *prefx; int rc; @@ -1015,19 +927,20 @@ pmix_status_t pmix_bfrop_print_proc(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_kval(char **output, char *prefix, - pmix_kval_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_kval(char **output, char *prefix, + pmix_kval_t *src, pmix_data_type_t type) { return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_modex(char **output, char *prefix, - pmix_modex_data_t *src, pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_modex(char **output, char *prefix, + pmix_modex_data_t *src, pmix_data_type_t type) { return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_persist(char **output, char *prefix, pmix_persistence_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_persist(char **output, char *prefix, + pmix_persistence_t *src, pmix_data_type_t type) { char *prefx; @@ -1061,9 +974,9 @@ pmix_status_t pmix_bfrop_print_persist(char **output, char *prefix, pmix_persist return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_scope(char **output, char *prefix, - pmix_scope_t *src, - pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_scope(char **output, char *prefix, + pmix_scope_t *src, + pmix_data_type_t type) { char *prefx; @@ -1087,9 +1000,9 @@ pmix_status_t pmix_bfrop_print_scope(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_range(char **output, char *prefix, - pmix_data_range_t *src, - pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_range(char **output, char *prefix, + pmix_data_range_t *src, + pmix_data_type_t type) { char *prefx; @@ -1112,10 +1025,9 @@ pmix_status_t pmix_bfrop_print_range(char **output, char *prefix, return PMIX_SUCCESS; } - -pmix_status_t pmix_bfrop_print_cmd(char **output, char *prefix, - pmix_cmd_t *src, - pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_cmd(char **output, char *prefix, + pmix_cmd_t *src, + pmix_data_type_t type) { char *prefx; @@ -1139,9 +1051,9 @@ pmix_status_t pmix_bfrop_print_cmd(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_infodirs(char **output, char *prefix, - pmix_info_directives_t *src, - pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_info_directives(char **output, char *prefix, + pmix_info_directives_t *src, + pmix_data_type_t type) { char *prefx; @@ -1165,8 +1077,9 @@ pmix_status_t pmix_bfrop_print_infodirs(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_bo(char **output, char *prefix, - pmix_byte_object_t *src, pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_datatype(char **output, char *prefix, + pmix_data_type_t *src, + pmix_data_type_t type) { char *prefx; @@ -1181,18 +1094,14 @@ pmix_status_t pmix_bfrop_print_bo(char **output, char *prefix, /* if src is NULL, just print data type and return */ if (NULL == src) { - if (0 > asprintf(output, "%sData type: PMIX_BYTE_OBJECT\tValue: NULL pointer", prefx)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_DATA_TYPE\tValue: NULL pointer", prefx); if (prefx != prefix) { free(prefx); } return PMIX_SUCCESS; } - if (0 > asprintf(output, "%sData type: PMIX_BYTE_OBJECT\tSize: %ld", prefx, (long)src->size)) { - return PMIX_ERR_NOMEM; - } + asprintf(output, "%sData type: PMIX_DATA_TYPE\tValue: %s", prefx, PMIx_Data_type_string(*src)); if (prefx != prefix) { free(prefx); } @@ -1200,8 +1109,8 @@ pmix_status_t pmix_bfrop_print_bo(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_ptr(char **output, char *prefix, - void *src, pmix_data_type_t type) +int pmix_bfrops_base_print_bo(char **output, char *prefix, + pmix_byte_object_t *src, pmix_data_type_t type) { char *prefx; @@ -1214,9 +1123,16 @@ pmix_status_t pmix_bfrop_print_ptr(char **output, char *prefix, prefx = prefix; } - if (0 > asprintf(output, "%sData type: PMIX_POINTER\tAddress: %p", prefx, src)) { - return PMIX_ERR_NOMEM; + /* if src is NULL, just print data type and return */ + if (NULL == src) { + asprintf(output, "%sData type: PMIX_BYTE_OBJECT\tValue: NULL pointer", prefx); + if (prefx != prefix) { + free(prefx); + } + return PMIX_SUCCESS; } + + asprintf(output, "%sData type: PMIX_BYTE_OBJECT\tSize: %ld", prefx, (long)src->size); if (prefx != prefix) { free(prefx); } @@ -1224,8 +1140,31 @@ pmix_status_t pmix_bfrop_print_ptr(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_pstate(char **output, char *prefix, - pmix_proc_state_t *src, pmix_data_type_t type) +int pmix_bfrops_base_print_ptr(char **output, char *prefix, + void *src, pmix_data_type_t type) +{ + char *prefx; + + /* deal with NULL prefix */ + if (NULL == prefix) { + if (0 > asprintf(&prefx, " ")) { + return PMIX_ERR_NOMEM; + } + } else { + prefx = prefix; + } + + asprintf(output, "%sData type: PMIX_POINTER\tAddress: %p", prefx, src); + if (prefx != prefix) { + free(prefx); + } + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_print_pstate(char **output, char *prefix, + pmix_proc_state_t *src, + pmix_data_type_t type) { char *prefx; @@ -1249,8 +1188,9 @@ pmix_status_t pmix_bfrop_print_pstate(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_pinfo(char **output, char *prefix, - pmix_proc_info_t *src, pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_pinfo(char **output, char *prefix, + pmix_proc_info_t *src, + pmix_data_type_t type) { char *prefx; pmix_status_t rc = PMIX_SUCCESS; @@ -1270,7 +1210,7 @@ pmix_status_t pmix_bfrop_print_pinfo(char **output, char *prefix, goto done; } - if (PMIX_SUCCESS != (rc = pmix_bfrop_print_proc(&tmp, p2, &src->proc, PMIX_PROC))) { + if (PMIX_SUCCESS != (rc = pmix_bfrops_base_print_proc(&tmp, p2, &src->proc, PMIX_PROC))) { free(p2); goto done; } @@ -1291,8 +1231,9 @@ pmix_status_t pmix_bfrop_print_pinfo(char **output, char *prefix, return rc; } -pmix_status_t pmix_bfrop_print_darray(char **output, char *prefix, - pmix_data_array_t *src, pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_darray(char **output, char *prefix, + pmix_data_array_t *src, + pmix_data_type_t type) { char *prefx; @@ -1316,8 +1257,9 @@ pmix_status_t pmix_bfrop_print_darray(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_query(char **output, char *prefix, - pmix_query_t *src, pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_query(char **output, char *prefix, + pmix_query_t *src, + pmix_data_type_t type) { char *prefx, *p2; pmix_status_t rc = PMIX_SUCCESS; @@ -1362,7 +1304,7 @@ pmix_status_t pmix_bfrop_print_query(char **output, char *prefix, /* now print the qualifiers */ if (0 < src->nqual) { for (n=0; n < src->nqual; n++) { - if (PMIX_SUCCESS != (rc = pmix_bfrop_print_info(&t2, p2, &src->qualifiers[n], PMIX_PROC))) { + if (PMIX_SUCCESS != (rc = pmix_bfrops_base_print_info(&t2, p2, &src->qualifiers[n], PMIX_PROC))) { free(p2); goto done; } @@ -1388,8 +1330,9 @@ pmix_status_t pmix_bfrop_print_query(char **output, char *prefix, return rc; } -pmix_status_t pmix_bfrop_print_rank(char **output, char *prefix, - pmix_rank_t *src, pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_rank(char **output, char *prefix, + pmix_rank_t *src, + pmix_data_type_t type) { char *prefx; int rc; @@ -1432,9 +1375,9 @@ pmix_status_t pmix_bfrop_print_rank(char **output, char *prefix, return PMIX_SUCCESS; } -pmix_status_t pmix_bfrop_print_alloc_directive(char **output, char *prefix, - pmix_alloc_directive_t *src, - pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_alloc_directive(char **output, char *prefix, + pmix_alloc_directive_t *src, + pmix_data_type_t type) { char *prefx; @@ -1460,8 +1403,8 @@ pmix_status_t pmix_bfrop_print_alloc_directive(char **output, char *prefix, /**** DEPRECATED ****/ -pmix_status_t pmix_bfrop_print_array(char **output, char *prefix, - pmix_info_array_t *src, pmix_data_type_t type) +pmix_status_t pmix_bfrops_base_print_array(char **output, char *prefix, + pmix_info_array_t *src, pmix_data_type_t type) { size_t j; char *tmp, *tmp2, *tmp3, *pfx; @@ -1477,7 +1420,7 @@ pmix_status_t pmix_bfrop_print_array(char **output, char *prefix, s1 = (pmix_info_t*)src->array; for (j=0; j < src->size; j++) { - pmix_bfrop_print_info(&tmp2, pfx, &s1[j], PMIX_INFO); + pmix_bfrops_base_print_info(&tmp2, pfx, &s1[j], PMIX_INFO); if (0 > asprintf(&tmp3, "%s%s", tmp, tmp2)) { free(tmp); free(tmp2); diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_select.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_select.c new file mode 100644 index 0000000000..5a65caaf0d --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_select.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include +#include + +#include + +#include "src/mca/mca.h" +#include "src/mca/base/base.h" + +#include "src/mca/bfrops/base/base.h" + +static bool selected = false; + +/* Function for selecting a prioritized list of components + * from all those that are available. */ +int pmix_bfrop_base_select(void) +{ + pmix_mca_base_component_list_item_t *cli = NULL; + pmix_mca_base_component_t *component = NULL; + pmix_mca_base_module_t *module = NULL; + pmix_bfrops_module_t *nmodule; + pmix_bfrops_base_active_module_t *newmodule, *mod; + int rc, priority; + bool inserted; + + if (selected) { + /* ensure we don't do this twice */ + return PMIX_SUCCESS; + } + selected = true; + + /* Query all available components and ask if they have a module */ + PMIX_LIST_FOREACH(cli, &pmix_bfrops_base_framework.framework_components, pmix_mca_base_component_list_item_t) { + component = (pmix_mca_base_component_t *) cli->cli_component; + + pmix_output_verbose(5, pmix_bfrops_base_framework.framework_output, + "mca:bfrops:select: checking available component %s", component->pmix_mca_component_name); + + /* If there's no query function, skip it */ + if (NULL == component->pmix_mca_query_component) { + pmix_output_verbose(5, pmix_bfrops_base_framework.framework_output, + "mca:bfrops:select: Skipping component [%s]. It does not implement a query function", + component->pmix_mca_component_name ); + continue; + } + + /* Query the component */ + pmix_output_verbose(5, pmix_bfrops_base_framework.framework_output, + "mca:bfrops:select: Querying component [%s]", + component->pmix_mca_component_name); + rc = component->pmix_mca_query_component(&module, &priority); + + /* If no module was returned, then skip component */ + if (PMIX_SUCCESS != rc || NULL == module) { + pmix_output_verbose(5, pmix_bfrops_base_framework.framework_output, + "mca:bfrops:select: Skipping component [%s]. Query failed to return a module", + component->pmix_mca_component_name ); + continue; + } + nmodule = (pmix_bfrops_module_t*) module; + + /* give it a chance to initialize */ + if (NULL != nmodule->init) { + if (PMIX_SUCCESS != nmodule->init()) { + /* reject the module */ + continue; + } + } + + /* If we got a module, keep it */ + /* add to the list of selected modules */ + newmodule = PMIX_NEW(pmix_bfrops_base_active_module_t); + newmodule->pri = priority; + newmodule->module = nmodule; + newmodule->component = (pmix_bfrops_base_component_t*)cli->cli_component; + + /* maintain priority order */ + inserted = false; + PMIX_LIST_FOREACH(mod, &pmix_bfrops_globals.actives, pmix_bfrops_base_active_module_t) { + if (priority > mod->pri) { + pmix_list_insert_pos(&pmix_bfrops_globals.actives, + (pmix_list_item_t*)mod, &newmodule->super); + inserted = true; + break; + } + } + if (!inserted) { + /* must be lowest priority - add to end */ + pmix_list_append(&pmix_bfrops_globals.actives, &newmodule->super); + } + } + + if (4 < pmix_output_get_verbosity(pmix_bfrops_base_framework.framework_output)) { + pmix_output(0, "Final Bfrop priorities"); + /* show the prioritized list */ + PMIX_LIST_FOREACH(mod, &pmix_bfrops_globals.actives, pmix_bfrops_base_active_module_t) { + pmix_output(0, "\tBfrop: %s Priority: %d", mod->component->base.pmix_mca_component_name, mod->pri); + } + } + + return PMIX_SUCCESS;; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_stubs.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_stubs.c new file mode 100644 index 0000000000..04543b83cc --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_stubs.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/include/pmix_globals.h" + +#include "src/mca/bfrops/base/base.h" + +PMIX_EXPORT const char* PMIx_Data_type_string(pmix_data_type_t type) +{ + pmix_bfrops_base_active_module_t *active; + char *reply; + + if (!pmix_bfrops_globals.initialized) { + return "NOT INITIALIZED"; + } + + PMIX_LIST_FOREACH(active, &pmix_bfrops_globals.actives, pmix_bfrops_base_active_module_t) { + if (NULL != active->module->data_type_string) { + if (NULL != (reply = (char*)active->module->data_type_string(type))) { + return reply; + } + } + } + return "UNKNOWN"; +} + +char* pmix_bfrops_base_get_available_modules(void) +{ + pmix_bfrops_base_active_module_t *active; + char **tmp=NULL, *reply=NULL; + + if (!pmix_bfrops_globals.initialized) { + return NULL; + } + + PMIX_LIST_FOREACH(active, &pmix_bfrops_globals.actives, pmix_bfrops_base_active_module_t) { + pmix_argv_append_nosize(&tmp, active->component->base.pmix_mca_component_name); + } + if (NULL != tmp) { + reply = pmix_argv_join(tmp, ','); + pmix_argv_free(tmp); + } + return reply; +} + +pmix_bfrops_module_t* pmix_bfrops_base_assign_module(const char *version) +{ + pmix_bfrops_base_active_module_t *active; + pmix_bfrops_module_t *mod; + char **tmp=NULL; + int i; + + if (!pmix_bfrops_globals.initialized) { + return NULL; + } + + if (NULL != version) { + tmp = pmix_argv_split(version, ','); + } + + PMIX_LIST_FOREACH(active, &pmix_bfrops_globals.actives, pmix_bfrops_base_active_module_t) { + if (NULL == tmp) { + if (NULL != (mod = active->component->assign_module())) { + return mod; + } + } else { + for (i=0; NULL != tmp[i]; i++) { + if (0 == strcmp(tmp[i], active->component->base.pmix_mca_component_name)) { + if (NULL != (mod = active->component->assign_module())) { + pmix_argv_free(tmp); + return mod; + } + } + } + } + } + + /* we only get here if nothing was found */ + if (NULL != tmp) { + pmix_argv_free(tmp); + } + return NULL; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_unpack.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_unpack.c new file mode 100644 index 0000000000..b9cf3b3059 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/base/bfrop_base_unpack.c @@ -0,0 +1,1678 @@ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2016 Mellanox Technologies, Inc. + * All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include + +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/util/output.h" +#include "src/include/pmix_globals.h" +#include "src/mca/bfrops/bfrops_types.h" +#include "src/mca/bfrops/base/base.h" + +/* Unpack generic size macros */ +#define UNPACK_SIZE_MISMATCH(unpack_type, remote_type, ret) \ + do { \ + switch(remote_type) { \ + case PMIX_UINT8: \ + UNPACK_SIZE_MISMATCH_FOUND(unpack_type, uint8_t, remote_type); \ + break; \ + case PMIX_INT8: \ + UNPACK_SIZE_MISMATCH_FOUND(unpack_type, int8_t, remote_type); \ + break; \ + case PMIX_UINT16: \ + UNPACK_SIZE_MISMATCH_FOUND(unpack_type, uint16_t, remote_type); \ + break; \ + case PMIX_INT16: \ + UNPACK_SIZE_MISMATCH_FOUND(unpack_type, int16_t, remote_type); \ + break; \ + case PMIX_UINT32: \ + UNPACK_SIZE_MISMATCH_FOUND(unpack_type, uint32_t, remote_type); \ + break; \ + case PMIX_INT32: \ + UNPACK_SIZE_MISMATCH_FOUND(unpack_type, int32_t, remote_type); \ + break; \ + case PMIX_UINT64: \ + UNPACK_SIZE_MISMATCH_FOUND(unpack_type, uint64_t, remote_type); \ + break; \ + case PMIX_INT64: \ + UNPACK_SIZE_MISMATCH_FOUND(unpack_type, int64_t, remote_type); \ + break; \ + default: \ + ret = PMIX_ERR_NOT_FOUND; \ + } \ + } while (0) + +/* NOTE: do not need to deal with endianness here, as the unpacking of + the underling sender-side type will do that for us. Repeat: the + data in tmpbuf[] is already in host byte order. */ +#define UNPACK_SIZE_MISMATCH_FOUND(unpack_type, tmptype, tmpbfroptype) \ + do { \ + int32_t i; \ + tmptype *tmpbuf = (tmptype*)malloc(sizeof(tmptype) * (*num_vals)); \ + ret = unpack_gentype(buffer, tmpbuf, num_vals, tmpbfroptype); \ + for (i = 0 ; i < *num_vals ; ++i) { \ + ((unpack_type*) dest)[i] = (unpack_type)(tmpbuf[i]); \ + } \ + free(tmpbuf); \ + } while (0) + + +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_bfrop_type_info_t *info; + + pmix_output_verbose(20, pmix_globals.debug_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(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); + assert(0); + 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(regtypes, type))) { + PMIX_ERROR_LOG(PMIX_ERR_UNPACK_FAILURE); + return PMIX_ERR_UNPACK_FAILURE; + } + + return info->odti_unpack_fn(buffer, dst, num_vals, type); +} + +pmix_status_t pmix_bfrops_base_unpack(pmix_pointer_array_t *regtypes, + pmix_buffer_t *buffer, + void *dst, int32_t *num_vals, + pmix_data_type_t type) +{ + pmix_status_t rc, ret; + int32_t local_num, n=1; + pmix_data_type_t local_type; + + /* check for error */ + if (NULL == buffer || NULL == dst || NULL == num_vals) { + return PMIX_ERR_BAD_PARAM; + } + + /* if user provides a zero for num_vals, then there is no storage allocated + * so return an appropriate error + */ + if (0 == *num_vals) { + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: inadequate space ( %p, %p, %lu, %d )\n", + (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); + return PMIX_ERR_UNPACK_INADEQUATE_SPACE; + } + + /** Unpack the declared number of values + * REMINDER: it is possible that the buffer is corrupted and that + * the BFROP will *think* there is a proper int32_t variable at the + * beginning of the unpack region - but that the value is bogus (e.g., just + * a byte field in a string array that so happens to have a value that + * matches the int32_t data type flag). Therefore, this error check is + * NOT completely safe. This is true for ALL unpack functions, not just + * int32_t as used here. + */ + if (PMIX_BFROP_BUFFER_FULLY_DESC == buffer->type) { + if (PMIX_SUCCESS != (rc = pmix_bfrop_get_data_type(buffer, &local_type))) { + *num_vals = 0; + /* don't error log here as the user may be unpacking past + * the end of the buffer, which isn't necessarily an error */ + return rc; + } + if (PMIX_INT32 != local_type) { /* if the length wasn't first, then error */ + *num_vals = 0; + return PMIX_ERR_UNPACK_FAILURE; + } + } + + n=1; + if (PMIX_SUCCESS != (rc = pmix_bfrops_base_unpack_int32(buffer, &local_num, &n, PMIX_INT32))) { + *num_vals = 0; + /* don't error log here as the user may be unpacking past + * the end of the buffer, which isn't necessarily an error */ + return rc; + } + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: found %d values for %d provided storage", + local_num, *num_vals); + + /** if the storage provided is inadequate, set things up + * to unpack as much as we can and to return an error code + * indicating that everything was not unpacked - the buffer + * is left in a state where it can not be further unpacked. + */ + if (local_num > *num_vals) { + local_num = *num_vals; + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: inadequate space ( %p, %p, %lu, %d )\n", + (void*)buffer, dst, (long unsigned int)*num_vals, (int)type); + ret = PMIX_ERR_UNPACK_INADEQUATE_SPACE; + } else { /** enough or more than enough storage */ + *num_vals = local_num; /** let the user know how many we actually unpacked */ + ret = PMIX_SUCCESS; + } + + /** Unpack the value(s) */ + if (PMIX_SUCCESS != (rc = pmix_bfrops_base_unpack_buffer(regtypes, buffer, dst, &local_num, type))) { + *num_vals = 0; + ret = rc; + } + + return ret; +} + +static pmix_status_t unpack_gentype(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + switch(type) { + case PMIX_INT8: + case PMIX_UINT8: + return pmix_bfrops_base_unpack_byte(buffer, dest, num_vals, type); + break; + + case PMIX_INT16: + case PMIX_UINT16: + return pmix_bfrops_base_unpack_int16(buffer, dest, num_vals, type); + break; + + case PMIX_INT32: + case PMIX_UINT32: + return pmix_bfrops_base_unpack_int32(buffer, dest, num_vals, type); + break; + + case PMIX_INT64: + case PMIX_UINT64: + return pmix_bfrops_base_unpack_int64(buffer, dest, num_vals, type); + break; + + default: + return PMIX_ERR_UNKNOWN_DATA_TYPE; + } +} + +/* UNPACK GENERIC SYSTEM TYPES */ + +/* + * BOOL + */ + pmix_status_t pmix_bfrops_base_unpack_bool(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) + { + int32_t i; + uint8_t *src; + bool *dst; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_bool * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, *num_vals)) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + src = (uint8_t*)buffer->unpack_ptr; + dst = (bool*)dest; + + for (i=0; i < *num_vals; i++) { + if (src[i]) { + dst[i] = true; + } else { + dst[i] = false; + } + } + + /* update buffer pointer */ + buffer->unpack_ptr += *num_vals; + + return PMIX_SUCCESS; +} + +/* + * INT + */ +pmix_status_t pmix_bfrops_base_unpack_int(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_status_t ret; + pmix_data_type_t remote_type; + + if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &remote_type))) { + return ret; + } + + if (remote_type == BFROP_TYPE_INT) { + /* fast path it if the sizes are the same */ + /* Turn around and unpack the real type */ + if (PMIX_SUCCESS != (ret = unpack_gentype(buffer, dest, num_vals, BFROP_TYPE_INT))) { + } + } else { + /* slow path - types are different sizes */ + UNPACK_SIZE_MISMATCH(int, remote_type, ret); + } + + return ret; +} + +/* + * SIZE_T + */ +pmix_status_t pmix_bfrops_base_unpack_sizet(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_status_t ret; + pmix_data_type_t remote_type; + + if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &remote_type))) { + return ret; + } + + if (remote_type == BFROP_TYPE_SIZE_T) { + /* fast path it if the sizes are the same */ + /* Turn around and unpack the real type */ + if (PMIX_SUCCESS != (ret = unpack_gentype(buffer, dest, num_vals, BFROP_TYPE_SIZE_T))) { + } + } else { + /* slow path - types are different sizes */ + UNPACK_SIZE_MISMATCH(size_t, remote_type, ret); + } + + return ret; +} + +/* + * PID_T + */ +pmix_status_t pmix_bfrops_base_unpack_pid(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_status_t ret; + pmix_data_type_t remote_type; + + if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &remote_type))) { + return ret; + } + + if (remote_type == BFROP_TYPE_PID_T) { + /* fast path it if the sizes are the same */ + /* Turn around and unpack the real type */ + if (PMIX_SUCCESS != (ret = unpack_gentype(buffer, dest, num_vals, BFROP_TYPE_PID_T))) { + } + } else { + /* slow path - types are different sizes */ + UNPACK_SIZE_MISMATCH(pid_t, remote_type, ret); + } + + return ret; +} + + +/* UNPACK FUNCTIONS FOR NON-GENERIC SYSTEM TYPES */ + +/* + * BYTE, CHAR, INT8 + */ +pmix_status_t pmix_bfrops_base_unpack_byte(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_byte * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, *num_vals)) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + memcpy(dest, buffer->unpack_ptr, *num_vals); + + /* update buffer pointer */ + buffer->unpack_ptr += *num_vals; + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_int16(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + int32_t i; + uint16_t tmp, *desttmp = (uint16_t*) dest; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_int16 * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + for (i = 0; i < (*num_vals); ++i) { + memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) ); + tmp = pmix_ntohs(tmp); + memcpy(&desttmp[i], &tmp, sizeof(tmp)); + buffer->unpack_ptr += sizeof(tmp); + } + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_int32(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + int32_t i; + uint32_t tmp, *desttmp = (uint32_t*) dest; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_int32 * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + for (i = 0; i < (*num_vals); ++i) { + memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) ); + tmp = ntohl(tmp); + memcpy(&desttmp[i], &tmp, sizeof(tmp)); + buffer->unpack_ptr += sizeof(tmp); + } + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_datatype(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_int16(buffer, dest, num_vals, type); +} + +pmix_status_t pmix_bfrops_base_unpack_int64(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + int32_t i; + uint64_t tmp, *desttmp = (uint64_t*) dest; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_int64 * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(tmp))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + for (i = 0; i < (*num_vals); ++i) { + memcpy( &(tmp), buffer->unpack_ptr, sizeof(tmp) ); + tmp = pmix_ntoh64(tmp); + memcpy(&desttmp[i], &tmp, sizeof(tmp)); + buffer->unpack_ptr += sizeof(tmp); + } + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_string(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_status_t ret; + int32_t i, len, n=1; + char **sdest = (char**) dest; + + for (i = 0; i < (*num_vals); ++i) { + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int32(buffer, &len, &n, PMIX_INT32))) { + return ret; + } + if (0 == len) { /* zero-length string - unpack the NULL */ + sdest[i] = NULL; + } else { + sdest[i] = (char*)malloc(len); // NULL terminator is included + if (NULL == sdest[i]) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, sdest[i], &len, PMIX_BYTE))) { + return ret; + } + } + } + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_float(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + int32_t i, n; + float *desttmp = (float*) dest, tmp; + pmix_status_t ret; + char *convert; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_float * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(float))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + for (i = 0; i < (*num_vals); ++i) { + n=1; + convert = NULL; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &convert, &n, PMIX_STRING))) { + return ret; + } + if (NULL != convert) { + tmp = strtof(convert, NULL); + memcpy(&desttmp[i], &tmp, sizeof(tmp)); + free(convert); + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_double(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + int32_t i, n; + double *desttmp = (double*) dest, tmp; + pmix_status_t ret; + char *convert; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_double * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(double))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + for (i = 0; i < (*num_vals); ++i) { + n=1; + convert = NULL; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &convert, &n, PMIX_STRING))) { + return ret; + } + if (NULL != convert) { + tmp = strtod(convert, NULL); + memcpy(&desttmp[i], &tmp, sizeof(tmp)); + free(convert); + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_timeval(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + int32_t i, n; + int64_t tmp[2]; + struct timeval *desttmp = (struct timeval *) dest, tt; + pmix_status_t ret; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_timeval * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, (*num_vals)*sizeof(struct timeval))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + for (i = 0; i < (*num_vals); ++i) { + n=2; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int64(buffer, tmp, &n, PMIX_INT64))) { + return ret; + } + tt.tv_sec = tmp[0]; + tt.tv_usec = tmp[1]; + memcpy(&desttmp[i], &tt, sizeof(tt)); + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_time(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + int32_t i, n; + time_t *desttmp = (time_t *) dest, tmp; + pmix_status_t ret; + uint64_t ui64; + + /* time_t is a system-dependent size, so cast it + * to uint64_t as a generic safe size + */ + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_time * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, (*num_vals)*(sizeof(uint64_t)))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + for (i = 0; i < (*num_vals); ++i) { + n=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int64(buffer, &ui64, &n, PMIX_UINT64))) { + return ret; + } + tmp = (time_t)ui64; + memcpy(&desttmp[i], &tmp, sizeof(tmp)); + } + return PMIX_SUCCESS; +} + + +pmix_status_t pmix_bfrops_base_unpack_status(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack_status * %d\n", (int)*num_vals); + + /* check to see if there's enough data in buffer */ + if (pmix_bfrop_too_small(buffer, (*num_vals)*(sizeof(pmix_status_t)))) { + return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER; + } + + /* unpack the data */ + return pmix_bfrops_base_unpack_int32(buffer, dest, num_vals, PMIX_INT32); +} + + +/* UNPACK FUNCTIONS FOR GENERIC PMIX TYPES */ + +/* + * PMIX_VALUE + */ +pmix_status_t pmix_bfrops_base_unpack_val(pmix_buffer_t *buffer, + pmix_value_t *val) +{ + int m; + pmix_status_t ret; + + m = 1; + switch (val->type) { + case PMIX_UNDEF: + break; + case PMIX_BOOL: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_bool(buffer, &val->data.flag, &m, PMIX_BOOL))) { + return ret; + } + break; + case PMIX_BYTE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, &val->data.byte, &m, PMIX_BYTE))) { + return ret; + } + break; + case PMIX_STRING: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &val->data.string, &m, PMIX_STRING))) { + return ret; + } + break; + case PMIX_SIZE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, &val->data.size, &m, PMIX_SIZE))) { + return ret; + } + break; + case PMIX_PID: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_pid(buffer, &val->data.pid, &m, PMIX_PID))) { + return ret; + } + break; + case PMIX_INT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int(buffer, &val->data.integer, &m, PMIX_INT))) { + return ret; + } + break; + case PMIX_INT8: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, &val->data.int8, &m, PMIX_INT8))) { + return ret; + } + break; + case PMIX_INT16: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int16(buffer, &val->data.int16, &m, PMIX_INT16))) { + return ret; + } + break; + case PMIX_INT32: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int32(buffer, &val->data.int32, &m, PMIX_INT32))) { + return ret; + } + break; + case PMIX_INT64: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int64(buffer, &val->data.int64, &m, PMIX_INT64))) { + return ret; + } + break; + case PMIX_UINT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int(buffer, &val->data.uint, &m, PMIX_UINT))) { + return ret; + } + break; + case PMIX_UINT8: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, &val->data.uint8, &m, PMIX_UINT8))) { + return ret; + } + break; + case PMIX_UINT16: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int16(buffer, &val->data.uint16, &m, PMIX_UINT16))) { + return ret; + } + break; + case PMIX_UINT32: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int32(buffer, &val->data.uint32, &m, PMIX_UINT32))) { + return ret; + } + break; + case PMIX_UINT64: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int64(buffer, &val->data.uint64, &m, PMIX_UINT64))) { + return ret; + } + break; + case PMIX_FLOAT: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_float(buffer, &val->data.fval, &m, PMIX_FLOAT))) { + return ret; + } + break; + case PMIX_DOUBLE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_double(buffer, &val->data.dval, &m, PMIX_DOUBLE))) { + return ret; + } + break; + case PMIX_TIMEVAL: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_timeval(buffer, &val->data.tv, &m, PMIX_TIMEVAL))) { + return ret; + } + break; + case PMIX_TIME: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_time(buffer, &val->data.time, &m, PMIX_TIME))) { + return ret; + } + break; + case PMIX_STATUS: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_status(buffer, &val->data.status, &m, PMIX_STATUS))) { + return ret; + } + 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; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_proc(buffer, val->data.proc, &m, PMIX_PROC))) { + return ret; + } + break; + case PMIX_PROC_RANK: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_rank(buffer, &val->data.rank, &m, PMIX_PROC_RANK))) { + return ret; + } + break; + case PMIX_BYTE_OBJECT: + case PMIX_COMPRESSED_STRING: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_bo(buffer, &val->data.bo, &m, PMIX_BYTE_OBJECT))) { + return ret; + } + break; + case PMIX_PERSIST: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_persist(buffer, &val->data.proc, &m, PMIX_PERSIST))) { + return ret; + } + break; + case PMIX_POINTER: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_ptr(buffer, &val->data.ptr, &m, PMIX_POINTER))) { + return ret; + } + break; + case PMIX_SCOPE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_scope(buffer, &val->data.scope, &m, PMIX_SCOPE))) { + return ret; + } + break; + case PMIX_DATA_RANGE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_range(buffer, &val->data.range, &m, PMIX_DATA_RANGE))) { + return ret; + } + break; + case PMIX_PROC_STATE: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_pstate(buffer, &val->data.state, &m, PMIX_PROC_STATE))) { + return ret; + } + 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; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_pinfo(buffer, val->data.pinfo, &m, PMIX_PROC_INFO))) { + return ret; + } + 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; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_darray(buffer, val->data.darray, &m, PMIX_DATA_ARRAY))) { + return ret; + } + break; + case PMIX_QUERY: + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_query(buffer, val->data.darray, &m, PMIX_QUERY))) { + return ret; + } + break; + /**** DEPRECATED ****/ + case PMIX_INFO_ARRAY: + /* this field is now a pointer, so we must allocate storage for it */ + val->data.array = (pmix_info_array_t*)malloc(sizeof(pmix_info_array_t)); + if (NULL == val->data.array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_array(buffer, val->data.array, &m, PMIX_INFO_ARRAY))) { + return ret; + } + break; + /********************/ + default: + pmix_output(0, "UNPACK-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)val->type); + return PMIX_ERROR; + } + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_value(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_value_t *ptr; + int32_t i, n; + pmix_status_t ret; + + ptr = (pmix_value_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + /* unpack the type */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &ptr[i].type))) { + PMIX_ERROR_LOG(ret); + return ret; + } + /* unpack value */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_val(buffer, &ptr[i])) ) { + PMIX_ERROR_LOG(ret); + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_info(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_info_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + char *tmp; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d info", *num_vals); + + ptr = (pmix_info_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + memset(ptr[i].key, 0, sizeof(ptr[i].key)); + memset(&ptr[i].value, 0, sizeof(pmix_value_t)); + /* unpack key */ + m=1; + tmp = NULL; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { + PMIX_ERROR_LOG(ret); + return ret; + } + if (NULL == tmp) { + return PMIX_ERROR; + } + (void)strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN); + free(tmp); + /* unpack the directives */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_info_directives(buffer, &ptr[i].flags, &m, PMIX_INFO_DIRECTIVES))) { + return ret; + } + /* unpack value - since the value structure is statically-defined + * instead of a pointer in this struct, we directly unpack it to + * avoid the malloc */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &ptr[i].value.type))) { + return ret; + } + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: info type %d", ptr[i].value.type); + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_val(buffer, &ptr[i].value))) { + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_pdata(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_pdata_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + char *tmp; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d pdata", *num_vals); + + ptr = (pmix_pdata_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + PMIX_PDATA_CONSTRUCT(&ptr[i]); + /* unpack the proc */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_proc(buffer, &ptr[i].proc, &m, PMIX_PROC))) { + return ret; + } + /* unpack key */ + m=1; + tmp = NULL; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { + return ret; + } + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERROR); + return PMIX_ERROR; + } + (void)strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN); + free(tmp); + /* unpack value - since the value structure is statically-defined + * instead of a pointer in this struct, we directly unpack it to + * avoid the malloc */ + if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &ptr[i].value.type))) { + PMIX_ERROR_LOG(ret); + return ret; + } + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: pdata type %d %s", ptr[i].value.type, ptr[i].value.data.string); + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_val(buffer, &ptr[i].value))) { + PMIX_ERROR_LOG(ret); + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_buf(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_buffer_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + size_t nbytes; + + ptr = (pmix_buffer_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + PMIX_CONSTRUCT(&ptr[i], pmix_buffer_t); + /* unpack the type of buffer */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, &ptr[i].type, &m, PMIX_BYTE))) { + return ret; + } + /* unpack the number of bytes */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, &nbytes, &m, PMIX_SIZE))) { + return ret; + } + m = nbytes; + /* setup the buffer's data region */ + if (0 < nbytes) { + ptr[i].base_ptr = (char*)malloc(nbytes); + if (NULL == ptr[i].base_ptr) { + return PMIX_ERR_NOMEM; + } + /* unpack the bytes */ + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, ptr[i].base_ptr, &m, PMIX_BYTE))) { + return ret; + } + } + ptr[i].pack_ptr = ptr[i].base_ptr + m; + ptr[i].unpack_ptr = ptr[i].base_ptr; + ptr[i].bytes_allocated = nbytes; + ptr[i].bytes_used = m; + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_proc(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_proc_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + char *tmp; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d procs", *num_vals); + + ptr = (pmix_proc_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: init proc[%d]", i); + memset(&ptr[i], 0, sizeof(pmix_proc_t)); + /* unpack nspace */ + m=1; + tmp = NULL; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { + PMIX_ERROR_LOG(ret); + return ret; + } + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERROR); + return PMIX_ERROR; + } + (void)strncpy(ptr[i].nspace, tmp, PMIX_MAX_NSLEN); + free(tmp); + /* unpack the rank */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_rank(buffer, &ptr[i].rank, &m, PMIX_PROC_RANK))) { + PMIX_ERROR_LOG(ret); + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_app(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_app_t *ptr; + int32_t i, k, n, m; + pmix_status_t ret; + int32_t nval; + char *tmp; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d apps", *num_vals); + + ptr = (pmix_app_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + /* initialize the fields */ + PMIX_APP_CONSTRUCT(&ptr[i]); + /* unpack cmd */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &ptr[i].cmd, &m, PMIX_STRING))) { + return ret; + } + /* unpack argc */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int(buffer, &nval, &m, PMIX_INT32))) { + return ret; + } + /* unpack argv */ + for (k=0; k < nval; k++) { + m=1; + tmp = NULL; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { + return ret; + } + if (NULL == tmp) { + return PMIX_ERROR; + } + pmix_argv_append_nosize(&ptr[i].argv, tmp); + free(tmp); + } + /* unpack env */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int32(buffer, &nval, &m, PMIX_INT32))) { + return ret; + } + for (k=0; k < nval; k++) { + m=1; + tmp = NULL; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { + return ret; + } + if (NULL == tmp) { + return PMIX_ERROR; + } + pmix_argv_append_nosize(&ptr[i].env, tmp); + free(tmp); + } + /* unpack cwd */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &ptr[i].cwd, &m, PMIX_STRING))) { + return ret; + } + /* unpack maxprocs */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int(buffer, &ptr[i].maxprocs, &m, PMIX_INT))) { + return ret; + } + /* unpack info array */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, &ptr[i].ninfo, &m, PMIX_SIZE))) { + return ret; + } + if (0 < ptr[i].ninfo) { + PMIX_INFO_CREATE(ptr[i].info, ptr[i].ninfo); + m = ptr[i].ninfo; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_info(buffer, ptr[i].info, &m, PMIX_INFO))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_kval(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_kval_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d kvals", *num_vals); + + ptr = (pmix_kval_t*) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + PMIX_CONSTRUCT(&ptr[i], pmix_kval_t); + /* unpack the key */ + m = 1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &ptr[i].key, &m, PMIX_STRING))) { + PMIX_ERROR_LOG(ret); + return ret; + } + /* allocate the space */ + ptr[i].value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + /* unpack the value */ + m = 1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_value(buffer, ptr[i].value, &m, PMIX_VALUE))) { + PMIX_ERROR_LOG(ret); + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_modex(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_modex_data_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d modex", *num_vals); + + ptr = (pmix_modex_data_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + memset(&ptr[i], 0, sizeof(pmix_modex_data_t)); + /* unpack the number of bytes */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { + return ret; + } + if (0 < ptr[i].size) { + ptr[i].blob = (uint8_t*)malloc(ptr[i].size * sizeof(uint8_t)); + m=ptr[i].size; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, ptr[i].blob, &m, PMIX_UINT8))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + + +pmix_status_t pmix_bfrops_base_unpack_persist(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_unpack_bo(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_byte_object_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d byte_object", *num_vals); + + ptr = (pmix_byte_object_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + memset(&ptr[i], 0, sizeof(pmix_byte_object_t)); + /* unpack the number of bytes */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { + return ret; + } + if (0 < ptr[i].size) { + ptr[i].bytes = (char*)malloc(ptr[i].size * sizeof(char)); + m=ptr[i].size; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, ptr[i].bytes, &m, PMIX_BYTE))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_ptr(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + uint8_t foo=1; + int32_t cnt=1; + + /* it obviously makes no sense to pack a pointer and + * send it somewhere else, so we just unpack the sentinel */ + return pmix_bfrops_base_unpack_byte(buffer, &foo, &cnt, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_unpack_scope(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_unpack_range(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_unpack_cmd(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); +} + +pmix_status_t pmix_bfrops_base_unpack_info_directives(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_int32(buffer, dest, num_vals, PMIX_UINT32); +} + +pmix_status_t pmix_bfrops_base_unpack_pstate(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); +} + + +pmix_status_t pmix_bfrops_base_unpack_pinfo(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_proc_info_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d pinfo", *num_vals); + + ptr = (pmix_proc_info_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + PMIX_PROC_INFO_CONSTRUCT(&ptr[i]); + /* unpack the proc */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_proc(buffer, &ptr[i].proc, &m, PMIX_PROC))) { + return ret; + } + /* unpack the hostname */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &ptr[i].hostname, &m, PMIX_STRING))) { + return ret; + } + /* unpack the executable */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, &ptr[i].executable_name, &m, PMIX_STRING))) { + return ret; + } + /* unpack pid */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_pid(buffer, &ptr[i].pid, &m, PMIX_PID))) { + return ret; + } + /* unpack state */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_pstate(buffer, &ptr[i].state, &m, PMIX_PROC_STATE))) { + return ret; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_darray(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_data_array_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d data arrays", *num_vals); + + ptr = (pmix_data_array_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + memset(&ptr[i], 0, sizeof(pmix_data_array_t)); + /* unpack the type */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrop_get_data_type(buffer, &ptr[i].type))) { + return ret; + } + /* unpack the number of array elements */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { + return ret; + } + if (0 == ptr[i].size || PMIX_UNDEF == ptr[i].type) { + /* nothing else to do */ + continue; + } + /* allocate storage for the array and unpack the array elements */ + m = ptr[i].size; + switch(ptr[i].type) { + case PMIX_BOOL: + ptr[i].array = (bool*)malloc(m * sizeof(bool)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_bool(buffer, ptr[i].array, &m, PMIX_BOOL))) { + return ret; + } + break; + case PMIX_BYTE: + case PMIX_INT8: + case PMIX_UINT8: + ptr[i].array = (uint8_t*)malloc(m * sizeof(uint8_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_byte(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_INT16: + case PMIX_UINT16: + ptr[i].array = (uint16_t*)malloc(m * sizeof(uint16_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int16(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_INT32: + case PMIX_UINT32: + ptr[i].array = (uint32_t*)malloc(m * sizeof(uint32_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int32(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_INT64: + case PMIX_UINT64: + ptr[i].array = (uint64_t*)malloc(m * sizeof(uint64_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int64(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_STRING: + ptr[i].array = (char**)malloc(m * sizeof(char*)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_SIZE: + ptr[i].array = (size_t*)malloc(m * sizeof(size_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_PID: + ptr[i].array = (pid_t*)malloc(m * sizeof(pid_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_pid(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_INT: + case PMIX_UINT: + ptr[i].array = (int*)malloc(m * sizeof(int)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_FLOAT: + ptr[i].array = (float*)malloc(m * sizeof(float)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_float(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_DOUBLE: + ptr[i].array = (double*)malloc(m * sizeof(double)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_double(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_TIMEVAL: + ptr[i].array = (struct timeval *)malloc(m * sizeof(struct timeval)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_timeval(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_TIME: + ptr[i].array = (time_t*)malloc(m * sizeof(time_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_time(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_STATUS: + ptr[i].array = (pmix_status_t*)malloc(m * sizeof(pmix_status_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_status(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_INFO: + ptr[i].array = (pmix_info_t*)malloc(m * sizeof(pmix_info_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_info(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_PROC: + ptr[i].array = (pmix_proc_t*)malloc(m * sizeof(pmix_proc_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_proc(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_BYTE_OBJECT: + case PMIX_COMPRESSED_STRING: + ptr[i].array = (pmix_byte_object_t*)malloc(m * sizeof(pmix_byte_object_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_bo(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_PERSIST: + ptr[i].array = (pmix_persistence_t*)malloc(m * sizeof(pmix_persistence_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_persist(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_POINTER: + ptr[i].array = (char*)malloc(m * sizeof(char*)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_ptr(buffer, ptr[i].array, &m, PMIX_POINTER))) { + return ret; + } + break; + case PMIX_SCOPE: + ptr[i].array = (pmix_scope_t*)malloc(m * sizeof(pmix_scope_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_scope(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_DATA_RANGE: + ptr[i].array = (pmix_data_range_t*)malloc(m * sizeof(pmix_data_range_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_range(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_PROC_STATE: + ptr[i].array = (pmix_proc_state_t*)malloc(m * sizeof(pmix_proc_state_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_pstate(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_PROC_INFO: + ptr[i].array = (pmix_proc_info_t*)malloc(m * sizeof(pmix_proc_info_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_pinfo(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + case PMIX_QUERY: + ptr[i].array = (pmix_query_t*)malloc(m * sizeof(pmix_query_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_query(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + /**** DEPRECATED ****/ + case PMIX_INFO_ARRAY: + ptr[i].array = (pmix_info_array_t*)malloc(m * sizeof(pmix_info_array_t)); + if (NULL == ptr[i].array) { + return PMIX_ERR_NOMEM; + } + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_array(buffer, ptr[i].array, &m, ptr[i].type))) { + return ret; + } + break; + /********************/ + default: + return PMIX_ERR_NOT_SUPPORTED; + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_rank(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_int32(buffer, dest, num_vals, PMIX_UINT32); +} + +pmix_status_t pmix_bfrops_base_unpack_query(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_query_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + int32_t nkeys; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d queries", *num_vals); + + ptr = (pmix_query_t *) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + PMIX_QUERY_CONSTRUCT(&ptr[i]); + /* unpack the number of keys */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_int32(buffer, &nkeys, &m, PMIX_INT32))) { + return ret; + } + if (0 < nkeys) { + /* unpack the keys */ + if (NULL == (ptr[i].keys = (char**)calloc(nkeys+1, sizeof(char*)))) { + return PMIX_ERR_NOMEM; + } + /* unpack keys */ + m=nkeys; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_string(buffer, ptr[i].keys, &m, PMIX_STRING))) { + return ret; + } + } + /* unpack the number of qualifiers */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, &ptr[i].nqual, &m, PMIX_SIZE))) { + return ret; + } + if (0 < ptr[i].nqual) { + /* unpack the qualifiers */ + PMIX_INFO_CREATE(ptr[i].qualifiers, ptr[i].nqual); + m = ptr[i].nqual; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_info(buffer, ptr[i].qualifiers, &m, PMIX_INFO))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} + +pmix_status_t pmix_bfrops_base_unpack_alloc_directive(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + return pmix_bfrops_base_unpack_byte(buffer, dest, num_vals, PMIX_UINT8); +} + + +/**** DEPRECATED ****/ +pmix_status_t pmix_bfrops_base_unpack_array(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + pmix_info_array_t *ptr; + int32_t i, n, m; + pmix_status_t ret; + + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: %d info arrays", *num_vals); + + ptr = (pmix_info_array_t*) dest; + n = *num_vals; + + for (i = 0; i < n; ++i) { + pmix_output_verbose(20, pmix_globals.debug_output, + "pmix_bfrop_unpack: init array[%d]", i); + memset(&ptr[i], 0, sizeof(pmix_info_array_t)); + /* unpack the size of this array */ + m=1; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_sizet(buffer, &ptr[i].size, &m, PMIX_SIZE))) { + return ret; + } + if (0 < ptr[i].size) { + ptr[i].array = (pmix_info_t*)malloc(ptr[i].size * sizeof(pmix_info_t)); + m=ptr[i].size; + if (PMIX_SUCCESS != (ret = pmix_bfrops_base_unpack_value(buffer, ptr[i].array, &m, PMIX_INFO))) { + return ret; + } + } + } + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/buffer_ops.h b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/bfrops.h similarity index 50% rename from opal/mca/pmix/pmix2x/pmix/src/buffer_ops/buffer_ops.h rename to opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/bfrops.h index a02bfa77a5..0260d95699 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/buffer_ops.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/bfrops.h @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. @@ -35,49 +35,91 @@ #include -#include "src/include/pmix_globals.h" -#include "src/buffer_ops/types.h" +#include "src/mca/mca.h" + +#include "bfrops_types.h" BEGIN_C_DECLS -/* A non-API function for something that happens in a number - * of places throughout the code base - transferring a value to - * another pmix_value_t structure +/* The overall objective of this framework is to provide seamless + * cross-version support for communications by allowing a process + * to communicate with a peer: + * + * (a) using a different version of the buffer operations. We are + * allowing changes in the structure compositions and/or data + * type definitions between versions. This specifically affects + * our ability to pack/unpack across versions. + * + * (b) using a different buffer type (described vs non-described). + * This resolves conflicts when one side was compiled with a + * debug option, while the other side has been "optimized". + * + * This is a mult-select framework - i.e., multiple components + * are selected and "active" at the same time. The intent is + * to have one component for each data type variation, with the + * expectation that the community will do its best not to revise + * existing data type definitions. Thus, new variations should be + * rare, and only a few components will exist. + * + * The framework itself reflects the fact that any given peer + * will utilize only one variation of the data type definitions. + * Thus, once a peer is identified, it will pass its version string + * to this framework's "assign_module" function, which will then + * pass it to each component until one returns a module capable of + * processing the given version. This module is then "attached" to + * the pmix_peer_t object so it can be used for all subsequent + * communication to/from that peer. + * + * Buffer type is included in the buffer metadata. Unfortunately, + * the metadata is not communicated at each exchange. Thus, the + * peers will indicate during the connection handshake the type + * of buffer they will use for all subsequent communications. The + * peer must then utilize that same buffer type for all messages + * sent to that remote proc, so we provide new macros for creating + * and constructing buffers that ensures the correct buffer type + * is marked. + * + * Accordingly, there are two levels of APIs defined for this + * framework: + * + * (a) component level - these allow for init/finalize of the + * component, and assignment of a module to a given peer + * based on the version that peer is using + * + * (b) module level - implement pack/unpack/copy/recv/etc. of + * the various datatypes. Note that the module only needs + * to provide those functions that differ from the base + * functions - they don't need to duplicate all that code! + */ + + +/* The following functions are exposed to the user - they + * therefore are implemented in the bfrops/base functions + * as wrappers to the real functions. + * + * NOTE: THESE FUNCTIONS ARE NOT TO BE USED INTERNALLY - + * USE THE MACROS INSTEAD */ pmix_status_t pmix_value_xfer(pmix_value_t *kv, pmix_value_t *src); void pmix_value_load(pmix_value_t *v, const void *data, - pmix_data_type_t type); + pmix_data_type_t type); pmix_status_t pmix_value_unload(pmix_value_t *kv, void **data, - size_t *sz, pmix_data_type_t type); + size_t *sz, pmix_data_type_t type); bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1); -#define PMIX_LOAD_BUFFER(b, d, s) \ - do { \ - (b)->base_ptr = (char*)(d); \ - (b)->bytes_used = (s); \ - (b)->bytes_allocated = (s); \ - (b)->pack_ptr = ((char*)(b)->base_ptr) + (s); \ - (b)->unpack_ptr = (b)->base_ptr; \ - (d) = NULL; \ - (s) = 0; \ - } while (0) -#define PMIX_UNLOAD_BUFFER(b, d, s) \ - do { \ - (d) = (char*)(b)->unpack_ptr; \ - (s) = (b)->bytes_used; \ - (b)->base_ptr = NULL; \ - (b)->bytes_used = 0; \ - (b)->bytes_allocated = 0; \ - (b)->pack_ptr = NULL; \ - (b)->unpack_ptr = NULL; \ - } while (0) +/**** MODULE INTERFACE DEFINITION ****/ +/* initialize the module - the module is expected + * to register its datatype functions at this time */ +typedef pmix_status_t (*pmix_bfrop_init_fn_t)(void); + +/* finalize the module */ +typedef void (*pmix_bfrop_finalize_fn_t)(void); /** - * Top-level interface function to pack one or more values into a - * buffer. + * Pack one or more values into a buffer. * * The pack function packs one or more values of a specified type into * the specified buffer. The buffer must have already been @@ -96,8 +138,10 @@ bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1); * @param *buffer A pointer to the buffer into which the value is to * be packed. * - * @param *src A void* pointer to the data that is to be packed. Note - * that strings are to be passed as (char **) - i.e., the caller must + * @param *src A void* pointer to the data that is to be packed. This + * is interpreted as a pointer to an array of that data type containing + * length num_values. Note that strings are of data type char*, and so + * they are to be passed as (char **) - i.e., the caller must * pass the address of the pointer to the string as the void*. This * allows the BFROP to use a single interface function, but still allow * the caller to pass multiple strings in a single call. @@ -125,7 +169,8 @@ bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1); * status_code = pmix_bfrop.pack(buffer, &src, 1, PMIX_INT32); * @endcode */ -typedef pmix_status_t (*pmix_bfrop_pack_fn_t)(pmix_buffer_t *buffer, const void *src, +typedef pmix_status_t (*pmix_bfrop_pack_fn_t)(pmix_buffer_t *buffer, + const void *src, int32_t num_values, pmix_data_type_t type); @@ -151,12 +196,6 @@ typedef pmix_status_t (*pmix_bfrop_pack_fn_t)(pmix_buffer_t *buffer, const void * matches the specified data type flag). Therefore, the data type error check * is NOT completely safe. This is true for ALL unpack functions. * - * - * Unpacking values is a "destructive" process - i.e., the values are - * removed from the buffer, thus reducing the buffer size. It is - * therefore not possible for the caller to re-unpack a value from the - * same buffer. - * * Warning: The caller is responsible for providing adequate memory * storage for the requested data. As noted below, the user * must provide a parameter indicating the maximum number of values that @@ -239,22 +278,6 @@ typedef pmix_status_t (*pmix_bfrop_unpack_fn_t)(pmix_buffer_t *buffer, void *des typedef pmix_status_t (*pmix_bfrop_copy_payload_fn_t)(pmix_buffer_t *dest, pmix_buffer_t *src); -/** - * BFROP initialization function. - * - * In dynamic libraries, declared objects and functions don't get - * loaded until called. We need to ensure that the pmix_bfrop function - * structure gets loaded, so we provide an "open" call that is - * executed as part of the program startup. - */ -pmix_status_t pmix_bfrop_open(void); - -/** - * BFROP finalize function - */ -pmix_status_t pmix_bfrop_close(void); - - /** * Copy a data value from one location to another. * @@ -278,7 +301,8 @@ pmix_status_t pmix_bfrop_close(void); * @retval PMIX_ERROR(s) An appropriate error code. * */ -typedef pmix_status_t (*pmix_bfrop_copy_fn_t)(void **dest, void *src, pmix_data_type_t type); +typedef pmix_status_t (*pmix_bfrop_copy_fn_t)(void **dest, void *src, + pmix_data_type_t type); /** * Print a data value. @@ -291,24 +315,169 @@ typedef pmix_status_t (*pmix_bfrop_copy_fn_t)(void **dest, void *src, pmix_data_ * * @retval PMIX_ERROR(s) An appropriate error code. */ -typedef pmix_status_t (*pmix_bfrop_print_fn_t)(char **output, char *prefix, void *src, pmix_data_type_t type); +typedef pmix_status_t (*pmix_bfrop_print_fn_t)(char **output, char *prefix, + void *src, pmix_data_type_t type); /** - * Base structure for the BFROP + * Transfer a value from one pmix_value_t to another. Ordinarily, + * this would be executed as a base function. However, it is + * possible that future versions may add new data types, and + * thus the xfer function may differ * - * Base module structure for the BFROP - presents the required function - * pointers to the calling interface. + * @retval PMIX_SUCCESS The value was successfully transferred + * + * @retval PMIX_ERROR(s) An appropriate error code */ -struct pmix_bfrop_t { +typedef pmix_status_t (*pmix_bfrop_value_xfer_fn_t)(pmix_value_t *dest, + pmix_value_t *src); + + +/** + * Load data into a pmix_value_t object. Again, this is provided + * as a component function to support different data types + */ +typedef void (*pmix_bfrop_value_load_fn_t)(pmix_value_t *v, const void *data, + pmix_data_type_t type); + +/** + * Unload data from a pmix_value_t object + * + * @retval PMIX_SUCCESS The value was successfully unloaded + * + * @retval PMIX_ERROR(s) An appropriate error code + */ +typedef pmix_status_t (*pmix_bfrop_value_unload_fn_t)(pmix_value_t *kv, + void **data, size_t *sz); + +/** + * Compare two pmix_value_t structs + */ +typedef pmix_value_cmp_t (*pmix_bfrop_value_cmp_fn_t)(pmix_value_t *p1, pmix_value_t *p2); + +/* define a component-level API for registering a new + * datatype, providing all the required functions */ +typedef pmix_status_t (*pmix_bfrop_base_register_fn_t)(const char *name, pmix_data_type_t type, + pmix_bfrop_pack_fn_t pack, + pmix_bfrop_unpack_fn_t unpack, + pmix_bfrop_copy_fn_t copy, + pmix_bfrop_print_fn_t print); + +/* return the string name of a provided data type */ +typedef const char* (*pmix_bfrop_data_type_string_fn_t)(pmix_data_type_t type); + +/** + * Base structure for a BFROP module + */ +typedef struct { + char *version; + pmix_bfrop_init_fn_t init; + pmix_bfrop_finalize_fn_t finalize; pmix_bfrop_pack_fn_t pack; pmix_bfrop_unpack_fn_t unpack; pmix_bfrop_copy_fn_t copy; pmix_bfrop_print_fn_t print; pmix_bfrop_copy_payload_fn_t copy_payload; -}; -typedef struct pmix_bfrop_t pmix_bfrop_t; + pmix_bfrop_value_xfer_fn_t value_xfer; + pmix_bfrop_value_load_fn_t value_load; + pmix_bfrop_value_unload_fn_t value_unload; + pmix_bfrop_value_cmp_fn_t value_cmp; + pmix_bfrop_base_register_fn_t register_type; + pmix_bfrop_data_type_string_fn_t data_type_string; +} pmix_bfrops_module_t; -extern pmix_bfrop_t pmix_bfrop; /* holds bfrop function pointers */ + +/* get a list of available versions - caller must free results + * when done */ +PMIX_EXPORT char* pmix_bfrops_base_get_available_modules(void); + +/* Select a bfrops module for a given version */ +PMIX_EXPORT pmix_bfrops_module_t* pmix_bfrops_base_assign_module(const char *version); + +/* MACROS FOR EXECUTING BFROPS FUNCTIONS */ +#define PMIX_BFROPS_ASSIGN_TYPE(p, b) \ + (b)->type = (p)->nptr->compat.type + +#define PMIX_BFROPS_PACK(r, p, b, s, n, t) \ + do { \ + if (PMIX_BFROP_BUFFER_UNDEF == (b)->type) { \ + (b)->type = (p)->nptr->compat.type; \ + (r) = (p)->nptr->compat.bfrops->pack(b, s, n, t); \ + } else if ((b)->type == (p)->nptr->compat.type) { \ + (r) = (p)->nptr->compat.bfrops->pack(b, s, n, t); \ + } else { \ + (r) = PMIX_ERR_PACK_MISMATCH; \ + } \ + } while(0) + +#define PMIX_BFROPS_UNPACK(r, p, b, d, m, t) \ + do { \ + if ((b)->type == (p)->nptr->compat.type) { \ + (r) = (p)->nptr->compat.bfrops->unpack(b, d, m, t); \ + } else { \ + pmix_output(0, "MISMATCH %d %d", (b)->type, (p)->nptr->compat.type); \ + (r) = PMIX_ERR_UNPACK_FAILURE; \ + } \ + } while(0) + +#define PMIX_BFROPS_COPY(r, p, d, s, t) \ + (r) = (p)->nptr->compat.bfrops->copy(d, s, t) + +#define PMIX_BFROPS_PRINT(r, p, o, pr, s, t) \ + (r) = (p)->nptr->compat.bfrops->print(o, pr, s, t) + +#define PMIX_BFROPS_COPY_PAYLOAD(r, p, d, s) \ + do { \ + if (PMIX_BFROP_BUFFER_UNDEF == (d)->type) { \ + (d)->type = (p)->nptr->compat.type; \ + (r) = (p)->nptr->compat.bfrops->copy_payload(d, s); \ + } else if ((d)->type == (p)->nptr->compat.type) { \ + (r) = (p)->nptr->compat.bfrops->copy_payload(d, s); \ + } else { \ + (r) = PMIX_ERR_PACK_MISMATCH; \ + } \ + } while(0) + +#define PMIX_BFROPS_VALUE_XFER(r, p, d, s) \ + (r) = (p)->nptr->compat.bfrops->value_xfer(d, s) + +#define PMIX_BFROPS_VALUE_LOAD(p, v, d, t) \ + (p)->nptr->compat.bfrops->value_load(v, d, t) + +#define PMIX_BFROPS_VALUE_UNLOAD(r, p, k, d, s) \ + (r) = (p)->nptr->compat.bfrops->value_unload(k,, d, s) + +#define PMIX_BFROPS_VALUE_CMP(r, p, q, s) \ + (r) = (p)->nptr->compat.bfrops->value_cmp(q, s) + +#define PMIX_BFROPS_REGISTER(r, p, n, t, pk, u, c, pr) \ + (r) = (p)->nptr->compat.bfrops->register_type(n, t, pk, u, c, pr) + +#define PMIX_BFROPS_PRINT_TYPE(c, p, t) \ + (c) = (p)->nptr->compat.bfrops->data_type_string(t) + + +/**** COMPONENT STRUCTURE DEFINITION ****/ + +/* define a component-level API for getting a module */ +typedef pmix_bfrops_module_t* (*pmix_bfrop_base_component_assign_module_fn_t)(void); + +/* + * the standard component data structure + */ +struct pmix_bfrops_base_component_t { + pmix_mca_base_component_t base; + pmix_mca_base_component_data_t data; + int priority; + pmix_pointer_array_t types; + pmix_bfrop_base_component_assign_module_fn_t assign_module; +}; +typedef struct pmix_bfrops_base_component_t pmix_bfrops_base_component_t; + +/* + * Macro for use in components that are of type bfrops + */ +#define PMIX_BFROPS_BASE_VERSION_1_0_0 \ + PMIX_MCA_BASE_VERSION_1_0_0("bfrops", 1, 0, 0) END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/bfrops_types.h b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/bfrops_types.h new file mode 100644 index 0000000000..6609bd9377 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/bfrops_types.h @@ -0,0 +1,149 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007-2011 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** + * @file + * + * Buffer management types. + */ + +#ifndef PMIX_MCA_BFROP_TYPES_H_ +#define PMIX_MCA_BFROP_TYPES_H_ + +#include + + +#include "src/class/pmix_object.h" +#include "src/class/pmix_pointer_array.h" +#include "src/class/pmix_list.h" +#include + +BEGIN_C_DECLS + +/* define the results values for comparisons so we can change them in only one place */ +typedef enum { + PMIX_EQUAL = 0, + PMIX_VALUE1_GREATER, + PMIX_VALUE2_GREATER +} pmix_value_cmp_t; + +/** + * buffer type + */ +typedef uint8_t pmix_bfrop_buffer_type_t; +#define PMIX_BFROP_BUFFER_UNDEF 0x00 +#define PMIX_BFROP_BUFFER_NON_DESC 0x01 +#define PMIX_BFROP_BUFFER_FULLY_DESC 0x02 + +#define PMIX_BFROP_BUFFER_TYPE_HTON(h) +#define PMIX_BFROP_BUFFER_TYPE_NTOH(h) + +/* internally used object for transferring data + * to/from the server and for storing in the + * hash tables */ +typedef struct { + pmix_list_item_t super; + char *key; + pmix_value_t *value; +} pmix_kval_t; +PMIX_CLASS_DECLARATION(pmix_kval_t); + + +/** + * Structure for holding a buffer */ +typedef struct { + /** First member must be the object's parent */ + pmix_object_t parent; + /** type of buffer */ + pmix_bfrop_buffer_type_t type; + /** Start of my memory */ + char *base_ptr; + /** Where the next data will be packed to (within the allocated + memory starting at base_ptr) */ + char *pack_ptr; + /** Where the next data will be unpacked from (within the + allocated memory starting as base_ptr) */ + char *unpack_ptr; + + /** Number of bytes allocated (starting at base_ptr) */ + size_t bytes_allocated; + /** Number of bytes used by the buffer (i.e., amount of data -- + including overhead -- packed in the buffer) */ + size_t bytes_used; +} pmix_buffer_t; +PMIX_CLASS_DECLARATION(pmix_buffer_t); + +/* Convenience macro for loading a data blob into a pmix_buffer_t + * + * p - the pmix_peer_t of the process that provided the blob. This + * is needed so we can set the buffer type for later unpacking + * + * b - pointer to pmix_buffer_t + * + * d - pointer to the data blob + * + * s - number of bytes in the blob + * + * NOTE: the macro does NOT copy the data, but simply assigns + * its address to the buffer. Accordingly, the macro will + * set the provided data blob pointer to NULL and the size + * to zero. + */ +#define PMIX_LOAD_BUFFER(p, b, d, s) \ + do { \ + (b)->type = (p)->nptr->compat.type; \ + (b)->base_ptr = (char*)(d); \ + (b)->bytes_used = (s); \ + (b)->bytes_allocated = (s); \ + (b)->pack_ptr = ((char*)(b)->base_ptr) + (s); \ + (b)->unpack_ptr = (b)->base_ptr; \ + (d) = NULL; \ + (s) = 0; \ + } while (0) + +/* Convenience macro for extracting a pmix_buffer_t's payload + * as a data blob + * + * b - pointer to the pmix_buffer_t + * + * d - char* pointer to the data blob + * + * s - number of bytes in the blob + * + * NOTE: the macro does NOT copy the data, but simply assigns + * the address of the buffer's payload to the provided pointer. + * Accordingly, the macro will set all pmix_buffer_t internal + * tracking pointers to NULL and all counters to zero */ +#define PMIX_UNLOAD_BUFFER(b, d, s) \ + do { \ + (d) = (char*)(b)->unpack_ptr; \ + (s) = (b)->bytes_used; \ + (b)->base_ptr = NULL; \ + (b)->bytes_used = 0; \ + (b)->bytes_allocated = 0; \ + (b)->pack_ptr = NULL; \ + (b)->unpack_ptr = NULL; \ + } while (0) + + +END_C_DECLS + +#endif /* PMIX_BFROP_TYPES_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/Makefile.am new file mode 100644 index 0000000000..4629bbc757 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/Makefile.am @@ -0,0 +1,50 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers = bfrop_pmix2.h +sources = \ + bfrop_pmix2_component.c \ + bfrop_pmix2.c + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if MCA_BUILD_pmix_bfrops_pmix2_DSO +lib = +lib_sources = +component = mca_bfrops_pmix2.la +component_sources = $(headers) $(sources) +else +lib = libmca_bfrops_pmix2.la +lib_sources = $(headers) $(sources) +component = +component_sources = +endif + +mcacomponentdir = $(pmixlibdir) +mcacomponent_LTLIBRARIES = $(component) +mca_bfrops_pmix2_la_SOURCES = $(component_sources) +mca_bfrops_pmix2_la_LDFLAGS = -module -avoid-version + +noinst_LTLIBRARIES = $(lib) +libmca_bfrops_pmix2_la_SOURCES = $(lib_sources) +libmca_bfrops_pmix2_la_LDFLAGS = -module -avoid-version diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2.c new file mode 100644 index 0000000000..ba5af4b285 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2011 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2010-2011 Oak Ridge National Labs. All rights reserved. + * Copyright (c) 2011-2014 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2011-2013 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ + +#include + +#include "src/mca/bfrops/base/base.h" +#include "bfrop_pmix2.h" + +static pmix_status_t init(void); +static void finalize(void); +static pmix_status_t pmix2_pack(pmix_buffer_t *buffer, + const void *src, int num_vals, + pmix_data_type_t type); +static pmix_status_t pmix2_unpack(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type); +static pmix_status_t pmix2_copy(void **dest, void *src, + pmix_data_type_t type); +static pmix_status_t pmix2_print(char **output, char *prefix, + void *src, pmix_data_type_t type); +static pmix_status_t register_type(const char *name, + pmix_data_type_t type, + pmix_bfrop_pack_fn_t pack, + pmix_bfrop_unpack_fn_t unpack, + pmix_bfrop_copy_fn_t copy, + pmix_bfrop_print_fn_t print); +static const char* data_type_string(pmix_data_type_t type); + +pmix_bfrops_module_t pmix_bfrops_pmix2_module = { + .version = "pmix2", + .init = init, + .finalize = finalize, + .pack = pmix2_pack, + .unpack = pmix2_unpack, + .copy = pmix2_copy, + .print = pmix2_print, + .copy_payload = pmix_bfrops_base_copy_payload, + .value_xfer = pmix_bfrops_base_value_xfer, + .value_load = pmix_bfrops_base_value_load, + .value_unload = pmix_bfrops_base_value_unload, + .value_cmp = pmix_bfrops_base_value_cmp, + .register_type = register_type, + .data_type_string = data_type_string +}; + +static pmix_status_t init(void) +{ + /* some standard types don't require anything special */ + PMIX_REGISTER_TYPE("PMIX_BOOL", PMIX_BOOL, + pmix_bfrops_base_pack_bool, + pmix_bfrops_base_unpack_bool, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_bool, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_BYTE", PMIX_BYTE, + pmix_bfrops_base_pack_byte, + pmix_bfrops_base_unpack_byte, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_byte, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_STRING", PMIX_STRING, + pmix_bfrops_base_pack_string, + pmix_bfrops_base_unpack_string, + pmix_bfrops_base_copy_string, + pmix_bfrops_base_print_string, + &mca_bfrops_pmix2_component.types); + + /* Register the rest of the standard generic types to point to internal functions */ + PMIX_REGISTER_TYPE("PMIX_SIZE", PMIX_SIZE, + pmix_bfrops_base_pack_sizet, + pmix_bfrops_base_unpack_sizet, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_size, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_PID", PMIX_PID, + pmix_bfrops_base_pack_pid, + pmix_bfrops_base_unpack_pid, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_pid, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_INT", PMIX_INT, + pmix_bfrops_base_pack_int, + pmix_bfrops_base_unpack_int, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_int, + &mca_bfrops_pmix2_component.types); + + /* Register all the standard fixed types to point to base functions */ + PMIX_REGISTER_TYPE("PMIX_INT8", PMIX_INT8, + pmix_bfrops_base_pack_byte, + pmix_bfrops_base_unpack_byte, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_int8, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_INT16", PMIX_INT16, + pmix_bfrops_base_pack_int16, + pmix_bfrops_base_unpack_int16, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_int16, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_INT32", PMIX_INT32, + pmix_bfrops_base_pack_int32, + pmix_bfrops_base_unpack_int32, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_int32, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_INT64", PMIX_INT64, + pmix_bfrops_base_pack_int64, + pmix_bfrops_base_unpack_int64, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_int64, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_UINT", PMIX_UINT, + pmix_bfrops_base_pack_int, + pmix_bfrops_base_unpack_int, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_uint, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_UINT8", PMIX_UINT8, + pmix_bfrops_base_pack_byte, + pmix_bfrops_base_unpack_byte, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_uint8, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_UINT16", PMIX_UINT16, + pmix_bfrops_base_pack_int16, + pmix_bfrops_base_unpack_int16, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_uint16, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_UINT32", PMIX_UINT32, + pmix_bfrops_base_pack_int32, + pmix_bfrops_base_unpack_int32, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_uint32, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_UINT64", PMIX_UINT64, + pmix_bfrops_base_pack_int64, + pmix_bfrops_base_unpack_int64, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_uint64, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_FLOAT", PMIX_FLOAT, + pmix_bfrops_base_pack_float, + pmix_bfrops_base_unpack_float, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_float, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_DOUBLE", PMIX_DOUBLE, + pmix_bfrops_base_pack_double, + pmix_bfrops_base_unpack_double, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_double, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_TIMEVAL", PMIX_TIMEVAL, + pmix_bfrops_base_pack_timeval, + pmix_bfrops_base_unpack_timeval, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_timeval, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_TIME", PMIX_TIME, + pmix_bfrops_base_pack_time, + pmix_bfrops_base_unpack_time, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_time, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_STATUS", PMIX_STATUS, + pmix_bfrops_base_pack_status, + pmix_bfrops_base_unpack_status, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_status, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_VALUE", PMIX_VALUE, + pmix_bfrops_base_pack_value, + pmix_bfrops_base_unpack_value, + pmix_bfrops_base_copy_value, + pmix_bfrops_base_print_value, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_PROC", PMIX_PROC, + pmix_bfrops_base_pack_proc, + pmix_bfrops_base_unpack_proc, + pmix_bfrops_base_copy_proc, + pmix_bfrops_base_print_proc, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_APP", PMIX_APP, + pmix_bfrops_base_pack_app, + pmix_bfrops_base_unpack_app, + pmix_bfrops_base_copy_app, + pmix_bfrops_base_print_app, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_INFO", PMIX_INFO, + pmix_bfrops_base_pack_info, + pmix_bfrops_base_unpack_info, + pmix_bfrops_base_copy_info, + pmix_bfrops_base_print_info, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_PDATA", PMIX_PDATA, + pmix_bfrops_base_pack_pdata, + pmix_bfrops_base_unpack_pdata, + pmix_bfrops_base_copy_pdata, + pmix_bfrops_base_print_pdata, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_BUFFER", PMIX_BUFFER, + pmix_bfrops_base_pack_buf, + pmix_bfrops_base_unpack_buf, + pmix_bfrops_base_copy_buf, + pmix_bfrops_base_print_buf, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_BYTE_OBJECT", PMIX_BYTE_OBJECT, + pmix_bfrops_base_pack_bo, + pmix_bfrops_base_unpack_bo, + pmix_bfrops_base_copy_bo, + pmix_bfrops_base_print_bo, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_KVAL", PMIX_KVAL, + pmix_bfrops_base_pack_kval, + pmix_bfrops_base_unpack_kval, + pmix_bfrops_base_copy_kval, + pmix_bfrops_base_print_kval, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_MODEX", PMIX_MODEX, + pmix_bfrops_base_pack_modex, + pmix_bfrops_base_unpack_modex, + pmix_bfrops_base_copy_modex, + pmix_bfrops_base_print_modex, + &mca_bfrops_pmix2_component.types); + + /* these are fixed-sized values and can be done by base */ + PMIX_REGISTER_TYPE("PMIX_PERSIST", PMIX_PERSIST, + pmix_bfrops_base_pack_persist, + pmix_bfrops_base_unpack_persist, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_persist, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_POINTER", PMIX_POINTER, + pmix_bfrops_base_pack_ptr, + pmix_bfrops_base_unpack_ptr, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_ptr, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_SCOPE", PMIX_SCOPE, + pmix_bfrops_base_pack_scope, + pmix_bfrops_base_unpack_scope, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_std_copy, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_DATA_RANGE", PMIX_DATA_RANGE, + pmix_bfrops_base_pack_range, + pmix_bfrops_base_unpack_range, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_ptr, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_COMMAND", PMIX_COMMAND, + pmix_bfrops_base_pack_cmd, + pmix_bfrops_base_unpack_cmd, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_cmd, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_INFO_DIRECTIVES", PMIX_INFO_DIRECTIVES, + pmix_bfrops_base_pack_info_directives, + pmix_bfrops_base_unpack_info_directives, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_info_directives, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_DATA_TYPE", PMIX_DATA_TYPE, + pmix_bfrops_base_pack_datatype, + pmix_bfrops_base_unpack_datatype, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_datatype, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_PROC_STATE", PMIX_PROC_STATE, + pmix_bfrops_base_pack_pstate, + pmix_bfrops_base_unpack_pstate, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_pstate, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_PROC_INFO", PMIX_PROC_INFO, + pmix_bfrops_base_pack_pinfo, + pmix_bfrops_base_unpack_pinfo, + pmix_bfrops_base_copy_pinfo, + pmix_bfrops_base_print_pinfo, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_DATA_ARRAY", PMIX_DATA_ARRAY, + pmix_bfrops_base_pack_darray, + pmix_bfrops_base_unpack_darray, + pmix_bfrops_base_copy_darray, + pmix_bfrops_base_print_darray, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_PROC_RANK", PMIX_PROC_RANK, + pmix_bfrops_base_pack_rank, + pmix_bfrops_base_unpack_rank, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_rank, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_QUERY", PMIX_QUERY, + pmix_bfrops_base_pack_query, + pmix_bfrops_base_unpack_query, + pmix_bfrops_base_copy_query, + pmix_bfrops_base_print_query, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_COMPRESSED_STRING", + PMIX_COMPRESSED_STRING, + pmix_bfrops_base_pack_bo, + pmix_bfrops_base_unpack_bo, + pmix_bfrops_base_copy_bo, + pmix_bfrops_base_print_bo, + &mca_bfrops_pmix2_component.types); + + PMIX_REGISTER_TYPE("PMIX_ALLOC_DIRECTIVE", + PMIX_ALLOC_DIRECTIVE, + pmix_bfrops_base_pack_alloc_directive, + pmix_bfrops_base_unpack_alloc_directive, + pmix_bfrops_base_std_copy, + pmix_bfrops_base_print_alloc_directive, + &mca_bfrops_pmix2_component.types); + + /**** DEPRECATED ****/ + PMIX_REGISTER_TYPE("PMIX_INFO_ARRAY", PMIX_INFO_ARRAY, + pmix_bfrops_base_pack_array, + pmix_bfrops_base_unpack_array, + pmix_bfrops_base_copy_array, + pmix_bfrops_base_print_array, + &mca_bfrops_pmix2_component.types); + /********************/ + + + return PMIX_SUCCESS; +} + +static void finalize(void) +{ + int n; + pmix_bfrop_type_info_t *info; + + for (n=0; n < mca_bfrops_pmix2_component.types.size; n++) { + if (NULL != (info = (pmix_bfrop_type_info_t*)pmix_pointer_array_get_item(&mca_bfrops_pmix2_component.types, n))) { + PMIX_RELEASE(info); + pmix_pointer_array_set_item(&mca_bfrops_pmix2_component.types, n, NULL); + } + } +} + +static pmix_status_t pmix2_pack(pmix_buffer_t *buffer, + const void *src, int num_vals, + pmix_data_type_t type) +{ + /* kick the process off by passing this in to the base */ + return pmix_bfrops_base_pack(&mca_bfrops_pmix2_component.types, + buffer, src, num_vals, type); +} + +static pmix_status_t pmix2_unpack(pmix_buffer_t *buffer, void *dest, + int32_t *num_vals, pmix_data_type_t type) +{ + /* kick the process off by passing this in to the base */ + return pmix_bfrops_base_unpack(&mca_bfrops_pmix2_component.types, + buffer, dest, num_vals, type); +} + +static pmix_status_t pmix2_copy(void **dest, void *src, + pmix_data_type_t type) +{ + return pmix_bfrops_base_copy(&mca_bfrops_pmix2_component.types, + dest, src, type); +} + +static pmix_status_t pmix2_print(char **output, char *prefix, + void *src, pmix_data_type_t type) +{ + return pmix_bfrops_base_print(&mca_bfrops_pmix2_component.types, + output, prefix, src, type); +} + +static pmix_status_t register_type(const char *name, pmix_data_type_t type, + pmix_bfrop_pack_fn_t pack, + pmix_bfrop_unpack_fn_t unpack, + pmix_bfrop_copy_fn_t copy, + pmix_bfrop_print_fn_t print) +{ + PMIX_REGISTER_TYPE(name, type, + pack, unpack, + copy, print, + &mca_bfrops_pmix2_component.types); + return PMIX_SUCCESS; +} + +static const char* data_type_string(pmix_data_type_t type) +{ + return pmix_bfrops_base_data_type_string(&mca_bfrops_pmix2_component.types, type); +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2.h b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2.h new file mode 100644 index 0000000000..acd01ffcf1 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_BFROPS_PMIX2_H +#define PMIX_BFROPS_PMIX2_H + +#include "src/mca/bfrops/bfrops.h" + +BEGIN_C_DECLS + +/* the component must be visible data for the linker to find it */ + PMIX_EXPORT extern pmix_bfrops_base_component_t mca_bfrops_pmix2_component; + +extern pmix_bfrops_module_t pmix_bfrops_pmix2_module; + +END_C_DECLS + +#endif /* PMIX_BFROPS_PMIX2_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2_component.c new file mode 100644 index 0000000000..54731b1985 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/bfrops/pmix2/bfrop_pmix2_component.c @@ -0,0 +1,99 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennbfropsee and The University + * of Tennbfropsee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + * These symbols are in a file by themselves to provide nice linker + * semantics. Since linkers generally pull in symbols by object + * files, keeping these symbols as the only symbols in this file + * prevents utility programs such as "ompi_info" from having to import + * entire components just to query their version and parameters. + */ + +#include +#include +#include "src/include/types.h" +#include "src/include/pmix_globals.h" + +#include "src/util/error.h" +#include "src/server/pmix_server_ops.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/bfrops/pmix2/bfrop_pmix2.h" + +extern pmix_bfrops_module_t pmix_bfrops_pmix2_module; + +static pmix_status_t component_open(void); +static pmix_status_t component_query(pmix_mca_base_module_t **module, int *priority); +static pmix_status_t component_close(void); +static pmix_bfrops_module_t* assign_module(void); + +/* + * Instantiate the public struct with all of our public information + * and pointers to our public functions in it + */ +pmix_bfrops_base_component_t mca_bfrops_pmix2_component = { + .base = { + PMIX_BFROPS_BASE_VERSION_1_0_0, + + /* Component name and version */ + .pmix_mca_component_name = "pmix2", + PMIX_MCA_BASE_MAKE_VERSION(component, PMIX_MAJOR_VERSION, PMIX_MINOR_VERSION, + PMIX_RELEASE_VERSION), + + /* Component open and close functions */ + .pmix_mca_open_component = component_open, + .pmix_mca_close_component = component_close, + .pmix_mca_query_component = component_query, + }, + .priority = 20, + .assign_module = assign_module +}; + + +pmix_status_t component_open(void) +{ + /* setup the types array */ + PMIX_CONSTRUCT(&mca_bfrops_pmix2_component.types, pmix_pointer_array_t); + pmix_pointer_array_init(&mca_bfrops_pmix2_component.types, 32, INT_MAX, 16); + + return PMIX_SUCCESS; +} + + +pmix_status_t component_query(pmix_mca_base_module_t **module, int *priority) +{ + + *priority = mca_bfrops_pmix2_component.priority; + *module = (pmix_mca_base_module_t *)&pmix_bfrops_pmix2_module; + return PMIX_SUCCESS; +} + + +pmix_status_t component_close(void) +{ + PMIX_DESTRUCT(&mca_bfrops_pmix2_component.types); + return PMIX_SUCCESS; +} + +static pmix_bfrops_module_t* assign_module(void) +{ + pmix_output_verbose(10, pmix_bfrops_base_framework.framework_output, + "bfrops:pmix2x assigning module"); + return &pmix_bfrops_pmix2_module; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/Makefile.am new file mode 100644 index 0000000000..383ab58854 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/Makefile.am @@ -0,0 +1,44 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_CPPFLAGS = $(LTDLINCL) + +# main library setup +noinst_LTLIBRARIES = libmca_gds.la +libmca_gds_la_SOURCES = + +# local files +headers = gds.h +sources = + +# Conditionally install the header files +if WANT_INSTALL_HEADERS +pmixdir = $(pmixincludedir)/$(subdir) +nobase_pmix_HEADERS = $(headers) +endif + +include base/Makefile.include + +libmca_gds_la_SOURCES += $(headers) $(sources) + +distclean-local: + rm -f base/static-components.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/Makefile.include similarity index 72% rename from opal/mca/pmix/pmix2x/pmix/src/buffer_ops/Makefile.am rename to opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/Makefile.include index 31a093e3f5..768f8fdb0d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/Makefile.include @@ -11,7 +11,8 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -23,14 +24,9 @@ # src/Makefile.am headers += \ - buffer_ops/buffer_ops.h \ - buffer_ops/types.h \ - buffer_ops/internal.h + base/base.h sources += \ - buffer_ops/copy.c \ - buffer_ops/internal_functions.c \ - buffer_ops/open_close.c \ - buffer_ops/pack.c \ - buffer_ops/print.c \ - buffer_ops/unpack.c + base/gds_base_frame.c \ + base/gds_base_select.c \ + base/gds_base_fns.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/base.h new file mode 100644 index 0000000000..3ada366984 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/base.h @@ -0,0 +1,103 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ +#ifndef PMIX_GDS_BASE_H_ +#define PMIX_GDS_BASE_H_ + +#include + + +#ifdef HAVE_SYS_TIME_H +#include /* for struct timeval */ +#endif +#ifdef HAVE_STRING_H +#include +#endif + +#include "src/class/pmix_list.h" +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_framework.h" + +#include "src/mca/gds/gds.h" + + +BEGIN_C_DECLS + +/* + * MCA Framework + */ +PMIX_EXPORT extern pmix_mca_base_framework_t pmix_gds_base_framework; +/** + * GDS select function + * + * Cycle across available components and construct the list + * of active modules + */ +PMIX_EXPORT pmix_status_t pmix_gds_base_select(pmix_info_t info[], size_t ninfo); + +/** + * Track an active component / module + */ +struct pmix_gds_base_active_module_t { + pmix_list_item_t super; + int pri; + pmix_gds_base_module_t *module; + pmix_gds_base_component_t *component; +}; +typedef struct pmix_gds_base_active_module_t pmix_gds_base_active_module_t; +PMIX_CLASS_DECLARATION(pmix_gds_base_active_module_t); + + +/* framework globals */ +struct pmix_gds_globals_t { + pmix_list_t actives; + bool initialized; + char *all_mods; +}; +typedef struct pmix_gds_globals_t pmix_gds_globals_t; + +PMIX_EXPORT extern pmix_gds_globals_t pmix_gds_globals; + +/* get a list of available support - caller must free results + * when done. The list is returned as a comma-delimited string + * of available components in priority order */ +PMIX_EXPORT char* pmix_gds_base_get_available_modules(void); + + +/* Select a gds module based on the provided directives */ +PMIX_EXPORT pmix_gds_base_module_t* pmix_gds_base_assign_module(pmix_info_t *info, + size_t ninfo); + +/** +* Add any envars to a peer's environment that the module needs +* to communicate. The API stub will rotate across all active modules, giving +* each a chance to contribute +* +* @return PMIX_SUCCESS on success. +*/ +PMIX_EXPORT pmix_status_t pmix_gds_base_setup_fork(const pmix_proc_t *proc, + char ***env); + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_fns.c b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_fns.c new file mode 100644 index 0000000000..16e88485c9 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_fns.c @@ -0,0 +1,85 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2016 Mellanox Technologies, Inc. + * All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include "src/include/pmix_globals.h" + +#include "src/class/pmix_list.h" +#include "src/util/argv.h" +#include "src/util/error.h" + +#include "src/mca/gds/base/base.h" + + +char* pmix_gds_base_get_available_modules(void) +{ + if (!pmix_gds_globals.initialized) { + return NULL; + } + + return strdup(pmix_gds_globals.all_mods); +} + +/* Select a gds module per the given directives */ +pmix_gds_base_module_t* pmix_gds_base_assign_module(pmix_info_t *info, size_t ninfo) +{ + pmix_gds_base_active_module_t *active; + pmix_gds_base_module_t *mod = NULL; + int pri, priority = -1; + + if (!pmix_gds_globals.initialized) { + return NULL; + } + + PMIX_LIST_FOREACH(active, &pmix_gds_globals.actives, pmix_gds_base_active_module_t) { + if (NULL == active->module->assign_module) { + continue; + } + if (PMIX_SUCCESS == active->module->assign_module(info, ninfo, &pri)) { + if (pri < 0) { + /* use the default priority from the component */ + pri = active->pri; + } + if (priority < pri) { + mod = active->module; + priority = pri; + } + } + } + + return mod; +} + +pmix_status_t pmix_gds_base_setup_fork(const pmix_proc_t *proc, + char ***env) +{ + pmix_gds_base_active_module_t *active; + pmix_status_t rc; + + if (!pmix_gds_globals.initialized) { + return PMIX_ERR_INIT; + } + + PMIX_LIST_FOREACH(active, &pmix_gds_globals.actives, pmix_gds_base_active_module_t) { + if (NULL == active->module->setup_fork) { + continue; + } + if (PMIX_SUCCESS != (rc = active->module->setup_fork(proc, env))) { + return rc; + } + } + + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_frame.c b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_frame.c new file mode 100644 index 0000000000..9ceca34f0a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_frame.c @@ -0,0 +1,92 @@ +/* -*- Mode: C; c-basic-offset:4 ; -*- */ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2009 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** @file: + * + */ +#include + +#include + +#ifdef HAVE_STRING_H +#include +#endif + +#include "src/class/pmix_list.h" +#include "src/util/argv.h" + +#include "src/mca/base/base.h" +#include "src/mca/gds/base/base.h" + +/* + * The following file was created by configure. It contains extern + * statements and the definition of an array of pointers to each + * component's public mca_base_component_t struct. + */ + +#include "src/mca/gds/base/static-components.h" + +/* Instantiate the global vars */ +pmix_gds_globals_t pmix_gds_globals = {{{0}}}; + +static pmix_status_t pmix_gds_close(void) +{ + pmix_gds_base_active_module_t *active, *prev; + + if (!pmix_gds_globals.initialized) { + return PMIX_SUCCESS; + } + pmix_gds_globals.initialized = false; + + PMIX_LIST_FOREACH_SAFE(active, prev, &pmix_gds_globals.actives, pmix_gds_base_active_module_t) { + pmix_list_remove_item(&pmix_gds_globals.actives, &active->super); + if (NULL != active->module->finalize) { + active->module->finalize(); + } + PMIX_RELEASE(active); + } + PMIX_DESTRUCT(&pmix_gds_globals.actives); + + if (NULL != pmix_gds_globals.all_mods) { + free(pmix_gds_globals.all_mods); + } + return pmix_mca_base_framework_components_close(&pmix_gds_base_framework, NULL); +} + +static pmix_status_t pmix_gds_open(pmix_mca_base_open_flag_t flags) +{ + /* initialize globals */ + pmix_gds_globals.initialized = true; + pmix_gds_globals.all_mods = NULL; + PMIX_CONSTRUCT(&pmix_gds_globals.actives, pmix_list_t); + + /* Open up all available components */ + return pmix_mca_base_framework_components_open(&pmix_gds_base_framework, flags); +} + +PMIX_MCA_BASE_FRAMEWORK_DECLARE(pmix, gds, "PMIx Generalized Data Store", + NULL, pmix_gds_open, pmix_gds_close, + mca_gds_base_static_components, 0); + +PMIX_CLASS_INSTANCE(pmix_gds_base_active_module_t, + pmix_list_item_t, + NULL, NULL); diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_select.c b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_select.c new file mode 100644 index 0000000000..807754d8f0 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/base/gds_base_select.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include +#include + +#include + +#include "src/util/argv.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" + +#include "src/mca/gds/base/base.h" + +static bool selected = false; + +/* Function for selecting a prioritized list of components + * from all those that are available. */ +int pmix_gds_base_select(pmix_info_t info[], size_t ninfo) +{ + pmix_mca_base_component_list_item_t *cli = NULL; + pmix_mca_base_component_t *component = NULL; + pmix_mca_base_module_t *module = NULL; + pmix_gds_base_module_t *nmodule; + pmix_gds_base_active_module_t *newmodule, *mod; + int rc, priority; + bool inserted; + char **mods = NULL; + + if (selected) { + /* ensure we don't do this twice */ + return PMIX_SUCCESS; + } + selected = true; + + /* Query all available components and ask if they have a module */ + PMIX_LIST_FOREACH(cli, &pmix_gds_base_framework.framework_components, pmix_mca_base_component_list_item_t) { + component = (pmix_mca_base_component_t *) cli->cli_component; + + pmix_output_verbose(5, pmix_gds_base_framework.framework_output, + "mca:gds:select: checking available component %s", component->pmix_mca_component_name); + + /* If there's no query function, skip it */ + if (NULL == component->pmix_mca_query_component) { + pmix_output_verbose(5, pmix_gds_base_framework.framework_output, + "mca:gds:select: Skipping component [%s]. It does not implement a query function", + component->pmix_mca_component_name ); + continue; + } + + /* Query the component */ + pmix_output_verbose(5, pmix_gds_base_framework.framework_output, + "mca:gds:select: Querying component [%s]", + component->pmix_mca_component_name); + rc = component->pmix_mca_query_component(&module, &priority); + + /* If no module was returned, then skip component */ + if (PMIX_SUCCESS != rc || NULL == module) { + pmix_output_verbose(5, pmix_gds_base_framework.framework_output, + "mca:gds:select: Skipping component [%s]. Query failed to return a module", + component->pmix_mca_component_name ); + continue; + } + + /* If we got a module, keep it */ + nmodule = (pmix_gds_base_module_t*) module; + /* let it initialize */ + if (NULL != nmodule->init && PMIX_SUCCESS != nmodule->init(info, ninfo)) { + continue; + } + /* add to the list of selected modules */ + newmodule = PMIX_NEW(pmix_gds_base_active_module_t); + newmodule->pri = priority; + newmodule->module = nmodule; + newmodule->component = (pmix_gds_base_component_t*)cli->cli_component; + + /* maintain priority order */ + inserted = false; + PMIX_LIST_FOREACH(mod, &pmix_gds_globals.actives, pmix_gds_base_active_module_t) { + if (priority > mod->pri) { + pmix_list_insert_pos(&pmix_gds_globals.actives, + (pmix_list_item_t*)mod, &newmodule->super); + inserted = true; + break; + } + } + if (!inserted) { + /* must be lowest priority - add to end */ + pmix_list_append(&pmix_gds_globals.actives, &newmodule->super); + } + } + + /* setup the list of all module names */ + PMIX_LIST_FOREACH(mod, &pmix_gds_globals.actives, pmix_gds_base_active_module_t) { + pmix_argv_append_nosize(&mods, mod->module->name); + } + pmix_gds_globals.all_mods = pmix_argv_join(mods, ','); + pmix_argv_free(mods); + + if (4 < pmix_output_get_verbosity(pmix_gds_base_framework.framework_output)) { + pmix_output(0, "Final gds priorities"); + /* show the prioritized list */ + PMIX_LIST_FOREACH(mod, &pmix_gds_globals.actives, pmix_gds_base_active_module_t) { + pmix_output(0, "\tgds: %s Priority: %d", mod->component->base.pmix_mca_component_name, mod->pri); + } + } + + return PMIX_SUCCESS;; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/Makefile.am new file mode 100644 index 0000000000..e80b98bf50 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/Makefile.am @@ -0,0 +1,60 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2017 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2017 Mellanox Technologies, Inc. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_CPPFLAGS = $(gds_ds12_CPPFLAGS) + +headers = \ + gds_dstore.h + +sources = \ + gds_dstore.c \ + gds_dstore_component.c + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if MCA_BUILD_pmix_gds_ds12_DSO +lib = +lib_sources = +component = mca_gds_ds12.la +component_sources = $(headers) $(sources) +else +lib = libmca_gds_ds12.la +lib_sources = $(headers) $(sources) +component = +component_sources = +endif + +mcacomponentdir = $(pmixlibdir) +mcacomponent_LTLIBRARIES = $(component) +mca_gds_ds12_la_SOURCES = $(component_sources) +mca_gds_ds12_la_LIBADD = $(gds_ds12_LIBS) +mca_gds_ds12_la_LDFLAGS = -module -avoid-version $(gds_ds12_LDFLAGS) + +noinst_LTLIBRARIES = $(lib) +libmca_gds_ds12_la_SOURCES = $(lib_sources) +libmca_gds_ds12_la_LIBADD = $(gds_dstore_LIBS) +libmca_gds_ds12_la_LDFLAGS = -module -avoid-version $(gds_ds12_LDFLAGS) diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/configure.m4 new file mode 100644 index 0000000000..dbafc18297 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/configure.m4 @@ -0,0 +1,20 @@ +# -*- shell-script -*- +# +# Copyright (c) 2015-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2015 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# MCA_gds_ds12_CONFIG([action-if-found], [action-if-not-found]) +# -------------------------------------------------------------------- +AC_DEFUN([MCA_pmix_gds_ds12_CONFIG],[ + AC_CONFIG_FILES([src/mca/gds/ds12/Makefile]) + + AS_IF([test "$enable_dstore" == "yes"], [$1], [$2]) + +])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore.c similarity index 70% rename from opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c rename to opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore.c index 22d60f7ba8..927372bfd2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore.c @@ -1,11 +1,9 @@ /* - * Copyright (c) 2015-2017 Mellanox Technologies, Inc. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2016 IBM Corporation. All rights reserved. + * Copyright (c) 2016-2017 Mellanox Technologies, Inc. * All rights reserved. - * Copyright (c) 2016-2017 Research Organization for Information Science - * and Technology (RIST). All rights reserved. - * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. - * Copyright (c) 2017 Los Alamos National Security, LLC. All rights - * reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -13,57 +11,45 @@ * $HEADER$ */ -#define _GNU_SOURCE +#include + #include #include #include #include #include #include - -#include -#include -#include -#include "src/include/pmix_globals.h" - -#include "src/class/pmix_value_array.h" -#include "src/buffer_ops/buffer_ops.h" -#include "src/buffer_ops/types.h" -#include "src/util/pmix_environ.h" -#include "src/util/hash.h" -#include "src/util/error.h" -#include "src/sm/pmix_sm.h" -#include "src/util/argv.h" - -#include "pmix_dstore.h" -#include "pmix_esh.h" - -#ifdef ESH_FCNTL_LOCK +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_FCNTL_H #include #endif +#include -#ifdef ESH_PTHREAD_LOCK -#include -#endif +#include -static int _esh_init(pmix_info_t info[], size_t ninfo); -static int _esh_finalize(void); -static int _esh_store(const char *nspace, pmix_rank_t rank, pmix_kval_t *kv); -static int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value_t **kvs); -static int _esh_patch_env(const char *nspace, char ***env); -static int _esh_nspace_add(const char *nspace, pmix_info_t info[], size_t ninfo); -static int _esh_nspace_del(const char *nspace); +#include "src/include/pmix_globals.h" +#include "src/class/pmix_list.h" +#include "src/client/pmix_client_ops.h" +#include "src/server/pmix_server_ops.h" +#include "src/util/argv.h" +#include "src/util/compress.h" +#include "src/util/error.h" +#include "src/util/output.h" +#include "src/util/pmix_environ.h" +#include "src/util/hash.h" +#include "src/mca/preg/preg.h" -pmix_dstore_base_module_t pmix_dstore_esh_module = { - "esh", - _esh_init, - _esh_finalize, - _esh_store, - _esh_fetch, - _esh_patch_env, - _esh_nspace_add, - _esh_nspace_del -}; +#include "src/mca/gds/base/base.h" +#include "gds_dstore.h" +#include "src/mca/pshmem/base/base.h" #define ESH_REGION_EXTENSION "EXTENSION_SLOT" #define ESH_REGION_INVALIDATED "INVALIDATED" @@ -213,7 +199,7 @@ static int _store_data_for_rank(ns_track_elem_t *ns_info, pmix_rank_t rank, pmix static seg_desc_t *_create_new_segment(segment_type type, const ns_map_data_t *ns_map, uint32_t id); static seg_desc_t *_attach_new_segment(segment_type type, const ns_map_data_t *ns_map, uint32_t id); static int _update_ns_elem(ns_track_elem_t *ns_elem, ns_seg_info_t *info); -static int _put_ns_info_to_initial_segment(const ns_map_data_t *ns_map, pmix_sm_seg_t *metaseg, pmix_sm_seg_t *dataseg); +static int _put_ns_info_to_initial_segment(const ns_map_data_t *ns_map, pmix_pshmem_seg_t *metaseg, pmix_pshmem_seg_t *dataseg); static ns_seg_info_t *_get_ns_info_from_initial_segment(const ns_map_data_t *ns_map); static ns_track_elem_t *_get_track_elem_for_namespace(ns_map_data_t *ns_map); static rank_meta_info *_get_rank_meta_info(pmix_rank_t rank, seg_desc_t *segdesc); @@ -237,6 +223,75 @@ static inline void _esh_sessions_cleanup(void); static inline void _esh_ns_map_cleanup(void); static inline int _esh_dir_del(const char *dirname); +static inline int _collect_key_for_rank(pmix_peer_t *peer, pmix_rank_t rank, pmix_kval_t *kv); +static inline int _collected_key_dstore_store(pmix_nspace_t *nptr); +static inline pmix_status_t store_map(pmix_peer_t *peer, char **nodes, char **ppn); + +static inline int _my_client(const char *nspace, pmix_rank_t rank); + +static pmix_status_t dstore_init(pmix_info_t info[], size_t ninfo); + +static void dstore_finalize(void); + +static pmix_status_t dstore_setup_fork(const pmix_proc_t *peer, char ***env); + +static pmix_status_t dstore_cache_job_info(struct pmix_nspace_t *ns, + pmix_info_t info[], size_t ninfo); + +static pmix_status_t dstore_register_job_info(struct pmix_peer_t *pr, + pmix_buffer_t *reply); + +static pmix_status_t dstore_store_job_info(const char *nspace, + pmix_buffer_t *job_data); + +static pmix_status_t _dstore_store(const char *nspace, + pmix_rank_t rank, + pmix_kval_t *kv); + +static pmix_status_t dstore_store(const pmix_proc_t *proc, + pmix_scope_t scope, + pmix_kval_t *kv); + +static pmix_status_t _dstore_fetch(const char *nspace, + pmix_rank_t rank, const char *key, pmix_value_t **kvs); + +static pmix_status_t dstore_fetch(const pmix_proc_t *proc, + pmix_scope_t scope, bool copy, + const char *key, + pmix_info_t info[], size_t ninfo, + pmix_list_t *kvs); + +static pmix_status_t dstore_add_nspace(const char *nspace, + pmix_info_t info[], + size_t ninfo); + +static pmix_status_t dstore_del_nspace(const char* nspace); + +static pmix_status_t dstore_assign_module(pmix_info_t *info, size_t ninfo, + int *priority); + +static pmix_status_t dstore_store_modex(struct pmix_nspace_t *nspace, + pmix_list_t *cbs, + pmix_byte_object_t *bo); + +pmix_gds_base_module_t pmix_ds12_module = { + .name = "ds12", + .init = dstore_init, + .finalize = dstore_finalize, + .assign_module = dstore_assign_module, + .cache_job_info = dstore_cache_job_info, + .register_job_info = dstore_register_job_info, + .store_job_info = dstore_store_job_info, + .store = dstore_store, + .store_modex = dstore_store_modex, + .fetch = dstore_fetch, + .setup_fork = dstore_setup_fork, + .add_nspace = dstore_add_nspace, + .del_nspace = dstore_del_nspace, +}; + +static pmix_value_array_t *rank_kv_bufs = NULL; + static char *_base_path = NULL; static size_t _initial_segment_size = 0; static size_t _max_ns_num; @@ -360,14 +415,13 @@ static inline int _rwlock_init(size_t idx) { rc = PMIX_ERR_INIT; return rc; } - _ESH_SESSION_pthread_seg(idx) = (pmix_sm_seg_t *)malloc(sizeof(pmix_sm_seg_t)); + _ESH_SESSION_pthread_seg(idx) = (pmix_pshmem_seg_t *)malloc(sizeof(pmix_pshmem_seg_t)); if (NULL == _ESH_SESSION_pthread_seg(idx)) { rc = PMIX_ERR_OUT_OF_RESOURCE; return rc; } - if (PMIX_PROC_SERVER == pmix_globals.proc_type) { - if (PMIX_SUCCESS != (rc = pmix_sm_segment_create(_ESH_SESSION_pthread_seg(idx), _ESH_SESSION_lockfile(idx), size))) { + if (PMIX_SUCCESS != (rc = pmix_pshmem.segment_create(_ESH_SESSION_pthread_seg(idx), _ESH_SESSION_lockfile(idx), size))) { return rc; } memset(_ESH_SESSION_pthread_seg(idx)->seg_base_addr, 0, size); @@ -388,26 +442,26 @@ static inline int _rwlock_init(size_t idx) { if (0 != pthread_rwlockattr_init(&attr)) { rc = PMIX_ERR_INIT; - pmix_sm_segment_detach(_ESH_SESSION_pthread_seg(idx)); + pmix_pshmem.segment_detach(_ESH_SESSION_pthread_seg(idx)); return rc; } if (0 != pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) { rc = PMIX_ERR_INIT; - pmix_sm_segment_detach(_ESH_SESSION_pthread_seg(idx)); + pmix_pshmem.segment_detach(_ESH_SESSION_pthread_seg(idx)); pthread_rwlockattr_destroy(&attr); return rc; } #ifdef HAVE_PTHREAD_SETKIND if (0 != pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) { rc = PMIX_ERR_INIT; - pmix_sm_segment_detach(_ESH_SESSION_pthread_seg(idx)); + pmix_pshmem.segment_detach(_ESH_SESSION_pthread_seg(idx)); pthread_rwlockattr_destroy(&attr); return rc; } #endif if (0 != pthread_rwlock_init(_ESH_SESSION_pthread_rwlock(idx), &attr)) { rc = PMIX_ERR_INIT; - pmix_sm_segment_detach(_ESH_SESSION_pthread_seg(idx)); + pmix_pshmem.segment_detach(_ESH_SESSION_pthread_seg(idx)); pthread_rwlockattr_destroy(&attr); return rc; } @@ -420,7 +474,7 @@ static inline int _rwlock_init(size_t idx) { else { _ESH_SESSION_pthread_seg(idx)->seg_size = size; snprintf(_ESH_SESSION_pthread_seg(idx)->seg_name, PMIX_PATH_MAX, "%s", _ESH_SESSION_lockfile(idx)); - if (PMIX_SUCCESS != (rc = pmix_sm_segment_attach(_ESH_SESSION_pthread_seg(idx), PMIX_SM_RW))) { + if (PMIX_SUCCESS != (rc = pmix_pshmem.segment_attach(_ESH_SESSION_pthread_seg(idx), PMIX_PSHMEM_RW))) { return rc; } _ESH_SESSION_pthread_rwlock(idx) = (pthread_rwlock_t *)_ESH_SESSION_pthread_seg(idx)->seg_base_addr; @@ -440,9 +494,9 @@ static inline void _rwlock_release(session_t *s) { /* detach & unlink from current desc */ if (s->rwlock_seg->seg_cpid == getpid()) { - pmix_sm_segment_unlink(s->rwlock_seg); + pmix_pshmem.segment_unlink(s->rwlock_seg); } - pmix_sm_segment_detach(s->rwlock_seg); + pmix_pshmem.segment_detach(s->rwlock_seg); free(s->rwlock_seg); s->rwlock_seg = NULL; @@ -798,7 +852,7 @@ static inline int _esh_session_init(size_t idx, ns_map_data_t *m, size_t jobuid, PMIX_ERROR_LOG(rc); return rc; } - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s _lockfile_name: %s", __FILE__, __LINE__, __func__, s->lockfile)); if (PMIX_PROC_SERVER == pmix_globals.proc_type) { @@ -854,13 +908,7 @@ static inline void _esh_session_release(session_t *s) } _delete_sm_desc(s->sm_seg_first); - /* the session_t structures are initialized to zero. If - * we release the session without having actually assigned - * a locking fd, then we don't want to close that fd - * as it doesn't belong to us */ - if (0 != s->lockfd) { - close(s->lockfd); - } + close(s->lockfd); if (NULL != s->lockfile) { if(PMIX_PROC_SERVER == pmix_globals.proc_type) { @@ -880,7 +928,1010 @@ static inline void _esh_session_release(session_t *s) memset ((char *) s, 0, sizeof(*s)); } -int _esh_init(pmix_info_t info[], size_t ninfo) +static void _set_constants_from_env() +{ + char *str; + int page_size = _pmix_getpagesize(); + + if( NULL != (str = getenv(ESH_ENV_INITIAL_SEG_SIZE)) ) { + _initial_segment_size = strtoul(str, NULL, 10); + if ((size_t)page_size > _initial_segment_size) { + _initial_segment_size = (size_t)page_size; + } + } + if (0 == _initial_segment_size) { + _initial_segment_size = INITIAL_SEG_SIZE; + } + if( NULL != (str = getenv(ESH_ENV_NS_META_SEG_SIZE)) ) { + _meta_segment_size = strtoul(str, NULL, 10); + if ((size_t)page_size > _meta_segment_size) { + _meta_segment_size = (size_t)page_size; + } + } + if (0 == _meta_segment_size) { + _meta_segment_size = NS_META_SEG_SIZE; + } + if( NULL != (str = getenv(ESH_ENV_NS_DATA_SEG_SIZE)) ) { + _data_segment_size = strtoul(str, NULL, 10); + if ((size_t)page_size > _data_segment_size) { + _data_segment_size = (size_t)page_size; + } + } + if (0 == _data_segment_size) { + _data_segment_size = NS_DATA_SEG_SIZE; + } + if (NULL != (str = getenv(ESH_ENV_LINEAR))) { + if (1 == strtoul(str, NULL, 10)) { + _direct_mode = 1; + } + } + + _lock_segment_size = page_size; + _max_ns_num = (_initial_segment_size - sizeof(size_t) * 2) / sizeof(ns_seg_info_t); + _max_meta_elems = (_meta_segment_size - sizeof(size_t)) / sizeof(rank_meta_info); + +} + +static void _delete_sm_desc(seg_desc_t *desc) +{ + seg_desc_t *tmp; + + /* free all global segments */ + while (NULL != desc) { + tmp = desc->next; + /* detach & unlink from current desc */ + if (desc->seg_info.seg_cpid == getpid()) { + pmix_pshmem.segment_unlink(&desc->seg_info); + } + pmix_pshmem.segment_detach(&desc->seg_info); + free(desc); + desc = tmp; + } +} + +static int _pmix_getpagesize(void) +{ +#if defined(_SC_PAGESIZE ) + return sysconf(_SC_PAGESIZE); +#elif defined(_SC_PAGE_SIZE) + return sysconf(_SC_PAGE_SIZE); +#else + return 65536; /* safer to overestimate than under */ +#endif +} + +static seg_desc_t *_create_new_segment(segment_type type, const ns_map_data_t *ns_map, uint32_t id) +{ + pmix_status_t rc; + char file_name[PMIX_PATH_MAX]; + size_t size; + seg_desc_t *new_seg = NULL; + + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: segment type %d, nspace %s, id %u", + __FILE__, __LINE__, __func__, type, ns_map->name, id)); + + switch (type) { + case INITIAL_SEGMENT: + size = _initial_segment_size; + snprintf(file_name, PMIX_PATH_MAX, "%s/initial-pmix_shared-segment-%u", + _ESH_SESSION_path(ns_map->tbl_idx), id); + break; + case NS_META_SEGMENT: + size = _meta_segment_size; + snprintf(file_name, PMIX_PATH_MAX, "%s/smseg-%s-%u", + _ESH_SESSION_path(ns_map->tbl_idx), ns_map->name, id); + break; + case NS_DATA_SEGMENT: + size = _data_segment_size; + snprintf(file_name, PMIX_PATH_MAX, "%s/smdataseg-%s-%d", + _ESH_SESSION_path(ns_map->tbl_idx), ns_map->name, id); + break; + default: + PMIX_ERROR_LOG(PMIX_ERROR); + return NULL; + } + new_seg = (seg_desc_t*)malloc(sizeof(seg_desc_t)); + if (new_seg) { + new_seg->id = id; + new_seg->next = NULL; + new_seg->type = type; + rc = pmix_pshmem.segment_create(&new_seg->seg_info, file_name, size); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + goto err_exit; + } + memset(new_seg->seg_info.seg_base_addr, 0, size); + + + if (_ESH_SESSION_setjobuid(ns_map->tbl_idx) > 0){ + rc = PMIX_ERR_PERM; + if (0 > chown(file_name, (uid_t) _ESH_SESSION_jobuid(ns_map->tbl_idx), (gid_t) -1)){ + PMIX_ERROR_LOG(rc); + goto err_exit; + } + /* set the mode as required */ + if (0 > chmod(file_name, S_IRUSR | S_IRGRP | S_IWGRP )) { + PMIX_ERROR_LOG(rc); + goto err_exit; + } + } + } + return new_seg; + +err_exit: + if( NULL != new_seg ){ + free(new_seg); + } + return NULL; +} + +static seg_desc_t *_attach_new_segment(segment_type type, const ns_map_data_t *ns_map, uint32_t id) +{ + pmix_status_t rc; + seg_desc_t *new_seg = NULL; + new_seg = (seg_desc_t*)malloc(sizeof(seg_desc_t)); + new_seg->id = id; + new_seg->next = NULL; + new_seg->type = type; + + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: segment type %d, nspace %s, id %u", + __FILE__, __LINE__, __func__, type, ns_map->name, id)); + + switch (type) { + case INITIAL_SEGMENT: + new_seg->seg_info.seg_size = _initial_segment_size; + snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/initial-pmix_shared-segment-%u", + _ESH_SESSION_path(ns_map->tbl_idx), id); + break; + case NS_META_SEGMENT: + new_seg->seg_info.seg_size = _meta_segment_size; + snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/smseg-%s-%u", + _ESH_SESSION_path(ns_map->tbl_idx), ns_map->name, id); + break; + case NS_DATA_SEGMENT: + new_seg->seg_info.seg_size = _data_segment_size; + snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/smdataseg-%s-%d", + _ESH_SESSION_path(ns_map->tbl_idx), ns_map->name, id); + break; + default: + PMIX_ERROR_LOG(PMIX_ERROR); + return NULL; + } + rc = pmix_pshmem.segment_attach(&new_seg->seg_info, PMIX_PSHMEM_RONLY); + if (PMIX_SUCCESS != rc) { + free(new_seg); + new_seg = NULL; + PMIX_ERROR_LOG(rc); + } + return new_seg; +} + +/* This function synchronizes the content of initial shared segment and the local track list. */ +static int _update_ns_elem(ns_track_elem_t *ns_elem, ns_seg_info_t *info) +{ + seg_desc_t *seg, *tmp = NULL; + size_t i, offs; + ns_map_data_t *ns_map = NULL; + pmix_status_t rc; + + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s", + __FILE__, __LINE__, __func__)); + + if (NULL == (ns_map = _esh_session_map_search(info->ns_map.name))) { + rc = PMIX_ERR_NOT_AVAILABLE; + PMIX_ERROR_LOG(rc); + return rc; + } + + tmp = ns_elem->meta_seg; + if (NULL != tmp) { + while(NULL != tmp->next) { + tmp = tmp->next; + } + } + + /* synchronize number of meta segments for the target namespace. */ + for (i = ns_elem->num_meta_seg; i < info->num_meta_seg; i++) { + if (PMIX_PROC_SERVER == pmix_globals.proc_type) { + seg = _create_new_segment(NS_META_SEGMENT, &info->ns_map, i); + if (NULL == seg) { + rc = PMIX_ERR_OUT_OF_RESOURCE; + PMIX_ERROR_LOG(rc); + return rc; + } + } else { + seg = _attach_new_segment(NS_META_SEGMENT, &info->ns_map, i); + if (NULL == seg) { + rc = PMIX_ERR_NOT_AVAILABLE; + PMIX_ERROR_LOG(rc); + return rc; + } + } + + if (NULL == tmp) { + ns_elem->meta_seg = seg; + } else { + tmp->next = seg; + } + tmp = seg; + ns_elem->num_meta_seg++; + } + + tmp = ns_elem->data_seg; + if (NULL != tmp) { + while(NULL != tmp->next) { + tmp = tmp->next; + } + } + /* synchronize number of data segments for the target namespace. */ + for (i = ns_elem->num_data_seg; i < info->num_data_seg; i++) { + if (PMIX_PROC_SERVER == pmix_globals.proc_type) { + seg = _create_new_segment(NS_DATA_SEGMENT, &info->ns_map, i); + if (NULL == seg) { + rc = PMIX_ERR_OUT_OF_RESOURCE; + PMIX_ERROR_LOG(rc); + return rc; + } + offs = sizeof(size_t);//shift on offset field itself + memcpy(seg->seg_info.seg_base_addr, &offs, sizeof(size_t)); + } else { + seg = _attach_new_segment(NS_DATA_SEGMENT, &info->ns_map, i); + if (NULL == seg) { + rc = PMIX_ERR_NOT_AVAILABLE; + PMIX_ERROR_LOG(rc); + return rc; + } + } + + if (NULL == tmp) { + ns_elem->data_seg = seg; + } else { + tmp->next = seg; + } + tmp = seg; + ns_elem->num_data_seg++; + } + + return PMIX_SUCCESS; +} + +static seg_desc_t *extend_segment(seg_desc_t *segdesc, const ns_map_data_t *ns_map) +{ + seg_desc_t *tmp, *seg; + + PMIX_OUTPUT_VERBOSE((2, pmix_gds_base_framework.framework_output, + "%s:%d:%s", + __FILE__, __LINE__, __func__)); + /* find last segment */ + tmp = segdesc; + while (NULL != tmp->next) { + tmp = tmp->next; + } + /* create another segment, the old one is full. */ + seg = _create_new_segment(segdesc->type, ns_map, tmp->id + 1); + tmp->next = seg; + + return seg; +} + +static int _put_ns_info_to_initial_segment(const ns_map_data_t *ns_map, pmix_pshmem_seg_t *metaseg, pmix_pshmem_seg_t *dataseg) +{ + ns_seg_info_t elem; + size_t num_elems; + num_elems = *((size_t*)(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr)); + seg_desc_t *last_seg = _ESH_SESSION_sm_seg_last(ns_map->tbl_idx); + pmix_status_t rc; + + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s", __FILE__, __LINE__, __func__)); + + if (_max_ns_num == num_elems) { + num_elems = 0; + if (NULL == (last_seg = extend_segment(last_seg, ns_map))) { + rc = PMIX_ERROR; + PMIX_ERROR_LOG(rc); + return rc; + } + /* mark previous segment as full */ + size_t full = 1; + memcpy((uint8_t*)(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr + sizeof(size_t)), &full, sizeof(size_t)); + _ESH_SESSION_sm_seg_last(ns_map->tbl_idx) = last_seg; + memset(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr, 0, _initial_segment_size); + } + memset(&elem.ns_map, 0, sizeof(elem.ns_map)); + strncpy(elem.ns_map.name, ns_map->name, sizeof(elem.ns_map.name)-1); + elem.ns_map.tbl_idx = ns_map->tbl_idx; + elem.num_meta_seg = 1; + elem.num_data_seg = 1; + memcpy((uint8_t*)(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr) + sizeof(size_t) * 2 + num_elems * sizeof(ns_seg_info_t), + &elem, sizeof(ns_seg_info_t)); + num_elems++; + memcpy((uint8_t*)(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr), &num_elems, sizeof(size_t)); + return PMIX_SUCCESS; +} + +/* clients should sync local info with information from initial segment regularly */ +static void _update_initial_segment_info(const ns_map_data_t *ns_map) +{ + seg_desc_t *tmp; + tmp = _ESH_SESSION_sm_seg_first(ns_map->tbl_idx); + + PMIX_OUTPUT_VERBOSE((2, pmix_gds_base_framework.framework_output, + "%s:%d:%s", __FILE__, __LINE__, __func__)); + + /* go through all global segments */ + do { + /* check if current segment was marked as full but no more next segment is in the chain */ + if (NULL == tmp->next && 1 == *((size_t*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t)))) { + tmp->next = _attach_new_segment(INITIAL_SEGMENT, ns_map, tmp->id+1); + } + tmp = tmp->next; + } + while (NULL != tmp); +} + +/* this function will be used by clients to get ns data from the initial segment and add them to the tracker list */ +static ns_seg_info_t *_get_ns_info_from_initial_segment(const ns_map_data_t *ns_map) +{ + pmix_status_t rc; + size_t i; + seg_desc_t *tmp; + ns_seg_info_t *elem, *cur_elem; + elem = NULL; + size_t num_elems; + + PMIX_OUTPUT_VERBOSE((2, pmix_gds_base_framework.framework_output, + "%s:%d:%s", __FILE__, __LINE__, __func__)); + + tmp = _ESH_SESSION_sm_seg_first(ns_map->tbl_idx); + + rc = 1; + /* go through all global segments */ + do { + num_elems = *((size_t*)(tmp->seg_info.seg_base_addr)); + for (i = 0; i < num_elems; i++) { + cur_elem = (ns_seg_info_t*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t) * 2 + i * sizeof(ns_seg_info_t)); + if (0 == (rc = strncmp(cur_elem->ns_map.name, ns_map->name, strlen(ns_map->name)+1))) { + break; + } + } + if (0 == rc) { + elem = cur_elem; + break; + } + tmp = tmp->next; + } + while (NULL != tmp); + return elem; +} + +static ns_track_elem_t *_get_track_elem_for_namespace(ns_map_data_t *ns_map) +{ + ns_track_elem_t *new_elem = NULL; + size_t size = pmix_value_array_get_size(_ns_track_array); + + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: nspace %s", + __FILE__, __LINE__, __func__, ns_map->name)); + + /* check if this namespace is already being tracked to avoid duplicating data. */ + if (ns_map->track_idx >= 0) { + if ((ns_map->track_idx + 1) > (int)size) { + return NULL; + } + /* data for this namespace should be already stored in shared memory region. */ + /* so go and just put new data. */ + return pmix_value_array_get_item(_ns_track_array, ns_map->track_idx); + } + + /* create shared memory regions for this namespace and store its info locally + * to operate with address and detach/unlink afterwards. */ + if (NULL == (new_elem = pmix_value_array_get_item(_ns_track_array, size))) { + return NULL; + } + PMIX_CONSTRUCT(new_elem, ns_track_elem_t); + strncpy(new_elem->ns_map.name, ns_map->name, sizeof(new_elem->ns_map.name)-1); + /* save latest track idx to info of nspace */ + ns_map->track_idx = size; + + return new_elem; +} + +static rank_meta_info *_get_rank_meta_info(pmix_rank_t rank, seg_desc_t *segdesc) +{ + size_t i; + rank_meta_info *elem = NULL; + seg_desc_t *tmp = segdesc; + size_t num_elems, rel_offset; + int id; + rank_meta_info *cur_elem; + + size_t rcount = rank == PMIX_RANK_WILDCARD ? 0 : rank + 1; + + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s", + __FILE__, __LINE__, __func__)); + + if (1 == _direct_mode) { + /* do linear search to find the requested rank inside all meta segments + * for this namespace. */ + /* go through all existing meta segments for this namespace */ + do { + num_elems = *((size_t*)(tmp->seg_info.seg_base_addr)); + for (i = 0; i < num_elems; i++) { + cur_elem = (rank_meta_info*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t) + i * sizeof(rank_meta_info)); + if (rcount == cur_elem->rank) { + elem = cur_elem; + break; + } + } + tmp = tmp->next; + } + while (NULL != tmp && NULL == elem); + } else { + /* directly compute index of meta segment (id) and relative offset (rel_offset) + * inside this segment for fast lookup a rank_meta_info object for the requested rank. */ + id = rcount/_max_meta_elems; + rel_offset = (rcount%_max_meta_elems) * sizeof(rank_meta_info) + sizeof(size_t); + /* go through all existing meta segments for this namespace. + * Stop at id number if it exists. */ + while (NULL != tmp->next && 0 != id) { + tmp = tmp->next; + id--; + } + if (0 == id) { + /* the segment is found, looking for data for the target rank. */ + elem = (rank_meta_info*)((uint8_t*)(tmp->seg_info.seg_base_addr) + rel_offset); + if ( 0 == elem->offset) { + /* offset can never be 0, it means that there is no data for this rank yet. */ + elem = NULL; + } + } + } + return elem; +} + +static int set_rank_meta_info(ns_track_elem_t *ns_info, rank_meta_info *rinfo) +{ + /* it's claimed that there is still no meta info for this rank stored */ + seg_desc_t *tmp; + size_t num_elems, rel_offset; + int id, count; + rank_meta_info *cur_elem; + + if (!ns_info || !rinfo) { + PMIX_ERROR_LOG(PMIX_ERROR); + return PMIX_ERROR; + } + + PMIX_OUTPUT_VERBOSE((2, pmix_gds_base_framework.framework_output, + "%s:%d:%s: nspace %s, add rank %lu offset %lu count %lu meta info", + __FILE__, __LINE__, __func__, + ns_info->ns_map.name, rinfo->rank, rinfo->offset, rinfo->count)); + + tmp = ns_info->meta_seg; + if (1 == _direct_mode) { + /* get the last meta segment to put new rank_meta_info at the end. */ + while (NULL != tmp->next) { + tmp = tmp->next; + } + num_elems = *((size_t*)(tmp->seg_info.seg_base_addr)); + if (_max_meta_elems <= num_elems) { + PMIX_OUTPUT_VERBOSE((2, pmix_gds_base_framework.framework_output, + "%s:%d:%s: extend meta segment for nspace %s", + __FILE__, __LINE__, __func__, ns_info->ns_map.name)); + /* extend meta segment, so create a new one */ + tmp = extend_segment(tmp, &ns_info->ns_map); + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERROR); + return PMIX_ERROR; + } + ns_info->num_meta_seg++; + memset(tmp->seg_info.seg_base_addr, 0, sizeof(rank_meta_info)); + /* update number of meta segments for namespace in initial_segment */ + ns_seg_info_t *elem = _get_ns_info_from_initial_segment(&ns_info->ns_map); + if (NULL == elem) { + PMIX_ERROR_LOG(PMIX_ERROR); + return PMIX_ERROR; + } + if (ns_info->num_meta_seg != elem->num_meta_seg) { + elem->num_meta_seg = ns_info->num_meta_seg; + } + num_elems = 0; + } + cur_elem = (rank_meta_info*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t) + num_elems * sizeof(rank_meta_info)); + memcpy(cur_elem, rinfo, sizeof(rank_meta_info)); + num_elems++; + memcpy(tmp->seg_info.seg_base_addr, &num_elems, sizeof(size_t)); + } else { + /* directly compute index of meta segment (id) and relative offset (rel_offset) + * inside this segment for fast lookup a rank_meta_info object for the requested rank. */ + size_t rcount = rinfo->rank == PMIX_RANK_WILDCARD ? 0 : rinfo->rank + 1; + id = rcount/_max_meta_elems; + rel_offset = (rcount % _max_meta_elems) * sizeof(rank_meta_info) + sizeof(size_t); + count = id; + /* go through all existing meta segments for this namespace. + * Stop at id number if it exists. */ + while (NULL != tmp->next && 0 != count) { + tmp = tmp->next; + count--; + } + /* if there is no segment with this id, then create all missing segments till the id number. */ + if ((int)ns_info->num_meta_seg < (id+1)) { + while ((int)ns_info->num_meta_seg != (id+1)) { + /* extend meta segment, so create a new one */ + tmp = extend_segment(tmp, &ns_info->ns_map); + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERROR); + return PMIX_ERROR; + } + memset(tmp->seg_info.seg_base_addr, 0, sizeof(rank_meta_info)); + ns_info->num_meta_seg++; + } + /* update number of meta segments for namespace in initial_segment */ + ns_seg_info_t *elem = _get_ns_info_from_initial_segment(&ns_info->ns_map); + if (NULL == elem) { + PMIX_ERROR_LOG(PMIX_ERROR); + return PMIX_ERROR; + } + if (ns_info->num_meta_seg != elem->num_meta_seg) { + elem->num_meta_seg = ns_info->num_meta_seg; + } + } + /* store rank_meta_info object by rel_offset. */ + cur_elem = (rank_meta_info*)((uint8_t*)(tmp->seg_info.seg_base_addr) + rel_offset); + memcpy(cur_elem, rinfo, sizeof(rank_meta_info)); + } + return PMIX_SUCCESS; +} + +static uint8_t *_get_data_region_by_offset(seg_desc_t *segdesc, size_t offset) +{ + seg_desc_t *tmp = segdesc; + size_t rel_offset = offset; + uint8_t *dataaddr = NULL; + + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s", + __FILE__, __LINE__, __func__)); + + /* go through all existing data segments for this namespace */ + do { + if (rel_offset >= _data_segment_size) { + rel_offset -= _data_segment_size; + } else { + dataaddr = tmp->seg_info.seg_base_addr + rel_offset; + } + tmp = tmp->next; + } while (NULL != tmp && NULL == dataaddr); + + return dataaddr; +} + +static size_t get_free_offset(seg_desc_t *data_seg) +{ + size_t offset; + seg_desc_t *tmp; + int id = 0; + tmp = data_seg; + /* first find the last data segment */ + while (NULL != tmp->next) { + tmp = tmp->next; + id++; + } + offset = *((size_t*)(tmp->seg_info.seg_base_addr)); + if (0 == offset) { + /* this is the first created data segment, the first 8 bytes are used to place the free offset value itself */ + offset = sizeof(size_t); + } + return (id * _data_segment_size + offset); +} + +static int put_empty_ext_slot(seg_desc_t *dataseg) +{ + size_t global_offset, rel_offset, data_ended, val = 0; + uint8_t *addr; + global_offset = get_free_offset(dataseg); + rel_offset = global_offset % _data_segment_size; + if (rel_offset + EXT_SLOT_SIZE() > _data_segment_size) { + PMIX_ERROR_LOG(PMIX_ERROR); + return PMIX_ERROR; + } + addr = _get_data_region_by_offset(dataseg, global_offset); + ESH_PUT_KEY(addr, ESH_REGION_EXTENSION, (void*)&val, sizeof(size_t)); + + /* update offset at the beginning of current segment */ + data_ended = rel_offset + EXT_SLOT_SIZE(); + addr = (uint8_t*)(addr - rel_offset); + memcpy(addr, &data_ended, sizeof(size_t)); + return PMIX_SUCCESS; +} + +static size_t put_data_to_the_end(ns_track_elem_t *ns_info, seg_desc_t *dataseg, char *key, void *buffer, size_t size) +{ + size_t offset, id = 0; + seg_desc_t *tmp; + size_t global_offset, data_ended; + uint8_t *addr; + + PMIX_OUTPUT_VERBOSE((2, pmix_gds_base_framework.framework_output, + "%s:%d:%s: key %s", + __FILE__, __LINE__, __func__, key)); + + tmp = dataseg; + while (NULL != tmp->next) { + tmp = tmp->next; + id++; + } + global_offset = get_free_offset(dataseg); + offset = global_offset % _data_segment_size; + + /* We should provide additional space at the end of segment to + * place EXTENSION_SLOT to have an ability to enlarge data for this rank.*/ + if ((sizeof(size_t) + ESH_KEY_SIZE(key, size) + EXT_SLOT_SIZE()) > _data_segment_size) { + /* this is an error case: segment is so small that cannot place evem a single key-value pair. + * warn a user about it and fail. */ + offset = 0; /* offset cannot be 0 in normal case, so we use this value to indicate a problem. */ + pmix_output(0, "PLEASE set NS_DATA_SEG_SIZE to value which is larger when %lu.", + sizeof(size_t) + strlen(key) + 1 + sizeof(size_t) + size + EXT_SLOT_SIZE()); + return offset; + } + + /* check the corner case that was observed at large scales: + * https://github.com/pmix/master/pull/282#issuecomment-277454198 + * + * if last time we stopped exactly on the border of the segment + * new segment wasn't allocated to us but (global_offset % _data_segment_size) == 0 + * so if offset is 0 here - we need to allocate the segment as well + */ + if ( (0 == offset) || ( (offset + ESH_KEY_SIZE(key, size) + EXT_SLOT_SIZE()) > _data_segment_size) ) { + id++; + /* create a new data segment. */ + tmp = extend_segment(tmp, &ns_info->ns_map); + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + offset = 0; /* offset cannot be 0 in normal case, so we use this value to indicate a problem. */ + return offset; + } + ns_info->num_data_seg++; + /* update_ns_info_in_initial_segment */ + ns_seg_info_t *elem = _get_ns_info_from_initial_segment(&ns_info->ns_map); + if (NULL == elem) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + offset = 0; /* offset cannot be 0 in normal case, so we use this value to indicate a problem. */ + return offset; + } + elem->num_data_seg++; + offset = sizeof(size_t); + } + global_offset = offset + id * _data_segment_size; + addr = (uint8_t*)(tmp->seg_info.seg_base_addr)+offset; + ESH_PUT_KEY(addr, key, buffer, size); + + /* update offset at the beginning of current segment */ + data_ended = offset + ESH_KEY_SIZE(key, size); + addr = (uint8_t*)(tmp->seg_info.seg_base_addr); + memcpy(addr, &data_ended, sizeof(size_t)); + PMIX_OUTPUT_VERBOSE((1, pmix_gds_base_framework.framework_output, + "%s:%d:%s: key %s, rel start offset %lu, rel end offset %lu, abs shift %lu size %lu", + __FILE__, __LINE__, __func__, key, offset, data_ended, id * _data_segment_size, size)); + return global_offset; +} + +static int pmix_sm_store(ns_track_elem_t *ns_info, pmix_rank_t rank, pmix_kval_t *kval, rank_meta_info **rinfo, int data_exist) +{ + size_t offset, size, kval_cnt; + pmix_buffer_t buffer; + pmix_status_t rc; + seg_desc_t *datadesc; + uint8_t *addr; + + PMIX_OUTPUT_VERBOSE((2, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u, replace flag %d", + __FILE__, __LINE__, __func__, rank, data_exist)); + + datadesc = ns_info->data_seg; + /* pack value to the buffer */ + PMIX_CONSTRUCT(&buffer, pmix_buffer_t); + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &buffer, kval->value, 1, PMIX_VALUE); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + goto exit; + } + size = buffer.bytes_used; + + if (0 == data_exist) { + /* there is no data blob for this rank yet, so add it. */ + size_t free_offset; + free_offset = get_free_offset(datadesc); + offset = put_data_to_the_end(ns_info, datadesc, kval->key, buffer.base_ptr, size); + if (0 == offset) { + /* this is an error */ + rc = PMIX_ERROR; + PMIX_ERROR_LOG(rc); + goto exit; + } + /* if it's the first time when we put data for this rank, then *rinfo == NULL, + * and even if segment was extended, and data was put into the next segment, + * we don't need to extension slot at the end of previous segment. + * If we try, we might overwrite other segments memory, + * because previous segment is already full. */ + if (free_offset != offset && NULL != *rinfo) { + /* here we compare previous free offset with the offset where we just put data. + * It should be equal in the normal case. It it's not true, then it means that + * segment was extended, and we put data to the next segment, so we now need to + * put extension slot at the end of previous segment with a "reference" to a new_offset */ + addr = _get_data_region_by_offset(datadesc, free_offset); + ESH_PUT_KEY(addr, ESH_REGION_EXTENSION, (void*)&offset, sizeof(size_t)); + } + if (NULL == *rinfo) { + *rinfo = (rank_meta_info*)malloc(sizeof(rank_meta_info)); + (*rinfo)->rank = rank; + (*rinfo)->offset = offset; + (*rinfo)->count = 0; + } + (*rinfo)->count++; + } else if (NULL != *rinfo) { + /* there is data blob for this rank */ + addr = _get_data_region_by_offset(datadesc, (*rinfo)->offset); + if (NULL == addr) { + rc = PMIX_ERROR; + PMIX_ERROR_LOG(rc); + goto exit; + } + /* go through previous data region and find key matches. + * If one is found, then mark this kval as invalidated. + * Then put a new empty offset to the next extension slot, + * and add new kval by this offset. + * no need to update meta info, it's still the same. */ + kval_cnt = (*rinfo)->count; + int add_to_the_end = 1; + while (0 < kval_cnt) { + /* data is stored in the following format: + * size_t size + * key[ESH_KNAME_LEN(addr)] + * byte buffer containing pmix_value, should be loaded to pmix_buffer_t and unpacked. + * next kval pair + * ..... + * extension slot which has key = EXTENSION_SLOT and a size_t value for offset to next data address for this process. + */ + if (0 == strncmp(ESH_KNAME_PTR(addr), ESH_REGION_EXTENSION, ESH_KNAME_LEN(ESH_REGION_EXTENSION))) { + memcpy(&offset, ESH_DATA_PTR(addr), sizeof(size_t)); + if (0 < offset) { + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u, replace flag %d %s is filled with %lu value", + __FILE__, __LINE__, __func__, rank, data_exist, ESH_REGION_EXTENSION, offset)); + /* go to next item, updating address */ + addr = _get_data_region_by_offset(datadesc, offset); + if (NULL == addr) { + rc = PMIX_ERROR; + PMIX_ERROR_LOG(rc); + goto exit; + } + } else { + /* should not be, we should be out of cycle when this happens */ + } + } else if (0 == strncmp(ESH_KNAME_PTR(addr), kval->key, ESH_KNAME_LEN(kval->key))) { + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u, replace flag %d found target key %s", + __FILE__, __LINE__, __func__, rank, data_exist, kval->key)); + /* target key is found, compare value sizes */ + if (ESH_DATA_SIZE(addr, ESH_DATA_PTR(addr)) != size) { + //if (1) { /* if we want to test replacing values for existing keys. */ + /* invalidate current value and store another one at the end of data region. */ + strncpy(ESH_KNAME_PTR(addr), ESH_REGION_INVALIDATED, ESH_KNAME_LEN(ESH_REGION_INVALIDATED)); + /* decrementing count, it will be incremented back when we add a new value for this key at the end of region. */ + (*rinfo)->count--; + kval_cnt--; + /* go to next item, updating address */ + addr += ESH_KV_SIZE(addr); + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u, replace flag %d mark key %s regions as invalidated. put new data at the end.", + __FILE__, __LINE__, __func__, rank, data_exist, kval->key)); + } else { + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u, replace flag %d replace data for key %s type %d in place", + __FILE__, __LINE__, __func__, rank, data_exist, kval->key, kval->value->type)); + /* replace old data with new one. */ + memset(ESH_DATA_PTR(addr), 0, ESH_DATA_SIZE(addr, ESH_DATA_PTR(addr))); + memcpy(ESH_DATA_PTR(addr), buffer.base_ptr, size); + addr += ESH_KV_SIZE(addr); + add_to_the_end = 0; + break; + } + } else { + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u, replace flag %d skip %s key, look for %s key", + __FILE__, __LINE__, __func__, rank, data_exist, ESH_KNAME_PTR(addr), kval->key)); + /* Skip it: key is "INVALIDATED" or key is valid but different from target one. */ + if (0 != strncmp(ESH_REGION_INVALIDATED, ESH_KNAME_PTR(addr), ESH_KNAME_LEN(ESH_KNAME_PTR(addr)))) { + /* count only valid items */ + kval_cnt--; + } + /* go to next item, updating address */ + addr += ESH_KV_SIZE(addr); + } + } + if (1 == add_to_the_end) { + /* if we get here, it means that we want to add a new item for the target rank, or + * we mark existing item with the same key as "invalidated" and want to add new item + * for the same key. */ + size_t free_offset; + (*rinfo)->count++; + free_offset = get_free_offset(datadesc); + /* add to the end */ + offset = put_data_to_the_end(ns_info, datadesc, kval->key, buffer.base_ptr, size); + if (0 == offset) { + rc = PMIX_ERROR; + PMIX_ERROR_LOG(rc); + goto exit; + } + /* we just reached the end of data for the target rank, and there can be two cases: + * (1) - we are in the middle of data segment; data for this rank is separated from + * data for different ranks, and that's why next element is EXTENSION_SLOT. + * We put new data to the end of data region and just update EXTENSION_SLOT value by new offset. + */ + if (0 == strncmp(ESH_KNAME_PTR(addr), ESH_REGION_EXTENSION, ESH_KNAME_LEN(ESH_REGION_EXTENSION))) { + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u, replace flag %d %s should be filled with offset %lu value", + __FILE__, __LINE__, __func__, rank, data_exist, ESH_REGION_EXTENSION, offset)); + memcpy(ESH_DATA_PTR(addr), &offset, sizeof(size_t)); + } else { + /* (2) - we point to the first free offset, no more data is stored further in this segment. + * There is no EXTENSION_SLOT by this addr since we continue pushing data for the same rank, + * and there is no need to split it. + * But it's possible that we reached the end of current data region and just jumped to the new region + * to put new data, in that case free_offset != offset and we must put EXTENSION_SLOT by the current addr + * forcibly and store new offset in its value. */ + if (free_offset != offset) { + /* segment was extended, need to put extension slot by free_offset indicating new_offset */ + ESH_PUT_KEY(addr, ESH_REGION_EXTENSION, (void*)&offset, sizeof(size_t)); + } + } + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u, replace flag %d item not found ext slot empty, put key %s to the end", + __FILE__, __LINE__, __func__, rank, data_exist, kval->key)); + } + } +exit: + PMIX_DESTRUCT(&buffer); + return rc; +} + +static int _store_data_for_rank(ns_track_elem_t *ns_info, pmix_rank_t rank, pmix_buffer_t *buf) +{ + pmix_status_t rc; + + pmix_kval_t *kp; + seg_desc_t *metadesc, *datadesc; + int32_t cnt; + + rank_meta_info *rinfo = NULL; + size_t num_elems, free_offset, new_free_offset; + int data_exist; + + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %u", __FILE__, __LINE__, __func__, rank)); + + metadesc = ns_info->meta_seg; + datadesc = ns_info->data_seg; + + if (NULL == datadesc || NULL == metadesc) { + rc = PMIX_ERR_BAD_PARAM; + PMIX_ERROR_LOG(rc); + return rc; + } + + num_elems = *((size_t*)(metadesc->seg_info.seg_base_addr)); + data_exist = 0; + /* when we don't use linear search (_direct_mode ==0 ) we don't use num_elems field, + * so anyway try to get rank_meta_info first. */ + if (0 < num_elems || 0 == _direct_mode) { + /* go through all elements in meta segment and look for target rank. */ + rinfo = _get_rank_meta_info(rank, metadesc); + if (NULL != rinfo) { + data_exist = 1; + } + } + /* incoming buffer may contain several inner buffers for different scopes, + * so unpack these buffers, and then unpack kvals from each modex buffer, + * storing them in the shared memory dstore. + */ + free_offset = get_free_offset(datadesc); + cnt = 1; + kp = PMIX_NEW(pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, buf, kp, &cnt, PMIX_KVAL); + while(PMIX_SUCCESS == rc) { + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "pmix: unpacked key %s", kp->key); + if (PMIX_SUCCESS != (rc = pmix_sm_store(ns_info, rank, kp, &rinfo, data_exist))) { + PMIX_ERROR_LOG(rc); + if (NULL != rinfo) { + free(rinfo); + } + return rc; + } + PMIX_RELEASE(kp); // maintain acctg - hash_store does a retain + cnt = 1; + kp = PMIX_NEW(pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, buf, kp, &cnt, PMIX_KVAL); + } + + PMIX_RELEASE(kp); + + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { + PMIX_ERROR_LOG(rc); + /* TODO: should we error-exit here? */ + } else { + rc = PMIX_SUCCESS; + } + + /* Check if new data was put at the end of data segment. + * It's possible that old data just was replaced with new one, + * in that case we don't reserve space for EXTENSION_SLOT, it's + * already reserved. + * */ + new_free_offset = get_free_offset(datadesc); + if (new_free_offset != free_offset) { + /* Reserve space for EXTENSION_SLOT at the end of data blob. + * We need it to split data for one rank from data for different + * ranks and to allow extending data further. + * We also put EXTENSION_SLOT at the end of each data segment, and + * its value points to the beginning of next data segment. + * */ + rc = put_empty_ext_slot(ns_info->data_seg); + if (PMIX_SUCCESS != rc) { + if ((0 == data_exist) && NULL != rinfo) { + free(rinfo); + } + PMIX_ERROR_LOG(rc); + return rc; + } + } + + /* if this is the first data posted for this rank, then + * update meta info for it */ + if (0 == data_exist) { + set_rank_meta_info(ns_info, rinfo); + if (NULL != rinfo) { + free(rinfo); + } + } + + return rc; +} + +static inline ssize_t _get_univ_size(const char *nspace) +{ + ssize_t nprocs = 0; + pmix_value_t *val; + int rc; + + rc = _dstore_fetch(nspace, PMIX_RANK_WILDCARD, PMIX_UNIV_SIZE, &val); + if( PMIX_SUCCESS != rc ) { + PMIX_ERROR_LOG(rc); + return rc; + } + if( val->type != PMIX_UINT32 ){ + rc = PMIX_ERR_BAD_PARAM; + PMIX_ERROR_LOG(rc); + return rc; + } + nprocs = (ssize_t)val->data.uint32; + PMIX_VALUE_RELEASE(val); + return nprocs; +} + +static pmix_status_t dstore_cache_job_info(struct pmix_nspace_t *ns, + pmix_info_t info[], size_t ninfo) +{ + return PMIX_SUCCESS; +} + +static pmix_status_t dstore_init(pmix_info_t info[], size_t ninfo) { pmix_status_t rc; size_t n; @@ -889,8 +1940,18 @@ int _esh_init(pmix_info_t info[], size_t ninfo) struct stat st = {0}; ns_map_data_t *ns_map = NULL; - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", __FILE__, __LINE__, __func__)); + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "pmix:gds:dstore init"); + + /* open the pshmem and select the active plugins */ + if( PMIX_SUCCESS != (rc = pmix_mca_base_framework_open(&pmix_pshmem_base_framework, 0)) ) { + PMIX_ERROR_LOG(rc); + goto err_exit; + } + if( PMIX_SUCCESS != (rc = pmix_pshmem_base_select()) ) { + PMIX_ERROR_LOG(rc); + goto err_exit; + } _jobuid = getuid(); _setjobuid = 0; @@ -907,7 +1968,7 @@ int _esh_init(pmix_info_t info[], size_t ninfo) goto err_exit; } - rc = pmix_sm_init(); + rc = pmix_pshmem.init(); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto err_exit; @@ -1037,19 +2098,19 @@ err_exit: return rc; } -int _esh_finalize(void) +static void dstore_finalize(void) { struct stat st = {0}; pmix_status_t rc = PMIX_SUCCESS; - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s", __FILE__, __LINE__, __func__)); _esh_sessions_cleanup(); _esh_ns_map_cleanup(); _esh_ns_track_cleanup(); - pmix_sm_finalize(); + pmix_pshmem.finalize(); if (NULL != _base_path){ if(PMIX_PROC_SERVER == pmix_globals.proc_type) { @@ -1062,11 +2123,11 @@ int _esh_finalize(void) free(_base_path); _base_path = NULL; } - - return rc; } -int _esh_store(const char *nspace, pmix_rank_t rank, pmix_kval_t *kv) +static pmix_status_t _dstore_store(const char *nspace, + pmix_rank_t rank, + pmix_kval_t *kv) { pmix_status_t rc = PMIX_SUCCESS, tmp_rc; ns_track_elem_t *elem; @@ -1078,7 +2139,7 @@ int _esh_store(const char *nspace, pmix_rank_t rank, pmix_kval_t *kv) return PMIX_ERROR; } - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s: for %s:%u", __FILE__, __LINE__, __func__, nspace, rank)); @@ -1140,7 +2201,7 @@ int _esh_store(const char *nspace, pmix_rank_t rank, pmix_kval_t *kv) /* Now we know info about meta segment for this namespace. If meta segment * is not empty, then we look for data for the target rank. If they present, replace it. */ PMIX_CONSTRUCT(&xfer, pmix_buffer_t); - PMIX_LOAD_BUFFER(&xfer, kv->value->data.bo.bytes, kv->value->data.bo.size); + PMIX_LOAD_BUFFER(pmix_globals.mypeer, &xfer, kv->value->data.bo.bytes, kv->value->data.bo.size); rc = _store_data_for_rank(elem, rank, &xfer); @@ -1165,11 +2226,41 @@ err_exit: return rc; } -/* - * See return codes description for the corresponding function - * in pmix_dstore.h - */ -int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value_t **kvs) +static pmix_status_t dstore_store(const pmix_proc_t *proc, + pmix_scope_t scope, + pmix_kval_t *kv) +{ + pmix_status_t rc = PMIX_SUCCESS; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds: dstore store for key '%s' scope %d", + proc->nspace, proc->rank, kv->key, scope); + + if (PMIX_PROC_CLIENT == pmix_globals.proc_type) { + rc = PMIX_ERR_NOT_SUPPORTED; + PMIX_ERROR_LOG(rc); + return rc; + } + else { + pmix_kval_t *kv2; + kv2 = PMIX_NEW(pmix_kval_t); + PMIX_VALUE_CREATE(kv2->value, 1); + kv2->value->type = PMIX_BYTE_OBJECT; + + pmix_buffer_t tmp; + PMIX_CONSTRUCT(&tmp, pmix_buffer_t); + + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &tmp, kv, 1, PMIX_KVAL); + PMIX_UNLOAD_BUFFER(&tmp, kv2->value->data.bo.bytes, kv2->value->data.bo.size); + + rc = _dstore_store(proc->nspace, proc->rank, kv2); + PMIX_RELEASE(kv2); + PMIX_DESTRUCT(&tmp); + } + return rc; +} + +inline pmix_status_t _dstore_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value_t **kvs) { ns_seg_info_t *ns_info = NULL; pmix_status_t rc = PMIX_ERROR, lock_rc; @@ -1179,22 +2270,28 @@ int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value seg_desc_t *meta_seg, *data_seg; uint8_t *addr; pmix_buffer_t buffer; - pmix_value_t val; + pmix_value_t val, *kval = NULL; uint32_t nprocs; pmix_rank_t cur_rank; ns_map_data_t *ns_map = NULL; bool all_ranks_found = true; bool key_found = false; + pmix_info_t *info = NULL; + size_t ninfo; - if (NULL == key) { - PMIX_OUTPUT_VERBOSE((7, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for %s:%u look for key %s", + __FILE__, __LINE__, __func__, nspace, rank, key)); + + if ((PMIX_RANK_UNDEF == rank) && (NULL == key)) { + PMIX_OUTPUT_VERBOSE((7, pmix_gds_base_framework.framework_output, "dstore: Does not support passed parameters")); rc = PMIX_ERR_BAD_PARAM; PMIX_ERROR_LOG(rc); return rc; } - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s: for %s:%u look for key %s", __FILE__, __LINE__, __func__, nspace, rank, key)); @@ -1250,7 +2347,7 @@ int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value ns_info = _get_ns_info_from_initial_segment(ns_map); if (NULL == ns_info) { /* no data for this namespace is found in the shared memory. */ - PMIX_OUTPUT_VERBOSE((7, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((7, pmix_gds_base_framework.framework_output, "%s:%d:%s: no data for ns %s is found in the shared memory.", __FILE__, __LINE__, __func__, ns_map->name)); rc = PMIX_ERR_PROC_ENTRY_NOT_FOUND; @@ -1283,7 +2380,7 @@ int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value /* Get the rank meta info in the shared meta segment. */ rinfo = _get_rank_meta_info(cur_rank, meta_seg); if (NULL == rinfo) { - PMIX_OUTPUT_VERBOSE((7, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((7, pmix_gds_base_framework.framework_output, "%s:%d:%s: no data for this rank is found in the shared memory. rank %u", __FILE__, __LINE__, __func__, cur_rank)); all_ranks_found = false; @@ -1298,6 +2395,33 @@ int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value } kval_cnt = rinfo->count; + /* Initialize array for all keys of rank */ + if ((NULL == key) || (kval_cnt > 0)) { + kval = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == kval) { + return PMIX_ERR_NOMEM; + } + + ninfo = kval_cnt; + PMIX_INFO_CREATE(info, ninfo); + if (NULL == info) { + rc = PMIX_ERR_NOMEM; + goto done; + } + + PMIX_VALUE_CONSTRUCT(kval); + kval->type = PMIX_DATA_ARRAY; + kval->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); + if (NULL == kval->data.darray) { + rc = PMIX_ERR_NOMEM; + goto done; + } + kval->data.darray->type = PMIX_INFO; + kval->data.darray->size = ninfo; + kval->data.darray->array = info; + *kvs = kval; + } + rc = PMIX_SUCCESS; while (0 < kval_cnt) { /* data is stored in the following format: @@ -1314,7 +2438,7 @@ int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value * to next data address for this process. */ if (0 == strncmp(ESH_KNAME_PTR(addr), ESH_REGION_INVALIDATED, ESH_KNAME_LEN(ESH_REGION_INVALIDATED))) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s: for rank %s:%u, skip %s region", __FILE__, __LINE__, __func__, nspace, cur_rank, ESH_REGION_INVALIDATED)); /* skip it @@ -1323,7 +2447,7 @@ int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value } else if (0 == strncmp(ESH_KNAME_PTR(addr), ESH_REGION_EXTENSION, ESH_KNAME_LEN(ESH_REGION_EXTENSION))) { size_t offset; memcpy(&offset, ESH_DATA_PTR(addr), sizeof(size_t)); - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s: for rank %s:%u, reached %s with %lu value", __FILE__, __LINE__, __func__, nspace, cur_rank, ESH_REGION_EXTENSION, offset)); if (0 < offset) { @@ -1337,28 +2461,57 @@ int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value } } else { /* no more data for this rank */ - PMIX_OUTPUT_VERBOSE((7, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((7, pmix_gds_base_framework.framework_output, "%s:%d:%s: no more data for this rank is found in the shared memory. rank %u key %s not found", __FILE__, __LINE__, __func__, cur_rank, key)); break; } + } else if (NULL == key) { + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, + "%s:%d:%s: for rank %s:%u, found target key %s", + __FILE__, __LINE__, __func__, nspace, cur_rank, ESH_KNAME_PTR(addr))); + + uint8_t *data_ptr = ESH_DATA_PTR(addr); + size_t data_size = ESH_DATA_SIZE(addr, data_ptr); + PMIX_CONSTRUCT(&buffer, pmix_buffer_t); + PMIX_LOAD_BUFFER(pmix_globals.mypeer, &buffer, data_ptr, data_size); + int cnt = 1; + /* unpack value for this key from the buffer. */ + PMIX_VALUE_CONSTRUCT(&val); + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, &buffer, &val, &cnt, PMIX_VALUE); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + goto done; + } + strncpy(info[kval_cnt - 1].key, ESH_KNAME_PTR(addr), ESH_KNAME_LEN((char *)addr)); + pmix_value_xfer(&info[kval_cnt - 1].value, &val); + PMIX_VALUE_DESTRUCT(&val); + buffer.base_ptr = NULL; + buffer.bytes_used = 0; + PMIX_DESTRUCT(&buffer); + key_found = true; + + kval_cnt--; + addr += ESH_KV_SIZE(addr); } else if (0 == strncmp(ESH_KNAME_PTR(addr), key, ESH_KNAME_LEN(key))) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s: for rank %s:%u, found target key %s", __FILE__, __LINE__, __func__, nspace, cur_rank, key)); /* target key is found, get value */ uint8_t *data_ptr = ESH_DATA_PTR(addr); size_t data_size = ESH_DATA_SIZE(addr, data_ptr); PMIX_CONSTRUCT(&buffer, pmix_buffer_t); - PMIX_LOAD_BUFFER(&buffer, data_ptr, data_size); + PMIX_LOAD_BUFFER(pmix_globals.mypeer, &buffer, data_ptr, data_size); int cnt = 1; /* unpack value for this key from the buffer. */ PMIX_VALUE_CONSTRUCT(&val); - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(&buffer, &val, &cnt, PMIX_VALUE))) { + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, &buffer, &val, &cnt, PMIX_VALUE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto done; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.copy((void**)kvs, &val, PMIX_VALUE))) { + PMIX_BFROPS_COPY(rc, pmix_globals.mypeer, (void**)kvs, &val, PMIX_VALUE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto done; } @@ -1369,7 +2522,7 @@ int _esh_fetch(const char *nspace, pmix_rank_t rank, const char *key, pmix_value key_found = true; goto done; } else { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s: for rank %s:%u, skip key %s look for key %s", __FILE__, __LINE__, __func__, nspace, cur_rank, ESH_KNAME_PTR(addr), key)); /* go to next item, updating address */ @@ -1390,6 +2543,11 @@ done: } if( rc != PMIX_SUCCESS ){ + if( NULL == key ) { + if( NULL != info ) { + PMIX_INFO_FREE(info, ninfo); + } + } return rc; } @@ -1409,18 +2567,82 @@ done: return rc; } -static int _esh_patch_env(const char *nspace, char ***env) +static pmix_status_t dstore_fetch(const pmix_proc_t *proc, + pmix_scope_t scope, bool copy, + const char *key, + pmix_info_t info[], size_t ninfo, + pmix_list_t *kvs) +{ + pmix_kval_t *kv; + pmix_value_t *val; + pmix_status_t rc = PMIX_SUCCESS; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "gds: dstore fetch `%s`", key == NULL ? "NULL" : key); + + rc = _dstore_fetch(proc->nspace, proc->rank, key, &val); + if (PMIX_SUCCESS == rc) { + if( NULL == key ) { + pmix_info_t *info; + size_t n, ninfo; + + if (NULL == val->data.darray || + PMIX_INFO != val->data.darray->type || + 0 == val->data.darray->size) { + PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); + return PMIX_ERR_NOT_FOUND; + } + info = (pmix_info_t*)val->data.darray->array; + ninfo = val->data.darray->size; + + for (n = 0; n < ninfo; n++){ + kv = PMIX_NEW(pmix_kval_t); + if (NULL == kv) { + rc = PMIX_ERR_NOMEM; + PMIX_VALUE_RELEASE(val); + return rc; + } + kv->key = strdup(info[n].key); + PMIX_VALUE_XFER(rc, kv->value, &info[n].value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kv); + PMIX_VALUE_RELEASE(val); + return rc; + } + pmix_list_append(kvs, &kv->super); + } + + return PMIX_SUCCESS; + } + /* just return the value */ + kv = PMIX_NEW(pmix_kval_t); + if (NULL == kv) { + PMIX_VALUE_RELEASE(val); + return PMIX_ERR_NOMEM; + } + kv->key = strdup(key); + kv->value = val; + pmix_list_append(kvs, &kv->super); + } + return rc; +} + +static pmix_status_t dstore_setup_fork(const pmix_proc_t *peer, char ***env) { pmix_status_t rc = PMIX_SUCCESS; ns_map_data_t *ns_map = NULL; + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "gds: dstore setup fork"); + if (NULL == _esh_session_map_search) { rc = PMIX_ERR_NOT_AVAILABLE; PMIX_ERROR_LOG(rc); return rc; } - if (NULL == (ns_map = _esh_session_map_search(nspace))) { + if (NULL == (ns_map = _esh_session_map_search(peer->nspace))) { rc = PMIX_ERR_NOT_AVAILABLE; PMIX_ERROR_LOG(rc); return rc; @@ -1439,7 +2661,9 @@ static int _esh_patch_env(const char *nspace, char ***env) return rc; } -static int _esh_nspace_add(const char *nspace, pmix_info_t info[], size_t ninfo) +static pmix_status_t dstore_add_nspace(const char *nspace, + pmix_info_t info[], + size_t ninfo) { pmix_status_t rc; size_t tbl_idx; @@ -1448,6 +2672,9 @@ static int _esh_nspace_add(const char *nspace, pmix_info_t info[], size_t ninfo) size_t n; ns_map_data_t *ns_map = NULL; + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "gds: dstore add nspace"); + if (NULL != info) { for (n=0; n < ninfo; n++) { if (0 == strcmp(PMIX_USERID, info[n].key)) { @@ -1490,7 +2717,7 @@ static int _esh_nspace_add(const char *nspace, pmix_info_t info[], size_t ninfo) return PMIX_SUCCESS; } -static int _esh_nspace_del(const char *nspace) +static pmix_status_t dstore_del_nspace(const char* nspace) { pmix_status_t rc = PMIX_SUCCESS; size_t map_idx, size; @@ -1500,7 +2727,7 @@ static int _esh_nspace_del(const char *nspace) session_t *session_tbl = NULL; ns_track_elem_t *trk = NULL; - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s delete nspace `%s`", __FILE__, __LINE__, __func__, nspace)); if (NULL == (ns_map_data = _esh_session_map_search(nspace))) { @@ -1538,7 +2765,7 @@ static int _esh_nspace_del(const char *nspace) if (!in_use) { session_tbl = PMIX_VALUE_ARRAY_GET_BASE(_session_array, session_t); - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, + PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output, "%s:%d:%s delete session for jobuid: %d", __FILE__, __LINE__, __func__, session_tbl[ns_map_data->tbl_idx].jobuid)); _esh_session_release(&session_tbl[ns_map_data->tbl_idx]); } @@ -1546,995 +2773,559 @@ exit: return rc; } -static void _set_constants_from_env() +static pmix_status_t dstore_assign_module(pmix_info_t *info, size_t ninfo, + int *priority) { - char *str; - int page_size = _pmix_getpagesize(); + size_t n, m; + char **options; - if( NULL != (str = getenv(ESH_ENV_INITIAL_SEG_SIZE)) ) { - _initial_segment_size = strtoul(str, NULL, 10); - if ((size_t)page_size > _initial_segment_size) { - _initial_segment_size = (size_t)page_size; - } - } - if (0 == _initial_segment_size) { - _initial_segment_size = INITIAL_SEG_SIZE; - } - if( NULL != (str = getenv(ESH_ENV_NS_META_SEG_SIZE)) ) { - _meta_segment_size = strtoul(str, NULL, 10); - if ((size_t)page_size > _meta_segment_size) { - _meta_segment_size = (size_t)page_size; - } - } - if (0 == _meta_segment_size) { - _meta_segment_size = NS_META_SEG_SIZE; - } - if( NULL != (str = getenv(ESH_ENV_NS_DATA_SEG_SIZE)) ) { - _data_segment_size = strtoul(str, NULL, 10); - if ((size_t)page_size > _data_segment_size) { - _data_segment_size = (size_t)page_size; - } - } - if (0 == _data_segment_size) { - _data_segment_size = NS_DATA_SEG_SIZE; - } - if (NULL != (str = getenv(ESH_ENV_LINEAR))) { - if (1 == strtoul(str, NULL, 10)) { - _direct_mode = 1; - } - } - - _lock_segment_size = page_size; - _max_ns_num = (_initial_segment_size - sizeof(size_t) * 2) / sizeof(ns_seg_info_t); - _max_meta_elems = (_meta_segment_size - sizeof(size_t)) / sizeof(rank_meta_info); - -} - -static void _delete_sm_desc(seg_desc_t *desc) -{ - seg_desc_t *tmp; - - /* free all global segments */ - while (NULL != desc) { - tmp = desc->next; - /* detach & unlink from current desc */ - if (desc->seg_info.seg_cpid == getpid()) { - pmix_sm_segment_unlink(&desc->seg_info); - } - pmix_sm_segment_detach(&desc->seg_info); - free(desc); - desc = tmp; - } -} - -static int _pmix_getpagesize(void) -{ -#if defined(_SC_PAGESIZE ) - return sysconf(_SC_PAGESIZE); -#elif defined(_SC_PAGE_SIZE) - return sysconf(_SC_PAGE_SIZE); -#else - return 65536; /* safer to overestimate than under */ -#endif -} - -static seg_desc_t *_create_new_segment(segment_type type, const ns_map_data_t *ns_map, uint32_t id) -{ - pmix_status_t rc; - char file_name[PMIX_PATH_MAX]; - size_t size; - seg_desc_t *new_seg = NULL; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: segment type %d, nspace %s, id %u", - __FILE__, __LINE__, __func__, type, ns_map->name, id)); - - switch (type) { - case INITIAL_SEGMENT: - size = _initial_segment_size; - snprintf(file_name, PMIX_PATH_MAX, "%s/initial-pmix_shared-segment-%u", - _ESH_SESSION_path(ns_map->tbl_idx), id); - break; - case NS_META_SEGMENT: - size = _meta_segment_size; - snprintf(file_name, PMIX_PATH_MAX, "%s/smseg-%s-%u", - _ESH_SESSION_path(ns_map->tbl_idx), ns_map->name, id); - break; - case NS_DATA_SEGMENT: - size = _data_segment_size; - snprintf(file_name, PMIX_PATH_MAX, "%s/smdataseg-%s-%d", - _ESH_SESSION_path(ns_map->tbl_idx), ns_map->name, id); - break; - default: - PMIX_ERROR_LOG(PMIX_ERROR); - return NULL; - } - new_seg = (seg_desc_t*)malloc(sizeof(seg_desc_t)); - if (new_seg) { - new_seg->id = id; - new_seg->next = NULL; - new_seg->type = type; - rc = pmix_sm_segment_create(&new_seg->seg_info, file_name, size); - if (PMIX_SUCCESS != rc) { - PMIX_ERROR_LOG(rc); - goto err_exit; - } - memset(new_seg->seg_info.seg_base_addr, 0, size); - - - if (_ESH_SESSION_setjobuid(ns_map->tbl_idx) > 0){ - rc = PMIX_ERR_PERM; - if (0 > chown(file_name, (uid_t) _ESH_SESSION_jobuid(ns_map->tbl_idx), (gid_t) -1)){ - PMIX_ERROR_LOG(rc); - goto err_exit; - } - /* set the mode as required */ - if (0 > chmod(file_name, S_IRUSR | S_IRGRP | S_IWGRP )) { - PMIX_ERROR_LOG(rc); - goto err_exit; - } - } - } - return new_seg; - -err_exit: - if( NULL != new_seg ){ - free(new_seg); - } - return NULL; -} - -static seg_desc_t *_attach_new_segment(segment_type type, const ns_map_data_t *ns_map, uint32_t id) -{ - pmix_status_t rc; - seg_desc_t *new_seg = NULL; - new_seg = (seg_desc_t*)malloc(sizeof(seg_desc_t)); - new_seg->id = id; - new_seg->next = NULL; - new_seg->type = type; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: segment type %d, nspace %s, id %u", - __FILE__, __LINE__, __func__, type, ns_map->name, id)); - - switch (type) { - case INITIAL_SEGMENT: - new_seg->seg_info.seg_size = _initial_segment_size; - snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/initial-pmix_shared-segment-%u", - _ESH_SESSION_path(ns_map->tbl_idx), id); - break; - case NS_META_SEGMENT: - new_seg->seg_info.seg_size = _meta_segment_size; - snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/smseg-%s-%u", - _ESH_SESSION_path(ns_map->tbl_idx), ns_map->name, id); - break; - case NS_DATA_SEGMENT: - new_seg->seg_info.seg_size = _data_segment_size; - snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/smdataseg-%s-%d", - _ESH_SESSION_path(ns_map->tbl_idx), ns_map->name, id); - break; - default: - PMIX_ERROR_LOG(PMIX_ERROR); - return NULL; - } - rc = pmix_sm_segment_attach(&new_seg->seg_info, PMIX_SM_RONLY); - if (PMIX_SUCCESS != rc) { - free(new_seg); - new_seg = NULL; - PMIX_ERROR_LOG(rc); - } - return new_seg; -} - -/* This function synchronizes the content of initial shared segment and the local track list. */ -static int _update_ns_elem(ns_track_elem_t *ns_elem, ns_seg_info_t *info) -{ - seg_desc_t *seg, *tmp = NULL; - size_t i, offs; - ns_map_data_t *ns_map = NULL; - pmix_status_t rc; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", - __FILE__, __LINE__, __func__)); - - if (NULL == (ns_map = _esh_session_map_search(info->ns_map.name))) { - rc = PMIX_ERR_NOT_AVAILABLE; - PMIX_ERROR_LOG(rc); - return rc; - } - - tmp = ns_elem->meta_seg; - if (NULL != tmp) { - while(NULL != tmp->next) { - tmp = tmp->next; - } - } - - /* synchronize number of meta segments for the target namespace. */ - for (i = ns_elem->num_meta_seg; i < info->num_meta_seg; i++) { - if (PMIX_PROC_SERVER == pmix_globals.proc_type) { - seg = _create_new_segment(NS_META_SEGMENT, &info->ns_map, i); - if (NULL == seg) { - rc = PMIX_ERR_OUT_OF_RESOURCE; - PMIX_ERROR_LOG(rc); - return rc; - } - } else { - seg = _attach_new_segment(NS_META_SEGMENT, &info->ns_map, i); - if (NULL == seg) { - rc = PMIX_ERR_NOT_AVAILABLE; - PMIX_ERROR_LOG(rc); - return rc; - } - } - - if (NULL == tmp) { - ns_elem->meta_seg = seg; - } else { - tmp->next = seg; - } - tmp = seg; - ns_elem->num_meta_seg++; - } - - tmp = ns_elem->data_seg; - if (NULL != tmp) { - while(NULL != tmp->next) { - tmp = tmp->next; - } - } - /* synchronize number of data segments for the target namespace. */ - for (i = ns_elem->num_data_seg; i < info->num_data_seg; i++) { - if (PMIX_PROC_SERVER == pmix_globals.proc_type) { - seg = _create_new_segment(NS_DATA_SEGMENT, &info->ns_map, i); - if (NULL == seg) { - rc = PMIX_ERR_OUT_OF_RESOURCE; - PMIX_ERROR_LOG(rc); - return rc; - } - offs = sizeof(size_t);//shift on offset field itself - memcpy(seg->seg_info.seg_base_addr, &offs, sizeof(size_t)); - } else { - seg = _attach_new_segment(NS_DATA_SEGMENT, &info->ns_map, i); - if (NULL == seg) { - rc = PMIX_ERR_NOT_AVAILABLE; - PMIX_ERROR_LOG(rc); - return rc; - } - } - - if (NULL == tmp) { - ns_elem->data_seg = seg; - } else { - tmp->next = seg; - } - tmp = seg; - ns_elem->num_data_seg++; - } - - return PMIX_SUCCESS; -} - -static seg_desc_t *extend_segment(seg_desc_t *segdesc, const ns_map_data_t *ns_map) -{ - seg_desc_t *tmp, *seg; - - PMIX_OUTPUT_VERBOSE((2, pmix_globals.debug_output, - "%s:%d:%s", - __FILE__, __LINE__, __func__)); - /* find last segment */ - tmp = segdesc; - while (NULL != tmp->next) { - tmp = tmp->next; - } - /* create another segment, the old one is full. */ - seg = _create_new_segment(segdesc->type, ns_map, tmp->id + 1); - tmp->next = seg; - - return seg; -} - -static int _put_ns_info_to_initial_segment(const ns_map_data_t *ns_map, pmix_sm_seg_t *metaseg, pmix_sm_seg_t *dataseg) -{ - ns_seg_info_t elem; - size_t num_elems; - num_elems = *((size_t*)(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr)); - seg_desc_t *last_seg = _ESH_SESSION_sm_seg_last(ns_map->tbl_idx); - pmix_status_t rc; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", __FILE__, __LINE__, __func__)); - - if (_max_ns_num == num_elems) { - num_elems = 0; - if (NULL == (last_seg = extend_segment(last_seg, ns_map))) { - rc = PMIX_ERROR; - PMIX_ERROR_LOG(rc); - return rc; - } - /* mark previous segment as full */ - size_t full = 1; - memcpy((uint8_t*)(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr + sizeof(size_t)), &full, sizeof(size_t)); - _ESH_SESSION_sm_seg_last(ns_map->tbl_idx) = last_seg; - memset(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr, 0, _initial_segment_size); - } - memset(&elem.ns_map, 0, sizeof(elem.ns_map)); - strncpy(elem.ns_map.name, ns_map->name, sizeof(elem.ns_map.name)-1); - elem.ns_map.tbl_idx = ns_map->tbl_idx; - elem.num_meta_seg = 1; - elem.num_data_seg = 1; - memcpy((uint8_t*)(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr) + sizeof(size_t) * 2 + num_elems * sizeof(ns_seg_info_t), - &elem, sizeof(ns_seg_info_t)); - num_elems++; - memcpy((uint8_t*)(_ESH_SESSION_sm_seg_last(ns_map->tbl_idx)->seg_info.seg_base_addr), &num_elems, sizeof(size_t)); - return PMIX_SUCCESS; -} - -/* clients should sync local info with information from initial segment regularly */ -static void _update_initial_segment_info(const ns_map_data_t *ns_map) -{ - seg_desc_t *tmp; - tmp = _ESH_SESSION_sm_seg_first(ns_map->tbl_idx); - - PMIX_OUTPUT_VERBOSE((2, pmix_globals.debug_output, - "%s:%d:%s", __FILE__, __LINE__, __func__)); - - /* go through all global segments */ - do { - /* check if current segment was marked as full but no more next segment is in the chain */ - if (NULL == tmp->next && 1 == *((size_t*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t)))) { - tmp->next = _attach_new_segment(INITIAL_SEGMENT, ns_map, tmp->id+1); - } - tmp = tmp->next; - } - while (NULL != tmp); -} - -/* this function will be used by clients to get ns data from the initial segment and add them to the tracker list */ -static ns_seg_info_t *_get_ns_info_from_initial_segment(const ns_map_data_t *ns_map) -{ - pmix_status_t rc; - size_t i; - seg_desc_t *tmp; - ns_seg_info_t *elem, *cur_elem; - elem = NULL; - size_t num_elems; - - PMIX_OUTPUT_VERBOSE((2, pmix_globals.debug_output, - "%s:%d:%s", __FILE__, __LINE__, __func__)); - - tmp = _ESH_SESSION_sm_seg_first(ns_map->tbl_idx); - - rc = 1; - /* go through all global segments */ - do { - num_elems = *((size_t*)(tmp->seg_info.seg_base_addr)); - for (i = 0; i < num_elems; i++) { - cur_elem = (ns_seg_info_t*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t) * 2 + i * sizeof(ns_seg_info_t)); - if (0 == (rc = strncmp(cur_elem->ns_map.name, ns_map->name, strlen(ns_map->name)+1))) { + *priority = -1; + if (NULL != info) { + for (n=0; n < ninfo; n++) { + if (0 == strncmp(info[n].key, PMIX_GDS_MODULE, PMIX_MAX_KEYLEN)) { + options = pmix_argv_split(info[n].value.data.string, ','); + for (m=0; NULL != options[m]; m++) { + if (0 == strcmp(options[m], "ds12")) { + /* they specifically asked for us */ + *priority = 100; + break; + } + if (0 == strcmp(options[m], "dstore")) { + /* they are asking for any dstore module - we + * take an intermediate priority in case another + * dstore is more modern than us */ + *priority = 50; + break; + } + } + pmix_argv_free(options); break; } } - if (0 == rc) { - elem = cur_elem; + } + +#if 0 + if PMIX_GDS_MODULE != "ds12" + *proirity = 0; + else PMIX_GDS_MODULE == "ds12" || !PMIX_GDS_MODULE + *priority = -1; +#endif + return PMIX_SUCCESS; +} + +static inline int _my_client(const char *nspace, pmix_rank_t rank) +{ + pmix_peer_t *peer; + int i; + int local = 0; + + for (i = 0; i < pmix_server_globals.clients.size; i++) { + if (NULL != (peer = (pmix_peer_t *)pmix_pointer_array_get_item(&pmix_server_globals.clients, i))) { + if (0 == strcmp(peer->info->pname.nspace, nspace) && peer->info->pname.rank == rank) { + local = 1; + break; + } + } + } + + return local; +} + +/* this function is only called by the PMIx server when its + * host has received data from some other peer. It therefore + * always contains data solely from remote procs, and we + * shall store it accordingly */ +static pmix_status_t dstore_store_modex(struct pmix_nspace_t *nspace, + pmix_list_t *cbs, + pmix_byte_object_t *bo) +{ + pmix_nspace_t *ns = (pmix_nspace_t*)nspace; + pmix_server_caddy_t *scd; + pmix_status_t rc = PMIX_SUCCESS; + int32_t cnt; + pmix_buffer_t pbkt; + pmix_proc_t proc; + pmix_kval_t *kv; + pmix_peer_t *peer; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:dstore:store_modex for nspace %s", + pmix_globals.myid.nspace, pmix_globals.myid.rank, + ns->nspace); + + /* this is data returned via the PMIx_Fence call when + * data collection was requested, so it only contains + * REMOTE/GLOBAL data. The byte object contains + * the rank followed by pmix_kval_t's. The list of callbacks + * contains all local participants. */ + peer = NULL; + PMIX_LIST_FOREACH(scd, cbs, pmix_server_caddy_t) { + if (scd->peer->nptr == ns) { + peer = scd->peer; break; } - tmp = tmp->next; } - while (NULL != tmp); - return elem; -} - -static ns_track_elem_t *_get_track_elem_for_namespace(ns_map_data_t *ns_map) -{ - ns_track_elem_t *new_elem = NULL; - size_t size = pmix_value_array_get_size(_ns_track_array); - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: nspace %s", - __FILE__, __LINE__, __func__, ns_map->name)); - - /* check if this namespace is already being tracked to avoid duplicating data. */ - if (ns_map->track_idx >= 0) { - if ((ns_map->track_idx + 1) > (int)size) { - return NULL; - } - /* data for this namespace should be already stored in shared memory region. */ - /* so go and just put new data. */ - return pmix_value_array_get_item(_ns_track_array, ns_map->track_idx); + if (NULL == peer) { + /* we can ignore this one */ + return PMIX_SUCCESS; } - /* create shared memory regions for this namespace and store its info locally - * to operate with address and detach/unlink afterwards. */ - if (NULL == (new_elem = pmix_value_array_get_item(_ns_track_array, size))) { - return NULL; - } - PMIX_CONSTRUCT(new_elem, ns_track_elem_t); - strncpy(new_elem->ns_map.name, ns_map->name, sizeof(new_elem->ns_map.name)-1); - /* save latest track idx to info of nspace */ - ns_map->track_idx = size; - - return new_elem; -} - -static rank_meta_info *_get_rank_meta_info(pmix_rank_t rank, seg_desc_t *segdesc) -{ - size_t i; - rank_meta_info *elem = NULL; - seg_desc_t *tmp = segdesc; - size_t num_elems, rel_offset; - int id; - rank_meta_info *cur_elem; - - size_t rcount = rank == PMIX_RANK_WILDCARD ? 0 : rank + 1; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", - __FILE__, __LINE__, __func__)); - - if (1 == _direct_mode) { - /* do linear search to find the requested rank inside all meta segments - * for this namespace. */ - /* go through all existing meta segments for this namespace */ - do { - num_elems = *((size_t*)(tmp->seg_info.seg_base_addr)); - for (i = 0; i < num_elems; i++) { - cur_elem = (rank_meta_info*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t) + i * sizeof(rank_meta_info)); - if (rcount == cur_elem->rank) { - elem = cur_elem; - break; - } - } - tmp = tmp->next; - } - while (NULL != tmp && NULL == elem); - } else { - /* directly compute index of meta segment (id) and relative offset (rel_offset) - * inside this segment for fast lookup a rank_meta_info object for the requested rank. */ - id = rcount/_max_meta_elems; - rel_offset = (rcount%_max_meta_elems) * sizeof(rank_meta_info) + sizeof(size_t); - /* go through all existing meta segments for this namespace. - * Stop at id number if it exists. */ - while (NULL != tmp->next && 0 != id) { - tmp = tmp->next; - id--; - } - if (0 == id) { - /* the segment is found, looking for data for the target rank. */ - elem = (rank_meta_info*)((uint8_t*)(tmp->seg_info.seg_base_addr) + rel_offset); - if ( 0 == elem->offset) { - /* offset can never be 0, it means that there is no data for this rank yet. */ - elem = NULL; - } - } - } - return elem; -} - -static int set_rank_meta_info(ns_track_elem_t *ns_info, rank_meta_info *rinfo) -{ - /* it's claimed that there is still no meta info for this rank stored */ - seg_desc_t *tmp; - size_t num_elems, rel_offset; - int id, count; - rank_meta_info *cur_elem; - - if (!ns_info || !rinfo) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - - PMIX_OUTPUT_VERBOSE((2, pmix_globals.debug_output, - "%s:%d:%s: nspace %s, add rank %lu offset %lu count %lu meta info", - __FILE__, __LINE__, __func__, - ns_info->ns_map.name, rinfo->rank, rinfo->offset, rinfo->count)); - - tmp = ns_info->meta_seg; - if (1 == _direct_mode) { - /* get the last meta segment to put new rank_meta_info at the end. */ - while (NULL != tmp->next) { - tmp = tmp->next; - } - num_elems = *((size_t*)(tmp->seg_info.seg_base_addr)); - if (_max_meta_elems <= num_elems) { - PMIX_OUTPUT_VERBOSE((2, pmix_globals.debug_output, - "%s:%d:%s: extend meta segment for nspace %s", - __FILE__, __LINE__, __func__, ns_info->ns_map.name)); - /* extend meta segment, so create a new one */ - tmp = extend_segment(tmp, &ns_info->ns_map); - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - ns_info->num_meta_seg++; - memset(tmp->seg_info.seg_base_addr, 0, sizeof(rank_meta_info)); - /* update number of meta segments for namespace in initial_segment */ - ns_seg_info_t *elem = _get_ns_info_from_initial_segment(&ns_info->ns_map); - if (NULL == elem) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - if (ns_info->num_meta_seg != elem->num_meta_seg) { - elem->num_meta_seg = ns_info->num_meta_seg; - } - num_elems = 0; - } - cur_elem = (rank_meta_info*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t) + num_elems * sizeof(rank_meta_info)); - memcpy(cur_elem, rinfo, sizeof(rank_meta_info)); - num_elems++; - memcpy(tmp->seg_info.seg_base_addr, &num_elems, sizeof(size_t)); - } else { - /* directly compute index of meta segment (id) and relative offset (rel_offset) - * inside this segment for fast lookup a rank_meta_info object for the requested rank. */ - size_t rcount = rinfo->rank == PMIX_RANK_WILDCARD ? 0 : rinfo->rank + 1; - id = rcount/_max_meta_elems; - rel_offset = (rcount % _max_meta_elems) * sizeof(rank_meta_info) + sizeof(size_t); - count = id; - /* go through all existing meta segments for this namespace. - * Stop at id number if it exists. */ - while (NULL != tmp->next && 0 != count) { - tmp = tmp->next; - count--; - } - /* if there is no segment with this id, then create all missing segments till the id number. */ - if ((int)ns_info->num_meta_seg < (id+1)) { - while ((int)ns_info->num_meta_seg != (id+1)) { - /* extend meta segment, so create a new one */ - tmp = extend_segment(tmp, &ns_info->ns_map); - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - memset(tmp->seg_info.seg_base_addr, 0, sizeof(rank_meta_info)); - ns_info->num_meta_seg++; - } - /* update number of meta segments for namespace in initial_segment */ - ns_seg_info_t *elem = _get_ns_info_from_initial_segment(&ns_info->ns_map); - if (NULL == elem) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - if (ns_info->num_meta_seg != elem->num_meta_seg) { - elem->num_meta_seg = ns_info->num_meta_seg; - } - } - /* store rank_meta_info object by rel_offset. */ - cur_elem = (rank_meta_info*)((uint8_t*)(tmp->seg_info.seg_base_addr) + rel_offset); - memcpy(cur_elem, rinfo, sizeof(rank_meta_info)); - } - return PMIX_SUCCESS; -} - -static uint8_t *_get_data_region_by_offset(seg_desc_t *segdesc, size_t offset) -{ - seg_desc_t *tmp = segdesc; - size_t rel_offset = offset; - uint8_t *dataaddr = NULL; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", - __FILE__, __LINE__, __func__)); - - /* go through all existing data segments for this namespace */ - do { - if (rel_offset >= _data_segment_size) { - rel_offset -= _data_segment_size; - } else { - dataaddr = tmp->seg_info.seg_base_addr + rel_offset; - } - tmp = tmp->next; - } while (NULL != tmp && NULL == dataaddr); - - return dataaddr; -} - -static size_t get_free_offset(seg_desc_t *data_seg) -{ - size_t offset; - seg_desc_t *tmp; - int id = 0; - tmp = data_seg; - /* first find the last data segment */ - while (NULL != tmp->next) { - tmp = tmp->next; - id++; - } - offset = *((size_t*)(tmp->seg_info.seg_base_addr)); - if (0 == offset) { - /* this is the first created data segment, the first 8 bytes are used to place the free offset value itself */ - offset = sizeof(size_t); - } - return (id * _data_segment_size + offset); -} - -static int put_empty_ext_slot(seg_desc_t *dataseg) -{ - size_t global_offset, rel_offset, data_ended, val = 0; - uint8_t *addr; - global_offset = get_free_offset(dataseg); - rel_offset = global_offset % _data_segment_size; - if (rel_offset + EXT_SLOT_SIZE() > _data_segment_size) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - addr = _get_data_region_by_offset(dataseg, global_offset); - ESH_PUT_KEY(addr, ESH_REGION_EXTENSION, (void*)&val, sizeof(size_t)); - - /* update offset at the beginning of current segment */ - data_ended = rel_offset + EXT_SLOT_SIZE(); - addr = (uint8_t*)(addr - rel_offset); - memcpy(addr, &data_ended, sizeof(size_t)); - return PMIX_SUCCESS; -} - -static size_t put_data_to_the_end(ns_track_elem_t *ns_info, seg_desc_t *dataseg, char *key, void *buffer, size_t size) -{ - size_t offset, id = 0; - seg_desc_t *tmp; - size_t global_offset, data_ended; - uint8_t *addr; - - PMIX_OUTPUT_VERBOSE((2, pmix_globals.debug_output, - "%s:%d:%s: key %s", - __FILE__, __LINE__, __func__, key)); - - tmp = dataseg; - while (NULL != tmp->next) { - tmp = tmp->next; - id++; - } - global_offset = get_free_offset(dataseg); - offset = global_offset % _data_segment_size; - - /* We should provide additional space at the end of segment to - * place EXTENSION_SLOT to have an ability to enlarge data for this rank.*/ - if ((sizeof(size_t) + ESH_KEY_SIZE(key, size) + EXT_SLOT_SIZE()) > _data_segment_size) { - /* this is an error case: segment is so small that cannot place evem a single key-value pair. - * warn a user about it and fail. */ - offset = 0; /* offset cannot be 0 in normal case, so we use this value to indicate a problem. */ - pmix_output(0, "PLEASE set NS_DATA_SEG_SIZE to value which is larger when %lu.", - sizeof(size_t) + strlen(key) + 1 + sizeof(size_t) + size + EXT_SLOT_SIZE()); - return offset; - } - - /* check the corner case that was observed at large scales: - * https://github.com/pmix/master/pull/282#issuecomment-277454198 - * - * if last time we stopped exactly on the border of the segment - * new segment wasn't allocated to us but (global_offset % _data_segment_size) == 0 - * so if offset is 0 here - we need to allocate the segment as well - */ - if ( (0 == offset) || ( (offset + ESH_KEY_SIZE(key, size) + EXT_SLOT_SIZE()) > _data_segment_size) ) { - id++; - /* create a new data segment. */ - tmp = extend_segment(tmp, &ns_info->ns_map); - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - offset = 0; /* offset cannot be 0 in normal case, so we use this value to indicate a problem. */ - return offset; - } - ns_info->num_data_seg++; - /* update_ns_info_in_initial_segment */ - ns_seg_info_t *elem = _get_ns_info_from_initial_segment(&ns_info->ns_map); - if (NULL == elem) { - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - offset = 0; /* offset cannot be 0 in normal case, so we use this value to indicate a problem. */ - return offset; - } - elem->num_data_seg++; - offset = sizeof(size_t); - } - global_offset = offset + id * _data_segment_size; - addr = (uint8_t*)(tmp->seg_info.seg_base_addr)+offset; - ESH_PUT_KEY(addr, key, buffer, size); - - /* update offset at the beginning of current segment */ - data_ended = offset + ESH_KEY_SIZE(key, size); - addr = (uint8_t*)(tmp->seg_info.seg_base_addr); - memcpy(addr, &data_ended, sizeof(size_t)); - PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, - "%s:%d:%s: key %s, rel start offset %lu, rel end offset %lu, abs shift %lu size %lu", - __FILE__, __LINE__, __func__, key, offset, data_ended, id * _data_segment_size, size)); - return global_offset; -} - -static int pmix_sm_store(ns_track_elem_t *ns_info, pmix_rank_t rank, pmix_kval_t *kval, rank_meta_info **rinfo, int data_exist) -{ - size_t offset, size, kval_cnt; - pmix_buffer_t buffer; - pmix_status_t rc; - seg_desc_t *datadesc; - uint8_t *addr; - - PMIX_OUTPUT_VERBOSE((2, pmix_globals.debug_output, - "%s:%d:%s: for rank %u, replace flag %d", - __FILE__, __LINE__, __func__, rank, data_exist)); - - datadesc = ns_info->data_seg; - /* pack value to the buffer */ - PMIX_CONSTRUCT(&buffer, pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&buffer, kval->value, 1, PMIX_VALUE))) { - PMIX_ERROR_LOG(rc); - goto exit; - } - size = buffer.bytes_used; - - if (0 == data_exist) { - /* there is no data blob for this rank yet, so add it. */ - size_t free_offset; - free_offset = get_free_offset(datadesc); - offset = put_data_to_the_end(ns_info, datadesc, kval->key, buffer.base_ptr, size); - if (0 == offset) { - /* this is an error */ - rc = PMIX_ERROR; - PMIX_ERROR_LOG(rc); - goto exit; - } - /* if it's the first time when we put data for this rank, then *rinfo == NULL, - * and even if segment was extended, and data was put into the next segment, - * we don't need to extension slot at the end of previous segment. - * If we try, we might overwrite other segments memory, - * because previous segment is already full. */ - if (free_offset != offset && NULL != *rinfo) { - /* here we compare previous free offset with the offset where we just put data. - * It should be equal in the normal case. It it's not true, then it means that - * segment was extended, and we put data to the next segment, so we now need to - * put extension slot at the end of previous segment with a "reference" to a new_offset */ - addr = _get_data_region_by_offset(datadesc, free_offset); - ESH_PUT_KEY(addr, ESH_REGION_EXTENSION, (void*)&offset, sizeof(size_t)); - } - if (NULL == *rinfo) { - *rinfo = (rank_meta_info*)malloc(sizeof(rank_meta_info)); - (*rinfo)->rank = rank; - (*rinfo)->offset = offset; - (*rinfo)->count = 0; - } - (*rinfo)->count++; - } else if (NULL != *rinfo) { - /* there is data blob for this rank */ - addr = _get_data_region_by_offset(datadesc, (*rinfo)->offset); - if (NULL == addr) { - rc = PMIX_ERROR; - PMIX_ERROR_LOG(rc); - goto exit; - } - /* go through previous data region and find key matches. - * If one is found, then mark this kval as invalidated. - * Then put a new empty offset to the next extension slot, - * and add new kval by this offset. - * no need to update meta info, it's still the same. */ - kval_cnt = (*rinfo)->count; - int add_to_the_end = 1; - while (0 < kval_cnt) { - /* data is stored in the following format: - * size_t size - * key[ESH_KNAME_LEN(addr)] - * byte buffer containing pmix_value, should be loaded to pmix_buffer_t and unpacked. - * next kval pair - * ..... - * extension slot which has key = EXTENSION_SLOT and a size_t value for offset to next data address for this process. - */ - if (0 == strncmp(ESH_KNAME_PTR(addr), ESH_REGION_EXTENSION, ESH_KNAME_LEN(ESH_REGION_EXTENSION))) { - memcpy(&offset, ESH_DATA_PTR(addr), sizeof(size_t)); - if (0 < offset) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %u, replace flag %d %s is filled with %lu value", - __FILE__, __LINE__, __func__, rank, data_exist, ESH_REGION_EXTENSION, offset)); - /* go to next item, updating address */ - addr = _get_data_region_by_offset(datadesc, offset); - if (NULL == addr) { - rc = PMIX_ERROR; - PMIX_ERROR_LOG(rc); - goto exit; - } - } else { - /* should not be, we should be out of cycle when this happens */ - } - } else if (0 == strncmp(ESH_KNAME_PTR(addr), kval->key, ESH_KNAME_LEN(kval->key))) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %u, replace flag %d found target key %s", - __FILE__, __LINE__, __func__, rank, data_exist, kval->key)); - /* target key is found, compare value sizes */ - if (ESH_DATA_SIZE(addr, ESH_DATA_PTR(addr)) != size) { - //if (1) { /* if we want to test replacing values for existing keys. */ - /* invalidate current value and store another one at the end of data region. */ - strncpy(ESH_KNAME_PTR(addr), ESH_REGION_INVALIDATED, ESH_KNAME_LEN(ESH_REGION_INVALIDATED)); - /* decrementing count, it will be incremented back when we add a new value for this key at the end of region. */ - (*rinfo)->count--; - kval_cnt--; - /* go to next item, updating address */ - addr += ESH_KV_SIZE(addr); - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %u, replace flag %d mark key %s regions as invalidated. put new data at the end.", - __FILE__, __LINE__, __func__, rank, data_exist, kval->key)); - } else { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %u, replace flag %d replace data for key %s type %d in place", - __FILE__, __LINE__, __func__, rank, data_exist, kval->key, kval->value->type)); - /* replace old data with new one. */ - memset(ESH_DATA_PTR(addr), 0, ESH_DATA_SIZE(addr, ESH_DATA_PTR(addr))); - memcpy(ESH_DATA_PTR(addr), buffer.base_ptr, size); - addr += ESH_KV_SIZE(addr); - add_to_the_end = 0; - break; - } - } else { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %u, replace flag %d skip %s key, look for %s key", - __FILE__, __LINE__, __func__, rank, data_exist, ESH_KNAME_PTR(addr), kval->key)); - /* Skip it: key is "INVALIDATED" or key is valid but different from target one. */ - if (0 != strncmp(ESH_REGION_INVALIDATED, ESH_KNAME_PTR(addr), ESH_KNAME_LEN(ESH_KNAME_PTR(addr)))) { - /* count only valid items */ - kval_cnt--; - } - /* go to next item, updating address */ - addr += ESH_KV_SIZE(addr); - } - } - if (1 == add_to_the_end) { - /* if we get here, it means that we want to add a new item for the target rank, or - * we mark existing item with the same key as "invalidated" and want to add new item - * for the same key. */ - size_t free_offset; - (*rinfo)->count++; - free_offset = get_free_offset(datadesc); - /* add to the end */ - offset = put_data_to_the_end(ns_info, datadesc, kval->key, buffer.base_ptr, size); - if (0 == offset) { - rc = PMIX_ERROR; - PMIX_ERROR_LOG(rc); - goto exit; - } - /* we just reached the end of data for the target rank, and there can be two cases: - * (1) - we are in the middle of data segment; data for this rank is separated from - * data for different ranks, and that's why next element is EXTENSION_SLOT. - * We put new data to the end of data region and just update EXTENSION_SLOT value by new offset. - */ - if (0 == strncmp(ESH_KNAME_PTR(addr), ESH_REGION_EXTENSION, ESH_KNAME_LEN(ESH_REGION_EXTENSION))) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %u, replace flag %d %s should be filled with offset %lu value", - __FILE__, __LINE__, __func__, rank, data_exist, ESH_REGION_EXTENSION, offset)); - memcpy(ESH_DATA_PTR(addr), &offset, sizeof(size_t)); - } else { - /* (2) - we point to the first free offset, no more data is stored further in this segment. - * There is no EXTENSION_SLOT by this addr since we continue pushing data for the same rank, - * and there is no need to split it. - * But it's possible that we reached the end of current data region and just jumped to the new region - * to put new data, in that case free_offset != offset and we must put EXTENSION_SLOT by the current addr - * forcibly and store new offset in its value. */ - if (free_offset != offset) { - /* segment was extended, need to put extension slot by free_offset indicating new_offset */ - ESH_PUT_KEY(addr, ESH_REGION_EXTENSION, (void*)&offset, sizeof(size_t)); - } - } - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %u, replace flag %d item not found ext slot empty, put key %s to the end", - __FILE__, __LINE__, __func__, rank, data_exist, kval->key)); - } - } -exit: - PMIX_DESTRUCT(&buffer); - return rc; -} - -static int _store_data_for_rank(ns_track_elem_t *ns_info, pmix_rank_t rank, pmix_buffer_t *buf) -{ - pmix_status_t rc; - - pmix_kval_t *kp; - seg_desc_t *metadesc, *datadesc; - - rank_meta_info *rinfo = NULL; - size_t num_elems, free_offset, new_free_offset; - int data_exist; - int32_t cnt; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %u", __FILE__, __LINE__, __func__, rank)); - - metadesc = ns_info->meta_seg; - datadesc = ns_info->data_seg; - - if (NULL == datadesc || NULL == metadesc) { - rc = PMIX_ERR_BAD_PARAM; + /* setup the byte object for unpacking */ + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + /* the next step unfortunately NULLs the byte object's + * entries, so we need to ensure we restore them! */ + PMIX_LOAD_BUFFER(peer, &pbkt, bo->bytes, bo->size); + /* unload the proc that provided this data */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, peer, &pbkt, &proc, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); + bo->bytes = pbkt.base_ptr; + bo->size = pbkt.bytes_used; // restore the incoming data + pbkt.base_ptr = NULL; + PMIX_DESTRUCT(&pbkt); return rc; } - - num_elems = *((size_t*)(metadesc->seg_info.seg_base_addr)); - data_exist = 0; - /* when we don't use linear search (_direct_mode ==0 ) we don't use num_elems field, - * so anyway try to get rank_meta_info first. */ - if (0 < num_elems || 0 == _direct_mode) { - /* go through all elements in meta segment and look for target rank. */ - rinfo = _get_rank_meta_info(rank, metadesc); - if (NULL != rinfo) { - data_exist = 1; - } - } - /* incoming buffer may contain several inner buffers for different scopes, - * so unpack these buffers, and then unpack kvals from each modex buffer, - * storing them in the shared memory dstore. - */ - free_offset = get_free_offset(datadesc); - kp = PMIX_NEW(pmix_kval_t); + /* unpack the remaining values until we hit the end of the buffer */ cnt = 1; - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(buf, kp, &cnt, PMIX_KVAL))) { - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix: unpacked key %s", kp->key); - if (PMIX_SUCCESS != (rc = pmix_sm_store(ns_info, rank, kp, &rinfo, data_exist))) { + kv = PMIX_NEW(pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, peer, &pbkt, kv, &cnt, PMIX_KVAL); + while (PMIX_SUCCESS == rc) { + /* don't store blobs to the sm dstore from local clients */ + if (_my_client(proc.nspace, proc.rank)) { + break; + } + /* store this in the hash table */ + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, &proc, PMIX_REMOTE, kv); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); - if (NULL != rinfo) { - free(rinfo); - } + bo->bytes = pbkt.base_ptr; + bo->size = pbkt.bytes_used; // restore the incoming data + pbkt.base_ptr = NULL; + PMIX_DESTRUCT(&pbkt); return rc; } - PMIX_RELEASE(kp); // maintain acctg - hash_store does a retain - kp = PMIX_NEW(pmix_kval_t); + if (PMIX_SUCCESS != (rc = dstore_store(&proc, PMIX_REMOTE, kv))) { + PMIX_ERROR_LOG(rc); + } + PMIX_RELEASE(kv); // maintain accounting as the hash increments the ref count + /* continue along */ + kv = PMIX_NEW(pmix_kval_t); cnt = 1; + PMIX_BFROPS_UNPACK(rc, peer, &pbkt, kv, &cnt, PMIX_KVAL); } - PMIX_RELEASE(kp); - + PMIX_RELEASE(kv); // maintain accounting if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { PMIX_ERROR_LOG(rc); - /* TODO: should we error-exit here? */ } else { rc = PMIX_SUCCESS; } + bo->bytes = pbkt.base_ptr; + bo->size = pbkt.bytes_used; // restore the incoming data + pbkt.base_ptr = NULL; + PMIX_DESTRUCT(&pbkt); + return rc; +} - /* Check if new data was put at the end of data segment. - * It's possible that old data just was replaced with new one, - * in that case we don't reserve space for EXTENSION_SLOT, it's - * already reserved. - * */ - new_free_offset = get_free_offset(datadesc); - if (new_free_offset != free_offset) { - /* Reserve space for EXTENSION_SLOT at the end of data blob. - * We need it to split data for one rank from data for different - * ranks and to allow extending data further. - * We also put EXTENSION_SLOT at the end of each data segment, and - * its value points to the beginning of next data segment. - * */ - rc = put_empty_ext_slot(ns_info->data_seg); - if (PMIX_SUCCESS != rc) { - if ((0 == data_exist) && NULL != rinfo) { - free(rinfo); - } +static inline int _collect_key_for_rank(pmix_peer_t *peer, pmix_rank_t rank, pmix_kval_t *kv) +{ + pmix_status_t rc = PMIX_SUCCESS; + uint32_t i, size; + pmix_buffer_t *tmp = NULL; + pmix_rank_t cur_rank; + + if (NULL == rank_kv_bufs) { + rank_kv_bufs = PMIX_NEW(pmix_value_array_t); + if (PMIX_SUCCESS != (rc = pmix_value_array_init(rank_kv_bufs, sizeof(pmix_buffer_t)))) { PMIX_ERROR_LOG(rc); return rc; } } + /* rank WILDCARD contained in the 0 item */ + cur_rank = PMIX_RANK_WILDCARD == rank ? 0 : rank + 1; + size = (uint32_t)pmix_value_array_get_size(rank_kv_bufs); - /* if this is the first data posted for this rank, then - * update meta info for it */ - if (0 == data_exist) { - set_rank_meta_info(ns_info, rinfo); - if (NULL != rinfo) { - free(rinfo); + if ((cur_rank + 1) <= size) { + tmp = &(PMIX_VALUE_ARRAY_GET_ITEM(rank_kv_bufs, pmix_buffer_t, cur_rank)); + PMIX_BFROPS_PACK(rc, peer, tmp, kv, 1, PMIX_KVAL); + return rc; + } + if (PMIX_SUCCESS != (rc = pmix_value_array_set_size(rank_kv_bufs, cur_rank + 1))) { + PMIX_ERROR_LOG(rc); + return rc; + } + for (i = size; i < (cur_rank + 1); i++) { + tmp = &(PMIX_VALUE_ARRAY_GET_ITEM(rank_kv_bufs, pmix_buffer_t, i)); + PMIX_CONSTRUCT(tmp, pmix_buffer_t); + } + PMIX_BFROPS_PACK(rc, peer, tmp, kv, 1, PMIX_KVAL); + + return rc; +} + +static inline int _collected_key_dstore_store(pmix_nspace_t *nptr) +{ + int rc = PMIX_SUCCESS; + uint32_t i, size; + pmix_buffer_t *tmp; + pmix_rank_t rank; + pmix_kval_t *kv = NULL; + + if (NULL == rank_kv_bufs) { + goto exit; + } + kv = PMIX_NEW(pmix_kval_t); + PMIX_VALUE_CREATE(kv->value, 1); + kv->value->type = PMIX_BYTE_OBJECT; + + size = pmix_value_array_get_size(rank_kv_bufs); + for (i = 0; i < size; i++) { + tmp = &(PMIX_VALUE_ARRAY_GET_ITEM(rank_kv_bufs, pmix_buffer_t, i)); + rank = 0 == i ? PMIX_RANK_WILDCARD : i - 1; + PMIX_UNLOAD_BUFFER(tmp, kv->value->data.bo.bytes, kv->value->data.bo.size); + if (PMIX_SUCCESS != (rc = _dstore_store(nptr->nspace, rank, kv))) { + PMIX_ERROR_LOG(rc); + goto exit; } } +exit: + if (NULL != kv) { + PMIX_RELEASE(kv); + } + if (NULL != rank_kv_bufs) { + size_t size = pmix_value_array_get_size(rank_kv_bufs); + size_t i; + for (i = 0; i < size; i++) { + pmix_buffer_t *tmp = &(PMIX_VALUE_ARRAY_GET_ITEM(rank_kv_bufs, pmix_buffer_t, i)); + PMIX_DESTRUCT(tmp); + } + PMIX_RELEASE(rank_kv_bufs); + rank_kv_bufs = NULL; + } + return rc; +} + +static inline pmix_status_t store_map(pmix_peer_t *peer, + char **nodes, char **ppn) +{ + pmix_status_t rc; + pmix_value_t *val; + size_t m, n; + pmix_info_t *iptr, *info; + pmix_rank_t rank; + bool updated; + pmix_kval_t *kp2; + char **procs; + pmix_proc_t proc; + pmix_cb_t cb; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:dstore:store_map", + pmix_globals.myid.nspace, pmix_globals.myid.rank); + + /* if the lists don't match, then that's wrong */ + if (pmix_argv_count(nodes) != pmix_argv_count(ppn)) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + return PMIX_ERR_BAD_PARAM; + } + + for (n=0; NULL != nodes[n]; n++) { + /* check and see if we already have data for this node */ + val = NULL; + proc.rank = PMIX_RANK_WILDCARD; + (void)strncpy(proc.nspace, peer->nptr->nspace, PMIX_MAX_NSLEN); + PMIX_CONSTRUCT(&cb, pmix_cb_t); + cb.proc = &proc; + cb.scope = PMIX_INTERNAL; + cb.copy = true; // ??? + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, &cb); + if (PMIX_SUCCESS == rc && 1 == pmix_list_get_size(&cb.kvs)) { + kp2 = (pmix_kval_t*)pmix_list_get_first(&cb.kvs); + val = kp2->value; + //kp2->value = NULL; // protect the value + /* already have some data. See if we have the list of local peers */ + if (PMIX_DATA_ARRAY != val->type || + NULL == val->data.darray || + PMIX_INFO != val->data.darray->type || + 0 == val->data.darray->size) { + /* something is wrong */ + PMIX_VALUE_RELEASE(val); + PMIX_ERROR_LOG(PMIX_ERR_INVALID_VAL); + return PMIX_ERR_INVALID_VAL; + } + iptr = (pmix_info_t*)val->data.darray->array; + updated = false; + for (m=0; m < val->data.darray->size; m++) { + if (0 == strncmp(iptr[m].key, PMIX_LOCAL_PEERS, PMIX_MAX_KEYLEN)) { + /* we will update this entry */ + if (NULL != iptr[m].value.data.string) { + free(iptr[m].value.data.string); + } + iptr[m].value.data.string = strdup(ppn[n]); + updated = true; + break; + } + } + if (!updated) { + /* append this entry to the current data */ + kp2 = PMIX_NEW(pmix_kval_t); + if (NULL == kp2) { + return PMIX_ERR_NOMEM; + } + kp2->key = strdup(nodes[n]); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == kp2->value) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->type = PMIX_DATA_ARRAY; + kp2->value->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); + if (NULL == kp2->value->data.darray) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->data.darray->type = PMIX_INFO; + kp2->value->data.darray->size = val->data.darray->size + 1; + PMIX_INFO_CREATE(info, kp2->value->data.darray->size); + if (NULL == info) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + /* copy the pre-existing data across */ + for (m=0; m < val->data.darray->size; m++) { + PMIX_INFO_XFER(&info[m], &iptr[m]); + } + PMIX_INFO_LOAD(&info[kp2->value->data.darray->size-1], PMIX_LOCAL_PEERS, ppn[n], PMIX_STRING); + kp2->value->data.darray->array = info; + + if (PMIX_SUCCESS != (rc = _collect_key_for_rank(peer, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + return rc; + } + PMIX_RELEASE(kp2); + } + } else { + /* store the list as-is */ + kp2 = PMIX_NEW(pmix_kval_t); + if (NULL == kp2) { + return PMIX_ERR_NOMEM; + } + kp2->key = strdup(nodes[n]); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == kp2->value) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->type = PMIX_DATA_ARRAY; + kp2->value->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); + if (NULL == kp2->value->data.darray) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->data.darray->type = PMIX_INFO; + PMIX_INFO_CREATE(info, 1); + if (NULL == info) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + PMIX_INFO_LOAD(&info[0], PMIX_LOCAL_PEERS, ppn[n], PMIX_STRING); + kp2->value->data.darray->array = info; + kp2->value->data.darray->size = 1; + if (PMIX_SUCCESS != (rc = _collect_key_for_rank(peer, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + return rc; + } + PMIX_RELEASE(kp2); + } + /* split the list of procs so we can store their + * individual location data */ + procs = pmix_argv_split(ppn[n], ','); + for (m=0; NULL != procs[m]; m++) { + /* store the hostname for each proc */ + kp2 = PMIX_NEW(pmix_kval_t); + kp2->key = strdup(PMIX_HOSTNAME); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + kp2->value->type = PMIX_STRING; + kp2->value->data.string = strdup(nodes[n]); + rank = strtol(procs[m], NULL, 10); + if (PMIX_SUCCESS != (rc = _collect_key_for_rank(peer, rank, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + pmix_argv_free(procs); + return rc; + } + PMIX_RELEASE(kp2); + } + pmix_argv_free(procs); + } + + /* store the comma-delimited list of nodes hosting + * procs in this nspace */ + kp2 = PMIX_NEW(pmix_kval_t); + kp2->key = strdup(PMIX_NODE_LIST); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + kp2->value->type = PMIX_STRING; + kp2->value->data.string = pmix_argv_join(nodes, ','); + if (PMIX_SUCCESS != (rc = _collect_key_for_rank(peer, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + return rc; + } + return PMIX_SUCCESS; +} + +static pmix_status_t dstore_register_job_info(struct pmix_peer_t *pr, + pmix_buffer_t *reply) +{ + pmix_peer_t *peer = (pmix_peer_t*)pr; + pmix_nspace_t *ns = peer->nptr; + char *msg; + pmix_status_t rc; + size_t j, n, size, len; + pmix_info_t *iptr; + pmix_rank_t rank; + pmix_kval_t *kp2; + uint8_t *tmp; + char **nodes=NULL, **procs=NULL; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:dstore:register_job_info for peer [%s:%d]", + pmix_globals.myid.nspace, pmix_globals.myid.rank, + peer->info->pname.nspace, peer->info->pname.rank); + + if (0 == ns->ndelivered) { // don't store twice + for (n=0; n < ns->njobinfo; n++) { + if (0 == strcmp(ns->jobinfo[n].key, PMIX_PROC_DATA)) { + + + if (PMIX_DATA_ARRAY != ns->jobinfo[n].value.type) { + rc = PMIX_ERR_BAD_PARAM; + PMIX_ERROR_LOG(rc); + return rc; + } + size = ns->jobinfo[n].value.data.darray->size; + iptr = (pmix_info_t*)ns->jobinfo[n].value.data.darray->array; + /* first element of the array must be the rank */ + if (0 != strcmp(iptr[0].key, PMIX_RANK) || + PMIX_PROC_RANK != iptr[0].value.type) { + rc = PMIX_ERR_BAD_PARAM; + PMIX_ERROR_LOG(rc); + return rc; + } + rank = iptr[0].value.data.rank; + /* cycle thru the values for this rank and store them */ + for (j=1; j < size; j++) { + kp2 = PMIX_NEW(pmix_kval_t); + if (NULL == kp2) { + rc = PMIX_ERR_NOMEM; + return rc; + } + kp2->key = strdup(iptr[j].key); + PMIX_VALUE_XFER(rc, kp2->value, &iptr[j].value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + return rc; + } + /* if the value contains a string that is longer than the + * limit, then compress it */ + if (PMIX_STRING_SIZE_CHECK(kp2->value)) { + if (pmix_util_compress_string(kp2->value->data.string, &tmp, &len)) { + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + rc = PMIX_ERR_NOMEM; + return rc; + } + kp2->value->type = PMIX_COMPRESSED_STRING; + free(kp2->value->data.string); + kp2->value->data.bo.bytes = (char*)tmp; + kp2->value->data.bo.size = len; + } + } + /* store it in the tmp buf */ + if (PMIX_SUCCESS != (rc = _collect_key_for_rank(peer, rank, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + return rc; + } + PMIX_RELEASE(kp2); // maintain acctg + } + } else if (0 == strcmp(ns->jobinfo[n].key, PMIX_NODE_MAP)) { + /* parse the regex to get the argv array of node names */ + if (PMIX_SUCCESS != (rc = pmix_preg.parse_nodes(ns->jobinfo[n].value.data.string, &nodes))) { + PMIX_ERROR_LOG(rc); + return rc; + } + /* if we have already found the proc map, then parse + * and store the detailed map */ + if (NULL != procs) { + if (PMIX_SUCCESS != (rc = store_map(peer, nodes, procs))) { + PMIX_ERROR_LOG(rc); + return rc; + } + } + } else if (0 == strcmp(ns->jobinfo[n].key, PMIX_PROC_MAP)) { + /* parse the regex to get the argv array containing proc ranks on each node */ + if (PMIX_SUCCESS != (rc = pmix_preg.parse_procs(ns->jobinfo[n].value.data.string, &procs))) { + PMIX_ERROR_LOG(rc); + return rc; + } + /* if we have already recv'd the node map, then parse + * and store the detailed map */ + if (NULL != nodes) { + if (PMIX_SUCCESS != (rc = store_map(peer, nodes, procs))) { + PMIX_ERROR_LOG(rc); + return rc; + } + } + } else { + pmix_kval_t *kv = PMIX_NEW(pmix_kval_t); + PMIX_VALUE_CREATE(kv->value, 1); + kv->key = strdup(ns->jobinfo[n].key); + PMIX_VALUE_XFER(rc, kv->value, &ns->jobinfo[n].value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kv); + return rc; + } + if ( PMIX_SUCCESS != (rc = _collect_key_for_rank(peer, PMIX_RANK_WILDCARD, kv))) { + PMIX_RELEASE(kv); + PMIX_ERROR_LOG(rc); + return rc; + } + } + } + /* store all keys in thr dstore */ + _collected_key_dstore_store(ns); + } + + /* answer to client */ + msg = ns->nspace; + PMIX_BFROPS_PACK(rc, peer, reply, &msg, 1, PMIX_STRING); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + return rc; + } + return rc; } -static inline ssize_t _get_univ_size(const char *nspace) +static pmix_status_t dstore_store_job_info(const char *nspace, pmix_buffer_t *buf) { - ssize_t nprocs = 0; - pmix_value_t *val; - int rc; + pmix_status_t rc = PMIX_SUCCESS; - rc = _esh_fetch(nspace, PMIX_RANK_WILDCARD, PMIX_UNIV_SIZE, &val); - if( PMIX_SUCCESS != rc ) { - PMIX_ERROR_LOG(rc); - return rc; - } - if( val->type != PMIX_UINT32 ){ + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%u] pmix:gds:dstore store job info for nspace %s", + pmix_globals.myid.nspace, pmix_globals.myid.rank, nspace); + + /* check buf data */ + if ((NULL == buf) || (0 == buf->bytes_used)) { rc = PMIX_ERR_BAD_PARAM; PMIX_ERROR_LOG(rc); return rc; } - nprocs = (ssize_t)val->data.uint32; - PMIX_VALUE_RELEASE(val); - return nprocs; + return rc; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.h b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore.h similarity index 81% rename from opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.h rename to opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore.h index 85c9f80066..abd4723ad2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore.h @@ -1,8 +1,7 @@ /* - * Copyright (c) 2015-2016 Mellanox Technologies, Inc. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2017 Mellanox Technologies, Inc. * All rights reserved. - * Copyright (c) 2017 Research Organization for Information Science - * and Technology (RIST). All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -10,18 +9,20 @@ * $HEADER$ */ -#ifndef PMIX_DSTORE_ESH_H -#define PMIX_DSTORE_ESH_H +#ifndef PMIX_DS12_H +#define PMIX_DS12_H + +#include + + +#include "src/mca/gds/gds.h" +#include "src/mca/pshmem/pshmem.h" + +BEGIN_C_DECLS #include #include "src/class/pmix_value_array.h" - -#include "pmix_dstore.h" -#include "src/sm/pmix_sm.h" - -BEGIN_C_DECLS - #define INITIAL_SEG_SIZE 4096 #define NS_META_SEG_SIZE (1<<22) #define NS_DATA_SEG_SIZE (1<<22) @@ -51,7 +52,7 @@ typedef enum { typedef struct seg_desc_t seg_desc_t; struct seg_desc_t { segment_type type; - pmix_sm_seg_t seg_info; + pmix_pshmem_seg_t seg_info; uint32_t id; seg_desc_t *next; }; @@ -67,7 +68,7 @@ struct session_s { char *nspace_path; char *lockfile; #ifdef ESH_PTHREAD_LOCK - pmix_sm_seg_t *rwlock_seg; + pmix_pshmem_seg_t *rwlock_seg; pthread_rwlock_t *rwlock; #endif int lockfd; @@ -119,8 +120,10 @@ typedef struct { bool in_use; } ns_track_elem_t; -extern pmix_dstore_base_module_t pmix_dstore_esh_module; +/* the component must be visible data for the linker to find it */ +PMIX_EXPORT extern pmix_gds_base_component_t mca_gds_ds12_component; +extern pmix_gds_base_module_t pmix_ds12_module; END_C_DECLS -#endif /* PMIX_DSTORE_ESH_H */ +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore_component.c new file mode 100644 index 0000000000..da955113b5 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/ds12/gds_dstore_component.c @@ -0,0 +1,86 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2017 Mellanox Technologies, Inc. + * All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + * These symbols are in a file by themselves to provide nice linker + * semantics. Since linkers generally pull in symbols by object + * files, keeping these symbols as the only symbols in this file + * prevents utility programs such as "ompi_info" from having to import + * entire components just to query their version and parameters. + */ + +#include +#include "pmix_common.h" + + +#include "src/mca/gds/gds.h" +#include "gds_dstore.h" + +static pmix_status_t component_open(void); +static pmix_status_t component_close(void); +static pmix_status_t component_query(pmix_mca_base_module_t **module, int *priority); + +/* + * Instantiate the public struct with all of our public information + * and pointers to our public functions in it + */ +pmix_gds_base_component_t mca_gds_ds12_component = { + .base = { + PMIX_GDS_BASE_VERSION_1_0_0, + + /* Component name and version */ + .pmix_mca_component_name = "ds12", + PMIX_MCA_BASE_MAKE_VERSION(component, + PMIX_MAJOR_VERSION, + PMIX_MINOR_VERSION, + PMIX_RELEASE_VERSION), + + /* Component open and close functions */ + .pmix_mca_open_component = component_open, + .pmix_mca_close_component = component_close, + .pmix_mca_query_component = component_query, + }, + .data = { + /* The component is checkpoint ready */ + PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT + } +}; + + +static int component_open(void) +{ + return PMIX_SUCCESS; +} + + +static int component_query(pmix_mca_base_module_t **module, int *priority) +{ + *priority = 20; + *module = (pmix_mca_base_module_t *)&pmix_ds12_module; + return PMIX_SUCCESS; +} + + +static int component_close(void) +{ + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/gds.h b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/gds.h new file mode 100644 index 0000000000..8d884c1515 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/gds.h @@ -0,0 +1,409 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2016-2017 Mellanox Technologies, Inc. + * All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_GDS_H +#define PMIX_GDS_H + +#include + + +#include +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_var.h" +#include "src/mca/base/pmix_mca_base_framework.h" +#include "src/mca/bfrops/bfrops_types.h" + + +/* The client dictates the GDS module that will be used to interact + * with the server - this module is stored in pmix_globals.mypeer->compat.gds + * Because that is a long address to keep typing out, convenience macros + * are provided for when that module is to be used in an operation. + * + * However, an application can open any number of GDS modules for + * purposes other than exchanging info with the server. For example, + * an application may wish to utilize a DHT module for its own + * peer-to-peer data sharing. Thus, the public and private interfaces + * are deliberately designed to be generic. The macros should make + * things easier for the typical internal operations + * + * NOTE: ALTHOUGH SOME GDS COMPONENTS MAY UTILIZE THEIR OWN INTERNAL + * PROGRESS THREADS, THE GDS IS NOT GUARANTEED TO BE THREAD-SAFE. + * GDS FUNCTIONS SHOULD THEREFORE ALWAYS BE CALLED IN A THREAD-SAFE + * CONDITION - E.G., FROM WITHIN AN EVENT + */ + +BEGIN_C_DECLS +/* forward declaration */ +struct pmix_peer_t; +struct pmix_nspace_t; + +/** + * Initialize the module. Returns an error if the module cannot + * run, success if it can. + */ +typedef pmix_status_t (*pmix_gds_base_module_init_fn_t)(pmix_info_t info[], size_t ninfo); + +/** + * Finalize the module. Tear down any allocated storage, disconnect + * from any system support. + */ +typedef void (*pmix_gds_base_module_fini_fn_t)(void); + +/** + * Assign a module per the requested directives. Modules should + * review the provided directives to determine if they can support + * the request. Modules are "scanned" in component priority order + * and given an opportunity to respond. If a module offers itself, + * it will provide a priority (which can be based on the directives + * and therefore different from the component priority). The highest + * returned priority received from a responder will be selected + * and a pointer to its module returned */ +typedef pmix_status_t (*pmix_gds_base_assign_module_fn_t)(pmix_info_t *info, + size_t ninfo, + int *priority); + +/* SERVER FN: assemble the keys buffer for server answer */ +typedef pmix_status_t (*pmix_gds_base_module_assemb_kvs_req_fn_t)(const pmix_proc_t *proc, + pmix_list_t *kvs, + pmix_buffer_t *buf, + void *cbdata); + +/* define a macro for server keys answer based on peer */ +#define PMIX_GDS_ASSEMB_KVS_REQ(s, p, r, k, b, c) \ + do { \ + pmix_gds_base_module_t *_g = (p)->nptr->compat.gds; \ + (s) = PMIX_SUCCESS; \ + if (NULL != _g->assemb_kvs_req) { \ + (s) = _g->assemb_kvs_req(r, k, b, (void*)c); \ + } \ + } while(0) + + +/* CLIENT FN: unpack buffer and key processing */ +typedef pmix_status_t (*pmix_gds_base_module_accept_kvs_resp_fn_t)(pmix_buffer_t *buf); + +/* define a macro for client key processing from a server response based on peer */ +#define PMIX_GDS_ACCEPT_KVS_RESP(s, p, b) \ + do { \ + pmix_gds_base_module_t *_g = (p)->nptr->compat.gds; \ + (s) = PMIX_SUCCESS; \ + if (NULL != _g->accept_kvs_resp) { \ + (s) = _g->accept_kvs_resp(b); \ + } \ + } while (0) + + +/* SERVER FN: cache job-level info in the server's GDS until client + * procs connect and we discover which GDS module to use for them. + * Note that this is essentially the same function as store_job_info, + * only we don't have packed data on the server side, and don't want + * to incur the overhead of packing it just to unpack it in the function. + */ +typedef pmix_status_t (*pmix_gds_base_module_cache_job_info_fn_t)(struct pmix_nspace_t *ns, + pmix_info_t info[], size_t ninfo); + +/* define a convenience macro for caching job info */ +#define PMIX_GDS_CACHE_JOB_INFO(s, p, n, i, ni) \ + do { \ + pmix_gds_base_module_t *_g = (p)->nptr->compat.gds; \ + (s) = _g->cache_job_info((struct pmix_nspace_t*)(n), (i), (ni)); \ + } while(0) + +/* register job-level info - this is provided as a special function + * to allow for optimization. Called solely by the server. We cannot + * prepare the job-level info provided at PMIx_Register_nspace, because + * we don't know the GDS component to use for that application until + * a local client contacts us. Thus, the module is required to process + * the job-level info cached in the pmix_nspace_t for this job and + * do whatever is necessary to support the client, packing any required + * return message into the provided buffer. + * + * This function will be called once for each local client of + * a given nspace. PMIx assumes that all peers of a given nspace + * will use the same GDS module. Thus, the module is free to perform + * any relevant optimizations (e.g., packing the data only once and + * then releasing the cached buffer once all local clients have + * been serviced, or storing it once in shared memory and simply + * returning the shared memory rendezvous information for subsequent + * calls). + * + * Info provided in the reply buffer will be given to the "store_job_info" + * API of the GDS module on the client. Since this should match the + * module used by the server, each module has full knowledge and control + * over what is in the reply buffer. + * + * The pmix_peer_t of the requesting client is provided here so that + * the module can access the job-level info cached on the corresponding + * pmix_nspace_t pointed to by the pmix_peer_t + */ +typedef pmix_status_t (*pmix_gds_base_module_register_job_info_fn_t)(struct pmix_peer_t *pr, + pmix_buffer_t *reply); + +/* define a convenience macro for registering job info for + * a given peer */ +#define PMIX_GDS_REGISTER_JOB_INFO(s, p, b) \ + do { \ + pmix_gds_base_module_t *_g = (p)->nptr->compat.gds; \ + (s) = _g->register_job_info((struct pmix_peer_t*)(p), b); \ + } while(0) + + +/* update job-level info - this is provided as a special function + * to allow for optimization. Called solely by the client. The buffer + * provided to this API is the same one given to the server by the + * corresponding "register_job_info" function + */ +typedef pmix_status_t (*pmix_gds_base_module_store_job_info_fn_t)(const char *nspace, + pmix_buffer_t *buf); + +/* define a convenience macro for storing job info based on peer */ +#define PMIX_GDS_STORE_JOB_INFO(s, p, n, b) \ + do { \ + pmix_gds_base_module_t *_g = (p)->nptr->compat.gds; \ + (s) = _g->store_job_info(n, b); \ + } while(0) + + +/** +* store key/value pair - these will either be values committed by the peer +* and transmitted to the server, or values stored locally by the peer. +* The format of the data depends on the GDS module. Note that data stored +* with PMIX_INTERNAL scope should be stored solely within the process and +* is never shared. +* +* @param peer pointer to pmix_peer_t object of the peer that +* provided the data +* +* @param proc the proc that the data describes +* +* @param scope scope of the data +* +* @param kv key/value pair. +* +* @return PMIX_SUCCESS on success. +*/ +typedef pmix_status_t (*pmix_gds_base_module_store_fn_t)(const pmix_proc_t *proc, + pmix_scope_t scope, + pmix_kval_t *kv); + +/* define a convenience macro for storing key-val pairs based on peer */ +#define PMIX_GDS_STORE_KV(s, p, pc, sc, k) \ + do { \ + pmix_gds_base_module_t *_g = (p)->nptr->compat.gds; \ + (s) = _g->store(pc, sc, k); \ + } while(0) + + +/** + * unpack and store a data "blob" from a peer so that the individual + * elements can later be retrieved. This is an optimization path to + * avoid repeatedly storing pmix_kval_t's for multiple local procs + * from the same nspace. + * + * ranks - a list of pmix_rank_info_t for the local ranks from this + * nspace - this is to be used to filter the cbs list + * + * cbs - a list of pmix_server_caddy_t's that contain the pmix_peer_t + * pointers of the local participants. The list can be used to + * identify those participants corresponding to this nspace + * (and thus, GDS component) + * + * bo - pointer to the byte object containing the data + * + */ +typedef pmix_status_t (*pmix_gds_base_module_store_modex_fn_t)(struct pmix_nspace_t *ns, + pmix_list_t *cbs, + pmix_byte_object_t *bo); + +/** + * define a convenience macro for storing modex byte objects + * + * r - return status code + * + * n - pointer to the pmix_nspace_t this blob is to be stored for + * + * l - pointer to pmix_list_t containing pmix_server_caddy_t objects + * of the local_cbs of the collective tracker + * + * b - pointer to pmix_byte_object_t containing the data + */ +#define PMIX_GDS_STORE_MODEX(r, n, l, b) \ + (r) = (n)->compat.gds->store_modex((struct pmix_nspace_t*)n, l, b) + +/** +* fetch value corresponding to provided key from within the defined +* scope. A NULL key returns all values committed by the given peer +* for that scope. +* +* @param proc namespace and rank whose info is being requested +* +* @param key key. +* +* @param scope scope of the data to be considered +* +* @param copy true if the caller _requires_ a copy of the data. This +* is used when the requestor is off-node. If +* set to false, then the GDS component can provide +* either a copy of the data, or shmem contact info +* to the location of the data +* +* @param info array of pmix_info_t the caller provided as +* qualifiers to guide the request +* +* @param ninfo number of elements in the info array +* +* @param kvs pointer to a list that will be populated with the +* returned pmix_kval_t data +* +* @return PMIX_SUCCESS on success. +* +* Note: all available job-level data for a given nspace can be fetched +* by passing a proc with rank=PMIX_RANK_WILDCARD and a NULL key. Similarly, +* passing a NULL key for a non-wildcard rank will return all data "put" +* by that rank. Scope is ignored for job-level data requests. +* +* When a specific rank if provided with a NULL key, then data for only +* that rank is returned. If the scope is PMIX_LOCAL, then the returned +* data shall include only data that was specifically "put" to local scope, +* plus any data that was put to PMIX_GLOBAL scope. Similarly, a scope of +* PMIX_REMOTE will return data that was "put" to remote scope, plus +* any data that was put to PMIX_GLOBAL scope. A scope of PMIX_GLOBAL +* will return LOCAL, REMOTE, and GLOBAL data. +* +* Data stored with PMIX_INTERNAL scope can be retrieved with that scope. +*/ +typedef pmix_status_t (*pmix_gds_base_module_fetch_fn_t)(const pmix_proc_t *proc, + pmix_scope_t scope, bool copy, + const char *key, + pmix_info_t info[], size_t ninfo, + pmix_list_t *kvs); + +/* define a convenience macro for fetch key-val pairs based on peer, + * passing a pmix_cb_t containing all the required info */ +#define PMIX_GDS_FETCH_KV(s, p, c) \ + do { \ + pmix_gds_base_module_t *_g = (p)->nptr->compat.gds; \ + (s) = _g->fetch((c)->proc, (c)->scope, (c)->copy, \ + (c)->key, (c)->info, (c)->ninfo, \ + &(c)->kvs); \ + } while(0) + + +/** +* Add any envars to a peer's environment that the module needs +* to communicate. The API stub will rotate across all active modules, giving +* each a chance to contribute +* +* @return PMIX_SUCCESS on success. +*/ +typedef pmix_status_t (*pmix_gds_base_module_setup_fork_fn_t)(const pmix_proc_t *proc, + char ***env); + +/** +* Define a new nspace in the GDS +* +* @param nspace namespace string +* +* @return PMIX_SUCCESS on success. +*/ +typedef pmix_status_t (*pmix_gds_base_module_add_nspace_fn_t)(const char *nspace, + pmix_info_t info[], + size_t ninfo); + +/* define a convenience macro for add_nspace based on peer */ +#define PMIX_GDS_ADD_NSPACE(s, n, i, ni) \ + do { \ + pmix_gds_base_active_module_t *_g; \ + pmix_status_t _s = PMIX_SUCCESS; \ + (s) = PMIX_SUCCESS; \ + PMIX_LIST_FOREACH(_g, &pmix_gds_globals.actives, \ + pmix_gds_base_active_module_t) { \ + if (NULL != _g->module->add_nspace) { \ + _s = _g->module->add_nspace(n, i, ni); \ + } \ + if (PMIX_SUCCESS != _s) { \ + (s) = PMIX_ERROR; \ + } \ + } \ + } while(0) + + +/** +* Delete nspace and its associated data +* +* @param nspace namespace string +* +* @return PMIX_SUCCESS on success. +*/ +typedef pmix_status_t (*pmix_gds_base_module_del_nspace_fn_t)(const char* nspace); + +/* define a convenience macro for del_nspace based on peer */ +#define PMIX_GDS_DEL_NSPACE(s, n) \ + do { \ + pmix_gds_base_active_module_t *_g; \ + pmix_status_t _s = PMIX_SUCCESS; \ + (s) = PMIX_SUCCESS; \ + PMIX_LIST_FOREACH(_g, &pmix_gds_globals.actives, \ + pmix_gds_base_active_module_t) { \ + if (NULL != _g->module->del_nspace) { \ + _s = _g->module->del_nspace(n); \ + } \ + if (PMIX_SUCCESS != _s) { \ + (s) = PMIX_ERROR; \ + } \ + } \ + } while(0) + + +/** +* structure for gds modules +*/ +typedef struct { + const char *name; + pmix_gds_base_module_init_fn_t init; + pmix_gds_base_module_fini_fn_t finalize; + pmix_gds_base_assign_module_fn_t assign_module; + pmix_gds_base_module_cache_job_info_fn_t cache_job_info; + pmix_gds_base_module_register_job_info_fn_t register_job_info; + pmix_gds_base_module_store_job_info_fn_t store_job_info; + pmix_gds_base_module_store_fn_t store; + pmix_gds_base_module_store_modex_fn_t store_modex; + pmix_gds_base_module_fetch_fn_t fetch; + pmix_gds_base_module_setup_fork_fn_t setup_fork; + pmix_gds_base_module_add_nspace_fn_t add_nspace; + pmix_gds_base_module_del_nspace_fn_t del_nspace; + pmix_gds_base_module_assemb_kvs_req_fn_t assemb_kvs_req; + pmix_gds_base_module_accept_kvs_resp_fn_t accept_kvs_resp; + +} pmix_gds_base_module_t; + +/* NOTE: there is no public GDS interface structure - all access is + * done directly to/from an assigned module */ + +/* define the component structure */ +struct pmix_gds_base_component_t { + pmix_mca_base_component_t base; + pmix_mca_base_component_data_t data; + int priority; +}; +typedef struct pmix_gds_base_component_t pmix_gds_base_component_t; + + +/* + * Macro for use in components that are of type gds + */ +#define PMIX_GDS_BASE_VERSION_1_0_0 \ + PMIX_MCA_BASE_VERSION_1_0_0("gds", 1, 0, 0) + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/Makefile.am new file mode 100644 index 0000000000..7d9da0189e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/Makefile.am @@ -0,0 +1,56 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2017 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_CPPFLAGS = $(gds_hash_CPPFLAGS) + +headers = gds_hash.h +sources = \ + gds_hash_component.c \ + gds_hash.c + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if MCA_BUILD_pmix_gds_hash_DSO +lib = +lib_sources = +component = mca_gds_hash.la +component_sources = $(headers) $(sources) +else +lib = libmca_gds_hash.la +lib_sources = $(headers) $(sources) +component = +component_sources = +endif + +mcacomponentdir = $(pmixlibdir) +mcacomponent_LTLIBRARIES = $(component) +mca_gds_hash_la_SOURCES = $(component_sources) +mca_gds_hash_la_LIBADD = $(gds_hash_LIBS) +mca_gds_hash_la_LDFLAGS = -module -avoid-version $(gds_hash_LDFLAGS) + +noinst_LTLIBRARIES = $(lib) +libmca_gds_hash_la_SOURCES = $(lib_sources) +libmca_gds_hash_la_LIBADD = $(gds_hash_LIBS) +libmca_gds_hash_la_LDFLAGS = -module -avoid-version $(gds_hash_LDFLAGS) diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash.c b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash.c new file mode 100644 index 0000000000..f52c3b0ef4 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash.c @@ -0,0 +1,1693 @@ +/* + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2016 IBM Corporation. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#include + +#include + +#include "src/include/pmix_globals.h" +#include "src/class/pmix_list.h" +#include "src/client/pmix_client_ops.h" +#include "src/server/pmix_server_ops.h" +#include "src/util/argv.h" +#include "src/util/compress.h" +#include "src/util/error.h" +#include "src/util/hash.h" +#include "src/util/output.h" +#include "src/util/pmix_environ.h" +#include "src/mca/preg/preg.h" + +#include "src/mca/gds/base/base.h" +#include "gds_hash.h" + +static pmix_status_t hash_init(pmix_info_t info[], size_t ninfo); +static void hash_finalize(void); + +static pmix_status_t hash_assign_module(pmix_info_t *info, size_t ninfo, + int *priority); + +static pmix_status_t hash_cache_job_info(struct pmix_nspace_t *ns, + pmix_info_t info[], size_t ninfo); + +static pmix_status_t hash_register_job_info(struct pmix_peer_t *pr, + pmix_buffer_t *reply); + +static pmix_status_t hash_store_job_info(const char *nspace, + pmix_buffer_t *buf); + +static pmix_status_t hash_store(const pmix_proc_t *proc, + pmix_scope_t scope, + pmix_kval_t *kv); + +static pmix_status_t hash_store_modex(struct pmix_nspace_t *ns, + pmix_list_t *cbs, + pmix_byte_object_t *bo); + +static pmix_status_t hash_fetch(const pmix_proc_t *proc, + pmix_scope_t scope, bool copy, + const char *key, + pmix_info_t info[], size_t ninfo, + pmix_list_t *kvs); + +static pmix_status_t setup_fork(const pmix_proc_t *peer, char ***env); + +static pmix_status_t nspace_add(const char *nspace, + pmix_info_t info[], + size_t ninfo); + +static pmix_status_t nspace_del(const char *nspace); + +static pmix_status_t assemb_kvs_req(const pmix_proc_t *proc, + pmix_list_t *kvs, + pmix_buffer_t *bo, + void *cbdata); + +static pmix_status_t accept_kvs_resp(pmix_buffer_t *buf); + +pmix_gds_base_module_t pmix_hash_module = { + .name = "hash", + .init = hash_init, + .finalize = hash_finalize, + .assign_module = hash_assign_module, + .cache_job_info = hash_cache_job_info, + .register_job_info = hash_register_job_info, + .store_job_info = hash_store_job_info, + .store = hash_store, + .store_modex = hash_store_modex, + .fetch = hash_fetch, + .setup_fork = setup_fork, + .add_nspace = nspace_add, + .del_nspace = nspace_del, + .assemb_kvs_req = assemb_kvs_req, + .accept_kvs_resp = accept_kvs_resp +}; + +typedef struct { + pmix_list_item_t super; + char *ns; + pmix_nspace_t *nptr; + pmix_hash_table_t internal; + pmix_hash_table_t remote; + pmix_hash_table_t local; +} pmix_hash_trkr_t; + +static void htcon(pmix_hash_trkr_t *p) +{ + p->ns = NULL; + p->nptr = NULL; + PMIX_CONSTRUCT(&p->internal, pmix_hash_table_t); + pmix_hash_table_init(&p->internal, 256); + PMIX_CONSTRUCT(&p->remote, pmix_hash_table_t); + pmix_hash_table_init(&p->remote, 256); + PMIX_CONSTRUCT(&p->local, pmix_hash_table_t); + pmix_hash_table_init(&p->local, 256); +} +static void htdes(pmix_hash_trkr_t *p) +{ + if (NULL != p->ns) { + free(p->ns); + } + if (NULL != p->nptr) { + PMIX_RELEASE(p->nptr); + } + PMIX_DESTRUCT(&p->internal); + PMIX_DESTRUCT(&p->remote); + PMIX_DESTRUCT(&p->local); +} +static PMIX_CLASS_INSTANCE(pmix_hash_trkr_t, + pmix_list_item_t, + htcon, htdes); + +static pmix_list_t myhashes; + +static pmix_status_t hash_init(pmix_info_t info[], size_t ninfo) +{ + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "gds: hash init"); + + PMIX_CONSTRUCT(&myhashes, pmix_list_t); + return PMIX_SUCCESS; +} + +static void hash_finalize(void) +{ + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "gds: hash finalize"); + + PMIX_LIST_DESTRUCT(&myhashes); +} + +static pmix_status_t hash_assign_module(pmix_info_t *info, size_t ninfo, + int *priority) +{ + size_t n, m; + char **options; + + *priority = -1; + if (NULL != info) { + for (n=0; n < ninfo; n++) { + if (0 == strncmp(info[n].key, PMIX_GDS_MODULE, PMIX_MAX_KEYLEN)) { + options = pmix_argv_split(info[n].value.data.string, ','); + for (m=0; NULL != options[m]; m++) { + if (0 == strcmp(options[m], "hash")) { + /* they specifically asked for us */ + *priority = 100; + break; + } + } + pmix_argv_free(options); + break; + } + } + } + return PMIX_SUCCESS; +} + +static pmix_status_t store_map(pmix_hash_table_t *ht, + char **nodes, char **ppn) +{ + pmix_status_t rc; + pmix_value_t *val; + size_t m, n; + pmix_info_t *iptr, *info; + pmix_rank_t rank; + bool updated; + pmix_kval_t *kp2; + char **procs; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:hash:store_map", + pmix_globals.myid.nspace, pmix_globals.myid.rank); + + /* if the lists don't match, then that's wrong */ + if (pmix_argv_count(nodes) != pmix_argv_count(ppn)) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + return PMIX_ERR_BAD_PARAM; + } + + for (n=0; NULL != nodes[n]; n++) { + /* check and see if we already have data for this node */ + val = NULL; + rc = pmix_hash_fetch(ht, PMIX_RANK_WILDCARD, nodes[n], &val); + if (PMIX_SUCCESS == rc && NULL != val) { + /* already have some data. See if we have the list of local peers */ + if (PMIX_DATA_ARRAY != val->type || + NULL == val->data.darray || + PMIX_INFO != val->data.darray->type || + 0 == val->data.darray->size) { + /* something is wrong */ + PMIX_VALUE_RELEASE(val); + PMIX_ERROR_LOG(PMIX_ERR_INVALID_VAL); + return PMIX_ERR_INVALID_VAL; + } + iptr = (pmix_info_t*)val->data.darray->array; + updated = false; + for (m=0; m < val->data.darray->size; m++) { + if (0 == strncmp(iptr[m].key, PMIX_LOCAL_PEERS, PMIX_MAX_KEYLEN)) { + /* we will update this entry */ + if (NULL != iptr[m].value.data.string) { + free(iptr[m].value.data.string); + } + iptr[m].value.data.string = strdup(ppn[n]); + updated = true; + break; + } + } + if (!updated) { + /* append this entry to the current data */ + kp2 = PMIX_NEW(pmix_kval_t); + if (NULL == kp2) { + return PMIX_ERR_NOMEM; + } + kp2->key = strdup(nodes[n]); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == kp2->value) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->type = PMIX_DATA_ARRAY; + kp2->value->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); + if (NULL == kp2->value->data.darray) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->data.darray->type = PMIX_INFO; + kp2->value->data.darray->size = val->data.darray->size + 1; + PMIX_INFO_CREATE(info, kp2->value->data.darray->size); + if (NULL == info) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + /* copy the pre-existing data across */ + for (m=0; m < val->data.darray->size; m++) { + PMIX_INFO_XFER(&info[m], &iptr[m]); + } + PMIX_INFO_LOAD(&info[kp2->value->data.darray->size-1], PMIX_LOCAL_PEERS, ppn[n], PMIX_STRING); + kp2->value->data.darray->array = info; + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + return rc; + } + PMIX_RELEASE(kp2); + } + } else { + /* store the list as-is */ + kp2 = PMIX_NEW(pmix_kval_t); + if (NULL == kp2) { + return PMIX_ERR_NOMEM; + } + kp2->key = strdup(nodes[n]); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == kp2->value) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->type = PMIX_DATA_ARRAY; + kp2->value->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); + if (NULL == kp2->value->data.darray) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->data.darray->type = PMIX_INFO; + PMIX_INFO_CREATE(info, 1); + if (NULL == info) { + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + PMIX_INFO_LOAD(&info[0], PMIX_LOCAL_PEERS, ppn[n], PMIX_STRING); + kp2->value->data.darray->array = info; + kp2->value->data.darray->size = 1; + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + return rc; + } + PMIX_RELEASE(kp2); + } + /* split the list of procs so we can store their + * individual location data */ + procs = pmix_argv_split(ppn[n], ','); + for (m=0; NULL != procs[m]; m++) { + /* store the hostname for each proc */ + kp2 = PMIX_NEW(pmix_kval_t); + kp2->key = strdup(PMIX_HOSTNAME); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + kp2->value->type = PMIX_STRING; + kp2->value->data.string = strdup(nodes[n]); + rank = strtol(procs[m], NULL, 10); + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, rank, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + pmix_argv_free(procs); + return rc; + } + PMIX_RELEASE(kp2); + } + pmix_argv_free(procs); + } + + /* store the comma-delimited list of nodes hosting + * procs in this nspace */ + kp2 = PMIX_NEW(pmix_kval_t); + kp2->key = strdup(PMIX_NODE_LIST); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + kp2->value->type = PMIX_STRING; + kp2->value->data.string = pmix_argv_join(nodes, ','); + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + return rc; + } + + return PMIX_SUCCESS; +} + +pmix_status_t hash_cache_job_info(struct pmix_nspace_t *ns, + pmix_info_t info[], size_t ninfo) +{ + pmix_nspace_t *nptr = (pmix_nspace_t*)ns; + pmix_hash_trkr_t *trk, *t; + pmix_hash_table_t *ht; + pmix_kval_t *kp2, *kvptr; + pmix_info_t *iptr; + char **nodes=NULL, **procs=NULL; + uint8_t *tmp; + pmix_rank_t rank; + pmix_status_t rc; + size_t n, j, size, len; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:hash:cache_job_info for nspace %s", + pmix_globals.myid.nspace, pmix_globals.myid.rank, + nptr->nspace); + + /* find the hash table for this nspace */ + trk = NULL; + PMIX_LIST_FOREACH(t, &myhashes, pmix_hash_trkr_t) { + if (0 == strcmp(nptr->nspace, t->ns)) { + trk = t; + break; + } + } + if (NULL == trk) { + /* create a tracker as we will likely need it */ + trk = PMIX_NEW(pmix_hash_trkr_t); + if (NULL == trk) { + return PMIX_ERR_NOMEM; + } + PMIX_RETAIN(nptr); + trk->nptr = nptr; + trk->ns = strdup(nptr->nspace); + pmix_list_append(&myhashes, &trk->super); + } + + /* if there isn't any data, then be content with just + * creating the tracker */ + if (NULL == info || 0 == ninfo) { + return PMIX_SUCCESS; + } + + /* this is duplicative, but for now, we copy the data to the nspace + * jobinfo array as well as cache it internally so we can look it + * up if required. We will later figure out a way to reconstruct + * the jobinfo array when required */ + PMIX_INFO_CREATE(nptr->jobinfo, ninfo); + nptr->njobinfo = ninfo; + for (n=0; n < ninfo; n++) { + (void)strncpy(nptr->jobinfo[n].key, info[n].key, PMIX_MAX_KEYLEN); + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, + &nptr->jobinfo[n].value, + &info[n].value); + } + + /* cache the job info on the internal hash table for this nspace */ + ht = &trk->internal; + for (n=0; n < ninfo; n++) { + if (0 == strcmp(info[n].key, PMIX_NODE_MAP)) { + /* parse the regex to get the argv array of node names */ + if (PMIX_SUCCESS != (rc = pmix_preg.parse_nodes(info[n].value.data.string, &nodes))) { + PMIX_ERROR_LOG(rc); + goto release; + } + /* if we have already found the proc map, then parse + * and store the detailed map */ + if (NULL != procs) { + if (PMIX_SUCCESS != (rc = store_map(ht, nodes, procs))) { + PMIX_ERROR_LOG(rc); + goto release; + } + } + } else if (0 == strcmp(info[n].key, PMIX_PROC_MAP)) { + /* parse the regex to get the argv array containing proc ranks on each node */ + if (PMIX_SUCCESS != (rc = pmix_preg.parse_procs(info[n].value.data.string, &procs))) { + PMIX_ERROR_LOG(rc); + goto release; + } + /* if we have already recv'd the node map, then parse + * and store the detailed map */ + if (NULL != nodes) { + if (PMIX_SUCCESS != (rc = store_map(ht, nodes, procs))) { + PMIX_ERROR_LOG(rc); + goto release; + } + } + } else if (0 == strcmp(info[n].key, PMIX_PROC_DATA)) { + /* an array of data pertaining to a specific proc */ + if (PMIX_DATA_ARRAY != info[n].value.type) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + goto release; + } + size = info[n].value.data.darray->size; + iptr = (pmix_info_t*)info[n].value.data.darray->array; + /* first element of the array must be the rank */ + if (0 != strcmp(iptr[0].key, PMIX_RANK) || + PMIX_PROC_RANK != iptr[0].value.type) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + goto release; + } + rank = iptr[0].value.data.rank; + /* cycle thru the values for this rank and store them */ + for (j=1; j < size; j++) { + kp2 = PMIX_NEW(pmix_kval_t); + if (NULL == kp2) { + rc = PMIX_ERR_NOMEM; + goto release; + } + kp2->key = strdup(iptr[j].key); + PMIX_VALUE_XFER(rc, kp2->value, &iptr[j].value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + goto release; + } + /* if the value contains a string that is longer than the + * limit, then compress it */ + if (PMIX_STRING_SIZE_CHECK(kp2->value)) { + if (pmix_util_compress_string(kp2->value->data.string, &tmp, &len)) { + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + rc = PMIX_ERR_NOMEM; + return rc; + } + kp2->value->type = PMIX_COMPRESSED_STRING; + free(kp2->value->data.string); + kp2->value->data.bo.bytes = (char*)tmp; + kp2->value->data.bo.size = len; + } + } + /* store it in the hash_table */ + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, rank, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + goto release; + } + PMIX_RELEASE(kp2); // maintain acctg + } + } else { + /* just a value relating to the entire job */ + kp2 = PMIX_NEW(pmix_kval_t); + if (NULL == kp2) { + rc = PMIX_ERR_NOMEM; + goto release; + } + kp2->key = strdup(info[n].key); + PMIX_VALUE_XFER(rc, kp2->value, &info[n].value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + goto release; + } + /* if the value contains a string that is longer than the + * limit, then compress it */ + if (PMIX_STRING_SIZE_CHECK(kp2->value)) { + if (pmix_util_compress_string(kp2->value->data.string, &tmp, &len)) { + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + PMIX_RELEASE(kp2); + rc = PMIX_ERR_NOMEM; + return rc; + } + kp2->value->type = PMIX_COMPRESSED_STRING; + free(kp2->value->data.string); + kp2->value->data.bo.bytes = (char*)tmp; + kp2->value->data.bo.size = len; + } + } + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + goto release; + } + } + } + + /* now add any global data that was provided */ + PMIX_LIST_FOREACH(kvptr, &pmix_server_globals.gdata, pmix_kval_t) { + /* sadly, the data cannot simultaneously exist on two lists, + * so we must make a copy of it here */ + kp2 = PMIX_NEW(pmix_kval_t); + if (NULL == kp2) { + rc = PMIX_ERR_NOMEM; + goto release; + } + kp2->key = strdup(kvptr->key); + PMIX_VALUE_XFER(rc, kp2->value, kvptr->value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + goto release; + } + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + break; + } + } + + release: + if (NULL != nodes) { + pmix_argv_free(nodes); + } + if (NULL != procs) { + pmix_argv_free(procs); + } + return rc; +} + +/* we need to pass three things to the client: + * + * (a) the list of nodes involved in this nspace + * + * (b) the hostname for each proc in this nspace + * + * (c) the list of procs on each node for reverse lookup + */ +static pmix_status_t pmix_pack_proc_map(struct pmix_peer_t *pr, + pmix_buffer_t *buf, + char **nodes, char **procs) +{ + pmix_peer_t *peer = (pmix_peer_t*)pr; + pmix_kval_t kv; + pmix_value_t val; + pmix_status_t rc; + pmix_buffer_t buf2; + size_t i, nnodes; + + /* bozo check - need procs for each node */ + if (pmix_argv_count(nodes) != pmix_argv_count(procs)) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + return PMIX_ERR_BAD_PARAM; + } + + PMIX_CONSTRUCT(&buf2, pmix_buffer_t); + PMIX_CONSTRUCT(&kv, pmix_kval_t); + kv.value = &val; + + /* pass the number of nodes involved in this namespace */ + nnodes = pmix_argv_count(nodes); + PMIX_BFROPS_PACK(rc, peer, &buf2, &nnodes, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + goto cleanup; + } + + for (i=0; i < nnodes; i++) { + /* pass the complete list of procs on this node */ + kv.key = nodes[i]; + val.type = PMIX_STRING; + val.data.string = procs[i]; + PMIX_BFROPS_PACK(rc, peer, &buf2, &kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + kv.key = NULL; + val.data.string = NULL; + goto cleanup; + } + } + kv.key = NULL; + val.data.string = NULL; // we didn't strdup it, so don't release it + + /* pass the completed blob */ + kv.key = PMIX_MAP_BLOB; + val.type = PMIX_BYTE_OBJECT; + PMIX_UNLOAD_BUFFER(&buf2, val.data.bo.bytes, val.data.bo.size); + PMIX_BFROPS_PACK(rc, peer, buf, &kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + } + kv.key = NULL; + if (NULL != val.data.bo.bytes) { + free(val.data.bo.bytes); + } + kv.value = NULL; + + cleanup: + PMIX_DESTRUCT(&buf2); + PMIX_DESTRUCT(&kv); + return rc; +} + +static pmix_status_t register_info(pmix_peer_t *peer, + pmix_nspace_t *ns, + pmix_buffer_t *reply) +{ + pmix_rank_t rank; + char **procs = NULL, **nodes = NULL; + size_t n, j, size; + pmix_status_t rc = PMIX_SUCCESS; + pmix_info_t *iptr; + pmix_buffer_t buf2; + pmix_kval_t kv, *kvptr; + pmix_value_t val; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:hash:register_info", + pmix_globals.myid.nspace, pmix_globals.myid.rank); + + /* pack the provided info */ + for (n=0; n < ns->njobinfo; n++) { + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "pmix:gds:hash packing job info %s", + ns->jobinfo[n].key); + + if (0 == strcmp(ns->jobinfo[n].key, PMIX_NODE_MAP)) { + /* parse the regex to get the argv array of node names */ + if (PMIX_SUCCESS != (rc = pmix_preg.parse_nodes(ns->jobinfo[n].value.data.string, &nodes))) { + PMIX_ERROR_LOG(rc); + continue; + } + /* if we have already found the proc map, then pass + * the detailed map */ + if (NULL != procs) { + rc = pmix_pack_proc_map(peer, reply, nodes, procs); + pmix_argv_free(nodes); + nodes = NULL; + pmix_argv_free(procs); + procs = NULL; + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + return rc; + } + } + } else if (0 == strcmp(ns->jobinfo[n].key, PMIX_PROC_MAP)) { + /* parse the regex to get the argv array containing proc ranks on each node */ + if (PMIX_SUCCESS != (rc = pmix_preg.parse_procs(ns->jobinfo[n].value.data.string, &procs))) { + PMIX_ERROR_LOG(rc); + continue; + } + /* if we have already recv'd the node map, then record + * the detailed map */ + if (NULL != nodes) { + rc = pmix_pack_proc_map(peer, reply, nodes, procs); + pmix_argv_free(nodes); + nodes = NULL; + pmix_argv_free(procs); + procs = NULL; + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + return rc; + } + } + } else if (0 == strcmp(ns->jobinfo[n].key, PMIX_PROC_DATA)) { + /* an array of data pertaining to a specific proc */ + if (PMIX_DATA_ARRAY != ns->jobinfo[n].value.type) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + goto release; + } + size = ns->jobinfo[n].value.data.darray->size; + iptr = (pmix_info_t*)ns->jobinfo[n].value.data.darray->array; + PMIX_CONSTRUCT(&buf2, pmix_buffer_t); + /* first element of the array must be the rank */ + if (0 != strcmp(iptr[0].key, PMIX_RANK) || + PMIX_PROC_RANK != iptr[0].value.type) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + PMIX_DESTRUCT(&buf2); + goto release; + } + /* pack it separately */ + rank = iptr[0].value.data.rank; + PMIX_BFROPS_PACK(rc, peer, &buf2, &rank, 1, PMIX_PROC_RANK); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&buf2); + goto release; + } + /* cycle thru the values for this rank and pack them */ + for (j=1; j < size; j++) { + kv.key = iptr[j].key; + kv.value = &iptr[j].value; + PMIX_BFROPS_PACK(rc, peer, &buf2, &kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&buf2); + goto release; + } + } + /* now add the blob */ + kv.key = PMIX_PROC_BLOB; + kv.value = &val; + val.type = PMIX_BYTE_OBJECT; + PMIX_UNLOAD_BUFFER(&buf2, val.data.bo.bytes, val.data.bo.size); + PMIX_BFROPS_PACK(rc, peer, reply, &kv, 1, PMIX_KVAL); + PMIX_VALUE_DESTRUCT(&val); // release the data + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&buf2); + goto release; + } + PMIX_DESTRUCT(&buf2); + } else { + /* just a value relating to the entire job */ + kv.key = ns->jobinfo[n].key; + kv.value = &ns->jobinfo[n].value; + PMIX_BFROPS_PACK(rc, peer, reply, &kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + goto release; + } + } + } + + /* now add any global data that was provided */ + PMIX_LIST_FOREACH(kvptr, &pmix_server_globals.gdata, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, peer, reply, kvptr, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + break; + } + } + + release: + /* cleanup */ + if (NULL != nodes) { + pmix_argv_free(nodes); + } + if (NULL != procs) { + pmix_argv_free(procs); + } + + return rc; +} + +/* the purpose of this function is to pack the job-level + * info stored in the pmix_nspace_t into a buffer and send + * it to the given client */ +static pmix_status_t hash_register_job_info(struct pmix_peer_t *pr, + pmix_buffer_t *reply) +{ + pmix_peer_t *peer = (pmix_peer_t*)pr; + pmix_nspace_t *ns = peer->nptr; + char *msg; + pmix_status_t rc; + pmix_hash_trkr_t *trk, *t2; + + if (PMIX_PROC_SERVER != pmix_globals.proc_type) { + /* this function is only available on servers */ + PMIX_ERROR_LOG(PMIX_ERR_NOT_SUPPORTED); + return PMIX_ERR_NOT_SUPPORTED; + } + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:hash:register_job_info for peer [%s:%d]", + pmix_globals.myid.nspace, pmix_globals.myid.rank, + peer->info->pname.nspace, peer->info->pname.rank); + + + /* NOTE: we do not need to worry here about PMIX_REGISTER_NODATA + * as there will be no jobinfo stored on this nspace object + * if that directive has been given */ + if (NULL == ns->jobinfo) { + return PMIX_SUCCESS; + } + + /* first see if we already have processed this data + * for another peer in this nspace so we don't waste + * time doing it again */ + if (NULL != ns->jobbkt) { + /* we have packed this before - can just deliver it */ + PMIX_BFROPS_COPY_PAYLOAD(rc, peer, reply, ns->jobbkt); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + } + /* now see if we have delivered it to all our local + * clients for this nspace */ + if (ns->ndelivered == ns->nlocalprocs) { + /* we have, so let's get rid of the packed + * copy of the data */ + PMIX_RELEASE(ns->jobbkt); + ns->jobbkt = NULL; + } + return rc; + } + + /* setup a tracker for this nspace as we will likely + * need it again */ + trk = NULL; + PMIX_LIST_FOREACH(t2, &myhashes, pmix_hash_trkr_t) { + if (ns == t2->nptr) { + trk = t2; + if (NULL == trk->ns) { + trk->ns = strdup(ns->nspace); + } + break; + } + } + if (NULL == trk) { + trk = PMIX_NEW(pmix_hash_trkr_t); + trk->ns = strdup(ns->nspace); + PMIX_RETAIN(ns); + trk->nptr = ns; + pmix_list_append(&myhashes, &trk->super); + } + + /* the job info for the specified nspace has + * been given to us in the info array - pack + * them for delivery */ + /* pack the name of the nspace */ + msg = ns->nspace; + PMIX_BFROPS_PACK(rc, peer, reply, &msg, 1, PMIX_STRING); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + return rc; + } + + rc = register_info(peer, ns, reply); + if (PMIX_SUCCESS == rc) { + /* if we have more than one local client for this nspace, + * save this packed object so we don't do this again */ + if (1 < ns->nlocalprocs) { + PMIX_RETAIN(reply); + ns->jobbkt = reply; + } + } else { + PMIX_ERROR_LOG(rc); + } + + return rc; +} + +static pmix_status_t hash_store_job_info(const char *nspace, + pmix_buffer_t *buf) +{ + pmix_status_t rc = PMIX_SUCCESS; + pmix_kval_t *kptr, *kp2, kv; + pmix_value_t *val; + int32_t cnt; + size_t nnodes, len, n; + uint32_t i, j; + char **procs = NULL; + uint8_t *tmp; + pmix_byte_object_t *bo; + pmix_buffer_t buf2; + int rank; + pmix_hash_trkr_t *htptr; + pmix_hash_table_t *ht; + char **nodelist = NULL; + pmix_info_t *info, *iptr; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%u] pmix:gds:hash store job info for nspace %s", + pmix_globals.myid.nspace, pmix_globals.myid.rank, nspace); + + if (PMIX_PROC_SERVER == pmix_globals.proc_type) { + /* this function is NOT available on servers */ + PMIX_ERROR_LOG(PMIX_ERR_NOT_SUPPORTED); + return PMIX_ERR_NOT_SUPPORTED; + } + + /* check buf data */ + if ((NULL == buf) || (0 == buf->bytes_used)) { + rc = PMIX_ERR_BAD_PARAM; + PMIX_ERROR_LOG(rc); + return rc; + } + + /* see if we already have a hash table for this nspace */ + ht = NULL; + PMIX_LIST_FOREACH(htptr, &myhashes, pmix_hash_trkr_t) { + if (0 == strcmp(htptr->ns, nspace)) { + ht = &htptr->internal; + break; + } + } + if (NULL == ht) { + /* nope - create one */ + htptr = PMIX_NEW(pmix_hash_trkr_t); + htptr->ns = strdup(nspace); + pmix_list_append(&myhashes, &htptr->super); + ht = &htptr->internal; + } + + cnt = 1; + kptr = PMIX_NEW(pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, kptr, &cnt, PMIX_KVAL); + while (PMIX_SUCCESS == rc) { + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%u] pmix:gds:hash store job info working key %s", + pmix_globals.myid.nspace, pmix_globals.myid.rank, kptr->key); + if (0 == strcmp(kptr->key, PMIX_PROC_BLOB)) { + bo = &(kptr->value->data.bo); + PMIX_CONSTRUCT(&buf2, pmix_buffer_t); + PMIX_LOAD_BUFFER(pmix_client_globals.myserver, &buf2, bo->bytes, bo->size); + /* start by unpacking the rank */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &buf2, &rank, &cnt, PMIX_PROC_RANK); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&buf2); + return rc; + } + /* unpack the blob and save the values for this rank */ + cnt = 1; + kp2 = PMIX_NEW(pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &buf2, kp2, &cnt, PMIX_KVAL); + while (PMIX_SUCCESS == rc) { + /* if the value contains a string that is longer than the + * limit, then compress it */ + if (PMIX_STRING_SIZE_CHECK(kp2->value)) { + if (pmix_util_compress_string(kp2->value->data.string, &tmp, &len)) { + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + rc = PMIX_ERR_NOMEM; + return rc; + } + kp2->value->type = PMIX_COMPRESSED_STRING; + free(kp2->value->data.string); + kp2->value->data.bo.bytes = (char*)tmp; + kp2->value->data.bo.size = len; + } + } + /* this is data provided by a job-level exchange, so store it + * in the job-level data hash_table */ + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, rank, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + PMIX_DESTRUCT(&buf2); + return rc; + } + PMIX_RELEASE(kp2); // maintain accounting + cnt = 1; + kp2 = PMIX_NEW(pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &buf2, kp2, &cnt, PMIX_KVAL); + } + /* cleanup */ + PMIX_DESTRUCT(&buf2); // releases the original kptr data + PMIX_RELEASE(kp2); + } else if (0 == strcmp(kptr->key, PMIX_MAP_BLOB)) { + /* transfer the byte object for unpacking */ + bo = &(kptr->value->data.bo); + PMIX_CONSTRUCT(&buf2, pmix_buffer_t); + PMIX_LOAD_BUFFER(pmix_client_globals.myserver, &buf2, bo->bytes, bo->size); + /* start by unpacking the number of nodes */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &buf2, &nnodes, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&buf2); + return rc; + } + /* unpack the list of procs on each node */ + for (i=0; i < nnodes; i++) { + cnt = 1; + PMIX_CONSTRUCT(&kv, pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &buf2, &kv, &cnt, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&buf2); + PMIX_DESTRUCT(&kv); + return rc; + } + /* track the nodes in this nspace */ + pmix_argv_append_nosize(&nodelist, kv.key); + /* save the list of peers for this node - but first + * check to see if we already have some data for this node */ + rc = pmix_hash_fetch(ht, PMIX_RANK_WILDCARD, kv.key, &val); + if (PMIX_SUCCESS == rc) { + /* already have some data, so we need to add to it */ + kp2 = PMIX_NEW(pmix_kval_t); + kp2->key = strdup(kv.key); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + kp2->value->type = PMIX_DATA_ARRAY; + kp2->value->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); + if (NULL == kp2->value->data.darray) { + PMIX_DESTRUCT(&buf2); + PMIX_DESTRUCT(&kv); + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->data.darray->type = PMIX_INFO; + kp2->value->data.darray->size = val->data.darray->size + 1; + PMIX_INFO_CREATE(info, kp2->value->data.darray->size); + if (NULL == info) { + PMIX_DESTRUCT(&buf2); + PMIX_DESTRUCT(&kv); + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + iptr = (pmix_info_t*)val->data.darray->array; + /* copy the pre-existing data across */ + for (n=0; n < val->data.darray->size; n++) { + PMIX_INFO_XFER(&info[n], &iptr[n]); + } + PMIX_INFO_LOAD(&info[kp2->value->data.darray->size-1], PMIX_LOCAL_PEERS, kv.value->data.string, PMIX_STRING); + kp2->value->data.darray->array = info; + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + PMIX_DESTRUCT(&kv); + PMIX_DESTRUCT(&buf2); + return rc; + } + PMIX_RELEASE(kp2); + } else { + /* nope - so add this by itself */ + kp2 = PMIX_NEW(pmix_kval_t); + kp2->key = strdup(kv.key); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + kp2->value->type = PMIX_DATA_ARRAY; + kp2->value->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t)); + if (NULL == kp2->value->data.darray) { + PMIX_DESTRUCT(&buf2); + PMIX_DESTRUCT(&kv); + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + kp2->value->data.darray->type = PMIX_INFO; + PMIX_INFO_CREATE(info, 1); + if (NULL == info) { + PMIX_DESTRUCT(&buf2); + PMIX_DESTRUCT(&kv); + PMIX_RELEASE(kp2); + return PMIX_ERR_NOMEM; + } + PMIX_INFO_LOAD(&info[0], PMIX_LOCAL_PEERS, kv.value->data.string, PMIX_STRING); + kp2->value->data.darray->array = info; + kp2->value->data.darray->size = 1; + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + PMIX_DESTRUCT(&kv); + PMIX_DESTRUCT(&buf2); + return rc; + } + PMIX_RELEASE(kp2); + } + /* split the list of procs so we can store their + * individual location data */ + procs = pmix_argv_split(kv.value->data.string, ','); + for (j=0; NULL != procs[j]; j++) { + /* store the hostname for each proc - again, this is + * data obtained via a job-level exchange, so store it + * in the job-level data hash_table */ + kp2 = PMIX_NEW(pmix_kval_t); + kp2->key = strdup(PMIX_HOSTNAME); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + kp2->value->type = PMIX_STRING; + kp2->value->data.string = strdup(kv.key); + rank = strtol(procs[j], NULL, 10); + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, rank, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + PMIX_DESTRUCT(&kv); + PMIX_DESTRUCT(&buf2); + pmix_argv_free(procs); + return rc; + } + PMIX_RELEASE(kp2); + } + pmix_argv_free(procs); + PMIX_DESTRUCT(&kv); + } + if (NULL != nodelist) { + /* store the comma-delimited list of nodes hosting + * procs in this nspace */ + kp2 = PMIX_NEW(pmix_kval_t); + kp2->key = strdup(PMIX_NODE_LIST); + kp2->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + kp2->value->type = PMIX_STRING; + kp2->value->data.string = pmix_argv_join(nodelist, ','); + pmix_argv_free(nodelist); + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kp2))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp2); + PMIX_DESTRUCT(&kv); + PMIX_DESTRUCT(&buf2); + return rc; + } + PMIX_RELEASE(kp2); + } + /* cleanup */ + PMIX_DESTRUCT(&buf2); + } else { + /* if the value contains a string that is longer than the + * limit, then compress it */ + if (PMIX_STRING_SIZE_CHECK(kptr->value)) { + if (pmix_util_compress_string(kptr->value->data.string, &tmp, &len)) { + if (NULL == tmp) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + rc = PMIX_ERR_NOMEM; + return rc; + } + kptr->value->type = PMIX_COMPRESSED_STRING; + free(kptr->value->data.string); + kptr->value->data.bo.bytes = (char*)tmp; + kptr->value->data.bo.size = len; + } + } + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%u] pmix:gds:hash store job info storing key %s for WILDCARD rank", + pmix_globals.myid.nspace, pmix_globals.myid.rank, kptr->key); + if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, PMIX_RANK_WILDCARD, kptr))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kptr); + return rc; + } + } + PMIX_RELEASE(kptr); + kptr = PMIX_NEW(pmix_kval_t); + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, kptr, &cnt, PMIX_KVAL); + } + /* need to release the leftover kptr */ + PMIX_RELEASE(kptr); + + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { + PMIX_ERROR_LOG(rc); + } else { + rc = PMIX_SUCCESS; + } + return rc; +} + +static pmix_status_t hash_store(const pmix_proc_t *proc, + pmix_scope_t scope, + pmix_kval_t *kv) +{ + pmix_hash_trkr_t *trk, *t; + pmix_status_t rc; + pmix_kval_t *kp; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:hash:hash_store for proc [%s:%d] key %s scope %s", + pmix_globals.myid.nspace, pmix_globals.myid.rank, + proc->nspace, proc->rank, kv->key, + PMIx_Scope_string(scope)); + + if (NULL == kv->key) { + return PMIX_ERR_BAD_PARAM; + } + + /* find the hash table for this nspace */ + trk = NULL; + PMIX_LIST_FOREACH(t, &myhashes, pmix_hash_trkr_t) { + if (0 == strcmp(proc->nspace, t->ns)) { + trk = t; + break; + } + } + if (NULL == trk) { + /* create one */ + trk = PMIX_NEW(pmix_hash_trkr_t); + trk->ns = strdup(proc->nspace); + pmix_list_append(&myhashes, &trk->super); + } + + /* see if the proc is me */ + if (proc->rank == pmix_globals.myid.rank && + 0 == strncmp(proc->nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN)) { + if (PMIX_INTERNAL != scope) { + /* always maintain a copy of my own info here to simplify + * later retrieval */ + kp = PMIX_NEW(pmix_kval_t); + if (NULL == kp) { + return PMIX_ERR_NOMEM; + } + kp->key = strdup(kv->key); + kp->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == kp->value) { + PMIX_RELEASE(kp); + return PMIX_ERR_NOMEM; + } + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, kp->value, kv->value); + if (PMIX_SUCCESS != rc) { + PMIX_RELEASE(kp); + return rc; + } + if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->internal, proc->rank, kp))) { + PMIX_ERROR_LOG(rc); + return rc; + } + } + } + + /* store it in the corresponding hash table */ + if (PMIX_INTERNAL == scope) { + if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->internal, proc->rank, kv))) { + PMIX_ERROR_LOG(rc); + return rc; + } + } else if (PMIX_REMOTE == scope) { + if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->remote, proc->rank, kv))) { + PMIX_ERROR_LOG(rc); + return rc; + } + } else if (PMIX_LOCAL == scope) { + if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->local, proc->rank, kv))) { + PMIX_ERROR_LOG(rc); + return rc; + } + } else if (PMIX_GLOBAL == scope) { + if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->remote, proc->rank, kv))) { + PMIX_ERROR_LOG(rc); + return rc; + } + /* a pmix_kval_t can only be on one list at a time, so we + * have to duplicate it here */ + kp = PMIX_NEW(pmix_kval_t); + if (NULL == kp) { + return PMIX_ERR_NOMEM; + } + kp->key = strdup(kv->key); + kp->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == kp->value) { + PMIX_RELEASE(kp); + return PMIX_ERR_NOMEM; + } + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, kp->value, kv->value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp); + return rc; + } + if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->local, proc->rank, kp))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp); + return rc; + } + PMIX_RELEASE(kp); // maintain accounting + } else { + return PMIX_ERR_BAD_PARAM; + } + + return PMIX_SUCCESS; +} + +/* this function is only called by the PMIx server when its + * host has received data from some other peer. It therefore + * always contains data solely from remote procs, and we + * shall store it accordingly */ +static pmix_status_t hash_store_modex(struct pmix_nspace_t *nspace, + pmix_list_t *cbs, + pmix_byte_object_t *bo) +{ + pmix_nspace_t *ns = (pmix_nspace_t*)nspace; + pmix_hash_trkr_t *trk, *t; + pmix_server_caddy_t *scd; + pmix_status_t rc = PMIX_SUCCESS; + int32_t cnt; + pmix_buffer_t pbkt; + pmix_proc_t proc; + pmix_kval_t *kv; + pmix_peer_t *peer; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%d] gds:hash:store_modex for nspace %s", + pmix_globals.myid.nspace, pmix_globals.myid.rank, + ns->nspace); + + /* find the hash table for this nspace */ + trk = NULL; + PMIX_LIST_FOREACH(t, &myhashes, pmix_hash_trkr_t) { + if (0 == strcmp(ns->nspace, t->ns)) { + trk = t; + break; + } + } + if (NULL == trk) { + /* create one */ + trk = PMIX_NEW(pmix_hash_trkr_t); + trk->ns = strdup(ns->nspace); + pmix_list_append(&myhashes, &trk->super); + } + + /* this is data returned via the PMIx_Fence call when + * data collection was requested, so it only contains + * REMOTE/GLOBAL data. The byte object contains + * the rank followed by pmix_kval_t's. The list of callbacks + * contains all local participants. */ + peer = NULL; + PMIX_LIST_FOREACH(scd, cbs, pmix_server_caddy_t) { + if (scd->peer->nptr == ns) { + peer = scd->peer; + break; + } + } + if (NULL == peer) { + /* we can ignore this one */ + return PMIX_SUCCESS; + } + + /* setup the byte object for unpacking */ + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + /* the next step unfortunately NULLs the byte object's + * entries, so we need to ensure we restore them! */ + PMIX_LOAD_BUFFER(peer, &pbkt, bo->bytes, bo->size); + /* unload the proc that provided this data */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, peer, &pbkt, &proc, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + bo->bytes = pbkt.base_ptr; + bo->size = pbkt.bytes_used; // restore the incoming data + pbkt.base_ptr = NULL; + PMIX_DESTRUCT(&pbkt); + return rc; + } + /* unpack the remaining values until we hit the end of the buffer */ + cnt = 1; + kv = PMIX_NEW(pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, peer, &pbkt, kv, &cnt, PMIX_KVAL); + while (PMIX_SUCCESS == rc) { + /* store this in the hash table */ + if (PMIX_SUCCESS != (rc = pmix_hash_store(&trk->remote, proc.rank, kv))) { + PMIX_ERROR_LOG(rc); + bo->bytes = pbkt.base_ptr; + bo->size = pbkt.bytes_used; // restore the incoming data + pbkt.base_ptr = NULL; + PMIX_DESTRUCT(&pbkt); + return rc; + } + PMIX_RELEASE(kv); // maintain accounting as the hash increments the ref count + /* continue along */ + kv = PMIX_NEW(pmix_kval_t); + cnt = 1; + PMIX_BFROPS_UNPACK(rc, peer, &pbkt, kv, &cnt, PMIX_KVAL); + } + PMIX_RELEASE(kv); // maintain accounting + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { + PMIX_ERROR_LOG(rc); + } else { + rc = PMIX_SUCCESS; + } + bo->bytes = pbkt.base_ptr; + bo->size = pbkt.bytes_used; // restore the incoming data + pbkt.base_ptr = NULL; + PMIX_DESTRUCT(&pbkt); + return rc; +} + + +static pmix_status_t hash_fetch(const pmix_proc_t *proc, + pmix_scope_t scope, bool copy, + const char *key, + pmix_info_t qualifiers[], size_t nqual, + pmix_list_t *kvs) +{ + pmix_hash_trkr_t *trk, *t; + pmix_status_t rc; + pmix_value_t *val; + pmix_kval_t *kv; + pmix_info_t *info; + size_t n, ninfo; + pmix_hash_table_t *ht; + + pmix_output_verbose(2, pmix_gds_base_framework.framework_output, + "[%s:%u] pmix:gds:hash fetch %s for proc %s:%u on scope %s", + pmix_globals.myid.nspace, pmix_globals.myid.rank, + (NULL == key) ? "NULL" : key, + proc->nspace, proc->rank, PMIx_Scope_string(scope)); + + /* if the rank is wildcard and the key is NULL, then + * they are asking for a complete copy of the job-level + * info for this nspace - retrieve it */ + if (NULL == key && PMIX_RANK_WILDCARD == proc->rank) { + /* see if we have a tracker for this nspace - we will + * if we already cached the job info for it */ + trk = NULL; + PMIX_LIST_FOREACH(t, &myhashes, pmix_hash_trkr_t) { + if (0 == strcmp(proc->nspace, t->ns)) { + trk = t; + break; + } + } + if (NULL == trk) { + /* let the caller know */ + return PMIX_ERR_INVALID_NAMESPACE; + } + /* the job data is stored on the internal hash table */ + ht = &trk->internal; + /* fetch all values from the hash table tied to rank=wildcard */ + val = NULL; + rc = pmix_hash_fetch(ht, PMIX_RANK_WILDCARD, NULL, &val); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + if (NULL != val) { + PMIX_VALUE_RELEASE(val); + } + return rc; + } + if (NULL == val) { + return PMIX_ERR_NOT_FOUND; + } + /* the data is returned in a pmix_data_array_t of pmix_info_t + * structs. cycle thru and transfer them to the list */ + if (PMIX_DATA_ARRAY != val->type || + NULL == val->data.darray || + PMIX_INFO != val->data.darray->type) { + PMIX_ERROR_LOG(PMIX_ERR_INVALID_VAL); + PMIX_VALUE_RELEASE(val); + return PMIX_ERR_INVALID_VAL; + } + info = (pmix_info_t*)val->data.darray->array; + ninfo = val->data.darray->size; + for (n=0; n < ninfo; n++) { + kv = PMIX_NEW(pmix_kval_t); + if (NULL == kv) { + rc = PMIX_ERR_NOMEM; + PMIX_VALUE_RELEASE(val); + return rc; + } + kv->key = strdup(info[n].key); + PMIX_VALUE_XFER(rc, kv->value, &info[n].value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kv); + PMIX_VALUE_RELEASE(val); + return rc; + } + pmix_list_append(kvs, &kv->super); + } + PMIX_VALUE_RELEASE(val); + return PMIX_SUCCESS; + } + + /* find the hash table for this nspace */ + trk = NULL; + PMIX_LIST_FOREACH(t, &myhashes, pmix_hash_trkr_t) { + if (0 == strcmp(proc->nspace, t->ns)) { + trk = t; + break; + } + } + if (NULL == trk) { + return PMIX_ERR_INVALID_NAMESPACE; + } + + /* fetch from the corresponding hash table - note that + * we always provide a copy as we don't support + * shared memory */ + if (PMIX_INTERNAL == scope || + PMIX_SCOPE_UNDEF == scope || + PMIX_GLOBAL == scope || + PMIX_RANK_WILDCARD == proc->rank) { + ht = &trk->internal; + } else if (PMIX_LOCAL == scope || + PMIX_GLOBAL == scope) { + ht = &trk->local; + } else if (PMIX_REMOTE == scope) { + ht = &trk->remote; + } else { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + return PMIX_ERR_BAD_PARAM; + } + + doover: + rc = pmix_hash_fetch(ht, proc->rank, key, &val); + if (PMIX_SUCCESS == rc) { + /* if the key was NULL, then all found keys will be + * returned as a pmix_data_array_t in the value */ + if (NULL == key) { + if (NULL == val->data.darray || + PMIX_INFO != val->data.darray->type || + 0 == val->data.darray->size) { + PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); + return PMIX_ERR_NOT_FOUND; + } + info = (pmix_info_t*)val->data.darray->array; + ninfo = val->data.darray->size; + for (n=0; n < ninfo; n++) { + kv = PMIX_NEW(pmix_kval_t); + if (NULL == kv) { + PMIX_VALUE_RELEASE(val); + return PMIX_ERR_NOMEM; + } + kv->key = strdup(info[n].key); + kv->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); + if (NULL == kv->value) { + PMIX_VALUE_RELEASE(val); + PMIX_RELEASE(kv); + return PMIX_ERR_NOMEM; + } + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, + kv->value, &info[n].value); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_VALUE_RELEASE(val); + PMIX_RELEASE(kv); + return rc; + } + pmix_list_append(kvs, &kv->super); + } + PMIX_VALUE_RELEASE(val); + if (PMIX_GLOBAL == scope && ht == &trk->local) { + /* need to do this again for the remote data */ + ht = &trk->remote; + goto doover; + } + return PMIX_SUCCESS; + } + /* just return the value */ + kv = PMIX_NEW(pmix_kval_t); + if (NULL == kv) { + PMIX_VALUE_RELEASE(val); + return PMIX_ERR_NOMEM; + } + kv->key = strdup(key); + kv->value = val; + pmix_list_append(kvs, &kv->super); + } else { + if (PMIX_GLOBAL == scope || + PMIX_SCOPE_UNDEF == scope) { + if (ht == &trk->internal) { + /* need to also try the local data */ + ht = &trk->local; + goto doover; + } else if (ht == &trk->local) { + /* need to also try the remote data */ + ht = &trk->remote; + goto doover; + } + } + } + + return rc; +} + +static pmix_status_t setup_fork(const pmix_proc_t *proc, char ***env) +{ + /* we don't need to add anything */ + return PMIX_SUCCESS; +} + +static pmix_status_t nspace_add(const char *nspace, + pmix_info_t info[], + size_t ninfo) +{ + /* we don't need to do anything here */ + return PMIX_SUCCESS; +} + +static pmix_status_t nspace_del(const char *nspace) +{ + /* we don't need to do anything here */ + return PMIX_SUCCESS; +} + +static pmix_status_t assemb_kvs_req(const pmix_proc_t *proc, + pmix_list_t *kvs, + pmix_buffer_t *buf, + void *cbdata) +{ + pmix_status_t rc = PMIX_SUCCESS; + pmix_server_caddy_t *cd = (pmix_server_caddy_t*)cbdata; + pmix_kval_t *kv; + + PMIX_BFROPS_PACK(rc, cd->peer, buf, proc, 1, PMIX_PROC); + if (PMIX_SUCCESS != rc) { + return rc; + } + PMIX_LIST_FOREACH(kv, kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, cd->peer, buf, kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + return rc; + } + } + return rc; +} + +static pmix_status_t accept_kvs_resp(pmix_buffer_t *buf) +{ + pmix_status_t rc = PMIX_SUCCESS; + int32_t cnt; + pmix_byte_object_t bo; + pmix_buffer_t pbkt; + pmix_kval_t *kv; + pmix_proc_t proct; + + /* the incoming payload is provided as a set of packed + * byte objects, one for each rank. A pmix_proc_t is the first + * entry in the byte object. If the rank=PMIX_RANK_WILDCARD, + * then that byte object contains job level info + * for the provided nspace. Otherwise, the byte + * object contains the pmix_kval_t's that were "put" by the + * referenced process */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &bo, &cnt, PMIX_BYTE_OBJECT); + while (PMIX_SUCCESS == rc) { + /* setup the byte object for unpacking */ + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + PMIX_LOAD_BUFFER(pmix_client_globals.myserver, + &pbkt, bo.bytes, bo.size); + /* unpack the id of the providing process */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &pbkt, &proct, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + return rc; + } + cnt = 1; + kv = PMIX_NEW(pmix_kval_t); + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &pbkt, kv, &cnt, PMIX_KVAL); + while (PMIX_SUCCESS == rc) { + /* let the GDS component for this peer store it - if + * the kval contains shmem connection info, then the + * component will know what to do about it (or else + * we selected the wrong component for this peer!) */ + + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, &proct, PMIX_INTERNAL, kv); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kv); + PMIX_DESTRUCT(&pbkt); + return rc; + } + PMIX_RELEASE(kv); // maintain accounting + /* get the next one */ + kv = PMIX_NEW(pmix_kval_t); + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + &pbkt, kv, &cnt, PMIX_KVAL); + } + PMIX_RELEASE(kv); // maintain accounting + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&pbkt); + return rc; + } + PMIX_DESTRUCT(&pbkt); + /* get the next one */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &bo, &cnt, PMIX_BYTE_OBJECT); + } + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { + PMIX_ERROR_LOG(rc); + return rc; + } + return rc; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash.h b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash.h new file mode 100644 index 0000000000..4d6e69a543 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_GDS_HASH_H +#define PMIX_GDS_HASH_H + +#include + + +#include "src/mca/gds/gds.h" + +BEGIN_C_DECLS + +/* the component must be visible data for the linker to find it */ +PMIX_EXPORT extern pmix_gds_base_component_t mca_gds_hash_component; +extern pmix_gds_base_module_t pmix_hash_module; + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash_component.c new file mode 100644 index 0000000000..f9c123963a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/gds/hash/gds_hash_component.c @@ -0,0 +1,84 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + * These symbols are in a file by themselves to provide nice linker + * semantics. Since linkers generally pull in symbols by object + * files, keeping these symbols as the only symbols in this file + * prevents utility programs such as "ompi_info" from having to import + * entire components just to query their version and parameters. + */ + +#include +#include "pmix_common.h" + + +#include "src/mca/gds/gds.h" +#include "gds_hash.h" + +static pmix_status_t component_open(void); +static pmix_status_t component_close(void); +static pmix_status_t component_query(pmix_mca_base_module_t **module, int *priority); + +/* + * Instantiate the public struct with all of our public information + * and pointers to our public functions in it + */ +pmix_gds_base_component_t mca_gds_hash_component = { + .base = { + PMIX_GDS_BASE_VERSION_1_0_0, + + /* Component name and version */ + .pmix_mca_component_name = "hash", + PMIX_MCA_BASE_MAKE_VERSION(component, + PMIX_MAJOR_VERSION, + PMIX_MINOR_VERSION, + PMIX_RELEASE_VERSION), + + /* Component open and close functions */ + .pmix_mca_open_component = component_open, + .pmix_mca_close_component = component_close, + .pmix_mca_query_component = component_query, + }, + .data = { + /* The component is checkpoint ready */ + PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT + } +}; + + +static int component_open(void) +{ + return PMIX_SUCCESS; +} + + +static int component_query(pmix_mca_base_module_t **module, int *priority) +{ + *priority = 10; + *module = (pmix_mca_base_module_t *)&pmix_hash_module; + return PMIX_SUCCESS; +} + + +static int component_close(void) +{ + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/mca.h b/opal/mca/pmix/pmix2x/pmix/src/mca/mca.h index 5970a10eb8..2ce93659bf 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/mca.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/mca.h @@ -13,7 +13,7 @@ * Copyright (c) 2008-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/Makefile.am index fdd56a8e2e..6218f318b6 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/Makefile.am @@ -3,6 +3,7 @@ # University Research and Technology # Corporation. All rights reserved. # Copyright (c) 2010-2015 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/Makefile.am index efc770a274..432c401103 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/Makefile.am @@ -1,5 +1,6 @@ # # Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/base.h index 2cb3725688..db39debf5d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/base.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/base.h @@ -3,7 +3,7 @@ * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_close.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_close.c index 7c6f5456a4..eeb4eab952 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_close.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_close.c @@ -2,7 +2,7 @@ * Copyright (c) 2004-2010 The Trustees of Indiana University. * All rights reserved. * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_fns.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_fns.c index 091715dadc..5d240c0e7f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_fns.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_fns.c @@ -2,7 +2,7 @@ * Copyright (c) 2004-2010 The Trustees of Indiana University. * All rights reserved. * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_open.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_open.c index 22b6cd4c47..ddf2cd51b9 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_open.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_open.c @@ -4,7 +4,7 @@ * Copyright (c) 2011-2013 Los Alamos National Security, LLC. * All rights reserved. * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_select.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_select.c index e42db673be..dde3b755d7 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_select.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_select.c @@ -4,6 +4,7 @@ * All rights reserved. * * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h index e34ac5bd6b..950e4f33c0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h @@ -3,6 +3,7 @@ * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/Makefile.am index c2811eecd8..fce6a5e14e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/Makefile.am @@ -2,6 +2,7 @@ # Copyright (c) 2004-2010 The Trustees of Indiana University. # All rights reserved. # Copyright (c) 2014-2015 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen.h index 7ba3e24760..101f457b96 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_component.c index 8e061d5ca9..5bee2fd73c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_component.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_component.c @@ -3,6 +3,7 @@ * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_module.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_module.c index 85e8854e8e..bea5630eda 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_module.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_module.c @@ -4,7 +4,7 @@ * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/Makefile.am index f444a5ca9b..fc206e0fb8 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/Makefile.am @@ -1,5 +1,6 @@ # # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/Makefile.am index 7bd00a4b3f..797be986a9 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/Makefile.am @@ -1,6 +1,6 @@ # # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/base.h index e219a065c6..33568a2546 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/base.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/base.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/pif_base_components.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/pif_base_components.c index 803e45c2a0..982a607520 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/pif_base_components.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/base/pif_base_components.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2010-2013 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015-2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/Makefile.am index fcc8f2bab9..f2a4afad67 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/Makefile.am @@ -1,6 +1,6 @@ # # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/configure.m4 index 6142c8032c..adf1bd7f6d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/configure.m4 @@ -3,7 +3,7 @@ # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2015 Research Organization for Information Science # and Technology (RIST). All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/pif_bsdx.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/pif_bsdx.c index 9157d54661..399147d81e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/pif_bsdx.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv4/pif_bsdx.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/Makefile.am index 8772eb3868..92871d285d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/Makefile.am @@ -1,6 +1,6 @@ # # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/configure.m4 index 22333fc258..caa792092f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/configure.m4 @@ -3,7 +3,7 @@ # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2015 Research Organization for Information Science # and Technology (RIST). All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/pif_bsdx_ipv6.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/pif_bsdx_ipv6.c index 2dac2550d3..d09ecc78f1 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/pif_bsdx_ipv6.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/bsdx_ipv6/pif_bsdx_ipv6.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/Makefile.am index 9bba51baeb..be3460a51e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/Makefile.am @@ -1,6 +1,6 @@ # # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/configure.m4 index e09ba899fc..e540d76b72 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/configure.m4 @@ -3,7 +3,7 @@ # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2015 Research Organization for Information Science # and Technology (RIST). All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/pif_linux_ipv6.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/pif_linux_ipv6.c index 2f240f9d8a..b7e601d24e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/pif_linux_ipv6.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/linux_ipv6/pif_linux_ipv6.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/pif.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/pif.h index 29c75b869c..d1a2dee03e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/pif.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/pif.h @@ -3,7 +3,7 @@ * Copyright (c) 2010-2013 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/Makefile.am index e8f8fd5f7b..316795d8a6 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/Makefile.am @@ -1,6 +1,6 @@ # # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/configure.m4 index 729c97d603..3bba3fdcf2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/configure.m4 @@ -3,7 +3,7 @@ # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2015 Research Organization for Information Science # and Technology (RIST). All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/pif_posix.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/pif_posix.c index 3c2e4603a6..f8c075b84d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/pif_posix.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/posix_ipv4/pif_posix.c @@ -4,7 +4,7 @@ * Copyright (c) 2013 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/Makefile.am index 9d62d2d7d7..5c3ec5986f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/Makefile.am @@ -1,6 +1,6 @@ # # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/configure.m4 index df109d516d..748a30e129 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/configure.m4 @@ -1,7 +1,7 @@ # -*- shell-script -*- # # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/pif_solaris_ipv6.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/pif_solaris_ipv6.c index 7403cebf0e..2d1688af03 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/pif_solaris_ipv6.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pif/solaris_ipv6/pif_solaris_ipv6.c @@ -3,7 +3,7 @@ * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/Makefile.am index deaa8fe667..da5e305a55 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/Makefile.am @@ -2,7 +2,7 @@ # Copyright (c) 2006 Los Alamos National Security, LLC. All rights # reserved. # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/Makefile.am index 1617f5688c..8b7d5164a7 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/Makefile.am @@ -1,6 +1,7 @@ # # Copyright (c) 2006 Los Alamos National Security, LLC. All rights # reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/base.h index a7592f0927..99ac117725 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/base.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/base.h @@ -3,7 +3,7 @@ * reserved. * Copyright (c) 2007-2010 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2010 Sandia National Laboratories. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_components.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_components.c index 5a8902886e..61d1c0b553 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_components.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_components.c @@ -5,7 +5,7 @@ * Copyright (c) 2010 Sandia National Laboratories. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_expand.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_expand.c index d52822d2d5..fd4b680d54 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_expand.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_expand.c @@ -4,7 +4,7 @@ * Copyright (c) 2007-2010 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2007 Sun Microsystem, Inc. All rights reserved. * Copyright (c) 2010 Sandia National Laboratories. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/Makefile.am index d05743fb5f..518453a576 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/Makefile.am @@ -4,7 +4,7 @@ # Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2009 High Performance Computing Center Stuttgart, # University of Stuttgart. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/configure.m4 index 2f652e9c66..a73172e07a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/configure.m4 @@ -3,7 +3,7 @@ # Copyright (c) 2006 Los Alamos National Security, LLC. All rights # reserved. # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Research Organization for Information Science # and Technology (RIST). All rights reserved. # $COPYRIGHT$ @@ -29,4 +29,3 @@ AC_DEFUN([MCA_pmix_pinstalldirs_config_CONFIG],[ AC_CONFIG_FILES([src/mca/pinstalldirs/config/Makefile src/mca/pinstalldirs/config/pinstall_dirs.h]) ]) - diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pinstall_dirs.h.in b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pinstall_dirs.h.in index e1569ae73a..22dd8bd4a5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pinstall_dirs.h.in +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pinstall_dirs.h.in @@ -11,7 +11,7 @@ * All rights reserved. * Copyright (c) 2007 Los Alamos National Security, LLC. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pmix_pinstalldirs_config.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pmix_pinstalldirs_config.c index f48de36bd8..1d087e5997 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pmix_pinstalldirs_config.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pmix_pinstalldirs_config.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/configure.m4 index 08217bd349..b2bed9ff37 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/configure.m4 @@ -1,7 +1,7 @@ dnl -*- shell-script -*- dnl dnl Copyright (c) 2006-2010 Sandia National Laboratories. All rights reserved. -dnl Copyright (c) 2016 Intel, Inc. All rights reserved. +dnl Copyright (c) 2016-2017 Intel, Inc. All rights reserved. dnl $COPYRIGHT$ dnl dnl Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/Makefile.am index 61471d1392..26ff104d7a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/Makefile.am @@ -3,6 +3,7 @@ # reserved. # Copyright (c) 2009 High Performance Computing Center Stuttgart, # University of Stuttgart. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/configure.m4 index 3fa7fa7674..90916d196e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/configure.m4 @@ -3,7 +3,7 @@ # Copyright (c) 2006 Los Alamos National Security, LLC. All rights # reserved. # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Research Organization for Information Science # and Technology (RIST). All rights reserved. # $COPYRIGHT$ @@ -27,4 +27,3 @@ AC_DEFUN([MCA_pmix_pinstalldirs_env_COMPILE_MODE], [ AC_DEFUN([MCA_pmix_pinstalldirs_env_CONFIG], [ AC_CONFIG_FILES([src/mca/pinstalldirs/env/Makefile]) ]) - diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/pmix_pinstalldirs_env.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/pmix_pinstalldirs_env.c index 9ee499b079..2f43925f45 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/pmix_pinstalldirs_env.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/pmix_pinstalldirs_env.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/pinstalldirs.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/pinstalldirs.h index 22930abeca..077ee129aa 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/pinstalldirs.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/pinstalldirs.h @@ -2,7 +2,7 @@ /* * Copyright (c) 2006-2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/Makefile.am index 9a078f0244..170fe2f772 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/Makefile.include index a45c86fd0b..13b086fcdf 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/Makefile.include @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/base.h index 7ed16e4787..aa64c7f0c2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/base.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/base.h @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -47,14 +47,14 @@ BEGIN_C_DECLS /* * MCA Framework */ -extern pmix_mca_base_framework_t pmix_pnet_base_framework; +PMIX_EXPORT extern pmix_mca_base_framework_t pmix_pnet_base_framework; /** * PNET select function * * Cycle across available components and construct the list * of active modules */ -pmix_status_t pmix_pnet_base_select(void); +PMIX_EXPORT pmix_status_t pmix_pnet_base_select(void); /** * Track an active component / module @@ -78,13 +78,13 @@ typedef struct pmix_pnet_globals_t pmix_pnet_globals_t; extern pmix_pnet_globals_t pmix_pnet_globals; -pmix_status_t pmix_pnet_base_setup_app(char *nspace, pmix_list_t *ilist); -pmix_status_t pmix_pnet_base_setup_local_network(char *nspace, - pmix_info_t info[], - size_t ninfo); -pmix_status_t pmix_pnet_base_setup_fork(const pmix_proc_t *peer, char ***env); -void pmix_pnet_base_child_finalized(pmix_peer_t *peer); -void pmix_pnet_base_local_app_finalized(char *nspace); +PMIX_EXPORT pmix_status_t pmix_pnet_base_setup_app(char *nspace, pmix_list_t *ilist); +PMIX_EXPORT pmix_status_t pmix_pnet_base_setup_local_network(char *nspace, + pmix_info_t info[], + size_t ninfo); +PMIX_EXPORT pmix_status_t pmix_pnet_base_setup_fork(const pmix_proc_t *peer, char ***env); +PMIX_EXPORT void pmix_pnet_base_child_finalized(pmix_peer_t *peer); +PMIX_EXPORT void pmix_pnet_base_local_app_finalized(char *nspace); END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_fns.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_fns.c index 3572fdf8e8..d868700414 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_fns.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_fns.c @@ -1,6 +1,6 @@ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. * All rights reserved. * diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_frame.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_frame.c index 0dd5410dae..a3ebb31ae0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_frame.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_frame.c @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015-2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_select.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_select.c index f751146948..cfa32bcbe5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_select.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/base/pnet_base_select.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/Makefile.am index 1223b43eca..1d140e020b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2017 Research Organization for Information Science # and Technology (RIST). All rights reserved. # $COPYRIGHT$ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/configure.m4 index 4d6d109a9d..97344fa373 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/configure.m4 @@ -12,7 +12,7 @@ # All rights reserved. # Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2013 Sandia National Laboratories. All rights reserved. -# Copyright (c) 2014-2016 Intel, Inc. All rights reserved. +# Copyright (c) 2014-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/pnet_opa.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/pnet_opa.h index 278c894863..4d777c46a1 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/pnet_opa.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/pnet_opa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * * $COPYRIGHT$ * diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/pnet_opa_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/pnet_opa_component.c index 7d07c400f6..ef7e180215 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/pnet_opa_component.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/opa/pnet_opa_component.c @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/pnet.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/pnet.h index dedb1eb63f..7a28f5d3dd 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/pnet.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pnet/pnet.h @@ -1,7 +1,7 @@ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/Makefile.am new file mode 100644 index 0000000000..401066445e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/Makefile.am @@ -0,0 +1,44 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_CPPFLAGS = $(LTDLINCL) + +# main library setup +noinst_LTLIBRARIES = libmca_preg.la +libmca_preg_la_SOURCES = + +# local files +headers = preg.h preg_types.h +sources = + +# Conditionally install the header files +if WANT_INSTALL_HEADERS +pmixdir = $(pmixincludedir)/$(subdir) +nobase_pmix_HEADERS = $(headers) +endif + +include base/Makefile.include + +libmca_preg_la_SOURCES += $(headers) $(sources) + +distclean-local: + rm -f base/static-components.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/Makefile.include new file mode 100644 index 0000000000..9e2461a785 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/Makefile.include @@ -0,0 +1,32 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from +# src/Makefile.am + +headers += \ + base/base.h + +sources += \ + base/preg_base_frame.c \ + base/preg_base_select.c \ + base/preg_base_stubs.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/base.h new file mode 100644 index 0000000000..1ed424b4bd --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/base.h @@ -0,0 +1,97 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ +#ifndef PMIX_PREG_BASE_H_ +#define PMIX_PREG_BASE_H_ + +#include + + +#ifdef HAVE_SYS_TIME_H +#include /* for struct timeval */ +#endif +#ifdef HAVE_STRING_H +#include +#endif + +#include "src/class/pmix_pointer_array.h" +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_framework.h" + +#include "src/mca/preg/preg.h" + + +BEGIN_C_DECLS + +/* + * MCA Framework + */ +PMIX_EXPORT extern pmix_mca_base_framework_t pmix_preg_base_framework; +/** + * PREG select function + * + * Cycle across available components and construct the list + * of active modules + */ +PMIX_EXPORT pmix_status_t pmix_preg_base_select(void); + +/** + * Track an active component / module + */ +struct pmix_preg_base_active_module_t { + pmix_list_item_t super; + int pri; + pmix_preg_module_t *module; + pmix_mca_base_component_t *component; +}; +typedef struct pmix_preg_base_active_module_t pmix_preg_base_active_module_t; +PMIX_CLASS_DECLARATION(pmix_preg_base_active_module_t); + + +/* framework globals */ +struct pmix_preg_globals_t { + pmix_list_t actives; + bool initialized; +}; +typedef struct pmix_preg_globals_t pmix_preg_globals_t; + +PMIX_EXPORT extern pmix_preg_globals_t pmix_preg_globals; + +PMIX_EXPORT pmix_status_t pmix_preg_base_generate_node_regex(const char *input, + char **regex); +PMIX_EXPORT pmix_status_t pmix_preg_base_generate_ppn(const char *input, + char **ppn); +PMIX_EXPORT pmix_status_t pmix_preg_base_parse_nodes(const char *regexp, + char ***names); +PMIX_EXPORT pmix_status_t pmix_preg_base_parse_procs(const char *regexp, + char ***procs); +PMIX_EXPORT pmix_status_t pmix_preg_base_resolve_peers(const char *nodename, + const char *nspace, + pmix_proc_t **procs, size_t *nprocs); +PMIX_EXPORT pmix_status_t pmix_preg_base_resolve_nodes(const char *nspace, + char **nodelist); + + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_frame.c b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_frame.c new file mode 100644 index 0000000000..dbf551ea64 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_frame.c @@ -0,0 +1,115 @@ +/* -*- Mode: C; c-basic-offset:4 ; -*- */ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2009 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** @file: + * + */ +#include + +#include + +#ifdef HAVE_STRING_H +#include +#endif + +#include "src/class/pmix_list.h" +#include "src/mca/base/base.h" +#include "src/mca/preg/base/base.h" + +/* + * The following file was created by configure. It contains extern + * statements and the definition of an array of pointers to each + * component's public mca_base_component_t struct. + */ + +#include "src/mca/preg/base/static-components.h" + +/* Instantiate the global vars */ +pmix_preg_globals_t pmix_preg_globals = {{{0}}}; +pmix_preg_module_t pmix_preg = { + .generate_node_regex = pmix_preg_base_generate_node_regex, + .generate_ppn = pmix_preg_base_generate_ppn, + .parse_nodes = pmix_preg_base_parse_nodes, + .parse_procs = pmix_preg_base_parse_procs, + .resolve_peers = pmix_preg_base_resolve_peers, + .resolve_nodes = pmix_preg_base_resolve_nodes +}; + +static pmix_status_t pmix_preg_close(void) +{ + if (!pmix_preg_globals.initialized) { + return PMIX_SUCCESS; + } + pmix_preg_globals.initialized = false; + + PMIX_LIST_DESTRUCT(&pmix_preg_globals.actives); + + return pmix_mca_base_framework_components_close(&pmix_preg_base_framework, NULL); +} + +static pmix_status_t pmix_preg_open(pmix_mca_base_open_flag_t flags) +{ + /* initialize globals */ + pmix_preg_globals.initialized = true; + PMIX_CONSTRUCT(&pmix_preg_globals.actives, pmix_list_t); + + /* Open up all available components */ + return pmix_mca_base_framework_components_open(&pmix_preg_base_framework, flags); +} + +PMIX_MCA_BASE_FRAMEWORK_DECLARE(pmix, preg, "PMIx Regex Operations", + NULL, pmix_preg_open, pmix_preg_close, + mca_preg_base_static_components, 0); + +PMIX_CLASS_INSTANCE(pmix_preg_base_active_module_t, + pmix_list_item_t, + NULL, NULL); + +static void rcon(pmix_regex_range_t *p) +{ + p->start = 0; + p->cnt = 0; +} +PMIX_CLASS_INSTANCE(pmix_regex_range_t, + pmix_list_item_t, + rcon, NULL); + +static void rvcon(pmix_regex_value_t *p) +{ + p->prefix = NULL; + p->suffix = NULL; + p->num_digits = 0; + PMIX_CONSTRUCT(&p->ranges, pmix_list_t); +} +static void rvdes(pmix_regex_value_t *p) +{ + if (NULL != p->prefix) { + free(p->prefix); + } + if (NULL != p->suffix) { + free(p->suffix); + } + PMIX_LIST_DESTRUCT(&p->ranges); +} +PMIX_CLASS_INSTANCE(pmix_regex_value_t, + pmix_list_item_t, + rvcon, rvdes); diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_select.c b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_select.c new file mode 100644 index 0000000000..fd9ccd0e49 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_select.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include +#include + +#include + +#include "src/mca/mca.h" +#include "src/mca/base/base.h" + +#include "src/mca/preg/base/base.h" + +static bool selected = false; + +/* Function for selecting a prioritized list of components + * from all those that are available. */ +int pmix_preg_base_select(void) +{ + pmix_mca_base_component_list_item_t *cli = NULL; + pmix_mca_base_component_t *component = NULL; + pmix_mca_base_module_t *module = NULL; + pmix_preg_module_t *nmodule; + pmix_preg_base_active_module_t *newmodule, *mod; + int rc, priority; + bool inserted; + + if (selected) { + /* ensure we don't do this twice */ + return PMIX_SUCCESS; + } + selected = true; + + /* Query all available components and ask if they have a module */ + PMIX_LIST_FOREACH(cli, &pmix_preg_base_framework.framework_components, pmix_mca_base_component_list_item_t) { + component = (pmix_mca_base_component_t *) cli->cli_component; + + pmix_output_verbose(5, pmix_preg_base_framework.framework_output, + "mca:preg:select: checking available component %s", component->pmix_mca_component_name); + + /* If there's no query function, skip it */ + if (NULL == component->pmix_mca_query_component) { + pmix_output_verbose(5, pmix_preg_base_framework.framework_output, + "mca:preg:select: Skipping component [%s]. It does not implement a query function", + component->pmix_mca_component_name ); + continue; + } + + /* Query the component */ + pmix_output_verbose(5, pmix_preg_base_framework.framework_output, + "mca:preg:select: Querying component [%s]", + component->pmix_mca_component_name); + rc = component->pmix_mca_query_component(&module, &priority); + + /* If no module was returned, then skip component */ + if (PMIX_SUCCESS != rc || NULL == module) { + pmix_output_verbose(5, pmix_preg_base_framework.framework_output, + "mca:preg:select: Skipping component [%s]. Query failed to return a module", + component->pmix_mca_component_name ); + continue; + } + + /* If we got a module, keep it */ + nmodule = (pmix_preg_module_t*) module; + /* add to the list of selected modules */ + newmodule = PMIX_NEW(pmix_preg_base_active_module_t); + newmodule->pri = priority; + newmodule->module = nmodule; + newmodule->component = (pmix_mca_base_component_t*)cli->cli_component; + + /* maintain priority order */ + inserted = false; + PMIX_LIST_FOREACH(mod, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) { + if (priority > mod->pri) { + pmix_list_insert_pos(&pmix_preg_globals.actives, + (pmix_list_item_t*)mod, &newmodule->super); + inserted = true; + break; + } + } + if (!inserted) { + /* must be lowest priority - add to end */ + pmix_list_append(&pmix_preg_globals.actives, &newmodule->super); + } + } + + if (4 < pmix_output_get_verbosity(pmix_preg_base_framework.framework_output)) { + pmix_output(0, "Final preg priorities"); + /* show the prioritized list */ + PMIX_LIST_FOREACH(mod, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) { + pmix_output(0, "\tpreg: %s Priority: %d", mod->component->pmix_mca_component_name, mod->pri); + } + } + + return PMIX_SUCCESS;; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_stubs.c b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_stubs.c new file mode 100644 index 0000000000..5fe85bf433 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/base/preg_base_stubs.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/include/pmix_globals.h" + +#include "src/mca/preg/base/base.h" + +pmix_status_t pmix_preg_base_generate_node_regex(const char *input, + char **regex) +{ + pmix_preg_base_active_module_t *active; + + PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) { + if (NULL != active->module->generate_node_regex) { + if (PMIX_SUCCESS == active->module->generate_node_regex(input, regex)) { + return PMIX_SUCCESS; + } + } + } + + return PMIX_ERR_NOT_SUPPORTED; +} + +pmix_status_t pmix_preg_base_generate_ppn(const char *input, + char **ppn) +{ + pmix_preg_base_active_module_t *active; + + PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) { + if (NULL != active->module->generate_ppn) { + if (PMIX_SUCCESS == active->module->generate_ppn(input, ppn)) { + return PMIX_SUCCESS; + } + } + } + + return PMIX_ERR_NOT_SUPPORTED; +} + +pmix_status_t pmix_preg_base_parse_nodes(const char *regexp, + char ***names) +{ + pmix_preg_base_active_module_t *active; + + PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) { + if (NULL != active->module->parse_nodes) { + if (PMIX_SUCCESS == active->module->parse_nodes(regexp, names)) { + return PMIX_SUCCESS; + } + } + } + + return PMIX_ERR_NOT_SUPPORTED; +} + +pmix_status_t pmix_preg_base_parse_procs(const char *regexp, + char ***procs) +{ + pmix_preg_base_active_module_t *active; + + PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) { + if (NULL != active->module->parse_procs) { + if (PMIX_SUCCESS == active->module->parse_procs(regexp, procs)) { + return PMIX_SUCCESS; + } + } + } + + return PMIX_ERR_NOT_SUPPORTED; +} + +pmix_status_t pmix_preg_base_resolve_peers(const char *nodename, + const char *nspace, + pmix_proc_t **procs, size_t *nprocs) +{ + pmix_preg_base_active_module_t *active; + + PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) { + if (NULL != active->module->resolve_peers) { + if (PMIX_SUCCESS == active->module->resolve_peers(nodename, nspace, procs, nprocs)) { + return PMIX_SUCCESS; + } + } + } + + return PMIX_ERR_NOT_SUPPORTED; +} + +pmix_status_t pmix_preg_base_resolve_nodes(const char *nspace, + char **nodelist) +{ + pmix_preg_base_active_module_t *active; + + PMIX_LIST_FOREACH(active, &pmix_preg_globals.actives, pmix_preg_base_active_module_t) { + if (NULL != active->module->resolve_nodes) { + if (PMIX_SUCCESS == active->module->resolve_nodes(nspace, nodelist)) { + return PMIX_SUCCESS; + } + } + } + + return PMIX_ERR_NOT_SUPPORTED; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/Makefile.am new file mode 100644 index 0000000000..fa51393622 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/Makefile.am @@ -0,0 +1,50 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers = preg_native.h +sources = \ + preg_native_component.c \ + preg_native.c + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if MCA_BUILD_pmix_preg_native_DSO +lib = +lib_sources = +component = mca_preg_native.la +component_sources = $(headers) $(sources) +else +lib = libmca_preg_native.la +lib_sources = $(headers) $(sources) +component = +component_sources = +endif + +mcacomponentdir = $(pmixlibdir) +mcacomponent_LTLIBRARIES = $(component) +mca_preg_native_la_SOURCES = $(component_sources) +mca_preg_native_la_LDFLAGS = -module -avoid-version + +noinst_LTLIBRARIES = $(lib) +libmca_preg_native_la_SOURCES = $(lib_sources) +libmca_preg_native_la_LDFLAGS = -module -avoid-version diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native.c b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native.c new file mode 100644 index 0000000000..12187b03c2 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native.c @@ -0,0 +1,1079 @@ +/* + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2016 IBM Corporation. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#ifdef HAVE_STRING_H +#include +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + + +#include +#include + +#include "src/include/pmix_socket_errno.h" +#include "src/include/pmix_globals.h" +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/util/output.h" +#include "src/class/pmix_list.h" +#include "src/mca/gds/gds.h" +#include "src/client/pmix_client_ops.h" + +#include "src/mca/preg/preg.h" +#include "preg_native.h" + +static pmix_status_t generate_node_regex(const char *input, + char **regex); +static pmix_status_t generate_ppn(const char *input, + char **ppn); +static pmix_status_t parse_nodes(const char *regexp, + char ***names); +static pmix_status_t parse_procs(const char *regexp, + char ***procs); +static pmix_status_t resolve_peers(const char *nodename, + const char *nspace, + pmix_proc_t **procs, size_t *nprocs); +static pmix_status_t resolve_nodes(const char *nspace, + char **nodelist); + +pmix_preg_module_t pmix_preg_native_module = { + .name = "pmix", + .generate_node_regex = generate_node_regex, + .generate_ppn = generate_ppn, + .parse_nodes = parse_nodes, + .parse_procs = parse_procs, + .resolve_peers = resolve_peers, + .resolve_nodes = resolve_nodes +}; + +static pmix_status_t regex_parse_value_ranges(char *base, char *ranges, + int num_digits, char *suffix, + char ***names); +static pmix_status_t regex_parse_value_range(char *base, char *range, + int num_digits, char *suffix, + char ***names); +static pmix_status_t pmix_regex_extract_nodes(char *regexp, char ***names); +static pmix_status_t pmix_regex_extract_ppn(char *regexp, char ***procs); + + +static pmix_status_t generate_node_regex(const char *input, + char **regexp) +{ + char *vptr, *vsave; + char prefix[PMIX_MAX_NODE_PREFIX]; + int i, j, len, startnum, vnum, numdigits; + bool found, fullval; + char *suffix, *sfx; + pmix_regex_value_t *vreg; + pmix_regex_range_t *range; + pmix_list_t vids; + char **regexargs = NULL, *tmp, *tmp2; + char *cptr; + + /* define the default */ + *regexp = NULL; + + /* setup the list of results */ + PMIX_CONSTRUCT(&vids, pmix_list_t); + + /* cycle thru the array of input values - first copy + * it so we don't overwrite what we were given*/ + vsave = strdup(input); + vptr = vsave; + while (NULL != (cptr = strchr(vptr, ',')) || 0 < strlen(vptr)) { + if (NULL != cptr) { + *cptr = '\0'; + } + /* determine this node's prefix by looking for first non-alpha char */ + fullval = false; + len = strlen(vptr); + startnum = -1; + memset(prefix, 0, PMIX_MAX_NODE_PREFIX); + numdigits = 0; + for (i=0, j=0; i < len; i++) { + if (!isalpha(vptr[i])) { + /* found a non-alpha char */ + if (!isdigit(vptr[i])) { + /* if it is anything but a digit, we just use + * the entire name + */ + fullval = true; + break; + } + /* count the size of the numeric field - but don't + * add the digits to the prefix + */ + numdigits++; + if (startnum < 0) { + /* okay, this defines end of the prefix */ + startnum = i; + } + continue; + } + if (startnum < 0) { + prefix[j++] = vptr[i]; + } + } + if (fullval || startnum < 0) { + /* can't compress this name - just add it to the list */ + vreg = PMIX_NEW(pmix_regex_value_t); + vreg->prefix = strdup(vptr); + pmix_list_append(&vids, &vreg->super); + /* move to the next posn */ + if (NULL == cptr) { + break; + } + vptr = cptr + 1; + continue; + } + /* convert the digits and get any suffix */ + vnum = strtol(&vptr[startnum], &sfx, 10); + if (NULL != sfx) { + suffix = strdup(sfx); + } else { + suffix = NULL; + } + /* is this value already on our list? */ + found = false; + PMIX_LIST_FOREACH(vreg, &vids, pmix_regex_value_t) { + if (0 < strlen(prefix) && NULL == vreg->prefix) { + continue; + } + if (0 == strlen(prefix) && NULL != vreg->prefix) { + continue; + } + if (0 < strlen(prefix) && NULL != vreg->prefix + && 0 != strcmp(prefix, vreg->prefix)) { + continue; + } + if (NULL == suffix && NULL != vreg->suffix) { + continue; + } + if (NULL != suffix && NULL == vreg->suffix) { + continue; + } + if (NULL != suffix && NULL != vreg->suffix && + 0 != strcmp(suffix, vreg->suffix)) { + continue; + } + if (numdigits != vreg->num_digits) { + continue; + } + /* found a match - flag it */ + found = true; + /* get the last range on this nodeid - we do this + * to preserve order + */ + range = (pmix_regex_range_t*)pmix_list_get_last(&vreg->ranges); + if (NULL == range) { + /* first range for this value */ + range = PMIX_NEW(pmix_regex_range_t); + range->start = vnum; + range->cnt = 1; + pmix_list_append(&vreg->ranges, &range->super); + break; + } + /* see if the value is out of sequence */ + if (vnum != (range->start + range->cnt)) { + /* start a new range */ + range = PMIX_NEW(pmix_regex_range_t); + range->start = vnum; + range->cnt = 1; + pmix_list_append(&vreg->ranges, &range->super); + break; + } + /* everything matches - just increment the cnt */ + range->cnt++; + break; + } + if (!found) { + /* need to add it */ + vreg = PMIX_NEW(pmix_regex_value_t); + if (0 < strlen(prefix)) { + vreg->prefix = strdup(prefix); + } + if (NULL != suffix) { + vreg->suffix = strdup(suffix); + } + vreg->num_digits = numdigits; + pmix_list_append(&vids, &vreg->super); + /* record the first range for this value - we took + * care of values we can't compress above + */ + range = PMIX_NEW(pmix_regex_range_t); + range->start = vnum; + range->cnt = 1; + pmix_list_append(&vreg->ranges, &range->super); + } + if (NULL != suffix) { + free(suffix); + } + /* move to the next posn */ + if (NULL == cptr) { + break; + } + vptr = cptr + 1; + } + free(vsave); + + /* begin constructing the regular expression */ + while (NULL != (vreg = (pmix_regex_value_t*)pmix_list_remove_first(&vids))) { + /* if no ranges, then just add the name */ + if (0 == pmix_list_get_size(&vreg->ranges)) { + if (NULL != vreg->prefix) { + pmix_argv_append_nosize(®exargs, vreg->prefix); + } + PMIX_RELEASE(vreg); + continue; + } + /* start the regex for this value with the prefix */ + if (NULL != vreg->prefix) { + if (0 > asprintf(&tmp, "%s[%d:", vreg->prefix, vreg->num_digits)) { + return PMIX_ERR_NOMEM; + } + } else { + if (0 > asprintf(&tmp, "[%d:", vreg->num_digits)) { + return PMIX_ERR_NOMEM; + } + } + /* add the ranges */ + while (NULL != (range = (pmix_regex_range_t*)pmix_list_remove_first(&vreg->ranges))) { + if (1 == range->cnt) { + if (0 > asprintf(&tmp2, "%s%d,", tmp, range->start)) { + return PMIX_ERR_NOMEM; + } + } else { + if (0 > asprintf(&tmp2, "%s%d-%d,", tmp, range->start, range->start + range->cnt - 1)) { + return PMIX_ERR_NOMEM; + } + } + free(tmp); + tmp = tmp2; + PMIX_RELEASE(range); + } + /* replace the final comma */ + tmp[strlen(tmp)-1] = ']'; + if (NULL != vreg->suffix) { + /* add in the suffix, if provided */ + if (0 > asprintf(&tmp2, "%s%s", tmp, vreg->suffix)) { + return PMIX_ERR_NOMEM; + } + free(tmp); + tmp = tmp2; + } + pmix_argv_append_nosize(®exargs, tmp); + free(tmp); + PMIX_RELEASE(vreg); + } + + /* assemble final result */ + tmp = pmix_argv_join(regexargs, ','); + if (0 > asprintf(regexp, "pmix[%s]", tmp)) { + return PMIX_ERR_NOMEM; + } + free(tmp); + + /* cleanup */ + pmix_argv_free(regexargs); + + PMIX_DESTRUCT(&vids); + return PMIX_SUCCESS; +} + +static pmix_status_t generate_ppn(const char *input, + char **regexp) +{ + char **ppn, **npn; + int i, j, start, end; + pmix_regex_value_t *vreg; + pmix_regex_range_t *rng; + pmix_list_t nodes; + char *tmp, *tmp2; + char *cptr; + + /* define the default */ + *regexp = NULL; + + /* setup the list of results */ + PMIX_CONSTRUCT(&nodes, pmix_list_t); + + /* split the input by node */ + ppn = pmix_argv_split(input, ';'); + + /* for each node, split the input by comma */ + for (i=0; NULL != ppn[i]; i++) { + rng = NULL; + /* create a record for this node */ + vreg = PMIX_NEW(pmix_regex_value_t); + pmix_list_append(&nodes, &vreg->super); + /* split the input for this node */ + npn = pmix_argv_split(ppn[i], ','); + /* look at each element */ + for (j=0; NULL != npn[j]; j++) { + /* is this a range? */ + if (NULL != (cptr = strchr(npn[j], '-'))) { + /* terminate the string */ + *cptr = '\0'; + ++cptr; + start = strtol(npn[j], NULL, 10); + end = strtol(cptr, NULL, 10); + /* are we collecting a range? */ + if (NULL == rng) { + /* no - better start one */ + rng = PMIX_NEW(pmix_regex_range_t); + rng->start = start; + rng->cnt = end - start + 1; + pmix_list_append(&vreg->ranges, &rng->super); + } else { + /* is this a continuation of the current range? */ + if (start == (rng->start + rng->cnt)) { + /* just add it to the end of this range */ + rng->cnt++; + } else { + /* nope, there is a break - create new range */ + rng = PMIX_NEW(pmix_regex_range_t); + rng->start = start; + rng->cnt = end - start + 1; + pmix_list_append(&vreg->ranges, &rng->super); + } + } + } else { + /* single rank given */ + start = strtol(npn[j], NULL, 10); + /* are we collecting a range? */ + if (NULL == rng) { + /* no - better start one */ + rng = PMIX_NEW(pmix_regex_range_t); + rng->start = start; + rng->cnt = 1; + pmix_list_append(&vreg->ranges, &rng->super); + } else { + /* is this a continuation of the current range? */ + if (start == (rng->start + rng->cnt)) { + /* just add it to the end of this range */ + rng->cnt++; + } else { + /* nope, there is a break - create new range */ + rng = PMIX_NEW(pmix_regex_range_t); + rng->start = start; + rng->cnt = 1; + pmix_list_append(&vreg->ranges, &rng->super); + } + } + } + } + pmix_argv_free(npn); + } + pmix_argv_free(ppn); + + + /* begin constructing the regular expression */ + tmp = strdup("pmix["); + PMIX_LIST_FOREACH(vreg, &nodes, pmix_regex_value_t) { + while (NULL != (rng = (pmix_regex_range_t*)pmix_list_remove_first(&vreg->ranges))) { + if (1 == rng->cnt) { + if (0 > asprintf(&tmp2, "%s%d,", tmp, rng->start)) { + return PMIX_ERR_NOMEM; + } + } else { + if (0 > asprintf(&tmp2, "%s%d-%d,", tmp, rng->start, rng->start + rng->cnt - 1)) { + return PMIX_ERR_NOMEM; + } + } + free(tmp); + tmp = tmp2; + PMIX_RELEASE(rng); + } + /* replace the final comma */ + tmp[strlen(tmp)-1] = ';'; + } + + /* replace the final semi-colon */ + tmp[strlen(tmp)-1] = ']'; + + /* assemble final result */ + *regexp = tmp; + + PMIX_LIST_DESTRUCT(&nodes); + return PMIX_SUCCESS; +} + +static pmix_status_t parse_nodes(const char *regexp, + char ***names) +{ + char *tmp, *ptr; + pmix_status_t rc; + + /* set default */ + *names = NULL; + + /* protect against bozo */ + if (NULL == regexp) { + return PMIX_SUCCESS; + } + + /* protect the input string */ + tmp = strdup(regexp); + /* strip the trailing bracket */ + tmp[strlen(tmp)-1] = '\0'; + + /* the regex generator used to create this regex + * is tagged at the beginning of the string */ + if (NULL == (ptr = strchr(tmp, '['))) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + free(tmp); + return PMIX_ERR_BAD_PARAM; + } + *ptr = '\0'; + ++ptr; + + /* if it was done by PMIx, use that parser */ + if (0 == strcmp(tmp, "pmix")) { + if (PMIX_SUCCESS != (rc = pmix_regex_extract_nodes(ptr, names))) { + PMIX_ERROR_LOG(rc); + } + } else { + /* this isn't an error - let someone else try */ + rc = PMIX_ERR_TAKE_NEXT_OPTION; + } + free(tmp); + return rc; + +} +static pmix_status_t parse_procs(const char *regexp, + char ***procs) +{ + char *tmp, *ptr; + pmix_status_t rc; + + /* set default */ + *procs = NULL; + + /* protect against bozo */ + if (NULL == regexp) { + return PMIX_SUCCESS; + } + + /* protect the input string */ + tmp = strdup(regexp); + /* strip the trailing bracket */ + tmp[strlen(tmp)-1] = '\0'; + + /* the regex generator used to create this regex + * is tagged at the beginning of the string */ + if (NULL == (ptr = strchr(tmp, '['))) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + free(tmp); + return PMIX_ERR_BAD_PARAM; + } + *ptr = '\0'; + ++ptr; + + /* if it was done by PMIx, use that parser */ + if (0 == strcmp(tmp, "pmix")) { + if (PMIX_SUCCESS != (rc = pmix_regex_extract_ppn(ptr, procs))) { + PMIX_ERROR_LOG(rc); + } + } else { + /* this isn't an error - let someone else try */ + rc = PMIX_ERR_TAKE_NEXT_OPTION; + } + free(tmp); + return rc; +} + +static void _resolve_peers(int sd, short args, void *cbdata) +{ + pmix_cb_t *cb = (pmix_cb_t*)cbdata; + pmix_status_t rc; + pmix_kval_t *kv; + pmix_proc_t proc; + char **ptr; + pmix_info_t *info; + pmix_proc_t *procs; + size_t ninfo, nprocs, n, j; + + /* this data isn't going anywhere, so we don't require a copy */ + cb->copy = false; + /* scope is irrelevant as the info we seek must be local */ + cb->scope = PMIX_SCOPE_UNDEF; + /* let the proc point to the nspace */ + (void)strncpy(proc.nspace, cb->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = PMIX_RANK_WILDCARD; + cb->proc = &proc; + + PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, cb); + if (PMIX_SUCCESS != rc) { + if (PMIX_ERR_INVALID_NAMESPACE != rc) { + PMIX_ERROR_LOG(rc); + } + goto complete; + } + /* should just be the one value on the list */ + if (1 != pmix_list_get_size(&cb->kvs)) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + rc = PMIX_ERR_BAD_PARAM; + goto complete; + } + kv = (pmix_kval_t*)pmix_list_get_first(&cb->kvs); + /* the hostname used as a key with wildcard rank will return + * a pmix_data_array_t of pmix_info_t structs */ + if (NULL == kv->value || + PMIX_DATA_ARRAY != kv->value->type || + NULL == kv->value->data.darray || + PMIX_INFO != kv->value->data.darray->type) { + PMIX_ERROR_LOG(PMIX_ERR_DATA_VALUE_NOT_FOUND); + rc = PMIX_ERR_DATA_VALUE_NOT_FOUND; + goto complete; + } + info = (pmix_info_t*)kv->value->data.darray->array; + ninfo = kv->value->data.darray->size; + /* find the PMIX_LOCAL_PEERS key */ + for (n=0; n < ninfo; n++) { + if (0 == strncmp(info[n].key, PMIX_LOCAL_PEERS, PMIX_MAX_KEYLEN)) { + /* split the string */ + ptr = pmix_argv_split(info[n].value.data.string, ','); + nprocs = pmix_argv_count(ptr); + PMIX_PROC_CREATE(procs, nprocs); + if (NULL == procs) { + rc = PMIX_ERR_NOMEM; + pmix_argv_free(ptr); + goto complete; + } + for (j=0; j < nprocs; j++) { + (void)strncpy(procs[j].nspace, cb->pname.nspace, PMIX_MAX_NSLEN); + procs[j].rank = strtoul(ptr[j], NULL, 10); + } + cb->procs = procs; + cb->nprocs = nprocs; + rc = PMIX_SUCCESS; + pmix_argv_free(ptr); + goto complete; + } + } + + complete: + cb->status = rc; + if (NULL != cb->info) { + PMIX_INFO_FREE(cb->info, cb->ninfo); + } + cb->pstatus = rc; + /* post the data so the receiving thread can acquire it */ + PMIX_POST_OBJECT(cb); + PMIX_WAKEUP_THREAD(&cb->lock); + return; +} + +static pmix_status_t resolve_peers(const char *nodename, + const char *nspace, + pmix_proc_t **procs, size_t *nprocs) +{ + pmix_cb_t *cb; + pmix_status_t rc; + pmix_proc_t proc; + + cb = PMIX_NEW(pmix_cb_t); + cb->key = (char*)nodename; + cb->pname.nspace = strdup(nspace); + + PMIX_THREADSHIFT(cb, _resolve_peers); + + /* wait for the result */ + PMIX_WAIT_THREAD(&cb->lock); + + /* if the nspace wasn't found, then we need to + * ask the server for that info */ + if (PMIX_ERR_INVALID_NAMESPACE == cb->status) { + (void)strncpy(proc.nspace, nspace, PMIX_MAX_NSLEN); + proc.rank = PMIX_RANK_WILDCARD; + /* any key will suffice as it will bring down + * the entire data blob */ + rc = PMIx_Get(&proc, PMIX_UNIV_SIZE, NULL, 0, NULL); + if (PMIX_SUCCESS != rc) { + PMIX_RELEASE(cb); + return rc; + } + /* retry the fetch */ + cb->lock.active = true; + PMIX_THREADSHIFT(cb, _resolve_peers); + PMIX_WAIT_THREAD(&cb->lock); + } + *procs = cb->procs; + *nprocs = cb->nprocs; + + rc = cb->status; + PMIX_RELEASE(cb); + return rc; +} + +static void _resolve_nodes(int sd, short args, void *cbdata) +{ + pmix_cb_t *cb = (pmix_cb_t*)cbdata; + pmix_status_t rc; + pmix_kval_t *kv; + pmix_proc_t proc; + + /* create a pmix_info_t so we can pass the nspace + * into the fetch as a qualifier */ + PMIX_INFO_CREATE(cb->info, 1); + if (NULL == cb->info) { + cb->status = PMIX_ERR_NOMEM; + PMIX_POST_OBJECT(cb); + PMIX_WAKEUP_THREAD(&cb->lock); + return; + } + cb->ninfo = 1; + PMIX_INFO_LOAD(&cb->info[0], PMIX_NSPACE, cb->pname.nspace, PMIX_STRING); + /* tell the GDS what we want */ + cb->key = PMIX_NODE_LIST; + /* this data isn't going anywhere, so we don't require a copy */ + cb->copy = false; + /* scope is irrelevant as the info we seek must be local */ + cb->scope = PMIX_SCOPE_UNDEF; + /* put the nspace in the proc field */ + (void)strncpy(proc.nspace, cb->pname.nspace, PMIX_MAX_NSLEN); + /* the info will be associated with PMIX_RANK_WILDCARD */ + proc.rank = PMIX_RANK_WILDCARD; + cb->proc = &proc; + + PMIX_GDS_FETCH_KV(rc, pmix_client_globals.myserver, cb); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + goto complete; + } + /* should just be the one value on the list */ + if (1 != pmix_list_get_size(&cb->kvs)) { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + rc = PMIX_ERR_BAD_PARAM; + goto complete; + } + kv = (pmix_kval_t*)pmix_list_get_first(&cb->kvs); + /* the PMIX_NODE_LIST key is supposed to return a comma-delimited + * string of nodes in this - check that it did */ + if (NULL == kv->value || + PMIX_STRING != kv->value->type) { + PMIX_ERROR_LOG(PMIX_ERR_DATA_VALUE_NOT_FOUND); + rc = PMIX_ERR_DATA_VALUE_NOT_FOUND; + goto complete; + } + /* return the string */ + if (NULL != kv->value->data.string) { + cb->key = strdup(kv->value->data.string); + } + + complete: + cb->status = rc; + if (NULL != cb->info) { + PMIX_INFO_FREE(cb->info, cb->ninfo); + } + /* post the data so the receiving thread can acquire it */ + PMIX_POST_OBJECT(cb); + PMIX_WAKEUP_THREAD(&cb->lock); + return; +} + +static pmix_status_t resolve_nodes(const char *nspace, + char **nodelist) +{ + pmix_cb_t *cb; + pmix_status_t rc; + pmix_proc_t proc; + + cb = PMIX_NEW(pmix_cb_t); + cb->pname.nspace = (char*)nspace; + + PMIX_THREADSHIFT(cb, _resolve_nodes); + + /* wait for the result */ + PMIX_WAIT_THREAD(&cb->lock); + + /* if the nspace wasn't found, then we need to + * ask the server for that info */ + if (PMIX_ERR_INVALID_NAMESPACE == cb->status) { + (void)strncpy(proc.nspace, nspace, PMIX_MAX_NSLEN); + proc.rank = PMIX_RANK_WILDCARD; + /* any key will suffice as it will bring down + * the entire data blob */ + rc = PMIx_Get(&proc, PMIX_UNIV_SIZE, NULL, 0, NULL); + if (PMIX_SUCCESS != rc) { + PMIX_RELEASE(cb); + return rc; + } + /* retry the fetch */ + cb->lock.active = true; + PMIX_THREADSHIFT(cb, _resolve_nodes); + PMIX_WAIT_THREAD(&cb->lock); + } + /* the string we want is in the key field */ + *nodelist = cb->key; + + rc = cb->status; + PMIX_RELEASE(cb); + return rc; + +} + +static pmix_status_t pmix_regex_extract_nodes(char *regexp, char ***names) +{ + int i, j, k, len; + pmix_status_t ret; + char *base; + char *orig, *suffix; + bool found_range = false; + bool more_to_come = false; + int num_digits; + + /* set the default */ + *names = NULL; + + if (NULL == regexp) { + return PMIX_SUCCESS; + } + + orig = base = strdup(regexp); + if (NULL == base) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, + "pmix:extract:nodes: checking list: %s", regexp)); + + do { + /* Find the base */ + len = strlen(base); + for (i = 0; i <= len; ++i) { + if (base[i] == '[') { + /* we found a range. this gets dealt with below */ + base[i] = '\0'; + found_range = true; + break; + } + if (base[i] == ',') { + /* we found a singleton value, and there are more to come */ + base[i] = '\0'; + found_range = false; + more_to_come = true; + break; + } + if (base[i] == '\0') { + /* we found a singleton value */ + found_range = false; + more_to_come = false; + break; + } + } + if (i == 0 && !found_range) { + /* we found a special character at the beginning of the string */ + free(orig); + return PMIX_ERR_BAD_PARAM; + } + + if (found_range) { + /* If we found a range, get the number of digits in the numbers */ + i++; /* step over the [ */ + for (j=i; j < len; j++) { + if (base[j] == ':') { + base[j] = '\0'; + break; + } + } + if (j >= len) { + /* we didn't find the number of digits */ + free(orig); + return PMIX_ERR_BAD_PARAM; + } + num_digits = strtol(&base[i], NULL, 10); + i = j + 1; /* step over the : */ + /* now find the end of the range */ + for (j = i; j < len; ++j) { + if (base[j] == ']') { + base[j] = '\0'; + break; + } + } + if (j >= len) { + /* we didn't find the end of the range */ + free(orig); + return PMIX_ERR_BAD_PARAM; + } + /* check for a suffix */ + if (j+1 < len && base[j+1] != ',') { + /* find the next comma, if present */ + for (k=j+1; k < len && base[k] != ','; k++); + if (k < len) { + base[k] = '\0'; + } + suffix = strdup(&base[j+1]); + if (k < len) { + base[k] = ','; + } + j = k-1; + } else { + suffix = NULL; + } + PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, + "regex:extract:nodes: parsing range %s %s %s", + base, base + i, suffix)); + + ret = regex_parse_value_ranges(base, base + i, num_digits, suffix, names); + if (NULL != suffix) { + free(suffix); + } + if (PMIX_SUCCESS != ret) { + free(orig); + return ret; + } + if (j+1 < len && base[j + 1] == ',') { + more_to_come = true; + base = &base[j + 2]; + } else { + more_to_come = false; + } + } else { + /* If we didn't find a range, just add the value */ + if(PMIX_SUCCESS != (ret = pmix_argv_append_nosize(names, base))) { + PMIX_ERROR_LOG(ret); + free(orig); + return ret; + } + /* step over the comma */ + i++; + /* set base equal to the (possible) next base to look at */ + base = &base[i]; + } + } while(more_to_come); + + free(orig); + + /* All done */ + return ret; +} + + +/* + * Parse one or more ranges in a set + * + * @param base The base text of the value name + * @param *ranges A pointer to a range. This can contain multiple ranges + * (i.e. "1-3,10" or "5" or "9,0100-0130,250") + * @param ***names An argv array to add the newly discovered values to + */ +static pmix_status_t regex_parse_value_ranges(char *base, char *ranges, + int num_digits, char *suffix, + char ***names) +{ + int i, len; + pmix_status_t ret; + char *start, *orig; + + /* Look for commas, the separator between ranges */ + + len = strlen(ranges); + for (orig = start = ranges, i = 0; i < len; ++i) { + if (',' == ranges[i]) { + ranges[i] = '\0'; + ret = regex_parse_value_range(base, start, num_digits, suffix, names); + if (PMIX_SUCCESS != ret) { + PMIX_ERROR_LOG(ret); + return ret; + } + start = ranges + i + 1; + } + } + + /* Pick up the last range, if it exists */ + + if (start < orig + len) { + + PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, + "regex:parse:ranges: parse range %s (2)", start)); + + ret = regex_parse_value_range(base, start, num_digits, suffix, names); + if (PMIX_SUCCESS != ret) { + PMIX_ERROR_LOG(ret); + return ret; + } + } + + /* All done */ + return PMIX_SUCCESS; +} + + +/* + * Parse a single range in a set and add the full names of the values + * found to the names argv + * + * @param base The base text of the value name + * @param *ranges A pointer to a single range. (i.e. "1-3" or "5") + * @param ***names An argv array to add the newly discovered values to + */ +static pmix_status_t regex_parse_value_range(char *base, char *range, + int num_digits, char *suffix, + char ***names) +{ + char *str, tmp[132]; + size_t i, k, start, end; + size_t base_len, len; + bool found; + pmix_status_t ret; + + if (NULL == base || NULL == range) { + return PMIX_ERROR; + } + + len = strlen(range); + base_len = strlen(base); + /* Silence compiler warnings; start and end are always assigned + properly, below */ + start = end = 0; + + /* Look for the beginning of the first number */ + + for (found = false, i = 0; i < len; ++i) { + if (isdigit((int) range[i])) { + if (!found) { + start = atoi(range + i); + found = true; + break; + } + } + } + if (!found) { + PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); + return PMIX_ERR_NOT_FOUND; + } + + /* Look for the end of the first number */ + + for (found = false; i < len; ++i) { + if (!isdigit(range[i])) { + break; + } + } + + /* Was there no range, just a single number? */ + + if (i >= len) { + end = start; + found = true; + } else { + /* Nope, there was a range. Look for the beginning of the second + * number + */ + for (; i < len; ++i) { + if (isdigit(range[i])) { + end = strtol(range + i, NULL, 10); + found = true; + break; + } + } + } + if (!found) { + PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); + return PMIX_ERR_NOT_FOUND; + } + + /* Make strings for all values in the range */ + + len = base_len + num_digits + 32; + if (NULL != suffix) { + len += strlen(suffix); + } + str = (char *) malloc(len); + if (NULL == str) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + return PMIX_ERR_OUT_OF_RESOURCE; + } + for (i = start; i <= end; ++i) { + memset(str, 0, len); + strcpy(str, base); + /* we need to zero-pad the digits */ + for (k=0; k < (size_t)num_digits; k++) { + str[k+base_len] = '0'; + } + memset(tmp, 0, 132); + snprintf(tmp, 132, "%lu", (unsigned long)i); + for (k=0; k < strlen(tmp); k++) { + str[base_len + num_digits - k - 1] = tmp[strlen(tmp)-k-1]; + } + /* if there is a suffix, add it */ + if (NULL != suffix) { + strcat(str, suffix); + } + ret = pmix_argv_append_nosize(names, str); + if(PMIX_SUCCESS != ret) { + PMIX_ERROR_LOG(ret); + free(str); + return ret; + } + } + free(str); + + /* All done */ + return PMIX_SUCCESS; +} + +static pmix_status_t pmix_regex_extract_ppn(char *regexp, char ***procs) +{ + char **rngs, **nds, *t, **ps=NULL; + int i, j, k, start, end; + + /* split on semi-colons for nodes */ + nds = pmix_argv_split(regexp, ';'); + for (j=0; NULL != nds[j]; j++) { + /* for each node, split it by comma */ + rngs = pmix_argv_split(nds[j], ','); + /* parse each element */ + for (i=0; NULL != rngs[i]; i++) { + /* look for a range */ + if (NULL == (t = strchr(rngs[i], '-'))) { + /* just one value */ + pmix_argv_append_nosize(&ps, rngs[i]); + } else { + /* handle the range */ + *t = '\0'; + start = strtol(rngs[i], NULL, 10); + ++t; + end = strtol(t, NULL, 10); + for (k=start; k <= end; k++) { + if (0 > asprintf(&t, "%d", k)) { + pmix_argv_free(nds); + pmix_argv_free(rngs); + return PMIX_ERR_NOMEM; + } + pmix_argv_append_nosize(&ps, t); + free(t); + } + } + } + pmix_argv_free(rngs); + /* create the node entry */ + t = pmix_argv_join(ps, ','); + pmix_argv_append_nosize(procs, t); + free(t); + pmix_argv_free(ps); + ps = NULL; + } + + pmix_argv_free(nds); + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native.h b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native.h new file mode 100644 index 0000000000..7f6715a844 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_PREG_NATIVE_H +#define PMIX_PREG_NATIVE_H + +#include + + +#include "src/mca/preg/preg.h" + +BEGIN_C_DECLS + +/* the component must be visible data for the linker to find it */ +PMIX_EXPORT extern pmix_mca_base_component_t mca_preg_native_component; +extern pmix_preg_module_t pmix_preg_native_module; + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native_component.c new file mode 100644 index 0000000000..88a850b343 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/native/preg_native_component.c @@ -0,0 +1,79 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + * These symbols are in a file by themselves to provide nice linker + * semantics. Since linkers generally pull in symbols by object + * files, keeping these symbols as the only symbols in this file + * prevents utility programs such as "ompi_info" from having to import + * entire components just to query their version and parameters. + */ + +#include +#include "pmix_common.h" + + +#include "src/mca/preg/preg.h" +#include "preg_native.h" + +static pmix_status_t component_open(void); +static pmix_status_t component_close(void); +static pmix_status_t component_query(pmix_mca_base_module_t **module, int *priority); + +/* + * Instantiate the public struct with all of our public information + * and pointers to our public functions in it + */ +pmix_mca_base_component_t mca_preg_native_component = { + PMIX_PREG_BASE_VERSION_1_0_0, + + /* Component name and version */ + .pmix_mca_component_name = "native", + PMIX_MCA_BASE_MAKE_VERSION(component, + PMIX_MAJOR_VERSION, + PMIX_MINOR_VERSION, + PMIX_RELEASE_VERSION), + + /* Component open and close functions */ + .pmix_mca_open_component = component_open, + .pmix_mca_close_component = component_close, + .pmix_mca_query_component = component_query, +}; + + +static int component_open(void) +{ + return PMIX_SUCCESS; +} + + +static int component_query(pmix_mca_base_module_t **module, int *priority) +{ + /* we should always be first in priority */ + *priority = 100; + *module = (pmix_mca_base_module_t *)&pmix_preg_native_module; + return PMIX_SUCCESS; +} + + +static int component_close(void) +{ + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/preg.h b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/preg.h new file mode 100644 index 0000000000..e02b512260 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/preg.h @@ -0,0 +1,113 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** + * @file + * + * This interface is for regex support. This is a multi-select framework. + * + * Available plugins may be defined at runtime via the typical MCA parameter + * syntax. + */ + +#ifndef PMIX_PREG_H +#define PMIX_PREG_H + +#include + +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_var.h" +#include "src/mca/base/pmix_mca_base_framework.h" + +#include "src/mca/preg/preg_types.h" + +BEGIN_C_DECLS + +/****** MODULE DEFINITION ******/ + +#define PMIX_MAX_NODE_PREFIX 50 + +/* given a semicolon-separated list of input values, generate + * a regex that can be passed down to a client for parsing. + * The caller is responsible for free'ing the resulting + * string + * + * If values have leading zero's, then that is preserved. + * Example: + * + * Input: odin009;odin010;odin011;odin012;odin017;odin018;thor176 + * + * Output: + * "foo:odin[009-012,017-018],thor176" + * + * Note that the "foo" at the beginning of the regex indicates + * that the "foo" regex component is to be used to parse the + * provided regex. + */ +typedef pmix_status_t (*pmix_preg_base_module_generate_node_regex_fn_t)(const char *input, + char **regex); + +/* The input is expected to consist of a comma-separated list + * of ranges. Thus, an input of: + * "1-4;2-5;8,10,11,12;6,7,9" + * would generate a regex of + * "[pmix:2x(3);8,10-12;6-7,9]" + * + * Note that the "pmix" at the beginning of each regex indicates + * that the PMIx native parser is to be used by the client for + * parsing the provided regex. Other parsers may be supported - see + * the pmix_client.h header for a list. + */ +typedef pmix_status_t (*pmix_preg_base_module_generate_ppn_fn_t)(const char *input, + char **ppn); + + +typedef pmix_status_t (*pmix_preg_base_module_parse_nodes_fn_t)(const char *regexp, + char ***names); + +typedef pmix_status_t (*pmix_preg_base_module_parse_procs_fn_t)(const char *regexp, + char ***procs); + +typedef pmix_status_t (*pmix_preg_base_module_resolve_peers_fn_t)(const char *nodename, + const char *nspace, + pmix_proc_t **procs, size_t *nprocs); + +typedef pmix_status_t (*pmix_preg_base_module_resolve_nodes_fn_t)(const char *nspace, + char **nodelist); + +/** + * Base structure for a PREG module + */ +typedef struct { + char *name; + pmix_preg_base_module_generate_node_regex_fn_t generate_node_regex; + pmix_preg_base_module_generate_ppn_fn_t generate_ppn; + pmix_preg_base_module_parse_nodes_fn_t parse_nodes; + pmix_preg_base_module_parse_procs_fn_t parse_procs; + pmix_preg_base_module_resolve_peers_fn_t resolve_peers; + pmix_preg_base_module_resolve_nodes_fn_t resolve_nodes; +} pmix_preg_module_t; + +/* we just use the standard component definition */ + +PMIX_EXPORT extern pmix_preg_module_t pmix_preg; + +/* + * Macro for use in components that are of type preg + */ +#define PMIX_PREG_BASE_VERSION_1_0_0 \ + PMIX_MCA_BASE_VERSION_1_0_0("preg", 1, 0, 0) + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/preg/preg_types.h b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/preg_types.h new file mode 100644 index 0000000000..95f0c5a2f2 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/preg/preg_types.h @@ -0,0 +1,59 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007-2011 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** + * @file + * + * Buffer management types. + */ + +#ifndef PMIX_MCA_PREG_TYPES_H_ +#define PMIX_MCA_PREG_TYPES_H_ + +#include + + +#include "src/class/pmix_object.h" +#include "src/class/pmix_list.h" + +BEGIN_C_DECLS + +/* these classes are required by the regex code */ +typedef struct { + pmix_list_item_t super; + int start; + int cnt; +} pmix_regex_range_t; +PMIX_CLASS_DECLARATION(pmix_regex_range_t); + +typedef struct { + /* list object */ + pmix_list_item_t super; + char *prefix; + char *suffix; + int num_digits; + pmix_list_t ranges; +} pmix_regex_value_t; +PMIX_CLASS_DECLARATION(pmix_regex_value_t); + +END_C_DECLS + +#endif /* PMIX_PREG_TYPES_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/Makefile.am index ce2cdabab6..dc10f4a08c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/Makefile.include index ac0e6009c6..84e9517d5d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/Makefile.include @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/base.h index fde87baf78..28873caf4a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/base.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/base.h @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -46,14 +46,14 @@ BEGIN_C_DECLS /* * MCA Framework */ -extern pmix_mca_base_framework_t pmix_psec_base_framework; +PMIX_EXPORT extern pmix_mca_base_framework_t pmix_psec_base_framework; /** * PSEC select function * * Cycle across available components and construct the list * of active modules */ -pmix_status_t pmix_psec_base_select(void); +PMIX_EXPORT pmix_status_t pmix_psec_base_select(void); /** * Track an active component / module @@ -78,15 +78,7 @@ typedef struct pmix_psec_globals_t pmix_psec_globals_t; extern pmix_psec_globals_t pmix_psec_globals; PMIX_EXPORT char* pmix_psec_base_get_available_modules(void); -PMIX_EXPORT pmix_status_t pmix_psec_base_assign_module(struct pmix_peer_t *peer, - const char *options); -PMIX_EXPORT pmix_status_t pmix_psec_base_create_cred(struct pmix_peer_t *peer, - pmix_listener_protocol_t protocol, - char **cred, size_t *len); -PMIX_EXPORT pmix_status_t pmix_psec_base_client_handshake(struct pmix_peer_t *peer, int sd); -PMIX_EXPORT pmix_status_t pmix_psec_base_validate_connection(struct pmix_peer_t *peer, - pmix_listener_protocol_t protocol, - char *cred, size_t len); +PMIX_EXPORT pmix_psec_module_t* pmix_psec_base_assign_module(const char *options); END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_fns.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_fns.c index 93ad018501..64e875b16b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_fns.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_fns.c @@ -1,6 +1,6 @@ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. * All rights reserved. * @@ -44,17 +44,15 @@ char* pmix_psec_base_get_available_modules(void) return reply; } -pmix_status_t pmix_psec_base_assign_module(struct pmix_peer_t *peer, - const char *options) +pmix_psec_module_t* pmix_psec_base_assign_module(const char *options) { - pmix_peer_t *pr = (pmix_peer_t*)peer; pmix_psec_base_active_module_t *active; pmix_psec_module_t *mod; char **tmp=NULL; int i; if (!pmix_psec_globals.initialized) { - return PMIX_ERR_INIT; + return NULL; } if (NULL != options) { @@ -64,16 +62,14 @@ pmix_status_t pmix_psec_base_assign_module(struct pmix_peer_t *peer, PMIX_LIST_FOREACH(active, &pmix_psec_globals.actives, pmix_psec_base_active_module_t) { if (NULL == tmp) { if (NULL != (mod = active->component->assign_module())) { - pr->compat.psec = mod; - return PMIX_SUCCESS; + return mod; } } else { for (i=0; NULL != tmp[i]; i++) { if (0 == strcmp(tmp[i], active->component->base.pmix_mca_component_name)) { if (NULL != (mod = active->component->assign_module())) { pmix_argv_free(tmp); - pr->compat.psec = mod; - return PMIX_SUCCESS; + return mod; } } } @@ -84,69 +80,5 @@ pmix_status_t pmix_psec_base_assign_module(struct pmix_peer_t *peer, if (NULL != tmp) { pmix_argv_free(tmp); } - return PMIX_ERR_NOT_AVAILABLE; -} - -pmix_status_t pmix_psec_base_create_cred(struct pmix_peer_t *peer, - pmix_listener_protocol_t protocol, - char **cred, size_t *len) -{ - pmix_peer_t *pr = (pmix_peer_t*)peer; - - if (NULL == pr->compat.psec->create_cred) { - return PMIX_ERR_NOT_SUPPORTED; - } - return pr->compat.psec->create_cred(protocol, cred, len); -} - -pmix_status_t pmix_psec_base_client_handshake(struct pmix_peer_t *peer, int sd) -{ - pmix_peer_t *pr = (pmix_peer_t*)peer; - - if (NULL == pr->compat.psec->client_handshake) { - return PMIX_ERR_NOT_SUPPORTED; - } - return pr->compat.psec->client_handshake(sd); -} - -pmix_status_t pmix_psec_base_validate_connection(struct pmix_peer_t *peer, - pmix_listener_protocol_t protocol, - char *cred, size_t len) -{ - pmix_peer_t *pr = (pmix_peer_t*)peer; - pmix_status_t rc; - - /* if a credential is available, then check it */ - if (NULL != pr->compat.psec->validate_cred) { - if (PMIX_SUCCESS != (rc = pr->compat.psec->validate_cred(peer, protocol, cred, len))) { - pmix_output_verbose(2, pmix_globals.debug_output, - "validation of credential failed: %s", - PMIx_Error_string(rc)); - return rc; - } - pmix_output_verbose(2, pmix_globals.debug_output, - "credential validated"); - /* send them success */ - rc = PMIX_SUCCESS; - if (PMIX_SUCCESS != (rc = pmix_ptl_base_send_blocking(pr->sd, (char*)&rc, sizeof(int)))) { - PMIX_ERROR_LOG(rc); - } - return rc; - } else if (NULL != pr->compat.psec->server_handshake) { - /* execute the handshake if the security mode calls for it */ - pmix_output_verbose(2, pmix_globals.debug_output, - "executing handshake"); - rc = PMIX_ERR_READY_FOR_HANDSHAKE; - if (PMIX_SUCCESS != (rc = pmix_ptl_base_send_blocking(pr->sd, (char*)&rc, sizeof(int)))) { - PMIX_ERROR_LOG(rc); - return rc; - } - if (PMIX_SUCCESS != (rc = pr->compat.psec->server_handshake(peer))) { - PMIX_ERROR_LOG(rc); - } - return rc; - } else { - /* this is not allowed */ - return PMIX_ERR_NOT_SUPPORTED; - } + return NULL; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_frame.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_frame.c index a0ae2e098a..7acd69c5e8 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_frame.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_frame.c @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015-2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -45,13 +45,6 @@ /* Instantiate the global vars */ pmix_psec_globals_t pmix_psec_globals = {{{0}}}; -pmix_psec_API_t pmix_psec = { - .get_available_modules = pmix_psec_base_get_available_modules, - .assign_module = pmix_psec_base_assign_module, - .create_cred = pmix_psec_base_create_cred, - .client_handshake = pmix_psec_base_client_handshake, - .validate_connection = pmix_psec_base_validate_connection -}; static pmix_status_t pmix_psec_close(void) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_select.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_select.c index 73dbeb9095..79e6e54310 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_select.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/base/psec_base_select.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/Makefile.am index a756c8b19d..bcf860ec33 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/configure.m4 index 503bc34f06..26a93ce5a6 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/configure.m4 @@ -1,6 +1,6 @@ # -*- shell-script -*- # -# Copyright (c) 2015-2016 Intel, Inc. All rights reserved +# Copyright (c) 2015-2017 Intel, Inc. All rights reserved. # Copyright (c) 2015 Research Organization for Information Science # and Technology (RIST). All rights reserved. # $COPYRIGHT$ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge.c index fcf7834aab..3d0a533226 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * * NOTE: THE MUNGE CLIENT LIBRARY (libmunge) IS LICENSED AS LGPL * @@ -32,8 +32,9 @@ static pmix_status_t munge_init(void); static void munge_finalize(void); static pmix_status_t create_cred(pmix_listener_protocol_t protocol, char **cred, size_t *len); -static pmix_status_t validate_cred(pmix_listener_protocol_t protocol, - pmix_peer_t *peer, char *cred, size_t len); +static pmix_status_t validate_cred(int sd, uid_t uid, gid_t gid, + pmix_listener_protocol_t protocol, + char *cred, size_t len); pmix_psec_module_t pmix_munge_module = { "munge", @@ -115,18 +116,19 @@ static pmix_status_t create_cred(pmix_listener_protocol_t protocol, return PMIX_SUCCESS; } -static pmix_status_t validate_cred(pmix_listener_protocol_t protocol, - pmix_peer_t *peer, char *cred, size_t len) +static pmix_status_t validate_cred(int sd, uid_t uid, gid_t gid, + pmix_listener_protocol_t protocol, + char *cred, size_t len) { - uid_t uid; - gid_t gid; + uid_t euid; + gid_t egid; munge_err_t rc; pmix_output_verbose(2, pmix_globals.debug_output, "psec: munge validate_cred %s", cred ? cred : "NULL"); /* parse the inbound string */ - if (EMUNGE_SUCCESS != (rc = munge_decode(cred, NULL, NULL, NULL, &uid, &gid))) { + if (EMUNGE_SUCCESS != (rc = munge_decode(cred, NULL, NULL, NULL, &euid, &egid))) { pmix_output_verbose(2, pmix_globals.debug_output, "psec: munge failed to decode credential: %s", munge_strerror(rc)); @@ -134,12 +136,12 @@ static pmix_status_t validate_cred(pmix_listener_protocol_t protocol, } /* check uid */ - if (uid != peer->info->uid) { + if (euid != uid) { return PMIX_ERR_INVALID_CRED; } /* check guid */ - if (gid != peer->info->gid) { + if (egid != gid) { return PMIX_ERR_INVALID_CRED; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge.h b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge.h index ff50bd4918..76d02d73ff 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * * $COPYRIGHT$ * diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge_component.c index c44a5232d0..9204f8ef3b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge_component.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/munge/psec_munge_component.c @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/Makefile.am index 9381d8ad60..18e7dc18c8 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native.c index ebfcb6308f..77b3d2eaf2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native.c @@ -31,7 +31,7 @@ static pmix_status_t native_init(void); static void native_finalize(void); static pmix_status_t create_cred(pmix_listener_protocol_t protocol, char **cred, size_t *len); -static pmix_status_t validate_cred(pmix_peer_t *peer, +static pmix_status_t validate_cred(int sd, uid_t uid, gid_t gid, pmix_listener_protocol_t protocol, char *cred, size_t len); @@ -91,7 +91,7 @@ static pmix_status_t create_cred(pmix_listener_protocol_t protocol, return PMIX_ERR_NOT_SUPPORTED; } -static pmix_status_t validate_cred(pmix_peer_t *peer, +static pmix_status_t validate_cred(int sd, uid_t uid, gid_t gid, pmix_listener_protocol_t protocol, char *cred, size_t len) { @@ -105,7 +105,7 @@ static pmix_status_t validate_cred(pmix_peer_t *peer, socklen_t crlen = sizeof (ucred); #endif uid_t euid; - gid_t gid; + gid_t egid; char *ptr; size_t ln; @@ -118,8 +118,8 @@ static pmix_status_t validate_cred(pmix_peer_t *peer, #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID)) /* Ignore received 'cred' and validate ucred for socket instead. */ pmix_output_verbose(2, pmix_globals.debug_output, - "psec:native checking getsockopt on socket %d for peer credentials", peer->sd); - if (getsockopt (peer->sd, SOL_SOCKET, SO_PEERCRED, &ucred, &crlen) < 0) { + "psec:native checking getsockopt on socket %d for peer credentials", sd); + if (getsockopt (sd, SOL_SOCKET, SO_PEERCRED, &ucred, &crlen) < 0) { pmix_output_verbose(2, pmix_globals.debug_output, "psec: getsockopt SO_PEERCRED failed: %s", strerror (pmix_socket_errno)); @@ -127,16 +127,16 @@ static pmix_status_t validate_cred(pmix_peer_t *peer, } #if defined(HAVE_STRUCT_UCRED_UID) euid = ucred.uid; - gid = ucred.gid; + egid = ucred.gid; #else euid = ucred.cr_uid; - gid = ucred.cr_gid; + egid = ucred.cr_gid; #endif #elif defined(HAVE_GETPEEREID) pmix_output_verbose(2, pmix_globals.debug_output, - "psec:native checking getpeereid on socket %d for peer credentials", peer->sd); - if (0 != getpeereid(peer->sd, &euid, &gid)) { + "psec:native checking getpeereid on socket %d for peer credentials", sd); + if (0 != getpeereid(sd, &euid, &egid)) { pmix_output_verbose(2, pmix_globals.debug_output, "psec: getsockopt getpeereid failed: %s", strerror (pmix_socket_errno)); @@ -147,22 +147,22 @@ static pmix_status_t validate_cred(pmix_peer_t *peer, #endif /* check uid */ - if (euid != peer->info->uid) { + if (euid != uid) { pmix_output_verbose(2, pmix_globals.debug_output, "psec: socket cred contains invalid uid %u", euid); return PMIX_ERR_INVALID_CRED; } /* check gid */ - if (gid != peer->info->gid) { + if (egid != gid) { pmix_output_verbose(2, pmix_globals.debug_output, - "psec: socket cred contains invalid gid %u", gid); + "psec: socket cred contains invalid gid %u", egid); return PMIX_ERR_INVALID_CRED; } pmix_output_verbose(2, pmix_globals.debug_output, "psec: native credential %u:%u valid", - euid, gid); + euid, egid); return PMIX_SUCCESS; } @@ -175,7 +175,7 @@ static pmix_status_t validate_cred(pmix_peer_t *peer, } ln = len; euid = 0; - gid = 0; + egid = 0; if (sizeof(uid_t) <= ln) { memcpy(&euid, cred, sizeof(uid_t)); ln -= sizeof(uid_t); @@ -184,27 +184,27 @@ static pmix_status_t validate_cred(pmix_peer_t *peer, return PMIX_ERR_INVALID_CRED; } if (sizeof(gid_t) <= ln) { - memcpy(&gid, ptr, sizeof(gid_t)); + memcpy(&egid, ptr, sizeof(gid_t)); } else { return PMIX_ERR_INVALID_CRED; } /* check uid */ - if (euid != peer->info->uid) { + if (euid != uid) { pmix_output_verbose(2, pmix_globals.debug_output, "psec: socket cred contains invalid uid %u", euid); return PMIX_ERR_INVALID_CRED; } /* check gid */ - if (gid != peer->info->gid) { + if (egid != gid) { pmix_output_verbose(2, pmix_globals.debug_output, - "psec: socket cred contains invalid gid %u", gid); + "psec: socket cred contains invalid gid %u", egid); return PMIX_ERR_INVALID_CRED; } pmix_output_verbose(2, pmix_globals.debug_output, "psec: native credential %u:%u valid", - euid, gid); + euid, egid); return PMIX_SUCCESS; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native.h b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native.h index 8adf0f8b11..20c63fdd50 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * * $COPYRIGHT$ * diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native_component.c index b392fe201f..037c40299c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native_component.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/native/psec_native_component.c @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/Makefile.am index 7423699637..46a6efc588 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none.c index 5fc22cec04..de0f71d50e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. * * $COPYRIGHT$ @@ -29,7 +29,7 @@ static pmix_status_t none_init(void); static void none_finalize(void); -static pmix_status_t validate_cred(pmix_peer_t *peer, +static pmix_status_t validate_cred(int sd, uid_t uid, gid_t gid, pmix_listener_protocol_t protocol, char *cred, size_t len); @@ -53,7 +53,7 @@ static void none_finalize(void) "psec: none finalize"); } -static pmix_status_t validate_cred(pmix_peer_t *peer, +static pmix_status_t validate_cred(int sd, uid_t uid, gid_t gid, pmix_listener_protocol_t protocol, char *cred, size_t len) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none.h b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none.h index d443c97448..16d199cdcf 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * * $COPYRIGHT$ * diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none_component.c index 17e9035b3a..0b254eaa13 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none_component.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/none/psec_none_component.c @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2015 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/psec.h b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/psec.h index c0cff0b091..0a4f5640ff 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psec/psec.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psec/psec.h @@ -1,7 +1,7 @@ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. @@ -37,9 +37,6 @@ BEGIN_C_DECLS -/*** forward declaration ***/ -struct pmix_peer_t; - /****** MODULE DEFINITION ******/ /** @@ -76,7 +73,7 @@ typedef pmix_status_t (*pmix_psec_base_module_client_hndshk_fn_t)(int sd); * Validate a client's credential - the credential could be a string * or an array of bytes, which is why we include the length */ -typedef pmix_status_t (*pmix_psec_base_module_validate_cred_fn_t)(struct pmix_peer_t *peer, +typedef pmix_status_t (*pmix_psec_base_module_validate_cred_fn_t)(int sd, uid_t uid, gid_t gid, pmix_listener_protocol_t protocol, char *cred, size_t len); @@ -85,7 +82,7 @@ typedef pmix_status_t (*pmix_psec_base_module_validate_cred_fn_t)(struct pmix_pe * (and indeed, would be rare) for a protocol to use both the * credential and handshake interfaces. It is acceptable, therefore, * for one of them to be NULL */ -typedef pmix_status_t (*pmix_psec_base_module_server_hndshk_fn_t)(struct pmix_peer_t *peer); +typedef pmix_status_t (*pmix_psec_base_module_server_hndshk_fn_t)(int sd); /** * Base structure for a PSEC module @@ -108,45 +105,59 @@ typedef struct { /* get a list of available options - caller must free results * when done */ -typedef char* (*pmix_psec_API_get_available_modules_fn_t)(void); +PMIX_EXPORT char* pmix_psec_base_get_available_modules(void); /* Select a psec module for a given peer */ -typedef pmix_status_t (*pmix_psec_API_assign_module_fn_t)(struct pmix_peer_t *peer, - const char *options); +PMIX_EXPORT pmix_psec_module_t* pmix_psec_base_assign_module(const char *options); -/** - * Create and return a string representation of a credential for this - * client - */ -typedef pmix_status_t (*pmix_psec_API_create_cred_fn_t)(struct pmix_peer_t *peer, - pmix_listener_protocol_t protocol, - char **cred, size_t *len); +/* MACROS FOR EXECUTING PSEC FUNCTIONS */ -/** - * Perform the client-side handshake. Note that it is not required - * (and indeed, would be rare) for a protocol to use both the - * credential and handshake interfaces. It is acceptable, therefore, - * for one of them to be NULL */ -typedef pmix_status_t (*pmix_psec_API_client_hndshk_fn_t)(struct pmix_peer_t *peer, int sd); +#define PMIX_PSEC_CREATE_CRED(r, p, pr, c, l) \ + (r) = (p)->nptr->compat.psec->create_cred(pr, c, l) +#define PMIX_PSEC_CLIENT_HANDSHAKE(r, p, sd) \ + (r) = (p)->nptr->compat.psec->client_handshake(sd) -/**** SERVER-SIDE FUNCTIONS ****/ -/** - * Validate a client's connection request - */ -typedef pmix_status_t (*pmix_psec_API_validate_connection_fn_t)(struct pmix_peer_t *peer, - pmix_listener_protocol_t protocol, - char *cred, size_t len); +#define PMIX_PSEC_VALIDATE_CRED(r, p, pr, c, l) \ + (r) = (p)->nptr->compat.psec->validate_cred((p)->sd, (p)->info->uid, (p)->info->gid, pr, c, l) -typedef struct { - pmix_psec_API_get_available_modules_fn_t get_available_modules; - pmix_psec_API_assign_module_fn_t assign_module; - pmix_psec_API_create_cred_fn_t create_cred; - pmix_psec_API_client_hndshk_fn_t client_handshake; - pmix_psec_API_validate_connection_fn_t validate_connection; -} pmix_psec_API_t; - -PMIX_EXPORT extern pmix_psec_API_t pmix_psec; +#define PMIX_PSEC_VALIDATE_CONNECTION(r, p, pr, c, l) \ + do { \ + int _r; \ + /* if a credential is available, then check it */ \ + if (NULL != (p)->nptr->compat.psec->validate_cred) { \ + _r = (p)->nptr->compat.psec->validate_cred((p)->sd, (p)->info->uid, (p)->info->gid, pr, c, l); \ + if (PMIX_SUCCESS != _r) { \ + pmix_output_verbose(2, pmix_globals.debug_output, \ + "validation of credential failed: %s", \ + PMIx_Error_string(_r)); \ + } \ + pmix_output_verbose(2, pmix_globals.debug_output, \ + "credential validated"); \ + /* send them success */ \ + _r = PMIX_SUCCESS; \ + if (PMIX_SUCCESS != (_r = pmix_ptl_base_send_blocking((p)->sd, (char*)&(_r), sizeof(int)))) { \ + PMIX_ERROR_LOG(_r); \ + } \ + (r) = _r; \ + } else if (NULL != (p)->nptr->compat.psec->server_handshake) { \ + /* execute the handshake if the security mode calls for it */ \ + pmix_output_verbose(2, pmix_globals.debug_output, \ + "executing handshake"); \ + _r = PMIX_ERR_READY_FOR_HANDSHAKE; \ + if (PMIX_SUCCESS != (_r = pmix_ptl_base_send_blocking((p)->sd, (char*)&(_r), sizeof(int)))) { \ + PMIX_ERROR_LOG(_r); \ + } else { \ + if (PMIX_SUCCESS != (_r = p->nptr->compat.psec->server_handshake((p)->sd))) { \ + PMIX_ERROR_LOG(_r); \ + } \ + } \ + (r) = _r; \ + } else { \ + /* this is not allowed */ \ + (r) = PMIX_ERR_NOT_SUPPORTED; \ + } \ + } while(0) /**** COMPONENT STRUCTURE DEFINITION ****/ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/file/psensor_file.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/file/psensor_file.c index e93bb88d03..aec018b218 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/file/psensor_file.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/file/psensor_file.c @@ -183,7 +183,7 @@ static pmix_status_t start(pmix_peer_t *requestor, pmix_status_t error, PMIX_OUTPUT_VERBOSE((1, pmix_psensor_base_framework.framework_output, "[%s:%d] checking file monitoring for requestor %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, - requestor->info->nptr->nspace, requestor->info->rank)); + requestor->info->pname.nspace, requestor->info->pname.rank)); /* if they didn't ask to monitor a file, then nothing for us to do */ if (0 != strcmp(monitor->key, PMIX_MONITOR_FILE)) { @@ -343,8 +343,8 @@ static void file_sample(int sd, short args, void *cbdata) /* stop monitoring this client */ pmix_list_remove_item(&mca_psensor_file_component.trackers, &ft->super); /* generate an event */ - (void)strncpy(source.nspace, ft->requestor->info->nptr->nspace, PMIX_MAX_NSLEN); - source.rank = ft->requestor->info->rank; + (void)strncpy(source.nspace, ft->requestor->info->pname.nspace, PMIX_MAX_NSLEN); + source.rank = ft->requestor->info->pname.rank; rc = PMIx_Notify_event(PMIX_MONITOR_FILE_ALERT, &source, ft->range, ft->info, ft->ninfo, opcbfunc, ft); if (PMIX_SUCCESS != rc) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/heartbeat/psensor_heartbeat.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/heartbeat/psensor_heartbeat.c index 3147cfd738..7d363c030b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/heartbeat/psensor_heartbeat.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/heartbeat/psensor_heartbeat.c @@ -172,7 +172,7 @@ static pmix_status_t heartbeat_start(pmix_peer_t *requestor, pmix_status_t error PMIX_OUTPUT_VERBOSE((1, pmix_psensor_base_framework.framework_output, "[%s:%d] checking heartbeat monitoring for requestor %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, - requestor->info->nptr->nspace, requestor->info->rank)); + requestor->info->pname.nspace, requestor->info->pname.rank)); /* if they didn't ask for heartbeats, then nothing for us to do */ if (0 != strcmp(monitor->key, PMIX_MONITOR_HEARTBEAT)) { @@ -272,19 +272,19 @@ static void check_heartbeat(int fd, short dummy, void *cbdata) PMIX_OUTPUT_VERBOSE((1, pmix_psensor_base_framework.framework_output, "[%s:%d] sensor:check_heartbeat for proc %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, - ft->requestor->info->nptr->nspace, ft->requestor->info->rank)); + ft->requestor->info->pname.nspace, ft->requestor->info->pname.rank)); if (0 == ft->nbeats) { /* no heartbeat recvd in last window */ PMIX_OUTPUT_VERBOSE((1, pmix_psensor_base_framework.framework_output, "[%s:%d] sensor:check_heartbeat failed for proc %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, - ft->requestor->info->nptr->nspace, ft->requestor->info->rank)); + ft->requestor->info->pname.nspace, ft->requestor->info->pname.rank)); /* stop monitoring this client */ pmix_list_remove_item(&mca_psensor_heartbeat_component.trackers, &ft->super); /* generate an event */ - (void)strncpy(source.nspace, ft->requestor->info->nptr->nspace, PMIX_MAX_NSLEN); - source.rank = ft->requestor->info->rank; + (void)strncpy(source.nspace, ft->requestor->info->pname.nspace, PMIX_MAX_NSLEN); + source.rank = ft->requestor->info->pname.rank; rc = PMIx_Notify_event(PMIX_MONITOR_HEARTBEAT_ALERT, &source, ft->range, ft->info, ft->ninfo, opcbfunc, ft); if (PMIX_SUCCESS != rc) { @@ -295,7 +295,7 @@ static void check_heartbeat(int fd, short dummy, void *cbdata) PMIX_OUTPUT_VERBOSE((1, pmix_psensor_base_framework.framework_output, "[%s:%d] sensor:check_heartbeat detected %d beats for proc %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, ft->nbeats, - ft->requestor->info->nptr->nspace, ft->requestor->info->rank)); + ft->requestor->info->pname.nspace, ft->requestor->info->pname.rank)); } /* reset for next period */ ft->nbeats = 0; diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/heartbeat/psensor_heartbeat_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/heartbeat/psensor_heartbeat_component.c index e16a26a347..7f6f18f2ff 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/heartbeat/psensor_heartbeat_component.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/psensor/heartbeat/psensor_heartbeat_component.c @@ -50,12 +50,14 @@ pmix_psensor_heartbeat_component_t mca_psensor_heartbeat_component = { */ static int heartbeat_open(void) { + pmix_status_t rc; + PMIX_CONSTRUCT(&mca_psensor_heartbeat_component.trackers, pmix_list_t); /* setup to receive heartbeats */ - pmix_ptl.recv(pmix_globals.mypeer, pmix_psensor_heartbeat_recv_beats, PMIX_PTL_TAG_HEARTBEAT); + PMIX_PTL_RECV(rc, pmix_globals.mypeer, pmix_psensor_heartbeat_recv_beats, PMIX_PTL_TAG_HEARTBEAT); - return PMIX_SUCCESS; + return rc; } @@ -72,10 +74,12 @@ static int heartbeat_query(pmix_mca_base_module_t **module, int *priority) static int heartbeat_close(void) { + pmix_status_t rc; + /* cancel our persistent recv */ - pmix_ptl.cancel(pmix_globals.mypeer, PMIX_PTL_TAG_HEARTBEAT); + PMIX_PTL_CANCEL(rc, pmix_globals.mypeer, PMIX_PTL_TAG_HEARTBEAT); PMIX_LIST_DESTRUCT(&mca_psensor_heartbeat_component.trackers); - return PMIX_SUCCESS; + return rc; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/Makefile.am new file mode 100644 index 0000000000..3934f0c78f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/Makefile.am @@ -0,0 +1,44 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_CPPFLAGS = $(LTDLINCL) + +# main library setup +noinst_LTLIBRARIES = libmca_pshmem.la +libmca_pshmem_la_SOURCES = + +# local files +headers = pshmem.h +sources = + +# Conditionally install the header files +if WANT_INSTALL_HEADERS +pmixdir = $(pmixincludedir)/$(subdir) +nobase_pmix_HEADERS = $(headers) +endif + +include base/Makefile.include + +libmca_pshmem_la_SOURCES += $(headers) $(sources) + +distclean-local: + rm -f base/static-components.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/Makefile.include new file mode 100644 index 0000000000..9c8aa21c4e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/Makefile.include @@ -0,0 +1,31 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from +# src/Makefile.am + +headers += \ + base/base.h + +sources += \ + base/pshmem_base_frame.c \ + base/pshmem_base_select.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/base.h new file mode 100644 index 0000000000..a1c12421ef --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/base.h @@ -0,0 +1,60 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ +#ifndef PMIX_PSHMEM_BASE_H_ +#define PMIX_PSHMEM_BASE_H_ + +#include + + +#ifdef HAVE_SYS_TIME_H +#include /* for struct timeval */ +#endif +#ifdef HAVE_STRING_H +#include +#endif + +#include "src/class/pmix_list.h" +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_framework.h" + +#include "src/mca/pshmem/pshmem.h" + + +BEGIN_C_DECLS + +/* + * MCA Framework + */ +PMIX_EXPORT extern pmix_mca_base_framework_t pmix_pshmem_base_framework; +/** + * PSHMEM select function + * + * Cycle across available components and construct the list + * of active modules + */ +PMIX_EXPORT pmix_status_t pmix_pshmem_base_select(void); + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/pshmem_base_frame.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/pshmem_base_frame.c new file mode 100644 index 0000000000..4c38005da6 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/pshmem_base_frame.c @@ -0,0 +1,72 @@ +/* -*- Mode: C; c-basic-offset:4 ; -*- */ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2009 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** @file: + * + */ +#include + +#include + +#ifdef HAVE_STRING_H +#include +#endif + +#include "src/class/pmix_list.h" +#include "src/mca/base/base.h" +#include "src/mca/pshmem/base/base.h" + +/* + * The following file was created by configure. It contains extern + * statements and the definition of an array of pointers to each + * component's public mca_base_component_t struct. + */ + +#include "src/mca/pshmem/base/static-components.h" + +static bool initialized = false; + +/* Instantiate the global vars */ +pmix_pshmem_base_module_t pmix_pshmem = {0}; + +static pmix_status_t pmix_pshmem_close(void) +{ + if (!initialized) { + return PMIX_SUCCESS; + } + initialized = false; + + return pmix_mca_base_framework_components_close(&pmix_pshmem_base_framework, NULL); +} + +static pmix_status_t pmix_pshmem_open(pmix_mca_base_open_flag_t flags) +{ + /* initialize globals */ + initialized = true; + + /* Open up all available components */ + return pmix_mca_base_framework_components_open(&pmix_pshmem_base_framework, flags); +} + +PMIX_MCA_BASE_FRAMEWORK_DECLARE(pmix, pshmem, "PMIx Shared memory", + NULL, pmix_pshmem_open, pmix_pshmem_close, + mca_pshmem_base_static_components, 0); diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/pshmem_base_select.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/pshmem_base_select.c new file mode 100644 index 0000000000..4b54a60a4c --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/base/pshmem_base_select.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include +#include + +#include + +#include "src/mca/mca.h" +#include "src/mca/base/base.h" + +#include "src/mca/pshmem/base/base.h" + +static bool selected = false; + +/* Function for selecting a prioritized list of components + * from all those that are available. */ +int pmix_pshmem_base_select(void) +{ + pmix_mca_base_component_list_item_t *cli; + pmix_mca_base_component_t *component; + pmix_mca_base_module_t *module; + pmix_pshmem_base_module_t *nmodule; + int rc, priority, best_pri = -1; + bool inserted = false; + + if (selected) { + /* ensure we don't do this twice */ + return PMIX_SUCCESS; + } + selected = true; + + /* Query all available components and ask if they have a module */ + PMIX_LIST_FOREACH(cli, &pmix_pshmem_base_framework.framework_components, pmix_mca_base_component_list_item_t) { + component = (pmix_mca_base_component_t *) cli->cli_component; + + pmix_output_verbose(5, pmix_pshmem_base_framework.framework_output, + "mca:pshmem:select: checking available component %s", component->pmix_mca_component_name); + + /* If there's no query function, skip it */ + if (NULL == component->pmix_mca_query_component) { + pmix_output_verbose(5, pmix_pshmem_base_framework.framework_output, + "mca:pshmem:select: Skipping component [%s]. It does not implement a query function", + component->pmix_mca_component_name ); + continue; + } + + /* Query the component */ + pmix_output_verbose(5, pmix_pshmem_base_framework.framework_output, + "mca:pshmem:select: Querying component [%s]", + component->pmix_mca_component_name); + rc = component->pmix_mca_query_component(&module, &priority); + + /* If no module was returned, then skip component */ + if (PMIX_SUCCESS != rc || NULL == module) { + pmix_output_verbose(5, pmix_pshmem_base_framework.framework_output, + "mca:pshmem:select: Skipping component [%s]. Query failed to return a module", + component->pmix_mca_component_name ); + continue; + } + + /* If we got a module, try to initialize it */ + nmodule = (pmix_pshmem_base_module_t*) module; + if (NULL != nmodule->init && PMIX_SUCCESS != nmodule->init()) { + continue; + } + + /* keep only the highest priority module */ + if (best_pri < priority) { + best_pri = priority; + /* give any prior module a chance to finalize */ + if (NULL != pmix_pshmem.finalize) { + pmix_pshmem.finalize(); + } + pmix_pshmem = *nmodule; + inserted = true; + } + } + + if (!inserted) { + return PMIX_ERR_NOT_FOUND; + } + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/Makefile.am new file mode 100644 index 0000000000..52109f28d2 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/Makefile.am @@ -0,0 +1,43 @@ +# -*- makefile -*- +# +# Copyright (c) 2017 Mellanox Technologies, Inc. +# All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers = \ + pshmem_mmap.h + +sources = \ + pshmem_mmap.c \ + pshmem_mmap_component.c + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if MCA_BUILD_pmix_pshmem_mmap_DSO +lib = +lib_sources = +component = mca_pshmem_mmap.la +component_sources = $(headers) $(sources) +else +lib = libmca_pshmem_mmap.la +lib_sources = $(headers) $(sources) +component = +component_sources = +endif + +mcacomponentdir = $(pmixlibdir) +mcacomponent_LTLIBRARIES = $(component) +mca_pshmem_mmap_la_SOURCES = $(component_sources) +mca_pshmem_mmap_la_LDFLAGS = -module -avoid-version + +noinst_LTLIBRARIES = $(lib) +libmca_pshmem_mmap_la_SOURCES = $(lib_sources) +libmca_pshmem_mmap_la_LDFLAGS = -module -avoid-version diff --git a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap.c similarity index 83% rename from opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.c rename to opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap.c index 157cf4d041..da016b7bd5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap.c @@ -25,29 +25,42 @@ #include #include "src/include/pmix_globals.h" -#include "pmix_sm.h" -#include "pmix_mmap.h" +//#include "pmix_sm.h" +#include +#include "pshmem_mmap.h" #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) # define MAP_ANONYMOUS MAP_ANON #endif /* MAP_ANONYMOUS and MAP_ANON */ +static int _mmap_init(void); +static void _mmap_finalize(void); +static int _mmap_segment_create(pmix_pshmem_seg_t *sm_seg, const char *file_name, size_t size); +static int _mmap_segment_attach(pmix_pshmem_seg_t *sm_seg, pmix_pshmem_access_mode_t sm_mode); +static int _mmap_segment_detach(pmix_pshmem_seg_t *sm_seg); +static int _mmap_segment_unlink(pmix_pshmem_seg_t *sm_seg); -static int _mmap_segment_create(pmix_sm_seg_t *sm_seg, const char *file_name, size_t size); -static int _mmap_segment_attach(pmix_sm_seg_t *sm_seg, pmix_sm_access_mode_t sm_mode); -static int _mmap_segment_detach(pmix_sm_seg_t *sm_seg); -static int _mmap_segment_unlink(pmix_sm_seg_t *sm_seg); - -pmix_sm_base_module_t pmix_sm_mmap_module = { +pmix_pshmem_base_module_t pmix_mmap_module = { "mmap", + _mmap_init, + _mmap_finalize, _mmap_segment_create, _mmap_segment_attach, _mmap_segment_detach, _mmap_segment_unlink }; +static int _mmap_init(void) +{ + return PMIX_SUCCESS; +} -int _mmap_segment_create(pmix_sm_seg_t *sm_seg, const char *file_name, size_t size) +static void _mmap_finalize(void) +{ + ; +} + +static int _mmap_segment_create(pmix_pshmem_seg_t *sm_seg, const char *file_name, size_t size) { int rc = PMIX_SUCCESS; void *seg_addr = MAP_FAILED; @@ -126,12 +139,12 @@ out: return rc; } -int _mmap_segment_attach(pmix_sm_seg_t *sm_seg, pmix_sm_access_mode_t sm_mode) +static int _mmap_segment_attach(pmix_pshmem_seg_t *sm_seg, pmix_pshmem_access_mode_t sm_mode) { mode_t mode = O_RDWR; int mmap_prot = PROT_READ | PROT_WRITE; - if (sm_mode == PMIX_SM_RONLY) { + if (sm_mode == PMIX_PSHMEM_RONLY) { mode = O_RDONLY; mmap_prot = PROT_READ; } @@ -163,7 +176,7 @@ int _mmap_segment_attach(pmix_sm_seg_t *sm_seg, pmix_sm_access_mode_t sm_mode) return PMIX_SUCCESS; } -int _mmap_segment_detach(pmix_sm_seg_t *sm_seg) +static int _mmap_segment_detach(pmix_pshmem_seg_t *sm_seg) { int rc = PMIX_SUCCESS; @@ -179,7 +192,7 @@ int _mmap_segment_detach(pmix_sm_seg_t *sm_seg) return rc; } -int _mmap_segment_unlink(pmix_sm_seg_t *sm_seg) +static int _mmap_segment_unlink(pmix_pshmem_seg_t *sm_seg) { if (-1 == unlink(sm_seg->seg_name)) { pmix_output_verbose(2, pmix_globals.debug_output, diff --git a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap.h similarity index 59% rename from opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.h rename to opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap.h index 349fb10c01..fade1af18d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2015-2016 Mellanox Technologies, Inc. * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -12,13 +13,12 @@ #define PMIX_SM_MMAP_H #include - - -#include "pmix_sm.h" +#include BEGIN_C_DECLS -extern pmix_sm_base_module_t pmix_sm_mmap_module; +PMIX_EXPORT extern pmix_pshmem_base_component_t mca_pshmem_mmap_component; +extern pmix_pshmem_base_module_t pmix_mmap_module; END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap_component.c new file mode 100644 index 0000000000..7ad0b072b9 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/mmap/pshmem_mmap_component.c @@ -0,0 +1,86 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2017 Mellanox Technologies, Inc. + * All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + * These symbols are in a file by themselves to provide nice linker + * semantics. Since linkers generally pull in symbols by object + * files, keeping these symbols as the only symbols in this file + * prevents utility programs such as "ompi_info" from having to import + * entire components just to query their version and parameters. + */ + +#include +#include "pmix_common.h" + + +#include +#include "pshmem_mmap.h" + +static pmix_status_t component_open(void); +static pmix_status_t component_close(void); +static pmix_status_t component_query(pmix_mca_base_module_t **module, int *priority); + +/* + * Instantiate the public struct with all of our public information + * and pointers to our public functions in it + */ +pmix_pshmem_base_component_t mca_pshmem_mmap_component = { + .base = { + PMIX_PSHMEM_BASE_VERSION_1_0_0, + + /* Component name and version */ + .pmix_mca_component_name = "mmap", + PMIX_MCA_BASE_MAKE_VERSION(component, + PMIX_MAJOR_VERSION, + PMIX_MINOR_VERSION, + PMIX_RELEASE_VERSION), + + /* Component open and close functions */ + .pmix_mca_open_component = component_open, + .pmix_mca_close_component = component_close, + .pmix_mca_query_component = component_query, + }, + .data = { + /* The component is checkpoint ready */ + PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT + } +}; + + +static int component_open(void) +{ + return PMIX_SUCCESS; +} + + +static int component_query(pmix_mca_base_module_t **module, int *priority) +{ + *priority = 10; + *module = (pmix_mca_base_module_t *)&pmix_mmap_module; + return PMIX_SUCCESS; +} + + +static int component_close(void) +{ + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/pshmem.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/pshmem.h new file mode 100644 index 0000000000..013bddb9ef --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pshmem/pshmem.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2015-2016 Mellanox Technologies, Inc. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_PSHMEM_H +#define PMIX_PSHMEM_H + +#include + +#include +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_var.h" +#include "src/mca/base/pmix_mca_base_framework.h" + + +BEGIN_C_DECLS + +#if !defined(MAP_FAILED) +# define MAP_FAILED ((char*)-1) +#endif /* MAP_FAILED */ + +#define PMIX_SHMEM_DS_ID_INVALID -1 + +typedef enum { + PMIX_PSHMEM_RONLY, + PMIX_PSHMEM_RW +} pmix_pshmem_access_mode_t; + +typedef struct pmix_pshmem_seg_t { + /* pid of the shared memory segment creator */ + pid_t seg_cpid; + /* ds id */ + int seg_id; + /* size of shared memory segment */ + size_t seg_size; + /* base address of shared memory segment */ + unsigned char *seg_base_addr; + char seg_name[PMIX_PATH_MAX]; +} pmix_pshmem_seg_t; + + +static inline void _segment_ds_reset(pmix_pshmem_seg_t *sm_seg) +{ + sm_seg->seg_cpid = 0; + sm_seg->seg_id = PMIX_SHMEM_DS_ID_INVALID; + sm_seg->seg_size = 0; + memset(sm_seg->seg_name, '\0', PMIX_PATH_MAX); + sm_seg->seg_base_addr = (unsigned char *)MAP_FAILED; +} + +/* initialize the module */ +typedef pmix_status_t (*pmix_pshmem_base_module_init_fn_t)(void); + +/* finalize the module */ +typedef void (*pmix_pshmem_base_module_finalize_fn_t)(void); + +/** +* create a new shared memory segment and initialize members in structure +* pointed to by sm_seg. +* +* @param sm_seg pointer to pmix_pshmem_seg_t structure +* +* @param file_name unique string identifier that must be a valid, +* writable path (IN). +* +* @param size size of the shared memory segment. +* +* @return PMIX_SUCCESS on success. +*/ +typedef int (*pmix_pshmem_base_module_segment_create_fn_t)(pmix_pshmem_seg_t *sm_seg, + const char *file_name, size_t size); + +/** +* attach to an existing shared memory segment initialized by segment_create. +* +* @param sm_seg pointer to initialized pmix_pshmem_seg_t typedef'd +* structure (IN/OUT). +* +* @return base address of shared memory segment on success. returns +* NULL otherwise. +*/ +typedef int (*pmix_pshmem_base_module_segment_attach_fn_t)(pmix_pshmem_seg_t *sm_seg, + pmix_pshmem_access_mode_t sm_mode); + +/** +* detach from an existing shared memory segment. +* +* @param sm_seg pointer to initialized pmix_pshmem_seg_t typedef'd structure +* (IN/OUT). +* +* @return PMIX_SUCCESS on success. +*/ +typedef int (*pmix_pshmem_base_module_segment_detach_fn_t)(pmix_pshmem_seg_t *sm_seg); + +/** +* unlink an existing shared memory segment. +* +* @param sm_seg pointer to initialized pmix_pshmem_seg_t typedef'd structure +* (IN/OUT). +* +* @return PMIX_SUCCESS on success. +*/ +typedef int (*pmix_pshmem_base_module_unlink_fn_t)(pmix_pshmem_seg_t *sm_seg); + + +/** +* structure for sm modules +*/ +typedef struct { + const char *name; + pmix_pshmem_base_module_init_fn_t init; + pmix_pshmem_base_module_finalize_fn_t finalize; + pmix_pshmem_base_module_segment_create_fn_t segment_create; + pmix_pshmem_base_module_segment_attach_fn_t segment_attach; + pmix_pshmem_base_module_segment_detach_fn_t segment_detach; + pmix_pshmem_base_module_unlink_fn_t segment_unlink; +} pmix_pshmem_base_module_t; + +/* define the component structure */ +struct pmix_pshmem_base_component_t { + pmix_mca_base_component_t base; + pmix_mca_base_component_data_t data; + int priority; +}; + +typedef struct pmix_pshmem_base_component_t pmix_pshmem_base_component_t; + +PMIX_EXPORT extern pmix_pshmem_base_module_t pmix_pshmem; + +/* + * Macro for use in components that are of type gds + */ +#define PMIX_PSHMEM_BASE_VERSION_1_0_0 \ + PMIX_MCA_BASE_VERSION_1_0_0("pshmem", 1, 0, 0) + +END_C_DECLS + +#endif /* PMIX_PSHMEM_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/Makefile.am index dcc0b2691b..7481f0f73f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/Makefile.include index ef5342171a..2c22f16a2f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/Makefile.include @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/base.h index ac92ed9dc9..7063370904 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/base.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/base.h @@ -53,7 +53,7 @@ PMIX_EXPORT extern pmix_mca_base_framework_t pmix_ptl_base_framework; * Cycle across available components and construct the list * of active modules */ -pmix_status_t pmix_ptl_base_select(void); +PMIX_EXPORT pmix_status_t pmix_ptl_base_select(void); /** * Track an active component @@ -83,21 +83,16 @@ typedef struct pmix_ptl_globals_t pmix_ptl_globals_t; PMIX_EXPORT extern pmix_ptl_globals_t pmix_ptl_globals; /* API stubs */ -PMIX_EXPORT pmix_status_t pmix_ptl_stub_set_notification_cbfunc(pmix_ptl_cbfunc_t cbfunc); -PMIX_EXPORT char* pmix_ptl_stub_get_available_modules(void); -PMIX_EXPORT pmix_status_t pmix_ptl_stub_send_recv(struct pmix_peer_t *peer, - pmix_buffer_t *bfr, - pmix_ptl_cbfunc_t cbfunc, - void *cbdata); -PMIX_EXPORT pmix_status_t pmix_ptl_stub_send_oneway(struct pmix_peer_t *peer, - pmix_buffer_t *bfr, - pmix_ptl_tag_t tag); -PMIX_EXPORT pmix_status_t pmix_ptl_stub_connect_to_peer(struct pmix_peer_t *peer, +PMIX_EXPORT pmix_status_t pmix_ptl_base_set_notification_cbfunc(pmix_ptl_cbfunc_t cbfunc); +PMIX_EXPORT char* pmix_ptl_base_get_available_modules(void); +PMIX_EXPORT pmix_ptl_module_t* pmix_ptl_base_assign_module(void); +PMIX_EXPORT pmix_status_t pmix_ptl_base_connect_to_peer(struct pmix_peer_t *peer, pmix_info_t info[], size_t ninfo); -PMIX_EXPORT pmix_status_t pmix_ptl_stub_register_recv(struct pmix_peer_t *peer, + +PMIX_EXPORT pmix_status_t pmix_ptl_base_register_recv(struct pmix_peer_t *peer, pmix_ptl_cbfunc_t cbfunc, pmix_ptl_tag_t tag); -PMIX_EXPORT pmix_status_t pmix_ptl_stub_cancel_recv(struct pmix_peer_t *peer, +PMIX_EXPORT pmix_status_t pmix_ptl_base_cancel_recv(struct pmix_peer_t *peer, pmix_ptl_tag_t tag); PMIX_EXPORT pmix_status_t pmix_ptl_base_start_listening(pmix_info_t *info, size_t ninfo); diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_connect.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_connect.c index f66d61e641..aeaa9bc3bb 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_connect.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_connect.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_frame.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_frame.c index fbcf19cb02..222e7bc64c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_frame.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_frame.c @@ -55,17 +55,6 @@ /* Instantiate the global vars */ pmix_ptl_globals_t pmix_ptl_globals = {{{0}}}; -pmix_ptl_API_t pmix_ptl = { - .set_notification_cbfunc = pmix_ptl_stub_set_notification_cbfunc, - .get_available_modules = pmix_ptl_stub_get_available_modules, - .send_recv = pmix_ptl_stub_send_recv, - .send_oneway = pmix_ptl_stub_send_oneway, - .connect_to_peer = pmix_ptl_stub_connect_to_peer, - .recv = pmix_ptl_stub_register_recv, - .cancel = pmix_ptl_stub_cancel_recv, - .start_listening = pmix_ptl_base_start_listening, - .stop_listening = pmix_ptl_base_stop_listening -}; static int pmix_ptl_register(pmix_mca_base_register_flag_t flags) { @@ -80,7 +69,7 @@ static pmix_status_t pmix_ptl_close(void) pmix_ptl_globals.initialized = false; /* ensure the listen thread has been shut down */ - pmix_ptl.stop_listening(); + pmix_ptl_base_stop_listening(); if (NULL != pmix_client_globals.myserver) { if (0 <= pmix_client_globals.myserver->sd) { @@ -195,8 +184,9 @@ static void pccon(pmix_pending_connection_t *p) memset(p->nspace, 0, PMIX_MAX_NSLEN+1); p->info = NULL; p->ninfo = 0; - p->bfrop = NULL; + p->bfrops = NULL; p->psec = NULL; + p->gds = NULL; p->ptl = NULL; p->cred = NULL; } @@ -205,12 +195,15 @@ static void pcdes(pmix_pending_connection_t *p) if (NULL != p->info) { PMIX_INFO_FREE(p->info, p->ninfo); } - if (NULL != p->bfrop) { - free(p->bfrop); + if (NULL != p->bfrops) { + free(p->bfrops); } if (NULL != p->psec) { free(p->psec); } + if (NULL != p->gds) { + free(p->gds); + } if (NULL != p->cred) { free(p->cred); } diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_sendrecv.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_sendrecv.c index 350c4d81bd..0349b10fc9 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_sendrecv.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_sendrecv.c @@ -58,7 +58,7 @@ static void _notify_complete(pmix_status_t status, void *cbdata) static void lost_connection(pmix_peer_t *peer, pmix_status_t err) { pmix_server_trkr_t *trk; - pmix_rank_info_t *rinfo, *rnext; + pmix_server_caddy_t *rinfo, *rnext; pmix_trkr_caddy_t *tcd; pmix_regevents_info_t *reginfoptr, *regnext; pmix_peer_events_info_t *pr, *pnext; @@ -91,17 +91,17 @@ static void lost_connection(pmix_peer_t *peer, pmix_status_t err) * after it successfully connected */ PMIX_LIST_FOREACH(trk, &pmix_server_globals.collectives, pmix_server_trkr_t) { /* see if this proc is participating in this tracker */ - PMIX_LIST_FOREACH_SAFE(rinfo, rnext, &trk->ranks, pmix_rank_info_t) { - if (0 != strncmp(rinfo->nptr->nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN)) { + PMIX_LIST_FOREACH_SAFE(rinfo, rnext, &trk->local_cbs, pmix_server_caddy_t) { + if (0 != strncmp(rinfo->peer->info->pname.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN)) { continue; } - if (rinfo->rank != peer->info->rank) { + if (rinfo->peer->info->pname.rank != peer->info->pname.rank) { continue; } /* it is - adjust the count */ --trk->nlocal; /* remove it from the list */ - pmix_list_remove_item(&trk->ranks, &rinfo->super); + pmix_list_remove_item(&trk->local_cbs, &rinfo->super); PMIX_RELEASE(rinfo); /* check for completion */ if (pmix_list_get_size(&trk->local_cbs) == trk->nlocal) { @@ -113,14 +113,16 @@ static void lost_connection(pmix_peer_t *peer, pmix_status_t err) } } } - /* remove this proc from the list of ranks for this nspace if it is still there */ - PMIX_LIST_FOREACH_SAFE(info, pinfo, &(peer->info->nptr->server->ranks), pmix_rank_info_t) { + /* remove this proc from the list of ranks for this nspace if it is + * still there - we must check for multiple copies as there will be + * one for each "clone" of this peer */ + PMIX_LIST_FOREACH_SAFE(info, pinfo, &(peer->nptr->ranks), pmix_rank_info_t) { if (info == peer->info) { - pmix_list_remove_item(&(peer->info->nptr->server->ranks), &(peer->info->super)); + pmix_list_remove_item(&(peer->nptr->ranks), &(peer->info->super)); } } /* reduce the number of local procs */ - --peer->info->nptr->server->nlocalprocs; + --peer->nptr->nlocalprocs; /* now decrease the refcount - might actually free the object */ PMIX_RELEASE(peer->info); /* remove this client from our array */ @@ -162,6 +164,8 @@ static void lost_connection(pmix_peer_t *peer, pmix_status_t err) * the return call from a sendrecv - i.e., any that are * waiting on dynamic tags */ PMIX_CONSTRUCT(&buf, pmix_buffer_t); + /* must set the buffer type so it doesn't fail in unpack */ + buf.type = pmix_client_globals.myserver->nptr->compat.type; hdr.nbytes = 0; // initialize the hdr to something safe PMIX_LIST_FOREACH(rcv, &pmix_ptl_globals.posted_recvs, pmix_ptl_posted_recv_t) { if (UINT_MAX != rcv->tag && NULL != rcv->cbfunc) { @@ -319,7 +323,7 @@ void pmix_ptl_base_send_handler(int sd, short flags, void *cbdata) pmix_output_verbose(2, pmix_globals.debug_output, "%s:%d ptl:base:send_handler SENDING TO PEER %s:%d tag %u with %s msg", pmix_globals.myid.nspace, pmix_globals.myid.rank, - peer->info->nptr->nspace, peer->info->rank, + peer->info->pname.nspace, peer->info->pname.rank, (NULL == msg) ? UINT_MAX : ntohl(msg->hdr.tag), (NULL == msg) ? "NULL" : "NON-NULL"); @@ -398,8 +402,8 @@ void pmix_ptl_base_recv_handler(int sd, short flags, void *cbdata) pmix_output_verbose(2, pmix_globals.debug_output, "%s:%d ptl:base:recv:handler called with peer %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, - (NULL == peer) ? "NULL" : peer->info->nptr->nspace, - (NULL == peer) ? PMIX_RANK_UNDEF : peer->info->rank); + (NULL == peer) ? "NULL" : peer->info->pname.nspace, + (NULL == peer) ? PMIX_RANK_UNDEF : peer->info->pname.rank); if (NULL == peer) { return; @@ -441,8 +445,8 @@ void pmix_ptl_base_recv_handler(int sd, short flags, void *cbdata) /* if this is a zero-byte message, then we are done */ if (0 == peer->recv_msg->hdr.nbytes) { pmix_output_verbose(2, pmix_globals.debug_output, - "RECVD ZERO-BYTE MESSAGE FROM %s:%d for tag %d", - peer->info->nptr->nspace, peer->info->rank, + "RECVD ZERO-BYTE MESSAGE FROM %s:%u 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; @@ -474,7 +478,7 @@ void pmix_ptl_base_recv_handler(int sd, short flags, void *cbdata) */ pmix_output_verbose(2, pmix_globals.debug_output, "ptl:base:msg_recv: peer %s:%d closed connection", - peer->info->nptr->nspace, peer->info->rank); + peer->nptr->nspace, peer->info->pname.rank); goto err_close; } } @@ -512,7 +516,7 @@ void pmix_ptl_base_recv_handler(int sd, short flags, void *cbdata) pmix_output_verbose(2, pmix_globals.debug_output, "%s:%d ptl:base:msg_recv: peer %s:%d closed connection", pmix_globals.myid.nspace, pmix_globals.myid.rank, - peer->info->nptr->nspace, peer->info->rank); + peer->nptr->nspace, peer->info->pname.rank); goto err_close; } } @@ -548,7 +552,7 @@ void pmix_ptl_base_send(int sd, short args, void *cbdata) PMIX_ACQUIRE_OBJECT(queue); if (NULL == queue->peer || queue->peer->sd < 0 || - NULL == queue->peer->info || NULL == queue->peer->info->nptr) { + NULL == queue->peer->info || NULL == queue->peer->nptr) { /* this peer has lost connection */ PMIX_RELEASE(queue); /* ensure we post the object before another thread @@ -558,10 +562,10 @@ void pmix_ptl_base_send(int sd, short args, void *cbdata) } pmix_output_verbose(2, pmix_globals.debug_output, - "[%s:%d] send to %s:%d on tag %d", + "[%s:%d] send to %s:%u on tag %d", __FILE__, __LINE__, - (queue->peer)->info->nptr->nspace, - (queue->peer)->info->rank, (queue->tag)); + (queue->peer)->info->pname.nspace, + (queue->peer)->info->pname.rank, (queue->tag)); snd = PMIX_NEW(pmix_ptl_send_t); snd->hdr.pindex = htonl(pmix_globals.pindex); @@ -685,10 +689,11 @@ void pmix_ptl_base_process_msg(int fd, short flags, void *cbdata) /* construct and load the buffer */ PMIX_CONSTRUCT(&buf, pmix_buffer_t); if (NULL != msg->data) { - buf.base_ptr = (char*)msg->data; - buf.bytes_allocated = buf.bytes_used = msg->hdr.nbytes; - buf.unpack_ptr = buf.base_ptr; - buf.pack_ptr = ((char*)buf.base_ptr) + buf.bytes_used; + PMIX_LOAD_BUFFER(msg->peer, &buf, msg->data, msg->hdr.nbytes); + } else { + /* we need to at least set the buffer type so + * unpack of a zero-byte message doesn't error */ + buf.type = msg->peer->nptr->compat.type; } msg->data = NULL; // protect the data region pmix_output_verbose(5, pmix_globals.debug_output, diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_stubs.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_stubs.c index f13fde1bd7..6ddb4a9332 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_stubs.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_stubs.c @@ -30,7 +30,7 @@ #include "src/mca/ptl/base/base.h" -pmix_status_t pmix_ptl_stub_set_notification_cbfunc(pmix_ptl_cbfunc_t cbfunc) +pmix_status_t pmix_ptl_base_set_notification_cbfunc(pmix_ptl_cbfunc_t cbfunc) { pmix_ptl_posted_recv_t *req; @@ -51,7 +51,7 @@ pmix_status_t pmix_ptl_stub_set_notification_cbfunc(pmix_ptl_cbfunc_t cbfunc) return PMIX_SUCCESS; } -char* pmix_ptl_stub_get_available_modules(void) +char* pmix_ptl_base_get_available_modules(void) { pmix_ptl_base_active_t *active; char **tmp=NULL, *reply=NULL; @@ -70,25 +70,20 @@ char* pmix_ptl_stub_get_available_modules(void) return reply; } -pmix_status_t pmix_ptl_stub_send_recv(struct pmix_peer_t *peer, - pmix_buffer_t *bfr, - pmix_ptl_cbfunc_t cbfunc, - void *cbdata) +/* return the highest priority module */ +pmix_ptl_module_t* pmix_ptl_base_assign_module(void) { - pmix_peer_t *pr = (pmix_peer_t*)peer; + pmix_ptl_base_active_t *active; - return pr->compat.ptl->send_recv(peer, bfr, cbfunc, cbdata); + if (!pmix_ptl_globals.initialized) { + return NULL; + } + + active = (pmix_ptl_base_active_t*)pmix_list_get_first(&pmix_ptl_globals.actives); + return active->module; } -pmix_status_t pmix_ptl_stub_send_oneway(struct pmix_peer_t *peer, - pmix_buffer_t *bfr, - pmix_ptl_tag_t tag) -{ - pmix_peer_t *pr = (pmix_peer_t*)peer; - return pr->compat.ptl->send(peer, bfr, tag); -} - -pmix_status_t pmix_ptl_stub_connect_to_peer(struct pmix_peer_t *peer, +pmix_status_t pmix_ptl_base_connect_to_peer(struct pmix_peer_t *peer, pmix_info_t info[], size_t ninfo) { pmix_peer_t *pr = (pmix_peer_t*)peer; @@ -97,7 +92,7 @@ pmix_status_t pmix_ptl_stub_connect_to_peer(struct pmix_peer_t *peer, PMIX_LIST_FOREACH(active, &pmix_ptl_globals.actives, pmix_ptl_base_active_t) { if (NULL != active->module->connect_to_peer) { if (PMIX_SUCCESS == active->module->connect_to_peer(peer, info, ninfo)) { - pr->compat.ptl = active->module; + pr->nptr->compat.ptl = active->module; return PMIX_SUCCESS; } } @@ -106,6 +101,7 @@ pmix_status_t pmix_ptl_stub_connect_to_peer(struct pmix_peer_t *peer, return PMIX_ERR_UNREACH; } + static void post_recv(int fd, short args, void *cbdata) { pmix_ptl_posted_recv_t *req = (pmix_ptl_posted_recv_t*)cbdata; @@ -141,7 +137,7 @@ static void post_recv(int fd, short args, void *cbdata) } } -pmix_status_t pmix_ptl_stub_register_recv(struct pmix_peer_t *peer, +pmix_status_t pmix_ptl_base_register_recv(struct pmix_peer_t *peer, pmix_ptl_cbfunc_t cbfunc, pmix_ptl_tag_t tag) { @@ -177,7 +173,7 @@ static void cancel_recv(int fd, short args, void *cbdata) PMIX_RELEASE(req); } -pmix_status_t pmix_ptl_stub_cancel_recv(struct pmix_peer_t *peer, +pmix_status_t pmix_ptl_base_cancel_recv(struct pmix_peer_t *peer, pmix_ptl_tag_t tag) { pmix_ptl_posted_recv_t *req; diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/ptl.h b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/ptl.h index f2f5ad6033..157f45f580 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/ptl.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/ptl.h @@ -38,7 +38,7 @@ #include "src/mca/mca.h" #include "src/mca/base/pmix_mca_base_var.h" #include "src/mca/base/pmix_mca_base_framework.h" -#include "src/buffer_ops/types.h" +#include "src/mca/bfrops/bfrops_types.h" #include "ptl_types.h" @@ -141,36 +141,22 @@ struct pmix_ptl_module_t { }; typedef struct pmix_ptl_module_t pmix_ptl_module_t; -/**** API MODULE DEFINITION ****/ -/* set the notification callback function to the provided one */ -typedef pmix_status_t (*pmix_ptl_set_notification_cbfunc_fn_t)(pmix_ptl_cbfunc_t cbfunc); -/* get a list of available support - caller must free results - * when done. The list is returned as a comma-delimited string - * of available components in priority order, suitable for - * passing to the assign_module function */ -typedef char* (*pmix_ptl_get_available_modules_fn_t)(void); +/***** MACROS FOR EXECUTING PTL FUNCTIONS *****/ +#define PMIX_PTL_SEND_RECV(r, p, b, c, d) \ + (r) = (p)->nptr->compat.ptl->send_recv((struct pmix_peer_t*)(p), b, c, d) -/* Start listening for PMIx clients (server-side function) */ -typedef pmix_status_t (*pmix_ptl_start_listening_fn_t)(pmix_info_t *info, size_t ninfo); +#define PMIX_PTL_SEND_ONEWAY(r, p, b, t) \ + (r) = (p)->nptr->compat.ptl->send((struct pmix_peer_t*)(p), b, t) -/* Stop listening for PMIx clients and cleanup all rendezvous - * points (server-side function) */ -typedef void (*pmix_ptl_stop_listening_fn_t)(void); +#define PMIX_PTL_RECV(r, p, c, t) \ + (r) = (p)->nptr->compat.ptl->recv((struct pmix_peer_t*)(p), c, t) -typedef struct { - pmix_ptl_set_notification_cbfunc_fn_t set_notification_cbfunc; - pmix_ptl_get_available_modules_fn_t get_available_modules; - pmix_ptl_send_recv_fn_t send_recv; - pmix_ptl_send_fn_t send_oneway; - pmix_ptl_recv_fn_t recv; - pmix_ptl_cancel_fn_t cancel; - pmix_ptl_connect_to_peer_fn_t connect_to_peer; - pmix_ptl_start_listening_fn_t start_listening; - pmix_ptl_stop_listening_fn_t stop_listening; -} pmix_ptl_API_t; +#define PMIX_PTL_CANCEL(r, p, t) \ + (r) = (p)->nptr->compat.ptl->cancel((struct pmix_peer_t*)(p), t) -PMIX_EXPORT extern pmix_ptl_API_t pmix_ptl; +extern pmix_status_t pmix_ptl_base_connect_to_peer(struct pmix_peer_t* peer, + pmix_info_t info[], size_t ninfo); /**** COMPONENT STRUCTURE DEFINITION ****/ @@ -198,9 +184,6 @@ struct pmix_ptl_base_component_t { typedef struct pmix_ptl_base_component_t pmix_ptl_base_component_t; -/**** DEFINE SOME GENERAL ACCESS FUNCTIONS ****/ - - /* * Macro for use in components that are of type ptl */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/ptl_types.h b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/ptl_types.h index 55e617690a..32a31a845d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/ptl_types.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/ptl_types.h @@ -53,7 +53,7 @@ #include "src/class/pmix_list.h" #include "src/util/output.h" -#include "src/buffer_ops/types.h" +#include "src/mca/bfrops/bfrops_types.h" BEGIN_C_DECLS @@ -170,8 +170,9 @@ typedef struct { size_t ninfo; pmix_status_t status; struct sockaddr_storage addr; - char *bfrop; + char *bfrops; char *psec; + char *gds; struct pmix_ptl_module_t *ptl; pmix_bfrop_buffer_type_t buffer_type; char *cred; @@ -230,8 +231,8 @@ PMIX_CLASS_DECLARATION(pmix_listener_t); pmix_output_verbose(5, pmix_globals.debug_output, \ "[%s:%d] queue callback called: reply to %s:%d on tag %d size %d", \ __FILE__, __LINE__, \ - (p)->info->nptr->nspace, \ - (p)->info->rank, (t), (int)(b)->bytes_used); \ + (p)->info->pname.nspace, \ + (p)->info->pname.rank, (t), (int)(b)->bytes_used); \ snd = PMIX_NEW(pmix_ptl_send_t); \ snd->hdr.pindex = htonl(pmix_globals.pindex); \ snd->hdr.tag = htonl(t); \ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/Makefile.am index 6788aba19c..12f4988c21 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp.c index 8c962c0fd5..a72dcf2d0d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp.c @@ -149,12 +149,21 @@ static pmix_status_t connect_to_peer(struct pmix_peer_t *peer, } *p2 = '\0'; ++p2; - pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); - pmix_client_globals.myserver->info->nptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(pmix_client_globals.myserver->info->nptr->nspace, p, PMIX_MAX_NSLEN); + if (NULL == pmix_client_globals.myserver->info) { + pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); + } + if (NULL == pmix_client_globals.myserver->nptr) { + pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_nspace_t); + } + if (NULL == pmix_client_globals.myserver->nptr->nspace) { + pmix_client_globals.myserver->nptr->nspace = strdup(p); + } + if (NULL == pmix_client_globals.myserver->info->pname.nspace) { + pmix_client_globals.myserver->info->pname.nspace = strdup(p); + } /* set the server rank */ - pmix_client_globals.myserver->info->rank = strtoull(p2, NULL, 10); + pmix_client_globals.myserver->info->pname.rank = strtoull(p2, NULL, 10); /* save the URI, but do not overwrite what we may have received from * the info-key directives */ @@ -208,16 +217,28 @@ static pmix_status_t connect_to_peer(struct pmix_peer_t *peer, *p2 = '\0'; ++p2; /* set the server nspace */ - pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); - pmix_client_globals.myserver->info->nptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(pmix_client_globals.myserver->info->nptr->nspace, srvr, PMIX_MAX_NSLEN); - pmix_client_globals.myserver->info->rank = strtoull(p2, NULL, 10); - /* now parse the uti itself */ + if (NULL == pmix_client_globals.myserver->info) { + pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); + } + if (NULL == pmix_client_globals.myserver->nptr) { + pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_nspace_t); + } + if (NULL == pmix_client_globals.myserver->nptr->nspace) { + pmix_client_globals.myserver->nptr->nspace = strdup(p); + } + if (NULL == pmix_client_globals.myserver->info->pname.nspace) { + pmix_client_globals.myserver->info->pname.nspace = strdup(p); + } + pmix_client_globals.myserver->info->pname.rank = strtoull(p2, NULL, 10); + /* now parse the uri itself */ mca_ptl_tcp_component.super.uri = strdup(p); free(srvr); } } + /* mark that we are the active module for this server */ + pmix_client_globals.myserver->nptr->compat.ptl = &pmix_ptl_tcp_module; + /* setup the path to the daemon rendezvous point */ memset(&mca_ptl_tcp_component.connection, 0, sizeof(struct sockaddr_storage)); if (0 == strncmp(mca_ptl_tcp_component.super.uri, "tcp4", 4)) { @@ -376,7 +397,8 @@ static pmix_status_t send_connect_ack(int sd) pmix_ptl_hdr_t hdr; size_t sdsize=0, csize=0, len; char *cred = NULL; - char *sec; + char *sec, *bfrops, *gds; + pmix_bfrop_buffer_type_t bftype; pmix_status_t rc; uint8_t flag; uid_t euid; @@ -401,8 +423,9 @@ static pmix_status_t send_connect_ack(int sd) * local PMIx server, if known. Now use that module to * get a credential, if the security system provides one. Not * every psec module will do so, thus we must first check */ - if (PMIX_SUCCESS != (rc = pmix_psec.create_cred(pmix_client_globals.myserver, - PMIX_PROTOCOL_V2, &cred, &len))) { + PMIX_PSEC_CREATE_CRED(rc, pmix_client_globals.myserver, + PMIX_PROTOCOL_V2, &cred, &len); + if (PMIX_SUCCESS != rc) { return rc; } @@ -419,11 +442,22 @@ static pmix_status_t send_connect_ack(int sd) sdsize += 2*sizeof(uint32_t); } - /* add our active sec module info */ - sec = pmix_psec.get_available_modules(); + /* add the name of our active sec module - we selected it + * in pmix_client.c prior to entering here */ + sec = pmix_globals.mypeer->nptr->compat.psec->name; + + /* add our active bfrops module name */ + bfrops = pmix_globals.mypeer->nptr->compat.bfrops->version; + /* and the type of buffer we are using */ + bftype = pmix_globals.mypeer->nptr->compat.type; + + /* add our active gds module for working with the server */ + gds = (char*)pmix_client_globals.myserver->nptr->compat.gds->name; /* set the number of bytes to be read beyond the header */ - hdr.nbytes = sdsize + strlen(PMIX_VERSION) + 1 + strlen(sec) + 1 + sizeof(uint32_t) + len; // must NULL terminate the VERSION string! + hdr.nbytes = sdsize + strlen(PMIX_VERSION) + 1 + strlen(sec) + 1 \ + + strlen(bfrops) + 1 + sizeof(bftype) \ + + strlen(gds) + 1 + sizeof(uint32_t) + len; // must NULL terminate the strings! /* create a space for our message */ sdsize = (sizeof(hdr) + hdr.nbytes); @@ -444,7 +478,18 @@ static pmix_status_t send_connect_ack(int sd) /* provide our active psec module */ memcpy(msg+csize, sec, strlen(sec)); csize += strlen(sec)+1; - free(sec); + + /* provide our active bfrops module */ + memcpy(msg+csize, bfrops, strlen(bfrops)); + csize += strlen(bfrops)+1; + + /* provide the bfrops type */ + memcpy(msg+csize, &bftype, sizeof(bftype)); + csize += sizeof(bftype); + + /* provide the gds module */ + memcpy(msg+csize, gds, strlen(gds)); + csize += strlen(gds)+1; /* load the length of the credential - we put this in uint32_t * format as that is a fixed size, and convert to network @@ -514,7 +559,7 @@ static pmix_status_t recv_connect_ack(int sd) pmix_socklen_t sz; bool sockopt = true; uint32_t u32; - pmix_nspace_t *nsptr; + char nspace[PMIX_MAX_NSLEN+1]; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: RECV CONNECT ACK FROM SERVER"); @@ -549,7 +594,8 @@ static pmix_status_t recv_connect_ack(int sd) if (PMIX_PROC_IS_CLIENT) { /* see if they want us to do the handshake */ if (PMIX_ERR_READY_FOR_HANDSHAKE == reply) { - if (PMIX_SUCCESS != (rc = pmix_psec.client_handshake(pmix_client_globals.myserver, sd))) { + PMIX_PSEC_CLIENT_HANDSHAKE(rc, pmix_client_globals.myserver, sd); + if (PMIX_SUCCESS != rc) { return rc; } } else if (PMIX_SUCCESS != reply) { @@ -565,7 +611,7 @@ static pmix_status_t recv_connect_ack(int sd) return rc; } pmix_globals.pindex = ntohl(u32); - } else { + } else { // we are a tool /* if the status indicates an error, then we are done */ if (PMIX_SUCCESS != reply) { PMIX_ERROR_LOG(reply); @@ -577,35 +623,30 @@ static pmix_status_t recv_connect_ack(int sd) PMIX_ERROR_LOG(rc); return rc; } - - /* setup required bookkeeping */ - nsptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(nsptr->nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN); - pmix_list_append(&pmix_globals.nspaces, &nsptr->super); /* our rank is always zero */ pmix_globals.myid.rank = 0; /* get the server's nspace and rank so we can send to it */ pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); - pmix_client_globals.myserver->info->nptr = PMIX_NEW(pmix_nspace_t); - pmix_ptl_base_recv_blocking(sd, (char*)pmix_client_globals.myserver->info->nptr->nspace, PMIX_MAX_NSLEN+1); - pmix_ptl_base_recv_blocking(sd, (char*)&(pmix_client_globals.myserver->info->rank), sizeof(int)); + pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_nspace_t); + pmix_ptl_base_recv_blocking(sd, (char*)nspace, PMIX_MAX_NSLEN+1); + pmix_client_globals.myserver->nptr->nspace = strdup(nspace); + pmix_client_globals.myserver->info->pname.nspace = strdup(nspace); + pmix_ptl_base_recv_blocking(sd, (char*)&(pmix_client_globals.myserver->info->pname.rank), sizeof(int)); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: RECV CONNECT CONFIRMATION FOR TOOL %s:%d FROM SERVER %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, - pmix_client_globals.myserver->info->nptr->nspace, - pmix_client_globals.myserver->info->rank); + pmix_client_globals.myserver->info->pname.nspace, + pmix_client_globals.myserver->info->pname.rank); /* get the returned status from the security handshake */ pmix_ptl_base_recv_blocking(sd, (char*)&reply, sizeof(pmix_status_t)); if (PMIX_SUCCESS != reply) { /* see if they want us to do the handshake */ if (PMIX_ERR_READY_FOR_HANDSHAKE == reply) { - if (NULL == pmix_psec.client_handshake) { - return PMIX_ERR_HANDSHAKE_FAILED; - } - if (PMIX_SUCCESS != (reply = pmix_psec.client_handshake(pmix_client_globals.myserver, sd))) { + PMIX_PSEC_CLIENT_HANDSHAKE(reply, pmix_client_globals.myserver, sd); + if (PMIX_SUCCESS != reply) { return reply; } /* if the handshake succeeded, then fall thru to the next step */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp.h b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp.h index fa82625836..6d3b6f363d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp_component.c index b85fdb23c2..04268bbd34 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp_component.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/tcp/ptl_tcp_component.c @@ -58,6 +58,9 @@ #include "src/util/show_help.h" #include "src/util/strnlen.h" #include "src/server/pmix_server_ops.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/gds/base/base.h" +#include "src/mca/psec/base/base.h" #include "src/mca/ptl/base/base.h" #include "src/mca/ptl/tcp/ptl_tcp.h" @@ -205,16 +208,9 @@ static pmix_status_t component_open(void) pmix_status_t component_close(void) { - if (NULL != mca_ptl_tcp_component.tmpdir) { - free(mca_ptl_tcp_component.tmpdir); - } - if (NULL != mca_ptl_tcp_component.super.uri) { - free(mca_ptl_tcp_component.super.uri); - } if (NULL != mca_ptl_tcp_component.filename) { /* remove the file */ unlink(mca_ptl_tcp_component.filename); - free(mca_ptl_tcp_component.filename); } return PMIX_SUCCESS; } @@ -677,7 +673,9 @@ static void connection_handler(int sd, short args, void *cbdata) pmix_peer_t *peer; pmix_rank_t rank; pmix_status_t rc; - char *msg, *mg, *sec; + char *msg, *mg; + char *sec, *bfrops, *gds; + pmix_bfrop_buffer_type_t bftype; char *nspace; uint32_t len, u32; size_t cnt, msglen, n; @@ -686,6 +684,7 @@ static void connection_handler(int sd, short args, void *cbdata) bool found; pmix_rank_info_t *info; pmix_proc_t proc; + pmix_info_t ginfo; /* acquire the object */ PMIX_ACQUIRE_OBJECT(pnd); @@ -747,6 +746,47 @@ static void connection_handler(int sd, short args, void *cbdata) goto error; } + /* extract the name of the bfrops module they used */ + PMIX_STRNLEN(msglen, mg, cnt); + if (msglen < cnt) { + bfrops = mg; + mg += strlen(bfrops) + 1; + cnt -= strlen(bfrops) + 1; + } else { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + free(msg); + /* send an error reply to the client */ + rc = PMIX_ERR_BAD_PARAM; + goto error; + } + + /* extract the type of buffer they used */ + if (sizeof(bftype) < cnt) { + memcpy(&bftype, mg, sizeof(bftype)); + mg += sizeof(bftype); + cnt -= sizeof(bftype); + } else { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + free(msg); + /* send an error reply to the client */ + rc = PMIX_ERR_BAD_PARAM; + goto error; + } + + /* extract the name of the gds module they used */ + PMIX_STRNLEN(msglen, mg, cnt); + if (msglen < cnt) { + gds = mg; + mg += strlen(gds) + 1; + cnt -= strlen(gds) + 1; + } else { + PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); + free(msg); + /* send an error reply to the client */ + rc = PMIX_ERR_BAD_PARAM; + goto error; + } + /* extract any credential so we can validate this connection * before doing anything else */ if (sizeof(uint32_t) <= cnt) { @@ -849,6 +889,9 @@ static void connection_handler(int sd, short args, void *cbdata) /* pass along the bfrop, buffer_type, and sec fields so * we can assign them once we create a peer object */ pnd->psec = strdup(sec); + pnd->bfrops = strdup(bfrops); + pnd->buffer_type = bftype; + pnd->gds = strdup(gds); /* release the msg */ free(msg); /* request an nspace for this requestor - it will @@ -885,7 +928,7 @@ static void connection_handler(int sd, short args, void *cbdata) /* see if we know this nspace */ nptr = NULL; - PMIX_LIST_FOREACH(tmp, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(tmp, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(tmp->nspace, nspace)) { nptr = tmp; break; @@ -902,8 +945,8 @@ static void connection_handler(int sd, short args, void *cbdata) /* see if we have this peer in our list */ info = NULL; found = false; - PMIX_LIST_FOREACH(info, &nptr->server->ranks, pmix_rank_info_t) { - if (info->rank == rank) { + PMIX_LIST_FOREACH(info, &nptr->ranks, pmix_rank_info_t) { + if (info->pname.rank == rank) { found = true; break; } @@ -927,6 +970,8 @@ static void connection_handler(int sd, short args, void *cbdata) PMIX_RELEASE(pnd); return; } + PMIX_RETAIN(nptr); + peer->nptr = nptr; PMIX_RETAIN(info); peer->info = info; info->proc_cnt++; /* increase number of processes on this rank */ @@ -941,9 +986,23 @@ static void connection_handler(int sd, short args, void *cbdata) PMIX_RELEASE(pnd); return; } + info->peerid = peer->index; /* set the sec module to match this peer */ - if (PMIX_SUCCESS != (rc = pmix_psec.assign_module(peer, sec))) { + peer->nptr->compat.psec = pmix_psec_base_assign_module(sec); + if (NULL == peer->nptr->compat.psec) { + free(msg); + info->proc_cnt--; + PMIX_RELEASE(info); + pmix_pointer_array_set_item(&pmix_server_globals.clients, peer->index, NULL); + PMIX_RELEASE(peer); + /* send an error reply to the client */ + goto error; + } + + /* set the bfrops module to match this peer */ + peer->nptr->compat.bfrops = pmix_bfrops_base_assign_module(bfrops); + if (NULL == peer->nptr->compat.bfrops) { free(msg); info->proc_cnt--; PMIX_RELEASE(info); @@ -953,13 +1012,30 @@ static void connection_handler(int sd, short args, void *cbdata) goto error; } free(msg); + /* and the buffer type to match */ + peer->nptr->compat.type = bftype; + + /* set the gds module to match this peer */ + PMIX_INFO_LOAD(&ginfo, PMIX_GDS_MODULE, gds, PMIX_STRING); + peer->nptr->compat.gds = pmix_gds_base_assign_module(&ginfo, 1); + if (NULL == peer->nptr->compat.gds) { + free(msg); + info->proc_cnt--; + PMIX_RELEASE(info); + pmix_pointer_array_set_item(&pmix_server_globals.clients, peer->index, NULL); + PMIX_RELEASE(peer); + /* send an error reply to the client */ + goto error; + } /* the choice of PTL module is obviously us */ - peer->compat.ptl = &pmix_ptl_tcp_module; + peer->nptr->compat.ptl = &pmix_ptl_tcp_module; /* validate the connection */ - if (PMIX_SUCCESS != (rc = pmix_psec.validate_connection((struct pmix_peer_t*)peer, - PMIX_PROTOCOL_V2, pnd->cred, pnd->len))) { + PMIX_PSEC_VALIDATE_CONNECTION(rc, peer, + PMIX_PROTOCOL_V2, + pnd->cred, pnd->len); + if (PMIX_SUCCESS != rc) { pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "validation of client connection failed"); info->proc_cnt--; @@ -1001,8 +1077,8 @@ static void connection_handler(int sd, short args, void *cbdata) /* let the host server know that this client has connected */ if (NULL != pmix_host_server.client_connected) { - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; rc = pmix_host_server.client_connected(&proc, peer->info->server_object, NULL, NULL); if (PMIX_SUCCESS != rc) { @@ -1021,7 +1097,7 @@ static void connection_handler(int sd, short args, void *cbdata) EV_WRITE|EV_PERSIST, pmix_ptl_base_send_handler, peer); pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "pmix:server client %s:%u has connected on socket %d", - peer->info->nptr->nspace, peer->info->rank, peer->sd); + peer->info->pname.nspace, peer->info->pname.rank, peer->sd); PMIX_RELEASE(pnd); return; @@ -1097,20 +1173,20 @@ static void process_cbfunc(int sd, short args, void *cbdata) /* add this nspace to our pool */ nptr = PMIX_NEW(pmix_nspace_t); (void)strncpy(nptr->nspace, cd->proc.nspace, PMIX_MAX_NSLEN); - nptr->server = PMIX_NEW(pmix_server_nspace_t); - pmix_list_append(&pmix_globals.nspaces, &nptr->super); + pmix_list_append(&pmix_server_globals.nspaces, &nptr->super); /* add this tool rank to the nspace */ info = PMIX_NEW(pmix_rank_info_t); - PMIX_RETAIN(nptr); - info->nptr = nptr; - info->rank = 0; + info->pname.nspace = strdup(cd->proc.nspace); + info->pname.rank = 0; /* need to include the uid/gid for validation */ info->uid = pnd->uid; info->gid = pnd->gid; - pmix_list_append(&nptr->server->ranks, &info->super); + pmix_list_append(&nptr->ranks, &info->super); /* setup a peer object for this tool */ pmix_peer_t *peer = PMIX_NEW(pmix_peer_t); + PMIX_RETAIN(nptr); + peer->nptr = nptr; PMIX_RETAIN(info); peer->info = info; peer->proc_cnt = 1; @@ -1118,9 +1194,10 @@ static void process_cbfunc(int sd, short args, void *cbdata) /* get the appropriate compatibility modules based on the * info provided by the tool during the initial connection request */ - if (PMIX_SUCCESS != pmix_psec.assign_module((struct pmix_peer_t*)peer, pnd->psec)) { + peer->nptr->compat.psec = pmix_psec_base_assign_module(pnd->psec); + if (NULL == peer->nptr->compat.psec) { PMIX_RELEASE(peer); - pmix_list_remove_item(&pmix_globals.nspaces, &nptr->super); + pmix_list_remove_item(&pmix_server_globals.nspaces, &nptr->super); PMIX_RELEASE(nptr); // will release the info object CLOSE_THE_SOCKET(pnd->sd); goto done; @@ -1128,17 +1205,18 @@ static void process_cbfunc(int sd, short args, void *cbdata) /* the choice of PTL module was obviously made by the connecting * tool as we received this request via that channel, so simply * record it here for future use */ - peer->compat.ptl = &pmix_ptl_tcp_module; + peer->nptr->compat.ptl = &pmix_ptl_tcp_module; /* validate the connection */ - if (PMIX_SUCCESS != (rc = pmix_psec.validate_connection((struct pmix_peer_t*)peer, - PMIX_PROTOCOL_V2, - pnd->cred, pnd->len))) { + PMIX_PSEC_VALIDATE_CONNECTION(rc, peer, + PMIX_PROTOCOL_V2, + pnd->cred, pnd->len); + if (PMIX_SUCCESS != rc) { pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "validation of tool credentials failed: %s", PMIx_Error_string(rc)); PMIX_RELEASE(peer); - pmix_list_remove_item(&pmix_globals.nspaces, &nptr->super); + pmix_list_remove_item(&pmix_server_globals.nspaces, &nptr->super); PMIX_RELEASE(nptr); // will release the info object CLOSE_THE_SOCKET(pnd->sd); goto done; @@ -1151,7 +1229,7 @@ static void process_cbfunc(int sd, short args, void *cbdata) PMIX_RELEASE(pnd); PMIX_RELEASE(cd); PMIX_RELEASE(peer); - pmix_list_remove_item(&pmix_globals.nspaces, &nptr->super); + pmix_list_remove_item(&pmix_server_globals.nspaces, &nptr->super); PMIX_RELEASE(nptr); // will release the info object /* probably cannot send an error reply if we are out of memory */ return; @@ -1166,7 +1244,7 @@ static void process_cbfunc(int sd, short args, void *cbdata) EV_WRITE|EV_PERSIST, pmix_ptl_base_send_handler, peer); pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "pmix:server tool %s:%d has connected on socket %d", - peer->info->nptr->nspace, peer->info->rank, peer->sd); + peer->info->pname.nspace, peer->info->pname.rank, peer->sd); done: PMIX_RELEASE(pnd); diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/Makefile.am index e6606e2e84..24a5cce109 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/Makefile.am @@ -11,7 +11,7 @@ # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock.c index 0a090bb51d..74f4f9d30b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock.c @@ -52,7 +52,7 @@ #include "src/client/pmix_client_ops.h" #include "src/include/pmix_globals.h" #include "src/include/pmix_socket_errno.h" -#include "src/mca/psec/psec.h" +#include "src/mca/psec/base/base.h" #include "src/mca/ptl/base/base.h" #include "ptl_usock.h" @@ -116,12 +116,21 @@ static pmix_status_t connect_to_peer(struct pmix_peer_t *peer, } /* set the server nspace */ - pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); - pmix_client_globals.myserver->info->nptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(pmix_client_globals.myserver->info->nptr->nspace, uri[0], PMIX_MAX_NSLEN); + if (NULL == pmix_client_globals.myserver->info) { + pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); + } + if (NULL == pmix_client_globals.myserver->nptr) { + pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_nspace_t); + } + if (NULL == pmix_client_globals.myserver->nptr->nspace) { + pmix_client_globals.myserver->nptr->nspace = strdup(uri[0]); + } + if (NULL == pmix_client_globals.myserver->info->pname.nspace) { + pmix_client_globals.myserver->info->pname.nspace = strdup(uri[0]); + } /* set the server rank */ - pmix_client_globals.myserver->info->rank = strtoull(uri[1], NULL, 10); + pmix_client_globals.myserver->info->pname.rank = strtoull(uri[1], NULL, 10); /* setup the path to the daemon rendezvous point */ memset(&mca_ptl_usock_component.connection, 0, sizeof(struct sockaddr_storage)); @@ -244,8 +253,9 @@ static pmix_status_t send_connect_ack(int sd) /* get a credential, if the security system provides one. Not * every SPC will do so, thus we must first check */ - if (PMIX_SUCCESS != (rc = pmix_psec.create_cred(pmix_client_globals.myserver, - PMIX_PROTOCOL_V1, &cred, &len))) { + PMIX_PSEC_CREATE_CRED(rc, pmix_client_globals.myserver, + PMIX_PROTOCOL_V1, &cred, &len); + if (PMIX_SUCCESS != rc) { return rc; } @@ -331,7 +341,8 @@ static pmix_status_t recv_connect_ack(int sd) /* see if they want us to do the handshake */ if (PMIX_ERR_READY_FOR_HANDSHAKE == reply) { - if (PMIX_SUCCESS != (rc = pmix_psec.client_handshake(pmix_client_globals.myserver, sd))) { + PMIX_PSEC_CLIENT_HANDSHAKE(rc, pmix_client_globals.myserver, sd); + if (PMIX_SUCCESS != rc) { return rc; } } else if (PMIX_SUCCESS != reply) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock.h b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock.h index 358b23ab37..9e45376f19 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock.h +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock_component.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock_component.c index 8f363be427..536282997f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock_component.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/usock/ptl_usock_component.c @@ -59,7 +59,7 @@ #include "src/util/fd.h" #include "src/util/show_help.h" #include "src/util/strnlen.h" -#include "src/mca/psec/psec.h" +#include "src/mca/psec/base/base.h" #include "src/server/pmix_server_ops.h" #include "src/mca/ptl/base/base.h" @@ -218,7 +218,7 @@ static pmix_status_t setup_listener(pmix_info_t info[], size_t ninfo, * are using as this wasn't included in their handshake. So * the best we can assume is that they are using the highest * priority default we have */ - secmods = pmix_psec.get_available_modules(); + secmods = pmix_psec_base_get_available_modules(); options = pmix_argv_split(secmods, ','); sec_mode = strdup(options[0]); pmix_argv_free(options); @@ -472,7 +472,7 @@ static void connection_handler(int sd, short args, void *cbdata) /* see if we know this nspace */ nptr = NULL; - PMIX_LIST_FOREACH(tmp, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(tmp, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(tmp->nspace, nspace)) { nptr = tmp; break; @@ -489,8 +489,8 @@ static void connection_handler(int sd, short args, void *cbdata) /* see if we have this peer in our list */ info = NULL; found = false; - PMIX_LIST_FOREACH(info, &nptr->server->ranks, pmix_rank_info_t) { - if (info->rank == rank) { + PMIX_LIST_FOREACH(info, &nptr->ranks, pmix_rank_info_t) { + if (info->pname.rank == rank) { found = true; break; } @@ -511,6 +511,8 @@ static void connection_handler(int sd, short args, void *cbdata) rc = PMIX_ERR_NOMEM; goto error; } + PMIX_RETAIN(nptr); + psave->nptr = nptr; PMIX_RETAIN(info); psave->info = info; info->proc_cnt++; /* increase number of processes on this rank */ @@ -525,9 +527,11 @@ static void connection_handler(int sd, short args, void *cbdata) PMIX_RELEASE(pnd); return; } + info->peerid = psave->index; /* get the appropriate compatibility modules */ - if (PMIX_SUCCESS != pmix_psec.assign_module((struct pmix_peer_t*)psave, sec_mode)) { + nptr->compat.psec = pmix_psec_base_assign_module(sec_mode); + if (NULL == nptr->compat.psec) { free(msg); info->proc_cnt--; PMIX_RELEASE(info); @@ -539,7 +543,7 @@ static void connection_handler(int sd, short args, void *cbdata) /* the choice of PTL module was obviously made by the connecting * tool as we received this request via that channel, so simply * record it here for future use */ - psave->compat.ptl = &pmix_ptl_usock_module; + nptr->compat.ptl = &pmix_ptl_usock_module; /* validate the connection */ if (NULL == cred) { @@ -547,8 +551,9 @@ static void connection_handler(int sd, short args, void *cbdata) } else { len = strlen(cred); } - if (PMIX_SUCCESS != (rc = pmix_psec.validate_connection((struct pmix_peer_t*)psave, - PMIX_PROTOCOL_V1, cred, len))) { + PMIX_PSEC_VALIDATE_CONNECTION(rc, psave, + PMIX_PROTOCOL_V1, cred, len); + if (PMIX_SUCCESS != rc) { pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "validation of client credentials failed: %s", PMIx_Error_string(rc)); @@ -592,8 +597,8 @@ static void connection_handler(int sd, short args, void *cbdata) /* let the host server know that this client has connected */ if (NULL != pmix_host_server.client_connected) { - (void)strncpy(proc.nspace, psave->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = psave->info->rank; + (void)strncpy(proc.nspace, psave->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = psave->info->pname.rank; rc = pmix_host_server.client_connected(&proc, psave->info->server_object, NULL, NULL); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); @@ -614,7 +619,7 @@ static void connection_handler(int sd, short args, void *cbdata) EV_WRITE|EV_PERSIST, pmix_ptl_base_send_handler, psave); pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "pmix:server client %s:%u has connected on socket %d", - psave->info->nptr->nspace, psave->info->rank, psave->sd); + psave->info->pname.nspace, psave->info->pname.rank, psave->sd); PMIX_RELEASE(pnd); return; diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/runtime/Makefile.include index 9c1c170dab..a4b7d80555 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/runtime/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/Makefile.include @@ -12,7 +12,7 @@ # All rights reserved. # Copyright (c) 2012 Los Alamos National Security, LLC. # All rights reserved. -# Copyright (c) 2014-2016 Intel, Inc. All rights reserved +# Copyright (c) 2014-2017 Intel, Inc. All rights reserved. # Copyright (c) 2014 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c index 4caeea2f56..13d3328a07 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c @@ -33,12 +33,14 @@ #include "src/util/show_help.h" #include "src/mca/base/base.h" #include "src/mca/base/pmix_mca_base_var.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/gds/base/base.h" #include "src/mca/pif/base/base.h" #include "src/mca/pinstalldirs/base/base.h" #include "src/mca/pnet/base/base.h" +#include "src/mca/preg/base/base.h" #include "src/mca/psec/base/base.h" #include "src/mca/ptl/base/base.h" -#include "src/dstore/pmix_dstore.h" #include PMIX_EVENT_HEADER #include "src/runtime/pmix_rte.h" @@ -68,11 +70,12 @@ void pmix_rte_finalize(void) return; } + + /* close preg */ + (void)pmix_mca_base_framework_close(&pmix_preg_base_framework); + /* cleanup communications */ (void)pmix_mca_base_framework_close(&pmix_ptl_base_framework); - #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - pmix_dstore_finalize(); - #endif /* PMIX_ENABLE_DSTORE */ /* close the security framework */ (void)pmix_mca_base_framework_close(&pmix_psec_base_framework); @@ -80,6 +83,12 @@ void pmix_rte_finalize(void) /* close the pnet framework */ (void)pmix_mca_base_framework_close(&pmix_pnet_base_framework); + /* close bfrops */ + (void)pmix_mca_base_framework_close(&pmix_bfrops_base_framework); + + /* close GDS */ + (void)pmix_mca_base_framework_close(&pmix_gds_base_framework); + /* finalize the mca */ /* Clear out all the registered MCA params */ pmix_deregister_params(); @@ -101,18 +110,8 @@ void pmix_rte_finalize(void) much */ pmix_output_finalize(); - /* close the bfrops */ - pmix_bfrop_close(); - /* clean out the globals */ PMIX_RELEASE(pmix_globals.mypeer); - PMIX_LIST_DESTRUCT(&pmix_globals.nspaces); - if (NULL != pmix_globals.cache_local) { - PMIX_RELEASE(pmix_globals.cache_local); - } - if (NULL != pmix_globals.cache_remote) { - PMIX_RELEASE(pmix_globals.cache_remote); - } PMIX_DESTRUCT(&pmix_globals.events); PMIX_LIST_DESTRUCT(&pmix_globals.cached_events); PMIX_DESTRUCT(&pmix_globals.notifications); diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c index 0249279960..5f84f90132 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c @@ -41,17 +41,19 @@ #include "src/util/show_help.h" #include "src/mca/base/base.h" #include "src/mca/base/pmix_mca_base_var.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/gds/base/base.h" #include "src/mca/pif/base/base.h" #include "src/mca/pinstalldirs/base/base.h" #include "src/mca/pnet/base/base.h" #include "src/mca/psec/base/base.h" +#include "src/mca/preg/base/base.h" #include "src/mca/ptl/base/base.h" #include "src/event/pmix_event.h" #include "src/include/types.h" #include "src/util/error.h" #include "src/util/keyval_parse.h" -#include "src/buffer_ops/buffer_ops.h" #include "src/runtime/pmix_rte.h" #include "src/runtime/pmix_progress_threads.h" @@ -77,8 +79,8 @@ PMIX_EXPORT pmix_globals_t pmix_globals = { .external_evbase = false, .debug_output = -1, .connected = false, - .cache_local = NULL, - .cache_remote = NULL + .commits_pending = false, + .mygds = NULL }; @@ -151,7 +153,6 @@ int pmix_rte_init(pmix_proc_type_t type, /* setup the globals structure */ pmix_globals.proc_type = type; memset(&pmix_globals.myid, 0, sizeof(pmix_proc_t)); - PMIX_CONSTRUCT(&pmix_globals.nspaces, pmix_list_t); PMIX_CONSTRUCT(&pmix_globals.events, pmix_events_t); pmix_globals.event_window.tv_sec = pmix_event_caching_window; pmix_globals.event_window.tv_usec = 0; @@ -175,6 +176,14 @@ int pmix_rte_init(pmix_proc_type_t type, ret = PMIX_ERR_NOMEM; goto return_error; } + /* create an nspace object for ourselves - we will + * fill in the nspace name later */ + pmix_globals.mypeer->nptr = PMIX_NEW(pmix_nspace_t); + if (NULL == pmix_globals.mypeer->nptr) { + PMIX_RELEASE(pmix_globals.mypeer); + ret = PMIX_ERR_NOMEM; + goto return_error; + } /* scan incoming info for directives */ if (NULL != info) { @@ -185,12 +194,21 @@ int pmix_rte_init(pmix_proc_type_t type, } } } - pmix_bfrop_open(); /* the choice of modules to use when communicating with a peer * will be done by the individual init functions and at the * time of connection to that peer */ + /* open the bfrops and select the active plugins */ + if( PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_bfrops_base_framework, 0)) ) { + error = "pmix_bfrops_base_open"; + goto return_error; + } + if( PMIX_SUCCESS != (ret = pmix_bfrop_base_select()) ) { + error = "pmix_bfrops_base_select"; + goto return_error; + } + /* open the ptl and select the active plugins */ if( PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_ptl_base_framework, 0)) ) { error = "pmix_ptl_base_open"; @@ -201,7 +219,7 @@ int pmix_rte_init(pmix_proc_type_t type, goto return_error; } /* set the notification callback function */ - if (PMIX_SUCCESS != (ret = pmix_ptl.set_notification_cbfunc(cbfunc))) { + if (PMIX_SUCCESS != (ret = pmix_ptl_base_set_notification_cbfunc(cbfunc))) { error = "pmix_ptl_set_notification_cbfunc"; goto return_error; } @@ -216,6 +234,16 @@ int pmix_rte_init(pmix_proc_type_t type, goto return_error; } + /* open the gds and select the active plugins */ + if( PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_gds_base_framework, 0)) ) { + error = "pmix_gds_base_open"; + goto return_error; + } + if( PMIX_SUCCESS != (ret = pmix_gds_base_select(info, ninfo)) ) { + error = "pmix_gds_base_select"; + goto return_error; + } + /* initialize pif framework */ if (PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_pif_base_framework, 0))) { error = "pmix_pif_base_open"; @@ -232,6 +260,16 @@ int pmix_rte_init(pmix_proc_type_t type, goto return_error; } + /* open the preg and select the active plugins */ + if( PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_preg_base_framework, 0)) ) { + error = "pmix_preg_base_open"; + goto return_error; + } + if( PMIX_SUCCESS != (ret = pmix_preg_base_select()) ) { + error = "pmix_preg_base_select"; + goto return_error; + } + /* tell libevent that we need thread support */ pmix_event_use_threads(); diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.include index 7e7cacaba9..c2d9301125 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.include @@ -1,6 +1,6 @@ # -*- makefile -*- # -# Copyright (c) 2014-2016 Intel, Inc. All rights reserved. +# Copyright (c) 2014-2017 Intel, Inc. All rights reserved. # Copyright (c) 2014 Artem Y. Polyakov . # All rights reserved. # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. @@ -19,5 +19,4 @@ headers += \ sources += \ server/pmix_server.c \ server/pmix_server_ops.c \ - server/pmix_server_regex.c \ server/pmix_server_get.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/help-pmix-server.txt b/opal/mca/pmix/pmix2x/pmix/src/server/help-pmix-server.txt index 894ec393ec..d1fd6c7e80 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/help-pmix-server.txt +++ b/opal/mca/pmix/pmix2x/pmix/src/server/help-pmix-server.txt @@ -1,6 +1,6 @@ # -*- text -*- # -# Copyright (c) 2016 Intel, Inc. All rights reserved. +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c index ca22d7c708..79680c2119 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c +++ b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c @@ -62,12 +62,14 @@ #include "src/mca/pnet/pnet.h" #include "src/runtime/pmix_progress_threads.h" #include "src/runtime/pmix_rte.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/gds/base/base.h" +#include "src/mca/preg/preg.h" #include "src/mca/ptl/base/base.h" -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -#include "src/dstore/pmix_dstore.h" -#endif /* PMIX_ENABLE_DSTORE */ -#include "src/include/pmix_jobdata.h" +/* the server also needs access to client operations + * as it can, and often does, behave as a client */ +#include "src/client/pmix_client_ops.h" #include "pmix_server_ops.h" // global variables @@ -76,6 +78,8 @@ pmix_server_globals_t pmix_server_globals = {{{0}}}; // local variables static char *security_mode = NULL; static char *ptl_mode = NULL; +static char *bfrops_mode = NULL; +static char *gds_mode = NULL; static pid_t mypid; // local functions for connection support @@ -85,35 +89,15 @@ static void server_message_handler(struct pmix_peer_t *pr, static inline int _my_client(const char *nspace, pmix_rank_t rank); -static pmix_status_t initialize_server_base(pmix_server_module_t *module) -{ - /* setup the server-specific globals */ - PMIX_CONSTRUCT(&pmix_server_globals.clients, pmix_pointer_array_t); - pmix_pointer_array_init(&pmix_server_globals.clients, 1, INT_MAX, 1); - PMIX_CONSTRUCT(&pmix_server_globals.collectives, pmix_list_t); - PMIX_CONSTRUCT(&pmix_server_globals.remote_pnd, pmix_list_t); - PMIX_CONSTRUCT(&pmix_server_globals.gdata, pmix_buffer_t); - PMIX_CONSTRUCT(&pmix_server_globals.events, pmix_list_t); - PMIX_CONSTRUCT(&pmix_server_globals.local_reqs, pmix_list_t); - - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix:server init called"); - - /* setup the function pointers */ - memset(&pmix_host_server, 0, sizeof(pmix_server_module_t)); - pmix_host_server = *module; - - return PMIX_SUCCESS; -} - PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module, pmix_info_t info[], size_t ninfo) { pmix_ptl_posted_recv_t *req; pmix_status_t rc; size_t n, m; - pmix_kval_t kv; + pmix_kval_t *kv; bool protect, nspace_given = false, rank_given = false; + pmix_info_t ginfo; char *protected[] = { PMIX_USERID, PMIX_GRPID, @@ -138,16 +122,97 @@ PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module, return rc; } - if (0 != (rc = initialize_server_base(module))) { + /* setup the server-specific globals */ + PMIX_CONSTRUCT(&pmix_server_globals.clients, pmix_pointer_array_t); + pmix_pointer_array_init(&pmix_server_globals.clients, 1, INT_MAX, 1); + PMIX_CONSTRUCT(&pmix_server_globals.collectives, pmix_list_t); + PMIX_CONSTRUCT(&pmix_server_globals.remote_pnd, pmix_list_t); + PMIX_CONSTRUCT(&pmix_server_globals.gdata, pmix_list_t); + PMIX_CONSTRUCT(&pmix_server_globals.events, pmix_list_t); + PMIX_CONSTRUCT(&pmix_server_globals.local_reqs, pmix_list_t); + PMIX_CONSTRUCT(&pmix_server_globals.nspaces, pmix_list_t); + + pmix_output_verbose(2, pmix_globals.debug_output, + "pmix:server init called"); + + /* setup the function pointers */ + memset(&pmix_host_server, 0, sizeof(pmix_server_module_t)); + pmix_host_server = *module; + + /* setup the wildcard recv for inbound messages from clients */ + req = PMIX_NEW(pmix_ptl_posted_recv_t); + req->tag = UINT32_MAX; + req->cbfunc = server_message_handler; + /* add it to the end of the list of recvs */ + pmix_list_append(&pmix_ptl_globals.posted_recvs, &req->super); + + if (PMIX_SUCCESS != pmix_ptl_base_start_listening(info, ninfo)) { + pmix_show_help("help-pmix-server.txt", "listener-thread-start", true); + PMIx_server_finalize(); + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_INIT; + } + + /* assign our internal bfrops module */ + pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module(NULL); + if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) { + PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; } + /* and set our buffer type */ + pmix_globals.mypeer->nptr->compat.type = pmix_bfrops_globals.default_type; + + /* assign our internal security module */ + pmix_globals.mypeer->nptr->compat.psec = pmix_psec_base_assign_module(NULL); + if (NULL == pmix_globals.mypeer->nptr->compat.psec) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE_THREAD(&pmix_global_lock); + return rc; + } + + /* assign our internal ptl module */ + pmix_globals.mypeer->nptr->compat.ptl = pmix_ptl_base_assign_module(); + if (NULL == pmix_globals.mypeer->nptr->compat.ptl) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE_THREAD(&pmix_global_lock); + return rc; + } + + /* assign our internal gds module */ + PMIX_INFO_LOAD(&ginfo, PMIX_GDS_MODULE, "hash", PMIX_STRING); + pmix_globals.mypeer->nptr->compat.gds = pmix_gds_base_assign_module(&ginfo, 1); + if (NULL == pmix_globals.mypeer->nptr->compat.gds) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE_THREAD(&pmix_global_lock); + return rc; + } + + /* copy need parts over to the client_globals.myserver field + * so that calls into client-side functions will use our peer */ + pmix_client_globals.myserver = PMIX_NEW(pmix_peer_t); + PMIX_RETAIN(pmix_globals.mypeer->nptr); + pmix_client_globals.myserver->nptr = pmix_globals.mypeer->nptr; + /* construct the global notification ring buffer */ + PMIX_CONSTRUCT(&pmix_globals.notifications, pmix_ring_buffer_t); + pmix_ring_buffer_init(&pmix_globals.notifications, 256); + + /* get our available security modules */ + security_mode = pmix_psec_base_get_available_modules(); + + /* get our available ptl modules */ + ptl_mode = pmix_ptl_base_get_available_modules(); + + /* get our available bfrop modules */ + bfrops_mode = pmix_bfrops_base_get_available_modules(); + + /* get available gds modules */ + gds_mode = pmix_gds_base_get_available_modules(); /* check the info keys for info we * need to provide to every client and * directives aimed at us */ if (NULL != info) { - PMIX_CONSTRUCT(&kv, pmix_kval_t); for (n=0; n < ninfo; n++) { if (0 == strncmp(info[n].key, PMIX_SERVER_NSPACE, PMIX_MAX_KEYLEN)) { (void)strncpy(pmix_globals.myid.nspace, info[n].value.data.string, PMIX_MAX_NSLEN); @@ -171,23 +236,19 @@ PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module, continue; } /* store and pass along to every client */ - kv.key = info[n].key; - kv.value = &info[n].value; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&pmix_server_globals.gdata, &kv, 1, PMIX_KVAL))) { + kv = PMIX_NEW(pmix_kval_t); + kv->key = strdup(info[n].key); + PMIX_VALUE_CREATE(kv->value, 1); + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, + kv->value, &info[n].value); + if (PMIX_SUCCESS != rc) { + PMIX_RELEASE(kv); PMIX_ERROR_LOG(rc); - pmix_show_help("help-pmix-server.txt", "data-store-failed", true, kv.key); - /* protect the incoming data */ - kv.key = NULL; - kv.value = NULL; - PMIX_DESTRUCT(&kv); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; } + pmix_list_append(&pmix_server_globals.gdata, &kv->super); } - /* protect the incoming data */ - kv.key = NULL; - kv.value = NULL; - PMIX_DESTRUCT(&kv); } if (!nspace_given) { @@ -217,48 +278,19 @@ PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module, } else { rinfo = pmix_globals.mypeer->info; } - if (NULL == rinfo->nptr) { - rinfo->nptr = PMIX_NEW(pmix_nspace_t); + if (NULL == pmix_globals.mypeer->nptr) { + pmix_globals.mypeer->nptr = PMIX_NEW(pmix_nspace_t); /* ensure our own nspace is first on the list */ - PMIX_RETAIN(rinfo->nptr); - rinfo->nptr->server = PMIX_NEW(pmix_server_nspace_t); - pmix_list_prepend(&pmix_globals.nspaces, &rinfo->nptr->super); - } - (void)strncpy(rinfo->nptr->nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN); - rinfo->rank = pmix_globals.myid.rank; - - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (PMIX_SUCCESS != (rc = pmix_dstore_init(info, ninfo))) { - PMIX_RELEASE_THREAD(&pmix_global_lock); - return rc; - } -#endif /* PMIX_ENABLE_DSTORE */ - - /* setup the wildcard recv for inbound messages from clients */ - req = PMIX_NEW(pmix_ptl_posted_recv_t); - req->tag = UINT32_MAX; - req->cbfunc = server_message_handler; - /* add it to the end of the list of recvs */ - pmix_list_append(&pmix_ptl_globals.posted_recvs, &req->super); - - if (PMIX_SUCCESS != pmix_ptl_base_start_listening(info, ninfo)) { - pmix_show_help("help-pmix-server.txt", "listener-thread-start", true); - PMIX_RELEASE_THREAD(&pmix_global_lock); - return PMIX_ERR_INIT; - } - - /* get our available security modules */ - security_mode = pmix_psec.get_available_modules(); - - /* get our available ptl modules */ - ptl_mode = pmix_ptl.get_available_modules(); - - /* just in case, assign our own default modules */ - if (PMIX_SUCCESS != (rc = pmix_psec.assign_module(pmix_globals.mypeer, NULL))) { - PMIX_RELEASE_THREAD(&pmix_global_lock); - return PMIX_ERR_INIT; + PMIX_RETAIN(pmix_globals.mypeer->nptr); + pmix_list_prepend(&pmix_server_globals.nspaces, &pmix_globals.mypeer->nptr->super); } + pmix_globals.mypeer->nptr->nspace = strdup(pmix_globals.myid.nspace); + rinfo->pname.nspace = strdup(pmix_globals.mypeer->nptr->nspace); + rinfo->pname.rank = pmix_globals.myid.rank; + rinfo->uid = pmix_globals.uid; + rinfo->gid = pmix_globals.gid; + PMIX_RETAIN(pmix_globals.mypeer->info); + pmix_client_globals.myserver->info = pmix_globals.mypeer->info; ++pmix_globals.init_cntr; PMIX_RELEASE_THREAD(&pmix_global_lock); @@ -307,8 +339,9 @@ PMIX_EXPORT pmix_status_t PMIx_server_finalize(void) PMIX_LIST_DESTRUCT(&pmix_server_globals.collectives); PMIX_LIST_DESTRUCT(&pmix_server_globals.remote_pnd); PMIX_LIST_DESTRUCT(&pmix_server_globals.local_reqs); - PMIX_DESTRUCT(&pmix_server_globals.gdata); + PMIX_LIST_DESTRUCT(&pmix_server_globals.gdata); PMIX_LIST_DESTRUCT(&pmix_server_globals.events); + PMIX_LIST_DESTRUCT(&pmix_server_globals.nspaces); if (NULL != security_mode) { free(security_mode); @@ -318,7 +351,13 @@ PMIX_EXPORT pmix_status_t PMIx_server_finalize(void) free(ptl_mode); } - pmix_bfrop_close(); + if (NULL != bfrops_mode) { + free(bfrops_mode); + } + + if (NULL != gds_mode) { + free(gds_mode); + } pmix_rte_finalize(); pmix_output_verbose(2, pmix_globals.debug_output, @@ -332,20 +371,7 @@ static void _register_nspace(int sd, short args, void *cbdata) pmix_setup_caddy_t *cd = (pmix_setup_caddy_t*)cbdata; pmix_nspace_t *nptr, *tmp; pmix_status_t rc; - size_t i, j, size; - int rank; - pmix_kval_t kv; - char **nodes=NULL, **procs=NULL; - pmix_buffer_t buf2; - pmix_info_t *iptr; - pmix_value_t val; - char *msg; -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - bool nodata = false; - pmix_buffer_t *jobdata = PMIX_NEW(pmix_buffer_t); - char *nspace = NULL; - int32_t cnt; -#endif + size_t i; PMIX_ACQUIRE_OBJECT(caddy); @@ -354,191 +380,54 @@ static void _register_nspace(int sd, short args, void *cbdata) /* see if we already have this nspace */ nptr = NULL; - PMIX_LIST_FOREACH(tmp, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(tmp, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(tmp->nspace, cd->proc.nspace)) { nptr = tmp; - /* release any existing packed data - we will replace it */ - if (0 < nptr->server->job_info.bytes_used) { - PMIX_DESTRUCT(&nptr->server->job_info); - PMIX_CONSTRUCT(&nptr->server->job_info, pmix_buffer_t); - } break; } } if (NULL == nptr) { nptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(nptr->nspace, cd->proc.nspace, PMIX_MAX_NSLEN); - nptr->server = PMIX_NEW(pmix_server_nspace_t); - pmix_list_append(&pmix_globals.nspaces, &nptr->super); + if (NULL == nptr) { + rc = PMIX_ERR_NOMEM; + goto release; + } + nptr->nspace = strdup(cd->proc.nspace); + pmix_list_append(&pmix_server_globals.nspaces, &nptr->super); } - nptr->server->nlocalprocs = cd->nlocalprocs; + nptr->nlocalprocs = cd->nlocalprocs; + /* see if we have everyone */ - if (nptr->server->nlocalprocs == pmix_list_get_size(&nptr->server->ranks)) { - nptr->server->all_registered = true; - } - /* pack the name of the nspace */ - msg = nptr->nspace; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&nptr->server->job_info, &msg, 1, PMIX_STRING))) { - PMIX_ERROR_LOG(rc); - pmix_list_remove_item(&pmix_globals.nspaces, &nptr->super); - PMIX_RELEASE(nptr); - goto release; + if (nptr->nlocalprocs == pmix_list_get_size(&nptr->ranks)) { + nptr->all_registered = true; } - /* pack the provided info */ - PMIX_CONSTRUCT(&kv, pmix_kval_t); + /* check info directives to see if we want to store this info */ for (i=0; i < cd->ninfo; i++) { - pmix_output_verbose(2, pmix_globals.debug_output, - "pmix:server _register_nspace recording %s", - cd->info[i].key); - if (0 == strcmp(cd->info[i].key, PMIX_REGISTER_NODATA)) { -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - /* we don't want to save any job data for this nspace */ - nodata = true; -#endif - /* free anything that was previously stored */ - PMIX_DESTRUCT(&nptr->server->job_info); - PMIX_CONSTRUCT(&nptr->server->job_info, pmix_buffer_t); - break; - } - if (0 == strcmp(cd->info[i].key, PMIX_NODE_MAP)) { - /* parse the regex to get the argv array of node names */ - if (PMIX_SUCCESS != (rc = pmix_regex_parse_nodes(cd->info[i].value.data.string, &nodes))) { - PMIX_ERROR_LOG(rc); - continue; - } - /* if we have already found the proc map, then pass - * the detailed map */ - if (NULL != procs) { - pmix_pack_proc_map(&nptr->server->job_info, nodes, procs); - pmix_argv_free(nodes); - nodes = NULL; - pmix_argv_free(procs); - procs = NULL; - } - } else if (0 == strcmp(cd->info[i].key, PMIX_PROC_MAP)) { - /* parse the regex to get the argv array containg proc ranks on each node */ - if (PMIX_SUCCESS != (rc = pmix_regex_parse_procs(cd->info[i].value.data.string, &procs))) { - PMIX_ERROR_LOG(rc); - continue; - } - /* if we have already recv'd the node map, then record - * the detailed map */ - if (NULL != nodes) { - pmix_pack_proc_map(&nptr->server->job_info, nodes, procs); - pmix_argv_free(nodes); - nodes = NULL; - pmix_argv_free(procs); - procs = NULL; - } - } else if (0 == strcmp(cd->info[i].key, PMIX_PROC_DATA)) { - /* an array of data pertaining to a specific proc */ - if (PMIX_DATA_ARRAY != cd->info[i].value.type || - PMIX_INFO != cd->info[i].value.data.darray->type) { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - goto release; - } - size = cd->info[i].value.data.darray->size; - iptr = (pmix_info_t*)cd->info[i].value.data.darray->array; - PMIX_CONSTRUCT(&buf2, pmix_buffer_t); - /* first element of the array must be the rank */ - if (0 != strcmp(iptr[0].key, PMIX_RANK)) { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - PMIX_DESTRUCT(&buf2); - goto release; - } - /* pack it separately */ - rank = iptr[0].value.data.rank; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&buf2, &rank, 1, PMIX_PROC_RANK))) { - PMIX_ERROR_LOG(rc); - pmix_list_remove_item(&pmix_globals.nspaces, &nptr->super); - PMIX_RELEASE(nptr); - PMIX_DESTRUCT(&buf2); - goto release; - } - /* cycle thru the values for this rank and pack them */ - for (j=1; j < size; j++) { - kv.key = iptr[j].key; - kv.value = &iptr[j].value; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&buf2, &kv, 1, PMIX_KVAL))) { - PMIX_ERROR_LOG(rc); - pmix_list_remove_item(&pmix_globals.nspaces, &nptr->super); - PMIX_RELEASE(nptr); - PMIX_DESTRUCT(&buf2); - goto release; - } - } - /* now add the blob */ - kv.key = PMIX_PROC_BLOB; - kv.value = &val; - val.type = PMIX_BYTE_OBJECT; - val.data.bo.bytes = buf2.base_ptr; - val.data.bo.size = buf2.bytes_used; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&nptr->server->job_info, &kv, 1, PMIX_KVAL))) { - PMIX_ERROR_LOG(rc); - pmix_list_remove_item(&pmix_globals.nspaces, &nptr->super); - PMIX_RELEASE(nptr); - PMIX_DESTRUCT(&buf2); - goto release; - } - PMIX_DESTRUCT(&buf2); - } else { - /* just a value relating to the entire job */ - kv.key = cd->info[i].key; - kv.value = &cd->info[i].value; - - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&nptr->server->job_info, &kv, 1, PMIX_KVAL))) { - PMIX_ERROR_LOG(rc); - pmix_list_remove_item(&pmix_globals.nspaces, &nptr->super); - PMIX_RELEASE(nptr); - goto release; - } + /* nope - so we are done */ + rc = PMIX_SUCCESS; + goto release; } } - /* do not destruct the kv object - no memory leak will result */ -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (PMIX_SUCCESS != (rc = pmix_dstore_nspace_add(cd->proc.nspace, cd->info, cd->ninfo))) { - PMIX_ERROR_LOG(rc); + /* register nspace for each activate components */ + PMIX_GDS_ADD_NSPACE(rc, nptr->nspace, cd->info, cd->ninfo); + if (PMIX_SUCCESS != rc) { goto release; } - if (!nodata) { - pmix_bfrop.copy_payload(jobdata, &nptr->server->job_info); - pmix_bfrop.copy_payload(jobdata, &pmix_server_globals.gdata); - /* unpack the nspace - we don't really need it, but have to - * unpack it to maintain sequence */ - cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(jobdata, &nspace, &cnt, PMIX_STRING))) { - PMIX_ERROR_LOG(rc); - goto release; - } - if (PMIX_SUCCESS != (rc = pmix_job_data_dstore_store(cd->proc.nspace, jobdata))) { - PMIX_ERROR_LOG(rc); - goto release; - } - } -#endif + /* store this data in our own GDS module - we will retrieve + * it later so it can be passed down to the launched procs + * once they connect to us and we know what GDS module they + * are using */ + PMIX_GDS_CACHE_JOB_INFO(rc, pmix_globals.mypeer, nptr, + cd->info, cd->ninfo); - release: - if (NULL != nodes) { - pmix_argv_free(nodes); - } - if (NULL != procs) { - pmix_argv_free(procs); - } + release: if (NULL != cd->opcbfunc) { cd->opcbfunc(rc, cd->cbdata); } -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (NULL != nspace) { - free(nspace); - } - if (NULL != jobdata) { - PMIX_RELEASE(jobdata); - } -#endif PMIX_RELEASE(cd); } @@ -577,7 +466,7 @@ static void _deregister_nspace(int sd, short args, void *cbdata) { pmix_setup_caddy_t *cd = (pmix_setup_caddy_t*)cbdata; pmix_nspace_t *tmp; - pmix_status_t rc = PMIX_SUCCESS; + pmix_status_t rc; PMIX_ACQUIRE_OBJECT(cd); @@ -586,19 +475,20 @@ static void _deregister_nspace(int sd, short args, void *cbdata) cd->proc.nspace); /* see if we already have this nspace */ - PMIX_LIST_FOREACH(tmp, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(tmp, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(tmp->nspace, cd->proc.nspace)) { - pmix_list_remove_item(&pmix_globals.nspaces, &tmp->super); + pmix_list_remove_item(&pmix_server_globals.nspaces, &tmp->super); PMIX_RELEASE(tmp); break; } } -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - rc = pmix_dstore_nspace_del(cd->proc.nspace); -#endif - - /* release any job-level resources */ + /* let our local storage clean up */ + PMIX_GDS_DEL_NSPACE(rc, cd->proc.nspace); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + } + /* release any job-level messaging resources */ pmix_pnet.local_app_finalized(cd->proc.nspace); /* release the caller */ @@ -642,11 +532,20 @@ void pmix_server_execute_collective(int sd, short args, void *cbdata) { pmix_trkr_caddy_t *tcd = (pmix_trkr_caddy_t*)cbdata; pmix_server_trkr_t *trk = tcd->trk; + pmix_server_caddy_t *cd; + pmix_peer_t *peer; char *data = NULL; size_t sz = 0; - pmix_buffer_t bucket, xfer; - pmix_rank_info_t *info; - pmix_value_t *val; + pmix_byte_object_t bo; + pmix_buffer_t bucket, pbkt; + pmix_kval_t *kv; + pmix_proc_t proc; + bool first; + pmix_status_t rc; + pmix_list_t pnames; + pmix_namelist_t *pn; + bool found; + pmix_cb_t cb; PMIX_ACQUIRE_OBJECT(tcd); @@ -660,44 +559,96 @@ void pmix_server_execute_collective(int sd, short args, void *cbdata) * participating! And only take data intended for remote * distribution as local data will be added when we send * the result to our local clients */ + if (trk->hybrid) { + /* if this is a hybrid, then we pack everything using + * the daemon-level bfrops module as each daemon is + * going to have to unpack it, and then repack it for + * each participant. */ + peer = pmix_globals.mypeer; + } else { + /* since all procs are the same, just use the first proc's module */ + cd = (pmix_server_caddy_t*)pmix_list_get_first(&trk->local_cbs); + peer = cd->peer; + } PMIX_CONSTRUCT(&bucket, pmix_buffer_t); - assert( PMIX_COLLECT_MAX < UCHAR_MAX ); unsigned char tmp = (unsigned char)trk->collect_type; - pmix_bfrop.pack(&bucket, &tmp, 1, PMIX_BYTE); + PMIX_BFROPS_PACK(rc, peer, &bucket, &tmp, 1, PMIX_BYTE); if (PMIX_COLLECT_YES == trk->collect_type) { - pmix_buffer_t databuf; - PMIX_CONSTRUCT(&databuf, pmix_buffer_t); pmix_output_verbose(2, pmix_globals.debug_output, "fence - assembling data"); - PMIX_LIST_FOREACH(info, &trk->ranks, pmix_rank_info_t) { - pmix_buffer_t rankbuf; - PMIX_CONSTRUCT(&rankbuf, pmix_buffer_t); + first = true; + PMIX_CONSTRUCT(&pnames, pmix_list_t); + PMIX_LIST_FOREACH(cd, &trk->local_cbs, pmix_server_caddy_t) { + /* see if we have already gotten the contribution from + * this proc */ + found = false; + PMIX_LIST_FOREACH(pn, &pnames, pmix_namelist_t) { + if (pn->pname == &cd->peer->info->pname) { + /* got it */ + found = true; + break; + } + } + if (found) { + continue; + } else { + pn = PMIX_NEW(pmix_namelist_t); + pn->pname = &cd->peer->info->pname; + } + if (trk->hybrid || first) { + /* setup the nspace */ + (void)strncpy(proc.nspace, cd->peer->info->pname.nspace, PMIX_MAX_NSLEN); + first = false; + } + proc.rank = cd->peer->info->pname.rank; /* get any remote contribution - note that there * may not be a contribution */ - if (PMIX_SUCCESS == pmix_hash_fetch(&info->nptr->server->myremote, info->rank, "modex", &val) && - NULL != val) { - /* pack the proc so we know the source */ - char *foobar = info->nptr->nspace; - pmix_bfrop.pack(&rankbuf, &foobar, 1, PMIX_STRING); - pmix_bfrop.pack(&rankbuf, &info->rank, 1, PMIX_PROC_RANK); - PMIX_CONSTRUCT(&xfer, pmix_buffer_t); - PMIX_LOAD_BUFFER(&xfer, val->data.bo.bytes, val->data.bo.size); - PMIX_VALUE_RELEASE(val); - pmix_buffer_t *pxfer = &xfer; - pmix_bfrop.pack(&rankbuf, &pxfer, 1, PMIX_BUFFER); - PMIX_DESTRUCT(&xfer); - /* now pack this proc's contribution into the bucket */ - pmix_buffer_t *pdatabuf = &rankbuf; - pmix_bfrop.pack(&databuf, &pdatabuf, 1, PMIX_BUFFER); + PMIX_CONSTRUCT(&cb, pmix_cb_t); + cb.proc = &proc; + cb.scope = PMIX_REMOTE; + cb.copy = true; + PMIX_GDS_FETCH_KV(rc, peer, &cb); + if (PMIX_SUCCESS == rc) { + /* pack the returned kvals */ + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + /* start with the proc id */ + PMIX_BFROPS_PACK(rc, peer, &pbkt, &proc, 1, PMIX_PROC); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&cb); + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&bucket); + return; + } + PMIX_LIST_FOREACH(kv, &cb.kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, peer, &pbkt, kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&cb); + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&bucket); + return; + } + } + /* extract the resulting byte object */ + PMIX_UNLOAD_BUFFER(&pbkt, bo.bytes, bo.size); + PMIX_DESTRUCT(&pbkt); + /* now pack that into the bucket for return */ + PMIX_BFROPS_PACK(rc, peer, &bucket, &bo, 1, PMIX_BYTE_OBJECT); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&cb); + PMIX_BYTE_OBJECT_DESTRUCT(&bo); + PMIX_DESTRUCT(&bucket); + PMIX_RELEASE(tcd); + return; + } } - PMIX_DESTRUCT(&rankbuf); + PMIX_DESTRUCT(&cb); } - // TODO: we have multiple data movings while only one is actually need - pmix_buffer_t *pbkt = &databuf; - pmix_bfrop.pack(&bucket, &pbkt, 1, PMIX_BUFFER); - PMIX_DESTRUCT(&databuf); + PMIX_LIST_DESTRUCT(&pnames); } PMIX_UNLOAD_BUFFER(&bucket, data, sz); PMIX_DESTRUCT(&bucket); @@ -724,12 +675,13 @@ void pmix_server_execute_collective(int sd, short args, void *cbdata) static void _register_client(int sd, short args, void *cbdata) { pmix_setup_caddy_t *cd = (pmix_setup_caddy_t*)cbdata; - pmix_rank_info_t *info, *iptr, *iptr2; - pmix_nspace_t *nptr, *tmp; + pmix_rank_info_t *info, *iptr; + pmix_nspace_t *nptr, *ns; pmix_server_trkr_t *trk; pmix_trkr_caddy_t *tcd; bool all_def; size_t i; + pmix_status_t rc; PMIX_ACQUIRE_OBJECT(cd); @@ -739,86 +691,85 @@ static void _register_client(int sd, short args, void *cbdata) /* see if we already have this nspace */ nptr = NULL; - PMIX_LIST_FOREACH(tmp, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strcmp(tmp->nspace, cd->proc.nspace)) { - nptr = tmp; + PMIX_LIST_FOREACH(ns, &pmix_server_globals.nspaces, pmix_nspace_t) { + if (0 == strcmp(ns->nspace, cd->proc.nspace)) { + nptr = ns; break; } } if (NULL == nptr) { nptr = PMIX_NEW(pmix_nspace_t); - (void)strncpy(nptr->nspace, cd->proc.nspace, PMIX_MAX_NSLEN); - /* add the server object */ - nptr->server = PMIX_NEW(pmix_server_nspace_t); - pmix_list_append(&pmix_globals.nspaces, &nptr->super); + if (NULL == nptr) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } + nptr->nspace = strdup(cd->proc.nspace); + pmix_list_append(&pmix_server_globals.nspaces, &nptr->super); } /* setup a peer object for this client - since the host server * only deals with the original processes and not any clones, * we know this function will be called only once per rank */ info = PMIX_NEW(pmix_rank_info_t); - PMIX_RETAIN(nptr); - info->nptr = nptr; - info->rank = cd->proc.rank; + if (NULL == info) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } + info->pname.nspace = strdup(nptr->nspace); + info->pname.rank = cd->proc.rank; info->uid = cd->uid; info->gid = cd->gid; info->server_object = cd->server_object; - pmix_list_append(&nptr->server->ranks, &info->super); + pmix_list_append(&nptr->ranks, &info->super); /* see if we have everyone */ - if (nptr->server->nlocalprocs == pmix_list_get_size(&nptr->server->ranks)) { - nptr->server->all_registered = true; + if (nptr->nlocalprocs == pmix_list_get_size(&nptr->ranks)) { + nptr->all_registered = true; /* check any pending trackers to see if they are * waiting for us. There is a slight race condition whereby * the host server could have spawned the local client and * it called back into the collective -before- our local event * would fire the register_client callback. Deal with that here. */ + all_def = true; PMIX_LIST_FOREACH(trk, &pmix_server_globals.collectives, pmix_server_trkr_t) { /* if this tracker is already complete, then we * don't need to update it */ if (trk->def_complete) { continue; } - /* see if any of our procs are involved - the tracker will + /* see if any of our procs from this nspace are involved - the tracker will * have been created because a callback was received, but - * no rank info will have been entered since the clients - * had not yet been registered. Thus, we couldn't enter rank - * objects into the tracker as we didn't know which - * of the ranks were local */ + * we may or may not have received _all_ callbacks by this + * time. So check and see if any procs from this nspace are + * involved, and add them to the count of local participants */ for (i=0; i < trk->npcs; i++) { - if (0 != strncmp(cd->proc.nspace, trk->pcs[i].nspace, PMIX_MAX_NSLEN)) { + /* since we have to do this search, let's see + * if the nspaces are all defined */ + if (all_def) { + /* so far, they have all been defined - check this one */ + PMIX_LIST_FOREACH(ns, &pmix_server_globals.nspaces, pmix_nspace_t) { + if (0 < ns->nlocalprocs && + 0 == strcmp(trk->pcs[i].nspace, ns->nspace)) { + all_def = ns->all_registered; + break; + } + } + } + /* now see if this proc is local to us */ + if (0 != strncmp(trk->pcs[i].nspace, nptr->nspace, PMIX_MAX_NSLEN)) { continue; } /* need to check if this rank is one of mine */ - PMIX_LIST_FOREACH(iptr, &nptr->server->ranks, pmix_rank_info_t) { + PMIX_LIST_FOREACH(iptr, &nptr->ranks, pmix_rank_info_t) { if (PMIX_RANK_WILDCARD == trk->pcs[i].rank || - iptr->rank == trk->pcs[i].rank) { - /* add a tracker for this proc - don't need more than - * the nspace pointer and rank */ - iptr2 = PMIX_NEW(pmix_rank_info_t); - PMIX_RETAIN(info->nptr); - iptr2->nptr = info->nptr; - iptr2->rank = info->rank; - pmix_list_append(&trk->ranks, &iptr2->super); - /* track the count */ + iptr->pname.rank == trk->pcs[i].rank) { + /* this is one of mine - track the count */ ++trk->nlocal; + break; } } } - /* we need to know if this tracker is now complete - the only - * way to do this is to check if all participating - * nspaces are fully registered */ - all_def = true; - /* search all the involved procs - fortunately, this - * list is usually very small */ - PMIX_LIST_FOREACH(iptr, &trk->ranks, pmix_rank_info_t) { - if (!iptr->nptr->server->all_registered) { - /* nope */ - all_def = false; - break; - } - } /* update this tracker's status */ trk->def_complete = all_def; - /* is this now completed? */ + /* is this now locally completed? */ if (trk->def_complete && pmix_list_get_size(&trk->local_cbs) == trk->nlocal) { /* it did, so now we need to process it * we don't want to block someone @@ -833,9 +784,12 @@ static void _register_client(int sd, short args, void *cbdata) * and so couldn't determine the proc was remote */ pmix_pending_nspace_requests(nptr); } + rc = PMIX_SUCCESS; + + cleanup: /* let the caller know we are done */ if (NULL != cd->opcbfunc) { - cd->opcbfunc(PMIX_SUCCESS, cd->cbdata); + cd->opcbfunc(rc, cd->cbdata); } PMIX_RELEASE(cd); } @@ -857,7 +811,10 @@ PMIX_EXPORT pmix_status_t PMIx_server_register_client(const pmix_proc_t *proc, "pmix:server register client %s:%d", proc->nspace, proc->rank); - cd = PMIX_NEW(pmix_setup_caddy_t); + cd = PMIX_NEW(pmix_setup_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } (void)strncpy(cd->proc.nspace, proc->nspace, PMIX_MAX_NSLEN); cd->proc.rank = proc->rank; cd->uid = uid; @@ -886,7 +843,7 @@ static void _deregister_client(int sd, short args, void *cbdata) /* see if we already have this nspace */ nptr = NULL; - PMIX_LIST_FOREACH(tmp, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(tmp, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(tmp->nspace, cd->proc.nspace)) { nptr = tmp; break; @@ -897,9 +854,9 @@ static void _deregister_client(int sd, short args, void *cbdata) goto cleanup; } /* find and remove this client */ - PMIX_LIST_FOREACH(info, &nptr->server->ranks, pmix_rank_info_t) { - if (info->rank == cd->proc.rank) { - pmix_list_remove_item(&nptr->server->ranks, &info->super); + PMIX_LIST_FOREACH(info, &nptr->ranks, pmix_rank_info_t) { + if (info->pname.rank == cd->proc.rank) { + pmix_list_remove_item(&nptr->ranks, &info->super); PMIX_RELEASE(info); break; } @@ -931,7 +888,13 @@ PMIX_EXPORT void PMIx_server_deregister_client(const pmix_proc_t *proc, "pmix:server deregister client %s:%d", proc->nspace, proc->rank); - cd = PMIX_NEW(pmix_setup_caddy_t); + cd = PMIX_NEW(pmix_setup_caddy_t); + if (NULL == cd) { + if (NULL != cbfunc) { + cbfunc(PMIX_ERR_NOMEM, cbdata); + } + return; + } (void)strncpy(cd->proc.nspace, proc->nspace, PMIX_MAX_NSLEN); cd->proc.rank = proc->rank; cd->opcbfunc = cbfunc; @@ -975,14 +938,16 @@ PMIX_EXPORT pmix_status_t PMIx_server_setup_fork(const pmix_proc_t *proc, char * pmix_setenv("PMIX_SECURITY_MODE", security_mode, true, env); /* pass our available ptl modules */ pmix_setenv("PMIX_PTL_MODULE", ptl_mode, true, env); - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - /* pass dstore path to files */ - if (PMIX_SUCCESS != (rc = pmix_dstore_patch_env(proc->nspace, env))) { - PMIX_ERROR_LOG(rc); - return rc; + /* pass our available bfrop modes */ + pmix_setenv("PMIX_BFROP_MODULE", bfrops_mode, true, env); + /* pass the type of buffer we are using */ + if (PMIX_BFROP_BUFFER_FULLY_DESC == pmix_globals.mypeer->nptr->compat.type) { + pmix_setenv("PMIX_BFROP_BUFFER_TYPE", "PMIX_BFROP_BUFFER_FULLY_DESC", true, env); + } else { + pmix_setenv("PMIX_BFROP_BUFFER_TYPE", "PMIX_BFROP_BUFFER_NON_DESC", true, env); } -#endif + /* pass our available gds modules */ + pmix_setenv("PMIX_GDS_MODULE", gds_mode, true, env); /* get any network contribution */ if (PMIX_SUCCESS != (rc = pmix_pnet.setup_fork(proc, env))) { @@ -990,6 +955,12 @@ PMIX_EXPORT pmix_status_t PMIx_server_setup_fork(const pmix_proc_t *proc, char * return rc; } + /* get any GDS contributions */ + if (PMIX_SUCCESS != (rc = pmix_gds_base_setup_fork(proc, env))) { + PMIX_ERROR_LOG(rc); + return rc; + } + return PMIX_SUCCESS; } @@ -1003,24 +974,26 @@ static void _dmodex_req(int sd, short args, void *cbdata) pmix_setup_caddy_t *cd = (pmix_setup_caddy_t*)cbdata; pmix_rank_info_t *info, *iptr; pmix_nspace_t *nptr, *ns; - pmix_buffer_t pbkt; - pmix_value_t *val; char *data = NULL; size_t sz = 0; pmix_dmdx_remote_t *dcd; pmix_status_t rc; + pmix_buffer_t pbkt; + pmix_kval_t *kv; + pmix_cb_t cb; PMIX_ACQUIRE_OBJECT(cd); pmix_output_verbose(2, pmix_globals.debug_output, "DMODX LOOKING FOR %s:%d", cd->proc.nspace, cd->proc.rank); + /* this should be one of my clients, but a race condition * could cause this request to arrive prior to us having * been informed of it - so first check to see if we know * about this nspace yet */ nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(ns, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(ns->nspace, cd->proc.nspace)) { nptr = ns; break; @@ -1031,6 +1004,10 @@ static void _dmodex_req(int sd, short args, void *cbdata) * haven't received the data from this proc yet - defer * the request until we do */ dcd = PMIX_NEW(pmix_dmdx_remote_t); + if (NULL == dcd) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } PMIX_RETAIN(cd); dcd->cd = cd; pmix_list_append(&pmix_server_globals.remote_pnd, &dcd->super); @@ -1040,20 +1017,42 @@ static void _dmodex_req(int sd, short args, void *cbdata) /* They are asking for job level data for this process */ if (cd->proc.rank == PMIX_RANK_WILDCARD) { - - data = nptr->server->job_info.base_ptr; - sz = nptr->server->job_info.bytes_used; - - /* execute the callback */ - cd->cbfunc(PMIX_SUCCESS, data, sz, cd->cbdata); - PMIX_WAKEUP_THREAD(&cd->lock); // ensure the request doesn't hang - return; + /* fetch the job-level info for this nspace */ + /* this is going to a remote peer, so inform the gds + * that we need an actual copy of the data */ + PMIX_CONSTRUCT(&cb, pmix_cb_t); + cb.proc = &cd->proc; + cb.scope = PMIX_REMOTE; + cb.copy = true; + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, &cb); + if (PMIX_SUCCESS == rc) { + /* assemble the provided data into a byte object */ + PMIX_LIST_FOREACH(kv, &cb.kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &pbkt, kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&cb); + goto cleanup; + } + } + } + PMIX_DESTRUCT(&cb); + PMIX_UNLOAD_BUFFER(&pbkt, data, sz); + PMIX_DESTRUCT(&pbkt); + /* execute the callback */ + cd->cbfunc(rc, data, sz, cd->cbdata); + PMIX_WAKEUP_THREAD(&cd->lock); // ensure the request doesn't hang + if (NULL != data) { + free(data); + } + return; } /* see if we have this peer in our list */ info = NULL; - PMIX_LIST_FOREACH(iptr, &nptr->server->ranks, pmix_rank_info_t) { - if (iptr->rank == cd->proc.rank) { + PMIX_LIST_FOREACH(iptr, &nptr->ranks, pmix_rank_info_t) { + if (iptr->pname.rank == cd->proc.rank) { info = iptr; break; } @@ -1083,19 +1082,28 @@ static void _dmodex_req(int sd, short args, void *cbdata) } /* collect the remote/global data from this proc */ - PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); - /* get any remote contribution - note that there - * may not be a contribution */ - if (PMIX_SUCCESS == (rc = pmix_hash_fetch(&nptr->server->myremote, info->rank, "modex", &val)) && - NULL != val) { - data = val->data.bo.bytes; - sz = val->data.bo.size; - /* protect the data */ - val->data.bo.bytes = NULL; - val->data.bo.size = 0; - PMIX_VALUE_RELEASE(val); + PMIX_CONSTRUCT(&cb, pmix_cb_t); + cb.proc = &cd->proc; + cb.scope = PMIX_REMOTE; + cb.copy = true; + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, &cb); + if (PMIX_SUCCESS == rc) { + /* assemble the provided data into a byte object */ + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + PMIX_LIST_FOREACH(kv, &cb.kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &pbkt, kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&cb); + goto cleanup; + } + } + PMIX_UNLOAD_BUFFER(&pbkt, data, sz); + PMIX_DESTRUCT(&pbkt); } + PMIX_DESTRUCT(&cb); + cleanup: /* execute the callback */ cd->cbfunc(rc, data, sz, cd->cbdata); if (NULL != data) { @@ -1144,23 +1152,14 @@ PMIX_EXPORT pmix_status_t PMIx_server_dmodex_request(const pmix_proc_t *proc, static void _store_internal(int sd, short args, void *cbdata) { pmix_shift_caddy_t *cd = (pmix_shift_caddy_t*)cbdata; - pmix_nspace_t *ns, *nsptr; + pmix_proc_t proc; PMIX_ACQUIRE_OBJECT(cd); - ns = NULL; - PMIX_LIST_FOREACH(nsptr, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strncmp(cd->nspace, nsptr->nspace, PMIX_MAX_NSLEN)) { - ns = nsptr; - break; - } - } - if (NULL == ns) { - /* shouldn't be possible */ - cd->status = PMIX_ERR_NOT_FOUND; - } else { - cd->status = pmix_hash_store(&ns->internal, cd->rank, cd->kv); - } + (void)strncpy(proc.nspace, cd->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = cd->pname.rank; + PMIX_GDS_STORE_KV(cd->status, pmix_globals.mypeer, + &proc, PMIX_INTERNAL, cd->kv); if (cd->lock.active) { PMIX_WAKEUP_THREAD(&cd->lock); } @@ -1181,13 +1180,20 @@ PMIX_EXPORT pmix_status_t PMIx_Store_internal(const pmix_proc_t *proc, /* setup to thread shift this request */ cd = PMIX_NEW(pmix_shift_caddy_t); - cd->nspace = proc->nspace; - cd->rank = proc->rank; + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } + cd->pname.nspace = strdup(proc->nspace); + cd->pname.rank = proc->rank; cd->kv = PMIX_NEW(pmix_kval_t); + if (NULL == cd->kv) { + PMIX_RELEASE(cd); + return PMIX_ERR_NOMEM; + } cd->kv->key = strdup((char*)key); cd->kv->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); - rc = pmix_value_xfer(cd->kv->value, val); + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, cd->kv->value, val); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(cd); @@ -1202,21 +1208,8 @@ PMIX_EXPORT pmix_status_t PMIx_Store_internal(const pmix_proc_t *proc, return rc; } -#define PMIX_MAX_NODE_PREFIX 50 - PMIX_EXPORT pmix_status_t PMIx_generate_regex(const char *input, char **regexp) { - char *vptr, *vsave; - char prefix[PMIX_MAX_NODE_PREFIX]; - int i, j, len, startnum, vnum, numdigits; - bool found, fullval; - char *suffix, *sfx; - pmix_regex_value_t *vreg; - pmix_regex_range_t *range; - pmix_list_t vids; - char **regexargs = NULL, *tmp, *tmp2; - char *cptr; - PMIX_ACQUIRE_THREAD(&pmix_global_lock); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); @@ -1224,231 +1217,11 @@ PMIX_EXPORT pmix_status_t PMIx_generate_regex(const char *input, char **regexp) } PMIX_RELEASE_THREAD(&pmix_global_lock); - /* define the default */ - *regexp = NULL; - - /* setup the list of results */ - PMIX_CONSTRUCT(&vids, pmix_list_t); - - /* cycle thru the array of input values - first copy - * it so we don't overwrite what we were given*/ - vsave = strdup(input); - vptr = vsave; - while (NULL != (cptr = strchr(vptr, ',')) || 0 < strlen(vptr)) { - if (NULL != cptr) { - *cptr = '\0'; - } - /* determine this node's prefix by looking for first non-alpha char */ - fullval = false; - len = strlen(vptr); - startnum = -1; - memset(prefix, 0, PMIX_MAX_NODE_PREFIX); - numdigits = 0; - for (i=0, j=0; i < len; i++) { - if (!isalpha(vptr[i])) { - /* found a non-alpha char */ - if (!isdigit(vptr[i])) { - /* if it is anything but a digit, we just use - * the entire name - */ - fullval = true; - break; - } - /* count the size of the numeric field - but don't - * add the digits to the prefix - */ - numdigits++; - if (startnum < 0) { - /* okay, this defines end of the prefix */ - startnum = i; - } - continue; - } - if (startnum < 0) { - prefix[j++] = vptr[i]; - } - } - if (fullval || startnum < 0) { - /* can't compress this name - just add it to the list */ - vreg = PMIX_NEW(pmix_regex_value_t); - vreg->prefix = strdup(vptr); - pmix_list_append(&vids, &vreg->super); - /* move to the next posn */ - if (NULL == cptr) { - break; - } - vptr = cptr + 1; - continue; - } - /* convert the digits and get any suffix */ - vnum = strtol(&vptr[startnum], &sfx, 10); - if (NULL != sfx) { - suffix = strdup(sfx); - } else { - suffix = NULL; - } - /* is this value already on our list? */ - found = false; - PMIX_LIST_FOREACH(vreg, &vids, pmix_regex_value_t) { - if (0 < strlen(prefix) && NULL == vreg->prefix) { - continue; - } - if (0 == strlen(prefix) && NULL != vreg->prefix) { - continue; - } - if (0 < strlen(prefix) && NULL != vreg->prefix - && 0 != strcmp(prefix, vreg->prefix)) { - continue; - } - if (NULL == suffix && NULL != vreg->suffix) { - continue; - } - if (NULL != suffix && NULL == vreg->suffix) { - continue; - } - if (NULL != suffix && NULL != vreg->suffix && - 0 != strcmp(suffix, vreg->suffix)) { - continue; - } - if (numdigits != vreg->num_digits) { - continue; - } - /* found a match - flag it */ - found = true; - /* get the last range on this nodeid - we do this - * to preserve order - */ - range = (pmix_regex_range_t*)pmix_list_get_last(&vreg->ranges); - if (NULL == range) { - /* first range for this value */ - range = PMIX_NEW(pmix_regex_range_t); - range->start = vnum; - range->cnt = 1; - pmix_list_append(&vreg->ranges, &range->super); - break; - } - /* see if the value is out of sequence */ - if (vnum != (range->start + range->cnt)) { - /* start a new range */ - range = PMIX_NEW(pmix_regex_range_t); - range->start = vnum; - range->cnt = 1; - pmix_list_append(&vreg->ranges, &range->super); - break; - } - /* everything matches - just increment the cnt */ - range->cnt++; - break; - } - if (!found) { - /* need to add it */ - vreg = PMIX_NEW(pmix_regex_value_t); - if (0 < strlen(prefix)) { - vreg->prefix = strdup(prefix); - } - if (NULL != suffix) { - vreg->suffix = strdup(suffix); - } - vreg->num_digits = numdigits; - pmix_list_append(&vids, &vreg->super); - /* record the first range for this value - we took - * care of values we can't compress above - */ - range = PMIX_NEW(pmix_regex_range_t); - range->start = vnum; - range->cnt = 1; - pmix_list_append(&vreg->ranges, &range->super); - } - if (NULL != suffix) { - free(suffix); - } - /* move to the next posn */ - if (NULL == cptr) { - break; - } - vptr = cptr + 1; - } - free(vsave); - - /* begin constructing the regular expression */ - while (NULL != (vreg = (pmix_regex_value_t*)pmix_list_remove_first(&vids))) { - /* if no ranges, then just add the name */ - if (0 == pmix_list_get_size(&vreg->ranges)) { - if (NULL != vreg->prefix) { - /* solitary value */ - if (0 > asprintf(&tmp, "%s", vreg->prefix)) { - return PMIX_ERR_NOMEM; - } - pmix_argv_append_nosize(®exargs, tmp); - free(tmp); - } - PMIX_RELEASE(vreg); - continue; - } - /* start the regex for this value with the prefix */ - if (NULL != vreg->prefix) { - if (0 > asprintf(&tmp, "%s[%d:", vreg->prefix, vreg->num_digits)) { - return PMIX_ERR_NOMEM; - } - } else { - if (0 > asprintf(&tmp, "[%d:", vreg->num_digits)) { - return PMIX_ERR_NOMEM; - } - } - /* add the ranges */ - while (NULL != (range = (pmix_regex_range_t*)pmix_list_remove_first(&vreg->ranges))) { - if (1 == range->cnt) { - if (0 > asprintf(&tmp2, "%s%d,", tmp, range->start)) { - return PMIX_ERR_NOMEM; - } - } else { - if (0 > asprintf(&tmp2, "%s%d-%d,", tmp, range->start, range->start + range->cnt - 1)) { - return PMIX_ERR_NOMEM; - } - } - free(tmp); - tmp = tmp2; - PMIX_RELEASE(range); - } - /* replace the final comma */ - tmp[strlen(tmp)-1] = ']'; - if (NULL != vreg->suffix) { - /* add in the suffix, if provided */ - if (0 > asprintf(&tmp2, "%s%s", tmp, vreg->suffix)) { - return PMIX_ERR_NOMEM; - } - free(tmp); - tmp = tmp2; - } - pmix_argv_append_nosize(®exargs, tmp); - free(tmp); - PMIX_RELEASE(vreg); - } - - /* assemble final result */ - tmp = pmix_argv_join(regexargs, ','); - if (0 > asprintf(regexp, "pmix[%s]", tmp)) { - return PMIX_ERR_NOMEM; - } - free(tmp); - - /* cleanup */ - pmix_argv_free(regexargs); - - PMIX_DESTRUCT(&vids); - return PMIX_SUCCESS; + return pmix_preg.generate_node_regex(input, regexp); } PMIX_EXPORT pmix_status_t PMIx_generate_ppn(const char *input, char **regexp) { - char **ppn, **npn; - int i, j, start, end; - pmix_regex_value_t *vreg; - pmix_regex_range_t *rng; - pmix_list_t nodes; - char *tmp, *tmp2; - char *cptr; - PMIX_ACQUIRE_THREAD(&pmix_global_lock); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); @@ -1456,111 +1229,7 @@ PMIX_EXPORT pmix_status_t PMIx_generate_ppn(const char *input, char **regexp) } PMIX_RELEASE_THREAD(&pmix_global_lock); - /* define the default */ - *regexp = NULL; - - /* setup the list of results */ - PMIX_CONSTRUCT(&nodes, pmix_list_t); - - /* split the input by node */ - ppn = pmix_argv_split(input, ';'); - - /* for each node, split the input by comma */ - for (i=0; NULL != ppn[i]; i++) { - rng = NULL; - /* create a record for this node */ - vreg = PMIX_NEW(pmix_regex_value_t); - pmix_list_append(&nodes, &vreg->super); - /* split the input for this node */ - npn = pmix_argv_split(ppn[i], ','); - /* look at each element */ - for (j=0; NULL != npn[j]; j++) { - /* is this a range? */ - if (NULL != (cptr = strchr(npn[j], '-'))) { - /* terminate the string */ - *cptr = '\0'; - ++cptr; - start = strtol(npn[j], NULL, 10); - end = strtol(cptr, NULL, 10); - /* are we collecting a range? */ - if (NULL == rng) { - /* no - better start one */ - rng = PMIX_NEW(pmix_regex_range_t); - rng->start = start; - rng->cnt = end - start + 1; - pmix_list_append(&vreg->ranges, &rng->super); - } else { - /* is this a continuation of the current range? */ - if (start == (rng->start + rng->cnt)) { - /* just add it to the end of this range */ - rng->cnt++; - } else { - /* nope, there is a break - create new range */ - rng = PMIX_NEW(pmix_regex_range_t); - rng->start = start; - rng->cnt = end - start + 1; - pmix_list_append(&vreg->ranges, &rng->super); - } - } - } else { - /* single rank given */ - start = strtol(npn[j], NULL, 10); - /* are we collecting a range? */ - if (NULL == rng) { - /* no - better start one */ - rng = PMIX_NEW(pmix_regex_range_t); - rng->start = start; - rng->cnt = 1; - pmix_list_append(&vreg->ranges, &rng->super); - } else { - /* is this a continuation of the current range? */ - if (start == (rng->start + rng->cnt)) { - /* just add it to the end of this range */ - rng->cnt++; - } else { - /* nope, there is a break - create new range */ - rng = PMIX_NEW(pmix_regex_range_t); - rng->start = start; - rng->cnt = 1; - pmix_list_append(&vreg->ranges, &rng->super); - } - } - } - } - pmix_argv_free(npn); - } - pmix_argv_free(ppn); - - - /* begin constructing the regular expression */ - tmp = strdup("pmix["); - PMIX_LIST_FOREACH(vreg, &nodes, pmix_regex_value_t) { - while (NULL != (rng = (pmix_regex_range_t*)pmix_list_remove_first(&vreg->ranges))) { - if (1 == rng->cnt) { - if (0 > asprintf(&tmp2, "%s%d,", tmp, rng->start)) { - return PMIX_ERR_NOMEM; - } - } else { - if (0 > asprintf(&tmp2, "%s%d-%d,", tmp, rng->start, rng->start + rng->cnt - 1)) { - return PMIX_ERR_NOMEM; - } - } - free(tmp); - tmp = tmp2; - PMIX_RELEASE(rng); - } - /* replace the final comma */ - tmp[strlen(tmp)-1] = ';'; - } - - /* replace the final semi-colon */ - tmp[strlen(tmp)-1] = ']'; - - /* assemble final result */ - *regexp = tmp; - - PMIX_LIST_DESTRUCT(&nodes); - return PMIX_SUCCESS; + return pmix_preg.generate_ppn(input, regexp); } static void _setup_op(pmix_status_t rc, void *cbdata) @@ -1605,7 +1274,9 @@ static void _setup_app(int sd, short args, void *cbdata) n = 0; PMIX_LIST_FOREACH(kv, &ilist, pmix_kval_t) { (void)strncpy(fcd->info[n].key, kv->key, PMIX_MAX_KEYLEN); - if (PMIX_SUCCESS != (rc = pmix_value_xfer(&fcd->info[n].value, kv->value))) { + PMIX_BFROPS_VALUE_XFER(rc, pmix_globals.mypeer, + &fcd->info[n].value, kv->value); + if (PMIX_SUCCESS != rc) { PMIX_INFO_FREE(fcd->info, fcd->ninfo); PMIX_RELEASE(fcd); fcd = NULL; @@ -1730,8 +1401,13 @@ static void op_cbfunc(pmix_status_t status, void *cbdata) * being accessed */ /* setup the reply with the returned status */ - reply = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &status, 1, PMIX_STATUS))) { + if (NULL == (reply = PMIX_NEW(pmix_buffer_t))) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + PMIX_RELEASE(cd); + return; + } + PMIX_BFROPS_PACK(rc, cd->peer, reply, &status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(reply); PMIX_RELEASE(cd); @@ -1741,7 +1417,8 @@ static void op_cbfunc(pmix_status_t status, void *cbdata) /* the function that created the server_caddy did a * retain on the peer, so we don't have to worry about * it still being present - send a copy to the originator */ - if (PMIX_SUCCESS != (rc = pmix_ptl.send_oneway(cd->peer, reply, cd->hdr.tag))) { + PMIX_PTL_SEND_ONEWAY(rc, cd->peer, reply, cd->hdr.tag); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(reply); } @@ -1753,39 +1430,55 @@ static void op_cbfunc(pmix_status_t status, void *cbdata) static void _spcb(int sd, short args, void *cbdata) { pmix_shift_caddy_t *cd = (pmix_shift_caddy_t*)cbdata; - pmix_nspace_t *nptr, *ns; pmix_buffer_t *reply; pmix_status_t rc; - char *msg; + pmix_proc_t proc; + pmix_cb_t cb; + pmix_kval_t *kv; PMIX_ACQUIRE_OBJECT(cd); /* setup the reply with the returned status */ - reply = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &cd->status, 1, PMIX_STATUS))) { + if (NULL == (reply = PMIX_NEW(pmix_buffer_t))) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + PMIX_RELEASE(cd->cd); + PMIX_WAKEUP_THREAD(&cd->lock); + return; + } + PMIX_BFROPS_PACK(rc, cd->cd->peer, reply, &cd->status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(cd->cd); PMIX_WAKEUP_THREAD(&cd->lock); return; } if (PMIX_SUCCESS == cd->status) { - /* add any job-related info we have on that nspace - this will - * include the name of the nspace */ - nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strcmp(ns->nspace, cd->nspace)) { - nptr = ns; - break; + /* pass back the name of the nspace */ + PMIX_BFROPS_PACK(rc, cd->cd->peer, reply, &cd->pname.nspace, 1, PMIX_STRING); + /* add the job-level info, if we have it */ + (void)strncpy(proc.nspace, cd->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = PMIX_RANK_WILDCARD; + /* this is going to a local client, so let the gds + * have the option of returning a copy of the data, + * or a pointer to local storage */ + PMIX_CONSTRUCT(&cb, pmix_cb_t); + cb.proc = &proc; + cb.scope = PMIX_SCOPE_UNDEF; + cb.copy = false; + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, &cb); + if (PMIX_SUCCESS == rc) { + PMIX_LIST_FOREACH(kv, &cb.kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, cd->cd->peer, reply, kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(cd->cd); + PMIX_RELEASE(reply); + PMIX_DESTRUCT(&cb); + PMIX_WAKEUP_THREAD(&cd->lock); + return; + } } - } - if (NULL == nptr) { - /* This can happen if there are no processes from this - * namespace running on this host. In this case just - * pack the name of the namespace because we need that. */ - msg = (char*)cd->nspace; - pmix_bfrop.pack(reply, &msg, 1, PMIX_STRING); - } else { - pmix_bfrop.copy_payload(reply, &nptr->server->job_info); + PMIX_DESTRUCT(&cb); } } @@ -1805,7 +1498,7 @@ static void spawn_cbfunc(pmix_status_t status, char *nspace, void *cbdata) /* need to thread-shift this request */ cd = PMIX_NEW(pmix_shift_caddy_t); cd->status = status; - cd->nspace = nspace; + cd->pname.nspace = strdup(nspace); cd->cd = (pmix_server_caddy_t*)cbdata;; PMIX_THREADSHIFT(cd, _spcb); @@ -1821,22 +1514,28 @@ static void lookup_cbfunc(pmix_status_t status, pmix_pdata_t pdata[], size_t nda pmix_status_t rc; /* no need to thread-shift as no global data is accessed */ - /* setup the reply with the returned status */ - reply = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &status, 1, PMIX_STATUS))) { + if (NULL == (reply = PMIX_NEW(pmix_buffer_t))) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + PMIX_RELEASE(cd); + return; + } + PMIX_BFROPS_PACK(rc, cd->peer, reply, &status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(reply); return; } if (PMIX_SUCCESS == status) { /* pack the returned data objects */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &ndata, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, cd->peer, reply, &ndata, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(reply); return; } - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, pdata, ndata, PMIX_PDATA))) { + PMIX_BFROPS_PACK(rc, cd->peer, reply, pdata, ndata, PMIX_PDATA); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(reply); return; @@ -1851,23 +1550,32 @@ static void lookup_cbfunc(pmix_status_t status, pmix_pdata_t pdata[], size_t nda PMIX_RELEASE(cd); } +/* fence modex calls return here when the host RM has completed + * the operation - any enclosed data is provided to us as a blob + * which contains byte objects, one for each set of data. Our + * peer servers will have packed the blobs using our common + * GDS module, so use the mypeer one to unpack them */ static void _mdxcbfunc(int sd, short argc, void *cbdata) { pmix_shift_caddy_t *scd = (pmix_shift_caddy_t*)cbdata; pmix_server_trkr_t *tracker = scd->tracker; - pmix_buffer_t xfer, *bptr, *databuf=NULL, *bpscope, *reply; - pmix_nspace_t *nptr, *ns; + pmix_buffer_t xfer, *reply, bkt; + pmix_byte_object_t bo, bo2; pmix_server_caddy_t *cd; - char *nspace; - int rank; - pmix_status_t rc = PMIX_SUCCESS; + pmix_status_t rc = PMIX_SUCCESS, ret; + pmix_nspace_caddy_t *nptr; + pmix_list_t nslist; int32_t cnt = 1; char byte; + bool found; + pmix_collect_t ctype; PMIX_ACQUIRE_OBJECT(scd); /* pass the blobs being returned */ PMIX_CONSTRUCT(&xfer, pmix_buffer_t); + PMIX_LOAD_BUFFER(pmix_globals.mypeer, &xfer, scd->data, scd->ndata); + PMIX_CONSTRUCT(&nslist, pmix_list_t); if (PMIX_SUCCESS != scd->status) { rc = scd->status; @@ -1879,141 +1587,115 @@ static void _mdxcbfunc(int sd, short argc, void *cbdata) goto finish_collective; } - PMIX_LOAD_BUFFER(&xfer, scd->data, scd->ndata); + // Skip the data if we didn't collect it + if (PMIX_COLLECT_YES != tracker->collect_type) { + rc = PMIX_SUCCESS; + goto finish_collective; + } - /* if data was returned, unpack and store it */ - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(&xfer, &byte, &cnt, PMIX_BYTE))) { - pmix_collect_t ctype = (pmix_collect_t)byte; + // collect the pmix_nspace_t's of all local participants + PMIX_LIST_FOREACH(cd, &tracker->local_cbs, pmix_server_caddy_t) { + // see if we already have this nspace + found = false; + PMIX_LIST_FOREACH(nptr, &nslist, pmix_nspace_caddy_t) { + if (nptr->ns == cd->peer->nptr) { + found = true; + break; + } + } + if (!found) { + // add it + nptr = PMIX_NEW(pmix_nspace_caddy_t); + PMIX_RETAIN(cd->peer->nptr); + nptr->ns = cd->peer->nptr; + pmix_list_append(&nslist, &nptr->super); + } + } + + /* Loop over the enclosed byte object envelopes and + * store them in our GDS module */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, + &xfer, &bo, &cnt, PMIX_BYTE_OBJECT); + while (PMIX_SUCCESS == rc) { + PMIX_LOAD_BUFFER(pmix_globals.mypeer, &bkt, bo.bytes, bo.size); + /* unpack the data collection flag */ + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, + &bkt, &byte, &cnt, PMIX_BYTE); + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER == rc) { + /* no data was returned, so we are done with this blob */ + break; + } + if (PMIX_SUCCESS != rc) { + /* we have an error */ + break; + } // Check that this blob was accumulated with the same data collection setting + ctype = (pmix_collect_t)byte; if (ctype != tracker->collect_type) { rc = PMIX_ERR_INVALID_ARG; - goto finish_collective; + break; } - - // Skip the rest of the iteration if there is no data - if (PMIX_COLLECT_YES != tracker->collect_type) { - continue; - } - - // Extract the node-wise blob containing rank data + /* unpack the enclosed blobs from the various peers */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(&xfer, &databuf, &cnt, PMIX_BUFFER))) { - rc = PMIX_ERR_DATA_VALUE_NOT_FOUND; - goto finish_collective; - } - - // Loop over rank blobs - cnt = 1; - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(databuf, &bptr, &cnt, PMIX_BUFFER))) { - /* unpack the nspace */ - cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(bptr, &nspace, &cnt, PMIX_STRING))) { - PMIX_ERROR_LOG(rc); - goto finish_collective; - } - pmix_output_verbose(2, pmix_globals.debug_output, - "server:modex_cbfunc unpacked blob for npsace %s", nspace); - /* find the nspace object */ - nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strcmp(nspace, ns->nspace)) { - nptr = ns; + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, + &bkt, &bo2, &cnt, PMIX_BYTE_OBJECT); + while (PMIX_SUCCESS == rc) { + /* unpack all the kval's from this peer and store them in + * our GDS. Note that PMIx by design holds all data at + * the server level until requested. If our GDS is a + * shared memory region, then the data may be available + * right away - but the client still has to be notified + * of its presence. */ + PMIX_LIST_FOREACH(nptr, &nslist, pmix_nspace_caddy_t) { + PMIX_GDS_STORE_MODEX(rc, nptr->ns, &tracker->local_cbs, &bo2); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); break; } } - - if (NULL == nptr) { - /* Shouldn't happen. The Fence is performed among well-known - * set of processes in known namespaces. Consider this as - * unrecoverable fault. - */ - pmix_output_verbose(8, pmix_globals.debug_output, - "modex_cbfunc: unknown nspace %s, Fence ", nspace); - free(nspace); - /* - * TODO: if some namespaces are OK and the bad one is not the first - * the server is in inconsistent state. Should we rely on the client to abort - * computation or this is our task? - */ - rc = PMIX_ERR_INVALID_NAMESPACE; - goto finish_collective; - } - free(nspace); - - /* unpack the rank */ - cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(bptr, &rank, &cnt, PMIX_PROC_RANK))) { - PMIX_ERROR_LOG(rc); - goto finish_collective; - } - pmix_output_verbose(2, pmix_globals.debug_output, - "client:unpack fence received blob for rank %d", rank); - /* there may be multiple blobs for this rank, each from a different scope */ - cnt = 1; - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(bptr, &bpscope, &cnt, PMIX_BUFFER))) { - /* don't store blobs to the sm dstore from local clients */ - if (_my_client(nptr->nspace, rank)) { - continue; - } - pmix_kval_t *kp = PMIX_NEW(pmix_kval_t); - kp->key = strdup("modex"); - PMIX_VALUE_CREATE(kp->value, 1); - kp->value->type = PMIX_BYTE_OBJECT; - PMIX_UNLOAD_BUFFER(bpscope, kp->value->data.bo.bytes, kp->value->data.bo.size); - /* store it in the appropriate hash */ - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nptr->server->remote, rank, kp))) { - PMIX_ERROR_LOG(rc); - } -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (PMIX_SUCCESS != (rc = pmix_dstore_store(nptr->nspace, rank, kp))) { - PMIX_ERROR_LOG(rc); - } -#endif /* PMIX_ENABLE_DSTORE */ - PMIX_RELEASE(kp); // maintain acctg - } // while bpscope - if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { - PMIX_ERROR_LOG(rc); - /* - * TODO: if some buffers are OK and the bad one is not the first - * the server is in inconsistent state. Should we rely on the client to abort - * computation or this is our task? - */ - goto finish_collective; - } - PMIX_RELEASE(bpscope); - PMIX_RELEASE(bptr); + PMIX_BYTE_OBJECT_DESTRUCT(&bo2); + /* get the next blob */ cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, + &bkt, &bo2, &cnt, PMIX_BYTE_OBJECT); } - if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { - goto finish_collective; - } else { + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER == rc) { rc = PMIX_SUCCESS; + } else if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + goto finish_collective; } + /* unpack and process the next blob */ cnt = 1; - } // while bptr - + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, + &xfer, &bo, &cnt, PMIX_BYTE_OBJECT); + } if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER == rc) { rc = PMIX_SUCCESS; + } else if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); } finish_collective: - if (NULL != databuf) { - PMIX_RELEASE(databuf); - } - /* setup the reply, starting with the returned status */ - reply = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &rc, 1, PMIX_STATUS))) { - PMIX_ERROR_LOG(rc); - goto cleanup; - } - /* loop across all procs in the tracker, sending them the reply */ PMIX_LIST_FOREACH(cd, &tracker->local_cbs, pmix_server_caddy_t) { - PMIX_RETAIN(reply); + reply = PMIX_NEW(pmix_buffer_t); + if (NULL == reply) { + rc = PMIX_ERR_NOMEM; + break; + } + /* setup the reply, starting with the returned status */ + PMIX_BFROPS_PACK(ret, cd->peer, reply, &rc, 1, PMIX_STATUS); + if (PMIX_SUCCESS != ret) { + PMIX_ERROR_LOG(ret); + goto cleanup; + } pmix_output_verbose(2, pmix_globals.debug_output, - "server:modex_cbfunc reply being sent to %s:%d", - cd->peer->info->nptr->nspace, cd->peer->info->rank); + "server:modex_cbfunc reply being sent to %s:%u", + cd->peer->info->pname.nspace, cd->peer->info->pname.rank); PMIX_SERVER_QUEUE_REPLY(cd->peer, cd->hdr.tag, reply); } @@ -2027,9 +1709,9 @@ static void _mdxcbfunc(int sd, short argc, void *cbdata) xfer.bytes_used = 0; PMIX_DESTRUCT(&xfer); - PMIX_RELEASE(reply); // maintain accounting pmix_list_remove_item(&pmix_server_globals.collectives, &tracker->super); PMIX_RELEASE(tracker); + PMIX_LIST_DESTRUCT(&nslist); /* we are done */ if (NULL != scd->cbfunc.relfn) { @@ -2037,6 +1719,7 @@ static void _mdxcbfunc(int sd, short argc, void *cbdata) } PMIX_RELEASE(scd); } + static void modex_cbfunc(pmix_status_t status, const char *data, size_t ndata, void *cbdata, pmix_release_cbfunc_t relfn, void *relcbd) { @@ -2057,6 +1740,13 @@ static void modex_cbfunc(pmix_status_t status, const char *data, size_t ndata, v /* need to thread-shift this callback as it accesses global data */ scd = PMIX_NEW(pmix_shift_caddy_t); + if (NULL == scd) { + /* nothing we can do */ + if (NULL != relfn) { + relfn(cbdata); + } + return; + } scd->status = status; scd->data = data; scd->ndata = ndata; @@ -2089,23 +1779,28 @@ static void get_cbfunc(pmix_status_t status, const char *data, size_t ndata, voi /* setup the reply, starting with the returned status */ reply = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &status, 1, PMIX_STATUS))) { + if (NULL == reply) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } + PMIX_BFROPS_PACK(rc, cd->peer, reply, &status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } /* pack the blob being returned */ PMIX_CONSTRUCT(&buf, pmix_buffer_t); - PMIX_LOAD_BUFFER(&buf, data, ndata); - pmix_bfrop.copy_payload(reply, &buf); + PMIX_LOAD_BUFFER(cd->peer, &buf, data, ndata); + PMIX_BFROPS_COPY_PAYLOAD(rc, cd->peer, reply, &buf); buf.base_ptr = NULL; buf.bytes_used = 0; PMIX_DESTRUCT(&buf); /* send the data to the requestor */ pmix_output_verbose(2, pmix_globals.debug_output, - "server:get_cbfunc reply being sent to %s:%d", - cd->peer->info->nptr->nspace, cd->peer->info->rank); + "server:get_cbfunc reply being sent to %s:%u", + cd->peer->info->pname.nspace, cd->peer->info->pname.rank); pmix_output_hexdump(5, pmix_globals.debug_output, - reply->base_ptr, (reply->bytes_used < 256 ? reply->bytes_used : 256)); + reply->base_ptr, (reply->bytes_used < 256 ? reply->bytes_used : 256)); PMIX_SERVER_QUEUE_REPLY(cd->peer, cd->hdr.tag, reply); @@ -2121,58 +1816,124 @@ static void _cnct(int sd, short args, void *cbdata) { pmix_shift_caddy_t *scd = (pmix_shift_caddy_t*)cbdata; pmix_server_trkr_t *tracker = scd->tracker; - pmix_buffer_t *reply; + pmix_buffer_t *reply, pbkt; + pmix_byte_object_t bo; pmix_status_t rc; int i; pmix_server_caddy_t *cd; char **nspaces=NULL; - pmix_nspace_t *nptr; - pmix_buffer_t *job_info_ptr; + bool found; + pmix_proc_t proc; + pmix_cb_t cb; + pmix_kval_t *kptr; PMIX_ACQUIRE_OBJECT(scd); - /* setup the reply, starting with the returned status */ - reply = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &scd->status, 1, PMIX_STATUS))) { - PMIX_ERROR_LOG(rc); - goto cleanup; + if (PMIX_CONNECTNB_CMD == tracker->type) { + /* find the unique nspaces that are participating */ + PMIX_LIST_FOREACH(cd, &tracker->local_cbs, pmix_server_caddy_t) { + if (NULL == nspaces) { + pmix_argv_append_nosize(&nspaces, cd->peer->info->pname.nspace); + } else { + found = false; + for (i=0; NULL != nspaces[i]; i++) { + if (0 == strcmp(nspaces[i], cd->peer->info->pname.nspace)) { + found = true; + break; + } + } + if (!found) { + pmix_argv_append_nosize(&nspaces, cd->peer->info->pname.nspace); + } + } + } } - if (PMIX_CONNECTNB_CMD == tracker->type) { - /* find the unique nspaces that are participating */ - PMIX_LIST_FOREACH(cd, &tracker->local_cbs, pmix_server_caddy_t) { - pmix_argv_append_unique_nosize(&nspaces, cd->peer->info->nptr->nspace, false); + /* loop across all local procs in the tracker, sending them the reply */ + PMIX_LIST_FOREACH(cd, &tracker->local_cbs, pmix_server_caddy_t) { + /* setup the reply, starting with the returned status */ + reply = PMIX_NEW(pmix_buffer_t); + if (NULL == reply) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + rc = PMIX_ERR_NOMEM; + goto cleanup; } - - /* loop across all participating nspaces and include their - * job-related info */ - for (i=0; NULL != nspaces[i]; i++) { - PMIX_LIST_FOREACH(nptr, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 != strcmp(nspaces[i], nptr->nspace)) { + PMIX_BFROPS_PACK(rc, cd->peer, reply, &scd->status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(reply); + goto cleanup; + } + if (PMIX_CONNECTNB_CMD == tracker->type) { + /* loop across all participating nspaces and include their + * job-related info */ + for (i=0; NULL != nspaces[i]; i++) { + /* if this is the local proc's own nspace, then + * ignore it - it already has this info */ + if (0 == strncmp(nspaces[i], cd->peer->info->pname.nspace, PMIX_MAX_NSLEN)) { continue; } - job_info_ptr = &nptr->server->job_info; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &job_info_ptr, 1, PMIX_BUFFER))) { + + /* this is a local request, so give the gds the option + * of returning a copy of the data, or a pointer to + * local storage */ + /* add the job-level info, if necessary */ + proc.rank = PMIX_RANK_WILDCARD; + (void)strncpy(proc.nspace, nspaces[i], PMIX_MAX_NSLEN); + PMIX_CONSTRUCT(&cb, pmix_cb_t); + /* this is for a local client, so give the gds the + * option of returning a complete copy of the data, + * or returning a pointer to local storage */ + cb.proc = &proc; + cb.scope = PMIX_SCOPE_UNDEF; + cb.copy = false; + PMIX_GDS_FETCH_KV(rc, cd->peer, &cb); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); - pmix_argv_free(nspaces); + PMIX_RELEASE(reply); + PMIX_DESTRUCT(&cb); goto cleanup; } + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + /* pack the nspace name */ + PMIX_BFROPS_PACK(rc, cd->peer, &pbkt, &nspaces[i], 1, PMIX_STRING); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(reply); + PMIX_DESTRUCT(&cb); + goto cleanup; + } + PMIX_LIST_FOREACH(kptr, &cb.kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, cd->peer, &pbkt, kptr, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(reply); + PMIX_DESTRUCT(&cb); + goto cleanup; + } + } + PMIX_DESTRUCT(&cb); + PMIX_UNLOAD_BUFFER(&pbkt, bo.bytes, bo.size); + PMIX_BFROPS_PACK(rc, cd->peer, reply, &bo, 1, PMIX_BYTE_OBJECT); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(reply); + PMIX_DESTRUCT(&pbkt); + goto cleanup; + } + PMIX_DESTRUCT(&pbkt); } } - pmix_argv_free(nspaces); - } - - /* loop across all procs in the tracker, sending them the reply */ - PMIX_LIST_FOREACH(cd, &tracker->local_cbs, pmix_server_caddy_t) { - PMIX_RETAIN(reply); pmix_output_verbose(2, pmix_globals.debug_output, - "server:cnct_cbfunc reply being sent to %s:%d", - cd->peer->info->nptr->nspace, cd->peer->info->rank); + "server:cnct_cbfunc reply being sent to %s:%u", + cd->peer->info->pname.nspace, cd->peer->info->pname.rank); PMIX_SERVER_QUEUE_REPLY(cd->peer, cd->hdr.tag, reply); } cleanup: - PMIX_RELEASE(reply); // maintain accounting + if (NULL != nspaces) { + pmix_argv_free(nspaces); + } pmix_list_remove_item(&pmix_server_globals.collectives, &tracker->super); PMIX_RELEASE(tracker); @@ -2195,6 +1956,10 @@ static void cnct_cbfunc(pmix_status_t status, void *cbdata) /* need to thread-shift this callback as it accesses global data */ scd = PMIX_NEW(pmix_shift_caddy_t); + if (NULL == scd) { + /* nothing we can do */ + return; + } scd->status = status; scd->tracker = tracker; PMIX_THREADSHIFT(scd, _cnct); @@ -2210,7 +1975,13 @@ static void regevents_cbfunc(pmix_status_t status, void *cbdata) "server:regevents_cbfunc called status = %d", status); reply = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &status, 1, PMIX_STATUS))) { + if (NULL == reply) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + PMIX_RELEASE(cd); + return; + } + PMIX_BFROPS_PACK(rc, cd->peer, reply, &status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); } // send reply @@ -2222,12 +1993,19 @@ static void notifyerror_cbfunc (pmix_status_t status, void *cbdata) { pmix_status_t rc; pmix_server_caddy_t *cd = (pmix_server_caddy_t*) cbdata; - pmix_buffer_t *reply = PMIX_NEW(pmix_buffer_t); + pmix_buffer_t *reply; pmix_output_verbose(2, pmix_globals.debug_output, "server:notifyerror_cbfunc called status = %d", status); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &status, 1, PMIX_STATUS))) { + reply = PMIX_NEW(pmix_buffer_t); + if (NULL == reply) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + PMIX_RELEASE(cd); + return; + } + PMIX_BFROPS_PACK(rc, cd->peer, reply, &status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); } // send reply @@ -2244,23 +2022,32 @@ static void query_cbfunc(pmix_status_t status, { pmix_query_caddy_t *qcd = (pmix_query_caddy_t*)cbdata; pmix_server_caddy_t *cd = (pmix_server_caddy_t*)qcd->cbdata; - pmix_buffer_t *reply = PMIX_NEW(pmix_buffer_t); + pmix_buffer_t *reply; pmix_status_t rc; pmix_output_verbose(2, pmix_globals.debug_output, "pmix:query callback with status %d", status); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &status, 1, PMIX_STATUS))) { + reply = PMIX_NEW(pmix_buffer_t); + if (NULL == reply) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + PMIX_RELEASE(cd); + return; + } + PMIX_BFROPS_PACK(rc, cd->peer, reply, &status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto complete; } /* pack the returned data */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &ninfo, 1, PMIX_SIZE))) { + PMIX_BFROPS_PACK(rc, cd->peer, reply, &ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto complete; } if (0 < ninfo) { - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, info, ninfo, PMIX_INFO))) { + PMIX_BFROPS_PACK(rc, cd->peer, reply, info, ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); } } @@ -2310,33 +2097,33 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, /* retrieve the cmd */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cmd, &cnt, PMIX_CMD))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cmd, &cnt, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } pmix_output_verbose(2, pmix_globals.debug_output, - "recvd pmix cmd %d from %s:%d", - cmd, peer->info->nptr->nspace, peer->info->rank); + "recvd pmix cmd %d from %s:%u", + cmd, peer->info->pname.nspace, peer->info->pname.rank); if (PMIX_REQ_CMD == cmd) { reply = PMIX_NEW(pmix_buffer_t); - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - char *msg = peer->info->nptr->nspace; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(reply, &msg, 1, PMIX_STRING))) { + if (NULL == reply) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return PMIX_ERR_NOMEM; + } + PMIX_GDS_REGISTER_JOB_INFO(rc, peer, reply); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } -#else - pmix_bfrop.copy_payload(reply, &(peer->info->nptr->server->job_info)); - pmix_bfrop.copy_payload(reply, &(pmix_server_globals.gdata)); -#endif PMIX_SERVER_QUEUE_REPLY(peer, tag, reply); - return PMIX_SUCCESS; // don't reply twice + peer->nptr->ndelivered++; + return PMIX_SUCCESS; } if (PMIX_ABORT_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); if (PMIX_SUCCESS != (rc = pmix_server_abort(peer, buf, op_cbfunc, cd))) { PMIX_RELEASE(cd); } @@ -2346,13 +2133,20 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, if (PMIX_COMMIT_CMD == cmd) { rc = pmix_server_commit(peer, buf); reply = PMIX_NEW(pmix_buffer_t); - pmix_bfrop.pack(reply, &rc, 1, PMIX_STATUS); + if (NULL == reply) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return PMIX_ERR_NOMEM; + } + PMIX_BFROPS_PACK(rc, peer, reply, &rc, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + } PMIX_SERVER_QUEUE_REPLY(peer, tag, reply); return PMIX_SUCCESS; // don't reply twice } if (PMIX_FENCENB_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); if (PMIX_SUCCESS != (rc = pmix_server_fence(cd, buf, modex_cbfunc, op_cbfunc))) { PMIX_RELEASE(cd); } @@ -2360,7 +2154,7 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, } if (PMIX_GETNB_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); if (PMIX_SUCCESS != (rc = pmix_server_get(buf, get_cbfunc, cd))) { PMIX_RELEASE(cd); } @@ -2374,9 +2168,9 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, peer->finalized = true; /* call the local server, if supported */ if (NULL != pmix_host_server.client_finalized) { - PMIX_PEER_CADDY(cd, peer, tag); - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; + PMIX_GDS_CADDY(cd, peer, tag); + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; /* since the client is finalizing, remove them from any event * registrations they may still have on our list */ PMIX_LIST_FOREACH(reginfo, &pmix_server_globals.events, pmix_regevents_info_t) { @@ -2411,7 +2205,7 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, if (PMIX_PUBLISHNB_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); if (PMIX_SUCCESS != (rc = pmix_server_publish(peer, buf, op_cbfunc, cd))) { PMIX_RELEASE(cd); } @@ -2420,7 +2214,7 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, if (PMIX_LOOKUPNB_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); if (PMIX_SUCCESS != (rc = pmix_server_lookup(peer, buf, lookup_cbfunc, cd))) { PMIX_RELEASE(cd); } @@ -2429,7 +2223,7 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, if (PMIX_UNPUBLISHNB_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); if (PMIX_SUCCESS != (rc = pmix_server_unpublish(peer, buf, op_cbfunc, cd))) { PMIX_RELEASE(cd); } @@ -2438,7 +2232,7 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, if (PMIX_SPAWNNB_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); if (PMIX_SUCCESS != (rc = pmix_server_spawn(peer, buf, spawn_cbfunc, cd))) { PMIX_RELEASE(cd); } @@ -2447,21 +2241,21 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, if (PMIX_CONNECTNB_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); rc = pmix_server_connect(cd, buf, false, cnct_cbfunc); PMIX_RELEASE(cd); return rc; } if (PMIX_DISCONNECTNB_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); rc = pmix_server_connect(cd, buf, true, cnct_cbfunc); PMIX_RELEASE(cd); return rc; } if (PMIX_REGEVENTS_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); if (PMIX_SUCCESS != (rc = pmix_server_register_events(peer, buf, regevents_cbfunc, cd))) { PMIX_RELEASE(cd); } @@ -2474,37 +2268,37 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, } if (PMIX_NOTIFY_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); rc = pmix_server_event_recvd_from_client(peer, buf, notifyerror_cbfunc, cd); return rc; } if (PMIX_QUERY_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); rc = pmix_server_query(peer, buf, query_cbfunc, cd); return rc; } if (PMIX_LOG_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); rc = pmix_server_log(peer, buf, op_cbfunc, cd); return rc; } if (PMIX_ALLOC_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); rc = pmix_server_alloc(peer, buf, query_cbfunc, cd); return rc; } if (PMIX_JOB_CONTROL_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); rc = pmix_server_job_ctrl(peer, buf, query_cbfunc, cd); return rc; } if (PMIX_MONITOR_CMD == cmd) { - PMIX_PEER_CADDY(cd, peer, tag); + PMIX_GDS_CADDY(cd, peer, tag); rc = pmix_server_monitor(peer, buf, query_cbfunc, cd); return rc; } @@ -2518,18 +2312,25 @@ static void server_message_handler(struct pmix_peer_t *pr, { pmix_peer_t *peer = (pmix_peer_t*)pr; pmix_buffer_t *reply; - pmix_status_t rc; + pmix_status_t rc, ret; pmix_output_verbose(2, pmix_globals.debug_output, - "SWITCHYARD for %s:%d:%d", - peer->info->nptr->nspace, - peer->info->rank, peer->sd); + "SWITCHYARD for %s:%u:%d", + peer->info->pname.nspace, + peer->info->pname.rank, peer->sd); - rc = server_switchyard(peer, hdr->tag, buf); + ret = server_switchyard(peer, hdr->tag, buf); /* send the return, if there was an error returned */ - if (PMIX_SUCCESS != rc) { + if (PMIX_SUCCESS != ret) { reply = PMIX_NEW(pmix_buffer_t); - pmix_bfrop.pack(reply, &rc, 1, PMIX_STATUS); + if (NULL == reply) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return; + } + PMIX_BFROPS_PACK(rc, pr, reply, &ret, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + } PMIX_SERVER_QUEUE_REPLY(peer, hdr->tag, reply); } } @@ -2542,7 +2343,7 @@ static inline int _my_client(const char *nspace, pmix_rank_t rank) for (i = 0; i < pmix_server_globals.clients.size; i++) { if (NULL != (peer = (pmix_peer_t *)pmix_pointer_array_get_item(&pmix_server_globals.clients, i))) { - if (0 == strcmp(peer->info->nptr->nspace, nspace) && peer->info->rank == rank) { + if (0 == strcmp(peer->info->pname.nspace, nspace) && peer->info->pname.rank == rank) { local = 1; break; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_get.c b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_get.c index ab1915a4a0..6086f814cd 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_get.c +++ b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_get.c @@ -47,14 +47,12 @@ #include PMIX_EVENT_HEADER #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" +#include "src/mca/gds/gds.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" #include "src/util/pmix_environ.h" -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -#include "src/dstore/pmix_dstore.h" -#endif /* PMIX_ENABLE_DSTORE */ #include "pmix_server_ops.h" @@ -124,9 +122,13 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf, pmix_dmdx_local_t *lcd; bool local; bool localonly = false; - pmix_buffer_t pbkt; + pmix_buffer_t pbkt, pkt; + pmix_byte_object_t bo; + pmix_cb_t cb; + pmix_proc_t proc; char *data; size_t sz, n; + pmix_peer_t *peer; pmix_output_verbose(2, pmix_globals.debug_output, "recvd GET"); @@ -136,27 +138,35 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf, /* retrieve the nspace and rank of the requested proc */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cptr, &cnt, PMIX_STRING))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, &cptr, &cnt, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } (void)strncpy(nspace, cptr, PMIX_MAX_NSLEN); free(cptr); cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &rank, &cnt, PMIX_PROC_RANK))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, &rank, &cnt, PMIX_PROC_RANK); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* retrieve any provided info structs */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, &ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } if (0 < ninfo) { PMIX_INFO_CREATE(info, ninfo); + if (NULL == info) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return PMIX_ERR_NOMEM; + } cnt = ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_INFO_FREE(info, ninfo); return rc; @@ -176,7 +186,7 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf, /* find the nspace object for this client */ nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(ns, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(nspace, ns->nspace)) { nptr = ns; break; @@ -187,42 +197,119 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf, "%s:%d EXECUTE GET FOR %s:%d ON BEHALF OF %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, nspace, rank, - cd->peer->info->nptr->nspace, - cd->peer->info->rank); + cd->peer->info->pname.nspace, + cd->peer->info->pname.rank); - if (NULL == nptr || NULL == nptr->server) { + /* This call flows upward from a local client If we don't + * know about this nspace, then it cannot refer to the + * nspace of the requestor - i.e., they aren't asking + * about one of their peers. There are two reasons why we + * might not know about this nspace at this time: + * + * (a) we don't host any local procs from this nspace, and + * so the local RM didn't tell us about it. We will have + * to request the information from it. + * + * (b) a race condition where the other job hasn't registered + * its nspace yet. This begs the question as to how the + * requestor got the nspace name in the first place! + * However, there _may_ be some path whereby that could + * happen, so we try to deal with it here. + * + * Either way, we are going to have to request the info from + * the host RM. Since we are hopeful of getting an answer, + * we add the nspace to our list of known nspaces so the + * info has a "landing zone" upon return */ + + if (NULL == nptr) { if (localonly) { + /* the user doesn't want us to look for the info, + * so we simply return at this point */ return PMIX_ERR_NOT_FOUND; } /* this is for an nspace we don't know about yet, so * record the request for data from this process and - * give the host server a chance to tell us about it */ - rc = create_local_tracker(nspace, rank, info, ninfo, + * give the host server a chance to tell us about it. + * The cbdata passed here is the pmix_server_caddy_t + * we were passed - it contains the pmix_peer_t of + * the original requestor so they will get the data + * back when we receive it */ + rc = create_local_tracker(nspace, rank, + info, ninfo, cbfunc, cbdata, &lcd); if (PMIX_ERR_NOMEM == rc) { PMIX_INFO_FREE(info, ninfo); return rc; + } else if (PMIX_ERR_NOT_FOUND != rc) { + return rc; } - /* - * Its possible there are no local processes on this + /* do NOT create the nspace tracker here so any request + * by another local client that hits before the RM responds + * to our request will get added to the local tracker so + * they receive their data upon completion */ + + /* Its possible there will be no local processes on this * host, so lets ask for this explicitly. There can - * be a timing issue here if this information shows - * up on its own, but I believe we handle it ok. */ - if( NULL != pmix_host_server.direct_modex ){ - pmix_host_server.direct_modex(&lcd->proc, info, ninfo, dmdx_cbfunc, lcd); + * be a race condition here if this information shows + * up on its own, but at worst the direct modex + * will simply overwrite the info later */ + if (NULL != pmix_host_server.direct_modex) { + pmix_host_server.direct_modex(&lcd->proc, info, ninfo, dmdx_cbfunc, lcd); } - return (rc == PMIX_ERR_NOT_FOUND ? PMIX_SUCCESS : rc); + + return PMIX_SUCCESS; } - /* if the rank is wildcard, then they are asking for the job-level - * info for this nspace - provide it */ + /* this nspace is known, so we can process the request. + * if the rank is wildcard, then they are asking for the + * job-level info for this nspace - provide it */ if (PMIX_RANK_WILDCARD == rank) { + /* see if we have the job-level info - we won't have it + * if we have no local procs and haven't already asked + * for it, so there is no guarantee we have it */ + data = NULL; + sz = 0; + (void)strncpy(proc.nspace, nspace, PMIX_MAX_NSLEN); + proc.rank = PMIX_RANK_WILDCARD; + /* if we have local procs for this nspace, then we + * can retrieve the info from that GDS. Otherwise, + * we need to retrieve it from our own */ + PMIX_CONSTRUCT(&cb, pmix_cb_t); + peer = pmix_globals.mypeer; + /* this data is for a local client, so give the gds the + * option of returning a complete copy of the data, + * or returning a pointer to local storage */ + cb.proc = &proc; + cb.scope = PMIX_SCOPE_UNDEF; + cb.copy = false; + PMIX_GDS_FETCH_KV(rc, peer, &cb); + if (PMIX_SUCCESS != rc) { + PMIX_DESTRUCT(&cb); + return rc; + } + PMIX_CONSTRUCT(&pkt, pmix_buffer_t); + /* assemble the provided data into a byte object */ + PMIX_GDS_ASSEMB_KVS_REQ(rc, peer, &proc, &cb.kvs, &pkt, cd); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&cb); + return rc; + } + PMIX_UNLOAD_BUFFER(&pkt, bo.bytes, bo.size); + PMIX_DESTRUCT(&pkt); + /* pack it into the payload */ PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); - pmix_bfrop.pack(&pbkt, &rank, 1, PMIX_PROC_RANK); - /* the client is expecting this to arrive as a byte object - * containing a buffer, so package it accordingly */ - pmix_bfrop.pack(&pbkt, &nptr->server->job_info, 1, PMIX_BUFFER); + PMIX_BFROPS_PACK(rc, cd->peer, &pbkt, &bo, 1, PMIX_BYTE_OBJECT); + free(bo.bytes); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&cb); + return rc; + } + /* unload the resulting payload */ PMIX_UNLOAD_BUFFER(&pbkt, data, sz); PMIX_DESTRUCT(&pbkt); cbfunc(PMIX_SUCCESS, data, sz, cbdata, relfn, data); @@ -235,8 +322,9 @@ pmix_status_t pmix_server_get(pmix_buffer_t *buf, * client that the host RM hasn't told us about yet. Fortunately, * we do know how many clients to expect, so first check to see if * all clients have been registered with us */ - if (!nptr->server->all_registered) { + if (!nptr->all_registered) { if (localonly) { + /* the client asked that we not wait, so return now */ return PMIX_ERR_NOT_FOUND; } /* we cannot do anything further, so just track this request @@ -375,8 +463,8 @@ void pmix_pending_nspace_requests(pmix_nspace_t *nptr) continue; } - PMIX_LIST_FOREACH(info, &nptr->server->ranks, pmix_rank_info_t) { - if (info->rank == cd->proc.rank) { + PMIX_LIST_FOREACH(info, &nptr->ranks, pmix_rank_info_t) { + if (info->pname.rank == cd->proc.rank) { found = true; // we will satisy this request upon commit from new proc break; } @@ -404,134 +492,167 @@ void pmix_pending_nspace_requests(pmix_nspace_t *nptr) static pmix_status_t _satisfy_request(pmix_nspace_t *nptr, pmix_rank_t rank, pmix_server_caddy_t *cd, pmix_modex_cbfunc_t cbfunc, - void *cbdata, bool *scope) + void *cbdata, bool *local) { pmix_status_t rc; - pmix_value_t *val; - char *data; - size_t sz; - pmix_rank_t cur_rank; - int found = 0; - pmix_buffer_t pbkt, *pbptr; - void *last; - pmix_hash_table_t *hts[3]; - pmix_hash_table_t **htptr; + bool found = false; + pmix_buffer_t pbkt, pkt; pmix_rank_info_t *iptr; - bool local; - - /* Since we know about all the local clients in this nspace, - * let's first try to satisfy the request with any available data. - * By default, we assume we are looking for data from a remote - * client, and then check to see if this is one of my local - * clients - if so, then we look in that hash table */ - memset(hts, 0, sizeof(hts)); - if (PMIX_RANK_UNDEF == rank) { - local = true; - hts[0] = &nptr->server->remote; - hts[1] = &nptr->server->mylocal; - } else if (PMIX_RANK_WILDCARD == rank) { - local = true; - hts[0] = NULL; - } else { - local = false; - hts[0] = &nptr->server->remote; - PMIX_LIST_FOREACH(iptr, &nptr->server->ranks, pmix_rank_info_t) { - if (iptr->rank == rank) { - /* it is known local client - check the local table */ - hts[0] = &nptr->server->mylocal; - local = true; - break; - } - } - } - - if (NULL != scope) { - *scope = local; - } + pmix_proc_t proc; + pmix_cb_t cb; + pmix_peer_t *peer; + pmix_byte_object_t bo; + char *data = NULL; + size_t sz = 0; + pmix_scope_t scope = PMIX_SCOPE_UNDEF; /* check to see if this data already has been * obtained as a result of a prior direct modex request from * a remote peer, or due to data from a local client * having been committed */ - htptr = hts; PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + (void)strncpy(proc.nspace, nptr->nspace, PMIX_MAX_NSLEN); + + /* if we have local clients of this nspace, then we use + * the corresponding GDS to retrieve the data. Otherwise, + * the data will have been stored under our GDS */ + if (0 < nptr->nlocalprocs) { + if (local) { + *local = true; + } + if (PMIX_RANK_WILDCARD != rank) { + /* see if the requested rank is local */ + PMIX_LIST_FOREACH(iptr, &nptr->ranks, pmix_rank_info_t) { + if (rank == iptr->pname.rank) { + scope = PMIX_LOCAL; + break; + } + } + if (PMIX_LOCAL == scope) { + /* must have found a local rank + * we need the personality module for a client from this + * nspace, but it doesn't matter which one as they all + * must use the same GDS module. We don't know the GDS + * module, however, until _after_ the first local client + * connects to us. Since the nspace of the requestor may + * not match the nspace of the proc whose info is being + * requested, we cannot be sure this will have occurred. + * So we have to loop again to see if someone has connected */ + peer = NULL; + PMIX_LIST_FOREACH(iptr, &nptr->ranks, pmix_rank_info_t) { + if (0 <= iptr->peerid) { + peer = (pmix_peer_t*)pmix_pointer_array_get_item(&pmix_server_globals.clients, iptr->peerid); + break; + } + } + if (NULL == peer) { + /* nobody has connected yet, so this request needs to be held */ + return PMIX_ERR_NOT_FOUND; + } + } else { + /* this must be a remote rank */ + if (local) { + *local = false; + } + scope = PMIX_REMOTE; + peer = pmix_globals.mypeer; + } + } + } else { + if (local) { + *local = false; + } + peer = pmix_globals.mypeer; + scope = PMIX_REMOTE; + } /* if they are asking about a rank from an nspace different - * from their own, then include a copy of the job-level info */ - if (rank == PMIX_RANK_WILDCARD || (NULL != cd && - 0 != strncmp(nptr->nspace, cd->peer->info->nptr->nspace, PMIX_MAX_NSLEN))) { - cur_rank = PMIX_RANK_WILDCARD; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&pbkt, &cur_rank, 1, PMIX_PROC_RANK))) { - PMIX_ERROR_LOG(rc); - PMIX_DESTRUCT(&pbkt); - cbfunc(rc, NULL, 0, cbdata, NULL, NULL); - return rc; - } - /* the client is expecting this to arrive as a byte object - * containing a buffer, so package it accordingly */ - pbptr = &nptr->server->job_info; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&pbkt, &pbptr, 1, PMIX_BUFFER))) { - PMIX_ERROR_LOG(rc); - PMIX_DESTRUCT(&pbkt); - cbfunc(rc, NULL, 0, cbdata, NULL, NULL); - return rc; + * from their own, or they gave a rank of "wildcard", then + * include a copy of the job-level info */ + if (PMIX_RANK_WILDCARD == rank || + 0 != strncmp(nptr->nspace, cd->peer->info->pname.nspace, PMIX_MAX_NSLEN)) { + proc.rank = PMIX_RANK_WILDCARD; + PMIX_CONSTRUCT(&cb, pmix_cb_t); + /* this data is requested by a local client, so give the gds the option + * of returning a copy of the data, or a pointer to + * local storage */ + cb.proc = &proc; + cb.scope = PMIX_INTERNAL; + cb.copy = false; + peer = pmix_globals.mypeer; + PMIX_GDS_FETCH_KV(rc, peer, &cb); + if (PMIX_SUCCESS == rc) { + PMIX_CONSTRUCT(&pkt, pmix_buffer_t); + /* assemble the provided data into a byte object */ + PMIX_GDS_ASSEMB_KVS_REQ(rc, peer, &proc, &cb.kvs, &pkt, cd); + if (rc != PMIX_SUCCESS) { + PMIX_DESTRUCT(&pkt); + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&cb); + return rc; + } + PMIX_UNLOAD_BUFFER(&pkt, bo.bytes, bo.size); + PMIX_DESTRUCT(&pkt); + /* pack it for transmission */ + PMIX_BFROPS_PACK(rc, cd->peer, &pbkt, &bo, 1, PMIX_BYTE_OBJECT); + if (PMIX_SUCCESS != rc) { + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&cb); + return rc; + } } + PMIX_DESTRUCT(&cb); if (rank == PMIX_RANK_WILDCARD) { - found++; + found = true; } } - while (NULL != *htptr) { - cur_rank = rank; - if (PMIX_RANK_UNDEF == rank) { - rc = pmix_hash_fetch_by_key(*htptr, "modex", &cur_rank, &val, &last); - } else { - rc = pmix_hash_fetch(*htptr, cur_rank, "modex", &val); - } - while (PMIX_SUCCESS == rc) { - if (NULL != val) { -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - pmix_kval_t *kv; - - /* setup to xfer the data */ - kv = PMIX_NEW(pmix_kval_t); - kv->key = strdup("modex"); - kv->value = (pmix_value_t *)malloc(sizeof(pmix_value_t)); - rc = pmix_value_xfer(kv->value, val); - if (PMIX_SUCCESS != (rc = pmix_dstore_store(nptr->nspace, cur_rank, kv))) { - PMIX_ERROR_LOG(rc); - } - PMIX_RELEASE(kv); -#else - pmix_buffer_t xfer, *xptr; - pmix_bfrop.pack(&pbkt, &cur_rank, 1, PMIX_PROC_RANK); - /* the client is expecting this to arrive as a byte object - * containing a buffer, so package it accordingly */ - PMIX_CONSTRUCT(&xfer, pmix_buffer_t); - xptr = &xfer; - PMIX_LOAD_BUFFER(&xfer, val->data.bo.bytes, val->data.bo.size); - pmix_bfrop.pack(&pbkt, &xptr, 1, PMIX_BUFFER); - xfer.base_ptr = NULL; // protect the passed data - xfer.bytes_used = 0; - PMIX_DESTRUCT(&xfer); -#endif /* PMIX_ENABLE_DSTORE */ - PMIX_VALUE_RELEASE(val); - found++; + /* retrieve the data for the specific rank they are asking about */ + if (PMIX_RANK_WILDCARD != rank) { + proc.rank = rank; + PMIX_CONSTRUCT(&cb, pmix_cb_t); + /* this is a local request, so give the gds the option + * of returning a copy of the data, or a pointer to + * local storage */ + cb.proc = &proc; + cb.scope = scope; + cb.copy = false; + PMIX_GDS_FETCH_KV(rc, peer, &cb); + if (PMIX_SUCCESS == rc) { + found = true; + PMIX_CONSTRUCT(&pkt, pmix_buffer_t); + /* assemble the provided data into a byte object */ + PMIX_GDS_ASSEMB_KVS_REQ(rc, peer, &proc, &cb.kvs, &pkt, cd); + if (rc != PMIX_SUCCESS) { + PMIX_DESTRUCT(&pkt); + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&cb); + return rc; } - if (PMIX_RANK_UNDEF == rank) { - rc = pmix_hash_fetch_by_key(*htptr, NULL, &cur_rank, &val, &last); - } else { - break; + PMIX_UNLOAD_BUFFER(&pkt, bo.bytes, bo.size); + PMIX_DESTRUCT(&pkt); + /* pack it for transmission */ + PMIX_BFROPS_PACK(rc, cd->peer, &pbkt, &bo, 1, PMIX_BYTE_OBJECT); + if (PMIX_SUCCESS != rc) { + PMIX_DESTRUCT(&pbkt); + PMIX_DESTRUCT(&cb); + return rc; } } - htptr++; + PMIX_DESTRUCT(&cb); } PMIX_UNLOAD_BUFFER(&pbkt, data, sz); PMIX_DESTRUCT(&pbkt); if (found) { /* pass it back */ - cbfunc(PMIX_SUCCESS, data, sz, cbdata, relfn, data); + cbfunc(rc, data, sz, cbdata, relfn, data); + return rc; + } + + if ((PMIX_LOCAL == scope) && !found) { + /* pass PMIX_ERR_NOT_FOUND for local request if it's not found*/ + cbfunc(PMIX_ERR_NOT_FOUND, NULL, 0, cbdata, NULL, NULL); return PMIX_SUCCESS; } @@ -544,6 +665,7 @@ pmix_status_t pmix_pending_resolve(pmix_nspace_t *nptr, pmix_rank_t rank, { pmix_dmdx_local_t *cd, *ptr; pmix_dmdx_request_t *req; + pmix_server_caddy_t *scd; /* find corresponding request (if exists) */ if (NULL == lcd) { @@ -574,14 +696,20 @@ pmix_status_t pmix_pending_resolve(pmix_nspace_t *nptr, pmix_rank_t rank, } else if (NULL != nptr) { /* if we've got the blob - try to satisfy requests */ /* run through all the requests to this rank */ + /* this info is going back to one of our peers, so provide a server + * caddy with our peer in it so the data gets packed correctly */ + scd = PMIX_NEW(pmix_server_caddy_t); + PMIX_RETAIN(pmix_globals.mypeer); + scd->peer = pmix_globals.mypeer; PMIX_LIST_FOREACH(req, &ptr->loc_reqs, pmix_dmdx_request_t) { pmix_status_t rc; - rc = _satisfy_request(nptr, rank, NULL, req->cbfunc, req->cbdata, NULL); + rc = _satisfy_request(nptr, rank, scd, req->cbfunc, req->cbdata, NULL); if( PMIX_SUCCESS != rc ){ /* if we can't satisfy this particular request (missing key?) */ req->cbfunc(rc, NULL, 0, req->cbdata, NULL, NULL); } } + PMIX_RELEASE(scd); } /* remove all requests to this rank and cleanup the corresponding structure */ pmix_list_remove_item(&pmix_server_globals.local_reqs, (pmix_list_item_t*)ptr); @@ -594,9 +722,18 @@ pmix_status_t pmix_pending_resolve(pmix_nspace_t *nptr, pmix_rank_t rank, static void _process_dmdx_reply(int fd, short args, void *cbdata) { pmix_dmdx_reply_caddy_t *caddy = (pmix_dmdx_reply_caddy_t *)cbdata; - pmix_kval_t *kp; + pmix_server_caddy_t *cd; + pmix_peer_t *peer; + pmix_rank_info_t *rinfo; + int32_t cnt; + pmix_kval_t *kv; pmix_nspace_t *ns, *nptr; pmix_status_t rc; + pmix_list_t nspaces; + pmix_nspace_caddy_t *nm; + pmix_dmdx_request_t *dm; + bool found; + pmix_buffer_t pbkt; PMIX_ACQUIRE_OBJECT(caddy); @@ -605,9 +742,9 @@ static void _process_dmdx_reply(int fd, short args, void *cbdata) __FILE__, __LINE__, caddy->lcd->proc.nspace, caddy->lcd->proc.rank); - /* find the nspace object for this client */ + /* find the nspace object for the proc whose data is being received */ nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(ns, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(caddy->lcd->proc.nspace, ns->nspace)) { nptr = ns; break; @@ -615,66 +752,87 @@ static void _process_dmdx_reply(int fd, short args, void *cbdata) } if (NULL == nptr) { - /* - * We may not have this namespace because someone asked about this namespace - * but there are not processses from it running on this host - */ + /* We may not have this namespace because there are no local + * processes from it running on this host - so just record it + * so we know we have the data for any future requests */ nptr = PMIX_NEW(pmix_nspace_t); (void)strncpy(nptr->nspace, caddy->lcd->proc.nspace, PMIX_MAX_NSLEN); - nptr->server = PMIX_NEW(pmix_server_nspace_t); - pmix_list_append(&pmix_globals.nspaces, &nptr->super); + /* add to the list */ + pmix_list_append(&pmix_server_globals.nspaces, &nptr->super); } - /* if the request was successfully satisfied, then store the data - * in our hash table for remote procs. Although we could immediately + /* if the request was successfully satisfied, then store the data. + * Although we could immediately * resolve any outstanding requests on our tracking list, we instead * store the data first so we can immediately satisfy any future * requests. Then, rather than duplicate the resolve code here, we * will let the pmix_pending_resolve function go ahead and retrieve - * it from the hash table. - * - * NOTE: A NULL data pointer indicates that the data has already - * been returned via completion of a background fence_nb operation. - * In this case, all we need to do is resolve the request */ - if (PMIX_SUCCESS == caddy->status && NULL != caddy->data) { - if (caddy->lcd->proc.rank == PMIX_RANK_WILDCARD) { - void * where = malloc(caddy->ndata); - if (where) { - memcpy(where, caddy->data, caddy->ndata); - PMIX_LOAD_BUFFER(&nptr->server->job_info, where, caddy->ndata); - } else { - /* The data was stored, so hate to change caddy->status just because - * we could not store it locally. - */ - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); - } - } else { - kp = PMIX_NEW(pmix_kval_t); - kp->key = strdup("modex"); - PMIX_VALUE_CREATE(kp->value, 1); - kp->value->type = PMIX_BYTE_OBJECT; - /* we don't know if the host is going to save this data - * or not, so we have to copy it - the client is expecting - * this to arrive as a byte object containing a buffer, so - * package it accordingly */ - kp->value->data.bo.bytes = malloc(caddy->ndata); - if (kp->value->data.bo.bytes) { - 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))) { - PMIX_ERROR_LOG(rc); + * it from the GDS */ + if (PMIX_SUCCESS == caddy->status) { + /* cycle across all outstanding local requests and collect their + * unique nspaces so we can store this for each one */ + PMIX_CONSTRUCT(&nspaces, pmix_list_t); + PMIX_LIST_FOREACH(dm, &caddy->lcd->loc_reqs, pmix_dmdx_request_t) { + /* this is a local proc that has requested this data - search + * the list of nspace's and see if we already have it */ + cd = (pmix_server_caddy_t*)dm->cbdata; + found = false; + PMIX_LIST_FOREACH(nm, &nspaces, pmix_nspace_caddy_t) { + if (0 == strcmp(nm->ns->nspace, cd->peer->nptr->nspace)) { + found = true; + break; } - } else { - /* The data was stored, so hate to change caddy->status just because - * we could not store it locally. - */ - PMIX_ERROR_LOG(PMIX_ERR_NOMEM); } - PMIX_RELEASE(kp); // maintain acctg + if (!found) { + /* add it */ + nm = PMIX_NEW(pmix_nspace_caddy_t); + PMIX_RETAIN(cd->peer->nptr); + nm->ns = cd->peer->nptr; + pmix_list_append(&nspaces, &nm->super); + } } + /* now go thru each unique nspace and store the data using its + * assigned GDS component */ + PMIX_LIST_FOREACH(nm, &nspaces, pmix_nspace_caddy_t) { + if (NULL == nm->ns->compat.gds || 0 == nm->ns->nlocalprocs) { + peer = pmix_globals.mypeer; + } else { + /* there must be at least one local proc */ + rinfo = (pmix_rank_info_t*)pmix_list_get_first(&nm->ns->ranks); + peer = (pmix_peer_t*)pmix_pointer_array_get_item(&pmix_server_globals.clients, rinfo->peerid); + } + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + + PMIX_LOAD_BUFFER(pmix_globals.mypeer, &pbkt, caddy->data, caddy->ndata); + /* unpack and store it*/ + kv = PMIX_NEW(pmix_kval_t); + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, &pbkt, kv, &cnt, PMIX_KVAL); + while (PMIX_SUCCESS == rc) { + PMIX_GDS_STORE_KV(rc, peer, &caddy->lcd->proc, PMIX_REMOTE, kv); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + caddy->status = rc; + goto complete; + } + PMIX_RELEASE(kv); + kv = PMIX_NEW(pmix_kval_t); + cnt = 1; + PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, &pbkt, kv, &cnt, PMIX_KVAL); + } + PMIX_RELEASE(kv); + pbkt.base_ptr = NULL; // protect the data + PMIX_DESTRUCT(&pbkt); + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { + PMIX_ERROR_LOG(rc); + caddy->status = rc; + goto complete; + } + } + PMIX_LIST_DESTRUCT(&nspaces); } + complete: /* always execute the callback to avoid having the client hang */ pmix_pending_resolve(nptr, caddy->lcd->proc.rank, caddy->status, caddy->lcd); diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_ops.c b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_ops.c index 5826c4b887..4c8b3fa95a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_ops.c +++ b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_ops.c @@ -49,7 +49,7 @@ #include PMIX_EVENT_HEADER #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" @@ -57,11 +57,6 @@ #include "pmix_server_ops.h" -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -#include "src/dstore/pmix_dstore.h" -#endif /* PMIX_ENABLE_DSTORE */ - - pmix_server_module_t pmix_host_server = {0}; pmix_status_t pmix_server_abort(pmix_peer_t *peer, pmix_buffer_t *buf, @@ -79,17 +74,20 @@ pmix_status_t pmix_server_abort(pmix_peer_t *peer, pmix_buffer_t *buf, /* unpack the status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &status, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &status, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { return rc; } /* unpack the message */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &msg, &cnt, PMIX_STRING))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &msg, &cnt, PMIX_STRING); + if (PMIX_SUCCESS != rc) { return rc; } /* unpack the number of procs */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &nprocs, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &nprocs, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { return rc; } @@ -97,16 +95,26 @@ pmix_status_t pmix_server_abort(pmix_peer_t *peer, pmix_buffer_t *buf, * wants aborted */ if (0 < nprocs) { PMIX_PROC_CREATE(procs, nprocs); + if (NULL == procs) { + if (NULL != msg) { + free(msg); + } + return PMIX_ERR_NOMEM; + } cnt = nprocs; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, procs, &cnt, PMIX_PROC))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, procs, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { + if (NULL != msg) { + free(msg); + } return rc; } } /* let the local host's server execute it */ if (NULL != pmix_host_server.abort) { - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; rc = pmix_host_server.abort(&proc, peer->info->server_object, status, msg, procs, nprocs, cbfunc, cbdata); } else { @@ -131,93 +139,82 @@ pmix_status_t pmix_server_commit(pmix_peer_t *peer, pmix_buffer_t *buf) { int32_t cnt; pmix_status_t rc; - pmix_buffer_t *b2; + pmix_buffer_t b2, pbkt; pmix_kval_t *kp; pmix_scope_t scope; - pmix_hash_table_t *ht; pmix_nspace_t *nptr; pmix_rank_info_t *info; + pmix_proc_t proc; pmix_dmdx_remote_t *dcd, *dcdnext; - pmix_value_t *val; char *data; size_t sz; + pmix_cb_t cb; /* shorthand */ info = peer->info; - nptr = info->nptr; + nptr = peer->nptr; + (void)strncpy(proc.nspace, nptr->nspace, PMIX_MAX_NSLEN); + proc.rank = info->pname.rank; pmix_output_verbose(2, pmix_globals.debug_output, "%s:%d EXECUTE COMMIT FOR %s:%d", pmix_globals.myid.nspace, pmix_globals.myid.rank, - nptr->nspace, info->rank); + nptr->nspace, info->pname.rank); /* this buffer will contain one or more buffers, each * representing a different scope. These need to be locally * stored separately so we can provide required data based * on the requestor's location */ cnt = 1; - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(buf, &scope, &cnt, PMIX_SCOPE))) { - if (PMIX_LOCAL == scope) { - ht = &nptr->server->mylocal; - } else if (PMIX_REMOTE == scope) { - ht = &nptr->server->myremote; - } else { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - rc = PMIX_ERR_BAD_PARAM; - return rc; - } + PMIX_BFROPS_UNPACK(rc, peer, buf, &scope, &cnt, PMIX_SCOPE); + while (PMIX_SUCCESS == rc) { /* unpack and store the blob */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &b2, &cnt, PMIX_BUFFER))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &b2, &cnt, PMIX_BUFFER); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } - - /* create the new data storage */ + /* unpack the buffer and store the values - we store them + * in this peer's native GDS component so that other local + * procs from that nspace can access it */ kp = PMIX_NEW(pmix_kval_t); - kp->key = strdup("modex"); - PMIX_VALUE_CREATE(kp->value, 1); - kp->value->type = PMIX_BYTE_OBJECT; - -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - /* The local buffer must go directly the dstore */ - if( PMIX_LOCAL == scope ){ - /* need to deposit this in the dstore now */ - PMIX_UNLOAD_BUFFER(b2, kp->value->data.bo.bytes, kp->value->data.bo.size); - if (PMIX_SUCCESS != (rc = pmix_dstore_store(nptr->nspace, info->rank, kp))) { - PMIX_ERROR_LOG(rc); - } - - /* restore the buffer for subsequent processing */ - PMIX_LOAD_BUFFER(b2, kp->value->data.bo.bytes, kp->value->data.bo.size); - kp->value->data.bo.bytes = NULL; - kp->value->data.bo.size = 0; - } -#endif /* PMIX_ENABLE_DSTORE */ - - /* see if we already have info for this proc */ - if (PMIX_SUCCESS == pmix_hash_fetch(ht, info->rank, "modex", &val) && NULL != val) { - /* get space for the new new data blob */ - kp->value->data.bo.bytes = (char*)malloc(b2->bytes_used + val->data.bo.size); - memcpy(kp->value->data.bo.bytes, val->data.bo.bytes, val->data.bo.size); - memcpy(kp->value->data.bo.bytes+val->data.bo.size, b2->base_ptr, b2->bytes_used); - kp->value->data.bo.size = val->data.bo.size + b2->bytes_used; - /* release the storage */ - PMIX_VALUE_FREE(val, 1); - } else { - PMIX_UNLOAD_BUFFER(b2, kp->value->data.bo.bytes, kp->value->data.bo.size); - } - - /* store it in the appropriate hash */ - if (PMIX_SUCCESS != (rc = pmix_hash_store(ht, info->rank, kp))) { - PMIX_ERROR_LOG(rc); - } - /* maintain the accounting */ - PMIX_RELEASE(kp); - PMIX_RELEASE(b2); - cnt = 1; + PMIX_BFROPS_UNPACK(rc, peer, &b2, kp, &cnt, PMIX_KVAL); + while (PMIX_SUCCESS == rc) { + if( PMIX_LOCAL == scope || PMIX_GLOBAL == scope){ + PMIX_GDS_STORE_KV(rc, peer, &proc, scope, kp); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp); + PMIX_DESTRUCT(&b2); + return rc; + } + } + if (PMIX_REMOTE == scope || PMIX_GLOBAL == scope) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, &proc, scope, kp); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(kp); + PMIX_DESTRUCT(&b2); + return rc; + } + } + PMIX_RELEASE(kp); // maintain accounting + kp = PMIX_NEW(pmix_kval_t); + cnt = 1; + PMIX_BFROPS_UNPACK(rc, peer, &b2, kp, &cnt, PMIX_KVAL); + + } + PMIX_RELEASE(kp); // maintain accounting + PMIX_DESTRUCT(&b2); + if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { + PMIX_ERROR_LOG(rc); + return rc; + } + cnt = 1; + PMIX_BFROPS_UNPACK(rc, peer, buf, &scope, &cnt, PMIX_SCOPE); } if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { PMIX_ERROR_LOG(rc); @@ -232,24 +229,30 @@ pmix_status_t pmix_server_commit(pmix_peer_t *peer, pmix_buffer_t *buf) if (0 != strncmp(dcd->cd->proc.nspace, nptr->nspace, PMIX_MAX_NSLEN)) { continue; } - if (dcd->cd->proc.rank == info->rank) { + if (dcd->cd->proc.rank == info->pname.rank) { /* we can now fulfill this request - collect the - * remote/global data from this proc */ - /* get any remote contribution - note that there + * remote/global data from this proc - note that there * may not be a contribution */ data = NULL; sz = 0; - if (PMIX_SUCCESS == pmix_hash_fetch(&nptr->server->myremote, info->rank, "modex", &val) && - NULL != val) { - data = val->data.bo.bytes; - sz = val->data.bo.size; - /* protect the data */ - val->data.bo.bytes = NULL; - val->data.bo.size = 0; - PMIX_VALUE_RELEASE(val); + PMIX_CONSTRUCT(&cb, pmix_cb_t); + cb.proc = &proc; + cb.scope = PMIX_REMOTE; + cb.copy = true; + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, &cb); + if (PMIX_SUCCESS == rc) { + /* package it up */ + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); + PMIX_LIST_FOREACH(kp, &cb.kvs, pmix_kval_t) { + /* we pack this in our native BFROPS form as it + * will be sent to another daemon */ + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &pbkt, &kp, 1, PMIX_KVAL); + } + PMIX_UNLOAD_BUFFER(&pbkt, data, sz); } + PMIX_DESTRUCT(&cb); /* execute the callback */ - dcd->cd->cbfunc(PMIX_SUCCESS, data, sz, dcd->cd->cbdata); + dcd->cd->cbfunc(rc, data, sz, dcd->cd->cbdata); if (NULL != data) { free(data); } @@ -259,7 +262,7 @@ pmix_status_t pmix_server_commit(pmix_peer_t *peer, pmix_buffer_t *buf) } } /* see if anyone local is waiting on this data- could be more than one */ - return pmix_pending_resolve(nptr, info->rank, PMIX_SUCCESS, NULL); + return pmix_pending_resolve(nptr, info->pname.rank, PMIX_SUCCESS, NULL); } /* get an existing object for tracking LOCAL participation in a collective @@ -350,10 +353,10 @@ static pmix_server_trkr_t* new_tracker(pmix_proc_t *procs, size_t nprocs, pmix_cmd_t type) { pmix_server_trkr_t *trk; - pmix_rank_info_t *iptr, *info; size_t i; bool all_def; pmix_nspace_t *nptr, *ns; + pmix_rank_info_t *info; pmix_output_verbose(5, pmix_globals.debug_output, "new_tracker called with %d procs", (int)nprocs); @@ -367,11 +370,20 @@ static pmix_server_trkr_t* new_tracker(pmix_proc_t *procs, pmix_output_verbose(5, pmix_globals.debug_output, "adding new tracker with %d procs", (int)nprocs); - /* get here if this tracker is new - create it */ + /* this tracker is new - create it */ trk = PMIX_NEW(pmix_server_trkr_t); + if (NULL == trk) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return NULL; + } /* copy the procs */ PMIX_PROC_CREATE(trk->pcs, nprocs); + if (NULL == trk->pcs) { + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + PMIX_RELEASE(trk); + return NULL; + } trk->npcs = nprocs; trk->type = type; @@ -379,9 +391,12 @@ static pmix_server_trkr_t* new_tracker(pmix_proc_t *procs, for (i=0; i < nprocs; i++) { (void)strncpy(trk->pcs[i].nspace, procs[i].nspace, PMIX_MAX_NSLEN); trk->pcs[i].rank = procs[i].rank; + if (!all_def) { + continue; + } /* is this nspace known to us? */ nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { + PMIX_LIST_FOREACH(ns, &pmix_server_globals.nspaces, pmix_nspace_t) { if (0 == strcmp(procs[i].nspace, ns->nspace)) { nptr = ns; break; @@ -395,29 +410,24 @@ static pmix_server_trkr_t* new_tracker(pmix_proc_t *procs, continue; } /* have all the clients for this nspace been defined? */ - if (!nptr->server->all_registered) { + if (!nptr->all_registered) { /* nope, so no point in going further on this one - we'll * process it once all the procs are known */ all_def = false; pmix_output_verbose(5, pmix_globals.debug_output, "new_tracker: all clients not registered nspace %s", procs[i].nspace); - continue; + /* we have to continue processing the list of procs + * to setup the trk->pcs array, so don't break out + * of the loop */ } /* is this one of my local ranks? */ - PMIX_LIST_FOREACH(info, &nptr->server->ranks, pmix_rank_info_t) { - if (procs[i].rank == info->rank || + PMIX_LIST_FOREACH(info, &nptr->ranks, pmix_rank_info_t) { + if (procs[i].rank == info->pname.rank || PMIX_RANK_WILDCARD == procs[i].rank) { - pmix_output_verbose(5, pmix_globals.debug_output, - "adding local proc %s.%d to tracker", - info->nptr->nspace, info->rank); - /* add a tracker for this proc - don't need more than - * the nspace pointer and rank */ - iptr = PMIX_NEW(pmix_rank_info_t); - PMIX_RETAIN(info->nptr); - iptr->nptr = info->nptr; - iptr->rank = info->rank; - pmix_list_append(&trk->ranks, &iptr->super); + pmix_output_verbose(5, pmix_globals.debug_output, + "adding local proc %s.%d to tracker", + info->pname.nspace, info->pname.rank); /* track the count */ ++trk->nlocal; if (PMIX_RANK_WILDCARD != procs[i].rank) { @@ -441,14 +451,16 @@ pmix_status_t pmix_server_fence(pmix_server_caddy_t *cd, int32_t cnt; pmix_status_t rc; size_t nprocs; - pmix_proc_t *procs=NULL; + pmix_proc_t *procs=NULL, pcs; bool collect_data = false; pmix_server_trkr_t *trk; char *data = NULL; size_t sz = 0; - pmix_buffer_t bucket, xfer; - pmix_rank_info_t *rkinfo; - pmix_value_t *val; + pmix_buffer_t bucket, pbkt; + pmix_server_caddy_t *scd; + pmix_cb_t cb; + pmix_kval_t *kv; + pmix_byte_object_t bo; pmix_info_t *info = NULL; size_t ninfo=0, n; @@ -462,12 +474,13 @@ pmix_status_t pmix_server_fence(pmix_server_caddy_t *cd, /* unpack the number of procs */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &nprocs, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, &nprocs, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { return rc; } pmix_output_verbose(2, pmix_globals.debug_output, "recvd fence from %s:%u with %d procs", - cd->peer->info->nptr->nspace, cd->peer->info->rank, (int)nprocs); + cd->peer->info->pname.nspace, cd->peer->info->pname.rank, (int)nprocs); /* there must be at least one as the client has to at least provide * their own namespace */ if (nprocs < 1) { @@ -476,22 +489,32 @@ pmix_status_t pmix_server_fence(pmix_server_caddy_t *cd, /* create space for the procs */ PMIX_PROC_CREATE(procs, nprocs); + if (NULL == procs) { + return PMIX_ERR_NOMEM; + } /* unpack the procs */ cnt = nprocs; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, procs, &cnt, PMIX_PROC))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, procs, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { goto cleanup; } /* unpack the number of provided info structs */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, &ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { return rc; } if (0 < ninfo) { PMIX_INFO_CREATE(info, ninfo); + if (NULL == info) { + PMIX_PROC_FREE(procs, nprocs); + return PMIX_ERR_NOMEM; + } /* unpack the info */ cnt = ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { goto cleanup; } /* see if we are to collect data - we don't internally care @@ -556,6 +579,7 @@ pmix_status_t pmix_server_fence(pmix_server_caddy_t *cd, /* add this contributor to the tracker so they get * notified when we are done */ pmix_list_append(&trk->local_cbs, &cd->super); + /* if all local contributions have been received, * let the local host's server know that we are at the * "fence" point - they will callback once the barrier @@ -569,48 +593,79 @@ pmix_status_t pmix_server_fence(pmix_server_caddy_t *cd, * server so they can circulate it - only take data * from the specified procs as not everyone is necessarily * participating! And only take data intended for remote - * distribution */ + * or global distribution */ PMIX_CONSTRUCT(&bucket, pmix_buffer_t); - assert( PMIX_COLLECT_MAX < UCHAR_MAX ); + /* mark the collection type so we can check on the + * receiving end that all participants did the same */ unsigned char tmp = (unsigned char)trk->collect_type; - pmix_bfrop.pack(&bucket, &tmp, 1, PMIX_BYTE); + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &bucket, + &tmp, 1, PMIX_BYTE); if (PMIX_COLLECT_YES == trk->collect_type) { - pmix_buffer_t databuf; - PMIX_CONSTRUCT(&databuf, pmix_buffer_t); pmix_output_verbose(2, pmix_globals.debug_output, "fence - assembling data"); - PMIX_LIST_FOREACH(rkinfo, &trk->ranks, pmix_rank_info_t) { - pmix_buffer_t rankbuf; - PMIX_CONSTRUCT(&rankbuf, pmix_buffer_t); + PMIX_LIST_FOREACH(scd, &trk->local_cbs, pmix_server_caddy_t) { /* get any remote contribution - note that there * may not be a contribution */ - if (PMIX_SUCCESS == pmix_hash_fetch(&rkinfo->nptr->server->myremote, rkinfo->rank, "modex", &val) && - NULL != val) { + (void)strncpy(pcs.nspace, scd->peer->info->pname.nspace, PMIX_MAX_NSLEN); + pcs.rank = scd->peer->info->pname.rank; + PMIX_CONSTRUCT(&cb, pmix_cb_t); + cb.proc = &pcs; + cb.scope = PMIX_REMOTE; + cb.copy = true; + PMIX_GDS_FETCH_KV(rc, pmix_globals.mypeer, &cb); + if (PMIX_SUCCESS == rc) { + PMIX_CONSTRUCT(&pbkt, pmix_buffer_t); /* pack the proc so we know the source */ - char *foobar = rkinfo->nptr->nspace; - pmix_bfrop.pack(&rankbuf, &foobar, 1, PMIX_STRING); - pmix_bfrop.pack(&rankbuf, &rkinfo->rank, 1, PMIX_PROC_RANK); - PMIX_CONSTRUCT(&xfer, pmix_buffer_t); - PMIX_LOAD_BUFFER(&xfer, val->data.bo.bytes, val->data.bo.size); - PMIX_VALUE_RELEASE(val); - pmix_buffer_t *pxfer = &xfer; - pmix_bfrop.pack(&rankbuf, &pxfer, 1, PMIX_BUFFER); - PMIX_DESTRUCT(&xfer); - /* now pack this proc's contribution into the bucket */ - pmix_buffer_t *pdatabuf = &rankbuf; - pmix_bfrop.pack(&databuf, &pdatabuf, 1, PMIX_BUFFER); + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &pbkt, + &pcs, 1, PMIX_PROC); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&cb); + goto cleanup; + } + /* pack the returned kval's */ + PMIX_LIST_FOREACH(kv, &cb.kvs, pmix_kval_t) { + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &pbkt, kv, 1, PMIX_KVAL); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&cb); + goto cleanup; + } + } + /* extract the blob */ + PMIX_UNLOAD_BUFFER(&pbkt, bo.bytes, bo.size); + PMIX_DESTRUCT(&pbkt); + /* pack the returned blob */ + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &bucket, + &bo, 1, PMIX_BYTE_OBJECT); + PMIX_BYTE_OBJECT_DESTRUCT(&bo); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&cb); + goto cleanup; + } } - PMIX_DESTRUCT(&rankbuf); + PMIX_DESTRUCT(&cb); } - // TODO: we have multiple data movings while only one is actually need - pmix_buffer_t *pbkt = &databuf; - pmix_bfrop.pack(&bucket, &pbkt, 1, PMIX_BUFFER); - PMIX_DESTRUCT(&databuf); } - + /* because the remote servers have to unpack things + * in chunks, we have to pack the bucket as a single + * byte object to allow remote unpack */ + PMIX_UNLOAD_BUFFER(&bucket, bo.bytes, bo.size); + PMIX_DESTRUCT(&bucket); + PMIX_CONSTRUCT(&bucket, pmix_buffer_t); + PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &bucket, + &bo, 1, PMIX_BYTE_OBJECT); + PMIX_BYTE_OBJECT_DESTRUCT(&bo); // releases the data + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + PMIX_DESTRUCT(&cb); + goto cleanup; + } + /* now unload the blob and pass it upstairs */ PMIX_UNLOAD_BUFFER(&bucket, data, sz); PMIX_DESTRUCT(&bucket); pmix_host_server.fence_nb(trk->pcs, trk->npcs, @@ -618,19 +673,38 @@ pmix_status_t pmix_server_fence(pmix_server_caddy_t *cd, data, sz, trk->modexcbfunc, trk); } - cleanup: + cleanup: PMIX_PROC_FREE(procs, nprocs); return rc; } +static void opcbfunc(pmix_status_t status, void *cbdata) +{ + pmix_setup_caddy_t *cd = (pmix_setup_caddy_t*)cbdata; + + if (NULL != cd->keys) { + pmix_argv_free(cd->keys); + } + if (NULL != cd->codes) { + free(cd->codes); + } + if (NULL != cd->info) { + PMIX_INFO_FREE(cd->info, cd->ninfo); + } + if (NULL != cd->opcbfunc) { + cd->opcbfunc(status, cd->cbdata); + } + PMIX_RELEASE(cd); +} + pmix_status_t pmix_server_publish(pmix_peer_t *peer, pmix_buffer_t *buf, pmix_op_cbfunc_t cbfunc, void *cbdata) { + pmix_setup_caddy_t *cd; pmix_status_t rc; int32_t cnt; - size_t ninfo, einfo; - pmix_info_t *info = NULL; + size_t ninfo; pmix_proc_t proc; uint32_t uid; @@ -643,51 +717,89 @@ pmix_status_t pmix_server_publish(pmix_peer_t *peer, /* unpack the effective user id */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &uid, &cnt, PMIX_UINT32))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &uid, &cnt, PMIX_UINT32); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* unpack the number of info objects */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* we will be adding one for the user id */ - einfo = ninfo + 1; - PMIX_INFO_CREATE(info, einfo); + cd = PMIX_NEW(pmix_setup_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } + cd->opcbfunc = cbfunc; + cd->cbdata = cbdata; + cd->ninfo = ninfo + 1; + PMIX_INFO_CREATE(cd->info, cd->ninfo); + if (NULL == cd->info) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } /* unpack the array of info objects */ - if (0 < ninfo) { - cnt=ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, info, &cnt, PMIX_INFO))) { + if (0 < cd->ninfo) { + cnt=cd->ninfo; + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } } - (void)strncpy(info[einfo-1].key, PMIX_USERID, PMIX_MAX_KEYLEN); - info[einfo-1].value.type = PMIX_UINT32; - info[einfo-1].value.data.uint32 = uid; + (void)strncpy(cd->info[cd->ninfo-1].key, PMIX_USERID, PMIX_MAX_KEYLEN); + cd->info[cd->ninfo-1].value.type = PMIX_UINT32; + cd->info[cd->ninfo-1].value.data.uint32 = uid; /* call the local server */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; - rc = pmix_host_server.publish(&proc, info, einfo, cbfunc, cbdata); + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; + rc = pmix_host_server.publish(&proc, cd->info, cd->ninfo, opcbfunc, cd); - cleanup: - PMIX_INFO_FREE(info, einfo); + cleanup: + if (PMIX_SUCCESS != rc) { + if (NULL != cd->info) { + PMIX_INFO_FREE(cd->info, cd->ninfo); + } + PMIX_RELEASE(cd); + } return rc; } +static void lkcbfunc(pmix_status_t status, + pmix_pdata_t data[], size_t ndata, + void *cbdata) +{ + pmix_setup_caddy_t *cd = (pmix_setup_caddy_t*)cbdata; + + /* cleanup the caddy */ + if (NULL != cd->keys) { + pmix_argv_free(cd->keys); + } + if (NULL != cd->info) { + PMIX_INFO_FREE(cd->info, cd->ninfo); + } + + /* return the results */ + if (NULL != cd->lkcbfunc) { + cd->lkcbfunc(status, data, ndata, cd->cbdata); + } + PMIX_RELEASE(cd); +} pmix_status_t pmix_server_lookup(pmix_peer_t *peer, pmix_buffer_t *buf, pmix_lookup_cbfunc_t cbfunc, void *cbdata) { + pmix_setup_caddy_t *cd; int32_t cnt; pmix_status_t rc; size_t nkeys, i; - char **keys=NULL, *sptr; - pmix_info_t *info = NULL; - size_t ninfo, einfo; + char *sptr; + size_t ninfo; pmix_proc_t proc; uint32_t uid; @@ -700,55 +812,78 @@ pmix_status_t pmix_server_lookup(pmix_peer_t *peer, /* unpack the effective user id */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &uid, &cnt, PMIX_UINT32))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &uid, &cnt, PMIX_UINT32); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* unpack the number of keys */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &nkeys, &cnt, PMIX_SIZE))) { - PMIX_ERROR_LOG(rc); + PMIX_BFROPS_UNPACK(rc, peer, buf, &nkeys, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); return rc; } + /* setup the caddy */ + cd = PMIX_NEW(pmix_setup_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } + cd->lkcbfunc = cbfunc; + cd->cbdata = cbdata; /* unpack the array of keys */ for (i=0; i < nkeys; i++) { cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &sptr, &cnt, PMIX_STRING))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &sptr, &cnt, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } - pmix_argv_append_nosize(&keys, sptr); + pmix_argv_append_nosize(&cd->keys, sptr); free(sptr); } /* unpack the number of info objects */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); - return rc; + goto cleanup; } /* we will be adding one for the user id */ - einfo = ninfo + 1; - PMIX_INFO_CREATE(info, einfo); + cd->ninfo = ninfo + 1; + PMIX_INFO_CREATE(cd->info, cd->ninfo); + if (NULL == cd->info) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } /* unpack the array of info objects */ if (0 < ninfo) { cnt=ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } } - (void)strncpy(info[einfo-1].key, PMIX_USERID, PMIX_MAX_KEYLEN); - info[einfo-1].value.type = PMIX_UINT32; - info[einfo-1].value.data.uint32 = uid; + (void)strncpy(cd->info[cd->ninfo-1].key, PMIX_USERID, PMIX_MAX_KEYLEN); + cd->info[cd->ninfo-1].value.type = PMIX_UINT32; + cd->info[cd->ninfo-1].value.data.uint32 = uid; /* call the local server */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; - rc = pmix_host_server.lookup(&proc, keys, info, einfo, cbfunc, cbdata); + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; + rc = pmix_host_server.lookup(&proc, cd->keys, cd->info, cd->ninfo, lkcbfunc, cd); - cleanup: - PMIX_INFO_FREE(info, einfo); - pmix_argv_free(keys); + cleanup: + if (PMIX_SUCCESS != rc) { + if (NULL != cd->keys) { + pmix_argv_free(cd->keys); + } + if (NULL != cd->info) { + PMIX_INFO_FREE(cd->info, cd->ninfo); + } + PMIX_RELEASE(cd); + } return rc; } @@ -756,13 +891,13 @@ pmix_status_t pmix_server_unpublish(pmix_peer_t *peer, pmix_buffer_t *buf, pmix_op_cbfunc_t cbfunc, void *cbdata) { + pmix_setup_caddy_t *cd; int32_t cnt; pmix_status_t rc; - size_t i, nkeys, ninfo, einfo; - char **keys=NULL, *sptr; + size_t i, nkeys, ninfo; + char *sptr; pmix_proc_t proc; uint32_t uid; - pmix_info_t *info; pmix_output_verbose(2, pmix_globals.debug_output, "recvd UNPUBLISH"); @@ -773,66 +908,106 @@ pmix_status_t pmix_server_unpublish(pmix_peer_t *peer, /* unpack the effective user id */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &uid, &cnt, PMIX_UINT32))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &uid, &cnt, PMIX_UINT32); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* unpack the number of keys */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &nkeys, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &nkeys, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } - /* unpack the keys */ + /* setup the caddy */ + cd = PMIX_NEW(pmix_setup_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } + cd->opcbfunc = cbfunc; + cd->cbdata = cbdata; + /* unpack the array of keys */ for (i=0; i < nkeys; i++) { cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &sptr, &cnt, PMIX_STRING))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &sptr, &cnt, PMIX_STRING); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } - pmix_argv_append_nosize(&keys, sptr); + pmix_argv_append_nosize(&cd->keys, sptr); free(sptr); } /* unpack the number of info objects */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); - return rc; + goto cleanup; } /* we will be adding one for the user id */ - einfo = ninfo + 1; - PMIX_INFO_CREATE(info, einfo); + cd->ninfo = ninfo + 1; + PMIX_INFO_CREATE(cd->info, cd->ninfo); + if (NULL == cd->info) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } /* unpack the array of info objects */ if (0 < ninfo) { cnt=ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } } - (void)strncpy(info[einfo-1].key, PMIX_USERID, PMIX_MAX_KEYLEN); - info[einfo-1].value.type = PMIX_UINT32; - info[einfo-1].value.data.uint32 = uid; + (void)strncpy(cd->info[cd->ninfo-1].key, PMIX_USERID, PMIX_MAX_KEYLEN); + cd->info[cd->ninfo-1].value.type = PMIX_UINT32; + cd->info[cd->ninfo-1].value.data.uint32 = uid; /* call the local server */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; - rc = pmix_host_server.unpublish(&proc, keys, info, einfo, cbfunc, cbdata); + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; + rc = pmix_host_server.unpublish(&proc, cd->keys, cd->info, cd->ninfo, opcbfunc, cd); - cleanup: - pmix_argv_free(keys); + cleanup: + if (PMIX_SUCCESS != rc) { + if (NULL != cd->keys) { + pmix_argv_free(cd->keys); + } + if (NULL != cd->info) { + PMIX_INFO_FREE(cd->info, cd->ninfo); + } + PMIX_RELEASE(cd); + } return rc; } +static void spcbfunc(pmix_status_t status, + char nspace[], void *cbdata) +{ + pmix_setup_caddy_t *cd = (pmix_setup_caddy_t*)cbdata; + + /* cleanup the caddy */ + if (NULL != cd->info) { + PMIX_INFO_FREE(cd->info, cd->ninfo); + } + if (NULL != cd->apps) { + PMIX_APP_CREATE(cd->apps, cd->napps); + } + if (NULL != cd->spcbfunc) { + cd->spcbfunc(status, nspace, cd->cbdata); + } + PMIX_RELEASE(cd); +} + pmix_status_t pmix_server_spawn(pmix_peer_t *peer, pmix_buffer_t *buf, pmix_spawn_cbfunc_t cbfunc, void *cbdata) { + pmix_setup_caddy_t *cd; int32_t cnt; - size_t napps, ninfo; - pmix_info_t *info=NULL; - pmix_app_t *apps=NULL; pmix_status_t rc; pmix_proc_t proc; @@ -844,17 +1019,32 @@ pmix_status_t pmix_server_spawn(pmix_peer_t *peer, return PMIX_ERR_NOT_SUPPORTED; } + /* setup */ + cd = PMIX_NEW(pmix_setup_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } + cd->spcbfunc = cbfunc; + cd->cbdata = cbdata; + /* unpack the number of job-level directives */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); + PMIX_RELEASE(cd); return rc; } /* unpack the array of directives */ - if (0 < ninfo) { - PMIX_INFO_CREATE(info, ninfo); - cnt=ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, info, &cnt, PMIX_INFO))) { + if (0 < cd->ninfo) { + PMIX_INFO_CREATE(cd->info, cd->ninfo); + if (NULL == cd->info) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } + cnt = cd->ninfo; + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } @@ -862,30 +1052,39 @@ pmix_status_t pmix_server_spawn(pmix_peer_t *peer, /* unpack the number of apps */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &napps, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->napps, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); - return rc; + goto cleanup; } /* unpack the array of apps */ - if (0 < napps) { - PMIX_APP_CREATE(apps, napps); - cnt=napps; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, apps, &cnt, PMIX_APP))) { + if (0 < cd->napps) { + PMIX_APP_CREATE(cd->apps, cd->napps); + if (NULL == cd->apps) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } + cnt = cd->napps; + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->apps, &cnt, PMIX_APP); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } } /* call the local server */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; - rc = pmix_host_server.spawn(&proc, info, ninfo, apps, napps, cbfunc, cbdata); + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; + rc = pmix_host_server.spawn(&proc, cd->info, cd->ninfo, cd->apps, cd->napps, spcbfunc, cd); - cleanup: - if (NULL != info) { - PMIX_INFO_FREE(info, ninfo); - } - if (NULL != apps) { - PMIX_APP_FREE(apps, napps); + cleanup: + if (PMIX_SUCCESS != rc) { + if (NULL != cd->info) { + PMIX_INFO_FREE(cd->info, cd->ninfo); + } + if (NULL != cd->apps) { + PMIX_APP_FREE(cd->apps, cd->napps); + } + PMIX_RELEASE(cd); } return rc; } @@ -897,15 +1096,15 @@ pmix_status_t pmix_server_connect(pmix_server_caddy_t *cd, int32_t cnt; pmix_status_t rc; pmix_proc_t *procs = NULL; - size_t nprocs; - pmix_server_trkr_t *trk; pmix_info_t *info = NULL; - size_t ninfo=0; + size_t nprocs, ninfo; + pmix_server_trkr_t *trk; pmix_cmd_t type = PMIX_CONNECTNB_CMD; pmix_output_verbose(2, pmix_globals.debug_output, "recvd CONNECT from peer %s:%d", - cd->peer->info->nptr->nspace, cd->peer->info->rank); + cd->peer->info->pname.nspace, + cd->peer->info->pname.rank); if ((disconnect && NULL == pmix_host_server.disconnect) || (!disconnect && NULL == pmix_host_server.connect)) { @@ -914,7 +1113,8 @@ pmix_status_t pmix_server_connect(pmix_server_caddy_t *cd, /* unpack the number of procs */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &nprocs, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, &nprocs, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } @@ -931,22 +1131,33 @@ pmix_status_t pmix_server_connect(pmix_server_caddy_t *cd, /* unpack the procs */ PMIX_PROC_CREATE(procs, nprocs); + if (NULL == procs) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } cnt = nprocs; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, procs, &cnt, PMIX_PROC))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, procs, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } /* unpack the number of provided info structs */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, &ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { return rc; } if (0 < ninfo) { PMIX_INFO_CREATE(info, ninfo); + if (NULL == info) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } /* unpack the info */ cnt = ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, cd->peer, buf, info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { goto cleanup; } } @@ -956,6 +1167,7 @@ pmix_status_t pmix_server_connect(pmix_server_caddy_t *cd, type = PMIX_DISCONNECTNB_CMD; } if (NULL == (trk = get_tracker(procs, nprocs, type))) { + /* we don't have this tracker yet, so get a new one */ if (NULL == (trk = new_tracker(procs, nprocs, type))) { /* only if a bozo error occurs */ PMIX_ERROR_LOG(PMIX_ERROR); @@ -968,6 +1180,14 @@ pmix_status_t pmix_server_connect(pmix_server_caddy_t *cd, } trk->op_cbfunc = cbfunc; } + /* if the info keys have not been provided yet, pass + * them along here */ + if (NULL == trk->info && NULL != info) { + trk->info = info; + trk->ninfo = ninfo; + info = NULL; + ninfo = 0; + } /* add this contributor to the tracker so they get * notified when we are done */ @@ -980,9 +1200,9 @@ pmix_status_t pmix_server_connect(pmix_server_caddy_t *cd, if (trk->def_complete && pmix_list_get_size(&trk->local_cbs) == trk->nlocal) { if (disconnect) { - rc = pmix_host_server.disconnect(procs, nprocs, info, ninfo, cbfunc, trk); + rc = pmix_host_server.disconnect(trk->pcs, trk->npcs, trk->info, trk->ninfo, cbfunc, trk); } else { - rc = pmix_host_server.connect(procs, nprocs, info, ninfo, cbfunc, trk); + rc = pmix_host_server.connect(trk->pcs, trk->npcs, trk->info, trk->ninfo, cbfunc, trk); } } else { rc = PMIX_SUCCESS; @@ -1011,24 +1231,33 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, pmix_regevents_info_t *reginfo; pmix_peer_events_info_t *prev; pmix_notify_caddy_t *cd; + pmix_setup_caddy_t *scd; int i; bool enviro_events = false; bool found, matched; + pmix_buffer_t *relay; + pmix_cmd_t cmd = PMIX_NOTIFY_CMD; pmix_output_verbose(2, pmix_globals.debug_output, "recvd register events"); /* unpack the number of codes */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ncodes, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &ncodes, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* unpack the array of codes */ if (0 < ncodes) { codes = (pmix_status_t*)malloc(ncodes * sizeof(pmix_status_t)); + if (NULL == codes) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } cnt=ncodes; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, codes, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, codes, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } @@ -1036,15 +1265,21 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, /* unpack the number of info objects */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } /* unpack the array of info objects */ if (0 < ninfo) { PMIX_INFO_CREATE(info, ninfo); + if (NULL == info) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } cnt=ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto cleanup; } @@ -1106,6 +1341,10 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, if (!found) { /* get here if we don't already have this peer */ prev = PMIX_NEW(pmix_peer_events_info_t); + if (NULL == prev) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } PMIX_RETAIN(peer); prev->peer = peer; prev->enviro_events = enviro_events; @@ -1114,6 +1353,10 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, } else { /* if we get here, then we didn't find an existing registration for this code */ reginfo = PMIX_NEW(pmix_regevents_info_t); + if (NULL == reginfo) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } if (NULL == codes) { reginfo->code = PMIX_MAX_ERR_CONSTANT; } else { @@ -1121,6 +1364,10 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, } pmix_list_append(&pmix_server_globals.events, ®info->super); prev = PMIX_NEW(pmix_peer_events_info_t); + if (NULL == prev) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } PMIX_RETAIN(peer); prev->peer = peer; prev->enviro_events = enviro_events; @@ -1131,9 +1378,51 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, /* if they asked for enviro events, call the local server */ if (enviro_events) { - if (PMIX_SUCCESS != (rc = pmix_host_server.register_events(codes, ncodes, info, ninfo, cbfunc, cbdata))) { + /* need to ensure the arrays don't go away until after the + * host RM is done with them */ + scd = PMIX_NEW(pmix_setup_caddy_t); + if (NULL == scd) { + rc = PMIX_ERR_NOMEM; + goto cleanup; + } + if (NULL != codes) { + scd->codes = (pmix_status_t*)malloc(ncodes * sizeof(pmix_status_t)); + if (NULL == scd->codes) { + rc = PMIX_ERR_NOMEM; + PMIX_RELEASE(scd); + goto cleanup; + } + memcpy(scd->codes, codes, ncodes * sizeof(pmix_status_t)); + scd->ncodes = ncodes; + } + if (NULL != info) { + PMIX_INFO_CREATE(scd->info, ninfo); + if (NULL == scd->info) { + rc = PMIX_ERR_NOMEM; + if (NULL != scd->codes) { + free(scd->codes); + } + PMIX_RELEASE(scd); + goto cleanup; + } + /* copy the info across */ + for (n=0; n < ninfo; n++) { + PMIX_INFO_XFER(&scd->info[n], &info[n]); + } + scd->ninfo = ninfo; + } + scd->opcbfunc = cbfunc; + scd->cbdata = cbdata; + if (PMIX_SUCCESS != (rc = pmix_host_server.register_events(scd->codes, scd->ncodes, scd->info, scd->ninfo, opcbfunc, scd))) { pmix_output_verbose(2, pmix_globals.debug_output, "server register events: host server reg events returned rc =%d", rc); + if (NULL != scd->codes) { + free(scd->codes); + } + if (NULL != scd->info) { + PMIX_INFO_FREE(scd->info, scd->ninfo); + } + PMIX_RELEASE(scd); } else { goto check; } @@ -1150,10 +1439,8 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, PMIX_INFO_FREE(info, ninfo); } if (PMIX_SUCCESS != rc) { - if (!enviro_events) { - if (NULL != codes) { - free(codes); - } + if (NULL != codes) { + free(codes); } return rc; } @@ -1181,18 +1468,18 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, if (NULL != cd->targets) { matched = false; for (n=0; n < cd->ntargets; n++) { - if (0 != strncmp(peer->info->nptr->nspace, cd->targets[n].nspace, PMIX_MAX_NSLEN)) { + if (0 != strncmp(peer->info->pname.nspace, cd->targets[n].nspace, PMIX_MAX_NSLEN)) { continue; } /* if the source of the event is the same peer just registered, then ignore it * as the event notification system will have already locally * processed it */ - if (0 == strncmp(peer->info->nptr->nspace, cd->source.nspace, PMIX_MAX_NSLEN) && - peer->info->rank == cd->source.rank) { + if (0 == strncmp(peer->info->pname.nspace, cd->source.nspace, PMIX_MAX_NSLEN) && + peer->info->pname.rank == cd->source.rank) { continue; } if (PMIX_RANK_WILDCARD == cd->targets[n].rank || - peer->info->rank == cd->targets[n].rank) { + peer->info->pname.rank == cd->targets[n].rank) { matched = true; break; } @@ -1202,9 +1489,42 @@ pmix_status_t pmix_server_register_events(pmix_peer_t *peer, continue; } } - /* all matches - notify */ - PMIX_RETAIN(cd->buf); - PMIX_SERVER_QUEUE_REPLY(peer, 0, cd->buf); + /* all matches - notify */ + relay = PMIX_NEW(pmix_buffer_t); + if (NULL == relay) { + /* nothing we can do */ + PMIX_ERROR_LOG(PMIX_ERR_NOMEM); + return PMIX_ERR_NOMEM; + } + /* pack the info data stored in the event */ + PMIX_BFROPS_PACK(rc, peer, relay, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + break; + } + PMIX_BFROPS_PACK(rc, peer, relay, &cd->status, 1, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + break; + } + PMIX_BFROPS_PACK(rc, peer, relay, &cd->source, 1, PMIX_PROC); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + break; + } + PMIX_BFROPS_PACK(rc, peer, relay, &cd->ninfo, 1, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + break; + } + if (0 < cd->ninfo) { + PMIX_BFROPS_PACK(rc, peer, relay, cd->info, cd->ninfo, PMIX_INFO); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + break; + } + } + PMIX_SERVER_QUEUE_REPLY(peer, 0, relay); } } if (!enviro_events) { @@ -1230,7 +1550,8 @@ void pmix_server_deregister_events(pmix_peer_t *peer, /* unpack codes and process until done */ cnt=1; - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(buf, &code, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &code, &cnt, PMIX_STATUS); + while (PMIX_SUCCESS == rc) { PMIX_LIST_FOREACH_SAFE(reginfo, reginfo_next, &pmix_server_globals.events, pmix_regevents_info_t) { if (code == reginfo->code) { /* found it - remove this peer from the list */ @@ -1250,6 +1571,8 @@ void pmix_server_deregister_events(pmix_peer_t *peer, } } } + cnt=1; + PMIX_BFROPS_UNPACK(rc, peer, buf, &code, &cnt, PMIX_STATUS); } if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { PMIX_ERROR_LOG(rc); @@ -1284,36 +1607,47 @@ pmix_status_t pmix_server_event_recvd_from_client(pmix_peer_t *peer, } cd = PMIX_NEW(pmix_notify_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } cd->cbfunc = cbfunc; cd->cbdata = cbdata; /* set the source */ - (void)strncpy(cd->source.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - cd->source.rank = peer->info->rank; + (void)strncpy(cd->source.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + cd->source.rank = peer->info->pname.rank; /* unpack status */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->status, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->status, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } /* unpack the range */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->range, &cnt, PMIX_DATA_RANGE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->range, &cnt, PMIX_DATA_RANGE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } /* unpack the info keys */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } if (0 < cd->ninfo) { PMIX_INFO_CREATE(cd->info, cd->ninfo); + if (NULL == cd->info) { + rc = PMIX_ERR_NOMEM; + goto exit; + } cnt = cd->ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, cd->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } @@ -1364,26 +1698,35 @@ pmix_status_t pmix_server_query(pmix_peer_t *peer, } cd = PMIX_NEW(pmix_query_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } cd->cbdata = cbdata; /* unpack the number of queries */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->nqueries, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->nqueries, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } /* unpack the queries */ if (0 < cd->nqueries) { PMIX_QUERY_CREATE(cd->queries, cd->nqueries); + if (NULL == cd->queries) { + rc = PMIX_ERR_NOMEM; + goto exit; + } cnt = cd->nqueries; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, cd->queries, &cnt, PMIX_QUERY))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->queries, &cnt, PMIX_QUERY); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } } /* setup the requesting peer name */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; /* ask the host for the info */ if (PMIX_SUCCESS != (rc = pmix_host_server.query(&proc, cd->queries, cd->nqueries, @@ -1423,11 +1766,15 @@ pmix_status_t pmix_server_log(pmix_peer_t *peer, } cd = PMIX_NEW(pmix_shift_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } cd->cbfunc.opcbfn = cbfunc; cd->cbdata = cbdata; /* unpack the number of data */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } @@ -1435,14 +1782,16 @@ pmix_status_t pmix_server_log(pmix_peer_t *peer, if (0 < cd->ninfo) { PMIX_INFO_CREATE(cd->info, cd->ninfo); cnt = cd->ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, cd->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } } /* unpack the number of directives */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->ndirs, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->ndirs, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } @@ -1450,15 +1799,16 @@ pmix_status_t pmix_server_log(pmix_peer_t *peer, if (0 < cd->ndirs) { PMIX_INFO_CREATE(cd->directives, cd->ndirs); cnt = cd->ndirs; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, cd->directives, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->directives, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } } /* setup the requesting peer name */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; /* ask the host to log the info */ pmix_host_server.log(&proc, cd->info, cd->ninfo, @@ -1490,18 +1840,23 @@ pmix_status_t pmix_server_alloc(pmix_peer_t *peer, } cd = PMIX_NEW(pmix_query_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } cd->cbdata = cbdata; /* unpack the directive */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &directive, &cnt, PMIX_ALLOC_DIRECTIVE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &directive, &cnt, PMIX_ALLOC_DIRECTIVE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } /* unpack the number of info objects */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } @@ -1509,15 +1864,16 @@ pmix_status_t pmix_server_alloc(pmix_peer_t *peer, if (0 < cd->ninfo) { PMIX_INFO_CREATE(cd->info, cd->ninfo); cnt = cd->ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, cd->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } } /* setup the requesting peer name */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; /* ask the host to execute the request */ if (PMIX_SUCCESS != (rc = pmix_host_server.allocate(&proc, directive, @@ -1550,25 +1906,31 @@ pmix_status_t pmix_server_job_ctrl(pmix_peer_t *peer, } cd = PMIX_NEW(pmix_query_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } cd->cbdata = cbdata; /* unpack the number of targets */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->ntargets, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->ntargets, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } if (0 < cd->ntargets) { PMIX_PROC_CREATE(cd->targets, cd->ntargets); cnt = cd->ntargets; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, cd->targets, &cnt, PMIX_PROC))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->targets, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } } /* unpack the number of info objects */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } @@ -1576,15 +1938,16 @@ pmix_status_t pmix_server_job_ctrl(pmix_peer_t *peer, if (0 < cd->ninfo) { PMIX_INFO_CREATE(cd->info, cd->ninfo); cnt = cd->ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, cd->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } } /* setup the requesting peer name */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; /* ask the host to execute the request */ if (PMIX_SUCCESS != (rc = pmix_host_server.job_control(&proc, @@ -1619,26 +1982,32 @@ pmix_status_t pmix_server_monitor(pmix_peer_t *peer, } cd = PMIX_NEW(pmix_query_caddy_t); + if (NULL == cd) { + return PMIX_ERR_NOMEM; + } cd->cbdata = cbdata; /* unpack what is to be monitored */ PMIX_INFO_CONSTRUCT(&monitor); cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &monitor, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &monitor, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } /* unpack the error code */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &error, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &error, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } /* unpack the number of directives */ cnt = 1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cd->ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, &cd->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } @@ -1646,15 +2015,16 @@ pmix_status_t pmix_server_monitor(pmix_peer_t *peer, if (0 < cd->ninfo) { PMIX_INFO_CREATE(cd->info, cd->ninfo); cnt = cd->ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, cd->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, peer, buf, cd->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto exit; } } /* setup the requesting peer name */ - (void)strncpy(proc.nspace, peer->info->nptr->nspace, PMIX_MAX_NSLEN); - proc.rank = peer->info->rank; + (void)strncpy(proc.nspace, peer->info->pname.nspace, PMIX_MAX_NSLEN); + proc.rank = peer->info->pname.rank; /* ask the host to execute the request */ if (PMIX_SUCCESS != (rc = pmix_host_server.monitor(&proc, &monitor, error, @@ -1677,7 +2047,6 @@ static void tcon(pmix_server_trkr_t *t) t->npcs = 0; PMIX_CONSTRUCT_LOCK(&t->lock); t->def_complete = false; - PMIX_CONSTRUCT(&t->ranks, pmix_list_t); PMIX_CONSTRUCT(&t->local_cbs, pmix_list_t); t->nlocal = 0; t->local_cnt = 0; @@ -1694,9 +2063,10 @@ static void tdes(pmix_server_trkr_t *t) if (NULL != t->pcs) { free(t->pcs); } - PMIX_LIST_DESTRUCT(&t->ranks); PMIX_LIST_DESTRUCT(&t->local_cbs); - PMIX_INFO_FREE(t->info, t->ninfo); + if (NULL != t->info) { + PMIX_INFO_FREE(t->info, t->ninfo); + } } PMIX_CLASS_INSTANCE(pmix_server_trkr_t, pmix_list_item_t, @@ -1705,36 +2075,37 @@ PMIX_CLASS_INSTANCE(pmix_server_trkr_t, static void cdcon(pmix_server_caddy_t *cd) { cd->peer = NULL; - PMIX_CONSTRUCT(&cd->snd, pmix_snd_caddy_t); } static void cddes(pmix_server_caddy_t *cd) { if (NULL != cd->peer) { PMIX_RELEASE(cd->peer); } - PMIX_DESTRUCT(&cd->snd); } PMIX_CLASS_INSTANCE(pmix_server_caddy_t, pmix_list_item_t, cdcon, cddes); -PMIX_CLASS_INSTANCE(pmix_snd_caddy_t, - pmix_object_t, - NULL, NULL); - static void scadcon(pmix_setup_caddy_t *p) { memset(&p->proc, 0, sizeof(pmix_proc_t)); PMIX_CONSTRUCT_LOCK(&p->lock); p->nspace = NULL; + p->codes = NULL; + p->ncodes = 0; + p->procs = NULL; + p->nprocs = 0; p->server_object = NULL; p->nlocalprocs = 0; p->info = NULL; p->ninfo = 0; + p->keys = NULL; p->cbfunc = NULL; p->opcbfunc = NULL; p->setupcbfunc = NULL; + p->lkcbfunc = NULL; + p->spcbfunc = NULL; p->cbdata = NULL; } static void scaddes(pmix_setup_caddy_t *p) @@ -1756,7 +2127,6 @@ static void ncon(pmix_notify_caddy_t *p) p->nondefault = false; p->info = NULL; p->ninfo = 0; - p->buf = PMIX_NEW(pmix_buffer_t); } static void ndes(pmix_notify_caddy_t *p) { @@ -1767,9 +2137,6 @@ static void ndes(pmix_notify_caddy_t *p) if (NULL != p->targets) { free(p->targets); } - if (NULL != p->buf) { - PMIX_RELEASE(p->buf); - } } PMIX_CLASS_INSTANCE(pmix_notify_caddy_t, pmix_object_t, diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_ops.h b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_ops.h index dac731d224..7a8c380bea 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_ops.h +++ b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_ops.h @@ -15,11 +15,13 @@ #define PMIX_SERVER_OPS_H #include - +#include "src/include/types.h" #include + #include #include #include "src/threads/threads.h" +#include "src/include/pmix_globals.h" #include "src/util/hash.h" typedef struct { @@ -35,16 +37,25 @@ typedef struct { pmix_lock_t lock; char *nspace; pmix_status_t status; + pmix_status_t *codes; + size_t ncodes; pmix_proc_t proc; + pmix_proc_t *procs; + size_t nprocs; uid_t uid; gid_t gid; void *server_object; int nlocalprocs; pmix_info_t *info; size_t ninfo; + char **keys; + pmix_app_t *apps; + size_t napps; pmix_op_cbfunc_t opcbfunc; pmix_dmodex_response_fn_t cbfunc; pmix_setup_application_cbfunc_t setupcbfunc; + pmix_lookup_cbfunc_t lkcbfunc; + pmix_spawn_cbfunc_t spcbfunc; void *cbdata; } pmix_setup_caddy_t; PMIX_CLASS_DECLARATION(pmix_setup_caddy_t); @@ -88,16 +99,17 @@ typedef struct { PMIX_CLASS_DECLARATION(pmix_regevents_info_t); typedef struct { + pmix_list_t nspaces; // list of pmix_nspace_t for the nspaces we know about pmix_pointer_array_t clients; // array of pmix_peer_t local clients pmix_list_t collectives; // list of active pmix_server_trkr_t pmix_list_t remote_pnd; // list of pmix_dmdx_remote_t awaiting arrival of data fror servicing remote req's pmix_list_t local_reqs; // list of pmix_dmdx_local_t awaiting arrival of data from local neighbours - pmix_buffer_t gdata; // cache of data given to me for passing to all clients + pmix_list_t gdata; // cache of data given to me for passing to all clients pmix_list_t events; // list of pmix_regevents_info_t registered events bool tool_connections_allowed; } pmix_server_globals_t; -#define PMIX_PEER_CADDY(c, p, t) \ +#define PMIX_GDS_CADDY(c, p, t) \ do { \ (c) = PMIX_NEW(pmix_server_caddy_t); \ (c)->hdr.tag = (t); \ @@ -166,11 +178,6 @@ pmix_status_t pmix_server_connect(pmix_server_caddy_t *cd, pmix_buffer_t *buf, bool disconnect, pmix_op_cbfunc_t cbfunc); -void pmix_pack_proc_map(pmix_buffer_t *buf, - char **nodes, char **procs); -pmix_status_t pmix_regex_parse_nodes(const char *regexp, char ***names); -pmix_status_t pmix_regex_parse_procs(const char *regexp, char ***procs); - pmix_status_t pmix_server_notify_error(pmix_status_t status, pmix_proc_t procs[], size_t nprocs, pmix_proc_t error_procs[], size_t error_nprocs, diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_regex.c b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_regex.c deleted file mode 100644 index 090b417491..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_regex.c +++ /dev/null @@ -1,553 +0,0 @@ -/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ -/* - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. - * Copyright (c) 2014-2015 Research Organization for Information Science - * and Technology (RIST). All rights reserved. - * Copyright (c) 2014 Artem Y. Polyakov . - * All rights reserved. - * Copyright (c) 2016 Mellanox Technologies, Inc. - * All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#include - -#include -#include -#include - -#include "src/include/pmix_globals.h" - -#ifdef HAVE_STRING_H -#include -#endif -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#include - -#include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" -#include "src/util/argv.h" -#include "src/util/error.h" -#include "src/util/output.h" -#include "src/server/pmix_server_ops.h" - -static pmix_status_t regex_parse_value_ranges(char *base, char *ranges, - int num_digits, char *suffix, - char ***names); -static pmix_status_t regex_parse_value_range(char *base, char *range, - int num_digits, char *suffix, - char ***names); -static pmix_status_t pmix_regex_extract_nodes(char *regexp, char ***names); -static pmix_status_t pmix_regex_extract_ppn(char *regexp, char ***procs); - -/* we need to pass three things to the client: - * - * (a) the list of nodes involved in this nspace - * - * (b) the hostname for each proc in this nspace - * - * (c) the list of procs on each node for reverse lookup - */ -void pmix_pack_proc_map(pmix_buffer_t *buf, - char **nodes, char **procs) -{ - pmix_kval_t kv; - pmix_value_t val; - pmix_status_t rc; - pmix_buffer_t buf2; - size_t i, nnodes; - - /* bozo check - need procs for each node */ - if (pmix_argv_count(nodes) != pmix_argv_count(procs)) { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - return; - } - - PMIX_CONSTRUCT(&buf2, pmix_buffer_t); - PMIX_CONSTRUCT(&kv, pmix_kval_t); - kv.value = &val; - val.type = PMIX_STRING; - - /* pass the number of nodes involved in this namespace */ - nnodes = pmix_argv_count(nodes); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&buf2, &nnodes, 1, PMIX_SIZE))) { - PMIX_ERROR_LOG(rc); - goto cleanup; - } - - for (i=0; i < nnodes; i++) { - /* pass the complete list of procs on this node */ - kv.key = nodes[i]; - val.data.string = procs[i]; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(&buf2, &kv, 1, PMIX_KVAL))) { - PMIX_ERROR_LOG(rc); - kv.key = NULL; - val.data.string = NULL; - goto cleanup; - } - } - kv.key = NULL; - val.data.string = NULL; - - /* pass the completed blob */ - kv.key = PMIX_MAP_BLOB; - val.type = PMIX_BYTE_OBJECT; - val.data.bo.bytes = buf2.base_ptr; - val.data.bo.size = buf2.bytes_used; - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(buf, &kv, 1, PMIX_KVAL))) { - PMIX_ERROR_LOG(rc); - } - kv.key = NULL; - kv.value = NULL; - val.data.bo.bytes = NULL; - val.data.bo.size = 0; - - cleanup: - PMIX_DESTRUCT(&buf2); - PMIX_DESTRUCT(&kv); - return; -} - - -pmix_status_t pmix_regex_parse_nodes(const char *regexp, char ***names) -{ - char *tmp, *ptr; - pmix_status_t rc; - - /* set default */ - *names = NULL; - - /* protect against bozo */ - if (NULL == regexp) { - return PMIX_SUCCESS; - } - - /* protect the input string */ - tmp = strdup(regexp); - /* strip the trailing bracket */ - tmp[strlen(tmp)-1] = '\0'; - - /* the regex generator used to create this regex - * is tagged at the beginning of the string */ - if (NULL == (ptr = strchr(tmp, '['))) { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - free(tmp); - return PMIX_ERR_BAD_PARAM; - } - *ptr = '\0'; - ++ptr; - - /* if it was done by PMIx, use that parser */ - if (0 == strcmp(tmp, "pmix")) { - if (PMIX_SUCCESS != (rc = pmix_regex_extract_nodes(ptr, names))) { - PMIX_ERROR_LOG(rc); - } - } else { - PMIX_ERROR_LOG(PMIX_ERR_NOT_SUPPORTED); - rc = PMIX_ERR_NOT_SUPPORTED; - } - free(tmp); - return rc; -} - - -pmix_status_t pmix_regex_parse_procs(const char *regexp, char ***procs) -{ - char *tmp, *ptr; - pmix_status_t rc; - - /* set default */ - *procs = NULL; - - /* protect against bozo */ - if (NULL == regexp) { - return PMIX_SUCCESS; - } - - /* protect the input string */ - tmp = strdup(regexp); - /* strip the trailing bracket */ - tmp[strlen(tmp)-1] = '\0'; - - /* the regex generator used to create this regex - * is tagged at the beginning of the string */ - if (NULL == (ptr = strchr(tmp, '['))) { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - free(tmp); - return PMIX_ERR_BAD_PARAM; - } - *ptr = '\0'; - ++ptr; - - /* if it was done by PMIx, use that parser */ - if (0 == strcmp(tmp, "pmix")) { - if (PMIX_SUCCESS != (rc = pmix_regex_extract_ppn(ptr, procs))) { - PMIX_ERROR_LOG(rc); - } - } else { - PMIX_ERROR_LOG(PMIX_ERR_NOT_SUPPORTED); - rc = PMIX_ERR_NOT_SUPPORTED; - } - free(tmp); - return rc; -} - - -static pmix_status_t pmix_regex_extract_nodes(char *regexp, char ***names) -{ - int i, j, k, len; - pmix_status_t ret; - char *base; - char *orig, *suffix; - bool found_range = false; - bool more_to_come = false; - int num_digits; - - /* set the default */ - *names = NULL; - - if (NULL == regexp) { - return PMIX_SUCCESS; - } - - orig = base = strdup(regexp); - if (NULL == base) { - PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); - return PMIX_ERR_OUT_OF_RESOURCE; - } - - PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, - "pmix:extract:nodes: checking list: %s", regexp)); - - do { - /* Find the base */ - len = strlen(base); - for (i = 0; i <= len; ++i) { - if (base[i] == '[') { - /* we found a range. this gets dealt with below */ - base[i] = '\0'; - found_range = true; - break; - } - if (base[i] == ',') { - /* we found a singleton value, and there are more to come */ - base[i] = '\0'; - found_range = false; - more_to_come = true; - break; - } - if (base[i] == '\0') { - /* we found a singleton value */ - found_range = false; - more_to_come = false; - break; - } - } - if (i == 0 && !found_range) { - /* we found a special character at the beginning of the string */ - free(orig); - return PMIX_ERR_BAD_PARAM; - } - - if (found_range) { - /* If we found a range, get the number of digits in the numbers */ - i++; /* step over the [ */ - for (j=i; j < len; j++) { - if (base[j] == ':') { - base[j] = '\0'; - break; - } - } - if (j >= len) { - /* we didn't find the number of digits */ - free(orig); - return PMIX_ERR_BAD_PARAM; - } - num_digits = strtol(&base[i], NULL, 10); - i = j + 1; /* step over the : */ - /* now find the end of the range */ - for (j = i; j < len; ++j) { - if (base[j] == ']') { - base[j] = '\0'; - break; - } - } - if (j >= len) { - /* we didn't find the end of the range */ - free(orig); - return PMIX_ERR_BAD_PARAM; - } - /* check for a suffix */ - if (j+1 < len && base[j+1] != ',') { - /* find the next comma, if present */ - for (k=j+1; k < len && base[k] != ','; k++); - if (k < len) { - base[k] = '\0'; - } - suffix = strdup(&base[j+1]); - if (k < len) { - base[k] = ','; - } - j = k-1; - } else { - suffix = NULL; - } - PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, - "regex:extract:nodes: parsing range %s %s %s", - base, base + i, suffix)); - - ret = regex_parse_value_ranges(base, base + i, num_digits, suffix, names); - if (NULL != suffix) { - free(suffix); - } - if (PMIX_SUCCESS != ret) { - free(orig); - return ret; - } - if (j+1 < len && base[j + 1] == ',') { - more_to_come = true; - base = &base[j + 2]; - } else { - more_to_come = false; - } - } else { - /* If we didn't find a range, just add the value */ - if(PMIX_SUCCESS != (ret = pmix_argv_append_nosize(names, base))) { - PMIX_ERROR_LOG(ret); - free(orig); - return ret; - } - /* step over the comma */ - i++; - /* set base equal to the (possible) next base to look at */ - base = &base[i]; - } - } while(more_to_come); - - free(orig); - - /* All done */ - return ret; -} - - -/* - * Parse one or more ranges in a set - * - * @param base The base text of the value name - * @param *ranges A pointer to a range. This can contain multiple ranges - * (i.e. "1-3,10" or "5" or "9,0100-0130,250") - * @param ***names An argv array to add the newly discovered values to - */ -static pmix_status_t regex_parse_value_ranges(char *base, char *ranges, - int num_digits, char *suffix, - char ***names) -{ - int i, len; - pmix_status_t ret; - char *start, *orig; - - /* Look for commas, the separator between ranges */ - - len = strlen(ranges); - for (orig = start = ranges, i = 0; i < len; ++i) { - if (',' == ranges[i]) { - ranges[i] = '\0'; - ret = regex_parse_value_range(base, start, num_digits, suffix, names); - if (PMIX_SUCCESS != ret) { - PMIX_ERROR_LOG(ret); - return ret; - } - start = ranges + i + 1; - } - } - - /* Pick up the last range, if it exists */ - - if (start < orig + len) { - - PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, - "regex:parse:ranges: parse range %s (2)", start)); - - ret = regex_parse_value_range(base, start, num_digits, suffix, names); - if (PMIX_SUCCESS != ret) { - PMIX_ERROR_LOG(ret); - return ret; - } - } - - /* All done */ - return PMIX_SUCCESS; -} - - -/* - * Parse a single range in a set and add the full names of the values - * found to the names argv - * - * @param base The base text of the value name - * @param *ranges A pointer to a single range. (i.e. "1-3" or "5") - * @param ***names An argv array to add the newly discovered values to - */ -static pmix_status_t regex_parse_value_range(char *base, char *range, - int num_digits, char *suffix, - char ***names) -{ - char *str, tmp[132]; - size_t i, k, start, end; - size_t base_len, len; - bool found; - pmix_status_t ret; - - if (NULL == base || NULL == range) { - return PMIX_ERROR; - } - - len = strlen(range); - base_len = strlen(base); - /* Silence compiler warnings; start and end are always assigned - properly, below */ - start = end = 0; - - /* Look for the beginning of the first number */ - - for (found = false, i = 0; i < len; ++i) { - if (isdigit((int) range[i])) { - if (!found) { - start = atoi(range + i); - found = true; - break; - } - } - } - if (!found) { - PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); - return PMIX_ERR_NOT_FOUND; - } - - /* Look for the end of the first number */ - - for (found = false; i < len; ++i) { - if (!isdigit(range[i])) { - break; - } - } - - /* Was there no range, just a single number? */ - - if (i >= len) { - end = start; - found = true; - } else { - /* Nope, there was a range. Look for the beginning of the second - * number - */ - for (; i < len; ++i) { - if (isdigit(range[i])) { - end = strtol(range + i, NULL, 10); - found = true; - break; - } - } - } - if (!found) { - PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); - return PMIX_ERR_NOT_FOUND; - } - - /* Make strings for all values in the range */ - - len = base_len + num_digits + 32; - if (NULL != suffix) { - len += strlen(suffix); - } - str = (char *) malloc(len); - if (NULL == str) { - PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); - return PMIX_ERR_OUT_OF_RESOURCE; - } - for (i = start; i <= end; ++i) { - memset(str, 0, len); - strcpy(str, base); - /* we need to zero-pad the digits */ - for (k=0; k < (size_t)num_digits; k++) { - str[k+base_len] = '0'; - } - memset(tmp, 0, 132); - snprintf(tmp, 132, "%lu", (unsigned long)i); - for (k=0; k < strlen(tmp); k++) { - str[base_len + num_digits - k - 1] = tmp[strlen(tmp)-k-1]; - } - /* if there is a suffix, add it */ - if (NULL != suffix) { - strcat(str, suffix); - } - ret = pmix_argv_append_nosize(names, str); - if(PMIX_SUCCESS != ret) { - PMIX_ERROR_LOG(ret); - free(str); - return ret; - } - } - free(str); - - /* All done */ - return PMIX_SUCCESS; -} - -static pmix_status_t pmix_regex_extract_ppn(char *regexp, char ***procs) -{ - char **rngs, **nds, *t, **ps=NULL; - int i, j, k, start, end; - - /* split on semi-colons for nodes */ - nds = pmix_argv_split(regexp, ';'); - for (j=0; NULL != nds[j]; j++) { - /* for each node, split it by comma */ - rngs = pmix_argv_split(nds[j], ','); - /* parse each element */ - for (i=0; NULL != rngs[i]; i++) { - /* look for a range */ - if (NULL == (t = strchr(rngs[i], '-'))) { - /* just one value */ - pmix_argv_append_nosize(&ps, rngs[i]); - } else { - /* handle the range */ - *t = '\0'; - start = strtol(rngs[i], NULL, 10); - ++t; - end = strtol(t, NULL, 10); - for (k=start; k <= end; k++) { - if (0 > asprintf(&t, "%d", k)) { - pmix_argv_free(nds); - pmix_argv_free(rngs); - return PMIX_ERR_NOMEM; - } - pmix_argv_append_nosize(&ps, t); - free(t); - } - } - } - pmix_argv_free(rngs); - /* create the node entry */ - t = pmix_argv_join(ps, ','); - pmix_argv_append_nosize(procs, t); - free(t); - pmix_argv_free(ps); - ps = NULL; - } - - pmix_argv_free(nds); - return PMIX_SUCCESS; -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/sm/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/sm/Makefile.include deleted file mode 100644 index 9ce63027d2..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/Makefile.include +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2016 Mellanox Technologies, Inc. -# All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -headers += \ - sm/pmix_sm.h \ - sm/pmix_mmap.h - -sources += \ - sm/pmix_sm.c \ - sm/pmix_mmap.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.c b/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.c deleted file mode 100644 index 26769267d0..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2015-2016 Mellanox Technologies, Inc. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#include -#include -#include "src/include/pmix_globals.h" - -#include "pmix_sm.h" -#include "pmix_mmap.h" - - -/* - * Array of all possible SMs - */ - -/**** ENSURE THE FOLLOWING VALUE IS AT LEAST AS - **** LARGE AS THE TOTAL NUMBER OF SUPPORTED SPCs - **** IN THE ARRAY BELOW - */ - -static pmix_sm_base_module_t *all[] = { - &pmix_sm_mmap_module, - - /* Always end the array with a NULL */ - NULL -}; - -pmix_sm_base_module_t pmix_sm = {0}; - -int pmix_sm_init(void) -{ - pmix_sm = *all[0]; - return PMIX_SUCCESS; -} - -void pmix_sm_finalize(void) -{ - return ; -} - -int pmix_sm_segment_create(pmix_sm_seg_t *sm_seg, const char *file_name, size_t size) -{ - if (!pmix_sm.segment_create) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_sm.segment_create(sm_seg, file_name, size); -} - -int pmix_sm_segment_attach(pmix_sm_seg_t *sm_seg, pmix_sm_access_mode_t sm_mode) -{ - if (!pmix_sm.segment_attach) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_sm.segment_attach(sm_seg, sm_mode); -} - -int pmix_sm_segment_detach(pmix_sm_seg_t *sm_seg) -{ - if (!pmix_sm.segment_detach) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_sm.segment_detach(sm_seg); -} - -int pmix_sm_segment_unlink(pmix_sm_seg_t *sm_seg) -{ - if (!pmix_sm.segment_unlink) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_sm.segment_unlink(sm_seg); -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.h b/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.h deleted file mode 100644 index 4e2495950a..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2015-2016 Mellanox Technologies, Inc. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#ifndef PMIX_SM_H -#define PMIX_SM_H - -#include - - - -BEGIN_C_DECLS - -#if !defined(MAP_FAILED) -# define MAP_FAILED ((char*)-1) -#endif /* MAP_FAILED */ - -#define PMIX_SHMEM_DS_ID_INVALID -1 - -typedef enum { - PMIX_SM_RONLY, - PMIX_SM_RW -} pmix_sm_access_mode_t; - -typedef struct pmix_sm_seg_t { - /* pid of the shared memory segment creator */ - pid_t seg_cpid; - /* ds id */ - int seg_id; - /* size of shared memory segment */ - size_t seg_size; - /* base address of shared memory segment */ - unsigned char *seg_base_addr; - char seg_name[PMIX_PATH_MAX]; -} pmix_sm_seg_t; - -int pmix_sm_init(void); -void pmix_sm_finalize(void); -int pmix_sm_segment_create(pmix_sm_seg_t *sm_seg, const char *file_name, size_t size); -int pmix_sm_segment_attach(pmix_sm_seg_t *sm_seg, pmix_sm_access_mode_t sm_mode); -int pmix_sm_segment_detach(pmix_sm_seg_t *sm_seg); -int pmix_sm_segment_unlink(pmix_sm_seg_t *sm_seg); - -static inline void _segment_ds_reset(pmix_sm_seg_t *sm_seg) -{ - sm_seg->seg_cpid = 0; - sm_seg->seg_id = PMIX_SHMEM_DS_ID_INVALID; - sm_seg->seg_size = 0; - memset(sm_seg->seg_name, '\0', PMIX_PATH_MAX); - sm_seg->seg_base_addr = (unsigned char *)MAP_FAILED; -} - - -/** -* create a new shared memory segment and initialize members in structure -* pointed to by sm_seg. -* -* @param sm_seg pointer to pmix_sm_seg_t structure -* -* @param file_name unique string identifier that must be a valid, -* writable path (IN). -* -* @param size size of the shared memory segment. -* -* @return PMIX_SUCCESS on success. -*/ -typedef int (*pmix_sm_base_module_segment_create_fn_t)(pmix_sm_seg_t *sm_seg, const char *file_name, size_t size); - -/** -* attach to an existing shared memory segment initialized by segment_create. -* -* @param sm_seg pointer to initialized pmix_sm_seg_t typedef'd -* structure (IN/OUT). -* -* @return base address of shared memory segment on success. returns -* NULL otherwise. -*/ -typedef int (*pmix_sm_base_module_segment_attach_fn_t)(pmix_sm_seg_t *sm_seg, pmix_sm_access_mode_t sm_mode); - -/** -* detach from an existing shared memory segment. -* -* @param sm_seg pointer to initialized pmix_sm_seg_t typedef'd structure -* (IN/OUT). -* -* @return PMIX_SUCCESS on success. -*/ -typedef int (*pmix_sm_base_module_segment_detach_fn_t)(pmix_sm_seg_t *sm_seg); - -/** -* unlink an existing shared memory segment. -* -* @param sm_seg pointer to initialized pmix_sm_seg_t typedef'd structure -* (IN/OUT). -* -* @return PMIX_SUCCESS on success. -*/ -typedef int (*pmix_sm_base_module_unlink_fn_t)(pmix_sm_seg_t *sm_seg); - - -/** -* structure for sm modules -*/ -typedef struct { - const char *name; - pmix_sm_base_module_segment_create_fn_t segment_create; - pmix_sm_base_module_segment_attach_fn_t segment_attach; - pmix_sm_base_module_segment_detach_fn_t segment_detach; - pmix_sm_base_module_unlink_fn_t segment_unlink; -} pmix_sm_base_module_t; - - -END_C_DECLS - -#endif /* PMIX_SM_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.c b/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.c index c825f4cb6b..9fcb7becf4 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.c +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.c @@ -17,7 +17,7 @@ static pmix_mutex_t wait_sync_lock = PMIX_MUTEX_STATIC_INIT; static pmix_wait_sync_t* wait_sync_list = NULL; -#define PMIX_WAIT_SYNC_PASS_OWNERSHIP(who) \ +#define PMIX_WAIT_SYNC_PASS_OWNERSHIP(who) \ do { \ pthread_mutex_lock( &(who)->lock); \ pthread_cond_signal( &(who)->condition ); \ diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.h b/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.h index e0ac8c63f1..d20704da62 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.h +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.h @@ -9,7 +9,6 @@ * Copyright (c) 2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2017 Intel, Inc. All rights reserved. - * Copyright (c) 2017 IBM Corporation. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -41,7 +40,7 @@ typedef struct pmix_wait_sync_t { #define REQUEST_PENDING (void*)0L #define REQUEST_COMPLETED (void*)1L -#define PMIX_SYNC_WAIT(sync) ompi_sync_wait_mt (sync) +#define PMIX_SYNC_WAIT(sync) pmix_sync_wait_mt (sync) /* The loop in release handles a race condition between the signaling * thread and the destruction of the condition variable. The signaling @@ -51,25 +50,25 @@ typedef struct pmix_wait_sync_t { * as possible. Note that the race window is small so spinning here * is more optimal than sleeping since this macro is called in * the critical path. */ -#define PMIX_WAIT_SYNC_RELEASE(sync) \ +#define PMIX_WAIT_SYNC_RELEASE(sync) \ while ((sync)->signaling) { \ continue; \ } \ pthread_cond_destroy(&(sync)->condition); \ pthread_mutex_destroy(&(sync)->lock); -#define PMIX_WAIT_SYNC_RELEASE_NOWAIT(sync) \ +#define PMIX_WAIT_SYNC_RELEASE_NOWAIT(sync) \ pthread_cond_destroy(&(sync)->condition); \ pthread_mutex_destroy(&(sync)->lock); -#define PMIX_WAIT_SYNC_SIGNAL(sync) \ +#define PMIX_WAIT_SYNC_SIGNAL(sync) \ pthread_mutex_lock(&(sync->lock)); \ pthread_cond_signal(&sync->condition); \ pthread_mutex_unlock(&(sync->lock)); \ sync->signaling = false; -#define PMIX_WAIT_SYNC_SIGNALLED(sync){ \ +#define PMIX_WAIT_SYNC_SIGNALLED(sync){ \ (sync)->signaling = false; \ } @@ -83,7 +82,7 @@ static inline int pmix_sync_wait_st (pmix_wait_sync_t *sync) } -#define PMIX_WAIT_SYNC_INIT(sync,c) \ +#define PMIX_WAIT_SYNC_INIT(sync,c) \ do { \ (sync)->count = (c); \ (sync)->next = NULL; \ @@ -100,7 +99,8 @@ static inline int pmix_sync_wait_st (pmix_wait_sync_t *sync) * triggered. The status of the synchronization will be reported to * the waiting threads. */ -static inline void pmix_wait_sync_update(pmix_wait_sync_t *sync, int updates, int status) +static inline void pmix_wait_sync_update(pmix_wait_sync_t *sync, + int updates, int status) { if( PMIX_LIKELY(PMIX_SUCCESS == status) ) { if( 0 != (PMIX_THREAD_ADD32(&sync->count, -updates)) ) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.include index 7d638ab8c5..7d04d20c6d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.include @@ -1,5 +1,5 @@ # -# Copyright (c) 2014-2016 Intel, Inc. All rights reserved. +# Copyright (c) 2014-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/tool/pmix_tool.c b/opal/mca/pmix/pmix2x/pmix/src/tool/pmix_tool.c index 196938a62b..0c05815df6 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/tool/pmix_tool.c +++ b/opal/mca/pmix/pmix2x/pmix/src/tool/pmix_tool.c @@ -61,19 +61,17 @@ extern pmix_client_globals_t pmix_client_globals; #include "src/class/pmix_list.h" -#include "src/buffer_ops/buffer_ops.h" #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/hash.h" #include "src/util/output.h" #include "src/runtime/pmix_progress_threads.h" #include "src/runtime/pmix_rte.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/gds/base/base.h" #include "src/mca/ptl/ptl.h" #include "src/mca/psec/psec.h" #include "src/include/pmix_globals.h" -#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) -#include "src/dstore/pmix_dstore.h" -#endif /* PMIX_ENABLE_DSTORE */ #define PMIX_MAX_RETRIES 10 @@ -101,34 +99,44 @@ static void pmix_tool_notify_recv(struct pmix_peer_t *peer, chain->final_cbdata = chain; cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &cmd, &cnt, PMIX_CMD))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &cmd, &cnt, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto error; } /* unpack the status */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &chain->status, &cnt, PMIX_STATUS))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &chain->status, &cnt, PMIX_STATUS); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto error; } /* unpack the source of the event */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &chain->source, &cnt, PMIX_PROC))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &chain->source, &cnt, PMIX_PROC); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto error; } /* unpack the info that might have been provided */ cnt=1; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &chain->ninfo, &cnt, PMIX_SIZE))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, &chain->ninfo, &cnt, PMIX_SIZE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto error; } if (0 < chain->ninfo) { PMIX_INFO_CREATE(chain->info, chain->ninfo); cnt = chain->ninfo; - if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, chain->info, &cnt, PMIX_INFO))) { + PMIX_BFROPS_UNPACK(rc, pmix_client_globals.myserver, + buf, chain->info, &cnt, PMIX_INFO); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); goto error; } @@ -155,8 +163,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, { pmix_kval_t *kptr; pmix_status_t rc; - pmix_nspace_t *nptr, *nsptr; char hostname[PMIX_MAX_NSLEN]; + bool found; + pmix_info_t ginfo; + size_t n; PMIX_ACQUIRE_THREAD(&pmix_global_lock); @@ -201,17 +211,56 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, pmix_output_verbose(2, pmix_globals.debug_output, "pmix: init called"); - /* select our psec module - we take the default as we cannot - * do any better */ - if (PMIX_SUCCESS != (rc = pmix_psec.assign_module(pmix_globals.mypeer, NULL))) { + /* select our bfrops compat module */ + pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module(NULL); + if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_INIT; } - /* the server will have to use the same */ - pmix_client_globals.myserver->compat.psec = pmix_globals.mypeer->compat.psec; + /* the server will be using the same */ + pmix_client_globals.myserver->nptr->compat.bfrops = pmix_globals.mypeer->nptr->compat.bfrops; + + /* set the buffer type */ + pmix_globals.mypeer->nptr->compat.type = pmix_bfrops_globals.default_type; + /* the server will be using the same */ + pmix_client_globals.myserver->nptr->compat.type = pmix_globals.mypeer->nptr->compat.type; + + /* select our psec compat module */ + pmix_globals.mypeer->nptr->compat.psec = pmix_psec_base_assign_module(NULL); + if (NULL == pmix_globals.mypeer->nptr->compat.psec) { + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_INIT; + } + /* the server will be using the same */ + pmix_client_globals.myserver->nptr->compat.psec = pmix_globals.mypeer->nptr->compat.psec; + + /* now select a GDS module for our own internal use - the user may + * have passed down a directive for this purpose. If they did, then + * use it. Otherwise, we want the "hash" module */ + found = false; + if (NULL != info) { + for (n=0; n < ninfo; n++) { + if (0 == strncmp(info[n].key, PMIX_GDS_MODULE, PMIX_MAX_KEYLEN)) { + PMIX_INFO_LOAD(&ginfo, PMIX_GDS_MODULE, info[n].value.data.string, PMIX_STRING); + found = true; + break; + } + } + } + if (!found) { + PMIX_INFO_LOAD(&ginfo, PMIX_GDS_MODULE, "hash", PMIX_STRING); + } + pmix_globals.mypeer->nptr->compat.gds = pmix_gds_base_assign_module(&ginfo, 1); + if (NULL == pmix_globals.mypeer->nptr->compat.gds) { + PMIX_INFO_DESTRUCT(&ginfo); + PMIX_RELEASE_THREAD(&pmix_global_lock); + return PMIX_ERR_INIT; + } + PMIX_INFO_DESTRUCT(&ginfo); /* connect to the server - returns job info if successful */ - if (PMIX_SUCCESS != (rc = pmix_ptl.connect_to_peer(pmix_client_globals.myserver, info, ninfo))){ + rc = pmix_ptl_base_connect_to_peer((struct pmix_peer_t*)pmix_client_globals.myserver, info, ninfo); + if (PMIX_SUCCESS != rc){ PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; } @@ -227,25 +276,17 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, * datastore with typical job-related info. No point * in having the server generate these as we are * obviously a singleton, and so the values are well-known */ - nsptr = NULL; - PMIX_LIST_FOREACH(nptr, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strncmp(pmix_globals.myid.nspace, nptr->nspace, PMIX_MAX_NSLEN)) { - nsptr = nptr; - break; - } - } - if (NULL == nsptr) { - PMIX_RELEASE_THREAD(&pmix_global_lock); - return PMIX_ERR_NOT_FOUND; - } /* the jobid is just our nspace */ kptr = PMIX_NEW(pmix_kval_t); kptr->key = strdup(PMIX_JOBID); PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_STRING; - kptr->value->data.string = strdup(nsptr->nspace); - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + kptr->value->data.string = strdup(pmix_globals.myid.nspace); + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -258,7 +299,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_INT; kptr->value->data.integer = 0; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -271,7 +315,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 0; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -284,7 +331,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 1; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -297,7 +347,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_STRING; kptr->value->data.string = strdup("0"); - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -310,9 +363,13 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 0; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); + return rc; } PMIX_RELEASE(kptr); // maintain accounting @@ -322,7 +379,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 1; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -335,7 +395,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 1; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -348,7 +411,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 1; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -362,7 +428,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 1; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -375,7 +444,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 0; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -388,7 +460,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 0; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -401,7 +476,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 0; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -414,7 +492,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 0; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -427,7 +508,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_UINT32; kptr->value->data.uint32 = 0; - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -446,7 +530,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_STRING; kptr->value->data.string = strdup(hostname); - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -464,7 +551,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_STRING; kptr->value->data.string = strdup(hostname); - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -478,7 +568,10 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, PMIX_VALUE_CREATE(kptr->value, 1); kptr->value->type = PMIX_STRING; kptr->value->data.string = strdup("0"); - if (PMIX_SUCCESS != (rc = pmix_hash_store(&nsptr->internal, pmix_globals.myid.rank, kptr))) { + PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer, + &pmix_globals.myid, + PMIX_INTERNAL, kptr); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE_THREAD(&pmix_global_lock); return rc; @@ -549,7 +642,9 @@ PMIX_EXPORT pmix_status_t PMIx_tool_finalize(void) * server that we are normally terminating */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { + PMIX_BFROPS_PACK(rc, pmix_client_globals.myserver, + msg, &cmd, 1, PMIX_CMD); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; @@ -567,8 +662,12 @@ PMIX_EXPORT pmix_status_t PMIx_tool_finalize(void) tev.active = true; PMIX_POST_OBJECT(&tev); pmix_event_add(&tev.ev, &tv); - if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(pmix_client_globals.myserver, msg, - finwait_cbfunc, (void*)&tev))){ + PMIX_PTL_SEND_RECV(rc, pmix_client_globals.myserver, msg, + finwait_cbfunc, (void*)&tev); + if (PMIX_SUCCESS != rc) { + if (tev.active) { + pmix_event_del(&tev.ev); + } return rc; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.include index 1a4065dd32..a42b51a5fa 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.include @@ -12,7 +12,7 @@ # All rights reserved. # Copyright (c) 2007-2016 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2013 NVIDIA Corporation. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2016 Research Organization for Information Science # and Technology (RIST). All rights reserved. # $COPYRIGHT$ diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/alfg.c b/opal/mca/pmix/pmix2x/pmix/src/util/alfg.c index 87e0e85172..f29738ff9b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/alfg.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/alfg.c @@ -3,7 +3,7 @@ * All rights reserved. * Copyright (c) 2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/argv.c b/opal/mca/pmix/pmix2x/pmix/src/util/argv.c index f5c08f80a0..054fe14a48 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/argv.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/argv.c @@ -11,7 +11,7 @@ * All rights reserved. * Copyright (c) 2007 Voltaire. All rights reserved. * Copyright (c) 2012 Los Alamos National Security, LLC. All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/argv.h b/opal/mca/pmix/pmix2x/pmix/src/util/argv.h index 44d83e7562..01e8a80ae0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/argv.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/argv.h @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2007 Voltaire. All rights reserved. * Copyright (c) 2012 Los Alamos National Security, LLC. All rights reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/basename.c b/opal/mca/pmix/pmix2x/pmix/src/util/basename.c index 64e5c27e7e..c7722bf33c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/basename.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/basename.c @@ -12,7 +12,7 @@ * Copyright (c) 2009-2014 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2014 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/basename.h b/opal/mca/pmix/pmix2x/pmix/src/util/basename.h index 55d29413b4..1a6d97599f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/basename.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/basename.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/compress.c b/opal/mca/pmix/pmix2x/pmix/src/util/compress.c index 867a3d5e57..56b7bf1554 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/compress.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/compress.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * Copyright (c) 2017 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/crc.c b/opal/mca/pmix/pmix2x/pmix/src/util/crc.c index 5045e4509c..3751a48535 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/crc.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/crc.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/crc.h b/opal/mca/pmix/pmix2x/pmix/src/util/crc.h index ed1e43d01c..9cfe66fea7 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/crc.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/crc.h @@ -12,7 +12,7 @@ * Copyright (c) 2009 IBM Corporation. All rights reserved. * Copyright (c) 2009 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/fd.c b/opal/mca/pmix/pmix2x/pmix/src/util/fd.c index 616c6fe97c..db22cba329 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/fd.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/fd.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2008-2014 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2009 Sandia National Laboratories. All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/fd.h b/opal/mca/pmix/pmix2x/pmix/src/util/fd.h index d67fe24835..70d2d09b19 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/fd.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/fd.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2008-2014 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2009 Sandia National Laboratories. All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/getid.c b/opal/mca/pmix/pmix2x/pmix/src/util/getid.c index f3ad8a9dd4..ebd821cf74 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/getid.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/getid.c @@ -10,7 +10,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/getid.h b/opal/mca/pmix/pmix2x/pmix/src/util/getid.h index 871eb6a259..cac7c72b94 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/getid.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/getid.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -28,4 +28,3 @@ pmix_status_t pmix_util_getid(int sd, uid_t *uid, gid_t *gid); END_C_DECLS #endif /* PMIX_PRINTF_H */ - diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/hash.c b/opal/mca/pmix/pmix2x/pmix/src/util/hash.c index fe31dd28ab..76d6c70723 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/hash.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/hash.c @@ -30,7 +30,7 @@ #include "src/include/pmix_globals.h" #include "src/class/pmix_hash_table.h" #include "src/class/pmix_pointer_array.h" -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops.h" #include "src/util/error.h" #include "src/util/output.h" @@ -74,7 +74,11 @@ pmix_status_t pmix_hash_store(pmix_hash_table_t *table, pmix_output_verbose(10, pmix_globals.debug_output, "HASH:STORE rank %d key %s", - rank, kin->key); + rank, (NULL == kin) ? "NULL KVAL" : kin->key); + + if (NULL == kin) { + return PMIX_ERR_BAD_PARAM; + } id = (uint64_t)rank; @@ -117,9 +121,9 @@ pmix_status_t pmix_hash_fetch(pmix_hash_table_t *table, pmix_rank_t rank, id = (uint64_t)rank; /* - PMIX_RANK_UNDEF should return following statuses - * PMIX_ERR_PROC_ENTRY_NOT_FOUND | PMIX_SUCCESS + * PMIX_ERR_PROC_ENTRY_NOT_FOUND | PMIX_SUCCESS * - specified rank can return following statuses - * PMIX_ERR_PROC_ENTRY_NOT_FOUND | PMIX_ERR_NOT_FOUND | PMIX_SUCCESS + * PMIX_ERR_PROC_ENTRY_NOT_FOUND | PMIX_ERR_NOT_FOUND | PMIX_SUCCESS * special logic is basing on these statuses on a client and a server */ if (PMIX_RANK_UNDEF == rank) { rc = pmix_hash_table_get_first_key_uint64(table, &id, @@ -181,7 +185,9 @@ pmix_status_t pmix_hash_fetch(pmix_hash_table_t *table, pmix_rank_t rank, hv = lookup_keyval(&proc_data->data, key); if (NULL != hv) { /* create the copy */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.copy((void**)kvs, hv->value, PMIX_VALUE))) { + PMIX_BFROPS_COPY(rc, pmix_globals.mypeer, + (void**)kvs, hv->value, PMIX_VALUE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } @@ -247,7 +253,9 @@ pmix_status_t pmix_hash_fetch_by_key(pmix_hash_table_t *table, const char *key, hv = lookup_keyval(&proc_data->data, key_r); if (hv) { /* create the copy */ - if (PMIX_SUCCESS != (rc = pmix_bfrop.copy((void**)kvs, hv->value, PMIX_VALUE))) { + PMIX_BFROPS_COPY(rc, pmix_globals.mypeer, + (void**)kvs, hv->value, PMIX_VALUE); + if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); return rc; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/hash.h b/opal/mca/pmix/pmix2x/pmix/src/util/hash.h index 6b385b2710..057e9a803e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/hash.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/hash.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved. - * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -17,7 +17,7 @@ #include -#include "src/buffer_ops/buffer_ops.h" +#include "src/mca/bfrops/bfrops_types.h" #include "src/class/pmix_hash_table.h" BEGIN_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/Makefile.am index 70572ec8f1..66145e2353 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/keyval/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/Makefile.am @@ -9,7 +9,7 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. -# Copyright (c) 2016 Intel, Inc. All rights reserved +# Copyright (c) 2016-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.h b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.h index 778982711d..eb91918edf 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.h @@ -10,7 +10,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - # Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.l b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.l index 9b9d0d6d14..320df3f9cd 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.l +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.l @@ -16,6 +16,7 @@ * All rights reserved. * Copyright (c) 2012 Los Alamos National Security, LLC. All rights * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.c b/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.c index c07e65e668..44eab45925 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.c @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.h b/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.h index 2d6e9f4c4e..5f2d54ccde 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/net.c b/opal/mca/pmix/pmix2x/pmix/src/util/net.c index b074a14dfa..26de695ae2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/net.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/net.c @@ -12,7 +12,7 @@ * Copyright (c) 2007 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2013 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/os_path.c b/opal/mca/pmix/pmix2x/pmix/src/util/os_path.c index 6abedaf8a3..e93596a821 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/os_path.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/os_path.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/os_path.h b/opal/mca/pmix/pmix2x/pmix/src/util/os_path.h index 715a5c8435..d7785bd394 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/os_path.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/os_path.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/parse_options.c b/opal/mca/pmix/pmix2x/pmix/src/util/parse_options.c index d7679af6ac..9111a87b09 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/parse_options.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/parse_options.c @@ -13,7 +13,7 @@ * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/parse_options.h b/opal/mca/pmix/pmix2x/pmix/src/util/parse_options.h index 67e239052d..bdd30bf128 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/parse_options.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/parse_options.h @@ -10,7 +10,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/path.c b/opal/mca/pmix/pmix2x/pmix/src/util/path.c index 4c532ef063..1b88d65fa3 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/path.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/path.c @@ -13,7 +13,7 @@ * Copyright (c) 2010 IBM Corporation. All rights reserved. * Copyright (c) 2012-2013 Los Alamos National Security, LLC. * All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 University of Houston. All rights reserved. * $COPYRIGHT$ * diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/path.h b/opal/mca/pmix/pmix2x/pmix/src/util/path.h index b9ab1d5874..a62160f4a0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/path.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/path.h @@ -12,7 +12,7 @@ * Copyright (c) 2012 Los Alamos National Security, LLC. * All rights reserved. * Copyright (c) 2016 University of Houston. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/pif.c b/opal/mca/pmix/pmix2x/pmix/src/util/pif.c index ab594e033a..2f58f0203a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/pif.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/pif.c @@ -16,7 +16,7 @@ * reserved. * Copyright (c) 2015-2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -269,20 +269,25 @@ int16_t pmix_ifaddrtokindex(const char* if_addr) for (r = res; r != NULL; r = r->ai_next) { PMIX_LIST_FOREACH(intf, &pmix_if_list, pmix_pif_t) { if (AF_INET == r->ai_family && AF_INET == intf->af_family) { - struct sockaddr ipv4; + struct sockaddr ipv4, intv4; memset(&ipv4, 0, sizeof(struct sockaddr)); len = (r->ai_addrlen < sizeof(struct sockaddr_in)) ? r->ai_addrlen : sizeof(struct sockaddr_in); memcpy(&ipv4, r->ai_addr, len); - if (pmix_net_samenetwork(&ipv4, (struct sockaddr*)&intf->if_addr, intf->if_mask)) { + memset(&intv4, 0, sizeof(struct sockaddr)); + memcpy(&intv4, &intf->if_addr, sizeof(struct sockaddr)); + if (pmix_net_samenetwork(&ipv4, &intv4, intf->if_mask)) { if_kernel_index = intf->if_kernel_index; freeaddrinfo (res); return if_kernel_index; } } else if (AF_INET6 == r->ai_family && AF_INET6 == intf->af_family) { - struct sockaddr_in6 ipv6; + struct sockaddr_in6 ipv6, intv6; + memset(&ipv6, 0, sizeof(struct sockaddr)); len = (r->ai_addrlen < sizeof(struct sockaddr_in6)) ? r->ai_addrlen : sizeof(struct sockaddr_in6); memcpy(&ipv6, r->ai_addr, len); - if (pmix_net_samenetwork((struct sockaddr*)((struct sockaddr_in6*)&intf->if_addr), + memset(&intv6, 0, sizeof(struct sockaddr)); + memcpy(&intv6, &intf->if_addr, sizeof(struct sockaddr_in6)); + if (pmix_net_samenetwork((struct sockaddr*)&intv6, (struct sockaddr*)&ipv6, intf->if_mask)) { if_kernel_index = intf->if_kernel_index; freeaddrinfo (res); diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/pif.h b/opal/mca/pmix/pmix2x/pmix/src/util/pif.h index fb9f1b79a2..5b2ebc8aa2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/pif.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/pif.h @@ -13,7 +13,7 @@ * reserved. * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2013 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.c b/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.c index 9587a464d2..1e1cfaaa88 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.c @@ -12,7 +12,7 @@ * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2007-2013 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. * $COPYRIGHT$ * @@ -237,4 +237,3 @@ const char* pmix_home_directory( void ) return home; } - diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.h b/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.h index f6ec9c95b2..244f50ace6 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.h @@ -11,7 +11,7 @@ * All rights reserved. * Copyright (c) 2007-2013 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/printf.c b/opal/mca/pmix/pmix2x/pmix/src/util/printf.c index 410c952154..551ff3bc6d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/printf.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/printf.c @@ -10,7 +10,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/printf.h b/opal/mca/pmix/pmix2x/pmix/src/util/printf.h index f4ab098596..4fa8ecc687 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/printf.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/printf.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -129,4 +129,3 @@ int pmix_vasprintf(char **ptr, const char *fmt, va_list ap) __pmix_attribute_fo END_C_DECLS #endif /* PMIX_PRINTF_H */ - diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/show_help.h b/opal/mca/pmix/pmix2x/pmix/src/util/show_help.h index b028c99ca0..13ba1adc57 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/show_help.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/show_help.h @@ -10,7 +10,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.h b/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.h index a507e4ddd8..1fc3643213 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.h @@ -10,7 +10,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.l b/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.l index d48130f0d8..1e5e68daa3 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.l +++ b/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.l @@ -13,7 +13,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/strnlen.h b/opal/mca/pmix/pmix2x/pmix/src/util/strnlen.h index d09cc1c5c4..b467fbf339 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/strnlen.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/strnlen.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -35,4 +35,3 @@ #endif #endif /* PMIX_STRNLEN_H */ - diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/timings.c b/opal/mca/pmix/pmix2x/pmix/src/util/timings.c index 10779bbe76..799aa50adb 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/timings.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/timings.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Artem Polyakov - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/timings.h b/opal/mca/pmix/pmix2x/pmix/src/util/timings.h index 06dc993c05..3550ce3ae0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/timings.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/timings.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Artem Polyakov - * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/tsd.h b/opal/mca/pmix/pmix2x/pmix/src/util/tsd.h index 1149fca10e..a079152267 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/tsd.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/tsd.h @@ -4,7 +4,7 @@ * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow diff --git a/opal/mca/pmix/pmix2x/pmix/test/pmix_client.c b/opal/mca/pmix/pmix2x/pmix/test/pmix_client.c index 53c7117263..d70acba8ed 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/pmix_client.c +++ b/opal/mca/pmix/pmix2x/pmix/test/pmix_client.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015-2017 Mellanox Technologies, Inc. All rights reserved. * $COPYRIGHT$ * @@ -31,7 +31,6 @@ #include #include "src/class/pmix_object.h" -#include "src/buffer_ops/types.h" #include "test_common.h" #include "test_fence.h" #include "test_publish.h" @@ -87,7 +86,20 @@ int main(int argc, char **argv) } /* init us */ - if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, NULL, 0))) { + pmix_info_t info[1]; + size_t ninfo = 0; + if (NULL != params.gds_mode) { + (void)strncpy(info[0].key, PMIX_GDS_MODULE, PMIX_MAX_KEYLEN); + info[0].value.type = PMIX_STRING; + info[0].value.data.string = strdup(params.gds_mode); + ninfo = 1; + { + int delay = 0; + while(delay) + sleep(1); + } + } + if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, info, ninfo))) { TEST_ERROR(("Client ns %s rank %d: PMIx_Init failed: %d", params.nspace, params.rank, rc)); FREE_TEST_PARAMS(params); exit(0); diff --git a/opal/mca/pmix/pmix2x/pmix/test/pmix_regex.c b/opal/mca/pmix/pmix2x/pmix/test/pmix_regex.c index 027f6fc5a3..cb347f704a 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/pmix_regex.c +++ b/opal/mca/pmix/pmix2x/pmix/test/pmix_regex.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2015 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -30,6 +30,7 @@ #include "src/util/pmix_environ.h" #include "src/util/output.h" #include "src/server/pmix_server_ops.h" +#include "src/mca/preg/preg.h" #include "server_callbacks.h" #include "utils.h" @@ -57,7 +58,7 @@ int main(int argc, char **argv) PMIx_generate_regex(TEST_NODES, ®ex); fprintf(stderr, "REGEX: %s\n\n", regex); /* test reverse parsing */ - rc = pmix_regex_parse_nodes(regex, &nodes); + rc = pmix_preg.parse_nodes(regex, &nodes); free(regex); if (PMIX_SUCCESS == rc) { regex = pmix_argv_join(nodes, ','); @@ -73,7 +74,7 @@ int main(int argc, char **argv) PMIx_generate_ppn(TEST_PROCS, ®ex); fprintf(stderr, "PPN: %s\n\n", regex); /* test reverse parsing */ - rc = pmix_regex_parse_procs(regex, &procs); + rc = pmix_preg.parse_procs(regex, &procs); free(regex); if (PMIX_SUCCESS == rc) { regex = pmix_argv_join(procs, ';'); @@ -87,4 +88,3 @@ int main(int argc, char **argv) return 0; } - diff --git a/opal/mca/pmix/pmix2x/pmix/test/pmix_test.c b/opal/mca/pmix/pmix2x/pmix/test/pmix_test.c index 6969c55f5d..c1a8130b1a 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/pmix_test.c +++ b/opal/mca/pmix/pmix2x/pmix/test/pmix_test.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. @@ -174,7 +174,10 @@ int main(int argc, char **argv) if( test_abort ){ TEST_ERROR(("Test was aborted!")); - cli_kill_all(); + /* do not simply kill the clients as that generates + * event notifications which these tests then print + * out, flooding the log */ + // cli_kill_all(); test_fail = 1; } @@ -203,4 +206,3 @@ int main(int argc, char **argv) return test_fail; } - diff --git a/opal/mca/pmix/pmix2x/pmix/test/server_callbacks.c b/opal/mca/pmix/pmix2x/pmix/test/server_callbacks.c index df5c576336..4525d13797 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/server_callbacks.c +++ b/opal/mca/pmix/pmix2x/pmix/test/server_callbacks.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. @@ -157,10 +157,7 @@ pmix_status_t dmodex_fn(const pmix_proc_t *proc, * have multi-server capability yet, so we'll just * respond right away */ - if (NULL != cbfunc) { - cbfunc(PMIX_ERR_NOT_FOUND, NULL, 0, cbdata, NULL, NULL); - } - return PMIX_SUCCESS; + return PMIX_ERR_NOT_FOUND; } pmix_status_t publish_fn(const pmix_proc_t *proc, @@ -214,15 +211,19 @@ pmix_status_t lookup_fn(const pmix_proc_t *proc, char **keys, if (0 == strcmp(tinfo->data.key, keys[i])) { (void)strncpy(pdata[i].proc.nspace, tinfo->namespace_published, PMIX_MAX_NSLEN); pdata[i].proc.rank = tinfo->rank_published; - (void)strncpy(pdata[i].key, keys[i], strlen(keys[i])+1); + memset(pdata[i].key, 0, PMIX_MAX_KEYLEN+1); + (void)strncpy(pdata[i].key, keys[i], PMIX_MAX_KEYLEN); pmix_value_xfer(&pdata[i].value, &tinfo->data.value); ret++; break; } } } + if (ret != ndata) { + return PMIX_ERR_NOT_FOUND; + } if (NULL != cbfunc) { - cbfunc((ret == ndata) ? PMIX_SUCCESS : PMIX_ERR_NOT_FOUND, pdata, ndata, cbdata); + cbfunc(PMIX_SUCCESS, pdata, ndata, cbdata); } PMIX_PDATA_FREE(pdata, ndata); return PMIX_SUCCESS; diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simpclient.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simpclient.c index cd58ee5ff4..4bc66e5d9e 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simpclient.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simpclient.c @@ -32,11 +32,10 @@ #include #include "src/class/pmix_object.h" -#include "src/buffer_ops/types.h" #include "src/util/output.h" #include "src/util/printf.h" -#define MAXCNT 2 +#define MAXCNT 1 static volatile bool completed = false; static pmix_proc_t myproc; @@ -253,6 +252,11 @@ int main(int argc, char **argv) myproc.nspace, myproc.rank, j, tmp, PMIx_Error_string(rc)); continue; } + if (NULL == val) { + pmix_output(0, "Client ns %s rank %d: NULL value returned", + myproc.nspace, myproc.rank); + break; + } if (PMIX_UINT64 != val->type) { pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Get %s returned wrong type: %d", myproc.nspace, myproc.rank, j, tmp, val->type); PMIX_VALUE_RELEASE(val); diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simpdie.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simpdie.c index 1949e3e391..db62d7832c 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simpdie.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simpdie.c @@ -32,7 +32,6 @@ #include #include "src/class/pmix_object.h" -#include "src/buffer_ops/types.h" #include "src/util/argv.h" #include "src/util/output.h" #include "src/util/printf.h" diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simpdmodex.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simpdmodex.c index c345e94a85..2151caf2b3 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simpdmodex.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simpdmodex.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. All rights reserved. * $COPYRIGHT$ * @@ -32,7 +32,6 @@ #include #include "src/class/pmix_object.h" -#include "src/buffer_ops/types.h" #include "src/util/output.h" #include "src/util/printf.h" diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simpdyn.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simpdyn.c index a71f8149f2..2dfbc57217 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simpdyn.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simpdyn.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. All rights reserved. * $COPYRIGHT$ * @@ -32,7 +32,6 @@ #include #include "src/class/pmix_object.h" -#include "src/buffer_ops/types.h" #include "src/util/argv.h" #include "src/util/output.h" #include "src/util/pmix_environ.h" diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simpft.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simpft.c index 0844b936e0..57a6bfc8c6 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simpft.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simpft.c @@ -32,7 +32,6 @@ #include #include "src/class/pmix_object.h" -#include "src/buffer_ops/types.h" #include "src/util/argv.h" #include "src/util/output.h" #include "src/util/printf.h" diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simppub.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simppub.c index 4d73146567..12d6c68735 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simppub.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simppub.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. All rights reserved. * $COPYRIGHT$ * @@ -32,7 +32,6 @@ #include #include "src/class/pmix_object.h" -#include "src/buffer_ops/types.h" #include "src/util/argv.h" #include "src/util/output.h" #include "src/util/printf.h" diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simptest.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simptest.c index 58b8980441..8982b805ac 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simptest.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simptest.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -39,11 +40,11 @@ #include #include PMIX_EVENT_HEADER +#include "src/class/pmix_list.h" #include "src/util/pmix_environ.h" #include "src/util/output.h" #include "src/util/printf.h" #include "src/util/argv.h" -#include "src/buffer_ops/buffer_ops.h" static pmix_status_t connected(const pmix_proc_t *proc, void *server_object, pmix_op_cbfunc_t cbfunc, void *cbdata); diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simptool.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simptool.c index ea31cedaa1..2af6f395ed 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simptool.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simptool.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. All rights reserved. * $COPYRIGHT$ * @@ -32,7 +32,6 @@ #include #include "src/class/pmix_object.h" -#include "src/buffer_ops/types.h" #include "src/util/argv.h" #include "src/util/output.h" #include "src/util/printf.h" diff --git a/opal/mca/pmix/pmix2x/pmix/test/test_common.c b/opal/mca/pmix/pmix2x/pmix/test/test_common.c index 5d9ba37441..fa3a8a7a47 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/test_common.c +++ b/opal/mca/pmix/pmix2x/pmix/test/test_common.c @@ -80,6 +80,7 @@ void parse_cmd(int argc, char **argv, test_params *params) fprintf(stderr, "\t--test-error test error handling api.\n"); fprintf(stderr, "\t--test-replace N:k0,k1,...,k(N-1) test key replace for N keys, k0,k1,k(N-1) - key indexes to replace \n"); fprintf(stderr, "\t--test-internal N test store internal key, N - number of internal keys\n"); + fprintf(stderr, "\t--gds set GDS module \"--gds hash|ds12\", default is hash\n"); exit(0); } else if (0 == strcmp(argv[i], "--exec") || 0 == strcmp(argv[i], "-e")) { i++; @@ -190,6 +191,9 @@ void parse_cmd(int argc, char **argv, test_params *params) } else { params->test_internal = 1; } + } else if(0 == strcmp(argv[i], "--gds") ) { + i++; + params->gds_mode = strdup(argv[i]); } else { diff --git a/opal/mca/pmix/pmix2x/pmix/test/test_common.h b/opal/mca/pmix/pmix2x/pmix/test/test_common.h index 9873c1b4d0..d906c08778 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/test_common.h +++ b/opal/mca/pmix/pmix2x/pmix/test/test_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Artem Y. Polyakov . * All rights reserved. * Copyright (c) 2015 Research Organization for Information Science @@ -119,6 +119,7 @@ typedef struct { int test_error; char *key_replace; int test_internal; + char *gds_mode; } test_params; #define INIT_TEST_PARAMS(params) do { \ @@ -149,6 +150,7 @@ typedef struct { params.test_error = 0; \ params.key_replace = NULL; \ params.test_internal = 0; \ + params.gds_mode = NULL; \ } while (0) #define FREE_TEST_PARAMS(params) do { \ diff --git a/opal/mca/pmix/pmix2x/pmix/test/test_fence.c b/opal/mca/pmix/pmix2x/pmix/test/test_fence.c index a738e40cac..04dc775899 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/test_fence.c +++ b/opal/mca/pmix/pmix2x/pmix/test/test_fence.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2016-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015-2017 Mellanox Technologies, Inc. * All rights reserved. * $COPYRIGHT$ @@ -11,7 +11,6 @@ */ #include "test_fence.h" -#include "src/buffer_ops/buffer_ops.h" static void get_cb(pmix_status_t status, pmix_value_t *kv, void *cbdata) { @@ -434,4 +433,3 @@ int test_job_fence(test_params params, char *my_nspace, pmix_rank_t my_rank) } return PMIX_SUCCESS; } - diff --git a/opal/mca/pmix/pmix2x/pmix/test/test_internal.c b/opal/mca/pmix/pmix2x/pmix/test/test_internal.c index 3f76f3cfaf..a9c2bdd6ce 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/test_internal.c +++ b/opal/mca/pmix/pmix2x/pmix/test/test_internal.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2017 Mellanox Technologies, Inc. * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -56,7 +57,6 @@ int test_internal(char *my_nspace, pmix_rank_t my_rank, test_params params) { /* Submit the data */ if (PMIX_SUCCESS != (rc = PMIx_Commit())) { TEST_ERROR(("%s:%d: PMIx_Commit failed: %d", my_nspace, my_rank, rc)); - PMIX_LIST_DESTRUCT(&key_replace); PMIX_PROC_DESTRUCT(&proc); return PMIX_ERROR; } @@ -65,7 +65,6 @@ int test_internal(char *my_nspace, pmix_rank_t my_rank, test_params params) { FENCE(1, 1, (&proc), 1); if (PMIX_SUCCESS != rc) { TEST_ERROR(("%s:%d: PMIx_Fence failed: %d", my_nspace, my_rank, rc)); - PMIX_LIST_DESTRUCT(&key_replace); PMIX_PROC_DESTRUCT(&proc); return rc; } diff --git a/opal/mca/pmix/pmix2x/pmix/test/test_publish.c b/opal/mca/pmix/pmix2x/pmix/test/test_publish.c index 86f799bdea..bd31a1724a 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/test_publish.c +++ b/opal/mca/pmix/pmix2x/pmix/test/test_publish.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. * All rights reserved. * $COPYRIGHT$ @@ -12,7 +12,7 @@ #include "test_publish.h" #include -#include "src/buffer_ops/buffer_ops.h" +#include typedef struct { int in_progress; @@ -193,4 +193,3 @@ int test_publish_lookup(char *my_nspace, int my_rank) } return PMIX_SUCCESS; } - diff --git a/opal/mca/pmix/pmix2x/pmix/test/test_resolve_peers.c b/opal/mca/pmix/pmix2x/pmix/test/test_resolve_peers.c index e9582cb0df..aac2606747 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/test_resolve_peers.c +++ b/opal/mca/pmix/pmix2x/pmix/test/test_resolve_peers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. * All rights reserved. * $COPYRIGHT$ @@ -13,6 +13,8 @@ #include "test_resolve_peers.h" #include "test_cd.h" +#include "src/util/output.h" + static int resolve_nspace(char *nspace, test_params params, char *my_nspace, int my_rank) { int rc; @@ -42,7 +44,8 @@ static int resolve_nspace(char *nspace, test_params params, char *my_nspace, int } for (i = 0; i < nprocs; i++) { if (procs[i].rank != ranks[i].rank) { - TEST_ERROR(("%s:%d: Resolve peers returned incorrect result: returned value %s:%d, expected rank %d", my_nspace, my_rank, procs[i].nspace, ranks[i].rank, procs[i].rank)); + TEST_ERROR(("%s:%d: Resolve peers returned incorrect result: returned value %s:%d, expected rank %d", + my_nspace, my_rank, procs[i].nspace, procs[i].rank, ranks[i].rank)); rc = PMIX_ERROR; break; } @@ -75,6 +78,7 @@ int test_resolve_peers(char *my_nspace, int my_rank, test_params params) return PMIX_ERROR; } for (n = 0; n < ns_num; n++) { + memset(nspace, 0, PMIX_MAX_NSLEN+1); /* then connect to processes from different namespaces and resolve peers. */ (void)snprintf(nspace, PMIX_MAX_NSLEN, "%s-%d", TEST_NAMESPACE, n); if (0 == strncmp(my_nspace, nspace, strlen(nspace)+1)) { @@ -101,6 +105,7 @@ int test_resolve_peers(char *my_nspace, int my_rank, test_params params) TEST_ERROR(("%s:%d: Connect to %s failed %s.", my_nspace, my_rank, nspace)); return PMIX_ERROR; } + /* then resolve peers from this namespace. */ rc = resolve_nspace(nspace, params, my_nspace, my_rank); if (PMIX_SUCCESS == rc) { @@ -109,6 +114,7 @@ int test_resolve_peers(char *my_nspace, int my_rank, test_params params) test_cd_common(procs, 2, 1, 1); break; } + /* disconnect from the processes of this namespace. */ rc = test_cd_common(procs, 2, 1, 0); if (PMIX_SUCCESS == rc) { diff --git a/opal/mca/pmix/pmix2x/pmix/test/utils.c b/opal/mca/pmix/pmix2x/pmix/test/utils.c index dfcd285aa5..1111a3cc95 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/utils.c +++ b/opal/mca/pmix/pmix2x/pmix/test/utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015-2017 Mellanox Technologies, Inc. * All rights reserved. * Copyright (c) 2016 Research Organization for Information Science @@ -161,10 +161,14 @@ void set_client_argv(test_params *params, char ***argv) } if (params->test_internal) { char tmp[32]; - sprintf(tmp, "%d", params->test_internal); + snprintf(tmp, 32, "%d", params->test_internal); pmix_argv_append_nosize(argv, "--test-internal"); pmix_argv_append_nosize(argv, tmp); } + if (params->gds_mode) { + pmix_argv_append_nosize(argv, "--gds"); + pmix_argv_append_nosize(argv, params->gds_mode); + } } int launch_clients(int num_procs, char *binary, char *** client_env, char ***base_argv) diff --git a/opal/mca/pmix/pmix2x/pmix2x_client.c b/opal/mca/pmix/pmix2x/pmix2x_client.c index 7ad5712ad5..e22ebce412 100644 --- a/opal/mca/pmix/pmix2x/pmix2x_client.c +++ b/opal/mca/pmix/pmix2x/pmix2x_client.c @@ -174,7 +174,6 @@ int pmix2x_client_finalize(void) } } OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock); - rc = PMIx_Finalize(NULL, 0); return pmix2x_convert_rc(rc);