diff options
author | Ralph Wuerthner <ralph.wuerthner@de.ibm.com> | 2018-10-05 13:53:30 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2018-11-01 01:59:10 +0100 |
commit | b5ea7946f844ff6b9337fea57fd002b716595703 (patch) | |
tree | 9379d720502fc88f6e0202a203ea624b7523401e /nsswitch | |
parent | 988182c3b8dab6511c75622e3484c9ef71e6d0db (diff) | |
download | samba-b5ea7946f844ff6b9337fea57fd002b716595703.tar.gz |
nsswitch: add test for parallel NSS & libwbclient calls
Signed-off-by: Ralph Wuerthner <ralph.wuerthner@de.ibm.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'nsswitch')
-rw-r--r-- | nsswitch/stress-nss-libwbclient.c | 156 | ||||
-rw-r--r-- | nsswitch/wscript_build | 7 |
2 files changed, 163 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> +#include <pthread.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <stdlib.h> +#include <sys/types.h> +#include <pwd.h> +#include <wbclient.h> + +#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; +} diff --git a/nsswitch/wscript_build b/nsswitch/wscript_build index ff98372fd6e..6acc4a19b9b 100644 --- a/nsswitch/wscript_build +++ b/nsswitch/wscript_build @@ -17,6 +17,13 @@ bld.SAMBA_BINARY('nsstest', install=False ) +if bld.CONFIG_SET('HAVE_PTHREAD'): + bld.SAMBA_BINARY('stress-nss-libwbclient', + source='stress-nss-libwbclient.c', + deps='wbclient', + install=False + ) + # The nss_wrapper code relies strictly on the linux implementation and # name, so compile but do not install a copy under this name. bld.SAMBA_LIBRARY('nss_wrapper_winbind', |