From b5ea7946f844ff6b9337fea57fd002b716595703 Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Fri, 5 Oct 2018 13:53:30 +0200 Subject: nsswitch: add test for parallel NSS & libwbclient calls Signed-off-by: Ralph Wuerthner Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison --- nsswitch/stress-nss-libwbclient.c | 156 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 nsswitch/stress-nss-libwbclient.c (limited to 'nsswitch/stress-nss-libwbclient.c') diff --git a/nsswitch/stress-nss-libwbclient.c b/nsswitch/stress-nss-libwbclient.c new file mode 100644 index 00000000000..cf85ff3f817 --- /dev/null +++ b/nsswitch/stress-nss-libwbclient.c @@ -0,0 +1,156 @@ +/* + Unix SMB/CIFS implementation. + + Stress test for parallel NSS & libwbclient calls. + + Copyright (C) Ralph Wuerthner 2018 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RUNTIME 10 + +struct thread_state { + const char *username; + time_t timeout; + pthread_mutex_t lock; + bool fail; + int nss_loop_count; + int wbc_loop_count; +}; + +static void *query_nss_thread(void *ptr) +{ + struct thread_state *state = ptr; + char buf[1024]; + int rc; + struct passwd pwd, *result; + + while (time(NULL) < state->timeout) { + rc = getpwnam_r(state->username, + &pwd, + buf, + sizeof(buf), + &result); + if (rc != 0 || result == NULL) { + pthread_mutex_lock(&state->lock); + state->fail = true; + pthread_mutex_unlock(&state->lock); + fprintf(stderr, + "getpwnam_r failed with rc='%s' result=%p\n", + strerror(rc), + result); + break; + } + state->nss_loop_count++; + pthread_mutex_lock(&state->lock); + if (state->fail) { + pthread_mutex_unlock(&state->lock); + break; + } + pthread_mutex_unlock(&state->lock); + } + return NULL; +} + +static void *query_wbc_thread(void *ptr) +{ + struct thread_state *state = ptr; + struct passwd *ppwd; + wbcErr wbc_status; + + while (time(NULL) < state->timeout) { + wbc_status = wbcGetpwnam(state->username, &ppwd); + if (!WBC_ERROR_IS_OK(wbc_status)) { + pthread_mutex_lock(&state->lock); + state->fail = true; + pthread_mutex_unlock(&state->lock); + fprintf(stderr, + "wbcGetpwnam failed with %s\n", + wbcErrorString(wbc_status)); + break; + } + wbcFreeMemory(ppwd); + state->wbc_loop_count++; + pthread_mutex_lock(&state->lock); + if (state->fail) { + pthread_mutex_unlock(&state->lock); + break; + } + pthread_mutex_unlock(&state->lock); + } + return NULL; +} + +int main(int argc, char *argv[]) +{ + int rc, n; + struct thread_state state; + pthread_t threads[2]; + + if (argc < 2 ) { + fprintf(stderr,"%s: missing domain user\n", argv[0]); + return 1; + } + + state.username = argv[1]; + state.timeout = time(NULL) + RUNTIME; + pthread_mutex_init(&state.lock, NULL); + state.fail = false; + state.nss_loop_count = 0; + state.wbc_loop_count = 0; + + printf("query domain user '%s'\n", state.username); + + /* create query threads */ + rc = pthread_create(&threads[0], NULL, query_nss_thread, &state); + if (rc != 0) { + fprintf(stderr, + "creating NSS thread failed: %s\n", + strerror(rc)); + exit(1); + } + rc = pthread_create(&threads[1], NULL, query_wbc_thread, &state); + if (rc != 0) { + fprintf(stderr, + "creating libwbclient thread failed: %s\n", + strerror(rc)); + exit(1); + } + + /* wait for query threads to terminate */ + for (n = 0; n < 2; n++) { + pthread_join(threads[n], NULL); + } + + fprintf(state.fail ? stderr: stdout, + "test %s with %i NSS and %i libwbclient calls\n", + state.fail ? "failed" : "passed", + state.nss_loop_count, + state.wbc_loop_count); + + return state.fail; +} -- cgit v1.2.1