From b0cc9b0bc885ece2f09cfcb55c2b86a11be8bc16 Mon Sep 17 00:00:00 2001 From: Ralph Castain Date: Wed, 10 Aug 2016 21:03:00 -0700 Subject: [PATCH 1/2] Update to latest PMIx toolext branch Fix indentations Update the ext20 component to match latest PMIx master. Cleanup name conflicts and uninit vars --- .gitignore | 6 + opal/mca/pmix/ext20/configure.m4 | 2 +- opal/mca/pmix/ext20/pmix_ext20.c | 1563 +++++++----- opal/mca/pmix/ext20/pmix_ext20.h | 305 +-- opal/mca/pmix/ext20/pmix_ext20_client.c | 805 +++--- opal/mca/pmix/ext20/pmix_ext20_component.c | 56 +- opal/mca/pmix/ext20/pmix_ext20_server_north.c | 854 ++++--- opal/mca/pmix/ext20/pmix_ext20_server_south.c | 359 +-- opal/mca/pmix/pmix2x/configure.m4 | 2 +- opal/mca/pmix/pmix2x/pmix/Makefile.am | 72 +- opal/mca/pmix/pmix2x/pmix/VERSION | 4 +- opal/mca/pmix/pmix2x/pmix/autogen.pl | 739 ++++++ opal/mca/pmix/pmix2x/pmix/autogen.sh | 5 - opal/mca/pmix/pmix2x/pmix/config/Makefile.am | 55 +- opal/mca/pmix/pmix2x/pmix/config/pmix.m4 | 187 +- .../pmix2x/pmix/config/pmix_config_subdir.m4 | 147 ++ .../pmix/config/pmix_config_subdir_args.m4 | 84 + .../pmix/pmix2x/pmix/config/pmix_functions.m4 | 40 +- opal/mca/pmix/pmix2x/pmix/config/pmix_mca.m4 | 918 +++++++ .../pmix/config/pmix_mca_priority_sort.pl | 31 + opal/mca/pmix/pmix2x/pmix/configure.ac | 21 +- .../pmix2x/pmix/contrib/platform/optimized | 3 - .../mca/pmix/pmix2x/pmix/examples/Makefile.am | 12 +- opal/mca/pmix/pmix2x/pmix/examples/dynamic.c | 3 +- opal/mca/pmix/pmix2x/pmix/include/Makefile.am | 26 +- opal/mca/pmix/pmix2x/pmix/include/pmix.h | 18 +- .../pmix/pmix2x/pmix/include/pmix/rename.h | 424 ---- .../pmix/include/{pmix => }/pmix_common.h | 13 +- .../pmix/pmix2x/pmix/include/pmix_server.h | 16 +- opal/mca/pmix/pmix2x/pmix/include/pmix_tool.h | 16 +- opal/mca/pmix/pmix2x/pmix/man/Makefile.am | 60 + opal/mca/pmix/pmix2x/pmix/man/README | 186 ++ .../pmix/pmix2x/pmix/man/man3/pmix_fence.3 | 95 - opal/mca/pmix/pmix2x/pmix/man/man3/pmix_get.3 | 87 - opal/mca/pmix/pmix2x/pmix/src/Makefile.am | 81 + .../pmix2x/pmix/src/buffer_ops/Makefile.am | 20 +- .../pmix/pmix2x/pmix/src/buffer_ops/copy.c | 53 +- .../pmix2x/pmix/src/buffer_ops/open_close.c | 2 +- .../pmix/pmix2x/pmix/src/buffer_ops/print.c | 2 +- .../pmix/pmix2x/pmix/src/buffer_ops/types.h | 2 +- .../class/{Makefile.am => Makefile.include} | 29 +- .../pmix2x/pmix/src/class/pmix_hash_table.c | 981 ++++--- .../pmix2x/pmix/src/class/pmix_hash_table.h | 113 +- .../pmix/pmix2x/pmix/src/class/pmix_hotel.h | 4 +- .../pmix/pmix2x/pmix/src/class/pmix_list.c | 3 +- .../pmix/pmix2x/pmix/src/class/pmix_list.h | 12 +- .../pmix/pmix2x/pmix/src/class/pmix_object.h | 22 +- .../pmix/src/class/pmix_pointer_array.c | 2 +- .../pmix/src/class/pmix_pointer_array.h | 14 +- .../pmix2x/pmix/src/class/pmix_ring_buffer.c | 2 +- .../pmix2x/pmix/src/class/pmix_ring_buffer.h | 10 +- .../pmix2x/pmix/src/class/pmix_value_array.c | 67 + .../pmix2x/pmix/src/class/pmix_value_array.h | 281 ++ .../pmix/pmix2x/pmix/src/client/Makefile.am | 27 - .../pmix2x/pmix/src/client/Makefile.include | 29 + .../pmix/pmix2x/pmix/src/client/pmix_client.c | 27 +- .../pmix/src/client/pmix_client_connect.c | 3 +- .../pmix/src/client/pmix_client_fence.c | 3 +- .../pmix2x/pmix/src/client/pmix_client_get.c | 3 +- .../pmix2x/pmix/src/client/pmix_client_pub.c | 3 +- .../pmix/src/client/pmix_client_spawn.c | 3 +- .../pmix/pmix2x/pmix/src/common/Makefile.am | 13 - .../pmix2x/pmix/src/common/Makefile.include | 15 + .../pmix/pmix2x/pmix/src/common/pmix_log.c | 4 +- .../pmix/pmix2x/pmix/src/common/pmix_query.c | 4 +- .../pmix2x/pmix/src/common/pmix_strings.c | 2 +- .../pmix/pmix2x/pmix/src/dstore/Makefile.am | 16 - .../pmix/pmix2x/pmix/src/dstore/pmix_dstore.c | 73 - .../pmix/pmix2x/pmix/src/dstore/pmix_dstore.h | 89 - .../pmix/pmix2x/pmix/src/dstore/pmix_esh.c | 1447 ----------- .../pmix/pmix2x/pmix/src/dstore/pmix_esh.h | 83 - .../pmix/pmix2x/pmix/src/event/Makefile.am | 15 - .../pmix2x/pmix/src/event/Makefile.include | 16 + .../pmix/pmix2x/pmix/src/event/pmix_event.h | 4 +- .../pmix/src/event/pmix_event_notification.c | 27 +- .../pmix/src/event/pmix_event_registration.c | 4 +- .../include/{Makefile.am => Makefile.include} | 31 +- .../pmix2x/pmix/src/include/pmix_config.h | 18 - .../pmix2x/pmix/src/include/pmix_config.h.in | 683 +++++ .../include}/pmix_config_bottom.h | 18 +- .../autogen => src/include}/pmix_config_top.h | 0 .../pmix2x/pmix/src/include/pmix_globals.c | 2 +- .../pmix2x/pmix/src/include/pmix_globals.h | 10 +- .../autogen => src/include}/pmix_stdint.h | 0 .../mca/pmix/pmix2x/pmix/src/include/rename.h | 14 + opal/mca/pmix/pmix2x/pmix/src/include/types.h | 40 + .../pmix/pmix2x/pmix/src/mca/Makefile.include | 26 + .../pmix/pmix2x/pmix/src/mca/base/Makefile.am | 66 + opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h | 246 ++ .../pmix/src/mca/base/help-mca-base.txt | 61 + .../pmix2x/pmix/src/mca/base/help-mca-var.txt | 139 + .../pmix/src/mca/base/pmix_mca_base_close.c | 68 + .../base/pmix_mca_base_component_compare.c | 152 ++ .../mca/base/pmix_mca_base_component_find.c | 389 +++ .../base/pmix_mca_base_component_repository.c | 572 +++++ .../base/pmix_mca_base_component_repository.h | 133 + .../mca/base/pmix_mca_base_components_close.c | 94 + .../mca/base/pmix_mca_base_components_open.c | 164 ++ .../base/pmix_mca_base_components_register.c | 163 ++ .../base/pmix_mca_base_components_select.c | 147 ++ .../src/mca/base/pmix_mca_base_framework.c | 242 ++ .../src/mca/base/pmix_mca_base_framework.h | 244 ++ .../pmix/src/mca/base/pmix_mca_base_list.c | 65 + .../pmix/src/mca/base/pmix_mca_base_open.c | 253 ++ .../mca/base/pmix_mca_base_parse_paramfile.c | 85 + .../pmix/src/mca/base/pmix_mca_base_var.c | 2256 +++++++++++++++++ .../pmix/src/mca/base/pmix_mca_base_var.h | 740 ++++++ .../src/mca/base/pmix_mca_base_var_enum.c | 623 +++++ .../src/mca/base/pmix_mca_base_var_enum.h | 246 ++ .../src/mca/base/pmix_mca_base_var_group.c | 477 ++++ .../src/mca/base/pmix_mca_base_var_group.h | 173 ++ .../pmix/src/mca/base/pmix_mca_base_vari.h | 165 ++ opal/mca/pmix/pmix2x/pmix/src/mca/mca.h | 324 +++ .../pmix/pmix2x/pmix/src/mca/pdl/Makefile.am | 36 + .../pmix2x/pmix/src/mca/pdl/base/Makefile.am | 17 + .../pmix/pmix2x/pmix/src/mca/pdl/base/base.h | 105 + .../pmix/src/mca/pdl/base/pdl_base_close.c | 26 + .../pmix/src/mca/pdl/base/pdl_base_fns.c | 70 + .../pmix/src/mca/pdl/base/pdl_base_open.c | 55 + .../pmix/src/mca/pdl/base/pdl_base_select.c | 55 + .../pmix/pmix2x/pmix/src/mca/pdl/configure.m4 | 78 + opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h | 186 ++ .../pmix/src/mca/pdl/pdlopen/Makefile.am | 23 + .../pmix/src/mca/pdl/pdlopen/configure.m4 | 55 + .../pmix/src/mca/pdl/pdlopen/pdl_pdlopen.h | 41 + .../mca/pdl/pdlopen/pdl_pdlopen_component.c | 127 + .../src/mca/pdl/pdlopen/pdl_pdlopen_module.c | 276 ++ .../pmix/src/mca/pinstalldirs/Makefile.am | 30 + .../src/mca/pinstalldirs/base/Makefile.am | 16 + .../pmix/src/mca/pinstalldirs/base/base.h | 40 + .../base/pinstalldirs_base_components.c | 177 ++ .../base/pinstalldirs_base_expand.c | 174 ++ .../src/mca/pinstalldirs/config/Makefile.am | 22 + .../src/mca/pinstalldirs/config/configure.m4 | 30 + .../pinstalldirs/config/pinstall_dirs.h.in | 129 + .../config/pmix_pinstalldirs_config.c | 57 + .../pmix/src/mca/pinstalldirs/configure.m4 | 12 + .../pmix/src/mca/pinstalldirs/env/Makefile.am | 16 + .../src/mca/pinstalldirs/env/configure.m4 | 28 + .../pinstalldirs/env/pmix_pinstalldirs_env.c | 84 + .../pmix/src/mca/pinstalldirs/pinstalldirs.h | 98 + .../pmix2x/pmix/src/runtime/Makefile.include | 36 + .../pmix/src/runtime/help-pmix-runtime.txt | 68 + .../pmix2x/pmix/src/runtime/pmix_finalize.c | 126 + .../pmix/pmix2x/pmix/src/runtime/pmix_init.c | 248 ++ .../pmix2x/pmix/src/runtime/pmix_params.c | 91 + .../pmix/src/runtime/pmix_progress_threads.c | 338 +++ .../pmix/src/runtime/pmix_progress_threads.h | 67 + .../pmix/pmix2x/pmix/src/runtime/pmix_rte.h | 78 + opal/mca/pmix/pmix2x/pmix/src/sec/Makefile.am | 16 +- .../mca/pmix/pmix2x/pmix/src/sec/pmix_munge.c | 2 +- .../pmix/pmix2x/pmix/src/sec/pmix_native.c | 2 +- opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sasl.c | 5 +- opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.c | 4 +- opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.h | 6 +- .../pmix/pmix2x/pmix/src/server/Makefile.am | 20 - .../pmix2x/pmix/src/server/Makefile.include | 22 + .../pmix/pmix2x/pmix/src/server/pmix_server.c | 64 +- .../pmix2x/pmix/src/server/pmix_server_get.c | 3 +- .../pmix/src/server/pmix_server_listener.c | 5 +- .../pmix2x/pmix/src/server/pmix_server_ops.c | 3 +- .../pmix2x/pmix/src/server/pmix_server_ops.h | 2 +- .../pmix/src/server/pmix_server_regex.c | 2 +- opal/mca/pmix/pmix2x/pmix/src/sm/Makefile.am | 17 - opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.c | 153 -- opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.h | 25 - opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.c | 82 - opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.h | 117 - .../tool/{Makefile.am => Makefile.include} | 2 +- .../mca/pmix/pmix2x/pmix/src/tool/pmix_tool.c | 52 +- .../pmix/pmix2x/pmix/src/usock/Makefile.am | 6 +- opal/mca/pmix/pmix2x/pmix/src/usock/usock.c | 2 +- opal/mca/pmix/pmix2x/pmix/src/usock/usock.h | 2 +- .../pmix2x/pmix/src/usock/usock_sendrecv.c | 2 +- .../mca/pmix/pmix2x/pmix/src/util/Makefile.am | 54 - .../pmix2x/pmix/src/util/Makefile.include | 68 + opal/mca/pmix/pmix2x/pmix/src/util/argv.h | 32 +- opal/mca/pmix/pmix2x/pmix/src/util/basename.h | 4 +- opal/mca/pmix/pmix2x/pmix/src/util/crc.h | 12 +- opal/mca/pmix/pmix2x/pmix/src/util/error.c | 13 +- opal/mca/pmix/pmix2x/pmix/src/util/error.h | 8 +- opal/mca/pmix/pmix2x/pmix/src/util/fd.c | 2 +- opal/mca/pmix/pmix2x/pmix/src/util/fd.h | 6 +- opal/mca/pmix/pmix2x/pmix/src/util/getid.c | 2 +- opal/mca/pmix/pmix2x/pmix/src/util/getid.h | 2 +- opal/mca/pmix/pmix2x/pmix/src/util/hash.c | 2 +- .../pmix2x/pmix/src/util/keyval/Makefile.am | 32 + .../pmix2x/pmix/src/util/keyval/keyval_lex.c | 2069 +++++++++++++++ .../pmix2x/pmix/src/util/keyval/keyval_lex.h | 74 + .../pmix2x/pmix/src/util/keyval/keyval_lex.l | 137 + .../pmix/pmix2x/pmix/src/util/keyval_parse.c | 363 +++ .../pmix/pmix2x/pmix/src/util/keyval_parse.h | 60 + opal/mca/pmix/pmix2x/pmix/src/util/os_path.h | 2 +- opal/mca/pmix/pmix2x/pmix/src/util/output.c | 2 +- opal/mca/pmix/pmix2x/pmix/src/util/output.h | 38 +- opal/mca/pmix/pmix2x/pmix/src/util/path.c | 717 ++++++ opal/mca/pmix/pmix2x/pmix/src/util/path.h | 162 ++ .../pmix/pmix2x/pmix/src/util/pmix_environ.c | 2 +- .../pmix/pmix2x/pmix/src/util/pmix_environ.h | 14 +- opal/mca/pmix/pmix2x/pmix/src/util/printf.h | 8 +- .../pmix2x/pmix/src/util/progress_threads.c | 134 - .../pmix2x/pmix/src/util/progress_threads.h | 34 - .../mca/pmix/pmix2x/pmix/src/util/show_help.c | 370 +++ .../mca/pmix/pmix2x/pmix/src/util/show_help.h | 177 ++ .../pmix/pmix2x/pmix/src/util/show_help_lex.c | 1863 ++++++++++++++ .../pmix/pmix2x/pmix/src/util/show_help_lex.h | 67 + .../pmix/pmix2x/pmix/src/util/show_help_lex.l | 114 + opal/mca/pmix/pmix2x/pmix/src/util/timings.c | 4 +- opal/mca/pmix/pmix2x/pmix/test/Makefile.am | 10 +- .../pmix/pmix2x/pmix/test/simple/Makefile.am | 16 +- opal/mca/pmix/pmix2x/pmix/test/test_common.c | 2 +- opal/mca/pmix/pmix2x/pmix/test/test_common.h | 2 +- opal/mca/pmix/pmix2x/pmix2x.c | 2 +- opal/mca/pmix/pmix2x/pmix2x.h | 2 +- 214 files changed, 24487 insertions(+), 5879 deletions(-) create mode 100755 opal/mca/pmix/pmix2x/pmix/autogen.pl delete mode 100755 opal/mca/pmix/pmix2x/pmix/autogen.sh create mode 100644 opal/mca/pmix/pmix2x/pmix/config/pmix_config_subdir.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/config/pmix_config_subdir_args.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/config/pmix_mca.m4 create mode 100755 opal/mca/pmix/pmix2x/pmix/config/pmix_mca_priority_sort.pl delete mode 100644 opal/mca/pmix/pmix2x/pmix/contrib/platform/optimized delete mode 100644 opal/mca/pmix/pmix2x/pmix/include/pmix/rename.h rename opal/mca/pmix/pmix2x/pmix/include/{pmix => }/pmix_common.h (99%) create mode 100644 opal/mca/pmix/pmix2x/pmix/man/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/man/README delete mode 100644 opal/mca/pmix/pmix2x/pmix/man/man3/pmix_fence.3 delete mode 100644 opal/mca/pmix/pmix2x/pmix/man/man3/pmix_get.3 create mode 100644 opal/mca/pmix/pmix2x/pmix/src/Makefile.am rename opal/mca/pmix/pmix2x/pmix/src/class/{Makefile.am => Makefile.include} (62%) create mode 100644 opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.h delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/client/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/client/Makefile.include delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/common/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/common/Makefile.include delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/dstore/Makefile.am delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.c delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.h delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.h delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/event/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/event/Makefile.include rename opal/mca/pmix/pmix2x/pmix/src/include/{Makefile.am => Makefile.include} (64%) delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h.in rename opal/mca/pmix/pmix2x/pmix/{include/pmix/autogen => src/include}/pmix_config_bottom.h (97%) rename opal/mca/pmix/pmix2x/pmix/{include/pmix/autogen => src/include}/pmix_config_top.h (100%) rename opal/mca/pmix/pmix2x/pmix/{include/pmix/autogen => src/include}/pmix_stdint.h (100%) create mode 100644 opal/mca/pmix/pmix2x/pmix/src/include/rename.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-base.txt create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-var.txt create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_close.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_compare.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_find.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_close.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_open.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_register.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_select.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_list.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_open.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_parse_paramfile.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_vari.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/mca.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/base.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_close.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_fns.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_open.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_select.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/configure.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/configure.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_component.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_module.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/base.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_components.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_expand.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/configure.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pinstall_dirs.h.in create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pmix_pinstalldirs_config.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/configure.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/configure.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/pmix_pinstalldirs_env.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/pinstalldirs.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/runtime/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/runtime/help-pmix-runtime.txt create mode 100644 opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_params.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_rte.h delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/server/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/server/Makefile.include delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/sm/Makefile.am delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.c delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.h delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.c delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.h rename opal/mca/pmix/pmix2x/pmix/src/tool/{Makefile.am => Makefile.include} (83%) delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/keyval/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.l create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/path.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/path.h delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/progress_threads.c delete mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/progress_threads.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/show_help.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/show_help.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.l diff --git a/.gitignore b/.gitignore index 9b79c28da3..85ff82ed41 100644 --- a/.gitignore +++ b/.gitignore @@ -305,6 +305,12 @@ 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 +opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h opal/tools/opal-checkpoint/opal-checkpoint opal/tools/opal-checkpoint/opal-checkpoint.1 diff --git a/opal/mca/pmix/ext20/configure.m4 b/opal/mca/pmix/ext20/configure.m4 index 483df1f7f8..423d670bfc 100644 --- a/opal/mca/pmix/ext20/configure.m4 +++ b/opal/mca/pmix/ext20/configure.m4 @@ -66,7 +66,7 @@ AC_DEFUN([MCA_opal_pmix_ext20_CONFIG],[ OPAL_CHECK_PACKAGE([opal_pmix_ext20], [pmix.h], [pmix], - [PMIx_Query_info], + [PMIx_Query_info_nb], [-lpmix], [$pmix_ext_install_dir], [$pmix_ext_install_dir/lib], diff --git a/opal/mca/pmix/ext20/pmix_ext20.c b/opal/mca/pmix/ext20/pmix_ext20.c index ef606e6037..55385468c4 100644 --- a/opal/mca/pmix/ext20/pmix_ext20.c +++ b/opal/mca/pmix/ext20/pmix_ext20.c @@ -39,100 +39,100 @@ #include "opal/mca/pmix/base/base.h" #include "opal/mca/pmix/pmix_types.h" -#include +#include /**** C.O.M.M.O.N I.N.T.E.R.F.A.C.E.S ****/ /* These are functions used by both client and server to * access common functions in the embedded PMIx library */ -static const char *pmix20_get_nspace(opal_jobid_t jobid); -static void pmix20_register_jobid(opal_jobid_t jobid, const char *nspace); +static const char *ext20_get_nspace(opal_jobid_t jobid); +static void ext20_register_jobid(opal_jobid_t jobid, const char *nspace); static void register_handler(opal_list_t *event_codes, - opal_list_t *info, - opal_pmix_notification_fn_t evhandler, - opal_pmix_evhandler_reg_cbfunc_t cbfunc, - void *cbdata); + opal_list_t *info, + opal_pmix_notification_fn_t evhandler, + opal_pmix_evhandler_reg_cbfunc_t cbfunc, + void *cbdata); static void deregister_handler(size_t evhandler, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata); + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata); static int notify_event(int status, - const opal_process_name_t *source, - opal_pmix_data_range_t range, - opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata); + const opal_process_name_t *source, + opal_pmix_data_range_t range, + opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata); const opal_pmix_base_module_t opal_pmix_ext20_module = { /* client APIs */ - .init = pmix20_client_init, - .finalize = pmix20_client_finalize, - .initialized = pmix20_initialized, - .abort = pmix20_abort, - .commit = pmix20_commit, - .fence = pmix20_fence, - .fence_nb = pmix20_fencenb, - .put = pmix20_put, - .get = pmix20_get, - .get_nb = pmix20_getnb, - .publish = pmix20_publish, - .publish_nb = pmix20_publishnb, - .lookup = pmix20_lookup, - .lookup_nb = pmix20_lookupnb, - .unpublish = pmix20_unpublish, - .unpublish_nb = pmix20_unpublishnb, - .spawn = pmix20_spawn, - .spawn_nb = pmix20_spawnnb, - .connect = pmix20_connect, - .connect_nb = pmix20_connectnb, - .disconnect = pmix20_disconnect, - .disconnect_nb = pmix20_disconnectnb, - .resolve_peers = pmix20_resolve_peers, - .resolve_nodes = pmix20_resolve_nodes, + .init = ext20_client_init, + .finalize = ext20_client_finalize, + .initialized = ext20_initialized, + .abort = ext20_abort, + .commit = ext20_commit, + .fence = ext20_fence, + .fence_nb = ext20_fencenb, + .put = ext20_put, + .get = ext20_get, + .get_nb = ext20_getnb, + .publish = ext20_publish, + .publish_nb = ext20_publishnb, + .lookup = ext20_lookup, + .lookup_nb = ext20_lookupnb, + .unpublish = ext20_unpublish, + .unpublish_nb = ext20_unpublishnb, + .spawn = ext20_spawn, + .spawn_nb = ext20_spawnnb, + .connect = ext20_connect, + .connect_nb = ext20_connectnb, + .disconnect = ext20_disconnect, + .disconnect_nb = ext20_disconnectnb, + .resolve_peers = ext20_resolve_peers, + .resolve_nodes = ext20_resolve_nodes, /* server APIs */ - .server_init = pmix20_server_init, - .server_finalize = pmix20_server_finalize, - .generate_regex = pmix20_server_gen_regex, - .generate_ppn = pmix20_server_gen_ppn, - .server_register_nspace = pmix20_server_register_nspace, - .server_deregister_nspace = pmix20_server_deregister_nspace, - .server_register_client = pmix20_server_register_client, - .server_deregister_client = pmix20_server_deregister_client, - .server_setup_fork = pmix20_server_setup_fork, - .server_dmodex_request = pmix20_server_dmodex, - .server_notify_event = pmix20_server_notify_event, + .server_init = ext20_server_init, + .server_finalize = ext20_server_finalize, + .generate_regex = ext20_server_gen_regex, + .generate_ppn = ext20_server_gen_ppn, + .server_register_nspace = ext20_server_register_nspace, + .server_deregister_nspace = ext20_server_deregister_nspace, + .server_register_client = ext20_server_register_client, + .server_deregister_client = ext20_server_deregister_client, + .server_setup_fork = ext20_server_setup_fork, + .server_dmodex_request = ext20_server_dmodex, + .server_notify_event = ext20_server_notify_event, /* utility APIs */ .get_version = PMIx_Get_version, .register_evhandler = register_handler, .deregister_evhandler = deregister_handler, .notify_event = notify_event, - .store_local = pmix20_store_local, - .get_nspace = pmix20_get_nspace, - .register_jobid = pmix20_register_jobid + .store_local = ext20_store_local, + .get_nspace = ext20_get_nspace, + .register_jobid = ext20_register_jobid }; -static const char *pmix20_get_nspace(opal_jobid_t jobid) +static const char *ext20_get_nspace(opal_jobid_t jobid) { - opal_pmix20_jobid_trkr_t *jptr; + opal_ext20_jobid_trkr_t *jptr; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { - if (jptr->jobid == jobid) { - return jptr->nspace; - } + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { + if (jptr->jobid == jobid) { + return jptr->nspace; + } } return NULL; } -static void pmix20_register_jobid(opal_jobid_t jobid, const char *nspace) +static void ext20_register_jobid(opal_jobid_t jobid, const char *nspace) { - opal_pmix20_jobid_trkr_t *jptr; + opal_ext20_jobid_trkr_t *jptr; /* if we don't already have it, add this to our jobid tracker */ - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { - if (jptr->jobid == jobid) { - return; - } + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { + if (jptr->jobid == jobid) { + return; + } } - jptr = OBJ_NEW(opal_pmix20_jobid_trkr_t); + jptr = OBJ_NEW(opal_ext20_jobid_trkr_t); (void)strncpy(jptr->nspace, nspace, PMIX_MAX_NSLEN); jptr->jobid = jobid; opal_list_append(&mca_pmix_ext20_component.jobids, &jptr->super); @@ -140,129 +140,129 @@ static void pmix20_register_jobid(opal_jobid_t jobid, const char *nspace) static void completion_handler(int status, void *cbdata) { - opal_pmix20_event_chain_t *chain = (opal_pmix20_event_chain_t*)cbdata; + opal_ext20_event_chain_t *chain = (opal_ext20_event_chain_t*)cbdata; if (NULL != chain->info) { - OPAL_LIST_RELEASE(chain->info); + OPAL_LIST_RELEASE(chain->info); } } static void progress_local_event_hdlr(int status, - opal_list_t *results, - opal_pmix_op_cbfunc_t cbfunc, void *thiscbdata, - void *notification_cbdata) + opal_list_t *results, + opal_pmix_op_cbfunc_t cbfunc, void *thiscbdata, + void *notification_cbdata) { - opal_pmix20_event_chain_t *chain = (opal_pmix20_event_chain_t*)notification_cbdata; + opal_ext20_event_chain_t *chain = (opal_ext20_event_chain_t*)notification_cbdata; size_t n; opal_list_item_t *nxt; - opal_pmix20_single_event_t *sing; - opal_pmix20_multi_event_t *multi; - opal_pmix20_default_event_t *def; - - /* if any results were provided, then add them here */ - if (NULL != results) { - while (NULL != (nxt = opal_list_remove_first(results))) { - opal_list_append(results, nxt); - } - } + opal_ext20_single_event_t *sing; + opal_ext20_multi_event_t *multi; + opal_ext20_default_event_t *def; /* if the caller indicates that the chain is completed, then stop here */ if (OPAL_ERR_HANDLERS_COMPLETE == status) { - goto complete; + goto complete; + } + + /* if any results were provided, then add them here */ + if (NULL != results) { + while (NULL != (nxt = opal_list_remove_first(results))) { + opal_list_append(results, nxt); + } } /* see if we need to continue, starting with the single code events */ if (NULL != chain->sing) { - /* the last handler was for a single code - see if there are - * any others that match this event */ - while (opal_list_get_end(&mca_pmix_ext20_component.single_events) != (nxt = opal_list_get_next(&chain->sing->super))) { - sing = (opal_pmix20_single_event_t*)nxt; - if (sing->code == chain->status) { - OBJ_RETAIN(chain); - chain->sing = sing; - sing->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - goto complete; - } - } - /* if we get here, then there are no more single code - * events that match */ - chain->sing = NULL; - /* pickup the beginning of the multi-code event list */ - if (0 < opal_list_get_size(&mca_pmix_ext20_component.multi_events)) { - chain->multi = (opal_pmix20_multi_event_t*)opal_list_get_begin(&mca_pmix_ext20_component.multi_events); - } + /* the last handler was for a single code - see if there are + * any others that match this event */ + while (opal_list_get_end(&mca_pmix_ext20_component.single_events) != (nxt = opal_list_get_next(&chain->sing->super))) { + sing = (opal_ext20_single_event_t*)nxt; + if (sing->code == chain->status) { + OBJ_RETAIN(chain); + chain->sing = sing; + sing->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + goto complete; + } + } + /* if we get here, then there are no more single code + * events that match */ + chain->sing = NULL; + /* pickup the beginning of the multi-code event list */ + if (0 < opal_list_get_size(&mca_pmix_ext20_component.multi_events)) { + chain->multi = (opal_ext20_multi_event_t*)opal_list_get_begin(&mca_pmix_ext20_component.multi_events); + } } /* see if we need to continue with the multi code events */ if (NULL != chain->multi) { - while (opal_list_get_end(&mca_pmix_ext20_component.multi_events) != (nxt = opal_list_get_next(&chain->multi->super))) { - multi = (opal_pmix20_multi_event_t*)nxt; - for (n=0; n < multi->ncodes; n++) { - if (multi->codes[n] == chain->status) { - /* found it - invoke the handler, pointing its - * callback function to our progression function */ - OBJ_RETAIN(chain); - chain->multi = multi; - multi->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - goto complete; - } - } - } - /* if we get here, then there are no more multi-mode - * events that match */ - chain->multi = NULL; - /* pickup the beginning of the default event list */ - if (0 < opal_list_get_size(&mca_pmix_ext20_component.default_events)) { - chain->def = (opal_pmix20_default_event_t*)opal_list_get_begin(&mca_pmix_ext20_component.default_events); - } + while (opal_list_get_end(&mca_pmix_ext20_component.multi_events) != (nxt = opal_list_get_next(&chain->multi->super))) { + multi = (opal_ext20_multi_event_t*)nxt; + for (n=0; n < multi->ncodes; n++) { + if (multi->codes[n] == chain->status) { + /* found it - invoke the handler, pointing its + * callback function to our progression function */ + OBJ_RETAIN(chain); + chain->multi = multi; + multi->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + goto complete; + } + } + } + /* if we get here, then there are no more multi-mode + * events that match */ + chain->multi = NULL; + /* pickup the beginning of the default event list */ + if (0 < opal_list_get_size(&mca_pmix_ext20_component.default_events)) { + chain->def = (opal_ext20_default_event_t*)opal_list_get_begin(&mca_pmix_ext20_component.default_events); + } } /* if they didn't want it to go to a default handler, then we are done */ if (chain->nondefault) { - goto complete; + goto complete; } if (NULL != chain->def) { - if (opal_list_get_end(&mca_pmix_ext20_component.default_events) != (nxt = opal_list_get_next(&chain->def->super))) { - def = (opal_pmix20_default_event_t*)nxt; - OBJ_RETAIN(chain); - chain->def = def; - def->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - } + if (opal_list_get_end(&mca_pmix_ext20_component.default_events) != (nxt = opal_list_get_next(&chain->def->super))) { + def = (opal_ext20_default_event_t*)nxt; + OBJ_RETAIN(chain); + chain->def = def; + def->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + } } complete: /* we still have to call their final callback */ if (NULL != chain->final_cbfunc) { - chain->final_cbfunc(OPAL_SUCCESS, chain->final_cbdata); + chain->final_cbfunc(OPAL_SUCCESS, chain->final_cbdata); } /* maintain acctng */ OBJ_RELEASE(chain); /* let the caller know that we are done with their callback */ if (NULL != cbfunc) { - cbfunc(OPAL_SUCCESS, thiscbdata); + cbfunc(OPAL_SUCCESS, thiscbdata); } } static void _event_hdlr(int sd, short args, void *cbdata) { - pmix20_threadshift_t *cd = (pmix20_threadshift_t*)cbdata; + ext20_threadshift_t *cd = (ext20_threadshift_t*)cbdata; size_t n; - opal_pmix20_event_chain_t *chain; - opal_pmix20_single_event_t *sing; - opal_pmix20_multi_event_t *multi; - opal_pmix20_default_event_t *def; + opal_ext20_event_chain_t *chain; + opal_ext20_single_event_t *sing; + opal_ext20_multi_event_t *multi; + opal_ext20_default_event_t *def; opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s RECEIVED NOTIFICATION OF STATUS %d", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), cd->status); + "%s RECEIVED NOTIFICATION OF STATUS %d", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), cd->status); - chain = OBJ_NEW(opal_pmix20_event_chain_t); + chain = OBJ_NEW(opal_ext20_event_chain_t); /* point it at our final callback */ chain->final_cbfunc = completion_handler; chain->final_cbdata = chain; @@ -274,48 +274,48 @@ static void _event_hdlr(int sd, short args, void *cbdata) chain->nondefault = cd->nondefault; /* cycle thru the single-event registrations first */ - OPAL_LIST_FOREACH(sing, &mca_pmix_ext20_component.single_events, opal_pmix20_single_event_t) { - if (sing->code == chain->status) { - /* found it - invoke the handler, pointing its - * callback function to our progression function */ - OBJ_RETAIN(chain); - chain->sing = sing; - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s CALLING SINGLE EVHDLR", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); - sing->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - return; - } + OPAL_LIST_FOREACH(sing, &mca_pmix_ext20_component.single_events, opal_ext20_single_event_t) { + if (sing->code == chain->status) { + /* found it - invoke the handler, pointing its + * callback function to our progression function */ + OBJ_RETAIN(chain); + chain->sing = sing; + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s CALLING SINGLE EVHDLR", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); + sing->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + return; + } } /* if we didn't find any match in the single-event registrations, * then cycle thru the multi-event registrations next */ - OPAL_LIST_FOREACH(multi, &mca_pmix_ext20_component.multi_events, opal_pmix20_multi_event_t) { - for (n=0; n < multi->ncodes; n++) { - if (multi->codes[n] == chain->status) { - /* found it - invoke the handler, pointing its - * callback function to our progression function */ - OBJ_RETAIN(chain); - chain->multi = multi; - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s CALLING MULTI EVHDLR", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); - multi->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - return; - } - } + OPAL_LIST_FOREACH(multi, &mca_pmix_ext20_component.multi_events, opal_ext20_multi_event_t) { + for (n=0; n < multi->ncodes; n++) { + if (multi->codes[n] == chain->status) { + /* found it - invoke the handler, pointing its + * callback function to our progression function */ + OBJ_RETAIN(chain); + chain->multi = multi; + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s CALLING MULTI EVHDLR", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); + multi->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + return; + } + } } /* if they didn't want it to go to a default handler, then we are done */ if (chain->nondefault) { - /* if we get here, then we need to cache this event in case they - * register for it later - we cannot lose individual events */ - opal_list_append(&mca_pmix_ext20_component.cache, &chain->super); - return; + /* if we get here, then we need to cache this event in case they + * register for it later - we cannot lose individual events */ + opal_list_append(&mca_pmix_ext20_component.cache, &chain->super); + return; } /* we are done with the threadshift caddy */ @@ -323,21 +323,21 @@ static void _event_hdlr(int sd, short args, void *cbdata) /* finally, pass it to any default handlers */ if (0 < opal_list_get_size(&mca_pmix_ext20_component.default_events)) { - def = (opal_pmix20_default_event_t*)opal_list_get_first(&mca_pmix_ext20_component.default_events); - OBJ_RETAIN(chain); - chain->def = def; - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s CALLING DEFAULT EVHDLR", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); - def->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - return; + def = (opal_ext20_default_event_t*)opal_list_get_first(&mca_pmix_ext20_component.default_events); + OBJ_RETAIN(chain); + chain->def = def; + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s CALLING DEFAULT EVHDLR", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); + def->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + return; } /* we still have to call their final callback */ if (NULL != chain->final_cbfunc) { - chain->final_cbfunc(PMIX_SUCCESS, chain->final_cbdata); + chain->final_cbfunc(PMIX_SUCCESS, chain->final_cbdata); } return; } @@ -348,14 +348,14 @@ static void _event_hdlr(int sd, short args, void *cbdata) * by mpirun), directly from a RM (when direct launched), or * from another process (via the local daemon). * The call will occur in the PMIx event base */ -void pmix20_event_hdlr(size_t evhdlr_registration_id, - pmix_status_t status, const pmix_proc_t *source, - pmix_info_t info[], size_t ninfo, - pmix_info_t results[], size_t nresults, - pmix_event_notification_cbfunc_fn_t cbfunc, - void *cbdata) +void ext20_event_hdlr(size_t evhdlr_registration_id, + pmix_status_t status, const pmix_proc_t *source, + pmix_info_t info[], size_t ninfo, + pmix_info_t results[], size_t nresults, + pmix_event_notification_cbfunc_fn_t cbfunc, + void *cbdata) { - pmix20_threadshift_t *cd; + ext20_threadshift_t *cd; int rc; opal_value_t *iptr; size_t n; @@ -365,550 +365,729 @@ void pmix20_event_hdlr(size_t evhdlr_registration_id, * lists and objects */ opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s RECEIVED NOTIFICATION OF STATUS %d", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), status); + "%s RECEIVED NOTIFICATION OF STATUS %d", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), status); - cd = OBJ_NEW(pmix20_threadshift_t); + cd = OBJ_NEW(ext20_threadshift_t); /* convert the incoming status */ - cd->status = pmix20_convert_rc(status); + cd->status = ext20_convert_rc(status); opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s CONVERTED STATUS %d TO STATUS %d", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), status, cd->status); + "%s CONVERTED STATUS %d TO STATUS %d", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), status, cd->status); /* convert the nspace/rank to an opal_process_name_t */ if (NULL == source) { - cd->pname.jobid = OPAL_NAME_INVALID->jobid; - cd->pname.vpid = OPAL_NAME_INVALID->vpid; + cd->pname.jobid = OPAL_NAME_INVALID->jobid; + cd->pname.vpid = OPAL_NAME_INVALID->vpid; } else { - if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&cd->pname.jobid, source->nspace))) { - OPAL_ERROR_LOG(rc); - OBJ_RELEASE(cd); - return; - } - cd->pname.vpid = source->rank; + if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&cd->pname.jobid, source->nspace))) { + OPAL_ERROR_LOG(rc); + OBJ_RELEASE(cd); + return; + } + cd->pname.vpid = ext20_convert_rank(source->rank); } /* convert the array of info */ if (NULL != info) { - cd->info = OBJ_NEW(opal_list_t); - for (n=0; n < ninfo; n++) { - if (0 == strncmp(info[n].key, PMIX_EVENT_NON_DEFAULT, PMIX_MAX_KEYLEN)) { - cd->nondefault = true; - } - iptr = OBJ_NEW(opal_value_t); - iptr->key = strdup(info[n].key); - pmix20_value_unload(iptr, &info[n].value); - opal_list_append(cd->info, &iptr->super); - } + cd->info = OBJ_NEW(opal_list_t); + for (n=0; n < ninfo; n++) { + if (0 == strncmp(info[n].key, PMIX_EVENT_NON_DEFAULT, PMIX_MAX_KEYLEN)) { + cd->nondefault = true; + } + iptr = OBJ_NEW(opal_value_t); + iptr->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(iptr, &info[n].value))) { + OPAL_ERROR_LOG(rc); + OBJ_RELEASE(iptr); + continue; + } + opal_list_append(cd->info, &iptr->super); + } } /* now push it into the local thread */ event_assign(&cd->ev, opal_pmix_base.evbase, - -1, EV_WRITE, _event_hdlr, cd); + -1, EV_WRITE, _event_hdlr, cd); event_active(&cd->ev, EV_WRITE, 1); /* we don't need any of the data they provided, * so let them go */ if (NULL != cbfunc) { - cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata); + cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata); } } -pmix_status_t pmix20_convert_opalrc(int rc) +opal_vpid_t ext20_convert_rank(int rank) +{ + switch(rank) { + case PMIX_RANK_UNDEF: + return OPAL_VPID_INVALID; + case PMIX_RANK_WILDCARD: + return OPAL_VPID_WILDCARD; + default: + return (opal_vpid_t)rank; + } +} + +pmix_rank_t ext20_convert_opalrank(opal_vpid_t vpid) +{ + switch(vpid) { + case OPAL_VPID_WILDCARD: + return PMIX_RANK_WILDCARD; + case OPAL_VPID_INVALID: + return PMIX_RANK_UNDEF; + default: + return (pmix_rank_t)vpid; + } +} + +pmix_status_t ext20_convert_opalrc(int rc) { switch (rc) { case OPAL_ERR_DEBUGGER_RELEASE: - return PMIX_ERR_DEBUGGER_RELEASE; + return PMIX_ERR_DEBUGGER_RELEASE; + + case OPAL_ERR_HANDLERS_COMPLETE: + return PMIX_EVENT_ACTION_COMPLETE; + + case OPAL_ERR_PROC_ABORTED: + return PMIX_ERR_PROC_ABORTED; + + case OPAL_ERR_PROC_REQUESTED_ABORT: + return PMIX_ERR_PROC_REQUESTED_ABORT; + + case OPAL_ERR_PROC_ABORTING: + return PMIX_ERR_PROC_ABORTING; + + case OPAL_ERR_NODE_DOWN: + return PMIX_ERR_NODE_DOWN; + + case OPAL_ERR_NODE_OFFLINE: + return PMIX_ERR_NODE_OFFLINE; case OPAL_ERR_NOT_IMPLEMENTED: case OPAL_ERR_NOT_SUPPORTED: - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; case OPAL_ERR_NOT_FOUND: - return PMIX_ERR_NOT_FOUND; + return PMIX_ERR_NOT_FOUND; case OPAL_ERR_PERM: case OPAL_ERR_UNREACH: case OPAL_ERR_SERVER_NOT_AVAIL: - return PMIX_ERR_UNREACH; + return PMIX_ERR_UNREACH; case OPAL_ERR_BAD_PARAM: - return PMIX_ERR_BAD_PARAM; + return PMIX_ERR_BAD_PARAM; case OPAL_ERR_OUT_OF_RESOURCE: - return PMIX_ERR_OUT_OF_RESOURCE; + return PMIX_ERR_OUT_OF_RESOURCE; case OPAL_ERR_DATA_VALUE_NOT_FOUND: - return PMIX_ERR_DATA_VALUE_NOT_FOUND; + return PMIX_ERR_DATA_VALUE_NOT_FOUND; case OPAL_ERR_TIMEOUT: - return PMIX_ERR_TIMEOUT; + return PMIX_ERR_TIMEOUT; case OPAL_ERR_WOULD_BLOCK: - return PMIX_ERR_WOULD_BLOCK; + return PMIX_ERR_WOULD_BLOCK; case OPAL_EXISTS: - return PMIX_EXISTS; + return PMIX_EXISTS; + + case OPAL_ERR_PARTIAL_SUCCESS: + return PMIX_QUERY_PARTIAL_SUCCESS; case OPAL_ERROR: - return PMIX_ERROR; + return PMIX_ERROR; case OPAL_SUCCESS: - return PMIX_SUCCESS; + return PMIX_SUCCESS; default: - return PMIX_ERROR; + return PMIX_ERROR; } } -int pmix20_convert_rc(pmix_status_t rc) +int ext20_convert_rc(pmix_status_t rc) { switch (rc) { case PMIX_ERR_DEBUGGER_RELEASE: - return OPAL_ERR_DEBUGGER_RELEASE; + return OPAL_ERR_DEBUGGER_RELEASE; + + case PMIX_EVENT_ACTION_COMPLETE: + return OPAL_ERR_HANDLERS_COMPLETE; + + case PMIX_ERR_PROC_ABORTED: + return OPAL_ERR_PROC_ABORTED; + + case PMIX_ERR_PROC_REQUESTED_ABORT: + return OPAL_ERR_PROC_REQUESTED_ABORT; + + case PMIX_ERR_PROC_ABORTING: + return OPAL_ERR_PROC_ABORTING; + + case PMIX_ERR_NODE_DOWN: + return OPAL_ERR_NODE_DOWN; + + case PMIX_ERR_NODE_OFFLINE: + return OPAL_ERR_NODE_OFFLINE; case PMIX_ERR_NOT_SUPPORTED: - return OPAL_ERR_NOT_SUPPORTED; + return OPAL_ERR_NOT_SUPPORTED; case PMIX_ERR_NOT_FOUND: - return OPAL_ERR_NOT_FOUND; + return OPAL_ERR_NOT_FOUND; case PMIX_ERR_OUT_OF_RESOURCE: - return OPAL_ERR_OUT_OF_RESOURCE; + return OPAL_ERR_OUT_OF_RESOURCE; case PMIX_ERR_INIT: - return OPAL_ERROR; + return OPAL_ERROR; case PMIX_ERR_BAD_PARAM: - return OPAL_ERR_BAD_PARAM; + return OPAL_ERR_BAD_PARAM; case PMIX_ERR_UNREACH: case PMIX_ERR_NO_PERMISSIONS: - return OPAL_ERR_UNREACH; + return OPAL_ERR_UNREACH; case PMIX_ERR_TIMEOUT: - return OPAL_ERR_TIMEOUT; + return OPAL_ERR_TIMEOUT; case PMIX_ERR_WOULD_BLOCK: - return OPAL_ERR_WOULD_BLOCK; + return OPAL_ERR_WOULD_BLOCK; case PMIX_ERR_LOST_CONNECTION_TO_SERVER: case PMIX_ERR_LOST_PEER_CONNECTION: case PMIX_ERR_LOST_CONNECTION_TO_CLIENT: - return OPAL_ERR_COMM_FAILURE; + return OPAL_ERR_COMM_FAILURE; case PMIX_EXISTS: - return OPAL_EXISTS; + return OPAL_EXISTS; + + case PMIX_QUERY_PARTIAL_SUCCESS: + return OPAL_ERR_PARTIAL_SUCCESS; case PMIX_ERROR: - return OPAL_ERROR; + return OPAL_ERROR; case PMIX_SUCCESS: - return OPAL_SUCCESS; + return OPAL_SUCCESS; default: - return OPAL_ERROR; + return OPAL_ERROR; } } -pmix_scope_t pmix20_convert_opalscope(opal_pmix_scope_t scope) { +opal_pmix_scope_t ext20_convert_scope(pmix_scope_t scope) +{ + switch(scope) { + case PMIX_SCOPE_UNDEF: + return OPAL_PMIX_SCOPE_UNDEF; + case PMIX_LOCAL: + return OPAL_PMIX_LOCAL; + case PMIX_REMOTE: + return OPAL_PMIX_REMOTE; + case PMIX_GLOBAL: + return OPAL_PMIX_GLOBAL; + default: + return OPAL_PMIX_SCOPE_UNDEF; + } +} + +pmix_scope_t ext20_convert_opalscope(opal_pmix_scope_t scope) { switch(scope) { case OPAL_PMIX_LOCAL: - return PMIX_LOCAL; + return PMIX_LOCAL; case OPAL_PMIX_REMOTE: - return PMIX_REMOTE; + return PMIX_REMOTE; case OPAL_PMIX_GLOBAL: - return PMIX_GLOBAL; + return PMIX_GLOBAL; default: - return PMIX_SCOPE_UNDEF; + return PMIX_SCOPE_UNDEF; } } -pmix_data_range_t pmix20_convert_opalrange(opal_pmix_data_range_t range) { +pmix_data_range_t ext20_convert_opalrange(opal_pmix_data_range_t range) { switch(range) { case OPAL_PMIX_RANGE_UNDEF: - return PMIX_RANGE_UNDEF; + return PMIX_RANGE_UNDEF; case OPAL_PMIX_RANGE_LOCAL: - return PMIX_RANGE_LOCAL; + return PMIX_RANGE_LOCAL; case OPAL_PMIX_RANGE_NAMESPACE: - return PMIX_RANGE_NAMESPACE; + return PMIX_RANGE_NAMESPACE; case OPAL_PMIX_RANGE_SESSION: - return PMIX_RANGE_SESSION; + return PMIX_RANGE_SESSION; case OPAL_PMIX_RANGE_GLOBAL: - return PMIX_RANGE_GLOBAL; + return PMIX_RANGE_GLOBAL; case OPAL_PMIX_RANGE_CUSTOM: - return PMIX_RANGE_CUSTOM; + return PMIX_RANGE_CUSTOM; default: - return PMIX_SCOPE_UNDEF; + return PMIX_SCOPE_UNDEF; } } -opal_pmix_data_range_t pmix20_convert_range(pmix_data_range_t range) { +opal_pmix_data_range_t ext20_convert_range(pmix_data_range_t range) { switch(range) { case PMIX_RANGE_UNDEF: - return OPAL_PMIX_RANGE_UNDEF; + return OPAL_PMIX_RANGE_UNDEF; case PMIX_RANGE_LOCAL: - return OPAL_PMIX_RANGE_LOCAL; + return OPAL_PMIX_RANGE_LOCAL; case PMIX_RANGE_NAMESPACE: - return OPAL_PMIX_RANGE_NAMESPACE; + return OPAL_PMIX_RANGE_NAMESPACE; case PMIX_RANGE_SESSION: - return OPAL_PMIX_RANGE_SESSION; + return OPAL_PMIX_RANGE_SESSION; case PMIX_RANGE_GLOBAL: - return OPAL_PMIX_RANGE_GLOBAL; + return OPAL_PMIX_RANGE_GLOBAL; case PMIX_RANGE_CUSTOM: - return OPAL_PMIX_RANGE_CUSTOM; + return OPAL_PMIX_RANGE_CUSTOM; default: - return OPAL_PMIX_SCOPE_UNDEF; + return OPAL_PMIX_SCOPE_UNDEF; } } - -void pmix20_value_load(pmix_value_t *v, - opal_value_t *kv) +opal_pmix_persistence_t ext20_convert_persist(pmix_persistence_t persist) { - size_t n; - char nspace[PMIX_MAX_NSLEN + 1]; - - switch(kv->type) { - case OPAL_UNDEF: - v->type = PMIX_UNDEF; - break; - case OPAL_BOOL: - v->type = PMIX_BOOL; - memcpy(&(v->data.flag), &kv->data.flag, 1); - break; - case OPAL_BYTE: - v->type = PMIX_BYTE; - memcpy(&(v->data.byte), &kv->data.byte, 1); - break; - case OPAL_STRING: - v->type = PMIX_STRING; - if (NULL != kv->data.string) { - v->data.string = strdup(kv->data.string); - } else { - v->data.string = NULL; - } - break; - case OPAL_SIZE: - v->type = PMIX_SIZE; - v->data.size = (size_t)kv->data.size; - break; - case OPAL_PID: - v->type = PMIX_PID; - memcpy(&(v->data.pid), &kv->data.pid, sizeof(pid_t)); - break; - case OPAL_INT: - v->type = PMIX_INT; - memcpy(&(v->data.integer), &kv->data.integer, sizeof(int)); - break; - case OPAL_INT8: - v->type = PMIX_INT8; - memcpy(&(v->data.int8), &kv->data.int8, 1); - break; - case OPAL_INT16: - v->type = PMIX_INT16; - memcpy(&(v->data.int16), &kv->data.int16, 2); - break; - case OPAL_INT32: - v->type = PMIX_INT32; - memcpy(&(v->data.int32), &kv->data.int32, 4); - break; - case OPAL_INT64: - v->type = PMIX_INT64; - memcpy(&(v->data.int64), &kv->data.int64, 8); - break; - case OPAL_UINT: - v->type = PMIX_UINT; - memcpy(&(v->data.uint), &kv->data.uint, sizeof(int)); - break; - case OPAL_UINT8: - v->type = PMIX_UINT8; - memcpy(&(v->data.uint8), &kv->data.uint8, 1); - break; - case OPAL_UINT16: - v->type = PMIX_UINT16; - memcpy(&(v->data.uint16), &kv->data.uint16, 2); - break; - case OPAL_UINT32: - v->type = PMIX_UINT32; - memcpy(&(v->data.uint32), &kv->data.uint32, 4); - break; - case OPAL_UINT64: - v->type = PMIX_UINT64; - memcpy(&(v->data.uint64), &kv->data.uint64, 8); - break; - case OPAL_FLOAT: - v->type = PMIX_FLOAT; - memcpy(&(v->data.fval), &kv->data.fval, sizeof(float)); - break; - case OPAL_DOUBLE: - v->type = PMIX_DOUBLE; - memcpy(&(v->data.dval), &kv->data.dval, sizeof(double)); - break; - case OPAL_TIMEVAL: - v->type = PMIX_TIMEVAL; - memcpy(&(v->data.tv), &kv->data.tv, sizeof(struct timeval)); - break; - case OPAL_BYTE_OBJECT: - v->type = PMIX_BYTE_OBJECT; - if (NULL != kv->data.bo.bytes) { - v->data.bo.bytes = (char*)malloc(kv->data.bo.size); - memcpy(v->data.bo.bytes, kv->data.bo.bytes, kv->data.bo.size); - v->data.bo.size = (size_t)kv->data.bo.size; - } else { - v->data.bo.bytes = NULL; - v->data.bo.size = 0; - } - break; - case OPAL_UINT32_ARRAY: - /* an array of 32-bit jobids */ - v->type = PMIX_INFO_ARRAY; - v->data.array.size = kv->data.uint32_array.size; - if (0 < v->data.array.size) { - PMIX_INFO_CREATE(v->data.array.array, v->data.array.size); - for (n=0; n < v->data.array.size; n++) { - v->data.array.array[n].value.type = PMIX_STRING; - (void)opal_snprintf_jobid(nspace, PMIX_MAX_NSLEN, kv->data.uint32_array.data[n]); - v->data.array.array[n].value.data.string = strdup(nspace); - } - } - break; - default: - /* silence warnings */ - break; + switch(persist) { + case PMIX_PERSIST_INDEF: + return OPAL_PMIX_PERSIST_INDEF; + case PMIX_PERSIST_FIRST_READ: + return OPAL_PMIX_PERSIST_FIRST_READ; + case PMIX_PERSIST_PROC: + return OPAL_PMIX_PERSIST_PROC; + case PMIX_PERSIST_APP: + return OPAL_PMIX_PERSIST_APP; + case PMIX_PERSIST_SESSION: + return OPAL_PMIX_PERSIST_SESSION; + default: + return OPAL_PMIX_PERSIST_INDEF; } } -int pmix20_value_unload(opal_value_t *kv, - const pmix_value_t *v) +pmix_persistence_t ext20_convert_opalpersist(opal_pmix_persistence_t persist) +{ + switch(persist) { + case OPAL_PMIX_PERSIST_INDEF: + return PMIX_PERSIST_INDEF; + case OPAL_PMIX_PERSIST_FIRST_READ: + return PMIX_PERSIST_FIRST_READ; + case OPAL_PMIX_PERSIST_PROC: + return PMIX_PERSIST_PROC; + case OPAL_PMIX_PERSIST_APP: + return PMIX_PERSIST_APP; + case OPAL_PMIX_PERSIST_SESSION: + return PMIX_PERSIST_SESSION; + default: + return PMIX_PERSIST_INDEF; + } +} + +/**** RHC: NEED TO ADD SUPPORT FOR NEW PMIX DATA TYPES, INCLUDING + **** CONVERSION OF PROC STATES ****/ + +void ext20_value_load(pmix_value_t *v, + opal_value_t *kv) +{ + switch(kv->type) { + case OPAL_UNDEF: + v->type = PMIX_UNDEF; + break; + case OPAL_BOOL: + v->type = PMIX_BOOL; + memcpy(&(v->data.flag), &kv->data.flag, 1); + break; + case OPAL_BYTE: + v->type = PMIX_BYTE; + memcpy(&(v->data.byte), &kv->data.byte, 1); + break; + case OPAL_STRING: + v->type = PMIX_STRING; + if (NULL != kv->data.string) { + v->data.string = strdup(kv->data.string); + } else { + v->data.string = NULL; + } + break; + case OPAL_SIZE: + v->type = PMIX_SIZE; + v->data.size = (size_t)kv->data.size; + break; + case OPAL_PID: + v->type = PMIX_PID; + memcpy(&(v->data.pid), &kv->data.pid, sizeof(pid_t)); + break; + case OPAL_INT: + v->type = PMIX_INT; + memcpy(&(v->data.integer), &kv->data.integer, sizeof(int)); + break; + case OPAL_INT8: + v->type = PMIX_INT8; + memcpy(&(v->data.int8), &kv->data.int8, 1); + break; + case OPAL_INT16: + v->type = PMIX_INT16; + memcpy(&(v->data.int16), &kv->data.int16, 2); + break; + case OPAL_INT32: + v->type = PMIX_INT32; + memcpy(&(v->data.int32), &kv->data.int32, 4); + break; + case OPAL_INT64: + v->type = PMIX_INT64; + memcpy(&(v->data.int64), &kv->data.int64, 8); + break; + case OPAL_UINT: + v->type = PMIX_UINT; + memcpy(&(v->data.uint), &kv->data.uint, sizeof(int)); + break; + case OPAL_UINT8: + v->type = PMIX_UINT8; + memcpy(&(v->data.uint8), &kv->data.uint8, 1); + break; + case OPAL_UINT16: + v->type = PMIX_UINT16; + memcpy(&(v->data.uint16), &kv->data.uint16, 2); + break; + case OPAL_UINT32: + v->type = PMIX_UINT32; + memcpy(&(v->data.uint32), &kv->data.uint32, 4); + break; + case OPAL_UINT64: + v->type = PMIX_UINT64; + memcpy(&(v->data.uint64), &kv->data.uint64, 8); + break; + case OPAL_FLOAT: + v->type = PMIX_FLOAT; + memcpy(&(v->data.fval), &kv->data.fval, sizeof(float)); + break; + case OPAL_DOUBLE: + v->type = PMIX_DOUBLE; + memcpy(&(v->data.dval), &kv->data.dval, sizeof(double)); + break; + case OPAL_TIMEVAL: + v->type = PMIX_TIMEVAL; + memcpy(&(v->data.tv), &kv->data.tv, sizeof(struct timeval)); + break; + case OPAL_TIME: + v->type = PMIX_TIME; + memcpy(&(v->data.time), &kv->data.time, sizeof(time_t)); + break; + case OPAL_STATUS: + v->type = PMIX_STATUS; + memcpy(&(v->data.status), &kv->data.status, sizeof(pmix_status_t)); + break; + case OPAL_VPID: + v->type = PMIX_PROC_RANK; + v->data.rank = ext20_convert_opalrank(kv->data.name.vpid); + break; + case OPAL_NAME: + v->type = PMIX_PROC; + /* have to stringify the jobid */ + (void)opal_snprintf_jobid(v->data.proc.nspace, PMIX_MAX_NSLEN, kv->data.name.vpid); + v->data.proc.rank = ext20_convert_opalrank(kv->data.name.vpid); + break; + case OPAL_BYTE_OBJECT: + v->type = PMIX_BYTE_OBJECT; + if (NULL != kv->data.bo.bytes) { + v->data.bo.bytes = (char*)malloc(kv->data.bo.size); + memcpy(v->data.bo.bytes, kv->data.bo.bytes, kv->data.bo.size); + v->data.bo.size = (size_t)kv->data.bo.size; + } else { + v->data.bo.bytes = NULL; + v->data.bo.size = 0; + } + break; + case OPAL_PERSIST: + v->type = PMIX_PERSIST; + v->data.persist = ext20_convert_opalpersist(kv->data.uint8); + break; + case OPAL_SCOPE: + v->type = PMIX_SCOPE; + v->data.scope = ext20_convert_opalscope(kv->data.uint8); + break; + case OPAL_DATA_RANGE: + v->type = PMIX_DATA_RANGE; + v->data.range = ext20_convert_opalrange(kv->data.uint8); + break; + case OPAL_PROC_STATE: + v->type = PMIX_PROC_STATE; + /* the OPAL layer doesn't have any concept of proc state, + * so the ORTE layer is responsible for converting it */ + memcpy(&v->data.state, &kv->data.uint8, sizeof(uint8_t)); + break; + default: + /* silence warnings */ + break; + } +} + +int ext20_value_unload(opal_value_t *kv, + const pmix_value_t *v) { int rc=OPAL_SUCCESS; switch(v->type) { case PMIX_UNDEF: - kv->type = OPAL_UNDEF; - break; + kv->type = OPAL_UNDEF; + break; case PMIX_BOOL: - kv->type = OPAL_BOOL; - memcpy(&kv->data.flag, &(v->data.flag), 1); - break; + kv->type = OPAL_BOOL; + memcpy(&kv->data.flag, &(v->data.flag), 1); + break; case PMIX_BYTE: - kv->type = OPAL_BYTE; - memcpy(&kv->data.byte, &(v->data.byte), 1); - break; + kv->type = OPAL_BYTE; + memcpy(&kv->data.byte, &(v->data.byte), 1); + break; case PMIX_STRING: - kv->type = OPAL_STRING; - if (NULL != v->data.string) { - kv->data.string = strdup(v->data.string); - } - break; + kv->type = OPAL_STRING; + if (NULL != v->data.string) { + kv->data.string = strdup(v->data.string); + } + break; case PMIX_SIZE: - kv->type = OPAL_SIZE; - kv->data.size = (int)v->data.size; - break; + kv->type = OPAL_SIZE; + kv->data.size = (int)v->data.size; + break; case PMIX_PID: - kv->type = OPAL_PID; - memcpy(&kv->data.pid, &(v->data.pid), sizeof(pid_t)); - break; + kv->type = OPAL_PID; + memcpy(&kv->data.pid, &(v->data.pid), sizeof(pid_t)); + break; case PMIX_INT: - kv->type = OPAL_INT; - memcpy(&kv->data.integer, &(v->data.integer), sizeof(int)); - break; + kv->type = OPAL_INT; + memcpy(&kv->data.integer, &(v->data.integer), sizeof(int)); + break; case PMIX_INT8: - kv->type = OPAL_INT8; - memcpy(&kv->data.int8, &(v->data.int8), 1); - break; + kv->type = OPAL_INT8; + memcpy(&kv->data.int8, &(v->data.int8), 1); + break; case PMIX_INT16: - kv->type = OPAL_INT16; - memcpy(&kv->data.int16, &(v->data.int16), 2); - break; + kv->type = OPAL_INT16; + memcpy(&kv->data.int16, &(v->data.int16), 2); + break; case PMIX_INT32: - kv->type = OPAL_INT32; - memcpy(&kv->data.int32, &(v->data.int32), 4); - break; + kv->type = OPAL_INT32; + memcpy(&kv->data.int32, &(v->data.int32), 4); + break; case PMIX_INT64: - kv->type = OPAL_INT64; - memcpy(&kv->data, &(v->data.int64), 8); - break; + kv->type = OPAL_INT64; + memcpy(&kv->data.int64, &(v->data.int64), 8); + break; case PMIX_UINT: - kv->type = OPAL_UINT; - memcpy(&kv->data, &(v->data.uint), sizeof(int)); - break; + kv->type = OPAL_UINT; + memcpy(&kv->data.uint, &(v->data.uint), sizeof(int)); + break; case PMIX_UINT8: - kv->type = OPAL_UINT8; - memcpy(&kv->data, &(v->data.uint8), 1); - break; + kv->type = OPAL_UINT8; + memcpy(&kv->data.uint8, &(v->data.uint8), 1); + break; case PMIX_UINT16: - kv->type = OPAL_UINT16; - memcpy(&kv->data, &(v->data.uint16), 2); - break; + kv->type = OPAL_UINT16; + memcpy(&kv->data.uint16, &(v->data.uint16), 2); + break; case PMIX_UINT32: - kv->type = OPAL_UINT32; - memcpy(&kv->data, &(v->data.uint32), 4); - break; + kv->type = OPAL_UINT32; + memcpy(&kv->data.uint32, &(v->data.uint32), 4); + break; case PMIX_UINT64: - kv->type = OPAL_UINT64; - memcpy(&kv->data, &(v->data.uint64), 8); - break; + kv->type = OPAL_UINT64; + memcpy(&kv->data.uint64, &(v->data.uint64), 8); + break; case PMIX_FLOAT: - kv->type = OPAL_FLOAT; - memcpy(&kv->data, &(v->data.fval), sizeof(float)); - break; + kv->type = OPAL_FLOAT; + memcpy(&kv->data.fval, &(v->data.fval), sizeof(float)); + break; case PMIX_DOUBLE: - kv->type = OPAL_DOUBLE; - memcpy(&kv->data, &(v->data.dval), sizeof(double)); - break; + kv->type = OPAL_DOUBLE; + memcpy(&kv->data.dval, &(v->data.dval), sizeof(double)); + break; case PMIX_TIMEVAL: - kv->type = OPAL_TIMEVAL; - memcpy(&kv->data, &(v->data.tv), sizeof(struct timeval)); - break; + kv->type = OPAL_TIMEVAL; + memcpy(&kv->data.tv, &(v->data.tv), sizeof(struct timeval)); + break; + case PMIX_TIME: + kv->type = OPAL_TIME; + memcpy(&kv->data.time, &(v->data.tv), sizeof(struct timeval)); + break; + case PMIX_STATUS: + kv->type = OPAL_STATUS; + memcpy(&kv->data.status, &(v->data.status), sizeof(opal_status_t)); + break; + case PMIX_PROC_RANK: + kv->type = OPAL_VPID; + kv->data.name.vpid = ext20_convert_rank(v->data.rank); + break; + case PMIX_PROC: + kv->type = OPAL_NAME; + if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&kv->data.name.jobid, v->data.proc.nspace))) { + return ext20_convert_opalrc(rc); + } + kv->data.name.vpid = ext20_convert_rank(v->data.proc.rank); + break; case PMIX_BYTE_OBJECT: - kv->type = OPAL_BYTE_OBJECT; - if (NULL != v->data.bo.bytes && 0 < v->data.bo.size) { - kv->data.bo.bytes = (uint8_t*)malloc(v->data.bo.size); - memcpy(kv->data.bo.bytes, v->data.bo.bytes, v->data.bo.size); - kv->data.bo.size = (int)v->data.bo.size; - } else { - kv->data.bo.bytes = NULL; - kv->data.bo.size = 0; - } - break; + kv->type = OPAL_BYTE_OBJECT; + if (NULL != v->data.bo.bytes && 0 < v->data.bo.size) { + kv->data.bo.bytes = (uint8_t*)malloc(v->data.bo.size); + memcpy(kv->data.bo.bytes, v->data.bo.bytes, v->data.bo.size); + kv->data.bo.size = (int)v->data.bo.size; + } else { + kv->data.bo.bytes = NULL; + kv->data.bo.size = 0; + } + break; + case PMIX_PERSIST: + kv->type = OPAL_PERSIST; + kv->data.uint8 = ext20_convert_persist(v->data.persist); + break; + case PMIX_SCOPE: + kv->type = OPAL_SCOPE; + kv->data.uint8 = ext20_convert_scope(v->data.persist); + break; + case PMIX_DATA_RANGE: + kv->type = OPAL_DATA_RANGE; + kv->data.uint8 = ext20_convert_range(v->data.persist); + case PMIX_PROC_STATE: + kv->type = OPAL_PROC_STATE; + /* the OPAL layer doesn't have any concept of proc state, + * so the ORTE layer is responsible for converting it */ + memcpy(&kv->data.uint8, &v->data.state, sizeof(uint8_t)); default: - /* silence warnings */ - rc = OPAL_ERROR; - break; + /* silence warnings */ + rc = OPAL_ERROR; + break; } return rc; } static void _reg_hdlr(int sd, short args, void *cbdata) { - pmix20_threadshift_t *cd = (pmix20_threadshift_t*)cbdata; - opal_pmix20_event_chain_t *chain; - opal_pmix20_single_event_t *sing = NULL; - opal_pmix20_multi_event_t *multi = NULL; - opal_pmix20_default_event_t *def = NULL; + ext20_threadshift_t *cd = (ext20_threadshift_t*)cbdata; + opal_ext20_event_chain_t *chain; + opal_ext20_single_event_t *sing = NULL; + opal_ext20_multi_event_t *multi = NULL; + opal_ext20_default_event_t *def = NULL; opal_value_t *kv; int i; bool prepend = false; size_t n; opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s REGISTER HANDLER CODES %s", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), - (NULL == cd->event_codes) ? "NULL" : "NON-NULL"); + "%s REGISTER HANDLER CODES %s", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), + (NULL == cd->event_codes) ? "NULL" : "NON-NULL"); if (NULL != cd->info) { - OPAL_LIST_FOREACH(kv, cd->info, opal_value_t) { - if (0 == strcmp(kv->key, OPAL_PMIX_EVENT_ORDER_PREPEND)) { - prepend = true; - break; - } - } + OPAL_LIST_FOREACH(kv, cd->info, opal_value_t) { + if (0 == strcmp(kv->key, OPAL_PMIX_EVENT_ORDER_PREPEND)) { + prepend = true; + break; + } + } } if (NULL == cd->event_codes) { - /* this is a default handler */ - def = OBJ_NEW(opal_pmix20_default_event_t); - def->handler = cd->evhandler; - def->index = mca_pmix_ext20_component.evindex; - if (prepend) { - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s PREPENDING TO DEFAULT EVENTS", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); - opal_list_prepend(&mca_pmix_ext20_component.default_events, &def->super); - } else { - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s APPENDING TO DEFAULT EVENTS", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); - opal_list_append(&mca_pmix_ext20_component.default_events, &def->super); - } + /* this is a default handler */ + def = OBJ_NEW(opal_ext20_default_event_t); + def->handler = cd->evhandler; + def->index = mca_pmix_ext20_component.evindex; + if (prepend) { + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s PREPENDING TO DEFAULT EVENTS", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); + opal_list_prepend(&mca_pmix_ext20_component.default_events, &def->super); + } else { + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s APPENDING TO DEFAULT EVENTS", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); + opal_list_append(&mca_pmix_ext20_component.default_events, &def->super); + } } else if (1 == opal_list_get_size(cd->event_codes)) { - /* single handler */ - sing = OBJ_NEW(opal_pmix20_single_event_t); - kv = (opal_value_t*)opal_list_get_first(cd->event_codes); - sing->code = kv->data.integer; - sing->index = mca_pmix_ext20_component.evindex; - sing->handler = cd->evhandler; - if (prepend) { - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s PREPENDING TO SINGLE EVENTS WITH CODE %d", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), sing->code); - opal_list_prepend(&mca_pmix_ext20_component.single_events, &sing->super); - } else { - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s APPENDING TO SINGLE EVENTS WITH CODE %d", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), sing->code); - opal_list_append(&mca_pmix_ext20_component.single_events, &sing->super); - } + /* single handler */ + sing = OBJ_NEW(opal_ext20_single_event_t); + kv = (opal_value_t*)opal_list_get_first(cd->event_codes); + sing->code = kv->data.integer; + sing->index = mca_pmix_ext20_component.evindex; + sing->handler = cd->evhandler; + if (prepend) { + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s PREPENDING TO SINGLE EVENTS WITH CODE %d", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), sing->code); + opal_list_prepend(&mca_pmix_ext20_component.single_events, &sing->super); + } else { + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s APPENDING TO SINGLE EVENTS WITH CODE %d", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), sing->code); + opal_list_append(&mca_pmix_ext20_component.single_events, &sing->super); + } } else { - multi = OBJ_NEW(opal_pmix20_multi_event_t); - multi->ncodes = opal_list_get_size(cd->event_codes); - multi->codes = (int*)malloc(multi->ncodes * sizeof(int)); - i=0; - OPAL_LIST_FOREACH(kv, cd->event_codes, opal_value_t) { - multi->codes[i] = kv->data.integer; - ++i; - } - multi->index = mca_pmix_ext20_component.evindex; - multi->handler = cd->evhandler; - if (prepend) { - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s PREPENDING TO MULTI EVENTS", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); - opal_list_prepend(&mca_pmix_ext20_component.multi_events, &multi->super); - } else { - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "%s APPENDING TO MULTI EVENTS", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); - opal_list_append(&mca_pmix_ext20_component.multi_events, &multi->super); - } + multi = OBJ_NEW(opal_ext20_multi_event_t); + multi->ncodes = opal_list_get_size(cd->event_codes); + multi->codes = (int*)malloc(multi->ncodes * sizeof(int)); + i=0; + OPAL_LIST_FOREACH(kv, cd->event_codes, opal_value_t) { + multi->codes[i] = kv->data.integer; + ++i; + } + multi->index = mca_pmix_ext20_component.evindex; + multi->handler = cd->evhandler; + if (prepend) { + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s PREPENDING TO MULTI EVENTS", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); + opal_list_prepend(&mca_pmix_ext20_component.multi_events, &multi->super); + } else { + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "%s APPENDING TO MULTI EVENTS", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME)); + opal_list_append(&mca_pmix_ext20_component.multi_events, &multi->super); + } } /* release the caller */ if (NULL != cd->cbfunc) { - cd->cbfunc(OPAL_SUCCESS, mca_pmix_ext20_component.evindex, cd->cbdata); + cd->cbfunc(OPAL_SUCCESS, mca_pmix_ext20_component.evindex, cd->cbdata); } mca_pmix_ext20_component.evindex++; /* check if any matching notifications have been cached - only nondefault * events will have been cached*/ if (NULL == def) { - /* check single code registrations */ - if (NULL != sing) { - OPAL_LIST_FOREACH(chain, &mca_pmix_ext20_component.cache, opal_pmix20_event_chain_t) { - if (sing->code == chain->status) { - opal_list_remove_item(&mca_pmix_ext20_component.cache, &chain->super); - chain->sing = sing; - sing->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - OBJ_RELEASE(cd); - return; - } - } - } else if (NULL != multi) { - /* check for multi code registrations */ - OPAL_LIST_FOREACH(chain, &mca_pmix_ext20_component.cache, opal_pmix20_event_chain_t) { - for (n=0; n < multi->ncodes; n++) { - if (multi->codes[n] == chain->status) { - opal_list_remove_item(&mca_pmix_ext20_component.cache, &chain->super); - chain->multi = multi; - multi->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - OBJ_RELEASE(cd); - return; - } - } - } - } + /* check single code registrations */ + if (NULL != sing) { + OPAL_LIST_FOREACH(chain, &mca_pmix_ext20_component.cache, opal_ext20_event_chain_t) { + if (sing->code == chain->status) { + opal_list_remove_item(&mca_pmix_ext20_component.cache, &chain->super); + chain->sing = sing; + sing->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + OBJ_RELEASE(cd); + return; + } + } + } else if (NULL != multi) { + /* check for multi code registrations */ + OPAL_LIST_FOREACH(chain, &mca_pmix_ext20_component.cache, opal_ext20_event_chain_t) { + for (n=0; n < multi->ncodes; n++) { + if (multi->codes[n] == chain->status) { + opal_list_remove_item(&mca_pmix_ext20_component.cache, &chain->super); + chain->multi = multi; + multi->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + OBJ_RELEASE(cd); + return; + } + } + } + } } OBJ_RELEASE(cd); return; } static void register_handler(opal_list_t *event_codes, - opal_list_t *info, - opal_pmix_notification_fn_t evhandler, - opal_pmix_evhandler_reg_cbfunc_t cbfunc, - void *cbdata) + opal_list_t *info, + opal_pmix_notification_fn_t evhandler, + opal_pmix_evhandler_reg_cbfunc_t cbfunc, + void *cbdata) { /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -919,46 +1098,46 @@ static void register_handler(opal_list_t *event_codes, static void _dereg_hdlr(int sd, short args, void *cbdata) { - pmix20_threadshift_t *cd = (pmix20_threadshift_t*)cbdata; - opal_pmix20_single_event_t *sing; - opal_pmix20_multi_event_t *multi; - opal_pmix20_default_event_t *def; + ext20_threadshift_t *cd = (ext20_threadshift_t*)cbdata; + opal_ext20_single_event_t *sing; + opal_ext20_multi_event_t *multi; + opal_ext20_default_event_t *def; /* check the single events first */ - OPAL_LIST_FOREACH(sing, &mca_pmix_ext20_component.single_events, opal_pmix20_single_event_t) { - if (cd->handler == sing->index) { - opal_list_remove_item(&mca_pmix_ext20_component.single_events, &sing->super); - OBJ_RELEASE(sing); - goto release; - } + OPAL_LIST_FOREACH(sing, &mca_pmix_ext20_component.single_events, opal_ext20_single_event_t) { + if (cd->handler == sing->index) { + opal_list_remove_item(&mca_pmix_ext20_component.single_events, &sing->super); + OBJ_RELEASE(sing); + goto release; + } } /* check multi events */ - OPAL_LIST_FOREACH(multi, &mca_pmix_ext20_component.multi_events, opal_pmix20_multi_event_t) { - if (cd->handler == multi->index) { - opal_list_remove_item(&mca_pmix_ext20_component.multi_events, &multi->super); - OBJ_RELEASE(multi); - goto release; - } + OPAL_LIST_FOREACH(multi, &mca_pmix_ext20_component.multi_events, opal_ext20_multi_event_t) { + if (cd->handler == multi->index) { + opal_list_remove_item(&mca_pmix_ext20_component.multi_events, &multi->super); + OBJ_RELEASE(multi); + goto release; + } } /* check default events */ - OPAL_LIST_FOREACH(def, &mca_pmix_ext20_component.default_events, opal_pmix20_default_event_t) { - if (cd->handler == def->index) { - opal_list_remove_item(&mca_pmix_ext20_component.default_events, &def->super); - OBJ_RELEASE(def); - break; - } + OPAL_LIST_FOREACH(def, &mca_pmix_ext20_component.default_events, opal_ext20_default_event_t) { + if (cd->handler == def->index) { + opal_list_remove_item(&mca_pmix_ext20_component.default_events, &def->super); + OBJ_RELEASE(def); + break; + } } release: if (NULL != cd->opcbfunc) { - cd->opcbfunc(OPAL_SUCCESS, cd->cbdata); + cd->opcbfunc(OPAL_SUCCESS, cd->cbdata); } OBJ_RELEASE(cd); } static void deregister_handler(size_t evhandler, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata) + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata) { /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -968,95 +1147,95 @@ static void deregister_handler(size_t evhandler, static void _notify_event(int sd, short args, void *cbdata) { - pmix20_threadshift_t *cd = (pmix20_threadshift_t*)cbdata; + ext20_threadshift_t *cd = (ext20_threadshift_t*)cbdata; size_t i; - opal_pmix20_single_event_t *sing; - opal_pmix20_multi_event_t *multi; - opal_pmix20_default_event_t *def; - opal_pmix20_event_chain_t *chain; + opal_ext20_single_event_t *sing; + opal_ext20_multi_event_t *multi; + opal_ext20_default_event_t *def; + opal_ext20_event_chain_t *chain; /* check the single events first */ - OPAL_LIST_FOREACH(sing, &mca_pmix_ext20_component.single_events, opal_pmix20_single_event_t) { - if (cd->status == sing->code) { - /* found it - invoke the handler, pointing its - * callback function to our progression function */ - chain = OBJ_NEW(opal_pmix20_event_chain_t); - chain->status = cd->status; - chain->range = pmix20_convert_opalrange(cd->range); - chain->source = *(cd->source); - chain->info = cd->info; - chain->final_cbfunc = cd->opcbfunc; - chain->final_cbdata = cd->cbdata; - chain->sing = sing; - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "[%s] CALLING SINGLE EVHDLR FOR STATUS %d", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), chain->status); - sing->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - OBJ_RELEASE(cd); - return; - } + OPAL_LIST_FOREACH(sing, &mca_pmix_ext20_component.single_events, opal_ext20_single_event_t) { + if (cd->status == sing->code) { + /* found it - invoke the handler, pointing its + * callback function to our progression function */ + chain = OBJ_NEW(opal_ext20_event_chain_t); + chain->status = cd->status; + chain->range = ext20_convert_opalrange(cd->range); + chain->source = *(cd->source); + chain->info = cd->info; + chain->final_cbfunc = cd->opcbfunc; + chain->final_cbdata = cd->cbdata; + chain->sing = sing; + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "[%s] CALLING SINGLE EVHDLR FOR STATUS %d", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), chain->status); + sing->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + OBJ_RELEASE(cd); + return; + } } /* check multi events */ - OPAL_LIST_FOREACH(multi, &mca_pmix_ext20_component.multi_events, opal_pmix20_multi_event_t) { - for (i=0; i < multi->ncodes; i++) { - if (cd->status == multi->codes[i]) { - /* found it - invoke the handler, pointing its - * callback function to our progression function */ - chain = OBJ_NEW(opal_pmix20_event_chain_t); - chain->status = cd->status; - chain->range = pmix20_convert_opalrange(cd->range); - chain->source = *(cd->source); - chain->info = cd->info; - chain->final_cbfunc = cd->opcbfunc; - chain->final_cbdata = cd->cbdata; - chain->multi = multi; - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "[%s] CALLING MULTI EVHDLR FOR STATUS %d", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), chain->status); - multi->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - OBJ_RELEASE(cd); - return; - } - } + OPAL_LIST_FOREACH(multi, &mca_pmix_ext20_component.multi_events, opal_ext20_multi_event_t) { + for (i=0; i < multi->ncodes; i++) { + if (cd->status == multi->codes[i]) { + /* found it - invoke the handler, pointing its + * callback function to our progression function */ + chain = OBJ_NEW(opal_ext20_event_chain_t); + chain->status = cd->status; + chain->range = ext20_convert_opalrange(cd->range); + chain->source = *(cd->source); + chain->info = cd->info; + chain->final_cbfunc = cd->opcbfunc; + chain->final_cbdata = cd->cbdata; + chain->multi = multi; + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "[%s] CALLING MULTI EVHDLR FOR STATUS %d", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), chain->status); + multi->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + OBJ_RELEASE(cd); + return; + } + } } /* check default events */ if (0 < opal_list_get_size(&mca_pmix_ext20_component.default_events)) { - def = (opal_pmix20_default_event_t*)opal_list_get_first(&mca_pmix_ext20_component.default_events); - chain = OBJ_NEW(opal_pmix20_event_chain_t); - chain->status = cd->status; - chain->range = pmix20_convert_opalrange(cd->range); - chain->source = *(cd->source); - chain->info = cd->info; - chain->final_cbfunc = cd->opcbfunc; - chain->final_cbdata = cd->cbdata; - chain->def = def; - opal_output_verbose(2, opal_pmix_base_framework.framework_output, - "[%s] CALLING DEFAULT EVHDLR FOR STATUS %d", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), chain->status); - def->handler(chain->status, &chain->source, - chain->info, &chain->results, - progress_local_event_hdlr, (void*)chain); - OBJ_RELEASE(cd); - return; + def = (opal_ext20_default_event_t*)opal_list_get_first(&mca_pmix_ext20_component.default_events); + chain = OBJ_NEW(opal_ext20_event_chain_t); + chain->status = cd->status; + chain->range = ext20_convert_opalrange(cd->range); + chain->source = *(cd->source); + chain->info = cd->info; + chain->final_cbfunc = cd->opcbfunc; + chain->final_cbdata = cd->cbdata; + chain->def = def; + opal_output_verbose(2, opal_pmix_base_framework.framework_output, + "[%s] CALLING DEFAULT EVHDLR FOR STATUS %d", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), chain->status); + def->handler(chain->status, &chain->source, + chain->info, &chain->results, + progress_local_event_hdlr, (void*)chain); + OBJ_RELEASE(cd); + return; } /* if we get here, then there are no registered event handlers */ if (NULL != cd->opcbfunc) { - cd->opcbfunc(OPAL_ERR_NOT_FOUND, cd->cbdata); + cd->opcbfunc(OPAL_ERR_NOT_FOUND, cd->cbdata); } OBJ_RELEASE(cd); return; } static int notify_event(int status, - const opal_process_name_t *source, - opal_pmix_data_range_t range, - opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata) + const opal_process_name_t *source, + opal_pmix_data_range_t range, + opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata) { /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -1065,34 +1244,34 @@ static int notify_event(int status, } /**** INSTANTIATE INTERNAL CLASSES ****/ -OBJ_CLASS_INSTANCE(opal_pmix20_jobid_trkr_t, - opal_list_item_t, - NULL, NULL); +OBJ_CLASS_INSTANCE(opal_ext20_jobid_trkr_t, + opal_list_item_t, + NULL, NULL); -OBJ_CLASS_INSTANCE(opal_pmix20_single_event_t, - opal_list_item_t, - NULL, NULL); +OBJ_CLASS_INSTANCE(opal_ext20_single_event_t, + opal_list_item_t, + NULL, NULL); -static void mtevcon(opal_pmix20_multi_event_t *p) +static void mtevcon(opal_ext20_multi_event_t *p) { p->codes = NULL; p->ncodes = 0; } -static void mtevdes(opal_pmix20_multi_event_t *p) +static void mtevdes(opal_ext20_multi_event_t *p) { if (NULL != p->codes) { - free(p->codes); + free(p->codes); } } -OBJ_CLASS_INSTANCE(opal_pmix20_multi_event_t, - opal_list_item_t, - mtevcon, mtevdes); +OBJ_CLASS_INSTANCE(opal_ext20_multi_event_t, + opal_list_item_t, + mtevcon, mtevdes); -OBJ_CLASS_INSTANCE(opal_pmix20_default_event_t, - opal_list_item_t, - NULL, NULL); +OBJ_CLASS_INSTANCE(opal_ext20_default_event_t, + opal_list_item_t, + NULL, NULL); -static void chcon(opal_pmix20_event_chain_t *p) +static void chcon(opal_ext20_event_chain_t *p) { p->nondefault = false; p->info = NULL; @@ -1103,15 +1282,15 @@ static void chcon(opal_pmix20_event_chain_t *p) p->final_cbfunc = NULL; p->final_cbdata = NULL; } -static void chdes(opal_pmix20_event_chain_t *p) +static void chdes(opal_ext20_event_chain_t *p) { OPAL_LIST_DESTRUCT(&p->results); } -OBJ_CLASS_INSTANCE(opal_pmix20_event_chain_t, - opal_list_item_t, - chcon, chdes); +OBJ_CLASS_INSTANCE(opal_ext20_event_chain_t, + opal_list_item_t, + chcon, chdes); -static void opcon(pmix20_opcaddy_t *p) +static void opcon(ext20_opcaddy_t *p) { memset(&p->p, 0, sizeof(pmix_proc_t)); p->procs = NULL; @@ -1130,26 +1309,26 @@ static void opcon(pmix20_opcaddy_t *p) p->spcbfunc = NULL; p->cbdata = NULL; } -static void opdes(pmix20_opcaddy_t *p) +static void opdes(ext20_opcaddy_t *p) { if (NULL != p->procs) { - PMIX_PROC_FREE(p->procs, p->nprocs); + PMIX_PROC_FREE(p->procs, p->nprocs); } if (NULL != p->error_procs) { - PMIX_PROC_FREE(p->error_procs, p->nerror_procs); + PMIX_PROC_FREE(p->error_procs, p->nerror_procs); } if (NULL != p->info) { - PMIX_INFO_FREE(p->info, p->sz); + PMIX_INFO_FREE(p->info, p->sz); } if (NULL != p->apps) { - PMIX_APP_FREE(p->apps, p->sz); + PMIX_APP_FREE(p->apps, p->sz); } } -OBJ_CLASS_INSTANCE(pmix20_opcaddy_t, - opal_object_t, - opcon, opdes); +OBJ_CLASS_INSTANCE(ext20_opcaddy_t, + opal_object_t, + opcon, opdes); -static void ocadcon(pmix20_opalcaddy_t *p) +static void ocadcon(ext20_opalcaddy_t *p) { OBJ_CONSTRUCT(&p->procs, opal_list_t); OBJ_CONSTRUCT(&p->info, opal_list_t); @@ -1161,23 +1340,21 @@ static void ocadcon(pmix20_opalcaddy_t *p) p->spwncbfunc = NULL; p->cbdata = NULL; p->odmdxfunc = NULL; -#if HAVE_PMIX_QUERY_FUNCTION p->infocbfunc = NULL; p->toolcbfunc = NULL; -#endif p->ocbdata = NULL; } -static void ocaddes(pmix20_opalcaddy_t *p) +static void ocaddes(ext20_opalcaddy_t *p) { OPAL_LIST_DESTRUCT(&p->procs); OPAL_LIST_DESTRUCT(&p->info); OPAL_LIST_DESTRUCT(&p->apps); } -OBJ_CLASS_INSTANCE(pmix20_opalcaddy_t, - opal_object_t, - ocadcon, ocaddes); +OBJ_CLASS_INSTANCE(ext20_opalcaddy_t, + opal_object_t, + ocadcon, ocaddes); -static void tscon(pmix20_threadshift_t *p) +static void tscon(ext20_threadshift_t *p) { p->active = false; p->source = NULL; @@ -1189,6 +1366,6 @@ static void tscon(pmix20_threadshift_t *p) p->opcbfunc = NULL; p->cbdata = NULL; } -OBJ_CLASS_INSTANCE(pmix20_threadshift_t, - opal_object_t, - tscon, NULL); +OBJ_CLASS_INSTANCE(ext20_threadshift_t, + opal_object_t, + tscon, NULL); diff --git a/opal/mca/pmix/ext20/pmix_ext20.h b/opal/mca/pmix/ext20/pmix_ext20.h index 902aef82fd..77dfb29955 100644 --- a/opal/mca/pmix/ext20/pmix_ext20.h +++ b/opal/mca/pmix/ext20/pmix_ext20.h @@ -4,7 +4,6 @@ * All rights reserved. * Copyright (c) 2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -12,8 +11,8 @@ * $HEADER$ */ -#ifndef MCA_PMIX_EXT20_H -#define MCA_PMIX_EXT20_H +#ifndef MCA_PMIX_PMIX2X_H +#define MCA_PMIX_PMIX2X_H #include "opal_config.h" @@ -31,7 +30,7 @@ #include "opal/mca/pmix/pmix.h" #include "pmix_server.h" -#include "pmix/pmix_common.h" +#include "pmix_common.h" BEGIN_C_DECLS @@ -56,16 +55,16 @@ typedef struct { opal_list_item_t super; opal_jobid_t jobid; char nspace[PMIX_MAX_NSLEN + 1]; -} opal_pmix20_jobid_trkr_t; -OBJ_CLASS_DECLARATION(opal_pmix20_jobid_trkr_t); +} opal_ext20_jobid_trkr_t; +OBJ_CLASS_DECLARATION(opal_ext20_jobid_trkr_t); typedef struct { opal_list_item_t super; size_t index; int code; opal_pmix_notification_fn_t handler; -} opal_pmix20_single_event_t; -OBJ_CLASS_DECLARATION(opal_pmix20_single_event_t); +} opal_ext20_single_event_t; +OBJ_CLASS_DECLARATION(opal_ext20_single_event_t); typedef struct { opal_list_item_t super; @@ -73,15 +72,15 @@ typedef struct { int *codes; size_t ncodes; opal_pmix_notification_fn_t handler; -} opal_pmix20_multi_event_t; -OBJ_CLASS_DECLARATION(opal_pmix20_multi_event_t); +} opal_ext20_multi_event_t; +OBJ_CLASS_DECLARATION(opal_ext20_multi_event_t); typedef struct { opal_list_item_t super; size_t index; opal_pmix_notification_fn_t handler; -} opal_pmix20_default_event_t; -OBJ_CLASS_DECLARATION(opal_pmix20_default_event_t); +} opal_ext20_default_event_t; +OBJ_CLASS_DECLARATION(opal_ext20_default_event_t); typedef struct { opal_list_item_t super; @@ -91,13 +90,13 @@ typedef struct { pmix_data_range_t range; opal_list_t *info; opal_list_t results; - opal_pmix20_single_event_t *sing; - opal_pmix20_multi_event_t *multi; - opal_pmix20_default_event_t *def; + opal_ext20_single_event_t *sing; + opal_ext20_multi_event_t *multi; + opal_ext20_default_event_t *def; opal_pmix_op_cbfunc_t final_cbfunc; void *final_cbdata; -} opal_pmix20_event_chain_t; -OBJ_CLASS_DECLARATION(opal_pmix20_event_chain_t); +} opal_ext20_event_chain_t; +OBJ_CLASS_DECLARATION(opal_ext20_event_chain_t); typedef struct { opal_object_t super; @@ -118,8 +117,8 @@ typedef struct { opal_pmix_lookup_cbfunc_t lkcbfunc; opal_pmix_spawn_cbfunc_t spcbfunc; void *cbdata; -} pmix20_opcaddy_t; -OBJ_CLASS_DECLARATION(pmix20_opcaddy_t); +} ext20_opcaddy_t; +OBJ_CLASS_DECLARATION(ext20_opcaddy_t); typedef struct { opal_object_t super; @@ -131,15 +130,13 @@ typedef struct { pmix_modex_cbfunc_t mdxcbfunc; pmix_lookup_cbfunc_t lkupcbfunc; pmix_spawn_cbfunc_t spwncbfunc; -#if HAVE_PMIX_QUERY_FUNCTION pmix_info_cbfunc_t infocbfunc; pmix_tool_connection_cbfunc_t toolcbfunc; -#endif void *cbdata; opal_pmix_release_cbfunc_t odmdxfunc; void *ocbdata; -} pmix20_opalcaddy_t; -OBJ_CLASS_DECLARATION(pmix20_opalcaddy_t); +} ext20_opalcaddy_t; +OBJ_CLASS_DECLARATION(ext20_opalcaddy_t); typedef struct { opal_object_t super; @@ -159,157 +156,167 @@ typedef struct { opal_pmix_evhandler_reg_cbfunc_t cbfunc; opal_pmix_op_cbfunc_t opcbfunc; void *cbdata; -} pmix20_threadshift_t; -OBJ_CLASS_DECLARATION(pmix20_threadshift_t); +} ext20_threadshift_t; +OBJ_CLASS_DECLARATION(ext20_threadshift_t); #define OPAL_PMIX_OPCD_THREADSHIFT(i, s, sr, if, nif, fn, cb, cd) \ do { \ - pmix20_opalcaddy_t *_cd; \ - _cd = OBJ_NEW(pmix20_opalcaddy_t); \ - _cd->id = (i); \ - _cd->status = (s); \ - _cd->source = (sr); \ - _cd->info = (i); \ - _cd->evcbfunc = (cb); \ - _cd->cbdata = (cd); \ - event_assign(&((_cd)->ev), opal_pmix_base.evbase, \ - -1, EV_WRITE, (fn), (_cd)); \ - event_active(&((_cd)->ev), EV_WRITE, 1); \ + ext20_opalcaddy_t *_cd; \ + _cd = OBJ_NEW(ext20_opalcaddy_t); \ + _cd->id = (i); \ + _cd->status = (s); \ + _cd->source = (sr); \ + _cd->info = (i); \ + _cd->evcbfunc = (cb); \ + _cd->cbdata = (cd); \ + event_assign(&((_cd)->ev), opal_pmix_base.evbase, \ + -1, EV_WRITE, (fn), (_cd)); \ + event_active(&((_cd)->ev), EV_WRITE, 1); \ } while(0) #define OPAL_PMIX_OP_THREADSHIFT(e, fn, cb, cd) \ do { \ - pmix20_threadshift_t *_cd; \ - _cd = OBJ_NEW(pmix20_threadshift_t); \ - _cd->handler = (e); \ - _cd->opcbfunc = (cb); \ - _cd->cbdata = (cd); \ - event_assign(&((_cd)->ev), opal_pmix_base.evbase, \ - -1, EV_WRITE, (fn), (_cd)); \ - event_active(&((_cd)->ev), EV_WRITE, 1); \ + ext20_threadshift_t *_cd; \ + _cd = OBJ_NEW(ext20_threadshift_t); \ + _cd->handler = (e); \ + _cd->opcbfunc = (cb); \ + _cd->cbdata = (cd); \ + event_assign(&((_cd)->ev), opal_pmix_base.evbase, \ + -1, EV_WRITE, (fn), (_cd)); \ + event_active(&((_cd)->ev), EV_WRITE, 1); \ } while(0) #define OPAL_PMIX_THREADSHIFT(e, i, eh, fn, cb, cd) \ do { \ - pmix20_threadshift_t *_cd; \ - _cd = OBJ_NEW(pmix20_threadshift_t); \ - _cd->event_codes = (e); \ - _cd->info = (i); \ - _cd->evhandler = (eh); \ - _cd->cbfunc = (cb); \ - _cd->cbdata = (cd); \ - event_assign(&((_cd)->ev), opal_pmix_base.evbase, \ - -1, EV_WRITE, (fn), (_cd)); \ - event_active(&((_cd)->ev), EV_WRITE, 1); \ + ext20_threadshift_t *_cd; \ + _cd = OBJ_NEW(ext20_threadshift_t); \ + _cd->event_codes = (e); \ + _cd->info = (i); \ + _cd->evhandler = (eh); \ + _cd->cbfunc = (cb); \ + _cd->cbdata = (cd); \ + event_assign(&((_cd)->ev), opal_pmix_base.evbase, \ + -1, EV_WRITE, (fn), (_cd)); \ + event_active(&((_cd)->ev), EV_WRITE, 1); \ } while(0) #define OPAL_PMIX_NOTIFY_THREADSHIFT(s, sr, r, i, fn, cb, cd) \ do { \ - pmix20_threadshift_t *_cd; \ - _cd = OBJ_NEW(pmix20_threadshift_t); \ - _cd->status = (s); \ - _cd->source = (sr); \ - _cd->range = (r); \ - _cd->info = (i); \ - _cd->opcbfunc = (cb); \ - _cd->cbdata = (cd); \ - event_assign(&((_cd)->ev), opal_pmix_base.evbase, \ - -1, EV_WRITE, (fn), (_cd)); \ - event_active(&((_cd)->ev), EV_WRITE, 1); \ + ext20_threadshift_t *_cd; \ + _cd = OBJ_NEW(ext20_threadshift_t); \ + _cd->status = (s); \ + _cd->source = (sr); \ + _cd->range = (r); \ + _cd->info = (i); \ + _cd->opcbfunc = (cb); \ + _cd->cbdata = (cd); \ + event_assign(&((_cd)->ev), opal_pmix_base.evbase, \ + -1, EV_WRITE, (fn), (_cd)); \ + event_active(&((_cd)->ev), EV_WRITE, 1); \ } while(0) /**** CLIENT FUNCTIONS ****/ -OPAL_MODULE_DECLSPEC int pmix20_client_init(void); -OPAL_MODULE_DECLSPEC int pmix20_client_finalize(void); -OPAL_MODULE_DECLSPEC int pmix20_initialized(void); -OPAL_MODULE_DECLSPEC int pmix20_abort(int flag, const char *msg, - opal_list_t *procs); -OPAL_MODULE_DECLSPEC int pmix20_commit(void); -OPAL_MODULE_DECLSPEC int pmix20_fence(opal_list_t *procs, int collect_data); -OPAL_MODULE_DECLSPEC int pmix20_fencenb(opal_list_t *procs, int collect_data, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_put(opal_pmix_scope_t scope, - opal_value_t *val); -OPAL_MODULE_DECLSPEC int pmix20_get(const opal_process_name_t *proc, const char *key, - opal_list_t *info, opal_value_t **val); -OPAL_MODULE_DECLSPEC int pmix20_getnb(const opal_process_name_t *proc, const char *key, - opal_list_t *info, - opal_pmix_value_cbfunc_t cbfunc, void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_publish(opal_list_t *info); -OPAL_MODULE_DECLSPEC int pmix20_publishnb(opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_lookup(opal_list_t *data, opal_list_t *info); -OPAL_MODULE_DECLSPEC int pmix20_lookupnb(char **keys, opal_list_t *info, - opal_pmix_lookup_cbfunc_t cbfunc, void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_unpublish(char **keys, opal_list_t *info); -OPAL_MODULE_DECLSPEC int pmix20_unpublishnb(char **keys, opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_spawn(opal_list_t *job_info, opal_list_t *apps, opal_jobid_t *jobid); -OPAL_MODULE_DECLSPEC int pmix20_spawnnb(opal_list_t *job_info, opal_list_t *apps, - opal_pmix_spawn_cbfunc_t cbfunc, void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_connect(opal_list_t *procs); -OPAL_MODULE_DECLSPEC int pmix20_connectnb(opal_list_t *procs, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_disconnect(opal_list_t *procs); -OPAL_MODULE_DECLSPEC int pmix20_disconnectnb(opal_list_t *procs, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_resolve_peers(const char *nodename, opal_jobid_t jobid, - opal_list_t *procs); -OPAL_MODULE_DECLSPEC int pmix20_resolve_nodes(opal_jobid_t jobid, char **nodelist); +OPAL_MODULE_DECLSPEC int ext20_client_init(void); +OPAL_MODULE_DECLSPEC int ext20_client_finalize(void); +OPAL_MODULE_DECLSPEC int ext20_initialized(void); +OPAL_MODULE_DECLSPEC int ext20_abort(int flag, const char *msg, + opal_list_t *procs); +OPAL_MODULE_DECLSPEC int ext20_commit(void); +OPAL_MODULE_DECLSPEC int ext20_fence(opal_list_t *procs, int collect_data); +OPAL_MODULE_DECLSPEC int ext20_fencenb(opal_list_t *procs, int collect_data, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_put(opal_pmix_scope_t scope, + opal_value_t *val); +OPAL_MODULE_DECLSPEC int ext20_get(const opal_process_name_t *proc, const char *key, + opal_list_t *info, opal_value_t **val); +OPAL_MODULE_DECLSPEC int ext20_getnb(const opal_process_name_t *proc, const char *key, + opal_list_t *info, + opal_pmix_value_cbfunc_t cbfunc, void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_publish(opal_list_t *info); +OPAL_MODULE_DECLSPEC int ext20_publishnb(opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_lookup(opal_list_t *data, opal_list_t *info); +OPAL_MODULE_DECLSPEC int ext20_lookupnb(char **keys, opal_list_t *info, + opal_pmix_lookup_cbfunc_t cbfunc, void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_unpublish(char **keys, opal_list_t *info); +OPAL_MODULE_DECLSPEC int ext20_unpublishnb(char **keys, opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_spawn(opal_list_t *job_info, opal_list_t *apps, opal_jobid_t *jobid); +OPAL_MODULE_DECLSPEC int ext20_spawnnb(opal_list_t *job_info, opal_list_t *apps, + opal_pmix_spawn_cbfunc_t cbfunc, void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_connect(opal_list_t *procs); +OPAL_MODULE_DECLSPEC int ext20_connectnb(opal_list_t *procs, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_disconnect(opal_list_t *procs); +OPAL_MODULE_DECLSPEC int ext20_disconnectnb(opal_list_t *procs, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_resolve_peers(const char *nodename, opal_jobid_t jobid, + opal_list_t *procs); +OPAL_MODULE_DECLSPEC int ext20_resolve_nodes(opal_jobid_t jobid, char **nodelist); /**** COMMON FUNCTIONS ****/ -OPAL_MODULE_DECLSPEC int pmix20_store_local(const opal_process_name_t *proc, - opal_value_t *val); +OPAL_MODULE_DECLSPEC int ext20_store_local(const opal_process_name_t *proc, + opal_value_t *val); /**** SERVER SOUTHBOUND FUNCTIONS ****/ -OPAL_MODULE_DECLSPEC int pmix20_server_init(opal_pmix_server_module_t *module, - opal_list_t *info); -OPAL_MODULE_DECLSPEC int pmix20_server_finalize(void); -OPAL_MODULE_DECLSPEC int pmix20_server_gen_regex(const char *input, char **regex); -OPAL_MODULE_DECLSPEC int pmix20_server_gen_ppn(const char *input, char **ppn); -OPAL_MODULE_DECLSPEC int pmix20_server_register_nspace(opal_jobid_t jobid, - int nlocalprocs, - opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata); -OPAL_MODULE_DECLSPEC void pmix20_server_deregister_nspace(opal_jobid_t jobid, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_server_register_client(const opal_process_name_t *proc, - uid_t uid, gid_t gid, - void *server_object, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata); -OPAL_MODULE_DECLSPEC void pmix20_server_deregister_client(const opal_process_name_t *proc, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_server_setup_fork(const opal_process_name_t *proc, char ***env); -OPAL_MODULE_DECLSPEC int pmix20_server_dmodex(const opal_process_name_t *proc, - opal_pmix_modex_cbfunc_t cbfunc, void *cbdata); -OPAL_MODULE_DECLSPEC int pmix20_server_notify_event(int status, - const opal_process_name_t *source, - opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_server_init(opal_pmix_server_module_t *module, + opal_list_t *info); +OPAL_MODULE_DECLSPEC int ext20_server_finalize(void); +OPAL_MODULE_DECLSPEC int ext20_server_gen_regex(const char *input, char **regex); +OPAL_MODULE_DECLSPEC int ext20_server_gen_ppn(const char *input, char **ppn); +OPAL_MODULE_DECLSPEC int ext20_server_register_nspace(opal_jobid_t jobid, + int nlocalprocs, + opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata); +OPAL_MODULE_DECLSPEC void ext20_server_deregister_nspace(opal_jobid_t jobid, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_server_register_client(const opal_process_name_t *proc, + uid_t uid, gid_t gid, + void *server_object, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata); +OPAL_MODULE_DECLSPEC void ext20_server_deregister_client(const opal_process_name_t *proc, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_server_setup_fork(const opal_process_name_t *proc, char ***env); +OPAL_MODULE_DECLSPEC int ext20_server_dmodex(const opal_process_name_t *proc, + opal_pmix_modex_cbfunc_t cbfunc, void *cbdata); +OPAL_MODULE_DECLSPEC int ext20_server_notify_event(int status, + const opal_process_name_t *source, + opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata); /**** COMPONENT UTILITY FUNCTIONS ****/ -OPAL_MODULE_DECLSPEC void pmix20_event_hdlr(size_t evhdlr_registration_id, - pmix_status_t status, const pmix_proc_t *source, - pmix_info_t info[], size_t ninfo, - pmix_info_t results[], size_t nresults, - pmix_event_notification_cbfunc_fn_t cbfunc, - void *cbdata); -OPAL_MODULE_DECLSPEC pmix_status_t pmix20_convert_opalrc(int rc); -OPAL_MODULE_DECLSPEC int pmix20_convert_rc(pmix_status_t rc); -OPAL_MODULE_DECLSPEC pmix_scope_t pmix20_convert_opalscope(opal_pmix_scope_t scope); -OPAL_MODULE_DECLSPEC pmix_data_range_t pmix20_convert_opalrange(opal_pmix_data_range_t range); -OPAL_MODULE_DECLSPEC opal_pmix_data_range_t pmix20_convert_range(pmix_data_range_t range); -OPAL_MODULE_DECLSPEC void pmix20_value_load(pmix_value_t *v, - opal_value_t *kv); -OPAL_MODULE_DECLSPEC int pmix20_value_unload(opal_value_t *kv, - const pmix_value_t *v); +OPAL_MODULE_DECLSPEC void ext20_event_hdlr(size_t evhdlr_registration_id, + pmix_status_t status, const pmix_proc_t *source, + pmix_info_t info[], size_t ninfo, + pmix_info_t results[], size_t nresults, + pmix_event_notification_cbfunc_fn_t cbfunc, + void *cbdata); +OPAL_MODULE_DECLSPEC pmix_status_t ext20_convert_opalrc(int rc); +OPAL_MODULE_DECLSPEC int ext20_convert_rc(pmix_status_t rc); + +OPAL_MODULE_DECLSPEC opal_vpid_t ext20_convert_rank(int rank); +OPAL_MODULE_DECLSPEC pmix_rank_t ext20_convert_opalrank(opal_vpid_t vpid); + +OPAL_MODULE_DECLSPEC opal_pmix_scope_t ext20_convert_scope(pmix_scope_t scope); +OPAL_MODULE_DECLSPEC pmix_scope_t ext20_convert_opalscope(opal_pmix_scope_t scope); + +OPAL_MODULE_DECLSPEC pmix_data_range_t ext20_convert_opalrange(opal_pmix_data_range_t range); +OPAL_MODULE_DECLSPEC opal_pmix_data_range_t ext20_convert_range(pmix_data_range_t range); + +OPAL_MODULE_DECLSPEC opal_pmix_persistence_t ext20_convert_persist(pmix_persistence_t scope); +OPAL_MODULE_DECLSPEC pmix_persistence_t ext20_convert_opalpersist(opal_pmix_persistence_t scope); + +OPAL_MODULE_DECLSPEC void ext20_value_load(pmix_value_t *v, + opal_value_t *kv); +OPAL_MODULE_DECLSPEC int ext20_value_unload(opal_value_t *kv, + const pmix_value_t *v); END_C_DECLS diff --git a/opal/mca/pmix/ext20/pmix_ext20_client.c b/opal/mca/pmix/ext20/pmix_ext20_client.c index 999bd854bd..c2f9d2e8c2 100644 --- a/opal/mca/pmix/ext20/pmix_ext20_client.c +++ b/opal/mca/pmix/ext20/pmix_ext20_client.c @@ -6,6 +6,8 @@ * Copyright (c) 2014-2015 Mellanox Technologies, Inc. * All rights reserved. * Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. All rights + * reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -54,12 +56,12 @@ static void errreg_cbfunc (pmix_status_t status, status, (unsigned long)errhandler_ref); } -int pmix20_client_init(void) +int ext20_client_init(void) { opal_process_name_t pname; pmix_status_t rc; int dbg; - opal_pmix20_jobid_trkr_t *job; + opal_ext20_jobid_trkr_t *job; opal_output_verbose(1, opal_pmix_base_framework.framework_output, "PMIx_client init"); @@ -71,7 +73,7 @@ int pmix20_client_init(void) rc = PMIx_Init(&my_proc, NULL, 0); if (PMIX_SUCCESS != rc) { - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } /* store our jobid and rank */ @@ -87,21 +89,21 @@ int pmix20_client_init(void) } /* insert this into our list of jobids - it will be the * first, and so we'll check it first */ - job = OBJ_NEW(opal_pmix20_jobid_trkr_t); + job = OBJ_NEW(opal_ext20_jobid_trkr_t); (void)strncpy(job->nspace, my_proc.nspace, PMIX_MAX_NSLEN); job->jobid = pname.jobid; opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); - pname.vpid = my_proc.rank; + pname.vpid = ext20_convert_rank(my_proc.rank); opal_proc_set_name(&pname); /* register the default event handler */ - PMIx_Register_event_handler(NULL, 0, NULL, 0, pmix20_event_hdlr, errreg_cbfunc, NULL); + PMIx_Register_event_handler(NULL, 0, NULL, 0, ext20_event_hdlr, errreg_cbfunc, NULL); return OPAL_SUCCESS; } -int pmix20_client_finalize(void) +int ext20_client_finalize(void) { pmix_status_t rc; @@ -112,10 +114,10 @@ int pmix20_client_finalize(void) PMIx_Deregister_event_handler(errhdler_ref, NULL, NULL); rc = PMIx_Finalize(NULL, 0); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_initialized(void) +int ext20_initialized(void) { opal_output_verbose(1, opal_pmix_base_framework.framework_output, "PMIx_client initialized"); @@ -123,14 +125,14 @@ int pmix20_initialized(void) return PMIx_Initialized(); } -int pmix20_abort(int flag, const char *msg, +int ext20_abort(int flag, const char *msg, opal_list_t *procs) { pmix_status_t rc; pmix_proc_t *parray=NULL; size_t n, cnt=0; opal_namelist_t *ptr; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; opal_output_verbose(1, opal_pmix_base_framework.framework_output, "PMIx_client abort"); @@ -144,17 +146,18 @@ int pmix20_abort(int flag, const char *msg, /* look thru our list of jobids and find the * corresponding nspace */ job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (jptr->jobid == ptr->name.jobid) { job = jptr; break; } } if (NULL == job) { + PMIX_PROC_FREE(parray, cnt); return OPAL_ERR_NOT_FOUND; } (void)strncpy(parray[n].nspace, job->nspace, PMIX_MAX_NSLEN); - parray[n].rank = ptr->name.vpid; + parray[n].rank = ext20_convert_opalrank(ptr->name.vpid); ++n; } } @@ -165,15 +168,15 @@ int pmix20_abort(int flag, const char *msg, /* release the array */ PMIX_PROC_FREE(parray, cnt); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_store_local(const opal_process_name_t *proc, opal_value_t *val) +int ext20_store_local(const opal_process_name_t *proc, opal_value_t *val) { pmix_value_t kv; pmix_status_t rc; pmix_proc_t p; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -182,7 +185,7 @@ int pmix20_store_local(const opal_process_name_t *proc, opal_value_t *val) /* look thru our list of jobids and find the * corresponding nspace */ job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (jptr->jobid == proc->jobid) { job = jptr; break; @@ -193,48 +196,48 @@ int pmix20_store_local(const opal_process_name_t *proc, opal_value_t *val) return OPAL_ERR_NOT_FOUND; } (void)strncpy(p.nspace, job->nspace, PMIX_MAX_NSLEN); - p.rank = proc->vpid; + p.rank = ext20_convert_opalrank(proc->vpid); } else { /* use our name */ (void)strncpy(p.nspace, my_proc.nspace, PMIX_MAX_NSLEN); - p.rank = OPAL_PROC_MY_NAME.vpid; + p.rank = ext20_convert_opalrank(OPAL_PROC_MY_NAME.vpid); } PMIX_VALUE_CONSTRUCT(&kv); - pmix20_value_load(&kv, val); + ext20_value_load(&kv, val); rc = PMIx_Store_internal(&p, val->key, &kv); PMIX_VALUE_DESTRUCT(&kv); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_commit(void) +int ext20_commit(void) { pmix_status_t rc; rc = PMIx_Commit(); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } static void opcbfunc(pmix_status_t status, void *cbdata) { - pmix20_opcaddy_t *op = (pmix20_opcaddy_t*)cbdata; + ext20_opcaddy_t *op = (ext20_opcaddy_t*)cbdata; if (NULL != op->opcbfunc) { - op->opcbfunc(pmix20_convert_rc(status), op->cbdata); + op->opcbfunc(ext20_convert_rc(status), op->cbdata); } OBJ_RELEASE(op); } -int pmix20_fence(opal_list_t *procs, int collect_data) +int ext20_fence(opal_list_t *procs, int collect_data) { pmix_status_t rc; pmix_proc_t *parray=NULL; size_t n, cnt=0; opal_namelist_t *ptr; pmix_info_t info, *iptr; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; opal_output_verbose(1, opal_pmix_base_framework.framework_output, "PMIx_client fence"); @@ -248,7 +251,7 @@ int pmix20_fence(opal_list_t *procs, int collect_data) /* look thru our list of jobids and find the * corresponding nspace */ job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (jptr->jobid == ptr->name.jobid) { job = jptr; break; @@ -258,7 +261,7 @@ int pmix20_fence(opal_list_t *procs, int collect_data) return OPAL_ERR_NOT_FOUND; } (void)strncpy(parray[n].nspace, job->nspace, PMIX_MAX_NSLEN); - parray[n].rank = ptr->name.vpid; + parray[n].rank = ext20_convert_opalrank(ptr->name.vpid); ++n; } } @@ -283,20 +286,20 @@ int pmix20_fence(opal_list_t *procs, int collect_data) PMIX_INFO_DESTRUCT(&info); } - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_fencenb(opal_list_t *procs, int collect_data, +int ext20_fencenb(opal_list_t *procs, int collect_data, opal_pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_status_t rc; pmix_proc_t *parray=NULL; size_t n, cnt=0; opal_namelist_t *ptr; - pmix20_opcaddy_t *op; + ext20_opcaddy_t *op; pmix_info_t info, *iptr; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -313,17 +316,18 @@ int pmix20_fencenb(opal_list_t *procs, int collect_data, /* look thru our list of jobids and find the * corresponding nspace */ job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (jptr->jobid == ptr->name.jobid) { job = jptr; break; } } if (NULL == job) { + PMIX_PROC_FREE(parray, cnt); return OPAL_ERR_NOT_FOUND; } (void)strncpy(parray[n].nspace, job->nspace, PMIX_MAX_NSLEN); - parray[n].rank = ptr->name.vpid; + parray[n].rank = ext20_convert_opalrank(ptr->name.vpid); ++n; } } @@ -341,7 +345,7 @@ int pmix20_fencenb(opal_list_t *procs, int collect_data, } /* create the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->opcbfunc = cbfunc; op->cbdata = cbdata; op->procs = parray; @@ -353,30 +357,30 @@ int pmix20_fencenb(opal_list_t *procs, int collect_data, OBJ_RELEASE(op); } - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_put(opal_pmix_scope_t opal_scope, +int ext20_put(opal_pmix_scope_t opal_scope, opal_value_t *val) { pmix_value_t kv; - pmix_scope_t pmix_scope = pmix20_convert_opalscope(opal_scope); + pmix_scope_t pmix_scope = ext20_convert_opalscope(opal_scope); pmix_status_t rc; opal_output_verbose(1, opal_pmix_base_framework.framework_output, "PMIx_client put"); PMIX_VALUE_CONSTRUCT(&kv); - pmix20_value_load(&kv, val); + ext20_value_load(&kv, val); rc = PMIx_Put(pmix_scope, val->key, &kv); PMIX_VALUE_DESTRUCT(&kv); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_get(const opal_process_name_t *proc, const char *key, - opal_list_t *info, opal_value_t **val) +int ext20_get(const opal_process_name_t *proc, const char *key, + opal_list_t *info, opal_value_t **val) { int ret; pmix_value_t *kv; @@ -385,165 +389,167 @@ int pmix20_get(const opal_process_name_t *proc, const char *key, size_t ninfo, n; pmix_info_t *pinfo; opal_value_t *ival; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; opal_output_verbose(1, opal_pmix_base_framework.framework_output, - "%s PMIx_client get on proc %s key %s", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), - (NULL == proc) ? "NULL" : OPAL_NAME_PRINT(*proc), key); + "%s PMIx_client get on proc %s key %s", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), + (NULL == proc) ? "NULL" : OPAL_NAME_PRINT(*proc), key); /* prep default response */ *val = NULL; if (NULL != proc) { - /* look thru our list of jobids and find the - * corresponding nspace */ - job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { - if (jptr->jobid == proc->jobid) { - job = jptr; - break; - } - } - if (NULL == job) { - return OPAL_ERR_NOT_FOUND; - } - (void)strncpy(p.nspace, job->nspace, PMIX_MAX_NSLEN); - p.rank = proc->vpid; - pptr = &p; + /* look thru our list of jobids and find the + * corresponding nspace */ + job = NULL; + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { + if (jptr->jobid == proc->jobid) { + job = jptr; + break; + } + } + if (NULL == job) { + return OPAL_ERR_NOT_FOUND; + } + (void)strncpy(p.nspace, job->nspace, PMIX_MAX_NSLEN); + p.rank = ext20_convert_opalrank(proc->vpid); + pptr = &p; } else { - /* if they are asking for our jobid, then return it */ - if (0 == strcmp(key, OPAL_PMIX_JOBID)) { - (*val) = OBJ_NEW(opal_value_t); - (*val)->type = OPAL_UINT32; - (*val)->data.uint32 = OPAL_PROC_MY_NAME.jobid; - return OPAL_SUCCESS; - } else if (0 == strcmp(key, OPAL_PMIX_RANK)) { - (*val) = OBJ_NEW(opal_value_t); - (*val)->type = OPAL_INT; - (*val)->data.integer = my_proc.rank; - return OPAL_SUCCESS; - } - pptr = NULL; + /* if they are asking for our jobid, then return it */ + if (0 == strcmp(key, OPAL_PMIX_JOBID)) { + (*val) = OBJ_NEW(opal_value_t); + (*val)->type = OPAL_UINT32; + (*val)->data.uint32 = OPAL_PROC_MY_NAME.jobid; + return OPAL_SUCCESS; + } else if (0 == strcmp(key, OPAL_PMIX_RANK)) { + (*val) = OBJ_NEW(opal_value_t); + (*val)->type = OPAL_INT; + (*val)->data.integer = ext20_convert_rank(my_proc.rank); + return OPAL_SUCCESS; + } + pptr = NULL; } if (NULL != info) { - ninfo = opal_list_get_size(info); - if (0 < ninfo) { - PMIX_INFO_CREATE(pinfo, ninfo); - n=0; - OPAL_LIST_FOREACH(ival, info, opal_value_t) { - (void)strncpy(pinfo[n].key, ival->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pinfo[n].value, ival); - } - } else { - pinfo = NULL; - } + ninfo = opal_list_get_size(info); + if (0 < ninfo) { + PMIX_INFO_CREATE(pinfo, ninfo); + n=0; + OPAL_LIST_FOREACH(ival, info, opal_value_t) { + (void)strncpy(pinfo[n].key, ival->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pinfo[n].value, ival); + ++n; + } + } else { + pinfo = NULL; + } } else { - pinfo = NULL; - ninfo = 0; + pinfo = NULL; + ninfo = 0; } /* pass the request down */ rc = PMIx_Get(pptr, key, pinfo, ninfo, &kv); if (PMIX_SUCCESS == rc) { - if (NULL == kv) { - ret = OPAL_SUCCESS; - } else { - *val = OBJ_NEW(opal_value_t); - ret = pmix20_value_unload(*val, kv); - PMIX_VALUE_FREE(kv, 1); - } + if (NULL == kv) { + ret = OPAL_SUCCESS; + } else { + *val = OBJ_NEW(opal_value_t); + ret = ext20_value_unload(*val, kv); + PMIX_VALUE_FREE(kv, 1); + } } else { - ret = pmix20_convert_rc(rc); + ret = ext20_convert_rc(rc); } PMIX_INFO_FREE(pinfo, ninfo); return ret; } static void val_cbfunc(pmix_status_t status, - pmix_value_t *kv, void *cbdata) + pmix_value_t *kv, void *cbdata) { - pmix20_opcaddy_t *op = (pmix20_opcaddy_t*)cbdata; + ext20_opcaddy_t *op = (ext20_opcaddy_t*)cbdata; int rc; opal_value_t val, *v=NULL; - rc = pmix20_convert_opalrc(status); + rc = ext20_convert_opalrc(status); if (PMIX_SUCCESS == status && NULL != kv) { - rc = pmix20_value_unload(&val, kv); - v = &val; + rc = ext20_value_unload(&val, kv); + v = &val; } if (NULL != op->valcbfunc) { - op->valcbfunc(rc, v, op->cbdata); + op->valcbfunc(rc, v, op->cbdata); } OBJ_RELEASE(op); } -int pmix20_getnb(const opal_process_name_t *proc, const char *key, - opal_list_t *info, - opal_pmix_value_cbfunc_t cbfunc, void *cbdata) +int ext20_getnb(const opal_process_name_t *proc, const char *key, + opal_list_t *info, + opal_pmix_value_cbfunc_t cbfunc, void *cbdata) { - pmix20_opcaddy_t *op; + ext20_opcaddy_t *op; pmix_status_t rc; size_t n; opal_value_t *ival; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; /* we must threadshift this request as we might not be in an event * and we are going to access shared lists/objects */ opal_output_verbose(1, opal_pmix_base_framework.framework_output, - "%s PMIx_client get_nb on proc %s key %s", - OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), - (NULL == proc) ? "NULL" : OPAL_NAME_PRINT(*proc), key); + "%s PMIx_client get_nb on proc %s key %s", + OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), + (NULL == proc) ? "NULL" : OPAL_NAME_PRINT(*proc), key); /* create the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->valcbfunc = cbfunc; op->cbdata = cbdata; if (NULL != proc) { - /* look thru our list of jobids and find the - * corresponding nspace */ - job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { - if (jptr->jobid == proc->jobid) { - job = jptr; - break; - } - } - if (NULL == job) { - return OPAL_ERR_NOT_FOUND; - } - (void)strncpy(op->p.nspace, job->nspace, PMIX_MAX_NSLEN); - op->p.rank = proc->vpid; + /* look thru our list of jobids and find the + * corresponding nspace */ + job = NULL; + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { + if (jptr->jobid == proc->jobid) { + job = jptr; + break; + } + } + if (NULL == job) { + return OPAL_ERR_NOT_FOUND; + } + (void)strncpy(op->p.nspace, job->nspace, PMIX_MAX_NSLEN); + op->p.rank = ext20_convert_opalrank(proc->vpid); } else { - (void)strncpy(op->p.nspace, my_proc.nspace, PMIX_MAX_NSLEN); - op->p.rank = PMIX_RANK_WILDCARD; + (void)strncpy(op->p.nspace, my_proc.nspace, PMIX_MAX_NSLEN); + op->p.rank = ext20_convert_rank(PMIX_RANK_WILDCARD); } if (NULL != info) { - op->sz = opal_list_get_size(info); - if (0 < op->sz) { - PMIX_INFO_CREATE(op->info, op->sz); - n=0; - OPAL_LIST_FOREACH(ival, info, opal_value_t) { - (void)strncpy(op->info[n].key, ival->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&op->info[n].value, ival); - } - } + op->sz = opal_list_get_size(info); + if (0 < op->sz) { + PMIX_INFO_CREATE(op->info, op->sz); + n=0; + OPAL_LIST_FOREACH(ival, info, opal_value_t) { + (void)strncpy(op->info[n].key, ival->key, PMIX_MAX_KEYLEN); + ext20_value_load(&op->info[n].value, ival); + ++n; + } + } } /* call the library function */ rc = PMIx_Get_nb(&op->p, key, op->info, op->sz, val_cbfunc, op); if (PMIX_SUCCESS != rc) { - OBJ_RELEASE(op); + OBJ_RELEASE(op); } - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_publish(opal_list_t *info) +int ext20_publish(opal_list_t *info) { pmix_info_t *pinfo; pmix_status_t ret; @@ -551,67 +557,67 @@ int pmix20_publish(opal_list_t *info) size_t sz, n; opal_output_verbose(1, opal_pmix_base_framework.framework_output, - "PMIx_client publish"); + "PMIx_client publish"); if (NULL == info) { - return OPAL_ERR_BAD_PARAM; + return OPAL_ERR_BAD_PARAM; } sz = opal_list_get_size(info); if (0 < sz) { - PMIX_INFO_CREATE(pinfo, sz); - n=0; - OPAL_LIST_FOREACH(iptr, info, opal_value_t) { - (void)strncpy(pinfo[n].key, iptr->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pinfo[n].value, iptr); - ++n; - } + PMIX_INFO_CREATE(pinfo, sz); + n=0; + OPAL_LIST_FOREACH(iptr, info, opal_value_t) { + (void)strncpy(pinfo[n].key, iptr->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pinfo[n].value, iptr); + ++n; + } } else { - pinfo = NULL; + pinfo = NULL; } ret = PMIx_Publish(pinfo, sz); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_publishnb(opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata) +int ext20_publishnb(opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_status_t ret; opal_value_t *iptr; size_t n; - pmix20_opcaddy_t *op; + ext20_opcaddy_t *op; opal_output_verbose(1, opal_pmix_base_framework.framework_output, - "PMIx_client publish_nb"); + "PMIx_client publish_nb"); if (NULL == info) { - return OPAL_ERR_BAD_PARAM; + return OPAL_ERR_BAD_PARAM; } /* create the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->opcbfunc = cbfunc; op->cbdata = cbdata; op->sz = opal_list_get_size(info); if (0 < op->sz) { - PMIX_INFO_CREATE(op->info, op->sz); - n=0; - OPAL_LIST_FOREACH(iptr, info, opal_value_t) { - (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&op->info[n].value, iptr); - ++n; - } + PMIX_INFO_CREATE(op->info, op->sz); + n=0; + OPAL_LIST_FOREACH(iptr, info, opal_value_t) { + (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN); + ext20_value_load(&op->info[n].value, iptr); + ++n; + } } ret = PMIx_Publish_nb(op->info, op->sz, opcbfunc, op); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_lookup(opal_list_t *data, opal_list_t *info) +int ext20_lookup(opal_list_t *data, opal_list_t *info) { pmix_pdata_t *pdata; pmix_info_t *pinfo; @@ -620,196 +626,188 @@ int pmix20_lookup(opal_list_t *data, opal_list_t *info) pmix_status_t ret; opal_pmix_pdata_t *d; opal_value_t *iptr; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; /* we must threadshift this request as we might not be in an event * and we are going to access shared lists/objects */ opal_output_verbose(1, opal_pmix_base_framework.framework_output, - "PMIx_client lookup"); + "PMIx_client lookup"); if (NULL == data) { - return OPAL_ERR_BAD_PARAM; + return OPAL_ERR_BAD_PARAM; } sz = opal_list_get_size(data); PMIX_PDATA_CREATE(pdata, sz); n=0; OPAL_LIST_FOREACH(d, data, opal_pmix_pdata_t) { - (void)strncpy(pdata[n++].key, d->value.key, PMIX_MAX_KEYLEN); + (void)strncpy(pdata[n++].key, d->value.key, PMIX_MAX_KEYLEN); } if (NULL != info) { - ninfo = opal_list_get_size(info); - PMIX_INFO_CREATE(pinfo, ninfo); - n=0; - OPAL_LIST_FOREACH(iptr, info, opal_value_t) { - (void)strncpy(pinfo[n++].key, iptr->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pinfo[n].value, iptr); - ++n; - } + ninfo = opal_list_get_size(info); + PMIX_INFO_CREATE(pinfo, ninfo); + n=0; + OPAL_LIST_FOREACH(iptr, info, opal_value_t) { + (void)strncpy(pinfo[n].key, iptr->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pinfo[n].value, iptr); + ++n; + } } else { - pinfo = NULL; - ninfo = 0; + pinfo = NULL; + ninfo = 0; } ret = PMIx_Lookup(pdata, sz, pinfo, ninfo); PMIX_INFO_FREE(pinfo, ninfo); if (PMIX_SUCCESS == ret) { - /* transfer the data back */ - n=0; - OPAL_LIST_FOREACH(d, data, opal_pmix_pdata_t) { - if (mca_pmix_ext20_component.native_launch) { - /* if we were launched by the OMPI RTE, then - * the jobid is in a special format - so get it */ - opal_convert_string_to_jobid(&d->proc.jobid, pdata[n].proc.nspace); - } else { - /* we were launched by someone else, so make the - * jobid just be the hash of the nspace */ - OPAL_HASH_STR(pdata[n].proc.nspace, d->proc.jobid); - } - /* if we don't already have it, add this to our jobid tracker */ - job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { - if (jptr->jobid == d->proc.jobid) { - job = jptr; - break; - } - } - if (NULL == job) { - job = OBJ_NEW(opal_pmix20_jobid_trkr_t); - (void)strncpy(job->nspace, pdata[n].proc.nspace, PMIX_MAX_NSLEN); - job->jobid = d->proc.jobid; - opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); - } - if (PMIX_RANK_WILDCARD == pdata[n].proc.rank) { - d->proc.vpid = OPAL_VPID_WILDCARD; - } else { - d->proc.vpid = pdata[n].proc.rank; - } - rc = pmix20_value_unload(&d->value, &pdata[n].value); - if (OPAL_SUCCESS != rc) { - OPAL_ERROR_LOG(rc); - PMIX_PDATA_FREE(pdata, sz); - return OPAL_ERR_BAD_PARAM; - } - ++n; - } + /* transfer the data back */ + n=0; + OPAL_LIST_FOREACH(d, data, opal_pmix_pdata_t) { + if (mca_pmix_ext20_component.native_launch) { + /* if we were launched by the OMPI RTE, then + * the jobid is in a special format - so get it */ + opal_convert_string_to_jobid(&d->proc.jobid, pdata[n].proc.nspace); + } else { + /* we were launched by someone else, so make the + * jobid just be the hash of the nspace */ + OPAL_HASH_STR(pdata[n].proc.nspace, d->proc.jobid); + } + /* if we don't already have it, add this to our jobid tracker */ + job = NULL; + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { + if (jptr->jobid == d->proc.jobid) { + job = jptr; + break; + } + } + if (NULL == job) { + job = OBJ_NEW(opal_ext20_jobid_trkr_t); + (void)strncpy(job->nspace, pdata[n].proc.nspace, PMIX_MAX_NSLEN); + job->jobid = d->proc.jobid; + opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); + } + d->proc.vpid = ext20_convert_rank(pdata[n].proc.rank); + rc = ext20_value_unload(&d->value, &pdata[n].value); + if (OPAL_SUCCESS != rc) { + OPAL_ERROR_LOG(rc); + PMIX_PDATA_FREE(pdata, sz); + return OPAL_ERR_BAD_PARAM; + } + ++n; + } } - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } static void lk_cbfunc(pmix_status_t status, - pmix_pdata_t data[], size_t ndata, - void *cbdata) + pmix_pdata_t data[], size_t ndata, + void *cbdata) { - pmix20_opcaddy_t *op = (pmix20_opcaddy_t*)cbdata; + ext20_opcaddy_t *op = (ext20_opcaddy_t*)cbdata; opal_pmix_pdata_t *d; opal_list_t results, *r = NULL; int rc; size_t n; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; /* this is in the PMIx local thread - need to threadshift to * our own thread as we will be accessing framework-global * lists and objects */ if (NULL == op->lkcbfunc) { - OBJ_RELEASE(op); - return; + OBJ_RELEASE(op); + return; } - rc = pmix20_convert_rc(status); + rc = ext20_convert_rc(status); if (OPAL_SUCCESS == rc) { - OBJ_CONSTRUCT(&results, opal_list_t); - for (n=0; n < ndata; n++) { - d = OBJ_NEW(opal_pmix_pdata_t); - opal_list_append(&results, &d->super); - if (mca_pmix_ext20_component.native_launch) { - /* if we were launched by the OMPI RTE, then - * the jobid is in a special format - so get it */ - opal_convert_string_to_jobid(&d->proc.jobid, data[n].proc.nspace); - } else { - /* we were launched by someone else, so make the - * jobid just be the hash of the nspace */ - OPAL_HASH_STR(data[n].proc.nspace, d->proc.jobid); - } - /* if we don't already have it, add this to our jobid tracker */ - job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { - if (jptr->jobid == d->proc.jobid) { - job = jptr; - break; - } - } - if (NULL == job) { - job = OBJ_NEW(opal_pmix20_jobid_trkr_t); - (void)strncpy(job->nspace, data[n].proc.nspace, PMIX_MAX_NSLEN); - job->jobid = d->proc.jobid; - opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); - } - if (PMIX_RANK_WILDCARD == data[n].proc.rank) { - d->proc.vpid = OPAL_VPID_WILDCARD; - } else { - d->proc.vpid = data[n].proc.rank; - } - d->value.key = strdup(data[n].key); - rc = pmix20_value_unload(&d->value, &data[n].value); - if (OPAL_SUCCESS != rc) { - rc = OPAL_ERR_BAD_PARAM; - OPAL_ERROR_LOG(rc); - goto release; - } - } - r = &results; + OBJ_CONSTRUCT(&results, opal_list_t); + for (n=0; n < ndata; n++) { + d = OBJ_NEW(opal_pmix_pdata_t); + opal_list_append(&results, &d->super); + if (mca_pmix_ext20_component.native_launch) { + /* if we were launched by the OMPI RTE, then + * the jobid is in a special format - so get it */ + opal_convert_string_to_jobid(&d->proc.jobid, data[n].proc.nspace); + } else { + /* we were launched by someone else, so make the + * jobid just be the hash of the nspace */ + OPAL_HASH_STR(data[n].proc.nspace, d->proc.jobid); + } + /* if we don't already have it, add this to our jobid tracker */ + job = NULL; + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { + if (jptr->jobid == d->proc.jobid) { + job = jptr; + break; + } + } + if (NULL == job) { + job = OBJ_NEW(opal_ext20_jobid_trkr_t); + (void)strncpy(job->nspace, data[n].proc.nspace, PMIX_MAX_NSLEN); + job->jobid = d->proc.jobid; + opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); + } + d->proc.vpid = ext20_convert_rank(data[n].proc.rank); + d->value.key = strdup(data[n].key); + rc = ext20_value_unload(&d->value, &data[n].value); + if (OPAL_SUCCESS != rc) { + rc = OPAL_ERR_BAD_PARAM; + OPAL_ERROR_LOG(rc); + goto release; + } + } + r = &results; } release: /* execute the callback */ op->lkcbfunc(rc, r, op->cbdata); if (NULL != r) { - OPAL_LIST_DESTRUCT(&results); + OPAL_LIST_DESTRUCT(&results); } OBJ_RELEASE(op); } -int pmix20_lookupnb(char **keys, opal_list_t *info, - opal_pmix_lookup_cbfunc_t cbfunc, void *cbdata) +int ext20_lookupnb(char **keys, opal_list_t *info, + opal_pmix_lookup_cbfunc_t cbfunc, void *cbdata) { pmix_status_t ret; - pmix20_opcaddy_t *op; + ext20_opcaddy_t *op; opal_value_t *iptr; size_t n; opal_output_verbose(1, opal_pmix_base_framework.framework_output, - "PMIx_client lookup_nb"); + "PMIx_client lookup_nb"); /* create the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->lkcbfunc = cbfunc; op->cbdata = cbdata; if (NULL != info) { - op->sz = opal_list_get_size(info); - if (0 < op->sz) { - PMIX_INFO_CREATE(op->info, op->sz); - n=0; - OPAL_LIST_FOREACH(iptr, info, opal_value_t) { - (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&op->info[n].value, iptr); - ++n; - } - } + op->sz = opal_list_get_size(info); + if (0 < op->sz) { + PMIX_INFO_CREATE(op->info, op->sz); + n=0; + OPAL_LIST_FOREACH(iptr, info, opal_value_t) { + (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN); + ext20_value_load(&op->info[n].value, iptr); + ++n; + } + } } ret = PMIx_Lookup_nb(keys, op->info, op->sz, lk_cbfunc, op); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_unpublish(char **keys, opal_list_t *info) +int ext20_unpublish(char **keys, opal_list_t *info) { pmix_status_t ret; size_t ninfo, n; @@ -817,57 +815,57 @@ int pmix20_unpublish(char **keys, opal_list_t *info) opal_value_t *iptr; if (NULL != info) { - ninfo = opal_list_get_size(info); - PMIX_INFO_CREATE(pinfo, ninfo); - n=0; - OPAL_LIST_FOREACH(iptr, info, opal_value_t) { - (void)strncpy(pinfo[n++].key, iptr->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pinfo[n].value, iptr); - ++n; - } + ninfo = opal_list_get_size(info); + PMIX_INFO_CREATE(pinfo, ninfo); + n=0; + OPAL_LIST_FOREACH(iptr, info, opal_value_t) { + (void)strncpy(pinfo[n].key, iptr->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pinfo[n].value, iptr); + ++n; + } } else { - pinfo = NULL; - ninfo = 0; + pinfo = NULL; + ninfo = 0; } ret = PMIx_Unpublish(keys, pinfo, ninfo); PMIX_INFO_FREE(pinfo, ninfo); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_unpublishnb(char **keys, opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata) +int ext20_unpublishnb(char **keys, opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_status_t ret; - pmix20_opcaddy_t *op; + ext20_opcaddy_t *op; opal_value_t *iptr; size_t n; /* create the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->opcbfunc = cbfunc; op->cbdata = cbdata; if (NULL != info) { - op->sz = opal_list_get_size(info); - if (0 < op->sz) { - PMIX_INFO_CREATE(op->info, op->sz); - n=0; - OPAL_LIST_FOREACH(iptr, info, opal_value_t) { - (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&op->info[n].value, iptr); - ++n; - } - } + op->sz = opal_list_get_size(info); + if (0 < op->sz) { + PMIX_INFO_CREATE(op->info, op->sz); + n=0; + OPAL_LIST_FOREACH(iptr, info, opal_value_t) { + (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN); + ext20_value_load(&op->info[n].value, iptr); + ++n; + } + } } ret = PMIx_Unpublish_nb(keys, op->info, op->sz, opcbfunc, op); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_spawn(opal_list_t *job_info, opal_list_t *apps, opal_jobid_t *jobid) +int ext20_spawn(opal_list_t *job_info, opal_list_t *apps, opal_jobid_t *jobid) { pmix_status_t ret; pmix_info_t *pinfo = NULL; @@ -876,74 +874,74 @@ int pmix20_spawn(opal_list_t *job_info, opal_list_t *apps, opal_jobid_t *jobid) char nspace[PMIX_MAX_NSLEN+1]; opal_value_t *info; opal_pmix_app_t *app; - opal_pmix20_jobid_trkr_t *job; + opal_ext20_jobid_trkr_t *job; if (NULL != job_info && 0 < (ninfo = opal_list_get_size(job_info))) { - PMIX_INFO_CREATE(pinfo, ninfo); - n=0; - OPAL_LIST_FOREACH(info, job_info, opal_value_t) { - (void)strncpy(pinfo[n].key, info->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pinfo[n].value, info); - ++n; - } + PMIX_INFO_CREATE(pinfo, ninfo); + n=0; + OPAL_LIST_FOREACH(info, job_info, opal_value_t) { + (void)strncpy(pinfo[n].key, info->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pinfo[n].value, info); + ++n; + } } napps = opal_list_get_size(apps); PMIX_APP_CREATE(papps, napps); n=0; OPAL_LIST_FOREACH(app, apps, opal_pmix_app_t) { - papps[n].cmd = strdup(app->cmd); - papps[n].argc = app->argc; - papps[n].argv = opal_argv_copy(app->argv); - papps[n].env = opal_argv_copy(app->env); - papps[n].maxprocs = app->maxprocs; - if (0 < (papps[n].ninfo = opal_list_get_size(&app->info))) { - PMIX_INFO_CREATE(papps[n].info, papps[n].ninfo); - m=0; - OPAL_LIST_FOREACH(info, &app->info, opal_value_t) { - (void)strncpy(papps[n].info[m].key, info->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&papps[n].info[m].value, info); - ++m; - } - } - ++n; + papps[n].cmd = strdup(app->cmd); + papps[n].argc = app->argc; + papps[n].argv = opal_argv_copy(app->argv); + papps[n].env = opal_argv_copy(app->env); + papps[n].maxprocs = app->maxprocs; + if (0 < (papps[n].ninfo = opal_list_get_size(&app->info))) { + PMIX_INFO_CREATE(papps[n].info, papps[n].ninfo); + m=0; + OPAL_LIST_FOREACH(info, &app->info, opal_value_t) { + (void)strncpy(papps[n].info[m].key, info->key, PMIX_MAX_KEYLEN); + ext20_value_load(&papps[n].info[m].value, info); + ++m; + } + } + ++n; } ret = PMIx_Spawn(pinfo, ninfo, papps, napps, nspace); if (PMIX_SUCCESS == ret) { - if (mca_pmix_ext20_component.native_launch) { - /* if we were launched by the OMPI RTE, then - * the jobid is in a special format - so get it */ - opal_convert_string_to_jobid(jobid, nspace); - } else { - /* we were launched by someone else, so make the - * jobid just be the hash of the nspace */ - OPAL_HASH_STR(nspace, *jobid); - } - /* add this to our jobid tracker */ - job = OBJ_NEW(opal_pmix20_jobid_trkr_t); - (void)strncpy(job->nspace, nspace, PMIX_MAX_NSLEN); - job->jobid = *jobid; - opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); + if (mca_pmix_ext20_component.native_launch) { + /* if we were launched by the OMPI RTE, then + * the jobid is in a special format - so get it */ + opal_convert_string_to_jobid(jobid, nspace); + } else { + /* we were launched by someone else, so make the + * jobid just be the hash of the nspace */ + OPAL_HASH_STR(nspace, *jobid); + } + /* add this to our jobid tracker */ + job = OBJ_NEW(opal_ext20_jobid_trkr_t); + (void)strncpy(job->nspace, nspace, PMIX_MAX_NSLEN); + job->jobid = *jobid; + opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); } PMIX_APP_FREE(papps, napps); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } static void spcbfunc(pmix_status_t status, char *nspace, void *cbdata) { - pmix20_opcaddy_t *op = (pmix20_opcaddy_t*)cbdata; + ext20_opcaddy_t *op = (ext20_opcaddy_t*)cbdata; int rc; opal_jobid_t jobid=OPAL_JOBID_INVALID; - opal_pmix20_jobid_trkr_t *job; + opal_ext20_jobid_trkr_t *job; /* this is in the PMIx local thread - need to threadshift to * our own thread as we will be accessing framework-global * lists and objects */ - rc = pmix20_convert_rc(status); + rc = ext20_convert_rc(status); if (PMIX_SUCCESS == status) { if (mca_pmix_ext20_component.native_launch) { /* if we were launched by the OMPI RTE, then @@ -955,7 +953,7 @@ static void spcbfunc(pmix_status_t status, OPAL_HASH_STR(nspace, jobid); } /* add this to our jobid tracker */ - job = OBJ_NEW(opal_pmix20_jobid_trkr_t); + job = OBJ_NEW(opal_ext20_jobid_trkr_t); (void)strncpy(job->nspace, nspace, PMIX_MAX_NSLEN); job->jobid = jobid; opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); @@ -965,17 +963,17 @@ static void spcbfunc(pmix_status_t status, OBJ_RELEASE(op); } -int pmix20_spawnnb(opal_list_t *job_info, opal_list_t *apps, +int ext20_spawnnb(opal_list_t *job_info, opal_list_t *apps, opal_pmix_spawn_cbfunc_t cbfunc, void *cbdata) { pmix_status_t ret; - pmix20_opcaddy_t *op; + ext20_opcaddy_t *op; size_t n, m; opal_value_t *info; opal_pmix_app_t *app; /* create the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->spcbfunc = cbfunc; op->cbdata = cbdata; @@ -984,7 +982,7 @@ int pmix20_spawnnb(opal_list_t *job_info, opal_list_t *apps, n=0; OPAL_LIST_FOREACH(info, job_info, opal_value_t) { (void)strncpy(op->info[n].key, info->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&op->info[n].value, info); + ext20_value_load(&op->info[n].value, info); ++n; } } @@ -1003,7 +1001,7 @@ int pmix20_spawnnb(opal_list_t *job_info, opal_list_t *apps, m=0; OPAL_LIST_FOREACH(info, &app->info, opal_value_t) { (void)strncpy(op->apps[n].info[m].key, info->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&op->apps[n].info[m].value, info); + ext20_value_load(&op->apps[n].info[m].value, info); ++m; } } @@ -1012,16 +1010,16 @@ int pmix20_spawnnb(opal_list_t *job_info, opal_list_t *apps, ret = PMIx_Spawn_nb(op->info, op->ninfo, op->apps, op->sz, spcbfunc, op); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_connect(opal_list_t *procs) +int ext20_connect(opal_list_t *procs) { pmix_status_t ret; pmix_proc_t *parray=NULL; size_t n, cnt=0; opal_namelist_t *ptr; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; /* protect against bozo error */ if (NULL == procs || 0 == (cnt = opal_list_get_size(procs))) { @@ -1036,7 +1034,7 @@ int pmix20_connect(opal_list_t *procs) /* look thru our list of jobids and find the * corresponding nspace */ job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (jptr->jobid == ptr->name.jobid) { job = jptr; break; @@ -1044,32 +1042,29 @@ int pmix20_connect(opal_list_t *procs) } if (NULL == job) { OPAL_ERROR_LOG(OPAL_ERR_NOT_FOUND); + PMIX_PROC_FREE(parray, cnt); return OPAL_ERR_NOT_FOUND; } (void)strncpy(parray[n].nspace, job->nspace, PMIX_MAX_NSLEN); - if (OPAL_VPID_WILDCARD == ptr->name.vpid) { - parray[n].rank = PMIX_RANK_WILDCARD; - } else { - parray[n].rank = ptr->name.vpid; - } + parray[n].rank = ext20_convert_opalrank(ptr->name.vpid); ++n; } ret = PMIx_Connect(parray, cnt, NULL, 0); PMIX_PROC_FREE(parray, cnt); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_connectnb(opal_list_t *procs, +int ext20_connectnb(opal_list_t *procs, opal_pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_status_t ret; size_t n, cnt=0; opal_namelist_t *ptr; - pmix20_opcaddy_t *op; - opal_pmix20_jobid_trkr_t *job; + ext20_opcaddy_t *op; + opal_ext20_jobid_trkr_t *job; /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -1080,7 +1075,7 @@ int pmix20_connectnb(opal_list_t *procs, } /* create the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->opcbfunc = cbfunc; op->cbdata = cbdata; op->nprocs = cnt; @@ -1092,32 +1087,28 @@ int pmix20_connectnb(opal_list_t *procs, OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) { /* look thru our list of jobids and find the * corresponding nspace */ - OPAL_LIST_FOREACH(job, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(job, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (job->jobid == ptr->name.jobid) { (void)strncpy(op->procs[n].nspace, job->nspace, PMIX_MAX_NSLEN); break; } } - if (OPAL_VPID_WILDCARD == ptr->name.vpid) { - op->procs[n].rank = PMIX_RANK_WILDCARD; - } else { - op->procs[n].rank = ptr->name.vpid; - } + op->procs[n].rank = ext20_convert_opalrank(ptr->name.vpid); ++n; } ret = PMIx_Connect_nb(op->procs, op->nprocs, NULL, 0, opcbfunc, op); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_disconnect(opal_list_t *procs) +int ext20_disconnect(opal_list_t *procs) { pmix_status_t ret; pmix_proc_t *parray=NULL; size_t n, cnt=0; opal_namelist_t *ptr; - opal_pmix20_jobid_trkr_t *job; + opal_ext20_jobid_trkr_t *job; /* protect against bozo error */ if (NULL == procs || 0 == (cnt = opal_list_get_size(procs))) { @@ -1131,35 +1122,31 @@ int pmix20_disconnect(opal_list_t *procs) OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) { /* look thru our list of jobids and find the * corresponding nspace */ - OPAL_LIST_FOREACH(job, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(job, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (job->jobid == ptr->name.jobid) { (void)strncpy(parray[n].nspace, job->nspace, PMIX_MAX_NSLEN); break; } } - if (OPAL_VPID_WILDCARD == ptr->name.vpid) { - parray[n].rank = PMIX_RANK_WILDCARD; - } else { - parray[n].rank = ptr->name.vpid; - } + parray[n].rank = ext20_convert_opalrank(ptr->name.vpid); ++n; } ret = PMIx_Disconnect(parray, cnt, NULL, 0); PMIX_PROC_FREE(parray, cnt); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_disconnectnb(opal_list_t *procs, +int ext20_disconnectnb(opal_list_t *procs, opal_pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_status_t ret; size_t n, cnt=0; opal_namelist_t *ptr; - pmix20_opcaddy_t *op; - opal_pmix20_jobid_trkr_t *job; + ext20_opcaddy_t *op; + opal_ext20_jobid_trkr_t *job; /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -1170,7 +1157,7 @@ int pmix20_disconnectnb(opal_list_t *procs, } /* create the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->opcbfunc = cbfunc; op->cbdata = cbdata; op->nprocs = cnt; @@ -1182,27 +1169,23 @@ int pmix20_disconnectnb(opal_list_t *procs, OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) { /* look thru our list of jobids and find the * corresponding nspace */ - OPAL_LIST_FOREACH(job, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(job, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (job->jobid == ptr->name.jobid) { (void)strncpy(op->procs[n].nspace, job->nspace, PMIX_MAX_NSLEN); break; } } - if (OPAL_VPID_WILDCARD == ptr->name.vpid) { - op->procs[n].rank = PMIX_RANK_WILDCARD; - } else { - op->procs[n].rank = ptr->name.vpid; - } + op->procs[n].rank = ext20_convert_opalrank(ptr->name.vpid); ++n; } ret = PMIx_Disconnect_nb(op->procs, op->nprocs, NULL, 0, opcbfunc, op); - return pmix20_convert_rc(ret); + return ext20_convert_rc(ret); } -int pmix20_resolve_peers(const char *nodename, opal_jobid_t jobid, +int ext20_resolve_peers(const char *nodename, opal_jobid_t jobid, opal_list_t *procs) { char *nspace; @@ -1211,7 +1194,7 @@ int pmix20_resolve_peers(const char *nodename, opal_jobid_t jobid, opal_namelist_t *nm; int rc; pmix_status_t ret; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -1220,7 +1203,7 @@ int pmix20_resolve_peers(const char *nodename, opal_jobid_t jobid, nspace = NULL; } else { job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (jptr->jobid == jobid) { job = jptr; break; @@ -1233,7 +1216,7 @@ int pmix20_resolve_peers(const char *nodename, opal_jobid_t jobid, } ret = PMIx_Resolve_peers(nodename, nspace, &array, &nprocs); - rc = pmix20_convert_rc(ret); + rc = ext20_convert_rc(ret); if (NULL != array && 0 < nprocs) { for (n=0; n < nprocs; n++) { @@ -1250,19 +1233,19 @@ int pmix20_resolve_peers(const char *nodename, opal_jobid_t jobid, } /* if we don't already have it, add this to our jobid tracker */ job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (jptr->jobid == nm->name.jobid) { job = jptr; break; } } if (NULL == job) { - job = OBJ_NEW(opal_pmix20_jobid_trkr_t); + job = OBJ_NEW(opal_ext20_jobid_trkr_t); (void)strncpy(job->nspace, nspace, PMIX_MAX_NSLEN); job->jobid = jobid; opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); } - nm->name.vpid = array[n].rank; + nm->name.vpid = ext20_convert_rank(array[n].rank); } } PMIX_PROC_FREE(array, nprocs); @@ -1270,11 +1253,11 @@ int pmix20_resolve_peers(const char *nodename, opal_jobid_t jobid, return rc; } -int pmix20_resolve_nodes(opal_jobid_t jobid, char **nodelist) +int ext20_resolve_nodes(opal_jobid_t jobid, char **nodelist) { pmix_status_t ret; char *nspace=NULL; - opal_pmix20_jobid_trkr_t *job, *jptr; + opal_ext20_jobid_trkr_t *job, *jptr; /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -1283,7 +1266,7 @@ int pmix20_resolve_nodes(opal_jobid_t jobid, char **nodelist) /* look thru our list of jobids and find the * corresponding nspace */ job = NULL; - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { if (jptr->jobid == jobid) { job = jptr; break; @@ -1297,5 +1280,5 @@ int pmix20_resolve_nodes(opal_jobid_t jobid, char **nodelist) ret = PMIx_Resolve_nodes(nspace, nodelist); - return pmix20_convert_rc(ret);; + return ext20_convert_rc(ret);; } diff --git a/opal/mca/pmix/ext20/pmix_ext20_component.c b/opal/mca/pmix/ext20/pmix_ext20_component.c index eaad4b83ca..f16a500102 100644 --- a/opal/mca/pmix/ext20/pmix_ext20_component.c +++ b/opal/mca/pmix/ext20/pmix_ext20_component.c @@ -49,30 +49,30 @@ mca_pmix_ext20_component_t mca_pmix_ext20_component = { /* First, the mca_component_t struct containing meta information about the component itself */ - .base_version = { - /* Indicate that we are a pmix v1.1.0 component (which also - implies a specific MCA version) */ + .base_version = { + /* Indicate that we are a pmix v1.1.0 component (which also + implies a specific MCA version) */ - OPAL_PMIX_BASE_VERSION_2_0_0, + OPAL_PMIX_BASE_VERSION_2_0_0, - /* Component name and version */ + /* Component name and version */ - .mca_component_name = "ext20", - MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION, - OPAL_RELEASE_VERSION), + .mca_component_name = "ext20", + MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION, + OPAL_RELEASE_VERSION), - /* Component open and close functions */ + /* Component open and close functions */ - .mca_open_component = external_open, - .mca_close_component = external_close, - .mca_query_component = external_component_query, - .mca_register_component_params = external_register, - }, - /* Next the MCA v1.0.0 component meta data */ - .base_data = { - /* The component is checkpoint ready */ - MCA_BASE_METADATA_PARAM_CHECKPOINT - } + .mca_open_component = external_open, + .mca_close_component = external_close, + .mca_query_component = external_component_query, + .mca_register_component_params = external_register, + }, + /* Next the MCA v1.0.0 component meta data */ + .base_data = { + /* The component is checkpoint ready */ + MCA_BASE_METADATA_PARAM_CHECKPOINT + } }, .native_launch = false }; @@ -81,10 +81,10 @@ static int external_register(void) { mca_pmix_ext20_component.cache_size = 256; mca_base_component_var_register(&mca_pmix_ext20_component.super.base_version, - "cache_size", "Size of the ring buffer cache for events", - MCA_BASE_VAR_TYPE_INT, NULL, 0, 0, OPAL_INFO_LVL_5, - MCA_BASE_VAR_SCOPE_CONSTANT, - &mca_pmix_ext20_component.cache_size); + "cache_size", "Size of the ring buffer cache for events", + MCA_BASE_VAR_TYPE_INT, NULL, 0, 0, OPAL_INFO_LVL_5, + MCA_BASE_VAR_SCOPE_CONSTANT, + &mca_pmix_ext20_component.cache_size); return OPAL_SUCCESS; } @@ -119,12 +119,12 @@ static int external_component_query(mca_base_module_t **module, int *priority) /* see if a PMIx server is present */ if (NULL != (t = getenv("PMIX_SERVER_URI")) || - NULL != (id = getenv("PMIX_ID"))) { - /* if PMIx is present, then we are a client and need to use it */ - *priority = 100; + NULL != (id = getenv("PMIX_ID"))) { + /* if PMIx is present, then we are a client and need to use it */ + *priority = 100; } else { - /* we could be a server, so we still need to be considered */ - *priority = 5; + /* we could be a server, so we still need to be considered */ + *priority = 5; } *module = (mca_base_module_t *)&opal_pmix_ext20_module; return OPAL_SUCCESS; diff --git a/opal/mca/pmix/ext20/pmix_ext20_server_north.c b/opal/mca/pmix/ext20/pmix_ext20_server_north.c index b6226ce580..2668547404 100644 --- a/opal/mca/pmix/ext20/pmix_ext20_server_north.c +++ b/opal/mca/pmix/ext20/pmix_ext20_server_north.c @@ -46,59 +46,60 @@ * to call up into ORTE for service requests */ static pmix_status_t server_client_connected_fn(const pmix_proc_t *proc, void* server_object, - pmix_op_cbfunc_t cbfunc, void *cbdata); + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_client_finalized_fn(const pmix_proc_t *proc, void* server_object, - pmix_op_cbfunc_t cbfunc, void *cbdata); + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_abort_fn(const pmix_proc_t *proc, void *server_object, - int status, const char msg[], - pmix_proc_t procs[], size_t nprocs, - pmix_op_cbfunc_t cbfunc, void *cbdata); + int status, const char msg[], + pmix_proc_t procs[], size_t nprocs, + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_fencenb_fn(const pmix_proc_t procs[], size_t nprocs, - const pmix_info_t info[], size_t ninfo, - char *data, size_t ndata, - pmix_modex_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t info[], size_t ninfo, + char *data, size_t ndata, + pmix_modex_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_dmodex_req_fn(const pmix_proc_t *proc, - const pmix_info_t info[], size_t ninfo, - pmix_modex_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t info[], size_t ninfo, + pmix_modex_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_publish_fn(const pmix_proc_t *proc, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_lookup_fn(const pmix_proc_t *proc, char **keys, - const pmix_info_t info[], size_t ninfo, - pmix_lookup_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t info[], size_t ninfo, + pmix_lookup_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_unpublish_fn(const pmix_proc_t *proc, char **keys, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_spawn_fn(const pmix_proc_t *proc, - const pmix_info_t job_info[], size_t ninfo, - const pmix_app_t apps[], size_t napps, - pmix_spawn_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t job_info[], size_t ninfo, + const pmix_app_t apps[], size_t napps, + pmix_spawn_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_connect_fn(const pmix_proc_t procs[], size_t nprocs, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_disconnect_fn(const pmix_proc_t procs[], size_t nprocs, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_register_events(pmix_status_t *codes, size_t ncodes, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata); + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_deregister_events(pmix_status_t *codes, size_t ncodes, - pmix_op_cbfunc_t cbfunc, void *cbdata); + pmix_op_cbfunc_t cbfunc, void *cbdata); static pmix_status_t server_notify_event(pmix_status_t code, - const pmix_proc_t *source, - pmix_data_range_t range, - pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata); - #if HAVE_PMIX_QUERY_FUNCTION -static pmix_status_t server_query(pmix_proc_t *proct, - pmix_info_t *info, size_t ninfo, - pmix_info_t *directives, size_t ndirs, - pmix_info_cbfunc_t cbfunc, - void *cbdata); -static void server_tool_connection(pmix_info_t *info, size_t ninfo, - pmix_tool_connection_cbfunc_t cbfunc, - void *cbdata); -#endif + const pmix_proc_t *source, + pmix_data_range_t range, + pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata); + static pmix_status_t server_query(pmix_proc_t *proct, + pmix_query_t *queryies, size_t nqueries, + pmix_info_cbfunc_t cbfunc, + void *cbdata); + static void server_tool_connection(pmix_info_t *info, size_t ninfo, + pmix_tool_connection_cbfunc_t cbfunc, + void *cbdata); +static void server_log(const pmix_proc_t *client, + const pmix_info_t data[], size_t ndata, + const pmix_info_t directives[], size_t ndirs, + pmix_op_cbfunc_t cbfunc, void *cbdata); pmix_server_module_t mymodule = { .client_connected = server_client_connected_fn, @@ -115,10 +116,9 @@ static void server_tool_connection(pmix_info_t *info, size_t ninfo, .register_events = server_register_events, .deregister_events = server_deregister_events, .notify_event = server_notify_event, -#if HAVE_PMIX_QUERY_FUNCTION .query = server_query, - .tool_connected = server_tool_connection -#endif + .tool_connected = server_tool_connection, + .log = server_log }; opal_pmix_server_module_t *host_module = NULL; @@ -126,453 +126,429 @@ opal_pmix_server_module_t *host_module = NULL; static void opal_opcbfunc(int status, void *cbdata) { - pmix20_opalcaddy_t *opalcaddy = (pmix20_opalcaddy_t*)cbdata; + ext20_opalcaddy_t *opalcaddy = (ext20_opalcaddy_t*)cbdata; if (NULL != opalcaddy->opcbfunc) { - opalcaddy->opcbfunc(pmix20_convert_opalrc(status), opalcaddy->cbdata); + opalcaddy->opcbfunc(ext20_convert_opalrc(status), opalcaddy->cbdata); } OBJ_RELEASE(opalcaddy); } static pmix_status_t server_client_connected_fn(const pmix_proc_t *p, void *server_object, - pmix_op_cbfunc_t cbfunc, void *cbdata) + pmix_op_cbfunc_t cbfunc, void *cbdata) { int rc; opal_process_name_t proc; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; if (NULL == host_module || NULL == host_module->client_connected) { - return PMIX_SUCCESS; + return PMIX_SUCCESS; } - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->opcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the nspace/rank to an opal_process_name_t */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) { - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } - proc.vpid = p->rank; + proc.vpid = ext20_convert_rank(p->rank); /* pass it up */ rc = host_module->client_connected(&proc, server_object, - opal_opcbfunc, opalcaddy); - return pmix20_convert_opalrc(rc); + opal_opcbfunc, opalcaddy); + return ext20_convert_opalrc(rc); } static pmix_status_t server_client_finalized_fn(const pmix_proc_t *p, void* server_object, - pmix_op_cbfunc_t cbfunc, void *cbdata) + pmix_op_cbfunc_t cbfunc, void *cbdata) { int rc; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_process_name_t proc; if (NULL == host_module || NULL == host_module->client_finalized) { - return PMIX_SUCCESS; + return PMIX_SUCCESS; } /* convert the nspace/rank to an opal_process_name_t */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) { - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } - proc.vpid = p->rank; + proc.vpid = ext20_convert_rank(p->rank); /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->opcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* pass it up */ rc = host_module->client_finalized(&proc, server_object, opal_opcbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static pmix_status_t server_abort_fn(const pmix_proc_t *p, void *server_object, - int status, const char msg[], - pmix_proc_t procs[], size_t nprocs, - pmix_op_cbfunc_t cbfunc, void *cbdata) + int status, const char msg[], + pmix_proc_t procs[], size_t nprocs, + pmix_op_cbfunc_t cbfunc, void *cbdata) { size_t n; opal_namelist_t *nm; opal_process_name_t proc; int rc; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; if (NULL == host_module || NULL == host_module->abort) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* convert the nspace/rank to an opal_process_name_t */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) { - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } - proc.vpid = p->rank; + proc.vpid = ext20_convert_rank(p->rank); /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->opcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the array of pmix_proc_t to the list of procs */ for (n=0; n < nprocs; n++) { - nm = OBJ_NEW(opal_namelist_t); - opal_list_append(&opalcaddy->procs, &nm->super); - if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == procs[n].rank) { - nm->name.vpid = OPAL_VPID_WILDCARD; - } else { - nm->name.vpid = procs[n].rank; - } + nm = OBJ_NEW(opal_namelist_t); + opal_list_append(&opalcaddy->procs, &nm->super); + if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } + nm->name.vpid = ext20_convert_rank(procs[n].rank); } /* pass it up */ rc = host_module->abort(&proc, server_object, status, msg, - &opalcaddy->procs, opal_opcbfunc, opalcaddy); + &opalcaddy->procs, opal_opcbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static void _data_release(void *cbdata) { - pmix20_opalcaddy_t *opalcaddy = (pmix20_opalcaddy_t*)cbdata; + ext20_opalcaddy_t *opalcaddy = (ext20_opalcaddy_t*)cbdata; if (NULL != opalcaddy->odmdxfunc) { - opalcaddy->odmdxfunc(opalcaddy->ocbdata); + opalcaddy->odmdxfunc(opalcaddy->ocbdata); } OBJ_RELEASE(opalcaddy); } static void opmdx_response(int status, const char *data, size_t sz, void *cbdata, - opal_pmix_release_cbfunc_t relcbfunc, void *relcbdata) + opal_pmix_release_cbfunc_t relcbfunc, void *relcbdata) { pmix_status_t rc; - pmix20_opalcaddy_t *opalcaddy = (pmix20_opalcaddy_t*)cbdata; + ext20_opalcaddy_t *opalcaddy = (ext20_opalcaddy_t*)cbdata; - rc = pmix20_convert_rc(status); + rc = ext20_convert_rc(status); if (NULL != opalcaddy->mdxcbfunc) { - opalcaddy->odmdxfunc = relcbfunc; - opalcaddy->ocbdata = relcbdata; - opalcaddy->mdxcbfunc(rc, data, sz, opalcaddy->cbdata, - _data_release, opalcaddy); + opalcaddy->odmdxfunc = relcbfunc; + opalcaddy->ocbdata = relcbdata; + opalcaddy->mdxcbfunc(rc, data, sz, opalcaddy->cbdata, + _data_release, opalcaddy); } else { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } } static pmix_status_t server_fencenb_fn(const pmix_proc_t procs[], size_t nprocs, - const pmix_info_t info[], size_t ninfo, - char *data, size_t ndata, - pmix_modex_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t info[], size_t ninfo, + char *data, size_t ndata, + pmix_modex_cbfunc_t cbfunc, void *cbdata) { - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; size_t n; opal_namelist_t *nm; opal_value_t *iptr; int rc; if (NULL == host_module || NULL == host_module->fence_nb) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->mdxcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the array of pmix_proc_t to the list of procs */ for (n=0; n < nprocs; n++) { - nm = OBJ_NEW(opal_namelist_t); - opal_list_append(&opalcaddy->procs, &nm->super); - if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == procs[n].rank) { - nm->name.vpid = OPAL_VPID_WILDCARD; - } else { - nm->name.vpid = procs[n].rank; - } + nm = OBJ_NEW(opal_namelist_t); + opal_list_append(&opalcaddy->procs, &nm->super); + if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } + nm->name.vpid = ext20_convert_rank(procs[n].rank); } /* convert the array of pmix_info_t to the list of info */ for (n=0; n < ninfo; n++) { - iptr = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &iptr->super); - iptr->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(iptr, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + iptr = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &iptr->super); + iptr->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(iptr, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* pass it up */ rc = host_module->fence_nb(&opalcaddy->procs, &opalcaddy->info, - data, ndata, opmdx_response, opalcaddy); + data, ndata, opmdx_response, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static pmix_status_t server_dmodex_req_fn(const pmix_proc_t *p, - const pmix_info_t info[], size_t ninfo, - pmix_modex_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t info[], size_t ninfo, + pmix_modex_cbfunc_t cbfunc, void *cbdata) { int rc; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_process_name_t proc; opal_value_t *iptr; size_t n; if (NULL == host_module || NULL == host_module->direct_modex) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* convert the nspace/rank to an opal_process_name_t */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) { - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == p->rank) { - proc.vpid = OPAL_VPID_WILDCARD; - } else { - proc.vpid = p->rank; + return ext20_convert_opalrc(rc); } + proc.vpid = ext20_convert_rank(p->rank); /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->mdxcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the array of pmix_info_t to the list of info */ for (n=0; n < ninfo; n++) { - iptr = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &iptr->super); - iptr->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(iptr, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + iptr = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &iptr->super); + iptr->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(iptr, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* pass it up */ rc = host_module->direct_modex(&proc, &opalcaddy->info, opmdx_response, opalcaddy); if (OPAL_SUCCESS != rc && OPAL_ERR_IN_PROCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } if (OPAL_ERR_IN_PROCESS == rc) { - rc = OPAL_SUCCESS; + rc = OPAL_SUCCESS; } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static pmix_status_t server_publish_fn(const pmix_proc_t *p, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata) { int rc; size_t n; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_process_name_t proc; opal_value_t *oinfo; if (NULL == host_module || NULL == host_module->publish) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* convert the nspace/rank to an opal_process_name_t */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) { - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == p->rank) { - proc.vpid = OPAL_VPID_WILDCARD; - } else { - proc.vpid = p->rank; + return ext20_convert_opalrc(rc); } + proc.vpid = ext20_convert_rank(p->rank); /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->opcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the info array */ for (n=0; n < ninfo; n++) { - oinfo = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &oinfo->super); - oinfo->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(oinfo, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + oinfo = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &oinfo->super); + oinfo->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* pass it up */ rc = host_module->publish(&proc, &opalcaddy->info, opal_opcbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static void opal_lkupcbfunc(int status, - opal_list_t *data, - void *cbdata) + opal_list_t *data, + void *cbdata) { - pmix20_opalcaddy_t *opalcaddy = (pmix20_opalcaddy_t*)cbdata; + ext20_opalcaddy_t *opalcaddy = (ext20_opalcaddy_t*)cbdata; pmix_status_t rc; pmix_pdata_t *d=NULL; size_t nd=0, n; opal_pmix_pdata_t *p; if (NULL != opalcaddy->lkupcbfunc) { - rc = pmix20_convert_opalrc(status); - /* convert any returned data */ - if (NULL != data) { - nd = opal_list_get_size(data); - PMIX_PDATA_CREATE(d, nd); - n=0; - OPAL_LIST_FOREACH(p, data, opal_pmix_pdata_t) { - /* convert the jobid */ - (void)opal_snprintf_jobid(d[n].proc.nspace, PMIX_MAX_NSLEN, p->proc.jobid); - d[n].proc.rank = p->proc.vpid; - (void)strncpy(d[n].key, p->value.key, PMIX_MAX_KEYLEN); - pmix20_value_load(&d[n].value, &p->value); - } - } - opalcaddy->lkupcbfunc(rc, d, nd, opalcaddy->cbdata); + rc = ext20_convert_opalrc(status); + /* convert any returned data */ + if (NULL != data) { + nd = opal_list_get_size(data); + PMIX_PDATA_CREATE(d, nd); + n=0; + OPAL_LIST_FOREACH(p, data, opal_pmix_pdata_t) { + /* convert the jobid */ + (void)opal_snprintf_jobid(d[n].proc.nspace, PMIX_MAX_NSLEN, p->proc.jobid); + d[n].proc.rank = ext20_convert_opalrank(p->proc.vpid); + (void)strncpy(d[n].key, p->value.key, PMIX_MAX_KEYLEN); + ext20_value_load(&d[n].value, &p->value); + } + } + opalcaddy->lkupcbfunc(rc, d, nd, opalcaddy->cbdata); } OBJ_RELEASE(opalcaddy); } static pmix_status_t server_lookup_fn(const pmix_proc_t *p, char **keys, - const pmix_info_t info[], size_t ninfo, - pmix_lookup_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t info[], size_t ninfo, + pmix_lookup_cbfunc_t cbfunc, void *cbdata) { int rc; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_process_name_t proc; opal_value_t *iptr; size_t n; if (NULL == host_module || NULL == host_module->lookup) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* convert the nspace/rank to an opal_process_name_t */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) { - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == p->rank) { - proc.vpid = OPAL_VPID_WILDCARD; - } else { - proc.vpid = p->rank; + return ext20_convert_opalrc(rc); } + proc.vpid = ext20_convert_rank(p->rank); /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->lkupcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the array of pmix_info_t to the list of info */ for (n=0; n < ninfo; n++) { - iptr = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &iptr->super); - iptr->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(iptr, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + iptr = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &iptr->super); + iptr->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(iptr, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* pass it up */ rc = host_module->lookup(&proc, keys, &opalcaddy->info, opal_lkupcbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static pmix_status_t server_unpublish_fn(const pmix_proc_t *p, char **keys, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata) { int rc; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_process_name_t proc; opal_value_t *iptr; size_t n; if (NULL == host_module || NULL == host_module->unpublish) { - return PMIX_SUCCESS; + return PMIX_SUCCESS; } /* convert the nspace/rank to an opal_process_name_t */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) { - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == p->rank) { - proc.vpid = OPAL_VPID_WILDCARD; - } else { - proc.vpid = p->rank; + return ext20_convert_opalrc(rc); } + proc.vpid = ext20_convert_rank(p->rank); /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->opcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the array of pmix_info_t to the list of info */ for (n=0; n < ninfo; n++) { - iptr = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &iptr->super); - iptr->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(iptr, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + iptr = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &iptr->super); + iptr->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(iptr, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* pass it up */ rc = host_module->unpublish(&proc, keys, &opalcaddy->info, opal_opcbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static void opal_spncbfunc(int status, opal_jobid_t jobid, void *cbdata) { - pmix20_opalcaddy_t *opalcaddy = (pmix20_opalcaddy_t*)cbdata; + ext20_opalcaddy_t *opalcaddy = (ext20_opalcaddy_t*)cbdata; pmix_status_t rc; char nspace[PMIX_MAX_NSLEN]; if (NULL != opalcaddy->spwncbfunc) { - rc = pmix20_convert_opalrc(status); - /* convert the jobid */ - (void)opal_snprintf_jobid(nspace, PMIX_MAX_NSLEN, jobid); - opalcaddy->spwncbfunc(rc, nspace, opalcaddy->cbdata); + rc = ext20_convert_opalrc(status); + /* convert the jobid */ + (void)opal_snprintf_jobid(nspace, PMIX_MAX_NSLEN, jobid); + opalcaddy->spwncbfunc(rc, nspace, opalcaddy->cbdata); } OBJ_RELEASE(opalcaddy); } static pmix_status_t server_spawn_fn(const pmix_proc_t *p, - const pmix_info_t job_info[], size_t ninfo, - const pmix_app_t apps[], size_t napps, - pmix_spawn_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t job_info[], size_t ninfo, + const pmix_app_t apps[], size_t napps, + pmix_spawn_cbfunc_t cbfunc, void *cbdata) { - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_process_name_t proc; opal_pmix_app_t *app; opal_value_t *oinfo; @@ -580,382 +556,448 @@ static pmix_status_t server_spawn_fn(const pmix_proc_t *p, int rc; if (NULL == host_module || NULL == host_module->spawn) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* convert the nspace/rank to an opal_process_name_t */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) { - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == p->rank) { - proc.vpid = OPAL_VPID_WILDCARD; - } else { - proc.vpid = p->rank; + return ext20_convert_opalrc(rc); } + proc.vpid = ext20_convert_rank(p->rank); /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->spwncbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the job info */ for (k=0; k < ninfo; k++) { - oinfo = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &oinfo->super); - oinfo->key = strdup(job_info[k].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(oinfo, &job_info[k].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + oinfo = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &oinfo->super); + oinfo->key = strdup(job_info[k].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &job_info[k].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* convert the apps */ for (n=0; n < napps; n++) { - app = OBJ_NEW(opal_pmix_app_t); - opal_list_append(&opalcaddy->apps, &app->super); - if (NULL != apps[n].cmd) { - app->cmd = strdup(apps[n].cmd); - } - app->argc = apps[n].argc; - if (NULL != apps[n].argv) { - app->argv = opal_argv_copy(apps[n].argv); - } - if (NULL != apps[n].env) { - app->env = opal_argv_copy(apps[n].env); - } - app->maxprocs = apps[n].maxprocs; - for (k=0; k < apps[n].ninfo; k++) { - oinfo = OBJ_NEW(opal_value_t); - opal_list_append(&app->info, &oinfo->super); - oinfo->key = strdup(apps[n].info[k].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(oinfo, &apps[n].info[k].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } - } + app = OBJ_NEW(opal_pmix_app_t); + opal_list_append(&opalcaddy->apps, &app->super); + if (NULL != apps[n].cmd) { + app->cmd = strdup(apps[n].cmd); + } + app->argc = apps[n].argc; + if (NULL != apps[n].argv) { + app->argv = opal_argv_copy(apps[n].argv); + } + if (NULL != apps[n].env) { + app->env = opal_argv_copy(apps[n].env); + } + app->maxprocs = apps[n].maxprocs; + for (k=0; k < apps[n].ninfo; k++) { + oinfo = OBJ_NEW(opal_value_t); + opal_list_append(&app->info, &oinfo->super); + oinfo->key = strdup(apps[n].info[k].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &apps[n].info[k].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } + } } /* pass it up */ rc = host_module->spawn(&proc, &opalcaddy->info, &opalcaddy->apps, opal_spncbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OPAL_ERROR_LOG(rc); - OBJ_RELEASE(opalcaddy); + OPAL_ERROR_LOG(rc); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static pmix_status_t server_connect_fn(const pmix_proc_t procs[], size_t nprocs, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata) { int rc; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_namelist_t *nm; size_t n; opal_value_t *oinfo; if (NULL == host_module || NULL == host_module->connect) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->opcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the array of pmix_proc_t to the list of procs */ for (n=0; n < nprocs; n++) { - nm = OBJ_NEW(opal_namelist_t); - opal_list_append(&opalcaddy->procs, &nm->super); - if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == procs[n].rank) { - nm->name.vpid = OPAL_VPID_WILDCARD; - } else { - nm->name.vpid = procs[n].rank; - } + nm = OBJ_NEW(opal_namelist_t); + opal_list_append(&opalcaddy->procs, &nm->super); + if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } + nm->name.vpid = ext20_convert_rank(procs[n].rank); } /* convert the info */ for (n=0; n < ninfo; n++) { - oinfo = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &oinfo->super); - oinfo->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(oinfo, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + oinfo = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &oinfo->super); + oinfo->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* pass it up */ rc = host_module->connect(&opalcaddy->procs, &opalcaddy->info, opal_opcbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static pmix_status_t server_disconnect_fn(const pmix_proc_t procs[], size_t nprocs, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata) { int rc; - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_namelist_t *nm; size_t n; opal_value_t *oinfo; if (NULL == host_module || NULL == host_module->disconnect) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->opcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the array of pmix_proc_t to the list of procs */ for (n=0; n < nprocs; n++) { - nm = OBJ_NEW(opal_namelist_t); - opal_list_append(&opalcaddy->procs, &nm->super); - if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } - if (PMIX_RANK_WILDCARD == procs[n].rank) { - nm->name.vpid = OPAL_VPID_WILDCARD; - } else { - nm->name.vpid = procs[n].rank; - } + nm = OBJ_NEW(opal_namelist_t); + opal_list_append(&opalcaddy->procs, &nm->super); + if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } + nm->name.vpid = ext20_convert_rank(procs[n].rank); } /* convert the info */ for (n=0; n < ninfo; n++) { - oinfo = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &oinfo->super); - oinfo->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(oinfo, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + oinfo = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &oinfo->super); + oinfo->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* pass it up */ rc = host_module->disconnect(&opalcaddy->procs, &opalcaddy->info, opal_opcbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static pmix_status_t server_register_events(pmix_status_t *codes, size_t ncodes, - const pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata) + const pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata) { - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; size_t n; opal_value_t *oinfo; int rc; /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->opcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the info */ for (n=0; n < ninfo; n++) { - oinfo = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &oinfo->super); - oinfo->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(oinfo, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + oinfo = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &oinfo->super); + oinfo->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } } /* pass it up */ rc = host_module->register_events(&opalcaddy->info, opal_opcbfunc, opalcaddy); if (OPAL_SUCCESS != rc) { - OBJ_RELEASE(opalcaddy); + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static pmix_status_t server_deregister_events(pmix_status_t *codes, size_t ncodes, - pmix_op_cbfunc_t cbfunc, void *cbdata) + pmix_op_cbfunc_t cbfunc, void *cbdata) { return PMIX_ERR_NOT_SUPPORTED; } static pmix_status_t server_notify_event(pmix_status_t code, - const pmix_proc_t *source, - pmix_data_range_t range, - pmix_info_t info[], size_t ninfo, - pmix_op_cbfunc_t cbfunc, void *cbdata) + const pmix_proc_t *source, + pmix_data_range_t range, + pmix_info_t info[], size_t ninfo, + pmix_op_cbfunc_t cbfunc, void *cbdata) { return PMIX_ERR_NOT_SUPPORTED; } -#if HAVE_PMIX_QUERY_FUNCTION static void _info_rel(void *cbdata) { - pmix20_opcaddy_t *pcaddy = (pmix20_opcaddy_t*)cbdata; + ext20_opcaddy_t *pcaddy = (ext20_opcaddy_t*)cbdata; OBJ_RELEASE(pcaddy); } static void info_cbfunc(int status, - opal_list_t *info, - void *cbdata, - opal_pmix_release_cbfunc_t release_fn, - void *release_cbdata) + opal_list_t *info, + void *cbdata, + opal_pmix_release_cbfunc_t release_fn, + void *release_cbdata) { - pmix20_opalcaddy_t *opalcaddy = (pmix20_opalcaddy_t*)cbdata; - pmix20_opcaddy_t *pcaddy; + ext20_opalcaddy_t *opalcaddy = (ext20_opalcaddy_t*)cbdata; + ext20_opcaddy_t *pcaddy; opal_value_t *kv; size_t n; - pcaddy = OBJ_NEW(pmix20_opcaddy_t); + pcaddy = OBJ_NEW(ext20_opcaddy_t); /* convert the status */ - pcaddy->status = pmix20_convert_opalrc(status); + pcaddy->status = ext20_convert_opalrc(status); /* convert the list to a pmix_info_t array */ if (NULL != info) { - pcaddy->ninfo = opal_list_get_size(info); - if (0 < pcaddy->ninfo) { - PMIX_INFO_CREATE(pcaddy->info, pcaddy->ninfo); - n = 0; - OPAL_LIST_FOREACH(kv, info, opal_value_t) { - (void)strncpy(pcaddy->info[n].key, kv->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pcaddy->info[n].value, kv); - } - } + pcaddy->ninfo = opal_list_get_size(info); + if (0 < pcaddy->ninfo) { + PMIX_INFO_CREATE(pcaddy->info, pcaddy->ninfo); + n = 0; + OPAL_LIST_FOREACH(kv, info, opal_value_t) { + (void)strncpy(pcaddy->info[n].key, kv->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pcaddy->info[n].value, kv); + } + } } /* we are done with the incoming data */ if (NULL != release_fn) { - release_fn(release_cbdata); + release_fn(release_cbdata); } /* provide the answer downward */ if (NULL != opalcaddy->infocbfunc) { - opalcaddy->infocbfunc(pcaddy->status, pcaddy->info, pcaddy->ninfo, - opalcaddy->cbdata, _info_rel, pcaddy); + opalcaddy->infocbfunc(pcaddy->status, pcaddy->info, pcaddy->ninfo, + opalcaddy->cbdata, _info_rel, pcaddy); } OBJ_RELEASE(opalcaddy); } static pmix_status_t server_query(pmix_proc_t *proct, - pmix_info_t *info, size_t ninfo, - pmix_info_t *directives, size_t ndirs, - pmix_info_cbfunc_t cbfunc, - void *cbdata) + pmix_query_t *queries, size_t nqueries, + pmix_info_cbfunc_t cbfunc, + void *cbdata) { - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; opal_process_name_t requestor; int rc; - size_t n; + size_t n, m; + opal_pmix_query_t *q; opal_value_t *oinfo; if (NULL == host_module || NULL == host_module->query) { - return PMIX_ERR_NOT_SUPPORTED; + return PMIX_ERR_NOT_SUPPORTED; } /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->infocbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the requestor */ if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&requestor.jobid, proct->nspace))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); + opal_output(0, "FILE: %s LINE %d", __FILE__, __LINE__); + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); } - requestor.vpid = proct->rank; + requestor.vpid = ext20_convert_rank(proct->rank); - /* convert the info */ - for (n=0; n < ninfo; n++) { - oinfo = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &oinfo->super); - oinfo->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(oinfo, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - return pmix20_convert_opalrc(rc); - } + /* convert the queries */ + for (n=0; n < nqueries; n++) { + q = OBJ_NEW(opal_pmix_query_t); + /* we "borrow" the info field of the caddy as we and the + * server function both agree on what will be there */ + opal_list_append(&opalcaddy->info, &q->super); + q->keys = opal_argv_copy(queries[n].keys); + for (m=0; m < queries[n].nqual; m++) { + oinfo = OBJ_NEW(opal_value_t); + opal_list_append(&q->qualifiers, &oinfo->super); + oinfo->key = strdup(queries[n].qualifiers[m].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &queries[n].qualifiers[m].value))) { + OBJ_RELEASE(opalcaddy); + return ext20_convert_opalrc(rc); + } + } } - /* we ignore directives for now */ - /* pass the call upwards */ if (OPAL_SUCCESS != (rc = host_module->query(&requestor, - &opalcaddy->info, NULL, - info_cbfunc, opalcaddy))) { - OBJ_RELEASE(opalcaddy); + &opalcaddy->info, + info_cbfunc, opalcaddy))) { + OBJ_RELEASE(opalcaddy); } - return pmix20_convert_opalrc(rc); + return ext20_convert_opalrc(rc); } static void toolcbfunc(int status, - opal_process_name_t proc, - void *cbdata) + opal_process_name_t proc, + void *cbdata) { - pmix20_opalcaddy_t *opalcaddy = (pmix20_opalcaddy_t*)cbdata; + ext20_opalcaddy_t *opalcaddy = (ext20_opalcaddy_t*)cbdata; pmix_status_t rc; pmix_proc_t p; - /* convert the status */ - rc = pmix20_convert_opalrc(status); + rc = ext20_convert_opalrc(status); /* convert the process name */ (void)opal_snprintf_jobid(p.nspace, PMIX_MAX_NSLEN, proc.jobid); - p.rank = proc.vpid; + p.rank = ext20_convert_opalrank(proc.vpid); /* pass it down */ if (NULL != opalcaddy->toolcbfunc) { - opalcaddy->toolcbfunc(rc, &p, opalcaddy->cbdata); + opalcaddy->toolcbfunc(rc, &p, opalcaddy->cbdata); } OBJ_RELEASE(opalcaddy); } static void server_tool_connection(pmix_info_t *info, size_t ninfo, - pmix_tool_connection_cbfunc_t cbfunc, - void *cbdata) + pmix_tool_connection_cbfunc_t cbfunc, + void *cbdata) { - pmix20_opalcaddy_t *opalcaddy; + ext20_opalcaddy_t *opalcaddy; size_t n; opal_value_t *oinfo; int rc; pmix_status_t err; /* setup the caddy */ - opalcaddy = OBJ_NEW(pmix20_opalcaddy_t); + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); opalcaddy->toolcbfunc = cbfunc; opalcaddy->cbdata = cbdata; /* convert the info */ for (n=0; n < ninfo; n++) { - oinfo = OBJ_NEW(opal_value_t); - opal_list_append(&opalcaddy->info, &oinfo->super); - oinfo->key = strdup(info[n].key); - if (OPAL_SUCCESS != (rc = pmix20_value_unload(oinfo, &info[n].value))) { - OBJ_RELEASE(opalcaddy); - err = pmix20_convert_opalrc(rc); - if (NULL != cbfunc) { - cbfunc(err, NULL, cbdata); - } - } + oinfo = OBJ_NEW(opal_value_t); + opal_list_append(&opalcaddy->info, &oinfo->super); + oinfo->key = strdup(info[n].key); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &info[n].value))) { + OBJ_RELEASE(opalcaddy); + err = ext20_convert_opalrc(rc); + if (NULL != cbfunc) { + cbfunc(err, NULL, cbdata); + } + } } /* pass it up */ host_module->tool_connected(&opalcaddy->info, toolcbfunc, opalcaddy); } -#endif + +static void server_log(const pmix_proc_t *proct, + const pmix_info_t data[], size_t ndata, + const pmix_info_t directives[], size_t ndirs, + pmix_op_cbfunc_t cbfunc, void *cbdata) +{ + ext20_opalcaddy_t *opalcaddy; + opal_process_name_t requestor; + int rc; + size_t n; + opal_value_t *oinfo; + pmix_status_t ret; + + if (NULL == host_module || NULL == host_module->log) { + if (NULL != cbfunc) { + cbfunc(PMIX_ERR_NOT_SUPPORTED, cbdata); + } + return; + } + + /* setup the caddy */ + opalcaddy = OBJ_NEW(ext20_opalcaddy_t); + opalcaddy->opcbfunc = cbfunc; + opalcaddy->cbdata = cbdata; + + /* convert the requestor */ + if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&requestor.jobid, proct->nspace))) { + opal_output(0, "FILE: %s LINE %d", __FILE__, __LINE__); + OBJ_RELEASE(opalcaddy); + ret = ext20_convert_opalrc(rc); + if (NULL != cbfunc) { + cbfunc(ret, cbdata); + } + return; + } + requestor.vpid = ext20_convert_rank(proct->rank); + + /* convert the data */ + for (n=0; n < ndata; n++) { + oinfo = OBJ_NEW(opal_value_t); + /* we "borrow" the info field of the caddy as we and the + * server function both agree on what will be there */ + opal_list_append(&opalcaddy->info, &oinfo->super); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &data[n].value))) { + OBJ_RELEASE(opalcaddy); + ret = ext20_convert_opalrc(rc); + if (NULL != cbfunc) { + cbfunc(ret, cbdata); + } + return; + } + } + + /* convert the directives */ + for (n=0; n < ndirs; n++) { + oinfo = OBJ_NEW(opal_value_t); + /* we "borrow" the apps field of the caddy as we and the + * server function both agree on what will be there */ + opal_list_append(&opalcaddy->apps, &oinfo->super); + if (OPAL_SUCCESS != (rc = ext20_value_unload(oinfo, &directives[n].value))) { + OBJ_RELEASE(opalcaddy); + ret = ext20_convert_opalrc(rc); + if (NULL != cbfunc) { + cbfunc(ret, cbdata); + } + return; + } + } + + /* pass the call upwards */ + host_module->log(&requestor, + &opalcaddy->info, + &opalcaddy->apps, + opal_opcbfunc, opalcaddy); +} diff --git a/opal/mca/pmix/ext20/pmix_ext20_server_south.c b/opal/mca/pmix/ext20/pmix_ext20_server_south.c index a7fc71f914..462b9a4820 100644 --- a/opal/mca/pmix/ext20/pmix_ext20_server_south.c +++ b/opal/mca/pmix/ext20/pmix_ext20_server_south.c @@ -53,26 +53,26 @@ static size_t errhdler_ref = 0; #define PMIX_WAIT_FOR_COMPLETION(a) \ do { \ - while ((a)) { \ - usleep(10); \ - } \ + while ((a)) { \ + usleep(10); \ + } \ } while (0) static void errreg_cbfunc (pmix_status_t status, - size_t errhandler_ref, - void *cbdata) + size_t errhandler_ref, + void *cbdata) { volatile bool *active = (volatile bool*)cbdata; errhdler_ref = errhandler_ref; opal_output_verbose(5, opal_pmix_base_framework.framework_output, - "PMIX server errreg_cbfunc - error handler registered status=%d, reference=%lu", - status, (unsigned long)errhandler_ref); + "PMIX server errreg_cbfunc - error handler registered status=%d, reference=%lu", + status, (unsigned long)errhandler_ref); *active = false; } -int pmix20_server_init(opal_pmix_server_module_t *module, - opal_list_t *info) +int ext20_server_init(opal_pmix_server_module_t *module, + opal_list_t *info) { pmix_status_t rc; int dbg; @@ -82,28 +82,28 @@ int pmix20_server_init(opal_pmix_server_module_t *module, volatile bool active; if (0 < (dbg = opal_output_get_verbosity(opal_pmix_base_framework.framework_output))) { - asprintf(&dbgvalue, "PMIX_DEBUG=%d", dbg); - putenv(dbgvalue); + asprintf(&dbgvalue, "PMIX_DEBUG=%d", dbg); + putenv(dbgvalue); } /* convert the list to an array of pmix_info_t */ if (NULL != info) { - sz = opal_list_get_size(info); - PMIX_INFO_CREATE(pinfo, sz); - n = 0; - OPAL_LIST_FOREACH(kv, info, opal_value_t) { - (void)strncpy(pinfo[n].key, kv->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pinfo[n].value, kv); - ++n; - } + sz = opal_list_get_size(info); + PMIX_INFO_CREATE(pinfo, sz); + n = 0; + OPAL_LIST_FOREACH(kv, info, opal_value_t) { + (void)strncpy(pinfo[n].key, kv->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pinfo[n].value, kv); + ++n; + } } else { - sz = 0; - pinfo = NULL; + sz = 0; + pinfo = NULL; } if (PMIX_SUCCESS != (rc = PMIx_server_init(&mymodule, pinfo, sz))) { - PMIX_INFO_FREE(pinfo, sz); - return pmix20_convert_rc(rc); + PMIX_INFO_FREE(pinfo, sz); + return ext20_convert_rc(rc); } PMIX_INFO_FREE(pinfo, sz); @@ -112,7 +112,7 @@ int pmix20_server_init(opal_pmix_server_module_t *module, /* register the default event handler */ active = true; - PMIx_Register_event_handler(NULL, 0, NULL, 0, pmix20_event_hdlr, errreg_cbfunc, (void*)&active); + PMIx_Register_event_handler(NULL, 0, NULL, 0, ext20_event_hdlr, errreg_cbfunc, (void*)&active); PMIX_WAIT_FOR_COMPLETION(active); return OPAL_SUCCESS; @@ -124,7 +124,7 @@ static void fincb(pmix_status_t status, void *cbdata) *active = false; } -int pmix20_server_finalize(void) +int ext20_server_finalize(void) { pmix_status_t rc; volatile bool active; @@ -135,52 +135,52 @@ int pmix20_server_finalize(void) PMIX_WAIT_FOR_COMPLETION(active); rc = PMIx_server_finalize(); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_server_gen_regex(const char *input, char **regex) +int ext20_server_gen_regex(const char *input, char **regex) { pmix_status_t rc; rc = PMIx_generate_regex(input, regex); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } -int pmix20_server_gen_ppn(const char *input, char **ppn) +int ext20_server_gen_ppn(const char *input, char **ppn) { pmix_status_t rc; rc = PMIx_generate_ppn(input, ppn); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } static void opcbfunc(pmix_status_t status, void *cbdata) { - pmix20_opcaddy_t *op = (pmix20_opcaddy_t*)cbdata; + ext20_opcaddy_t *op = (ext20_opcaddy_t*)cbdata; if (NULL != op->opcbfunc) { - op->opcbfunc(pmix20_convert_rc(status), op->cbdata); + op->opcbfunc(ext20_convert_rc(status), op->cbdata); } if (op->active) { - op->status = status; - op->active = false; + op->status = status; + op->active = false; } else { - OBJ_RELEASE(op); + OBJ_RELEASE(op); } } static void _reg_nspace(int sd, short args, void *cbdata) { - pmix20_threadshift_t *cd = (pmix20_threadshift_t*)cbdata; + ext20_threadshift_t *cd = (ext20_threadshift_t*)cbdata; opal_value_t *kv, *k2; pmix_info_t *pinfo = NULL, *pmap; size_t sz, szmap, m, n; char nspace[PMIX_MAX_NSLEN]; pmix_status_t rc; opal_list_t *pmapinfo; - opal_pmix20_jobid_trkr_t *job; - pmix20_opcaddy_t op; + opal_ext20_jobid_trkr_t *job; + ext20_opcaddy_t op; /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ @@ -189,74 +189,75 @@ static void _reg_nspace(int sd, short args, void *cbdata) (void)opal_snprintf_jobid(nspace, PMIX_MAX_NSLEN, cd->jobid); /* store this job in our list of known nspaces */ - job = OBJ_NEW(opal_pmix20_jobid_trkr_t); + job = OBJ_NEW(opal_ext20_jobid_trkr_t); (void)strncpy(job->nspace, nspace, PMIX_MAX_NSLEN); job->jobid = cd->jobid; opal_list_append(&mca_pmix_ext20_component.jobids, &job->super); /* convert the list to an array of pmix_info_t */ if (NULL != cd->info) { - sz = opal_list_get_size(cd->info); - PMIX_INFO_CREATE(pinfo, sz); - n = 0; - OPAL_LIST_FOREACH(kv, cd->info, opal_value_t) { - (void)strncpy(pinfo[n].key, kv->key, PMIX_MAX_KEYLEN); - if (0 == strcmp(kv->key, OPAL_PMIX_PROC_DATA)) { - pinfo[n].value.type = PMIX_INFO_ARRAY; - /* the value contains a list of values - convert - * that list to another array */ - pmapinfo = (opal_list_t*)kv->data.ptr; - szmap = opal_list_get_size(pmapinfo); - PMIX_INFO_CREATE(pmap, szmap); - pinfo[n].value.data.array.array = (struct pmix_info_t*)pmap; - pinfo[n].value.data.array.size = szmap; - m = 0; - OPAL_LIST_FOREACH(k2, pmapinfo, opal_value_t) { - (void)strncpy(pmap[m].key, k2->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pmap[m].value, k2); - ++m; - } - } else { - pmix20_value_load(&pinfo[n].value, kv); - } - ++n; - } + sz = opal_list_get_size(cd->info); + PMIX_INFO_CREATE(pinfo, sz); + n = 0; + OPAL_LIST_FOREACH(kv, cd->info, opal_value_t) { + (void)strncpy(pinfo[n].key, kv->key, PMIX_MAX_KEYLEN); + if (0 == strcmp(kv->key, OPAL_PMIX_PROC_DATA)) { + pinfo[n].value.type = PMIX_DATA_ARRAY; + /* the value contains a list of values - convert + * that list to another array */ + pmapinfo = (opal_list_t*)kv->data.ptr; + szmap = opal_list_get_size(pmapinfo); + PMIX_INFO_CREATE(pmap, szmap); + pinfo[n].value.data.darray.type = PMIX_INFO; + pinfo[n].value.data.darray.array = (struct pmix_info_t*)pmap; + pinfo[n].value.data.darray.size = szmap; + m = 0; + OPAL_LIST_FOREACH(k2, pmapinfo, opal_value_t) { + (void)strncpy(pmap[m].key, k2->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pmap[m].value, k2); + ++m; + } + } else { + ext20_value_load(&pinfo[n].value, kv); + } + ++n; + } } else { - sz = 0; - pinfo = NULL; + sz = 0; + pinfo = NULL; } - OBJ_CONSTRUCT(&op, pmix20_opcaddy_t); + OBJ_CONSTRUCT(&op, ext20_opcaddy_t); op.active = true; rc = PMIx_server_register_nspace(nspace, cd->status, pinfo, sz, - opcbfunc, (void*)&op); + opcbfunc, (void*)&op); if (PMIX_SUCCESS == rc) { - PMIX_WAIT_FOR_COMPLETION(op.active); + PMIX_WAIT_FOR_COMPLETION(op.active); } else { - op.status = rc; + op.status = rc; } /* ensure we execute the cbfunc so the caller doesn't hang */ if (NULL != cd->opcbfunc) { - cd->opcbfunc(pmix20_convert_rc(op.status), cd->cbdata); + cd->opcbfunc(ext20_convert_rc(op.status), cd->cbdata); } if (NULL != pinfo) { - PMIX_INFO_FREE(pinfo, sz); + PMIX_INFO_FREE(pinfo, sz); } OBJ_DESTRUCT(&op); OBJ_RELEASE(cd); } -int pmix20_server_register_nspace(opal_jobid_t jobid, - int nlocalprocs, - opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata) +int ext20_server_register_nspace(opal_jobid_t jobid, + int nlocalprocs, + opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata) { - pmix20_threadshift_t *cd; + ext20_threadshift_t *cd; /* we must threadshift this request as it touches * shared lists of objects */ - cd = OBJ_NEW(pmix20_threadshift_t); + cd = OBJ_NEW(ext20_threadshift_t); cd->jobid = jobid; cd->status = nlocalprocs; cd->info = info; @@ -265,11 +266,11 @@ int pmix20_server_register_nspace(opal_jobid_t jobid, /* if the cbfunc is NULL, then the caller is in an event * and we can directly call the processing function */ if (NULL == cbfunc) { - _reg_nspace(0, 0, cd); + _reg_nspace(0, 0, cd); } else { - event_assign(&cd->ev, opal_pmix_base.evbase, - -1, EV_WRITE, _reg_nspace, cd); - event_active(&cd->ev, EV_WRITE, 1); + event_assign(&cd->ev, opal_pmix_base.evbase, + -1, EV_WRITE, _reg_nspace, cd); + event_active(&cd->ev, EV_WRITE, 1); } return OPAL_SUCCESS; @@ -277,144 +278,144 @@ int pmix20_server_register_nspace(opal_jobid_t jobid, static void tdcbfunc(pmix_status_t status, void *cbdata) { - pmix20_threadshift_t *cd = (pmix20_threadshift_t*)cbdata; + ext20_threadshift_t *cd = (ext20_threadshift_t*)cbdata; if (NULL != cd->opcbfunc) { - cd->opcbfunc(pmix20_convert_rc(status), cd->cbdata); + cd->opcbfunc(ext20_convert_rc(status), cd->cbdata); } if (cd->active) { - cd->active = false; + cd->active = false; } else { - OBJ_RELEASE(cd); + OBJ_RELEASE(cd); } } static void _dereg_nspace(int sd, short args, void *cbdata) { - pmix20_threadshift_t *cd = (pmix20_threadshift_t*)cbdata; - opal_pmix20_jobid_trkr_t *jptr; + ext20_threadshift_t *cd = (ext20_threadshift_t*)cbdata; + opal_ext20_jobid_trkr_t *jptr; /* if we don't already have it, we can ignore this */ - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { - if (jptr->jobid == cd->jobid) { - /* found it - tell the server to deregister */ - cd->active = true; - PMIx_server_deregister_nspace(jptr->nspace, tdcbfunc, cd); - PMIX_WAIT_FOR_COMPLETION(cd->active); - OBJ_RELEASE(cd); - /* now get rid of it from our list */ - opal_list_remove_item(&mca_pmix_ext20_component.jobids, &jptr->super); - OBJ_RELEASE(jptr); - return; - } + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { + if (jptr->jobid == cd->jobid) { + /* found it - tell the server to deregister */ + cd->active = true; + PMIx_server_deregister_nspace(jptr->nspace, tdcbfunc, cd); + PMIX_WAIT_FOR_COMPLETION(cd->active); + OBJ_RELEASE(cd); + /* now get rid of it from our list */ + opal_list_remove_item(&mca_pmix_ext20_component.jobids, &jptr->super); + OBJ_RELEASE(jptr); + return; + } } /* must release the caller */ tdcbfunc(PMIX_ERR_NOT_FOUND, cd); } -void pmix20_server_deregister_nspace(opal_jobid_t jobid, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata) +void ext20_server_deregister_nspace(opal_jobid_t jobid, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata) { - pmix20_threadshift_t *cd; + ext20_threadshift_t *cd; /* we must threadshift this request as it touches * shared lists of objects */ - cd = OBJ_NEW(pmix20_threadshift_t); + cd = OBJ_NEW(ext20_threadshift_t); cd->jobid = jobid; cd->opcbfunc = cbfunc; cd->cbdata = cbdata; if (NULL == cbfunc) { - _dereg_nspace(0, 0, cd); + _dereg_nspace(0, 0, cd); } else { - event_assign(&cd->ev, opal_pmix_base.evbase, - -1, EV_WRITE, _dereg_nspace, cd); - event_active(&cd->ev, EV_WRITE, 1); + event_assign(&cd->ev, opal_pmix_base.evbase, + -1, EV_WRITE, _dereg_nspace, cd); + event_active(&cd->ev, EV_WRITE, 1); } } -int pmix20_server_register_client(const opal_process_name_t *proc, - uid_t uid, gid_t gid, - void *server_object, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata) +int ext20_server_register_client(const opal_process_name_t *proc, + uid_t uid, gid_t gid, + void *server_object, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata) { pmix_status_t rc; pmix_proc_t p; - pmix20_opcaddy_t op; + ext20_opcaddy_t op; /* convert the jobid */ (void)opal_snprintf_jobid(p.nspace, PMIX_MAX_NSLEN, proc->jobid); - p.rank = proc->vpid; + p.rank = ext20_convert_opalrank(proc->vpid); - OBJ_CONSTRUCT(&op, pmix20_opcaddy_t); + OBJ_CONSTRUCT(&op, ext20_opcaddy_t); op.active = true; rc = PMIx_server_register_client(&p, uid, gid, server_object, - opcbfunc, (void*)&op); + opcbfunc, (void*)&op); if (PMIX_SUCCESS == rc) { - PMIX_WAIT_FOR_COMPLETION(op.active); - rc = op.status; + PMIX_WAIT_FOR_COMPLETION(op.active); + rc = op.status; } OBJ_DESTRUCT(&op); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } static void _dereg_client(int sd, short args, void *cbdata) { - pmix20_threadshift_t *cd = (pmix20_threadshift_t*)cbdata; - opal_pmix20_jobid_trkr_t *jptr; + ext20_threadshift_t *cd = (ext20_threadshift_t*)cbdata; + opal_ext20_jobid_trkr_t *jptr; pmix_proc_t p; /* if we don't already have it, we can ignore this */ - OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_pmix20_jobid_trkr_t) { - if (jptr->jobid == cd->source->jobid) { - /* found it - tell the server to deregister */ - (void)strncpy(p.nspace, jptr->nspace, PMIX_MAX_NSLEN); - p.rank = cd->source->vpid; - cd->active = true; - PMIx_server_deregister_client(&p, tdcbfunc, (void*)cd); - PMIX_WAIT_FOR_COMPLETION(cd->active); - break; - } + OPAL_LIST_FOREACH(jptr, &mca_pmix_ext20_component.jobids, opal_ext20_jobid_trkr_t) { + if (jptr->jobid == cd->source->jobid) { + /* found it - tell the server to deregister */ + (void)strncpy(p.nspace, jptr->nspace, PMIX_MAX_NSLEN); + p.rank = ext20_convert_opalrank(cd->source->vpid); + cd->active = true; + PMIx_server_deregister_client(&p, tdcbfunc, (void*)cd); + PMIX_WAIT_FOR_COMPLETION(cd->active); + break; + } } OBJ_RELEASE(cd); } /* tell the local PMIx server to cleanup this client as it is * done executing */ -void pmix20_server_deregister_client(const opal_process_name_t *proc, - opal_pmix_op_cbfunc_t cbfunc, - void *cbdata) +void ext20_server_deregister_client(const opal_process_name_t *proc, + opal_pmix_op_cbfunc_t cbfunc, + void *cbdata) { - pmix20_threadshift_t *cd; + ext20_threadshift_t *cd; /* we must threadshift this request as we might not be in an event * and we are going to access framework-global lists/objects */ - cd = OBJ_NEW(pmix20_threadshift_t); + cd = OBJ_NEW(ext20_threadshift_t); cd->source = proc; cd->opcbfunc = cbfunc; cd->cbdata = cbdata; if (NULL == cbfunc) { - _dereg_client(0, 0, cd); + _dereg_client(0, 0, cd); } else { - event_assign(&cd->ev, opal_pmix_base.evbase, - -1, EV_WRITE, _dereg_client, cd); - event_active(&cd->ev, EV_WRITE, 1); + event_assign(&cd->ev, opal_pmix_base.evbase, + -1, EV_WRITE, _dereg_client, cd); + event_active(&cd->ev, EV_WRITE, 1); } } /* have the local PMIx server setup the environment for this client */ -int pmix20_server_setup_fork(const opal_process_name_t *proc, char ***env) +int ext20_server_setup_fork(const opal_process_name_t *proc, char ***env) { pmix_status_t rc; pmix_proc_t p; /* convert the jobid */ (void)opal_snprintf_jobid(p.nspace, PMIX_MAX_NSLEN, proc->jobid); - p.rank = proc->vpid; + p.rank = ext20_convert_opalrank(proc->vpid); rc = PMIx_server_setup_fork(&p, env); - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } /* this is the call back up from the embedded PMIx server that @@ -423,87 +424,87 @@ int pmix20_server_setup_fork(const opal_process_name_t *proc, char ***env) static void dmdx_response(pmix_status_t status, char *data, size_t sz, void *cbdata) { int rc; - pmix20_opcaddy_t *op = (pmix20_opcaddy_t*)cbdata; + ext20_opcaddy_t *op = (ext20_opcaddy_t*)cbdata; - rc = pmix20_convert_rc(status); + rc = ext20_convert_rc(status); if (NULL != op->mdxcbfunc) { - op->mdxcbfunc(rc, data, sz, op->cbdata, NULL, NULL); + op->mdxcbfunc(rc, data, sz, op->cbdata, NULL, NULL); } OBJ_RELEASE(op); } /* request modex data for a local proc from the PMIx server */ -int pmix20_server_dmodex(const opal_process_name_t *proc, - opal_pmix_modex_cbfunc_t cbfunc, void *cbdata) +int ext20_server_dmodex(const opal_process_name_t *proc, + opal_pmix_modex_cbfunc_t cbfunc, void *cbdata) { - pmix20_opcaddy_t *op; + ext20_opcaddy_t *op; pmix_status_t rc; /* setup the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->mdxcbfunc = cbfunc; op->cbdata = cbdata; /* convert the jobid */ (void)opal_snprintf_jobid(op->p.nspace, PMIX_MAX_NSLEN, proc->jobid); - op->p.rank = proc->vpid; + op->p.rank = ext20_convert_opalrank(proc->vpid); /* find the internally-cached data for this proc */ rc = PMIx_server_dmodex_request(&op->p, dmdx_response, op); if (PMIX_SUCCESS != rc) { - OBJ_RELEASE(op); + OBJ_RELEASE(op); } - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } /* tell the PMIx server to notify its local clients of an event */ -int pmix20_server_notify_event(int status, - const opal_process_name_t *source, - opal_list_t *info, - opal_pmix_op_cbfunc_t cbfunc, void *cbdata) +int ext20_server_notify_event(int status, + const opal_process_name_t *source, + opal_list_t *info, + opal_pmix_op_cbfunc_t cbfunc, void *cbdata) { opal_value_t *kv; pmix_info_t *pinfo; size_t sz, n; pmix_status_t rc; - pmix20_opcaddy_t *op; + ext20_opcaddy_t *op; /* convert the list to an array of pmix_info_t */ if (NULL != info) { - sz = opal_list_get_size(info); - PMIX_INFO_CREATE(pinfo, sz); - n = 0; - OPAL_LIST_FOREACH(kv, info, opal_value_t) { - (void)strncpy(pinfo[n].key, kv->key, PMIX_MAX_KEYLEN); - pmix20_value_load(&pinfo[n].value, kv); - } + sz = opal_list_get_size(info); + PMIX_INFO_CREATE(pinfo, sz); + n = 0; + OPAL_LIST_FOREACH(kv, info, opal_value_t) { + (void)strncpy(pinfo[n].key, kv->key, PMIX_MAX_KEYLEN); + ext20_value_load(&pinfo[n].value, kv); + } } else { - sz = 0; - pinfo = NULL; + sz = 0; + pinfo = NULL; } /* setup the caddy */ - op = OBJ_NEW(pmix20_opcaddy_t); + op = OBJ_NEW(ext20_opcaddy_t); op->info = pinfo; op->sz = sz; op->opcbfunc = cbfunc; op->cbdata = cbdata; /* convert the jobid */ if (NULL == source) { - (void)opal_snprintf_jobid(op->p.nspace, PMIX_MAX_NSLEN, OPAL_JOBID_INVALID); - op->p.rank = OPAL_VPID_INVALID; + (void)opal_snprintf_jobid(op->p.nspace, PMIX_MAX_NSLEN, OPAL_JOBID_INVALID); + op->p.rank = ext20_convert_opalrank(OPAL_VPID_INVALID); } else { - (void)opal_snprintf_jobid(op->p.nspace, PMIX_MAX_NSLEN, source->jobid); - op->p.rank = source->vpid; + (void)opal_snprintf_jobid(op->p.nspace, PMIX_MAX_NSLEN, source->jobid); + op->p.rank = ext20_convert_opalrank(source->vpid); } - rc = pmix20_convert_opalrc(status); + rc = ext20_convert_opalrc(status); /* the range is irrelevant here as the server is passing * the event down to its local clients */ rc = PMIx_Notify_event(rc, &op->p, PMIX_RANGE_LOCAL, - pinfo, sz, opcbfunc, op); + pinfo, sz, opcbfunc, op); if (PMIX_SUCCESS != rc) { - OBJ_RELEASE(op); + OBJ_RELEASE(op); } - return pmix20_convert_rc(rc); + return ext20_convert_rc(rc); } diff --git a/opal/mca/pmix/pmix2x/configure.m4 b/opal/mca/pmix/pmix2x/configure.m4 index 53b13c5be1..3fded7ce79 100644 --- a/opal/mca/pmix/pmix2x/configure.m4 +++ b/opal/mca/pmix/pmix2x/configure.m4 @@ -55,7 +55,7 @@ AC_DEFUN([MCA_opal_pmix_pmix2x_CONFIG],[ AS_IF([test $opal_pmix_pmix2x_happy -eq 1], [PMIX_VERSION="internal v`$srcdir/$opal_pmix_pmix2x_basedir/pmix/config/pmix_get_version.sh $srcdir/$opal_pmix_pmix2x_basedir/pmix/VERSION`" # Build flags for our Makefile.am - opal_pmix_pmix2x_LIBS='$(OPAL_TOP_BUILDDIR)/'"$opal_pmix_pmix2x_basedir"'/pmix/libpmix.la' + opal_pmix_pmix2x_LIBS='$(OPAL_TOP_BUILDDIR)/'"$opal_pmix_pmix2x_basedir"'/pmix/src/libpmix.la' opal_pmix_pmix2x_CPPFLAGS='-I$(OPAL_TOP_BUILDDIR)/opal/mca/pmix/pmix2x/pmix/include/pmix -I$(OPAL_TOP_BUILDDIR)/opal/mca/pmix/pmix2x/pmix/include -I$(OPAL_TOP_BUILDDIR)/opal/mca/pmix/pmix2x/pmix -I$(OPAL_TOP_SRCDIR)/opal/mca/pmix/pmix2x/pmix' AC_SUBST([opal_pmix_pmix2x_LIBS]) AC_SUBST([opal_pmix_pmix2x_CPPFLAGS])]) diff --git a/opal/mca/pmix/pmix2x/pmix/Makefile.am b/opal/mca/pmix/pmix2x/pmix/Makefile.am index 0cdb201523..1001fd43da 100644 --- a/opal/mca/pmix/pmix2x/pmix/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/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) 2006-2015 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2006-2016 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. # Copyright (c) 2013-2016 Intel, Inc. All rights reserved # $COPYRIGHT$ @@ -23,64 +23,28 @@ # via AC_CONFIG_MACRO_DIR in configure.ac. ACLOCAL_AMFLAGS = -I ./config +SUBDIRS = config include src + + headers = sources = nodist_headers = -EXTRA_DIST = +EXTRA_DIST = AUTHORS README INSTALL VERSION LICENSE autogen.pl -# Only install the valgrind suppressions file if we're building in -# standalone mode +# Only install the valgrind suppressions file and man pages +# if we're building in standalone mode dist_pmixdata_DATA = -man_MANS = - if ! PMIX_EMBEDDED_MODE dist_pmixdata_DATA += contrib/pmix-valgrind.supp -man_MANS += \ - man/man3/pmix_init.3 \ - man/man3/pmix_finalize.3 \ - man/man3/pmix_initialized.3 \ - man/man3/pmix_abort.3 \ - man/man3/pmix_put.3 \ - man/man3/pmix_commit.3 \ - man/man3/pmix_fence.3 \ - man/man3/pmix_get.3 \ - man/man7/pmix.7 \ - man/man7/pmix_constants.7 + +if PMIX_HAVE_PANDOC +SUBDIRS += man endif -include config/Makefile.am -include include/Makefile.am -include src/class/Makefile.am -include src/include/Makefile.am -include src/buffer_ops/Makefile.am -include src/util/Makefile.am -include src/usock/Makefile.am -include src/client/Makefile.am -include src/server/Makefile.am -include src/sec/Makefile.am -include src/event/Makefile.am -include src/common/Makefile.am -include src/tool/Makefile.am - -if WANT_DSTORE -include src/sm/Makefile.am -include src/dstore/Makefile.am -endif - -if PMIX_EMBEDDED_MODE -noinst_LTLIBRARIES = libpmix.la -libpmix_la_SOURCES = $(headers) $(sources) -libpmix_la_LDFLAGS = - -else - -lib_LTLIBRARIES = libpmix.la -libpmix_la_SOURCES = $(headers) $(sources) -libpmix_la_LDFLAGS = -version-info $(libpmix_so_version) endif if PMIX_TESTS_EXAMPLES -SUBDIRS = . test examples +SUBDIRS += . test examples endif if WANT_INSTALL_HEADERS @@ -93,19 +57,7 @@ noinst_HEADERS = $(headers) endif nroff: - @for file in $(man_MANS); do \ - source=`echo $$file | sed -e 's@/man[0-9]@@'`; \ - contrib/md2nroff.pl --source=$$source.md; \ - done - -EXTRA_DIST += AUTHORS README INSTALL VERSION LICENSE autogen.sh \ - config/pmix_get_version.sh $(man_MANS) \ - contrib/platform/optimized \ - test/test_common.h test/cli_stages.h \ - test/server_callbacks.h test/test_fence.h \ - test/test_publish.h test/test_resolve_peers.h \ - test/test_spawn.h test/utils.h test/test_cd.h - + (cd man; $(MAKE) nroff) dist-hook: env LS_COLORS= sh "$(top_srcdir)/config/distscript.sh" "$(top_srcdir)" "$(distdir)" "$(PMIX_VERSION)" "$(PMIX_REPO_REV)" diff --git a/opal/mca/pmix/pmix2x/pmix/VERSION b/opal/mca/pmix/pmix2x/pmix/VERSION index 87d4ad54cc..fc51a4cb9b 100644 --- a/opal/mca/pmix/pmix2x/pmix/VERSION +++ b/opal/mca/pmix/pmix2x/pmix/VERSION @@ -30,7 +30,7 @@ greek= # command, or with the date (if "git describe" fails) in the form of # "date". -repo_rev=git23ee156 +repo_rev=gitc2e543b # 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="Aug 07, 2016" +date="Aug 10, 2016" # 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/autogen.pl b/opal/mca/pmix/pmix2x/pmix/autogen.pl new file mode 100755 index 0000000000..8ca3350362 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/autogen.pl @@ -0,0 +1,739 @@ +#!/usr/bin/env perl +# +# Copyright (c) 2009-2016 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013 Mellanox Technologies, Inc. +# All rights reserved. +# Copyright (c) 2013-2016 Intel, Inc. All rights reserved. +# Copyright (c) 2015 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2015 IBM Corporation. All rights reserved. +# +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +use strict; + +use Cwd; +use File::Basename; +use File::Find; +use Data::Dumper; +use Getopt::Long; + +# +# Global variables +# + +# Sentinel file to remove if we fail +my $sentinel; + +# The m4 file we'll write at the end +my $m4_output_file = "config/autogen_found_items.m4"; +my $m4; +# Sanity check file +my $topdir_file = "include/pmix.h"; +my $dnl_line = "dnl ---------------------------------------------------------------------------"; + +# Data structures to fill up with all the stuff we find +my $mca_found; +my @subdirs; + +# Command line parameters +my $quiet_arg = 0; +my $debug_arg = 0; +my $help_arg = 0; +my $include_arg = 0; +my $exclude_arg = 0; +my $force_arg = 0; + +# Include/exclude lists +my $include_list; +my $exclude_list; + +# Minimum versions +my $pmix_automake_version = "1.12.2"; +my $pmix_autoconf_version = "2.69"; +my $pmix_libtool_version = "2.4.2"; + +# Search paths +my $pmix_autoconf_search = "autoconf"; +my $pmix_automake_search = "automake"; +my $pmix_libtoolize_search = "libtoolize;glibtoolize"; + +# One-time setup +my $username; +my $hostname; +my $full_hostname; + +$username = getpwuid($>); +$full_hostname = `hostname`; +chomp($full_hostname); +$hostname = $full_hostname; +$hostname =~ s/^([\w\-]+)\..+/\1/; + +############################################################################## + +sub my_die { + unlink($sentinel) + if ($sentinel); + die @_; +} + +sub my_exit { + my ($ret) = @_; + unlink($sentinel) + if ($sentinel && $ret != 0); + exit($ret); +} + +############################################################################## + +sub verbose { + print @_ + if (!$quiet_arg); +} + +sub debug { + print @_ + if ($debug_arg); +} + +sub debug_dump { + my $d = new Data::Dumper([@_]); + $d->Purity(1)->Indent(1); + debug $d->Dump; +} + +############################################################################## + +sub mca_process_component { + my ($framework, $component) = @_; + + my $cdir = "src/mca/$framework/$component"; + + return + if (! -d $cdir); + + # Process this directory + my $found_component; + + $found_component = { + name => $component, + framework_name => $framework, + abs_dir => $cdir, + }; + + # Does this directory have a configure.m4 file? + if (-f "$cdir/configure.m4") { + $found_component->{"configure.m4"} = 1; + verbose " Found configure.m4 file\n"; + } + + # Push the results onto the $mca_found hash array + push(@{$mca_found->{$framework}->{"components"}}, + $found_component); + +} + +############################################################################## + +sub ignored { + my ($dir) = @_; + + # If this directory does not have .pmix_ignore, or if it has a + # .pmix_unignore that has my username in it, then add it to the + # list of components. + my $ignored = 0; + + if (-f "$dir/.pmix_ignore") { + $ignored = 1; + } + if (-f "$dir/.pmix_unignore") { + open(UNIGNORE, "$dir/.pmix_unignore") || + my_die "Can't open $dir/.pmix_unignore file"; + my $unignore; + $unignore .= $_ + while (); + close(UNIGNORE); + + $ignored = 0 + if ($unignore =~ /^$username$/m || + $unignore =~ /^$username\@$hostname$/m || + $unignore =~ /^$username\@$full_hostname$/m); + } + + return $ignored; +} + +############################################################################## + +sub mca_process_framework { + my ($framework) = @_; + + # Does this framework have a configure.m4 file? + my $dir = "src/mca/$framework"; + if (-f "$dir/configure.m4") { + $mca_found->{$framework}->{"configure.m4"} = 1; + verbose " Found framework configure.m4 file\n"; + } + + # Did we exclude all components for this framework? + if (exists($exclude_list->{$framework}) && + $exclude_list->{$framework}[0] eq "AGEN_EXCLUDE_ALL") { + verbose " => Excluded\n"; + } else { + # Look for component directories in this framework + if (-d $dir) { + $mca_found->{$framework}->{found} = 1; + opendir(DIR, $dir) || + my_die "Can't open $dir directory"; + foreach my $d (readdir(DIR)) { + # Skip any non-directory, "base", or any dir that + # begins with "." + next + if (! -d "$dir/$d" || $d eq "base" || + substr($d, 0, 1) eq "."); + + # Skip any component that doesn't have a configure.m4 + # or Makefile.am as we couldn't build it anyway + if (! -f "$dir/$d/configure.m4" && + ! -f "$dir/$d/Makefile.am" && + ! -f "$dir/$d/configure.ac" && + ! -f "$dir/$d/configure.in") { + verbose " => No sentinel file found in $dir/$d -> Excluded\n"; + next; + } + + verbose "--- Found pmix / $framework / $d component: src/mca/$framework/$d\n"; + + # Skip if specifically excluded + if (exists($exclude_list->{$framework}) && + $exclude_list->{$framework}[0] eq $d) { + verbose " => Excluded\n"; + next; + } + + # Skip if the framework is on the include list, but + # doesn't contain this component + if (exists($include_list->{$framework})) { + my $tst = 0; + foreach my $ck (@{$include_list->{$framework}}) { + if ($ck ne $d) { + verbose " => Not included\n"; + $tst = 1; + last; + } + } + if ($tst) { + next; + } + } + + # Check ignore status + if (ignored("$dir/$d")) { + verbose " => Ignored (found .pmix_ignore file)\n"; + } else { + mca_process_component($framework, $d); + } + } + } + closedir(DIR); + } +} + +############################################################################## + +sub mca_generate_framework_header(\$\@) { + my (@frameworks) = @_; + my $framework_array_output=""; + my $framework_decl_output=""; + + foreach my $framework (@frameworks) { + # There is no common framework object + if ($framework ne "common") { + my $framework_name = "pmix_${framework}_base_framework"; + $framework_array_output .= " &$framework_name,\n"; + $framework_decl_output .= "extern pmix_mca_base_framework_t $framework_name;\n"; + } + } + + my $ifdef_string = uc "pmix_FRAMEWORKS_H"; + open(FRAMEWORKS_OUT, ">src/include/frameworks.h"); + printf FRAMEWORKS_OUT "%s", "/* + * This file is autogenerated by autogen.pl. Do not edit this file by hand. + */ +#ifndef $ifdef_string +#define $ifdef_string + +#include + +$framework_decl_output +static pmix_mca_base_framework_t *pmix_frameworks[] = { +$framework_array_output NULL +}; + +#endif /* $ifdef_string */\n\n"; + close(FRAMEWORKS_OUT); +} + +############################################################################## + +sub mca_process_project { + + # Look for framework directories + my $dir = "src/mca"; + opendir(DIR, $dir) || + my_die "Can't open $dir directory"; + my @my_dirs = readdir(DIR); + @my_dirs = sort(@my_dirs); + + foreach my $d (@my_dirs) { + # Skip any non-directory, "base", or any dir that begins with "." + next + if (! -d "$dir/$d" || $d eq "base" || substr($d, 0, 1) eq "."); + + # If this directory has a $dir.h file and a base/ + # subdirectory, or its name is "common", then it's a + # framework. + if ("common" eq $d || + (-f "$dir/$d/$d.h" && -d "$dir/$d/base")) { + verbose "\n=== Found pmix framework: src/mca/$d\n"; + mca_process_framework($d); + } + } + closedir(DIR); +} + +############################################################################## + +sub mca_run_global { + + # Go find a list of frameworks, and for each of + # those, go find a list of components. + mca_process_project(); + + # Debugging output + debug_dump($mca_found); + + $m4 .= "\n$dnl_line +$dnl_line +$dnl_line + +dnl MCA information\n"; + + # Array for all the m4_includes that we'll need to pick up the + # configure.m4's. + my @includes; + + # Write the list of frameworks + my $frameworks_comma; + + # Print out project-level info + my @mykeys = keys(%{$mca_found}); + @mykeys = sort(@mykeys); + + # Ensure that the "common" framework is listed first + # (if it exists) + my @tmp; + push(@tmp, "common") + if (grep(/common/, @mykeys)); + foreach my $f (@mykeys) { + push(@tmp, $f) + if ($f ne "common"); + } + @mykeys = @tmp; + + foreach my $f (@mykeys) { + $frameworks_comma .= ", $f"; + + # Does this framework have a configure.m4 file? + push(@includes, "src/mca/$f/configure.m4") + if (exists($mca_found->{$f}->{"configure.m4"})); + + # This framework does have a Makefile.am (or at least, + # it should!) + my_die "Missing src/mca/$f/Makefile.am" + if (! -f "src/mca/$f/Makefile.am"); + } + $frameworks_comma =~ s/^, //; + + &mca_generate_framework_header("src", @mykeys); + + $m4 .= "$dnl_line + +dnl Frameworks in the pmix project and their corresponding directories +m4_define([mca_pmix_framework_list], [$frameworks_comma]) + +"; + + # Print out framework-level info + foreach my $f (@mykeys) { + my $components; + my $m4_config_component_list; + my $no_config_component_list; + + # Troll through each of the found components + foreach my $comp (@{$mca_found->{$f}->{components}}) { + my $c = $comp->{name}; + $components .= "$c "; + + # Does this component have a configure.m4 file? + if (exists($comp->{"configure.m4"})) { + push(@includes, "src/mca/$f/$c/configure.m4"); + $m4_config_component_list .= ", $c"; + } else { + $no_config_component_list .= ", $c"; + } + } + $m4_config_component_list =~ s/^, //; + $no_config_component_list =~ s/^, //; + + $m4 .= "dnl Components in the pmix / $f framework +m4_define([mca_pmix_${f}_m4_config_component_list], [$m4_config_component_list]) +m4_define([mca_pmix_${f}_no_config_component_list], [$no_config_component_list]) + +"; + } + + # List out all the m4_include + $m4 .= "$dnl_line + +dnl List of configure.m4 files to include\n"; + foreach my $i (@includes) { + $m4 .= "m4_include([$i])\n"; + } +} + + +############################################################################## +# Find and remove stale files + +sub find_and_delete { + foreach my $file (@_) { + my $removed = 0; + if (-f $file) { + unlink($file); + $removed = 1; + } + if (-f "config/$file") { + unlink("config/$file"); + $removed = 1; + } + debug " Removed stale copy of $file\n" + if ($removed); + } +} + +############################################################################## +# Find a specific executable and ensure that it is a recent enough +# version. + +sub find_and_check { + my ($app, $app_name, $req_version) = @_; + + my @search_path = split(/;/, $app_name); + my @min_version = split(/\./, $req_version); + my @versions_found = (); + + foreach (@search_path) { + verbose " Searching for $_\n"; + my $version = `$_ --version`; + if (!defined($version)) { + verbose " $_ not found\n"; + next; + } + + # Matches a version string with 1 or more parts possibly prefixed with a letter (ex: + # v2.2) or followed by a letter (ex: 2.2.6b). This regex assumes there is a space + # before the version string and that the version is ok if there is no version. + if (!($version =~ m/\s[vV]?(\d[\d\.]*\w?)/m)) { + verbose " WARNING: $_ does not appear to support --version. Assuming it is ok\n"; + + return; + } + + $version = $1; + + verbose " Found $_ version $version; checking version...\n"; + push(@versions_found, $version); + + my @parts = split(/\./, $version); + my $i = 0; + # Check every component of the version number + while ($i <= $#min_version) { + verbose " Found version component $parts[$i] -- need $min_version[$i]\n"; + + # Check to see if there are any characters (!) in the + # version number (e.g., Libtool's "2.2.6b" -- #%@#$%!!!). + # Do separate comparisons between the number and any + # trailing digits. You can't just "lt" compare the whole + # string because "10 lt 2b" will return true. #@$@#$#@$ + # Libtool!! + $parts[$i] =~ m/(\d+)([a-z]*)/i; + my $pn = $1; + my $pa = $2; + $min_version[$i] =~ m/(\d+)([a-z]*)/i; + my $mn = $1; + my $ma = $2; + + # If the version is higher, we're done. + if ($pn > $mn) { + verbose " ==> ACCEPTED\n"; + return; + } + # If the version is lower, we're done. + elsif ($pn < $mn || + ($pn == $mn && $pa lt $ma)) { + verbose " ==> Too low! Skipping this version\n"; + last; + } + + # If the version was equal, keep checking. + ++$i; + } + + # If we found a good version, return. + if ($i > $#min_version) { + verbose " ==> ACCEPTED\n"; + return; + } + } + + # if no acceptable version found, reject it + print " +================================================================= +I could not find a recent enough copy of $app. +I need at least $req_version, but only found the following versions:\n\n"; + + my $i = 0; + foreach (@search_path) { + print " $_: $versions_found[$i]\n"; + $i++; + } + + print "\nI am gonna abort. :-( + +Please make sure you are using at least the following versions of the +tools: + + GNU Autoconf: $pmix_autoconf_version + GNU Automake: $pmix_automake_version + GNU Libtool: $pmix_libtool_version +=================================================================\n"; + my_exit(1); +} + +############################################################################## + +sub safe_system { + print "Running: " . join(/ /, @_) . "\n"; + my $ret = system(@_); + $ret >>= 8; + if (0 != $ret) { + print "Command failed: @_\n"; + my_exit($ret); + } + $ret; +} + +############################################################################## + +sub in_tarball { + my $tarball = 0; + open(IN, "VERSION") || my_die "Can't open VERSION"; + # If repo_rev is not an empty string, we are in a tarball + while () { + my $line = $_; + my @fields = split(/=/,$line); + if ($fields[0] eq "repo_rev") { + if ($fields[1] ne "\n") { + $tarball = 1; + last; + } + } + } + close(IN); + return $tarball; +} + +############################################################################## +############################################################################## +## main - do the real work... +############################################################################## +############################################################################## + +# Command line parameters + +my $ok = Getopt::Long::GetOptions("quiet|q" => \$quiet_arg, + "debug|d" => \$debug_arg, + "help|h" => \$help_arg, + "include=s" => \$include_arg, + "exclude=s" => \$exclude_arg, + "force|f" => \$force_arg, + ); + +if (!$ok || $help_arg) { + print "Invalid command line argument.\n\n" + if (!$ok); + print "Options: + --quiet | -q Do not display normal verbose output + --debug | -d Output lots of debug information + --help | -h This help list + --include | -i Comma-separated list of framework-component pairs + to be exclusively built - i.e., all other components + will be ignored and only those specified will be marked + to build + --exclude | -e Comma-separated list of framework or framework-component + to be excluded from the build + --force | -f Run even if invoked from the source tree of an expanded + distribution tarball\n"; + my_exit($ok ? 0 : 1); +} + +#--------------------------------------------------------------------------- + +# Check for project existence +my $project_name_long = "PMIx"; +my $project_name_short = "PMIx"; + +#--------------------------------------------------------------------------- + +$full_hostname = `hostname`; +chomp($full_hostname); + +$m4 = "dnl +dnl \$HEADER\$ +dnl +$dnl_line +dnl This file is automatically created by autogen.pl; it should not +dnl be edited by hand!! +dnl +dnl Generated by $username at " . localtime(time) . " +dnl on $full_hostname. +$dnl_line\n\n"; + +#--------------------------------------------------------------------------- + +# Verify that we're in the PMIx root directory by checking for a token file. + +my_die "Not at the root directory of an PMIx source tree" + if (! -f "config/pmix_mca.m4"); + +$force_arg = 1; + +my_die "autogen.pl has been invoked in the source tree of a PMIx distribution tarball; aborting... +You likely do not need to invoke \"autogen.pl\" -- you can probably run \"configure\" directly. +If you really know what you are doing, and really need to run autogen.pl, use the \"--force\" flag." + if (!$force_arg && in_tarball()); + +# Now that we've verified that we're in the top-level OMPI directory, +# set the sentinel file to remove if we abort. +$sentinel = Cwd::cwd() . "/configure"; + +#--------------------------------------------------------------------------- + +my $step = 1; +verbose "PMIx autogen (buckle up!) + +$step. Checking tool versions\n\n"; + +# Check the autotools revision levels +&find_and_check("autoconf", $pmix_autoconf_search, $pmix_autoconf_version); +&find_and_check("libtool", $pmix_libtoolize_search, $pmix_libtool_version); +&find_and_check("automake", $pmix_automake_search, $pmix_automake_version); + +#--------------------------------------------------------------------------- + +# No platform file -- write an empty list +$m4 .= "m4_define([autogen_platform_file], [])\n\n"; + +if ($exclude_arg) { + debug "Using exclude list: $exclude_arg"; + my @list = split(/,/, $exclude_arg); + foreach (@list) { + my @pairs = split(/-/, $_); + if (exists($pairs[1])) { + # Remove any trailing newlines + chomp($pairs[1]); + debug " Adding ".$pairs[0]."->".$pairs[1]." to exclude list\n"; + push(@{$exclude_list->{$pairs[0]}}, $pairs[1]); + } else { + debug " Adding $pairs[0] to exclude list\n"; + push(@{$exclude_list->{$pairs[0]}}, "AGEN_EXCLUDE_ALL"); + } + } +} +if ($include_arg) { + debug "Using include list: $include_arg"; + my @list = split(/,/, $include_arg); + foreach (@list) { + my @pairs = split(/-/, $_); + if (exists($pairs[1])) { + # Remove any trailing newlines + chomp($pairs[1]); + debug " Adding ".$pairs[0]."->".$pairs[1]." to include list\n"; + push(@{$include_list->{$pairs[0]}}, $pairs[1]); + } + # NOTE: it makes no sense to include all as that is the default + # so ignore that scenario here, if given + } +} + +#--------------------------------------------------------------------------- + +# Find frameworks, components +++$step; +verbose "\n$step. Searching for MCA frameworks and components\n"; + +my $ret; + +# Figure out if we're at the top level of the PMIx tree or not. +if (! (-f "VERSION" && -f "configure.ac" && -f $topdir_file)) { + print("\n\nYou must run this script from the top-level directory of the PMIx tree.\n\n"); + my_exit(1); +} + +$m4 .= "\ndnl Project names +m4_define([project_name_long], [$project_name_long]) +m4_define([project_name_short], [$project_name_short])\n"; + +# Setup MCA +mca_run_global(); + +#--------------------------------------------------------------------------- + +# If we got here, all was good. Run the auto tools. +++$step; +verbose "\n$step. Running autotools on top-level tree\n\n"; + +# Remove old versions of the files (this is probably overkill, but...) +verbose "==> Remove stale files\n"; +find_and_delete(qw/config.guess config.sub depcomp compile install-sh ltconfig + ltmain.sh missing mkinstalldirs libtool/); + +# Remove the old m4 file and write the new one +verbose "==> Writing m4 file with autogen.pl results\n"; +unlink($m4_output_file); +open(M4, ">$m4_output_file") || + my_die "Can't open $m4_output_file"; +print M4 $m4; +close(M4); + +# Run autoreconf +verbose "==> Running autoreconf\n"; +my $cmd = "autoreconf -ivf --warnings=all,no-obsolete,no-override -I config"; +safe_system($cmd); + +#--------------------------------------------------------------------------- + +verbose " +================================================ +PMIx autogen: completed successfully. w00t! +================================================\n\n"; + +# Done! +exit(0); diff --git a/opal/mca/pmix/pmix2x/pmix/autogen.sh b/opal/mca/pmix/pmix2x/pmix/autogen.sh deleted file mode 100755 index b5b509eac8..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/autogen.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# Run all the rest of the Autotools -echo "==> Running autoreconf"; -autoreconf ${autoreconf_args:-"-ivf"} diff --git a/opal/mca/pmix/pmix2x/pmix/config/Makefile.am b/opal/mca/pmix/pmix2x/pmix/config/Makefile.am index e78b92de62..2593f42484 100644 --- a/opal/mca/pmix/pmix2x/pmix/config/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/config/Makefile.am @@ -1,10 +1,7 @@ -# PMIx copyrights: -# Copyright (c) 2013-2015 Intel, Inc. All rights reserved +# Copyright (c) 2013-2016 Intel, Inc. All rights reserved # Copyright (c) 2016 Research Organization for Information Science # and Technology (RIST). All rights reserved. -# -######################### -# +# Copyright (c) 2006-2016 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana # University Research and Technology # Corporation. All rights reserved. @@ -15,10 +12,10 @@ # University of Stuttgart. All rights reserved. # Copyright (c) 2004-2005 The Regents of the University of California. # All rights reserved. -# Copyright (c) 2006-2010 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2010 Oracle and/or its affiliates. All rights # reserved. -######################### +# Copyright (c) 2016 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -26,28 +23,28 @@ # $HEADER$ # -EXTRA_DIST += \ - config/c_get_alignment.m4 \ - config/pmix_get_version.sh \ - config/distscript.sh \ - config/pmix_check_attributes.m4 \ - config/pmix_check_broken_qsort.m4 \ - config/pmix_check_compiler_version.m4 \ - config/pmix_check_icc.m4 \ - config/pmix_check_ident.m4 \ - config/pmix_check_munge.m4 \ - config/pmix_check_package.m4 \ - config/pmix_check_sasl.m4 \ - config/pmix_check_vendor.m4 \ - config/pmix_check_visibility.m4 \ - config/pmix_ensure_contains_optflags.m4 \ - config/pmix_functions.m4 \ - config/pmix.m4 \ - config/pmix_search_libs.m4 \ - config/pmix_setup_cc.m4 \ - config/pmix_setup_hwloc.m4 \ - config/pmix_setup_libevent.m4 +EXTRA_DIST = \ + c_get_alignment.m4 \ + pmix_get_version.sh \ + distscript.sh \ + pmix_check_attributes.m4 \ + pmix_check_broken_qsort.m4 \ + pmix_check_compiler_version.m4 \ + pmix_check_icc.m4 \ + pmix_check_ident.m4 \ + pmix_check_package.m4 \ + pmix_check_vendor.m4 \ + pmix_check_visibility.m4 \ + pmix_config_subdir.m4 \ + pmix_ensure_contains_optflags.m4 \ + pmix_functions.m4 \ + pmix.m4 \ + pmix_search_libs.m4 \ + pmix_setup_cc.m4 \ + pmix_setup_hwloc.m4 \ + pmix_setup_libevent.m4 \ + pmix_mca_priority_sort.pl maintainer-clean-local: - rm -f config/pmix_get_version.sh + rm -f pmix_get_version.sh diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix.m4 index f2d4f16a8a..3b20850a4c 100644 --- a/opal/mca/pmix/pmix2x/pmix/config/pmix.m4 +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix.m4 @@ -10,19 +10,18 @@ dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, dnl University of Stuttgart. All rights reserved. dnl Copyright (c) 2004-2005 The Regents of the University of California. dnl All rights reserved. -dnl Copyright (c) 2006-2015 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2006-2016 Cisco Systems, Inc. All rights reserved. dnl Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. dnl Copyright (c) 2009 IBM Corporation. All rights reserved. dnl Copyright (c) 2009 Los Alamos National Security, LLC. All rights dnl reserved. dnl Copyright (c) 2009-2011 Oak Ridge National Labs. All rights reserved. dnl Copyright (c) 2011-2013 NVIDIA Corporation. All rights reserved. -dnl Copyright (c) 2013-2016 Intel, Inc. All rights reserved +dnl Copyright (c) 2013-2015 Intel, Inc. All rights reserved dnl Copyright (c) 2015 Research Organization for Information Science dnl and Technology (RIST). All rights reserved. dnl Copyright (c) 2016 Mellanox Technologies, Inc. dnl All rights reserved. -dnl Copyright (c) 2016 IBM Corporation. All rights reserved. dnl dnl $COPYRIGHT$ dnl @@ -78,12 +77,13 @@ AC_DEFUN([PMIX_SETUP_CORE],[ if test "$?" != "0"; then AC_MSG_ERROR([Cannot continue]) fi - PMIX_RELEASE_DATE="`$PMIX_top_srcdir/config/pmix_get_version.sh $PMIX_top_srcdir/VERSION --release-date`" + AC_MSG_RESULT([$PMIX_VERSION]) AC_SUBST(PMIX_VERSION) AC_DEFINE_UNQUOTED([PMIX_VERSION], ["$PMIX_VERSION"], [The library version is always available, contrary to VERSION]) + + PMIX_RELEASE_DATE="`$PMIX_top_srcdir/config/pmix_get_version.sh $PMIX_top_srcdir/VERSION --release-date`" AC_SUBST(PMIX_RELEASE_DATE) - AC_MSG_RESULT([$PMIX_VERSION]) # Save the breakdown the version information AC_MSG_CHECKING([for pmix major version]) @@ -92,31 +92,25 @@ AC_DEFUN([PMIX_SETUP_CORE],[ AC_MSG_ERROR([Cannot continue]) fi AC_SUBST(PMIX_MAJOR_VERSION) - AC_DEFINE_UNQUOTED([PMIX_MAJOR_VERSION], ["$PMIX_MAJOR_VERSION"], + AC_DEFINE_UNQUOTED([PMIX_MAJOR_VERSION], [$PMIX_MAJOR_VERSION], [The library major version is always available, contrary to VERSION]) - AC_DEFINE_UNQUOTED([PMIX_VERSION_MAJOR], [${PMIX_MAJOR_VERSION}L], - [The library major version as integer]) - AC_MSG_CHECKING([for pmix minor version]) PMIX_MINOR_VERSION="`$PMIX_top_srcdir/config/pmix_get_version.sh $PMIX_top_srcdir/VERSION --minor`" if test "$?" != "0"; then AC_MSG_ERROR([Cannot continue]) fi AC_SUBST(PMIX_MINOR_VERSION) - AC_DEFINE_UNQUOTED([PMIX_MINOR_VERSION], ["$PMIX_MINOR_VERSION"], + AC_DEFINE_UNQUOTED([PMIX_MINOR_VERSION], [$PMIX_MINOR_VERSION], [The library minor version is always available, contrary to VERSION]) - AC_DEFINE_UNQUOTED([PMIX_VERSION_MINOR], [${PMIX_MINOR_VERSION}L], - [The library minor version as integer]) - AC_MSG_CHECKING([for pmix release version]) PMIX_RELEASE_VERSION="`$PMIX_top_srcdir/config/pmix_get_version.sh $PMIX_top_srcdir/VERSION --release`" if test "$?" != "0"; then AC_MSG_ERROR([Cannot continue]) fi AC_SUBST(PMIX_RELEASE_VERSION) - AC_DEFINE_UNQUOTED([PMIX_RELEASE_VERSION], ["$PMIX_RELEASE_VERSION"], + AC_DEFINE_UNQUOTED([PMIX_RELEASE_VERSION], [$PMIX_RELEASE_VERSION], [The library release version is always available, contrary to VERSION]) # Debug mode? @@ -136,29 +130,11 @@ AC_DEFUN([PMIX_SETUP_CORE],[ AC_MSG_CHECKING([for pmix directory prefix]) AC_MSG_RESULT(m4_ifval([$1], pmix_config_prefix, [(none)])) - AC_CONFIG_HEADERS(pmix_config_prefix[include/pmix/autogen/config.h]) - - # What prefix are we using? - AC_MSG_CHECKING([for pmix symbol prefix]) - AS_IF([test "$pmix_symbol_prefix_value" = ""], - [AS_IF([test "$with_pmix_symbol_prefix" = ""], - [pmix_symbol_prefix_value=pmix_], - [pmix_symbol_prefix_value=$with_pmix_symbol_prefix])]) - AC_DEFINE_UNQUOTED(PMIX_SYM_PREFIX, [$pmix_symbol_prefix_value], - [The pmix symbol prefix]) - # Ensure to [] escape the whole next line so that we can get the - # proper tr tokens - [pmix_symbol_prefix_value_caps="`echo $pmix_symbol_prefix_value | tr '[:lower:]' '[:upper:]'`"] - AC_DEFINE_UNQUOTED(PMIX_SYM_PREFIX_CAPS, [$pmix_symbol_prefix_value_caps], - [The pmix symbol prefix in all caps]) - AC_MSG_RESULT([$pmix_symbol_prefix_value]) - - # Give an easy #define to know if we need to transform all the - # pmix names - AH_TEMPLATE([PMIX_SYM_TRANSFORM], [Whether we need to re-define all the pmix public symbols or not]) - AS_IF([test "$pmix_symbol_prefix_value" = "pmix_"], - [AC_DEFINE([PMIX_SYM_TRANSFORM], [0])], - [AC_DEFINE([PMIX_SYM_TRANSFORM], [1])]) + # Note that private/config.h *MUST* be listed first so that it + # becomes the "main" config header file. Any AC-CONFIG-HEADERS + # after that (pmix/config.h) will only have selective #defines + # replaced, not the entire file. + AC_CONFIG_HEADERS(pmix_config_prefix[src/include/pmix_config.h]) # GCC specifics. if test "x$GCC" = "xyes"; then @@ -324,13 +300,14 @@ AC_DEFUN([PMIX_SETUP_CORE],[ sys/wait.h syslog.h \ time.h unistd.h dirent.h \ crt_externs.h signal.h \ - ioLib.h sockLib.h hostLib.h limits.h]) + ioLib.h sockLib.h hostLib.h limits.h \ + sys/statfs.h sys/statvfs.h]) # Note that sometimes we have , but it doesn't work (e.g., # have both Portland and GNU installed; using pgcc will find GNU's # , which all it does -- by standard -- is define "bool" to # "_Bool" [see - # http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html], + # http://pmixw.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html], # and Portland has no idea what to do with _Bool). # So first figure out if we have (i.e., check the value of @@ -467,6 +444,7 @@ AC_DEFUN([PMIX_SETUP_CORE],[ [#include #include ]) + # # Check for ptrdiff type. Yes, there are platforms where # sizeof(void*) != sizeof(long) (64 bit Windows, apparently). # @@ -487,6 +465,34 @@ AC_DEFUN([PMIX_SETUP_CORE],[ [type to use for ptrdiff_t]) AC_MSG_RESULT([$pmix_ptrdiff_t (size: $pmix_ptrdiff_size)]) + ################################## + # Linker characteristics + ################################## + + AC_MSG_CHECKING([the linker for support for the -fini option]) + PMIX_VAR_SCOPE_PUSH([LDFLAGS_save]) + LDFLAGS_save=$LDFLAGS + LDFLAGS="$LDFLAGS_save -Wl,-fini -Wl,finalize" + AC_TRY_LINK([void finalize (void) {}], [], [AC_MSG_RESULT([yes]) + pmix_ld_have_fini=1], [AC_MSG_RESULT([no]) + pmix_ld_have_fini=0]) + LDFLAGS=$LDFLAGS_save + PMIX_VAR_SCOPE_POP + + pmix_destructor_use_fini=0 + pmix_no_destructor=0 + if test x$pmix_cv___attribute__destructor = x0 ; then + if test x$pmix_ld_have_fini = x1 ; then + pmix_destructor_use_fini=1 + else + pmix_no_destructor=1; + fi + fi + + AC_DEFINE_UNQUOTED(PMIX_NO_LIB_DESTRUCTOR, [$pmix_no_destructor], + [Whether libraries can be configured with destructor functions]) + AM_CONDITIONAL(PMIX_DESTRUCTOR_USE_FINI, [test x$pmix_destructor_use_fini = x1]) + ################################## # Libraries ################################## @@ -501,14 +507,14 @@ AC_DEFUN([PMIX_SETUP_CORE],[ # Darwin doesn't need -lm, as it's a symlink to libSystem.dylib PMIX_SEARCH_LIBS_CORE([ceil], [m]) - AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf strsignal socketpair strncpy_s usleep getpeereid strnlen]) + AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf strsignal socketpair strncpy_s usleep statfs statvfs getpeereid strnlen]) # On some hosts, htonl is a define, so the AC_CHECK_FUNC will get # confused. On others, it's in the standard library, but stubbed with # the magic glibc foo as not implemented. and on other systems, it's # just not there. This covers all cases. AC_CACHE_CHECK([for htonl define], - [ompi_cv_htonl_define], + [pmix_cv_htonl_define], [AC_PREPROC_IFELSE([AC_LANG_PROGRAM([ #ifdef HAVE_SYS_TYPES_H #include @@ -522,12 +528,16 @@ AC_DEFUN([PMIX_SETUP_CORE],[ #ifndef ntohl #error "ntohl not defined" #endif - ])], [ompi_cv_htonl_define=yes], [ompi_cv_htonl_define=no])]) - AC_CHECK_FUNC([htonl], [ompi_have_htonl=yes], [ompi_have_htonl=no]) - AS_IF([test "$ompi_cv_htonl_define" = "yes" || test "$ompi_have_htonl" = "yes"], + ])], [pmix_cv_htonl_define=yes], [pmix_cv_htonl_define=no])]) + AC_CHECK_FUNC([htonl], [pmix_have_htonl=yes], [pmix_have_htonl=no]) + AS_IF([test "$pmix_cv_htonl_define" = "yes" || test "$pmix_have_htonl" = "yes"], [AC_DEFINE_UNQUOTED([HAVE_UNIX_BYTESWAP], [1], [whether unix byteswap routines -- htonl, htons, nothl, ntohs -- are available])]) + # check pandoc separately so we can setup an AM_CONDITIONAL off it + AC_CHECK_PROG([pmix_have_pandoc], [pandoc], [yes], [no]) + AM_CONDITIONAL([PMIX_HAVE_PANDOC], [test "x$pmix_have_pandoc" = "xyes"]) + # # Make sure we can copy va_lists (need check declared, not linkable) # @@ -595,6 +605,18 @@ AC_DEFUN([PMIX_SETUP_CORE],[ PMIX_MUNGE_CONFIG + ################################## + # MCA + ################################## + + pmix_show_title "Modular Component Architecture (MCA) setup" + + AC_MSG_CHECKING([for subdir args]) + PMIX_CONFIG_SUBDIR_ARGS([pmix_subdir_args]) + AC_MSG_RESULT([$pmix_subdir_args]) + + PMIX_MCA + ############################################################################ # final compiler config ############################################################################ @@ -636,7 +658,14 @@ AC_DEFUN([PMIX_SETUP_CORE],[ pmix_show_subtitle "Final output" - AC_CONFIG_FILES(pmix_config_prefix[Makefile]) + AC_CONFIG_FILES( + pmix_config_prefix[Makefile] + pmix_config_prefix[config/Makefile] + pmix_config_prefix[include/Makefile] + pmix_config_prefix[src/Makefile] + pmix_config_prefix[src/util/keyval/Makefile] + pmix_config_prefix[src/mca/base/Makefile] + ) # Success $2 @@ -654,6 +683,16 @@ AC_DEFUN([PMIX_DEFINE_ARGS],[ [pmix_mode=standalone AC_MSG_RESULT([no])]) + # Rename symbols? + AC_ARG_WITH([pmix-symbol-rename], + AC_HELP_STRING([--with-pmix-symbol-rename=FILE], + [Provide an include file that contains directives to rename PMIx symbols])) + AS_IF([test ! -z "$with_pmix_symbol_rename" && test "$with_pmix_symbol_rename" != "yes"], + [pmix_symbol_rename="$with_pmix_symbol_rename"], + [pmix_symbol_rename=\"src/include/rename.h\"]) + AC_DEFINE_UNQUOTED(PMIX_SYMBOL_RENAME, [$pmix_symbol_rename], + [The pmix symbol rename include directive]) + # Install tests and examples? AC_MSG_CHECKING([if tests and examples are to be installed]) AC_ARG_WITH([tests-examples], @@ -665,11 +704,6 @@ AC_DEFUN([PMIX_DEFINE_ARGS],[ [pmix_tests=yes AC_MSG_RESULT([yes])]) - # Change the symbol prefix? - AC_ARG_WITH([pmix-symbol-prefix], - AC_HELP_STRING([--with-pmix-symbol-prefix=STRING], - [STRING can be any valid C symbol name. It will be prefixed to all public PMIx symbols. Default: "pmix_"])) - # # Is this a developer copy? # @@ -751,6 +785,20 @@ else fi AM_CONDITIONAL(WANT_INSTALL_HEADERS, test "$WANT_INSTALL_HEADERS" = 1) +# +# Support per-user config files? +# +AC_ARG_ENABLE([per-user-config-files], + [AC_HELP_STRING([--enable-per-user-config-files], + [Disable per-user configuration files, to save disk accesses during job start-up. This is likely desirable for large jobs. Note that this can also be acheived by environment variables at run-time. (default: enabled)])]) +if test "$enable_per_user_config_files" = "no" ; then + result=0 +else + result=1 +fi +AC_DEFINE_UNQUOTED([PMIX_WANT_HOME_CONFIG_FILES], [$result], + [Enable per-user config files]) + # # Do we want the pretty-print stack trace feature? # @@ -770,26 +818,6 @@ AC_DEFINE_UNQUOTED([PMIX_WANT_PRETTY_PRINT_STACKTRACE], [$WANT_PRETTY_PRINT_STACKTRACE], [if want pretty-print stack trace feature]) -# -# Do we want the shared memory datastore usage? -# - -AC_MSG_CHECKING([if want special dstore usage]) -AC_ARG_ENABLE([dstore], - [AC_HELP_STRING([--enable-dstore], - [Using special datastore (default: disabled)])]) -if test "$enable_dstore" = "yes" ; then - AC_MSG_RESULT([yes]) - WANT_DSTORE=1 -else - AC_MSG_RESULT([no]) - WANT_DSTORE=0 -fi -AC_DEFINE_UNQUOTED([PMIX_ENABLE_DSTORE], - [$WANT_DSTORE], - [if want special dstore feature]) -AM_CONDITIONAL([WANT_DSTORE],[test "x$enable_dstore" = "xyes"]) - # # Ident string # @@ -832,11 +860,22 @@ fi AC_DEFINE_UNQUOTED([PMIX_ENABLE_TIMING], [$WANT_TIMING], [Whether we want developer-level timing support or not]) -])dnl +# +# Install header files +# +AC_MSG_CHECKING([if want to head developer-level header files]) +AC_ARG_WITH(devel-headers, + AC_HELP_STRING([--with-devel-headers], + [also install developer-level header files (only for internal PMIx developers, default: disabled)])) +if test "$with_devel_headers" = "yes"; then + AC_MSG_RESULT([yes]) + WANT_INSTALL_HEADERS=1 +else + AC_MSG_RESULT([no]) + WANT_INSTALL_HEADERS=0 +fi -# Specify the symbol prefix -AC_DEFUN([PMIX_SET_SYMBOL_PREFIX],[ - pmix_symbol_prefix_value=$1 +AM_CONDITIONAL([WANT_INSTALL_HEADERS], [test $WANT_INSTALL_HEADERS -eq 1]) ])dnl # This must be a standalone routine so that it can be called both by diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_config_subdir.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_subdir.m4 new file mode 100644 index 0000000000..ff60f311b0 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_subdir.m4 @@ -0,0 +1,147 @@ +dnl -*- shell-script -*- +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2005 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl Copyright (c) 2012-2016 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2014 Intel, Inc. All rights reserved. +dnl Copyright (c) 2015 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +AC_DEFUN([PMIX_CONFIG_SUBDIR],[ +PMIX_VAR_SCOPE_PUSH([subdir_parent sub_configure subdir_dir subdir_srcdir subdir_cache_file subdir_args subdir_dots total_dir dir_part temp]) + +# +# Invoke configure in a specific subdirectory. +# +# $1 is the directory to invoke in +# $2 is the list of arguments to pass +# $3 is actions to execute upon success +# $4 is actions to execute upon failure +# +subdir_dir="$1" +subdir_args="$2" +subdir_success="$3" +subdir_failure="$4" + +# +# Sanity checks +# + +if test "$subdir_dir" != ":" && test -d $srcdir/$subdir_dir; then + AC_MSG_NOTICE([PMIX configuring in $subdir_dir]) + + # + # Gotta check where srcdir is for VPATH builds. If srcdir is not + # ., then we need to mkdir the subdir. Otherwise, we can just cd + # into it. + # + + case $srcdir in + .) + ;; + *) + { case $subdir_dir in + [[\\/]]* | ?:[[\\/]]* ) total_dir=;; + *) total_dir=.;; + esac + temp=$subdir_dir + for dir_part in `IFS='/\\'; set X $temp; shift; echo "$[@]"`; do + case $dir_part in + # Skip DOS drivespec + ?:) total_dir=$dir_part ;; + *) total_dir=$total_dir/$dir_part + test -d "$total_dir" || + mkdir "$total_dir" || + AC_MSG_ERROR([cannot create $subdir_dir]) + ;; + esac + done; } + + if test -d ./$subdir_dir; then :; + else + AC_MSG_ERROR([cannot create `pwd`/$subdir_dir]) + fi + ;; + esac + + # + # Move into the target directory + # + + subdir_parent=`pwd` + cd $subdir_dir + + # + # Make a "../" for each directory in $subdir_dir. + # + + subdir_dots=`[echo $subdir_dir | sed 's,^\./,,;s,[^/]$,&/,;s,[^/]*/,../,g]'` + # + # Construct the --srcdir argument + # + + case $srcdir in + .) + # In place + subdir_srcdir="$srcdir" + ;; + [[\\/]* | ?:[\\/]*] ) + # Absolute path + subdir_srcdir="$srcdir/$subdir_dir" + ;; + *) + # Relative path + subdir_srcdir="$subdir_dots$srcdir/$subdir_dir" + ;; + esac + + # + # Construct the --cache-file argument + # + + # BWB - subdir caching is a pain since we change CFLAGS and all that. + # Just disable it for now + subdir_cache_file="/dev/null" + + # + # Invoke the configure script in the subdirectory + # + + sub_configure="$SHELL '$subdir_srcdir/configure'" + AC_MSG_NOTICE([running $sub_configure $subdir_args --cache-file=$subdir_cache_file --srcdir=$subdir_srcdir --disable-option-checking]) + eval "$sub_configure $subdir_args \ + --cache-file=\"\$subdir_cache_file\" --srcdir=\"$subdir_srcdir\" --disable-option-checking" + if test "$?" = "0"; then + eval $subdir_success + AC_MSG_NOTICE([$sub_configure succeeded for $subdir_dir]) + else + eval $subdir_failure + AC_MSG_NOTICE([$sub_configure *failed* for $subdir_dir]) + fi + + # + # Go back to the topdir + # + + cd $subdir_parent +fi + +# +# Clean up +# + +PMIX_VAR_SCOPE_POP])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_config_subdir_args.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_subdir_args.m4 new file mode 100644 index 0000000000..2702383796 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_subdir_args.m4 @@ -0,0 +1,84 @@ +dnl -*- shell-script -*- +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2005 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl Copyright (c) 2014-2016 Intel, Inc. All rights reserved. +dnl Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +AC_DEFUN([PMIX_CONFIG_SUBDIR_ARGS],[ +PMIX_VAR_SCOPE_PUSH([subdirs_str subdirs_skip subdirs_args subdirs_arg]) +# +# Invoke configure in subdirectories. +# +# $1 is the name of the variable to assign the output to +# + +# +# Make a list of command line args --eliminate the --srcdir and +# --cache-file args, because we need to replace them with our own +# values when invoking the sub-configure script. Also eliminate +# the --with-platform as this will confuse any subdir with +# similar options +# + +subdirs_args= +subdirs_skip=no + +eval "set x $ac_configure_args" +shift +for subdirs_arg +do + if test "$subdirs_skip" = "yes"; then + subdirs_skip=no + else + case $subdirs_arg in + -cache-file | --cache-file | -cache | --cache) + subdirs_skip=yes + ;; + --config-cache | -C) + ;; + -cache-file=* | --cache-file=*) + ;; + -srcdir | --srcdir) + subdirs_skip=yes + ;; + -srcdir=* | --srcdir=*) + ;; + -with-platform=* | --with-platform=*) + ;; + *) + case $subdir_arg in + *\'*) subdir_arg=`echo "$subdir_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + subdirs_args="$subdirs_args '$subdirs_arg'" + ;; + esac + fi +done + +# +# Assign the output +# + +subdirs_str=$1=\"$subdirs_args\" +eval "$subdirs_str" + +# +# Clean up +# + +PMIX_VAR_SCOPE_POP])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_functions.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_functions.m4 index 5fb6d7a58c..4b1eadcd86 100644 --- a/opal/mca/pmix/pmix2x/pmix/config/pmix_functions.m4 +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_functions.m4 @@ -12,7 +12,7 @@ dnl Copyright (c) 2004-2005 The Regents of the University of California. dnl All rights reserved. dnl Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. dnl Copyright (c) 2009 Oak Ridge National Labs. All rights reserved. -dnl Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2009-2016 Cisco Systems, Inc. All rights reserved. dnl Copyright (c) 2013 Intel, Inc. All rights reserved dnl dnl $COPYRIGHT$ @@ -79,6 +79,15 @@ EOF PMIX_LOG_MSG([--- ${1}], 1) } +pmix_show_verbose() { + if test "$V" = "1"; then + cat <`. It is # preferable to simply using `which ` because backticks (`) (aka # backquotes) invoke a sub-shell which may source a "noisy" diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_mca.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_mca.m4 new file mode 100644 index 0000000000..262e6f4a88 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_mca.m4 @@ -0,0 +1,918 @@ +dnl -*- shell-script -*- +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2005 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl Copyright (c) 2010-2015 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2013-2016 Intel, Inc. All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +# PMIX_EVAL_ARG(arg) +# ------------------ +# evaluates and returns argument +AC_DEFUN([PMIX_EVAL_ARG], [$1]) + +###################################################################### +# +# PMIX_MCA +# +# configure the MCA (modular component architecture). Works hand in hand +# with PMIX's autogen.pl, requiring it's specially formatted lists +# of frameworks, components, etc. +# +# USAGE: +# PMIX_MCA() +# +###################################################################### +AC_DEFUN([PMIX_MCA],[ + dnl for PMIX_CONFIGURE_USER env variable + AC_REQUIRE([PMIX_CONFIGURE_SETUP]) + + # Find which components should be built as run-time loadable components + # Acceptable combinations: + # + # [default -- no option given] + # --enable-mca-dso + # --enable-mca-dso=[.+,]*COMPONENT_TYPE[.+,]* + # --enable-mca-dso=[.+,]*COMPONENT_TYPE-COMPONENT_NAME[.+,]* + # --disable-mca-dso + # + AC_ARG_ENABLE([mca-no-build], + [AC_HELP_STRING([--enable-mca-no-build=LIST], + [Comma-separated list of - pairs + that will not be built. Example: "--enable-mca-no-build=maffinity,btl-portals" will disable building all maffinity components and the "portals" btl components.])]) + AC_ARG_ENABLE(mca-dso, + AC_HELP_STRING([--enable-mca-dso=LIST], + [Comma-separated list of types and/or + type-component pairs that will be built as + run-time loadable components (as opposed to + statically linked in), if supported on this + platform. The default is to build all components + as DSOs.])) + AC_ARG_ENABLE(mca-static, + AC_HELP_STRING([--enable-mca-static=LIST], + [Comma-separated list of types and/or + type-component pairs that will be built statically + linked into the library. The default (if DSOs are + supported) is to build all components as DSOs. + Enabling a component as static disables it + building as a DSO.])) + AC_ARG_ENABLE(mca-direct, + AC_HELP_STRING([--enable-mca-direct=LIST], + [Comma-separated list of type-component pairs that + will be hard coded as the one component to use for + a given component type, saving the (small) + overhead of the component architecture. LIST must + not be empty and implies given component pairs are + build as static components.])) + + AC_MSG_CHECKING([which components should be disabled]) + if test "$enable_mca_no_build" = "yes"; then + AC_MSG_RESULT([yes]) + AC_MSG_ERROR([*** The enable-mca-no-build flag requires an explicit list +*** of type-component pairs. For example, --enable-mca-direct=pml-ob1]) + else + ifs_save="$IFS" + IFS="${IFS}$PATH_SEPARATOR," + msg= + for item in $enable_mca_no_build; do + type="`echo $item | cut -s -f1 -d-`" + comp="`echo $item | cut -s -f2- -d-`" + if test -z $type ; then + type=$item + fi + if test -z $comp ; then + str="`echo DISABLE_${type}=1 | sed s/-/_/g`" + eval $str + msg="$item $msg" + else + str="`echo DISABLE_${type}_${comp}=1 | sed s/-/_/g`" + eval $str + msg="$item $msg" + fi + done + IFS="$ifs_save" + fi + AC_MSG_RESULT([$msg]) + unset msg + + # + # First, add all the mca-direct components / types into the mca-static + # lists and create a list of component types that are direct compile, + # in the form DIRECT_[type]=[component] + # + AC_MSG_CHECKING([which components should be direct-linked into the library]) + if test "$enable_mca_direct" = "yes" ; then + AC_MSG_RESULT([yes]) + AC_MSG_ERROR([*** The enable-mca-direct flag requires an explicit list of +*** type-component pairs. For example, --enable-mca-direct=pml-ob1,coll-basic]) + elif test ! -z "$enable_mca_direct" && test "$enable_mca_direct" != "" ; then + # + # we need to add this into the static list, unless the static list + # is everything + # + if test "$enable_mca_static" = "no" ; then + AC_MSG_WARN([*** Re-enabling static component support for direct call]) + enable_mca_static="$enable_mca_direct" + elif test -z "$enable_mca_static" ; then + enable_mca_static="$enable_mca_direct" + elif test "$enable_mca_static" != "yes" ; then + enable_mca_static="$enable_mca_direct,$enable_mca_static" + fi + + ifs_save="$IFS" + IFS="${IFS}$PATH_SEPARATOR," + msg= + for item in $enable_mca_direct; do + type="`echo $item | cut -f1 -d-`" + comp="`echo $item | cut -f2- -d-`" + if test -z $type || test -z $comp ; then + AC_MSG_ERROR([*** The enable-mca-direct flag requires a +*** list of type-component pairs. Invalid input detected.]) + else + str="`echo DIRECT_$type=$comp | sed s/-/_/g`" + eval $str + msg="$item $msg" + fi + done + IFS="$ifs_save" + fi + AC_MSG_RESULT([$msg]) + unset msg + + # + # Second, set the DSO_all and STATIC_all variables. conflict + # resolution (prefer static) is done in the big loop below + # + AC_MSG_CHECKING([which components should be run-time loadable]) + if test "$enable_static" != "no"; then + DSO_all=0 + msg=none + elif test -z "$enable_mca_dso" || test "$enable_mca_dso" = "yes"; then + DSO_all=1 + msg=all + elif test "$enable_mca_dso" = "no"; then + DSO_all=0 + msg=none + else + DSO_all=0 + ifs_save="$IFS" + IFS="${IFS}$PATH_SEPARATOR," + msg= + for item in $enable_mca_dso; do + str="`echo DSO_$item=1 | sed s/-/_/g`" + eval $str + msg="$item $msg" + done + IFS="$ifs_save" + fi + AC_MSG_RESULT([$msg]) + unset msg + if test "$enable_static" != "no"; then + AC_MSG_WARN([*** Shared libraries have been disabled (--disable-shared)]) + AC_MSG_WARN([*** Building MCA components as DSOs automatically disabled]) + fi + + AC_MSG_CHECKING([which components should be static]) + if test "$enable_mca_static" = "yes"; then + STATIC_all=1 + msg=all + elif test -z "$enable_mca_static" || test "$enable_mca_static" = "no"; then + STATIC_all=0 + msg=none + else + STATIC_all=0 + ifs_save="$IFS" + IFS="${IFS}$PATH_SEPARATOR," + msg= + for item in $enable_mca_static; do + str="`echo STATIC_$item=1 | sed s/-/_/g`" + eval $str + msg="$item $msg" + done + IFS="$ifs_save" + fi + AC_MSG_RESULT([$msg]) + unset msg + + # now configure the PMIx project. Most + # of the hard stuff is in here + MCA_PROJECT_SUBDIRS= + + # can't use a variable rename here because these need to be evaled + # at auto* time. + + pmix_show_subtitle "Configuring MCA" + + AC_MSG_CHECKING([for frameworks]) + AC_MSG_RESULT([mca_pmix_framework_list]) + + # iterate through the list of frameworks. There is something + # funky with m4 foreach if the list is defined, but empty. It + # will call the 3rd argument once with an empty value for the + # first argument. Protect against calling MCA_CONFIGURE_FRAMEWORK + # with an empty second argument. Grrr.... + # if there isn't a project list, abort + # + # Also setup two variables for Makefiles: + # MCA_project_FRAMEWORKS - list of frameworks in that project + # MCA_project_FRAMEWORK_LIBS - list of libraries (or variables pointing + # to more libraries) that must be included + # in the project's main library + m4_ifdef([mca_pmix_framework_list], [], + [m4_fatal([Could not find mca_pmix_framework_list - please rerun autogen.pl])]) + + MCA_pmix_FRAMEWORKS= + MCA_pmix_FRAMEWORKS_SUBDIRS= + MCA_pmix_FRAMEWORK_COMPONENT_ALL_SUBDIRS= + MCA_pmix_FRAMEWORK_COMPONENT_DSO_SUBDIRS= + MCA_pmix_FRAMEWORK_COMPONENT_STATIC_SUBDIRS= + MCA_pmix_FRAMEWORK_LIBS= + + m4_foreach(mca_framework, [mca_pmix_framework_list], + [m4_ifval(mca_framework, + [dnl common has to go up front + m4_if(mca_framework, [common], + [MCA_pmix_FRAMEWORKS="mca_framework $MCA_pmix_FRAMEWORKS" + MCA_pmix_FRAMEWORKS_SUBDIRS="[mca/]mca_framework $MCA_pmix_FRAMEWORKS_SUBDIRS" + MCA_pmix_FRAMEWORK_COMPONENT_ALL_SUBDIRS="[\$(MCA_pmix_]mca_framework[_ALL_SUBDIRS)] $MCA_pmix_FRAMEWORK_COMPONENT_ALL_SUBDIRS" + MCA_pmix_FRAMEWORK_COMPONENT_DSO_SUBDIRS="[\$(MCA_pmix_]mca_framework[_DSO_SUBDIRS)] $MCA_pmix_FRAMEWORK_COMPONENT_DSO_SUBDIRS" + MCA_pmix_FRAMEWORK_COMPONENT_STATIC_SUBDIRS="[\$(MCA_pmix_]mca_framework[_STATIC_SUBDIRS)] $MCA_pmix_FRAMEWORK_COMPONENT_STATIC_SUBDIRS" + ], [ + MCA_pmix_FRAMEWORKS="$MCA_pmix_FRAMEWORKS mca_framework" + MCA_pmix_FRAMEWORKS_SUBDIRS="$MCA_pmix_FRAMEWORKS_SUBDIRS [mca/]mca_framework" + MCA_pmix_FRAMEWORK_COMPONENT_ALL_SUBDIRS="$MCA_pmix_FRAMEWORK_COMPONENT_ALL_SUBDIRS [\$(MCA_pmix_]mca_framework[_ALL_SUBDIRS)]" + MCA_pmix_FRAMEWORK_COMPONENT_DSO_SUBDIRS="$MCA_pmix_FRAMEWORK_COMPONENT_DSO_SUBDIRS [\$(MCA_]pmix[_]mca_framework[_DSO_SUBDIRS)]" + MCA_pmix_FRAMEWORK_COMPONENT_STATIC_SUBDIRS="$MCA_pmix_FRAMEWORK_COMPONENT_STATIC_SUBDIRS [\$(MCA_pmix_]mca_framework[_STATIC_SUBDIRS)]" + MCA_pmix_FRAMEWORK_LIBS="$MCA_pmix_FRAMEWORK_LIBS [mca/]mca_framework[/libmca_]mca_framework[.la]"]) + MCA_pmix_FRAMEWORK_LIBS="$MCA_pmix_FRAMEWORK_LIBS [\$(MCA_pmix_]mca_framework[_STATIC_LTLIBS)]" + m4_ifdef([MCA_pmix_]mca_framework[_CONFIG], + [MCA_pmix_]mca_framework[_CONFIG](mca_framework), + [MCA_CONFIGURE_FRAMEWORK(mca_framework, 1)])])]) + + # note that mca_wrapper_extra_* is a running list, and we take checkpoints at the end of our project + pmix_mca_wrapper_extra_cppflags="$mca_wrapper_extra_cppflags" + pmix_mca_wrapper_extra_ldflags="$mca_wrapper_extra_ldflags" + pmix_mca_wrapper_extra_libs="$mca_wrapper_extra_libs" + + AC_SUBST(MCA_pmix_FRAMEWORKS) + AC_SUBST(MCA_pmix_FRAMEWORKS_SUBDIRS) + AC_SUBST(MCA_pmix_FRAMEWORK_COMPONENT_ALL_SUBDIRS) + AC_SUBST(MCA_pmix_FRAMEWORK_COMPONENT_DSO_SUBDIRS) + AC_SUBST(MCA_pmix_FRAMEWORK_COMPONENT_STATIC_SUBDIRS) + AC_SUBST(MCA_pmix_FRAMEWORK_LIBS) + + AC_SUBST(MCA_PROJECT_SUBDIRS) + +]) + +# MCA_ORDER_COMPONENT_LIST(framework_name) +AC_DEFUN([MCA_ORDER_COMPONENT_LIST], [ + m4_foreach(mca_component, [mca_pmix_$1_m4_config_component_list], + [m4_ifval(mca_component, + [m4_ifdef([MCA_pmix_]$1[_]mca_component[_PRIORITY], [], + [m4_fatal([MCA_pmix_$1_]mca_component[_PRIORITY not found, but required.])])])]) + m4_define([component_list], + [esyscmd([config/pmix_mca_priority_sort.pl] m4_foreach([mca_component], [mca_pmix_$1_m4_config_component_list], + [m4_ifval(mca_component, [mca_component ]PMIX_EVAL_ARG([MCA_pmix_]$1[_]mca_component[_PRIORITY ]))]))]) +]) + +AC_DEFUN([MCA_CHECK_IGNORED_PRIORITY], [ + m4_foreach(mca_component, [mca_pmix_$1_m4_config_component_list], + [m4_ifval(mca_component, + [m4_ifdef([MCA_pmix_]$1[_]mca_component[_PRIORITY], + [m4_warn([unsupported], [MCA_pmix_]$1[_]mca_component[_PRIORITY found, but ignored.])])])]) +]) + + +###################################################################### +# +# MCA_CONFIGURE_FRAMEWORK +# +# Configure the given framework and all components inside the +# framework. Assumes that the framework is located in +# src/mca/[framework], and that all components are +# available under the framework directory. Will configure all +# no-configure and builtin components, then search for components with +# configure scripts. Assumes that no component is marked as builtin +# AND has a configure script. +# +# USAGE: +# MCA_CONFIGURE_FRAMEWORK(framework_name, allow_succeed) +# +###################################################################### +AC_DEFUN([MCA_CONFIGURE_FRAMEWORK],[ + pmix_show_subsubtitle "Configuring MCA framework $1" + + m4_ifdef([mca_pmix_$1_no_config_component_list], [], + [m4_fatal([Could not find mca_pmix_$1_no_config_component_list - please rerun autogen.pl])]) + m4_ifdef([mca_pmix_$1_m4_config_component_list], [], + [m4_fatal([Could not find mca_pmix_$1_m4_config_component_list - please rerun autogen.pl])]) + + # setup for framework + all_components= + static_components= + dso_components= + static_ltlibs= + + # Ensure that the directory where the #include file is to live + # exists. Need to do this for VPATH builds, because the directory + # may not exist yet. For the "common" type, it's not really a + # component, so it doesn't have a base. + m4_if([$1], [common], [outdir=src/mca/common], [outdir=src/mca/$1/base]) + AS_MKDIR_P([$outdir]) + + # emit Makefile rule + AC_CONFIG_FILES([src/mca/$1/Makefile]) + + # remove any previously generated #include files + outfile_real=$outdir/static-components.h + outfile=$outfile_real.new + rm -f $outfile $outfile.struct $outfile.extern + touch $outfile.struct $outfile.extern + + # print some nice messages about what we're about to do... + AC_MSG_CHECKING([for no configure components in framework $1]) + AC_MSG_RESULT([mca_pmix_$1_no_config_component_list]) + AC_MSG_CHECKING([for m4 configure components in framework $1]) + AC_MSG_RESULT([mca_pmix_$1_m4_config_component_list]) + + # If there are components in the no configure list, but we're + # doing one of the "special" selection logics, abort with a + # reasonable message. + m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [STOP_AT_FIRST], + [m4_ifval(mca_pmix_$1_no_config_component_list, + [m4_fatal([Framework $1 using STOP_AT_FIRST but at least one component has no configure.m4])])]) + m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [STOP_AT_FIRST_PRIORITY], + [m4_ifval(mca_pmix_$1_no_config_component_list, + [m4_fatal([Framework $1 using STOP_AT_FIRST_PRIORITY but at least one component has no configure.m4])])]) + m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [PRIORITY], + [m4_ifval(mca_pmix_$1_no_config_component_list, + [m4_fatal([Framework $1 using PRIORITY but at least one component has no configure.m4])])]) + # run the configure logic for the no-config components + m4_foreach(mca_component, [mca_pmix_$1_no_config_component_list], + [m4_ifval(mca_component, + [MCA_CONFIGURE_NO_CONFIG_COMPONENT($1, mca_component, + [all_components], + [static_components], + [dso_components], + [static_ltlibs], + [$2])])]) + + # configure components that use built-in configuration scripts + m4_ifdef([component_list], [m4_undefine([component_list])]) + m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [STOP_AT_FIRST], [MCA_ORDER_COMPONENT_LIST($1)], + [m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [STOP_AT_FIRST_PRIORITY], [MCA_ORDER_COMPONENT_LIST($1)], + [m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [PRIORITY], [MCA_ORDER_COMPONENT_LIST($1)], + [m4_define([component_list], [mca_pmix_$1_m4_config_component_list])])])]) + + best_mca_component_priority=0 + components_looking_for_succeed=$2 + components_last_result=0 + m4_foreach(mca_component, [component_list], + [m4_ifval(mca_component, + [m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [STOP_AT_FIRST_PRIORITY], + [AS_IF([test $best_mca_component_priority -gt MCA_pmix_$1_]mca_component[_PRIORITY], [components_looking_for_succeed=0])]) + MCA_CONFIGURE_M4_CONFIG_COMPONENT($1, mca_component, + [all_components], + [static_components], + [dso_components], + [static_ltlibs], + [$components_looking_for_succeed], + [components_last_result=1], + [components_last_result=0]) + m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [STOP_AT_FIRST], + [AS_IF([test $components_last_result -eq 1], [components_looking_for_succeed=0])]) + m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [STOP_AT_FIRST_PRIORITY], + [AS_IF([test $components_last_result -eq 1], [best_mca_component_priority=]PMIX_EVAL_ARG([MCA_pmix_$1_]mca_component[_PRIORITY]))]) + ])]) + + # configure components that provide their own configure script. + # It would be really hard to run these for "find first that + # works", so we don't :) + m4_if(PMIX_EVAL_ARG([MCA_pmix_]$1[_CONFIGURE_MODE]), [STOP_AT_FIRST], [], + [m4_if(PMIX_EVAL_ARG([MCA_pmix_]$1[_CONFIGURE_MODE]), [STOP_AT_FIRST_PRIORITY], [], + [m4_if(PMIX_EVAL_ARG([MCA_pmix_]$1[_CONFIGURE_MODE]), [PRIORITY], [], + [MCA_CHECK_IGNORED_PRIORITY($1) + AS_IF([test "$2" != "0"], + [MCA_CONFIGURE_ALL_CONFIG_COMPONENTS($1, [all_components], + [static_components], [dso_components], + [static_ltlibs])])])])]) + + MCA_pmix_$1_ALL_COMPONENTS="$all_components" + MCA_pmix_$1_STATIC_COMPONENTS="$static_components" + MCA_pmix_$1_DSO_COMPONENTS="$dso_components" + MCA_pmix_$1_STATIC_LTLIBS="$static_ltlibs" + + AC_SUBST(MCA_pmix_$1_ALL_COMPONENTS) + AC_SUBST(MCA_pmix_$1_STATIC_COMPONENTS) + AC_SUBST(MCA_pmix_$1_DSO_COMPONENTS) + AC_SUBST(MCA_pmix_$1_STATIC_LTLIBS) + + PMIX_MCA_MAKE_DIR_LIST(MCA_pmix_$1_ALL_SUBDIRS, $1, [$all_components]) + PMIX_MCA_MAKE_DIR_LIST(MCA_pmix_$1_STATIC_SUBDIRS, $1, [$static_components]) + PMIX_MCA_MAKE_DIR_LIST(MCA_pmix_$1_DSO_SUBDIRS, $1, [$dso_components]) + + # Create the final .h file that will be included in the type's + # top-level glue. This lists all the static components. We don't + # need to do this for "common". + if test "$2" != "common"; then + cat > $outfile < /dev/null 2>&1 + if test "$?" != "0"; then + mv $outfile $outfile_real + else + rm -f $outfile + fi + fi + rm -f $outfile.struct $outfile.extern + + unset all_components static_components dso_components outfile outfile_real +]) + + +###################################################################### +# +# MCA_CONFIGURE_NO_CONFIG_COMPONENT +# +# Configure the given framework and all components inside the framework. +# Assumes that the framework is located in [project_name]/mca/[framework], +# and that all components are available under the framework directory. +# Will configure all builtin components, then search for components with +# configure scripts. Assumes that no component is marked as builtin +# AND has a configure script. +# +# USAGE: +# MCA_CONFIGURE_PROJECT(framework_name, component_name +# all_components_variable, +# static_components_variable, +# dso_components_variable, +# static_ltlibs_variable, +# allowed_to_succeed) +# +###################################################################### +AC_DEFUN([MCA_CONFIGURE_NO_CONFIG_COMPONENT],[ + pmix_show_subsubsubtitle "MCA component $1:$2 (no configuration)" + + pmix_show_verbose "PMIX_MCA_NO_CONFIG_COMPONENT: before, should_build=$7" + MCA_COMPONENT_BUILD_CHECK($1, $2, + [should_build=$7], [should_build=0]) + MCA_COMPONENT_COMPILE_MODE($1, $2, compile_mode) + pmix_show_verbose "PMIX_MCA_NO_CONFIG_COMPONENT: after, should_build=$should_build" + + if test "$should_build" = "1" ; then + MCA_PROCESS_COMPONENT($1, $2, $3, $4, $5, $6, $compile_mode) + else + MCA_PROCESS_DEAD_COMPONENT($1, $2) + # add component to all component list + $3="$$3 $2" + fi + + # set the AM_CONDITIONAL on how we should build + if test "$compile_mode" = "dso" ; then + BUILD_pmix_$1_$2_DSO=1 + else + BUILD_pmix_$1_$2_DSO=0 + fi + AM_CONDITIONAL(MCA_BUILD_pmix_$1_$2_DSO, test "$BUILD_pmix_$1_$2_DSO" = "1") + + AC_CONFIG_FILES([src/mca/$1/$2/Makefile]) + + unset compile_mode +]) + + +###################################################################### +# +# MCA_CONFIGURE_M4_CONFIG_COMPONENT +# +# +# USAGE: +# MCA_CONFIGURE_PROJECT(framework_name, component_name +# all_components_variable, +# static_components_variable, +# dso_components_variable, +# static_ltlibs_variable, +# allowed_to_succeed, +# [eval if should build], +# [eval if should not build]) +# +###################################################################### +AC_DEFUN([MCA_CONFIGURE_M4_CONFIG_COMPONENT],[ + m4_ifdef([MCA_pmix_$1_$2_PRIORITY], + [pmix_show_subsubsubtitle "MCA component $1:$2 (m4 configuration macro, priority MCA_pmix_$1_$2_PRIORITY)"], + [pmix_show_subsubsubtitle "MCA component $1:$2 (m4 configuration macro)"]) + + pmix_show_verbose "PMIX_MCA_M4_CONFIG_COMPONENT: before, should_build=$7" + MCA_COMPONENT_BUILD_CHECK($1, $2, [should_build=$7], [should_build=0]) + # Allow the component to override the build mode if it really wants to. + # It is, of course, free to end up calling MCA_COMPONENT_COMPILE_MODE + m4_ifdef([MCA_pmix_$1_$2_COMPILE_MODE], + [MCA_pmix_$1_$2_COMPILE_MODE($1, $2, compile_mode)], + [MCA_COMPONENT_COMPILE_MODE($1, $2, compile_mode)]) + + # try to configure the component + m4_ifdef([MCA_pmix_$1_$2_CONFIG], + [MCA_pmix_$1_$2_CONFIG([should_build=$should_build], + [should_build=0])], + [m4_fatal([MCA_pmix_$1_$2_CONFIG macro not found])]) + pmix_show_verbose "PMIX_MCA_M4_CONFIG_COMPONENT: after, should_build=$should_build" + + AS_IF([test "$should_build" = "1"], + [MCA_PROCESS_COMPONENT($1, $2, $3, $4, $5, $6, $compile_mode)], + [MCA_PROCESS_DEAD_COMPONENT($1, $2) + # add component to all component list + $3="$$3 $2"]) + + m4_ifdef([MCA_pmix_$1_$2_POST_CONFIG], + [ MCA_pmix_$1_$2_POST_CONFIG($should_build)]) + + # set the AM_CONDITIONAL on how we should build + AS_IF([test "$compile_mode" = "dso"], + [BUILD_pmix_$1_$2_DSO=1], + [BUILD_pmix_$1_$2_DSO=0]) + AM_CONDITIONAL(MCA_BUILD_pmix_$1_$2_DSO, test "$BUILD_pmix_$1_$2_DSO" = "1") + + AS_IF([test "$should_build" = "1"], [$8], [$9]) + + unset compile_mode +]) + + +###################################################################### +# +# MCA_CONFIGURE_ALL_CONFIG_COMPONENTS +# +# configure all components in the given framework that have configure +# scripts and should be configured according to the usual rules... +# +# USAGE: +# MCA_CONFIGURE_ALL_CONFIG_COMPONENTS(framework_name, +# all_components_variable, +# static_components_variable, +# dso_components_variable, +# static_ltlibs_variable) +# +###################################################################### +AC_DEFUN([MCA_CONFIGURE_ALL_CONFIG_COMPONENTS],[ + for component_path in $srcdir/src/mca/$1/* ; do + component="`basename $component_path`" + if test -d $component_path && test -x $component_path/configure ; then + pmix_show_subsubsubtitle "MCA component $1:$component (need to configure)" + + pmix_show_verbose "PMIX_MCA_ALL_CONFIG_COMPONENTS: before, should_build=$7" + MCA_COMPONENT_BUILD_CHECK($1, $component, + [should_build=1], [should_build=0]) + MCA_COMPONENT_COMPILE_MODE($1, $component, compile_mode) + pmix_show_verbose "PMIX_MCA_ALL_CONFIG_COMPONENTS: after, should_build=$should_build" + + if test "$should_build" = "1" ; then + PMIX_CONFIG_SUBDIR([src/mca/$1/$component], + [$pmix_subdir_args], + [should_build=1], [should_build=0]) + pmix_show_verbose "PMIX_MCA_ALL_CONFIG_COMPONENTS: after subdir, should_build=$should_build" + fi + + if test "$should_build" = "1" ; then + # do some extra work to pass flags back from the + # top-level configure, the way a configure.m4 + # component would. + infile="$srcdir/src/mca/$1/$2/post_configure.sh" + if test -f $infile; then + + # First check for the ABORT tag + line="`$GREP ABORT= $infile | cut -d= -f2-`" + if test -n "$line" && test "$line" != "no"; then + AC_MSG_WARN([MCA component configure script told me to abort]) + AC_MSG_ERROR([cannot continue]) + fi + + m4_foreach(flags, [LDFLAGS, LIBS], + [[line="`$GREP WRAPPER_EXTRA_]flags[= $infile | cut -d= -f2-`"] + eval "line=$line" + if test -n "$line"; then + $2[_]$3[_WRAPPER_EXTRA_]flags[="$line"] + fi + ])dnl + fi + + MCA_PROCESS_COMPONENT($1, $component, $2, $3, $4, $5, $compile_mode) + else + MCA_PROCESS_DEAD_COMPONENT($1, $component) + fi + fi + done +]) + + +# MCA_COMPONENT_COMPILE_MODE(framework_name (1), +# component_name (2), compile_mode_variable (3)) +# ------------------------------------------------------------------------- +# set compile_mode_variable to the compile mode for the given component +# +# NOTE: component_name may not be determined until runtime.... +AC_DEFUN([MCA_COMPONENT_COMPILE_MODE],[ + SHARED_FRAMEWORK="$DSO_$1" + AS_LITERAL_IF([$2], + [SHARED_COMPONENT="$DSO_$1_$2"], + [str="SHARED_COMPONENT=\$DSO_$1_$2" + eval $str]) + + STATIC_FRAMEWORK="$STATIC_$1" + AS_LITERAL_IF([$2], + [STATIC_COMPONENT="$STATIC_$1_$2"], + [str="STATIC_COMPONENT=\$STATIC_$1_$2" + eval $str]) + + shared_mode_override=static + + # Setup for either shared or static + if test "$STATIC_FRAMEWORK" = "1" || \ + test "$STATIC_COMPONENT" = "1" || \ + test "$STATIC_all" = "1" ; then + $3="static" + elif test "$shared_mode_override" = "dso" || \ + test "$SHARED_FRAMEWORK" = "1" || \ + test "$SHARED_COMPONENT" = "1" || \ + test "$DSO_all" = "1"; then + $3="dso" + else + $3="static" + fi + + AC_MSG_CHECKING([for MCA component $1:$2 compile mode]) + if test "$DIRECT_$1" = "$2" ; then + AC_MSG_RESULT([$$3 - direct]) + else + AC_MSG_RESULT([$$3]) + fi +]) + + +# MCA_PROCESS_COMPONENT(framework_name (1), component_name (2), +# all_components_variable (3), static_components_variable (4) +# dso_components_variable (5), static_ltlibs_variable (6), +# compile_mode_variable (7)) +#--------------------------------------------------------------------- +# Final setup work for a given component. It should be known before +# calling that this component can build properly (and exists) +# +# NOTE: component_name may not be determined until runtime.... +AC_DEFUN([MCA_PROCESS_COMPONENT],[ + AC_REQUIRE([AC_PROG_GREP]) + + # See if it dropped an output file for us to pick up some + # shell variables in. + infile="$srcdir/src/mca/$1/$2/post_configure.sh" + + # Add this subdir to the mast list of all MCA component subdirs + $3="$$3 $2" + + if test "$7" = "dso" ; then + $5="$$5 $2" + else + if test "$1" = "common"; then + # Static libraries in "common" frameworks are installed, and + # therefore must obey the $FRAMEWORK_LIB_PREFIX that was + # set. + $6="mca/$1/$2/lib${m4_translit([pmix], [a-z], [A-Z])_LIB_PREFIX}mca_$1_$2.la $$6" + else + # Other frameworks do not have to obey the + # $FRAMEWORK_LIB_PREFIX prefix. + $6="mca/$1/$2/libmca_$1_$2.la $$6" + fi + echo "extern const pmix_mca_base_component_t mca_$1_$2_component;" >> $outfile.extern + echo " &mca_$1_$2_component, " >> $outfile.struct + $4="$$4 $2" + fi + + # Output pretty results + AC_MSG_CHECKING([if MCA component $1:$2 can compile]) + AC_MSG_RESULT([yes]) + + dnl BWB: FIX ME: We still use the post_configure.sh for frameworks that use the direct call infrastructure. + dnl All other uses we can ignore here, because config_components will have read it in and set all the + dnl proper environment variables. At some point, we should handle the direct call stuff the same way we + dnl handle the headers for static components like timers in PMIx, ie, have a framework level configure.m4 that + dnl does the right thing + if test -f $infile; then + # check for direct call header to include. This will be + # AC_SUBSTed later. + if test "$DIRECT_$1" = "$2" ; then + if test "`$GREP DIRECT_CALL_HEADER $infile`" != "" ; then + line="`$GREP DIRECT_CALL_HEADER $infile | cut -d= -f2-`" + str="MCA_pmix_$1_DIRECT_CALL_HEADER=$line" + eval $str + else +AC_MSG_ERROR([*** $1 component $2 was supposed to be direct-called, but +*** does not appear to support direct calling. +*** Aborting]) + fi + fi + else + # were we supposed to have found something in the + # post_configure.sh, but the file didn't exist? + if test "$DIRECT_$1" = "$2" ; then +AC_MSG_ERROR([*** $1 component $2 was supposed to be direct-called, but +*** does not appear to support direct calling. +*** Aborting]) + fi + fi + + # if the component is building, add it's WRAPPER_EXTRA_LDFLAGS and + # WRAPPER_EXTRA_LIBS. If the component doesn't specify it's + # WRAPPER_EXTRA_LIBS and WRAPPER_EXTRA_LDFLAGS, try using LDFLAGS and LIBS if + # component didn't have it's own configure script (in which case, + # we know it didn't set LDFLAGS and LIBS because it can't) Don't + # have to do this if the component is building dynamically, + # because it will link against these (without a dependency from + # libmpi.so to these flags) + if test "$7" = "static"; then + AS_LITERAL_IF([$2], + [m4_foreach(flags, [LDFLAGS, LIBS], + [AS_IF([test "$$1_$2_WRAPPER_EXTRA_]flags[" = ""], + [PMIX_FLAGS_APPEND_UNIQ([mca_wrapper_extra_]m4_tolower(flags), [$$1_$2_]flags)], + [PMIX_FLAGS_APPEND_UNIQ([mca_wrapper_extra_]m4_tolower(flags), [$$1_$2_WRAPPER_EXTRA_]flags)]) + ])], + [m4_foreach(flags, [LDFLAGS, LIBS], + [[str="line=\$$1_$2_WRAPPER_EXTRA_]flags["] + eval "$str" + PMIX_FLAGS_APPEND_UNIQ([mca_wrapper_extra_]m4_tolower(flags), [$line])])]) + fi + + # if needed, copy over WRAPPER_EXTRA_CPPFLAGS. Since a configure script + # component can never be used in a STOP_AT_FIRST framework, we + # don't have to implement the else clause in the literal check... + AS_LITERAL_IF([$2], + [AS_IF([test "$$1_$2_WRAPPER_EXTRA_CPPFLAGS" != ""], + [m4_if(PMIX_EVAL_ARG([MCA_pmix_$1_CONFIGURE_MODE]), [STOP_AT_FIRST], [stop_at_first=1], [stop_at_first=0]) + AS_IF([test "$7" = "static" && test "$stop_at_first" = "1"], + [AS_IF([test "$with_devel_headers" = "yes"], + [PMIX_FLAGS_APPEND_UNIQ([mca_wrapper_extra_cppflags], [$$1_$2_WRAPPER_EXTRA_CPPFLAGS])])], + [AC_MSG_WARN([ignoring $1_$2_WRAPPER_EXTRA_CPPFLAGS ($$1_$2_WRAPPER_EXTRA_CPPFLAGS): component conditions not met])])])]) +]) + + +# MCA_PROCESS_DEAD_COMPONENT(framework_name (1), +# component_name (2)) +# ---------------------------------------------------------------- +# Finall setup work for a component that can not be built. Do the +# last minute checks to make sure the user isn't doing something +# stupid. +# +# NOTE: component_name may not be determined until runtime.... +AC_DEFUN([MCA_PROCESS_DEAD_COMPONENT],[ + AC_MSG_CHECKING([if MCA component $1:$2 can compile]) + AC_MSG_RESULT([no]) + + # If this component was requested as the default for this + # type, then abort. + if test "$with_$1" = "$2" ; then + AC_MSG_WARN([MCA component "$2" failed to configure properly]) + AC_MSG_WARN([This component was selected as the default]) + AC_MSG_ERROR([Cannot continue]) + fi + + if test ! -z "$DIRECT_$1" ; then + if test "$DIRECT_$1" = "$2" ; then + AC_MSG_WARN([MCA component "$2" failed to configure properly]) + AC_MSG_WARN([This component was selected as the default (direct call)]) + AC_MSG_ERROR([Cannot continue]) + fi + fi +]) + + +# MCA_COMPONENT_BUILD_CHECK(framework_name(1), +# component_name (2), action-if-build (3) +# action-if-not-build (4) +# ----------------------------------------------------------------- +# checks the standard rules of component building to see if the +# given component should be built. +# +# Note: component_name may not be determined until runtime.... +AC_DEFUN([MCA_COMPONENT_BUILD_CHECK],[ + AC_REQUIRE([AC_PROG_GREP]) + + component_path="$srcdir/src/mca/$1/$2" + want_component=0 + + # build if: + # - the component type is direct and we are that component + # - there is no pmix_ignore file + # - there is an pmix_ignore, but there is an empty pmix_unignore + # - there is an pmix_ignore, but username is in pmix_unignore + if test -d $component_path ; then + # decide if we want the component to be built or not. This + # is spread out because some of the logic is a little complex + # and test's syntax isn't exactly the greatest. We want to + # build the component by default. + want_component=1 + if test -f $component_path/.pmix_ignore ; then + # If there is an pmix_ignore file, don't build + # the component. Note that this decision can be + # overridden by the unignore logic below. + want_component=0 + fi + if test -f $component_path/.pmix_unignore ; then + # if there is an empty pmix_unignore, that is + # equivalent to having your userid in the unignore file. + # If userid is in the file, unignore the ignore file. + if test ! -s $component_path/.pmix_unignore ; then + want_component=1 + elif test ! -z "`$GREP $PMIX_CONFIGURE_USER $component_path/.pmix_unignore`" ; then + want_component=1 + fi + fi + # if this component type is direct and we are not it, we don't want + # to be built. Otherwise, we do want to be built. + if test ! -z "$DIRECT_$1" ; then + if test "$DIRECT_$1" = "$2" ; then + want_component=1 + else + want_component=0 + fi + fi + fi + + # if we were explicitly disabled, don't build :) + AS_IF([test "$DISABLE_$1" = "1"], [want_component=0]) + AS_LITERAL_IF([$2], + [AS_IF([test "$DISABLE_$1_$2" = "1"], [want_component=0])], + [str="DISABLED_COMPONENT_CHECK=\$DISABLE_$1_$2" + eval $str + if test "$DISABLED_COMPONENT_CHECK" = "1" ; then + want_component=0 + fi]) + + AS_IF([test "$want_component" = "1"], [$3], [$4]) +]) + + +# MCA_SETUP_DIRECT_CALL(framework_name (1)) +# ------------------------------------------------------------- +AC_DEFUN([MCA_SETUP_DIRECT_CALL],[ + if test ! -z "$DIRECT_$1" ; then + MCA_pmix_$1_DIRECT_CALL_COMPONENT=$DIRECT_$1 + MCA_pmix_$1_DIRECT_CALL=1 + else + MCA_pmix_$1_DIRECT_CALL_COMPONENT= + MCA_pmix_$1_DIRECT_CALL=0 + fi + + AC_SUBST(MCA_pmix_$1_DIRECT_CALL_HEADER) + AC_DEFINE_UNQUOTED([MCA_pmix_$2_DIRECT_CALL], [$MCA_pmix_$1_DIRECT_CALL], + [Defined to 1 if PMIx:$1 should use direct calls instead of components]) + AC_DEFINE_UNQUOTED([MCA_pmix_$1_DIRECT_CALL_COMPONENT], [$MCA_pmix_$1_DIRECT_CALL_COMPONENT], + [name of component to use for direct calls, if MCA_pmix_$1_DIRECT_CALL is 1]) + AC_DEFINE_UNQUOTED([MCA_pmix_$1_DIRECT_CALL_HEADER], + ["[$MCA_pmix_]$1[_DIRECT_CALL_HEADER]"], + [Header PMIx:$1 includes to be direct called]) +]) + + +# PMIX_MCA_MAKE_DIR_LIST(subst'ed variable, framework, shell list) +# ------------------------------------------------------------------------- +AC_DEFUN([PMIX_MCA_MAKE_DIR_LIST],[ + $1= + for item in $3 ; do + $1="$$1 mca/$2/$item" + done + AC_SUBST($1) +]) diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_mca_priority_sort.pl b/opal/mca/pmix/pmix2x/pmix/config/pmix_mca_priority_sort.pl new file mode 100755 index 0000000000..4026e990ed --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_mca_priority_sort.pl @@ -0,0 +1,31 @@ +#!/usr/bin/env perl +# +# Copyright (c) 2010 Sandia National Laboratories. All rights reserved. +# +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +my $components; +my @result; + +while (@ARGV) { + my $component; + $component->{"name"} = shift(@ARGV); + $component->{"value"} = shift(@ARGV); + push(@{$components}, $component); +} + +foreach my $component (sort { $b->{value} <=> $a->{value} } @{$components}) { + push(@result, $component->{name}); +} +sub commify_series { + (@_ == 0) ? '' : + (@_ == 1) ? $_[0] : + join(", ", @_[0 .. ($#_-1)], "$_[-1]"); +} + +print commify_series(@result); diff --git a/opal/mca/pmix/pmix2x/pmix/configure.ac b/opal/mca/pmix/pmix2x/pmix/configure.ac index ef58684970..e7838edeb1 100644 --- a/opal/mca/pmix/pmix2x/pmix/configure.ac +++ b/opal/mca/pmix/pmix2x/pmix/configure.ac @@ -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) 2006-2015 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2006-2016 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2006-2008 Sun Microsystems, Inc. All rights reserved. # Copyright (c) 2006-2011 Los Alamos National Security, LLC. All rights # reserved. @@ -33,14 +33,21 @@ # Initialization, version number, and other random setup/init stuff ############################################################################ +# Load in everything found by autogen.pl +m4_include([config/autogen_found_items.m4]) + +# We don't have the version number to put in here yet, and we can't +# call PMIX_GET_VERSION (etc.) before AC_INIT. So use the shell +# version. + AC_INIT([pmix], [m4_normalize(esyscmd([config/pmix_get_version.sh VERSION --tarball]))], - [http://www.open-mpi.org/projects/pmix/], [pmix]) + [http://pmix.github.io/master], [pmix]) AC_PREREQ(2.69) AC_CONFIG_AUX_DIR(./config) # Note that this directory must *exactly* match what was specified via # -I in ACLOCAL_AMFLAGS in the top-level Makefile.am. -AC_CONFIG_MACRO_DIR(./config) +AC_CONFIG_MACRO_DIRS(./config) # Get our platform support file. This has to be done very, very early # because it twiddles random bits of autoconf @@ -103,11 +110,11 @@ AH_TOP([/* -*- c -*- #ifndef PMIX_CONFIG_H #define PMIX_CONFIG_H -#include +#include ]) AH_BOTTOM([ -#include +#include #endif /* PMIX_CONFIG_H */ ]) @@ -137,6 +144,7 @@ AM_DISABLE_STATIC # This did not exist pre AM 1.11.x (where x is somewhere >0 and <3), # but it is necessary in AM 1.12.x. m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +AM_PROG_LEX LT_INIT() LT_LANG([C]) @@ -160,7 +168,7 @@ AS_IF([test "$pmix_debug" = "1"], ############################################################################ # Setup the pmix core -PMIX_SETUP_CORE([]) +PMIX_SETUP_CORE() # Run the AM_CONDITIONALs PMIX_DO_AM_CONDITIONALS @@ -209,6 +217,7 @@ AC_SUBST([CONFIGURE_DEPENDENCIES], ['$(top_srcdir)/VERSION']) AC_SUBST([libpmix_so_version]) AC_CONFIG_FILES(pmix_config_prefix[examples/Makefile] + pmix_config_prefix[man/Makefile] pmix_config_prefix[test/Makefile] pmix_config_prefix[test/simple/Makefile]) diff --git a/opal/mca/pmix/pmix2x/pmix/contrib/platform/optimized b/opal/mca/pmix/pmix2x/pmix/contrib/platform/optimized deleted file mode 100644 index e2c6fd0d20..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/contrib/platform/optimized +++ /dev/null @@ -1,3 +0,0 @@ -enable_mem_debug=no -enable_mem_profile=no -enable_debug=no diff --git a/opal/mca/pmix/pmix2x/pmix/examples/Makefile.am b/opal/mca/pmix/pmix2x/pmix/examples/Makefile.am index 8e07ee8ecf..0dc0c63039 100644 --- a/opal/mca/pmix/pmix2x/pmix/examples/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/examples/Makefile.am @@ -25,27 +25,27 @@ noinst_PROGRAMS = client dmodex dynamic fault pub tool client_SOURCES = client.c client_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) -client_LDADD = $(top_builddir)/libpmix.la +client_LDADD = $(top_builddir)/src/libpmix.la dmodex_SOURCES = dmodex.c dmodex_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) -dmodex_LDADD = $(top_builddir)/libpmix.la +dmodex_LDADD = $(top_builddir)/src/libpmix.la dynamic_SOURCES = dynamic.c dynamic_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) -dynamic_LDADD = $(top_builddir)/libpmix.la +dynamic_LDADD = $(top_builddir)/src/libpmix.la fault_SOURCES = fault.c fault_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) -fault_LDADD = $(top_builddir)/libpmix.la +fault_LDADD = $(top_builddir)/src/libpmix.la pub_SOURCES = pub.c pub_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) -pub_LDADD = $(top_builddir)/libpmix.la +pub_LDADD = $(top_builddir)/src/libpmix.la tool_SOURCES = tool.c tool_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) -tool_LDADD = $(top_builddir)/libpmix.la +tool_LDADD = $(top_builddir)/src/libpmix.la distclean-local: rm -f *.o client dmodex dynamic fault pub server diff --git a/opal/mca/pmix/pmix2x/pmix/examples/dynamic.c b/opal/mca/pmix/pmix2x/pmix/examples/dynamic.c index 22f0c1ccf0..41a513420d 100644 --- a/opal/mca/pmix/pmix2x/pmix/examples/dynamic.c +++ b/opal/mca/pmix/pmix2x/pmix/examples/dynamic.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -45,7 +46,7 @@ int main(int argc, char **argv) uint32_t nprocs; char nsp2[PMIX_MAX_NSLEN+1]; pmix_app_t *app; - char hostname[PMIX_MAXHOSTNAMELEN], dir[1024]; + char hostname[MAXHOSTNAMELEN], dir[1024]; pmix_proc_t *peers; size_t npeers, ntmp=0; char *nodelist; diff --git a/opal/mca/pmix/pmix2x/pmix/include/Makefile.am b/opal/mca/pmix/pmix2x/pmix/include/Makefile.am index b38ac2b4e1..93bdfac4ea 100644 --- a/opal/mca/pmix/pmix2x/pmix/include/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/include/Makefile.am @@ -1,6 +1,5 @@ # # Copyright 2015-2016 Intel, Inc. All rights reserved -# Copyright (c) 2016 IBM Corporation. All rights reserved. # # $COPYRIGHT$ # @@ -11,26 +10,13 @@ # Only install the headers if we're in standalone mode - if ! PMIX_EMBEDDED_MODE include_HEADERS = \ - include/pmix.h \ - include/pmix_server.h \ - include/pmi.h \ - include/pmi2.h \ - include/pmix_tool.h - -include_pmixdir = $(includedir)/pmix -include_pmix_HEADERS = \ - include/pmix/rename.h \ - include/pmix/pmix_common.h - -include_pmix_autogendir = $(includedir)/pmix/autogen -include_pmix_autogen_HEADERS = \ - include/pmix/autogen/pmix_config_top.h \ - include/pmix/autogen/pmix_config_bottom.h \ - include/pmix/autogen/pmix_stdint.h -nodist_include_pmix_autogen_HEADERS = \ - include/pmix/autogen/config.h + pmix.h \ + pmix_common.h \ + pmix_server.h \ + pmi.h \ + pmi2.h \ + pmix_tool.h endif ! PMIX_EMBEDDED_MODE diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix.h b/opal/mca/pmix/pmix2x/pmix/include/pmix.h index b5e7a89837..b4e338a2dc 100644 --- a/opal/mca/pmix/pmix2x/pmix/include/pmix.h +++ b/opal/mca/pmix/pmix2x/pmix/include/pmix.h @@ -46,16 +46,13 @@ #ifndef PMIx_H #define PMIx_H -#include - -/* Symbol transforms */ -#include - /* Structure and constant definitions */ -#include +#include -BEGIN_C_DECLS +#if defined(c_plusplus) || defined(__cplusplus) +extern "C" { +#endif /**** PMIX API ****/ @@ -438,5 +435,10 @@ pmix_status_t PMIx_Query_info_nb(pmix_query_t queries[], size_t nqueries, pmix_status_t PMIx_Log_nb(const pmix_info_t data[], size_t ndata, const pmix_info_t directives[], size_t ndirs, pmix_op_cbfunc_t cbfunc, void *cbdata); -END_C_DECLS + + +#if defined(c_plusplus) || defined(__cplusplus) +} +#endif + #endif diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix/rename.h b/opal/mca/pmix/pmix2x/pmix/include/pmix/rename.h deleted file mode 100644 index 7143865813..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/include/pmix/rename.h +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright 2015 Intel, Inc. All rights reserved - */ - -#ifndef PMIX_RENAME_H -#define PMIX_RENAME_H - -#include - - -BEGIN_C_DECLS - - -/* Only enact these defines if we're actually renaming the symbols - (i.e., avoid trying to have no-op defines if we're *not* - renaming). - - Note that we don't symbol shift if we aren't in embedded mode - as that wouldn't make any sense. If we are in embedded mode, - then we aren't building the PMI-1/2 APIs as that also doesn't - make any sense -*/ - -#if PMIX_SYM_TRANSFORM - -/* Use a preprocessor two-step in order to get the prefixing right. - Make 2 macros: PMIX_NAME and PMIX_NAME_CAPS for renaming - things. */ - -#define PMIX_MUNGE_NAME(a, b) PMIX_MUNGE_NAME2(a, b) -#define PMIX_MUNGE_NAME2(a, b) a ## b -#define PMIX_NAME(name) PMIX_MUNGE_NAME(PMIX_SYM_PREFIX, pmix_ ## name) -#define PMIX_NAME_CAPS(name) PMIX_MUNGE_NAME(PMIX_SYM_PREFIX_CAPS, PMIx_ ## name) - -/* Now define all the "real" names to be the prefixed names. This - allows us to use the real names throughout the code base (i.e., - "pmix_"); the preprocessor will adjust to have the prefixed - name under the covers. */ - -/* PMIx APIs */ -#define PMI2_Abort PMIX_NAME_CAPS(PMI2_Abort) -#define PMI2_Finalize PMIX_NAME_CAPS(PMI2_Finalize) -#define PMI2_Info_GetJobAttr PMIX_NAME_CAPS(PMI2_Info_GetJobAttr) -#define PMI2_Info_GetJobAttrIntArray PMIX_NAME_CAPS(PMI2_Info_GetJobAttrIntArray) -#define PMI2_Info_GetNodeAttr PMIX_NAME_CAPS(PMI2_Info_GetNodeAttr) -#define PMI2_Info_GetSize PMIX_NAME_CAPS(PMI2_Info_GetSize) -#define PMI2_Info_PutNodeAttr PMIX_NAME_CAPS(PMI2_Info_PutNodeAttr) -#define PMI2_Init PMIX_NAME_CAPS(PMI2_Init) -#define PMI2_Initialized PMIX_NAME_CAPS(PMI2_Initialized) -#define PMI2_Job_Connect PMIX_NAME_CAPS(PMI2_Job_Connect) -#define PMI2_Job_Disconnect PMIX_NAME_CAPS(PMI2_Job_Disconnect) -#define PMI2_Job_GetId PMIX_NAME_CAPS(PMI2_Job_GetId) -#define PMI2_Job_GetRank PMIX_NAME_CAPS(PMI2_Job_GetRank) -#define PMI2_Job_Spawn PMIX_NAME_CAPS(PMI2_Job_Spawn) -#define PMI2_KVS_Fence PMIX_NAME_CAPS(PMI2_KVS_Fence) -#define PMI2_KVS_Get PMIX_NAME_CAPS(PMI2_KVS_Get) -#define PMI2_KVS_Put PMIX_NAME_CAPS(PMI2_KVS_Put) -#define PMI2_Nameserv_lookup PMIX_NAME_CAPS(PMI2_Nameserv_lookup) -#define PMI2_Nameserv_publish PMIX_NAME_CAPS(PMI2_Nameserv_publish) -#define PMI2_Nameserv_unpublish PMIX_NAME_CAPS(PMI2_Nameserv_unpublish) -#define PMI_Abort PMIX_NAME_CAPS(PMI_Abort) -#define PMI_Args_to_keyval PMIX_NAME_CAPS(PMI_Args_to_keyval) -#define PMI_Barrier PMIX_NAME_CAPS(PMI_Barrier) -#define PMI_Finalize PMIX_NAME_CAPS(PMI_Finalize) -#define PMI_Free_keyvals PMIX_NAME_CAPS(PMI_Free_keyvals) -#define PMI_Get_appnum PMIX_NAME_CAPS(PMI_Get_appnum) -#define PMI_Get_clique_ranks PMIX_NAME_CAPS(PMI_Get_clique_ranks) -#define PMI_Get_clique_size PMIX_NAME_CAPS(PMI_Get_clique_size) -#define PMI_Get_id PMIX_NAME_CAPS(PMI_Get_id) -#define PMI_Get_id_length_max PMIX_NAME_CAPS(PMI_Get_id_length_max) -#define PMI_Get_kvs_domain_id PMIX_NAME_CAPS(PMI_Get_kvs_domain_id) -#define PMI_Get_options PMIX_NAME_CAPS(PMI_Get_options) -#define PMI_Get_rank PMIX_NAME_CAPS(PMI_Get_rank) -#define PMI_Get_size PMIX_NAME_CAPS(PMI_Get_size) -#define PMI_Get_universe_size PMIX_NAME_CAPS(PMI_Get_universe_size) -#define PMI_Init PMIX_NAME_CAPS(PMI_Init) -#define PMI_Initialized PMIX_NAME_CAPS(PMI_Initialized) -#define PMI_KVS_Commit PMIX_NAME_CAPS(PMI_KVS_Commit) -#define PMI_KVS_Create PMIX_NAME_CAPS(PMI_KVS_Create) -#define PMI_KVS_Destroy PMIX_NAME_CAPS(PMI_KVS_Destroy) -#define PMI_KVS_Get PMIX_NAME_CAPS(PMI_KVS_Get) -#define PMI_KVS_Get_key_length_max PMIX_NAME_CAPS(PMI_KVS_Get_key_length_max) -#define PMI_KVS_Get_my_name PMIX_NAME_CAPS(PMI_KVS_Get_my_name) -#define PMI_KVS_Get_name_length_max PMIX_NAME_CAPS(PMI_KVS_Get_name_length_max) -#define PMI_KVS_Get_value_length_max PMIX_NAME_CAPS(PMI_KVS_Get_value_length_max) -#define PMI_KVS_Iter_first PMIX_NAME_CAPS(PMI_KVS_Iter_first) -#define PMI_KVS_Iter_next PMIX_NAME_CAPS(PMI_KVS_Iter_next) -#define PMI_KVS_Put PMIX_NAME_CAPS(PMI_KVS_Put) -#define PMI_Lookup_name PMIX_NAME_CAPS(PMI_Lookup_name) -#define PMI_Parse_option PMIX_NAME_CAPS(PMI_Parse_option) -#define PMI_Publish_name PMIX_NAME_CAPS(PMI_Publish_name) -#define PMI_Spawn_multiple PMIX_NAME_CAPS(PMI_Spawn_multiple) -#define PMI_Unpublish_name PMIX_NAME_CAPS(PMI_Unpublish_name) -#define PMIx_Abort PMIX_NAME_CAPS(Abort) -#define PMIx_Commit PMIX_NAME_CAPS(Commit) -#define PMIx_Connect PMIX_NAME_CAPS(Connect) -#define PMIx_Connect_nb PMIX_NAME_CAPS(Connect_nb) -#define PMIx_Deregister_errhandler PMIX_NAME_CAPS(Deregister_errhandler) -#define PMIx_Disconnect PMIX_NAME_CAPS(Disconnect) -#define PMIx_Disconnect_nb PMIX_NAME_CAPS(Disconnect_nb) -#define PMIx_Error_string PMIX_NAME_CAPS(Error_string) -#define PMIx_Fence PMIX_NAME_CAPS(Fence) -#define PMIx_Fence_nb PMIX_NAME_CAPS(Fence_nb) -#define PMIx_Finalize PMIX_NAME_CAPS(Finalize) -#define PMIx_Get PMIX_NAME_CAPS(Get) -#define PMIx_Get_nb PMIX_NAME_CAPS(Get_nb) -#define PMIx_Get_version PMIX_NAME_CAPS(Get_version) -#define PMIx_Init PMIX_NAME_CAPS(Init) -#define PMIx_Initialized PMIX_NAME_CAPS(Initialized) -#define PMIx_Lookup PMIX_NAME_CAPS(Lookup) -#define PMIx_Lookup_nb PMIX_NAME_CAPS(Lookup_nb) -#define PMIx_Notify_error PMIX_NAME_CAPS(Notify_error) -#define PMIx_Publish PMIX_NAME_CAPS(Publish) -#define PMIx_Publish_nb PMIX_NAME_CAPS(Publish_nb) -#define PMIx_Put PMIX_NAME_CAPS(Put) -#define PMIx_Register_errhandler PMIX_NAME_CAPS(Register_errhandler) -#define PMIx_Resolve_nodes PMIX_NAME_CAPS(Resolve_nodes) -#define PMIx_Resolve_peers PMIX_NAME_CAPS(Resolve_peers) -#define PMIx_Spawn PMIX_NAME_CAPS(Spawn) -#define PMIx_Spawn_nb PMIX_NAME_CAPS(Spawn_nb) -#define PMIx_Store_internal PMIX_NAME_CAPS(Store_internal) -#define PMIx_Unpublish PMIX_NAME_CAPS(Unpublish) -#define PMIx_Unpublish_nb PMIX_NAME_CAPS(Unpublish_nb) -#define PMIx_generate_ppn PMIX_NAME_CAPS(generate_ppn) -#define PMIx_generate_regex PMIX_NAME_CAPS(generate_regex) -#define PMIx_server_deregister_client PMIX_NAME_CAPS(server_deregister_client) -#define PMIx_server_deregister_nspace PMIX_NAME_CAPS(server_deregister_nspace) -#define PMIx_server_dmodex_request PMIX_NAME_CAPS(server_dmodex_request) -#define PMIx_server_finalize PMIX_NAME_CAPS(server_finalize) -#define PMIx_server_init PMIX_NAME_CAPS(server_init) -#define PMIx_server_register_client PMIX_NAME_CAPS(server_register_client) -#define PMIx_server_register_nspace PMIX_NAME_CAPS(server_register_nspace) -#define PMIx_server_setup_fork PMIX_NAME_CAPS(server_setup_fork) - -/* internal functions */ -#define pmix_argv_append PMIX_NAME(argv_append) -#define pmix_argv_append_nosize PMIX_NAME(argv_append_nosize) -#define pmix_argv_append_unique_nosize PMIX_NAME(argv_append_unique_nosize) -#define pmix_argv_copy PMIX_NAME(argv_copy) -#define pmix_argv_count PMIX_NAME(argv_count) -#define pmix_argv_delete PMIX_NAME(argv_delete) -#define pmix_argv_free PMIX_NAME(argv_free) -#define pmix_argv_insert PMIX_NAME(argv_insert) -#define pmix_argv_insert_element PMIX_NAME(argv_insert_element) -#define pmix_argv_join PMIX_NAME(argv_join) -#define pmix_argv_join_range PMIX_NAME(argv_join_range) -#define pmix_argv_len PMIX_NAME(argv_len) -#define pmix_argv_prepend_nosize PMIX_NAME(argv_prepend_nosize) -#define pmix_argv_split PMIX_NAME(argv_split) -#define pmix_argv_split_with_empty PMIX_NAME(argv_split_with_empty) -#define pmix_asprintf PMIX_NAME(asprintf) -#define pmix_basename PMIX_NAME(basename) -#define pmix_bcopy_csum_partial PMIX_NAME(bcopy_csum_partial) -#define pmix_bcopy_uicrc_partial PMIX_NAME(bcopy_uicrc_partial) -#define pmix_bcopy_uicsum_partial PMIX_NAME(bcopy_uicsum_partial) -#define pmix_bfrop PMIX_NAME(bfrop) -#define pmix_bfrop_buffer_extend PMIX_NAME(bfrop_buffer_extend) -#define pmix_bfrop_close PMIX_NAME(bfrop_close) -#define pmix_bfrop_copy PMIX_NAME(bfrop_copy) -#define pmix_bfrop_copy_app PMIX_NAME(bfrop_copy_app) -#define pmix_bfrop_copy_array PMIX_NAME(bfrop_copy_array) -#define pmix_bfrop_copy_bo PMIX_NAME(bfrop_copy_bo) -#define pmix_bfrop_copy_buf PMIX_NAME(bfrop_copy_buf) -#define pmix_bfrop_copy_info PMIX_NAME(bfrop_copy_info) -#define pmix_bfrop_copy_kval PMIX_NAME(bfrop_copy_kval) -#define pmix_bfrop_copy_modex PMIX_NAME(bfrop_copy_modex) -#define pmix_bfrop_copy_payload PMIX_NAME(bfrop_copy_payload) -#define pmix_bfrop_copy_pdata PMIX_NAME(bfrop_copy_pdata) -#define pmix_bfrop_copy_persist PMIX_NAME(bfrop_copy_persist) -#define pmix_bfrop_copy_proc PMIX_NAME(bfrop_copy_proc) -#define pmix_bfrop_copy_string PMIX_NAME(bfrop_copy_string) -#define pmix_bfrop_copy_topo PMIX_NAME(bfrop_copy_topo) -#define pmix_bfrop_copy_value PMIX_NAME(bfrop_copy_value) -#define pmix_bfrop_get_data_type PMIX_NAME(bfrop_get_data_type) -#define pmix_bfrop_initial_size PMIX_NAME(pmix_bfrop_initial_size) -#define pmix_bfrop_initialized PMIX_NAME(bfrop_initialized) -#define pmix_bfrop_num_reg_types PMIX_NAME(pmix_bfrop_num_reg_types) -#define pmix_bfrop_open PMIX_NAME(bfrop_open) -#define pmix_bfrop_pack PMIX_NAME(bfrop_pack) -#define pmix_bfrop_pack_app PMIX_NAME(bfrop_pack_app) -#define pmix_bfrop_pack_array PMIX_NAME(bfrop_pack_array) -#define pmix_bfrop_pack_bo PMIX_NAME(bfrop_pack_bo) -#define pmix_bfrop_pack_bool PMIX_NAME(bfrop_pack_bool) -#define pmix_bfrop_pack_buf PMIX_NAME(bfrop_pack_buf) -#define pmix_bfrop_pack_buffer PMIX_NAME(bfrop_pack_buffer) -#define pmix_bfrop_pack_byte PMIX_NAME(bfrop_pack_byte) -#define pmix_bfrop_pack_datatype PMIX_NAME(bfrop_pack_datatype) -#define pmix_bfrop_pack_double PMIX_NAME(bfrop_pack_double) -#define pmix_bfrop_pack_float PMIX_NAME(bfrop_pack_float) -#define pmix_bfrop_pack_info PMIX_NAME(bfrop_pack_info) -#define pmix_bfrop_pack_int PMIX_NAME(bfrop_pack_int) -#define pmix_bfrop_pack_int16 PMIX_NAME(bfrop_pack_int16) -#define pmix_bfrop_pack_int32 PMIX_NAME(bfrop_pack_int32) -#define pmix_bfrop_pack_int64 PMIX_NAME(bfrop_pack_int64) -#define pmix_bfrop_pack_kval PMIX_NAME(bfrop_pack_kval) -#define pmix_bfrop_pack_modex PMIX_NAME(bfrop_pack_modex) -#define pmix_bfrop_pack_pdata PMIX_NAME(bfrop_pack_pdata) -#define pmix_bfrop_pack_persist PMIX_NAME(bfrop_pack_persist) -#define pmix_bfrop_pack_pid PMIX_NAME(bfrop_pack_pid) -#define pmix_bfrop_pack_proc PMIX_NAME(bfrop_pack_proc) -#define pmix_bfrop_pack_sizet PMIX_NAME(bfrop_pack_sizet) -#define pmix_bfrop_pack_string PMIX_NAME(bfrop_pack_string) -#define pmix_bfrop_pack_time PMIX_NAME(bfrop_pack_time) -#define pmix_bfrop_pack_timeval PMIX_NAME(bfrop_pack_timeval) -#define pmix_bfrop_pack_topo PMIX_NAME(bfrop_pack_topo) -#define pmix_bfrop_pack_value PMIX_NAME(bfrop_pack_value) -#define pmix_bfrop_print PMIX_NAME(bfrop_print) -#define pmix_bfrop_print_app PMIX_NAME(bfrop_print_app) -#define pmix_bfrop_print_array PMIX_NAME(bfrop_print_array) -#define pmix_bfrop_print_bo PMIX_NAME(bfrop_print_bo) -#define pmix_bfrop_print_bool PMIX_NAME(bfrop_print_bool) -#define pmix_bfrop_print_buf PMIX_NAME(bfrop_print_buf) -#define pmix_bfrop_print_byte PMIX_NAME(bfrop_print_byte) -#define pmix_bfrop_print_double PMIX_NAME(bfrop_print_double) -#define pmix_bfrop_print_float PMIX_NAME(bfrop_print_float) -#define pmix_bfrop_print_info PMIX_NAME(bfrop_print_info) -#define pmix_bfrop_print_int PMIX_NAME(bfrop_print_int) -#define pmix_bfrop_print_int16 PMIX_NAME(bfrop_print_int16) -#define pmix_bfrop_print_int32 PMIX_NAME(bfrop_print_int32) -#define pmix_bfrop_print_int64 PMIX_NAME(bfrop_print_int64) -#define pmix_bfrop_print_int8 PMIX_NAME(bfrop_print_int8) -#define pmix_bfrop_print_kval PMIX_NAME(bfrop_print_kval) -#define pmix_bfrop_print_modex PMIX_NAME(bfrop_print_modex) -#define pmix_bfrop_print_pdata PMIX_NAME(bfrop_print_pdata) -#define pmix_bfrop_print_persist PMIX_NAME(bfrop_print_persist) -#define pmix_bfrop_print_pid PMIX_NAME(bfrop_print_pid) -#define pmix_bfrop_print_proc PMIX_NAME(bfrop_print_proc) -#define pmix_bfrop_print_size PMIX_NAME(bfrop_print_size) -#define pmix_bfrop_print_string PMIX_NAME(bfrop_print_string) -#define pmix_bfrop_print_time PMIX_NAME(bfrop_print_time) -#define pmix_bfrop_print_timeval PMIX_NAME(bfrop_print_timeval) -#define pmix_bfrop_print_topo PMIX_NAME(bfrop_print_topo) -#define pmix_bfrop_print_uint PMIX_NAME(bfrop_print_uint) -#define pmix_bfrop_print_uint16 PMIX_NAME(bfrop_print_uint16) -#define pmix_bfrop_print_uint32 PMIX_NAME(bfrop_print_uint32) -#define pmix_bfrop_print_uint64 PMIX_NAME(bfrop_print_uint64) -#define pmix_bfrop_print_uint8 PMIX_NAME(bfrop_print_uint8) -#define pmix_bfrop_print_value PMIX_NAME(bfrop_print_value) -#define pmix_bfrop_std_copy PMIX_NAME(bfrop_std_copy) -#define pmix_bfrop_store_data_type PMIX_NAME(bfrop_store_data_type) -#define pmix_bfrop_threshold_size PMIX_NAME(pmix_bfrop_threshold_size) -#define pmix_bfrop_too_small PMIX_NAME(bfrop_too_small) -#define pmix_bfrop_types PMIX_NAME(bfrop_types) -#define pmix_bfrop_type_info_t_class PMIX_NAME(bfrop_type_info_t_class) -#define pmix_bfrop_unpack PMIX_NAME(bfrop_unpack) -#define pmix_bfrop_unpack_app PMIX_NAME(bfrop_unpack_app) -#define pmix_bfrop_unpack_array PMIX_NAME(bfrop_unpack_array) -#define pmix_bfrop_unpack_bo PMIX_NAME(bfrop_unpack_bo) -#define pmix_bfrop_unpack_bool PMIX_NAME(bfrop_unpack_bool) -#define pmix_bfrop_unpack_buf PMIX_NAME(bfrop_unpack_buf) -#define pmix_bfrop_unpack_buffer PMIX_NAME(bfrop_unpack_buffer) -#define pmix_bfrop_unpack_byte PMIX_NAME(bfrop_unpack_byte) -#define pmix_bfrop_unpack_datatype PMIX_NAME(bfrop_unpack_datatype) -#define pmix_bfrop_unpack_double PMIX_NAME(bfrop_unpack_double) -#define pmix_bfrop_unpack_float PMIX_NAME(bfrop_unpack_float) -#define pmix_bfrop_unpack_info PMIX_NAME(bfrop_unpack_info) -#define pmix_bfrop_unpack_int PMIX_NAME(bfrop_unpack_int) -#define pmix_bfrop_unpack_int16 PMIX_NAME(bfrop_unpack_int16) -#define pmix_bfrop_unpack_int32 PMIX_NAME(bfrop_unpack_int32) -#define pmix_bfrop_unpack_int64 PMIX_NAME(bfrop_unpack_int64) -#define pmix_bfrop_unpack_kval PMIX_NAME(bfrop_unpack_kval) -#define pmix_bfrop_unpack_modex PMIX_NAME(bfrop_unpack_modex) -#define pmix_bfrop_unpack_pdata PMIX_NAME(bfrop_unpack_pdata) -#define pmix_bfrop_unpack_persist PMIX_NAME(bfrop_unpack_persist) -#define pmix_bfrop_unpack_pid PMIX_NAME(bfrop_unpack_pid) -#define pmix_bfrop_unpack_proc PMIX_NAME(bfrop_unpack_proc) -#define pmix_bfrop_unpack_sizet PMIX_NAME(bfrop_unpack_sizet) -#define pmix_bfrop_unpack_string PMIX_NAME(bfrop_unpack_string) -#define pmix_bfrop_unpack_time PMIX_NAME(bfrop_unpack_time) -#define pmix_bfrop_unpack_timeval PMIX_NAME(bfrop_unpack_timeval) -#define pmix_bfrop_unpack_topo PMIX_NAME(bfrop_unpack_topo) -#define pmix_bfrop_unpack_value PMIX_NAME(bfrop_unpack_value) -#define pmix_buffer_t_class PMIX_NAME(buffer_t_class) -#define pmix_cb_t_class PMIX_NAME(cb_t_class) -#define pmix_class_finalize PMIX_NAME(class_finalize) -#define pmix_class_initialize PMIX_NAME(class_initialize) -#define pmix_client_globals PMIX_NAME(pmix_client_globals) -#define pmix_client_process_nspace_blob PMIX_NAME(client_process_nspace_blob) -#define pmix_csum_partial PMIX_NAME(csum_partial) -#define pmix_dirname PMIX_NAME(dirname) -#define pmix_dmdx_local_t_class PMIX_NAME(dmdx_local_t_class) -#define pmix_dmdx_remote_t_class PMIX_NAME(dmdx_remote_t_class) -#define pmix_dmdx_reply_caddy_t_class PMIX_NAME(dmdx_reply_caddy_t_class) -#define pmix_dmdx_request_t_class PMIX_NAME(dmdx_request_t_class) -#define pmix_environ_merge PMIX_NAME(environ_merge) -#define pmix_errhandler_invoke PMIX_NAME(errhandler_invoke) -#define pmix_fd_read PMIX_NAME(fd_read) -#define pmix_fd_set_cloexec PMIX_NAME(fd_set_cloexec) -#define pmix_fd_write PMIX_NAME(fd_write) -#define pmix_globals PMIX_NAME(globals) -#define pmix_globals_finalize PMIX_NAME(globals_finalize) -#define pmix_globals_init PMIX_NAME(globals_init) -#define pmix_hash_fetch PMIX_NAME(hash_fetch) -#define pmix_hash_remove_data PMIX_NAME(hash_remove_data) -#define pmix_hash_store PMIX_NAME(hash_store) -#define pmix_hash_table_get_first_key_uint32 PMIX_NAME(hash_table_get_first_key_uint32) -#define pmix_hash_table_get_first_key_uint64 PMIX_NAME(hash_table_get_first_key_uint64) -#define pmix_hash_table_get_next_key_uint32 PMIX_NAME(hash_table_get_next_key_uint32) -#define pmix_hash_table_get_next_key_uint64 PMIX_NAME(hash_table_get_next_key_uint64) -#define pmix_hash_table_get_value_ptr PMIX_NAME(hash_table_get_value_ptr) -#define pmix_hash_table_get_value_uint32 PMIX_NAME(hash_table_get_value_uint32) -#define pmix_hash_table_get_value_uint64 PMIX_NAME(hash_table_get_value_uint64) -#define pmix_hash_table_init PMIX_NAME(hash_table_init) -#define pmix_hash_table_remove_all PMIX_NAME(hash_table_remove_all) -#define pmix_hash_table_remove_value_ptr PMIX_NAME(hash_table_remove_value_ptr) -#define pmix_hash_table_remove_value_uint32 PMIX_NAME(hash_table_remove_value_uint32) -#define pmix_hash_table_remove_value_uint64 PMIX_NAME(hash_table_remove_value_uint64) -#define pmix_hash_table_set_value_ptr PMIX_NAME(hash_table_set_value_ptr) -#define pmix_hash_table_set_value_uint32 PMIX_NAME(hash_table_set_value_uint32) -#define pmix_hash_table_set_value_uint64 PMIX_NAME(hash_table_set_value_uint64) -#define pmix_hash_table_t_class PMIX_NAME(hash_table_t_class) -#define pmix_home_directory PMIX_NAME(home_directory) -#define pmix_host_server PMIX_NAME(pmix_host_server) -#define pmix_initialize_crc_table PMIX_NAME(initialize_crc_table) -#define pmix_kval_t_class PMIX_NAME(kval_t_class) -#define pmix_list_insert PMIX_NAME(list_insert) -#define pmix_list_item_t_class PMIX_NAME(list_item_t_class) -#define pmix_list_join PMIX_NAME(list_join) -#define pmix_list_sort PMIX_NAME(list_sort) -#define pmix_list_splice PMIX_NAME(list_splice) -#define pmix_list_t_class PMIX_NAME(list_t_class) -#define pmix_munge_module PMIX_NAME(munge_module) -#define pmix_native_module PMIX_NAME(native_module) -#define pmix_notify_caddy_t_class PMIX_NAME(notify_caddy_t_class) -#define pmix_nrec_t_class PMIX_NAME(nrec_t_class) -#define pmix_nspace_t_class PMIX_NAME(nspace_t_class) -#define pmix_object_t_class PMIX_NAME(object_t_class) -#define pmix_os_path PMIX_NAME(os_path) -#define pmix_output PMIX_NAME(output) -#define pmix_output_close PMIX_NAME(output_close) -#define pmix_output_finalize PMIX_NAME(output_finalize) -#define pmix_output_get_verbosity PMIX_NAME(output_get_verbosity) -#define pmix_output_init PMIX_NAME(output_init) -#define pmix_output_open PMIX_NAME(output_open) -#define pmix_output_redirected_syslog_pri PMIX_NAME(pmix_output_redirected_syslog_pri) -#define pmix_output_redirected_to_syslog PMIX_NAME(output_redirected_to_syslog) -#define pmix_output_reopen PMIX_NAME(output_reopen) -#define pmix_output_reopen_all PMIX_NAME(output_reopen_all) -#define pmix_output_set_output_file_info PMIX_NAME(output_set_output_file_info) -#define pmix_output_set_verbosity PMIX_NAME(output_set_verbosity) -#define pmix_output_stream_t_class PMIX_NAME(output_stream_t_class) -#define pmix_output_string PMIX_NAME(output_string) -#define pmix_output_switch PMIX_NAME(output_switch) -#define pmix_output_verbose PMIX_NAME(output_verbose) -#define pmix_output_vstring PMIX_NAME(output_vstring) -#define pmix_output_vverbose PMIX_NAME(output_vverbose) -#define pmix_pack_proc_map PMIX_NAME(pack_proc_map) -#define pmix_peer_t_class PMIX_NAME(peer_t_class) -#define pmix_pending_connection_t_class PMIX_NAME(pending_connection_t_class) -#define pmix_pending_nspace_requests PMIX_NAME(pending_nspace_requests) -#define pmix_pending_resolve PMIX_NAME(pending_resolve) -#define pmix_pointer_array_add PMIX_NAME(pointer_array_add) -#define pmix_pointer_array_init PMIX_NAME(pointer_array_init) -#define pmix_pointer_array_set_item PMIX_NAME(pointer_array_set_item) -#define pmix_pointer_array_set_size PMIX_NAME(pointer_array_set_size) -#define pmix_pointer_array_t_class PMIX_NAME(pointer_array_t_class) -#define pmix_pointer_array_test_and_set_item PMIX_NAME(pointer_array_test_and_set_item) -#define pmix_rank_info_t_class PMIX_NAME(rank_info_t_class) -#define pmix_regex_parse_nodes PMIX_NAME(regex_parse_nodes) -#define pmix_regex_parse_procs PMIX_NAME(regex_parse_procs) -#define pmix_regex_range_t_class PMIX_NAME(regex_range_t_class) -#define pmix_regex_value_t_class PMIX_NAME(regex_value_t_class) -#define pmix_sec PMIX_NAME(pmix_sec) -#define pmix_sec_finalize PMIX_NAME(sec_finalize) -#define pmix_sec_init PMIX_NAME(sec_init) -#define pmix_server_abort PMIX_NAME(server_abort) -#define pmix_server_caddy_t_class PMIX_NAME(server_caddy_t_class) -#define pmix_server_commit PMIX_NAME(server_commit) -#define pmix_server_connect PMIX_NAME(server_connect) -#define pmix_server_deregister_errhandler PMIX_NAME(server_deregister_errhandler) -#define pmix_server_fence PMIX_NAME(server_fence) -#define pmix_server_get PMIX_NAME(server_get) -#define pmix_server_globals PMIX_NAME(pmix_server_globals) -#define pmix_server_lookup PMIX_NAME(server_lookup) -#define pmix_server_notify_error PMIX_NAME(server_notify_error) -#define pmix_server_nspace_t_class PMIX_NAME(server_nspace_t_class) -#define pmix_server_publish PMIX_NAME(server_publish) -#define pmix_server_register_errhandler PMIX_NAME(server_register_errhandler) -#define pmix_server_spawn PMIX_NAME(server_spawn) -#define pmix_server_trkr_t_class PMIX_NAME(server_trkr_t_class) -#define pmix_server_unpublish PMIX_NAME(server_unpublish) -#define pmix_setenv PMIX_NAME(setenv) -#define pmix_setup_caddy_t_class PMIX_NAME(setup_caddy_t_class) -#define pmix_shift_caddy_t_class PMIX_NAME(shift_caddy_t_class) -#define pmix_snd_caddy_t_class PMIX_NAME(snd_caddy_t_class) -#define pmix_snprintf PMIX_NAME(snprintf) -#define pmix_start_listening PMIX_NAME(start_listening) -#define pmix_start_progress_thread PMIX_NAME(start_progress_thread) -#define pmix_stop_listening PMIX_NAME(stop_listening) -#define pmix_stop_progress_thread PMIX_NAME(stop_progress_thread) -#define pmix_timer_t_class PMIX_NAME(timer_t_class) -#define pmix_tmp_directory PMIX_NAME(tmp_directory) -#define pmix_trkr_caddy_t_class PMIX_NAME(trkr_caddy_t_class) -#define pmix_uicrc_partial PMIX_NAME(uicrc_partial) -#define pmix_uicsum_partial PMIX_NAME(uicsum_partial) -#define pmix_unsetenv PMIX_NAME(unsetenv) -#define pmix_usock_finalize PMIX_NAME(usock_finalize) -#define pmix_usock_globals PMIX_NAME(pmix_usock_globals) -#define pmix_usock_init PMIX_NAME(usock_init) -#define pmix_usock_posted_recv_t_class PMIX_NAME(usock_posted_recv_t_class) -#define pmix_usock_process_msg PMIX_NAME(usock_process_msg) -#define pmix_usock_queue_t_class PMIX_NAME(usock_queue_t_class) -#define pmix_usock_recv_blocking PMIX_NAME(usock_recv_blocking) -#define pmix_usock_recv_handler PMIX_NAME(usock_recv_handler) -#define pmix_usock_recv_t_class PMIX_NAME(usock_recv_t_class) -#define pmix_usock_send_blocking PMIX_NAME(usock_send_blocking) -#define pmix_usock_send_handler PMIX_NAME(usock_send_handler) -#define pmix_usock_send_recv PMIX_NAME(usock_send_recv) -#define pmix_usock_send_t_class PMIX_NAME(usock_send_t_class) -#define pmix_usock_set_blocking PMIX_NAME(usock_set_blocking) -#define pmix_usock_set_nonblocking PMIX_NAME(usock_set_nonblocking) -#define pmix_usock_sr_t_class PMIX_NAME(usock_sr_t_class) -#define pmix_value_load PMIX_NAME(value_load) -#define pmix_value_unload PMIX_NAME(value_unload) -#define pmix_value_xfer PMIX_NAME(value_xfer) -#define pmix_vasprintf PMIX_NAME(vasprintf) -#define pmix_vsnprintf PMIX_NAME(vsnprintf) - - -#endif /* PMIX_SYM_TRANSFORM */ - -END_C_DECLS - -#endif /* PMIX_RENAME_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix/pmix_common.h b/opal/mca/pmix/pmix2x/pmix/include/pmix_common.h similarity index 99% rename from opal/mca/pmix/pmix2x/pmix/include/pmix/pmix_common.h rename to opal/mca/pmix/pmix2x/pmix/include/pmix_common.h index 96a9019776..3e27d09c74 100644 --- a/opal/mca/pmix/pmix2x/pmix/include/pmix/pmix_common.h +++ b/opal/mca/pmix/pmix2x/pmix/include/pmix_common.h @@ -51,9 +51,6 @@ #ifndef PMIx_COMMON_H #define PMIx_COMMON_H -#include -#include - #include #include #include @@ -68,7 +65,9 @@ #include /* for uid_t and gid_t */ #endif -BEGIN_C_DECLS +#if defined(c_plusplus) || defined(__cplusplus) +extern "C" { +#endif /**** PMIX CONSTANTS ****/ @@ -127,6 +126,7 @@ typedef uint32_t pmix_rank_t; /* identification attributes */ #define PMIX_USERID "pmix.euid" // (uint32_t) effective user id #define PMIX_GRPID "pmix.egid" // (uint32_t) effective group id +#define PMIX_DSTPATH "pmix.dstpath" // (char*) path to dstore files /* attributes for the rendezvous socket */ #define PMIX_SOCKET_MODE "pmix.sockmode" // (uint32_t) POSIX mode_t (9 bits valid) @@ -1336,5 +1336,8 @@ pmix_status_t PMIx_Store_internal(const pmix_proc_t *proc, #define PMIX_VAL_FREE(_v) \ PMIx_free_value_data(_v) -END_C_DECLS +#if defined(c_plusplus) || defined(__cplusplus) +} +#endif + #endif diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix_server.h b/opal/mca/pmix/pmix2x/pmix/include/pmix_server.h index d7b55d7725..9416ab8964 100644 --- a/opal/mca/pmix/pmix2x/pmix/include/pmix_server.h +++ b/opal/mca/pmix/pmix2x/pmix/include/pmix_server.h @@ -59,15 +59,12 @@ #ifndef PMIx_SERVER_API_H #define PMIx_SERVER_API_H -#include - -/* Symbol transforms */ -#include - /* Structure and constant definitions */ -#include +#include -BEGIN_C_DECLS +#if defined(c_plusplus) || defined(__cplusplus) +extern "C" { +#endif /**** SERVER FUNCTION-SHIPPED APIs ****/ /* NOTE: for performance purposes, the host server is required to @@ -81,7 +78,6 @@ BEGIN_C_DECLS * by the host server via callback function is owned by the host * server, which is free to release it upon return from the callback */ - /* Notify the host server that a client connected to us - note * that the client will be in a blocked state until the host server * executes the callback function, thus allowing the PMIx server support @@ -487,6 +483,8 @@ pmix_status_t PMIx_server_dmodex_request(const pmix_proc_t *proc, pmix_dmodex_response_fn_t cbfunc, void *cbdata); -END_C_DECLS +#if defined(c_plusplus) || defined(__cplusplus) +} +#endif #endif diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix_tool.h b/opal/mca/pmix/pmix2x/pmix/include/pmix_tool.h index c4376e0b81..91aa6d3b81 100644 --- a/opal/mca/pmix/pmix2x/pmix/include/pmix_tool.h +++ b/opal/mca/pmix/pmix2x/pmix/include/pmix_tool.h @@ -59,18 +59,12 @@ #ifndef PMIx_TOOL_API_H #define PMIx_TOOL_API_H -#include - -/* Symbol transforms */ -#include - -/* Structure and constant definitions */ -#include - /* provide access to the rest of the client functions */ #include -BEGIN_C_DECLS +#if defined(c_plusplus) || defined(__cplusplus) +extern "C" { +#endif /**** TOOL INIT/FINALIZE FUNCTIONS ****/ @@ -104,6 +98,8 @@ pmix_status_t PMIx_tool_init(pmix_proc_t *proc, * operation. */ pmix_status_t PMIx_tool_finalize(void); -END_C_DECLS +#if defined(c_plusplus) || defined(__cplusplus) +} +#endif #endif diff --git a/opal/mca/pmix/pmix2x/pmix/man/Makefile.am b/opal/mca/pmix/pmix2x/pmix/man/Makefile.am new file mode 100644 index 0000000000..7c0f8bffe4 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/man/Makefile.am @@ -0,0 +1,60 @@ +# +# 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-2009 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) 2006-2016 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +if !PMIX_EMBEDDED_MODE + +man_MANS = \ + man3/pmix_init.3 \ + man3/pmix_finalize.3 \ + man3/pmix_initialized.3 \ + man3/pmix_abort.3 \ + man3/pmix_put.3 \ + man3/pmix_commit.3 \ + man7/pmix.7 \ + man7/pmix_constants.7 + +EXTRA_DIST = $(man_MANS) + +man3/pmix_init.3: + $(top_srcdir)/contrib/md2nroff.pl --source=pmix_init.3.md; + +man3/pmix_finalize.3: + $(top_srcdir)/contrib/md2nroff.pl --source=pmix_finalize.3.md; + +man3/pmix_initialized.3: + $(top_srcdir)/contrib/md2nroff.pl --source=pmix_initialized.3.md; + +man3/pmix_abort.3: + $(top_srcdir)/contrib/md2nroff.pl --source=pmix_abort.3.md; + +man3/pmix_put.3: + $(top_srcdir)/contrib/md2nroff.pl --source=pmix_put.3.md; + +man3/pmix_commit.3: + $(top_srcdir)/contrib/md2nroff.pl --source=pmix_commit.3.md; + +man7/pmix.7: + $(top_srcdir)/contrib/md2nroff.pl --source=pmix.7.md; + +man7/pmix_constants.7: + $(top_srcdir)/contrib/md2nroff.pl --source=pmix_constants.7.md; + +endif # !PMIX_EMBEDDED_MODE diff --git a/opal/mca/pmix/pmix2x/pmix/man/README b/opal/mca/pmix/pmix2x/pmix/man/README new file mode 100644 index 0000000000..73c605cb7f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/man/README @@ -0,0 +1,186 @@ +This file describes how the developer side of man pages work in PMIx. + +The Definitive Source Of Truth man pages are the Markdown man pages in +this directory (i.e., the files ending in ..md. If you want to +edit man pages, you need to edit the ..md pages. Do NOT edit +the . nroff man pages directly; these files are automatically +generated -- you will lose any manual edits the next time those files +are generated. + +The Markdown web pages are rendered in two different ways: + +1. Nroff man pages. These man pages are put into the `master` branch + and later included in PMIx distribution tarballs. + +2. HTML. The http://open-mpi.github.io/pmix/ web site (which is + served by the Github web servers) automatically renders the content + of the `gh-pages` branch of the PMIx repo. + +Markdown syntax +=============== + +The definitive man pages are the Markdown man pages. To edit them, +you need to understand the syntax used in these files. + +The canonical reference for Markdown is here: + + http://daringfireball.net/projects/markdown/syntax + +Note, however, that the PMIx Markdown man pages are served via +the Github Pages web servers, which use a system called Jekyll to +render the Markdown into HTML (https://github.com/jekyll/jekyll). +As such, there are a few Jekyll annotations in the PMIx Markdown +pages (so that they can be served up properly from Github's web +servers). + +If you're familiar with Markdown, you should be ok. But there are a +small number differences and quirks with which you should be familiar: + +1. The first few lines of each file are a YAML header and include + directive for Jekyll. DO NOT REMOVE THIS HEADER (or the file will + not render to HTML properly when served up from Github's web + servers). Here's a sample YAML header from pmix.7.md: + +--- +layout: page +title: PMIx(7) +tagline: PMIx Programmer's Manual +--- +{% include JB/setup %} + + The whole block is needed, and it must be the first input in the + file. + +2. In Github-flavored Markdown, you may be used to using "fenced + blocks" for multi-line code blocks, like this: + +```c +void my_c_code(void) { + int i; + /* Hello, world */ +} +``` + + Such fenced blocks will not work in Jekyll. Instead, you must + delineate your code blocks with Jekyll delimiters: + +{% highlight c %} +void my_c_code(void) { + int i; + /* Hello, world */ +} +{% endhighlight %} + + This will result in a pretty code box in the rendered HTML output, + and it will be syntax highlighted for the C language. Leave the + "c" out of the first directive if your multi-line block is not C + code, and then it won't do C syntax highlighting. + +3. The PMIx man pages are full of 2-level lists of things. E.g., + lists of functions, and then in some of the functions, there is a + sub-list of flags that can be used with that function. + + The convention used in the PMIx man pages is to highlight a + word/phrase representing each list item. Then use a ":" to start + the next line that describes that item. For example: + +*PMIX_FLOAT* +: A single-precision floating point value (IEEE 754). + + This will make the token "PMIX_FLOAT" be highlighted in both + HTML and nroff output, and then the paragraph that comes after it + will be properly delimited and indented. + + To make a sub-list inside an item, use the same format, but prefix + the sub-list items with "-", like this: + +*scope* +: Flag that controls the visible scope of the data. + +- *PMIX_GLOBAL* +: Indicates that the data is to be visible to all applications executed + by this user. + +4. There may be a small number of places in the PMIx man pages where + there are unnumbered lists with deliberate line breaks. For + example: + +foo / bar +baz / goo +: Something really intelligent + + Note the first line is "foo / bar", and then there is + a deliberate line break, and then the second line is "baz / goo". + + To effect the deliberate line break, you have to put two blank + spaces after "bar". To show that graphically (showing "_" + for " "): + +foo / bar__ +baz / goo +: Something really intelligent + +5. The "SEE ALSO" items at the end of each man page are linked to + their corresponding man pages. Note that the links are made to + ".html" files -- *not* ".md" files. If you care, the reason is + because the Github web servers statically generate .html files from + the .md files when you git push to the gh-pages branch. Hence, the + man pages are actually served from static .html files on the Github + web servers. + + Also, since links are meaningless in nroff, they are effectively + ignored in the resulting nroff output. + +Workflow +======== + +The workflow is like this: + +1. Developer edits ..md files for new changes. + +2. In a perfect world, the developer makes perfect edits and pushes + the changes up to `master`. An automated cron job will eventually + notice the new pages, and do two things: + + 2a. Copy the modified Markdown pages to the `gh-master` branch (so + that they go live on the web site). + + 2b. Re-generate any relevant nroff man pages in `master`. + + The automated cron job actually does exist and does these things, + but it should only be relied upon once a developer is sure that + their changes to the Markdown man pages are correct. + +3. To check that the changes will render properly, developers should + do two things: + + 3a. Run "make nroff". This will convert all the Markdown man pages + into nroff man pages (in the man/ directory). Check to ensure + that your changes look appropriate in the rendered nroff + output. + + *CAUTION* The "pandoc" utility is used to generate the nroff + files from the Markdown source. Different versions of pandoc + will generate slightly different nroff output. Meaning: when + you run "make nroff", you might end up changing every nroff man + page, simply because your version of pandoc is different than + the last person who ran it. Please only check in your changes, + if possible. + + 3b. Check out the `gh-pages` branch from PMIx and copy any + modified Markdown pages into the "master/man" directory (i.e., + the directory for man pages from the master development + branch). + + Then run the "jekyll serve" command from the top-level + directory in `gh-pages`. This runs a local web server on your + computer and renders the Markdown files into HTML such that you + can point a browser to http://127.0.0.1:4000 and see the web + site. + + If you make any changes to files in the tree where "jekyll" is + running, Jekyll will notice the changes and automatically + re-generate the relevant HTML. Meaning: you can just refresh + the page from http://127.0.0.1:4000 in your browser and you'll + see your changes -- there's no need to restart Jekyll to force + it to notice new changes. diff --git a/opal/mca/pmix/pmix2x/pmix/man/man3/pmix_fence.3 b/opal/mca/pmix/pmix2x/pmix/man/man3/pmix_fence.3 deleted file mode 100644 index ee659e47ab..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/man/man3/pmix_fence.3 +++ /dev/null @@ -1,95 +0,0 @@ -.TH "pmix_fence" "3" "2016\-03\-01" "PMIx Programmer\[aq]s Manual" "\@VERSION\@" -.SH NAME -.PP -PMIx_Fence[_nb] \- Execute a blocking[non\-blocking] barrier across the -processes identified in the specified array. -.SH SYNOPSIS -.IP -.nf -\f[C] -#include\ - -pmix\\_status\\_t\ PMIx\\_Fence(const\ pmix\\_proc\\_t\ procs[],\ size_t\ nprocs, -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ const\ pmix\\_info\\_t\ info[],\ size_t\ ninfo); - -pmix\\_status\\_t\ PMIx\\_Fence\\_nb(const\ pmix\\_proc\\_t\ procs[],\ size_t\ nprocs, -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ const\ pmix\\_info\\_t\ info[],\ size_t\ ninfo, -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ pmix_op_cbfunc_t\ cbfunc,\ void\ *cbdata); -\f[] -.fi -.SH ARGUMENTS -.PP -\f[I]procs\f[] : An array of pmix_proc_t structures defining the -processes that will be participating in the fence collective operation. -.PP -\f[I]nprocs\f[] : Number of pmix_proc_t structures in the \f[I]procs\f[] -array -.PP -\f[I]info\f[] : An optional array of pmix_info_t structures -.PP -\f[I]ninfo\f[] : Number of pmix_info_t structures in the pmix_info_t -array -.SH DESCRIPTION -.PP -Execute a blocking[non\-blocking] barrier across the processes -identified in the specified array. -Passing a \f[I]NULL\f[] pointer as the \f[I]procs\f[] parameter -indicates that the barrier is to span all processes in the client\[aq]s -namespace. -Each provided pmix_proc_t struct can pass PMIX_RANK_WILDCARD to indicate -that all processes in the given namespace are participating. -.PP -The info array is used to pass user requests regarding the fence -operation. -This can include: -.IP "(a)" 4 -PMIX_COLLECT_DATA \- a boolean indicating whether or not the barrier -operation is to return the \f[I]put\f[] data from all participating -processes. -A value of \f[I]false\f[] indicates that the callback is just used as a -release and no data is to be returned at that time. -A value of \f[I]true\f[] indicates that all \f[I]put\f[] data is to be -collected by the barrier. -Returned data is cached at the server to reduce memory footprint, and -can be retrieved as needed by calls to PMIx_Get(nb). -.RS 4 -.PP -Note that for scalability reasons, the default behavior for PMIx_Fence -is to \f[I]not\f[] collect the data. -.RE -.IP "(b)" 4 -PMIX_COLLECTIVE_ALGO \- a comma\-delimited string indicating the algos -to be used for executing the barrier, in priority order. -Note that PMIx itself does not contain any internode communication -support. -Thus, execution of the \f[I]fence\f[] collective is deferred to the host -resource manager, which are free to implement whatever algorithms they -choose. -Thus, different resource managers may or may not be able to comply with -a request for a specific algorithm, or set of algorithms. -Marking this info key as \f[I]required\f[] instructs the host RM that it -should return an error if none of the specified algos are available. -Otherwise, the RM is to use one of the specified algos if possible, but -is free to use any of its available methods to execute the operation if -none of the specified algos are available. -.IP "(c)" 4 -PMIX_TIMEOUT \- maximum time for the fence to execute before declaring -an error. -By default, the RM shall terminate the operation and notify participants -if one or more of the indicated procs fails during the fence. -However, the timeout parameter can help avoid "hangs" due to programming -errors that prevent one or more procs from reaching the "fence". -.SH RETURN VALUE -.PP -Returns PMIX_SUCCESS on success. -On error, a negative value corresponding to a PMIx errno is returned. -.SH ERRORS -.PP -PMIx errno values are defined in \f[C]pmix_common.h\f[]. -.SH NOTES -.SH SEE ALSO -.PP -\f[C]PMIx_Put\f[](3), \f[C]PMIx_Commit\f[](3), -\f[C]PMIx_Constants\f[](7) -.SH AUTHORS -PMIx. diff --git a/opal/mca/pmix/pmix2x/pmix/man/man3/pmix_get.3 b/opal/mca/pmix/pmix2x/pmix/man/man3/pmix_get.3 deleted file mode 100644 index f842731823..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/man/man3/pmix_get.3 +++ /dev/null @@ -1,87 +0,0 @@ -.TH "pmix_get" "3" "2016\-03\-01" "PMIx Programmer\[aq]s Manual" "\@VERSION\@" -.SH NAME -.PP -PMIx_Get[_nb] \- Retrieve data that was pushed into the PMIx key\-value -store via calls to \f[I]PMIx_Put\f[] and \f[I]PMIx_Commit\f[]. -.SH SYNOPSIS -.IP -.nf -\f[C] -#include\ - -pmix\\_status\\_t\ PMIx\\_Get(const\ pmix\\_proc\\_t\ *proc,\ const\ char\ key[], -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ const\ pmix\\_info\\_t\ info[],\ size_t\ ninfo, -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ pmix\\_value\\_t\ **val); - -pmix\\_status\\_t\ PMIx_Get_nb(const\ pmix\\_proc\\_t\ *proc,\ const\ char\ key[], -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ const\ pmix\\_info\\_t\ info[],\ size_t\ ninfo, -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ pmix\\_value\\_cbfunc_t\ cbfunc,\ void\ *cbdata); -\f[] -.fi -.SH ARGUMENTS -.PP -\f[I]proc\f[] : A pointer to a pmix_proc_t structure identifying the -namespace and rank of the proc whose data is being requested. -Note that a \f[I]NULL\f[] value is permitted if the specified -\f[I]key\f[] is unique within the PMIx key\-value store. -This is provided for use by the backward compatibility APIs and is -\f[I]not\f[] recommended for use by native PMIx applications. -.PP -\f[I]key\f[] : String key identifying the information. -This can be either one of the PMIx defined attributes, or a -user\-defined value -.PP -\f[I]info\f[] : An optional array of pmix_info_t structures -.PP -\f[I]ninfo\f[] : The number of pmix_info_t structures in the specified -\f[I]info\f[] array. -.PP -\f[I]val\f[] : Address where the pointer to a pmix_value_t structure -containing the data to be returned can be placed. -Note that the caller is responsible for releasing the malloc\[aq]d -storage. -The \f[I]PMIX_VALUE_FREE\f[] macro is provided for this purpose. -.SH DESCRIPTION -.PP -Retrieve information for the specified \f[I]key\f[] as published by the -process identified in the given pmix_proc_t, returning a pointer to the -value in the given address. -.PP -The blocking form of this function will block until the specified data -has been pushed into the PMIx key\-value store via a call to -\f[I]PMIx_Commit\f[] by the specified process. -The caller is responsible for freeing all memory associated with the -returned value when no longer required. -.PP -The non\-blocking form will execute the callback function once the -specified data becomes available and has been retrieved by the local -server. -Note that failure of the specified process to \f[I]put\f[] and -\f[I]commit\f[] the requested data can result in the callback function -never being executed. -.PP -The info array is used to pass user requests regarding the get -operation. -This can include: -.IP "(a)" 4 -PMIX_TIMEOUT \- maximum time for the get to execute before declaring an -error. -The timeout parameter can help avoid "hangs" due to programming errors -that prevent the target proc from ever exposing its data. -.SH RETURN VALUE -.PP -Returns PMIX_SUCCESS on success. -On error, a negative value corresponding to a PMIx errno is returned. -.SH ERRORS -.PP -PMIx errno values are defined in \f[C]pmix_common.h\f[]. -.SH NOTES -.PP -See \[aq]_pmix_common.h\[aq] for definition of the pmix_value_t -structure. -.SH SEE ALSO -.PP -\f[C]PMIx_Put\f[](3), \f[C]PMIx_Commit\f[](3), -\f[C]PMIx_Constants\f[](7), \f[C]PMIx_Structures\f[](7) -.SH AUTHORS -PMIx. diff --git a/opal/mca/pmix/pmix2x/pmix/src/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/Makefile.am new file mode 100644 index 0000000000..905b42dd0e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/Makefile.am @@ -0,0 +1,81 @@ +# +# 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-2009 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) 2006-2016 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. +# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# Note that the -I directory must *exactly* match what was specified +# via AC_CONFIG_MACRO_DIR in configure.ac. +ACLOCAL_AMFLAGS = -I ./config + +SUBDIRS = \ + util/keyval \ + mca/base \ + $(MCA_pmix_FRAMEWORKS_SUBDIRS) \ + $(MCA_pmix_FRAMEWORK_COMPONENT_STATIC_SUBDIRS) \ + . \ + $(MCA_pmix_FRAMEWORK_COMPONENT_DSO_SUBDIRS) + +DIST_SUBDIRS = \ + util/keyval \ + mca/base \ + $(MCA_pmix_FRAMEWORKS_SUBDIRS) \ + $(MCA_pmix_FRAMEWORK_COMPONENT_ALL_SUBDIRS) + +headers = +sources = +nodist_headers = +EXTRA_DIST = +dist_pmixdata_DATA = + +libpmix_la_LIBADD = \ + mca/base/libpmix_mca_base.la \ + $(MCA_pmix_FRAMEWORK_LIBS) +libpmix_la_DEPENDENCIES = $(libpmix_la_LIBADD) + +if PMIX_EMBEDDED_MODE +noinst_LTLIBRARIES = libpmix.la +libpmix_la_SOURCES = $(headers) $(sources) +libpmix_la_LDFLAGS = + +else + +lib_LTLIBRARIES = libpmix.la +libpmix_la_SOURCES = $(headers) $(sources) +libpmix_la_LDFLAGS = -version-info $(libpmix_so_version) + +endif !PMIX_EMBEDDED_MODE + +include class/Makefile.include +include event/Makefile.include +include include/Makefile.include +include mca/Makefile.include +include util/Makefile.include +include client/Makefile.include +include server/Makefile.include +include runtime/Makefile.include +include tool/Makefile.include +include common/Makefile.include +include buffer_ops/Makefile.am +include usock/Makefile.am +include sec/Makefile.am + +MAINTAINERCLEANFILES = Makefile.in config.h config.h.in +DISTCLEANFILES = Makefile +CLEANFILES = core.* *~ +AM_CFLAGS = -Wall diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/Makefile.am index a737b15abd..31a093e3f5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/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-2015 Intel, Inc. All rights reserved +# Copyright (c) 2013-2016 Intel, Inc. All rights reserved # $COPYRIGHT$ # # Additional copyrights may follow @@ -23,14 +23,14 @@ # src/Makefile.am headers += \ - src/buffer_ops/buffer_ops.h \ - src/buffer_ops/types.h \ - src/buffer_ops/internal.h + buffer_ops/buffer_ops.h \ + buffer_ops/types.h \ + buffer_ops/internal.h sources += \ - src/buffer_ops/copy.c \ - src/buffer_ops/internal_functions.c \ - src/buffer_ops/open_close.c \ - src/buffer_ops/pack.c \ - src/buffer_ops/print.c \ - src/buffer_ops/unpack.c + 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 diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/copy.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/copy.c index 229a475329..deaf244fd0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/copy.c +++ b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/copy.c @@ -533,6 +533,7 @@ pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) sv = (pmix_value_t*)src->data.darray.array; for (n=0; n < src->data.darray.size; n++) { if (PMIX_SUCCESS != (rc = pmix_value_xfer(&pv[n], &sv[n]))) { + PMIX_VALUE_FREE(pv, src->data.darray.size); return rc; } } @@ -566,6 +567,7 @@ pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) 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, src->data.darray.size); return PMIX_ERR_NOMEM; } pa[n].ninfo = sa[n].ninfo; @@ -638,6 +640,7 @@ pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) if (NULL != sk[n].value) { PMIX_VALUE_CREATE(pk[n].value, 1); if (NULL == pk[n].value) { + free(p->data.darray.array); return PMIX_ERR_NOMEM; } if (PMIX_SUCCESS != (rc = pmix_value_xfer(pk[n].value, sk[n].value))) { @@ -676,7 +679,7 @@ pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) memcpy(p->data.darray.array, src->data.darray.array, src->data.darray.size * sizeof(pmix_persistence_t)); break; case PMIX_POINTER: - p->data.darray.array = (void*)malloc(src->data.darray.size * sizeof(void*)); + p->data.darray.array = (void**)malloc(src->data.darray.size * sizeof(void*)); if (NULL == p->data.darray.array) { return PMIX_ERR_NOMEM; } @@ -750,6 +753,7 @@ pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src) if (NULL != sq[n].qualifiers && 0 < sq[n].nqual) { PMIX_INFO_CREATE(pq[n].qualifiers, sq[n].nqual); if (NULL == pq[n].qualifiers) { + PMIX_QUERY_FREE(pq, src->data.darray.size); return PMIX_ERR_NOMEM; } for (m=0; m < sq[n].nqual; m++) { @@ -1002,6 +1006,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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); @@ -1010,6 +1015,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1018,6 +1024,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1026,6 +1033,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1033,6 +1041,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1040,6 +1049,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1047,6 +1057,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1054,6 +1065,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1068,6 +1080,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1075,6 +1088,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1082,6 +1096,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1089,6 +1104,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1096,6 +1112,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1103,6 +1120,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1110,6 +1128,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1123,6 +1142,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1130,6 +1150,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1137,6 +1158,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1156,6 +1178,8 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1167,6 +1191,10 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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++) { @@ -1176,6 +1204,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1187,6 +1216,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1199,6 +1229,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, case PMIX_BYTE_OBJECT: 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; @@ -1217,6 +1248,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1228,6 +1260,8 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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))) { @@ -1239,6 +1273,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1248,6 +1283,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, if (NULL != sm[n].blob && 0 < sm[n].size) { pm[n].blob = (uint8_t*)malloc(sm[n].size); if (NULL == pm[n].blob) { + free(p); return PMIX_ERR_NOMEM; } memcpy(pm[n].blob, sm[n].blob, sm[n].size); @@ -1261,13 +1297,15 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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 = (void*)malloc(src->size * sizeof(void*)); + p->array = (void**)malloc(src->size * sizeof(void*)); if (NULL == p->array) { + free(p); return PMIX_ERR_NOMEM; } memcpy(p->array, src->array, src->size * sizeof(void*)); @@ -1275,6 +1313,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1282,6 +1321,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1289,6 +1329,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1296,6 +1337,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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)); @@ -1303,6 +1345,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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; @@ -1325,10 +1368,12 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, } 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; @@ -1340,6 +1385,8 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, 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++) { @@ -1353,6 +1400,7 @@ pmix_status_t pmix_bfrop_copy_darray(pmix_data_array_t **dest, } break; default: + free(p); return PMIX_ERR_UNKNOWN_DATA_TYPE; } @@ -1373,6 +1421,7 @@ pmix_status_t pmix_bfrop_copy_query(pmix_query_t **dest, (*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; } } 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 index ee7728e23a..b3c4d723a3 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c +++ b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c @@ -26,7 +26,7 @@ */ #include -#include +#include #ifdef HAVE_STRING_H #include diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/print.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/print.c index c6b8044929..3bce173b23 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/print.c +++ b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/print.c @@ -23,7 +23,7 @@ #include -#include +#include #include #ifdef HAVE_TIME_H diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/types.h b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/types.h index cb9288131a..c48a30b8b5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/types.h +++ b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/types.h @@ -34,7 +34,7 @@ #include "src/class/pmix_object.h" #include "src/class/pmix_pointer_array.h" #include "src/class/pmix_list.h" -#include +#include BEGIN_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/class/Makefile.include similarity index 62% rename from opal/mca/pmix/pmix2x/pmix/src/class/Makefile.am rename to opal/mca/pmix/pmix2x/pmix/src/class/Makefile.include index d13dad2d5d..904995173d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/class/Makefile.include @@ -11,6 +11,7 @@ # 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) 2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -19,21 +20,23 @@ # # This makefile.am does not stand on its own - it is included from -# src/Makefile.am +# Makefile.am # Source code files headers += \ - src/class/pmix_object.h \ - src/class/pmix_list.h \ - src/class/pmix_pointer_array.h \ - src/class/pmix_hash_table.h \ - src/class/pmix_hotel.h \ - src/class/pmix_ring_buffer.h + class/pmix_object.h \ + class/pmix_list.h \ + class/pmix_pointer_array.h \ + class/pmix_hash_table.h \ + class/pmix_hotel.h \ + class/pmix_ring_buffer.h \ + class/pmix_value_array.h sources += \ - src/class/pmix_object.c \ - src/class/pmix_list.c \ - src/class/pmix_pointer_array.c \ - src/class/pmix_hash_table.c \ - src/class/pmix_hotel.c \ - src/class/pmix_ring_buffer.c + class/pmix_object.c \ + class/pmix_list.c \ + class/pmix_pointer_array.c \ + class/pmix_hash_table.c \ + class/pmix_hotel.c \ + class/pmix_ring_buffer.c \ + class/pmix_value_array.c 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 609cf257fc..ead33aecfa 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 @@ -12,7 +12,6 @@ * 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) 2016 IBM Corporation. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -30,16 +29,47 @@ #include "src/class/pmix_list.h" #include "src/class/pmix_hash_table.h" -#include +#include "include/pmix_common.h" /* * pmix_hash_table_t */ +#define HASH_MULTIPLIER 31 + +/* + * Define the structs that are opaque in the .h + */ + +struct pmix_hash_element_t { + int valid; /* whether this element is valid */ + union { /* the key, in its various forms */ + uint32_t u32; + uint64_t u64; + struct { + const void * key; + size_t key_size; + } ptr; + } key; + void * value; /* the value */ +}; +typedef struct pmix_hash_element_t pmix_hash_element_t; + +struct pmix_hash_type_methods_t { + /* Frees any storage associated with the element + * The value is not owned by the hash table + * The key,key_size of pointer keys is + */ + void (*elt_destructor)(pmix_hash_element_t * elt); + /* Hash the key of the element -- for growing and adjusting-after-removal */ + uint64_t (*hash_elt)(pmix_hash_element_t * elt); +}; + +/* interact with the class-like mechanism */ + static void pmix_hash_table_construct(pmix_hash_table_t* ht); static void pmix_hash_table_destruct(pmix_hash_table_t* ht); - PMIX_CLASS_INSTANCE( pmix_hash_table_t, pmix_object_t, @@ -47,561 +77,720 @@ PMIX_CLASS_INSTANCE( pmix_hash_table_destruct ); - -static void pmix_hash_table_construct(pmix_hash_table_t* ht) +static void +pmix_hash_table_construct(pmix_hash_table_t* ht) { - PMIX_CONSTRUCT(&ht->ht_nodes, pmix_list_t); - ht->ht_table = NULL; - ht->ht_table_size = 0; - ht->ht_size = 0; + ht->ht_table = NULL; + ht->ht_capacity = ht->ht_size = ht->ht_growth_trigger = 0; + ht->ht_density_numer = ht->ht_density_denom = 0; + ht->ht_growth_numer = ht->ht_growth_denom = 0; + ht->ht_type_methods = NULL; } - -static void pmix_hash_table_destruct(pmix_hash_table_t* ht) +static void +pmix_hash_table_destruct(pmix_hash_table_t* ht) { - size_t i; pmix_hash_table_remove_all(ht); - for(i=0; iht_table_size; i++) { - PMIX_DESTRUCT(ht->ht_table+i); - } - if(NULL != ht->ht_table) { - free(ht->ht_table); - } - PMIX_DESTRUCT(&ht->ht_nodes); + free(ht->ht_table); } +/* + * Init, etc + */ -pmix_status_t pmix_hash_table_init(pmix_hash_table_t* ht, size_t table_size) +static size_t +pmix_hash_round_capacity_up(size_t capacity) { - size_t i; - size_t power2 = pmix_next_poweroftwo (table_size); + /* round up to (1 mod 30) */ + return ((capacity+29)/30*30 + 1); +} - ht->ht_mask = power2-1; - ht->ht_table = (pmix_list_t *)malloc(power2 * sizeof(pmix_list_t)); - if(NULL == ht->ht_table) { +/* this could be the new init if people wanted a more general API */ +/* (that's why it isn't static) */ +int /* PMIX_ return code */ +pmix_hash_table_init2(pmix_hash_table_t* ht, size_t estimated_max_size, + int density_numer, int density_denom, + int growth_numer, int growth_denom) +{ + size_t est_capacity = estimated_max_size * density_denom / density_numer; + size_t capacity = pmix_hash_round_capacity_up(est_capacity); + ht->ht_table = (pmix_hash_element_t*) calloc(capacity, sizeof(pmix_hash_element_t)); + if (NULL == ht->ht_table) { return PMIX_ERR_OUT_OF_RESOURCE; } - for(i=ht->ht_table_size; iht_table+i; - PMIX_CONSTRUCT(list, pmix_list_t); - } - ht->ht_table_size = power2; + ht->ht_capacity = capacity; + ht->ht_density_numer = density_numer; + ht->ht_density_denom = density_denom; + ht->ht_growth_numer = growth_numer; + ht->ht_growth_denom = growth_denom; + ht->ht_growth_trigger = capacity * density_numer / density_denom; + ht->ht_type_methods = NULL; return PMIX_SUCCESS; } -pmix_status_t pmix_hash_table_remove_all(pmix_hash_table_t* ht) +int /* PMIX_ return code */ +pmix_hash_table_init(pmix_hash_table_t* ht, size_t table_size) { - size_t i; - for(i=0; iht_table_size; i++) { - pmix_list_t* list = ht->ht_table+i; - while(pmix_list_get_size(list)) { - pmix_list_item_t *item = pmix_list_remove_first(list); - PMIX_RELEASE(item); - } - } + /* default to density of 1/2 and growth of 2/1 */ + return pmix_hash_table_init2(ht, table_size, 1, 2, 2, 1); +} - while(pmix_list_get_size(&ht->ht_nodes)) { - pmix_list_item_t* item = pmix_list_remove_first(&ht->ht_nodes); - PMIX_RELEASE(item); +int /* PMIX_ return code */ +pmix_hash_table_remove_all(pmix_hash_table_t* ht) +{ + size_t ii; + for (ii = 0; ii < ht->ht_capacity; ii += 1) { + pmix_hash_element_t * elt = &ht->ht_table[ii]; + if (elt->valid && ht->ht_type_methods && ht->ht_type_methods->elt_destructor) { + ht->ht_type_methods->elt_destructor(elt); + } + elt->valid = 0; + elt->value = NULL; } ht->ht_size = 0; + /* the tests reuse the hash table for different types after removing all */ + /* so we should allow that by forgetting what type it used to be */ + ht->ht_type_methods = NULL; + return PMIX_SUCCESS; +} + +static int /* PMIX_ return code */ +pmix_hash_grow(pmix_hash_table_t * ht) +{ + size_t jj, ii; + pmix_hash_element_t* old_table; + pmix_hash_element_t* new_table; + size_t old_capacity; + size_t new_capacity; + + old_table = ht->ht_table; + old_capacity = ht->ht_capacity; + + new_capacity = old_capacity * ht->ht_growth_numer / ht->ht_growth_denom; + new_capacity = pmix_hash_round_capacity_up(new_capacity); + + new_table = (pmix_hash_element_t*) calloc(new_capacity, sizeof(new_table[0])); + if (NULL == new_table) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + /* for each element of the old table (indexed by jj), insert it + into the new table (indexed by ii), using the hash_elt method + to generically hash an element, then modulo the new capacity, + and using struct-assignment to copy an old element into its + place int he new table. The hash table never owns the value, + and in the case of ptr keys the old dlements will be blindly + deleted, so we still own the ptr key storage, just in the new + table now */ + for (jj = 0; jj < old_capacity; jj += 1) { + pmix_hash_element_t * old_elt; + pmix_hash_element_t * new_elt; + old_elt = &old_table[jj]; + if (old_elt->valid) { + for (ii = (ht->ht_type_methods->hash_elt(old_elt)%new_capacity); ; ii += 1) { + if (ii == new_capacity) { ii = 0; } + new_elt = &new_table[ii]; + if (! new_elt->valid) { + *new_elt = *old_elt; + break; + } + } + } + } + /* update with the new, free the old, return */ + ht->ht_table = new_table; + ht->ht_capacity = new_capacity; + ht->ht_growth_trigger = new_capacity * ht->ht_density_numer / ht->ht_density_denom; + free(old_table); + return PMIX_SUCCESS; +} + +/* one of the removal functions has determined which element should be + removed. With the help of the type methods this can be generic. + The important thing is to rehash any valid elements immediately + following the element-being-removed */ +static int /* PMIX_ return code */ +pmix_hash_table_remove_elt_at(pmix_hash_table_t * ht, size_t ii) +{ + size_t jj, capacity = ht->ht_capacity; + pmix_hash_element_t* elts = ht->ht_table; + pmix_hash_element_t * elt; + + elt = &elts[ii]; + + if (! elt->valid) { + /* huh? removing a not-valid element? */ + return PMIX_ERROR; + } + + elt->valid = 0; + if (ht->ht_type_methods->elt_destructor) { + ht->ht_type_methods->elt_destructor(elt); + } + + /* need to possibly re-insert followers because of the now-gap */ + /* E.g., XYyAaCbz. (where upper is ideal, lower is not) + * remove A + * leaving XYy.aCbz. and we need to reconsider aCbz + * first a gets reinserted where it wants to be: XYya.Cbz. + * next C doesn't move: XYya.Cbz. + * then b gets put where it wants to be: XYyabC.z. + * then z moves down a little: XYyabCz.. + * then . means we're done + */ + for (ii = ii+1; ; ii += 1) { /* scan immediately following elements */ + if (ii == capacity) { ii = 0; } + elt = &elts[ii]; + if (! elt->valid) { + break; /* done */ + } + /* rehash it and move it if necessary */ + for (jj = ht->ht_type_methods->hash_elt(elt)%capacity; ; jj += 1) { + if (jj == capacity) { jj = 0; } + if (jj == ii) { + /* already in place, either ideal or best-for-now */ + break; + } else if (! elts[jj].valid) { + /* move it down, and invaildate where it came from */ + elts[jj] = elts[ii]; + elts[ii].valid = 0; + break; + } else { + /* still need to find its place */ + } + } + } ht->ht_size -= 1; return PMIX_SUCCESS; } + /***************************************************************************/ -/* - * pmix_uint32_hash_node_t - */ - -struct pmix_uint32_hash_node_t +static uint64_t +pmix_hash_hash_elt_uint32(pmix_hash_element_t * elt) { - pmix_list_item_t super; - uint32_t hn_key; - void *hn_value; + return elt->key.u32; +} + +static const struct pmix_hash_type_methods_t +pmix_hash_type_methods_uint32 = { + NULL, + pmix_hash_hash_elt_uint32 }; -typedef struct pmix_uint32_hash_node_t pmix_uint32_hash_node_t; -static PMIX_CLASS_INSTANCE(pmix_uint32_hash_node_t, - pmix_list_item_t, - NULL, - NULL); - - -pmix_status_t pmix_hash_table_get_value_uint32(pmix_hash_table_t* ht, uint32_t key, - void **ptr) +int /* PMIX_ return code */ +pmix_hash_table_get_value_uint32(pmix_hash_table_t* ht, uint32_t key, void * *value) { - pmix_list_t* list = ht->ht_table + (key & ht->ht_mask); - pmix_uint32_hash_node_t *node; + size_t ii, capacity = ht->ht_capacity; + pmix_hash_element_t * elt; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { + if(capacity == 0) { pmix_output(0, "pmix_hash_table_get_value_uint32:" - "pmix_hash_table_init() has not been called"); + "pmix_hash_table_init() has not been called"); return PMIX_ERROR; } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_uint32 != ht->ht_type_methods) { + pmix_output(0, "pmix_hash_table_get_value_uint32:" + "hash table is for a different key type"); + return PMIX_ERROR; + } #endif - for(node = (pmix_uint32_hash_node_t*)pmix_list_get_first(list); - node != (pmix_uint32_hash_node_t*)pmix_list_get_end(list); - node = (pmix_uint32_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key == key) { - *ptr = node->hn_value; + + ht->ht_type_methods = &pmix_hash_type_methods_uint32; + for (ii = key%capacity; ; ii += 1) { + if (ii == capacity) { ii = 0; } + elt = &ht->ht_table[ii]; + if (! elt->valid) { + return PMIX_ERR_NOT_FOUND; + } else if (elt->key.u32 == key) { + *value = elt->value; return PMIX_SUCCESS; + } else { + /* keey looking */ } } - return PMIX_ERR_NOT_FOUND; + } - -pmix_status_t pmix_hash_table_set_value_uint32(pmix_hash_table_t* ht, - uint32_t key, void* value) +int /* PMIX_ return code */ +pmix_hash_table_set_value_uint32(pmix_hash_table_t * ht, uint32_t key, void * value) { - pmix_list_t* list = ht->ht_table + (key & ht->ht_mask); - pmix_uint32_hash_node_t *node; + int rc; + size_t ii, capacity = ht->ht_capacity; + pmix_hash_element_t * elt; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { + if(capacity == 0) { pmix_output(0, "pmix_hash_table_set_value_uint32:" - "pmix_hash_table_init() has not been called"); + "pmix_hash_table_init() has not been called"); return PMIX_ERR_BAD_PARAM; } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_uint32 != ht->ht_type_methods) { + pmix_output(0, "pmix_hash_table_set_value_uint32:" + "hash table is for a different key type"); + return PMIX_ERROR; + } #endif - for(node = (pmix_uint32_hash_node_t*)pmix_list_get_first(list); - node != (pmix_uint32_hash_node_t*)pmix_list_get_end(list); - node = (pmix_uint32_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key == key) { - node->hn_value = value; + + ht->ht_type_methods = &pmix_hash_type_methods_uint32; + for (ii = key%capacity; ; ii += 1) { + if (ii == capacity) { ii = 0; } + elt = &ht->ht_table[ii]; + if (! elt->valid) { + /* new entry */ + elt->key.u32 = key; + elt->value = value; + elt->valid = 1; + ht->ht_size += 1; + if (ht->ht_size >= ht->ht_growth_trigger) { + if (PMIX_SUCCESS != (rc = pmix_hash_grow(ht))) { + return rc; + } + } return PMIX_SUCCESS; + } else if (elt->key.u32 == key) { + /* replace existing element */ + elt->value = value; + return PMIX_SUCCESS; + } else { + /* keep looking */ } } - - node = (pmix_uint32_hash_node_t*)pmix_list_remove_first(&ht->ht_nodes); - if(NULL == node) { - node = PMIX_NEW(pmix_uint32_hash_node_t); - if(NULL == node) - return PMIX_ERR_OUT_OF_RESOURCE; - } - node->hn_key = key; - node->hn_value = value; - pmix_list_append(list, (pmix_list_item_t*)node); - ht->ht_size++; - return PMIX_SUCCESS; } - -pmix_status_t pmix_hash_table_remove_value_uint32(pmix_hash_table_t* ht, uint32_t key) +int +pmix_hash_table_remove_value_uint32(pmix_hash_table_t * ht, uint32_t key) { - pmix_list_t* list = ht->ht_table + (key & ht->ht_mask); - pmix_uint32_hash_node_t *node; + size_t ii, capacity = ht->ht_capacity; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { + if(capacity == 0) { + pmix_output(0, "pmix_hash_table_get_value_uint32:" + "pmix_hash_table_init() has not been called"); + return PMIX_ERROR; + } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_uint32 != ht->ht_type_methods) { pmix_output(0, "pmix_hash_table_remove_value_uint32:" - "pmix_hash_table_init() has not been called"); - return PMIX_ERR_BAD_PARAM; + "hash table is for a different key type"); + return PMIX_ERROR; } #endif - for(node = (pmix_uint32_hash_node_t*)pmix_list_get_first(list); - node != (pmix_uint32_hash_node_t*)pmix_list_get_end(list); - node = (pmix_uint32_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key == key) { - pmix_list_remove_item(list, (pmix_list_item_t*)node); - pmix_list_append(&ht->ht_nodes, (pmix_list_item_t*)node); - ht->ht_size--; - return PMIX_SUCCESS; + + ht->ht_type_methods = &pmix_hash_type_methods_uint32; + for (ii = key%capacity; ; ii += 1) { + pmix_hash_element_t * elt; + if (ii == capacity) ii = 0; + elt = &ht->ht_table[ii]; + if (! elt->valid) { + return PMIX_ERR_NOT_FOUND; + } else if (elt->key.u32 == key) { + return pmix_hash_table_remove_elt_at(ht, ii); + } else { + /* keep looking */ } } - return PMIX_ERR_NOT_FOUND; } + /***************************************************************************/ -/* - * pmix_uint64_hash_node_t - */ -struct pmix_uint64_hash_node_t +static uint64_t +pmix_hash_hash_elt_uint64(pmix_hash_element_t * elt) { - pmix_list_item_t super; - uint64_t hn_key; - void* hn_value; + return elt->key.u64; +} + +static const struct pmix_hash_type_methods_t +pmix_hash_type_methods_uint64 = { + NULL, + pmix_hash_hash_elt_uint64 }; -typedef struct pmix_uint64_hash_node_t pmix_uint64_hash_node_t; -static PMIX_CLASS_INSTANCE(pmix_uint64_hash_node_t, - pmix_list_item_t, - NULL, - NULL); - - -pmix_status_t pmix_hash_table_get_value_uint64(pmix_hash_table_t* ht, uint64_t key, - void **ptr) +int /* PMIX_ return code */ +pmix_hash_table_get_value_uint64(pmix_hash_table_t * ht, uint64_t key, void * *value) { - pmix_list_t* list = ht->ht_table + (key & ht->ht_mask); - pmix_uint64_hash_node_t *node; + size_t ii; + size_t capacity = ht->ht_capacity; + pmix_hash_element_t * elt; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { + if(capacity == 0) { pmix_output(0, "pmix_hash_table_get_value_uint64:" - "pmix_hash_table_init() has not been called"); + "pmix_hash_table_init() has not been called"); return PMIX_ERROR; } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_uint64 != ht->ht_type_methods) { + pmix_output(0, "pmix_hash_table_get_value_uint64:" + "hash table is for a different key type"); + return PMIX_ERROR; + } #endif - for(node = (pmix_uint64_hash_node_t*)pmix_list_get_first(list); - node != (pmix_uint64_hash_node_t*)pmix_list_get_end(list); - node = (pmix_uint64_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key == key) { - *ptr = node->hn_value; + + ht->ht_type_methods = &pmix_hash_type_methods_uint64; + for (ii = key%capacity; ; ii += 1) { + if (ii == capacity) { ii = 0; } + elt = &ht->ht_table[ii]; + if (! elt->valid) { + return PMIX_ERR_NOT_FOUND; + } else if (elt->key.u64 == key) { + *value = elt->value; return PMIX_SUCCESS; + } else { + /* keep looking */ } } - return PMIX_ERR_NOT_FOUND; + } - -pmix_status_t pmix_hash_table_set_value_uint64(pmix_hash_table_t* ht, - uint64_t key, void* value) +int /* PMIX_ return code */ +pmix_hash_table_set_value_uint64(pmix_hash_table_t * ht, uint64_t key, void * value) { - pmix_list_t* list = ht->ht_table + (key & ht->ht_mask); - pmix_uint64_hash_node_t *node; + int rc; + size_t ii, capacity = ht->ht_capacity; + pmix_hash_element_t * elt; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { + if(capacity == 0) { pmix_output(0, "pmix_hash_table_set_value_uint64:" - "pmix_hash_table_init() has not been called"); + "pmix_hash_table_init() has not been called"); return PMIX_ERR_BAD_PARAM; } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_uint64 != ht->ht_type_methods) { + pmix_output(0, "pmix_hash_table_set_value_uint64:" + "hash table is for a different key type"); + return PMIX_ERROR; + } #endif - for(node = (pmix_uint64_hash_node_t*)pmix_list_get_first(list); - node != (pmix_uint64_hash_node_t*)pmix_list_get_end(list); - node = (pmix_uint64_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key == key) { - node->hn_value = value; - return PMIX_SUCCESS; - } - } - node = (pmix_uint64_hash_node_t*)pmix_list_remove_first(&ht->ht_nodes); - if(NULL == node) { - node = PMIX_NEW(pmix_uint64_hash_node_t); - if(NULL == node) { - return PMIX_ERR_OUT_OF_RESOURCE; + ht->ht_type_methods = &pmix_hash_type_methods_uint64; + for (ii = key%capacity; ; ii += 1) { + if (ii == capacity) { ii = 0; } + elt = &ht->ht_table[ii]; + if (! elt->valid) { + /* new entry */ + elt->key.u64 = key; + elt->value = value; + elt->valid = 1; + ht->ht_size += 1; + if (ht->ht_size >= ht->ht_growth_trigger) { + if (PMIX_SUCCESS != (rc = pmix_hash_grow(ht))) { + return rc; + } + } + return PMIX_SUCCESS; + } else if (elt->key.u64 == key) { + elt->value = value; + return PMIX_SUCCESS; + } else { + /* keep looking */ } } - node->hn_key = key; - node->hn_value = value; - pmix_list_append(list, (pmix_list_item_t*)node); - ht->ht_size++; - return PMIX_SUCCESS; } -pmix_status_t pmix_hash_table_remove_value_uint64(pmix_hash_table_t* ht, uint64_t key) +int /* PMIX_ return code */ +pmix_hash_table_remove_value_uint64(pmix_hash_table_t * ht, uint64_t key) { - pmix_list_t* list = ht->ht_table + (key & ht->ht_mask); - pmix_uint64_hash_node_t *node; + size_t ii, capacity = ht->ht_capacity; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { + if(capacity == 0) { + pmix_output(0, "pmix_hash_table_get_value_uint64:" + "pmix_hash_table_init() has not been called"); + return PMIX_ERROR; + } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_uint64 != ht->ht_type_methods) { pmix_output(0, "pmix_hash_table_remove_value_uint64:" - "pmix_hash_table_init() has not been called"); - return PMIX_ERR_BAD_PARAM; + "hash table is for a different key type"); + return PMIX_ERROR; } #endif - for(node = (pmix_uint64_hash_node_t*)pmix_list_get_first(list); - node != (pmix_uint64_hash_node_t*)pmix_list_get_end(list); - node = (pmix_uint64_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key == key) { - pmix_list_remove_item(list, (pmix_list_item_t*)node); - pmix_list_append(&ht->ht_nodes, (pmix_list_item_t*)node); - ht->ht_size--; - return PMIX_SUCCESS; + + ht->ht_type_methods = &pmix_hash_type_methods_uint64; + for (ii = key%capacity; ; ii += 1) { + pmix_hash_element_t * elt; + if (ii == capacity) { ii = 0; } + elt = &ht->ht_table[ii]; + if (! elt->valid) { + return PMIX_ERR_NOT_FOUND; + } else if (elt->key.u64 == key) { + return pmix_hash_table_remove_elt_at(ht, ii); + } else { + /* keep looking */ } } - return PMIX_ERR_NOT_FOUND; } + /***************************************************************************/ -/* - * pmix_ptr_hash_node_t - */ - -struct pmix_ptr_hash_node_t +/* helper function used in several places */ +static uint64_t +pmix_hash_hash_key_ptr(const void * key, size_t key_size) { - pmix_list_item_t super; - void* hn_key; - size_t hn_key_size; - void* hn_value; -}; -typedef struct pmix_ptr_hash_node_t pmix_ptr_hash_node_t; + uint64_t hash; + const unsigned char *scanner; + size_t ii; -static void pmix_ptr_hash_node_construct(pmix_ptr_hash_node_t* hn) -{ - hn->hn_key_size = 0; - hn->hn_key = NULL; - hn->hn_value = NULL; + hash = 0; + scanner = (const unsigned char *)key; + for (ii = 0; ii < key_size; ii += 1) { + hash = HASH_MULTIPLIER*hash + *scanner++; + } + return hash; } -static void pmix_ptr_hash_node_destruct(pmix_ptr_hash_node_t* hn) +/* ptr methods */ + +static void +pmix_hash_destruct_elt_ptr(pmix_hash_element_t * elt) { - if(NULL != hn->hn_key) { - free(hn->hn_key); + elt->key.ptr.key_size = 0; + void * key = (void *) elt->key.ptr.key; /* cast away const so we can free it */ + if (NULL != key) { + elt->key.ptr.key = NULL; + free(key); } } -static PMIX_CLASS_INSTANCE(pmix_ptr_hash_node_t, - pmix_list_item_t, - pmix_ptr_hash_node_construct, - pmix_ptr_hash_node_destruct); - -static inline uint32_t pmix_hash_value(size_t mask, const void *key, - size_t keysize) +static uint64_t +pmix_hash_hash_elt_ptr(pmix_hash_element_t * elt) { - unsigned int crc = pmix_uicrc_partial (key, keysize, 0); - return (uint32_t) (crc & mask); + return pmix_hash_hash_key_ptr(elt->key.ptr.key, elt->key.ptr.key_size); } -pmix_status_t pmix_hash_table_get_value_ptr(pmix_hash_table_t* ht, const void* key, - size_t key_size, void **ptr) +static const struct pmix_hash_type_methods_t +pmix_hash_type_methods_ptr = { + pmix_hash_destruct_elt_ptr, + pmix_hash_hash_elt_ptr +}; + +int /* PMIX_ return code */ +pmix_hash_table_get_value_ptr(pmix_hash_table_t * ht, + const void * key, size_t key_size, + void * *value) { - pmix_list_t* list = ht->ht_table + pmix_hash_value(ht->ht_mask, key, - key_size); - pmix_ptr_hash_node_t *node; + size_t ii, capacity = ht->ht_capacity; + pmix_hash_element_t * elt; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { + if(capacity == 0) { pmix_output(0, "pmix_hash_table_get_value_ptr:" - "pmix_hash_table_init() has not been called"); + "pmix_hash_table_init() has not been called"); return PMIX_ERROR; } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_ptr != ht->ht_type_methods) { + pmix_output(0, "pmix_hash_table_get_value_ptr:" + "hash table is for a different key type"); + return PMIX_ERROR; + } #endif - for(node = (pmix_ptr_hash_node_t*)pmix_list_get_first(list); - node != (pmix_ptr_hash_node_t*)pmix_list_get_end(list); - node = (pmix_ptr_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key_size == key_size && - memcmp(node->hn_key, key, key_size) == 0) { - *ptr = node->hn_value; - return PMIX_SUCCESS; + + ht->ht_type_methods = &pmix_hash_type_methods_ptr; + for (ii = pmix_hash_hash_key_ptr(key, key_size)%capacity; ; ii += 1) { + if (ii == capacity) { ii = 0; } + elt = &ht->ht_table[ii]; + if (! elt->valid) { + return PMIX_ERR_NOT_FOUND; + } else if (elt->key.ptr.key_size == key_size && + 0 == memcmp(elt->key.ptr.key, key, key_size)) { + *value = elt->value; + return PMIX_SUCCESS; + } else { + /* keep going */ } } - return PMIX_ERR_NOT_FOUND; } - -pmix_status_t pmix_hash_table_set_value_ptr(pmix_hash_table_t* ht, const void* key, - size_t key_size, void* value) +int /* PMIX_ return code */ +pmix_hash_table_set_value_ptr(pmix_hash_table_t * ht, + const void * key, size_t key_size, + void * value) { - pmix_list_t* list = ht->ht_table + pmix_hash_value(ht->ht_mask, key, - key_size); - pmix_ptr_hash_node_t *node; + int rc; + size_t ii, capacity = ht->ht_capacity; + pmix_hash_element_t * elt; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { + if(capacity == 0) { pmix_output(0, "pmix_hash_table_set_value_ptr:" - "pmix_hash_table_init() has not been called"); + "pmix_hash_table_init() has not been called"); return PMIX_ERR_BAD_PARAM; } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_ptr != ht->ht_type_methods) { + pmix_output(0, "pmix_hash_table_set_value_ptr:" + "hash table is for a different key type"); + return PMIX_ERROR; + } #endif - for(node = (pmix_ptr_hash_node_t*)pmix_list_get_first(list); - node != (pmix_ptr_hash_node_t*)pmix_list_get_end(list); - node = (pmix_ptr_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key_size == key_size && - memcmp(node->hn_key, key, key_size) == 0) { - node->hn_value = value; - return PMIX_SUCCESS; - } - } - node = (pmix_ptr_hash_node_t*)pmix_list_remove_first(&ht->ht_nodes); - if(NULL == node) { - node = PMIX_NEW(pmix_ptr_hash_node_t); - if(NULL == node) { - return PMIX_ERR_OUT_OF_RESOURCE; + ht->ht_type_methods = &pmix_hash_type_methods_ptr; + for (ii = pmix_hash_hash_key_ptr(key, key_size)%capacity; ; ii += 1) { + if (ii == capacity) { ii = 0; } + elt = &ht->ht_table[ii]; + if (! elt->valid) { + /* new entry */ + void * key_local = malloc(key_size); + memcpy(key_local, key, key_size); + elt->key.ptr.key = key_local; + elt->key.ptr.key_size = key_size; + elt->value = value; + elt->valid = 1; + ht->ht_size += 1; + if (ht->ht_size >= ht->ht_growth_trigger) { + if (PMIX_SUCCESS != (rc = pmix_hash_grow(ht))) { + return rc; + } + } + return PMIX_SUCCESS; + } else if (elt->key.ptr.key_size == key_size && + 0 == memcmp(elt->key.ptr.key, key, key_size)) { + /* replace existing value */ + elt->value = value; + return PMIX_SUCCESS; + } else { + /* keep looking */ } } - node->hn_key = malloc(key_size); - node->hn_key_size = key_size; - node->hn_value = value; - memcpy(node->hn_key, key, key_size); - pmix_list_append(list, (pmix_list_item_t*)node); - ht->ht_size++; - return PMIX_SUCCESS; } - -pmix_status_t pmix_hash_table_remove_value_ptr(pmix_hash_table_t* ht, - const void* key, size_t key_size) +int /* PMIX_ return code */ +pmix_hash_table_remove_value_ptr(pmix_hash_table_t * ht, + const void * key, size_t key_size) { - pmix_list_t* list = ht->ht_table + pmix_hash_value(ht->ht_mask, - key, key_size); - pmix_ptr_hash_node_t *node; + size_t ii, capacity = ht->ht_capacity; #if PMIX_ENABLE_DEBUG - if(ht->ht_table_size == 0) { - pmix_output(0, "pmix_hash_table_remove_value_ptr: " - "pmix_hash_table_init() has not been called"); - return PMIX_ERR_BAD_PARAM; + if(capacity == 0) { + pmix_output(0, "pmix_hash_table_get_value_ptr:" + "pmix_hash_table_init() has not been called"); + return PMIX_ERROR; + } + if (NULL != ht->ht_type_methods && + &pmix_hash_type_methods_ptr != ht->ht_type_methods) { + pmix_output(0, "pmix_hash_table_remove_value_ptr:" + "hash table is for a different key type"); + return PMIX_ERROR; } #endif - for(node = (pmix_ptr_hash_node_t*)pmix_list_get_first(list); - node != (pmix_ptr_hash_node_t*)pmix_list_get_end(list); - node = (pmix_ptr_hash_node_t*)pmix_list_get_next(node)) { - if (node->hn_key_size == key_size && - memcmp(node->hn_key, key, key_size) == 0) { - free(node->hn_key); - node->hn_key = NULL; - node->hn_key_size = 0; - pmix_list_remove_item(list, (pmix_list_item_t*)node); - pmix_list_append(&ht->ht_nodes, (pmix_list_item_t*)node); - ht->ht_size--; - return PMIX_SUCCESS; + + ht->ht_type_methods = &pmix_hash_type_methods_ptr; + for (ii = pmix_hash_hash_key_ptr(key, key_size)%capacity; ; ii += 1) { + pmix_hash_element_t * elt; + if (ii == capacity) { ii = 0; } + elt = &ht->ht_table[ii]; + if (! elt->valid) { + return PMIX_ERR_NOT_FOUND; + } else if (elt->key.ptr.key_size == key_size && + 0 == memcmp(elt->key.ptr.key, key, key_size)) { + return pmix_hash_table_remove_elt_at(ht, ii); + } else { + /* keep looking */ } } - return PMIX_ERR_NOT_FOUND; } +/***************************************************************************/ +/* Traversals */ -pmix_status_t -pmix_hash_table_get_first_key_uint32(pmix_hash_table_t *ht, uint32_t *key, - void **value, void **node) +static int /* PMIX_ return code */ +pmix_hash_table_get_next_elt(pmix_hash_table_t *ht, + pmix_hash_element_t * prev_elt, /* NULL means find first */ + pmix_hash_element_t * *next_elt) { - size_t i; - pmix_uint32_hash_node_t *list_node; + pmix_hash_element_t* elts = ht->ht_table; + size_t ii, capacity = ht->ht_capacity; - /* Go through all the lists and return the first element off the - first non-empty list */ - - for (i = 0; i < ht->ht_table_size; ++i) { - if (pmix_list_get_size(ht->ht_table + i) > 0) { - list_node = (pmix_uint32_hash_node_t*) - pmix_list_get_first(ht->ht_table + i); - *node = list_node; - *key = list_node->hn_key; - *value = list_node->hn_value; - return PMIX_SUCCESS; - } + for (ii = (NULL == prev_elt ? 0 : (prev_elt-elts)+1); ii < capacity; ii += 1) { + pmix_hash_element_t * elt = &elts[ii]; + if (elt->valid) { + *next_elt = elt; + return PMIX_SUCCESS; } - - /* The hash table is empty */ - - return PMIX_ERROR; + } + return PMIX_ERROR; } - -pmix_status_t -pmix_hash_table_get_next_key_uint32(pmix_hash_table_t *ht, uint32_t *key, - void **value, void *in_node, - void **out_node) +int /* PMIX_ return code */ +pmix_hash_table_get_first_key_uint32(pmix_hash_table_t * ht, + uint32_t *key, void * *value, + void * *node) { - size_t i; - pmix_list_t *list; - pmix_list_item_t *item; - pmix_uint32_hash_node_t *next; - - /* Try to simply get the next value in the list. If there isn't - one, find the next non-empty list and take the first value */ - - next = (pmix_uint32_hash_node_t*) in_node; - list = ht->ht_table + (next->hn_key & ht->ht_mask); - item = pmix_list_get_next(next); - if (pmix_list_get_end(list) == item) { - item = NULL; - for (i = (list - ht->ht_table) + 1; i < ht->ht_table_size; ++i) { - if (pmix_list_get_size(ht->ht_table + i) > 0) { - item = pmix_list_get_first(ht->ht_table + i); - break; - } - } - - /* If we didn't find another non-empty list after this one, - then we're at the end of the hash table */ - - if (NULL == item) { - return PMIX_ERROR; - } - } - - /* We found it. Save the values (use "next" to avoid some - typecasting) */ - - *out_node = (void *) item; - next = (pmix_uint32_hash_node_t *) *out_node; - *key = next->hn_key; - *value = next->hn_value; + return pmix_hash_table_get_next_key_uint32(ht, key, value, NULL, node); +} +int /* PMIX_ return code */ +pmix_hash_table_get_next_key_uint32(pmix_hash_table_t * ht, + uint32_t *key, void * *value, + void * in_node, void * *out_node) +{ + pmix_hash_element_t * elt; + if (PMIX_SUCCESS == pmix_hash_table_get_next_elt(ht, (pmix_hash_element_t *) in_node, &elt)) { + *key = elt->key.u32; + *value = elt->value; + *out_node = elt; return PMIX_SUCCESS; + } + return PMIX_ERROR; } - -pmix_status_t -pmix_hash_table_get_first_key_uint64(pmix_hash_table_t *ht, uint64_t *key, - void **value, void **node) +int /* PMIX_ return code */ +pmix_hash_table_get_first_key_ptr(pmix_hash_table_t * ht, + void * *key, size_t *key_size, void * *value, + void * *node) { - size_t i; - pmix_uint64_hash_node_t *list_node; - - /* Go through all the lists and return the first element off the - first non-empty list */ - - for (i = 0; i < ht->ht_table_size; ++i) { - if (pmix_list_get_size(ht->ht_table + i) > 0) { - list_node = (pmix_uint64_hash_node_t*) - pmix_list_get_first(ht->ht_table + i); - *node = list_node; - *key = list_node->hn_key; - *value = list_node->hn_value; - return PMIX_SUCCESS; - } - } - - /* The hash table is empty */ - - return PMIX_ERROR; + return pmix_hash_table_get_next_key_ptr(ht, key, key_size, value, NULL, node); } - -pmix_status_t -pmix_hash_table_get_next_key_uint64(pmix_hash_table_t *ht, uint64_t *key, - void **value, void *in_node, - void **out_node) +int /* PMIX_ return code */ +pmix_hash_table_get_next_key_ptr(pmix_hash_table_t * ht, + void * *key, size_t *key_size, void * *value, + void * in_node, void * *out_node) { - size_t i; - pmix_list_t *list; - pmix_list_item_t *item; - pmix_uint64_hash_node_t *next; - - /* Try to simply get the next value in the list. If there isn't - one, find the next non-empty list and take the first value */ - - next = (pmix_uint64_hash_node_t*) in_node; - list = ht->ht_table + (next->hn_key & ht->ht_mask); - item = pmix_list_get_next(next); - if (pmix_list_get_end(list) == item) { - item = NULL; - for (i = (list - ht->ht_table) + 1; i < ht->ht_table_size; ++i) { - if (pmix_list_get_size(ht->ht_table + i) > 0) { - item = pmix_list_get_first(ht->ht_table + i); - break; - } - } - - /* If we didn't find another non-empty list after this one, - then we're at the end of the hash table */ - - if (NULL == item) { - return PMIX_ERROR; - } - } - - /* We found it. Save the values (use "next" to avoid some - typecasting) */ - - *out_node = (void *) item; - next = (pmix_uint64_hash_node_t *) *out_node; - *key = next->hn_key; - *value = next->hn_value; - + pmix_hash_element_t * elt; + if (PMIX_SUCCESS == pmix_hash_table_get_next_elt(ht, (pmix_hash_element_t *) in_node, &elt)) { + *key = (void *)elt->key.ptr.key; + *key_size = elt->key.ptr.key_size; + *value = elt->value; + *out_node = elt; return PMIX_SUCCESS; + } + return PMIX_ERROR; } + +int /* PMIX_ return code */ +pmix_hash_table_get_first_key_uint64(pmix_hash_table_t * ht, + uint64_t *key, void * *value, + void * *node) +{ + return pmix_hash_table_get_next_key_uint64(ht, key, value, NULL, node); +} + +int /* PMIX_ return code */ +pmix_hash_table_get_next_key_uint64(pmix_hash_table_t * ht, + uint64_t *key, void * *value, + void * in_node, void * *out_node) +{ + pmix_hash_element_t * elt; + if (PMIX_SUCCESS == pmix_hash_table_get_next_elt(ht, (pmix_hash_element_t *) in_node, &elt)) { + *key = elt->key.u64; + *value = elt->value; + *out_node = elt; + return PMIX_SUCCESS; + } + return PMIX_ERROR; +} + +/* there was/is no traversal for the ptr case; it would go here */ +/* interact with the class-like mechanism */ 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 24f3ed829c..8185579161 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,12 +9,12 @@ * 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-2016 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 @@ -43,20 +43,22 @@ #include "src/class/pmix_list.h" -#include +#include BEGIN_C_DECLS -PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_hash_table_t); +PMIX_CLASS_DECLARATION(pmix_hash_table_t); struct pmix_hash_table_t { pmix_object_t super; /**< subclass of pmix_object_t */ - pmix_list_t ht_nodes; /**< free list of hash nodes */ - pmix_list_t *ht_table; /**< each item is an array of pmix_fhnode_t nodes */ - size_t ht_table_size; /**< size of table */ - size_t ht_size; /**< number of values on table */ - size_t ht_mask; + struct pmix_hash_element_t * ht_table; /**< table of elements (opaque to users) */ + size_t ht_capacity; /**< allocated size (capacity) of table */ + size_t ht_size; /**< number of extant entries */ + size_t ht_growth_trigger; /**< size hits this and table is grown */ + int ht_density_numer, ht_density_denom; /**< max allowed density of table */ + int ht_growth_numer, ht_growth_denom; /**< growth factor when grown */ + const struct pmix_hash_type_methods_t * ht_type_methods; }; typedef struct pmix_hash_table_t pmix_hash_table_t; @@ -73,12 +75,10 @@ typedef struct pmix_hash_table_t pmix_hash_table_t; * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_init(pmix_hash_table_t* ht, size_t table_size); +int pmix_hash_table_init(pmix_hash_table_t* ht, size_t table_size); -/** - * Alternative form - */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_init2(pmix_hash_table_t* ht, size_t estimated_max_size, +/* this could be the new init if people wanted a more general API */ +int pmix_hash_table_init2(pmix_hash_table_t* ht, size_t estimated_max_size, int density_numer, int density_denom, int growth_numer, int growth_denom); @@ -103,7 +103,7 @@ static inline size_t pmix_hash_table_get_size(pmix_hash_table_t *ht) * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_remove_all(pmix_hash_table_t *ht); +int pmix_hash_table_remove_all(pmix_hash_table_t *ht); /** * Retrieve value via uint32_t key. @@ -118,8 +118,8 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_remove_all(pmix_hash_table_t *ht); * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_value_uint32(pmix_hash_table_t* table, uint32_t key, - void** ptr); +int pmix_hash_table_get_value_uint32(pmix_hash_table_t* table, uint32_t key, + void** ptr); /** * Set value based on uint32_t key. @@ -131,7 +131,7 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_value_uint32(pmix_hash_table_t* * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_set_value_uint32(pmix_hash_table_t* table, uint32_t key, void* value); +int pmix_hash_table_set_value_uint32(pmix_hash_table_t* table, uint32_t key, void* value); /** * Remove value based on uint32_t key. @@ -142,7 +142,7 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_set_value_uint32(pmix_hash_table_t* * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_remove_value_uint32(pmix_hash_table_t* table, uint32_t key); +int pmix_hash_table_remove_value_uint32(pmix_hash_table_t* table, uint32_t key); /** * Retrieve value via uint64_t key. @@ -157,8 +157,8 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_remove_value_uint32(pmix_hash_table_ * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_value_uint64(pmix_hash_table_t *table, uint64_t key, - void **ptr); +int pmix_hash_table_get_value_uint64(pmix_hash_table_t *table, uint64_t key, + void **ptr); /** * Set value based on uint64_t key. @@ -170,7 +170,7 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_value_uint64(pmix_hash_table_t * * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_set_value_uint64(pmix_hash_table_t *table, uint64_t key, void* value); +int pmix_hash_table_set_value_uint64(pmix_hash_table_t *table, uint64_t key, void* value); /** * Remove value based on uint64_t key. @@ -181,7 +181,7 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_set_value_uint64(pmix_hash_table_t * * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_remove_value_uint64(pmix_hash_table_t *table, uint64_t key); +int pmix_hash_table_remove_value_uint64(pmix_hash_table_t *table, uint64_t key); /** * Retrieve value via arbitrary length binary key. @@ -196,8 +196,8 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_remove_value_uint64(pmix_hash_table_ * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_value_ptr(pmix_hash_table_t *table, const void* key, - size_t keylen, void **ptr); +int pmix_hash_table_get_value_ptr(pmix_hash_table_t *table, const void* key, + size_t keylen, void **ptr); /** * Set value based on arbitrary length binary key. @@ -209,7 +209,7 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_value_ptr(pmix_hash_table_t *tab * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_set_value_ptr(pmix_hash_table_t *table, const void* key, size_t keylen, void* value); +int pmix_hash_table_set_value_ptr(pmix_hash_table_t *table, const void* key, size_t keylen, void* value); /** * Remove value based on arbitrary length binary key. @@ -220,7 +220,7 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_set_value_ptr(pmix_hash_table_t *tab * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_remove_value_ptr(pmix_hash_table_t *table, const void* key, size_t keylen); +int pmix_hash_table_remove_value_ptr(pmix_hash_table_t *table, const void* key, size_t keylen); /** The following functions are only for allowing iterating through @@ -245,8 +245,8 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_remove_value_ptr(pmix_hash_table_t * * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_first_key_uint32(pmix_hash_table_t *table, uint32_t *key, - void **value, void **node); +int pmix_hash_table_get_first_key_uint32(pmix_hash_table_t *table, uint32_t *key, + void **value, void **node); /** @@ -263,9 +263,9 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_first_key_uint32(pmix_hash_table * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_next_key_uint32(pmix_hash_table_t *table, uint32_t *key, - void **value, void *in_node, - void **out_node); +int pmix_hash_table_get_next_key_uint32(pmix_hash_table_t *table, uint32_t *key, + void **value, void *in_node, + void **out_node); /** @@ -281,8 +281,8 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_next_key_uint32(pmix_hash_table_ * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_first_key_uint64(pmix_hash_table_t *table, uint64_t *key, - void **value, void **node); +int pmix_hash_table_get_first_key_uint64(pmix_hash_table_t *table, uint64_t *key, + void **value, void **node); /** @@ -299,9 +299,48 @@ PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_first_key_uint64(pmix_hash_table * */ -PMIX_DECLSPEC pmix_status_t pmix_hash_table_get_next_key_uint64(pmix_hash_table_t *table, uint64_t *key, - void **value, void *in_node, - void **out_node); +int pmix_hash_table_get_next_key_uint64(pmix_hash_table_t *table, uint64_t *key, + void **value, void *in_node, + void **out_node); + + +/** + * Get the first ptr bit key from the hash table, which can be used later to + * get the next key + * @param table The hash table pointer (IN) + * @param key The first key (OUT) + * @param key_size The first key size (OUT) + * @param value The value corresponding to this key (OUT) + * @param node The pointer to the hash table internal node which stores + * the key-value pair (this is required for subsequent calls + * to get_next_key) (OUT) + * @return PMIX error code + * + */ + +int pmix_hash_table_get_first_key_ptr(pmix_hash_table_t *table, void* *key, + size_t *key_size, void **value, void **node); + + +/** + * Get the next ptr bit key from the hash table, knowing the current key + * @param table The hash table pointer (IN) + * @param key The key (OUT) + * @param key_size The key size (OUT) + * @param value The value corresponding to this key (OUT) + * @param in_node The node pointer from previous call to either get_first + or get_next (IN) + * @param out_node The pointer to the hash table internal node which stores + * the key-value pair (this is required for subsequent calls + * to get_next_key) (OUT) + * @return PMIX error code + * + */ + +int pmix_hash_table_get_next_key_ptr(pmix_hash_table_t *table, void* *key, + size_t *key_size, void **value, + void *in_node, void **out_node); + /** * @brief Returns next power-of-two of the given value. diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hotel.h b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hotel.h index c2e6f0f4af..f7958578f0 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hotel.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_hotel.h @@ -54,7 +54,7 @@ #include #include "src/include/types.h" #include "src/include/prefetch.h" -#include "pmix/pmix_common.h" +#include "pmix_common.h" #include "src/class/pmix_object.h" #include PMIX_EVENT_HEADER @@ -157,7 +157,7 @@ PMIX_CLASS_DECLARATION(pmix_hotel_t); * @return PMIX_SUCCESS if all initializations were succesful. Otherwise, * the error indicate what went wrong in the function. */ -PMIX_DECLSPEC int pmix_hotel_init(pmix_hotel_t *hotel, int num_rooms, +int pmix_hotel_init(pmix_hotel_t *hotel, int num_rooms, pmix_event_base_t *evbase, uint32_t eviction_timeout, int eviction_event_priority, 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 f4fdf04ce6..933c5bcd5a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.c +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.c @@ -20,9 +20,8 @@ */ #include - +#include "include/pmix_common.h" #include "src/class/pmix_list.h" -#include /* * List classes 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 d3a6c652d1..4d8a195bb3 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_list.h @@ -83,13 +83,13 @@ BEGIN_C_DECLS * * The class for the list container. */ -PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_list_t); +PMIX_CLASS_DECLARATION(pmix_list_t); /** * \internal * * Base class for items that are put in list (pmix_list_t) containers. */ -PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_list_item_t); +PMIX_CLASS_DECLARATION(pmix_list_item_t); /** @@ -807,7 +807,7 @@ static inline void pmix_list_insert_pos(pmix_list_t *list, pmix_list_item_t *pos * If index is greater than the length of the list, no action is * performed and false is returned. */ - PMIX_DECLSPEC bool pmix_list_insert(pmix_list_t *list, pmix_list_item_t *item, + bool pmix_list_insert(pmix_list_t *list, pmix_list_item_t *item, long long idx); @@ -828,7 +828,7 @@ static inline void pmix_list_insert_pos(pmix_list_t *list, pmix_list_item_t *pos * containers remain valid, including those that point to elements * in \c xlist. */ - PMIX_DECLSPEC void pmix_list_join(pmix_list_t *thislist, pmix_list_item_t *pos, + void pmix_list_join(pmix_list_t *thislist, pmix_list_item_t *pos, pmix_list_t *xlist); @@ -855,7 +855,7 @@ static inline void pmix_list_insert_pos(pmix_list_t *list, pmix_list_item_t *pos * This is an O(N) operation because the length of both lists must * be recomputed. */ - PMIX_DECLSPEC void pmix_list_splice(pmix_list_t *thislist, pmix_list_item_t *pos, + void pmix_list_splice(pmix_list_t *thislist, pmix_list_item_t *pos, pmix_list_t *xlist, pmix_list_item_t *first, pmix_list_item_t *last); @@ -902,7 +902,7 @@ static inline void pmix_list_insert_pos(pmix_list_t *list, pmix_list_item_t *pos * whatever the underlying type is). See the documentation of * pmix_list_item_compare_fn_t for an example). */ - PMIX_DECLSPEC int pmix_list_sort(pmix_list_t* list, pmix_list_item_compare_fn_t compare); + int pmix_list_sort(pmix_list_t* list, pmix_list_item_compare_fn_t compare); END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.h b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.h index a9d19e1e81..26c5f12af9 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_object.h @@ -130,7 +130,7 @@ BEGIN_C_DECLS #if PMIX_ENABLE_DEBUG /* Any kind of unique ID should do the job */ -#define PMIX_PMIX_MAGIC_ID ((0xdeafbeedULL << 32) + 0xdeafbeedULL) +#define PMIX_OBJ_MAGIC_ID ((0xdeafbeedULL << 32) + 0xdeafbeedULL) #endif /* typedefs ***********************************************************/ @@ -169,9 +169,9 @@ struct pmix_class_t { * @param NAME Name of the class to initialize */ #if PMIX_ENABLE_DEBUG -#define PMIX_PMIX_STATIC_INIT(BASE_CLASS) { PMIX_PMIX_MAGIC_ID, PMIX_CLASS(BASE_CLASS), 1, __FILE__, __LINE__ } +#define PMIX_OBJ_STATIC_INIT(BASE_CLASS) { PMIX_OBJ_MAGIC_ID, PMIX_CLASS(BASE_CLASS), 1, __FILE__, __LINE__ } #else -#define PMIX_PMIX_STATIC_INIT(BASE_CLASS) { PMIX_CLASS(BASE_CLASS), 1 } +#define PMIX_OBJ_STATIC_INIT(BASE_CLASS) { PMIX_CLASS(BASE_CLASS), 1 } #endif /** @@ -249,7 +249,7 @@ static inline pmix_object_t *pmix_obj_new(pmix_class_t * cls); static inline pmix_object_t *pmix_obj_new_debug(pmix_class_t* type, const char* file, int line) { pmix_object_t* object = pmix_obj_new(type); - object->obj_magic_id = PMIX_PMIX_MAGIC_ID; + object->obj_magic_id = PMIX_OBJ_MAGIC_ID; object->cls_init_file_name = file; object->cls_init_lineno = line; return object; @@ -270,7 +270,7 @@ static inline pmix_object_t *pmix_obj_new_debug(pmix_class_t* type, const char* #define PMIX_RETAIN(object) \ do { \ assert(NULL != ((pmix_object_t *) (object))->obj_class); \ - assert(PMIX_PMIX_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \ + assert(PMIX_OBJ_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \ pmix_obj_update((pmix_object_t *) (object), 1); \ assert(((pmix_object_t *) (object))->obj_reference_count >= 0); \ } while (0) @@ -311,7 +311,7 @@ static inline pmix_object_t *pmix_obj_new_debug(pmix_class_t* type, const char* #define PMIX_RELEASE(object) \ do { \ assert(NULL != ((pmix_object_t *) (object))->obj_class); \ - assert(PMIX_PMIX_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \ + assert(PMIX_OBJ_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \ if (0 == pmix_obj_update((pmix_object_t *) (object), -1)) { \ PMIX_SET_MAGIC_ID((object), 0); \ pmix_obj_run_destructors((pmix_object_t *) (object)); \ @@ -346,7 +346,7 @@ do { \ #define PMIX_CONSTRUCT_INTERNAL(object, type) \ do { \ - PMIX_SET_MAGIC_ID((object), PMIX_PMIX_MAGIC_ID); \ + PMIX_SET_MAGIC_ID((object), PMIX_OBJ_MAGIC_ID); \ if (0 == (type)->cls_initialized) { \ pmix_class_initialize((type)); \ } \ @@ -365,7 +365,7 @@ do { \ #if PMIX_ENABLE_DEBUG #define PMIX_DESTRUCT(object) \ do { \ - assert(PMIX_PMIX_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \ + assert(PMIX_OBJ_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \ PMIX_SET_MAGIC_ID((object), 0); \ pmix_obj_run_destructors((pmix_object_t *) (object)); \ PMIX_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \ @@ -378,7 +378,7 @@ do { \ } while (0) #endif -PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_object_t); +PMIX_CLASS_DECLARATION(pmix_object_t); /* declarations *******************************************************/ @@ -390,7 +390,7 @@ PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_object_t); * * @param class Pointer to class descriptor */ -PMIX_DECLSPEC void pmix_class_initialize(pmix_class_t *); +void pmix_class_initialize(pmix_class_t *); /** * Shut down the class system and release all memory @@ -401,7 +401,7 @@ PMIX_DECLSPEC void pmix_class_initialize(pmix_class_t *); * tools like valgrind and purify don't report still-reachable memory * upon process termination. */ -PMIX_DECLSPEC int pmix_class_finalize(void); +int pmix_class_finalize(void); /** * Run the hierarchy of class constructors for this object, in a diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.c b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.c index 06fcd6f24c..e24526ffee 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.c +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.c @@ -32,7 +32,7 @@ #include "src/class/pmix_pointer_array.h" #include "src/util/output.h" -#include +#include "include/pmix_common.h" enum { TABLE_INIT = 1, TABLE_GROW = 2 }; diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.h b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.h index 4887c18a7c..9674ef3e98 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.h @@ -30,7 +30,7 @@ #endif #include "src/class/pmix_object.h" -#include +#include BEGIN_C_DECLS @@ -63,7 +63,7 @@ typedef struct pmix_pointer_array_t pmix_pointer_array_t; /** * Class declaration */ -PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_pointer_array_t); +PMIX_CLASS_DECLARATION(pmix_pointer_array_t); /** * Initialize the pointer array with an initial size of initial_allocation. @@ -79,7 +79,7 @@ PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_pointer_array_t); * @return PMIX_SUCCESS if all initializations were succesfull. Otherwise, * the error indicate what went wrong in the function. */ -PMIX_DECLSPEC pmix_status_t pmix_pointer_array_init(pmix_pointer_array_t* array, +pmix_status_t pmix_pointer_array_init(pmix_pointer_array_t* array, int initial_allocation, int max_size, int block_size ); @@ -92,7 +92,7 @@ PMIX_DECLSPEC pmix_status_t pmix_pointer_array_init(pmix_pointer_array_t* array, * @return Index of inserted array element. Return value of * (-1) indicates an error. */ -PMIX_DECLSPEC int pmix_pointer_array_add(pmix_pointer_array_t *array, void *ptr); +int pmix_pointer_array_add(pmix_pointer_array_t *array, void *ptr); /** * Set the value of an element in array @@ -104,7 +104,7 @@ PMIX_DECLSPEC int pmix_pointer_array_add(pmix_pointer_array_t *array, void *ptr) * @return PMIX_SUCCESS if item was inserted. Otherwise, * the error indicate what went wrong in the function. */ -PMIX_DECLSPEC pmix_status_t pmix_pointer_array_set_item(pmix_pointer_array_t *array, +pmix_status_t pmix_pointer_array_set_item(pmix_pointer_array_t *array, int index, void *value); /** @@ -157,7 +157,7 @@ static inline int pmix_pointer_array_get_size(pmix_pointer_array_t *array) * Simple function to set the size of the array in order to * hide the member field from external users. */ -PMIX_DECLSPEC pmix_status_t pmix_pointer_array_set_size(pmix_pointer_array_t *array, int size); +pmix_status_t pmix_pointer_array_set_size(pmix_pointer_array_t *array, int size); /** * Test whether a certain element is already in use. If not yet @@ -173,7 +173,7 @@ PMIX_DECLSPEC pmix_status_t pmix_pointer_array_set_size(pmix_pointer_array_t *ar * In contrary to array_set, this function does not allow to overwrite * a value, unless the previous value is NULL ( equiv. to free ). */ -PMIX_DECLSPEC bool pmix_pointer_array_test_and_set_item (pmix_pointer_array_t *table, +bool pmix_pointer_array_test_and_set_item (pmix_pointer_array_t *table, int index, void *value); 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 1967cdb185..e578a4e22b 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 @@ -25,7 +25,7 @@ #include #include -#include "pmix/pmix_common.h" +#include "pmix_common.h" #include "src/class/pmix_ring_buffer.h" #include "src/util/output.h" 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 966f917e33..27baae7c33 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 @@ -53,7 +53,7 @@ typedef struct pmix_ring_buffer_t pmix_ring_buffer_t; /** * Class declaration */ -PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_ring_buffer_t); +PMIX_CLASS_DECLARATION(pmix_ring_buffer_t); /** * Initialize the ring buffer, defining its size. @@ -64,7 +64,7 @@ PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_ring_buffer_t); * @return PMIX_SUCCESS if all initializations were succesful. Otherwise, * the error indicate what went wrong in the function. */ -PMIX_DECLSPEC int pmix_ring_buffer_init(pmix_ring_buffer_t* ring, int size); +int pmix_ring_buffer_init(pmix_ring_buffer_t* ring, int size); /** * Push an item onto the ring buffer, displacing the oldest @@ -76,7 +76,7 @@ PMIX_DECLSPEC int pmix_ring_buffer_init(pmix_ring_buffer_t* ring, int size); * @return Pointer to displaced item, NULL if ring * is not yet full */ -PMIX_DECLSPEC void* pmix_ring_buffer_push(pmix_ring_buffer_t *ring, void *ptr); +void* pmix_ring_buffer_push(pmix_ring_buffer_t *ring, void *ptr); /** @@ -88,14 +88,14 @@ PMIX_DECLSPEC void* pmix_ring_buffer_push(pmix_ring_buffer_t *ring, void *ptr); * @return Error code. NULL indicates an error. */ -PMIX_DECLSPEC void* pmix_ring_buffer_pop(pmix_ring_buffer_t *ring); +void* pmix_ring_buffer_pop(pmix_ring_buffer_t *ring); /* * Access an element of the ring, without removing it, indexed * starting at the tail - a value of -1 will return the element * at the head of the ring */ -PMIX_DECLSPEC void* pmix_ring_buffer_poke(pmix_ring_buffer_t *ring, int i); +void* pmix_ring_buffer_poke(pmix_ring_buffer_t *ring, int i); END_C_DECLS 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 new file mode 100644 index 0000000000..f46e494c38 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.c @@ -0,0 +1,67 @@ +/* + * 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-2007 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 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "src/class/pmix_value_array.h" + + +static void pmix_value_array_construct(pmix_value_array_t* array) +{ + array->array_items = NULL; + array->array_size = 0; + array->array_item_sizeof = 0; + array->array_alloc_size = 0; +} + +static void pmix_value_array_destruct(pmix_value_array_t* array) +{ + if (NULL != array->array_items) + free(array->array_items); +} + +PMIX_CLASS_INSTANCE( + pmix_value_array_t, + pmix_object_t, + pmix_value_array_construct, + pmix_value_array_destruct +); + + +int pmix_value_array_set_size(pmix_value_array_t* array, size_t size) +{ +#if PMIX_ENABLE_DEBUG + if(array->array_item_sizeof == 0) { + pmix_output(0, "pmix_value_array_set_size: item size must be initialized"); + return PMIX_ERR_BAD_PARAM; + } +#endif + + if(size > array->array_alloc_size) { + while(array->array_alloc_size < size) + array->array_alloc_size <<= 1; + array->array_items = (unsigned char *)realloc(array->array_items, + array->array_alloc_size * array->array_item_sizeof); + if (NULL == array->array_items) + return PMIX_ERR_OUT_OF_RESOURCE; + } + 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 new file mode 100644 index 0000000000..e6e74dc362 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_value_array.h @@ -0,0 +1,281 @@ +/* + * 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) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_VALUE_ARRAY_H +#define PMIX_VALUE_ARRAY_H + +#include + +#include +#ifdef HAVE_STRINGS_H +#include +#endif /* HAVE_STRINGS_H */ + +#include "src/class/pmix_object.h" +#if PMIX_ENABLE_DEBUG +#include "src/util/output.h" +#endif +#include "pmix_common.h" + +BEGIN_C_DECLS + +/* + * @file Array of elements maintained by value. + */ + +struct pmix_value_array_t +{ + pmix_object_t super; + unsigned char* array_items; + size_t array_item_sizeof; + size_t array_size; + size_t array_alloc_size; +}; +typedef struct pmix_value_array_t pmix_value_array_t; + +PMIX_CLASS_DECLARATION(pmix_value_array_t); + +/** + * Initialize the array to hold items by value. This routine must + * be called prior to using the array. + * + * @param array The array to initialize (IN). + * @param item_size The sizeof each array element (IN). + * @return PMIX error code + * + * Note that there is no corresponding "finalize" function -- use + * OBJ_DESTRUCT (for stack arrays) or OBJ_RELEASE (for heap arrays) to + * delete it. + */ + +static inline int pmix_value_array_init(pmix_value_array_t *array, size_t item_sizeof) +{ + array->array_item_sizeof = item_sizeof; + array->array_alloc_size = 1; + array->array_size = 0; + array->array_items = (unsigned char*)realloc(array->array_items, item_sizeof * array->array_alloc_size); + return (NULL != array->array_items) ? PMIX_SUCCESS : PMIX_ERR_OUT_OF_RESOURCE; +} + + +/** + * Reserve space in the array for new elements, but do not change the size. + * + * @param array The input array (IN). + * @param size The anticipated size of the array (IN). + * @return PMIX error code. + */ + +static inline int pmix_value_array_reserve(pmix_value_array_t* array, size_t size) +{ + if(size > array->array_alloc_size) { + array->array_items = (unsigned char*)realloc(array->array_items, array->array_item_sizeof * size); + if(NULL == array->array_items) { + array->array_size = 0; + array->array_alloc_size = 0; + return PMIX_ERR_OUT_OF_RESOURCE; + } + array->array_alloc_size = size; + } + return PMIX_SUCCESS; +} + + + +/** + * Retreives the number of elements in the array. + * + * @param array The input array (IN). + * @return The number of elements currently in use. + */ + +static inline size_t pmix_value_array_get_size(pmix_value_array_t* array) +{ + return array->array_size; +} + + +/** + * Set the number of elements in the array. + * + * @param array The input array (IN). + * @param size The new array size. + * + * @return PMIX error code. + * + * Note that resizing the array to a smaller size may not change + * the underlying memory allocated by the array. However, setting + * the size larger than the current allocation will grow it. In either + * case, if the routine is successful, pmix_value_array_get_size() will + * return the new size. + */ + +int pmix_value_array_set_size(pmix_value_array_t* array, size_t size); + + +/** + * Macro to retrieve an item from the array by value. + * + * @param array The input array (IN). + * @param item_type The C datatype of the array item (IN). + * @param item_index The array index (IN). + * + * @returns item The requested item. + * + * Note that this does not change the size of the array - this macro is + * strictly for performance - the user assumes the responsibility of + * ensuring the array index is valid (0 <= item index < array size). + */ + +#define PMIX_VALUE_ARRAY_GET_ITEM(array, item_type, item_index) \ + ((item_type*)((array)->array_items))[item_index] + +/** + * Retrieve an item from the array by reference. + * + * @param array The input array (IN). + * @param item_index The array index (IN). + * + * @return ptr Pointer to the requested item. + * + * Note that if the specified item_index is larger than the current + * array size, the array is grown to satisfy the request. + */ + +static inline void* pmix_value_array_get_item(pmix_value_array_t *array, size_t item_index) +{ + if(item_index >= array->array_size && pmix_value_array_set_size(array, item_index+1) != PMIX_SUCCESS) + return NULL; + return array->array_items + (item_index * array->array_item_sizeof); +} + +/** + * Macro to set an array element by value. + * + * @param array The input array (IN). + * @param item_type The C datatype of the array item (IN). + * @param item_index The array index (IN). + * @param item_value The new value for the specified index (IN). + * + * Note that this does not change the size of the array - this macro is + * strictly for performance - the user assumes the responsibility of + * ensuring the array index is valid (0 <= item index < array size). + * + * It is safe to free the item after returning from this call; it is + * copied into the array by value. + */ + +#define PMIX_VALUE_ARRAY_SET_ITEM(array, item_type, item_index, item_value) \ + (((item_type*)((array)->array_items))[item_index] = item_value) + +/** + * Set an array element by value. + * + * @param array The input array (IN). + * @param item_index The array index (IN). + * @param item_value A pointer to the item, which is copied into + * the array. + * + * @return PMIX error code. + * + * It is safe to free the item after returning from this call; it is + * copied into the array by value. + */ + +static inline int pmix_value_array_set_item(pmix_value_array_t *array, size_t item_index, const void* item) +{ + int rc; + if(item_index >= array->array_size && + (rc = pmix_value_array_set_size(array, item_index+1)) != PMIX_SUCCESS) + return rc; + memcpy(array->array_items + (item_index * array->array_item_sizeof), item, array->array_item_sizeof); + return PMIX_SUCCESS; +} + + +/** + * Appends an item to the end of the array. + * + * @param array The input array (IN). + * @param item A pointer to the item to append, which is copied + * into the array. + * + * @return PMIX error code + * + * This will grow the array if it is not large enough to contain the + * item. It is safe to free the item after returning from this call; + * it is copied by value into the array. + */ + +static inline int pmix_value_array_append_item(pmix_value_array_t *array, const void *item) +{ + return pmix_value_array_set_item(array, array->array_size, item); +} + + +/** + * Remove a specific item from the array. + * + * @param array The input array (IN). + * @param item_index The index to remove, which must be less than + * the current array size (IN). + * + * @return PMIX error code. + * + * All elements following this index are shifted down. + */ + +static inline int pmix_value_array_remove_item(pmix_value_array_t *array, size_t item_index) +{ +#if PMIX_ENABLE_DEBUG + if (item_index >= array->array_size) { + pmix_output(0, "pmix_value_array_remove_item: invalid index %lu\n", (unsigned long)item_index); + return PMIX_ERR_BAD_PARAM; + } +#endif + memmove(array->array_items+(array->array_item_sizeof * item_index), + array->array_items+(array->array_item_sizeof * (item_index+1)), + array->array_item_sizeof * (array->array_size - item_index - 1)); + array->array_size--; + return PMIX_SUCCESS; +} + +/** + * Get the base pointer of the underlying array. + * + * @param array The input array (IN). + * @param array_type The C datatype of the array (IN). + * + * @returns ptr Pointer to the actual array. + * + * This function is helpful when you need to iterate through an + * entire array; simply get the base value of the array and use native + * C to iterate through it manually. This can have better performance + * than looping over PMIX_VALUE_ARRAY_GET_ITEM() and + * PMIX_VALUE_ARRAY_SET_ITEM() because it will [potentially] reduce the + * number of pointer dereferences. + */ + +#define PMIX_VALUE_ARRAY_GET_BASE(array, item_type) \ + ((item_type*) ((array)->array_items)) + +END_C_DECLS + +#endif + diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.am deleted file mode 100644 index 52316ad974..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2014-2015 Intel, Inc. All rights reserved. -# Copyright (c) 2014 Artem Y. Polyakov . -# All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -headers += \ - src/client/pmix_client_ops.h - -sources += \ - src/client/pmix_client.c \ - src/client/pmix_client_fence.c \ - src/client/pmix_client_get.c \ - src/client/pmix_client_pub.c \ - src/client/pmix_client_spawn.c \ - src/client/pmix_client_connect.c - -if !PMIX_EMBEDDED_MODE -sources += \ - src/client/pmi1.c \ - src/client/pmi2.c -endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.include new file mode 100644 index 0000000000..2f4fd6eeb1 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.include @@ -0,0 +1,29 @@ +# -*- makefile -*- +# +# Copyright (c) 2014-2015 Intel, Inc. All rights reserved. +# Copyright (c) 2014 Artem Y. Polyakov . +# All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers += \ + client/pmix_client_ops.h + +sources += \ + client/pmix_client.c \ + client/pmix_client_fence.c \ + client/pmix_client_get.c \ + client/pmix_client_pub.c \ + client/pmix_client_spawn.c \ + client/pmix_client_connect.c + +if !PMIX_EMBEDDED_MODE +sources += \ + client/pmi1.c \ + client/pmi2.c +endif 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 b20d473b2f..c6250baf68 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -61,7 +61,7 @@ #include "src/util/error.h" #include "src/util/hash.h" #include "src/util/output.h" -#include "src/util/progress_threads.h" +#include "src/runtime/pmix_progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" #include "src/include/pmix_globals.h" @@ -183,6 +183,8 @@ static void job_data(struct pmix_peer_t *pr, pmix_usock_hdr_t *hdr, * unpack it to maintain sequence */ if (PMIX_SUCCESS != (rc = pmix_bfrop.unpack(buf, &nspace, &cnt, PMIX_STRING))) { PMIX_ERROR_LOG(rc); + cb->status = PMIX_ERROR; + cb->active = false; return; } /* decode it */ @@ -374,8 +376,11 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, /* setup the support */ #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (PMIX_SUCCESS != (rc = pmix_dstore_init())) { - return rc; + if (PMIX_SUCCESS != (rc = pmix_dstore_init(NULL, 0))) { + pmix_output_close(pmix_globals.debug_output); + pmix_output_finalize(); + pmix_class_finalize(); + return PMIX_ERR_DATA_VALUE_NOT_FOUND; } #endif /* PMIX_ENABLE_DSTORE */ pmix_bfrop_open(); @@ -384,7 +389,7 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, if (!pmix_globals.external_evbase) { /* create an event base and progress thread for us */ - if (NULL == (pmix_globals.evbase = pmix_start_progress_thread())) { + if (NULL == (pmix_globals.evbase = pmix_progress_thread_init(NULL))) { pmix_sec_finalize(); pmix_usock_finalize(); pmix_bfrop_close(); @@ -402,7 +407,7 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, /* connect to the server - returns job info if successful */ if (PMIX_SUCCESS != (rc = connect_to_server(&address, &cb))){ PMIX_DESTRUCT(&cb); - pmix_stop_progress_thread(pmix_globals.evbase); + pmix_progress_thread_finalize(NULL); pmix_sec_finalize(); pmix_usock_finalize(); pmix_bfrop_close(); @@ -498,7 +503,10 @@ PMIX_EXPORT pmix_status_t PMIx_Finalize(const pmix_info_t info[], size_t ninfo) } if (!pmix_globals.external_evbase) { - pmix_stop_progress_thread(pmix_globals.evbase); + #ifdef HAVE_LIBEVENT_GLOBAL_SHUTDOWN + libevent_global_shutdown(); + #endif + pmix_progress_thread_finalize(NULL); } pmix_usock_finalize(); @@ -508,10 +516,7 @@ PMIX_EXPORT pmix_status_t PMIx_Finalize(const pmix_info_t info[], size_t ninfo) if (0 <= pmix_client_globals.myserver.sd) { CLOSE_THE_SOCKET(pmix_client_globals.myserver.sd); } - event_base_free(pmix_globals.evbase); -#ifdef HAVE_LIBEVENT_GLOBAL_SHUTDOWN - libevent_global_shutdown(); -#endif + pmix_bfrop_close(); pmix_sec_finalize(); #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) 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 5c63a0631b..e97465b051 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 @@ -18,7 +18,7 @@ #include #include -#include +#include #include @@ -50,7 +50,6 @@ #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" -#include "src/util/progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" 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 e24fbe013c..77d528b446 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 @@ -18,7 +18,7 @@ #include #include -#include +#include #include @@ -51,7 +51,6 @@ #include "src/util/error.h" #include "src/util/hash.h" #include "src/util/output.h" -#include "src/util/progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" 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 33145b089e..b62c1ca528 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 @@ -18,7 +18,7 @@ #include #include -#include +#include #include @@ -51,7 +51,6 @@ #include "src/util/error.h" #include "src/util/hash.h" #include "src/util/output.h" -#include "src/util/progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) 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 135546b8d9..bbb4ff2f09 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 @@ -18,7 +18,7 @@ #include #include -#include +#include #include @@ -50,7 +50,6 @@ #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" -#include "src/util/progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" 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 a1e6e74901..96da72045b 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 @@ -18,7 +18,7 @@ #include #include -#include +#include #include @@ -50,7 +50,6 @@ #include "src/util/argv.h" #include "src/util/error.h" #include "src/util/output.h" -#include "src/util/progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.am deleted file mode 100644 index 3b4d0807b5..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (c) 2015-2016 Intel, Inc. All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -sources += \ - src/common/pmix_query.c \ - src/common/pmix_strings.c \ - src/common/pmix_log.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.include new file mode 100644 index 0000000000..fe6f790ef1 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/common/Makefile.include @@ -0,0 +1,15 @@ +# -*- makefile -*- +# +# Copyright (c) 2015 Intel, Inc. All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +sources += \ + common/pmix_query.c \ + common/pmix_strings.c \ + common/pmix_log.c 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 87295d0463..441060828f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_log.c +++ b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_log.c @@ -13,11 +13,11 @@ #include #include -#include +#include #include #include -#include +#include #include #include "src/util/argv.h" 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 23f7ac3312..b1745528a4 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_query.c +++ b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_query.c @@ -13,11 +13,11 @@ #include #include -#include +#include #include #include -#include +#include #include #include "src/util/argv.h" 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 bbd6ea8dee..ffbeb99df5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/common/pmix_strings.c +++ b/opal/mca/pmix/pmix2x/pmix/src/common/pmix_strings.c @@ -31,7 +31,7 @@ #include #endif -#include +#include #include "src/buffer_ops/internal.h" #include "src/include/pmix_globals.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/dstore/Makefile.am deleted file mode 100644 index 5ad482f884..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2015-2016 Mellanox Technologies, Inc. -# All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ - - -headers += \ - src/dstore/pmix_dstore.h \ - src/dstore/pmix_esh.h - -sources += \ - src/dstore/pmix_dstore.c \ - src/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 1cc7e7fbf5..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.c +++ /dev/null @@ -1,73 +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(void) -{ - pmix_dstore = *all[0]; - - if (!pmix_dstore.init) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_dstore.init(); -} - -void pmix_dstore_finalize(void) -{ - if (!pmix_dstore.finalize) { - pmix_dstore.finalize(); - } - - return ; -} - -int pmix_dstore_store(const char *nspace, int 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, int 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); -} 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 a306a9abdf..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_dstore.h +++ /dev/null @@ -1,89 +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(void); -void pmix_dstore_finalize(void); -int pmix_dstore_store(const char *nspace, - int rank, pmix_kval_t *kv); -int pmix_dstore_fetch(const char *nspace, int rank, - const char *key, pmix_value_t **kvs); - -/** - * 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)(void); - -/** - * 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_dstrore_base_module_fetch_fn_t)(const char *nspace, - pmix_rank_t rank, - const char *key, - pmix_value_t **kvs); - - -/** -* 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_dstrore_base_module_fetch_fn_t fetch; -} pmix_dstore_base_module_t; - -END_C_DECLS - -#endif /* PMIX_DSTORE_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c b/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c deleted file mode 100644 index 2318c6dcd7..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c +++ /dev/null @@ -1,1447 +0,0 @@ -/* - * Copyright (c) 2015-2016 Mellanox Technologies, Inc. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#include -#include -#include - -#include -#include -#include "src/include/pmix_globals.h" - -#include "src/class/pmix_list.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 "pmix_dstore.h" -#include "pmix_esh.h" - - -static int _esh_init(void); -static int _esh_finalize(void); -static int _esh_store(const char *nspace, int rank, pmix_kval_t *kv); -static int _esh_fetch(const char *nspace, int rank, const char *key, pmix_value_t **kvs); - -pmix_dstore_base_module_t pmix_dstore_esh_module = { - "esh", - _esh_init, - _esh_finalize, - _esh_store, - _esh_fetch -}; - -#define ESH_REGION_EXTENSION "EXTENSION_SLOT" -#define ESH_REGION_INVALIDATED "INVALIDATED" -#define ESH_ENV_INITIAL_SEG_SIZE "INITIAL_SEG_SIZE" -#define ESH_ENV_NS_META_SEG_SIZE "NS_META_SEG_SIZE" -#define ESH_ENV_NS_DATA_SEG_SIZE "NS_DATA_SEG_SIZE" -#define ESH_ENV_LINEAR "SM_USE_LINEAR_SEARCH" - -#define EXT_SLOT_SIZE (PMIX_MAX_KEYLEN + 1 + 2*sizeof(size_t)) /* in ext slot new offset will be stored in case if new data were added for the same process during next commit */ -#define KVAL_SIZE(size) (PMIX_MAX_KEYLEN + 1 + sizeof(size_t) + size) - -static int _store_data_for_rank(ns_track_elem_t *ns_info, int rank, pmix_buffer_t *buf); -static seg_desc_t *_create_new_segment(segment_type type, char *nsname, uint32_t id); -static seg_desc_t *_attach_new_segment(segment_type type, char *nsname, 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 char *nspace, pmix_sm_seg_t *metaseg, pmix_sm_seg_t *dataseg); -static ns_seg_info_t *_get_ns_info_from_initial_segment(const char *nspace); -static ns_track_elem_t *_get_track_elem_for_namespace(const char *nspace); -static rank_meta_info *_get_rank_meta_info(int rank, seg_desc_t *segdesc); -static uint8_t *_get_data_region_by_offset(seg_desc_t *segdesc, size_t offset); -static void _update_initial_segment_info(void); -static void _set_constants_from_env(void); -static void _delete_sm_desc(seg_desc_t *desc); -static int _pmix_getpagesize(void); -static inline uint32_t _get_univ_size(const char *nspace); - -static seg_desc_t *_global_sm_seg_first; -static seg_desc_t *_global_sm_seg_last; -static pmix_list_t _namespace_info_list; -static char *_tmp_dir = NULL; -static size_t _initial_segment_size = 0; -static size_t _max_ns_num; -static size_t _meta_segment_size = 0; -static size_t _max_meta_elems; -static size_t _data_segment_size = 0; -static int _lockfd; -static char *_lockfile_name; - -/* If _direct_mode is set, it means that we use linear search - * along the array of rank meta info objects inside a meta segment - * to find the requested rank. Otherwise, we do a fast lookup - * based on rank and directly compute offset. - * This mode is called direct because it's effectively used in - * sparse communication patterns when direct modex is usually used. - */ -static int _direct_mode = 0; - -static void ncon(ns_track_elem_t *p) { - p->meta_seg = NULL; - p->data_seg = NULL; - p->num_meta_seg = 0; - p->num_data_seg = 0; -} - -static void ndes(ns_track_elem_t *p) { - _delete_sm_desc(p->meta_seg); - _delete_sm_desc(p->data_seg); -} - -PMIX_CLASS_INSTANCE(ns_track_elem_t, - pmix_list_item_t, - ncon, ndes); - -static inline int _is_server(void) -{ - return (pmix_globals.server); -} - -static inline const char *_unique_id(void) -{ - static const char *str = NULL; - if (!str) { - /* see: pmix_server.c initialize_server_base() - * to get format of uri - */ - if (_is_server()) { - static char buf[100]; - snprintf(buf, sizeof(buf) - 1, "pmix-%d", getpid()); - str = buf; - } else { - str = getenv("PMIX_SERVER_URI"); - if (str) { - str = strrchr(str, '/'); - } - str = (str ? str + 1 : "$$$"); - } - } - return str; -} - -int _esh_init(void) -{ - int rc; - seg_desc_t *seg; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", __FILE__, __LINE__, __func__)); - - rc = pmix_sm_init(); - if (PMIX_SUCCESS != rc) { - PMIX_ERROR_LOG(rc); - return rc; - } - - PMIX_CONSTRUCT(&_namespace_info_list, pmix_list_t); - _global_sm_seg_first = NULL; - _global_sm_seg_last = NULL; - _tmp_dir = strdup(pmix_tmp_directory()); - _set_constants_from_env(); - _max_ns_num = (_initial_segment_size - sizeof(size_t) - sizeof(int)) / sizeof(ns_seg_info_t); - _max_meta_elems = (_meta_segment_size - sizeof(size_t)) / sizeof(rank_meta_info); - - /* create a lock file to prevent clients from reading while server is writing to the shared memory. - * This situation is quite often, especially in case of direct modex when clients might ask for data - * simultaneously.*/ - _lockfile_name = malloc(256); - snprintf(_lockfile_name, 256, "%s/%s_dstore_sm.lock", _tmp_dir, _unique_id()); - if (_is_server()) { - _lockfd = open(_lockfile_name, O_CREAT | O_RDWR | O_EXCL, 0600); - /* if previous launch was crashed, the lockfile might not be deleted and unlocked, - * so we delete it and create a new one. */ - if (-1 == _lockfd) { - unlink(_lockfile_name); - _lockfd = open(_lockfile_name, O_CREAT | O_RDWR, 0600); - } - } else { - _lockfd = open(_lockfile_name, O_RDWR); - } - if (-1 == _lockfd) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - - if (_is_server()) { - seg = _create_new_segment(INITIAL_SEGMENT, NULL, 0); - } else { - seg = _attach_new_segment(INITIAL_SEGMENT, NULL, 0); - } - if (NULL != seg) { - _global_sm_seg_first = seg; - _global_sm_seg_last = _global_sm_seg_first; - return PMIX_SUCCESS; - } - return PMIX_ERROR; -} - -int _esh_finalize(void) -{ - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", __FILE__, __LINE__, __func__)); - - _delete_sm_desc(_global_sm_seg_first); - PMIX_LIST_DESTRUCT(&_namespace_info_list); - if (NULL != _tmp_dir) { - free(_tmp_dir); - } - close(_lockfd); - if (_is_server()) { - unlink(_lockfile_name); - } - free(_lockfile_name); - - pmix_sm_finalize(); - - return PMIX_SUCCESS; -} - - -int _esh_store(const char *nspace, int rank, pmix_kval_t *kv) -{ - int rc; - ns_track_elem_t *elem; - pmix_buffer_t pbkt, xfer; - ns_seg_info_t ns_info; - - if (NULL == kv) { - return PMIX_ERROR; - } - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for %s:%d", - __FILE__, __LINE__, __func__, nspace, rank)); - - /* set exclusive lock */ - flock(_lockfd, LOCK_EX); - - /* First of all, we go through local track list (list of ns_track_elem_t structures) - * and look for an element for the target namespace. - * If it is there, then shared memory segments for it are created, so we take it. - * Otherwise, create a new element, fill its fields, create corresponding meta - * and data segments for this namespace, add it to the local track list, - * and put this info (ns_seg_info_t) to the initial segment. If initial segment - * if full, then extend it by creating a new one and mark previous one as full. - * All this stuff is done inside _get_track_elem_for_namespace function. - */ - - elem = _get_track_elem_for_namespace(nspace); - if (NULL == elem) { - PMIX_ERROR_LOG(PMIX_ERROR); - /* unset lock */ - flock(_lockfd, LOCK_UN); - return PMIX_ERROR; - } - - /* If a new element was just created, we need to create corresponding meta and - * data segments and update corresponding element's fields. */ - if (NULL == elem->meta_seg || NULL == elem->data_seg) { - strncpy(ns_info.ns_name, nspace, PMIX_MAX_NSLEN+1); - ns_info.num_meta_seg = 1; - ns_info.num_data_seg = 1; - rc = _update_ns_elem(elem, &ns_info); - if (PMIX_SUCCESS != rc || NULL == elem->meta_seg || NULL == elem->data_seg) { - PMIX_ERROR_LOG(rc); - /* unset lock */ - flock(_lockfd, LOCK_UN); - return PMIX_ERROR; - } - - /* zero created shared memory segments for this namespace */ - memset(elem->meta_seg->seg_info.seg_base_addr, 0, _meta_segment_size); - memset(elem->data_seg->seg_info.seg_base_addr, 0, _data_segment_size); - - /* put ns's shared segments info to the global meta segment. */ - rc = _put_ns_info_to_initial_segment(nspace, &elem->meta_seg->seg_info, &elem->data_seg->seg_info); - if (PMIX_SUCCESS != rc) { - PMIX_ERROR_LOG(rc); - /* unset lock */ - flock(_lockfd, LOCK_UN); - return rc; - } - } - - /* 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(&pbkt, pmix_buffer_t); - PMIX_CONSTRUCT(&xfer, pmix_buffer_t); - PMIX_LOAD_BUFFER(&xfer, kv->value->data.bo.bytes, kv->value->data.bo.size); - pmix_buffer_t *pxfer = &xfer; - pmix_bfrop.pack(&pbkt, &pxfer, 1, PMIX_BUFFER); - xfer.base_ptr = NULL; - xfer.bytes_used = 0; - - rc = _store_data_for_rank(elem, rank, &pbkt); - - PMIX_DESTRUCT(&xfer); - PMIX_DESTRUCT(&pbkt); - - /* unset lock */ - flock(_lockfd, LOCK_UN); - return rc; -} - -int _esh_fetch(const char *nspace, int rank, const char *key, pmix_value_t **kvs) -{ - ns_seg_info_t *ns_info = NULL; - int rc; - ns_track_elem_t *elem; - rank_meta_info *rinfo = NULL; - size_t kval_cnt; - seg_desc_t *meta_seg, *data_seg; - uint8_t *addr; - pmix_buffer_t buffer; - pmix_value_t val; - uint32_t nprocs; - int cur_rank; - - if (NULL == key) { - PMIX_OUTPUT_VERBOSE((7, pmix_globals.debug_output, - "dstore: Does not support passed parameters")); - return PMIX_ERROR; - } - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for %s:%d look for key %s", - __FILE__, __LINE__, __func__, nspace, rank, key)); - - if (kvs) { - *kvs = NULL; - } - - if (PMIX_RANK_UNDEF == rank) { - nprocs = _get_univ_size(nspace); - cur_rank = -1; - } else { - nprocs = 1; - cur_rank = rank; - } - - /* set shared lock */ - flock(_lockfd, LOCK_SH); - - /* First of all, we go through all initial segments and look at their field. - * If it’s 1, then generate name of next initial segment incrementing id by one and attach to it. - * We need this step to synchronize initial shared segments with our local track list. - * Then we look for the target namespace in all initial segments. - * If it is found, we get numbers of meta & data segments and - * compare these numbers with the number of trackable meta & data - * segments for this namespace in the local track list. - * If the first number exceeds the last, or the local track list - * doesn't track current namespace yet, then we update it (attach - * to additional segments). - */ - - /* first update local information about initial segments. they can be extended, so then we need to attach to new segments. */ - _update_initial_segment_info(); - - /* get information about shared segments per this namespace from the initial segment. */ - ns_info = _get_ns_info_from_initial_segment(nspace); - if (NULL == ns_info) { - /* no data for this namespace is found in the shared memory. */ - PMIX_OUTPUT_VERBOSE((7, pmix_globals.debug_output, - "%s:%d:%s: no data for ns %s is found in the shared memory.", - __FILE__, __LINE__, __func__, nspace)); - /* unset lock */ - flock(_lockfd, LOCK_UN); - return PMIX_ERROR; - } - - /* get ns_track_elem_t object for the target namespace from the local track list. */ - elem = _get_track_elem_for_namespace(nspace); - if (NULL == elem) { - PMIX_ERROR_LOG(PMIX_ERROR); - /* unset lock */ - flock(_lockfd, LOCK_UN); - return PMIX_ERROR; - } - /* need to update tracker: - * attach to shared memory regions for this namespace and store its info locally - * to operate with address and detach/unlink afterwards. */ - rc = _update_ns_elem(elem, ns_info); - if (PMIX_SUCCESS != rc) { - PMIX_ERROR_LOG(PMIX_ERROR); - /* unset lock */ - flock(_lockfd, LOCK_UN); - return PMIX_ERROR; - } - - /* now we know info about meta segment for this namespace. */ - meta_seg = elem->meta_seg; - data_seg = elem->data_seg; - - while (nprocs--) { - if (PMIX_RANK_UNDEF == rank) { - cur_rank++; - } - /* Then we look for 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, - "%s:%d:%s: no data for this rank is found in the shared memory. rank %d", - __FILE__, __LINE__, __func__, cur_rank)); - rc = PMIX_ERR_PROC_ENTRY_NOT_FOUND; - continue; - } - addr = _get_data_region_by_offset(data_seg, rinfo->offset); - if (NULL == addr) { - PMIX_ERROR_LOG(PMIX_ERROR); - rc = PMIX_ERR_PROC_ENTRY_NOT_FOUND; - continue; - } - kval_cnt = rinfo->count; - /* TODO: probably PMIX_ERR_NOT_FOUND is a better way but - * setting to one initiates wrong next logic for unknown reason */ - rc = PMIX_ERROR; - - while (0 < kval_cnt) { - /* data is stored in the following format: - * key[PMIX_MAX_KEYLEN+1] - * size_t size - * 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((const char *)addr, ESH_REGION_INVALIDATED, PMIX_MAX_KEYLEN+1)) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %s:%d, skip %s region", - __FILE__, __LINE__, __func__, nspace, cur_rank, ESH_REGION_INVALIDATED)); - /*skip it */ - size_t size = *(size_t *)(addr + PMIX_MAX_KEYLEN + 1); - /* go to next item, updating address */ - addr += KVAL_SIZE(size); - } else if (0 == strncmp((const char *)addr, ESH_REGION_EXTENSION, PMIX_MAX_KEYLEN+1)) { - size_t offset = *(size_t *)(addr + PMIX_MAX_KEYLEN + 1 + sizeof(size_t)); - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %s:%d, reached %s with %lu value", - __FILE__, __LINE__, __func__, nspace, cur_rank, ESH_REGION_EXTENSION, offset)); - if (0 < offset) { - /* go to next item, updating address */ - addr = _get_data_region_by_offset(data_seg, offset); - if (NULL == addr) { - /* report problem and return */ - PMIX_ERROR_LOG(PMIX_ERROR); - rc = PMIX_ERROR; - goto done; - } - } else { - /* no more data for this rank */ - PMIX_OUTPUT_VERBOSE((7, pmix_globals.debug_output, - "%s:%d:%s: no more data for this rank is found in the shared memory. rank %d key %s not found", - __FILE__, __LINE__, __func__, cur_rank, key)); - break; - } - } else if (0 == strncmp((const char *)addr, key, PMIX_MAX_KEYLEN+1)) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %s:%d, found target key %s", - __FILE__, __LINE__, __func__, nspace, cur_rank, key)); - /* target key is found, get value */ - size_t size = *(size_t *)(addr + PMIX_MAX_KEYLEN + 1); - addr += PMIX_MAX_KEYLEN + 1 + sizeof(size_t); - PMIX_CONSTRUCT(&buffer, pmix_buffer_t); - PMIX_LOAD_BUFFER(&buffer, addr, 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_ERROR_LOG(rc); - } else if (PMIX_SUCCESS != (rc = pmix_bfrop.copy((void**)kvs, &val, PMIX_VALUE))) { - PMIX_ERROR_LOG(rc); - } - PMIX_VALUE_DESTRUCT(&val); - buffer.base_ptr = NULL; - buffer.bytes_used = 0; - PMIX_DESTRUCT(&buffer); - goto done; - } else { - char ckey[PMIX_MAX_KEYLEN+1] = {0}; - strncpy(ckey, (const char *)addr, PMIX_MAX_KEYLEN+1); - size_t size = *(size_t *)(addr + PMIX_MAX_KEYLEN + 1); - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %s:%d, skip key %s look for key %s", __FILE__, __LINE__, __func__, nspace, cur_rank, ckey, key)); - /* go to next item, updating address */ - addr += KVAL_SIZE(size); - kval_cnt--; - } - } - } - -done: - /* unset lock */ - flock(_lockfd, LOCK_UN); - return rc; -} - -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; - } - } -} - -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, char *nsname, uint32_t id) -{ - int 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, nsname, id)); - - switch (type) { - case INITIAL_SEGMENT: - size = _initial_segment_size; - snprintf(file_name, PMIX_PATH_MAX, "%s/%s_initial-pmix_shared-segment-%u", _tmp_dir, _unique_id(), id); - break; - case NS_META_SEGMENT: - size = _meta_segment_size; - snprintf(file_name, PMIX_PATH_MAX, "%s/%s_smseg-%s-%u", _tmp_dir, _unique_id(), nsname, id); - break; - case NS_DATA_SEGMENT: - size = _data_segment_size; - snprintf(file_name, PMIX_PATH_MAX, "%s/%s_smdataseg-%s-%d", _tmp_dir, _unique_id(), nsname, 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) { - memset(new_seg->seg_info.seg_base_addr, 0, size); - } else { - free(new_seg); - new_seg = NULL; - PMIX_ERROR_LOG(rc); - } - } - return new_seg; -} - -static seg_desc_t *_attach_new_segment(segment_type type, char *nsname, uint32_t id) -{ - int 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, nsname, 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/%s_initial-pmix_shared-segment-%u", _tmp_dir, _unique_id(), 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/%s_smseg-%s-%u", _tmp_dir, _unique_id(), nsname, 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/%s_smdataseg-%s-%d", _tmp_dir, _unique_id(), nsname, id); - break; - default: - PMIX_ERROR_LOG(PMIX_ERROR); - return NULL; - } - rc = pmix_sm_segment_attach(&new_seg->seg_info); - 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; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", - __FILE__, __LINE__, __func__)); - - 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 (_is_server()) { - seg = _create_new_segment(NS_META_SEGMENT, info->ns_name, i); - } else { - seg = _attach_new_segment(NS_META_SEGMENT, info->ns_name, i); - } - if (NULL == seg) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - 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 (_is_server()) { - seg = _create_new_segment(NS_DATA_SEGMENT, info->ns_name, i); - if (seg) { - 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_name, i); - } - if (NULL == seg) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - 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, char *nspace) -{ - 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, nspace, tmp->id + 1); - if (NULL == seg) { - PMIX_ERROR_LOG(PMIX_ERROR); - return NULL; - } - - tmp->next = seg; - - return seg; -} - -static int _put_ns_info_to_initial_segment(const char *nspace, pmix_sm_seg_t *metaseg, pmix_sm_seg_t *dataseg) -{ - ns_seg_info_t elem; - size_t num_elems; - num_elems = *((size_t*)(_global_sm_seg_last->seg_info.seg_base_addr)); - seg_desc_t *last_seg = _global_sm_seg_last; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s", __FILE__, __LINE__, __func__)); - - if (_max_ns_num == num_elems) { - if (NULL == (last_seg = extend_segment(last_seg, NULL))) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - /* mark previous segment as full */ - int full = 1; - memcpy((uint8_t*)(_global_sm_seg_last->seg_info.seg_base_addr + sizeof(size_t)), &full, sizeof(int)); - _global_sm_seg_last = last_seg; - memset(_global_sm_seg_last->seg_info.seg_base_addr, 0, _initial_segment_size); - } - strncpy(elem.ns_name, nspace, PMIX_MAX_NSLEN+1); - elem.num_meta_seg = 1; - elem.num_data_seg = 1; - memcpy((uint8_t*)(_global_sm_seg_last->seg_info.seg_base_addr) + sizeof(size_t) + sizeof(int) + num_elems * sizeof(ns_seg_info_t), - &elem, sizeof(ns_seg_info_t)); - num_elems++; - memcpy((uint8_t*)(_global_sm_seg_last->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(void) -{ - seg_desc_t *tmp; - tmp = _global_sm_seg_first; - - 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 == *((int*)((uint8_t*)(tmp->seg_info.seg_base_addr) + sizeof(size_t)))) { - tmp->next = _attach_new_segment(INITIAL_SEGMENT, NULL, 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 char *nspace) -{ - int 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 = _global_sm_seg_first; - - 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) + sizeof(int) + i * sizeof(ns_seg_info_t)); - if (0 == (rc = strncmp(cur_elem->ns_name, nspace, strlen(nspace)+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(const char *nspace) -{ - ns_track_elem_t *new_elem = NULL; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: nspace %s", - __FILE__, __LINE__, __func__, nspace)); - - /* check if this namespace is already being tracked to avoid duplicating data. */ - PMIX_LIST_FOREACH(new_elem, &_namespace_info_list, ns_track_elem_t) { - if (0 == strncmp(nspace, new_elem->ns_name, PMIX_MAX_NSLEN+1)) { - /* data for this namespace should be already stored in shared memory region. */ - /* so go and just put new data. */ - PMIX_OUTPUT_VERBOSE((7, pmix_globals.debug_output, - "%s:%d:%s: found nspace %s in the track list", - __FILE__, __LINE__, __func__, nspace)); - return new_elem; - } - } - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: create new object for nspace %s", - __FILE__, __LINE__, __func__, nspace)); - /* create shared memory regions for this namespace and store its info locally - * to operate with address and detach/unlink afterwards. */ - new_elem = PMIX_NEW(ns_track_elem_t); - strncpy(new_elem->ns_name, nspace, PMIX_MAX_NSLEN+1); - - pmix_list_append(&_namespace_info_list, &new_elem->super); - - return new_elem; -} - -static rank_meta_info *_get_rank_meta_info(int 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; - - 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 (rank == (int)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 = rank/_max_meta_elems; - rel_offset = (rank%_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_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_name)); - /* extend meta segment, so create a new one */ - tmp = extend_segment(tmp, ns_info->ns_name); - 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_name); - 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. */ - id = rinfo->rank/_max_meta_elems; - rel_offset = (rinfo->rank % _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_name); - 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_name); - 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, sz, val; - 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) { - return PMIX_ERROR; - } - addr = _get_data_region_by_offset(dataseg, global_offset); - strncpy((char *)addr, ESH_REGION_EXTENSION, PMIX_MAX_KEYLEN+1); - val = 0; - sz = sizeof(size_t); - memcpy(addr + PMIX_MAX_KEYLEN + 1, &sz, sz); - memcpy(addr + PMIX_MAX_KEYLEN + 1 + sizeof(size_t), &val, sz); - - /* 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; - seg_desc_t *tmp; - int id = 0; - size_t global_offset, data_ended; - uint8_t *addr; - size_t sz; - - 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) + KVAL_SIZE(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) + PMIX_MAX_KEYLEN + 1 + sizeof(size_t) + size + EXT_SLOT_SIZE); - return offset; - } - if (offset + KVAL_SIZE(size) + EXT_SLOT_SIZE > _data_segment_size) { - id++; - /* create a new data segment. */ - tmp = extend_segment(tmp, ns_info->ns_name); - if (NULL == tmp) { - PMIX_ERROR_LOG(PMIX_ERROR); - 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_name); - if (NULL == elem) { - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - 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; - strncpy((char *)addr, key, PMIX_MAX_KEYLEN+1); - sz = size; - memcpy(addr + PMIX_MAX_KEYLEN + 1, &sz, sizeof(size_t)); - memcpy(addr + PMIX_MAX_KEYLEN + 1 + sizeof(size_t), buffer, size); - - /* update offset at the beginning of current segment */ - data_ended = offset + KVAL_SIZE(size); - addr = (uint8_t*)(tmp->seg_info.seg_base_addr); - memcpy(addr, &data_ended, sizeof(size_t)); - PMIX_OUTPUT_VERBOSE((2, 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, int rank, pmix_kval_t *kval, rank_meta_info **rinfo, int data_exist) -{ - size_t offset, size, kval_cnt; - pmix_buffer_t *buffer; - int rc; - seg_desc_t *datadesc; - uint8_t *addr; - - PMIX_OUTPUT_VERBOSE((2, pmix_globals.debug_output, - "%s:%d:%s: for rank %d, replace flag %d", - __FILE__, __LINE__, __func__, rank, data_exist)); - - datadesc = ns_info->data_seg; - /* pack value to the buffer */ - buffer = PMIX_NEW(pmix_buffer_t); - if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(buffer, kval->value, 1, PMIX_VALUE))) { - PMIX_RELEASE(buffer); - PMIX_ERROR_LOG(rc); - return rc; - } - 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 */ - PMIX_RELEASE(buffer); - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - /* 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 */ - size_t sz = sizeof(size_t); - addr = _get_data_region_by_offset(datadesc, free_offset); - strncpy((char *)addr, ESH_REGION_EXTENSION, PMIX_MAX_KEYLEN+1); - memcpy(addr + PMIX_MAX_KEYLEN + 1, &sz, sizeof(size_t)); - memcpy(addr + PMIX_MAX_KEYLEN + 1 + sizeof(size_t), &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) { - PMIX_RELEASE(buffer); - PMIX_ERROR_LOG(PMIX_ERROR); - return rc; - } - /* 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: - * key[PMIX_MAX_KEYLEN+1] - * size_t size - * 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((const char *)addr, ESH_REGION_EXTENSION, PMIX_MAX_KEYLEN+1)) { - offset = *(size_t *)(addr + PMIX_MAX_KEYLEN + 1 + sizeof(size_t)); - if (0 < offset) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %d, 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) { - PMIX_RELEASE(buffer); - PMIX_ERROR_LOG(PMIX_ERROR); - return rc; - } - } else { - /* should not be, we should be out of cycle when this happens */ - } - } else if (0 == strncmp((const char *)addr, kval->key, PMIX_MAX_KEYLEN+1)) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %d, replace flag %d found target key %s", - __FILE__, __LINE__, __func__, rank, data_exist, kval->key)); - /* target key is found, compare value sizes */ - size_t cur_size = *(size_t *)(addr + PMIX_MAX_KEYLEN + 1); - if (cur_size != 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((char *)addr, ESH_REGION_INVALIDATED, PMIX_MAX_KEYLEN+1); - /* 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 += KVAL_SIZE(cur_size); - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %d, 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 %d, 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. */ - addr += PMIX_MAX_KEYLEN + 1; - memcpy(addr, &size, sizeof(size_t)); - addr += sizeof(size_t); - memset(addr, 0, cur_size); - memcpy(addr, buffer->base_ptr, size); - addr += cur_size; - add_to_the_end = 0; - break; - } - } else { - char ckey[PMIX_MAX_KEYLEN+1] = {0}; - strncpy(ckey, (const char *)addr, PMIX_MAX_KEYLEN+1); - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %d, replace flag %d skip %s key, look for %s key", - __FILE__, __LINE__, __func__, rank, data_exist, ckey, kval->key)); - /* Skip it: key is "INVALIDATED" or key is valid but different from target one. */ - if (0 != strncmp(ESH_REGION_INVALIDATED, ckey, PMIX_MAX_KEYLEN+1)) { - /* count only valid items */ - kval_cnt--; - } - size_t size = *(size_t *)(addr + PMIX_MAX_KEYLEN + 1); - /* go to next item, updating address */ - addr += KVAL_SIZE(size); - } - } - 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. */ - (*rinfo)->count++; - size_t free_offset; - 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) { - PMIX_RELEASE(buffer); - PMIX_ERROR_LOG(PMIX_ERROR); - return PMIX_ERROR; - } - /* 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((const char *)addr, ESH_REGION_EXTENSION, PMIX_MAX_KEYLEN+1)) { - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %d, replace flag %d %s should be filled with offset %lu value", - __FILE__, __LINE__, __func__, rank, data_exist, ESH_REGION_EXTENSION, offset)); - memcpy(addr + PMIX_MAX_KEYLEN + 1 + sizeof(size_t), &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 */ - size_t sz = sizeof(size_t); - strncpy((char *)addr, ESH_REGION_EXTENSION, PMIX_MAX_KEYLEN+1); - memcpy(addr + PMIX_MAX_KEYLEN + 1, &sz, sz); - memcpy(addr + PMIX_MAX_KEYLEN + 1 + sizeof(size_t), &offset, sz); - } - } - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %d, replace flag %d item not found ext slot empty, put key %s to the end", - __FILE__, __LINE__, __func__, rank, data_exist, kval->key)); - } - } - buffer->base_ptr = NULL; - buffer->bytes_used = 0; - PMIX_RELEASE(buffer); - return rc; -} - -static int _store_data_for_rank(ns_track_elem_t *ns_info, int rank, pmix_buffer_t *buf) -{ - int rc; - int32_t cnt; - - pmix_buffer_t *bptr; - 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; - - PMIX_OUTPUT_VERBOSE((10, pmix_globals.debug_output, - "%s:%d:%s: for rank %d", __FILE__, __LINE__, __func__, rank)); - - metadesc = ns_info->meta_seg; - datadesc = ns_info->data_seg; - - if (NULL == datadesc || NULL == metadesc) { - PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); - return PMIX_ERROR; - } - - 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. - */ - cnt = 1; - free_offset = get_free_offset(datadesc); - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(buf, &bptr, &cnt, PMIX_BUFFER))) { - cnt = 1; - kp = PMIX_NEW(pmix_kval_t); - while (PMIX_SUCCESS == (rc = pmix_bfrop.unpack(bptr, 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))) { - PMIX_ERROR_LOG(rc); - } - PMIX_RELEASE(kp); // maintain acctg - hash_store does a retain - cnt = 1; - kp = PMIX_NEW(pmix_kval_t); - } - cnt = 1; - PMIX_RELEASE(kp); - PMIX_RELEASE(bptr); // free's the data region - if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { - PMIX_ERROR_LOG(rc); - break; - } - } - if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) { - PMIX_ERROR_LOG(rc); - } 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 (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 uint32_t _get_univ_size(const char *nspace) -{ - pmix_value_t *val = NULL; - uint32_t nprocs = 0; - pmix_nspace_t *ns, *nptr; - - nptr = NULL; - PMIX_LIST_FOREACH(ns, &pmix_globals.nspaces, pmix_nspace_t) { - if (0 == strcmp(nspace, ns->nspace)) { - nptr = ns; - break; - } - } - - if (nptr && (PMIX_SUCCESS == pmix_hash_fetch(&nptr->internal, PMIX_RANK_WILDCARD, PMIX_UNIV_SIZE, &val))) { - if (val->type == PMIX_UINT32) { - nprocs = val->data.uint32; - } - PMIX_VALUE_RELEASE(val); - } - - return nprocs; -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.h b/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.h deleted file mode 100644 index d47719ef51..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2015-2016 Mellanox Technologies, Inc. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#ifndef PMIX_DSTORE_ESH_H -#define PMIX_DSTORE_ESH_H - -#include - - -#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) - -typedef enum { - INITIAL_SEGMENT, - NS_META_SEGMENT, - NS_DATA_SEGMENT -} segment_type; - -/* initial segment format: - * size_t num_elems; - * int full; //indicate to client that it needs to attach to the next segment - * ns_seg_info_t ns_seg_info[max_ns_num]; - */ - -typedef struct { - char ns_name[PMIX_MAX_NSLEN+1]; - size_t num_meta_seg;/* read by clients to attach to this number of segments. */ - size_t num_data_seg; -} ns_seg_info_t; - -/* meta segment format: - * size_t num_elems; - * rank_meta_info meta_info[max_meta_elems]; - */ - -typedef struct { - size_t rank; - size_t offset; - size_t count; -} rank_meta_info; - -/* this structs are used to store information about - * shared segments addresses locally at each process, - * so they are common for different types of segments - * and don't have a specific content (namespace's info, - * rank's meta info, ranks's data). */ - -typedef struct seg_desc_t seg_desc_t; -struct seg_desc_t { - segment_type type; - pmix_sm_seg_t seg_info; - uint32_t id; - seg_desc_t *next; -}; - -typedef struct { - pmix_list_item_t super; - char ns_name[PMIX_MAX_NSLEN+1]; - size_t num_meta_seg; - size_t num_data_seg; - seg_desc_t *meta_seg; - seg_desc_t *data_seg; -} ns_track_elem_t; -PMIX_CLASS_DECLARATION(ns_track_elem_t); - -extern pmix_dstore_base_module_t pmix_dstore_esh_module; - -END_C_DECLS - -#endif /* PMIX_DSTORE_ESH_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.am deleted file mode 100644 index 079b1c0c11..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2015-2016 Intel, Inc. All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -headers += \ - src/event/pmix_event.h - -sources += \ - src/event/pmix_event_registration.c \ - src/event/pmix_event_notification.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.include new file mode 100644 index 0000000000..2f970896a4 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/event/Makefile.include @@ -0,0 +1,16 @@ +# -*- makefile -*- +# +# Copyright (c) 2016 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ + + +headers += \ + event/pmix_event.h + +sources += \ + event/pmix_event_notification.c \ + event/pmix_event_registration.c 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 f184035153..4148c210ca 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h +++ b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h @@ -22,9 +22,9 @@ #define PMIX_EVENT_H #include -#include +#include -#include +#include #include "src/class/pmix_list.h" #include "src/util/output.h" 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 b9db00567e..fa4d6796cf 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 @@ -8,11 +8,11 @@ * $HEADER$ */ #include -#include +#include -#include -#include -#include +#include "include/pmix.h" +#include "include/pmix_common.h" +#include "include/pmix_server.h" #include "src/util/error.h" #include "src/util/output.h" @@ -321,13 +321,20 @@ void pmix_invoke_local_event_hdlr(pmix_event_chain_t *chain) pmix_single_event_t *sing; pmix_multi_event_t *multi; pmix_default_event_t *def; + pmix_status_t rc = PMIX_SUCCESS; + + /* sanity check */ + if (NULL == chain->info) { + /* should never happen as the return object must + * at least be there, even if it is NULL */ + rc = PMIX_ERR_BAD_PARAM; + goto complete; + } /* check for directives */ - if (NULL != chain->info) { - for (i=0; i < chain->ninfo; i++) { - if (0 == strncmp(chain->info[i].key, PMIX_EVENT_NON_DEFAULT, PMIX_MAX_KEYLEN)) { - chain->nondefault = true; - } + for (i=0; i < chain->ninfo; i++) { + if (0 == strncmp(chain->info[i].key, PMIX_EVENT_NON_DEFAULT, PMIX_MAX_KEYLEN)) { + chain->nondefault = true; } } @@ -401,7 +408,7 @@ void pmix_invoke_local_event_hdlr(pmix_event_chain_t *chain) complete: /* we still have to call their final callback */ if (NULL != chain->final_cbfunc) { - chain->final_cbfunc(PMIX_SUCCESS, chain->final_cbdata); + chain->final_cbfunc(rc, chain->final_cbdata); } return; } 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 b18c7afd85..8de8920980 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 @@ -8,10 +8,10 @@ * $HEADER$ */ #include -#include +#include #include -#include +#include #include #include "src/util/error.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/include/Makefile.include similarity index 64% rename from opal/mca/pmix/pmix2x/pmix/src/include/Makefile.am rename to opal/mca/pmix/pmix2x/pmix/src/include/Makefile.include index a0969fa924..602c7407f6 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/include/Makefile.include @@ -1,3 +1,4 @@ +# -*- makefile -*- # # Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana # University Research and Technology @@ -9,9 +10,8 @@ # University of Stuttgart. All rights reserved. # 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) 2013-2016 Intel, Inc. All rights reserved -# Copyright (c) 2016 IBM Corporation. All rights reserved. +# Copyright (c) 2007-2016 Cisco Systems, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -20,22 +20,29 @@ # # This makefile.am does not stand on its own - it is included from -# src/Makefile.am +# Makefile.am headers += \ - src/include/pmix_globals.h + include/pmix_globals.h sources += \ - src/include/pmix_globals.c + include/pmix_globals.c if ! PMIX_EMBEDDED_MODE headers += \ - src/include/pmix_config.h \ - src/include/align.h \ - src/include/hash_string.h \ - src/include/pmix_socket_errno.h \ - src/include/prefetch.h \ - src/include/types.h + include/align.h \ + include/hash_string.h \ + include/pmix_socket_errno.h \ + include/pmix_stdint.h \ + include/prefetch.h \ + include/types.h \ + include/pmix_config_top.h \ + include/pmix_config_bottom.h \ + include/rename.h -#noinst_include_private_autogen_HEADERS = endif ! PMIX_EMBEDDED_MODE + +if WANT_INSTALL_HEADERS +headers += \ + include/pmix_config.h +endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h deleted file mode 100644 index e614a332a3..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2016 Mellanox Technologies, Inc. - * All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#ifndef PMIX_INCLUDE_CONFIG_H -#define PMIX_INCLUDE_CONFIG_H - -#include -#include - -#endif /* PMIX_INCLUDE_CONFIG_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h.in b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h.in new file mode 100644 index 0000000000..9a54a45201 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config.h.in @@ -0,0 +1,683 @@ +/* src/include/pmix_config.h.in. Generated from configure.ac by autoheader. */ + +/* -*- c -*- + * + * Copyright (c) 2004-2005 The Trustees of Indiana University. + * All rights reserved. + * Copyright (c) 2004-2005 The Trustees of the University of Tennessee. + * 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) 2013-2015 Intel, Inc. All rights reserved + * Copyright (c) 2016 IBM Corporation. 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 PMIX_CONFIG_H +#define PMIX_CONFIG_H + +#include + + + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the `asprintf' function. */ +#undef HAVE_ASPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_CRT_EXTERNS_H + +/* Define to 1 if you have the declaration of `AF_INET6', and to 0 if you + don't. */ +#undef HAVE_DECL_AF_INET6 + +/* Define to 1 if you have the declaration of `AF_UNSPEC', and to 0 if you + don't. */ +#undef HAVE_DECL_AF_UNSPEC + +/* Define to 1 if you have the declaration of `PF_INET6', and to 0 if you + don't. */ +#undef HAVE_DECL_PF_INET6 + +/* Define to 1 if you have the declaration of `PF_UNSPEC', and to 0 if you + don't. */ +#undef HAVE_DECL_PF_UNSPEC + +/* Define to 1 if you have the declaration of `__func__', and to 0 if you + don't. */ +#undef HAVE_DECL___FUNC__ + +/* 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 header file. */ +#undef HAVE_EVENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `getpeereid' function. */ +#undef HAVE_GETPEEREID + +/* Define to 1 if you have the header file. */ +#undef HAVE_HOSTLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_HWLOC_H + +/* Define to 1 if the system has the type `int16_t'. */ +#undef HAVE_INT16_T + +/* Define to 1 if the system has the type `int32_t'. */ +#undef HAVE_INT32_T + +/* Define to 1 if the system has the type `int64_t'. */ +#undef HAVE_INT64_T + +/* Define to 1 if the system has the type `int8_t'. */ +#undef HAVE_INT8_T + +/* Define to 1 if the system has the type `intptr_t'. */ +#undef HAVE_INTPTR_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOLIB_H + +/* Define to 1 if you have the `event' library (-levent). */ +#undef HAVE_LIBEVENT + +/* Define to 1 if you have the `libevent_global_shutdown' function. */ +#undef HAVE_LIBEVENT_GLOBAL_SHUTDOWN + +/* Define to 1 if you have the `event_pthreads' library (-levent_pthreads). */ +#undef HAVE_LIBEVENT_PTHREADS + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBGEN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if the system has the type `long long'. */ +#undef HAVE_LONG_LONG + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MUNGE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_UIO_H + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#undef HAVE_PTRDIFF_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_SASL_SASL_H + +/* Define to 1 if `si_band' is a member of `siginfo_t'. */ +#undef HAVE_SIGINFO_T_SI_BAND + +/* Define to 1 if `si_fd' is a member of `siginfo_t'. */ +#undef HAVE_SIGINFO_T_SI_FD + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the `socketpair' function. */ +#undef HAVE_SOCKETPAIR + +/* Define to 1 if the system has the type `socklen_t'. */ +#undef HAVE_SOCKLEN_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_SOCKLIB_H + +/* Define to 1 if you have the `statfs' function. */ +#undef HAVE_STATFS + +/* Define to 1 if you have the `statvfs' function. */ +#undef HAVE_STATVFS + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDARG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDDEF_H + +/* 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 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 `strncpy_s' function. */ +#undef HAVE_STRNCPY_S + +/* Define to 1 if you have the `strnlen' function. */ +#undef HAVE_STRNLEN + +/* Define to 1 if you have the `strsignal' function. */ +#undef HAVE_STRSIGNAL + +/* Define to 1 if `d_type' is a member of `struct dirent'. */ +#undef HAVE_STRUCT_DIRENT_D_TYPE + +/* Define to 1 if the system has the type `struct sockaddr_in'. */ +#undef HAVE_STRUCT_SOCKADDR_IN + +/* Define to 1 if the system has the type `struct sockaddr_in6'. */ +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ +#undef HAVE_STRUCT_SOCKADDR_SA_LEN + +/* Define to 1 if the system has the type `struct sockaddr_storage'. */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define to 1 if the system has the type `struct sockaddr_un'. */ +#undef HAVE_STRUCT_SOCKADDR_UN + +/* Define to 1 if `uid' is a member of `struct sockpeercred'. */ +#undef HAVE_STRUCT_SOCKPEERCRED_UID + +/* Define to 1 if `f_fstypename' is a member of `struct statfs'. */ +#undef HAVE_STRUCT_STATFS_F_FSTYPENAME + +/* Define to 1 if `f_type' is a member of `struct statfs'. */ +#undef HAVE_STRUCT_STATFS_F_TYPE + +/* Define to 1 if `f_basetype' is a member of `struct statvfs'. */ +#undef HAVE_STRUCT_STATVFS_F_BASETYPE + +/* Define to 1 if `f_fstypename' is a member of `struct statvfs'. */ +#undef HAVE_STRUCT_STATVFS_F_FSTYPENAME + +/* Define to 1 if `cr_uid' is a member of `struct ucred'. */ +#undef HAVE_STRUCT_UCRED_CR_UID + +/* Define to 1 if `uid' is a member of `struct ucred'. */ +#undef HAVE_STRUCT_UCRED_UID + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_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_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STATFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STATVFS_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_TIME_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_UIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if the system has the type `uint16_t'. */ +#undef HAVE_UINT16_T + +/* Define to 1 if the system has the type `uint32_t'. */ +#undef HAVE_UINT32_T + +/* Define to 1 if the system has the type `uint64_t'. */ +#undef HAVE_UINT64_T + +/* Define to 1 if the system has the type `uint8_t'. */ +#undef HAVE_UINT8_T + +/* Define to 1 if the system has the type `uintptr_t'. */ +#undef HAVE_UINTPTR_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* whether unix byteswap routines -- htonl, htons, nothl, ntohs -- are + available */ +#undef HAVE_UNIX_BYTESWAP + +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + +/* Define to 1 if you have the `vasprintf' function. */ +#undef HAVE_VASPRINTF + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* 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 + +/* Alignment of type bool */ +#undef PMIX_ALIGNMENT_BOOL + +/* Alignment of type char */ +#undef PMIX_ALIGNMENT_CHAR + +/* Alignment of type double */ +#undef PMIX_ALIGNMENT_DOUBLE + +/* Alignment of type float */ +#undef PMIX_ALIGNMENT_FLOAT + +/* Alignment of type int */ +#undef PMIX_ALIGNMENT_INT + +/* Alignment of type int16_t */ +#undef PMIX_ALIGNMENT_INT16 + +/* Alignment of type int32_t */ +#undef PMIX_ALIGNMENT_INT32 + +/* Alignment of type int64_t */ +#undef PMIX_ALIGNMENT_INT64 + +/* Alignment of type int8_t */ +#undef PMIX_ALIGNMENT_INT8 + +/* Alignment of type long */ +#undef PMIX_ALIGNMENT_LONG + +/* Alignment of type long double */ +#undef PMIX_ALIGNMENT_LONG_DOUBLE + +/* Alignment of type long long */ +#undef PMIX_ALIGNMENT_LONG_LONG + +/* Alignment of type short */ +#undef PMIX_ALIGNMENT_SHORT + +/* Alignment of type size_t */ +#undef PMIX_ALIGNMENT_SIZE_T + +/* Alignment of type void * */ +#undef PMIX_ALIGNMENT_VOID_P + +/* Alignment of type wchar_t */ +#undef PMIX_ALIGNMENT_WCHAR + +/* The compiler $lower which PMIx was built with */ +#undef PMIX_BUILD_PLATFORM_COMPILER_FAMILYID + +/* The compiler $lower which PMIX was built with */ +#undef PMIX_BUILD_PLATFORM_COMPILER_FAMILYNAME + +/* The compiler $lower which PMIx was built with */ +#undef PMIX_BUILD_PLATFORM_COMPILER_VERSION + +/* The compiler $lower which PMIX was built with */ +#undef PMIX_BUILD_PLATFORM_COMPILER_VERSION_STR + +/* PMIx underlying C compiler */ +#undef PMIX_CC + +/* Use static const char[] strings for C files */ +#undef PMIX_CC_USE_CONST_CHAR_IDENT + +/* Use #ident strings for C files */ +#undef PMIX_CC_USE_IDENT + +/* Use #pragma comment for C files */ +#undef PMIX_CC_USE_PRAGMA_COMMENT + +/* Use #pragma ident strings for C files */ +#undef PMIX_CC_USE_PRAGMA_IDENT + +/* Whether C compiler supports __builtin_clz */ +#undef PMIX_C_HAVE_BUILTIN_CLZ + +/* Whether C compiler supports __builtin_expect */ +#undef PMIX_C_HAVE_BUILTIN_EXPECT + +/* Whether C compiler supports __builtin_prefetch */ +#undef PMIX_C_HAVE_BUILTIN_PREFETCH + +/* Whether C compiler supports symbol visibility or not */ +#undef PMIX_C_HAVE_VISIBILITY + +/* Whether we are in debugging mode or not */ +#undef PMIX_ENABLE_DEBUG + +/* Whether we want developer-level timing support or not */ +#undef PMIX_ENABLE_TIMING + +/* Location of event2/thread.h */ +#undef PMIX_EVENT2_THREAD_HEADER + +/* Location of event.h */ +#undef PMIX_EVENT_HEADER + +/* Whether your compiler has __attribute__ or not */ +#undef PMIX_HAVE_ATTRIBUTE + +/* Whether your compiler has __attribute__ aligned or not */ +#undef PMIX_HAVE_ATTRIBUTE_ALIGNED + +/* Whether your compiler has __attribute__ always_inline or not */ +#undef PMIX_HAVE_ATTRIBUTE_ALWAYS_INLINE + +/* Whether your compiler has __attribute__ cold or not */ +#undef PMIX_HAVE_ATTRIBUTE_COLD + +/* Whether your compiler has __attribute__ const or not */ +#undef PMIX_HAVE_ATTRIBUTE_CONST + +/* Whether your compiler has __attribute__ deprecated or not */ +#undef PMIX_HAVE_ATTRIBUTE_DEPRECATED + +/* Whether your compiler has __attribute__ deprecated with optional argument + */ +#undef PMIX_HAVE_ATTRIBUTE_DEPRECATED_ARGUMENT + +/* Whether your compiler has __attribute__ destructor or not */ +#undef PMIX_HAVE_ATTRIBUTE_DESTRUCTOR + +/* Whether your compiler has __attribute__ format or not */ +#undef PMIX_HAVE_ATTRIBUTE_FORMAT + +/* Whether your compiler has __attribute__ format and it works on function + pointers */ +#undef PMIX_HAVE_ATTRIBUTE_FORMAT_FUNCPTR + +/* Whether your compiler has __attribute__ hot or not */ +#undef PMIX_HAVE_ATTRIBUTE_HOT + +/* Whether your compiler has __attribute__ malloc or not */ +#undef PMIX_HAVE_ATTRIBUTE_MALLOC + +/* Whether your compiler has __attribute__ may_alias or not */ +#undef PMIX_HAVE_ATTRIBUTE_MAY_ALIAS + +/* Whether your compiler has __attribute__ nonnull or not */ +#undef PMIX_HAVE_ATTRIBUTE_NONNULL + +/* Whether your compiler has __attribute__ noreturn or not */ +#undef PMIX_HAVE_ATTRIBUTE_NORETURN + +/* Whether your compiler has __attribute__ noreturn and it works on function + pointers */ +#undef PMIX_HAVE_ATTRIBUTE_NORETURN_FUNCPTR + +/* Whether your compiler has __attribute__ no_instrument_function or not */ +#undef PMIX_HAVE_ATTRIBUTE_NO_INSTRUMENT_FUNCTION + +/* Whether your compiler has __attribute__ packed or not */ +#undef PMIX_HAVE_ATTRIBUTE_PACKED + +/* Whether your compiler has __attribute__ pure or not */ +#undef PMIX_HAVE_ATTRIBUTE_PURE + +/* Whether your compiler has __attribute__ sentinel or not */ +#undef PMIX_HAVE_ATTRIBUTE_SENTINEL + +/* Whether your compiler has __attribute__ unused or not */ +#undef PMIX_HAVE_ATTRIBUTE_UNUSED + +/* Whether your compiler has __attribute__ visibility or not */ +#undef PMIX_HAVE_ATTRIBUTE_VISIBILITY + +/* Whether your compiler has __attribute__ warn unused result or not */ +#undef PMIX_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT + +/* Whether your compiler has __attribute__ weak alias or not */ +#undef PMIX_HAVE_ATTRIBUTE_WEAK_ALIAS + +/* whether qsort is broken or not */ +#undef PMIX_HAVE_BROKEN_QSORT + +/* whether ceil is found and available */ +#undef PMIX_HAVE_CEIL + +/* whether dirname is found and available */ +#undef PMIX_HAVE_DIRNAME + +/* Whether we have hwloc support or not */ +#undef PMIX_HAVE_HWLOC + +/* Whether the PMIX PDL framework is functional or not */ +#undef PMIX_HAVE_PDL_SUPPORT + +/* Whether we have sasl support or not */ +#undef PMIX_HAVE_SASL + +/* Whether we have SA_RESTART in or not */ +#undef PMIX_HAVE_SA_RESTART + +/* whether socket is found and available */ +#undef PMIX_HAVE_SOCKET + +/* Whether we have __va_copy or not */ +#undef PMIX_HAVE_UNDERSCORE_VA_COPY + +/* Whether we have va_copy or not */ +#undef PMIX_HAVE_VA_COPY + +/* Location of hwloc.h */ +#undef PMIX_HWLOC_HEADER + +/* ident string for PMIX */ +#undef PMIX_IDENT_STRING + +/* The library major version is always available, contrary to VERSION */ +#undef PMIX_MAJOR_VERSION + +/* The library minor version is always available, contrary to VERSION */ +#undef PMIX_MINOR_VERSION + +/* Whether the C compiler supports "bool" without any other help (such as + ) */ +#undef PMIX_NEED_C_BOOL + +/* Whether libraries can be configured with destructor functions */ +#undef PMIX_NO_LIB_DESTRUCTOR + +/* type to use for ptrdiff_t */ +#undef PMIX_PTRDIFF_TYPE + +/* The library release version is always available, contrary to VERSION */ +#undef PMIX_RELEASE_VERSION + +/* The pmix symbol rename include directive */ +#undef PMIX_SYMBOL_RENAME + +/* Whether to use or not */ +#undef PMIX_USE_STDBOOL_H + +/* The library version is always available, contrary to VERSION */ +#undef PMIX_VERSION + +/* Enable per-user config files */ +#undef PMIX_WANT_HOME_CONFIG_FILES + +/* Whether we want munge support or not */ +#undef PMIX_WANT_MUNGE + +/* if want pretty-print stack trace feature */ +#undef PMIX_WANT_PRETTY_PRINT_STACKTRACE + +/* The size of `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of `double', as computed by sizeof. */ +#undef SIZEOF_DOUBLE + +/* The size of `float', as computed by sizeof. */ +#undef SIZEOF_FLOAT + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* The size of `pid_t', as computed by sizeof. */ +#undef SIZEOF_PID_T + +/* The size of `ptrdiff_t', as computed by sizeof. */ +#undef SIZEOF_PTRDIFF_T + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* The size of `ssize_t', as computed by sizeof. */ +#undef SIZEOF_SSIZE_T + +/* The size of `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* The size of `wchar_t', as computed by sizeof. */ +#undef SIZEOF_WCHAR_T + +/* The size of `_Bool', as computed by sizeof. */ +#undef SIZEOF__BOOL + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* 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 + + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif + +/* 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 to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + + +#include +#endif /* PMIX_CONFIG_H */ + diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix/autogen/pmix_config_bottom.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_bottom.h similarity index 97% rename from opal/mca/pmix/pmix2x/pmix/include/pmix/autogen/pmix_config_bottom.h rename to opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_bottom.h index 417160cdc9..13ce998a70 100644 --- a/opal/mca/pmix/pmix2x/pmix/include/pmix/autogen/pmix_config_bottom.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_bottom.h @@ -343,27 +343,15 @@ # define __pmix_attribute_destructor__ #endif -#ifndef PMIX_DECLSPEC -# define PMIX_DECLSPEC #ifdef PMIX_C_HAVE_VISIBILITY # if PMIX_C_HAVE_VISIBILITY -# define PMIX_EXPORT __attribute__((__visibility__("default"))) +# define PMIX_EXPORT __pmix_attribute_visibility__("default") # else # define PMIX_EXPORT # endif #else # define PMIX_EXPORT #endif -#endif - -#ifndef PMIX_DECLSPEC -#define PMIX_DECLSPEC -# if PMIX_C_HAVE_VISIBILITY -# define PMIX_EXPORT __pmix_attribute_visibility__("default") -# else -# define PMIX_EXPORT -# endif -#endif /* * Do we have ? @@ -375,10 +363,10 @@ including stdint.h */ #define __STDC_LIMIT_MACROS #endif -#include +#include #include #else -#include +#include #endif /*********************************************************************** diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix/autogen/pmix_config_top.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_top.h similarity index 100% rename from opal/mca/pmix/pmix2x/pmix/include/pmix/autogen/pmix_config_top.h rename to opal/mca/pmix/pmix2x/pmix/src/include/pmix_config_top.h 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 69a1e75f62..c28fd7071a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include "src/include/pmix_globals.h" 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 7992c3533b..1e4e1f3505 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h @@ -30,7 +30,7 @@ #endif #include PMIX_EVENT_HEADER -#include +#include #include "src/buffer_ops/types.h" #include "src/class/pmix_hash_table.h" @@ -82,6 +82,14 @@ typedef enum { PMIX_COLLECT_MAX } pmix_collect_t; +/* define a process type */ +typedef enum { + PMIX_PROC_UNDEF, + PMIX_PROC_CLIENT, + PMIX_PROC_SERVER, + PMIX_PROC_TOOL +} pmix_proc_type_t; + /**** MESSAGING STRUCTURES ****/ /* header for messages */ diff --git a/opal/mca/pmix/pmix2x/pmix/include/pmix/autogen/pmix_stdint.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_stdint.h similarity index 100% rename from opal/mca/pmix/pmix2x/pmix/include/pmix/autogen/pmix_stdint.h rename to opal/mca/pmix/pmix2x/pmix/src/include/pmix_stdint.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/rename.h b/opal/mca/pmix/pmix2x/pmix/src/include/rename.h new file mode 100644 index 0000000000..8e5582cf0a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/include/rename.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_RENAME_H +#define PMIX_RENAME_H + +#endif + diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/types.h b/opal/mca/pmix/pmix2x/pmix/src/include/types.h index 0bc5dc2dd7..422ca0d7c5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/types.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/types.h @@ -215,7 +215,47 @@ static inline uint64_t pmix_swap_bytes8(uint64_t val) #define pmix_swap_bytes8 hton64 #endif /* WORDS_BIGENDIAN || !HAVE_UNIX_BYTESWAP */ +#define PMIX_EV_TIMEOUT EV_TIMEOUT +#define PMIX_EV_READ EV_READ +#define PMIX_EV_WRITE EV_WRITE +#define PMIX_EV_SIGNAL EV_SIGNAL +/* Persistent event: won't get removed automatically when activated. */ +#define PMIX_EV_PERSIST EV_PERSIST + +#define PMIX_EVLOOP_ONCE EVLOOP_ONCE /**< Block at most once. */ +#define PMIX_EVLOOP_NONBLOCK EVLOOP_NONBLOCK /**< Do not block. */ + typedef struct event_base pmix_event_base_t; typedef struct event pmix_event_t; +#define pmix_event_base_create() event_base_new() + +#define pmix_event_base_free(b) event_base_free(b) + +#define pmix_event_base_loopbreak(b) event_base_loopbreak(b) + +#define pmix_event_base_loopexit(b) event_base_loopexit(b, NULL) + +/* thread support APIs */ +#define pmix_event_use_threads() evthread_use_pthreads() + +/* Basic event APIs */ +#define pmix_event_enable_debug_mode() event_enable_debug_mode() + +#define pmix_event_set(b, x, fd, fg, cb, arg) event_assign((x), (b), (fd), (fg), (event_callback_fn) (cb), (arg)) + +#define pmix_event_add(ev, tv) event_add((ev), (tv)) + +#define pmix_event_del(ev) event_del((ev)) + +#define pmix_event_active(x, y, z) event_active((x), (y), (z)) + +#define pmix_event_new(b, fd, fg, cb, arg) event_new((b), (fd), (fg), (event_callback_fn) (cb), (arg)) + +#define pmix_event_loop(b, fg) event_base_loop((b), (fg)) + +#ifdef HAVE_LIBEVENT_GLOBAL_SHUTDOWN +#define pmix_libevent_global_shutdown() libevent_global_shutdown() +#endif + #endif /* PMIX_TYPES_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/mca/Makefile.include new file mode 100644 index 0000000000..67f92a9207 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/Makefile.include @@ -0,0 +1,26 @@ +# -*- 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) 2016 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 + +# Source code files +headers += \ + mca/mca.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/base/Makefile.am new file mode 100644 index 0000000000..948d687eed --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/Makefile.am @@ -0,0 +1,66 @@ +# +# 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) 2010-2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# Need this so that the base knows where to load dynamic components from +# (by default) + +AM_CPPFLAGS = \ + $(LTDLINCL) + +noinst_LTLIBRARIES = libpmix_mca_base.la + +dist_pmixdata_DATA = help-mca-base.txt help-mca-var.txt + +# Source code files + +headers = \ + base.h \ + pmix_mca_base_component_repository.h \ + pmix_mca_base_var.h \ + pmix_mca_base_var_enum.h \ + pmix_mca_base_var_group.h \ + pmix_mca_base_vari.h \ + pmix_mca_base_framework.h + +# Library + +libpmix_mca_base_la_SOURCES = \ + $(headers) \ + pmix_mca_base_close.c \ + pmix_mca_base_component_compare.c \ + pmix_mca_base_component_find.c \ + pmix_mca_base_component_repository.c \ + pmix_mca_base_components_open.c \ + pmix_mca_base_components_close.c \ + pmix_mca_base_components_select.c \ + pmix_mca_base_list.c \ + pmix_mca_base_open.c \ + pmix_mca_base_var.c \ + pmix_mca_base_var_enum.c \ + pmix_mca_base_var_group.c \ + pmix_mca_base_parse_paramfile.c \ + pmix_mca_base_components_register.c \ + pmix_mca_base_framework.c + +# Conditionally install the header files + +if WANT_INSTALL_HEADERS +pmixdir = $(pmixincludedir)/$(subdir) +pmix_HEADERS = $(headers) +endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h b/opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h new file mode 100644 index 0000000000..c3a9fc6869 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/base.h @@ -0,0 +1,246 @@ +/* -*- 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-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) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2013-2015 Los Alamos National Security, LLC. 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef MCA_BASE_H +#define MCA_BASE_H + +#include + +#include "src/class/pmix_object.h" +#include "src/class/pmix_list.h" + +/* + * These units are large enough to warrant their own .h files + */ +#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/util/output.h" + +BEGIN_C_DECLS + +/* + * Structure for making plain lists of components + */ +struct pmix_mca_base_component_list_item_t { + pmix_list_item_t super; + const pmix_mca_base_component_t *cli_component; +}; +typedef struct pmix_mca_base_component_list_item_t pmix_mca_base_component_list_item_t; +PMIX_CLASS_DECLARATION(pmix_mca_base_component_list_item_t); + +/* + * Structure for making priority lists of components + */ +struct pmix_mca_base_component_priority_list_item_t { + pmix_mca_base_component_list_item_t super; + int cpli_priority; +}; +typedef struct pmix_mca_base_component_priority_list_item_t + pmix_mca_base_component_priority_list_item_t; + +PMIX_CLASS_DECLARATION(pmix_mca_base_component_priority_list_item_t); + +/* + * Public variables + */ +extern char *pmix_mca_base_component_path; +extern bool pmix_mca_base_component_show_load_errors; +extern bool pmix_mca_base_component_disable_dlopen; +extern char *pmix_mca_base_system_default_path; +extern char *pmix_mca_base_user_default_path; + +/* + * Standard verbosity levels + */ +enum { + /** total silence */ + PMIX_MCA_BASE_VERBOSE_NONE = -1, + /** only errors are printed */ + PMIX_MCA_BASE_VERBOSE_ERROR = 0, + /** emit messages about component selection, open, and unloading */ + PMIX_MCA_BASE_VERBOSE_COMPONENT = 10, + /** also emit warnings */ + PMIX_MCA_BASE_VERBOSE_WARN = 20, + /** also emit general, user-relevant information, such as rationale as to why certain choices + * or code paths were taken, information gleaned from probing the local system, etc. */ + PMIX_MCA_BASE_VERBOSE_INFO = 40, + /** also emit relevant tracing information (e.g., which functions were invoked / + * call stack entry/exit info) */ + PMIX_MCA_BASE_VERBOSE_TRACE = 60, + /** also emit PMIX-developer-level (i.e,. highly detailed) information */ + PMIX_MCA_BASE_VERBOSE_DEBUG = 80, + /** also output anything else that might be useful */ + PMIX_MCA_BASE_VERBOSE_MAX = 100, +}; + +/* + * Public functions + */ + +/** + * First function called in the MCA. + * + * @return PMIX_SUCCESS Upon success + * @return PMIX_ERROR Upon failure + * + * This function starts up the entire MCA. It initializes a bunch + * of built-in MCA parameters, and initialized the MCA component + * repository. + * + * It must be the first MCA function invoked. It is normally + * invoked during the initialization stage and specifically + * invoked in the special case of the *_info command. + */ +int pmix_mca_base_open(void); + +/** + * Last function called in the MCA + * + * @return PMIX_SUCCESS Upon success + * @return PMIX_ERROR Upon failure + * + * This function closes down the entire MCA. It clears all MCA + * parameters and closes down the MCA component respository. + * + * It must be the last MCA function invoked. It is normally invoked + * during the finalize stage. + */ +int pmix_mca_base_close(void); + +/** + * A generic select function + * + */ +int pmix_mca_base_select(const char *type_name, int output_id, + pmix_list_t *components_available, + pmix_mca_base_module_t **best_module, + pmix_mca_base_component_t **best_component, + int *priority_out); + +/** + * A function for component query functions to discover if they have + * been explicitly required to or requested to be selected. + * + * exclusive: If the specified component is the only component that is + * available for selection. + * + */ +int pmix_mca_base_is_component_required(pmix_list_t *components_available, + pmix_mca_base_component_t *component, + bool exclusive, + bool *is_required); + +/* pmix_mca_base_component_compare.c */ + +int pmix_mca_base_component_compare_priority(pmix_mca_base_component_priority_list_item_t *a, + pmix_mca_base_component_priority_list_item_t *b); +int pmix_mca_base_component_compare(const pmix_mca_base_component_t *a, + const pmix_mca_base_component_t *b); +int pmix_mca_base_component_compatible(const pmix_mca_base_component_t *a, + const pmix_mca_base_component_t *b); +char * pmix_mca_base_component_to_string(const pmix_mca_base_component_t *a); + +/* pmix_mca_base_component_find.c */ + +int pmix_mca_base_component_find (const char *directory, pmix_mca_base_framework_t *framework, + bool ignore_requested, bool open_dso_components); + +/** + * Parse the requested component string and return an pmix_argv of the requested + * (or not requested) components. + */ +int pmix_mca_base_component_parse_requested (const char *requested, bool *include_mode, + char ***requested_component_names); + +/** + * Filter a list of components based on a comma-delimted list of names and/or + * a set of meta-data flags. + * + * @param[in,out] components List of components to filter + * @param[in] output_id Output id to write to for error/warning/debug messages + * @param[in] filter_names Comma delimited list of components to use. Negate with ^. + * May be NULL. + * @param[in] filter_flags Metadata flags components are required to have set (CR ready) + * + * @returns PMIX_SUCCESS On success + * @returns PMIX_ERR_NOT_FOUND If some component in {filter_names} is not found in + * {components}. Does not apply to negated filters. + * @returns pmix error code On other error. + * + * This function closes and releases any components that do not match the filter_name and + * filter flags. + */ +int pmix_mca_base_components_filter (pmix_mca_base_framework_t *framework, uint32_t filter_flags); + + + +/* Safely release some memory allocated by pmix_mca_base_component_find() + (i.e., is safe to call even if you never called + pmix_mca_base_component_find()). */ +int pmix_mca_base_component_find_finalize(void); + +/* pmix_mca_base_components_register.c */ +int pmix_mca_base_framework_components_register (struct pmix_mca_base_framework_t *framework, + pmix_mca_base_register_flag_t flags); + +/* pmix_mca_base_components_open.c */ +int pmix_mca_base_framework_components_open (struct pmix_mca_base_framework_t *framework, + pmix_mca_base_open_flag_t flags); + +int pmix_mca_base_components_open(const char *type_name, int output_id, + const pmix_mca_base_component_t **static_components, + pmix_list_t *components_available, + bool open_dso_components); + +/* pmix_mca_base_components_close.c */ +/** + * Close and release a component. + * + * @param[in] component Component to close + * @param[in] output_id Output id for debugging output + * + * After calling this function the component may no longer be used. + */ +void pmix_mca_base_component_close (const pmix_mca_base_component_t *component, int output_id); + +/** + * Release a component without closing it. + * @param[in] component Component to close + * @param[in] output_id Output id for debugging output + * + * After calling this function the component may no longer be used. + */ +void pmix_mca_base_component_unload (const pmix_mca_base_component_t *component, int output_id); + +int pmix_mca_base_components_close(int output_id, pmix_list_t *components_available, + const pmix_mca_base_component_t *skip); + +int pmix_mca_base_framework_components_close (struct pmix_mca_base_framework_t *framework, + const pmix_mca_base_component_t *skip); + +END_C_DECLS + +#endif /* MCA_BASE_H */ 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 new file mode 100644 index 0000000000..c0b8251076 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-base.txt @@ -0,0 +1,61 @@ +# -*- text -*- +# +# 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) 2008-2014 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# +# This is the US/English help file for PMIX MCA error messages. +# +[find-available:not-valid] +A requested component was not found, or was unable to be opened. This +means that this component is either not installed or is unable to be +used on your system (e.g., sometimes this means that shared libraries +that the component requires are unable to be found/loaded). Note that +PMIX stopped checking at the first component that it did not find. + +Host: %s +Framework: %s +Component: %s +# +[find-available:none found] +No components were able to be opened in the %s framework. + +This typically means that either no components of this type were +installed, or none of the installed componnets can be loaded. +Sometimes this means that shared libraries required by these +components are unable to be found/loaded. + + Host: %s + Framework: %s +# +[framework-param:too-many-negates] +MCA framework parameters can only take a single negation operator +("^"), and it must be at the beginning of the value. The following +value violates this rule: + + %s + +When used, the negation operator sets the "exclusive" behavior mode, +meaning that it will exclude all specified components (and implicitly +include all others). If the negation operator is not specified, the +"inclusive" mode is assumed, meaning that all specified components +will be included (and implicitly exclude all others). + +For example, "^a,b" specifies the exclusive behavior and means "use +all components *except* a and b", while "c,d" specifies the inclusive +behavior and means "use *only* components c and d." + +You cannot mix inclusive and exclusive behavior. 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 new file mode 100644 index 0000000000..b306c31ff9 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/help-mca-var.txt @@ -0,0 +1,139 @@ +# -*- text -*- +# +# 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) 2008-2011 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2013 Los Alamos National Security, LLC. All rights +# reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# +# This is the US/English help file for PMIX MCA error messages. +# +[invalid-flag-combination] +ERROR: An invalid combination of flags was passed to pmix_mca_base_var_register. + + Variable: %s + Flags: %s %s +# +[default-only-param-set] +WARNING: A user-supplied value attempted to override the default-only MCA +variable named "%s". + +The user-supplied value was ignored. +# +[missing-param-file] +Process %d Unable to locate the variable file "%s" in the following search path: + %s +# +[deprecated-mca-env] +A deprecated MCA variable value was specified in the environment or +on the command line. Deprecated MCA variables should be avoided; +they may disappear in future releases. + + Deprecated variable: %s + New variable: %s +# +[deprecated-mca-cli] +A deprecated MCA variable value was specified on the command line. Deprecated +MCA variables should be avoided; they may disappear in future releases. + + Deprecated variable: %s + New variable: %s +# +[deprecated-mca-file] +A deprecated MCA variable value was specified in an MCA variable +file. Deprecated MCA variables should be avoided; they may disappear +in future releases. + + Deprecated variable: %s + Source file: %s + New variable: %s +# +[mutually-exclusive-vars] +Two mutually-exclusive MCA variables were specified. This can result +in undefined behavior, such as ignoring the components that the MCA +variables are supposed to affect. + + 1st MCA variable: %s + Source of value: %s + 2nd MCA variable: %s + Source of value: %s +# +[re-register-with-different-type] +An MCA variable was re-registered with a different type (i.e., it was +either originally registered as an INT and re-registered as a STRING, +or it was originially registered as a STRING and re-registered as an +INT). This a developer error; your job may abort. + + MCA variable name: %s +# +[var-name-conflict] +A name collision was detected on an MCA variable name. This can happen +if two components try to register the same variable with slightly +different name components. The conflicting variables are listed below: + + MCA variable name: %s + New name: %s %s %s + Existing name: %s %s %s +# +[overridden-param-set] +WARNING: A user-supplied value attempted to set a variable that is set +in the override variable file (pmix-mca-params-override.conf). + + Variable: %s + +The user-supplied value was ignored. +# +[invalid-value] +An invalid value was supplied for an MCA variable. + + Variable : %s + Value : %s +# +[invalid-value-enum] +An invalid value was supplied for an enum variable. + + Variable : %s + Value : %s + Valid values : %s +# +[environment-only-param] +WARNING: The special MCA parameter "%s" was set in +an unexpected way, and is likely not working the way you want it to. + +Specifically, this MCA parameter is "special" in that it can *only* be +set in the environment. Setting this value in a file -- and sometimes +even on the command line -- will not work as intended. The *only* way +to set this value is to set "PMIX_MCA_%s" in the environment before +starting your job. + + Value: %s + Source: %s +# +[incorrect-env-list-param] +WARNING: The format of "pmix_mca_base_env_list" parameter is a delimited list of VAR=VAL or +VAR instances. By default, the delimiter is a semicolon: VAR1=VAL1;VAR2;VAR3=VAL3;... +You can set other via "pmix_mca_base_env_list_delimiter" parameter. If the delimiter is a +semicolon, the value of "pmix_mca_base_env_list" variable should be quoted to not interfere +with SHELL command line parsing. In the case where a value is not assigned to variable +VAR, the value will be taken from the current environment. +The following environment variable was not found in the environment: + Variable: %s + MCA variable value: %s +# +[incorrect-env-list-sep] +An invalid value was supplied for an MCA variable "pmix_mca_base_env_list_delimiter". +The "pmix_mca_base_env_list" variable will be ignored. + Value: %s 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 new file mode 100644 index 0000000000..f42c2f038f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_close.c @@ -0,0 +1,68 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "src/util/output.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_component_repository.h" +#include "pmix_common.h" + +extern int pmix_mca_base_opened; + +/* + * Main MCA shutdown. + */ +int pmix_mca_base_close(void) +{ + assert (pmix_mca_base_opened); + if (!--pmix_mca_base_opened) { + /* deregister all MCA base parameters */ + int group_id = pmix_mca_base_var_group_find ("pmix", "mca", "base"); + + if (-1 < group_id) { + pmix_mca_base_var_group_deregister (group_id); + } + + /* release the default paths */ + if (NULL != pmix_mca_base_system_default_path) { + free(pmix_mca_base_system_default_path); + } + if (NULL != pmix_mca_base_user_default_path) { + free(pmix_mca_base_user_default_path); + } + + /* Close down the component repository */ + pmix_mca_base_component_repository_finalize(); + + /* Shut down the dynamic component finder */ + pmix_mca_base_component_find_finalize(); + + /* Close pmix output stream 0 */ + pmix_output_close(0); + } + + /* All done */ + return PMIX_SUCCESS; +} 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 new file mode 100644 index 0000000000..e4c9507069 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_compare.c @@ -0,0 +1,152 @@ +/* + * 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) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include + +#include "src/mca/mca.h" +#include "src/mca/base/base.h" + + +/* + * Function for comparing two pmix_mca_base_component_priority_t structs so + * that we can build prioritized listss of them. This assumed that + * the types of the modules are the same. Sort first by priority, + * second by module name, third by module version. + * + * Note that we acutally want a *reverse* ordering here -- the al_* + * functions will put "smaller" items at the head, and "larger" items + * at the tail. Since we want the highest priority at the head, it + * may help the gentle reader to consider this an inverse comparison. + * :-) + */ +int +pmix_mca_base_component_compare_priority(pmix_mca_base_component_priority_list_item_t *a, + pmix_mca_base_component_priority_list_item_t *b) +{ + /* First, compare the priorties */ + + if (a->cpli_priority > b->cpli_priority) { + return -1; + } else if (a->cpli_priority < b->cpli_priority) { + return 1; + } else { + return pmix_mca_base_component_compare(a->super.cli_component, + b->super.cli_component); + } +} + + +int pmix_mca_base_component_compare(const pmix_mca_base_component_t* aa, + const pmix_mca_base_component_t* bb) +{ + int val; + + val = strncmp(aa->pmix_mca_type_name, bb->pmix_mca_type_name, + PMIX_MCA_BASE_MAX_TYPE_NAME_LEN); + if (val != 0) { + return -val; + } + + val = strncmp(aa->pmix_mca_component_name, bb->pmix_mca_component_name, + PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN); + if (val != 0) { + return -val; + } + + /* The names were equal, so compare the versions */ + + if (aa->pmix_mca_component_major_version > + bb->pmix_mca_component_major_version) { + return -1; + } else if (aa->pmix_mca_component_major_version < + bb->pmix_mca_component_major_version) { + return 1; + } else if (aa->pmix_mca_component_minor_version > + bb->pmix_mca_component_minor_version) { + return -1; + } else if (aa->pmix_mca_component_minor_version < + bb->pmix_mca_component_minor_version) { + return 1; + } else if (aa->pmix_mca_component_release_version > + bb->pmix_mca_component_release_version) { + return -1; + } else if (aa->pmix_mca_component_release_version < + bb->pmix_mca_component_release_version) { + return 1; + } + + return 0; +} + + +/** + * compare but exclude the release version - declare compatible + * if the major/minor version are the same. + */ +int pmix_mca_base_component_compatible(const pmix_mca_base_component_t* aa, + const pmix_mca_base_component_t* bb) +{ + int val; + + val = strncmp(aa->pmix_mca_type_name, bb->pmix_mca_type_name, + PMIX_MCA_BASE_MAX_TYPE_NAME_LEN); + if (val != 0) { + return -val; + } + + val = strncmp(aa->pmix_mca_component_name, bb->pmix_mca_component_name, + PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN); + if (val != 0) { + return -val; + } + + /* The names were equal, so compare the versions */ + + if (aa->pmix_mca_component_major_version > + bb->pmix_mca_component_major_version) { + return -1; + } else if (aa->pmix_mca_component_major_version < + bb->pmix_mca_component_major_version) { + return 1; + } else if (aa->pmix_mca_component_minor_version > + bb->pmix_mca_component_minor_version) { + return -1; + } else if (aa->pmix_mca_component_minor_version < + bb->pmix_mca_component_minor_version) { + return 1; + } + return 0; +} + +/** + * Returns a string which represents the component name and version. + * Has the form: comp_type.comp_name.major_version.minor_version + */ +char * pmix_mca_base_component_to_string(const pmix_mca_base_component_t *a) { + char * str = NULL; + if(0 > asprintf(&str, "%s.%s.%d.%d", a->pmix_mca_type_name, + a->pmix_mca_component_name, a->pmix_mca_component_major_version, + a->pmix_mca_component_minor_version)) { + return NULL; + } + 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 new file mode 100644 index 0000000000..981511ee5a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_find.c @@ -0,0 +1,389 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 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) 2008-2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif + +#include "src/mca/pinstalldirs/pinstalldirs.h" +#include "src/util/pmix_environ.h" +#include "src/util/output.h" +#include "src/util/argv.h" +#include "src/util/show_help.h" +#include "src/class/pmix_list.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_component_repository.h" +#include "pmix_common.h" +#include "src/mca/pdl/base/base.h" + +#if PMIX_HAVE_PDL_SUPPORT +/* + * Private functions + */ +static void find_dyn_components(const char *path, pmix_mca_base_framework_t *framework, + const char **names, bool include_mode); + +#endif /* PMIX_HAVE_PDL_SUPPORT */ + +static int component_find_check (pmix_mca_base_framework_t *framework, char **requested_component_names); + +/* + * Dummy structure for casting for open_only logic + */ +struct pmix_mca_base_open_only_dummy_component_t { + /** MCA base component */ + pmix_mca_base_component_t version; + /** MCA base data */ + pmix_mca_base_component_data_t data; +}; +typedef struct pmix_mca_base_open_only_dummy_component_t pmix_mca_base_open_only_dummy_component_t; + +static char negate[] = "^"; + +static bool use_component(const bool include_mode, + const char **requested_component_names, + const char *component_name); + + +/* + * Function to find as many components of a given type as possible. This + * includes statically-linked in components as well as opening up a + * directory and looking for shared-library MCA components of the + * appropriate type (load them if available). + * + * Return one consolidated array of (pmix_mca_base_component_t*) pointing to all + * available components. + */ +int pmix_mca_base_component_find (const char *directory, pmix_mca_base_framework_t *framework, + bool ignore_requested, bool open_dso_components) +{ + const pmix_mca_base_component_t **static_components = framework->framework_static_components; + char **requested_component_names = NULL; + pmix_mca_base_component_list_item_t *cli; + bool include_mode = true; + int ret; + + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, framework->framework_output, + "mca: base: component_find: searching %s for %s components", + directory, framework->framework_name); + + if (!ignore_requested) { + ret = pmix_mca_base_component_parse_requested (framework->framework_selection, &include_mode, + &requested_component_names); + if (PMIX_SUCCESS != ret) { + return ret; + } + } + + /* Find all the components that were statically linked in */ + if (static_components) { + for (int i = 0 ; NULL != static_components[i]; ++i) { + if ( use_component(include_mode, + (const char**)requested_component_names, + static_components[i]->pmix_mca_component_name) ) { + cli = PMIX_NEW(pmix_mca_base_component_list_item_t); + if (NULL == cli) { + ret = PMIX_ERR_OUT_OF_RESOURCE; + goto component_find_out; + } + cli->cli_component = static_components[i]; + pmix_list_append(&framework->framework_components, (pmix_list_item_t *) cli); + } + } + } + +#if PMIX_HAVE_PDL_SUPPORT + /* Find any available dynamic components in the specified directory */ + if (open_dso_components && !pmix_mca_base_component_disable_dlopen) { + find_dyn_components(directory, framework, (const char**)requested_component_names, + include_mode); + } else { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0, + "pmix:mca: base: component_find: dso loading for %s MCA components disabled", + framework->framework_name); + } +#endif + + if (include_mode) { + ret = component_find_check (framework, requested_component_names); + } else { + ret = PMIX_SUCCESS; + } + +component_find_out: + + if (NULL != requested_component_names) { + pmix_argv_free(requested_component_names); + } + + /* All done */ + + return ret; +} + +int pmix_mca_base_component_find_finalize(void) +{ + return PMIX_SUCCESS; +} + +int pmix_mca_base_components_filter (pmix_mca_base_framework_t *framework, uint32_t filter_flags) +{ + pmix_list_t *components = &framework->framework_components; + int output_id = framework->framework_output; + pmix_mca_base_component_list_item_t *cli, *next; + char **requested_component_names = NULL; + bool include_mode, can_use; + int ret; + + assert (NULL != components); + + if (0 == filter_flags && NULL == framework->framework_selection) { + return PMIX_SUCCESS; + } + + ret = pmix_mca_base_component_parse_requested (framework->framework_selection, &include_mode, + &requested_component_names); + if (PMIX_SUCCESS != ret) { + return ret; + } + + PMIX_LIST_FOREACH_SAFE(cli, next, components, pmix_mca_base_component_list_item_t) { + const pmix_mca_base_component_t *component = cli->cli_component; + pmix_mca_base_open_only_dummy_component_t *dummy = + (pmix_mca_base_open_only_dummy_component_t *) cli->cli_component; + + can_use = use_component(include_mode, (const char **) requested_component_names, + cli->cli_component->pmix_mca_component_name); + + if (!can_use || (filter_flags & dummy->data.param_field) != filter_flags) { + if (can_use && (filter_flags & PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT) && + !(PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT & dummy->data.param_field)) { + pmix_output_verbose(PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "pmix:mca: base: components_filter: " + "(%s) Component %s is *NOT* Checkpointable - Disabled", + component->reserved, + component->pmix_mca_component_name); + } + + pmix_list_remove_item(components, &cli->super); + + pmix_mca_base_component_unload(component, output_id); + + PMIX_RELEASE(cli); + } else if (filter_flags & PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT) { + pmix_output_verbose(PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "pmix:mca: base: components_filter: " + "(%s) Component %s is Checkpointable", + component->reserved, + component->pmix_mca_component_name); + } + } + + if (include_mode) { + ret = component_find_check(framework, requested_component_names); + } else { + ret = PMIX_SUCCESS; + } + + if (NULL != requested_component_names) { + pmix_argv_free(requested_component_names); + } + + return ret; +} + +#if PMIX_HAVE_PDL_SUPPORT + +/* + * Open up all directories in a given path and search for components of + * the specified type (and possibly of a given name). + * + * Note that we use our own path iteration functionality because we + * need to look at companion .ompi_info files in the same directory as + * the library to generate dependencies, etc. + */ +static void find_dyn_components(const char *path, pmix_mca_base_framework_t *framework, + const char **names, bool include_mode) +{ + pmix_mca_base_component_repository_item_t *ri; + pmix_list_t *dy_components; + int ret; + + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, framework->framework_output, + "mca: base: find_dyn_components: checking %s for %s components", + path, framework->framework_name); + + if (NULL != path) { + ret = pmix_mca_base_component_repository_add(path); + if (PMIX_SUCCESS != ret) { + return; + } + } + + ret = pmix_mca_base_component_repository_get_components(framework, &dy_components); + if (PMIX_SUCCESS != ret) { + return; + } + + /* Iterate through the repository and find components that can be included */ + PMIX_LIST_FOREACH(ri, dy_components, pmix_mca_base_component_repository_item_t) { + if (use_component(include_mode, names, ri->ri_name)) { + pmix_mca_base_component_repository_open(framework, ri); + } + } +} + +#endif /* PMIX_HAVE_PDL_SUPPORT */ + +static bool use_component(const bool include_mode, + const char **requested_component_names, + const char *component_name) +{ + bool found = false; + const char **req_comp_name = requested_component_names; + + /* + * If no selection is specified then we use all components + * we can find. + */ + if (NULL == req_comp_name) { + return true; + } + + while ( *req_comp_name != NULL ) { + if ( strcmp(component_name, *req_comp_name) == 0 ) { + found = true; + break; + } + req_comp_name++; + } + + /* + * include_mode found | use + * --------------------+------ + * 0 0 | true + * 0 1 | false + * 1 0 | false + * 1 1 | true + * + * -> inverted xor + * As xor is a binary operator let's implement it manually before + * a compiler screws it up. + */ + + return (include_mode && found) || !(include_mode || found); +} + +/* Ensure that *all* requested components exist. Print a warning + and abort if they do not. */ +static int component_find_check (pmix_mca_base_framework_t *framework, char **requested_component_names) +{ + pmix_list_t *components = &framework->framework_components; + pmix_mca_base_component_list_item_t *cli; + + if (NULL == requested_component_names) { + return PMIX_SUCCESS; + } + + for (int i = 0; NULL != requested_component_names[i]; ++i) { + bool found = false; + + PMIX_LIST_FOREACH(cli, components, pmix_mca_base_component_list_item_t) { + if (0 == strcmp(requested_component_names[i], + cli->cli_component->pmix_mca_component_name)) { + found = true; + break; + } + } + + if (!found) { + char h[MAXHOSTNAMELEN]; + gethostname(h, sizeof(h)); + pmix_show_help("help-mca-base.txt", + "find-available:not-valid", true, + h, framework->framework_name, requested_component_names[i]); + return PMIX_ERR_NOT_FOUND; + } + } + + return PMIX_SUCCESS; +} + +int pmix_mca_base_component_parse_requested (const char *requested, bool *include_mode, + char ***requested_component_names) +{ + const char *requested_orig = requested; + + *requested_component_names = NULL; + *include_mode = true; + + /* See if the user requested anything */ + if (NULL == requested || 0 == strlen (requested)) { + return PMIX_SUCCESS; + } + + /* Are we including or excluding? We only allow the negate + character to be the *first* character of the value (but be nice + and allow any number of negate characters in the beginning). */ + *include_mode = requested[0] != negate[0]; + + /* skip over all negate symbols at the beginning */ + requested += strspn (requested, negate); + + /* Double check to ensure that the user did not specify the negate + character anywhere else in the value. */ + if (NULL != strstr (requested, negate)) { + pmix_show_help("help-mca-base.txt", + "framework-param:too-many-negates", + true, requested_orig); + return PMIX_ERROR; + } + + /* Split up the value into individual component names */ + *requested_component_names = pmix_argv_split(requested, ','); + + /* All done */ + return PMIX_SUCCESS; +} 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 new file mode 100644 index 0000000000..de1c735e64 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.c @@ -0,0 +1,572 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 2008-2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/class/pmix_list.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_component_repository.h" +#include "src/mca/pdl/base/base.h" +#include "pmix_common.h" +#include "src/class/pmix_hash_table.h" +#include "src/util/basename.h" + +#if PMIX_HAVE_PDL_SUPPORT + +/* + * Private types + */ +static void ri_constructor(pmix_mca_base_component_repository_item_t *ri); +static void ri_destructor(pmix_mca_base_component_repository_item_t *ri); +PMIX_CLASS_INSTANCE(pmix_mca_base_component_repository_item_t, pmix_list_item_t, + ri_constructor, ri_destructor); + +#endif /* PMIX_HAVE_PDL_SUPPORT */ + + +/* + * Private variables + */ +static bool initialized = false; + + +#if PMIX_HAVE_PDL_SUPPORT + +static pmix_hash_table_t pmix_mca_base_component_repository; + +/* two-level macro for stringifying a number */ +#define STRINGIFYX(x) #x +#define STRINGIFY(x) STRINGIFYX(x) + +static int process_repository_item (const char *filename, void *data) +{ + char name[PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN + 1]; + char type[PMIX_MCA_BASE_MAX_TYPE_NAME_LEN + 1]; + pmix_mca_base_component_repository_item_t *ri; + pmix_list_t *component_list; + char *base; + int ret; + + base = pmix_basename (filename); + if (NULL == base) { + return PMIX_ERROR; + } + + /* check if the plugin has the appropriate prefix */ + if (0 != strncmp (base, "mca_", 4)) { + free (base); + return PMIX_SUCCESS; + } + + /* read framework and component names. framework names may not include an _ + * but component names may */ + ret = sscanf(base, "mca_%" STRINGIFY(PMIX_MCA_BASE_MAX_TYPE_NAME_LEN) "[^_]_%" + STRINGIFY(PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN) "s", type, name); + if (0 > ret) { + /* does not patch the expected template. skip */ + free(base); + return PMIX_SUCCESS; + } + + /* lookup the associated framework list and create if it doesn't already exist */ + ret = pmix_hash_table_get_value_ptr(&pmix_mca_base_component_repository, type, + strlen (type), (void **) &component_list); + if (PMIX_SUCCESS != ret) { + component_list = PMIX_NEW(pmix_list_t); + if (NULL == component_list) { + free (base); + /* OOM. nothing to do but fail */ + return PMIX_ERR_OUT_OF_RESOURCE; + } + + ret = pmix_hash_table_set_value_ptr(&pmix_mca_base_component_repository, type, + strlen (type), (void *) component_list); + if (PMIX_SUCCESS != ret) { + free (base); + PMIX_RELEASE(component_list); + return ret; + } + } + + /* check for duplicate components */ + PMIX_LIST_FOREACH(ri, component_list, pmix_mca_base_component_repository_item_t) { + if (0 == strcmp (ri->ri_name, name)) { + /* already scanned this component */ + free (base); + return PMIX_SUCCESS; + } + } + + ri = PMIX_NEW(pmix_mca_base_component_repository_item_t); + if (NULL == ri) { + free (base); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + ri->ri_base = base; + + ri->ri_path = strdup (filename); + if (NULL == ri->ri_path) { + PMIX_RELEASE(ri); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + /* strncpy does not guarantee a \0 */ + ri->ri_type[PMIX_MCA_BASE_MAX_TYPE_NAME_LEN] = '\0'; + strncpy (ri->ri_type, type, PMIX_MCA_BASE_MAX_TYPE_NAME_LEN); + + ri->ri_name[PMIX_MCA_BASE_MAX_TYPE_NAME_LEN] = '\0'; + strncpy (ri->ri_name, name, PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN); + + pmix_list_append (component_list, &ri->super); + + return PMIX_SUCCESS; +} + +static int file_exists(const char *filename, const char *ext) +{ + char *final; + int ret; + + if (NULL == ext) { + return access (filename, F_OK) == 0; + } + + ret = asprintf(&final, "%s.%s", filename, ext); + if (0 > ret || NULL == final) { + return 0; + } + + ret = access (final, F_OK); + free(final); + return (0 == ret); +} + +#endif /* PMIX_HAVE_PDL_SUPPORT */ + +int pmix_mca_base_component_repository_add (const char *path) +{ +#if PMIX_HAVE_PDL_SUPPORT + char *path_to_use = NULL, *dir, *ctx; + const char sep[] = {PMIX_ENV_SEP, '\0'}; + + if (NULL == path) { + /* nothing to do */ + return PMIX_SUCCESS; + } + + path_to_use = strdup (path); + + dir = strtok_r (path_to_use, sep, &ctx); + do { + if ((0 == strcmp(dir, "USER_DEFAULT") || 0 == strcmp(dir, "USR_DEFAULT")) + && NULL != pmix_mca_base_user_default_path) { + dir = pmix_mca_base_user_default_path; + } else if (0 == strcmp(dir, "SYS_DEFAULT") || + 0 == strcmp(dir, "SYSTEM_DEFAULT")) { + dir = pmix_mca_base_system_default_path; + } + + if (0 != pmix_pdl_foreachfile(dir, process_repository_item, NULL)) { + break; + } + } while (NULL != (dir = strtok_r (NULL, sep, &ctx))); + + free (path_to_use); + +#endif /* PMIX_HAVE_PDL_SUPPORT */ + + return PMIX_SUCCESS; +} + + +/* + * Initialize the repository + */ +int pmix_mca_base_component_repository_init(void) +{ + /* Setup internal structures */ + + if (!initialized) { +#if PMIX_HAVE_PDL_SUPPORT + + /* Initialize the dl framework */ + int ret = pmix_mca_base_framework_open(&pmix_pdl_base_framework, 0); + if (PMIX_SUCCESS != ret) { + pmix_output(0, "%s %d:%s failed -- process will likely abort (open the dl framework returned %d instead of PMIX_SUCCESS)\n", + __FILE__, __LINE__, __func__, ret); + return ret; + } + pmix_pdl_base_select(); + + PMIX_CONSTRUCT(&pmix_mca_base_component_repository, pmix_hash_table_t); + ret = pmix_hash_table_init (&pmix_mca_base_component_repository, 128); + if (PMIX_SUCCESS != ret) { + (void) pmix_mca_base_framework_close(&pmix_pdl_base_framework); + return ret; + } + + ret = pmix_mca_base_component_repository_add(pmix_mca_base_component_path); + if (PMIX_SUCCESS != ret) { + PMIX_DESTRUCT(&pmix_mca_base_component_repository); + (void) pmix_mca_base_framework_close(&pmix_pdl_base_framework); + return ret; + } +#endif + + initialized = true; + } + + /* All done */ + + return PMIX_SUCCESS; +} + +int pmix_mca_base_component_repository_get_components (pmix_mca_base_framework_t *framework, + pmix_list_t **framework_components) +{ + *framework_components = NULL; +#if PMIX_HAVE_PDL_SUPPORT + return pmix_hash_table_get_value_ptr (&pmix_mca_base_component_repository, framework->framework_name, + strlen (framework->framework_name), (void **) framework_components); +#endif + return PMIX_ERR_NOT_FOUND; +} + +#if PMIX_HAVE_PDL_SUPPORT +static void pmix_mca_base_component_repository_release_internal(pmix_mca_base_component_repository_item_t *ri) { + int group_id; + + group_id = pmix_mca_base_var_group_find (NULL, ri->ri_type, ri->ri_name); + if (0 <= group_id) { + /* ensure all variables are deregistered before we dlclose the component */ + pmix_mca_base_var_group_deregister (group_id); + } + + /* Close the component (and potentially unload it from memory */ + if (ri->ri_dlhandle) { + pmix_pdl_close(ri->ri_dlhandle); + ri->ri_dlhandle = NULL; + } +} +#endif + +#if PMIX_HAVE_PDL_SUPPORT +static pmix_mca_base_component_repository_item_t *find_component(const char *type, const char *name) +{ + pmix_mca_base_component_repository_item_t *ri; + pmix_list_t *component_list; + int ret; + + ret = pmix_hash_table_get_value_ptr (&pmix_mca_base_component_repository, type, + strlen (type), (void **) &component_list); + if (PMIX_SUCCESS != ret) { + /* component does not exist in the repository */ + return NULL; + } + + PMIX_LIST_FOREACH(ri, component_list, pmix_mca_base_component_repository_item_t) { + if (0 == strcmp (ri->ri_name, name)) { + return ri; + } + } + + return NULL; +} +#endif + +void pmix_mca_base_component_repository_release(const pmix_mca_base_component_t *component) +{ +#if PMIX_HAVE_PDL_SUPPORT + pmix_mca_base_component_repository_item_t *ri; + + ri = find_component (component->pmix_mca_type_name, component->pmix_mca_component_name); + if (NULL != ri && !(--ri->ri_refcnt)) { + pmix_mca_base_component_repository_release_internal (ri); + } +#endif +} + +int pmix_mca_base_component_repository_retain_component(const char *type, const char *name) +{ +#if PMIX_HAVE_PDL_SUPPORT + pmix_mca_base_component_repository_item_t *ri = find_component(type, name); + + if (NULL != ri) { + ++ri->ri_refcnt; + return PMIX_SUCCESS; + } + + return PMIX_ERR_NOT_FOUND; +#else + return PMIX_ERR_NOT_SUPPORTED; +#endif +} + +int pmix_mca_base_component_repository_open(pmix_mca_base_framework_t *framework, + pmix_mca_base_component_repository_item_t *ri) +{ +#if PMIX_HAVE_PDL_SUPPORT + pmix_mca_base_component_t *component_struct; + pmix_mca_base_component_list_item_t *mitem = NULL; + char *struct_name = NULL; + int vl, ret; + + pmix_output_verbose(PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix_mca_base_component_repository_open: examining dynamic " + "%s MCA component \"%s\" at path %s", ri->ri_type, ri->ri_name, ri->ri_path); + + vl = pmix_mca_base_component_show_load_errors ? PMIX_MCA_BASE_VERBOSE_ERROR : PMIX_MCA_BASE_VERBOSE_INFO; + + /* Ensure that this component is not already loaded (should only happen + if it was statically loaded). It's an error if it's already + loaded because we're evaluating this file -- not this component. + Hence, returning PMIX_ERR_PARAM indicates that the *file* failed + to load, not the component. */ + + PMIX_LIST_FOREACH(mitem, &framework->framework_components, pmix_mca_base_component_list_item_t) { + if (0 == strcmp(mitem->cli_component->pmix_mca_component_name, ri->ri_name)) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix_mca_base_component_repository_open: already loaded (ignored)"); + return PMIX_ERR_BAD_PARAM; + } + } + + /* silence coverity issue (invalid free) */ + mitem = NULL; + + if (NULL != ri->ri_dlhandle) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix_mca_base_component_repository_open: already loaded. returning cached component"); + mitem = PMIX_NEW(pmix_mca_base_component_list_item_t); + if (NULL == mitem) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + mitem->cli_component = ri->ri_component_struct; + pmix_list_append (&framework->framework_components, &mitem->super); + + return PMIX_SUCCESS; + } + + if (0 != strcmp (ri->ri_type, framework->framework_name)) { + /* shouldn't happen. attempting to open a component belonging to + * another framework. if this happens it is likely a MCA base + * bug so assert */ + assert (0); + return PMIX_ERR_NOT_SUPPORTED; + } + + /* Now try to load the component */ + + char *err_msg = NULL; + if (PMIX_SUCCESS != pmix_pdl_open(ri->ri_path, true, false, &ri->ri_dlhandle, &err_msg)) { + if (NULL == err_msg) { + err_msg = "pmix_dl_open() error message was NULL!"; + } + /* Because libltdl erroneously says "file not found" for any + type of error -- which is especially misleading when the file + is actually there but cannot be opened for some other reason + (e.g., missing symbol) -- do some simple huersitics and if + the file [probably] does exist, print a slightly better error + message. */ + if (0 == strcasecmp("file not found", err_msg) && + (file_exists(ri->ri_path, "lo") || + file_exists(ri->ri_path, "so") || + file_exists(ri->ri_path, "dylib") || + file_exists(ri->ri_path, "dll"))) { + err_msg = "perhaps a missing symbol, or compiled for a different version of Open MPI?"; + } + pmix_output_verbose(vl, 0, "pmix_mca_base_component_repository_open: unable to open %s: %s (ignored)", + ri->ri_base, err_msg); + return PMIX_ERR_BAD_PARAM; + } + + /* Successfully opened the component; now find the public struct. + Malloc out enough space for it. */ + + do { + ret = asprintf (&struct_name, "mca_%s_%s_component", ri->ri_type, ri->ri_name); + if (0 > ret) { + ret = PMIX_ERR_OUT_OF_RESOURCE; + break; + } + + mitem = PMIX_NEW(pmix_mca_base_component_list_item_t); + if (NULL == mitem) { + ret = PMIX_ERR_OUT_OF_RESOURCE; + break; + } + + err_msg = NULL; + ret = pmix_pdl_lookup(ri->ri_dlhandle, struct_name, (void**) &component_struct, &err_msg); + if (PMIX_SUCCESS != ret || NULL == component_struct) { + if (NULL == err_msg) { + err_msg = "pmix_dl_loookup() error message was NULL!"; + } + pmix_output_verbose(vl, 0, "pmix_mca_base_component_repository_open: \"%s\" does not appear to be a valid " + "%s MCA dynamic component (ignored): %s. ret %d", ri->ri_base, ri->ri_type, err_msg, ret); + + ret = PMIX_ERR_BAD_PARAM; + break; + } + + /* done with the structure name */ + free (struct_name); + struct_name = NULL; + + /* We found the public struct. Make sure its MCA major.minor + version is the same as ours. TODO -- add checks for project version (from framework) */ + if (!(PMIX_MCA_BASE_VERSION_MAJOR == component_struct->pmix_mca_major_version && + PMIX_MCA_BASE_VERSION_MINOR == component_struct->pmix_mca_minor_version)) { + pmix_output_verbose(vl, 0, "pmix_mca_base_component_repository_open: %s \"%s\" uses an MCA interface that is " + "not recognized (component MCA v%d.%d.%d != supported MCA v%d.%d.%d) -- ignored", + ri->ri_type, ri->ri_path, component_struct->pmix_mca_major_version, + component_struct->pmix_mca_minor_version, component_struct->pmix_mca_release_version, + PMIX_MCA_BASE_VERSION_MAJOR, PMIX_MCA_BASE_VERSION_MINOR, PMIX_MCA_BASE_VERSION_RELEASE); + ret = PMIX_ERR_BAD_PARAM; + break; + } + + /* Also check that the component struct framework and component + names match the expected names from the filename */ + if (0 != strcmp(component_struct->pmix_mca_type_name, ri->ri_type) || + 0 != strcmp(component_struct->pmix_mca_component_name, ri->ri_name)) { + pmix_output_verbose(vl, 0, "Component file data does not match filename: %s (%s / %s) != %s %s -- ignored", + ri->ri_path, ri->ri_type, ri->ri_name, + component_struct->pmix_mca_type_name, + component_struct->pmix_mca_component_name); + ret = PMIX_ERR_BAD_PARAM; + break; + } + + /* Alles gut. Save the component struct, and register this + component to be closed later. */ + + ri->ri_component_struct = mitem->cli_component = component_struct; + ri->ri_refcnt = 1; + pmix_list_append(&framework->framework_components, &mitem->super); + + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix_mca_base_component_repository_open: opened dynamic %s MCA " + "component \"%s\"", ri->ri_type, ri->ri_name); + + return PMIX_SUCCESS; + } while (0); + + if (mitem) { + PMIX_RELEASE(mitem); + } + + if (struct_name) { + free (struct_name); + } + + pmix_pdl_close (ri->ri_dlhandle); + ri->ri_dlhandle = NULL; + + return ret; +#else + + /* no dlopen support */ + return PMIX_ERR_NOT_SUPPORTED; +#endif +} + +/* + * Finalize the repository -- close everything that's still open. + */ +void pmix_mca_base_component_repository_finalize(void) +{ + if (!initialized) { + return; + } + + initialized = false; + +#if PMIX_HAVE_PDL_SUPPORT + pmix_list_t *component_list; + void *node, *key; + size_t key_size; + int ret; + + ret = pmix_hash_table_get_first_key_ptr (&pmix_mca_base_component_repository, &key, &key_size, + (void **) &component_list, &node); + while (PMIX_SUCCESS == ret) { + PMIX_LIST_RELEASE(component_list); + ret = pmix_hash_table_get_next_key_ptr (&pmix_mca_base_component_repository, &key, + &key_size, (void **) &component_list, + node, &node); + } + + (void) pmix_mca_base_framework_close(&pmix_pdl_base_framework); + PMIX_DESTRUCT(&pmix_mca_base_component_repository); +#endif +} + +#if PMIX_HAVE_PDL_SUPPORT + +/* + * Basic sentinel values, and construct the inner list + */ +static void ri_constructor (pmix_mca_base_component_repository_item_t *ri) +{ + memset(ri->ri_type, 0, sizeof(ri->ri_type)); + ri->ri_dlhandle = NULL; + ri->ri_component_struct = NULL; + ri->ri_path = NULL; +} + + +/* + * Close a component + */ +static void ri_destructor (pmix_mca_base_component_repository_item_t *ri) +{ + /* dlclose the component if it is still open */ + pmix_mca_base_component_repository_release_internal (ri); + + /* It should be obvious, but I'll state it anyway because it bit me + during debugging: after the dlclose(), the pmix_mca_base_component_t + pointer is no longer valid because it has [potentially] been + unloaded from memory. So don't try to use it. :-) */ + + if (ri->ri_path) { + free (ri->ri_path); + } + + if (ri->ri_base) { + free (ri->ri_base); + } +} + +#endif /* PMIX_HAVE_PDL_SUPPORT */ 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 new file mode 100644 index 0000000000..8b29414aba --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_component_repository.h @@ -0,0 +1,133 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** + * @file pmix_mca_base_component_repository.h + * + * This file provide the external interface to our base component + * module. Most of the components that depend on it, will use the + * retain_component() function to increase the reference count on a + * particular component (as opposed to the retain() function, which is + * internal to the pmix/mca/base). But it's convenient to have all + * the functions exported from one header file rather than to separate + * retain_component() and retain() into two separate header files + * (i.e., have a separate header file just for retain()). + */ + +#ifndef MCA_BASE_COMPONENT_REPOSITORY_H +#define MCA_BASE_COMPONENT_REPOSITORY_H + +#include + +#include "src/mca/pdl/pdl.h" +#include "src/mca/pdl/base/base.h" + +BEGIN_C_DECLS +struct pmix_mca_base_component_repository_item_t { + pmix_list_item_t super; + + char ri_type[PMIX_MCA_BASE_MAX_TYPE_NAME_LEN + 1]; + char ri_name[PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN + 1]; + + char *ri_path; + char *ri_base; + + pmix_pdl_handle_t *ri_dlhandle; + const pmix_mca_base_component_t *ri_component_struct; + + int ri_refcnt; +}; +typedef struct pmix_mca_base_component_repository_item_t pmix_mca_base_component_repository_item_t; + +PMIX_CLASS_DECLARATION(pmix_mca_base_component_repository_item_t); + +/** + * @brief initialize the component repository + * + * This function must be called before any frameworks are registered or + * opened. It is responsible for setting up the repository of dynamically + * loaded components. The initial search path is taken from the + * pmix_mca_base_component_path MCA parameter. pmix_mca_base_open () is a + * prerequisite call as it registers the pmix_mca_base_component_path parameter. + */ +int pmix_mca_base_component_repository_init(void); + +/** + * @brief add search path for dynamically loaded components + * + * @param[in] path delimited list of search paths to add + */ +int pmix_mca_base_component_repository_add(const char *path); + + +/** + * @brief return the list of components that match a given framework + * + * @param[in] framework framework to match + * @param[out] framework_components components that match this framework + * + * The list returned in {framework_components} is owned by the component + * repository and CAN NOT be modified by the caller. + */ +int pmix_mca_base_component_repository_get_components(pmix_mca_base_framework_t *framework, + pmix_list_t **framework_components); + +/** + * @brief finalize the mca component repository + */ +void pmix_mca_base_component_repository_finalize(void); + +/** + * @brief open the repository item and add it to the framework's component + * list + * + * @param[in] framework framework that matches the component + * @param[in] ri dynamic component to open + */ +int pmix_mca_base_component_repository_open(pmix_mca_base_framework_t *framework, + pmix_mca_base_component_repository_item_t *ri); + + +/** + * @brief Reduce the reference count of a component and dlclose it if necessary + */ +void pmix_mca_base_component_repository_release(const pmix_mca_base_component_t *component); + +/** + * @brief Increase the reference count of a component + * + * Each component repository item starts with a reference count of 0. This ensures that + * when a framework closes it's components the repository items are all correctly + * dlclosed. This function can be used to prevent the dlclose if a component is needed + * after its framework has closed the associated component. Users of this function + * should call pmix_mca_base_component_repository_release() once they are finished with the + * component. + * + * @note all components are automatically unloaded by the + * pmix_mca_base_component_repository_finalize() call. + */ +int pmix_mca_base_component_repository_retain_component(const char *type, const char *name); + +END_C_DECLS + +#endif /* MCA_BASE_COMPONENT_REPOSITORY_H */ 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 new file mode 100644 index 0000000000..22d757a0ae --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_close.c @@ -0,0 +1,94 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2006 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-2006 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2006 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2013-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "src/class/pmix_list.h" +#include "src/util/output.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_component_repository.h" +#include "pmix_common.h" + +void pmix_mca_base_component_unload (const pmix_mca_base_component_t *component, int output_id) +{ + int ret; + + /* Unload */ + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca: base: close: unloading component %s", + component->pmix_mca_component_name); + + ret = pmix_mca_base_var_group_find (component->pmix_mca_project_name, component->pmix_mca_type_name, + component->pmix_mca_component_name); + if (0 <= ret) { + pmix_mca_base_var_group_deregister (ret); + } + + pmix_mca_base_component_repository_release (component); +} + +void pmix_mca_base_component_close (const pmix_mca_base_component_t *component, int output_id) +{ + /* Close */ + if (NULL != component->pmix_mca_close_component) { + component->pmix_mca_close_component(); + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca: base: close: component %s closed", + component->pmix_mca_component_name); + } + + pmix_mca_base_component_unload (component, output_id); +} + +int pmix_mca_base_framework_components_close (pmix_mca_base_framework_t *framework, + const pmix_mca_base_component_t *skip) +{ + return pmix_mca_base_components_close (framework->framework_output, + &framework->framework_components, + skip); +} + +int pmix_mca_base_components_close(int output_id, pmix_list_t *components, + const pmix_mca_base_component_t *skip) +{ + pmix_mca_base_component_list_item_t *cli, *next; + + /* Close and unload all components in the available list, except the + "skip" item. This is handy to close out all non-selected + components. It's easier to simply remove the entire list and + then simply re-add the skip entry when done. */ + + PMIX_LIST_FOREACH_SAFE(cli, next, components, pmix_mca_base_component_list_item_t) { + if (skip == cli->cli_component) { + continue; + } + + pmix_mca_base_component_close (cli->cli_component, output_id); + pmix_list_remove_item (components, &cli->super); + + PMIX_RELEASE(cli); + } + + /* All done */ + return PMIX_SUCCESS; +} 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 new file mode 100644 index 0000000000..5489ab5259 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_open.c @@ -0,0 +1,164 @@ +/* -*- 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-2013 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) 2008-2012 Cisco Systems, Inc. All rights reserved. + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#include + +#include "src/class/pmix_list.h" +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/util/output.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "pmix_common.h" + +/* + * Local functions + */ +static int open_components(pmix_mca_base_framework_t *framework); + +struct pmix_mca_base_dummy_framework_list_item_t { + pmix_list_item_t super; + pmix_mca_base_framework_t framework; +}; + +/** + * Function for finding and opening either all MCA components, or the + * one that was specifically requested via a MCA parameter. + */ +int pmix_mca_base_framework_components_open (pmix_mca_base_framework_t *framework, + pmix_mca_base_open_flag_t flags) +{ + /* Open flags are not used at this time. Suppress compiler warning. */ + if (flags & PMIX_MCA_BASE_OPEN_FIND_COMPONENTS) { + bool open_dso_components = !(flags & PMIX_MCA_BASE_OPEN_STATIC_ONLY); + /* Find and load requested components */ + int ret = pmix_mca_base_component_find(NULL, framework, false, open_dso_components); + if (PMIX_SUCCESS != ret) { + return ret; + } + } + + /* Open all registered components */ + return open_components (framework); +} + +/* + * Traverse the entire list of found components (a list of + * pmix_mca_base_component_t instances). If the requested_component_names + * array is empty, or the name of each component in the list of found + * components is in the requested_components_array, try to open it. + * If it opens, add it to the components_available list. + */ +static int open_components(pmix_mca_base_framework_t *framework) +{ + pmix_list_t *components = &framework->framework_components; + uint32_t open_only_flags = PMIX_MCA_BASE_METADATA_PARAM_NONE; + int output_id = framework->framework_output; + pmix_mca_base_component_list_item_t *cli, *next; + int ret; + + /* + * Pre-process the list with parameter constraints + * e.g., If requested to select only CR enabled components + * then only make available those components. + * + * JJH Note: Currently checkpoint/restart is the only user of this + * functionality. If other component constraint options are + * added, then this logic can be used for all contraint + * options. + * + * NTH: Logic moved to pmix_mca_base_components_filter. + */ + + /* If pmix_mca_base_framework_register_components was called with the MCA_BASE_COMPONENTS_ALL flag + we need to trim down and close any extra components we do not want open */ + ret = pmix_mca_base_components_filter (framework, open_only_flags); + if (PMIX_SUCCESS != ret) { + return ret; + } + + /* Announce */ + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca: base: components_open: opening %s components", + framework->framework_name); + + /* Traverse the list of components */ + PMIX_LIST_FOREACH_SAFE(cli, next, components, pmix_mca_base_component_list_item_t) { + const pmix_mca_base_component_t *component = cli->cli_component; + + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca: base: components_open: found loaded component %s", + component->pmix_mca_component_name); + + if (NULL != component->pmix_mca_open_component) { + /* Call open if register didn't call it already */ + ret = component->pmix_mca_open_component(); + + if (PMIX_SUCCESS == ret) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca: base: components_open: " + "component %s open function successful", + component->pmix_mca_component_name); + } else { + if (PMIX_ERR_NOT_AVAILABLE != ret) { + /* If the component returns PMIX_ERR_NOT_AVAILABLE, + it's a cue to "silently ignore me" -- it's not a + failure, it's just a way for the component to say + "nope!". + + Otherwise, however, display an error. We may end + up displaying this twice, but it may go to separate + streams. So better to be redundant than to not + display the error in the stream where it was + expected. */ + + if (pmix_mca_base_component_show_load_errors) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_ERROR, output_id, + "mca: base: components_open: component %s " + "/ %s open function failed", + component->pmix_mca_type_name, + component->pmix_mca_component_name); + } + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca: base: components_open: " + "component %s open function failed", + component->pmix_mca_component_name); + } + + pmix_mca_base_component_close (component, output_id); + + pmix_list_remove_item (components, &cli->super); + PMIX_RELEASE(cli); + } + } + } + + /* All done */ + + return PMIX_SUCCESS; +} 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 new file mode 100644 index 0000000000..fc53b411cd --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_register.c @@ -0,0 +1,163 @@ +/* -*- 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-2012 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#include + +#include "src/class/pmix_list.h" +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/util/output.h" +#include "src/util/show_help.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_framework.h" +#include "src/mca/base/pmix_mca_base_component_repository.h" +#include "pmix_common.h" + +/* + * Local functions + */ +static int register_components(pmix_mca_base_framework_t *framework); +/** + * Function for finding and opening either all MCA components, or the + * one that was specifically requested via a MCA parameter. + */ +int pmix_mca_base_framework_components_register (pmix_mca_base_framework_t *framework, + pmix_mca_base_register_flag_t flags) +{ + bool open_dso_components = !(flags & PMIX_MCA_BASE_REGISTER_STATIC_ONLY); + bool ignore_requested = !!(flags & PMIX_MCA_BASE_REGISTER_ALL); + int ret; + + /* Find and load requested components */ + ret = pmix_mca_base_component_find(NULL, framework, ignore_requested, open_dso_components); + if (PMIX_SUCCESS != ret) { + return ret; + } + + /* Register all remaining components */ + return register_components(framework); +} + +/* + * Traverse the entire list of found components (a list of + * pmix_mca_base_component_t instances). If the requested_component_names + * array is empty, or the name of each component in the list of found + * components is in the requested_components_array, try to open it. + * If it opens, add it to the components_available list. + */ +static int register_components(pmix_mca_base_framework_t *framework) +{ + int ret; + pmix_mca_base_component_t *component; + pmix_mca_base_component_list_item_t *cli, *next; + int output_id = framework->framework_output; + + /* Announce */ + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "pmix:mca: base: components_register: registering framework %s components", + framework->framework_name); + + /* Traverse the list of found components */ + + PMIX_LIST_FOREACH_SAFE(cli, next, &framework->framework_components, pmix_mca_base_component_list_item_t) { + component = (pmix_mca_base_component_t *)cli->cli_component; + + pmix_output_verbose(PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "pmix:mca: base: components_register: found loaded component %s", + component->pmix_mca_component_name); + + /* Call the component's MCA parameter registration function (or open if register doesn't exist) */ + if (NULL == component->pmix_mca_register_component_params) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "pmix:mca: base: components_register: " + "component %s has no register or open function", + component->pmix_mca_component_name); + ret = PMIX_SUCCESS; + } else { + ret = component->pmix_mca_register_component_params(); + } + + if (PMIX_SUCCESS != ret) { + if (PMIX_ERR_NOT_AVAILABLE != ret) { + /* If the component returns PMIX_ERR_NOT_AVAILABLE, + it's a cue to "silently ignore me" -- it's not a + failure, it's just a way for the component to say + "nope!". + + Otherwise, however, display an error. We may end + up displaying this twice, but it may go to separate + streams. So better to be redundant than to not + display the error in the stream where it was + expected. */ + + if (pmix_mca_base_component_show_load_errors) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_ERROR, output_id, + "pmix:mca: base: components_register: component %s " + "/ %s register function failed", + component->pmix_mca_type_name, + component->pmix_mca_component_name); + } + + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "pmix:mca: base: components_register: " + "component %s register function failed", + component->pmix_mca_component_name); + } + + pmix_list_remove_item (&framework->framework_components, &cli->super); + + /* Release this list item */ + PMIX_RELEASE(cli); + continue; + } + + if (NULL != component->pmix_mca_register_component_params) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, "pmix:mca: base: components_register: " + "component %s register function successful", + component->pmix_mca_component_name); + } + + /* Register this component's version */ + pmix_mca_base_component_var_register (component, "major_version", NULL, PMIX_MCA_BASE_VAR_TYPE_INT, NULL, + 0, PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY | PMIX_MCA_BASE_VAR_FLAG_INTERNAL, + PMIX_INFO_LVL_9, PMIX_MCA_BASE_VAR_SCOPE_CONSTANT, + &component->pmix_mca_component_major_version); + pmix_mca_base_component_var_register (component, "minor_version", NULL, PMIX_MCA_BASE_VAR_TYPE_INT, NULL, + 0, PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY | PMIX_MCA_BASE_VAR_FLAG_INTERNAL, + PMIX_INFO_LVL_9, PMIX_MCA_BASE_VAR_SCOPE_CONSTANT, + &component->pmix_mca_component_minor_version); + pmix_mca_base_component_var_register (component, "release_version", NULL, PMIX_MCA_BASE_VAR_TYPE_INT, NULL, + 0, PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY | PMIX_MCA_BASE_VAR_FLAG_INTERNAL, + PMIX_INFO_LVL_9, PMIX_MCA_BASE_VAR_SCOPE_CONSTANT, + &component->pmix_mca_component_release_version); + } + + /* All done */ + + return PMIX_SUCCESS; +} 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 new file mode 100644 index 0000000000..b039bf66c2 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_components_select.c @@ -0,0 +1,147 @@ +/* -*- 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) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#include "src/class/pmix_list.h" +#include "src/util/error.h" +#include "src/util/output.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_component_repository.h" +#include "pmix_common.h" + + +int pmix_mca_base_select(const char *type_name, int output_id, + pmix_list_t *components_available, + pmix_mca_base_module_t **best_module, + pmix_mca_base_component_t **best_component, + int *priority_out) +{ + pmix_mca_base_component_list_item_t *cli = NULL; + pmix_mca_base_component_t *component = NULL; + pmix_mca_base_module_t *module = NULL; + int priority = 0, best_priority = INT32_MIN; + int rc; + + *best_module = NULL; + *best_component = NULL; + + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca:base:select: Auto-selecting %s components", + type_name); + + /* + * Traverse the list of available components. + * For each call their 'query' functions to determine relative priority. + */ + PMIX_LIST_FOREACH(cli, components_available, pmix_mca_base_component_list_item_t) { + component = (pmix_mca_base_component_t *) cli->cli_component; + + /* + * If there is a query function then use it. + */ + if (NULL == component->pmix_mca_query_component) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca:base:select:(%5s) Skipping component [%s]. It does not implement a query function", + type_name, component->pmix_mca_component_name ); + continue; + } + + /* + * Query this component for the module and priority + */ + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca:base:select:(%5s) Querying component [%s]", + type_name, component->pmix_mca_component_name); + + rc = component->pmix_mca_query_component(&module, &priority); + if (PMIX_ERR_FATAL == rc) { + /* a fatal error was detected by this component - e.g., the + * user specified a required element and the component could + * not find it. In this case, we must not continue as we might + * find some other component that could run, causing us to do + * something the user didn't want */ + return rc; + } else if (PMIX_SUCCESS != rc) { + /* silently skip this component */ + continue; + } + + /* + * If no module was returned, then skip component + */ + if (NULL == module) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca:base:select:(%5s) Skipping component [%s]. Query failed to return a module", + type_name, component->pmix_mca_component_name ); + continue; + } + + /* + * Determine if this is the best module we have seen by looking the priority + */ + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca:base:select:(%5s) Query of component [%s] set priority to %d", + type_name, component->pmix_mca_component_name, priority); + if (priority > best_priority) { + best_priority = priority; + *best_component = component; + *best_module = module; + } + } + + if (priority_out) { + *priority_out = best_priority; + } + + /* + * Finished querying all components. + * Make sure we found something in the process. + */ + if (NULL == *best_component) { + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca:base:select:(%5s) No component selected!", + type_name); + /* + * Still close the non-selected components + */ + pmix_mca_base_components_close(0, /* Pass 0 to keep this from closing the output handle */ + components_available, + NULL); + return PMIX_ERR_NOT_FOUND; + } + + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, + "mca:base:select:(%5s) Selected component [%s]", + type_name, (*best_component)->pmix_mca_component_name); + + /* + * Close the non-selected components + */ + pmix_mca_base_components_close(output_id, + components_available, + (pmix_mca_base_component_t *) (*best_component)); + + + return PMIX_SUCCESS; +} 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 new file mode 100644 index 0000000000..3e0ddfa57e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.c @@ -0,0 +1,242 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "pmix_common.h" +#include "src/util/output.h" + +#include "pmix_mca_base_framework.h" +#include "pmix_mca_base_var.h" +#include "src/mca/base/base.h" + +bool pmix_mca_base_framework_is_registered (struct pmix_mca_base_framework_t *framework) +{ + return !!(framework->framework_flags & PMIX_MCA_BASE_FRAMEWORK_FLAG_REGISTERED); +} + +bool pmix_mca_base_framework_is_open (struct pmix_mca_base_framework_t *framework) +{ + return !!(framework->framework_flags & PMIX_MCA_BASE_FRAMEWORK_FLAG_OPEN); +} + +static void framework_open_output (struct pmix_mca_base_framework_t *framework) +{ + if (0 < framework->framework_verbose) { + if (-1 == framework->framework_output) { + framework->framework_output = pmix_output_open (NULL); + } + pmix_output_set_verbosity(framework->framework_output, + framework->framework_verbose); + } else if (-1 != framework->framework_output) { + pmix_output_close (framework->framework_output); + framework->framework_output = -1; + } +} + +static void framework_close_output (struct pmix_mca_base_framework_t *framework) +{ + if (-1 != framework->framework_output) { + pmix_output_close (framework->framework_output); + framework->framework_output = -1; + } +} + +int pmix_mca_base_framework_register (struct pmix_mca_base_framework_t *framework, + pmix_mca_base_register_flag_t flags) +{ + char *desc; + int ret; + + assert (NULL != framework); + + framework->framework_refcnt++; + + if (pmix_mca_base_framework_is_registered (framework)) { + return PMIX_SUCCESS; + } + + PMIX_CONSTRUCT(&framework->framework_components, pmix_list_t); + + if (framework->framework_flags & PMIX_MCA_BASE_FRAMEWORK_FLAG_NO_DSO) { + flags |= PMIX_MCA_BASE_REGISTER_STATIC_ONLY; + } + + if (!(PMIX_MCA_BASE_FRAMEWORK_FLAG_NOREGISTER & framework->framework_flags)) { + /* register this framework with the MCA variable system */ + ret = pmix_mca_base_var_group_register (framework->framework_project, + framework->framework_name, + NULL, framework->framework_description); + if (0 > ret) { + return ret; + } + + asprintf (&desc, "Default selection set of components for the %s framework (" + " means use all components that can be found)", framework->framework_name); + ret = pmix_mca_base_var_register (framework->framework_project, framework->framework_name, + NULL, NULL, desc, PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, + PMIX_MCA_BASE_VAR_FLAG_SETTABLE, PMIX_INFO_LVL_2, + PMIX_MCA_BASE_VAR_SCOPE_ALL_EQ, &framework->framework_selection); + free (desc); + if (0 > ret) { + return ret; + } + + /* register a verbosity variable for this framework */ + ret = asprintf (&desc, "Verbosity level for the %s framework (default: 0)", + framework->framework_name); + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + framework->framework_verbose = PMIX_MCA_BASE_VERBOSE_ERROR; + ret = pmix_mca_base_framework_var_register (framework, "verbose", desc, + PMIX_MCA_BASE_VAR_TYPE_INT, + &pmix_mca_base_var_enum_verbose, 0, + PMIX_MCA_BASE_VAR_FLAG_SETTABLE, + PMIX_INFO_LVL_8, + PMIX_MCA_BASE_VAR_SCOPE_LOCAL, + &framework->framework_verbose); + free(desc); + if (0 > ret) { + return ret; + } + + /* check the initial verbosity and open the output if necessary. we + will recheck this on open */ + framework_open_output (framework); + + /* register framework variables */ + if (NULL != framework->framework_register) { + ret = framework->framework_register (flags); + if (PMIX_SUCCESS != ret) { + return ret; + } + } + + /* register components variables */ + ret = pmix_mca_base_framework_components_register (framework, flags); + if (PMIX_SUCCESS != ret) { + return ret; + } + } + + framework->framework_flags |= PMIX_MCA_BASE_FRAMEWORK_FLAG_REGISTERED; + + /* framework did not provide a register function */ + return PMIX_SUCCESS; +} + +int pmix_mca_base_framework_open (struct pmix_mca_base_framework_t *framework, + pmix_mca_base_open_flag_t flags) { + int ret; + + assert (NULL != framework); + + /* register this framework before opening it */ + ret = pmix_mca_base_framework_register (framework, PMIX_MCA_BASE_REGISTER_DEFAULT); + if (PMIX_SUCCESS != ret) { + return ret; + } + + /* check if this framework is already open */ + if (pmix_mca_base_framework_is_open (framework)) { + return PMIX_SUCCESS; + } + + if (PMIX_MCA_BASE_FRAMEWORK_FLAG_NOREGISTER & framework->framework_flags) { + flags |= PMIX_MCA_BASE_OPEN_FIND_COMPONENTS; + + if (PMIX_MCA_BASE_FRAMEWORK_FLAG_NO_DSO & framework->framework_flags) { + flags |= PMIX_MCA_BASE_OPEN_STATIC_ONLY; + } + } + + /* lock all of this frameworks's variables */ + ret = pmix_mca_base_var_group_find (framework->framework_project, + framework->framework_name, + NULL); + pmix_mca_base_var_group_set_var_flag (ret, PMIX_MCA_BASE_VAR_FLAG_SETTABLE, false); + + /* check the verbosity level and open (or close) the output */ + framework_open_output (framework); + + if (NULL != framework->framework_open) { + ret = framework->framework_open (flags); + } else { + ret = pmix_mca_base_framework_components_open (framework, flags); + } + + if (PMIX_SUCCESS != ret) { + framework->framework_refcnt--; + } else { + framework->framework_flags |= PMIX_MCA_BASE_FRAMEWORK_FLAG_OPEN; + } + + return ret; +} + +int pmix_mca_base_framework_close (struct pmix_mca_base_framework_t *framework) { + bool is_open = pmix_mca_base_framework_is_open (framework); + bool is_registered = pmix_mca_base_framework_is_registered (framework); + int ret, group_id; + + assert (NULL != framework); + + if (!(is_open || is_registered)) { + return PMIX_SUCCESS; + } + + assert (framework->framework_refcnt); + if (--framework->framework_refcnt) { + return PMIX_SUCCESS; + } + + /* find and deregister all component groups and variables */ + group_id = pmix_mca_base_var_group_find (framework->framework_project, + framework->framework_name, NULL); + if (0 <= group_id) { + (void) pmix_mca_base_var_group_deregister (group_id); + } + + /* close the framework and all of its components */ + if (is_open) { + if (NULL != framework->framework_close) { + ret = framework->framework_close (); + } else { + ret = pmix_mca_base_framework_components_close (framework, NULL); + } + + if (PMIX_SUCCESS != ret) { + return ret; + } + } else { + pmix_list_item_t *item; + while (NULL != (item = pmix_list_remove_first (&framework->framework_components))) { + pmix_mca_base_component_list_item_t *cli; + cli = (pmix_mca_base_component_list_item_t*) item; + pmix_mca_base_component_unload(cli->cli_component, + framework->framework_output); + PMIX_RELEASE(item); + } + ret = PMIX_SUCCESS; + } + + framework->framework_flags &= ~(PMIX_MCA_BASE_FRAMEWORK_FLAG_REGISTERED | PMIX_MCA_BASE_FRAMEWORK_FLAG_OPEN); + + PMIX_DESTRUCT(&framework->framework_components); + + framework_close_output (framework); + + return ret; +} 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 new file mode 100644 index 0000000000..d62c589f40 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_framework.h @@ -0,0 +1,244 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2012-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#if !defined(PMIX_MCA_BASE_FRAMEWORK_H) +#define PMIX_MCA_BASE_FRAMEWORK_H +#include + +#include "src/mca/mca.h" +#include "src/class/pmix_list.h" + +/* + * Register and open flags + */ +enum pmix_mca_base_register_flag_t { + PMIX_MCA_BASE_REGISTER_DEFAULT = 0, + /** Register all components (ignore selection MCA variables) */ + PMIX_MCA_BASE_REGISTER_ALL = 1, + /** Do not register DSO components */ + PMIX_MCA_BASE_REGISTER_STATIC_ONLY = 2 +}; + +typedef enum pmix_mca_base_register_flag_t pmix_mca_base_register_flag_t; + +enum pmix_mca_base_open_flag_t { + PMIX_MCA_BASE_OPEN_DEFAULT = 0, + /** Find components in pmix_mca_base_components_find. Used by + pmix_mca_base_framework_open() when NOREGISTER is specified + by the framework */ + PMIX_MCA_BASE_OPEN_FIND_COMPONENTS = 1, + /** Do not open DSO components */ + PMIX_MCA_BASE_OPEN_STATIC_ONLY = 2, +}; + +typedef enum pmix_mca_base_open_flag_t pmix_mca_base_open_flag_t; + + +/** + * Register the MCA framework parameters + * + * @param[in] flags Registration flags (see mca/base/base.h) + * + * @retval PMIX_SUCCESS on success + * @retval pmix error code on failure + * + * This function registers all framework MCA parameters. This + * function should not call pmix_mca_base_framework_components_register(). + * + * Frameworks are NOT required to provide this function. It + * may be NULL. + */ +typedef int (*pmix_mca_base_framework_register_params_fn_t) (pmix_mca_base_register_flag_t flags); + +/** + * Initialize the MCA framework + * + * @retval PMIX_SUCCESS Upon success + * @retval PMIX_ERROR Upon failure + * + * This must be the first function invoked in the MCA framework. + * It initializes the MCA framework, finds and opens components, + * populates the components list, etc. + * + * This function is invoked during pmix_init() and during the + * initialization of the special case of the ompi_info command. + * + * This function fills in the components framework value, which + * is a list of all components that were successfully opened. + * This variable should \em only be used by other framework base + * functions or by ompi_info -- it is not considered a public + * interface member -- and is only mentioned here for completeness. + * + * Any resources allocated by this function must be freed + * in the framework close function. + * + * Frameworks are NOT required to provide this function. It may + * be NULL. If a framework does not provide an open function the + * default behavior of pmix_mca_base_framework_open() is to call + * pmix_mca_base_framework_components_open(). If a framework provides + * an open function it will need to call pmix_mca_base_framework_components_open() + * if it needs to open any components. + */ +typedef int (*pmix_mca_base_framework_open_fn_t) (pmix_mca_base_open_flag_t flags); + +/** + * Shut down the MCA framework. + * + * @retval PMIX_SUCCESS Always + * + * This function should shut downs everything in the MCA + * framework, and is called during pmix_finalize() and the + * special case of the ompi_info command. + * + * It must be the last function invoked on the MCA framework. + * + * Frameworks are NOT required to provide this function. It may + * be NULL. If a framework does not provide a close function the + * default behavior of pmix_mca_base_framework_close() is to call + * pmix_mca_base_framework_components_close(). If a framework provide + * a close function it will need to call pmix_mca_base_framework_components_close() + * if any components were opened. + */ +typedef int (*pmix_mca_base_framework_close_fn_t) (void); + +typedef enum { + PMIX_MCA_BASE_FRAMEWORK_FLAG_DEFAULT = 0, + /** Don't register any variables for this framework */ + PMIX_MCA_BASE_FRAMEWORK_FLAG_NOREGISTER = 1, + /** Internal. Don't set outside pmix_mca_base_framework.h */ + PMIX_MCA_BASE_FRAMEWORK_FLAG_REGISTERED = 2, + /** Framework does not have any DSO components */ + PMIX_MCA_BASE_FRAMEWORK_FLAG_NO_DSO = 4, + /** Internal. Don't set outside pmix_mca_base_framework.h */ + PMIX_MCA_BASE_FRAMEWORK_FLAG_OPEN = 8, + /** + * The upper 16 bits are reserved for project specific flags. + */ +} pmix_mca_base_framework_flags_t; + +typedef struct pmix_mca_base_framework_t { + /** Project name for this component (ex "pmix") */ + char *framework_project; + /** Framework name */ + char *framework_name; + /** Description of this framework or NULL */ + const char *framework_description; + /** Framework register function or NULL if the framework + and all its components have nothing to register */ + pmix_mca_base_framework_register_params_fn_t framework_register; + /** Framework open function or NULL */ + pmix_mca_base_framework_open_fn_t framework_open; + /** Framework close function or NULL */ + pmix_mca_base_framework_close_fn_t framework_close; + /** Framework flags (future use) set to 0 */ + pmix_mca_base_framework_flags_t framework_flags; + /** Framework open count */ + int framework_refcnt; + /** List of static components */ + const pmix_mca_base_component_t **framework_static_components; + /** Component selection. This will be registered with the MCA + variable system and should be either NULL (all components) or + a heap allocated, comma-delimited list of components. */ + char *framework_selection; + /** Verbosity level (0-100) */ + int framework_verbose; + /** Pmix output for this framework (or -1) */ + int framework_output; + /** List of selected components (filled in by pmix_mca_base_framework_register() + or pmix_mca_base_framework_open() */ + pmix_list_t framework_components; +} pmix_mca_base_framework_t; + + +/** + * Register a framework with MCA. + * + * @param[in] framework framework to register + * + * @retval PMIX_SUCCESS Upon success + * @retval PMIX_ERROR Upon failure + * + * Call a framework's register function. + */ +int pmix_mca_base_framework_register (pmix_mca_base_framework_t *framework, + pmix_mca_base_register_flag_t flags); + +/** + * Open a framework + * + * @param[in] framework framework to open + * + * @retval PMIX_SUCCESS Upon success + * @retval PMIX_ERROR Upon failure + * + * Call a framework's open function. + */ +int pmix_mca_base_framework_open (pmix_mca_base_framework_t *framework, + pmix_mca_base_open_flag_t flags); + +/** + * Close a framework + * + * @param[in] framework framework to close + * + * @retval PMIX_SUCCESS Upon success + * @retval PMIX_ERROR Upon failure + * + * Call a framework's close function. + */ +int pmix_mca_base_framework_close (pmix_mca_base_framework_t *framework); + + +/** + * Check if a framework is already registered + * + * @param[in] framework framework to query + * + * @retval true if the framework's mca variables are registered + * @retval false if not + */ +bool pmix_mca_base_framework_is_registered (struct pmix_mca_base_framework_t *framework); + + +/** + * Check if a framework is already open + * + * @param[in] framework framework to query + * + * @retval true if the framework is open + * @retval false if not + */ +bool pmix_mca_base_framework_is_open (struct pmix_mca_base_framework_t *framework); + + +/** + * Macro to declare an MCA framework + * + * Example: + * PMIX_MCA_BASE_FRAMEWORK_DECLARE(pmix, foo, NULL, pmix_foo_open, pmix_foo_close, MCA_BASE_FRAMEWORK_FLAG_LAZY) + */ +#define PMIX_MCA_BASE_FRAMEWORK_DECLARE(project, name, description, registerfn, openfn, closefn, static_components, flags) \ + pmix_mca_base_framework_t project##_##name##_base_framework = { \ + .framework_project = #project, \ + .framework_name = #name, \ + .framework_description = description, \ + .framework_register = registerfn, \ + .framework_open = openfn, \ + .framework_close = closefn, \ + .framework_flags = flags, \ + .framework_refcnt = 0, \ + .framework_static_components = static_components, \ + .framework_selection = NULL, \ + .framework_verbose = 0, \ + .framework_output = -1} + +#endif /* PMIX_MCA_BASE_FRAMEWORK_H */ 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 new file mode 100644 index 0000000000..1d5f8b6fcd --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_list.c @@ -0,0 +1,65 @@ +/* + * 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) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "src/class/pmix_list.h" +#include "src/mca/base/base.h" + + +/* + * Local functions + */ +static void cl_constructor(pmix_object_t *obj); +static void cpl_constructor(pmix_object_t *obj); + + +/* + * Class instance of the pmix_mca_base_component_list_item_t class + */ +PMIX_CLASS_INSTANCE(pmix_mca_base_component_list_item_t, + pmix_list_item_t, cl_constructor, NULL); + + +/* + * Class instance of the pmix_mca_base_component_priority_list_item_t class + */ +PMIX_CLASS_INSTANCE(pmix_mca_base_component_priority_list_item_t, + pmix_mca_base_component_list_item_t, cpl_constructor, NULL); + + +/* + * Just do basic sentinel intialization + */ +static void cl_constructor(pmix_object_t *obj) +{ + pmix_mca_base_component_list_item_t *cli = (pmix_mca_base_component_list_item_t *) obj; + cli->cli_component = NULL; +} + + +/* + * Just do basic sentinel intialization + */ +static void cpl_constructor(pmix_object_t *obj) +{ + pmix_mca_base_component_priority_list_item_t *cpli = + (pmix_mca_base_component_priority_list_item_t *) obj; + cpli->cpli_priority = -1; +} 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 new file mode 100644 index 0000000000..72b387ce1f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_open.c @@ -0,0 +1,253 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2008 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 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#ifdef HAVE_SYSLOG_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/mca/pinstalldirs/pinstalldirs.h" +#include "src/util/output.h" +#include "src/util/printf.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_component_repository.h" +#include "pmix_common.h" +#include "src/util/pmix_environ.h" + +/* + * Public variables + */ +char *pmix_mca_base_component_path = NULL; +int pmix_mca_base_opened = 0; +char *pmix_mca_base_system_default_path = NULL; +char *pmix_mca_base_user_default_path = NULL; +bool pmix_mca_base_component_show_load_errors = true; +bool pmix_mca_base_component_disable_dlopen = false; + +static char *pmix_mca_base_verbose = NULL; + +/* + * Private functions + */ +static void set_defaults(pmix_output_stream_t *lds); +static void parse_verbose(char *e, pmix_output_stream_t *lds); + + +/* + * Main MCA initialization. + */ +int pmix_mca_base_open(void) +{ + char *value; + pmix_output_stream_t lds; + char hostname[64]; + int var_id; + + if (pmix_mca_base_opened++) { + return PMIX_SUCCESS; + } + + /* define the system and user default paths */ +#if PMIX_WANT_HOME_CONFIG_FILES + pmix_mca_base_system_default_path = strdup(pmix_pinstall_dirs.pmixlibdir); + asprintf(&pmix_mca_base_user_default_path, "%s"PMIX_PATH_SEP".pmix"PMIX_PATH_SEP"components", pmix_home_directory()); +#else + asprintf(&pmix_mca_base_system_default_path, "%s", pmix_pinstall_dirs.pmixlibdir); +#endif + + /* see if the user wants to override the defaults */ + if (NULL == pmix_mca_base_user_default_path) { + value = strdup(pmix_mca_base_system_default_path); + } else { + asprintf(&value, "%s%c%s", pmix_mca_base_system_default_path, + PMIX_ENV_SEP, pmix_mca_base_user_default_path); + } + + pmix_mca_base_component_path = value; + var_id = pmix_mca_base_var_register("pmix", "mca", "base", "component_path", + "Path where to look for additional components", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + PMIX_INFO_LVL_9, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, + &pmix_mca_base_component_path); + (void) pmix_mca_base_var_register_synonym(var_id, "pmix", "mca", NULL, "component_path", + PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED); + free(value); + + pmix_mca_base_component_show_load_errors = true; + var_id = pmix_mca_base_var_register("pmix", "mca", "base", "component_show_load_errors", + "Whether to show errors for components that failed to load or not", + PMIX_MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, + PMIX_INFO_LVL_9, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, + &pmix_mca_base_component_show_load_errors); + (void) pmix_mca_base_var_register_synonym(var_id, "pmix", "mca", NULL, "component_show_load_errors", + PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED); + + pmix_mca_base_component_disable_dlopen = false; + var_id = pmix_mca_base_var_register("pmix", "mca", "base", "component_disable_dlopen", + "Whether to attempt to disable opening dynamic components or not", + PMIX_MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, + PMIX_INFO_LVL_9, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, + &pmix_mca_base_component_disable_dlopen); + (void) pmix_mca_base_var_register_synonym(var_id, "pmix", "mca", NULL, "component_disable_dlopen", + PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED); + + /* What verbosity level do we want for the default 0 stream? */ + pmix_mca_base_verbose = "stderr"; + var_id = pmix_mca_base_var_register("pmix", "mca", "base", "verbose", + "Specifies where the default error output stream goes (this is separate from distinct help messages). Accepts a comma-delimited list of: stderr, stdout, syslog, syslogpri:, syslogid: (where str is the prefix string for all syslog notices), file[:filename] (if filename is not specified, a default filename is used), fileappend (if not specified, the file is opened for truncation), level[:N] (if specified, integer verbose level; otherwise, 0 is implied)", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + PMIX_INFO_LVL_9, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, + &pmix_mca_base_verbose); + (void) pmix_mca_base_var_register_synonym(var_id, "pmix", "mca", NULL, "verbose", + PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED); + + memset(&lds, 0, sizeof(lds)); + if (NULL != pmix_mca_base_verbose) { + parse_verbose(pmix_mca_base_verbose, &lds); + } else { + set_defaults(&lds); + } + gethostname(hostname, 64); + asprintf(&lds.lds_prefix, "[%s:%05d] ", hostname, getpid()); + pmix_output_reopen(0, &lds); + pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, 0, + "mca: base: opening components at %s", pmix_mca_base_component_path); + free(lds.lds_prefix); + + /* Open up the component repository */ + + return pmix_mca_base_component_repository_init(); +} + + +/* + * Set sane default values for the lds + */ +static void set_defaults(pmix_output_stream_t *lds) +{ + + /* Load up defaults */ + + PMIX_CONSTRUCT(lds, pmix_output_stream_t); + lds->lds_syslog_priority = LOG_INFO; + lds->lds_syslog_ident = "ompi"; + lds->lds_want_stderr = true; +} + + +/* + * Parse the value of an environment variable describing verbosity + */ +static void parse_verbose(char *e, pmix_output_stream_t *lds) +{ + char *edup; + char *ptr, *next; + bool have_output = false; + + if (NULL == e) { + return; + } + + edup = strdup(e); + ptr = edup; + + /* Now parse the environment variable */ + + while (NULL != ptr && strlen(ptr) > 0) { + next = strchr(ptr, ','); + if (NULL != next) { + *next = '\0'; + } + + if (0 == strcasecmp(ptr, "syslog")) { + lds->lds_want_syslog = true; + have_output = true; + } + else if (strncasecmp(ptr, "syslogpri:", 10) == 0) { + lds->lds_want_syslog = true; + have_output = true; + if (strcasecmp(ptr + 10, "notice") == 0) + lds->lds_syslog_priority = LOG_NOTICE; + else if (strcasecmp(ptr + 10, "INFO") == 0) + lds->lds_syslog_priority = LOG_INFO; + else if (strcasecmp(ptr + 10, "DEBUG") == 0) + lds->lds_syslog_priority = LOG_DEBUG; + } else if (strncasecmp(ptr, "syslogid:", 9) == 0) { + lds->lds_want_syslog = true; + lds->lds_syslog_ident = ptr + 9; + } + + else if (strcasecmp(ptr, "stdout") == 0) { + lds->lds_want_stdout = true; + have_output = true; + } else if (strcasecmp(ptr, "stderr") == 0) { + lds->lds_want_stderr = true; + have_output = true; + } + + else if (strcasecmp(ptr, "file") == 0) { + lds->lds_want_file = true; + have_output = true; + } else if (strncasecmp(ptr, "file:", 5) == 0) { + lds->lds_want_file = true; + lds->lds_file_suffix = ptr + 5; + have_output = true; + } else if (strcasecmp(ptr, "fileappend") == 0) { + lds->lds_want_file = true; + lds->lds_want_file_append = 1; + have_output = true; + } + + else if (strncasecmp(ptr, "level", 5) == 0) { + lds->lds_verbose_level = 0; + if (ptr[5] == PMIX_ENV_SEP) + lds->lds_verbose_level = atoi(ptr + 6); + } + + if (NULL == next) { + break; + } + ptr = next + 1; + } + + /* If we didn't get an output, default to stderr */ + + if (!have_output) { + lds->lds_want_stderr = true; + } + + /* All done */ + + free(edup); +} 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 new file mode 100644 index 0000000000..12785f22d5 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_parse_paramfile.c @@ -0,0 +1,85 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 2013 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include + +#include "src/class/pmix_list.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_vari.h" +#include "src/util/keyval_parse.h" + +static void save_value(const char *name, const char *value); + +static char * file_being_read; +static pmix_list_t * _param_list; + +int pmix_mca_base_parse_paramfile(const char *paramfile, pmix_list_t *list) +{ + file_being_read = (char*)paramfile; + _param_list = list; + + return pmix_util_keyval_parse(paramfile, save_value); +} + +int pmix_mca_base_internal_env_store(void) +{ + return pmix_util_keyval_save_internal_envars(save_value); +} + +static void save_value(const char *name, const char *value) +{ + pmix_mca_base_var_file_value_t *fv; + bool found = false; + + /* First traverse through the list and ensure that we don't + already have a param of this name. If we do, just replace the + value. */ + + PMIX_LIST_FOREACH(fv, _param_list, pmix_mca_base_var_file_value_t) { + if (0 == strcmp(name, fv->mbvfv_var)) { + if (NULL != fv->mbvfv_value) { + free (fv->mbvfv_value); + } + found = true; + break; + } + } + + if (!found) { + /* We didn't already have the param, so append it to the list */ + fv = PMIX_NEW(pmix_mca_base_var_file_value_t); + if (NULL == fv) { + return; + } + + fv->mbvfv_var = strdup(name); + pmix_list_append(_param_list, &fv->super); + } + + fv->mbvfv_value = value ? strdup(value) : NULL; + fv->mbvfv_file = file_being_read; + fv->mbvfv_lineno = pmix_util_keyval_parse_lineno; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c new file mode 100644 index 0000000000..413c38999b --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c @@ -0,0 +1,2256 @@ +/* -*- 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-2012 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) 2008-2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2012-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2014-2016 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 +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#include + +#include "src/include/pmix_stdint.h" +#include "src/mca/pinstalldirs/pinstalldirs.h" +#include "src/util/os_path.h" +#include "src/util/path.h" +#include "src/util/show_help.h" +#include "src/util/printf.h" +#include "src/util/argv.h" +#include "src/util/error.h" +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_vari.h" +#include "pmix_common.h" +#include "src/util/output.h" +#include "src/util/pmix_environ.h" + +/* + * local variables + */ +static pmix_pointer_array_t pmix_mca_base_vars; +static const char *mca_prefix = "PMIX_MCA_"; +static char *home = NULL; +static char *cwd = NULL; +bool pmix_mca_base_var_initialized = false; +static char * force_agg_path = NULL; +static char *pmix_mca_base_var_files = NULL; +static char *pmix_mca_base_envar_files = NULL; +static char **pmix_mca_base_var_file_list = NULL; +static char *pmix_mca_base_var_override_file = NULL; +static char *pmix_mca_base_var_file_prefix = NULL; +static char *pmix_mca_base_envar_file_prefix = NULL; +static char *pmix_mca_base_param_file_path = NULL; +static char *pmix_mca_base_env_list = NULL; +#define PMIX_MCA_BASE_ENV_LIST_SEP_DEFAULT ";" +static char *pmix_mca_base_env_list_sep = PMIX_MCA_BASE_ENV_LIST_SEP_DEFAULT; +static char *pmix_mca_base_env_list_internal = NULL; +static bool pmix_mca_base_var_suppress_override_warning = false; +static pmix_list_t pmix_mca_base_var_file_values; +static pmix_list_t pmix_mca_base_envar_file_values; +static pmix_list_t pmix_mca_base_var_override_values; + +static int pmix_mca_base_var_count = 0; + +static pmix_hash_table_t pmix_mca_base_var_index_hash; + +const char *pmix_var_type_names[] = { + "int", + "unsigned_int", + "unsigned_long", + "unsigned_long_long", + "size_t", + "string", + "version_string", + "bool", + "double" +}; + +const size_t pmix_var_type_sizes[] = { + sizeof (int), + sizeof (unsigned), + sizeof (unsigned long), + sizeof (unsigned long long), + sizeof (size_t), + sizeof (char), + sizeof (char), + sizeof (bool), + sizeof (double) +}; + +const char *var_source_names[] = { + "default", + "command line", + "environment", + "file", + "set", + "override" +}; + + +static const char *info_lvl_strings[] = { + "user/basic", + "user/detail", + "user/all", + "tuner/basic", + "tuner/detail", + "tuner/all", + "dev/basic", + "dev/detail", + "dev/all" +}; + +/* + * local functions + */ +static int fixup_files(char **file_list, char * path, bool rel_path_search, char sep); +static int read_files (char *file_list, pmix_list_t *file_values, char sep); +static int var_set_initial (pmix_mca_base_var_t *var, pmix_mca_base_var_t *original); +static int var_get (int vari, pmix_mca_base_var_t **var_out, bool original); +static int var_value_string (pmix_mca_base_var_t *var, char **value_string); + +/* + * classes + */ +static void var_constructor (pmix_mca_base_var_t *p); +static void var_destructor (pmix_mca_base_var_t *p); +PMIX_CLASS_INSTANCE(pmix_mca_base_var_t, pmix_object_t, + var_constructor, var_destructor); + +static void fv_constructor (pmix_mca_base_var_file_value_t *p); +static void fv_destructor (pmix_mca_base_var_file_value_t *p); +PMIX_CLASS_INSTANCE(pmix_mca_base_var_file_value_t, pmix_list_item_t, + fv_constructor, fv_destructor); + +static const char *pmix_mca_base_var_source_file (const pmix_mca_base_var_t *var) +{ + pmix_mca_base_var_file_value_t *fv = (pmix_mca_base_var_file_value_t *) var->mbv_file_value; + + if (NULL != var->mbv_source_file) { + return var->mbv_source_file; + } + + if (fv) { + return fv->mbvfv_file; + } + + return NULL; +} + +/* + * Generate a full name from three names + */ +int pmix_mca_base_var_generate_full_name4 (const char *project, const char *framework, const char *component, + const char *variable, char **full_name) +{ + const char * const names[] = {project, framework, component, variable}; + char *name, *tmp; + size_t i, len; + + *full_name = NULL; + + for (i = 0, len = 0 ; i < 4 ; ++i) { + if (NULL != names[i]) { + /* Add space for the string + _ or \0 */ + len += strlen (names[i]) + 1; + } + } + + name = calloc (1, len); + if (NULL == name) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + for (i = 0, tmp = name ; i < 4 ; ++i) { + if (NULL != names[i]) { + if (name != tmp) { + *tmp++ = '_'; + } + strncat (name, names[i], len - (size_t)(uintptr_t)(tmp - name)); + tmp += strlen (names[i]); + } + } + + *full_name = name; + return PMIX_SUCCESS; +} + +static int compare_strings (const char *str1, const char *str2) { + if ((NULL != str1 && 0 == strcmp (str1, "*")) || + (NULL == str1 && NULL == str2)) { + return 0; + } + + if (NULL != str1 && NULL != str2) { + return strcmp (str1, str2); + } + + return 1; +} + +/* + * Append a filename to the file list if it does not exist and return a + * pointer to the filename in the list. + */ +static char *append_filename_to_list(const char *filename) +{ + int i, count; + + (void) pmix_argv_append_unique_nosize(&pmix_mca_base_var_file_list, filename, false); + + count = pmix_argv_count(pmix_mca_base_var_file_list); + + for (i = count - 1; i >= 0; --i) { + if (0 == strcmp (pmix_mca_base_var_file_list[i], filename)) { + return pmix_mca_base_var_file_list[i]; + } + } + + /* *#@*? */ + return NULL; +} + +/* + * Set it up + */ +int pmix_mca_base_var_init(void) +{ + int ret; + char *name = NULL; + + if (!pmix_mca_base_var_initialized) { + /* Init the value array for the param storage */ + + PMIX_CONSTRUCT(&pmix_mca_base_vars, pmix_pointer_array_t); + /* These values are arbitrary */ + ret = pmix_pointer_array_init (&pmix_mca_base_vars, 128, 16384, 128); + if (PMIX_SUCCESS != ret) { + return ret; + } + + pmix_mca_base_var_count = 0; + + /* Init the file param value list */ + + PMIX_CONSTRUCT(&pmix_mca_base_var_file_values, pmix_list_t); + PMIX_CONSTRUCT(&pmix_mca_base_envar_file_values, pmix_list_t); + PMIX_CONSTRUCT(&pmix_mca_base_var_override_values, pmix_list_t); + PMIX_CONSTRUCT(&pmix_mca_base_var_index_hash, pmix_hash_table_t); + + ret = pmix_hash_table_init (&pmix_mca_base_var_index_hash, 1024); + if (PMIX_SUCCESS != ret) { + return ret; + } + + ret = pmix_mca_base_var_group_init (); + if (PMIX_SUCCESS != ret) { + return ret; + } + + /* Set this before we register the parameter, below */ + + pmix_mca_base_var_initialized = true; + + pmix_mca_base_var_cache_files(false); + + /* register the envar-forwarding params */ + (void)pmix_mca_base_var_register ("pmix", "mca", "base", "env_list", + "Set SHELL env variables", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_env_list); + + pmix_mca_base_env_list_sep = PMIX_MCA_BASE_ENV_LIST_SEP_DEFAULT; + (void)pmix_mca_base_var_register ("pmix", "mca", "base", "env_list_delimiter", + "Set SHELL env variables delimiter. Default: semicolon ';'", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_env_list_sep); + + /* Set OMPI_MCA_pmix_mca_base_env_list variable, it might not be set before + * if mca variable was taken from amca conf file. Need to set it + * here because pmix_mca_base_var_process_env_list is called from schizo_ompi.c + * only when this env variable was set. + */ + if (NULL != pmix_mca_base_env_list) { + (void) pmix_mca_base_var_env_name ("pmix_mca_base_env_list", &name); + if (NULL != name) { + pmix_setenv(name, pmix_mca_base_env_list, false, &environ); + free(name); + } + } + + /* Register internal MCA variable pmix_mca_base_env_list_internal. It can be set only during + * parsing of amca conf file and contains SHELL env variables specified via -x there. + * Its format is the same as for pmix_mca_base_env_list. + */ + (void)pmix_mca_base_var_register ("pmix", "mca", "base", "env_list_internal", + "Store SHELL env variables from amca conf file", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, PMIX_MCA_BASE_VAR_FLAG_INTERNAL, PMIX_INFO_LVL_3, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_env_list_internal); + } + + return PMIX_SUCCESS; +} + +static void process_env_list(char *env_list, char ***argv, char sep) +{ + char** tokens; + char *ptr, *value; + + tokens = pmix_argv_split(env_list, (int)sep); + if (NULL == tokens) { + return; + } + + for (int i = 0 ; NULL != tokens[i] ; ++i) { + if (NULL == (ptr = strchr(tokens[i], '='))) { + value = getenv(tokens[i]); + if (NULL == value) { + pmix_show_help("help-mca-var.txt", "incorrect-env-list-param", + true, tokens[i], env_list); + break; + } + + /* duplicate the value to silence tainted string coverity issue */ + value = strdup (value); + if (NULL == value) { + /* out of memory */ + break; + } + + if (NULL != (ptr = strchr(value, '='))) { + *ptr = '\0'; + pmix_setenv(value, ptr + 1, true, argv); + } else { + pmix_setenv(tokens[i], value, true, argv); + } + + free (value); + } else { + *ptr = '\0'; + pmix_setenv(tokens[i], ptr + 1, true, argv); + /* NTH: don't bother resetting ptr to = since the string will not be used again */ + } + } + + pmix_argv_free(tokens); +} + +int pmix_mca_base_var_process_env_list(char ***argv) +{ + char sep; + sep = ';'; + if (NULL != pmix_mca_base_env_list_sep) { + if (1 == strlen(pmix_mca_base_env_list_sep)) { + sep = pmix_mca_base_env_list_sep[0]; + } else { + pmix_show_help("help-mca-var.txt", "incorrect-env-list-sep", + true, pmix_mca_base_env_list_sep); + return PMIX_SUCCESS; + } + } + if (NULL != pmix_mca_base_env_list) { + process_env_list(pmix_mca_base_env_list, argv, sep); + } + + return PMIX_SUCCESS; +} + +int pmix_mca_base_var_process_env_list_from_file(char ***argv) +{ + if (NULL != pmix_mca_base_env_list_internal) { + process_env_list(pmix_mca_base_env_list_internal, argv, ';'); + } + return PMIX_SUCCESS; +} + +static void resolve_relative_paths(char **file_prefix, char *file_path, bool rel_path_search, char **files, char sep) +{ + char *tmp_str; + /* + * Resolve all relative paths. + * the file list returned will contain only absolute paths + */ + if( PMIX_SUCCESS != fixup_files(file_prefix, file_path, rel_path_search, sep) ) { +#if 0 + /* JJH We need to die! */ + abort(); +#else + ; +#endif + } + else { + /* Prepend the files to the search list */ + asprintf(&tmp_str, "%s%c%s", *file_prefix, sep, *files); + free (*files); + *files = tmp_str; + } +} + +int pmix_mca_base_var_cache_files(bool rel_path_search) +{ + char *tmp; + int ret; + + /* We may need this later */ + home = (char*)pmix_home_directory(); + + if(NULL == cwd) { + cwd = (char *) malloc(sizeof(char) * MAXPATHLEN); + if( NULL == (cwd = getcwd(cwd, MAXPATHLEN) )) { + pmix_output(0, "Error: Unable to get the current working directory\n"); + cwd = strdup("."); + } + } + +#if PMIX_WANT_HOME_CONFIG_FILES + asprintf(&pmix_mca_base_var_files, "%s"PMIX_PATH_SEP".pmix" PMIX_PATH_SEP + "mca-params.conf%c%s" PMIX_PATH_SEP "pmix-mca-params.conf", + home, PMIX_ENV_SEP, pmix_pinstall_dirs.sysconfdir); +#else + asprintf(&pmix_mca_base_var_files, "%s" PMIX_PATH_SEP "pmix-mca-params.conf", + pmix_pinstall_dirs.sysconfdir); +#endif + + /* Initialize a parameter that says where MCA param files can be found. + We may change this value so set the scope to PMIX_MCA_BASE_VAR_SCOPE_READONLY */ + tmp = pmix_mca_base_var_files; + ret = pmix_mca_base_var_register ("pmix", "mca", "base", "param_files", "Path for MCA " + "configuration files containing variable values", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_2, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_var_files); + free (tmp); + if (PMIX_SUCCESS != ret) { + return ret; + } + + pmix_mca_base_envar_files = strdup(pmix_mca_base_var_files); + + (void) pmix_mca_base_var_register_synonym (ret, "pmix", "mca", NULL, "param_files", + PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED); + + ret = asprintf(&pmix_mca_base_var_override_file, "%s" PMIX_PATH_SEP "pmix-mca-params-override.conf", + pmix_pinstall_dirs.sysconfdir); + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + tmp = pmix_mca_base_var_override_file; + ret = pmix_mca_base_var_register ("pmix", "mca", "base", "override_param_file", + "Variables set in this file will override any value set in" + "the environment or another configuration file", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY, + PMIX_INFO_LVL_2, PMIX_MCA_BASE_VAR_SCOPE_CONSTANT, + &pmix_mca_base_var_override_file); + free (tmp); + if (0 > ret) { + return ret; + } + + /* Disable reading MCA parameter files. */ + if (0 == strcmp (pmix_mca_base_var_files, "none")) { + return PMIX_SUCCESS; + } + + pmix_mca_base_var_suppress_override_warning = false; + ret = pmix_mca_base_var_register ("pmix", "mca", "base", "suppress_override_warning", + "Suppress warnings when attempting to set an overridden value (default: false)", + PMIX_MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, PMIX_INFO_LVL_2, + PMIX_MCA_BASE_VAR_SCOPE_LOCAL, &pmix_mca_base_var_suppress_override_warning); + if (0 > ret) { + return ret; + } + + /* Aggregate MCA parameter files + * A prefix search path to look up aggregate MCA parameter file + * requests that do not specify an absolute path + */ + pmix_mca_base_var_file_prefix = NULL; + ret = pmix_mca_base_var_register ("pmix", "mca", "base", "param_file_prefix", + "Aggregate MCA parameter file sets", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_var_file_prefix); + if (0 > ret) { + return ret; + } + + pmix_mca_base_envar_file_prefix = NULL; + ret = pmix_mca_base_var_register ("pmix", "mca", "base", "envar_file_prefix", + "Aggregate MCA parameter file set for env variables", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_envar_file_prefix); + if (0 > ret) { + return ret; + } + + ret = asprintf(&pmix_mca_base_param_file_path, "%s" PMIX_PATH_SEP "amca-param-sets%c%s", + pmix_pinstall_dirs.pmixdatadir, PMIX_ENV_SEP, cwd); + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + tmp = pmix_mca_base_param_file_path; + ret = pmix_mca_base_var_register ("pmix", "mca", "base", "param_file_path", + "Aggregate MCA parameter Search path", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_param_file_path); + free (tmp); + if (0 > ret) { + return ret; + } + + force_agg_path = NULL; + ret = pmix_mca_base_var_register ("pmix", "mca", "base", "param_file_path_force", + "Forced Aggregate MCA parameter Search path", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3, + PMIX_MCA_BASE_VAR_SCOPE_READONLY, &force_agg_path); + if (0 > ret) { + return ret; + } + + if (NULL != force_agg_path) { + if (NULL != pmix_mca_base_param_file_path) { + char *tmp_str = pmix_mca_base_param_file_path; + + asprintf(&pmix_mca_base_param_file_path, "%s%c%s", force_agg_path, PMIX_ENV_SEP, tmp_str); + free(tmp_str); + } else { + pmix_mca_base_param_file_path = strdup(force_agg_path); + } + } + + if (NULL != pmix_mca_base_var_file_prefix) { + resolve_relative_paths(&pmix_mca_base_var_file_prefix, pmix_mca_base_param_file_path, rel_path_search, &pmix_mca_base_var_files, PMIX_ENV_SEP); + } + read_files (pmix_mca_base_var_files, &pmix_mca_base_var_file_values, PMIX_ENV_SEP); + + if (NULL != pmix_mca_base_envar_file_prefix) { + resolve_relative_paths(&pmix_mca_base_envar_file_prefix, pmix_mca_base_param_file_path, rel_path_search, &pmix_mca_base_envar_files, ','); + } + read_files (pmix_mca_base_envar_files, &pmix_mca_base_envar_file_values, ','); + + if (0 == access(pmix_mca_base_var_override_file, F_OK)) { + read_files (pmix_mca_base_var_override_file, &pmix_mca_base_var_override_values, PMIX_ENV_SEP); + } + + return PMIX_SUCCESS; +} + +/* + * Look up an integer MCA parameter. + */ +int pmix_mca_base_var_get_value (int vari, const void *value, + pmix_mca_base_var_source_t *source, + const char **source_file) +{ + pmix_mca_base_var_t *var; + void **tmp = (void **) value; + int ret; + + ret = var_get (vari, &var, true); + if (PMIX_SUCCESS != ret) { + return ret; + } + + if (!PMIX_VAR_IS_VALID(var[0])) { + return PMIX_ERR_NOT_FOUND; + } + + if (NULL != value) { + /* Return a poiner to our backing store (either a char **, int *, + or bool *) */ + *tmp = var->mbv_storage; + } + + if (NULL != source) { + *source = var->mbv_source; + } + + if (NULL != source_file) { + *source_file = pmix_mca_base_var_source_file (var); + } + + return PMIX_SUCCESS; +} + +static int var_set_string (pmix_mca_base_var_t *var, char *value) +{ + char *tmp; + int ret; + + if (NULL != var->mbv_storage->stringval) { + free (var->mbv_storage->stringval); + } + + var->mbv_storage->stringval = NULL; + + if (NULL == value || 0 == strlen (value)) { + return PMIX_SUCCESS; + } + + /* Replace all instances of ~/ in a path-style string with the + user's home directory. This may be handled by the enumerator + in the future. */ + if (0 == strncmp (value, "~/", 2)) { + if (NULL != home) { + ret = asprintf (&value, "%s/%s", home, value + 2); + if (0 > ret) { + return PMIX_ERROR; + } + } else { + value = strdup (value + 2); + } + } else { + value = strdup (value); + } + + if (NULL == value) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + while (NULL != (tmp = strstr (value, ":~/"))) { + tmp[0] = '\0'; + tmp += 3; + + ret = asprintf (&tmp, "%s:%s%s%s", value, + home ? home : "", home ? "/" : "", tmp); + + free (value); + + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + value = tmp; + } + + var->mbv_storage->stringval = value; + + return PMIX_SUCCESS; +} + +static int int_from_string(const char *src, pmix_mca_base_var_enum_t *enumerator, uint64_t *value_out) +{ + uint64_t value; + bool is_int; + char *tmp; + + if (NULL == src || 0 == strlen (src)) { + if (NULL == enumerator) { + *value_out = 0; + } + + return PMIX_SUCCESS; + } + + if (enumerator) { + int int_val, ret; + ret = enumerator->value_from_string(enumerator, src, &int_val); + if (PMIX_SUCCESS != ret) { + return ret; + } + *value_out = (uint64_t) int_val; + + return PMIX_SUCCESS; + } + + /* Check for an integer value */ + value = strtoull (src, &tmp, 0); + if (tmp[0] == '\0') { + is_int = true; + } else { + is_int = false; + } + + if (!is_int && tmp != src) { + switch (tmp[0]) { + case 'G': + case 'g': + value <<= 30; + break; + case 'M': + case 'm': + value <<= 20; + break; + case 'K': + case 'k': + value <<= 10; + break; + default: + break; + } + } + + *value_out = value; + + return PMIX_SUCCESS; +} + +static int var_set_from_string (pmix_mca_base_var_t *var, char *src) +{ + pmix_mca_base_var_storage_t *dst = var->mbv_storage; + uint64_t int_value = 0; + int ret; + + switch (var->mbv_type) { + case PMIX_MCA_BASE_VAR_TYPE_INT: + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT: + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG: + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG: + case PMIX_MCA_BASE_VAR_TYPE_BOOL: + case PMIX_MCA_BASE_VAR_TYPE_SIZE_T: + ret = int_from_string(src, var->mbv_enumerator, &int_value); + if (PMIX_ERR_VALUE_OUT_OF_BOUNDS == ret || + (PMIX_MCA_BASE_VAR_TYPE_INT == var->mbv_type && ((int) int_value != (int64_t) int_value)) || + (PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT == var->mbv_type && ((unsigned int) int_value != int_value))) { + if (var->mbv_enumerator) { + char *valid_values; + (void) var->mbv_enumerator->dump(var->mbv_enumerator, &valid_values); + pmix_show_help("help-mca-var.txt", "invalid-value-enum", + true, var->mbv_full_name, src, valid_values); + free(valid_values); + } else { + pmix_show_help("help-mca-var.txt", "invalid-value", + true, var->mbv_full_name, src); + } + + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + + if (PMIX_MCA_BASE_VAR_TYPE_INT == var->mbv_type || + PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT == var->mbv_type) { + int *castme = (int*) var->mbv_storage; + *castme = int_value; + } else if (PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG == var->mbv_type) { + unsigned long *castme = (unsigned long*) var->mbv_storage; + *castme = (unsigned long) int_value; + } else if (PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG == var->mbv_type) { + unsigned long long *castme = (unsigned long long*) var->mbv_storage; + *castme = (unsigned long long) int_value; + } else if (PMIX_MCA_BASE_VAR_TYPE_SIZE_T == var->mbv_type) { + size_t *castme = (size_t*) var->mbv_storage; + *castme = (size_t) int_value; + } else if (PMIX_MCA_BASE_VAR_TYPE_BOOL == var->mbv_type) { + bool *castme = (bool*) var->mbv_storage; + *castme = !!int_value; + } + + return ret; + case PMIX_MCA_BASE_VAR_TYPE_DOUBLE: + dst->lfval = strtod (src, NULL); + break; + case PMIX_MCA_BASE_VAR_TYPE_STRING: + case PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING: + var_set_string (var, src); + break; + case PMIX_MCA_BASE_VAR_TYPE_MAX: + return PMIX_ERROR; + } + + return PMIX_SUCCESS; +} + +/* + * Set a variable + */ +int pmix_mca_base_var_set_value (int vari, const void *value, size_t size, pmix_mca_base_var_source_t source, + const char *source_file) +{ + pmix_mca_base_var_t *var; + int ret; + + ret = var_get (vari, &var, true); + if (PMIX_SUCCESS != ret) { + return ret; + } + + if (!PMIX_VAR_IS_VALID(var[0])) { + return PMIX_ERR_BAD_PARAM; + } + + if (!PMIX_VAR_IS_SETTABLE(var[0])) { + return PMIX_ERR_PERM; + } + + if (NULL != var->mbv_enumerator) { + /* Validate */ + ret = var->mbv_enumerator->string_from_value(var->mbv_enumerator, + ((int *) value)[0], NULL); + if (PMIX_SUCCESS != ret) { + return ret; + } + } + + if (PMIX_MCA_BASE_VAR_TYPE_STRING != var->mbv_type && PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING != var->mbv_type) { + memmove (var->mbv_storage, value, pmix_var_type_sizes[var->mbv_type]); + } else { + var_set_string (var, (char *) value); + } + + var->mbv_source = source; + + if (PMIX_MCA_BASE_VAR_SOURCE_FILE == source && NULL != source_file) { + var->mbv_file_value = NULL; + var->mbv_source_file = append_filename_to_list(source_file); + } + + return PMIX_SUCCESS; +} + +/* + * Deregister a parameter + */ +int pmix_mca_base_var_deregister(int vari) +{ + pmix_mca_base_var_t *var; + int ret; + + ret = var_get (vari, &var, false); + if (PMIX_SUCCESS != ret) { + return ret; + } + + if (!PMIX_VAR_IS_VALID(var[0])) { + return PMIX_ERR_BAD_PARAM; + } + + /* Mark this parameter as invalid but keep its info in case this + parameter is reregistered later */ + var->mbv_flags &= ~PMIX_MCA_BASE_VAR_FLAG_VALID; + + /* Done deregistering synonym */ + if (PMIX_MCA_BASE_VAR_FLAG_SYNONYM & var->mbv_flags) { + return PMIX_SUCCESS; + } + + /* Release the current value if it is a string. */ + if ((PMIX_MCA_BASE_VAR_TYPE_STRING == var->mbv_type || PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) && + var->mbv_storage->stringval) { + free (var->mbv_storage->stringval); + var->mbv_storage->stringval = NULL; + } else if (var->mbv_enumerator && !var->mbv_enumerator->enum_is_static) { + PMIX_RELEASE(var->mbv_enumerator); + } + + var->mbv_enumerator = NULL; + + var->mbv_storage = NULL; + + return PMIX_SUCCESS; +} + +static int var_get (int vari, pmix_mca_base_var_t **var_out, bool original) +{ + pmix_mca_base_var_t *var; + + if (var_out) { + *var_out = NULL; + } + + /* Check for bozo cases */ + if (!pmix_mca_base_var_initialized) { + return PMIX_ERROR; + } + + if (vari < 0) { + return PMIX_ERR_BAD_PARAM; + } + + var = pmix_pointer_array_get_item (&pmix_mca_base_vars, vari); + if (NULL == var) { + return PMIX_ERR_BAD_PARAM; + } + + if (PMIX_VAR_IS_SYNONYM(var[0]) && original) { + return var_get(var->mbv_synonym_for, var_out, false); + } + + if (var_out) { + *var_out = var; + } + + return PMIX_SUCCESS; +} + +int pmix_mca_base_var_env_name(const char *param_name, + char **env_name) +{ + int ret; + + assert (NULL != env_name); + + ret = asprintf(env_name, "%s%s", mca_prefix, param_name); + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + return PMIX_SUCCESS; +} + +/* + * Find the index for an MCA parameter based on its names. + */ +static int var_find_by_name (const char *full_name, int *vari, bool invalidok) +{ + pmix_mca_base_var_t *var = NULL; + void *tmp; + int rc; + + rc = pmix_hash_table_get_value_ptr (&pmix_mca_base_var_index_hash, full_name, strlen (full_name), + &tmp); + if (PMIX_SUCCESS != rc) { + return rc; + } + + (void) var_get ((int)(uintptr_t) tmp, &var, false); + + if (invalidok || (var && PMIX_VAR_IS_VALID(var[0]))) { + *vari = (int)(uintptr_t) tmp; + return PMIX_SUCCESS; + } + + return PMIX_ERR_NOT_FOUND; +} + +static int var_find (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name, + bool invalidok) +{ + char *full_name; + int ret, vari; + + ret = pmix_mca_base_var_generate_full_name4 (NULL, framework_name, component_name, + variable_name, &full_name); + if (PMIX_SUCCESS != ret) { + return PMIX_ERROR; + } + + ret = var_find_by_name(full_name, &vari, invalidok); + + /* NTH: should we verify the name components match? */ + + free (full_name); + + if (PMIX_SUCCESS != ret) { + return ret; + } + + return vari; +} + +/* + * Find the index for an MCA parameter based on its name components. + */ +int pmix_mca_base_var_find (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name) +{ + return var_find (project_name, framework_name, component_name, variable_name, false); +} + +/* + * Find the index for an MCA parameter based on full name. + */ +int pmix_mca_base_var_find_by_name (const char *full_name, int *vari) +{ + return var_find_by_name (full_name, vari, false); +} + +int pmix_mca_base_var_set_flag (int vari, pmix_mca_base_var_flag_t flag, bool set) +{ + pmix_mca_base_var_t *var; + int ret; + + ret = var_get (vari, &var, true); + if (PMIX_SUCCESS != ret || PMIX_VAR_IS_SYNONYM(var[0])) { + return PMIX_ERR_BAD_PARAM; + } + + var->mbv_flags = (var->mbv_flags & ~flag) | (set ? flag : 0); + + /* All done */ + return PMIX_SUCCESS; +} + +/* + * Return info on a parameter at an index + */ +int pmix_mca_base_var_get (int vari, const pmix_mca_base_var_t **var) +{ + int ret; + ret = var_get (vari, (pmix_mca_base_var_t **) var, false); + + if (PMIX_SUCCESS != ret) { + return ret; + } + + if (!PMIX_VAR_IS_VALID(*(var[0]))) { + return PMIX_ERR_NOT_FOUND; + } + + return PMIX_SUCCESS; +} + +/* + * Make an argv-style list of strings suitable for an environment + */ +int pmix_mca_base_var_build_env(char ***env, int *num_env, bool internal) +{ + pmix_mca_base_var_t *var; + size_t i, len; + int ret; + + /* Check for bozo cases */ + + if (!pmix_mca_base_var_initialized) { + return PMIX_ERROR; + } + + /* Iterate through all the registered parameters */ + + len = pmix_pointer_array_get_size(&pmix_mca_base_vars); + for (i = 0; i < len; ++i) { + char *value_string; + char *str = NULL; + + var = pmix_pointer_array_get_item (&pmix_mca_base_vars, i); + if (NULL == var) { + continue; + } + + /* Don't output default values or internal variables (unless + requested) */ + if (PMIX_MCA_BASE_VAR_SOURCE_DEFAULT == var->mbv_source || + (!internal && PMIX_VAR_IS_INTERNAL(var[0]))) { + continue; + } + + if ((PMIX_MCA_BASE_VAR_TYPE_STRING == var->mbv_type || PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) && + NULL == var->mbv_storage->stringval) { + continue; + } + + ret = var_value_string (var, &value_string); + if (PMIX_SUCCESS != ret) { + goto cleanup; + } + + ret = asprintf (&str, "%s%s=%s", mca_prefix, var->mbv_full_name, + value_string); + free (value_string); + if (0 > ret) { + goto cleanup; + } + + pmix_argv_append(num_env, env, str); + free(str); + + switch (var->mbv_source) { + case PMIX_MCA_BASE_VAR_SOURCE_FILE: + case PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE: + asprintf (&str, "%sSOURCE_%s=FILE:%s", mca_prefix, var->mbv_full_name, + pmix_mca_base_var_source_file (var)); + break; + case PMIX_MCA_BASE_VAR_SOURCE_COMMAND_LINE: + asprintf (&str, "%sSOURCE_%s=COMMAND_LINE", mca_prefix, var->mbv_full_name); + break; + case PMIX_MCA_BASE_VAR_SOURCE_ENV: + case PMIX_MCA_BASE_VAR_SOURCE_SET: + case PMIX_MCA_BASE_VAR_SOURCE_DEFAULT: + str = NULL; + break; + case PMIX_MCA_BASE_VAR_SOURCE_MAX: + goto cleanup; + } + + if (NULL != str) { + pmix_argv_append(num_env, env, str); + free(str); + } + } + + /* All done */ + + return PMIX_SUCCESS; + + /* Error condition */ + + cleanup: + if (*num_env > 0) { + pmix_argv_free(*env); + *num_env = 0; + *env = NULL; + } + return PMIX_ERR_NOT_FOUND; +} + +/* + * Shut down the MCA parameter system (normally only invoked by the + * MCA framework itself). + */ +int pmix_mca_base_var_finalize(void) +{ + pmix_object_t *pmixect; + pmix_list_item_t *item; + int size, i; + + if (pmix_mca_base_var_initialized) { + size = pmix_pointer_array_get_size(&pmix_mca_base_vars); + for (i = 0 ; i < size ; ++i) { + pmixect = pmix_pointer_array_get_item (&pmix_mca_base_vars, i); + if (NULL != pmixect) { + PMIX_RELEASE(pmixect); + } + } + PMIX_DESTRUCT(&pmix_mca_base_vars); + + while (NULL != + (item = pmix_list_remove_first(&pmix_mca_base_var_file_values))) { + PMIX_RELEASE(item); + } + PMIX_DESTRUCT(&pmix_mca_base_var_file_values); + + while (NULL != + (item = pmix_list_remove_first(&pmix_mca_base_envar_file_values))) { + PMIX_RELEASE(item); + } + PMIX_DESTRUCT(&pmix_mca_base_envar_file_values); + + while (NULL != + (item = pmix_list_remove_first(&pmix_mca_base_var_override_values))) { + PMIX_RELEASE(item); + } + PMIX_DESTRUCT(&pmix_mca_base_var_override_values); + + if( NULL != cwd ) { + free(cwd); + cwd = NULL; + } + + pmix_mca_base_var_initialized = false; + pmix_mca_base_var_count = 0; + + if (NULL != pmix_mca_base_var_file_list) { + pmix_argv_free(pmix_mca_base_var_file_list); + } + pmix_mca_base_var_file_list = NULL; + + (void) pmix_mca_base_var_group_finalize (); + + PMIX_DESTRUCT(&pmix_mca_base_var_index_hash); + + free (pmix_mca_base_envar_files); + pmix_mca_base_envar_files = NULL; + } + + /* All done */ + + return PMIX_SUCCESS; +} + + +/*************************************************************************/ +static int fixup_files(char **file_list, char * path, bool rel_path_search, char sep) { + int exit_status = PMIX_SUCCESS; + char **files = NULL; + char **search_path = NULL; + char * tmp_file = NULL; + char **argv = NULL; + char *rel_path; + int mode = R_OK; /* The file exists, and we can read it */ + int count, i, argc = 0; + + search_path = pmix_argv_split(path, PMIX_ENV_SEP); + files = pmix_argv_split(*file_list, sep); + count = pmix_argv_count(files); + + rel_path = force_agg_path ? force_agg_path : cwd; + + /* Read in reverse order, so we can preserve the original ordering */ + for (i = 0 ; i < count; ++i) { + char *msg_path = path; + if (pmix_path_is_absolute(files[i])) { + /* Absolute paths preserved */ + tmp_file = pmix_path_access(files[i], NULL, mode); + } else if (!rel_path_search && NULL != strchr(files[i], PMIX_PATH_SEP[0])) { + /* Resolve all relative paths: + * - If filename contains a "/" (e.g., "./foo" or "foo/bar") + * - look for it relative to cwd + * - if exists, use it + * - ow warn/error + */ + msg_path = rel_path; + tmp_file = pmix_path_access(files[i], rel_path, mode); + } else { + /* Resolve all relative paths: + * - Use path resolution + * - if found and readable, use it + * - otherwise, warn/error + */ + tmp_file = pmix_path_find (files[i], search_path, mode, NULL); + } + + if (NULL == tmp_file) { + pmix_show_help("help-mca-var.txt", "missing-param-file", + true, getpid(), files[i], msg_path); + exit_status = PMIX_ERROR; + break; + } + + pmix_argv_append(&argc, &argv, tmp_file); + + free(tmp_file); + tmp_file = NULL; + } + + if (PMIX_SUCCESS == exit_status) { + free(*file_list); + *file_list = pmix_argv_join(argv, sep); + } + + if( NULL != files ) { + pmix_argv_free(files); + files = NULL; + } + + if( NULL != argv ) { + pmix_argv_free(argv); + argv = NULL; + } + + if( NULL != search_path ) { + pmix_argv_free(search_path); + search_path = NULL; + } + + return exit_status; +} + +static int read_files(char *file_list, pmix_list_t *file_values, char sep) +{ + char **tmp = pmix_argv_split(file_list, sep); + int i, count; + + if (!tmp) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + count = pmix_argv_count(tmp); + + /* Iterate through all the files passed in -- read them in reverse + order so that we preserve unix/shell path-like semantics (i.e., + the entries farthest to the left get precedence) */ + + for (i = count - 1; i >= 0; --i) { + char *file_name = append_filename_to_list (tmp[i]); + pmix_mca_base_parse_paramfile(file_name, file_values); + } + + pmix_argv_free (tmp); + + pmix_mca_base_internal_env_store(); + + return PMIX_SUCCESS; +} + +/******************************************************************************/ +static int register_variable (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name, + const char *description, pmix_mca_base_var_type_t type, + pmix_mca_base_var_enum_t *enumerator, int bind, + pmix_mca_base_var_flag_t flags, pmix_mca_base_var_info_lvl_t info_lvl, + pmix_mca_base_var_scope_t scope, int synonym_for, + void *storage) +{ + int ret, var_index, group_index, tmp; + pmix_mca_base_var_group_t *group; + pmix_mca_base_var_t *var, *original = NULL; + + /* Developer error. Storage can not be NULL and type must exist */ + assert (((flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM) || NULL != storage) && type >= 0 && type < PMIX_MCA_BASE_VAR_TYPE_MAX); + +#if PMIX_ENABLE_DEBUG + /* Developer error: check for alignments */ + uintptr_t align = 0; + switch (type) { + case PMIX_MCA_BASE_VAR_TYPE_INT: + align = PMIX_ALIGNMENT_INT; + break; + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT: + align = PMIX_ALIGNMENT_INT; + break; + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG: + align = PMIX_ALIGNMENT_LONG; + break; + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG: + align = PMIX_ALIGNMENT_LONG_LONG; + break; + case PMIX_MCA_BASE_VAR_TYPE_SIZE_T: + align = PMIX_ALIGNMENT_SIZE_T; + break; + case PMIX_MCA_BASE_VAR_TYPE_BOOL: + align = PMIX_ALIGNMENT_BOOL; + break; + case PMIX_MCA_BASE_VAR_TYPE_DOUBLE: + align = PMIX_ALIGNMENT_DOUBLE; + break; + case PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING: + case PMIX_MCA_BASE_VAR_TYPE_STRING: + default: + align = 0; + break; + } + + if (0 != align) { + assert(((uintptr_t) storage) % align == 0); + } + + /* Also check to ensure that synonym_for>=0 when + MCA_BCASE_VAR_FLAG_SYNONYM is specified */ + if (flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM && synonym_for < 0) { + assert((flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM) && synonym_for >= 0); + } +#endif + + if (flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM) { + if (synonym_for < 0) { + return PMIX_ERR_BAD_PARAM; + } + original = pmix_pointer_array_get_item (&pmix_mca_base_vars, synonym_for); + if (NULL == original) { + /* Attempting to create a synonym for a non-existent variable. probably a + * developer error. */ + assert (NULL != original); + return PMIX_ERR_NOT_FOUND; + } + } + + /* Initialize the array if it has never been initialized */ + if (!pmix_mca_base_var_initialized) { + pmix_mca_base_var_init(); + } + + /* See if this entry is already in the array */ + var_index = var_find (project_name, framework_name, component_name, variable_name, + true); + + if (0 > var_index) { + /* Create a new parameter entry */ + group_index = pmix_mca_base_var_group_register (project_name, framework_name, component_name, + NULL); + if (-1 > group_index) { + return group_index; + } + + /* Read-only and constant variables can't be settable */ + if (scope < PMIX_MCA_BASE_VAR_SCOPE_LOCAL || (flags & PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY)) { + if ((flags & PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY) && (flags & PMIX_MCA_BASE_VAR_FLAG_SETTABLE)) { + pmix_show_help("help-mca-var.txt", "invalid-flag-combination", + true, "PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY", "PMIX_MCA_BASE_VAR_FLAG_SETTABLE"); + return PMIX_ERROR; + } + + /* Should we print a warning for other cases? */ + flags &= ~PMIX_MCA_BASE_VAR_FLAG_SETTABLE; + } + + var = PMIX_NEW(pmix_mca_base_var_t); + + var->mbv_type = type; + var->mbv_flags = flags; + var->mbv_group_index = group_index; + var->mbv_info_lvl = info_lvl; + var->mbv_scope = scope; + var->mbv_synonym_for = synonym_for; + var->mbv_bind = bind; + + if (NULL != description) { + var->mbv_description = strdup(description); + } + + if (NULL != variable_name) { + var->mbv_variable_name = strdup(variable_name); + if (NULL == var->mbv_variable_name) { + PMIX_RELEASE(var); + return PMIX_ERR_OUT_OF_RESOURCE; + } + } + + ret = pmix_mca_base_var_generate_full_name4 (NULL, framework_name, component_name, + variable_name, &var->mbv_full_name); + if (PMIX_SUCCESS != ret) { + PMIX_RELEASE(var); + return PMIX_ERROR; + } + + ret = pmix_mca_base_var_generate_full_name4 (project_name, framework_name, component_name, + variable_name, &var->mbv_long_name); + if (PMIX_SUCCESS != ret) { + PMIX_RELEASE(var); + return PMIX_ERROR; + } + + /* Add it to the array. Note that we copy the mca_var_t by value, + so the entire contents of the struct is copied. The synonym list + will always be empty at this point, so there's no need for an + extra RETAIN or RELEASE. */ + var_index = pmix_pointer_array_add (&pmix_mca_base_vars, var); + if (0 > var_index) { + PMIX_RELEASE(var); + return PMIX_ERROR; + } + + var->mbv_index = var_index; + + if (0 <= group_index) { + pmix_mca_base_var_group_add_var (group_index, var_index); + } + + pmix_mca_base_var_count++; + if (0 <= var_find_by_name (var->mbv_full_name, &tmp, 0)) { + /* XXX --- FIXME: variable overshadows an existing variable. this is difficult to support */ + assert (0); + } + + pmix_hash_table_set_value_ptr (&pmix_mca_base_var_index_hash, var->mbv_full_name, strlen (var->mbv_full_name), + (void *)(uintptr_t) var_index); + } else { + ret = var_get (var_index, &var, false); + if (PMIX_SUCCESS != ret) { + /* Shouldn't ever happen */ + return PMIX_ERROR; + } + + ret = pmix_mca_base_var_group_get_internal (var->mbv_group_index, &group, true); + if (PMIX_SUCCESS != ret) { + /* Shouldn't ever happen */ + return PMIX_ERROR; + } + + if (!group->group_isvalid) { + group->group_isvalid = true; + } + + /* Verify the name components match */ + if (0 != compare_strings(framework_name, group->group_framework) || + 0 != compare_strings(component_name, group->group_component) || + 0 != compare_strings(variable_name, var->mbv_variable_name)) { + pmix_show_help("help-mca-var.txt", "var-name-conflict", + true, var->mbv_full_name, framework_name, + component_name, variable_name, + group->group_framework, group->group_component, + var->mbv_variable_name); + /* This is developer error. abort! */ + assert (0); + return PMIX_ERROR; + } + + if (var->mbv_type != type) { +#if PMIX_ENABLE_DEBUG + pmix_show_help("help-mca-var.txt", + "re-register-with-different-type", + true, var->mbv_full_name); +#endif + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + } + + if (PMIX_MCA_BASE_VAR_TYPE_BOOL == var->mbv_type) { + enumerator = &pmix_mca_base_var_enum_bool; + } else if (NULL != enumerator) { + if (var->mbv_enumerator) { + PMIX_RELEASE (var->mbv_enumerator); + } + + if (!enumerator->enum_is_static) { + PMIX_RETAIN(enumerator); + } + } + + var->mbv_enumerator = enumerator; + + if (!original) { + var->mbv_storage = storage; + + /* make a copy of the default string value */ + if ((PMIX_MCA_BASE_VAR_TYPE_STRING == type || PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING == type) && NULL != ((char **)storage)[0]) { + ((char **)storage)[0] = strdup (((char **)storage)[0]); + } + } else { + /* synonym variable */ + pmix_value_array_append_item(&original->mbv_synonyms, &var_index); + } + + /* go ahead and mark this variable as valid */ + var->mbv_flags |= PMIX_MCA_BASE_VAR_FLAG_VALID; + + ret = var_set_initial (var, original); + if (PMIX_SUCCESS != ret) { + return ret; + } + + /* All done */ + return var_index; +} + +int pmix_mca_base_var_register (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name, + const char *description, pmix_mca_base_var_type_t type, + pmix_mca_base_var_enum_t *enumerator, int bind, + pmix_mca_base_var_flag_t flags, + pmix_mca_base_var_info_lvl_t info_lvl, + pmix_mca_base_var_scope_t scope, void *storage) +{ + /* Only integer variables can have enumerator */ + assert (NULL == enumerator || (PMIX_MCA_BASE_VAR_TYPE_INT == type || PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT == type)); + + return register_variable (project_name, framework_name, component_name, + variable_name, description, type, enumerator, + bind, flags, info_lvl, scope, -1, storage); +} + +int pmix_mca_base_component_var_register (const pmix_mca_base_component_t *component, + const char *variable_name, const char *description, + pmix_mca_base_var_type_t type, pmix_mca_base_var_enum_t *enumerator, + int bind, pmix_mca_base_var_flag_t flags, + pmix_mca_base_var_info_lvl_t info_lvl, + pmix_mca_base_var_scope_t scope, void *storage) +{ + return pmix_mca_base_var_register (component->pmix_mca_project_name, + component->pmix_mca_type_name, + component->pmix_mca_component_name, + variable_name, description, type, enumerator, + bind, flags | PMIX_MCA_BASE_VAR_FLAG_DWG, + info_lvl, scope, storage); +} + +int pmix_mca_base_framework_var_register (const pmix_mca_base_framework_t *framework, + const char *variable_name, + const char *help_msg, pmix_mca_base_var_type_t type, + pmix_mca_base_var_enum_t *enumerator, int bind, + pmix_mca_base_var_flag_t flags, + pmix_mca_base_var_info_lvl_t info_level, + pmix_mca_base_var_scope_t scope, void *storage) +{ + return pmix_mca_base_var_register (framework->framework_project, framework->framework_name, + "base", variable_name, help_msg, type, enumerator, bind, + flags | PMIX_MCA_BASE_VAR_FLAG_DWG, info_level, scope, storage); +} + +int pmix_mca_base_var_register_synonym (int synonym_for, const char *project_name, + const char *framework_name, + const char *component_name, + const char *synonym_name, + pmix_mca_base_var_syn_flag_t flags) +{ + pmix_mca_base_var_flag_t var_flags = (pmix_mca_base_var_flag_t) PMIX_MCA_BASE_VAR_FLAG_SYNONYM; + pmix_mca_base_var_t *var; + int ret; + + ret = var_get (synonym_for, &var, false); + if (PMIX_SUCCESS != ret || PMIX_VAR_IS_SYNONYM(var[0])) { + return PMIX_ERR_BAD_PARAM; + } + + if (flags & PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED) { + var_flags |= PMIX_MCA_BASE_VAR_FLAG_DEPRECATED; + } + if (flags & PMIX_MCA_BASE_VAR_SYN_FLAG_INTERNAL) { + var_flags |= PMIX_MCA_BASE_VAR_FLAG_INTERNAL; + } + + return register_variable (project_name, framework_name, component_name, + synonym_name, var->mbv_description, var->mbv_type, var->mbv_enumerator, + var->mbv_bind, var_flags, var->mbv_info_lvl, var->mbv_scope, + synonym_for, NULL); +} + +static int var_get_env (pmix_mca_base_var_t *var, const char *name, char **source, char **value) +{ + char *source_env, *value_env; + int ret; + + ret = asprintf (&source_env, "%sSOURCE_%s", mca_prefix, name); + if (0 > ret) { + return PMIX_ERROR; + } + + ret = asprintf (&value_env, "%s%s", mca_prefix, name); + if (0 > ret) { + free (source_env); + return PMIX_ERROR; + } + + *source = getenv (source_env); + *value = getenv (value_env); + + free (source_env); + free (value_env); + + if (NULL == *value) { + *source = NULL; + return PMIX_ERR_NOT_FOUND; + } + + return PMIX_SUCCESS; +} + +/* + * Lookup a param in the environment + */ +static int var_set_from_env (pmix_mca_base_var_t *var, pmix_mca_base_var_t *original) +{ + const char *var_full_name = var->mbv_full_name; + const char *var_long_name = var->mbv_long_name; + bool deprecated = PMIX_VAR_IS_DEPRECATED(var[0]); + bool is_synonym = PMIX_VAR_IS_SYNONYM(var[0]); + char *source_env, *value_env; + int ret; + + ret = var_get_env (var, var_long_name, &source_env, &value_env); + if (PMIX_SUCCESS != ret) { + ret = var_get_env (var, var_full_name, &source_env, &value_env); + } + + if (PMIX_SUCCESS != ret) { + return ret; + } + + /* we found an environment variable but this variable is default-only. print + a warning. */ + if (PMIX_VAR_IS_DEFAULT_ONLY(original[0])) { + pmix_show_help("help-mca-var.txt", "default-only-param-set", + true, var_full_name); + + return PMIX_ERR_NOT_FOUND; + } + + if (PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE == original->mbv_source) { + if (!pmix_mca_base_var_suppress_override_warning) { + pmix_show_help("help-mca-var.txt", "overridden-param-set", + true, var_full_name); + } + + return PMIX_ERR_NOT_FOUND; + } + + original->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_ENV; + + if (NULL != source_env) { + if (0 == strncasecmp (source_env, "file:", 5)) { + original->mbv_source_file = append_filename_to_list(source_env + 5); + if (0 == strcmp (var->mbv_source_file, pmix_mca_base_var_override_file)) { + original->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE; + } else { + original->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_FILE; + } + } else if (0 == strcasecmp (source_env, "command")) { + var->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_COMMAND_LINE; + } + } + + if (deprecated) { + const char *new_variable = "None (going away)"; + + if (is_synonym) { + new_variable = var->mbv_full_name; + } + + switch (var->mbv_source) { + case PMIX_MCA_BASE_VAR_SOURCE_ENV: + pmix_show_help("help-mca-var.txt", "deprecated-mca-env", + true, var_full_name, new_variable); + break; + case PMIX_MCA_BASE_VAR_SOURCE_COMMAND_LINE: + pmix_show_help("help-mca-var.txt", "deprecated-mca-cli", + true, var_full_name, new_variable); + break; + case PMIX_MCA_BASE_VAR_SOURCE_FILE: + case PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE: + pmix_show_help("help-mca-var.txt", "deprecated-mca-file", + true, var_full_name, pmix_mca_base_var_source_file (var), + new_variable); + break; + + case PMIX_MCA_BASE_VAR_SOURCE_DEFAULT: + case PMIX_MCA_BASE_VAR_SOURCE_MAX: + case PMIX_MCA_BASE_VAR_SOURCE_SET: + /* silence compiler warnings about unhandled enumerations */ + break; + } + } + + return var_set_from_string (original, value_env); +} + +/* + * Lookup a param in the files + */ +static int var_set_from_file (pmix_mca_base_var_t *var, pmix_mca_base_var_t *original, pmix_list_t *file_values) +{ + const char *var_full_name = var->mbv_full_name; + const char *var_long_name = var->mbv_long_name; + bool deprecated = PMIX_VAR_IS_DEPRECATED(var[0]); + bool is_synonym = PMIX_VAR_IS_SYNONYM(var[0]); + pmix_mca_base_var_file_value_t *fv; + + /* Scan through the list of values read in from files and try to + find a match. If we do, cache it on the param (for future + lookups) and save it in the storage. */ + + PMIX_LIST_FOREACH(fv, file_values, pmix_mca_base_var_file_value_t) { + if (0 != strcmp(fv->mbvfv_var, var_full_name) && + 0 != strcmp(fv->mbvfv_var, var_long_name)) { + continue; + } + + /* found it */ + if (PMIX_VAR_IS_DEFAULT_ONLY(var[0])) { + pmix_show_help("help-mca-var.txt", "default-only-param-set", + true, var_full_name); + + return PMIX_ERR_NOT_FOUND; + } + + if (PMIX_MCA_BASE_VAR_FLAG_ENVIRONMENT_ONLY & original->mbv_flags) { + pmix_show_help("help-mca-var.txt", "environment-only-param", + true, var_full_name, fv->mbvfv_value, + fv->mbvfv_file); + + return PMIX_ERR_NOT_FOUND; + } + + if (PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE == original->mbv_source) { + if (!pmix_mca_base_var_suppress_override_warning) { + pmix_show_help("help-mca-var.txt", "overridden-param-set", + true, var_full_name); + } + + return PMIX_ERR_NOT_FOUND; + } + + if (deprecated) { + const char *new_variable = "None (going away)"; + + if (is_synonym) { + new_variable = original->mbv_full_name; + } + + pmix_show_help("help-mca-var.txt", "deprecated-mca-file", + true, var_full_name, fv->mbvfv_file, + new_variable); + } + + original->mbv_file_value = (void *) fv; + original->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_FILE; + if (is_synonym) { + var->mbv_file_value = (void *) fv; + var->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_FILE; + } + + return var_set_from_string (original, fv->mbvfv_value); + } + + return PMIX_ERR_NOT_FOUND; +} + +/* + * Lookup the initial value for a parameter + */ +static int var_set_initial (pmix_mca_base_var_t *var, pmix_mca_base_var_t *original) +{ + int ret; + + if (original) { + /* synonym */ + var->mbv_source = original->mbv_source; + var->mbv_file_value = original->mbv_file_value; + var->mbv_source_file = original->mbv_source_file; + } else { + var->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_DEFAULT; + original = var; + } + + /* Check all the places that the param may be hiding, in priority + order. If the default only flag is set the user will get a + warning if they try to set a value from the environment or a + file. */ + ret = var_set_from_file (var, original, &pmix_mca_base_var_override_values); + if (PMIX_SUCCESS == ret) { + var->mbv_flags = ~PMIX_MCA_BASE_VAR_FLAG_SETTABLE & (var->mbv_flags | PMIX_MCA_BASE_VAR_FLAG_OVERRIDE); + var->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE; + } + + ret = var_set_from_env (var, original); + if (PMIX_ERR_NOT_FOUND != ret) { + return ret; + } + + ret = var_set_from_file (var, original, &pmix_mca_base_envar_file_values); + if (PMIX_ERR_NOT_FOUND != ret) { + return ret; + } + + ret = var_set_from_file (var, original, &pmix_mca_base_var_file_values); + if (PMIX_ERR_NOT_FOUND != ret) { + return ret; + } + + return PMIX_SUCCESS; +} + +/* + * Create an empty param container + */ +static void var_constructor(pmix_mca_base_var_t *var) +{ + memset ((char *) var + sizeof (var->super), 0, sizeof (*var) - sizeof (var->super)); + + var->mbv_type = PMIX_MCA_BASE_VAR_TYPE_MAX; + PMIX_CONSTRUCT(&var->mbv_synonyms, pmix_value_array_t); + pmix_value_array_init (&var->mbv_synonyms, sizeof (int)); +} + + +/* + * Free all the contents of a param container + */ +static void var_destructor(pmix_mca_base_var_t *var) +{ + if ((PMIX_MCA_BASE_VAR_TYPE_STRING == var->mbv_type || + PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) && + NULL != var->mbv_storage && + NULL != var->mbv_storage->stringval) { + free (var->mbv_storage->stringval); + var->mbv_storage->stringval = NULL; + } + + /* don't release the boolean enumerator */ + if (var->mbv_enumerator && !var->mbv_enumerator->enum_is_static) { + PMIX_RELEASE(var->mbv_enumerator); + } + + if (NULL != var->mbv_variable_name) { + free(var->mbv_variable_name); + } + if (NULL != var->mbv_full_name) { + free(var->mbv_full_name); + } + if (NULL != var->mbv_long_name) { + free(var->mbv_long_name); + } + + if (NULL != var->mbv_description) { + free(var->mbv_description); + } + + /* Destroy the synonym array */ + PMIX_DESTRUCT(&var->mbv_synonyms); + + /* mark this parameter as invalid */ + var->mbv_type = PMIX_MCA_BASE_VAR_TYPE_MAX; + +#if PMIX_ENABLE_DEBUG + /* Cheap trick to reset everything to NULL */ + memset ((char *) var + sizeof (var->super), 0, sizeof (*var) - sizeof (var->super)); +#endif +} + + +static void fv_constructor(pmix_mca_base_var_file_value_t *f) +{ + memset ((char *) f + sizeof (f->super), 0, sizeof (*f) - sizeof (f->super)); +} + + +static void fv_destructor(pmix_mca_base_var_file_value_t *f) +{ + if (NULL != f->mbvfv_var) { + free(f->mbvfv_var); + } + if (NULL != f->mbvfv_value) { + free(f->mbvfv_value); + } + /* the file name is stored in mca_*/ + fv_constructor(f); +} + +static char *source_name(pmix_mca_base_var_t *var) +{ + char *ret; + + if (PMIX_MCA_BASE_VAR_SOURCE_FILE == var->mbv_source || PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE == var->mbv_source) { + struct pmix_mca_base_var_file_value_t *fv = var->mbv_file_value; + int rc; + + if (fv) { + rc = asprintf(&ret, "file (%s:%d)", fv->mbvfv_file, fv->mbvfv_lineno); + } else { + rc = asprintf(&ret, "file (%s)", var->mbv_source_file); + } + + /* some compilers will warn if the return code of asprintf is not checked (even if it is cast to void) */ + if (0 > rc) { + return NULL; + } + return ret; + } else if (PMIX_MCA_BASE_VAR_SOURCE_MAX <= var->mbv_source) { + return strdup ("unknown(!!)"); + } + + return strdup (var_source_names[var->mbv_source]); +} + +static int var_value_string (pmix_mca_base_var_t *var, char **value_string) +{ + const pmix_mca_base_var_storage_t *value; + int ret; + + assert (PMIX_MCA_BASE_VAR_TYPE_MAX > var->mbv_type); + + ret = pmix_mca_base_var_get_value(var->mbv_index, &value, NULL, NULL); + if (PMIX_SUCCESS !=ret) { + return ret; + } + + if (NULL == var->mbv_enumerator) { + switch (var->mbv_type) { + case PMIX_MCA_BASE_VAR_TYPE_INT: + ret = asprintf (value_string, "%d", value->intval); + break; + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT: + ret = asprintf (value_string, "%u", value->uintval); + break; + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG: + ret = asprintf (value_string, "%lu", value->ulval); + break; + case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG: + ret = asprintf (value_string, "%llu", value->ullval); + break; + case PMIX_MCA_BASE_VAR_TYPE_SIZE_T: + ret = asprintf (value_string, "%" PRIsize_t, value->sizetval); + break; + case PMIX_MCA_BASE_VAR_TYPE_STRING: + case PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING: + ret = asprintf (value_string, "%s", + value->stringval ? value->stringval : ""); + break; + case PMIX_MCA_BASE_VAR_TYPE_BOOL: + ret = asprintf (value_string, "%d", value->boolval); + break; + case PMIX_MCA_BASE_VAR_TYPE_DOUBLE: + ret = asprintf (value_string, "%lf", value->lfval); + break; + default: + ret = -1; + break; + } + + ret = (0 > ret) ? PMIX_ERR_OUT_OF_RESOURCE : PMIX_SUCCESS; + } else { + /* we use an enumerator to handle string->bool and bool->string conversion */ + if (PMIX_MCA_BASE_VAR_TYPE_BOOL == var->mbv_type) { + ret = var->mbv_enumerator->string_from_value(var->mbv_enumerator, value->boolval, value_string); + } else { + ret = var->mbv_enumerator->string_from_value(var->mbv_enumerator, value->intval, value_string); + } + + if (PMIX_SUCCESS != ret) { + return ret; + } + } + + return ret; +} + +int pmix_mca_base_var_check_exclusive (const char *project, + const char *type_a, + const char *component_a, + const char *param_a, + const char *type_b, + const char *component_b, + const char *param_b) +{ + pmix_mca_base_var_t *var_a = NULL, *var_b = NULL; + int var_ai, var_bi; + + /* XXX -- Remove me once the project name is in the componennt */ + project = NULL; + + var_ai = pmix_mca_base_var_find (project, type_a, component_a, param_a); + var_bi = pmix_mca_base_var_find (project, type_b, component_b, param_b); + if (var_bi < 0 || var_ai < 0) { + return PMIX_ERR_NOT_FOUND; + } + + (void) var_get (var_ai, &var_a, true); + (void) var_get (var_bi, &var_b, true); + if (NULL == var_a || NULL == var_b) { + return PMIX_ERR_NOT_FOUND; + } + + if (PMIX_MCA_BASE_VAR_SOURCE_DEFAULT != var_a->mbv_source && + PMIX_MCA_BASE_VAR_SOURCE_DEFAULT != var_b->mbv_source) { + char *str_a, *str_b; + + /* Form cosmetic string names for A */ + str_a = source_name(var_a); + + /* Form cosmetic string names for B */ + str_b = source_name(var_b); + + /* Print it all out */ + pmix_show_help("help-mca-var.txt", + "mutually-exclusive-vars", + true, var_a->mbv_full_name, + str_a, var_b->mbv_full_name, + str_b); + + /* Free the temp strings */ + free(str_a); + free(str_b); + + return PMIX_ERR_BAD_PARAM; + } + + return PMIX_SUCCESS; +} + +int pmix_mca_base_var_get_count (void) +{ + return pmix_mca_base_var_count; +} + +int pmix_mca_base_var_dump(int vari, char ***out, pmix_mca_base_var_dump_type_t output_type) +{ + const char *framework, *component, *full_name; + int i, line_count, line = 0, enum_count = 0; + char *value_string, *source_string, *tmp; + int synonym_count, ret, *synonyms = NULL; + pmix_mca_base_var_t *var, *original=NULL; + pmix_mca_base_var_group_t *group; + + ret = var_get(vari, &var, false); + if (PMIX_SUCCESS != ret) { + return ret; + } + + ret = pmix_mca_base_var_group_get_internal(var->mbv_group_index, &group, false); + if (PMIX_SUCCESS != ret) { + return ret; + } + + if (PMIX_VAR_IS_SYNONYM(var[0])) { + ret = var_get(var->mbv_synonym_for, &original, false); + if (PMIX_SUCCESS != ret) { + return ret; + } + /* just for protection... */ + if (NULL == original) { + return PMIX_ERR_NOT_FOUND; + } + } + + framework = group->group_framework; + component = group->group_component ? group->group_component : "base"; + full_name = var->mbv_full_name; + + synonym_count = pmix_value_array_get_size(&var->mbv_synonyms); + if (synonym_count) { + synonyms = PMIX_VALUE_ARRAY_GET_BASE(&var->mbv_synonyms, int); + } + + ret = var_value_string (var, &value_string); + if (PMIX_SUCCESS != ret) { + return ret; + } + + source_string = source_name(var); + if (NULL == source_string) { + free (value_string); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + if (PMIX_MCA_BASE_VAR_DUMP_PARSABLE == output_type) { + if (NULL != var->mbv_enumerator) { + (void) var->mbv_enumerator->get_count(var->mbv_enumerator, &enum_count); + } + + line_count = 8 + (var->mbv_description ? 1 : 0) + (PMIX_VAR_IS_SYNONYM(var[0]) ? 1 : synonym_count) + + enum_count; + + *out = (char **) calloc (line_count + 1, sizeof (char *)); + if (NULL == *out) { + free (value_string); + free (source_string); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + /* build the message*/ + asprintf(&tmp, "mca:%s:%s:param:%s:", framework, component, + full_name); + + /* Output the value */ + char *colon = strchr(value_string, ':'); + if (NULL != colon) { + asprintf(out[0] + line++, "%svalue:\"%s\"", tmp, value_string); + } else { + asprintf(out[0] + line++, "%svalue:%s", tmp, value_string); + } + + /* Output the source */ + asprintf(out[0] + line++, "%ssource:%s", tmp, source_string); + + /* Output whether it's read only or writable */ + asprintf(out[0] + line++, "%sstatus:%s", tmp, PMIX_VAR_IS_DEFAULT_ONLY(var[0]) ? "read-only" : "writeable"); + + /* Output the info level of this parametere */ + asprintf(out[0] + line++, "%slevel:%d", tmp, var->mbv_info_lvl + 1); + + /* If it has a help message, output the help message */ + if (var->mbv_description) { + asprintf(out[0] + line++, "%shelp:%s", tmp, var->mbv_description); + } + + if (NULL != var->mbv_enumerator) { + for (i = 0 ; i < enum_count ; ++i) { + const char *enum_string = NULL; + int enum_value; + + ret = var->mbv_enumerator->get_value(var->mbv_enumerator, i, &enum_value, + &enum_string); + if (PMIX_SUCCESS != ret) { + continue; + } + + asprintf(out[0] + line++, "%senumerator:value:%d:%s", tmp, enum_value, enum_string); + } + } + + /* Is this variable deprecated? */ + asprintf(out[0] + line++, "%sdeprecated:%s", tmp, PMIX_VAR_IS_DEPRECATED(var[0]) ? "yes" : "no"); + + asprintf(out[0] + line++, "%stype:%s", tmp, pmix_var_type_names[var->mbv_type]); + + /* Does this parameter have any synonyms or is it a synonym? */ + if (PMIX_VAR_IS_SYNONYM(var[0])) { + asprintf(out[0] + line++, "%ssynonym_of:name:%s", tmp, original->mbv_full_name); + } else if (pmix_value_array_get_size(&var->mbv_synonyms)) { + for (i = 0 ; i < synonym_count ; ++i) { + pmix_mca_base_var_t *synonym; + + ret = var_get(synonyms[i], &synonym, false); + if (PMIX_SUCCESS != ret) { + continue; + } + + asprintf(out[0] + line++, "%ssynonym:name:%s", tmp, synonym->mbv_full_name); + } + } + + free (tmp); + } else if (PMIX_MCA_BASE_VAR_DUMP_READABLE == output_type) { + /* There will be at most three lines in the pretty print case */ + *out = (char **) calloc (4, sizeof (char *)); + if (NULL == *out) { + free (value_string); + free (source_string); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + asprintf (out[0], "%s \"%s\" (current value: \"%s\", data source: %s, level: %d %s, type: %s", + PMIX_VAR_IS_DEFAULT_ONLY(var[0]) ? "informational" : "parameter", + full_name, value_string, source_string, var->mbv_info_lvl + 1, + info_lvl_strings[var->mbv_info_lvl], pmix_var_type_names[var->mbv_type]); + + tmp = out[0][0]; + if (PMIX_VAR_IS_DEPRECATED(var[0])) { + asprintf (out[0], "%s, deprecated", tmp); + free (tmp); + tmp = out[0][0]; + } + + /* Does this parameter have any synonyms or is it a synonym? */ + if (PMIX_VAR_IS_SYNONYM(var[0])) { + asprintf(out[0], "%s, synonym of: %s)", tmp, original->mbv_full_name); + free (tmp); + } else if (synonym_count) { + asprintf(out[0], "%s, synonyms: ", tmp); + free (tmp); + + for (i = 0 ; i < synonym_count ; ++i) { + pmix_mca_base_var_t *synonym; + + ret = var_get(synonyms[i], &synonym, false); + if (PMIX_SUCCESS != ret) { + continue; + } + + tmp = out[0][0]; + if (synonym_count == i+1) { + asprintf(out[0], "%s%s)", tmp, synonym->mbv_full_name); + } else { + asprintf(out[0], "%s%s, ", tmp, synonym->mbv_full_name); + } + free(tmp); + } + } else { + asprintf(out[0], "%s)", tmp); + free(tmp); + } + + line++; + + if (var->mbv_description) { + asprintf(out[0] + line++, "%s", var->mbv_description); + } + + if (NULL != var->mbv_enumerator) { + char *values; + + ret = var->mbv_enumerator->dump(var->mbv_enumerator, &values); + if (PMIX_SUCCESS == ret) { + asprintf (out[0] + line++, "Valid values: %s", values); + free (values); + } + } + } else if (PMIX_MCA_BASE_VAR_DUMP_SIMPLE == output_type) { + *out = (char **) calloc (2, sizeof (char *)); + if (NULL == *out) { + free (value_string); + free (source_string); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + asprintf(out[0], "%s=%s (%s)", var->mbv_full_name, value_string, source_string); + } + + free (value_string); + free (source_string); + + return PMIX_SUCCESS; +} + diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.h b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.h new file mode 100644 index 0000000000..8888a22b2d --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.h @@ -0,0 +1,740 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 2008-2011 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** @file + * This file presents the MCA variable interface. + * + * Note that there are two scopes for MCA variables: "normal" and + * attributes. Specifically, all MCA variables are "normal" -- some + * are special and may also be found on attributes on communicators, + * datatypes, or windows. + * + * In general, these functions are intended to be used as follows: + * + * - Creating MCA variables + * -# Register a variable, get an index back + * - Using MCA variables + * -# Lookup a "normal" variable value on a specific index, or + * -# Lookup an attribute variable on a specific index and + * communicator / datatype / window. + * + * MCA variables can be defined in multiple different places. As + * such, variables are \em resolved to find their value. The order + * of resolution is as follows: + * + * - An "override" location that is only available to be set via the + * pmix_mca_base_param API. + * - Look for an environment variable corresponding to the MCA + * variable. + * - See if a file contains the MCA variable (MCA variable files are + * read only once -- when the first time any mca_param_t function is + * invoked). + * - If nothing else was found, use the variable's default value. + * + * Note that there is a second header file (pmix_mca_base_vari.h) + * that contains several internal type delcarations for the variable + * system. The internal file is only used within the variable system + * itself; it should not be required by any other PMIX entities. + */ + +#ifndef PMIX_MCA_BASE_VAR_H +#define PMIX_MCA_BASE_VAR_H + +#include + +#include "src/class/pmix_list.h" +#include "src/class/pmix_value_array.h" +#include "src/mca/base/pmix_mca_base_var_enum.h" +#include "src/mca/base/pmix_mca_base_var_group.h" +#include "src/mca/base/pmix_mca_base_framework.h" +#include "src/mca/mca.h" + +/** + * The types of MCA variables. + */ +typedef enum { + /** The variable is of type int. */ + PMIX_MCA_BASE_VAR_TYPE_INT, + /** The variable is of type unsigned int */ + PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT, + /** The variable is of type unsigned long */ + PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG, + /** The variable is of type unsigned long long */ + PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG, + /** The variable is of type size_t */ + PMIX_MCA_BASE_VAR_TYPE_SIZE_T, + /** The variable is of type string. */ + PMIX_MCA_BASE_VAR_TYPE_STRING, + /** The variable is of type string and contains version. */ + PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING, + /** The variable is of type bool */ + PMIX_MCA_BASE_VAR_TYPE_BOOL, + /** The variable is of type double */ + PMIX_MCA_BASE_VAR_TYPE_DOUBLE, + /** Maximum variable type. */ + PMIX_MCA_BASE_VAR_TYPE_MAX +} pmix_mca_base_var_type_t; + +extern const char *pmix_var_type_names[]; + +/** + * Source of an MCA variable's value + */ +typedef enum { + /** The default value */ + PMIX_MCA_BASE_VAR_SOURCE_DEFAULT, + /** The value came from the command line */ + PMIX_MCA_BASE_VAR_SOURCE_COMMAND_LINE, + /** The value came from the environment */ + PMIX_MCA_BASE_VAR_SOURCE_ENV, + /** The value came from a file */ + PMIX_MCA_BASE_VAR_SOURCE_FILE, + /** The value came a "set" API call */ + PMIX_MCA_BASE_VAR_SOURCE_SET, + /** The value came from the override file */ + PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE, + + /** Maximum source type */ + PMIX_MCA_BASE_VAR_SOURCE_MAX +} pmix_mca_base_var_source_t; + +/** + * MCA variable scopes + * + * Equivalent to MPI_T scopes with the same base name (e.g., + * MCA_BASE_VAR_SCOPE_CONSTANT corresponts to MPI_T_SCOPE_CONSTANT). + */ +typedef enum { + /** The value of this variable will not change after it is + registered. This flag is incompatible with + MCA_BASE_VAR_FLAG_SETTABLE, and also implies + MCA_BASE_VAR_SCOPE_READONLY. */ + PMIX_MCA_BASE_VAR_SCOPE_CONSTANT, + /** Setting the READONLY flag means that the pmix_mca_base_var_set() + function cannot be used to set the value of this variable + (e.g., the MPI_T_cvar_write() MPI_T function). */ + PMIX_MCA_BASE_VAR_SCOPE_READONLY, + /** The value of this variable may be changed locally. */ + PMIX_MCA_BASE_VAR_SCOPE_LOCAL, + /** The value of this variable must be set to a consistent value + within a group */ + PMIX_MCA_BASE_VAR_SCOPE_GROUP, + /** The value of this variable must be set to the same value + within a group */ + PMIX_MCA_BASE_VAR_SCOPE_GROUP_EQ, + /** The value of this variable must be set to a consistent value + for all processes */ + PMIX_MCA_BASE_VAR_SCOPE_ALL, + /** The value of this variable must be set to the same value + for all processes */ + PMIX_MCA_BASE_VAR_SCOPE_ALL_EQ, + PMIX_MCA_BASE_VAR_SCOPE_MAX +} pmix_mca_base_var_scope_t; + +typedef enum { + PMIX_INFO_LVL_1, + PMIX_INFO_LVL_2, + PMIX_INFO_LVL_3, + PMIX_INFO_LVL_4, + PMIX_INFO_LVL_5, + PMIX_INFO_LVL_6, + PMIX_INFO_LVL_7, + PMIX_INFO_LVL_8, + PMIX_INFO_LVL_9, + PMIX_INFO_LVL_MAX +} pmix_mca_base_var_info_lvl_t; + +typedef enum { + PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED = 0x0001, + PMIX_MCA_BASE_VAR_SYN_FLAG_INTERNAL = 0x0002 +} pmix_mca_base_var_syn_flag_t; + +typedef enum { + /** Variable is internal (hidden from *_info/MPIT) */ + PMIX_MCA_BASE_VAR_FLAG_INTERNAL = 0x0001, + /** Variable will always be the default value. Implies + !MCA_BASE_VAR_FLAG_SETTABLE */ + PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY = 0x0002, + /** Variable can be set with pmix_mca_base_var_set() */ + PMIX_MCA_BASE_VAR_FLAG_SETTABLE = 0x0004, + /** Variable is deprecated */ + PMIX_MCA_BASE_VAR_FLAG_DEPRECATED = 0x0008, + /** Variable has been overridden */ + PMIX_MCA_BASE_VAR_FLAG_OVERRIDE = 0x0010, + /** Variable may not be set from a file */ + PMIX_MCA_BASE_VAR_FLAG_ENVIRONMENT_ONLY = 0x0020, + /** Variable should be deregistered when the group is deregistered + (DWG = "deregister with group"). This flag is set + automatically when you register a variable with + pmix_mca_base_component_var_register(), but can also be set + manually when you register a variable with + pmix_mca_base_var_register(). Analogous to the + MCA_BASE_PVAR_FLAG_IWG. */ + PMIX_MCA_BASE_VAR_FLAG_DWG = 0x0040 +} pmix_mca_base_var_flag_t; + + +/** + * Types for MCA parameters. + */ +typedef union { + /** integer value */ + int intval; + /** unsigned int value */ + unsigned int uintval; + /** string value */ + char *stringval; + /** boolean value */ + bool boolval; + /** unsigned long value */ + unsigned long ulval; + /** unsigned long long value */ + unsigned long long ullval; + /** size_t value */ + size_t sizetval; + /** double value */ + double lfval; +} pmix_mca_base_var_storage_t; + + +/** + * Entry for holding information about an MCA variable. + */ +struct pmix_mca_base_var_t { + /** Allow this to be an PMIX OBJ */ + pmix_object_t super; + + /** Variable index. This will remain constant until pmix_mca_base_var_finalize() + is called. */ + int mbv_index; + /** Group index. This will remain constant until pmix_mca_base_var_finalize() + is called. This variable will be deregistered if the associated group + is deregistered with pmix_mca_base_var_group_deregister() */ + int mbv_group_index; + + /** Info level of this variable */ + pmix_mca_base_var_info_lvl_t mbv_info_lvl; + + /** Enum indicating the type of the variable (integer, string, boolean) */ + pmix_mca_base_var_type_t mbv_type; + + /** String of the variable name */ + char *mbv_variable_name; + /** Full variable name, in case it is not __ */ + char *mbv_full_name; + /** Long variable name ___ */ + char *mbv_long_name; + + /** List of synonym names for this variable. This *must* be a + pointer (vs. a plain pmix_list_t) because we copy this whole + struct into a new var for permanent storage + (pmix_vale_array_append_item()), and the internal pointers in + the pmix_list_t will be invalid when that happens. Hence, we + simply keep a pointer to an external pmix_list_t. Synonyms + are uncommon enough that this is not a big performance hit. */ + pmix_value_array_t mbv_synonyms; + + /** Variable flags */ + pmix_mca_base_var_flag_t mbv_flags; + + /** Variable scope */ + pmix_mca_base_var_scope_t mbv_scope; + + /** Source of the current value */ + pmix_mca_base_var_source_t mbv_source; + + /** Synonym for */ + int mbv_synonym_for; + + /** Variable description */ + char *mbv_description; + + /** File the value came from */ + char *mbv_source_file; + + /** Value enumerator (only valid for integer variables) */ + pmix_mca_base_var_enum_t *mbv_enumerator; + + /** Bind value for this variable (0 - none) */ + int mbv_bind; + + /** Storage for this variable */ + pmix_mca_base_var_storage_t *mbv_storage; + + /** File value structure */ + void *mbv_file_value; +}; +/** + * Convenience typedef. + */ +typedef struct pmix_mca_base_var_t pmix_mca_base_var_t; + +/* + * Global functions for MCA + */ + +BEGIN_C_DECLS + +/** + * Object declarayion for pmix_mca_base_var_t + */ +PMIX_CLASS_DECLARATION(pmix_mca_base_var_t); + +/** + * Initialize the MCA variable system. + * + * @retval PMIX_SUCCESS + * + * This function initalizes the MCA variable system. It is + * invoked internally (by pmix_mca_base_open()) and is only documented + * here for completeness. + */ +int pmix_mca_base_var_init(void); + +/** + * Register an MCA variable + * + * @param[in] project_name The name of the project associated with + * this variable + * @param[in] framework_name The name of the framework associated with + * this variable + * @param[in] component_name The name of the component associated with + * this variable + * @param[in] variable_name The name of this variable + * @param[in] description A string describing the use and valid + * values of the variable (string). + * @param[in] type The type of this variable (string, int, bool). + * @param[in] enumerator Enumerator describing valid values. + * @param[in] bind Hint for MPIT to specify type of binding (0 = none) + * @param[in] flags Flags for this variable. + * @param[in] info_lvl Info level of this variable + * @param[in] scope Indicates the scope of this variable + * @param[in,out] storage Pointer to the value's location. + * + * @retval index Index value representing this variable. + * @retval PMIX_ERR_OUT_OF_RESOURCE Upon failure to allocate memory. + * @retval PMIX_ERROR Upon failure to register the variable. + * + * This function registers an MCA variable and associates it + * with a specific group. + * + * {description} is a string of arbitrary length (verbose is good!) + * for explaining what the variable is for and what its valid values + * are. This message is used in help messages, such as the output + * from the ompi_info executable. The {description} string is copied + * internally; the caller can free {description} upon successful + * return. + * + * {enumerator} is either NULL or a handle that was created via + * pmix_mca_base_var_enum_create(), and describes the valid values of an + * integer variable (i.e., one with type MCA_BASE_VAR_TYPE_INT). When + * a non-NULL {enumerator} is used, the value set for this variable by + * the user will be compared against the values in the enumerator. + * The MCA variable system will allow the parameter to be set to + * either one of the enumerator values (0, 1, 2, etc) or a string + * representing one of those values. {enumerator} is retained until + * either the variable is deregistered using + * pmix_mca_base_var_deregister(), pmix_mca_base_var_group_deregister(), or + * pmix_mca_base_var_finalize(). {enumerator} should be NULL for + * parameters that do not support enumerated values. + * + * {flags} indicate attributes of this variable (internal, settable, + * default only, etc.), as listed below. + * + * If MCA_BASE_VAR_FLAG_SETTABLE is set in {flags}, this variable may + * be set using pmix_mca_base_var_set_value() (i.e., the MPI_T interface). + * + * If MCA_BASE_VAR_FLAG_INTERNAL is set in {flags}, this variable + * is not shown by default in the output of ompi_info. That is, + * this variable is considered internal to the PMIX implementation + * and is not supposed to be viewed / changed by the user. + * + * If MCA_BASE_VAR_FLAG_DEFAULT_ONLY is set in {flags}, then the value + * provided in storage will not be modified by the MCA variable system + * (i.e., users cannot set the value of this variable via CLI + * parameter, environment variable, file, etc.). It is up to the + * caller to specify (using the scope) if this value may change + * (MCA_BASE_VAR_SCOPE_READONLY) or remain constant + * (MCA_BASE_VAR_SCOPE_CONSTANT). MCA_BASE_VAR_FLAG_DEFAULT_ONLY must + * not be specified with MCA_BASE_VAR_FLAG_SETTABLE. + * + * Set MCA_BASE_VAR_FLAG_DEPRECATED in {flags} to indicate that + * this variable name is deprecated. The user will get a warning + * if they set this variable. + * + * {scope} is for informational purposes to indicate how this variable + * can be set, or if it is considered constant or readonly (which, by + * MPI_T's definitions, are different things). See the comments in + * the description of pmix_mca_base_var_scope_t for information about the + * different scope meanings. + * + * {storage} points to a (char *), (int), or (bool) where the value of + * this variable is stored ({type} indicates the type of this + * pointer). The location pointed to by {storage} must exist until + * the variable is deregistered. Note that the initial value in + * {storage} may be overwritten if the MCA_BASE_VAR_FLAG_DEFAULT_ONLY + * flag is not set (e.g., if the user sets this variable via CLI + * option, environment variable, or file value). If input value of + * {storage} points to a (char *), the pointed-to string will be + * duplicated and maintained internally by the MCA variable system; + * the caller may free the original string after this function returns + * successfully. + */ +int pmix_mca_base_var_register (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name, + const char *description, pmix_mca_base_var_type_t type, + pmix_mca_base_var_enum_t *enumerator, int bind, pmix_mca_base_var_flag_t flags, + pmix_mca_base_var_info_lvl_t info_lvl, + pmix_mca_base_var_scope_t scope, void *storage); + +/** + * Convenience function for registering a variable associated with a + * component. + * + * While quite similar to pmix_mca_base_var_register(), there is one key + * difference: vars registered this this function will automatically + * be unregistered / made unavailable when that component is closed by + * its framework. + */ +int pmix_mca_base_component_var_register (const pmix_mca_base_component_t *component, + const char *variable_name, const char *description, + pmix_mca_base_var_type_t type, pmix_mca_base_var_enum_t *enumerator, + int bind, pmix_mca_base_var_flag_t flags, + pmix_mca_base_var_info_lvl_t info_lvl, + pmix_mca_base_var_scope_t scope, void *storage); + +/** + * Convenience function for registering a variable associated with a framework. This + * function is equivalent to pmix_mca_base_var_register with component_name = "base" and + * with the MCA_BASE_VAR_FLAG_DWG set. See pmix_mca_base_var_register(). + */ +int pmix_mca_base_framework_var_register (const pmix_mca_base_framework_t *framework, + const char *variable_name, + const char *help_msg, pmix_mca_base_var_type_t type, + pmix_mca_base_var_enum_t *enumerator, int bind, + pmix_mca_base_var_flag_t flags, + pmix_mca_base_var_info_lvl_t info_level, + pmix_mca_base_var_scope_t scope, void *storage); + +/** + * Register a synonym name for an MCA variable. + * + * @param[in] synonym_for The index of the original variable. This index + * must not refer to a synonym. + * @param[in] project_name The project this synonym belongs to. Should + * not be NULL (except for legacy reasons). + * @param[in] framework_name The framework this synonym belongs to. + * @param[in] component_name The component this synonym belongs to. + * @param[in] synonym_name The synonym name. + * @param[in] flags Flags for this synonym. + * + * @returns index Variable index for new synonym on success. + * @returns PMIX_ERR_BAD_VAR If synonym_for does not reference a valid + * variable. + * @returns PMIX_ERR_OUT_OF_RESOURCE If memory could not be allocated. + * @returns PMIX_ERROR For all other errors. + * + * Upon success, this function creates a synonym MCA variable + * that will be treated almost exactly like the original. The + * type (int or string) is irrelevant; this function simply + * creates a new name that by which the same variable value is + * accessible. + * + * Note that the original variable name has precendence over all + * synonyms. For example, consider the case if variable is + * originally registered under the name "A" and is later + * registered with synonyms "B" and "C". If the user sets values + * for both MCA variable names "A" and "B", the value associated + * with the "A" name will be used and the value associated with + * the "B" will be ignored (and will not even be visible by the + * pmix_mca_base_var_*() API). If the user sets values for both MCA + * variable names "B" and "C" (and does *not* set a value for + * "A"), it is undefined as to which value will be used. + */ +int pmix_mca_base_var_register_synonym (int synonym_for, const char *project_name, + const char *framework_name, + const char *component_name, + const char *synonym_name, + pmix_mca_base_var_syn_flag_t flags); + +/** + * Deregister a MCA variable or synonym + * + * @param vari Index returned from pmix_mca_base_var_register() or + * pmix_mca_base_var_register_synonym(). + * + * Deregistering a variable does not free the variable or any memory assoicated + * with it. All memory will be freed and the variable index released when + * pmix_mca_base_var_finalize() is called. + * + * If an enumerator is associated with this variable it will be dereferenced. + */ +int pmix_mca_base_var_deregister(int vari); + + +/** + * Get the current value of an MCA variable. + * + * @param[in] vari Index of variable + * @param[in,out] value Pointer to copy the value to. Can be NULL. + * @param[in,out] value_size Size of memory pointed to by value. + * copied size will be returned in value_size. + * @param[out] source Source of current value. Can be NULL. + * @param[out] source_file Source file for the current value if + * it was set from a file. + * + * @return PMIX_ERROR Upon failure. The contents of value are + * undefined. + * @return PMIX_SUCCESS Upon success. value (if not NULL) will be filled + * with the variable's current value. value_size will contain the size + * copied. source (if not NULL) will contain the source of the variable. + * + * Note: The value can be changed by the registering code without using + * the pmix_mca_base_var_* interface so the source may be incorrect. + */ +int pmix_mca_base_var_get_value (int vari, const void *value, + pmix_mca_base_var_source_t *source, + const char **source_file); + +/** + * Sets an "override" value for an integer MCA variable. + * + * @param[in] vari Index of MCA variable to set + * @param[in] value Pointer to the value to set. Should point to + * a char * for string variables or a int * for integer variables. + * @param[in] size Size of value. + * @param[in] source Source of this value. + * @param[in] source_file Source file if source is MCA_BASE_VAR_SOURCE_FILE. + * + * @retval PMIX_SUCCESS Upon success. + * @retval PMIX_ERR_PERM If the variable is not settable. + * @retval PMIX_ERR_BAD_PARAM If the variable does not exist or has + * been deregistered. + * @retval PMIX_ERROR On other error. + * + * This function sets the value of an MCA variable. This value will + * overwrite the current value of the variable (or if index represents + * a synonym the variable the synonym represents) if the value is + * settable. + */ +int pmix_mca_base_var_set_value (int vari, const void *value, size_t size, + pmix_mca_base_var_source_t source, + const char *source_file); + +/** + * Get the string name corresponding to the MCA variable + * value in the environment. + * + * @param param_name Name of the type containing the variable. + * + * @retval string A string suitable for setenv() or appending to + * an environ-style string array. + * @retval NULL Upon failure. + * + * The string that is returned is owned by the caller; if + * appropriate, it must be eventually freed by the caller. + */ +int pmix_mca_base_var_env_name(const char *param_name, + char **env_name); + +/** + * Find the index for an MCA variable based on its names. + * + * @param project_name Name of the project + * @param type_name Name of the type containing the variable. + * @param component_name Name of the component containing the variable. + * @param param_name Name of the variable. + * + * @retval PMIX_ERROR If the variable was not found. + * @retval vari If the variable was found. + * + * It is not always convenient to widely propagate a variable's index + * value, or it may be necessary to look up the variable from a + * different component. This function can be used to look up the index + * of any registered variable. The returned index can be used with + * pmix_mca_base_var_get() and pmix_mca_base_var_get_value(). + */ +int pmix_mca_base_var_find (const char *project_name, + const char *type_name, + const char *component_name, + const char *param_name); + +/** + * Find the index for a variable based on its full name + * + * @param full_name [in] Full name of the variable + * @param vari [out] Index of the variable + * + * See pmix_mca_base_var_find(). + */ +int pmix_mca_base_var_find_by_name (const char *full_name, int *vari); + +/** + * Check that two MCA variables were not both set to non-default + * values. + * + * @param type_a [in] Framework name of variable A (string). + * @param component_a [in] Component name of variable A (string). + * @param param_a [in] Variable name of variable A (string. + * @param type_b [in] Framework name of variable A (string). + * @param component_b [in] Component name of variable A (string). + * @param param_b [in] Variable name of variable A (string. + * + * This function is useful for checking that the user did not set both + * of 2 mutually-exclusive MCA variables. + * + * This function will print an pmix_show_help() message and return + * PMIX_ERR_BAD_VAR if it finds that the two variables both have + * value sources that are not MCA_BASE_VAR_SOURCE_DEFAULT. This + * means that both variables have been set by the user (i.e., they're + * not default values). + * + * Note that pmix_show_help() allows itself to be hooked, so if this + * happens after the aggregated pmix_show_help() system is + * initialized, the messages will be aggregated (w00t). + * + * @returns PMIX_ERR_BAD_VAR if the two variables have sources that + * are not MCA_BASE_VAR_SOURCE_DEFAULT. + * @returns PMIX_SUCCESS otherwise. + */ +int pmix_mca_base_var_check_exclusive (const char *project, + const char *type_a, + const char *component_a, + const char *param_a, + const char *type_b, + const char *component_b, + const char *param_b); + +/** + * Set or unset a flag on a variable. + * + * @param[in] vari Index of variable + * @param[in] flag Flag(s) to set or unset. + * @param[in] set Boolean indicating whether to set flag(s). + * + * @returns PMIX_SUCCESS If the flags are set successfully. + * @returns PMIX_ERR_BAD_PARAM If the variable is not registered. + * @returns PMIX_ERROR Otherwise + */ +int pmix_mca_base_var_set_flag(int vari, pmix_mca_base_var_flag_t flag, + bool set); + +/** + * Obtain basic info on a single variable (name, help message, etc) + * + * @param[in] vari Valid variable index. + * @param[out] var Storage for the variable pointer. + * + * @retval PMIX_SUCCESS Upon success. + * @retval pmix error code Upon failure. + * + * The returned pointer belongs to the MCA variable system. Do not + * modify/free/retain the pointer. + */ +int pmix_mca_base_var_get (int vari, const pmix_mca_base_var_t **var); + +/** + * Obtain the number of variables that have been registered. + * + * @retval count on success + * @return pmix error code on error + * + * Note: This function does not return the number of valid MCA variables as + * pmix_mca_base_var_deregister() has no impact on the variable count. The count + * returned is equal to the number of calls to pmix_mca_base_var_register with + * unique names. ie. two calls with the same name will not affect the count. + */ +int pmix_mca_base_var_get_count (void); + +/** + * Obtain a list of enironment variables describing the all + * valid (non-default) MCA variables and their sources. + * + * @param[out] env A pointer to an argv-style array of key=value + * strings, suitable for use in an environment + * @param[out] num_env A pointer to an int, containing the length + * of the env array (not including the final NULL entry). + * @param[in] internal Whether to include internal variables. + * + * @retval PMIX_SUCCESS Upon success. + * @retval PMIX_ERROR Upon failure. + * + * This function is similar to pmix_mca_base_var_dump() except that + * its output is in terms of an argv-style array of key=value + * strings, suitable for using in an environment. + */ +int pmix_mca_base_var_build_env(char ***env, int *num_env, + bool internal); + +/** + * Shut down the MCA variable system (normally only invoked by the + * MCA framework itself). + * + * @returns PMIX_SUCCESS This function never fails. + * + * This function shuts down the MCA variable repository and frees all + * associated memory. No other pmix_mca_base_var*() functions can be + * invoked after this function. + * + * This function is normally only invoked by the MCA framework itself + * when the process is shutting down (e.g., during MPI_FINALIZE). It + * is only documented here for completeness. + */ +int pmix_mca_base_var_finalize(void); + +typedef enum { + /* Dump human-readable strings */ + PMIX_MCA_BASE_VAR_DUMP_READABLE = 0, + /* Dump easily parsable strings */ + PMIX_MCA_BASE_VAR_DUMP_PARSABLE = 1, + /* Dump simple name=value string */ + PMIX_MCA_BASE_VAR_DUMP_SIMPLE = 2 +} pmix_mca_base_var_dump_type_t; + +/** + * Dump strings describing the MCA variable at an index. + * + * @param[in] vari Variable index + * @param[out] out Array of strings describing this variable + * @param[in] output_type Type of output desired + * + * This function returns an array of strings describing the variable. All strings + * and the array must be freed by the caller. + */ +int pmix_mca_base_var_dump(int vari, char ***out, pmix_mca_base_var_dump_type_t output_type); + +#define MCA_COMPILETIME_VER "print_compiletime_version" +#define MCA_RUNTIME_VER "print_runtime_version" + +int pmix_mca_base_var_cache_files (bool rel_path_search); + +/* + * Parse a provided list of envars and add their local value, or + * their assigned value, to the provided argv + */ +int pmix_mca_base_var_process_env_list(char ***argv); +int pmix_mca_base_var_process_env_list_from_file(char ***argv); + +END_C_DECLS + +#endif /* PMIX_MCA_BASE_VAR_H */ 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 new file mode 100644 index 0000000000..b5bb281b68 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.c @@ -0,0 +1,623 @@ +/* -*- 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-2012 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "src/mca/base/pmix_mca_base_var_enum.h" +#include "src/mca/base/base.h" +#include "src/util/argv.h" +#include "src/util/error.h" + +#include +#include +#include + +static void pmix_mca_base_var_enum_constructor (pmix_mca_base_var_enum_t *enumerator); +static void pmix_mca_base_var_enum_destructor (pmix_mca_base_var_enum_t *enumerator); +PMIX_CLASS_INSTANCE(pmix_mca_base_var_enum_t, pmix_object_t, pmix_mca_base_var_enum_constructor, + pmix_mca_base_var_enum_destructor); + +static void pmix_mca_base_var_enum_flag_constructor (pmix_mca_base_var_enum_flag_t *enumerator); +static void pmix_mca_base_var_enum_flag_destructor (pmix_mca_base_var_enum_flag_t *enumerator); +PMIX_CLASS_INSTANCE(pmix_mca_base_var_enum_flag_t, pmix_object_t, pmix_mca_base_var_enum_flag_constructor, + pmix_mca_base_var_enum_flag_destructor); + +static int enum_dump (pmix_mca_base_var_enum_t *self, char **out); +static int enum_get_count (pmix_mca_base_var_enum_t *self, int *count); +static int enum_get_value (pmix_mca_base_var_enum_t *self, int index, int *value, const char **string_value); + +static int pmix_mca_base_var_enum_bool_get_count (pmix_mca_base_var_enum_t *enumerator, int *count) +{ + *count = 2; + return PMIX_SUCCESS; +} + +static int pmix_mca_base_var_enum_bool_get_value (pmix_mca_base_var_enum_t *self, int index, + int *value, const char **string_value) +{ + if (1 < index) { + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + + *value = index ? 1 : 0; + *string_value = index ? "true" : "false"; + + return PMIX_SUCCESS; +} + +static int pmix_mca_base_var_enum_bool_vfs (pmix_mca_base_var_enum_t *self, const char *string_value, + int *value) +{ + char *tmp; + int v; + + /* skip whitespace */ + string_value += strspn (string_value, " \t\n\v\f\r"); + + v = strtol (string_value, &tmp, 10); + if (*tmp != '\0') { + if (0 == strcmp (string_value, "true") || 0 == strcmp (string_value, "t") || + 0 == strcmp (string_value, "enabled") || 0 == strcmp (string_value, "yes")) { + v = 1; + } else if (0 == strcmp (string_value, "false") || 0 == strcmp (string_value, "f") || + 0 == strcmp (string_value, "disabled") || 0 == strcmp (string_value, "no")) { + v = 0; + } else { + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + } + + *value = !!v; + + return PMIX_SUCCESS; +} + +static int pmix_mca_base_var_enum_bool_sfv (pmix_mca_base_var_enum_t *self, const int value, + char **string_value) +{ + if (string_value) { + *string_value = strdup (value ? "true" : "false"); + } + + return PMIX_SUCCESS; +} + +static int pmix_mca_base_var_enum_bool_dump (pmix_mca_base_var_enum_t *self, char **out) +{ + *out = strdup ("0: f|false|disabled|no, 1: t|true|enabled|yes"); + return *out ? PMIX_SUCCESS : PMIX_ERR_OUT_OF_RESOURCE; +} + +pmix_mca_base_var_enum_t pmix_mca_base_var_enum_bool = { + .super = PMIX_OBJ_STATIC_INIT(pmix_object_t), + .enum_is_static = true, + .enum_name = "boolean", + .get_count = pmix_mca_base_var_enum_bool_get_count, + .get_value = pmix_mca_base_var_enum_bool_get_value, + .value_from_string = pmix_mca_base_var_enum_bool_vfs, + .string_from_value = pmix_mca_base_var_enum_bool_sfv, + .dump = pmix_mca_base_var_enum_bool_dump +}; + +/* verbosity enumerator */ +static pmix_mca_base_var_enum_value_t verbose_values[] = { + {PMIX_MCA_BASE_VERBOSE_NONE, "none"}, + {PMIX_MCA_BASE_VERBOSE_ERROR, "error"}, + {PMIX_MCA_BASE_VERBOSE_COMPONENT, "component"}, + {PMIX_MCA_BASE_VERBOSE_WARN, "warn"}, + {PMIX_MCA_BASE_VERBOSE_INFO, "info"}, + {PMIX_MCA_BASE_VERBOSE_TRACE, "trace"}, + {PMIX_MCA_BASE_VERBOSE_DEBUG, "debug"}, + {PMIX_MCA_BASE_VERBOSE_MAX, "max"}, + {-1, NULL} +}; + +static int pmix_mca_base_var_enum_verbose_vfs (pmix_mca_base_var_enum_t *self, const char *string_value, + int *value) +{ + char *tmp; + int v; + + /* skip whitespace */ + string_value += strspn (string_value, " \t\n\v\f\r"); + + v = strtol (string_value, &tmp, 10); + if (*tmp != '\0') { + for (int i = 0 ; verbose_values[i].string ; ++i) { + if (0 == strcmp (verbose_values[i].string, string_value)) { + *value = verbose_values[i].value; + return PMIX_SUCCESS; + } + } + + return PMIX_ERR_NOT_FOUND; + } else if (v < PMIX_MCA_BASE_VERBOSE_NONE) { + v = PMIX_MCA_BASE_VERBOSE_NONE; + } else if (v > PMIX_MCA_BASE_VERBOSE_MAX) { + v = PMIX_MCA_BASE_VERBOSE_MAX; + } + + *value = v; + + return PMIX_SUCCESS; +} + +static int pmix_mca_base_var_enum_verbose_sfv (pmix_mca_base_var_enum_t *self, const int value, + char **string_value) +{ + int ret; + + if (value < 0 || value > 100) { + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + + for (int i = 0 ; verbose_values[i].string ; ++i) { + if (verbose_values[i].value == value) { + *string_value = strdup (verbose_values[i].string); + return PMIX_SUCCESS; + } + } + + if (string_value) { + ret = asprintf (string_value, "%d", value); + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + } + + return PMIX_SUCCESS; +} + +static int pmix_mca_base_var_enum_verbose_dump (pmix_mca_base_var_enum_t *self, char **out) +{ + char *tmp; + int ret; + + ret = enum_dump (self, out); + if (PMIX_SUCCESS != ret) { + return ret; + } + + ret = asprintf (&tmp, "%s, 0 - 100", *out); + free (*out); + if (0 > ret) { + *out = NULL; + return PMIX_ERR_OUT_OF_RESOURCE; + } + + *out = tmp; + + return PMIX_SUCCESS; +} + +pmix_mca_base_var_enum_t pmix_mca_base_var_enum_verbose = { + .super = PMIX_OBJ_STATIC_INIT(pmix_object_t), + .enum_is_static = true, + .enum_name = "verbosity", + .get_count = enum_get_count, + .get_value = enum_get_value, + .value_from_string = pmix_mca_base_var_enum_verbose_vfs, + .string_from_value = pmix_mca_base_var_enum_verbose_sfv, + .dump = pmix_mca_base_var_enum_verbose_dump, + .enum_value_count = 8, + .enum_values = verbose_values, +}; + + +int pmix_mca_base_var_enum_create (const char *name, const pmix_mca_base_var_enum_value_t *values, pmix_mca_base_var_enum_t **enumerator) +{ + pmix_mca_base_var_enum_t *new_enum; + int i; + + *enumerator = NULL; + + new_enum = PMIX_NEW(pmix_mca_base_var_enum_t); + if (NULL == new_enum) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + new_enum->enum_name = strdup (name); + if (NULL == new_enum->enum_name) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + for (i = 0 ; values[i].string ; ++i); + new_enum->enum_value_count = i; + + /* make a copy of the values */ + new_enum->enum_values = calloc (new_enum->enum_value_count + 1, sizeof (*new_enum->enum_values)); + if (NULL == new_enum->enum_values) { + PMIX_RELEASE(new_enum); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + for (i = 0 ; i < new_enum->enum_value_count ; ++i) { + new_enum->enum_values[i].value = values[i].value; + new_enum->enum_values[i].string = strdup (values[i].string); + } + + *enumerator = new_enum; + + return PMIX_SUCCESS; +} + +int pmix_mca_base_var_enum_create_flag (const char *name, const pmix_mca_base_var_enum_value_flag_t *flags, pmix_mca_base_var_enum_flag_t **enumerator) +{ + pmix_mca_base_var_enum_flag_t *new_enum; + int i; + + *enumerator = NULL; + + new_enum = PMIX_NEW(pmix_mca_base_var_enum_flag_t); + if (NULL == new_enum) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + new_enum->super.enum_name = strdup (name); + if (NULL == new_enum->super.enum_name) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + for (i = 0 ; flags[i].string ; ++i); + new_enum->super.enum_value_count = i; + + /* make a copy of the values */ + new_enum->enum_flags = calloc (new_enum->super.enum_value_count + 1, sizeof (*new_enum->enum_flags)); + if (NULL == new_enum->enum_flags) { + PMIX_RELEASE(new_enum); + return PMIX_ERR_OUT_OF_RESOURCE; + } + + int all_flags = 0; + for (i = 0 ; i < new_enum->super.enum_value_count ; ++i) { + new_enum->enum_flags[i].flag = flags[i].flag; + new_enum->enum_flags[i].string = strdup (flags[i].string); + new_enum->enum_flags[i].conflicting_flag = flags[i].conflicting_flag; + /* ensure flags are only set a single bit, doesn't conflict with itself, and + * hasn't already been specified. */ + assert (!(flags[i].flag & (flags[i].flag - 1))); + assert (!(flags[i].flag & flags[i].conflicting_flag)); + assert (!(all_flags & flags[i].flag)); + assert (flags[i].flag); + all_flags |= flags[i].flag; + } + + *enumerator = new_enum; + + return PMIX_SUCCESS; +} + +static int enum_dump (pmix_mca_base_var_enum_t *self, char **out) +{ + int i; + char *tmp; + int ret; + + *out = NULL; + + if (NULL == self) { + return PMIX_ERROR; + } + + tmp = NULL; + for (i = 0; i < self->enum_value_count && self->enum_values[i].string ; ++i) { + ret = asprintf (out, "%s%s%d:\"%s\"", tmp ? tmp : "", tmp ? ", " : "", self->enum_values[i].value, + self->enum_values[i].string); + if (tmp) free (tmp); + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + tmp = *out; + } + + return PMIX_SUCCESS; +} + +static int enum_get_count (pmix_mca_base_var_enum_t *self, int *count) +{ + *count = self->enum_value_count; + return PMIX_SUCCESS; +} + +static int enum_get_value (pmix_mca_base_var_enum_t *self, int index, int *value, const char **string_value) +{ + int count, ret; + + ret = self->get_count(self, &count); + if (PMIX_SUCCESS != ret) { + return ret; + } + + if (index >= count) { + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + + if (value) { + *value = self->enum_values[index].value; + } + + if (string_value) { + *string_value = strdup (self->enum_values[index].string); + } + + return PMIX_SUCCESS; +} + +static int enum_value_from_string(pmix_mca_base_var_enum_t *self, const char *string_value, int *value_out) { + int value, count, ret, i; + bool is_int; + char *tmp; + + ret = self->get_count(self, &count); + if (PMIX_SUCCESS != ret) { + return ret; + } + + value = strtol(string_value, &tmp, 0); + + /* Check if the string is an integer */ + is_int = tmp[0] == '\0'; + + for (i = 0 ; i < count ; ++i) { + if ((is_int && value == self->enum_values[i].value) || + 0 == strcasecmp (string_value, self->enum_values[i].string)) { + break; + } + } + + if (i == count) { + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + + *value_out = self->enum_values[i].value; + + return PMIX_SUCCESS; +} + +static int enum_string_from_value(pmix_mca_base_var_enum_t *self, const int value, char **string_value) { + int count, ret, i; + + ret = self->get_count(self, &count); + if (PMIX_SUCCESS != ret) { + return ret; + } + + for (i = 0 ; i < count ; ++i) { + if (value == self->enum_values[i].value) { + break; + } + } + + if (i == count) { + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + + if (string_value) { + *string_value = strdup (self->enum_values[i].string); + } + + return PMIX_SUCCESS; +} + +static void pmix_mca_base_var_enum_constructor (pmix_mca_base_var_enum_t *enumerator) +{ + memset ((char *) enumerator + sizeof (enumerator->super), 0 , sizeof(*enumerator) - sizeof(enumerator->super)); + + enumerator->get_value = enum_get_value; + enumerator->get_count = enum_get_count; + enumerator->value_from_string = enum_value_from_string; + enumerator->string_from_value = enum_string_from_value; + enumerator->dump = enum_dump; + enumerator->enum_is_static = false; +} + +static void pmix_mca_base_var_enum_destructor (pmix_mca_base_var_enum_t *enumerator) +{ + if (enumerator->enum_name) { + free (enumerator->enum_name); + } + + /* release the copy of the values */ + if (enumerator->enum_values) { + for (int i = 0 ; i < enumerator->enum_value_count ; ++i) { + free ((void *) enumerator->enum_values[i].string); + } + free (enumerator->enum_values); + } +} + +static int enum_get_value_flag (pmix_mca_base_var_enum_t *self, int index, int *value, const char **string_value) +{ + pmix_mca_base_var_enum_flag_t *flag_enum = (pmix_mca_base_var_enum_flag_t *) self; + int count, ret; + + ret = self->get_count(self, &count); + if (PMIX_SUCCESS != ret) { + return ret; + } + + if (index >= count) { + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + + if (value) { + *value = flag_enum->enum_flags[index].flag; + } + + if (string_value) { + *string_value = strdup (flag_enum->enum_flags[index].string); + } + + return PMIX_SUCCESS; +} + +static int enum_value_from_string_flag (pmix_mca_base_var_enum_t *self, const char *string_value, int *value_out) { + pmix_mca_base_var_enum_flag_t *flag_enum = (pmix_mca_base_var_enum_flag_t *) self; + int value, count, ret, flag; + char **flags; + bool is_int; + char *tmp; + + ret = self->get_count(self, &count); + if (PMIX_SUCCESS != ret) { + return ret; + } + + flags = pmix_argv_split (string_value, ','); + if (NULL == flags) { + return PMIX_ERR_BAD_PARAM; + } + + flag = 0; + + for (int i = 0 ; flags[i] ; ++i) { + value = strtol (flags[i], &tmp, 0); + is_int = tmp[0] == '\0'; + + bool found = false, conflict = false; + for (int j = 0 ; j < count ; ++j) { + if ((is_int && (value == flag_enum->enum_flags[i].flag)) || + 0 == strcasecmp (flags[i], flag_enum->enum_flags[i].string)) { + found = true; + + if (flag & flag_enum->enum_flags[i].conflicting_flag) { + conflict = true; + } else { + flag |= flag_enum->enum_flags[i].flag; + } + + break; + } + } + + if (!found || conflict) { + pmix_argv_free (flags); + return !found ? PMIX_ERR_VALUE_OUT_OF_BOUNDS : PMIX_ERR_BAD_PARAM; + } + } + + pmix_argv_free (flags); + *value_out = flag; + + return PMIX_SUCCESS; +} + +static int enum_string_from_value_flag (pmix_mca_base_var_enum_t *self, const int value, char **string_value) { + pmix_mca_base_var_enum_flag_t *flag_enum = (pmix_mca_base_var_enum_flag_t *) self; + int count, ret, current; + char *out = NULL, *tmp; + + ret = self->get_count(self, &count); + if (PMIX_SUCCESS != ret) { + return ret; + } + + current = value; + for (int i = 0 ; i < count ; ++i) { + if (!(flag_enum->enum_flags[i].flag & current)) { + continue; + } + + tmp = out; + + ret = asprintf (&out, "%s%s%s", tmp ? tmp : "", tmp ? "," : "", flag_enum->enum_flags[i].string); + free (tmp); + + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + if (value & flag_enum->enum_flags[i].conflicting_flag) { + free (out); + return PMIX_ERR_BAD_PARAM; + } + + current &= ~flag_enum->enum_flags[i].flag; + } + + if (current) { + free (out); + return PMIX_ERR_VALUE_OUT_OF_BOUNDS; + } + + if (string_value) { + *string_value = out ? out : strdup (""); + } else { + free (out); + } + + return PMIX_SUCCESS; +} + +static int enum_dump_flag (pmix_mca_base_var_enum_t *self, char **out) +{ + pmix_mca_base_var_enum_flag_t *flag_enum = (pmix_mca_base_var_enum_flag_t *) self; + char *tmp; + int ret; + + *out = NULL; + + if (NULL == self) { + return PMIX_ERROR; + } + + *out = strdup ("Comma-delimited list of: "); + if (NULL == *out) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + for (int i = 0; i < self->enum_value_count ; ++i) { + tmp = *out; + + ret = asprintf (out, "%s%s0x%x:\"%s\"", tmp, i ? ", " : " ", flag_enum->enum_flags[i].flag, + flag_enum->enum_flags[i].string); + free (tmp); + if (0 > ret) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + } + + return PMIX_SUCCESS; +} + +static void pmix_mca_base_var_enum_flag_constructor (pmix_mca_base_var_enum_flag_t *enumerator) +{ + enumerator->enum_flags = NULL; + enumerator->super.get_value = enum_get_value_flag; + enumerator->super.get_count = enum_get_count; + enumerator->super.value_from_string = enum_value_from_string_flag; + enumerator->super.string_from_value = enum_string_from_value_flag; + enumerator->super.dump = enum_dump_flag; + enumerator->super.enum_is_static = false; +} + +static void pmix_mca_base_var_enum_flag_destructor (pmix_mca_base_var_enum_flag_t *enumerator) +{ + /* release the copy of the values */ + if (enumerator->enum_flags) { + for (int i = 0 ; i < enumerator->super.enum_value_count ; ++i) { + free ((void *) enumerator->enum_flags[i].string); + } + free (enumerator->enum_flags); + } +} 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 new file mode 100644 index 0000000000..fbe0bcaee4 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_enum.h @@ -0,0 +1,246 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#if !defined(PMIX_MCA_BASE_VAR_ENUM_H) +#define PMIX_MCA_BASE_VAR_ENUM_H + +#include + +#include "src/class/pmix_object.h" +#include "pmix_common.h" + +typedef struct pmix_mca_base_var_enum_t pmix_mca_base_var_enum_t; + +/** + * Get the number of values in the enumerator + * + * @param[in] self the enumerator + * @param[out] count the number of values in the enumerator + */ +typedef int (*pmix_mca_base_var_enum_get_count_fn_t)(pmix_mca_base_var_enum_t *self, int *count); + +/** + * Get the value and its string representation for an index 0..get_count() + * + * @param[in] self the enumerator + * @param[in] index the index to get the value of + * @param[out] value integer value + * @param[out] string_value string value + */ +typedef int (*pmix_mca_base_var_enum_get_value_fn_t)(pmix_mca_base_var_enum_t *self, int index, + int *value, const char **string_value); + +/** + * Look up the integer value of a string + * + * @param[in] self the enumerator + * @param[in] string_value string to lookup + * @param[out] value integer value for the string + * + * @retval PMIX_SUCCESS if found + * @retval PMIX_ERR_VALUE_OUT_OF_BOUNDS if not + */ +typedef int (*pmix_mca_base_var_enum_vfs_fn_t)(pmix_mca_base_var_enum_t *self, const char *string_value, + int *value); + +/** + * Dump a textual representation of all the values in an enumerator + * + * @param[in] self the enumerator + * @param[out] out the string representation + * + * @retval PMIX_SUCCESS on success + * @retval pmix error on error + */ +typedef int (*pmix_mca_base_var_enum_dump_fn_t)(pmix_mca_base_var_enum_t *self, char **out); + +/** + * Get the string representation for an enumerator value + * + * @param[in] self the enumerator + * @param[in] value integer value + * @param[out] string_value string value for value + * + * @retval PMIX_SUCCESS on success + * @retval PMIX_ERR_VALUE_OUT_OF_BOUNDS if not found + * + * @long This function returns the string value for a given interger value in the + * {string_value} parameter. The {string_value} parameter may be NULL in which case + * no string is returned. If a string is returned in {string_value} the caller + * must free the string with free(). + */ +typedef int (*pmix_mca_base_var_enum_sfv_fn_t)(pmix_mca_base_var_enum_t *self, const int value, + char **string_value); + +/** + * The default enumerator class takes in a list of integer-string pairs. If a + * string is read from an environment variable or a file value the matching + * integer value is used for the MCA variable. + */ +struct pmix_mca_base_var_enum_value_t { + int value; + const char *string; +}; + +typedef struct pmix_mca_base_var_enum_value_t pmix_mca_base_var_enum_value_t; + +/** + * enumerator base class + */ +struct pmix_mca_base_var_enum_t { + pmix_object_t super; + + /** Is the enumerator statically allocated */ + bool enum_is_static; + + /** Name of this enumerator. This value is duplicated from the argument provided to + pmix_mca_base_var_enum_create() */ + char *enum_name; + + /** Get the number of values this enumerator represents. Subclasses should override + the default function. */ + pmix_mca_base_var_enum_get_count_fn_t get_count; + /** Get the value and string representation for a particular index. Subclasses should + override the default function */ + pmix_mca_base_var_enum_get_value_fn_t get_value; + /** Given a string return corresponding integer value. If the string does not match a + valid value return PMIX_ERR_VALUE_OUT_OF_BOUNDS */ + pmix_mca_base_var_enum_vfs_fn_t value_from_string; + /** Given an integer return the corresponding string value. If the integer does not + match a valid value return PMIX_ERR_VALUE_OUT_OF_BOUNDS */ + pmix_mca_base_var_enum_sfv_fn_t string_from_value; + /** Dump a textual representation of the enumerator. The caller is responsible for + freeing the string */ + pmix_mca_base_var_enum_dump_fn_t dump; + + int enum_value_count; + /** Copy of the enumerators values (used by the default functions). This array and + and the strings it contains are freed by the destructor if not NULL. */ + pmix_mca_base_var_enum_value_t *enum_values; +}; + + +/** + * The default flag enumerator class takes in a list of integer-string pairs. If a + * string is read from an environment variable or a file value the matching + * flag value is used for the MCA variable. The conflicting_flag is used to + * indicate any flags that should conflict. + */ +struct pmix_mca_base_var_enum_value_flag_t { + /** flag value (must be power-of-two) */ + int flag; + /** corresponding string name */ + const char *string; + /** conflicting flag(s) if any */ + int conflicting_flag; +}; + +typedef struct pmix_mca_base_var_enum_value_flag_t pmix_mca_base_var_enum_value_flag_t; + +/** + * flag enumerator base class + */ +struct pmix_mca_base_var_enum_flag_t { + /** use the existing enumerator interface */ + pmix_mca_base_var_enum_t super; + /** flag value(s) */ + pmix_mca_base_var_enum_value_flag_t *enum_flags; +}; + +typedef struct pmix_mca_base_var_enum_flag_t pmix_mca_base_var_enum_flag_t; + +/** + * Object declaration for pmix_mca_base_var_enum_t + */ +PMIX_CLASS_DECLARATION(pmix_mca_base_var_enum_t); + +/** + * Create a new default enumerator + * + * @param[in] name Name for this enumerator + * @param[in] values List of values terminated with a NULL .string + * member. + * @param[out] enumerator Newly created enumerator. + * + * @retval PMIX_SUCCESS On success + * @retval pmix error code On error + * + * This function creates a value enumerator for integer variables. The + * OUT enumerator value will be a newly OBJ_NEW'ed object that should + * be released by the caller via OBJ_RELEASE. + * + * Note that the output enumerator can be OBJ_RELEASE'd after it has + * been used in a cvar or pvar registration, because the variable + * registration functions will OBJ_RETAIN the enumberator. + * + * Note that all the strings in the values[] array are strdup'ed into + * internal storage, meaning that the caller can free all of the + * strings passed in values[] after pmix_mca_base_var_enum_create() + * returns. + */ +int pmix_mca_base_var_enum_create (const char *name, const pmix_mca_base_var_enum_value_t values[], + pmix_mca_base_var_enum_t **enumerator); + +/** + * Create a new default flag enumerator + * + * @param[in] name Name for this enumerator + * @param[in] flags List of flags terminated with a NULL .string + * member. + * @param[out] enumerator Newly created enumerator. + * + * @retval PMIX_SUCCESS On success + * @retval pmix error code On error + * + * This function creates a flag enumerator for integer variables. The + * OUT enumerator value will be a newly OBJ_NEW'ed object that should + * be released by the caller via OBJ_RELEASE. + * + * Note that the output enumerator can be OBJ_RELEASE'd after it has + * been used in a cvar or pvar registration, because the variable + * registration functions will OBJ_RETAIN the enumberator. + * + * Note that all the strings in the values[] array are strdup'ed into + * internal storage, meaning that the caller can free all of the + * strings passed in values[] after pmix_mca_base_var_enum_create() + * returns. + */ +int pmix_mca_base_var_enum_create_flag (const char *name, const pmix_mca_base_var_enum_value_flag_t flags[], + pmix_mca_base_var_enum_flag_t **enumerator); + +/* standard enumerators. it is invalid to call OBJ_RELEASE on any of these enumerators */ +/** + * Boolean enumerator + * + * This enumerator maps: + * positive integer, true, yes, enabled, t -> 1 + * 0, false, no, disabled, f -> 0 + */ +extern pmix_mca_base_var_enum_t pmix_mca_base_var_enum_bool; + +/** + * Verbosity level enumerator + */ +extern pmix_mca_base_var_enum_t pmix_mca_base_var_enum_verbose; + +#endif /* !defined(MCA_BASE_VAR_ENUM_H) */ 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 new file mode 100644 index 0000000000..8cef65e83c --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.c @@ -0,0 +1,477 @@ +/* -*- 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-2012 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#include + +#include "src/include/pmix_stdint.h" +#include "src/util/show_help.h" +#include "src/mca/mca.h" +#include "src/mca/base/pmix_mca_base_vari.h" +#include "pmix_common.h" +#include "src/util/output.h" +#include "src/util/pmix_environ.h" + +static pmix_pointer_array_t pmix_mca_base_var_groups; +static pmix_hash_table_t pmix_mca_base_var_group_index_hash; +static int pmix_mca_base_var_group_count = 0; +static int pmix_mca_base_var_groups_timestamp = 0; +static bool pmix_mca_base_var_group_initialized = false; + +static void pmix_mca_base_var_group_constructor (pmix_mca_base_var_group_t *group); +static void pmix_mca_base_var_group_destructor (pmix_mca_base_var_group_t *group); +PMIX_CLASS_INSTANCE(pmix_mca_base_var_group_t, pmix_object_t, + pmix_mca_base_var_group_constructor, + pmix_mca_base_var_group_destructor); + +int pmix_mca_base_var_group_init (void) +{ + int ret; + + if (!pmix_mca_base_var_group_initialized) { + PMIX_CONSTRUCT(&pmix_mca_base_var_groups, pmix_pointer_array_t); + + /* These values are arbitrary */ + ret = pmix_pointer_array_init (&pmix_mca_base_var_groups, 128, 16384, 128); + if (PMIX_SUCCESS != ret) { + return ret; + } + + PMIX_CONSTRUCT(&pmix_mca_base_var_group_index_hash, pmix_hash_table_t); + ret = pmix_hash_table_init (&pmix_mca_base_var_group_index_hash, 256); + if (PMIX_SUCCESS != ret) { + return ret; + } + + pmix_mca_base_var_group_initialized = true; + pmix_mca_base_var_group_count = 0; + } + + return PMIX_SUCCESS; +} + +int pmix_mca_base_var_group_finalize (void) +{ + pmix_object_t *object; + int size, i; + + if (pmix_mca_base_var_group_initialized) { + size = pmix_pointer_array_get_size(&pmix_mca_base_var_groups); + for (i = 0 ; i < size ; ++i) { + object = pmix_pointer_array_get_item (&pmix_mca_base_var_groups, i); + if (NULL != object) { + PMIX_RELEASE(object); + } + } + PMIX_DESTRUCT(&pmix_mca_base_var_groups); + PMIX_DESTRUCT(&pmix_mca_base_var_group_index_hash); + pmix_mca_base_var_group_count = 0; + pmix_mca_base_var_group_initialized = false; + } + + return PMIX_SUCCESS; +} + +int pmix_mca_base_var_group_get_internal (const int group_index, pmix_mca_base_var_group_t **group, bool invalidok) +{ + if (group_index < 0) { + return PMIX_ERR_NOT_FOUND; + } + + *group = (pmix_mca_base_var_group_t *) pmix_pointer_array_get_item (&pmix_mca_base_var_groups, + group_index); + if (NULL == *group || (!invalidok && !(*group)->group_isvalid)) { + *group = NULL; + return PMIX_ERR_NOT_FOUND; + } + + return PMIX_SUCCESS; +} + +static int group_find_by_name (const char *full_name, int *index, bool invalidok) +{ + pmix_mca_base_var_group_t *group; + void *tmp; + int rc; + + rc = pmix_hash_table_get_value_ptr (&pmix_mca_base_var_group_index_hash, full_name, + strlen (full_name), &tmp); + if (PMIX_SUCCESS != rc) { + return rc; + } + + rc = pmix_mca_base_var_group_get_internal ((int)(uintptr_t) tmp, &group, invalidok); + if (PMIX_SUCCESS != rc) { + return rc; + } + + if (invalidok || group->group_isvalid) { + *index = (int)(uintptr_t) tmp; + return PMIX_SUCCESS; + } + + return PMIX_ERR_NOT_FOUND; +} + +static bool compare_strings (const char *str1, const char *str2) { + if ((NULL != str1 && 0 == strcmp (str1, "*")) || + (NULL == str1 && NULL == str2)) { + return true; + } + + if (NULL != str1 && NULL != str2) { + return 0 == strcmp (str1, str2); + } + + return false; +} + +static int group_find_linear (const char *project_name, const char *framework_name, + const char *component_name, bool invalidok) +{ + for (int i = 0 ; i < pmix_mca_base_var_group_count ; ++i) { + pmix_mca_base_var_group_t *group; + + int rc = pmix_mca_base_var_group_get_internal (i, &group, invalidok); + if (PMIX_SUCCESS != rc) { + continue; + } + + if (compare_strings (project_name, group->group_project) && + compare_strings (framework_name, group->group_framework) && + compare_strings (component_name, group->group_component)) { + return i; + } + } + + return PMIX_ERR_NOT_FOUND; +} + +static int group_find (const char *project_name, const char *framework_name, + const char *component_name, bool invalidok) +{ + char *full_name; + int ret, index=0; + + if (!pmix_mca_base_var_initialized) { + return PMIX_ERR_NOT_FOUND; + } + + /* check for wildcards */ + if ((project_name && '*' == project_name[0]) || (framework_name && '*' == framework_name[0]) || + (component_name && '*' == component_name[0])) { + return group_find_linear (project_name, framework_name, component_name, invalidok); + } + + ret = pmix_mca_base_var_generate_full_name4(project_name, framework_name, component_name, + NULL, &full_name); + if (PMIX_SUCCESS != ret) { + return PMIX_ERROR; + } + + ret = group_find_by_name(full_name, &index, invalidok); + free (full_name); + + return (0 > ret) ? ret : index; +} + +static int group_register (const char *project_name, const char *framework_name, + const char *component_name, const char *description) +{ + pmix_mca_base_var_group_t *group; + int group_id, parent_id = -1; + int ret; + + if (NULL == project_name && NULL == framework_name && NULL == component_name) { + /* don't create a group with no name (maybe we should create a generic group?) */ + return -1; + } + + /* avoid groups of the form pmix_pmix, etc */ + if (NULL != project_name && NULL != framework_name && + (0 == strcmp (project_name, framework_name))) { + project_name = NULL; + } + + group_id = group_find (project_name, framework_name, component_name, true); + if (0 <= group_id) { + ret = pmix_mca_base_var_group_get_internal (group_id, &group, true); + if (PMIX_SUCCESS != ret) { + /* something went horribly wrong */ + assert (NULL != group); + return ret; + } + group->group_isvalid = true; + pmix_mca_base_var_groups_timestamp++; + + /* group already exists. return it's index */ + return group_id; + } + + group = PMIX_NEW(pmix_mca_base_var_group_t); + + group->group_isvalid = true; + + if (NULL != project_name) { + group->group_project = strdup (project_name); + if (NULL == group->group_project) { + PMIX_RELEASE(group); + return PMIX_ERR_OUT_OF_RESOURCE; + } + } + if (NULL != framework_name) { + group->group_framework = strdup (framework_name); + if (NULL == group->group_framework) { + PMIX_RELEASE(group); + return PMIX_ERR_OUT_OF_RESOURCE; + } + } + if (NULL != component_name) { + group->group_component = strdup (component_name); + if (NULL == group->group_component) { + PMIX_RELEASE(group); + return PMIX_ERR_OUT_OF_RESOURCE; + } + } + if (NULL != description) { + group->group_description = strdup (description); + if (NULL == group->group_description) { + PMIX_RELEASE(group); + return PMIX_ERR_OUT_OF_RESOURCE; + } + } + + if (NULL != framework_name && NULL != component_name) { + parent_id = group_register (project_name, framework_name, NULL, NULL); + } + + /* build the group name */ + ret = pmix_mca_base_var_generate_full_name4 (NULL, project_name, framework_name, component_name, + &group->group_full_name); + if (PMIX_SUCCESS != ret) { + PMIX_RELEASE(group); + return ret; + } + + group_id = pmix_pointer_array_add (&pmix_mca_base_var_groups, group); + if (0 > group_id) { + PMIX_RELEASE(group); + return PMIX_ERROR; + } + + pmix_hash_table_set_value_ptr (&pmix_mca_base_var_group_index_hash, group->group_full_name, + strlen (group->group_full_name), (void *)(uintptr_t) group_id); + + pmix_mca_base_var_group_count++; + pmix_mca_base_var_groups_timestamp++; + + if (0 <= parent_id) { + pmix_mca_base_var_group_t *parent_group; + + (void) pmix_mca_base_var_group_get_internal(parent_id, &parent_group, false); + pmix_value_array_append_item (&parent_group->group_subgroups, &group_id); + } + + return group_id; +} + +int pmix_mca_base_var_group_register (const char *project_name, const char *framework_name, + const char *component_name, const char *description) +{ + return group_register (project_name, framework_name, component_name, description); +} + +int pmix_mca_base_var_group_component_register (const pmix_mca_base_component_t *component, + const char *description) +{ + /* 1.7 components do not store the project */ + return group_register (NULL, component->pmix_mca_type_name, + component->pmix_mca_component_name, description); +} + + +int pmix_mca_base_var_group_deregister (int group_index) +{ + pmix_mca_base_var_group_t *group; + int size, ret; + int *params, *subgroups; + + ret = pmix_mca_base_var_group_get_internal (group_index, &group, false); + if (PMIX_SUCCESS != ret) { + return ret; + } + + group->group_isvalid = false; + + /* deregister all associated mca parameters */ + size = pmix_value_array_get_size(&group->group_vars); + params = PMIX_VALUE_ARRAY_GET_BASE(&group->group_vars, int); + + for (int i = 0 ; i < size ; ++i) { + const pmix_mca_base_var_t *var; + + ret = pmix_mca_base_var_get (params[i], &var); + if (PMIX_SUCCESS != ret || !(var->mbv_flags & PMIX_MCA_BASE_VAR_FLAG_DWG)) { + continue; + } + + (void) pmix_mca_base_var_deregister (params[i]); + } + + size = pmix_value_array_get_size(&group->group_subgroups); + subgroups = PMIX_VALUE_ARRAY_GET_BASE(&group->group_subgroups, int); + for (int i = 0 ; i < size ; ++i) { + (void) pmix_mca_base_var_group_deregister (subgroups[i]); + } + /* ordering of variables and subgroups must be the same if the + * group is re-registered */ + + pmix_mca_base_var_groups_timestamp++; + + return PMIX_SUCCESS; +} + +int pmix_mca_base_var_group_find (const char *project_name, + const char *framework_name, + const char *component_name) +{ + return group_find (project_name, framework_name, component_name, false); +} + +int pmix_mca_base_var_group_find_by_name (const char *full_name, int *index) +{ + return group_find_by_name (full_name, index, false); +} + +int pmix_mca_base_var_group_add_var (const int group_index, const int param_index) +{ + pmix_mca_base_var_group_t *group; + int size, i, ret; + int *params; + + ret = pmix_mca_base_var_group_get_internal (group_index, &group, false); + if (PMIX_SUCCESS != ret) { + return ret; + } + + size = pmix_value_array_get_size(&group->group_vars); + params = PMIX_VALUE_ARRAY_GET_BASE(&group->group_vars, int); + for (i = 0 ; i < size ; ++i) { + if (params[i] == param_index) { + return i; + } + } + + if (PMIX_SUCCESS != + (ret = pmix_value_array_append_item (&group->group_vars, ¶m_index))) { + return ret; + } + + pmix_mca_base_var_groups_timestamp++; + + /* return the group index */ + return (int) pmix_value_array_get_size (&group->group_vars) - 1; +} + +int pmix_mca_base_var_group_get (const int group_index, const pmix_mca_base_var_group_t **group) +{ + return pmix_mca_base_var_group_get_internal (group_index, (pmix_mca_base_var_group_t **) group, false); +} + +int pmix_mca_base_var_group_set_var_flag (const int group_index, int flags, bool set) +{ + pmix_mca_base_var_group_t *group; + int size, i, ret; + int *vars; + + ret = pmix_mca_base_var_group_get_internal (group_index, &group, false); + if (PMIX_SUCCESS != ret) { + return ret; + } + + /* set the flag on each valid variable */ + size = pmix_value_array_get_size(&group->group_vars); + vars = PMIX_VALUE_ARRAY_GET_BASE(&group->group_vars, int); + + for (i = 0 ; i < size ; ++i) { + if (0 <= vars[i]) { + (void) pmix_mca_base_var_set_flag (vars[i], flags, set); + } + } + + return PMIX_SUCCESS; +} + + +static void pmix_mca_base_var_group_constructor (pmix_mca_base_var_group_t *group) +{ + memset ((char *) group + sizeof (group->super), 0, sizeof (*group) - sizeof (group->super)); + + PMIX_CONSTRUCT(&group->group_subgroups, pmix_value_array_t); + pmix_value_array_init (&group->group_subgroups, sizeof (int)); + + PMIX_CONSTRUCT(&group->group_vars, pmix_value_array_t); + pmix_value_array_init (&group->group_vars, sizeof (int)); + +} + +static void pmix_mca_base_var_group_destructor (pmix_mca_base_var_group_t *group) +{ + free (group->group_full_name); + group->group_full_name = NULL; + + free (group->group_description); + group->group_description = NULL; + + free (group->group_project); + group->group_project = NULL; + + free (group->group_framework); + group->group_framework = NULL; + + free (group->group_component); + group->group_component = NULL; + + PMIX_DESTRUCT(&group->group_subgroups); + PMIX_DESTRUCT(&group->group_vars); +} + +int pmix_mca_base_var_group_get_count (void) +{ + return pmix_mca_base_var_group_count; +} + +int pmix_mca_base_var_group_get_stamp (void) +{ + return pmix_mca_base_var_groups_timestamp; +} 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 new file mode 100644 index 0000000000..bd43c7840a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var_group.h @@ -0,0 +1,173 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_MCA_BASE_VAR_GROUP_H +#define PMIX_MCA_BASE_VAR_GROUP_H + +#include "src/mca/mca.h" + +struct pmix_mca_base_var_group_t { + pmix_list_item_t super; + + /** Index of group */ + int group_index; + + /** Group is valid (registered) */ + bool group_isvalid; + + /** Group name */ + char *group_full_name; + + char *group_project; + char *group_framework; + char *group_component; + + /** Group help message (description) */ + char *group_description; + + /** Integer value array of subgroup indices */ + pmix_value_array_t group_subgroups; + + /** Integer array of group variables */ + pmix_value_array_t group_vars; + +}; + +typedef struct pmix_mca_base_var_group_t pmix_mca_base_var_group_t; + +/** + * Object declaration for pmix_mca_base_var_group_t + */ +PMIX_CLASS_DECLARATION(pmix_mca_base_var_group_t); + +/** + * Register an MCA variable group + * + * @param[in] project_name Project name for this group. + * @param[in] framework_name Framework name for this group. + * @param[in] component_name Component name for this group. + * @param[in] descrition Description of this group. + * + * @retval index Unique group index + * @return pmix error code on Error + * + * Create an MCA variable group. If the group already exists + * this call is equivalent to pmix_mca_base_ver_find_group(). + */ +int pmix_mca_base_var_group_register(const char *project_name, + const char *framework_name, + const char *component_name, + const char *description); + +/** + * Register an MCA variable group for a component + * + * @param[in] component [in] Pointer to the component for which the + * group is being registered. + * @param[in] description Description of this group. + * + * @retval index Unique group index + * @return pmix error code on Error + */ +int pmix_mca_base_var_group_component_register (const pmix_mca_base_component_t *component, + const char *description); + +/** + * Deregister an MCA param group + * + * @param group_index [in] Group index from pmix_mca_base_var_group_register (), + * pmix_mca_base_var_group_find(). + * + * This call deregisters all associated variables and subgroups. + */ +int pmix_mca_base_var_group_deregister (int group_index); + +/** + * Find an MCA group + * + * @param[in] project_name Project name + * @param[in] framework_name Framework name + * @param[in] component_name Component name + * + * @returns PMIX_SUCCESS if found + * @returns PMIX_ERR_NOT_FOUND if not found + */ +int pmix_mca_base_var_group_find (const char *project_name, + const char *framework_name, + const char *component_name); + +/** + * Find an MCA group by its full name + * + * @param[in] full_name Full name of MCA variable group. Ex: shmem_mmap + * @param[out] index Index of group if found + * + * @returns PMIX_SUCCESS if found + * @returns PMIX_ERR_NOT_FOUND if not found + */ +int pmix_mca_base_var_group_find_by_name (const char *full_name, int *index); + +/** + * Get the group at a specified index + * + * @param[in] group_index Group index + * @param[out] group Storage for the group object pointer. + * + * @retval PMIX_ERR_NOT_FOUND If the group specified by group_index does not exist. + * @retval PMIX_SUCCESS If the group is found + * + * The returned pointer belongs to the MCA variable system. Do not modify/release/retain + * the pointer. + */ +int pmix_mca_base_var_group_get (const int group_index, + const pmix_mca_base_var_group_t **group); + +/** + * Set/unset a flags for all variables in a group. + * + * @param[in] group_index Index of group + * @param[in] flag Flag(s) to set or unset. + * @param[in] set Boolean indicating whether to set flag(s). + * + * Set a flag for every variable in a group. See pmix_mca_base_var_set_flag() for more info. + */ +int pmix_mca_base_var_group_set_var_flag (const int group_index, int flags, + bool set); + +/** + * Get the number of registered MCA groups + * + * @retval count Number of registered MCA groups + */ +int pmix_mca_base_var_group_get_count (void); + +/** + * Get a relative timestamp for the MCA group system + * + * @retval stamp + * + * This value will change if groups or variables are either added or removed. + */ +int pmix_mca_base_var_group_get_stamp (void); + +#endif /* PMIX_MCA_BASE_VAR_GROUP_H */ 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 new file mode 100644 index 0000000000..e2bd97b1e2 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_vari.h @@ -0,0 +1,165 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** + * @file + * + * This is the private declarations for the MCA variable system. + * This file is internal to the MCA variable system and should not + * need to be used by any other elements in PMIX except the + * special case of the ompi_info command. + * + * All the rest of the doxygen documentation in this file is marked as + * "internal" and won't show up unless you specifically tell doxygen + * to generate internal documentation (by default, it is skipped). + */ + +#ifndef PMIX_MCA_BASE_VAR_INTERNAL_H +#define PMIX_MCA_BASE_VAR_INTERNAL_H + +#include + +#include "src/class/pmix_object.h" +#include "src/class/pmix_list.h" +#include "src/class/pmix_value_array.h" +#include "src/class/pmix_pointer_array.h" +#include "src/class/pmix_hash_table.h" +#include "src/mca/base/pmix_mca_base_var.h" + +BEGIN_C_DECLS + +/* Internal flags start at bit 16 */ +#define PMIX_MCA_BASE_VAR_FLAG_EXTERNAL_MASK 0x0000ffff + +typedef enum { + /** Variable is valid */ + PMIX_MCA_BASE_VAR_FLAG_VALID = 0x00010000, + /** Variable is a synonym */ + PMIX_MCA_BASE_VAR_FLAG_SYNONYM = 0x00020000, + /** mbv_source_file needs to be freed */ + PMIX_MCA_BASE_VAR_FLAG_SOURCE_FILE_NEEDS_FREE = 0x00040000 +} pmix_mca_base_var_flag_internal_t; + +#define PMIX_VAR_FLAG_ISSET(var, flag) (!!((var).mbp_flags & (flag))) + +#define PMIX_VAR_IS_VALID(var) (!!((var).mbv_flags & PMIX_MCA_BASE_VAR_FLAG_VALID)) +#define PMIX_VAR_IS_SYNONYM(var) (!!((var).mbv_flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM)) +#define PMIX_VAR_IS_INTERNAL(var) (!!((var).mbv_flags & PMIX_MCA_BASE_VAR_FLAG_INTERNAL)) +#define PMIX_VAR_IS_DEFAULT_ONLY(var) (!!((var).mbv_flags & PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY)) +#define PMIX_VAR_IS_SETTABLE(var) (!!((var).mbv_flags & PMIX_MCA_BASE_VAR_FLAG_SETTABLE)) +#define PMIX_VAR_IS_DEPRECATED(var) (!!((var).mbv_flags & PMIX_MCA_BASE_VAR_FLAG_DEPRECATED)) + +extern const char *pmix_var_type_names[]; +extern const size_t pmix_var_type_sizes[]; +extern bool pmix_mca_base_var_initialized; + +/** + * \internal + * + * Structure for holding param names and values read in from files. + */ +struct pmix_mca_base_var_file_value_t { + /** Allow this to be an PMIX OBJ */ + pmix_list_item_t super; + + /** Parameter name */ + char *mbvfv_var; + /** Parameter value */ + char *mbvfv_value; + /** File it came from */ + char *mbvfv_file; + /** Line it came from */ + int mbvfv_lineno; +}; + +/** + * \internal + * + * Convenience typedef + */ +typedef struct pmix_mca_base_var_file_value_t pmix_mca_base_var_file_value_t; + +/** + * Object declaration for pmix_mca_base_var_file_value_t + */ +PMIX_CLASS_DECLARATION(pmix_mca_base_var_file_value_t); + +/** + * \internal + * + * Get a group + * + * @param[in] group_index Group index + * @param[out] group Returned group if it exists + * @param[in] invalidok Return group even if it has been deregistered + */ +int pmix_mca_base_var_group_get_internal (const int group_index, pmix_mca_base_var_group_t **group, bool invalidok); + +/** + * \internal + * + * Parse a parameter file. + */ +int pmix_mca_base_parse_paramfile(const char *paramfile, pmix_list_t *list); + +/** + * \internal + * + * Add a variable to a group + */ +int pmix_mca_base_var_group_add_var (const int group_index, const int param_index); + +/** + * \internal + * + * Add a performance variable to a group + */ +int pmix_mca_base_var_group_add_pvar (const int group_index, const int param_index); + +/** + * \internal + * + * Generate a full name with _ between all of the non-NULL arguments + */ +int pmix_mca_base_var_generate_full_name4 (const char *project, const char *framework, + const char *component, const char *variable, + char **full_name); + +/** + * \internal + * + * Call save_value callback for generated internal mca parameter storing env variables + */ +int pmix_mca_base_internal_env_store(void); + +/** + * \internal + * + * Initialize/finalize MCA variable groups + */ +int pmix_mca_base_var_group_init (void); +int pmix_mca_base_var_group_finalize (void); + +END_C_DECLS + +#endif /* PMIX_MCA_BASE_VAR_INTERNAL_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/mca.h b/opal/mca/pmix/pmix2x/pmix/src/mca/mca.h new file mode 100644 index 0000000000..5970a10eb8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/mca.h @@ -0,0 +1,324 @@ +/* -*- 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** + * @file + * + * Top-level interface for all pmix MCA components. + */ + +#ifndef PMIX_MCA_H +#define PMIX_MCA_H + +#include + +/** + * Common type for all MCA modules. + * + * An instance of this type is always the first element in MCA + * modules, allowing the module to be associated with a + * particular version of a specific framework, and to publish its own + * name and version. + */ +struct pmix_mca_base_module_2_0_0_t { + int dummy_value; +}; +/** Unversioned convenience typedef; use this name in + frameworks/components to stay forward source-compatible */ +typedef struct pmix_mca_base_module_2_0_0_t pmix_mca_base_module_t; +/** Versioned convenience typedef */ +typedef struct pmix_mca_base_module_2_0_0_t pmix_mca_base_module_2_0_0_t; + + +/** + * MCA component open function. + * + * @retval PMIX_SUCCESS This component can be used in the process. + * + * @retval PMIX_ERR_NOT_AVAILABLE Silently ignore this component for + * the duration of the process (it may even be unloaded from the + * process). + * + * @retval anything_else The MCA base will print an error message + * ignore this component for the duration of the process (it may even + * be unloaded from the process). + * + * All MCA components can have an "open" function that is invoked once + * per process, when the component is located and loaded. + * + * This function should avoid registering MCA parameters (use the + * component "register" function for that; i.e., + * mca_base_register_component_params_2_0_0_fn_t for that). Legacy + * components still register MCA params in their component "open" + * function, but their authors should update them to use the component + * "register" function. + * + * This function can also be used to allocate any resources necessary + * for the component (e.g., heap memory). + * + * This function should return PMIX_SUCCESS if it wishes to remain + * loaded in the process. Any other return value will cause the MCA + * base to unload the component. Although most components do not use + * this mechanism to force themselves to be unloaded (because if they + * are immediately unloaded, ompi_info will not display them), the + * mechanism is available should the need arise. + * + * If the component a) has no MCA parameters to register, b) no + * resources to allocate, and c) can always be used in a process + * (albiet perhaps not selected), it may provide NULL for this + * function. In this cause, the MCA will act as if it called the open + * function and it returned PMIX_SUCCESS. + */ +typedef int (*pmix_mca_base_open_component_1_0_0_fn_t)(void); + +/** + * MCA component close function. + * + * @retval PMIX_SUCCESS The component successfully shut down. + * + * @retval any_other_value Some error occurred, but is likely to be + * ignored. + * + * This function is invoked on a component after all of its modules + * have been finalized (according to the rules of its framework) and + * the component will never be used in the process again; the + * component may be unloaded from the process memory after the close + * function has been invoked. + * + * This function is typically used to release any resources still in + * use by the component. + * + * If the component has no resources to free, it may provide NULL for + * this function. In this case, the MCA will act as if it called the + * close function and it returned PMIX_SUCCESS. + */ +typedef int (*pmix_mca_base_close_component_1_0_0_fn_t)(void); + +/** + * MCA component query function. + * + * @retval PMIX_SUCCESS The component successfully queried. + * + * @retval any_other_value Some error occurred, but is likely to be + * ignored. + * + * @param module The module to be used if this component is selected. + * + * @param priority The priority of this component. + * + * This function is used by the mca_base_select function to find the + * highest priority component to select. Frameworks are free to + * implement their own query function, but must also implment their + * own select function as a result. + */ +typedef int (*pmix_mca_base_query_component_2_0_0_fn_t)(pmix_mca_base_module_2_0_0_t **module, int *priority); + +/** + * MCA component parameter registration function. + * + * @retval PMIX_SUCCESS This component successfully registered its + * parameters and can be used in this process. + * @retval PMIX_ERR_BAD_PARAM Indicates that the register function + * failed because an MCA parameter got an invalid/incorrect value. + * + * @retval anything_else The MCA will ignore this component for the + * duration of the process. + * + * If a component has a non-NULL parameter registration function, it + * will be invoked to register all MCA parameters associated with the + * component. This function is invoked *before* the component "open" + * function is invoked. + * + * The registration function should not allocate any resources that + * need to be freed (aside from registering MCA parameters). + * Specifically, strings that are passed to the MCA parameter + * registration functions are all internally copied; there's no need + * for the caller to keep them after registering a parameter. Hence, + * it is possible that the registration function will be the *only* + * function invoked on a component; component authors should take care + * that no resources are leaked in this case. + * + * This function should return PMIX_SUCCESS if it wishes to remain + * loaded in the process. Any other return value will cause the MCA + * base to unload the component. Although most components do not use + * this mechanism to force themselves to be unloaded (because if they + * are immediately unloaded, ompi_info will not display them), the + * mechanism is available should the need arise. + * + * Note that if the function returns PMIX_ERR_BAD_PARAM, it is + * possible (likely?) that the component didn't register all of its + * parameters. When this happens, ompi_info (and friends) will stop + * execution and print out all existing registered parameters from the + * entire framework (since ompi_info doesn't track individual + * component register failures). This allows a user to know exactly + * what value is incorrect, and from where it was set (e.g., via an + * MCA params file). + * + * If the component a) has no MCA parameters to register, b) no + * resources to allocate, and c) can always be used in a process + * (albiet perhaps not selected), it may provide NULL for this + * function. In this cause, the MCA will act as if it called the + * registration function and it returned PMIX_SUCCESS. + */ +typedef int (*pmix_mca_base_register_component_params_2_0_0_fn_t)(void); + + +/** + * Maximum length of MCA project string names. + */ +#define PMIX_MCA_BASE_MAX_PROJECT_NAME_LEN 15 +/** + * Maximum length of MCA framework string names. + */ +#define PMIX_MCA_BASE_MAX_TYPE_NAME_LEN 31 +/** + * Maximum length of MCA component string names. + */ +#define PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN 63 + +/** + * Common type for all MCA components. + * + * An instance of this type is always the first element in MCA + * components, allowing the component to be associated with a + * particular version of a specific framework, and to publish its own + * name and version. + */ +struct pmix_mca_base_component_2_1_0_t { + + int pmix_mca_major_version; + /**< Major number of the MCA. */ + int pmix_mca_minor_version; + /**< Minor number of the MCA. */ + int pmix_mca_release_version; + /**< Release number of the MCA. */ + + char pmix_mca_project_name[PMIX_MCA_BASE_MAX_PROJECT_NAME_LEN + 1]; + /**< String name of the project that this component belongs to. */ + int pmix_mca_project_major_version; + /**< Major version number of the project that this component + belongs to. */ + int pmix_mca_project_minor_version; + /**< Minor version number of the project that this component + belongs to. */ + int pmix_mca_project_release_version; + /**< Release version number of the project that this component + belongs to. */ + + char pmix_mca_type_name[PMIX_MCA_BASE_MAX_TYPE_NAME_LEN + 1]; + /**< String name of the framework that this component belongs to. */ + int pmix_mca_type_major_version; + /**< Major version number of the framework that this component + belongs to. */ + int pmix_mca_type_minor_version; + /**< Minor version number of the framework that this component + belongs to. */ + int pmix_mca_type_release_version; + /**< Release version number of the framework that this component + belongs to. */ + + char pmix_mca_component_name[PMIX_MCA_BASE_MAX_COMPONENT_NAME_LEN + 1]; + /**< This comopnent's string name. */ + int pmix_mca_component_major_version; + /**< This component's major version number. */ + int pmix_mca_component_minor_version; + /**< This component's minor version number. */ + int pmix_mca_component_release_version; + /**< This component's release version number. */ + + pmix_mca_base_open_component_1_0_0_fn_t pmix_mca_open_component; + /**< Method for opening this component. */ + pmix_mca_base_close_component_1_0_0_fn_t pmix_mca_close_component; + /**< Method for closing this component. */ + pmix_mca_base_query_component_2_0_0_fn_t pmix_mca_query_component; + /**< Method for querying this component. */ + pmix_mca_base_register_component_params_2_0_0_fn_t pmix_mca_register_component_params; + /**< Method for registering the component's MCA parameters */ + + /** Extra space to allow for expansion in the future without + breaking older components. */ + char reserved[32]; +}; +/** Unversioned convenience typedef; use this name in + frameworks/components to stay forward source-compatible */ +typedef struct pmix_mca_base_component_2_1_0_t pmix_mca_base_component_t; +/** Versioned convenience typedef */ +typedef struct pmix_mca_base_component_2_1_0_t pmix_mca_base_component_2_1_0_t; + +/* + * Metadata Bit field parameters + */ +#define PMIX_MCA_BASE_METADATA_PARAM_NONE (uint32_t)0x00 /**< No Metadata flags */ +#define PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT (uint32_t)0x02 /**< Checkpoint enabled Component */ +#define PMIX_MCA_BASE_METADATA_PARAM_DEBUG (uint32_t)0x04 /**< Debug enabled/only Component */ + +/** + * Meta data for MCA v2.0.0 components. + */ +struct pmix_mca_base_component_data_2_0_0_t { + uint32_t param_field; + /**< Metadata parameter bit field filled in by the parameters + defined above */ + + /** Extra space to allow for expansion in the future without + breaking older components. */ + char reserved[32]; +}; +/** Unversioned convenience typedef; use this name in + frameworks/components to stay forward source-compatible */ +typedef struct pmix_mca_base_component_data_2_0_0_t pmix_mca_base_component_data_t; +/** Versioned convenience typedef */ +typedef struct pmix_mca_base_component_data_2_0_0_t pmix_mca_base_component_data_2_0_0_t; + +/** + * Macro for framework author convenience. + * + * This macro is used by frameworks defining their component types, + * indicating that they subscribe to the MCA version 2.0.0. See + * component header files (e.g., coll.h) for examples of its usage. + */ +#define PMIX_MCA_BASE_VERSION_MAJOR 2 +#define PMIX_MCA_BASE_VERSION_MINOR 1 +#define PMIX_MCA_BASE_VERSION_RELEASE 0 + +#define PMIX_MCA_BASE_MAKE_VERSION(level, MAJOR, MINOR, RELEASE) \ + .pmix_mca_## level ##_major_version = MAJOR, \ + .pmix_mca_## level ##_minor_version = MINOR, \ + .pmix_mca_## level ##_release_version = RELEASE + + +#define PMIX_MCA_BASE_VERSION_2_1_0(PROJECT, project_major, project_minor, project_release, TYPE, type_major, type_minor, type_release) \ + .pmix_mca_major_version = PMIX_MCA_BASE_VERSION_MAJOR, \ + .pmix_mca_minor_version = PMIX_MCA_BASE_VERSION_MINOR, \ + .pmix_mca_release_version = PMIX_MCA_BASE_VERSION_RELEASE, \ + .pmix_mca_project_name = PROJECT, \ + PMIX_MCA_BASE_MAKE_VERSION(project, project_major, project_minor, project_release), \ + .pmix_mca_type_name = TYPE, \ + PMIX_MCA_BASE_MAKE_VERSION(type, type_major, type_minor, type_release) + + +#define PMIX_MCA_BASE_VERSION_1_0_0(type, type_major, type_minor, type_release) \ + PMIX_MCA_BASE_VERSION_2_1_0("pmix", PMIX_MAJOR_VERSION, PMIX_MINOR_VERSION, \ + PMIX_RELEASE_VERSION, type, type_major, type_minor, \ + type_release) + +#endif /* PMIX_MCA_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/Makefile.am new file mode 100644 index 0000000000..fdd56a8e2e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/Makefile.am @@ -0,0 +1,36 @@ +# +# Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2010-2015 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# main library setup +noinst_LTLIBRARIES = libmca_pdl.la +libmca_pdl_la_SOURCES = + +# local files +headers = pdl.h +libmca_pdl_la_SOURCES += $(headers) + +# Ensure that the man pages are rebuilt if the pmix_config.h file +# changes; a "good enough" way to know if configure was run again (and +# therefore the release date or version may have changed) +$(nodist_man_MANS): $(top_builddir)/pmix/include/pmix_config.h + +# Conditionally install the header files +if WANT_INSTALL_HEADERS +pmixdir = $(pmixincludedir)/$(subdir) +nobase_pmix_HEADERS = $(headers) +endif + +include base/Makefile.am + +distclean-local: + rm -f base/static-components.h + rm -f $(nodist_man_MANS) 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 new file mode 100644 index 0000000000..efc770a274 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/Makefile.am @@ -0,0 +1,17 @@ +# +# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers += \ + base/base.h + +libmca_pdl_la_SOURCES += \ + base/pdl_base_open.c \ + base/pdl_base_close.c \ + base/pdl_base_select.c \ + base/pdl_base_fns.c 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 new file mode 100644 index 0000000000..2cb3725688 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/base.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_PDL_BASE_H +#define PMIX_PDL_BASE_H + +#include +#include "src/mca/pdl/pdl.h" +#include "src/util/pmix_environ.h" + +#include "src/mca/base/base.h" + + +BEGIN_C_DECLS + +/** + * Globals + */ +extern pmix_mca_base_framework_t pmix_pdl_base_framework; +extern pmix_pdl_base_component_t +*pmix_pdl_base_selected_component; +extern pmix_pdl_base_module_t *pmix_pdl; + + +/** + * Initialize the PDL MCA framework + * + * @retval PMIX_SUCCESS Upon success + * @retval PMIX_ERROR Upon failures + * + * This function is invoked during pmix_init(); + */ +int pmix_pdl_base_open(pmix_mca_base_open_flag_t flags); + +/** + * Select an available component. + * + * @retval PMIX_SUCCESS Upon Success + * @retval PMIX_NOT_FOUND If no component can be selected + * @retval PMIX_ERROR Upon other failure + * + */ +int pmix_pdl_base_select(void); + +/** + * Finalize the PDL MCA framework + * + * @retval PMIX_SUCCESS Upon success + * @retval PMIX_ERROR Upon failures + * + * This function is invoked during pmix_finalize(); + */ +int pmix_pdl_base_close(void); + +/** + * Open a DSO + * + * (see pmix_pdl_base_module_open_ft_t in pmix/mca/pdl/pdl.h for + * documentation of this function) + */ +int pmix_pdl_open(const char *fname, + bool use_ext, bool private_namespace, + pmix_pdl_handle_t **handle, char **err_msg); + +/** + * Lookup a symbol in a DSO + * + * (see pmix_pdl_base_module_lookup_ft_t in pmix/mca/pdl/pdl.h for + * documentation of this function) + */ +int pmix_pdl_lookup(pmix_pdl_handle_t *handle, + const char *symbol, + void **ptr, char **err_msg); + +/** + * Close a DSO + * + * (see pmix_pdl_base_module_close_ft_t in pmix/mca/pdl/pdl.h for + * documentation of this function) + */ +int pmix_pdl_close(pmix_pdl_handle_t *handle); + +/** + * Iterate over files in a path + * + * (see pmix_pdl_base_module_foreachfile_ft_t in pmix/mca/pdl/pdl.h for + * documentation of this function) + */ +int pmix_pdl_foreachfile(const char *search_path, + int (*cb_func)(const char *filename, void *context), + void *context); + +END_C_DECLS + +#endif /* PMIX_PDL_BASE_H */ 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 new file mode 100644 index 0000000000..7c6f5456a4 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_close.c @@ -0,0 +1,26 @@ +/* + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "src/mca/mca.h" +#include "src/mca/base/base.h" + +#include "src/mca/pdl/pdl.h" +#include "src/mca/pdl/base/base.h" + + +int pmix_pdl_base_close(void) +{ + /* Close all available modules that are open */ + return pmix_mca_base_framework_components_close(&pmix_pdl_base_framework, NULL); +} 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 new file mode 100644 index 0000000000..091715dadc --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_fns.c @@ -0,0 +1,70 @@ +/* + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** + * This file is a simple set of wrappers around the selected PMIX PDL + * component (it's a compile-time framework with, at most, a single + * component; see pdl.h for details). + */ + +#include + +#include "pmix_common.h" + +#include "src/util/output.h" +#include "src/mca/pdl/base/base.h" + + +int pmix_pdl_open(const char *fname, + bool use_ext, bool private_namespace, + pmix_pdl_handle_t **handle, char **err_msg) +{ + *handle = NULL; + + if (NULL != pmix_pdl && NULL != pmix_pdl->open) { + return pmix_pdl->open(fname, use_ext, private_namespace, + handle, err_msg); + } + + return PMIX_ERR_NOT_SUPPORTED; +} + +int pmix_pdl_lookup(pmix_pdl_handle_t *handle, + const char *symbol, + void **ptr, char **err_msg) +{ + if (NULL != pmix_pdl && NULL != pmix_pdl->lookup) { + return pmix_pdl->lookup(handle, symbol, ptr, err_msg); + } + + return PMIX_ERR_NOT_SUPPORTED; +} + +int pmix_pdl_close(pmix_pdl_handle_t *handle) +{ + if (NULL != pmix_pdl && NULL != pmix_pdl->close) { + return pmix_pdl->close(handle); + } + + return PMIX_ERR_NOT_SUPPORTED; +} + +int pmix_pdl_foreachfile(const char *search_path, + int (*cb_func)(const char *filename, void *context), + void *context) +{ + if (NULL != pmix_pdl && NULL != pmix_pdl->foreachfile) { + return pmix_pdl->foreachfile(search_path, cb_func, context); + } + + return PMIX_ERR_NOT_SUPPORTED; +} 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 new file mode 100644 index 0000000000..22b6cd4c47 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_open.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2004-2010 The Trustees of Indiana University. + * All rights reserved. + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "src/mca/pdl/base/base.h" + +#include "src/mca/pdl/base/static-components.h" + + +/* + * Globals + */ +pmix_pdl_base_module_t *pmix_pdl = NULL; +pmix_pdl_base_component_t *pmix_pdl_base_selected_component = NULL; + + +/* + * Function for finding and opening either all MCA components, + * or the one that was specifically requested via a MCA parameter. + * + * Note that we really don't need this function -- we could specify a + * NULL pointer in the framework declare and the base would do this + * exact same thing. However, we need to have at least some + * executable code in this file, or some linkers (cough cough OS X + * cough cough) may not actually link in this .o file. + */ +int pmix_pdl_base_open(pmix_mca_base_open_flag_t flags) +{ + /* Open up all available components */ + return pmix_mca_base_framework_components_open(&pmix_pdl_base_framework, flags); +} + +/* VERY IMPORTANT: This framework is static, and is opened before any + other dyanmic frameworks are opened (which makes sense, of course). + But we must mark this framework is NO_DSO so that the MCA framework + base doesn't try to open any dynamic components in this + framework. */ +PMIX_MCA_BASE_FRAMEWORK_DECLARE(pmix, pdl, "Dynamic loader framework", + NULL /* register */, + pmix_pdl_base_open /* open */, + NULL /* close */, + mca_pdl_base_static_components, + PMIX_MCA_BASE_FRAMEWORK_FLAG_NO_DSO); 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 new file mode 100644 index 0000000000..e42db673be --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/base/pdl_base_select.c @@ -0,0 +1,55 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2010 The Trustees of Indiana University. + * All rights reserved. + * + * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#ifdef HAVE_UNISTD_H +#include "unistd.h" +#endif + +#include "pmix_common.h" +#include "src/util/output.h" +#include "src/mca/mca.h" +#include "src/mca/base/base.h" +#include "src/mca/pdl/pdl.h" +#include "src/mca/pdl/base/base.h" + + +int pmix_pdl_base_select(void) +{ + int exit_status = PMIX_SUCCESS; + pmix_pdl_base_component_t *best_component = NULL; + pmix_pdl_base_module_t *best_module = NULL; + + /* + * Select the best component + */ + if (PMIX_SUCCESS != pmix_mca_base_select("pdl", + pmix_pdl_base_framework.framework_output, + &pmix_pdl_base_framework.framework_components, + (pmix_mca_base_module_t **) &best_module, + (pmix_mca_base_component_t **) &best_component, NULL) ) { + /* This will only happen if no component was selected */ + exit_status = PMIX_ERROR; + goto cleanup; + } + + /* Save the winner */ + pmix_pdl_base_selected_component = best_component; + pmix_pdl = best_module; + + cleanup: + return exit_status; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/configure.m4 new file mode 100644 index 0000000000..68c9b3cc5e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/configure.m4 @@ -0,0 +1,78 @@ +dnl -*- shell-script -*- +dnl +dnl Copyright (c) 2010-2015 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2016 Intel, Inc. All right reserved +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +dnl There will only be one component used in this framework, and it will +dnl be selected at configure time by priority. Components must set +dnl their priorities in their configure.m4 file. + +dnl We only want one winning component (vs. STOP_AT_FIRST_PRIORITY, +dnl which will allow all components of the same priority who succeed to +dnl win) +m4_define(MCA_pmix_pdl_CONFIGURE_MODE, STOP_AT_FIRST) + +AC_DEFUN([MCA_pmix_pdl_CONFIG],[ + PMIX_HAVE_PDL_SUPPORT=0 + + # If --disable-dlopen was used, then have all the components fail + # (we still need to configure them all so that things like "make + # dist" work", but we just want the MCA system to (artificially) + # conclude that it can't build any of the components. + AS_IF([test "$enable_dlopen" = "no"], + [want_pdl=0], [want_pdl=1]) + + MCA_CONFIGURE_FRAMEWORK([pdl], [$want_pdl]) + + # If we found no suitable static pdl component and dlopen support + # was not specifically disabled, this is an error. + AS_IF([test "$MCA_pmix_pdl_STATIC_COMPONENTS" = "" && \ + test "$enable_dlopen" != "no"], + [AC_MSG_WARN([Did not find a suitable static pmix pdl component]) + AC_MSG_WARN([You might need to install libltld (and its headers) or]) + AC_MSG_WARN([specify --disable-dlopen to configure.]) + AC_MSG_ERROR([Cannot continue])]) + + # If we have a winning component (which, per above, will only + # happen if --disable-dlopen was *not* specified), do some more + # logic. + AS_IF([test "$MCA_pmix_pdl_STATIC_COMPONENTS" != ""], + [ # We had a winner -- w00t! + + PMIX_HAVE_PDL_SUPPORT=1 + # If we added any -L flags to ADD_LDFLAGS, then we (might) + # need to add those directories to LD_LIBRARY_PATH. + # Otherwise, if we try to AC RUN_IFELSE anything here in + # configure, it might die because it can't find the libraries + # we just linked against. + PMIX_VAR_SCOPE_PUSH([pmix_pdl_base_found_l pmix_pdl_base_token pmix_pdl_base_tmp pmix_pdl_base_dir]) + pmix_pdl_base_found_l=0 + eval "pmix_pdl_base_tmp=\$pmix_pdl_${pmix_pdl_winner}_ADD_LIBS" + for pmix_pdl_base_token in $pmix_pdl_base_tmp; do + case $pmix_pdl_base_token in + -l*) pmix_pdl_base_found_l=1 ;; + esac + done + AS_IF([test $pmix_pdl_base_found_l -eq 1], + [eval "pmix_pdl_base_tmp=\$pmix_pdl_${pmix_pdl_winner}_ADD_LDFLAGS" + for pmix_pdl_base_token in $pmix_pdl_base_tmp; do + case $pmix_pdl_base_token in + -L*) + pmix_pdl_base_dir=`echo $pmix_pdl_base_token | cut -c3-` + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$pmix_pdl_base_dir + AC_MSG_WARN([Adding to LD_LIBRARY_PATH: $pmix_pdl_base_dir]) + ;; + esac + done]) + PMIX_VAR_SCOPE_POP + ]) + + AC_DEFINE_UNQUOTED([PMIX_HAVE_PDL_SUPPORT], [$PMIX_HAVE_PDL_SUPPORT], + [Whether the PMIX PDL framework is functional or not]) +]) diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h new file mode 100644 index 0000000000..e34ac5bd6b --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdl.h @@ -0,0 +1,186 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** + * @file + * + * Dynamic library framework + * + * General Description: + * + * This framework provides portable access to dlopen- and dlsym-like + * functionality, very similar to Libtool's libltdl. Indeed, one of + * the components in this framework will use libltdl, if it is + * present/available. However, on some common types systems where + * libltdl headers and libraries are *not* available, we can support + * plugins via this simple framework. + * + * This is a compile-time framework: a single component will be + * selected by the priority that its configure.m4 provides. All other + * components will be ignored (i.e., not built/not part of the + * installation). Meaning: the static_components of the pdl framework + * will always contain 0 or 1 components. + * + * SIDENOTE: PMIX used to embed libltdl. However, as of early + * 2015, this became problematic, for a variety of complex and + * uninteresting reasons (see the following if you care about the + * details: https://github.com/open-mpi/ompi/issues/311, + * http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19370, + * https://github.com/open-mpi/ompi/pull/366, + * https://github.com/open-mpi/ompi/pull/390). That being said, we, + * as a developer community, still wanted to be able to natively use + * DSOs by default. A small/simple framework for PDL functionality, + * along with a simple component that supports dlopen/dlsym on POSIX + * platforms and another component that natively uses libltdl seemed + * like a good solution. + */ + +#ifndef PMIX_MCA_PDL_PDL_H +#define PMIX_MCA_PDL_PDL_H + +#include + +#include "src/mca/mca.h" +#include "src/mca/base/base.h" + +BEGIN_C_DECLS + +/** + * Handle for an opened file + */ +struct pmix_pdl_handle_t; +typedef struct pmix_pdl_handle_t pmix_pdl_handle_t; + +/** + * Dynamically open the file specified. + * + * Arguments: + * fname = Base filename to open. If NULL, open this process. + * use_ext = If true, try various filename suffixes that are + * relevant on this platform (e.g., .so, .dll, .dylib). If + * false, just use exactly whatever was passed as fname. + * private = If true, open the file in a private namespace. + * Otherwise, open the file in a global namespace. + * handle = Upon successful open, a handle to the opened file will + * be returned. + * err_msg= if non-NULL and !=PMIX_SUCCESS is returned, will point to a + * string error message + * + * Returns: + * PMIX_SUCCESS on success, or PMIX_ERROR + * + * Space for the handle must be allocated by the module (it can be + * freed during the call to pmix_pdl_base_module_dlclose_fn_t). + * + * The err_msg points to an internal string and should not be altered + * or freed by the caller. The contents of the err_msg string may + * change after successive calls to pmix_pdl API calls. + */ +typedef int (*pmix_pdl_base_module_open_fn_t) + (const char *fname, bool use_ext, bool private_namespace, + pmix_pdl_handle_t **handle, char **err_msg); + +/** + * Lookup a symbol in an opened file. + * + * Arguments: + * handle = handle of a previously dynamically opened file + * symbol = name of the symbol to lookup + * ptr = if found, a pointer to the symbol. Otherwise, NULL. + * err_msg= if non-NULL and !=PMIX_SUCCESS is returned, will point to a + * string error message + * Returns: + * PMIX_SUCCESS on success, or PMIX_ERROR + * + * + * The err_msg points to an internal string and should not be altered + * or freed by the caller. The contents of the err_msg string may + * change after successive calls to pmix_pdl API calls. + */ +typedef int (*pmix_pdl_base_module_lookup_fn_t) + (pmix_pdl_handle_t *handle, const char *symbol, void **ptr, char **err_msg); + +/** + * Dynamically close a previously dynamically-opened file. + * + * Arguments: + * handle = handle of a previously dynamically opened file. + * Returns: + * PMIX_SUCCESS on success, or PMIX_ERROR + * + * This function should close the file and free and resources + * associated with it (e.g., whatever is cached on the handle). + */ +typedef int (*pmix_pdl_base_module_close_fn_t) + (pmix_pdl_handle_t *handle); + +/** + * Search through a path of directories, invoking a callback on each + * unique regular (non-Libtool) file basename found (e.g., will only + * be invoked once for the files "foo.la" and "foo.so", with the + * parameter "foo"). + * + * Arguments: + * path = PMIX_ENV_SEP-delimited list of directories + * cb_func= function to invoke on each filename found + * data = context for callback function + * Returns: + * PMIX_SUCESS on success, PMIX_ERR* otherwise + */ +typedef int (*pmix_pdl_base_module_foreachfile_fn_t) + (const char *search_path, + int (*cb_func)(const char *filename, void *context), + void *context); + +/** + * Structure for PDL components. + */ +struct pmix_pdl_base_component_1_0_0_t { + /** MCA base component */ + pmix_mca_base_component_t base_version; + /** MCA base data */ + pmix_mca_base_component_data_t base_data; + + /** Default priority */ + int priority; +}; +typedef struct pmix_pdl_base_component_1_0_0_t pmix_pdl_base_component_1_0_0_t; +typedef struct pmix_pdl_base_component_1_0_0_t pmix_pdl_base_component_t; + +/** + * Structure for PDL modules + */ +struct pmix_pdl_base_module_1_0_0_t { + pmix_mca_base_module_2_0_0_t super; + + /** Open / close */ + pmix_pdl_base_module_open_fn_t open; + pmix_pdl_base_module_close_fn_t close; + + /** Lookup a symbol */ + pmix_pdl_base_module_lookup_fn_t lookup; + + /** Iterate looking for files */ + pmix_pdl_base_module_foreachfile_fn_t foreachfile; +}; +typedef struct pmix_pdl_base_module_1_0_0_t pmix_pdl_base_module_1_0_0_t; +typedef struct pmix_pdl_base_module_1_0_0_t pmix_pdl_base_module_t; + +/** + * Macro for use in components that are of type PDL + */ +#define PMIX_PDL_BASE_VERSION_1_0_0 \ + PMIX_MCA_BASE_VERSION_1_0_0("pdl", 1, 0, 0) + +END_C_DECLS + +#endif /* PMIX_MCA_PDL_PDL_H */ 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 new file mode 100644 index 0000000000..c2811eecd8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/Makefile.am @@ -0,0 +1,23 @@ +# +# Copyright (c) 2004-2010 The Trustees of Indiana University. +# All rights reserved. +# Copyright (c) 2014-2015 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +sources = \ + pdl_pdlopen.h \ + pdl_pdlopen_component.c \ + pdl_pdlopen_module.c + +# This component will only ever be built statically -- never as a DSO. + +noinst_LTLIBRARIES = libmca_pdl_pdlopen.la + +libmca_pdl_pdlopen_la_SOURCES = $(sources) +libmca_pdl_pdlopen_la_LDFLAGS = -module -avoid-version +libmca_pdl_pdlopen_la_LIBADD = $(pmix_pdl_pdlopen_LIBS) diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/configure.m4 new file mode 100644 index 0000000000..28cb5e6bb6 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/configure.m4 @@ -0,0 +1,55 @@ +# -*- shell-script -*- +# +# Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved. +# +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AC_DEFUN([MCA_pmix_pdl_pdlopen_PRIORITY], [80]) + +# +# Force this component to compile in static-only mode +# +AC_DEFUN([MCA_pmix_pdl_pdlopen_COMPILE_MODE], [ + AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) + $4="static" + AC_MSG_RESULT([$$4]) +]) + +# MCA_pdl_pdlopen_CONFIG([action-if-can-compile], +# [action-if-cant-compile]) +# ------------------------------------------------ +AC_DEFUN([MCA_pmix_pdl_pdlopen_CONFIG],[ + AC_CONFIG_FILES([src/mca/pdl/pdlopen/Makefile]) + + dnl This is effectively a back-door for PMIX developers to + dnl force the use of the libltdl pdl component. + AC_ARG_ENABLE([pdl-dlopen], + [AS_HELP_STRING([--disable-pdl-dlopen], + [Disable the "dlopen" PDL component (and probably force the use of the "libltdl" PDL component). This option should really only be used by PMIX developers. You are probably actually looking for the "--disable-dlopen" option, which disables all dlopen-like functionality from PMIX.]) + ]) + + pmix_pdl_pdlopen_happy=no + AS_IF([test "$enable_pdl_dlopen" != "no"], + [PMIX_CHECK_PACKAGE([pmix_pdl_pdlopen], + [dlfcn.h], + [dl], + [dlopen], + [], + [], + [], + [pmix_pdl_pdlopen_happy=yes], + [pmix_pdl_pdlopen_happy=no]) + ]) + + AS_IF([test "$pmix_pdl_pdlopen_happy" = "yes"], + [pmix_pdl_pdlopen_ADD_LIBS=$pmix_pdl_pdlopen_LIBS + $1], + [$2]) + + AC_SUBST(pmix_pdl_pdlopen_LIBS) +]) 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 new file mode 100644 index 0000000000..7ba3e24760 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_PDL_PDLOPEN +#define PMIX_PDL_PDLOPEN + +#include + +#include "src/mca/pdl/pdl.h" + +extern pmix_pdl_base_module_t pmix_pdl_pdlopen_module; + +/* + * Dynamic library handles generated by this component. + * + * If we're debugging, keep a copy of the name of the file we've opened. + */ +struct pmix_pdl_handle_t { + void *dlopen_handle; +#if PMIX_ENABLE_DEBUG + void *filename; +#endif +}; + +typedef struct { + pmix_pdl_base_component_t base; + + char *filename_suffixes_mca_storage; + char **filename_suffixes; +} pmix_pdl_pdlopen_component_t; + +extern pmix_pdl_pdlopen_component_t mca_pdl_pdlopen_component; + +#endif /* PMIX_PDL_PDLOPEN */ 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 new file mode 100644 index 0000000000..8e061d5ca9 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_component.c @@ -0,0 +1,127 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "pmix_common.h" +#include "src/mca/pdl/pdl.h" +#include "src/util/argv.h" + +#include "pdl_pdlopen.h" + + +/* + * Public string showing the sysinfo ompi_linux component version number + */ +const char *pmix_pdl_pdlopen_component_version_string = + "PMIX pdl pdlopen MCA component version " PMIX_VERSION; + + +/* + * Local functions + */ +static int pdlopen_component_register(void); +static int pdlopen_component_open(void); +static int pdlopen_component_close(void); +static int pdlopen_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_pdl_pdlopen_component_t mca_pdl_pdlopen_component = { + + /* Fill in the mca_pdl_base_component_t */ + .base = { + + /* First, the mca_component_t struct containing meta information + about the component itself */ + .base_version = { + PMIX_PDL_BASE_VERSION_1_0_0, + + /* Component name and version */ + .pmix_mca_component_name = "pdlopen", + PMIX_MCA_BASE_MAKE_VERSION(component, PMIX_MAJOR_VERSION, PMIX_MINOR_VERSION, + PMIX_RELEASE_VERSION), + + /* Component functions */ + .pmix_mca_register_component_params = pdlopen_component_register, + .pmix_mca_open_component = pdlopen_component_open, + .pmix_mca_close_component = pdlopen_component_close, + .pmix_mca_query_component = pdlopen_component_query, + }, + + .base_data = { + /* The component is checkpoint ready */ + PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT + }, + + /* The pdl framework members */ + .priority = 80 + }, +}; + + +static int pdlopen_component_register(void) +{ + int ret; + + mca_pdl_pdlopen_component.filename_suffixes_mca_storage = ".so,.dylib,.dll,.sl"; + ret = + pmix_mca_base_component_var_register(&mca_pdl_pdlopen_component.base.base_version, + "filename_suffixes", + "Comma-delimited list of filename suffixes that the pdlopen component will try", + PMIX_MCA_BASE_VAR_TYPE_STRING, + NULL, + 0, + PMIX_MCA_BASE_VAR_FLAG_SETTABLE, + PMIX_INFO_LVL_5, + PMIX_MCA_BASE_VAR_SCOPE_LOCAL, + &mca_pdl_pdlopen_component.filename_suffixes_mca_storage); + if (ret < 0) { + return ret; + } + mca_pdl_pdlopen_component.filename_suffixes = + pmix_argv_split(mca_pdl_pdlopen_component.filename_suffixes_mca_storage, + ','); + + return PMIX_SUCCESS; +} + +static int pdlopen_component_open(void) +{ + return PMIX_SUCCESS; +} + + +static int pdlopen_component_close(void) +{ + if (NULL != mca_pdl_pdlopen_component.filename_suffixes) { + pmix_argv_free(mca_pdl_pdlopen_component.filename_suffixes); + mca_pdl_pdlopen_component.filename_suffixes = NULL; + } + + return PMIX_SUCCESS; +} + + +static int pdlopen_component_query(pmix_mca_base_module_t **module, int *priority) +{ + /* The priority value is somewhat meaningless here; by + pmix/mca/pdl/configure.m4, there's at most one component + available. */ + *priority = mca_pdl_pdlopen_component.base.priority; + *module = &pmix_pdl_pdlopen_module.super; + + return PMIX_SUCCESS; +} 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 new file mode 100644 index 0000000000..85e8854e8e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/pdl_pdlopen_module.c @@ -0,0 +1,276 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "pmix_common.h" +#include "src/mca/pdl/pdl.h" +#include "src/util/argv.h" +#include "src/util/error.h" + +#include "pdl_pdlopen.h" + + +/* + * Trivial helper function to avoid replicating code + */ +static void do_pdlopen(const char *fname, int flags, + void **handle, char **err_msg) +{ + assert(handle); + + *handle = dlopen(fname, flags); + + if (NULL != err_msg) { + if (NULL != *handle) { + *err_msg = NULL; + } else { + *err_msg = dlerror(); + } + } +} + + +static int pdlopen_open(const char *fname, bool use_ext, bool private_namespace, + pmix_pdl_handle_t **handle, char **err_msg) +{ + assert(handle); + + *handle = NULL; + + /* Setup the dlopen flags */ + int flags = RTLD_LAZY; + if (private_namespace) { + flags |= RTLD_LOCAL; + } else { + flags |= RTLD_GLOBAL; + } + + /* If the caller wants to use filename extensions, loop through + them */ + void *local_handle = NULL; + if (use_ext && NULL != fname) { + int i; + char *ext; + + for (i = 0, ext = mca_pdl_pdlopen_component.filename_suffixes[i]; + NULL != ext; + ext = mca_pdl_pdlopen_component.filename_suffixes[++i]) { + char *name; + + asprintf(&name, "%s%s", fname, ext); + if (NULL == name) { + return PMIX_ERR_IN_ERRNO; + } + + /* Does the file exist? */ + struct stat buf; + if (stat(name, &buf) < 0) { + free(name); + if (NULL != err_msg) { + *err_msg = "File not found"; + } + continue; + } + + /* Yes, the file exists -- try to dlopen it. If we can't + dlopen it, bail. */ + do_pdlopen(name, flags, &local_handle, err_msg); + free(name); + break; + } + } + + /* Otherwise, the caller does not want to use filename extensions, + so just use the single filename that the caller provided */ + else { + do_pdlopen(fname, flags, &local_handle, err_msg); + } + + if (NULL != local_handle) { + *handle = calloc(1, sizeof(pmix_pdl_handle_t)); + (*handle)->dlopen_handle = local_handle; + +#if PMIX_ENABLE_DEBUG + if( NULL != fname ) { + (*handle)->filename = strdup(fname); + } + else { + (*handle)->filename = strdup("(null)"); + } +#endif + } + return (NULL != local_handle) ? PMIX_SUCCESS : PMIX_ERROR; +} + + +static int pdlopen_lookup(pmix_pdl_handle_t *handle, const char *symbol, + void **ptr, char **err_msg) +{ + assert(handle); + assert(handle->dlopen_handle); + assert(symbol); + assert(ptr); + + *ptr = dlsym(handle->dlopen_handle, symbol); + if (NULL != *ptr) { + return PMIX_SUCCESS; + } + + if (NULL != err_msg) { + *err_msg = dlerror(); + } + return PMIX_ERROR; +} + + +static int pdlopen_close(pmix_pdl_handle_t *handle) +{ + assert(handle); + + int ret; + ret = dlclose(handle->dlopen_handle); + +#if PMIX_ENABLE_DEBUG + free(handle->filename); +#endif + free(handle); + + return ret; +} + +/* + * Scan all the files in a directory (or path) and invoke a callback + * on each one. + */ +static int pdlopen_foreachfile(const char *search_path, + int (*func)(const char *filename, void *data), + void *data) +{ + int ret; + DIR *dp = NULL; + char **dirs = NULL; + char **good_files = NULL; + + dirs = pmix_argv_split(search_path, PMIX_ENV_SEP); + for (int i = 0; NULL != dirs && NULL != dirs[i]; ++i) { + + dp = opendir(dirs[i]); + if (NULL == dp) { + ret = PMIX_ERR_IN_ERRNO; + goto error; + } + + struct dirent *de; + while (NULL != (de = readdir(dp))) { + + /* Make the absolute path name */ + char *abs_name = NULL; + asprintf(&abs_name, "%s/%s", dirs[i], de->d_name); + if (NULL == abs_name) { + ret = PMIX_ERR_IN_ERRNO; + goto error; + } + + /* Stat the file */ + struct stat buf; + if (stat(abs_name, &buf) < 0) { + free(abs_name); + ret = PMIX_ERR_IN_ERRNO; + goto error; + } + + /* Skip if not a file */ + if (!S_ISREG(buf.st_mode)) { + free(abs_name); + continue; + } + + /* Find the suffix */ + char *ptr = strrchr(abs_name, '.'); + if (NULL != ptr) { + + /* Skip libtool files */ + if (strcmp(ptr, ".la") == 0 || + strcmp(ptr, ".lo") == 0) { + free (abs_name); + continue; + } + + *ptr = '\0'; + } + + /* Have we already found this file? Or already found a + file with the same basename (but different suffix)? */ + bool found = false; + for (int j = 0; NULL != good_files && + NULL != good_files[j]; ++j) { + if (strcmp(good_files[j], abs_name) == 0) { + found = true; + break; + } + } + + if (!found) { + pmix_argv_append_nosize(&good_files, abs_name); + } + free(abs_name); + } + closedir(dp); + } + dp = NULL; + + /* Invoke the callback on all the found files */ + if (NULL != good_files) { + for (int i = 0; NULL != good_files[i]; ++i) { + ret = func(good_files[i], data); + if (PMIX_SUCCESS != ret) { + goto error; + } + } + } + + ret = PMIX_SUCCESS; + + error: + if (NULL != dp) { + closedir(dp); + } + if (NULL != dirs) { + pmix_argv_free(dirs); + } + if (NULL != good_files) { + pmix_argv_free(good_files); + } + + return ret; +} + + +/* + * Module definition + */ +pmix_pdl_base_module_t pmix_pdl_pdlopen_module = { + .open = pdlopen_open, + .lookup = pdlopen_lookup, + .close = pdlopen_close, + .foreachfile = pdlopen_foreachfile +}; diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/Makefile.am new file mode 100644 index 0000000000..deaa8fe667 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/Makefile.am @@ -0,0 +1,30 @@ +# +# 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$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# main library setup +noinst_LTLIBRARIES = libmca_pinstalldirs.la +libmca_pinstalldirs_la_SOURCES = + +# local files +headers = pinstalldirs.h +libmca_pinstalldirs_la_SOURCES += $(headers) + +# Conditionally install the header files +if WANT_INSTALL_HEADERS +pmixdir = $(pmixincludedir)/$(subdir) +nobase_pmix_HEADERS = $(headers) +endif + +include base/Makefile.am + +distclean-local: + rm -f base/static-components.h 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 new file mode 100644 index 0000000000..1617f5688c --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/Makefile.am @@ -0,0 +1,16 @@ +# +# Copyright (c) 2006 Los Alamos National Security, LLC. All rights +# reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers += \ + base/base.h + +libmca_pinstalldirs_la_SOURCES += \ + base/pinstalldirs_base_components.c \ + base/pinstalldirs_base_expand.c 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 new file mode 100644 index 0000000000..a7592f0927 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/base.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006-2013 Los Alamos National Security, LLC. All rights + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ + +#ifndef PMIX_PINSTALLDIRS_BASE_H +#define PMIX_PINSTALLDIRS_BASE_H + +#include +#include "src/mca/base/pmix_mca_base_framework.h" +#include "src/mca/pinstalldirs/pinstalldirs.h" + +/* + * Global functions for MCA overall pinstalldirs open and close + */ +BEGIN_C_DECLS + +/** + * Framework structure declaration + */ +extern pmix_mca_base_framework_t pmix_pinstalldirs_base_framework; + +/* Just like pmix_pinstall_dirs_expand() (see pinstalldirs.h), but will + also insert the value of the environment variable $PMIX_DESTDIR, if + it exists/is set. This function should *only* be used during the + setup routines of pinstalldirs. */ +char * pmix_pinstall_dirs_expand_setup(const char* input); + +END_C_DECLS + +#endif /* PMIX_BASE_PINSTALLDIRS_H */ 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 new file mode 100644 index 0000000000..5a8902886e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_components.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2006-2012 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ + +#include + +#include "pmix_common.h" +#include "src/mca/mca.h" +#include "src/mca/pinstalldirs/pinstalldirs.h" +#include "src/mca/pinstalldirs/base/base.h" +#include "src/mca/pinstalldirs/base/static-components.h" + +pmix_pinstall_dirs_t pmix_pinstall_dirs = {0}; + +#define CONDITIONAL_COPY(target, origin, field) \ + do { \ + if (origin.field != NULL && target.field == NULL) { \ + target.field = origin.field; \ + } \ + } while (0) + +static int +pmix_pinstalldirs_base_open(pmix_mca_base_open_flag_t flags) +{ + pmix_mca_base_component_list_item_t *component_item; + int ret; + + ret = pmix_mca_base_framework_components_open(&pmix_pinstalldirs_base_framework, flags); + if (PMIX_SUCCESS != ret) { + return ret; + } + + PMIX_LIST_FOREACH(component_item, &pmix_pinstalldirs_base_framework.framework_components, pmix_mca_base_component_list_item_t) { + const pmix_pinstalldirs_base_component_t *component = + (const pmix_pinstalldirs_base_component_t *) component_item->cli_component; + + /* copy over the data, if something isn't already there */ + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + prefix); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + exec_prefix); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + bindir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + sbindir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + libexecdir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + datarootdir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + datadir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + sysconfdir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + sharedstatedir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + localstatedir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + libdir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + includedir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + infodir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + mandir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + pmixdatadir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + pmixlibdir); + CONDITIONAL_COPY(pmix_pinstall_dirs, component->install_dirs_data, + pmixincludedir); + } + + /* expand out all the fields */ + pmix_pinstall_dirs.prefix = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.prefix); + pmix_pinstall_dirs.exec_prefix = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.exec_prefix); + pmix_pinstall_dirs.bindir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.bindir); + pmix_pinstall_dirs.sbindir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.sbindir); + pmix_pinstall_dirs.libexecdir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.libexecdir); + pmix_pinstall_dirs.datarootdir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.datarootdir); + pmix_pinstall_dirs.datadir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.datadir); + pmix_pinstall_dirs.sysconfdir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.sysconfdir); + pmix_pinstall_dirs.sharedstatedir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.sharedstatedir); + pmix_pinstall_dirs.localstatedir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.localstatedir); + pmix_pinstall_dirs.libdir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.libdir); + pmix_pinstall_dirs.includedir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.includedir); + pmix_pinstall_dirs.infodir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.infodir); + pmix_pinstall_dirs.mandir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.mandir); + pmix_pinstall_dirs.pmixdatadir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.pmixdatadir); + pmix_pinstall_dirs.pmixlibdir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.pmixlibdir); + pmix_pinstall_dirs.pmixincludedir = + pmix_pinstall_dirs_expand_setup(pmix_pinstall_dirs.pmixincludedir); + +#if 0 + fprintf(stderr, "prefix: %s\n", pmix_pinstall_dirs.prefix); + fprintf(stderr, "exec_prefix: %s\n", pmix_pinstall_dirs.exec_prefix); + fprintf(stderr, "bindir: %s\n", pmix_pinstall_dirs.bindir); + fprintf(stderr, "sbindir: %s\n", pmix_pinstall_dirs.sbindir); + fprintf(stderr, "libexecdir: %s\n", pmix_pinstall_dirs.libexecdir); + fprintf(stderr, "datarootdir: %s\n", pmix_pinstall_dirs.datarootdir); + fprintf(stderr, "datadir: %s\n", pmix_pinstall_dirs.datadir); + fprintf(stderr, "sysconfdir: %s\n", pmix_pinstall_dirs.sysconfdir); + fprintf(stderr, "sharedstatedir: %s\n", pmix_pinstall_dirs.sharedstatedir); + fprintf(stderr, "localstatedir: %s\n", pmix_pinstall_dirs.localstatedir); + fprintf(stderr, "libdir: %s\n", pmix_pinstall_dirs.libdir); + fprintf(stderr, "includedir: %s\n", pmix_pinstall_dirs.includedir); + fprintf(stderr, "infodir: %s\n", pmix_pinstall_dirs.infodir); + fprintf(stderr, "mandir: %s\n", pmix_pinstall_dirs.mandir); + fprintf(stderr, "pkgdatadir: %s\n", pmix_pinstall_dirs.pkgdatadir); + fprintf(stderr, "pkglibdir: %s\n", pmix_pinstall_dirs.pkglibdir); + fprintf(stderr, "pkgincludedir: %s\n", pmix_pinstall_dirs.pkgincludedir); +#endif + + /* NTH: Is it ok not to close the components? If not we can add a flag + to mca_base_framework_components_close to indicate not to deregister + variable groups */ + return PMIX_SUCCESS; +} + + +static int +pmix_pinstalldirs_base_close(void) +{ + free(pmix_pinstall_dirs.prefix); + free(pmix_pinstall_dirs.exec_prefix); + free(pmix_pinstall_dirs.bindir); + free(pmix_pinstall_dirs.sbindir); + free(pmix_pinstall_dirs.libexecdir); + free(pmix_pinstall_dirs.datarootdir); + free(pmix_pinstall_dirs.datadir); + free(pmix_pinstall_dirs.sysconfdir); + free(pmix_pinstall_dirs.sharedstatedir); + free(pmix_pinstall_dirs.localstatedir); + free(pmix_pinstall_dirs.libdir); + free(pmix_pinstall_dirs.includedir); + free(pmix_pinstall_dirs.infodir); + free(pmix_pinstall_dirs.mandir); + free(pmix_pinstall_dirs.pmixdatadir); + free(pmix_pinstall_dirs.pmixlibdir); + free(pmix_pinstall_dirs.pmixincludedir); + memset (&pmix_pinstall_dirs, 0, sizeof (pmix_pinstall_dirs)); + + return pmix_mca_base_framework_components_close (&pmix_pinstalldirs_base_framework, NULL); +} + +/* Declare the pinstalldirs framework */ +PMIX_MCA_BASE_FRAMEWORK_DECLARE(pmix, pinstalldirs, NULL, NULL, pmix_pinstalldirs_base_open, + pmix_pinstalldirs_base_close, mca_pinstalldirs_base_static_components, + PMIX_MCA_BASE_FRAMEWORK_FLAG_NOREGISTER | PMIX_MCA_BASE_FRAMEWORK_FLAG_NO_DSO); 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 new file mode 100644 index 0000000000..d52822d2d5 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_expand.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights + * reserved. + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ + +#include + +#include + +#include "src/util/os_path.h" +#include "src/mca/pinstalldirs/base/base.h" +#include "src/mca/pinstalldirs/pinstalldirs.h" + +/* Support both ${name} and @{name} forms. The latter allows us to + pass values through AC_SUBST without being munged by m4 (e.g., if + we want to pass "@{libdir}" and not have it replaced by m4 to be + whatever the actual value of the shell variable is. */ +#define EXPAND_STRING(name) EXPAND_STRING2(name, name) + +#define EXPAND_STRING2(ompiname, fieldname) \ + do { \ + if (NULL != (start_pos = strstr(retval, "${" #fieldname "}"))) { \ + tmp = retval; \ + *start_pos = '\0'; \ + end_pos = start_pos + strlen("${" #fieldname "}"); \ + asprintf(&retval, "%s%s%s", tmp, \ + pmix_pinstall_dirs.ompiname + destdir_offset, \ + end_pos); \ + free(tmp); \ + changed = true; \ + } else if (NULL != (start_pos = strstr(retval, "@{" #fieldname "}"))) { \ + tmp = retval; \ + *start_pos = '\0'; \ + end_pos = start_pos + strlen("@{" #fieldname "}"); \ + asprintf(&retval, "%s%s%s", tmp, \ + pmix_pinstall_dirs.ompiname + destdir_offset, \ + end_pos); \ + free(tmp); \ + changed = true; \ + } \ + } while (0) + + +/* + * Read the lengthy comment below to understand the value of the + * is_setup parameter. + */ +static char * +pmix_pinstall_dirs_expand_internal(const char* input, bool is_setup) +{ + size_t len, i; + bool needs_expand = false; + char *retval = NULL; + char *destdir = NULL; + size_t destdir_offset = 0; + + /* This is subtle, and worth explaining. + + If we substitute in any ${FIELD} values, we need to prepend it + with the value of the $PMIX_DESTDIR environment variable -- if + it is set. + + We need to handle at least three cases properly (assume that + configure was invoked with --prefix=/opt/pmix and no other + directory specifications, and PMIX_DESTDIR is set to + /tmp/buildroot): + + 1. Individual directories, such as libdir. These need to be + prepended with DESTDIR. I.e., return + /tmp/buildroot/opt/pmix/lib. + + 2. Compiler flags that have ${FIELD} values embedded in them. + For example, consider if a wrapper compiler data file + contains the line: + + preprocessor_flags=-DMYFLAG="${prefix}/share/randomthingy/" + + The value we should return is: + + -DMYFLAG="/tmp/buildroot/opt/pmix/share/randomthingy/" + + 3. Compiler flags that do not have any ${FIELD} values. + For example, consider if a wrapper compiler data file + contains the line: + + preprocessor_flags=-pthread + + The value we should return is: + + -pthread + + Note, too, that this PMIX_DESTDIR futzing only needs to occur + during pmix_init(). By the time pmix_init() has completed, all + values should be substituted in that need substituting. Hence, + we take an extra parameter (is_setup) to know whether we should + do this futzing or not. */ + if (is_setup) { + destdir = getenv("PMIX_DESTDIR"); + if (NULL != destdir && strlen(destdir) > 0) { + destdir_offset = strlen(destdir); + } + } + + len = strlen(input); + for (i = 0 ; i < len ; ++i) { + if ('$' == input[i] || '@' == input[i]) { + needs_expand = true; + break; + } + } + + retval = strdup(input); + if (NULL == retval) return NULL; + + if (needs_expand) { + bool changed = false; + char *start_pos, *end_pos, *tmp; + + do { + changed = false; + EXPAND_STRING(prefix); + EXPAND_STRING(exec_prefix); + EXPAND_STRING(bindir); + EXPAND_STRING(sbindir); + EXPAND_STRING(libexecdir); + EXPAND_STRING(datarootdir); + EXPAND_STRING(datadir); + EXPAND_STRING(sysconfdir); + EXPAND_STRING(sharedstatedir); + EXPAND_STRING(localstatedir); + EXPAND_STRING(libdir); + EXPAND_STRING(includedir); + EXPAND_STRING(infodir); + EXPAND_STRING(mandir); + EXPAND_STRING2(pmixdatadir, pkgdatadir); + EXPAND_STRING2(pmixlibdir, pkglibdir); + EXPAND_STRING2(pmixincludedir, pkgincludedir); + } while (changed); + } + + if (NULL != destdir) { + char *tmp = retval; + retval = pmix_os_path(false, destdir, tmp, NULL); + free(tmp); + } + + return retval; +} + + +char * +pmix_pinstall_dirs_expand(const char* input) +{ + /* We do NOT want PMIX_DESTDIR expansion in this case. */ + return pmix_pinstall_dirs_expand_internal(input, false); +} + + +char * +pmix_pinstall_dirs_expand_setup(const char* input) +{ + /* We DO want PMIX_DESTDIR expansion in this case. */ + return pmix_pinstall_dirs_expand_internal(input, true); +} 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 new file mode 100644 index 0000000000..d05743fb5f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/Makefile.am @@ -0,0 +1,22 @@ +# +# Copyright (c) 2006 Los Alamos National Security, LLC. All rights +# reserved. +# 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$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +noinst_LTLIBRARIES = libmca_pinstalldirs_config.la + +libmca_pinstalldirs_config_la_SOURCES = \ + pmix_pinstalldirs_config.c + +# This file is generated; we do not want to include it in the tarball +nodist_libmca_pinstalldirs_config_la_SOURCES = \ + install_dirs.h 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 new file mode 100644 index 0000000000..265334cb66 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/configure.m4 @@ -0,0 +1,30 @@ +# -*- shell-script -*- +# +# 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$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AC_DEFUN([MCA_pmix_pinstalldirs_config_PRIORITY], [0]) + +AC_DEFUN([MCA_pmix_pinstalldirs_config_COMPILE_MODE], [ + AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) + $4="static" + AC_MSG_RESULT([$$4]) +]) + + +# MCA_pinstalldirs_config_CONFIG(action-if-can-compile, +# [action-if-cant-compile]) +# ------------------------------------------------ +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 new file mode 100644 index 0000000000..e1569ae73a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pinstall_dirs.h.in @@ -0,0 +1,129 @@ +/* + * 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) 2007 Los Alamos National Security, LLC. + * All rights reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + * This file should be included by any file that needs the + * installation directories hard-coded into the object file. This + * should be avoided if at all possible, but there are some places + * (like the wrapper compilers) where it is infinitely easier to have + * the paths stored. + * + * If you have questions about which directory to use, we try as best + * we can to follow the GNU coding standards on this issue. The + * description of each directory can be found at the following URL: + * + * http://www.gnu.org/prep/standards/html_node/Directory-Variables.html + * + * The line below is to shut AC 2.60 up about datarootdir. Don't remove. + * datarootdir=foo + */ + +#ifndef PMIX_INST_DIRS_H +#define PMIX_INST_DIRS_H + +#define PMIX_INSTALL_PREFIX "@prefix@" +#define PMIX_EXEC_PREFIX "@exec_prefix@" + +/* The directory for installing executable programs that users can + run. */ +#define PMIX_BINDIR "@bindir@" + +/* The directory for installing executable programs that can be run + from the shell, but are only generally useful to system + administrators. */ +#define PMIX_SBINDIR "@sbindir@" + +/* The directory for installing executable programs to be run by other + programs rather than by users. + + The definition of ‘libexecdir’ is the same for all packages, so + you should install your data in a subdirectory thereof. Most + packages install their data under $(libexecdir)/package-name/, + possibly within additional subdirectories thereof, such as + $(libexecdir)/package-name/machine/version. */ +#define PMIX_LIBEXECDIR "@libexecdir@" + +/* The root of the directory tree for read-only + architecture-independent data files. + + See not about PMIX_DATADIR. And you probably want that one, not + this one. This is one of those "building block" paths, that is + really only used for defining other paths. */ +#define PMIX_DATAROOTDIR "@datarootdir@" + +/* The directory for installing idiosyncratic read-only + architecture-independent data files for this program. + + The definition of ‘datadir’ is the same for all packages, so you + should install your data in a subdirectory thereof. Most packages + install their data under $(datadir)/package-name/. */ +#define PMIX_DATADIR "@datadir@" + +/* $(datadir)/package-name/. You probably want to use this instead of + PMIX_DATADIR */ +#define PMIX_PKGDATADIR "@pmixdatadir@" + +/* The directory for installing read-only data files that pertain to a + single machine–that is to say, files for configuring a host. Mailer + and network configuration files, /etc/passwd, and so forth belong + here. All the files in this directory should be ordinary ASCII text + files. + + Do not install executables here in this directory (they probably + belong in $(libexecdir) or $(sbindir)). Also do not install files + that are modified in the normal course of their use (programs whose + purpose is to change the configuration of the system + excluded). Those probably belong in $(localstatedir). */ +#define PMIX_SYSCONFDIR "@sysconfdir@" + +/* The directory for installing architecture-independent data files + which the programs modify while they run. */ +#define PMIX_SHAREDSTATEDIR "@sharedstatedir@" + +/* The directory for installing data files which the programs modify + while they run, and that pertain to one specific machine. Users + should never need to modify files in this directory to configure + the package's operation; put such configuration information in + separate files that go in $(datadir) or + $(sysconfdir). */ +#define PMIX_LOCALSTATEDIR "@localstatedir@" + +/* The directory for object files and libraries of object code. Do not + install executables here, they probably ought to go in + $(libexecdir) instead. */ +#define PMIX_LIBDIR "@libdir@" + +/* $(libdir)/package-name/. This is where components should go */ +#define PMIX_PKGLIBDIR "@pmixlibdir@" + +/* The directory for installing header files to be included by user + programs with the C ‘#include’ preprocessor directive. */ +#define PMIX_INCLUDEDIR "@includedir@" + +/* $(includedir)/package-name/. The devel headers go in here */ +#define PMIX_PKGINCLUDEDIR "@pmixincludedir@" + +/* The directory for installing the Info files for this package. */ +#define PMIX_INFODIR "@infodir@" + +/* The top-level directory for installing the man pages (if any) for + this package. */ +#define PMIX_MANDIR "@mandir@" + +#endif 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 new file mode 100644 index 0000000000..f48de36bd8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/config/pmix_pinstalldirs_config.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "src/mca/pinstalldirs/pinstalldirs.h" +#include "src/mca/pinstalldirs/config/pinstall_dirs.h" + +const pmix_pinstalldirs_base_component_t mca_pinstalldirs_config_component = { + /* First, the mca_component_t struct containing meta information + about the component itself */ + { + PMIX_PINSTALLDIRS_BASE_VERSION_1_0_0, + + /* Component name and version */ + "config", + PMIX_MAJOR_VERSION, + PMIX_MINOR_VERSION, + PMIX_RELEASE_VERSION, + + /* Component open and close functions */ + NULL, + NULL + }, + { + /* This component is Checkpointable */ + PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT + }, + + { + PMIX_INSTALL_PREFIX, + PMIX_EXEC_PREFIX, + PMIX_BINDIR, + PMIX_SBINDIR, + PMIX_LIBEXECDIR, + PMIX_DATAROOTDIR, + PMIX_DATADIR, + PMIX_SYSCONFDIR, + PMIX_SHAREDSTATEDIR, + PMIX_LOCALSTATEDIR, + PMIX_LIBDIR, + PMIX_INCLUDEDIR, + PMIX_INFODIR, + PMIX_MANDIR, + PMIX_PKGDATADIR, + PMIX_PKGLIBDIR, + PMIX_PKGINCLUDEDIR + } +}; diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/configure.m4 new file mode 100644 index 0000000000..08217bd349 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/configure.m4 @@ -0,0 +1,12 @@ +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$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +AC_DEFUN([MCA_pmix_pinstalldirs_CONFIGURE_MODE], [PRIORITY]) 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 new file mode 100644 index 0000000000..61471d1392 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/Makefile.am @@ -0,0 +1,16 @@ +# +# Copyright (c) 2006 Los Alamos National Security, LLC. All rights +# reserved. +# Copyright (c) 2009 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +noinst_LTLIBRARIES = libmca_pinstalldirs_env.la + +libmca_pinstalldirs_env_la_SOURCES = \ + pmix_pinstalldirs_env.c 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 new file mode 100644 index 0000000000..1807ed752c --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/configure.m4 @@ -0,0 +1,28 @@ +# -*- shell-script -*- +# +# 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$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AC_DEFUN([MCA_pmix_pinstalldirs_env_PRIORITY], [10]) + +AC_DEFUN([MCA_pmix_pinstalldirs_env_COMPILE_MODE], [ + AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) + $4="static" + AC_MSG_RESULT([$$4]) +]) + +# MCA_pinstalldirs_config_CONFIG(action-if-can-compile, +# [action-if-cant-compile]) +# ------------------------------------------------ +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 new file mode 100644 index 0000000000..9ee499b079 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/env/pmix_pinstalldirs_env.c @@ -0,0 +1,84 @@ +/* + * 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include + +#include "pmix_common.h" +#include "src/mca/pinstalldirs/pinstalldirs.h" + +static int pinstalldirs_env_open(void); + + +pmix_pinstalldirs_base_component_t mca_pinstalldirs_env_component = { + /* First, the mca_component_t struct containing meta information + about the component itself */ + { + PMIX_PINSTALLDIRS_BASE_VERSION_1_0_0, + + /* Component name and version */ + "env", + PMIX_MAJOR_VERSION, + PMIX_MINOR_VERSION, + PMIX_RELEASE_VERSION, + + /* Component open and close functions */ + pinstalldirs_env_open, + NULL + }, + { + /* This component is checkpointable */ + PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT + }, + + /* Next the pmix_pinstall_dirs_t install_dirs_data information */ + { + NULL, + }, +}; + + +#define SET_FIELD(field, envname) \ + do { \ + char *tmp = getenv(envname); \ + if (NULL != tmp && 0 == strlen(tmp)) { \ + tmp = NULL; \ + } \ + mca_pinstalldirs_env_component.install_dirs_data.field = tmp; \ + } while (0) + + +static int +pinstalldirs_env_open(void) +{ + SET_FIELD(prefix, "PMIX_INSTALL_PREFIX"); + SET_FIELD(exec_prefix, "PMIX_EXEC_PREFIX"); + SET_FIELD(bindir, "PMIX_BINDIR"); + SET_FIELD(sbindir, "PMIX_SBINDIR"); + SET_FIELD(libexecdir, "PMIX_LIBEXECDIR"); + SET_FIELD(datarootdir, "PMIX_DATAROOTDIR"); + SET_FIELD(datadir, "PMIX_DATADIR"); + SET_FIELD(sysconfdir, "PMIX_SYSCONFDIR"); + SET_FIELD(sharedstatedir, "PMIX_SHAREDSTATEDIR"); + SET_FIELD(localstatedir, "PMIX_LOCALSTATEDIR"); + SET_FIELD(libdir, "PMIX_LIBDIR"); + SET_FIELD(includedir, "PMIX_INCLUDEDIR"); + SET_FIELD(infodir, "PMIX_INFODIR"); + SET_FIELD(mandir, "PMIX_MANDIR"); + SET_FIELD(pmixdatadir, "PMIX_PKGDATADIR"); + SET_FIELD(pmixlibdir, "PMIX_PKGLIBDIR"); + SET_FIELD(pmixincludedir, "PMIX_PKGINCLUDEDIR"); + + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/pinstalldirs.h b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/pinstalldirs.h new file mode 100644 index 0000000000..22930abeca --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pinstalldirs/pinstalldirs.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2006-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_MCA_PINSTALLDIRS_PINSTALLDIRS_H +#define PMIX_MCA_PINSTALLDIRS_PINSTALLDIRS_H + +#include + +#include "src/mca/mca.h" +#include "src/mca/base/base.h" + +BEGIN_C_DECLS + +/* + * Most of this file is just for ompi_info. The only public interface + * once pmix_init has been called is the pmix_pinstall_dirs structure + * and the pmix_pinstall_dirs_expand() call */ +struct pmix_pinstall_dirs_t { + char* prefix; + char* exec_prefix; + char* bindir; + char* sbindir; + char* libexecdir; + char* datarootdir; + char* datadir; + char* sysconfdir; + char* sharedstatedir; + char* localstatedir; + char* libdir; + char* includedir; + char* infodir; + char* mandir; + + /* Note that the following fields intentionally have an "ompi" + prefix, even though they're down in the PMIX layer. This is + not abstraction break because the "ompi" they're referring to + is for the build system of the overall software tree -- not an + individual project within that overall tree. + + Rather than using pkg{data,lib,includedir}, use our own + ompi{data,lib,includedir}, which is always set to + {datadir,libdir,includedir}/pmix. This will keep us from + having help files in prefix/share/open-rte when building + without PMIX, but in prefix/share/pmix when building + with PMIX. + + Note that these field names match macros set by configure that + are used in Makefile.am files. E.g., project help files are + installed into $(pmixdatadir). */ + char* pmixdatadir; + char* pmixlibdir; + char* pmixincludedir; +}; +typedef struct pmix_pinstall_dirs_t pmix_pinstall_dirs_t; + +/* Install directories. Only available after pmix_init() */ +extern pmix_pinstall_dirs_t pmix_pinstall_dirs; + +/** + * Expand out path variables (such as ${prefix}) in the input string + * using the current pmix_pinstall_dirs structure */ +char * pmix_pinstall_dirs_expand(const char* input); + + +/** + * Structure for pinstalldirs components. + */ +struct pmix_pinstalldirs_base_component_2_0_0_t { + /** MCA base component */ + pmix_mca_base_component_t component; + /** MCA base data */ + pmix_mca_base_component_data_t component_data; + /** install directories provided by the given component */ + pmix_pinstall_dirs_t install_dirs_data; +}; +/** + * Convenience typedef + */ +typedef struct pmix_pinstalldirs_base_component_2_0_0_t pmix_pinstalldirs_base_component_t; + +/* + * Macro for use in components that are of type pinstalldirs + */ +#define PMIX_PINSTALLDIRS_BASE_VERSION_1_0_0 \ + PMIX_MCA_BASE_VERSION_1_0_0("pinstalldirs", 1, 0, 0) + +END_C_DECLS + +#endif /* PMIX_MCA_PINSTALLDIRS_PINSTALLDIRS_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/runtime/Makefile.include new file mode 100644 index 0000000000..9c1c170dab --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/Makefile.include @@ -0,0 +1,36 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2007 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, LLC. +# All rights reserved. +# Copyright (c) 2014-2016 Intel, Inc. All rights reserved +# Copyright (c) 2014 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 + +dist_pmixdata_DATA += runtime/help-pmix-runtime.txt + +headers += \ + runtime/pmix_rte.h \ + runtime/pmix_progress_threads.h + +libpmix_la_SOURCES += \ + runtime/pmix_finalize.c \ + runtime/pmix_init.c \ + runtime/pmix_params.c \ + runtime/pmix_progress_threads.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/help-pmix-runtime.txt b/opal/mca/pmix/pmix2x/pmix/src/runtime/help-pmix-runtime.txt new file mode 100644 index 0000000000..01b5a84227 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/help-pmix-runtime.txt @@ -0,0 +1,68 @@ +# -*- text -*- +# +# Copyright (c) 2004-2007 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) 2011 Oak Ridge National Labs. All rights reserved. +# Copyright (c) 2014 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# +# This is the US/English general help file for PMIX. +# +[pmix_init:startup:internal-failure] +It looks like pmix_init failed for some reason; your parallel process is +likely to abort. There are many reasons that a parallel process can +fail during pmix_init; some of which are due to configuration or +environment problems. This failure appears to be an internal failure; +here's some additional information (which may only be relevant to an +PMIX developer): + + %s failed + --> Returned value %d instead of PMIX_SUCCESS +# +[pmix_cr_init:no-crs] +It looks like pmix_cr_init failed. This usually means that the CRS component +could not be activated on this machine. Check the installation of your +checkpointer, MCA parameters, and configuration. If all of that seems +correct, then copy this error message with the additional information below +to the PMIX users list. + Function: %s + Return value: %d +# +# Just want a clean printout for sys limit as the +# message was already generated by show-help +[pmix_init:syslimit] +%s +# +[pmix_init:warn-fork] +A process has executed an operation involving a call to the +"fork()" system call to create a child process. PMIX is currently +operating in a condition that could result in memory corruption or +other system errors; your job may hang, crash, or produce silent +data corruption. The use of fork() (or system() or other calls that +create child processes) is strongly discouraged. + +The process that invoked fork was: + + Local host: %s (PID %d) + +If you are *absolutely sure* that your application will successfully +and correctly survive a call to fork(), you may disable this warning +by setting the mpi_warn_on_fork MCA parameter to 0. +# +[mpi-params:leave-pinned-and-pipeline-selected] +WARNING: Cannot set both the MCA parameters pmix_leave_pinned (a.k.a., +mpi_leave_pinned) and pmix_leave_pinned_pipeline (a.k.a., +mpi_leave_pinned_pipeline) to "true". Defaulting to mpi_leave_pinned +ONLY. diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c new file mode 100644 index 0000000000..fafb0ccbcb --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2004-2010 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) 2008-2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2010-2015 Los Alamos National Security, LLC. + * All rights reserved. + * Copyright (c) 2013-2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** @file **/ + +#include + +#if 0 + +#include "src/class/pmix_object.h" +#include "src/client/pmix_client_ops.h" +#include "src/usock/usock.h" +#include "src/util/output.h" +#include "src/util/keyval_parse.h" +#include "src/util/show_help.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_var.h" +#include "src/mca/pinstalldirs/base/base.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/psec/base/base.h" +#include PMIX_EVENT_HEADER + +#include "src/runtime/pmix_rte.h" +#include "src/runtime/pmix_progress_threads.h" + +extern int pmix_initialized; +extern bool pmix_init_called; + +static void __pmix_attribute_destructor__ pmix_cleanup (void) +{ + if (!pmix_initialized) { + /* nothing to do */ + return; + } + + /* finalize the class/object system */ + pmix_class_finalize(); +} + +void pmix_rte_finalize(void) +{ + if( --pmix_initialized != 0 ) { + if( pmix_initialized < 0 ) { + fprintf(stderr, "PMIx Finalize called too many times\n"); + return; + } + return; + } + + /* shutdown communications */ + pmix_usock_finalize(); + if (PMIX_PROC_CLIENT == pmix_globals.proc_type && + 0 <= pmix_client_globals.myserver.sd) { + CLOSE_THE_SOCKET(pmix_client_globals.myserver.sd); + } + #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); + + /* Clear out all the registered MCA params */ + pmix_deregister_params(); + pmix_mca_base_var_finalize(); + + /* keyval lex-based parser */ + pmix_util_keyval_parse_finalize(); + + (void)pmix_mca_base_framework_close(&pmix_pinstalldirs_base_framework); + + /* finalize the show_help system */ + pmix_show_help_finalize(); + + /* finalize the output system. This has to come *after* the + malloc code, as the malloc code needs to call into this, but + the malloc code turning off doesn't affect pmix_output that + much */ + pmix_output_finalize(); + + /* close the bfrops */ + (void)pmix_mca_base_framework_close(&pmix_bfrops_base_framework); + + if (!pmix_globals.external_evbase) { + /* stop the progress thread */ + (void)pmix_progress_thread_finalize(NULL); + #ifdef HAVE_LIBEVENT_GLOBAL_SHUTDOWN + pmix_libevent_global_shutdown(); + #endif + } + + /* 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); + + #if PMIX_NO_LIB_DESTRUCTOR + pmix_cleanup(); + #endif +} +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c new file mode 100644 index 0000000000..6811069c45 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c @@ -0,0 +1,248 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2010 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) 2007-2012 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved. + * Copyright (c) 2010-2015 Los Alamos National Security, LLC. + * All rights reserved. + * Copyright (c) 2013-2016 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 + +#if 0 + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/util/output.h" +#include "src/util/show_help.h" +#include "src/mca/base/base.h" +#include "src/mca/base/pmix_mca_base_var.h" +#include "src/mca/pinstalldirs/base/base.h" +#include "src/mca/bfrops/base/base.h" +#include "src/mca/psec/base/base.h" + +#include "src/event/pmix_event.h" +#include "src/include/types.h" +#include "src/usock/usock.h" +#include "src/util/error.h" +#include "src/util/keyval_parse.h" + +#include "src/runtime/pmix_rte.h" +#include "src/runtime/pmix_progress_threads.h" + +#if PMIX_CC_USE_PRAGMA_IDENT +#pragma ident PMIX_IDENT_STRING +#elif PMIX_CC_USE_IDENT +#ident PMIX_IDENT_STRING +#endif +const char pmix_version_string[] = PMIX_IDENT_STRING; + +int pmix_initialized = 0; +bool pmix_init_called = false; +pmix_globals_t pmix_globals = { + .init_cntr = 0, + .mypeer = NULL, + .pindex = 0, + .evbase = NULL, + .external_evbase = false, + .debug_output = -1, + .proc_type = PMIX_PROC_UNDEF, + .connected = false, + .cache_local = NULL, + .cache_remote = NULL +}; + + +int pmix_rte_init(pmix_proc_type_t type, + pmix_info_t info[], size_t ninfo) +{ + int ret, debug_level; + char *error = NULL, *evar; + char *param; + size_t n; + + if( ++pmix_initialized != 1 ) { + if( pmix_initialized < 1 ) { + return PMIX_ERROR; + } + return PMIX_SUCCESS; + } + + #if PMIX_NO_LIB_DESTRUCTOR + if (pmix_init_called) { + /* can't use show_help here */ + fprintf (stderr, "pmix_init: attempted to initialize after finalize without compiler " + "support for either __attribute__(destructor) or linker support for -fini -- process " + "will likely abort\n"); + return PMIX_ERR_NOT_SUPPORTED; + } + #endif + + pmix_init_called = true; + + /* initialize the output system */ + if (!pmix_output_init()) { + return PMIX_ERROR; + } + + /* initialize install dirs code */ + if (PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_pinstalldirs_base_framework, 0))) { + fprintf(stderr, "pmix_pinstalldirs_base_open() failed -- process will likely abort (%s:%d, returned %d instead of PMIX_SUCCESS)\n", + __FILE__, __LINE__, ret); + return ret; + } + + /* initialize the help system */ + pmix_show_help_init(); + + /* keyval lex-based parser */ + if (PMIX_SUCCESS != (ret = pmix_util_keyval_parse_init())) { + error = "pmix_util_keyval_parse_init"; + goto return_error; + } + + /* Setup the parameter system */ + if (PMIX_SUCCESS != (ret = pmix_mca_base_var_init())) { + error = "mca_base_var_init"; + goto return_error; + } + + /* read any param files that were provided */ + if (PMIX_SUCCESS != (ret = pmix_mca_base_var_cache_files(false))) { + error = "failed to cache files"; + goto return_error; + } + + /* register params for pmix */ + if (PMIX_SUCCESS != (ret = pmix_register_params())) { + error = "pmix_register_params"; + goto return_error; + } + + /* initialize the mca */ + if (PMIX_SUCCESS != (ret = pmix_mca_base_open())) { + error = "mca_base_open"; + goto return_error; + } + + /* 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); + /* get our effective id's */ + pmix_globals.uid = geteuid(); + pmix_globals.gid = getegid(); + /* see if debug is requested */ + if (NULL != (evar = getenv("PMIX_DEBUG"))) { + debug_level = strtol(evar, NULL, 10); + pmix_globals.debug_output = pmix_output_open(NULL); + pmix_output_set_verbosity(pmix_globals.debug_output, debug_level); + } + /* create our peer object */ + pmix_globals.mypeer = PMIX_NEW(pmix_peer_t); + + /* scan incoming info for directives */ + if (NULL != info) { + for (n=0; n < ninfo; n++) { + if (0 == strcmp(PMIX_EVENT_BASE, info[n].key)) { + pmix_globals.evbase = (pmix_event_base_t*)info[n].value.data.ptr; + pmix_globals.external_evbase = true; + } + } + } + + /* open the bfrops - we will select the active plugin later */ + 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 psec and select the default module for this environment */ + if (PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_psec_base_framework, 0))) { + error = "pmix_psec_base_open"; + goto return_error; + } + if (PMIX_SUCCESS != (ret = pmix_psec_base_select())) { + error = "pmix_psec_base_select"; + goto return_error; + } + param = getenv("PMIX_SEC_MODULE"); // if directive was given, use it + pmix_globals.mypeer->comm.sec = pmix_psec_base_assign_module(param); + + /* tell libevent that we need thread support */ + pmix_event_use_threads(); + if (!pmix_globals.external_evbase) { + /* create an event base and progress thread for us */ + if (NULL == (pmix_globals.evbase = pmix_progress_thread_init(NULL))) { + error = "progress thread"; + ret = PMIX_ERROR; + goto return_error; + } + } + + /* open the PMIx Transport Layer (ptl) - we will select the + * active plugin later */ + if( PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_ptl_base_framework, 0)) ) { + error = "pmix_ptl_base_open"; + goto return_error; + } + if( PMIX_SUCCESS != (ret = pmix_ptl_base_select()) ) { + error = "pmix_ptl_base_select"; + goto return_error; + } + + /* open the dstor framework - we will select the active + * plugin later */ + if( PMIX_SUCCESS != (ret = pmix_mca_base_framework_open(&pmix_pdstor_base_framework, 0)) ) { + error = "pmix_pdstor_base_open"; + goto return_error; + } + if( PMIX_SUCCESS != (ret = pmix_pdstor_base_select()) ) { + error = "pmix_pdstor_base_select"; + goto return_error; + } + + /* setup the usock service */ + if (PMIX_PROC_SERVER == type) { + pmix_usock_init(NULL); + } else { + pmix_usock_init(pmix_client_notify_recv); + } + + return PMIX_SUCCESS; + + return_error: + pmix_show_help( "help-pmix-runtime.txt", + "pmix_init:startup:internal-failure", true, + error, ret ); + return ret; +} + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_params.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_params.c new file mode 100644 index 0000000000..34c4e9e428 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_params.c @@ -0,0 +1,91 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2014 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) 2006 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2008-2015 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved. + * Copyright (c) 2010-2014 Los Alamos National Security, LLC. + * All rights reserved. + * Copyright (c) 2014 Hochschule Esslingen. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2015 Mellanox Technologies, Inc. + * All rights reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "pmix_config.h" + +#include "src/include/types.h" +#include "src/mca/base/pmix_mca_base_var.h" +#include "src/runtime/pmix_rte.h" +#include "src/util/timings.h" + +#if PMIX_ENABLE_TIMING +char *pmix_timing_sync_file = NULL; +char *pmix_timing_output = NULL; +bool pmix_timing_overhead = true; +#endif + +static bool pmix_register_done = false; + +pmix_status_t pmix_register_params(void) +{ + if (pmix_register_done) { + return PMIX_SUCCESS; + } + + pmix_register_done = true; + +#if PMIX_ENABLE_TIMING + pmix_timing_sync_file = NULL; + (void) pmix_mca_base_var_register ("pmix", "pmix", NULL, "timing_sync_file", + "Clock synchronisation information generated by mpisync tool. You don't need to touch this if you use mpirun_prof tool.", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + PMIX_INFO_LVL_9, PMIX_MCA_BASE_VAR_SCOPE_ALL, + &pmix_timing_sync_file); + if( pmix_timing_clocksync_read(pmix_timing_sync_file) ){ + pmix_output(0, "Cannot read file %s containing clock synchronisation information\n", pmix_timing_sync_file); + } + + pmix_timing_output = NULL; + (void) pmix_mca_base_var_register ("pmix", "pmix", NULL, "timing_output", + "The name of output file for timing information. If this parameter is not set then output will be directed into PMIX debug channel.", + PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + PMIX_INFO_LVL_9, PMIX_MCA_BASE_VAR_SCOPE_ALL, + &pmix_timing_output); + + pmix_timing_overhead = true; + (void) pmix_mca_base_var_register ("pmix", "pmix", NULL, "timing_overhead", + "Timing framework introduce additional overhead (malloc's mostly)." + " The time spend in such costly routines is measured and may be accounted" + " (subtracted from timestamps). 'true' means consider overhead, 'false' - ignore (default: true).", + PMIX_MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, + PMIX_INFO_LVL_9, PMIX_MCA_BASE_VAR_SCOPE_ALL, + &pmix_timing_overhead); +#endif + + return PMIX_SUCCESS; +} + +pmix_status_t pmix_deregister_params(void) +{ + pmix_register_done = false; + + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.c new file mode 100644 index 0000000000..2540f0714a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include +#include "src/include/types.h" + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include PMIX_EVENT_HEADER + +#include "src/class/pmix_list.h" +#include "src/util/error.h" +#include "src/util/fd.h" + +#include "src/runtime/pmix_progress_threads.h" + +/* define a thread object */ +#define PMIX_THREAD_CANCELLED ((void*)1); +typedef void *(*pmix_thread_fn_t) (pmix_object_t *); + +typedef struct pmix_thread_t { + pmix_object_t super; + pmix_thread_fn_t t_run; + void* t_arg; + pthread_t t_handle; +} pmix_thread_t; +static void ptcon(pmix_thread_t *p) +{ + p->t_arg = NULL; + p->t_handle = (pthread_t) -1; +} +PMIX_CLASS_INSTANCE(pmix_thread_t, + pmix_object_t, + ptcon, NULL); + +static int pmix_thread_start(pmix_thread_t *t) +{ + int rc; + + if (PMIX_ENABLE_DEBUG) { + if (NULL == t->t_run || t->t_handle != (pthread_t) -1) { + return PMIX_ERR_BAD_PARAM; + } + } + + rc = pthread_create(&t->t_handle, NULL, (void*(*)(void*)) t->t_run, t); + + return (rc == 0) ? PMIX_SUCCESS : PMIX_ERROR; +} + + +static int pmix_thread_join(pmix_thread_t *t, void **thr_return) +{ + int rc = pthread_join(t->t_handle, thr_return); + t->t_handle = (pthread_t) -1; + return (rc == 0) ? PMIX_SUCCESS : PMIX_ERROR; +} + + +/* create a tracking object for progress threads */ +typedef struct { + pmix_list_item_t super; + + int refcount; + char *name; + + pmix_event_base_t *ev_base; + + /* This will be set to false when it is time for the progress + thread to exit */ + volatile bool ev_active; + + /* This event will always be set on the ev_base (so that the + ev_base is not empty!) */ + pmix_event_t block; + + bool engine_constructed; + pmix_thread_t engine; +} pmix_progress_tracker_t; + +static void tracker_constructor(pmix_progress_tracker_t *p) +{ + p->refcount = 1; // start at one since someone created it + p->name = NULL; + p->ev_base = NULL; + p->ev_active = false; + p->engine_constructed = false; +} + +static void tracker_destructor(pmix_progress_tracker_t *p) +{ + pmix_event_del(&p->block); + + if (NULL != p->name) { + free(p->name); + } + if (NULL != p->ev_base) { + pmix_event_base_free(p->ev_base); + } + if (p->engine_constructed) { + PMIX_DESTRUCT(&p->engine); + } +} + +static PMIX_CLASS_INSTANCE(pmix_progress_tracker_t, + pmix_list_item_t, + tracker_constructor, + tracker_destructor); + +static bool inited = false; +static pmix_list_t tracking; +static struct timeval long_timeout = { + .tv_sec = 3600, + .tv_usec = 0 +}; +static const char *shared_thread_name = "PMIX-wide async progress thread"; + +/* + * If this event is fired, just restart it so that this event base + * continues to have something to block on. + */ +static void dummy_timeout_cb(int fd, short args, void *cbdata) +{ + pmix_progress_tracker_t *trk = (pmix_progress_tracker_t*)cbdata; + + pmix_event_add(&trk->block, &long_timeout); +} + +/* + * Main for the progress thread + */ +static void* progress_engine(pmix_object_t *obj) +{ + pmix_thread_t *t = (pmix_thread_t*)obj; + pmix_progress_tracker_t *trk = (pmix_progress_tracker_t*)t->t_arg; + + while (trk->ev_active) { + pmix_event_loop(trk->ev_base, PMIX_EVLOOP_ONCE); + } + + return PMIX_THREAD_CANCELLED; +} + +static void stop_progress_engine(pmix_progress_tracker_t *trk) +{ + assert(trk->ev_active); + trk->ev_active = false; + + /* break the event loop - this will cause the loop to exit upon + completion of any current event */ + pmix_event_base_loopbreak(trk->ev_base); + + pmix_thread_join(&trk->engine, NULL); +} + +static int start_progress_engine(pmix_progress_tracker_t *trk) +{ + assert(!trk->ev_active); + trk->ev_active = true; + + /* fork off a thread to progress it */ + trk->engine.t_run = progress_engine; + trk->engine.t_arg = trk; + + int rc = pmix_thread_start(&trk->engine); + if (PMIX_SUCCESS != rc) { + PMIX_ERROR_LOG(rc); + } + + return rc; +} + +pmix_event_base_t *pmix_progress_thread_init(const char *name) +{ + pmix_progress_tracker_t *trk; + int rc; + + if (!inited) { + PMIX_CONSTRUCT(&tracking, pmix_list_t); + inited = true; + } + + if (NULL == name) { + name = shared_thread_name; + } + + /* check if we already have this thread */ + PMIX_LIST_FOREACH(trk, &tracking, pmix_progress_tracker_t) { + if (0 == strcmp(name, trk->name)) { + /* we do, so up the refcount on it */ + ++trk->refcount; + /* return the existing base */ + return trk->ev_base; + } + } + + trk = PMIX_NEW(pmix_progress_tracker_t); + if (NULL == trk) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + return NULL; + } + + trk->name = strdup(name); + if (NULL == trk->name) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + PMIX_RELEASE(trk); + return NULL; + } + + if (NULL == (trk->ev_base = pmix_event_base_create())) { + PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); + PMIX_RELEASE(trk); + return NULL; + } + + /* add an event to the new event base (if there are no events, + pmix_event_loop() will return immediately) */ + pmix_event_set(trk->ev_base, &trk->block, -1, PMIX_EV_PERSIST, + dummy_timeout_cb, trk); + pmix_event_add(&trk->block, &long_timeout); + + /* construct the thread object */ + PMIX_CONSTRUCT(&trk->engine, pmix_thread_t); + trk->engine_constructed = true; + if (PMIX_SUCCESS != (rc = start_progress_engine(trk))) { + PMIX_ERROR_LOG(rc); + PMIX_RELEASE(trk); + return NULL; + } + pmix_list_append(&tracking, &trk->super); + + return trk->ev_base; +} + +int pmix_progress_thread_finalize(const char *name) +{ + pmix_progress_tracker_t *trk; + + if (!inited) { + /* nothing we can do */ + return PMIX_ERR_NOT_FOUND; + } + + if (NULL == name) { + name = shared_thread_name; + } + + /* find the specified engine */ + PMIX_LIST_FOREACH(trk, &tracking, pmix_progress_tracker_t) { + if (0 == strcmp(name, trk->name)) { + /* decrement the refcount */ + --trk->refcount; + + /* If the refcount is still above 0, we're done here */ + if (trk->refcount > 0) { + return PMIX_SUCCESS; + } + + /* If the progress thread is active, stop it */ + if (trk->ev_active) { + stop_progress_engine(trk); + } + + pmix_list_remove_item(&tracking, &trk->super); + PMIX_RELEASE(trk); + return PMIX_SUCCESS; + } + } + + return PMIX_ERR_NOT_FOUND; +} + +/* + * Stop the progress thread, but don't delete the tracker (or event base) + */ +int pmix_progress_thread_pause(const char *name) +{ + pmix_progress_tracker_t *trk; + + if (!inited) { + /* nothing we can do */ + return PMIX_ERR_NOT_FOUND; + } + + if (NULL == name) { + name = shared_thread_name; + } + + /* find the specified engine */ + PMIX_LIST_FOREACH(trk, &tracking, pmix_progress_tracker_t) { + if (0 == strcmp(name, trk->name)) { + if (trk->ev_active) { + stop_progress_engine(trk); + } + + return PMIX_SUCCESS; + } + } + + return PMIX_ERR_NOT_FOUND; +} + +int pmix_progress_thread_resume(const char *name) +{ + pmix_progress_tracker_t *trk; + + if (!inited) { + /* nothing we can do */ + return PMIX_ERR_NOT_FOUND; + } + + if (NULL == name) { + name = shared_thread_name; + } + + /* find the specified engine */ + PMIX_LIST_FOREACH(trk, &tracking, pmix_progress_tracker_t) { + if (0 == strcmp(name, trk->name)) { + if (trk->ev_active) { + return PMIX_ERR_RESOURCE_BUSY; + } + + return start_progress_engine(trk); + } + } + + return PMIX_ERR_NOT_FOUND; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.h b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.h new file mode 100644 index 0000000000..91f099b953 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_PROGRESS_THREADS_H +#define PMIX_PROGRESS_THREADS_H + +#include "pmix_config.h" + +/** + * Initialize a progress thread name; if a progress thread is not + * already associated with that name, start a progress thread. + * + * If you have general events that need to run in *a* progress thread + * (but not necessarily a your own, dedicated progress thread), pass + * NULL the "name" argument to the pmix_progress_thead_init() function + * to glom on to the general PMIX-wide progress thread. + * + * If a name is passed that was already used in a prior call to + * pmix_progress_thread_init(), the event base associated with that + * already-running progress thread will be returned (i.e., no new + * progress thread will be started). + */ +pmix_event_base_t *pmix_progress_thread_init(const char *name); + +/** + * Finalize a progress thread name (reference counted). + * + * Once this function is invoked as many times as + * pmix_progress_thread_init() was invoked on this name (or NULL), the + * progress function is shut down and the event base associated with + * it is destroyed. + * + * Will return PMIX_ERR_NOT_FOUND if the progress thread name does not + * exist; PMIX_SUCCESS otherwise. + */ +int pmix_progress_thread_finalize(const char *name); + +/** + * Temporarily pause the progress thread associated with this name. + * + * This function does not destroy the event base associated with this + * progress thread name, but it does stop processing all events on + * that event base until pmix_progress_thread_resume() is invoked on + * that name. + * + * Will return PMIX_ERR_NOT_FOUND if the progress thread name does not + * exist; PMIX_SUCCESS otherwise. + */ +int pmix_progress_thread_pause(const char *name); + +/** + * Restart a previously-paused progress thread associated with this + * name. + * + * Will return PMIX_ERR_NOT_FOUND if the progress thread name does not + * exist; PMIX_SUCCESS otherwise. + */ +int pmix_progress_thread_resume(const char *name); + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_rte.h b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_rte.h new file mode 100644 index 0000000000..51ed5a5e14 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_rte.h @@ -0,0 +1,78 @@ +/* + * 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) 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** @file **/ + +#ifndef PMIX_RTE_H +#define PMIX_RTE_H + +#include "pmix_config.h" +#include "pmix_common.h" +#include "src/class/pmix_object.h" + +#include +#include +#include +#include PMIX_EVENT_HEADER + +#include "src/include/pmix_globals.h" + +BEGIN_C_DECLS + +#if PMIX_ENABLE_TIMING +extern char *pmix_timing_sync_file; +extern char *pmix_timing_output; +extern bool pmix_timing_overhead; +#endif + +extern int pmix_initialized; + +/** version string of pmix */ +extern const char pmix_version_string[]; + +/** + * Initialize the PMIX layer, including the MCA system. + * + * @retval PMIX_SUCCESS Upon success. + * @retval PMIX_ERROR Upon failure. + * + */ +pmix_status_t pmix_rte_init(pmix_proc_type_t type, + pmix_info_t info[], size_t ninfo); + +/** + * Finalize the PMIX layer, including the MCA system. + * + */ +void pmix_rte_finalize(void); + +/** + * Internal function. Do not call. + */ +pmix_status_t pmix_register_params(void); +pmix_status_t pmix_deregister_params(void); + +void pmix_client_notify_recv(struct pmix_peer_t *peer, pmix_usock_hdr_t *hdr, + pmix_buffer_t *buf, void *cbdata); + +END_C_DECLS + +#endif /* PMIX_RTE_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/sec/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/sec/Makefile.am index 85a51882df..479387a5ba 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/sec/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/sec/Makefile.am @@ -8,25 +8,25 @@ # headers += \ - src/sec/pmix_sec.h \ - src/sec/pmix_native.h + sec/pmix_sec.h \ + sec/pmix_native.h sources += \ - src/sec/pmix_sec.c \ - src/sec/pmix_native.c + sec/pmix_sec.c \ + sec/pmix_native.c if PMIX_WANT_MUNGE headers += \ - src/sec/pmix_munge.h + sec/pmix_munge.h sources += \ - src/sec/pmix_munge.c + sec/pmix_munge.c endif if PMIX_WANT_SASL headers += \ - src/sec/pmix_sasl.h + sec/pmix_sasl.h sources += \ - src/sec/pmix_sasl.c + sec/pmix_sasl.c endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_munge.c b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_munge.c index 3502335674..7698ab42c4 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_munge.c +++ b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_munge.c @@ -12,7 +12,7 @@ #include -#include +#include #include "src/include/pmix_globals.h" #include "src/util/argv.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_native.c b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_native.c index a4dd549a02..170e186cff 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_native.c +++ b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_native.c @@ -11,7 +11,7 @@ #include -#include +#include #include "src/include/pmix_socket_errno.h" #include "src/include/pmix_globals.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sasl.c b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sasl.c index 04a858d8ad..abf475c367 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sasl.c +++ b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sasl.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include "src/include/pmix_globals.h" @@ -51,7 +51,6 @@ #include "src/util/error.h" #include "src/util/output.h" #include "src/util/pmix_environ.h" -#include "src/util/progress_threads.h" #include "src/usock/usock.h" #include "pmix_sasl.h" @@ -76,7 +75,7 @@ static int sasl_init(void) { pmix_output_verbose(2, pmix_globals.debug_output, "sec: sasl init"); - + return PMIX_ERR_NOT_SUPPORTED; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.c b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.c index 24934bee07..33e7cdf161 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.c +++ b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.c @@ -14,9 +14,9 @@ #include #include -#include +#include -#include +#include #include "src/include/pmix_globals.h" #ifdef HAVE_STRING_H diff --git a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.h b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.h index 73e3dec6fe..5e0385342e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.h +++ b/opal/mca/pmix/pmix2x/pmix/src/sec/pmix_sec.h @@ -132,11 +132,11 @@ typedef struct { pmix_sec_base_module_server_hndshk_fn_t server_handshake; } pmix_sec_base_module_t; -PMIX_DECLSPEC extern pmix_sec_base_module_t pmix_sec; +extern pmix_sec_base_module_t pmix_sec; /* initialize and finalize the security system */ -PMIX_DECLSPEC int pmix_sec_init(void); -PMIX_DECLSPEC void pmix_sec_finalize(void); +int pmix_sec_init(void); +void pmix_sec_finalize(void); END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.am deleted file mode 100644 index 88b0468e47..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2014-2015 Intel, Inc. All rights reserved. -# Copyright (c) 2014 Artem Y. Polyakov . -# All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -headers += \ - src/server/pmix_server_ops.h - -sources += \ - src/server/pmix_server.c \ - src/server/pmix_server_ops.c \ - src/server/pmix_server_regex.c \ - src/server/pmix_server_listener.c \ - src/server/pmix_server_get.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.include new file mode 100644 index 0000000000..e62f430538 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/server/Makefile.include @@ -0,0 +1,22 @@ +# -*- makefile -*- +# +# Copyright (c) 2014-2016 Intel, Inc. All rights reserved. +# Copyright (c) 2014 Artem Y. Polyakov . +# All rights reserved. +# Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers += \ + server/pmix_server_ops.h + +sources += \ + server/pmix_server.c \ + server/pmix_server_ops.c \ + server/pmix_server_regex.c \ + server/pmix_server_get.c \ + server/pmix_server_listener.c 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 80733ba54f..7d2105ad9c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c +++ b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c @@ -18,11 +18,11 @@ #include #include -#include +#include #include #include -#include +#include #include "src/include/pmix_globals.h" #ifdef HAVE_STRING_H @@ -52,7 +52,7 @@ #include "src/util/error.h" #include "src/util/output.h" #include "src/util/pmix_environ.h" -#include "src/util/progress_threads.h" +#include "src/runtime/pmix_progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) @@ -240,20 +240,39 @@ PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module, bool session_tool = false; pmix_listener_t *tl; - ++pmix_globals.init_cntr; - if (1 < pmix_globals.init_cntr) { + if (0 < pmix_globals.init_cntr) { return PMIX_SUCCESS; } pmix_output_verbose(2, pmix_globals.debug_output, "pmix:server init called"); + /* Check for the info keys that are not independent from + * initialize_server_base() and even may be needed there */ + if (NULL != info) { + for (n=0; n < ninfo; n++) { + if (0 == strcmp(info[n].key, PMIX_SERVER_TMPDIR) && + NULL == mytmpdir) { + mytmpdir = strdup(info[n].value.data.string); + /* push this onto our protected list of keys not + * to be passed to the clients */ + pmix_argv_append_nosize(&protected, PMIX_SERVER_TMPDIR); + } else if (0 == strcmp(info[n].key, PMIX_SYSTEM_TMPDIR) && + NULL == systmpdir) { + systmpdir = strdup(info[n].value.data.string); + /* push this onto our protected list of keys not + * to be passed to the clients */ + pmix_argv_append_nosize(&protected, PMIX_SYSTEM_TMPDIR); + } + } + } + if (0 != (rc = initialize_server_base(module))) { return rc; } #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) - if (PMIX_SUCCESS != (rc = pmix_dstore_init())) { + if (PMIX_SUCCESS != (rc = pmix_dstore_init(info, ninfo))) { return rc; } #endif /* PMIX_ENABLE_DSTORE */ @@ -262,13 +281,12 @@ PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module, pmix_usock_init(NULL); /* create an event base and progress thread for us */ - if (NULL == (pmix_globals.evbase = pmix_start_progress_thread())) { + if (NULL == (pmix_globals.evbase = pmix_progress_thread_init(NULL))) { return PMIX_ERR_INIT; } /* check the info keys for a directive about the uid/gid - * to be set for the rendezvous file, and for indication - * of willingness to support tool connections */ + * to be set for the rendezvous file */ if (NULL != info) { for (n=0; n < ninfo; n++) { if (0 == strcmp(info[n].key, PMIX_USERID)) { @@ -309,16 +327,6 @@ PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module, /* push this onto our protected list of keys not * to be passed to the clients */ pmix_argv_append_nosize(&protected, PMIX_SERVER_TOOL_SUPPORT); - } else if (0 == strcmp(info[n].key, PMIX_SERVER_TMPDIR)) { - mytmpdir = strdup(info[n].value.data.string); - /* push this onto our protected list of keys not - * to be passed to the clients */ - pmix_argv_append_nosize(&protected, PMIX_SERVER_TMPDIR); - } else if (0 == strcmp(info[n].key, PMIX_SYSTEM_TMPDIR)) { - systmpdir = strdup(info[n].value.data.string); - /* push this onto our protected list of keys not - * to be passed to the clients */ - pmix_argv_append_nosize(&protected, PMIX_SYSTEM_TMPDIR); } } } @@ -447,6 +455,8 @@ PMIX_EXPORT pmix_status_t PMIx_server_init(pmix_server_module_t *module, PMIX_DESTRUCT(&kv); } + ++pmix_globals.init_cntr; + return PMIX_SUCCESS; } @@ -492,7 +502,6 @@ static void cleanup_server_state(void) PMIX_EXPORT pmix_status_t PMIx_server_finalize(void) { - if (1 != pmix_globals.init_cntr) { --pmix_globals.init_cntr; return PMIX_SUCCESS; @@ -506,8 +515,7 @@ PMIX_EXPORT pmix_status_t PMIx_server_finalize(void) pmix_stop_listening(); } - pmix_stop_progress_thread(pmix_globals.evbase); - event_base_free(pmix_globals.evbase); + pmix_progress_thread_finalize(NULL); #ifdef HAVE_LIBEVENT_GLOBAL_SHUTDOWN libevent_global_shutdown(); #endif @@ -676,6 +684,13 @@ static void _register_nspace(int sd, short args, void *cbdata) } /* do not destruct the kv object - no memory leak will result */ +#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) + if (0 > pmix_dstore_nspace_add(cd->proc.nspace)) { + PMIX_ERROR_LOG(rc); + goto release; + } +#endif + release: if (NULL != nodes) { pmix_argv_free(nodes); @@ -1062,6 +1077,11 @@ PMIX_EXPORT pmix_status_t PMIx_server_setup_fork(const pmix_proc_t *proc, char * /* pass our active security mode */ pmix_setenv("PMIX_SECURITY_MODE", security_mode, true, env); +#if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) + /* pass dstore path to files */ + pmix_dstore_patch_env(env); +#endif + return PMIX_SUCCESS; } 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 fca6dafed7..17227a1166 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 @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -51,7 +51,6 @@ #include "src/util/error.h" #include "src/util/output.h" #include "src/util/pmix_environ.h" -#include "src/util/progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_listener.c b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_listener.c index da608c986b..f44475c626 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_listener.c +++ b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_listener.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -56,7 +56,6 @@ #include "src/util/getid.h" #include "src/util/output.h" #include "src/util/pmix_environ.h" -#include "src/util/progress_threads.h" #include "src/util/strnlen.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" @@ -533,7 +532,7 @@ static pmix_status_t pmix_server_authenticate(pmix_pending_connection_t *pnd, { char *msg, *nspace, *version, *cred; pmix_status_t rc; - pmix_rank_t rank; + pmix_rank_t rank=PMIX_RANK_UNDEF; pmix_usock_hdr_t hdr; pmix_nspace_t *nptr, *tmp; pmix_rank_info_t *info; 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 5c8a4710ac..55c93bdade 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 @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -51,7 +51,6 @@ #include "src/util/error.h" #include "src/util/output.h" #include "src/util/pmix_environ.h" -#include "src/util/progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" 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 06b7bd8dfb..cf4c4bf2ec 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 @@ -16,7 +16,7 @@ #include -#include +#include #include #include #include "src/usock/usock.h" 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 index cc0caa01d4..b1a261635f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_regex.c +++ b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server_regex.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include "src/include/pmix_globals.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/sm/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/sm/Makefile.am deleted file mode 100644 index 476011224e..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2016 Mellanox Technologies, Inc. -# All rights reserved. -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -headers += \ - src/sm/pmix_sm.h \ - src/sm/pmix_mmap.h - -sources += \ - src/sm/pmix_sm.c \ - src/sm/pmix_mmap.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.c b/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.c deleted file mode 100644 index 5a104d757f..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2015-2016 Mellanox Technologies, Inc. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - - -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#include -#include -#include - -#include -#include -#include "src/include/pmix_globals.h" - -#include "pmix_sm.h" -#include "pmix_mmap.h" - -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -# define MAP_ANONYMOUS MAP_ANON -#endif /* MAP_ANONYMOUS and MAP_ANON */ - - -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); -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 = { - "mmap", - _mmap_segment_create, - _mmap_segment_attach, - _mmap_segment_detach, - _mmap_segment_unlink -}; - - -int _mmap_segment_create(pmix_sm_seg_t *sm_seg, const char *file_name, size_t size) -{ - int rc = PMIX_SUCCESS; - void *seg_addr = MAP_FAILED; - pid_t my_pid = getpid(); - - _segment_ds_reset(sm_seg); - /* enough space is available, so create the segment */ - if (-1 == (sm_seg->seg_id = open(file_name, O_CREAT | O_RDWR, 0600))) { - pmix_output_verbose(2, pmix_globals.debug_output, - "sys call open(2) fail\n"); - rc = PMIX_ERROR; - goto out; - } - /* size backing file - note the use of real_size here */ - if (0 != ftruncate(sm_seg->seg_id, size)) { - pmix_output_verbose(2, pmix_globals.debug_output, - "sys call ftruncate(2) fail\n"); - rc = PMIX_ERROR; - goto out; - } - if (MAP_FAILED == (seg_addr = mmap(NULL, size, - PROT_READ | PROT_WRITE, MAP_SHARED, - sm_seg->seg_id, 0))) { - pmix_output_verbose(2, pmix_globals.debug_output, - "sys call mmap(2) fail\n"); - rc = PMIX_ERROR; - goto out; - } - sm_seg->seg_cpid = my_pid; - sm_seg->seg_size = size; - sm_seg->seg_base_addr = (unsigned char *)seg_addr; - (void)strncpy(sm_seg->seg_name, file_name, PMIX_PATH_MAX - 1); - -out: - if (-1 != sm_seg->seg_id) { - if (0 != close(sm_seg->seg_id)) { - pmix_output_verbose(2, pmix_globals.debug_output, - "sys call close(2) fail\n"); - rc = PMIX_ERROR; - } - } - /* an error occured, so invalidate the shmem object and munmap if needed */ - if (PMIX_SUCCESS != rc) { - if (MAP_FAILED != seg_addr) { - munmap((void *)seg_addr, size); - } - _segment_ds_reset(sm_seg); - } - return rc; -} - -int _mmap_segment_attach(pmix_sm_seg_t *sm_seg) -{ - if (-1 == (sm_seg->seg_id = open(sm_seg->seg_name, O_RDWR))) { - return PMIX_ERROR; - } - if (MAP_FAILED == (sm_seg->seg_base_addr = (unsigned char *) - mmap(NULL, sm_seg->seg_size, - PROT_READ | PROT_WRITE, MAP_SHARED, - sm_seg->seg_id, 0))) { - /* mmap failed, so close the file and return NULL - no error check - * here because we are already in an error path... - */ - pmix_output_verbose(2, pmix_globals.debug_output, - "sys call mmap(2) fail\n"); - close(sm_seg->seg_id); - return PMIX_ERROR; - } - /* all is well */ - /* if close fails here, that's okay. just let the user know and - * continue. if we got this far, open and mmap were successful... - */ - if (0 != close(sm_seg->seg_id)) { - pmix_output_verbose(2, pmix_globals.debug_output, - "sys call close(2) fail\n"); - } - sm_seg->seg_cpid = 0;/* FIXME */ - return PMIX_SUCCESS; -} - -int _mmap_segment_detach(pmix_sm_seg_t *sm_seg) -{ - int rc = PMIX_SUCCESS; - - if (0 != munmap((void *)sm_seg->seg_base_addr, sm_seg->seg_size)) { - pmix_output_verbose(2, pmix_globals.debug_output, - "sys call munmap(2) fail\n"); - rc = PMIX_ERROR; - } - /* reset the contents of the pmix_sm_seg_t associated with this - * shared memory segment. - */ - _segment_ds_reset(sm_seg); - return rc; -} - -int _mmap_segment_unlink(pmix_sm_seg_t *sm_seg) -{ - if (-1 == unlink(sm_seg->seg_name)) { - pmix_output_verbose(2, pmix_globals.debug_output, - "sys call unlink(2) fail\n"); - return PMIX_ERROR; - } - - sm_seg->seg_id = PMIX_SHMEM_DS_ID_INVALID; - return PMIX_SUCCESS; -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.h b/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.h deleted file mode 100644 index 349fb10c01..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_mmap.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2015-2016 Mellanox Technologies, Inc. - * All rights reserved. - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#ifndef PMIX_SM_MMAP_H -#define PMIX_SM_MMAP_H - -#include - - -#include "pmix_sm.h" - -BEGIN_C_DECLS - -extern pmix_sm_base_module_t pmix_sm_mmap_module; - -END_C_DECLS - -#endif /* PMIX_SM_MMAP_H */ 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 e508b60550..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) -{ - if (!pmix_sm.segment_attach) { - return PMIX_ERR_NOT_SUPPORTED; - } - - return pmix_sm.segment_attach(sm_seg); -} - -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 6429b07510..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/sm/pmix_sm.h +++ /dev/null @@ -1,117 +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 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); -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); - -/** -* 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/tool/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.include similarity index 83% rename from opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.am rename to opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.include index fd4ffb81f7..7d638ab8c5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/tool/Makefile.include @@ -8,4 +8,4 @@ # sources += \ - src/tool/pmix_tool.c + tool/pmix_tool.c 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 7d18b7b7a2..da652459a3 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/tool/pmix_tool.c +++ b/opal/mca/pmix/pmix2x/pmix/src/tool/pmix_tool.c @@ -64,7 +64,7 @@ extern pmix_client_globals_t pmix_client_globals; #include "src/util/error.h" #include "src/util/hash.h" #include "src/util/output.h" -#include "src/util/progress_threads.h" +#include "src/runtime/pmix_progress_threads.h" #include "src/usock/usock.h" #include "src/sec/pmix_sec.h" #include "src/include/pmix_globals.h" @@ -74,6 +74,9 @@ extern pmix_client_globals_t pmix_client_globals; #define PMIX_MAX_RETRIES 10 +static char *mytmpdir = NULL; +static char *systmpdir = NULL; + static pmix_status_t usock_connect(struct sockaddr_un *address, int *fd); static void _notify_complete(pmix_status_t status, void *cbdata) @@ -189,7 +192,7 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, pmix_kval_t *kptr; pmix_status_t rc; pmix_nspace_t *nptr, *nsptr; - pid_t server_pid; + pid_t server_pid=0; bool server_pid_given = false; int hostnamelen = 30; char hostname[hostnamelen]; @@ -198,8 +201,6 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, bool connect_to_system_server = false; bool connect_to_system_first = false; bool connection_defined = false; - char *mytmpdir = NULL; - char *systmpdir = NULL; if (NULL == proc) { return PMIX_ERR_BAD_PARAM; @@ -327,17 +328,11 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, snprintf(address.sun_path, sizeof(address.sun_path)-1, "%s/pmix.%s.%d", tdir, hostname, server_pid); /* if the rendezvous file doesn't exist, that's an error */ if (0 != access(address.sun_path, R_OK)) { - pmix_output_close(pmix_globals.debug_output); - pmix_output_finalize(); - pmix_class_finalize(); return PMIX_ERR_NOT_FOUND; } } else { /* open up the temp directory */ if (NULL == (cur_dirp = opendir(tdir))) { - pmix_output_close(pmix_globals.debug_output); - pmix_output_finalize(); - pmix_class_finalize(); return PMIX_ERR_NOT_FOUND; } /* search the entries for something that starts with pmix.hostname */ @@ -353,9 +348,6 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, closedir(cur_dirp); free(evar); free(tmp); - pmix_output_close(pmix_globals.debug_output); - pmix_output_finalize(); - pmix_class_finalize(); return PMIX_ERR_INIT; } evar = strdup(dir_entry->d_name); @@ -365,9 +357,6 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, closedir(cur_dirp); if (NULL == evar) { /* none found */ - pmix_output_close(pmix_globals.debug_output); - pmix_output_finalize(); - pmix_class_finalize(); return PMIX_ERR_INIT; } /* use the found one as our contact point */ @@ -382,13 +371,7 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, if (!pmix_globals.external_evbase) { /* create an event base and progress thread for us */ - if (NULL == (pmix_globals.evbase = pmix_start_progress_thread())) { - pmix_sec_finalize(); - pmix_usock_finalize(); - pmix_bfrop_close(); - pmix_output_close(pmix_globals.debug_output); - pmix_output_finalize(); - pmix_class_finalize(); + if (NULL == (pmix_globals.evbase = pmix_progress_thread_init(NULL))) { return -1; } @@ -396,13 +379,6 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, /* connect to the server */ if (PMIX_SUCCESS != (rc = connect_to_server(&address))) { - pmix_stop_progress_thread(pmix_globals.evbase); - pmix_sec_finalize(); - pmix_usock_finalize(); - pmix_bfrop_close(); - pmix_output_close(pmix_globals.debug_output); - pmix_output_finalize(); - pmix_class_finalize(); return rc; } /* increment our init reference counter */ @@ -424,14 +400,6 @@ PMIX_EXPORT int PMIx_tool_init(pmix_proc_t *proc, } } if (NULL == nsptr) { - /* should never happen */ - pmix_stop_progress_thread(pmix_globals.evbase); - pmix_sec_finalize(); - pmix_usock_finalize(); - pmix_bfrop_close(); - pmix_output_close(pmix_globals.debug_output); - pmix_output_finalize(); - pmix_class_finalize(); return PMIX_ERR_NOT_FOUND; } @@ -678,7 +646,7 @@ PMIX_EXPORT pmix_status_t PMIx_tool_finalize(void) "pmix:tool finalize called"); if (!pmix_globals.external_evbase) { - pmix_stop_progress_thread(pmix_globals.evbase); + pmix_progress_thread_finalize(NULL); } pmix_usock_finalize(); @@ -695,6 +663,12 @@ PMIX_EXPORT pmix_status_t PMIx_tool_finalize(void) pmix_bfrop_close(); pmix_sec_finalize(); + if (NULL != mytmpdir) { + free(mytmpdir); + } + if (NULL != systmpdir) { + free(systmpdir); + } pmix_globals_finalize(); pmix_output_close(pmix_globals.debug_output); diff --git a/opal/mca/pmix/pmix2x/pmix/src/usock/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/usock/Makefile.am index 7f75623ca4..d26a6dd248 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/usock/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/usock/Makefile.am @@ -10,8 +10,8 @@ # headers += \ - src/usock/usock.h + usock/usock.h sources += \ - src/usock/usock.c \ - src/usock/usock_sendrecv.c + usock/usock.c \ + usock/usock_sendrecv.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/usock/usock.c b/opal/mca/pmix/pmix2x/pmix/src/usock/usock.c index 6e1c42ad40..1504323b45 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/usock/usock.c +++ b/opal/mca/pmix/pmix2x/pmix/src/usock/usock.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include "src/include/pmix_globals.h" diff --git a/opal/mca/pmix/pmix2x/pmix/src/usock/usock.h b/opal/mca/pmix/pmix2x/pmix/src/usock/usock.h index b9c15ac62a..c7bbc09c6d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/usock/usock.h +++ b/opal/mca/pmix/pmix2x/pmix/src/usock/usock.h @@ -35,7 +35,7 @@ #include #include -#include +#include #ifdef HAVE_UNISTD_H #include diff --git a/opal/mca/pmix/pmix2x/pmix/src/usock/usock_sendrecv.c b/opal/mca/pmix/pmix2x/pmix/src/usock/usock_sendrecv.c index 05658ef987..124718dd59 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/usock/usock_sendrecv.c +++ b/opal/mca/pmix/pmix2x/pmix/src/usock/usock_sendrecv.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include #ifdef HAVE_STRING_H diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.am deleted file mode 100644 index 40cec232a4..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.am +++ /dev/null @@ -1,54 +0,0 @@ -# -# 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) 2007-2010 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2013 NVIDIA Corporation. All rights reserved. -# Copyright (c) 2013 Intel, Inc. All rights reserved -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved -# $COPYRIGHT$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -# Source code files - -headers += \ - src/util/argv.h \ - src/util/error.h \ - src/util/printf.h \ - src/util/output.h \ - src/util/pmix_environ.h \ - src/util/crc.h \ - src/util/progress_threads.h \ - src/util/fd.h \ - src/util/timings.h \ - src/util/os_path.h \ - src/util/basename.h \ - src/util/hash.h \ - src/util/strnlen.h \ - src/util/getid.h - -sources += \ - src/util/argv.c \ - src/util/error.c \ - src/util/printf.c \ - src/util/output.c \ - src/util/pmix_environ.c \ - src/util/crc.c \ - src/util/progress_threads.c \ - src/util/fd.c \ - src/util/timings.c \ - src/util/os_path.c \ - src/util/basename.c \ - src/util/hash.c \ - src/util/getid.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.include new file mode 100644 index 0000000000..9b38cc195f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/Makefile.include @@ -0,0 +1,68 @@ +# -*- 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) 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$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_LFLAGS = -Ppmix_show_help_yy +LEX_OUTPUT_ROOT = lex.pmix_show_help_yy + +# Source code files + +headers += \ + util/argv.h \ + util/error.h \ + util/printf.h \ + util/output.h \ + util/pmix_environ.h \ + util/crc.h \ + util/fd.h \ + util/timings.h \ + util/os_path.h \ + util/basename.h \ + util/keyval_parse.h \ + util/show_help.h \ + util/show_help_lex.h \ + util/path.h \ + util/getid.h \ + util/strnlen.h \ + util/hash.h + +sources += \ + util/argv.c \ + util/error.c \ + util/printf.c \ + util/output.c \ + util/pmix_environ.c \ + util/crc.c \ + util/fd.c \ + util/timings.c \ + util/os_path.c \ + util/basename.c \ + util/keyval_parse.c \ + util/show_help.c \ + util/show_help_lex.l \ + util/path.c \ + util/getid.c \ + util/hash.c + +libpmix_la_LIBADD += \ + util/keyval/libpmixutilkeyval.la +libpmix_la_DEPENDENCIES += \ + util/keyval/libpmixutilkeyval.la diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/argv.h b/opal/mca/pmix/pmix2x/pmix/src/util/argv.h index 8790254f74..d4edd198bb 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/argv.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/argv.h @@ -41,7 +41,7 @@ #include #endif -#include +#include BEGIN_C_DECLS @@ -74,7 +74,7 @@ BEGIN_C_DECLS * value into the argv array; there is no need to keep the original * string (i.e., the arg parameter) after invoking this function. */ -PMIX_DECLSPEC pmix_status_t pmix_argv_append(int *argc, char ***argv, const char *arg) __pmix_attribute_nonnull__(1) __pmix_attribute_nonnull__(3); +pmix_status_t pmix_argv_append(int *argc, char ***argv, const char *arg) __pmix_attribute_nonnull__(1) __pmix_attribute_nonnull__(3); /** * Append to an argv-style array, but ignore the size of the array. @@ -91,7 +91,7 @@ PMIX_DECLSPEC pmix_status_t pmix_argv_append(int *argc, char ***argv, const cha * argv-style arrays that do not have integers that are actively * maintaing their sizes. */ -PMIX_DECLSPEC pmix_status_t pmix_argv_append_nosize(char ***argv, const char *arg); +pmix_status_t pmix_argv_append_nosize(char ***argv, const char *arg); /** * Insert the provided arg at the beginning of the array @@ -102,7 +102,7 @@ PMIX_DECLSPEC pmix_status_t pmix_argv_append_nosize(char ***argv, const char *a * @retval PMIX_SUCCESS On success * @retval PMIX_ERROR On failure */ -PMIX_DECLSPEC pmix_status_t pmix_argv_prepend_nosize(char ***argv, const char *arg); +pmix_status_t pmix_argv_prepend_nosize(char ***argv, const char *arg); /** * Append to an argv-style array, but only if the provided argument @@ -119,7 +119,7 @@ PMIX_DECLSPEC pmix_status_t pmix_argv_prepend_nosize(char ***argv, const char *a * except that it only appends the provided argument if it does not already * exist in the provided array, or overwrites it if it is. */ -PMIX_DECLSPEC pmix_status_t pmix_argv_append_unique_nosize(char ***argv, const char *arg, bool overwrite); +pmix_status_t pmix_argv_append_unique_nosize(char ***argv, const char *arg, bool overwrite); /** * Free a NULL-terminated argv array. @@ -134,7 +134,7 @@ PMIX_DECLSPEC pmix_status_t pmix_argv_append_unique_nosize(char ***argv, const * not safe to invoke this function with a non-NULL-terminated argv * array. */ -PMIX_DECLSPEC void pmix_argv_free(char **argv); +void pmix_argv_free(char **argv); /** * Split a string into a NULL-terminated argv array. Do not include empty @@ -151,7 +151,7 @@ PMIX_DECLSPEC void pmix_argv_free(char **argv); * argument (i.e., it can be freed after calling this function * without invalidating the output argv). */ -PMIX_DECLSPEC char **pmix_argv_split(const char *src_string, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; +char **pmix_argv_split(const char *src_string, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; /** * Split a string into a NULL-terminated argv array. Include empty @@ -168,7 +168,7 @@ PMIX_DECLSPEC char **pmix_argv_split(const char *src_string, int delimiter) __p * argument (i.e., it can be freed after calling this function * without invalidating the output argv). */ -PMIX_DECLSPEC char **pmix_argv_split_with_empty(const char *src_string, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; +char **pmix_argv_split_with_empty(const char *src_string, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; /** * Return the length of a NULL-terminated argv array. @@ -180,7 +180,7 @@ PMIX_DECLSPEC char **pmix_argv_split_with_empty(const char *src_string, int del * * The argv array must be NULL-terminated. */ -PMIX_DECLSPEC int pmix_argv_count(char **argv); +int pmix_argv_count(char **argv); /** * Join all the elements of an argv array into a single @@ -198,9 +198,9 @@ PMIX_DECLSPEC int pmix_argv_count(char **argv); * * It is the callers responsibility to free the returned string. */ -PMIX_DECLSPEC char *pmix_argv_join(char **argv, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; +char *pmix_argv_join(char **argv, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; -PMIX_DECLSPEC char *pmix_argv_join_range(char **argv, size_t start, size_t end, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; +char *pmix_argv_join_range(char **argv, size_t start, size_t end, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; /** * Return the number of bytes consumed by an argv array. @@ -211,7 +211,7 @@ PMIX_DECLSPEC char *pmix_argv_join_range(char **argv, size_t start, size_t end, * array. This includes the number of bytes used by each of the * strings as well as the pointers used in the argv array. */ -PMIX_DECLSPEC size_t pmix_argv_len(char **argv); +size_t pmix_argv_len(char **argv); /** * Copy a NULL-terminated argv array. @@ -225,7 +225,7 @@ PMIX_DECLSPEC size_t pmix_argv_len(char **argv); * Specifically, the output argv will be an array of the same length * as the input argv, and strcmp(argv_in[i], argv_out[i]) will be 0. */ -PMIX_DECLSPEC char **pmix_argv_copy(char **argv) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; +char **pmix_argv_copy(char **argv) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; /** * Delete one or more tokens from the middle of an argv. @@ -252,7 +252,7 @@ PMIX_DECLSPEC char **pmix_argv_copy(char **argv) __pmix_attribute_malloc__ __pm * free()ed (it is assumed that the argv "owns" the memory that * the pointer points to). */ -PMIX_DECLSPEC pmix_status_t pmix_argv_delete(int *argc, char ***argv, +pmix_status_t pmix_argv_delete(int *argc, char ***argv, int start, int num_to_delete); /** @@ -276,7 +276,7 @@ PMIX_DECLSPEC pmix_status_t pmix_argv_delete(int *argc, char ***argv, * source points to are strdup'ed into the new locations in * target). */ -PMIX_DECLSPEC pmix_status_t pmix_argv_insert(char ***target, int start, char **source); +pmix_status_t pmix_argv_insert(char ***target, int start, char **source); /** * Insert one argv element in front of a specific position in an array @@ -299,7 +299,7 @@ PMIX_DECLSPEC pmix_status_t pmix_argv_insert(char ***target, int start, char ** * source points to is strdup'ed into the new location in * target). */ -PMIX_DECLSPEC pmix_status_t pmix_argv_insert_element(char ***target, int location, char *source); +pmix_status_t pmix_argv_insert_element(char ***target, int location, char *source); END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/basename.h b/opal/mca/pmix/pmix2x/pmix/src/util/basename.h index d0cedc62ea..55d29413b4 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/basename.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/basename.h @@ -68,7 +68,7 @@ BEGIN_C_DECLS * * The caller is responsible for freeing the returned string. */ -PMIX_DECLSPEC char *pmix_basename(const char* filename) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; +char *pmix_basename(const char* filename) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; /** * Return the dirname of a filename. @@ -107,7 +107,7 @@ PMIX_DECLSPEC char *pmix_basename(const char* filename) __pmix_attribute_malloc_ * * The caller is responsible for freeing the returned string. */ -PMIX_DECLSPEC char *pmix_dirname(const char* filename) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; +char *pmix_dirname(const char* filename) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/crc.h b/opal/mca/pmix/pmix2x/pmix/src/util/crc.h index 27e64b68f6..d04bbdefba 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/crc.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/crc.h @@ -42,7 +42,7 @@ BEGIN_C_DECLS #define PMIX_CSUM_ZERO 0 -PMIX_DECLSPEC unsigned long +unsigned long pmix_bcopy_csum_partial( const void * source, void * destination, @@ -65,7 +65,7 @@ pmix_bcopy_csum ( return pmix_bcopy_csum_partial(source, destination, copylen, csumlen, &plong, &plength); } -PMIX_DECLSPEC unsigned int +unsigned int pmix_bcopy_uicsum_partial ( const void * source, void * destination, @@ -88,7 +88,7 @@ pmix_bcopy_uicsum ( return pmix_bcopy_uicsum_partial(source, destination, copylen, csumlen, &pint, &plength); } -PMIX_DECLSPEC unsigned long +unsigned long pmix_csum_partial ( const void * source, size_t csumlen, @@ -127,7 +127,7 @@ pmix_csum16 (const void * source, size_t csumlen) return csum; } -PMIX_DECLSPEC unsigned int +unsigned int pmix_uicsum_partial ( const void * source, size_t csumlen, @@ -149,7 +149,7 @@ pmix_uicsum(const void * source, size_t csumlen) void pmix_initialize_crc_table(void); -PMIX_DECLSPEC unsigned int +unsigned int pmix_bcopy_uicrc_partial( const void * source, void * destination, @@ -167,7 +167,7 @@ pmix_bcopy_uicrc( return pmix_bcopy_uicrc_partial(source, destination, copylen, crclen, CRC_INITIAL_REGISTER); } -PMIX_DECLSPEC unsigned int +unsigned int pmix_uicrc_partial( const void * source, size_t crclen, diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/error.c b/opal/mca/pmix/pmix2x/pmix/src/util/error.c index acfee9691b..238cfa3c5d 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/error.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/error.c @@ -31,11 +31,9 @@ #include #endif -#include +#include #include "src/util/error.h" -#include "src/include/pmix_globals.h" -#include "src/buffer_ops/buffer_ops.h" const char* PMIx_Error_string(pmix_status_t errnum) { @@ -139,9 +137,16 @@ const char* PMIx_Error_string(pmix_status_t errnum) return "SILENT_ERROR"; case PMIX_ERROR: return "ERROR"; + case PMIX_ERR_NOT_AVAILABLE: + return "PMIX_ERR_NOT_AVAILABLE"; + case PMIX_ERR_FATAL: + return "PMIX_ERR_FATAL"; + case PMIX_ERR_VALUE_OUT_OF_BOUNDS: + return "PMIX_ERR_VALUE_OUT_OF_BOUNDS"; + case PMIX_ERR_PERM: + return "PMIX_ERR_PERM"; case PMIX_SUCCESS: return "SUCCESS"; - default: return "ERROR STRING NOT FOUND"; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/error.h b/opal/mca/pmix/pmix2x/pmix/src/util/error.h index e2e3c53260..d3a30e0649 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/error.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/error.h @@ -23,7 +23,7 @@ #include -#include +#include #include "src/util/output.h" BEGIN_C_DECLS @@ -56,7 +56,11 @@ #define PMIX_ERR_SILENT (PMIX_INTERNAL_ERR_BASE - 25) #define PMIX_ERR_UNKNOWN_DATATYPE (PMIX_INTERNAL_ERR_BASE - 26) #define PMIX_ERR_RESOURCE_BUSY (PMIX_INTERNAL_ERR_BASE - 27) -#define PMIX_ERR_OPERATION_IN_PROGRESS (PMIX_INTERNAL_ERR_BASE - 28) +#define PMIX_ERR_NOT_AVAILABLE (PMIX_INTERNAL_ERR_BASE - 28) +#define PMIX_ERR_FATAL (PMIX_INTERNAL_ERR_BASE - 29) +#define PMIX_ERR_VALUE_OUT_OF_BOUNDS (PMIX_INTERNAL_ERR_BASE - 30) +#define PMIX_ERR_PERM (PMIX_INTERNAL_ERR_BASE - 31) +#define PMIX_ERR_OPERATION_IN_PROGRESS (PMIX_INTERNAL_ERR_BASE - 32) #define PMIX_ERROR_LOG(r) \ do { \ diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/fd.c b/opal/mca/pmix/pmix2x/pmix/src/util/fd.c index 20f298f4b2..616c6fe97c 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/fd.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/fd.c @@ -13,7 +13,7 @@ #include -#include +#include #ifdef HAVE_UNISTD_H #include diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/fd.h b/opal/mca/pmix/pmix2x/pmix/src/util/fd.h index 6f51936658..ab950ba817 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/fd.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/fd.h @@ -36,7 +36,7 @@ BEGIN_C_DECLS * Loop over reading from the fd until len bytes are read or an error * occurs. EAGAIN and EINTR are transparently handled. */ -PMIX_DECLSPEC pmix_status_t pmix_fd_read(int fd, int len, void *buffer); +pmix_status_t pmix_fd_read(int fd, int len, void *buffer); /** * Write a complete buffer to a file descriptor. @@ -51,7 +51,7 @@ PMIX_DECLSPEC pmix_status_t pmix_fd_read(int fd, int len, void *buffer); * Loop over writing to the fd until len bytes are written or an error * occurs. EAGAIN and EINTR are transparently handled. */ -PMIX_DECLSPEC pmix_status_t pmix_fd_write(int fd, int len, const void *buffer); +pmix_status_t pmix_fd_write(int fd, int len, const void *buffer); /** * Convenience function to set a file descriptor to be close-on-exec. @@ -65,7 +65,7 @@ PMIX_DECLSPEC pmix_status_t pmix_fd_write(int fd, int len, const void *buffer); * This is simply a convenience function because there's a few steps * to setting a file descriptor to be close-on-exec. */ -PMIX_DECLSPEC pmix_status_t pmix_fd_set_cloexec(int fd); +pmix_status_t pmix_fd_set_cloexec(int fd); END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/getid.c b/opal/mca/pmix/pmix2x/pmix/src/util/getid.c index 72b08c3573..f3ad8a9dd4 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/getid.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/getid.c @@ -23,7 +23,7 @@ */ #include -#include "include/pmix/pmix_common.h" +#include "include/pmix_common.h" #include "src/include/pmix_socket_errno.h" #ifdef HAVE_UNISTD_H diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/getid.h b/opal/mca/pmix/pmix2x/pmix/src/util/getid.h index f617f0a57b..871eb6a259 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/getid.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/getid.h @@ -11,7 +11,7 @@ #define PMIX_GETID_H #include -#include "include/pmix/pmix_common.h" +#include "include/pmix_common.h" #ifdef HAVE_UNISTD_H #include diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/hash.c b/opal/mca/pmix/pmix2x/pmix/src/util/hash.c index 125e13479e..ba479ab335 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/hash.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/hash.c @@ -22,7 +22,7 @@ #include -#include +#include #include #include diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/Makefile.am new file mode 100644 index 0000000000..70572ec8f1 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/Makefile.am @@ -0,0 +1,32 @@ +# +# 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) 2016 Intel, Inc. All rights reserved +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + + +AM_LFLAGS = -Ppmix_util_keyval_yy +LEX_OUTPUT_ROOT = lex.pmix_util_keyval_yy + +noinst_LTLIBRARIES = libpmixutilkeyval.la + +# Source code files + +libpmixutilkeyval_la_SOURCES = \ + keyval_lex.h \ + keyval_lex.l + +MAINTAINERCLEANFILES = keyval_lex.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.c b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.c new file mode 100644 index 0000000000..852f21cbdc --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.c @@ -0,0 +1,2069 @@ + +#line 3 "keyval_lex.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer pmix_util_keyval_yy_create_buffer +#define yy_delete_buffer pmix_util_keyval_yy_delete_buffer +#define yy_flex_debug pmix_util_keyval_yy_flex_debug +#define yy_init_buffer pmix_util_keyval_yy_init_buffer +#define yy_flush_buffer pmix_util_keyval_yy_flush_buffer +#define yy_load_buffer_state pmix_util_keyval_yy_load_buffer_state +#define yy_switch_to_buffer pmix_util_keyval_yy_switch_to_buffer +#define yyin pmix_util_keyval_yyin +#define yyleng pmix_util_keyval_yyleng +#define yylex pmix_util_keyval_yylex +#define yylineno pmix_util_keyval_yylineno +#define yyout pmix_util_keyval_yyout +#define yyrestart pmix_util_keyval_yyrestart +#define yytext pmix_util_keyval_yytext +#define yywrap pmix_util_keyval_yywrap +#define yyalloc pmix_util_keyval_yyalloc +#define yyrealloc pmix_util_keyval_yyrealloc +#define yyfree pmix_util_keyval_yyfree + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE pmix_util_keyval_yyrestart(pmix_util_keyval_yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t pmix_util_keyval_yyleng; + +extern FILE *pmix_util_keyval_yyin, *pmix_util_keyval_yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE pmix_util_keyval_yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-pmix_util_keyval_yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < pmix_util_keyval_yyleng; ++yyl )\ + if ( pmix_util_keyval_yytext[yyl] == '\n' )\ + --pmix_util_keyval_yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up pmix_util_keyval_yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up pmix_util_keyval_yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via pmix_util_keyval_yyrestart()), so that the user can continue scanning by + * just pointing pmix_util_keyval_yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when pmix_util_keyval_yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t pmix_util_keyval_yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow pmix_util_keyval_yywrap()'s to do buffer switches + * instead of setting up a fresh pmix_util_keyval_yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void pmix_util_keyval_yyrestart (FILE *input_file ); +void pmix_util_keyval_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE pmix_util_keyval_yy_create_buffer (FILE *file,int size ); +void pmix_util_keyval_yy_delete_buffer (YY_BUFFER_STATE b ); +void pmix_util_keyval_yy_flush_buffer (YY_BUFFER_STATE b ); +void pmix_util_keyval_yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void pmix_util_keyval_yypop_buffer_state (void ); + +static void pmix_util_keyval_yyensure_buffer_stack (void ); +static void pmix_util_keyval_yy_load_buffer_state (void ); +static void pmix_util_keyval_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER pmix_util_keyval_yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE pmix_util_keyval_yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE pmix_util_keyval_yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE pmix_util_keyval_yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *pmix_util_keyval_yyalloc (yy_size_t ); +void *pmix_util_keyval_yyrealloc (void *,yy_size_t ); +void pmix_util_keyval_yyfree (void * ); + +#define yy_new_buffer pmix_util_keyval_yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + pmix_util_keyval_yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + pmix_util_keyval_yy_create_buffer(pmix_util_keyval_yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + pmix_util_keyval_yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + pmix_util_keyval_yy_create_buffer(pmix_util_keyval_yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *pmix_util_keyval_yyin = (FILE *) 0, *pmix_util_keyval_yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int pmix_util_keyval_yylineno; + +int pmix_util_keyval_yylineno = 1; + +extern char *pmix_util_keyval_yytext; +#define yytext_ptr pmix_util_keyval_yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up pmix_util_keyval_yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + pmix_util_keyval_yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 22 +#define YY_END_OF_BUFFER 23 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_acclist[93] = + { 0, + 5, 5, 23, 21, 22, 10, 21, 22, 1, 22, + 21, 22, 11, 21, 22, 11, 21, 22, 21, 22, + 9, 21, 22, 8205, 22,16397, 22, 12, 22, 8205, + 22,16397, 5, 22, 7, 22, 6, 22, 14, 22, + 22, 17, 22, 14, 22, 14, 22, 14, 22, 10, + 1, 9, 2, 11, 11, 11, 11, 4, 9, 8205, + 16397, 8205, 12, 8205,16397, 8205, 5, 6, 6, 8, + 14, 17, 14, 14, 14, 14, 14, 11, 3, 16, + 14, 16, 15, 14, 15, 11, 20, 20, 20, 19, + 19, 18 + + } ; + +static yyconst flex_int16_t yy_accept[85] = + { 0, + 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, + 6, 9, 11, 13, 16, 19, 21, 24, 27, 28, + 30, 33, 35, 37, 39, 41, 42, 44, 46, 48, + 50, 51, 52, 53, 53, 54, 55, 56, 57, 58, + 59, 59, 60, 62, 63, 63, 64, 66, 67, 68, + 69, 70, 71, 72, 72, 73, 74, 75, 75, 76, + 77, 77, 78, 79, 79, 79, 80, 80, 81, 83, + 83, 84, 86, 87, 87, 87, 88, 89, 90, 91, + 91, 92, 93, 93 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 5, 6, 1, 1, 1, 7, 1, + 1, 8, 1, 1, 9, 10, 11, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, + 12, 1, 1, 1, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 1, 1, 1, 1, 10, 1, 13, 10, 14, 10, + + 10, 10, 10, 10, 10, 10, 10, 10, 15, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 16, + 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[17] = + { 0, + 1, 2, 3, 4, 1, 1, 1, 5, 6, 6, + 1, 1, 6, 6, 6, 6 + } ; + +static yyconst flex_int16_t yy_base[100] = + { 0, + 0, 0, 15, 18, 20, 21, 28, 34, 143, 252, + 40, 252, 121, 44, 52, 37, 23, 115, 67, 252, + 70, 0, 252, 38, 0, 111, 252, 73, 45, 49, + 0, 252, 60, 105, 252, 50, 0, 93, 76, 252, + 98, 77, 98, 91, 80, 252, 83, 86, 0, 83, + 84, 252, 0, 60, 252, 94, 97, 50, 101, 102, + 33, 108, 21, 109, 23, 252, 114, 0, 0, 118, + 0, 0, 119, 125, 140, 252, 136, 0, 151, 152, + 155, 156, 252, 160, 166, 172, 178, 184, 190, 196, + 202, 207, 211, 217, 223, 229, 235, 240, 245 + + } ; + +static yyconst flex_int16_t yy_def[100] = + { 0, + 83, 1, 84, 84, 85, 85, 86, 86, 83, 83, + 83, 83, 87, 83, 14, 83, 83, 88, 88, 83, + 88, 89, 83, 90, 91, 92, 83, 91, 93, 94, + 11, 83, 83, 87, 83, 15, 15, 15, 15, 83, + 95, 83, 88, 88, 88, 83, 88, 88, 89, 90, + 90, 83, 91, 92, 83, 91, 93, 96, 93, 94, + 97, 94, 15, 98, 95, 83, 96, 67, 59, 97, + 70, 62, 15, 83, 99, 83, 74, 74, 83, 99, + 83, 83, 0, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83 + + } ; + +static yyconst flex_int16_t yy_nxt[269] = + { 0, + 10, 11, 12, 11, 10, 13, 10, 10, 14, 15, + 16, 17, 15, 15, 15, 15, 19, 20, 21, 19, + 20, 21, 23, 23, 42, 66, 42, 24, 24, 26, + 27, 28, 29, 73, 30, 26, 27, 28, 29, 70, + 30, 31, 32, 31, 40, 51, 58, 41, 52, 59, + 61, 33, 36, 37, 67, 62, 37, 37, 38, 39, + 37, 42, 55, 42, 38, 39, 37, 37, 45, 46, + 47, 48, 46, 47, 54, 55, 56, 64, 42, 64, + 42, 45, 46, 47, 48, 46, 47, 48, 46, 47, + 83, 51, 44, 83, 52, 54, 55, 56, 58, 44, + + 66, 59, 68, 61, 69, 59, 63, 35, 62, 71, + 64, 72, 64, 55, 62, 68, 44, 68, 67, 71, + 75, 71, 75, 35, 70, 76, 77, 76, 77, 76, + 76, 76, 76, 78, 78, 76, 79, 78, 78, 78, + 78, 75, 83, 75, 76, 76, 83, 83, 76, 76, + 76, 76, 81, 82, 81, 82, 81, 82, 81, 82, + 18, 18, 18, 18, 18, 18, 22, 22, 22, 22, + 22, 22, 25, 25, 25, 25, 25, 25, 34, 34, + 34, 34, 34, 34, 43, 43, 83, 43, 43, 43, + 49, 49, 83, 49, 83, 49, 50, 50, 83, 50, + + 50, 50, 53, 83, 83, 53, 53, 53, 54, 54, + 54, 57, 57, 83, 57, 57, 57, 60, 60, 83, + 60, 60, 60, 65, 65, 65, 65, 65, 65, 58, + 58, 83, 58, 58, 58, 61, 61, 83, 61, 61, + 61, 74, 83, 74, 83, 74, 80, 83, 80, 83, + 80, 9, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83 + } ; + +static yyconst flex_int16_t yy_chk[269] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 3, 3, 4, + 4, 4, 5, 6, 17, 65, 17, 5, 6, 7, + 7, 7, 7, 63, 7, 8, 8, 8, 8, 61, + 8, 11, 11, 11, 16, 24, 29, 16, 24, 29, + 30, 11, 14, 14, 58, 30, 14, 14, 14, 14, + 15, 33, 54, 33, 36, 36, 15, 15, 19, 19, + 19, 21, 21, 21, 28, 28, 28, 39, 42, 39, + 42, 45, 45, 45, 47, 47, 47, 48, 48, 48, + 50, 51, 44, 50, 51, 56, 56, 56, 57, 43, + + 41, 57, 59, 60, 59, 59, 38, 34, 60, 62, + 64, 62, 64, 26, 62, 67, 18, 67, 67, 70, + 73, 70, 73, 13, 70, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 75, 9, 75, 77, 77, 0, 0, 77, 77, + 77, 77, 79, 80, 79, 80, 81, 82, 81, 82, + 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, + 85, 85, 86, 86, 86, 86, 86, 86, 87, 87, + 87, 87, 87, 87, 88, 88, 0, 88, 88, 88, + 89, 89, 0, 89, 0, 89, 90, 90, 0, 90, + + 90, 90, 91, 0, 0, 91, 91, 91, 92, 92, + 92, 93, 93, 0, 93, 93, 93, 94, 94, 0, + 94, 94, 94, 95, 95, 95, 95, 95, 95, 96, + 96, 0, 96, 96, 96, 97, 97, 0, 97, 97, + 97, 98, 0, 98, 0, 98, 99, 0, 99, 0, + 99, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83 + } ; + +/* Table of booleans, true if rule could match eol. */ +static yyconst flex_int32_t yy_rule_can_match_eol[23] = + { 0, +1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, + 1, 0, 0, }; + +extern int pmix_util_keyval_yy_flex_debug; +int pmix_util_keyval_yy_flex_debug = 0; + +static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; +static char *yy_full_match; +static int yy_lp; +static int yy_looking_for_trail_begin = 0; +static int yy_full_lp; +static int *yy_full_state; +#define YY_TRAILING_MASK 0x2000 +#define YY_TRAILING_HEAD_MASK 0x4000 +#define REJECT \ +{ \ +*yy_cp = (yy_hold_char); /* undo effects of setting up pmix_util_keyval_yytext */ \ +yy_cp = (yy_full_match); /* restore poss. backed-over text */ \ +(yy_lp) = (yy_full_lp); /* restore orig. accepting pos. */ \ +(yy_state_ptr) = (yy_full_state); /* restore orig. state */ \ +yy_current_state = *(yy_state_ptr); /* restore curr. state */ \ +++(yy_lp); \ +goto find_rule; \ +} + +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *pmix_util_keyval_yytext; +#line 1 "keyval_lex.l" +#define YY_NO_INPUT 1 +#line 6 "keyval_lex.l" +/* + * 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) 2012 Los Alamos National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/util/keyval/keyval_lex.h" + +/* + * local functions + */ + +BEGIN_C_DECLS + +int pmix_util_keyval_yywrap(void); + +END_C_DECLS + +/* + * global variables + */ +int pmix_util_keyval_yynewlines = 1; +bool pmix_util_keyval_parse_done = false; +char *pmix_util_keyval_string = NULL; + + + + +#line 651 "keyval_lex.c" + +#define INITIAL 0 +#define VALUE 1 +#define comment 2 +#define MCA_VALUE 3 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int pmix_util_keyval_yylex_destroy (void ); + +int pmix_util_keyval_yyget_debug (void ); + +void pmix_util_keyval_yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE pmix_util_keyval_yyget_extra (void ); + +void pmix_util_keyval_yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *pmix_util_keyval_yyget_in (void ); + +void pmix_util_keyval_yyset_in (FILE * in_str ); + +FILE *pmix_util_keyval_yyget_out (void ); + +void pmix_util_keyval_yyset_out (FILE * out_str ); + +yy_size_t pmix_util_keyval_yyget_leng (void ); + +char *pmix_util_keyval_yyget_text (void ); + +int pmix_util_keyval_yyget_lineno (void ); + +void pmix_util_keyval_yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int pmix_util_keyval_yywrap (void ); +#else +extern int pmix_util_keyval_yywrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( pmix_util_keyval_yytext, pmix_util_keyval_yyleng, 1, pmix_util_keyval_yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( pmix_util_keyval_yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( pmix_util_keyval_yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, pmix_util_keyval_yyin))==0 && ferror(pmix_util_keyval_yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(pmix_util_keyval_yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int pmix_util_keyval_yylex (void); + +#define YY_DECL int pmix_util_keyval_yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after pmix_util_keyval_yytext and pmix_util_keyval_yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 61 "keyval_lex.l" + + +#line 837 "keyval_lex.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + /* Create the reject buffer large enough to save one state per allowed character. */ + if ( ! (yy_state_buf) ) + (yy_state_buf) = (yy_state_type *)pmix_util_keyval_yyalloc(YY_STATE_BUF_SIZE ); + if ( ! (yy_state_buf) ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_util_keyval_yylex()" ); + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! pmix_util_keyval_yyin ) + pmix_util_keyval_yyin = stdin; + + if ( ! pmix_util_keyval_yyout ) + pmix_util_keyval_yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + pmix_util_keyval_yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + pmix_util_keyval_yy_create_buffer(pmix_util_keyval_yyin,YY_BUF_SIZE ); + } + + pmix_util_keyval_yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of pmix_util_keyval_yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 84 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *(yy_state_ptr)++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 252 ); + +yy_find_action: + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; +find_rule: /* we branch to this label when backing up */ + for ( ; ; ) /* until we find what rule we matched */ + { + if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[(yy_lp)]; + if ( yy_act & YY_TRAILING_HEAD_MASK || + (yy_looking_for_trail_begin) ) + { + if ( yy_act == (yy_looking_for_trail_begin) ) + { + (yy_looking_for_trail_begin) = 0; + yy_act &= ~YY_TRAILING_HEAD_MASK; + break; + } + } + else if ( yy_act & YY_TRAILING_MASK ) + { + (yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK; + (yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK; + } + else + { + (yy_full_match) = yy_cp; + (yy_full_state) = (yy_state_ptr); + (yy_full_lp) = (yy_lp); + break; + } + ++(yy_lp); + goto find_rule; + } + --yy_cp; + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < pmix_util_keyval_yyleng; ++yyl ) + if ( pmix_util_keyval_yytext[yyl] == '\n' ) + + pmix_util_keyval_yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 63 "keyval_lex.l" +{ pmix_util_keyval_yynewlines++; return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 64 "keyval_lex.l" +{ pmix_util_keyval_yynewlines++; return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 65 "keyval_lex.l" +{ pmix_util_keyval_yynewlines++; return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 67 "keyval_lex.l" +{ BEGIN(comment); + return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 69 "keyval_lex.l" +; /* Eat up non '*'s */ + YY_BREAK +case 6: +YY_RULE_SETUP +#line 70 "keyval_lex.l" +; /* Eat '*'s not followed by a '/' */ + YY_BREAK +case 7: +/* rule 7 can match eol */ +YY_RULE_SETUP +#line 71 "keyval_lex.l" +{ pmix_util_keyval_yynewlines++; + return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 73 "keyval_lex.l" +{ BEGIN(INITIAL); /* Done with Block Comment */ + return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 76 "keyval_lex.l" +{ BEGIN(VALUE); return PMIX_UTIL_KEYVAL_PARSE_EQUAL; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 77 "keyval_lex.l" +; /* whitespace */ + YY_BREAK +case 11: +YY_RULE_SETUP +#line 78 "keyval_lex.l" +{ return PMIX_UTIL_KEYVAL_PARSE_SINGLE_WORD; } + YY_BREAK +case 12: +/* rule 12 can match eol */ +YY_RULE_SETUP +#line 80 "keyval_lex.l" +{ BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 81 "keyval_lex.l" +{ return PMIX_UTIL_KEYVAL_PARSE_VALUE; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 83 "keyval_lex.l" +{ BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_VALUE; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 84 "keyval_lex.l" +{ BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_VALUE; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 85 "keyval_lex.l" +{ BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_VALUE; } + YY_BREAK +case 17: +/* rule 17 can match eol */ +YY_RULE_SETUP +#line 86 "keyval_lex.l" +{ BEGIN(INITIAL); BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 88 "keyval_lex.l" +{BEGIN(MCA_VALUE); return PMIX_UTIL_KEYVAL_PARSE_MCAVAR; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 89 "keyval_lex.l" +{BEGIN(MCA_VALUE); return PMIX_UTIL_KEYVAL_PARSE_ENVEQL; } + YY_BREAK +case 20: +/* rule 20 can match eol */ +*yy_cp = (yy_hold_char); /* undo effects of setting up pmix_util_keyval_yytext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up pmix_util_keyval_yytext again */ +YY_RULE_SETUP +#line 90 "keyval_lex.l" +{ return PMIX_UTIL_KEYVAL_PARSE_ENVVAR; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 92 "keyval_lex.l" +{ return PMIX_UTIL_KEYVAL_PARSE_ERROR; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 94 "keyval_lex.l" +ECHO; + YY_BREAK +#line 1082 "keyval_lex.c" + case YY_STATE_EOF(INITIAL): + case YY_STATE_EOF(VALUE): + case YY_STATE_EOF(comment): + case YY_STATE_EOF(MCA_VALUE): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed pmix_util_keyval_yyin at a new source and called + * pmix_util_keyval_yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = pmix_util_keyval_yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( pmix_util_keyval_yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * pmix_util_keyval_yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of pmix_util_keyval_yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + pmix_util_keyval_yyrestart(pmix_util_keyval_yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pmix_util_keyval_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 84 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *(yy_state_ptr)++ = yy_current_state; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + + register YY_CHAR yy_c = 1; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 84 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 83); + if ( ! yy_is_jam ) + *(yy_state_ptr)++ = yy_current_state; + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + pmix_util_keyval_yyrestart(pmix_util_keyval_yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( pmix_util_keyval_yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve pmix_util_keyval_yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + if ( c == '\n' ) + + pmix_util_keyval_yylineno++; +; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void pmix_util_keyval_yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + pmix_util_keyval_yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + pmix_util_keyval_yy_create_buffer(pmix_util_keyval_yyin,YY_BUF_SIZE ); + } + + pmix_util_keyval_yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + pmix_util_keyval_yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void pmix_util_keyval_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * pmix_util_keyval_yypop_buffer_state(); + * pmix_util_keyval_yypush_buffer_state(new_buffer); + */ + pmix_util_keyval_yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + pmix_util_keyval_yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (pmix_util_keyval_yywrap()) processing, but the only time this flag + * is looked at is after pmix_util_keyval_yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void pmix_util_keyval_yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + pmix_util_keyval_yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE pmix_util_keyval_yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) pmix_util_keyval_yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_util_keyval_yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) pmix_util_keyval_yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_util_keyval_yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + pmix_util_keyval_yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with pmix_util_keyval_yy_create_buffer() + * + */ + void pmix_util_keyval_yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + pmix_util_keyval_yyfree((void *) b->yy_ch_buf ); + + pmix_util_keyval_yyfree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a pmix_util_keyval_yyrestart() or at EOF. + */ + static void pmix_util_keyval_yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + pmix_util_keyval_yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then pmix_util_keyval_yy_init_buffer was _probably_ + * called from pmix_util_keyval_yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void pmix_util_keyval_yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + pmix_util_keyval_yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void pmix_util_keyval_yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + pmix_util_keyval_yyensure_buffer_stack(); + + /* This block is copied from pmix_util_keyval_yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from pmix_util_keyval_yy_switch_to_buffer. */ + pmix_util_keyval_yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void pmix_util_keyval_yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + pmix_util_keyval_yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + pmix_util_keyval_yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void pmix_util_keyval_yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)pmix_util_keyval_yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_util_keyval_yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)pmix_util_keyval_yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_util_keyval_yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE pmix_util_keyval_yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) pmix_util_keyval_yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_util_keyval_yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + pmix_util_keyval_yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to pmix_util_keyval_yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * pmix_util_keyval_yy_scan_bytes() instead. + */ +YY_BUFFER_STATE pmix_util_keyval_yy_scan_string (yyconst char * yystr ) +{ + + return pmix_util_keyval_yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to pmix_util_keyval_yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE pmix_util_keyval_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) pmix_util_keyval_yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_util_keyval_yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = pmix_util_keyval_yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in pmix_util_keyval_yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up pmix_util_keyval_yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + pmix_util_keyval_yytext[pmix_util_keyval_yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = pmix_util_keyval_yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + pmix_util_keyval_yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int pmix_util_keyval_yyget_lineno (void) +{ + + return pmix_util_keyval_yylineno; +} + +/** Get the input stream. + * + */ +FILE *pmix_util_keyval_yyget_in (void) +{ + return pmix_util_keyval_yyin; +} + +/** Get the output stream. + * + */ +FILE *pmix_util_keyval_yyget_out (void) +{ + return pmix_util_keyval_yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t pmix_util_keyval_yyget_leng (void) +{ + return pmix_util_keyval_yyleng; +} + +/** Get the current token. + * + */ + +char *pmix_util_keyval_yyget_text (void) +{ + return pmix_util_keyval_yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void pmix_util_keyval_yyset_lineno (int line_number ) +{ + + pmix_util_keyval_yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see pmix_util_keyval_yy_switch_to_buffer + */ +void pmix_util_keyval_yyset_in (FILE * in_str ) +{ + pmix_util_keyval_yyin = in_str ; +} + +void pmix_util_keyval_yyset_out (FILE * out_str ) +{ + pmix_util_keyval_yyout = out_str ; +} + +int pmix_util_keyval_yyget_debug (void) +{ + return pmix_util_keyval_yy_flex_debug; +} + +void pmix_util_keyval_yyset_debug (int bdebug ) +{ + pmix_util_keyval_yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from pmix_util_keyval_yylex_destroy(), so don't allocate here. + */ + + /* We do not touch pmix_util_keyval_yylineno unless the option is enabled. */ + pmix_util_keyval_yylineno = 1; + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + + (yy_state_buf) = 0; + (yy_state_ptr) = 0; + (yy_full_match) = 0; + (yy_lp) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + pmix_util_keyval_yyin = stdin; + pmix_util_keyval_yyout = stdout; +#else + pmix_util_keyval_yyin = (FILE *) 0; + pmix_util_keyval_yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * pmix_util_keyval_yylex_init() + */ + return 0; +} + +/* pmix_util_keyval_yylex_destroy is for both reentrant and non-reentrant scanners. */ +int pmix_util_keyval_yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + pmix_util_keyval_yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + pmix_util_keyval_yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + pmix_util_keyval_yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + pmix_util_keyval_yyfree ( (yy_state_buf) ); + (yy_state_buf) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * pmix_util_keyval_yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *pmix_util_keyval_yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *pmix_util_keyval_yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void pmix_util_keyval_yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see pmix_util_keyval_yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 94 "keyval_lex.l" + + + +/* Old flex (2.5.4a? and older) does not define a destroy function */ +#if !defined(YY_FLEX_SUBMINOR_VERSION) +#define YY_FLEX_SUBMINOR_VERSION 0 +#endif + +#if (YY_FLEX_MAJOR_VERSION < 2) || (YY_FLEX_MAJOR_VERSION == 2 && (YY_FLEX_MINOR_VERSION < 5 || (YY_FLEX_MINOR_VERSION == 5 && YY_FLEX_SUBMINOR_VERSION < 5))) +int pmix_util_keyval_yylex_destroy(void) +{ + if (NULL != YY_CURRENT_BUFFER) { + pmix_util_keyval_yy_delete_buffer(YY_CURRENT_BUFFER); +#if defined(YY_CURRENT_BUFFER_LVALUE) + YY_CURRENT_BUFFER_LVALUE = NULL; +#else + YY_CURRENT_BUFFER = NULL; +#endif /* YY_CURRENT_BUFFER_LVALUE */ + } + return YY_NULL; +} +#endif + +int pmix_util_keyval_yywrap(void) +{ + pmix_util_keyval_parse_done = true; + return 1; +} + +/* + * Ensure that we have a valid yybuffer to use. Specifically, if this + * scanner is invoked a second time, finish_parsing() (above) will + * have been executed, and the current buffer will have been freed. + * Flex doesn't recognize this fact because as far as it's concerned, + * its internal state was already initialized, so it thinks it should + * have a valid buffer. Hence, here we ensure to give it a valid + * buffer. + */ +int pmix_util_keyval_init_buffer(FILE *file) +{ + YY_BUFFER_STATE buf = pmix_util_keyval_yy_create_buffer(file,YY_BUF_SIZE); + pmix_util_keyval_yy_switch_to_buffer(buf); + + return 0; +} + 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 new file mode 100644 index 0000000000..778982711d --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.h @@ -0,0 +1,74 @@ +/* -*- C -*- + * + * 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) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_UTIL_KEYVAL_LEX_H_ +#define PMIX_UTIL_KEYVAL_LEX_H_ + +#include + +#ifdef malloc +#undef malloc +#endif +#ifdef realloc +#undef realloc +#endif +#ifdef free +#undef free +#endif + +#include + +int pmix_util_keyval_yylex(void); +int pmix_util_keyval_init_buffer(FILE *file); +int pmix_util_keyval_yylex_destroy(void); + +extern FILE *pmix_util_keyval_yyin; +extern bool pmix_util_keyval_parse_done; +extern char *pmix_util_keyval_yytext; +extern int pmix_util_keyval_yynewlines; +extern int pmix_util_keyval_yylineno; + +/* + * Make lex-generated files not issue compiler warnings + */ +#define YY_STACK_USED 0 +#define YY_ALWAYS_INTERACTIVE 0 +#define YY_NEVER_INTERACTIVE 0 +#define YY_MAIN 0 +#define YY_NO_UNPUT 1 +#define YY_SKIP_YYWRAP 1 + +enum pmix_keyval_parse_state_t { + PMIX_UTIL_KEYVAL_PARSE_DONE, + PMIX_UTIL_KEYVAL_PARSE_ERROR, + + PMIX_UTIL_KEYVAL_PARSE_NEWLINE, + PMIX_UTIL_KEYVAL_PARSE_EQUAL, + PMIX_UTIL_KEYVAL_PARSE_SINGLE_WORD, + PMIX_UTIL_KEYVAL_PARSE_VALUE, + PMIX_UTIL_KEYVAL_PARSE_MCAVAR, + PMIX_UTIL_KEYVAL_PARSE_ENVVAR, + PMIX_UTIL_KEYVAL_PARSE_ENVEQL, + + PMIX_UTIL_KEYVAL_PARSE_MAX +}; +typedef enum pmix_keyval_parse_state_t pmix_keyval_parse_state_t; + +#endif 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 new file mode 100644 index 0000000000..9b9d0d6d14 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval/keyval_lex.l @@ -0,0 +1,137 @@ +%option nounput +%option noinput +%option yylineno + +%{ /* -*- 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) 2012 Los Alamos National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/util/keyval/keyval_lex.h" + +/* + * local functions + */ + +BEGIN_C_DECLS + +int pmix_util_keyval_yywrap(void); + +END_C_DECLS + +/* + * global variables + */ +int pmix_util_keyval_yynewlines = 1; +bool pmix_util_keyval_parse_done = false; +char *pmix_util_keyval_string = NULL; + +%} + +WHITE [\f\t\v ] +CHAR [A-Za-z0-9_\-\.] + +%x VALUE +%x comment +%x MCA_VALUE + +%% + +{WHITE}*\n { pmix_util_keyval_yynewlines++; return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } +#.*\n { pmix_util_keyval_yynewlines++; return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } +"//".*\n { pmix_util_keyval_yynewlines++; return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + +"/*" { BEGIN(comment); + return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } +[^*\n]* ; /* Eat up non '*'s */ +"*"+[^*/\n]* ; /* Eat '*'s not followed by a '/' */ +\n { pmix_util_keyval_yynewlines++; + return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } +"*"+"/" { BEGIN(INITIAL); /* Done with Block Comment */ + return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + +{WHITE}*"="{WHITE}* { BEGIN(VALUE); return PMIX_UTIL_KEYVAL_PARSE_EQUAL; } +{WHITE}+ ; /* whitespace */ +{CHAR}+ { return PMIX_UTIL_KEYVAL_PARSE_SINGLE_WORD; } + +{WHITE}*\n { BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } +[^\n]*[^\t \n]/[\t ]* { return PMIX_UTIL_KEYVAL_PARSE_VALUE; } + +[^\n \t]+ { BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_VALUE; } +"'"[^\n]*"'"{WHITE}+ { BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_VALUE; } +"\""[^\n]*"\""{WHITE}+ { BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_VALUE; } +{WHITE}*\n { BEGIN(INITIAL); BEGIN(INITIAL); return PMIX_UTIL_KEYVAL_PARSE_NEWLINE; } + +"-"?"-mca"{WHITE}+{CHAR}+{WHITE}+ {BEGIN(MCA_VALUE); return PMIX_UTIL_KEYVAL_PARSE_MCAVAR; } +"-"?"-x"{WHITE}+{CHAR}+{WHITE}*"="{WHITE}* {BEGIN(MCA_VALUE); return PMIX_UTIL_KEYVAL_PARSE_ENVEQL; } +"-"?"-x"{WHITE}+{CHAR}+{WHITE}*/[^=] { return PMIX_UTIL_KEYVAL_PARSE_ENVVAR; } + +. { return PMIX_UTIL_KEYVAL_PARSE_ERROR; } + +%% + +/* Old flex (2.5.4a? and older) does not define a destroy function */ +#if !defined(YY_FLEX_SUBMINOR_VERSION) +#define YY_FLEX_SUBMINOR_VERSION 0 +#endif + +#if (YY_FLEX_MAJOR_VERSION < 2) || (YY_FLEX_MAJOR_VERSION == 2 && (YY_FLEX_MINOR_VERSION < 5 || (YY_FLEX_MINOR_VERSION == 5 && YY_FLEX_SUBMINOR_VERSION < 5))) +int pmix_util_keyval_yylex_destroy(void) +{ + if (NULL != YY_CURRENT_BUFFER) { + yy_delete_buffer(YY_CURRENT_BUFFER); +#if defined(YY_CURRENT_BUFFER_LVALUE) + YY_CURRENT_BUFFER_LVALUE = NULL; +#else + YY_CURRENT_BUFFER = NULL; +#endif /* YY_CURRENT_BUFFER_LVALUE */ + } + return YY_NULL; +} +#endif + +int pmix_util_keyval_yywrap(void) +{ + pmix_util_keyval_parse_done = true; + return 1; +} + +/* + * Ensure that we have a valid yybuffer to use. Specifically, if this + * scanner is invoked a second time, finish_parsing() (above) will + * have been executed, and the current buffer will have been freed. + * Flex doesn't recognize this fact because as far as it's concerned, + * its internal state was already initialized, so it thinks it should + * have a valid buffer. Hence, here we ensure to give it a valid + * buffer. + */ +int pmix_util_keyval_init_buffer(FILE *file) +{ + YY_BUFFER_STATE buf = yy_create_buffer(file, YY_BUF_SIZE); + yy_switch_to_buffer(buf); + + return 0; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.c b/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.c new file mode 100644 index 0000000000..c07e65e668 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.c @@ -0,0 +1,363 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * 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) 2015-2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "pmix_common.h" +#include "src/util/keyval_parse.h" +#include "src/util/keyval/keyval_lex.h" +#include "src/util/output.h" +#include +#include + +int pmix_util_keyval_parse_lineno = 0; + +static const char *keyval_filename; +static pmix_keyval_parse_fn_t keyval_callback; +static char *key_buffer = NULL; +static size_t key_buffer_len = 0; + +static int parse_line(void); +static int parse_line_new(pmix_keyval_parse_state_t first_val); +static void parse_error(int num); + +static char *env_str = NULL; +static int envsize = 1024; + +int pmix_util_keyval_parse_init(void) +{ + return PMIX_SUCCESS; +} + + +int +pmix_util_keyval_parse_finalize(void) +{ + if (NULL != key_buffer) free(key_buffer); + key_buffer = NULL; + key_buffer_len = 0; + + return PMIX_SUCCESS; +} + +int +pmix_util_keyval_parse(const char *filename, + pmix_keyval_parse_fn_t callback) +{ + int val; + int ret = PMIX_SUCCESS;; + + keyval_filename = filename; + keyval_callback = callback; + + /* Open the pmix */ + pmix_util_keyval_yyin = fopen(keyval_filename, "r"); + if (NULL == pmix_util_keyval_yyin) { + ret = PMIX_ERR_NOT_FOUND; + goto cleanup; + } + + pmix_util_keyval_parse_done = false; + pmix_util_keyval_yynewlines = 1; + pmix_util_keyval_init_buffer(pmix_util_keyval_yyin); + while (!pmix_util_keyval_parse_done) { + val = pmix_util_keyval_yylex(); + switch (val) { + case PMIX_UTIL_KEYVAL_PARSE_DONE: + /* This will also set pmix_util_keyval_parse_done to true, so just + break here */ + break; + + case PMIX_UTIL_KEYVAL_PARSE_NEWLINE: + /* blank line! ignore it */ + break; + + case PMIX_UTIL_KEYVAL_PARSE_SINGLE_WORD: + parse_line(); + break; + + case PMIX_UTIL_KEYVAL_PARSE_MCAVAR: + case PMIX_UTIL_KEYVAL_PARSE_ENVVAR: + case PMIX_UTIL_KEYVAL_PARSE_ENVEQL: + parse_line_new(val); + break; + + default: + /* anything else is an error */ + parse_error(1); + break; + } + } + fclose(pmix_util_keyval_yyin); + pmix_util_keyval_yylex_destroy (); + +cleanup: + return ret; +} + + + +static int parse_line(void) +{ + int val; + + pmix_util_keyval_parse_lineno = pmix_util_keyval_yylineno; + + /* Save the name name */ + if (key_buffer_len < strlen(pmix_util_keyval_yytext) + 1) { + char *tmp; + key_buffer_len = strlen(pmix_util_keyval_yytext) + 1; + tmp = (char*)realloc(key_buffer, key_buffer_len); + if (NULL == tmp) { + free(key_buffer); + key_buffer_len = 0; + key_buffer = NULL; + return PMIX_ERR_OUT_OF_RESOURCE; + } + key_buffer = tmp; + } + + strncpy(key_buffer, pmix_util_keyval_yytext, key_buffer_len); + + /* The first thing we have to see is an "=" */ + + val = pmix_util_keyval_yylex(); + if (pmix_util_keyval_parse_done || PMIX_UTIL_KEYVAL_PARSE_EQUAL != val) { + parse_error(2); + return PMIX_ERROR; + } + + /* Next we get the value */ + + val = pmix_util_keyval_yylex(); + if (PMIX_UTIL_KEYVAL_PARSE_SINGLE_WORD == val || + PMIX_UTIL_KEYVAL_PARSE_VALUE == val) { + keyval_callback(key_buffer, pmix_util_keyval_yytext); + + /* Now we need to see the newline */ + + val = pmix_util_keyval_yylex(); + if (PMIX_UTIL_KEYVAL_PARSE_NEWLINE == val || + PMIX_UTIL_KEYVAL_PARSE_DONE == val) { + return PMIX_SUCCESS; + } + } + + /* Did we get an EOL or EOF? */ + + else if (PMIX_UTIL_KEYVAL_PARSE_DONE == val || + PMIX_UTIL_KEYVAL_PARSE_NEWLINE == val) { + keyval_callback(key_buffer, NULL); + return PMIX_SUCCESS; + } + + /* Nope -- we got something unexpected. Bonk! */ + parse_error(3); + return PMIX_ERROR; +} + + +static void parse_error(int num) +{ + /* JMS need better error/warning message here */ + pmix_output(0, "keyval parser: error %d reading file %s at line %d:\n %s\n", + num, keyval_filename, pmix_util_keyval_yynewlines, pmix_util_keyval_yytext); +} + +int pmix_util_keyval_save_internal_envars(pmix_keyval_parse_fn_t callback) +{ + if (NULL != env_str && 0 < strlen(env_str)) { + callback("mca_base_env_list_internal", env_str); + free(env_str); + env_str = NULL; + } + return PMIX_SUCCESS; +} + +static void trim_name(char *buffer, const char* prefix, const char* suffix) +{ + char *pchr, *echr; + size_t buffer_len; + + if (NULL == buffer) { + return; + } + + buffer_len = strlen (buffer); + + pchr = buffer; + if (NULL != prefix) { + size_t prefix_len = strlen (prefix); + + if (0 == strncmp (buffer, prefix, prefix_len)) { + pchr += prefix_len; + } + } + + /* trim spaces at the beginning */ + while (isspace (*pchr)) { + pchr++; + } + + /* trim spaces at the end */ + echr = buffer + buffer_len; + while (echr > buffer && isspace (*(echr - 1))) { + echr--; + } + echr[0] = '\0'; + + if (NULL != suffix && (uintptr_t) (echr - buffer) > strlen (suffix)) { + size_t suffix_len = strlen (suffix); + + echr -= suffix_len; + + if (0 == strncmp (echr, suffix, strlen(suffix))) { + do { + echr--; + } while (isspace (*echr)); + echr[1] = '\0'; + } + } + + if (buffer != pchr) { + /* move the trimmed string to the beginning of the buffer */ + memmove (buffer, pchr, strlen (pchr) + 1); + } +} + +static int save_param_name (void) +{ + if (key_buffer_len < strlen(pmix_util_keyval_yytext) + 1) { + char *tmp; + key_buffer_len = strlen(pmix_util_keyval_yytext) + 1; + tmp = (char*)realloc(key_buffer, key_buffer_len); + if (NULL == tmp) { + free(key_buffer); + key_buffer_len = 0; + key_buffer = NULL; + return PMIX_ERR_OUT_OF_RESOURCE; + } + key_buffer = tmp; + } + + strncpy (key_buffer, pmix_util_keyval_yytext, key_buffer_len); + + return PMIX_SUCCESS; +} + +static int add_to_env_str(char *var, char *val) +{ + int sz, varsz, valsz; + void *tmp; + + if (NULL == var) { + return PMIX_ERR_BAD_PARAM; + } + + if (NULL != env_str) { + varsz = strlen(var); + valsz = (NULL != val) ? strlen(val) : 0; + sz = strlen(env_str)+varsz+valsz+2; + if (envsize <= sz) { + envsize *=2; + + tmp = realloc(env_str, envsize); + if (NULL == tmp) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + env_str = tmp; + } + strcat(env_str, ";"); + } else { + env_str = calloc(1, envsize); + if (NULL == env_str) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + } + + strcat(env_str, var); + if (NULL != val) { + strcat(env_str, "="); + strcat(env_str, val); + } + + return PMIX_SUCCESS; +} + +static int parse_line_new(pmix_keyval_parse_state_t first_val) +{ + pmix_keyval_parse_state_t val; + char *tmp; + int rc; + + val = first_val; + while (PMIX_UTIL_KEYVAL_PARSE_NEWLINE != val && PMIX_UTIL_KEYVAL_PARSE_DONE != val) { + rc = save_param_name (); + if (PMIX_SUCCESS != rc) { + return rc; + } + + if (PMIX_UTIL_KEYVAL_PARSE_MCAVAR == val) { + trim_name (key_buffer, "-mca", NULL); + trim_name (key_buffer, "--mca", NULL); + + val = pmix_util_keyval_yylex(); + if (PMIX_UTIL_KEYVAL_PARSE_VALUE == val) { + if (NULL != pmix_util_keyval_yytext) { + tmp = strdup(pmix_util_keyval_yytext); + if ('\'' == tmp[0] || '\"' == tmp[0]) { + trim_name (tmp, "\'", "\'"); + trim_name (tmp, "\"", "\""); + } + keyval_callback(key_buffer, tmp); + free(tmp); + } + } else { + parse_error(4); + return PMIX_ERROR; + } + } else if (PMIX_UTIL_KEYVAL_PARSE_ENVEQL == val) { + trim_name (key_buffer, "-x", "="); + trim_name (key_buffer, "--x", NULL); + + val = pmix_util_keyval_yylex(); + if (PMIX_UTIL_KEYVAL_PARSE_VALUE == val) { + add_to_env_str(key_buffer, pmix_util_keyval_yytext); + } else { + parse_error(5); + return PMIX_ERROR; + } + } else if (PMIX_UTIL_KEYVAL_PARSE_ENVVAR == val) { + trim_name (key_buffer, "-x", "="); + trim_name (key_buffer, "--x", NULL); + add_to_env_str(key_buffer, NULL); + } else { + /* we got something unexpected. Bonk! */ + parse_error(6); + return PMIX_ERROR; + } + + val = pmix_util_keyval_yylex(); + } + + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.h b/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.h new file mode 100644 index 0000000000..2d6e9f4c4e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/keyval_parse.h @@ -0,0 +1,60 @@ +/* + * 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) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** @file */ + +#ifndef PMIX_UTIL_KEYVAL_PARSE_H +#define PMIX_UTIL_KEYVAL_PARSE_H + +#include + +BEGIN_C_DECLS + +extern int pmix_util_keyval_parse_lineno; + +/** + * Callback triggered for each key = value pair + * + * Callback triggered from pmix_util_keyval_parse for each key = value + * pair. Both key and value will be pointers into static buffers. + * The buffers must not be free()ed and contents may be overwritten + * immediately after the callback returns. + */ +typedef void (*pmix_keyval_parse_fn_t)(const char *key, const char *value); + +/** + * Parse \c filename, made up of key = value pairs. + * + * Parse \c filename, made up of key = value pairs. For each line + * that appears to contain a key = value pair, \c callback will be + * called exactly once. In a multithreaded context, calls to + * pmix_util_keyval_parse() will serialize multiple calls. + */ +int pmix_util_keyval_parse(const char *filename, + pmix_keyval_parse_fn_t callback); + +int pmix_util_keyval_parse_init(void); + +int pmix_util_keyval_parse_finalize(void); + +int pmix_util_keyval_save_internal_envars(pmix_keyval_parse_fn_t callback); + +END_C_DECLS + +#endif 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 546d258e99..010e7086cf 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/os_path.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/os_path.h @@ -65,7 +65,7 @@ BEGIN_C_DECLS * appropriate to the local operating system. The path_name string has been malloc'd * and therefore the user is responsible for free'ing the field. */ -PMIX_DECLSPEC char *pmix_os_path(bool relative, ...) __pmix_attribute_malloc__ __pmix_attribute_sentinel__ __pmix_attribute_warn_unused_result__; +char *pmix_os_path(bool relative, ...) __pmix_attribute_malloc__ __pmix_attribute_sentinel__ __pmix_attribute_warn_unused_result__; /** * Convert the path to be OS friendly. On UNIX this function will diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/output.c b/opal/mca/pmix/pmix2x/pmix/src/util/output.c index 3218b62caf..7f01ae9c1e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/output.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/output.c @@ -22,7 +22,7 @@ #include -#include +#include #include #include diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/output.h b/opal/mca/pmix/pmix2x/pmix/src/util/output.h index 3bd08d1dcb..5fabcda823 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/output.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/output.h @@ -94,8 +94,8 @@ BEGIN_C_DECLS * subsystem to tell it to dump any collected output directly to * syslog instead of forwarding it to another location. */ -PMIX_DECLSPEC extern bool pmix_output_redirected_to_syslog; -PMIX_DECLSPEC extern int pmix_output_redirected_syslog_pri; +extern bool pmix_output_redirected_to_syslog; +extern int pmix_output_redirected_syslog_pri; /** * \class pmix_output_stream_t @@ -266,7 +266,7 @@ struct pmix_output_stream_t { * By definition, the default verbose stream has a handle ID of 0, * and has a verbose level of 0. */ - PMIX_DECLSPEC bool pmix_output_init(void); + bool pmix_output_init(void); /** * Shut down the output stream system. @@ -274,7 +274,7 @@ struct pmix_output_stream_t { * Shut down the output stream system, including the default verbose * stream. */ - PMIX_DECLSPEC void pmix_output_finalize(void); + void pmix_output_finalize(void); /** * Opens an output stream. @@ -298,7 +298,7 @@ struct pmix_output_stream_t { * when open_open() / pmix_output() is directed to send output to a * file but the process session directory does not yet exist. */ - PMIX_DECLSPEC int pmix_output_open(pmix_output_stream_t *lds); + int pmix_output_open(pmix_output_stream_t *lds); /** * Re-opens / redirects an output stream. @@ -312,7 +312,7 @@ struct pmix_output_stream_t { * passed is invalid, this call is effectively the same as opening a * new stream with a specific stream handle. */ - PMIX_DECLSPEC int pmix_output_reopen(int output_id, pmix_output_stream_t *lds); + int pmix_output_reopen(int output_id, pmix_output_stream_t *lds); /** * Enables and disables output streams. @@ -331,7 +331,7 @@ struct pmix_output_stream_t { * to the stream via PMIX_OUTPUT() or pmix_output() until the output * is re-enabled. */ - PMIX_DECLSPEC bool pmix_output_switch(int output_id, bool enable); + bool pmix_output_switch(int output_id, bool enable); /** * \internal @@ -342,7 +342,7 @@ struct pmix_output_stream_t { * typically only invoked after a restart (i.e., in a new process) * where output streams need to be re-initialized. */ - PMIX_DECLSPEC void pmix_output_reopen_all(void); + void pmix_output_reopen_all(void); /** * Close an output stream. @@ -354,7 +354,7 @@ struct pmix_output_stream_t { * re-used; it is possible that after a stream is closed, if another * stream is opened, it will get the same handle value. */ - PMIX_DECLSPEC void pmix_output_close(int output_id); + void pmix_output_close(int output_id); /** * Main function to send output to a stream. @@ -381,7 +381,7 @@ struct pmix_output_stream_t { * created, pmix_output() will automatically create the file and * writing to it. */ - PMIX_DECLSPEC void pmix_output(int output_id, const char *format, ...) __pmix_attribute_format__(__printf__, 2, 3); + void pmix_output(int output_id, const char *format, ...) __pmix_attribute_format__(__printf__, 2, 3); /** * Send output to a stream only if the passed verbosity level is @@ -411,13 +411,13 @@ struct pmix_output_stream_t { * * @see pmix_output_set_verbosity() */ - PMIX_DECLSPEC void pmix_output_verbose(int verbose_level, int output_id, + void pmix_output_verbose(int verbose_level, int output_id, const char *format, ...) __pmix_attribute_format__(__printf__, 3, 4); /** * Same as pmix_output_verbose(), but takes a va_list form of varargs. */ - PMIX_DECLSPEC void pmix_output_vverbose(int verbose_level, int output_id, + void pmix_output_vverbose(int verbose_level, int output_id, const char *format, va_list ap) __pmix_attribute_format__(__printf__, 3, 0); /** @@ -434,13 +434,13 @@ struct pmix_output_stream_t { * level is not high enough, NULL is returned. The caller is * responsible for free()'ing the returned string. */ - PMIX_DECLSPEC char *pmix_output_string(int verbose_level, int output_id, + char *pmix_output_string(int verbose_level, int output_id, const char *format, ...) __pmix_attribute_format__(__printf__, 3, 4); /** * Same as pmix_output_string, but accepts a va_list form of varargs. */ - PMIX_DECLSPEC char *pmix_output_vstring(int verbose_level, int output_id, + char *pmix_output_vstring(int verbose_level, int output_id, const char *format, va_list ap) __pmix_attribute_format__(__printf__, 3, 0); /** @@ -452,7 +452,7 @@ struct pmix_output_stream_t { * This function sets the verbosity level on a given stream. It * will be used for all future invocations of pmix_output_verbose(). */ - PMIX_DECLSPEC void pmix_output_set_verbosity(int output_id, int level); + void pmix_output_set_verbosity(int output_id, int level); /** * Get the verbosity level for a stream @@ -460,7 +460,7 @@ struct pmix_output_stream_t { * @param output_id Stream id returned from pmix_output_open() * @returns Verbosity of stream */ - PMIX_DECLSPEC int pmix_output_get_verbosity(int output_id); + int pmix_output_get_verbosity(int output_id); /** * Set characteristics for output files. @@ -502,7 +502,7 @@ struct pmix_output_stream_t { * this function affects both new streams \em and any stream that * was previously opened but had not yet output anything. */ - PMIX_DECLSPEC void pmix_output_set_output_file_info(const char *dir, + void pmix_output_set_output_file_info(const char *dir, const char *prefix, char **olddir, char **oldprefix); @@ -510,7 +510,7 @@ struct pmix_output_stream_t { /** * Same as pmix_output_verbose(), but pointer to buffer and size. */ - PMIX_DECLSPEC void pmix_output_hexdump(int verbose_level, int output_id, + void pmix_output_hexdump(int verbose_level, int output_id, void *ptr, int buflen); #if PMIX_ENABLE_DEBUG @@ -559,7 +559,7 @@ struct pmix_output_stream_t { * The intended usage is to invoke the constructor and then enable * the output fields that you want. */ -PMIX_DECLSPEC PMIX_CLASS_DECLARATION(pmix_output_stream_t); +PMIX_CLASS_DECLARATION(pmix_output_stream_t); END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/path.c b/opal/mca/pmix/pmix2x/pmix/src/util/path.c new file mode 100644 index 0000000000..4c532ef063 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/path.c @@ -0,0 +1,717 @@ +/* + * Copyright (c) 2004-2005 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) 2009-2014 Cisco Systems, Inc. All rights reserved. + * 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) 2016 University of Houston. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SHLWAPI_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_SYS_VFS_H +#include +#endif +#ifdef HAVE_SYS_STATFS_H +#include +#endif +#ifdef HAVE_SYS_STATVFS_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif +#ifdef HAVE_MNTENT_H +#include +#endif +#ifdef HAVE_PATHS_H +#include +#endif + +#ifdef _PATH_MOUNTED +#define MOUNTED_FILE _PATH_MOUNTED +#else +#define MOUNTED_FILE "/etc/mtab" +#endif + + +#include "src/include/pmix_stdint.h" +#include "src/util/output.h" +#include "src/util/path.h" +#include "src/util/os_path.h" +#include "src/util/argv.h" + +/* + * Sanity check to ensure we have either statfs or statvfs + */ +#if !defined(HAVE_STATFS) && !defined(HAVE_STATVFS) +#error Must have either statfs() or statvfs() +#endif + +/* + * Note that some OS's (e.g., NetBSD and Solaris) have statfs(), but + * no struct statfs (!). So check to make sure we have struct statfs + * before allowing the use of statfs(). + */ +#if defined(HAVE_STATFS) && \ + (defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || \ + defined(HAVE_STRUCT_STATFS_F_TYPE)) +#define USE_STATFS 1 +#endif + +static void path_env_load(char *path, int *pargc, char ***pargv); +static char *list_env_get(char *var, char **list); + +bool pmix_path_is_absolute( const char *path ) +{ + if( PMIX_PATH_SEP[0] == *path ) { + return true; + } + return false; +} + +/** + * Locates a file with certain permissions + */ +char *pmix_path_find(char *fname, char **pathv, int mode, char **envv) +{ + char *fullpath; + char *delimit; + char *env; + char *pfix; + int i; + + /* If absolute path is given, return it without searching. */ + if( pmix_path_is_absolute(fname) ) { + return pmix_path_access(fname, NULL, mode); + } + + /* Initialize. */ + + fullpath = NULL; + i = 0; + + /* Consider each directory until the file is found. Thus, the + order of directories is important. */ + + while (pathv[i] && NULL == fullpath) { + + /* Replace environment variable at the head of the string. */ + if ('$' == *pathv[i]) { + delimit = strchr(pathv[i], PMIX_PATH_SEP[0]); + if (delimit) { + *delimit = '\0'; + } + env = list_env_get(pathv[i]+1, envv); + if (delimit) { + *delimit = PMIX_PATH_SEP[0]; + } + if (NULL != env) { + if (!delimit) { + fullpath = pmix_path_access(fname, env, mode); + } else { + pfix = (char*) malloc(strlen(env) + strlen(delimit) + 1); + if (NULL == pfix) { + return NULL; + } + strcpy(pfix, env); + strcat(pfix, delimit); + fullpath = pmix_path_access(fname, pfix, mode); + free(pfix); + } + } + } + else { + fullpath = pmix_path_access(fname, pathv[i], mode); + } + i++; + } + return pmix_make_filename_os_friendly(fullpath); +} + +/* + * Locates a file with certain permissions from a list of search paths + */ +char *pmix_path_findv(char *fname, int mode, char **envv, char *wrkdir) +{ + char **dirv; + char *fullpath; + char *path; + int dirc; + int i; + bool found_dot = false; + + /* Set the local search paths. */ + + dirc = 0; + dirv = NULL; + + if (NULL != (path = list_env_get("PATH", envv))) { + path_env_load(path, &dirc, &dirv); + } + + /* Replace the "." path by the working directory. */ + + if (NULL != wrkdir) { + for (i = 0; i < dirc; ++i) { + if (0 == strcmp(dirv[i], ".")) { + found_dot = true; + free(dirv[i]); + dirv[i] = strdup(wrkdir); + if (NULL == dirv[i]){ + return NULL; + } + } + } + } + + /* If we didn't find "." in the path and we have a wrkdir, append + the wrkdir to the end of the path */ + + if (!found_dot && NULL != wrkdir) { + pmix_argv_append(&dirc, &dirv, wrkdir); + } + + if(NULL == dirv) + return NULL; + fullpath = pmix_path_find(fname, dirv, mode, envv); + pmix_argv_free(dirv); + return fullpath; +} + + +/** + * Forms a complete pathname and checks it for existance and + * permissions + * + * Accepts: + * -fname File name + * -path Path prefix + * -mode Target permissions which must be satisfied + * + * Returns: + * -Full pathname of located file Success + * -NULL Failure + */ +char *pmix_path_access(char *fname, char *path, int mode) +{ + char *fullpath = NULL; + struct stat buf; + + /* Allocate space for the full pathname. */ + if (NULL == path) { + fullpath = pmix_os_path(false, fname, NULL); + } else { + fullpath = pmix_os_path(false, path, fname, NULL); + } + if (NULL == fullpath) + return NULL; + + /* first check to see - is this a file or a directory? We + * only want files + */ + if (0 != stat(fullpath, &buf)) { + /* couldn't stat the path - obviously, this also meets the + * existence check, if that was requested + */ + free(fullpath); + return NULL; + } + + if (!(S_IFREG & buf.st_mode) && + !(S_IFLNK & buf.st_mode)) { + /* this isn't a regular file or a symbolic link, so + * ignore it + */ + free(fullpath); + return NULL; + } + + /* check the permissions */ + if ((X_OK & mode) && !(S_IXUSR & buf.st_mode)) { + /* if they asked us to check executable permission, + * and that isn't set, then return NULL + */ + free(fullpath); + return NULL; + } + if ((R_OK & mode) && !(S_IRUSR & buf.st_mode)) { + /* if they asked us to check read permission, + * and that isn't set, then return NULL + */ + free(fullpath); + return NULL; + } + if ((W_OK & mode) && !(S_IWUSR & buf.st_mode)) { + /* if they asked us to check write permission, + * and that isn't set, then return NULL + */ + free(fullpath); + return NULL; + } + + /* must have met all criteria! */ + return fullpath; +} + + +/** + * + * Loads argument array with $PATH env var. + * + * Accepts + * -path String contiaing the $PATH + * -argc Pointer to argc + * -argv Pointer to list of argv + */ +static void path_env_load(char *path, int *pargc, char ***pargv) +{ + char *p; + char saved; + + if (NULL == path) { + *pargc = 0; + return; + } + + /* Loop through the paths (delimited by PATHENVSEP), adding each + one to argv. */ + + while ('\0' != *path) { + + /* Locate the delimiter. */ + + for (p = path; *p && (*p != PMIX_ENV_SEP); ++p) { + continue; + } + + /* Add the path. */ + + if (p != path) { + saved = *p; + *p = '\0'; + pmix_argv_append(pargc, pargv, path); + *p = saved; + path = p; + } + + /* Skip past the delimiter, if present. */ + + if (*path) { + ++path; + } + } +} + + +/** + * Gets value of variable in list or environment. Looks in the list first + * + * Accepts: + * -var String variable + * -list Pointer to environment list + * + * Returns: + * -List Pointer to environment list Success + * -NULL Failure + */ +static char *list_env_get(char *var, char **list) +{ + size_t n; + + if (NULL != list) { + n = strlen(var); + + while (NULL != *list) { + if ((0 == strncmp(var, *list, n)) && ('=' == (*list)[n])) { + return (*list + n + 1); + } + ++list; + } + } + return getenv(var); +} + +/** + * Try to figure out the absolute path based on the application name + * (usually argv[0]). If the path is already absolute return a copy, if + * it start with . look into the current directory, if not dig into + * the $PATH. + * In case of error or if executable was not found (as an example if + * the application did a cwd between the start and this call), the + * function will return NULL. Otherwise, an newly allocated string + * will be returned. + */ +char* pmix_find_absolute_path( char* app_name ) +{ + char* abs_app_name; + char cwd[PMIX_PATH_MAX], *pcwd; + + if( pmix_path_is_absolute(app_name) ) { /* already absolute path */ + abs_app_name = app_name; + } else if ( '.' == app_name[0] || + NULL != strchr(app_name, PMIX_PATH_SEP[0])) { + /* the app is in the current directory or below it */ + pcwd = getcwd( cwd, PMIX_PATH_MAX ); + if( NULL == pcwd ) { + /* too bad there is no way we can get the app absolute name */ + return NULL; + } + abs_app_name = pmix_os_path( false, pcwd, app_name, NULL ); + } else { + /* Otherwise try to search for the application in the PATH ... */ + abs_app_name = pmix_path_findv( app_name, X_OK, NULL, NULL ); + } + + if( NULL != abs_app_name ) { + char* resolved_path = (char*)malloc(PMIX_PATH_MAX); + realpath( abs_app_name, resolved_path ); + if( abs_app_name != app_name ) free(abs_app_name); + return resolved_path; + } + return NULL; +} + +/** + * Read real FS type from /etc/mtab, needed to translate autofs fs type into real fs type + * TODO: solaris? OSX? + * Limitations: autofs on solaris/osx will be assumed as "nfs" type + */ + +static char *pmix_check_mtab(char *dev_path) +{ + +#ifdef HAVE_MNTENT_H + FILE * mtab = NULL; + struct mntent * part = NULL; + + if ((mtab = setmntent(MOUNTED_FILE, "r")) != NULL) { + while (NULL != (part = getmntent(mtab))) { + if ((NULL != part->mnt_dir) && + (NULL != part->mnt_type) && + (0 == strcmp(part->mnt_dir, dev_path))) + { + endmntent(mtab); + return strdup(part->mnt_type); + } + } + endmntent(mtab); + } +#endif + return NULL; +} + + +/** + * @brief Figure out, whether fname is on network file system + * + * Try to figure out, whether the file name specified through fname is + * on any network file system (currently NFS, Lustre, Panasas and GPFS). + * + * If the file is not created, the parent directory is checked. + * This allows checking for NFS prior to opening the file. + * + * @fname[in] File name to check + * @fstype[out] File system type if retval is true + * + * @retval true If fname is on NFS, Lustre, Panasas or GPFS + * @retval false otherwise + * + * + * Linux: + * statfs(const char *path, struct statfs *buf); + * with fsid_t f_fsid; (in kernel struct{ int val[2] };) + * return 0 success, -1 on failure with errno set. + * statvfs (const char *path, struct statvfs *buf); + * with unsigned long f_fsid; -- returns wrong info + * return 0 success, -1 on failure with errno set. + * Solaris: + * statvfs (const char *path, struct statvfs *buf); + * with f_basetype, contains a string of length FSTYPSZ + * return 0 success, -1 on failure with errno set. + * FreeBSD: + * statfs(const char *path, struct statfs *buf); + * with f_fstypename, contains a string of length MFSNAMELEN + * return 0 success, -1 on failure with errno set. + * compliant with: 4.4BSD. + * NetBSD: + * statvfs (const char *path, struct statvfs *buf); + * with f_fstypename, contains a string of length VFS_NAMELEN + * return 0 success, -1 on failure with errno set. + * Mac OSX (10.6.2 through 10.9): + * statvfs(const char * restrict path, struct statvfs * restrict buf); + * with fsid Not meaningful in this implementation. + * is just a wrapper around statfs() + * statfs(const char *path, struct statfs *buf); + * with f_fstypename, contains a string of length MFSTYPENAMELEN + * return 0 success, -1 on failure with errno set. + */ +#ifndef LL_SUPER_MAGIC +#define LL_SUPER_MAGIC 0x0BD00BD0 /* Lustre magic number */ +#endif +#ifndef NFS_SUPER_MAGIC +#define NFS_SUPER_MAGIC 0x6969 +#endif +#ifndef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC +#define PAN_KERNEL_FS_CLIENT_SUPER_MAGIC 0xAAD7AAEA /* Panasas FS */ +#endif +#ifndef GPFS_SUPER_MAGIC +#define GPFS_SUPER_MAGIC 0x47504653 /* Thats GPFS in ASCII */ +#endif +#ifndef AUTOFS_SUPER_MAGIC +#define AUTOFS_SUPER_MAGIC 0x0187 +#endif +#ifndef PVFS2_SUPER_MAGIC +#define PVFS2_SUPER_MAGIC 0x20030528 +#endif + +#define MASK2 0xffff +#define MASK4 0xffffffff + +bool pmix_path_nfs(char *fname, char **ret_fstype) +{ + int i; + int fsrc = -1; + int vfsrc = -1; + int trials; + char * file = strdup (fname); +#if defined(USE_STATFS) + struct statfs fsbuf; +#endif +#if defined(HAVE_STATVFS) + struct statvfs vfsbuf; +#endif + /* + * Be sure to update the test (test/util/pmix_path_nfs.c) + * while adding a new Network/Cluster Filesystem here + */ + static struct fs_types_t { + unsigned long long f_fsid; + unsigned long long f_mask; + const char * f_fsname; + } fs_types[] = { + {LL_SUPER_MAGIC, MASK4, "lustre"}, + {NFS_SUPER_MAGIC, MASK2, "nfs"}, + {AUTOFS_SUPER_MAGIC, MASK2, "autofs"}, + {PAN_KERNEL_FS_CLIENT_SUPER_MAGIC, MASK4, "panfs"}, + {GPFS_SUPER_MAGIC, MASK4, "gpfs"}, + {PVFS2_SUPER_MAGIC, MASK4, "pvfs2"} + }; +#define FS_TYPES_NUM (int)(sizeof (fs_types)/sizeof (fs_types[0])) + + /* + * First, get the OS-dependent struct stat(v)fs buf. This may + * return the ESTALE error on NFS, if the underlying file/path has + * changed. + */ +again: +#if defined(USE_STATFS) + trials = 5; + do { + fsrc = statfs(file, &fsbuf); + } while (-1 == fsrc && ESTALE == errno && (0 < --trials)); +#endif +#if defined(HAVE_STATVFS) + trials = 5; + do { + vfsrc = statvfs(file, &vfsbuf); + } while (-1 == vfsrc && ESTALE == errno && (0 < --trials)); +#endif + + /* In case some error with the current filename, try the parent + directory */ + if (-1 == fsrc && -1 == vfsrc) { + char * last_sep; + + PMIX_OUTPUT_VERBOSE((10, 0, "pmix_path_nfs: stat(v)fs on file:%s failed errno:%d directory:%s\n", + fname, errno, file)); + if (EPERM == errno) { + free(file); + if ( NULL != ret_fstype ) { + *ret_fstype = NULL; + } + return false; + } + + last_sep = strrchr(file, PMIX_PATH_SEP[0]); + /* Stop the search, when we have searched past root '/' */ + if (NULL == last_sep || (1 == strlen(last_sep) && + PMIX_PATH_SEP[0] == *last_sep)) { + free (file); + if ( NULL != ret_fstype ) { + *ret_fstype=NULL; + } + return false; + } + *last_sep = '\0'; + + goto again; + } + + /* Next, extract the magic value */ + for (i = 0; i < FS_TYPES_NUM; i++) { +#if defined(USE_STATFS) + /* These are uses of struct statfs */ +# if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) + if (0 == fsrc && + 0 == strncasecmp(fs_types[i].f_fsname, fsbuf.f_fstypename, + sizeof(fsbuf.f_fstypename))) { + goto found; + } +# endif +# if defined(HAVE_STRUCT_STATFS_F_TYPE) + if (0 == fsrc && + fs_types[i].f_fsid == (fsbuf.f_type & fs_types[i].f_mask)) { + goto found; + } +# endif +#endif + +#if defined(HAVE_STATVFS) + /* These are uses of struct statvfs */ +# if defined(HAVE_STRUCT_STATVFS_F_BASETYPE) + if (0 == vfsrc && + 0 == strncasecmp(fs_types[i].f_fsname, vfsbuf.f_basetype, + sizeof(vfsbuf.f_basetype))) { + goto found; + } +# endif +# if defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) + if (0 == vfsrc && + 0 == strncasecmp(fs_types[i].f_fsname, vfsbuf.f_fstypename, + sizeof(vfsbuf.f_fstypename))) { + goto found; + } +# endif +#endif + } + + free (file); + if ( NULL != ret_fstype ) { + *ret_fstype=NULL; + } + return false; + +#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || \ + defined(HAVE_STRUCT_STATFS_F_TYPE) || \ + defined(HAVE_STRUCT_STATVFS_F_BASETYPE) || \ + defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) + found: +#endif + + free (file); + if (AUTOFS_SUPER_MAGIC == fs_types[i].f_fsid) { + char *fs_type = pmix_check_mtab(fname); + int x; + if (NULL != fs_type) { + for (x = 0; x < FS_TYPES_NUM; x++) { + if (AUTOFS_SUPER_MAGIC == fs_types[x].f_fsid) { + continue; + } + if (0 == strcasecmp(fs_types[x].f_fsname, fs_type)) { + PMIX_OUTPUT_VERBOSE((10, 0, "pmix_path_nfs: file:%s on fs:%s\n", fname, fs_type)); + free(fs_type); + if ( NULL != ret_fstype ) { + *ret_fstype = strdup(fs_types[x].f_fsname); + } + return true; + } + } + free(fs_type); + if ( NULL != ret_fstype ) { + *ret_fstype=NULL; + } + return false; + } + } + + PMIX_OUTPUT_VERBOSE((10, 0, "pmix_path_nfs: file:%s on fs:%s\n", + fname, fs_types[i].f_fsname)); + if ( NULL != ret_fstype ) { + *ret_fstype = strdup (fs_types[i].f_fsname); + } + return true; + +#undef FS_TYPES_NUM +} + +int +pmix_path_df(const char *path, + uint64_t *out_avail) +{ + int rc = -1; + int trials = 5; + int err = 0; +#if defined(USE_STATFS) + struct statfs buf; +#elif defined(HAVE_STATVFS) + struct statvfs buf; +#endif + + if (NULL == path || NULL == out_avail) { + return PMIX_ERROR; + } + *out_avail = 0; + + do { +#if defined(USE_STATFS) + rc = statfs(path, &buf); +#elif defined(HAVE_STATVFS) + rc = statvfs(path, &buf); +#endif + err = errno; + } while (-1 == rc && ESTALE == err && (--trials > 0)); + + if (-1 == rc) { + PMIX_OUTPUT_VERBOSE((10, 2, "pmix_path_df: stat(v)fs on " + "path: %s failed with errno: %d (%s)\n", + path, err, strerror(err))); + return PMIX_ERROR; + } + + /* now set the amount of free space available on path */ + /* sometimes buf.f_bavail is negative */ + *out_avail = buf.f_bsize * ((int)buf.f_bavail < 0 ? 0 : buf.f_bavail); + + PMIX_OUTPUT_VERBOSE((10, 2, "pmix_path_df: stat(v)fs states " + "path: %s has %"PRIu64 " B of free space.", + path, *out_avail)); + + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/path.h b/opal/mca/pmix/pmix2x/pmix/src/util/path.h new file mode 100644 index 0000000000..b9ab1d5874 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/path.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2004-2005 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + * @file + */ + +#ifndef PMIX_PATH_H +#define PMIX_PATH_H + +#include + +#include "pmix_common.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +BEGIN_C_DECLS + +/** + * Locates a file with certain permissions + * + * @param fname File name + * @param pathv Array of search directories + * @param mode Permissions which must be satisfied (see access(2)) + * @param envv Pointer to string containing environment + * + * @retval Full pathname of located file Success + * @retval NULL Failure + * + * Environment variables can appear in the form $variable at the + * start of a prefix path and will be replaced by the environment + * value if it is defined; otherwise the whole prefix is ignored. + * Environment variables must be followed by a path delimiter or + * end-of-string. + * + * The caller is responsible for freeing the returned string. + */ +char *pmix_path_find(char *fname, char **pathv, int mode, + char **envv) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; + +/** + * Locates a file with certain permissions from a list of search + * paths + * + * @param fname File name + * @param mode Target permissions which must be satisfied (see access(2)) + * @param envv Pointer to environment list + * @param wrkdir Working directory + * + * @retval Full pathname of located file Success + * @retval NULL Failure + * + * Locates a file with certain permissions from the list of paths + * given by the $PATH environment variable. Replaces "." in the + * path with the working dir. + * + * The caller is responsible for freeing the returned string. + */ +char *pmix_path_findv(char *fname, int mode, + char **envv, char *wrkdir) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; +/** + * Detect if the requested path is absolute or relative. + * + * @param path File name + * + * @retval true if the path is absolute + * @retval false otherwise + * + * Detect if a path is absolute or relative. Handle Windows + * with special care as an absolute path on Windows starts + * with [A-Za-z]: or \\ instead of the usual / on UNIX. + */ +bool pmix_path_is_absolute( const char *path ); + +/** + * Find the absolute path for an executable and return it. + * + * @param app_name Executable name + * + * @retval The absolute path if the application can be reached, + * @retval NULL otherwise. + * + * Try to figure out the absolute path based on the application name + * (usually argv[0]). If the path is already absolute return a copy, if + * it start with . look into the current directory, if not dig into + * the $PATH. + * In case of error or if executable was not found (as an example if + * the application did a cwd between the start and this call), the + * function will return NULL. Otherwise, an newly allocated string + * will be returned. + */ +char* pmix_find_absolute_path( char* app_name ) __pmix_attribute_warn_unused_result__; + +/** + * Forms a complete pathname and checks it for existance and + * permissions + * + * @param fname File name + * @param path Path prefix, if NULL then fname is an absolute path + * @param mode Target permissions which must be satisfied (see access(2)) + * + * @retval NULL Failure + * @retval Full pathname of the located file on Success + * + * The caller is responsible for freeing the returned string. + */ +char *pmix_path_access(char *fname, char *path, int mode) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; + + +/** + * @brief Figure out, whether fname is on network file system + * and return fstype if known + * + * Try to figure out, whether the file name specified through fname is + * on any network file system (currently NFS, Lustre, GPFS, Panasas + * and PVFS2 ). + * + * If the file is not created, the parent directory is checked. + * This allows checking for NFS prior to opening the file. + * + * @fname[in] File name to check + * @fstype[out] File system type if retval is true + * + * @retval true If fname is on NFS, Lustre or Panasas + * @retval false otherwise + */ +bool pmix_path_nfs(char *fname, char **fstype) __pmix_attribute_warn_unused_result__; + +/** + * @brief Returns the disk usage of path. + * + * @param[in] path Path to check + * @out_avail[out] Amount of free space available on path (if successful) + * + * @retval PMIX_SUCCESS If the operation was successful + * @retval PMIX_ERROR otherwise + */ +int +pmix_path_df(const char *path, + uint64_t *out_avail)__pmix_attribute_warn_unused_result__; + +END_C_DECLS +#endif /* PMIX_PATH_H */ 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 4e63989088..9587a464d2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.c +++ b/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.c @@ -23,7 +23,7 @@ #include -#include +#include #include #include 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 2567c915b8..f6ec9c95b2 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/pmix_environ.h @@ -38,7 +38,7 @@ #include #endif -#include +#include BEGIN_C_DECLS @@ -65,7 +65,7 @@ BEGIN_C_DECLS * one of the two is NULL, the other list is simply copied to the * output. If both are NULL, NULL is returned. */ -PMIX_DECLSPEC char **pmix_environ_merge(char **minor, char **major) __pmix_attribute_warn_unused_result__; +char **pmix_environ_merge(char **minor, char **major) __pmix_attribute_warn_unused_result__; /** * Portable version of setenv(3), allowing editing of any @@ -113,7 +113,7 @@ PMIX_DECLSPEC char **pmix_environ_merge(char **minor, char **major) __pmix_attri * pmix_setenv("foo", "bar", true, &my_env); * \endcode */ -PMIX_DECLSPEC pmix_status_t pmix_setenv(const char *name, const char *value, +pmix_status_t pmix_setenv(const char *name, const char *value, bool overwrite, char ***env) __pmix_attribute_nonnull__(1); /** @@ -130,20 +130,20 @@ PMIX_DECLSPEC pmix_status_t pmix_setenv(const char *name, const char *value, * If \em name is found in \em env, the string corresponding to * that entry is freed and its entry is eliminated from the array. */ -PMIX_DECLSPEC pmix_status_t pmix_unsetenv(const char *name, char ***env) __pmix_attribute_nonnull__(1); +pmix_status_t pmix_unsetenv(const char *name, char ***env) __pmix_attribute_nonnull__(1); /* A consistent way to retrieve the home and tmp directory on all supported * platforms. */ -PMIX_DECLSPEC const char* pmix_home_directory( void ); -PMIX_DECLSPEC const char* pmix_tmp_directory( void ); +const char* pmix_home_directory( void ); +const char* pmix_tmp_directory( void ); /* Some care is needed with environ on OS X when dealing with shared libraries. Handle that care here... */ #ifdef HAVE__NSGETENVIRON #define environ (*_NSGetEnviron()) #else -PMIX_DECLSPEC extern char **environ; +extern char **environ; #endif END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/printf.h b/opal/mca/pmix/pmix2x/pmix/src/util/printf.h index 66538cfe7c..f4ab098596 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/util/printf.h +++ b/opal/mca/pmix/pmix2x/pmix/src/util/printf.h @@ -53,7 +53,7 @@ BEGIN_C_DECLS * * THIS IS A PORTABILITY FEATURE: USE snprintf() in CODE. */ -PMIX_DECLSPEC int pmix_snprintf(char *str, size_t size, const char *fmt, ...) __pmix_attribute_format__(__printf__, 3, 4); +int pmix_snprintf(char *str, size_t size, const char *fmt, ...) __pmix_attribute_format__(__printf__, 3, 4); /** @@ -78,7 +78,7 @@ PMIX_DECLSPEC int pmix_snprintf(char *str, size_t size, const char *fmt, ...) _ * * THIS IS A PORTABILITY FEATURE: USE vsnprintf() in CODE. */ -PMIX_DECLSPEC int pmix_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) __pmix_attribute_format__(__printf__, 3, 0); +int pmix_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) __pmix_attribute_format__(__printf__, 3, 0); /** * Allocates and writes to a string under the control of a format @@ -99,7 +99,7 @@ PMIX_DECLSPEC int pmix_vsnprintf(char *str, size_t size, const char *fmt, va_li * * THIS IS A PORTABILITY FEATURE: USE asprintf() in CODE. */ -PMIX_DECLSPEC int pmix_asprintf(char **ptr, const char *fmt, ...) __pmix_attribute_format__(__printf__, 2, 3); +int pmix_asprintf(char **ptr, const char *fmt, ...) __pmix_attribute_format__(__printf__, 2, 3); /** @@ -123,7 +123,7 @@ PMIX_DECLSPEC int pmix_asprintf(char **ptr, const char *fmt, ...) __pmix_attrib * * THIS IS A PORTABILITY FEATURE: USE vasprintf() in CODE. */ -PMIX_DECLSPEC int pmix_vasprintf(char **ptr, const char *fmt, va_list ap) __pmix_attribute_format__(__printf__, 2, 0); +int pmix_vasprintf(char **ptr, const char *fmt, va_list ap) __pmix_attribute_format__(__printf__, 2, 0); END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/progress_threads.c b/opal/mca/pmix/pmix2x/pmix/src/util/progress_threads.c deleted file mode 100644 index 29e95e76a7..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/util/progress_threads.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2014-2016 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 -#include PMIX_EVENT_HEADER -#include PMIX_EVENT2_THREAD_HEADER -#include -#ifdef HAVE_STRING_H -#include -#endif - -#include "src/class/pmix_list.h" -#include "src/util/error.h" -#include "src/util/fd.h" - -#include -#include "src/util/progress_threads.h" - -static volatile bool evlib_active; -static int block_pipe[2]; -static pmix_event_t block_ev; -static pthread_t engine; -static bool block_active = false; -static bool thread_initalized = false; - -static void wakeup(int fd, short args, void *cbdata) -{ - /* if this event fired, then the blocker event will - * be deleted from the event base by libevent, so flag - * it so we don't try to delete it again */ - block_active = false; -} -static void* progress_engine(void *obj) -{ - pmix_event_base_t *ev_base = (pmix_event_base_t *)obj; - while (evlib_active) { - event_base_loop(ev_base, EVLOOP_ONCE); - } - return NULL; -} - -pmix_event_base_t* pmix_start_progress_thread() -{ - pmix_event_base_t *ev_base; - /* Setup threading */ - evthread_use_pthreads(); - /* Create base for events */ - if (NULL == (ev_base = (pmix_event_base_t*)event_base_new())) { - PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); - return NULL; - } - - /* add an event it can block on */ - if (0 > pipe(block_pipe)) { - PMIX_ERROR_LOG(PMIX_ERR_IN_ERRNO); - return NULL; - } - /* Make sure the pipe FDs are set to close-on-exec so that - they don't leak into children */ - if (pmix_fd_set_cloexec(block_pipe[0]) != PMIX_SUCCESS || - pmix_fd_set_cloexec(block_pipe[1]) != PMIX_SUCCESS) { - PMIX_ERROR_LOG(PMIX_ERR_IN_ERRNO); - close(block_pipe[0]); - close(block_pipe[1]); - event_base_free(ev_base); - return NULL; - } - event_assign(&block_ev, ev_base, block_pipe[0], - EV_READ, wakeup, NULL); - event_add(&block_ev, 0); - evlib_active = true; - block_active = true; - - /* fork off a thread to progress it */ - if (0 > pthread_create(&engine, NULL, progress_engine, (void*)ev_base)) { - PMIX_ERROR_LOG(PMIX_ERROR); - return NULL; - } - if (!thread_initalized) { - thread_initalized = true; - } - return ev_base; -} - -void pmix_stop_progress_thread(pmix_event_base_t *ev_base) -{ - int i; - - if (!thread_initalized) { - /* nothing we can do */ - return; - } - - /* mark it as inactive */ - evlib_active = false; - /* if present, use the block to break it loose just in - * case the thread is blocked in a call to select for - * a long time */ - if (block_active) { - i=1; - if (0 > write(block_pipe[1], &i, sizeof(int))) { - return; - } - } - /* break the event loop - this will cause the loop to exit - * upon completion of any current event */ - event_base_loopbreak(ev_base); - /* wait for thread to exit */ - pthread_join(engine, NULL); - if (block_active) { - /* delete the blocking event */ - event_del(&block_ev); - block_active = false; - } - /* close the pipes */ - close(block_pipe[0]); - close(block_pipe[1]); - return; -} diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/progress_threads.h b/opal/mca/pmix/pmix2x/pmix/src/util/progress_threads.h deleted file mode 100644 index 3ead034838..0000000000 --- a/opal/mca/pmix/pmix2x/pmix/src/util/progress_threads.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. - * Copyright (c) 2016 Mellanox Technologies, Inc. - * All rights reserved. - * - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#ifndef PROGRESS_THREADS_H -#define PROGRESS_THREADS_H - -#include - -#include - -#include PMIX_EVENT_HEADER - -/* start a progress thread, assigning it the provided name for - * tracking purposes. If create_block is true, then this function - * will also create a pipe so that libevent has something to block - * against, thus keeping the thread from free-running - */ -PMIX_DECLSPEC pmix_event_base_t* pmix_start_progress_thread(void); - -/* stop the progress thread of the provided name. This function will - * also cleanup the blocking pipes and release the event base if - * the cleanup param is true */ -PMIX_DECLSPEC void pmix_stop_progress_thread(pmix_event_base_t *ev_base); - -#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/show_help.c b/opal/mca/pmix/pmix2x/pmix/src/util/show_help.c new file mode 100644 index 0000000000..21b29337b9 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/show_help.c @@ -0,0 +1,370 @@ +/* + * 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) 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$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#include +#include +#include + +#include "src/mca/pinstalldirs/pinstalldirs.h" +#include "src/util/show_help.h" +#include "src/util/show_help_lex.h" +#include "src/util/printf.h" +#include "src/util/argv.h" +#include "src/util/os_path.h" +#include "src/util/output.h" +#include "pmix_common.h" + + +/* + * Private variables + */ +static const char *default_filename = "help-messages"; +static const char *dash_line = "--------------------------------------------------------------------------\n"; +static int output_stream = -1; +static char **search_dirs = NULL; + +/* + * Local functions + */ +static int pmix_show_vhelp_internal(const char *filename, const char *topic, + bool want_error_header, va_list arglist); +static int pmix_show_help_internal(const char *filename, const char *topic, + bool want_error_header, ...); + +pmix_show_help_fn_t pmix_show_help = pmix_show_help_internal; +pmix_show_vhelp_fn_t pmix_show_vhelp = pmix_show_vhelp_internal; + + +int pmix_show_help_init(void) +{ + pmix_output_stream_t lds; + + PMIX_CONSTRUCT(&lds, pmix_output_stream_t); + lds.lds_want_stderr = true; + output_stream = pmix_output_open(&lds); + + pmix_argv_append_nosize(&search_dirs, pmix_pinstall_dirs.pmixdatadir); + + return PMIX_SUCCESS; +} + +int pmix_show_help_finalize(void) +{ + pmix_output_close(output_stream); + output_stream = -1; + + /* destruct the search list */ + if (NULL != search_dirs) { + pmix_argv_free(search_dirs); + search_dirs = NULL; + }; + + return PMIX_SUCCESS; +} + +/* + * Make one big string with all the lines. This isn't the most + * efficient method in the world, but we're going for clarity here -- + * not optimization. :-) + */ +static int array2string(char **outstring, + bool want_error_header, char **lines) +{ + int i, count; + size_t len; + + /* See how much space we need */ + + len = want_error_header ? 2 * strlen(dash_line) : 0; + count = pmix_argv_count(lines); + for (i = 0; i < count; ++i) { + if (NULL == lines[i]) { + break; + } + len += strlen(lines[i]) + 1; + } + + /* Malloc it out */ + + (*outstring) = (char*) malloc(len + 1); + if (NULL == *outstring) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + + /* Fill the big string */ + + *(*outstring) = '\0'; + if (want_error_header) { + strcat(*outstring, dash_line); + } + for (i = 0; i < count; ++i) { + if (NULL == lines[i]) { + break; + } + strcat(*outstring, lines[i]); + strcat(*outstring, "\n"); + } + if (want_error_header) { + strcat(*outstring, dash_line); + } + + return PMIX_SUCCESS; +} + + +/* + * Find the right file to open + */ +static int open_file(const char *base, const char *topic) +{ + char *filename; + char *err_msg = NULL; + size_t base_len; + int i; + + /* If no filename was supplied, use the default */ + + if (NULL == base) { + base = default_filename; + } + + /* if this is called prior to someone initializing the system, + * then don't try to look + */ + if (NULL != search_dirs) { + /* Try to open the file. If we can't find it, try it with a .txt + * extension. + */ + for (i=0; NULL != search_dirs[i]; i++) { + filename = pmix_os_path( false, search_dirs[i], base, NULL ); + pmix_show_help_yyin = fopen(filename, "r"); + if (NULL == pmix_show_help_yyin) { + asprintf(&err_msg, "%s: %s", filename, strerror(errno)); + base_len = strlen(base); + if (4 > base_len || 0 != strcmp(base + base_len - 4, ".txt")) { + free(filename); + asprintf(&filename, "%s%s%s.txt", search_dirs[i], PMIX_PATH_SEP, base); + pmix_show_help_yyin = fopen(filename, "r"); + } + } + free(filename); + if (NULL != pmix_show_help_yyin) { + break; + } + } + } + + /* If we still couldn't open it, then something is wrong */ + if (NULL == pmix_show_help_yyin) { + pmix_output(output_stream, "%sSorry! You were supposed to get help about:\n %s\nBut I couldn't open the help file:\n %s. Sorry!\n%s", dash_line, topic, err_msg, dash_line); + free(err_msg); + return PMIX_ERR_NOT_FOUND; + } + + if (NULL != err_msg) { + free(err_msg); + } + + /* Set the buffer */ + + pmix_show_help_init_buffer(pmix_show_help_yyin); + + /* Happiness */ + + return PMIX_SUCCESS; +} + + +/* + * In the file that has already been opened, find the topic that we're + * supposed to output + */ +static int find_topic(const char *base, const char *topic) +{ + int token, ret; + char *tmp; + + /* Examine every topic */ + + while (1) { + token = pmix_show_help_yylex(); + switch (token) { + case PMIX_SHOW_HELP_PARSE_TOPIC: + tmp = strdup(pmix_show_help_yytext); + if (NULL == tmp) { + return PMIX_ERR_OUT_OF_RESOURCE; + } + tmp[strlen(tmp) - 1] = '\0'; + ret = strcmp(tmp + 1, topic); + free(tmp); + if (0 == ret) { + return PMIX_SUCCESS; + } + break; + + case PMIX_SHOW_HELP_PARSE_MESSAGE: + break; + + case PMIX_SHOW_HELP_PARSE_DONE: + pmix_output(output_stream, "%sSorry! You were supposed to get help about:\n %s\nfrom the file:\n %s\nBut I couldn't find that topic in the file. Sorry!\n%s", dash_line, topic, base, dash_line); + return PMIX_ERR_NOT_FOUND; + break; + + default: + break; + } + } + + /* Never get here */ +} + + +/* + * We have an open file, and we're pointed at the right topic. So + * read in all the lines in the topic and make a list of them. + */ +static int read_topic(char ***array) +{ + int token, rc; + + while (1) { + token = pmix_show_help_yylex(); + switch (token) { + case PMIX_SHOW_HELP_PARSE_MESSAGE: + /* pmix_argv_append_nosize does strdup(pmix_show_help_yytext) */ + rc = pmix_argv_append_nosize(array, pmix_show_help_yytext); + if (rc != PMIX_SUCCESS) { + return rc; + } + break; + + default: + return PMIX_SUCCESS; + break; + } + } + + /* Never get here */ +} + + +static int load_array(char ***array, const char *filename, const char *topic) +{ + int ret; + + if (PMIX_SUCCESS != (ret = open_file(filename, topic))) { + return ret; + } + + ret = find_topic(filename, topic); + if (PMIX_SUCCESS == ret) { + ret = read_topic(array); + } + + fclose(pmix_show_help_yyin); + pmix_show_help_yylex_destroy (); + + if (PMIX_SUCCESS != ret) { + pmix_argv_free(*array); + } + + return ret; +} + +char *pmix_show_help_vstring(const char *filename, const char *topic, + bool want_error_header, va_list arglist) +{ + int rc; + char *single_string, *output, **array = NULL; + + /* Load the message */ + if (PMIX_SUCCESS != (rc = load_array(&array, filename, topic))) { + return NULL; + } + + /* Convert it to a single raw string */ + rc = array2string(&single_string, want_error_header, array); + + if (PMIX_SUCCESS == rc) { + /* Apply the formatting to make the final output string */ + vasprintf(&output, single_string, arglist); + free(single_string); + } + + pmix_argv_free(array); + return (PMIX_SUCCESS == rc) ? output : NULL; +} + +char *pmix_show_help_string(const char *filename, const char *topic, + bool want_error_handler, ...) +{ + char *output; + va_list arglist; + + va_start(arglist, want_error_handler); + output = pmix_show_help_vstring(filename, topic, want_error_handler, + arglist); + va_end(arglist); + + return output; +} + +static int pmix_show_vhelp_internal(const char *filename, const char *topic, + bool want_error_header, va_list arglist) +{ + char *output; + + /* Convert it to a single string */ + output = pmix_show_help_vstring(filename, topic, want_error_header, + arglist); + + /* If we got a single string, output it with formatting */ + if (NULL != output) { + pmix_output(output_stream, "%s", output); + free(output); + } + + return (NULL == output) ? PMIX_ERROR : PMIX_SUCCESS; +} + +static int pmix_show_help_internal(const char *filename, const char *topic, + bool want_error_header, ...) +{ + va_list arglist; + int rc; + + /* Convert it to a single string */ + va_start(arglist, want_error_header); + rc = pmix_show_vhelp(filename, topic, want_error_header, arglist); + va_end(arglist); + + return rc; +} + +int pmix_show_help_add_dir(const char *directory) +{ + pmix_argv_append_nosize(&search_dirs, directory); + return PMIX_SUCCESS; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/show_help.h b/opal/mca/pmix/pmix2x/pmix/src/util/show_help.h new file mode 100644 index 0000000000..69c4047ddc --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/show_help.h @@ -0,0 +1,177 @@ +/* + * 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) 2008-2011 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** + * @file + * + * The "show help" subsystem (SHS) in PMIX is intended to help the + * developer convey meaningful information to the user (read longer + * than is convenient in a single printf), particularly when errors + * occur. The SHS allows the storage of arbitrary-length help + * messages in text files which can be parameterized by text filename, + * message name, POSIX locale, and printf()-style parameters (e.g., + * "%s", "%d", etc.). Note that the primary purpose of the SHS is to + * display help messages, but it can actually be used to display any + * arbitrary text messages. + * + * The function pmix_show_help() is used to find a help message and + * display it. Its important parameters are a filename, message name, + * and printf()-style varargs parameters used to substitute into the + * message. + * + * It was originally intended that this system would support a very + * simple version of i18n-like support, but we got (strong) feedback + * that i18n support was not desired. So it never happened. + * + * As such, the file lookup is quite straightforward -- the caller + * passes in the filename to find the help message, and the SHS looks + * for that file in $pkgdatadir (typically $prefix/share/pmix). + * + * Once the file is successfully opened, the SHS looks for the + * appropriate help message to display. It looks for the message name + * in the file, reads in the message, and displays it. printf()-like + * substitutions are performed (e.g., %d, %s, etc.) -- + * pmix_show_help() takes a variable legnth argument list that are + * used for these substitutions. + * + * The format of the help file is simplistic: + * + * - Comments begin with #. Any characters after a # on a line are + * ignored. It is not possible to escape a #. + * - Message names are on a line by themselves and marked with []. + * Names can be any ASCII string within the [] (excluding the + * characters newline, linefeed, [, ], and #). + * - Messages are any characters between message names and/or the end + * of the file. + * + * Here's a sample helpfile: + * + * \verbatimbegin + * # This is a comment. + * [topic 1] + * Here's the first message. Let's substitute in an integer: %d. + * The quick brown fox jumped over the lazy %s. + * # This is another comment -- it's not displayed in the first message. + * [another:topic:foo:foo:foo] + * This is the second message. Let's just keep rolling along to get + * to the second line in the message for this example. + * \verbatimend + * + * It is expected that help messages will be grouped by filename; + * similar messages should be in a single file. For example, an MCA + * component may install its own helpfile in PMIX's $pkgdatadir, + * and therefore the component can invoke pmix_show_help() to display + * its own help messages. + * + * Message files in $pkgdatadir have a naming convention: they + * generally start with the prefix "help-" and are followed by a name + * descriptive of what kind of messages they contain. MCA components + * should generally abide by the MCA prefix rule, with the exception + * that they should start the filename with "help-", as mentioned + * previously. + */ + +#ifndef PMIX_SHOW_HELP_H +#define PMIX_SHOW_HELP_H + +#include + +#include + +BEGIN_C_DECLS + +/** + * \internal + * + * Initialization of show_help subsystem + */ +int pmix_show_help_init(void); + + +/** + * \internal + * + * Finalization of show_help subsystem + */ +int pmix_show_help_finalize(void); + + +/** + * Look up a text message in a text file and display it to the + * stderr using printf()-like substitutions (%d, %s, etc.). + * + * @param filename File where the text messages are contained. + * @param topic String index of which message to display from the + * text file. + * @param want_error_header Display error-bar line header and + * footer with the message. + * @param varargs Any additional parameters are substituted, + * printf()-style into the help message that is displayed. + * + * This function looks for the filename in the $pkgdatadir + * (typically $prefix/share/pmix), and looks up the message + * based on the topic, and displays it. If want_error_header is + * true, a header and footer of asterisks are also displayed. + */ +typedef int (*pmix_show_help_fn_t)(const char *filename, const char *topic, + bool want_error_header, ...); +extern pmix_show_help_fn_t pmix_show_help; + +/** + * This function does the same thing as pmix_show_help(), but accepts + * a va_list form of varargs. + */ +typedef int (*pmix_show_vhelp_fn_t)(const char *filename, const char *topic, + bool want_error_header, va_list ap); +extern pmix_show_vhelp_fn_t pmix_show_vhelp; + +/** + * This function does the same thing as pmix_show_help(), but returns + * its output in a string (that must be freed by the caller). + */ +char* pmix_show_help_string(const char *filename, + const char *topic, + bool want_error_header, ...); + +/** + * This function does the same thing as pmix_show_help_string(), but + * accepts a va_list form of varargs. + */ +char* pmix_show_help_vstring(const char *filename, + const char *topic, + bool want_error_header, va_list ap); + +/** + * This function adds another search location for the files that + * back show_help messages. Locations will be searched starting + * with the prefix installation directory, then cycled through + * any additional directories in the order they were added + * + * This interface allows libraries that use OMPI to take advantage + * of the show_help functionality. OMPI defines the show_help directory + * based on where OMPI was installed. However, if the library wants to + * use show_help to provide error output specific to itself, then it + * nees to tell show_help how to find its own show_help files - without + * interfering with the linked ORTE libs when they need to do show_help. + */ +int pmix_show_help_add_dir(const char *directory); + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.c b/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.c new file mode 100644 index 0000000000..d066e98437 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.c @@ -0,0 +1,1863 @@ + +#line 3 "util/show_help_lex.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer pmix_show_help_yy_create_buffer +#define yy_delete_buffer pmix_show_help_yy_delete_buffer +#define yy_flex_debug pmix_show_help_yy_flex_debug +#define yy_init_buffer pmix_show_help_yy_init_buffer +#define yy_flush_buffer pmix_show_help_yy_flush_buffer +#define yy_load_buffer_state pmix_show_help_yy_load_buffer_state +#define yy_switch_to_buffer pmix_show_help_yy_switch_to_buffer +#define yyin pmix_show_help_yyin +#define yyleng pmix_show_help_yyleng +#define yylex pmix_show_help_yylex +#define yylineno pmix_show_help_yylineno +#define yyout pmix_show_help_yyout +#define yyrestart pmix_show_help_yyrestart +#define yytext pmix_show_help_yytext +#define yywrap pmix_show_help_yywrap +#define yyalloc pmix_show_help_yyalloc +#define yyrealloc pmix_show_help_yyrealloc +#define yyfree pmix_show_help_yyfree + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE pmix_show_help_yyrestart(pmix_show_help_yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t pmix_show_help_yyleng; + +extern FILE *pmix_show_help_yyin, *pmix_show_help_yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up pmix_show_help_yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up pmix_show_help_yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via pmix_show_help_yyrestart()), so that the user can continue scanning by + * just pointing pmix_show_help_yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when pmix_show_help_yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t pmix_show_help_yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow pmix_show_help_yywrap()'s to do buffer switches + * instead of setting up a fresh pmix_show_help_yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void pmix_show_help_yyrestart (FILE *input_file ); +void pmix_show_help_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE pmix_show_help_yy_create_buffer (FILE *file,int size ); +void pmix_show_help_yy_delete_buffer (YY_BUFFER_STATE b ); +void pmix_show_help_yy_flush_buffer (YY_BUFFER_STATE b ); +void pmix_show_help_yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void pmix_show_help_yypop_buffer_state (void ); + +static void pmix_show_help_yyensure_buffer_stack (void ); +static void pmix_show_help_yy_load_buffer_state (void ); +static void pmix_show_help_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER pmix_show_help_yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE pmix_show_help_yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE pmix_show_help_yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE pmix_show_help_yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *pmix_show_help_yyalloc (yy_size_t ); +void *pmix_show_help_yyrealloc (void *,yy_size_t ); +void pmix_show_help_yyfree (void * ); + +#define yy_new_buffer pmix_show_help_yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + pmix_show_help_yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + pmix_show_help_yy_create_buffer(pmix_show_help_yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + pmix_show_help_yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + pmix_show_help_yy_create_buffer(pmix_show_help_yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *pmix_show_help_yyin = (FILE *) 0, *pmix_show_help_yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int pmix_show_help_yylineno; + +int pmix_show_help_yylineno = 1; + +extern char *pmix_show_help_yytext; +#define yytext_ptr pmix_show_help_yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up pmix_show_help_yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + pmix_show_help_yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 5 +#define YY_END_OF_BUFFER 6 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_acclist[17] = + { 0, + 6, 5, 4, 5, 5, 5, 5, 3, 5, 4, + 1, 4, 3,16386, 8194, 4 + } ; + +static yyconst flex_int16_t yy_accept[24] = + { 0, + 1, 1, 1, 1, 1, 2, 3, 5, 6, 7, + 8, 10, 10, 11, 11, 13, 13, 13, 14, 15, + 15, 17, 17 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 5, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[6] = + { 0, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[30] = + { 0, + 0, 3, 28, 27, 28, 25, 31, 24, 23, 22, + 31, 21, 31, 20, 31, 7, 19, 31, 11, 15, + 31, 31, 18, 17, 14, 13, 10, 9, 0 + } ; + +static yyconst flex_int16_t yy_def[30] = + { 0, + 23, 22, 24, 24, 22, 25, 22, 26, 27, 28, + 22, 25, 22, 26, 22, 27, 28, 22, 29, 29, + 22, 0, 22, 22, 22, 22, 22, 22, 22 + } ; + +static yyconst flex_int16_t yy_nxt[37] = + { 0, + 20, 7, 8, 6, 7, 8, 9, 6, 13, 17, + 16, 19, 21, 14, 12, 19, 21, 10, 6, 19, + 18, 15, 13, 18, 13, 15, 13, 22, 11, 11, + 5, 22, 22, 22, 22, 22 + } ; + +static yyconst flex_int16_t yy_chk[37] = + { 0, + 29, 1, 1, 2, 2, 2, 2, 2, 16, 28, + 27, 16, 19, 26, 25, 19, 20, 24, 23, 20, + 17, 14, 12, 10, 9, 8, 6, 5, 4, 3, + 22, 22, 22, 22, 22, 22 + } ; + +extern int pmix_show_help_yy_flex_debug; +int pmix_show_help_yy_flex_debug = 0; + +static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; +static char *yy_full_match; +static int yy_lp; +static int yy_looking_for_trail_begin = 0; +static int yy_full_lp; +static int *yy_full_state; +#define YY_TRAILING_MASK 0x2000 +#define YY_TRAILING_HEAD_MASK 0x4000 +#define REJECT \ +{ \ +*yy_cp = (yy_hold_char); /* undo effects of setting up pmix_show_help_yytext */ \ +yy_cp = (yy_full_match); /* restore poss. backed-over text */ \ +(yy_lp) = (yy_full_lp); /* restore orig. accepting pos. */ \ +(yy_state_ptr) = (yy_full_state); /* restore orig. state */ \ +yy_current_state = *(yy_state_ptr); /* restore curr. state */ \ +++(yy_lp); \ +goto find_rule; \ +} + +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *pmix_show_help_yytext; +#line 1 "util/show_help_lex.l" +#define YY_NO_INPUT 1 +#line 5 "util/show_help_lex.l" +/* + * 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) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/util/show_help_lex.h" + +BEGIN_C_DECLS + +/* + * public functions + */ +extern int pmix_show_help_finish_parsing(void); + +/* + * local functions + */ +static int pmix_show_help_yywrap(void); + +END_C_DECLS + +/* + * global variables + */ +int pmix_show_help_yynewlines = 1; +bool pmix_show_help_parse_done = false; + + +#line 550 "util/show_help_lex.c" + +#define INITIAL 0 +#define CHOMP 1 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int pmix_show_help_yylex_destroy (void ); + +int pmix_show_help_yyget_debug (void ); + +void pmix_show_help_yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE pmix_show_help_yyget_extra (void ); + +void pmix_show_help_yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *pmix_show_help_yyget_in (void ); + +void pmix_show_help_yyset_in (FILE * in_str ); + +FILE *pmix_show_help_yyget_out (void ); + +void pmix_show_help_yyset_out (FILE * out_str ); + +yy_size_t pmix_show_help_yyget_leng (void ); + +char *pmix_show_help_yyget_text (void ); + +int pmix_show_help_yyget_lineno (void ); + +void pmix_show_help_yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int pmix_show_help_yywrap (void ); +#else +extern int pmix_show_help_yywrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( pmix_show_help_yytext, pmix_show_help_yyleng, 1, pmix_show_help_yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( pmix_show_help_yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( pmix_show_help_yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, pmix_show_help_yyin))==0 && ferror(pmix_show_help_yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(pmix_show_help_yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int pmix_show_help_yylex (void); + +#define YY_DECL int pmix_show_help_yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after pmix_show_help_yytext and pmix_show_help_yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + if ( pmix_show_help_yyleng > 0 ) \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ + (pmix_show_help_yytext[pmix_show_help_yyleng - 1] == '\n'); \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 60 "util/show_help_lex.l" + + +#line 737 "util/show_help_lex.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + /* Create the reject buffer large enough to save one state per allowed character. */ + if ( ! (yy_state_buf) ) + (yy_state_buf) = (yy_state_type *)pmix_show_help_yyalloc(YY_STATE_BUF_SIZE ); + if ( ! (yy_state_buf) ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_show_help_yylex()" ); + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! pmix_show_help_yyin ) + pmix_show_help_yyin = stdin; + + if ( ! pmix_show_help_yyout ) + pmix_show_help_yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + pmix_show_help_yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + pmix_show_help_yy_create_buffer(pmix_show_help_yyin,YY_BUF_SIZE ); + } + + pmix_show_help_yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of pmix_show_help_yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 23 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *(yy_state_ptr)++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 31 ); + +yy_find_action: + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; +find_rule: /* we branch to this label when backing up */ + for ( ; ; ) /* until we find what rule we matched */ + { + if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[(yy_lp)]; + if ( yy_act & YY_TRAILING_HEAD_MASK || + (yy_looking_for_trail_begin) ) + { + if ( yy_act == (yy_looking_for_trail_begin) ) + { + (yy_looking_for_trail_begin) = 0; + yy_act &= ~YY_TRAILING_HEAD_MASK; + break; + } + } + else if ( yy_act & YY_TRAILING_MASK ) + { + (yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK; + (yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK; + } + else + { + (yy_full_match) = yy_cp; + (yy_full_state) = (yy_state_ptr); + (yy_full_lp) = (yy_lp); + break; + } + ++(yy_lp); + goto find_rule; + } + --yy_cp; + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 62 "util/show_help_lex.l" +; /* comment line */ + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 64 "util/show_help_lex.l" +{ BEGIN(CHOMP); return PMIX_SHOW_HELP_PARSE_TOPIC; } + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 66 "util/show_help_lex.l" +{ BEGIN(INITIAL); } + YY_BREAK +case 4: +/* rule 4 can match eol */ +*yy_cp = (yy_hold_char); /* undo effects of setting up pmix_show_help_yytext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up pmix_show_help_yytext again */ +YY_RULE_SETUP +#line 68 "util/show_help_lex.l" +{ BEGIN(CHOMP); return PMIX_SHOW_HELP_PARSE_MESSAGE; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 70 "util/show_help_lex.l" +ECHO; + YY_BREAK +#line 882 "util/show_help_lex.c" + case YY_STATE_EOF(INITIAL): + case YY_STATE_EOF(CHOMP): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed pmix_show_help_yyin at a new source and called + * pmix_show_help_yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = pmix_show_help_yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( pmix_show_help_yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * pmix_show_help_yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of pmix_show_help_yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + pmix_show_help_yyrestart(pmix_show_help_yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pmix_show_help_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 23 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *(yy_state_ptr)++ = yy_current_state; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + + register YY_CHAR yy_c = 1; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 23 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 22); + if ( ! yy_is_jam ) + *(yy_state_ptr)++ = yy_current_state; + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + pmix_show_help_yyrestart(pmix_show_help_yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( pmix_show_help_yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve pmix_show_help_yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void pmix_show_help_yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + pmix_show_help_yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + pmix_show_help_yy_create_buffer(pmix_show_help_yyin,YY_BUF_SIZE ); + } + + pmix_show_help_yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + pmix_show_help_yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void pmix_show_help_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * pmix_show_help_yypop_buffer_state(); + * pmix_show_help_yypush_buffer_state(new_buffer); + */ + pmix_show_help_yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + pmix_show_help_yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (pmix_show_help_yywrap()) processing, but the only time this flag + * is looked at is after pmix_show_help_yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void pmix_show_help_yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + pmix_show_help_yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE pmix_show_help_yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) pmix_show_help_yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_show_help_yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) pmix_show_help_yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_show_help_yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + pmix_show_help_yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with pmix_show_help_yy_create_buffer() + * + */ + void pmix_show_help_yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + pmix_show_help_yyfree((void *) b->yy_ch_buf ); + + pmix_show_help_yyfree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a pmix_show_help_yyrestart() or at EOF. + */ + static void pmix_show_help_yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + pmix_show_help_yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then pmix_show_help_yy_init_buffer was _probably_ + * called from pmix_show_help_yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void pmix_show_help_yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + pmix_show_help_yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void pmix_show_help_yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + pmix_show_help_yyensure_buffer_stack(); + + /* This block is copied from pmix_show_help_yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from pmix_show_help_yy_switch_to_buffer. */ + pmix_show_help_yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void pmix_show_help_yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + pmix_show_help_yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + pmix_show_help_yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void pmix_show_help_yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)pmix_show_help_yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_show_help_yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)pmix_show_help_yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_show_help_yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE pmix_show_help_yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) pmix_show_help_yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_show_help_yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + pmix_show_help_yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to pmix_show_help_yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * pmix_show_help_yy_scan_bytes() instead. + */ +YY_BUFFER_STATE pmix_show_help_yy_scan_string (yyconst char * yystr ) +{ + + return pmix_show_help_yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to pmix_show_help_yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE pmix_show_help_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) pmix_show_help_yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in pmix_show_help_yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = pmix_show_help_yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in pmix_show_help_yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up pmix_show_help_yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + pmix_show_help_yytext[pmix_show_help_yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = pmix_show_help_yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + pmix_show_help_yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int pmix_show_help_yyget_lineno (void) +{ + + return pmix_show_help_yylineno; +} + +/** Get the input stream. + * + */ +FILE *pmix_show_help_yyget_in (void) +{ + return pmix_show_help_yyin; +} + +/** Get the output stream. + * + */ +FILE *pmix_show_help_yyget_out (void) +{ + return pmix_show_help_yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t pmix_show_help_yyget_leng (void) +{ + return pmix_show_help_yyleng; +} + +/** Get the current token. + * + */ + +char *pmix_show_help_yyget_text (void) +{ + return pmix_show_help_yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void pmix_show_help_yyset_lineno (int line_number ) +{ + + pmix_show_help_yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see pmix_show_help_yy_switch_to_buffer + */ +void pmix_show_help_yyset_in (FILE * in_str ) +{ + pmix_show_help_yyin = in_str ; +} + +void pmix_show_help_yyset_out (FILE * out_str ) +{ + pmix_show_help_yyout = out_str ; +} + +int pmix_show_help_yyget_debug (void) +{ + return pmix_show_help_yy_flex_debug; +} + +void pmix_show_help_yyset_debug (int bdebug ) +{ + pmix_show_help_yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from pmix_show_help_yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + + (yy_state_buf) = 0; + (yy_state_ptr) = 0; + (yy_full_match) = 0; + (yy_lp) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + pmix_show_help_yyin = stdin; + pmix_show_help_yyout = stdout; +#else + pmix_show_help_yyin = (FILE *) 0; + pmix_show_help_yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * pmix_show_help_yylex_init() + */ + return 0; +} + +/* pmix_show_help_yylex_destroy is for both reentrant and non-reentrant scanners. */ +int pmix_show_help_yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + pmix_show_help_yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + pmix_show_help_yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + pmix_show_help_yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + pmix_show_help_yyfree ( (yy_state_buf) ); + (yy_state_buf) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * pmix_show_help_yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *pmix_show_help_yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *pmix_show_help_yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void pmix_show_help_yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see pmix_show_help_yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 70 "util/show_help_lex.l" + + + +/* Old flex (2.5.4a? and older) does not define a destroy function */ +#if !defined(YY_FLEX_SUBMINOR_VERSION) +#define YY_FLEX_SUBMINOR_VERSION 0 +#endif + +#if (YY_FLEX_MAJOR_VERSION < 2) || (YY_FLEX_MAJOR_VERSION == 2 && (YY_FLEX_MINOR_VERSION < 5 || (YY_FLEX_MINOR_VERSION == 5 && YY_FLEX_SUBMINOR_VERSION < 5))) +int pmix_show_help_yylex_destroy(void) +{ + if (NULL != YY_CURRENT_BUFFER) { + pmix_show_help_yy_delete_buffer(YY_CURRENT_BUFFER); +#if defined(YY_CURRENT_BUFFER_LVALUE) + YY_CURRENT_BUFFER_LVALUE = NULL; +#else + YY_CURRENT_BUFFER = NULL; +#endif /* YY_CURRENT_BUFFER_LVALUE */ + } + return YY_NULL; +} +#endif + +static int pmix_show_help_yywrap(void) +{ + pmix_show_help_parse_done = true; + return 1; +} + + +/* + * Ensure that we have a valid yybuffer to use. Specifically, if this + * scanner is invoked a second time, finish_parsing() (above) will + * have been executed, and the current buffer will have been freed. + * Flex doesn't recognize this fact because as far as it's concerned, + * its internal state was already initialized, so it thinks it should + * have a valid buffer. Hence, here we ensure to give it a valid + * buffer. + */ +int pmix_show_help_init_buffer(FILE *file) +{ + YY_BUFFER_STATE buf = pmix_show_help_yy_create_buffer(file,YY_BUF_SIZE); + pmix_show_help_yy_switch_to_buffer(buf); + + return 0; +} + 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 new file mode 100644 index 0000000000..a507e4ddd8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.h @@ -0,0 +1,67 @@ +/* + * 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) 2006 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SHOW_HELP_LEX_H +#define PMIX_SHOW_HELP_LEX_H + +#include + +#ifdef malloc +#undef malloc +#endif +#ifdef realloc +#undef realloc +#endif +#ifdef free +#undef free +#endif + +#include +BEGIN_C_DECLS +int pmix_show_help_yylex(void); +int pmix_show_help_init_buffer(FILE *file); +int pmix_show_help_yylex_destroy(void); + +extern FILE *pmix_show_help_yyin; +extern bool pmix_show_help_parse_done; +extern char *pmix_show_help_yytext; +extern int pmix_show_help_yynewlines; + +/* + * Make lex-generated files not issue compiler warnings + */ +#define YY_STACK_USED 0 +#define YY_ALWAYS_INTERACTIVE 0 +#define YY_NEVER_INTERACTIVE 0 +#define YY_MAIN 0 +#define YY_NO_UNPUT 1 +#define YY_SKIP_YYWRAP 1 + +enum { + PMIX_SHOW_HELP_PARSE_DONE, + PMIX_SHOW_HELP_PARSE_ERROR, + + PMIX_SHOW_HELP_PARSE_TOPIC, + PMIX_SHOW_HELP_PARSE_MESSAGE, + + PMIX_SHOW_HELP_PARSE_MAX +}; +END_C_DECLS +#endif 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 new file mode 100644 index 0000000000..d48130f0d8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/util/show_help_lex.l @@ -0,0 +1,114 @@ +%option nounput +%option noinput + +%{ /* -*- 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) 2016 Intel, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "src/util/show_help_lex.h" + +BEGIN_C_DECLS + +/* + * public functions + */ +extern int pmix_show_help_finish_parsing(void); + +/* + * local functions + */ +static int pmix_show_help_yywrap(void); + +END_C_DECLS + +/* + * global variables + */ +int pmix_show_help_yynewlines = 1; +bool pmix_show_help_parse_done = false; + +%} + +WHITE [\f\t\v ] +CHAR [A-Za-z0-9_\-\.] + +%x CHOMP + +%% + +#.*\n ; /* comment line */ + +^\[.+\]/[^\]\n]*\n { BEGIN(CHOMP); return PMIX_SHOW_HELP_PARSE_TOPIC; } + +.*\n { BEGIN(INITIAL); } + +.*/\n { BEGIN(CHOMP); return PMIX_SHOW_HELP_PARSE_MESSAGE; } + +%% + +/* Old flex (2.5.4a? and older) does not define a destroy function */ +#if !defined(YY_FLEX_SUBMINOR_VERSION) +#define YY_FLEX_SUBMINOR_VERSION 0 +#endif + +#if (YY_FLEX_MAJOR_VERSION < 2) || (YY_FLEX_MAJOR_VERSION == 2 && (YY_FLEX_MINOR_VERSION < 5 || (YY_FLEX_MINOR_VERSION == 5 && YY_FLEX_SUBMINOR_VERSION < 5))) +int pmix_show_help_yylex_destroy(void) +{ + if (NULL != YY_CURRENT_BUFFER) { + yy_delete_buffer(YY_CURRENT_BUFFER); +#if defined(YY_CURRENT_BUFFER_LVALUE) + YY_CURRENT_BUFFER_LVALUE = NULL; +#else + YY_CURRENT_BUFFER = NULL; +#endif /* YY_CURRENT_BUFFER_LVALUE */ + } + return YY_NULL; +} +#endif + +static int pmix_show_help_yywrap(void) +{ + pmix_show_help_parse_done = true; + return 1; +} + + +/* + * Ensure that we have a valid yybuffer to use. Specifically, if this + * scanner is invoked a second time, finish_parsing() (above) will + * have been executed, and the current buffer will have been freed. + * Flex doesn't recognize this fact because as far as it's concerned, + * its internal state was already initialized, so it thinks it should + * have a valid buffer. Hence, here we ensure to give it a valid + * buffer. + */ +int pmix_show_help_init_buffer(FILE *file) +{ + YY_BUFFER_STATE buf = yy_create_buffer(file, YY_BUF_SIZE); + yy_switch_to_buffer(buf); + + return 0; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/util/timings.c b/opal/mca/pmix/pmix2x/pmix/src/util/timings.c index 7c81b66492..10779bbe76 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-2015 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -10,7 +10,7 @@ #include -#include +#include #include #include diff --git a/opal/mca/pmix/pmix2x/pmix/test/Makefile.am b/opal/mca/pmix/pmix2x/pmix/test/Makefile.am index 9dbd63eede..852e0821dd 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/test/Makefile.am @@ -39,30 +39,30 @@ pmix_test_SOURCES = $(headers) \ pmix_test.c test_common.c cli_stages.c server_callbacks.c utils.c pmix_test_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) pmix_test_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la pmi_client_SOURCES = $(headers) \ pmi_client.c pmi_client_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) pmi_client_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la pmi2_client_SOURCES = $(headers) \ pmi2_client.c pmi2_client_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) pmi2_client_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la pmix_client_SOURCES = $(headers) \ pmix_client.c test_fence.c test_common.c test_publish.c test_spawn.c test_cd.c test_resolve_peers.c test_error.c pmix_client_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) pmix_client_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la pmix_regex_SOURCES = $(headers) \ pmix_regex.c test_common.c cli_stages.c utils.c pmix_regex_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) pmix_regex_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la EXTRA_DIST = $(noinst_SCRIPTS) diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/Makefile.am b/opal/mca/pmix/pmix2x/pmix/test/simple/Makefile.am index 602f58bff8..8c1dfbffaf 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/Makefile.am @@ -27,46 +27,46 @@ simptest_SOURCES = \ simptest.c simptest_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) simptest_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la simpclient_SOURCES = \ simpclient.c simpclient_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) simpclient_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la simppub_SOURCES = \ simppub.c simppub_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) simppub_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la simpdmodex_SOURCES = \ simpdmodex.c simpdmodex_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) simpdmodex_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la simpft_SOURCES = \ simpft.c simpft_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) simpft_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la simpdyn_SOURCES = \ simpdyn.c simpdyn_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) simpdyn_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la test_pmix_SOURCES = \ test_pmix.c test_pmix_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) test_pmix_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la simptool_SOURCES = \ simptool.c simptool_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) simptool_LDADD = \ - $(top_builddir)/libpmix.la + $(top_builddir)/src/libpmix.la diff --git a/opal/mca/pmix/pmix2x/pmix/test/test_common.c b/opal/mca/pmix/pmix2x/pmix/test/test_common.c index 83197ec234..ae053569e7 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/test_common.c +++ b/opal/mca/pmix/pmix2x/pmix/test/test_common.c @@ -13,7 +13,7 @@ */ #include -#include +#include #include "test_common.h" #include diff --git a/opal/mca/pmix/pmix2x/pmix/test/test_common.h b/opal/mca/pmix/pmix2x/pmix/test/test_common.h index 29ff8a0c46..e54e75c050 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/test_common.h +++ b/opal/mca/pmix/pmix2x/pmix/test/test_common.h @@ -18,7 +18,7 @@ #define TEST_COMMON_H #include -#include +#include #include #include diff --git a/opal/mca/pmix/pmix2x/pmix2x.c b/opal/mca/pmix/pmix2x/pmix2x.c index bdc5d33b33..c4cc6315a9 100644 --- a/opal/mca/pmix/pmix2x/pmix2x.c +++ b/opal/mca/pmix/pmix2x/pmix2x.c @@ -39,7 +39,7 @@ #include "opal/mca/pmix/base/base.h" #include "opal/mca/pmix/pmix_types.h" -#include +#include /**** C.O.M.M.O.N I.N.T.E.R.F.A.C.E.S ****/ diff --git a/opal/mca/pmix/pmix2x/pmix2x.h b/opal/mca/pmix/pmix2x/pmix2x.h index 51519cba7d..c93aa9d4a0 100644 --- a/opal/mca/pmix/pmix2x/pmix2x.h +++ b/opal/mca/pmix/pmix2x/pmix2x.h @@ -30,7 +30,7 @@ #include "opal/mca/pmix/pmix.h" #include "pmix_server.h" -#include "pmix/pmix_common.h" +#include "pmix_common.h" BEGIN_C_DECLS From 73544d2e00fc4750f9f34f359b319a04356e6265 Mon Sep 17 00:00:00 2001 From: Ralph Castain Date: Thu, 11 Aug 2016 13:06:46 -0700 Subject: [PATCH 2/2] Rename symbol --- opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c index 413c38999b..4e0b568b1f 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/base/pmix_mca_base_var.c @@ -103,7 +103,7 @@ const size_t pmix_var_type_sizes[] = { sizeof (double) }; -const char *var_source_names[] = { +const char *pmix_var_source_names[] = { "default", "command line", "environment", @@ -1921,7 +1921,7 @@ static char *source_name(pmix_mca_base_var_t *var) return strdup ("unknown(!!)"); } - return strdup (var_source_names[var->mbv_source]); + return strdup (pmix_var_source_names[var->mbv_source]); } static int var_value_string (pmix_mca_base_var_t *var, char **value_string)