Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UCS/TEST: Remove entry from configuration list when library is unloaded - v1.6.x #3671

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Bugfixes:
- RPM Spec file cleanup
- Fixing compilation issues with most recent clang and gcc compilers
- Fixing the wrong name of aliases
- Fix segfault when libuct.so is reloaded - issue #3558

Tested configurations:
- RDMA: MLNX_OFED 4.5, distribution inbox drivers, rdma-core 22.1
Expand Down
4 changes: 4 additions & 0 deletions contrib/test_jenkins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,10 @@ test_ucs_dlopen() {
# Make sure UCM is not unloaded
echo "==== Running UCS dlopen test with memhooks ===="
./test/apps/test_ucs_dlopen

# Test global config list integrity after loading/unloading of UCT
echo "==== Running test_dlopen_cfg_print ===="
./test/apps/test_dlopen_cfg_print
}

test_ucp_dlopen() {
Expand Down
17 changes: 11 additions & 6 deletions src/ucs/config/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,19 @@ typedef struct ucs_config_bw_spec {


#define UCS_CONFIG_REGISTER_TABLE(_fields, _name, _prefix, _type) \
static ucs_config_global_list_entry_t _fields##_config_entry; \
UCS_STATIC_INIT { \
ucs_config_global_list_entry_t *entry = &_fields##_config_entry; \
extern ucs_list_link_t ucs_config_global_list; \
static ucs_config_global_list_entry_t entry; \
entry.fields = _fields; \
entry.name = _name; \
entry.prefix = _prefix; \
entry.size = sizeof(_type); \
ucs_list_add_tail(&ucs_config_global_list, &entry.list); \
entry->fields = _fields; \
entry->name = _name; \
entry->prefix = _prefix; \
entry->size = sizeof(_type); \
ucs_list_add_tail(&ucs_config_global_list, &entry->list); \
} \
\
UCS_STATIC_CLEANUP { \
ucs_list_del(&_fields##_config_entry.list); \
}


Expand Down
10 changes: 9 additions & 1 deletion test/apps/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ endif
noinst_PROGRAMS = \
test_ucp_dlopen \
test_ucs_dlopen \
test_link_map
test_link_map \
test_dlopen_cfg_print

objdir = $(shell sed -n -e 's/^objdir=\(.*\)$$/\1/p' $(LIBTOOL))

Expand All @@ -34,6 +35,13 @@ test_link_map_CPPFLAGS = $(BASE_CPPFLAGS)
test_link_map_CFLAGS = $(BASE_CFLAGS)
test_link_map_LDADD = -ldl $(top_builddir)/src/ucp/libucp.la

test_dlopen_cfg_print_SOURCES = test_dlopen_cfg_print.c
test_dlopen_cfg_print_CPPFLAGS = $(BASE_CPPFLAGS) -g \
-DUCS_LIB_PATH=$(abs_top_builddir)/src/ucs/$(objdir)/libucs.so \
-DUCT_LIB_PATH=$(abs_top_builddir)/src/uct/$(objdir)/libuct.so
test_dlopen_cfg_print_CFLAGS = $(BASE_CFLAGS)
test_dlopen_cfg_print_LDADD = -ldl

if HAVE_TCMALLOC
noinst_PROGRAMS += test_tcmalloc
test_tcmalloc_SOURCES = test_tcmalloc.c
Expand Down
54 changes: 54 additions & 0 deletions test/apps/test_dlopen_cfg_print.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright (C) Mellanox Technologies Ltd. 2019. ALL RIGHTS RESERVED.
*
* See file LICENSE for terms.
*/

#include <stdlib.h>
#include <dlfcn.h>
#include <stdio.h>

#define _QUOTE(x) #x
#define QUOTE(x) _QUOTE(x)


static void* do_dlopen_or_exit(const char *filename)
{
void *handle;

(void)dlerror();
printf("opening '%s'\n", filename);
handle = dlopen(filename, RTLD_LAZY);
if (handle == NULL) {
fprintf(stderr, "failed to open %s: %s\n", filename,
dlerror());
exit(1);
}

return handle;
}

int main(int argc, char **argv)
{
const char *ucs_filename = QUOTE(UCS_LIB_PATH);
const char *uct_filename = QUOTE(UCT_LIB_PATH);
void *ucs_handle, *uct_handle;
int i;

/* unload and reload uct while ucs is loaded
* would fail if uct global vars are kept on global lists in ucs */
ucs_handle = do_dlopen_or_exit(ucs_filename);
for (i = 0; i < 2; ++i) {
uct_handle = do_dlopen_or_exit(uct_filename);
dlclose(uct_handle);
}

/* print all config table, to force going over the global list in ucs */
void (*print_all_opts)(FILE*, int) =
dlsym(ucs_handle, "ucs_config_parser_print_all_opts");
print_all_opts(stdout, 0);
dlclose(ucs_handle);

printf("done\n");
return 0;
}