diff --git a/ci/test_files_to_stash.txt b/ci/test_files_to_stash.txt index a0b2ce45386..9c161e66530 100755 --- a/ci/test_files_to_stash.txt +++ b/ci/test_files_to_stash.txt @@ -5,6 +5,7 @@ build/*/*/src/tests/ftest/cart/utest/utest_swim, build/*/*/src/gurt/tests/test_gurt, build/*/*/src/gurt/tests/test_gurt_telem_producer, build/*/*/src/gurt/tests/test_gurt_telem_consumer, +build/*/*/src/gurt/tests/test_shm, build/*/*/src/rdb/raft/src/tests_main, build/*/*/src/common/tests/btree_direct, build/*/*/src/common/tests/btree, diff --git a/debian/daos-client-tests.install b/debian/daos-client-tests.install index 67da4debbe9..b1c31a4ea5c 100644 --- a/debian/daos-client-tests.install +++ b/debian/daos-client-tests.install @@ -16,7 +16,6 @@ usr/bin/daos_perf usr/bin/daos_racer usr/bin/daos_test usr/bin/dfs_test -usr/bin/shm_test usr/bin/jobtest usr/bin/crt_launch usr/bin/daos_gen_io_conf diff --git a/src/gurt/shm_alloc.c b/src/gurt/shm_alloc.c index 8b0fafa0ec4..69291139058 100644 --- a/src/gurt/shm_alloc.c +++ b/src/gurt/shm_alloc.c @@ -1,5 +1,5 @@ /** - * (C) Copyright 2024 Intel Corporation. + * (C) Copyright 2024-2025 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -44,6 +44,82 @@ pthread_mutexattr_t d_shm_mutex_attr; */ static int pid_shm_creator; +static uint64_t page_size; + +static int +create_shm_region(uint64_t shm_size, uint64_t shm_pool_size) +{ + int i; + int shm_ht_fd; + int shmopen_perm = 0600; + void *shm_addr; + char daos_shm_name_buf[64]; + + /* the shared memory only accessible for individual user for now */ + sprintf(daos_shm_name_buf, "%s_%d", daos_shm_name, getuid()); + shm_ht_fd = shm_open(daos_shm_name_buf, O_RDWR | O_CREAT | O_EXCL, shmopen_perm); + /* failed to create */ + if (shm_ht_fd == -1) { + if (errno == EEXIST) + return errno; + DS_ERROR(errno, "shm_open() failed to create shared memory"); + return errno; + } + /* set the size of shared memory region */ + if (ftruncate(shm_ht_fd, shm_size) != 0) { + DS_ERROR(errno, "ftruncate() failed for shm_ht_fd"); + goto err; + } + /* map the shared memory at a fixed address for now. We will remove this limit later. */ + shm_addr = mmap(FIXED_SHM_ADDR, shm_size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, shm_ht_fd, 0); + if (shm_addr != FIXED_SHM_ADDR) { + DS_ERROR(errno, "mmap() failed to map at desired address"); + goto err; + } + d_shm_head = (struct d_shm_hdr *)shm_addr; + d_shm_head->magic = 0; + /* initialize memory allocators */ + for (i = 0; i < N_SHM_POOL; i++) { + d_shm_head->tlsf[i] = tlsf_create_with_pool( + shm_addr + sizeof(struct d_shm_hdr) + (i * shm_pool_size), shm_pool_size); + } + + if (shm_mutex_init(&(d_shm_head->g_lock)) != 0) { + DS_ERROR(errno, "shm_mutex_init() failed"); + goto err_unmap; + } + for (i = 0; i < N_SHM_POOL; i++) { + if (shm_mutex_init(&(d_shm_head->mem_lock[i])) != 0) { + DS_ERROR(errno, "shm_mutex_init() failed"); + goto err_unmap; + } + } + if (shm_mutex_init(&(d_shm_head->ht_lock)) != 0) { + DS_ERROR(errno, "shm_mutex_init() failed"); + goto err_unmap; + } + + pid_shm_creator = pid; + d_shm_head->off_ht_head = INVALID_OFFSET; + + atomic_store_relaxed(&(d_shm_head->ref_count), 1); + atomic_store_relaxed(&(d_shm_head->large_mem_count), 0); + d_shm_head->size = shm_size; + d_shm_head->shm_pool_size = shm_pool_size; + d_shm_head->magic = DSM_MAGIC; + /* initialization is finished now. */ + return 0; + +err_unmap: + d_shm_head = NULL; + munmap(shm_addr, shm_size); + +err: + close(shm_ht_fd); + return errno; +} + int shm_init(void) { @@ -56,6 +132,8 @@ shm_init(void) uint64_t shm_size; uint64_t shm_pool_size; + if (page_size == 0) + page_size = sysconf(_SC_PAGESIZE); if (pid == 0) pid = getpid(); if (d_shm_head) { @@ -69,9 +147,9 @@ shm_init(void) if (rc != -DER_NONEXIST) { /* set parameter from env */ shm_pool_size = shm_size / N_SHM_POOL; - if (shm_pool_size % 4096) + if (shm_pool_size % page_size) /* make shm_pool_size 4K aligned */ - shm_pool_size += (4096 - (shm_pool_size % 4096)); + shm_pool_size += (page_size - (shm_pool_size % page_size)); shm_size = shm_pool_size * N_SHM_POOL + sizeof(struct d_shm_hdr); } else { shm_pool_size = SHM_POOL_SIZE; @@ -94,7 +172,11 @@ shm_init(void) /* failed to open */ if (shm_ht_fd == -1) { if (errno == ENOENT) { - goto create_shm; + rc = create_shm_region(shm_size, shm_pool_size); + if (rc == EEXIST) + goto open_rw; + else + return rc; } else { DS_ERROR(errno, "unexpected error shm_open()"); for (i = 0; i < RETRY; i++) { @@ -133,61 +215,6 @@ shm_init(void) close(shm_ht_fd); return 0; -create_shm: - shm_ht_fd = shm_open(daos_shm_name_buf, O_RDWR | O_CREAT | O_EXCL, shmopen_perm); - /* failed to create */ - if (shm_ht_fd == -1) { - if (errno == EEXIST) - goto open_rw; - DS_ERROR(errno, "shm_open() failed to create shared memory"); - return errno; - } - /* set the size of shared memory region */ - if (ftruncate(shm_ht_fd, shm_size) != 0) { - DS_ERROR(errno, "ftruncate() failed for shm_ht_fd"); - goto err; - } - /* map the shared memory at a fixed address for now. We will remove this limit later. */ - shm_addr = mmap(FIXED_SHM_ADDR, shm_size, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_FIXED, shm_ht_fd, 0); - if (shm_addr != FIXED_SHM_ADDR) { - DS_ERROR(errno, "mmap() failed to map at desired address"); - goto err; - } - d_shm_head = (struct d_shm_hdr *)shm_addr; - d_shm_head->magic = 0; - /* initialize memory allocators */ - for (i = 0; i < N_SHM_POOL; i++) { - d_shm_head->tlsf[i] = tlsf_create_with_pool( - shm_addr + sizeof(struct d_shm_hdr) + (i * shm_pool_size), shm_pool_size); - } - - if (shm_mutex_init(&(d_shm_head->g_lock)) != 0) { - DS_ERROR(errno, "shm_mutex_init() failed"); - goto err_unmap; - } - for (i = 0; i < N_SHM_POOL; i++) { - if (shm_mutex_init(&(d_shm_head->mem_lock[i])) != 0) { - DS_ERROR(errno, "shm_mutex_init() failed"); - goto err_unmap; - } - } - if (shm_mutex_init(&(d_shm_head->ht_lock)) != 0) { - DS_ERROR(errno, "shm_mutex_init() failed"); - goto err_unmap; - } - - pid_shm_creator = pid; - d_shm_head->off_ht_head = INVALID_OFFSET; - - atomic_store_relaxed(&(d_shm_head->ref_count), 1); - atomic_store_relaxed(&(d_shm_head->large_mem_count), 0); - d_shm_head->size = shm_size; - d_shm_head->shm_pool_size = shm_pool_size; - d_shm_head->magic = DSM_MAGIC; - /* initialization is finished now. */ - return 0; - err_unmap: d_shm_head = NULL; munmap(shm_addr, shm_size); diff --git a/src/gurt/tests/SConscript b/src/gurt/tests/SConscript index 86b3cbb4fb4..783d7ce60c3 100644 --- a/src/gurt/tests/SConscript +++ b/src/gurt/tests/SConscript @@ -6,7 +6,7 @@ import os -TEST_SRC = ['test_gurt.c', 'test_gurt_telem_producer.c'] +TEST_SRC = ['test_gurt.c', 'test_gurt_telem_producer.c', 'test_shm.c'] def scons(): diff --git a/src/tests/suite/shm_test.c b/src/gurt/tests/test_shm.c similarity index 76% rename from src/tests/suite/shm_test.c rename to src/gurt/tests/test_shm.c index fd4f1050f8a..629ab13213e 100644 --- a/src/tests/suite/shm_test.c +++ b/src/gurt/tests/test_shm.c @@ -27,33 +27,15 @@ #include #include +#include #include #include #include -#include - -/* Tests can be run by specifying the appropriate argument for a test or all will be run if no test - * is specified. - */ -static const char *all_tests = "hlm"; - -static void -print_usage() -{ - print_message("\n\nShared memory tests\n=============================\n"); - print_message("Tests: Use one of these arg(s) for specific test\n"); - print_message("shm_test -a|--all\n"); - print_message("shm_test -h|--hash\n"); - print_message("shm_test -l|--lock\n"); - print_message("shm_test -m|--memory\n"); - print_message("Default runs all tests\n"); - print_message("\n=============================\n"); -} #define N_LOOP_MEM (8) void -do_mem(void **state) +test_mem(void **state) { int i; int rc; @@ -155,7 +137,7 @@ verify_hash_by_child(void) } void -do_hash(void **state) +test_hash(void **state) { int rc; int status; @@ -163,7 +145,7 @@ do_hash(void **state) struct d_shm_ht_head *ht_head; struct shm_ht_rec *link; char *value; - char *argv[3] = {"shm_test", "--verifykv", NULL}; + char *argv[3] = {"test_shm", "--verifykv", NULL}; char *exe_path; pid_t pid; @@ -189,7 +171,7 @@ do_hash(void **state) verify_hash(); - /* start a child process and run shm_test & verify key-value pairs */ + /* start a child process and run test_shm & verify key-value pairs */ exe_path = malloc(PATH_MAX); assert_non_null(exe_path); rc = readlink("/proc/self/exe", exe_path, PATH_MAX - 1); @@ -262,7 +244,7 @@ do_lock_mutex_child(bool lock_only) } void -do_lock(void **state) +test_lock(void **state) { int rc; int status; @@ -274,8 +256,8 @@ do_lock(void **state) struct timeval tm1, tm2; double dt; struct shm_ht_rec *link; - char *argv[3] = {"shm_test", "--lockmutex", NULL}; - char *argv2[3] = {"shm_test", "--lockonly", NULL}; + char *argv[3] = {"test_shm", "--lockmutex", NULL}; + char *argv2[3] = {"test_shm", "--lockonly", NULL}; char *exe_path; pid_t pid; bool owner_dead; @@ -341,64 +323,31 @@ do_lock(void **state) } static int -run_specified_tests(const char *tests, int *sub_tests, int sub_tests_size) +init_tests(void **state) { - int nr_failed = 0; - - if (strlen(tests) == 0) - tests = all_tests; - - while (*tests != '\0') { - switch (*tests) { - case 'h': - printf("\n\n================="); - printf("shm hash table tests"); - printf("=====================\n"); - const struct CMUnitTest ht_tests[] = { - cmocka_unit_test(do_hash), - }; - nr_failed += cmocka_run_group_tests(ht_tests, NULL, NULL); - break; - - case 'l': - printf("\n\n================="); - printf("shm lock/unlock tests"); - printf("=====================\n"); - const struct CMUnitTest lock_tests[] = { - cmocka_unit_test(do_lock), - }; - nr_failed += cmocka_run_group_tests(lock_tests, NULL, NULL); - break; - - case 'm': - printf("\n\n================="); - printf("shm allocation/deallocation tests"); - printf("=====================\n"); - const struct CMUnitTest mem_tests[] = { - cmocka_unit_test(do_mem), - }; - nr_failed += cmocka_run_group_tests(mem_tests, NULL, NULL); - break; - - default: - assert_true(0); - } + return d_log_init(); +} - tests++; - } +static int +fini_tests(void **state) +{ + /* unlink shared memory file under /dev/shm/ */ + shm_destroy(); + d_log_fini(); - return nr_failed; + return 0; } int main(int argc, char **argv) { - char tests[64] = {}; - int ntests = 0; - int nr_failed = 0; - int opt = 0, index = 0, rc; + int opt = 0, index = 0, rc; + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_hash), + cmocka_unit_test(test_lock), + cmocka_unit_test(test_mem)}; - static struct option long_options[] = { + static struct option long_options[] = { {"all", no_argument, NULL, 'a'}, {"hash", no_argument, NULL, 'h'}, {"lock", no_argument, NULL, 'l'}, @@ -409,15 +358,7 @@ main(int argc, char **argv) {NULL, 0, NULL, 0} }; - rc = daos_debug_init(NULL); - assert_true(rc == 0); - while ((opt = getopt_long(argc, argv, ":ahlkmov", long_options, &index)) != -1) { - if (strchr(all_tests, opt) != NULL) { - tests[ntests] = opt; - ntests++; - continue; - } switch (opt) { case 'a': break; @@ -435,26 +376,18 @@ main(int argc, char **argv) goto exit_child; default: printf("Unknown Option\n"); - print_usage(); return 1; } } - nr_failed = run_specified_tests(tests, NULL, 0); - - print_message("\n============ Summary %s\n", __FILE__); - if (nr_failed == 0) - print_message("OK - NO TEST FAILURES\n"); - else - print_message("ERROR, %i TEST(S) FAILED\n", nr_failed); + d_register_alt_assert(mock_assert); + rc = cmocka_run_group_tests_name("test_shm", tests, init_tests, fini_tests); /* unlink shared memory file under /dev/shm/ */ shm_destroy(); - daos_debug_fini(); - return nr_failed; + return rc; exit_child: - daos_debug_fini(); return 0; } diff --git a/src/tests/ftest/daos_test/shm.py b/src/tests/ftest/daos_test/shm.py deleted file mode 100644 index 640302a8df7..00000000000 --- a/src/tests/ftest/daos_test/shm.py +++ /dev/null @@ -1,44 +0,0 @@ -""" - (C) Copyright 2024 Hewlett Packard Enterprise Development LP. - - SPDX-License-Identifier: BSD-2-Clause-Patent -""" - -import os - -from apricot import TestWithServers -from cmocka_utils import CmockaUtils, get_cmocka_command -from job_manager_utils import get_job_manager - - -class DaosCoreTestShm(TestWithServers): - """Runs DAOS shared memory tests. - - :avocado: recursive - """ - - def test_daos_shm_unit(self): - """Jira ID: DAOS-16877. - - Test Description: - Run shm_test - - Use cases: - DAOS shared memory unit tests - - :avocado: tags=all,pr,daily_regression - :avocado: tags=vm - :avocado: tags=daos_test,shm_test,shm - :avocado: tags=DaosCoreTestShm,test_daos_shm_unit - """ - daos_test = os.path.join(self.bin, 'shm_test') - cmocka_utils = CmockaUtils( - self.hostlist_clients, "shm", self.outputdir, self.test_dir, self.log) - daos_test_env = cmocka_utils.get_cmocka_env() - job = get_job_manager(self, "Clush", get_cmocka_command(daos_test)) - job.assign_hosts(cmocka_utils.hosts) - job.assign_environment(daos_test_env) - - cmocka_utils.run_cmocka_test(self, job) - if not job.result.passed: - self.fail(f'Error running {job.command} on {job.hosts}') diff --git a/src/tests/ftest/daos_test/shm.yaml b/src/tests/ftest/daos_test/shm.yaml deleted file mode 100644 index 9a3caa75175..00000000000 --- a/src/tests/ftest/daos_test/shm.yaml +++ /dev/null @@ -1,20 +0,0 @@ -hosts: - test_servers: 1 -timeout: 90 -server_config: - name: daos_server - engines_per_host: 1 - engines: - 0: - targets: 4 - nr_xs_helpers: 0 - storage: - 0: - class: ram - scm_mount: /mnt/daos - system_ram_reserved: 1 -pool: - scm_size: 1G -container: - type: POSIX - control_method: daos diff --git a/src/tests/suite/SConscript b/src/tests/suite/SConscript index c13d376d226..a118227fabd 100644 --- a/src/tests/suite/SConscript +++ b/src/tests/suite/SConscript @@ -13,15 +13,6 @@ def scons(): dfusetest = dfuse_env.d_program(File("dfuse_test.c"), LIBS='cmocka') denv.Install('$PREFIX/bin/', dfusetest) - shm_test_env = base_env.Clone() - shm_test_env.compiler_setup() - shm_test_env.AppendUnique(LIBPATH=[Dir('../../gurt')]) - shm_test_env.AppendUnique(LIBPATH=[Dir('../../common')]) - shm_test_env.AppendUnique(LIBPATH=[Dir('../../cart')]) - shmtest = shm_test_env.d_program(File("shm_test.c"), LIBS=['gurt', 'daos_common', 'cart', - 'cmocka', 'rt', 'pthread']) - denv.Install('$PREFIX/bin/', shmtest) - denv.AppendUnique(LIBPATH=[Dir('../../client/dfs')]) denv.AppendUnique(CPPPATH=[Dir('../../client/dfs').srcnode()]) denv.AppendUnique(CPPPATH=[Dir('../../mgmt').srcnode()]) diff --git a/utils/rpms/daos.rpmlintrc b/utils/rpms/daos.rpmlintrc index cddd4f4ad90..9912465edf4 100644 --- a/utils/rpms/daos.rpmlintrc +++ b/utils/rpms/daos.rpmlintrc @@ -20,7 +20,7 @@ addFilter("daos-client\.x86_64: E: post(i|u)n-without-ldconfig \/usr\/lib64\/lib addFilter("daos-(client|server)\.x86_64: W: dangerous-command-in-%post(un)? rm") # lots of missing manpages -addFilter("W: no-manual-page-for-binary (cart_ctl|daos_agent|dfuse|self_test|acl_dump_test|agent_tests|crt_launch|daos_debug_set_params|daos_gen_io_conf|daos_perf|daos_racer|daos_run_io_conf|daos_test|dfs_test|dfuse_test|shm_test|drpc_engine_test|drpc_test|eq_tests|fault_status|hello_drpc|job_tests|jobtest|security_test|daos_firmware|daos_admin|daos_engine|daos_metrics|daos_server|daos_storage_estimator.py|evt_ctl|jump_pl_map|obj_ctl|pl_bench|rdbt|ring_pl_map|smd_ut|bio_ut|vea_stress|vea_ut|vos_perf|vos_tests|dtx_tests|ddb|ddb_tests)") +addFilter("W: no-manual-page-for-binary (cart_ctl|daos_agent|dfuse|self_test|acl_dump_test|agent_tests|crt_launch|daos_debug_set_params|daos_gen_io_conf|daos_perf|daos_racer|daos_run_io_conf|daos_test|dfs_test|dfuse_test|drpc_engine_test|drpc_test|eq_tests|fault_status|hello_drpc|job_tests|jobtest|security_test|daos_firmware|daos_admin|daos_engine|daos_metrics|daos_server|daos_storage_estimator.py|evt_ctl|jump_pl_map|obj_ctl|pl_bench|rdbt|ring_pl_map|smd_ut|bio_ut|vea_stress|vea_ut|vos_perf|vos_tests|dtx_tests|ddb|ddb_tests)") addFilter("daos-(server|firmware)\.x86_64: W: non-standard-(u|g)id \/.+ daos_server") diff --git a/utils/rpms/daos.spec b/utils/rpms/daos.spec index 61d2eabeac7..e9de33b41c7 100644 --- a/utils/rpms/daos.spec +++ b/utils/rpms/daos.spec @@ -527,7 +527,6 @@ getent passwd daos_agent >/dev/null || useradd -s /sbin/nologin -r -g daos_agent %{_bindir}/drpc_engine_test %{_bindir}/drpc_test %{_bindir}/dfuse_test -%{_bindir}/shm_test %{_bindir}/eq_tests %{_bindir}/job_tests %{_bindir}/security_test diff --git a/utils/utest.yaml b/utils/utest.yaml index faf0102050d..53e6966683e 100644 --- a/utils/utest.yaml +++ b/utils/utest.yaml @@ -1,4 +1,4 @@ -# (C) Copyright 2023-2024 Intel Corporation. +# (C) Copyright 2023-2025 Intel Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent - name: common @@ -52,6 +52,7 @@ tests: - cmd: ["src/gurt/tests/test_gurt"] - cmd: ["src/gurt/tests/test_gurt_telem_producer"] + - cmd: ["src/gurt/tests/test_shm"] - name: DTX base: "PREFIX" tests: