From 5f2e4fb3683f1f2a6fb476d9d25d8f830ea5c3cf Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Tue, 6 Dec 2016 16:40:51 -0600 Subject: [PATCH] kdc: add --testing option for leak testing The kdc nowadays forks and restarts worker children. This is nice, but for leak checking in tests on OS X with leak(1) we really need the worker to be the one process. --- kdc/config.c | 2 + kdc/connect.c | 184 +++++++++++++++++++++++++++++---------------------------- kdc/kdc_locl.h | 2 + 3 files changed, 99 insertions(+), 89 deletions(-) diff --git a/kdc/config.c b/kdc/config.c index f5ce794fb..e8e0ee4a5 100644 --- a/kdc/config.c +++ b/kdc/config.c @@ -52,6 +52,7 @@ static char *max_request_str; /* `max_request' as a string */ static int disable_des = -1; static int builtin_hdb_flag; +int testing_flag; static int help_flag; static int version_flag; @@ -120,6 +121,7 @@ static struct getargs args[] = { { "chroot", 0, arg_string, &chroot_string, "chroot directory to run in", NULL }, + { "testing", 0, arg_flag, &testing_flag, NULL, NULL }, { "help", 'h', arg_flag, &help_flag, NULL, NULL }, { "version", 'v', arg_flag, &version_flag, NULL, NULL } }; diff --git a/kdc/connect.c b/kdc/connect.c index 73b338903..5c4c0909a 100644 --- a/kdc/connect.c +++ b/kdc/connect.c @@ -1153,109 +1153,115 @@ start_kdc(krb5_context context, tv1.tv_usec = 0; #ifdef HAVE_FORK - /* Note that we might never execute the body of this loop */ - while (exit_flag == 0) { + if (!testing_flag) { + /* Note that we might never execute the body of this loop */ + while (exit_flag == 0) { - /* Slow down the creation of KDCs... */ + /* Slow down the creation of KDCs... */ - gettimeofday(&tv2, NULL); - if (tv1.tv_sec == tv2.tv_sec && tv2.tv_usec - tv1.tv_usec < 25000) { + gettimeofday(&tv2, NULL); + if (tv1.tv_sec == tv2.tv_sec && tv2.tv_usec - tv1.tv_usec < 25000) { #if 0 /* XXXrcd: should print a message... */ - kdc_log(context, config, 0, "Spawning KDCs too quickly, " - "pausing for 50ms"); + kdc_log(context, config, 0, "Spawning KDCs too quickly, " + "pausing for 50ms"); #endif - select_sleep(12500); - continue; - } - - if (num_kdcs >= max_kdcs) { - num_kdcs -= reap_kid(context, config, pids, max_kdcs, 0); - continue; - } - - if (num_kdcs > 0) - num_kdcs -= reap_kids(context, config, pids, max_kdcs); - - pid = fork(); - switch (pid) { - case 0: - close(islive[0]); - loop(context, config, d, ndescr, islive[1]); - exit(0); - case -1: - /* XXXrcd: hmmm, do something useful?? */ - kdc_log(context, config, 0, - "KDC master process could not fork worker process"); - sleep(10); - break; - default: - for (i=0; i < max_kdcs; i++) { - if (pids[i] == 0) { - pids[i] = pid; - break; - } - } - kdc_log(context, config, 0, "KDC worker process started: %d", pid); - num_kdcs++; - gettimeofday(&tv1, NULL); - break; - } - } - - /* Closing these sockets should cause the kids to die... */ + select_sleep(12500); + continue; + } + + if (num_kdcs >= max_kdcs) { + num_kdcs -= reap_kid(context, config, pids, max_kdcs, 0); + continue; + } + + if (num_kdcs > 0) + num_kdcs -= reap_kids(context, config, pids, max_kdcs); + + pid = fork(); + switch (pid) { + case 0: + close(islive[0]); + loop(context, config, d, ndescr, islive[1]); + exit(0); + case -1: + /* XXXrcd: hmmm, do something useful?? */ + kdc_log(context, config, 0, + "KDC master process could not fork worker process"); + sleep(10); + break; + default: + for (i=0; i < max_kdcs; i++) { + if (pids[i] == 0) { + pids[i] = pid; + break; + } + } + kdc_log(context, config, 0, "KDC worker process started: %d", + pid); + num_kdcs++; + gettimeofday(&tv1, NULL); + break; + } + } - close(islive[0]); - close(islive[1]); + /* Closing these sockets should cause the kids to die... */ - /* Close our listener sockets before terminating workers */ - for (i = 0; i < ndescr; ++i) - clear_descr(&d[i]); + close(islive[0]); + close(islive[1]); - gettimeofday(&tv1, NULL); - tv2 = tv1; + /* Close our listener sockets before terminating workers */ + for (i = 0; i < ndescr; ++i) + clear_descr(&d[i]); + + gettimeofday(&tv1, NULL); + tv2 = tv1; + + /* Reap every 10ms, terminate stragglers once a second, give up after 10 */ + for (;;) { + struct timeval tv3; + num_kdcs -= reap_kids(context, config, pids, max_kdcs); + if (num_kdcs == 0 && bonjour_pid <= 0) + goto end; + /* + * Using select to sleep will fail with EINTR if we receive a + * SIGCHLD. This is desirable. + */ + select_sleep(10000); + gettimeofday(&tv3, NULL); + if (tv3.tv_sec - tv1.tv_sec > 10 || + (tv3.tv_sec - tv1.tv_sec == 10 && tv3.tv_usec >= tv1.tv_usec)) + break; + if (tv3.tv_sec - tv2.tv_sec > 1 || + (tv3.tv_sec - tv2.tv_sec == 1 && tv3.tv_usec >= tv2.tv_usec)) { + kill_kids(pids, max_kdcs, SIGTERM); + tv2 = tv3; + } + } - /* Reap every 10ms, terminate stragglers once a second, give up after 10 */ - for (;;) { - struct timeval tv3; - num_kdcs -= reap_kids(context, config, pids, max_kdcs); - if (num_kdcs == 0 && bonjour_pid <= 0) - goto end; - /* - * Using select to sleep will fail with EINTR if we receive a - * SIGCHLD. This is desirable. - */ - select_sleep(10000); - gettimeofday(&tv3, NULL); - if (tv3.tv_sec - tv1.tv_sec > 10 || - (tv3.tv_sec - tv1.tv_sec == 10 && tv3.tv_usec >= tv1.tv_usec)) - break; - if (tv3.tv_sec - tv2.tv_sec > 1 || - (tv3.tv_sec - tv2.tv_sec == 1 && tv3.tv_usec >= tv2.tv_usec)) { - kill_kids(pids, max_kdcs, SIGTERM); - tv2 = tv3; + /* Kill stragglers and reap every 200ms, give up after 15s */ + for (;;) { + kill_kids(pids, max_kdcs, SIGKILL); + num_kdcs -= reap_kids(context, config, pids, max_kdcs); + if (num_kdcs == 0 && bonjour_pid <= 0) + break; + select_sleep(200000); + gettimeofday(&tv2, NULL); + if (tv2.tv_sec - tv1.tv_sec > 15 || + (tv2.tv_sec - tv1.tv_sec == 15 && tv2.tv_usec >= tv1.tv_usec)) + break; } - } - /* Kill stragglers and reap every 200ms, give up after 15s */ - for (;;) { - kill_kids(pids, max_kdcs, SIGKILL); - num_kdcs -= reap_kids(context, config, pids, max_kdcs); - if (num_kdcs == 0 && bonjour_pid <= 0) - break; - select_sleep(200000); - gettimeofday(&tv2, NULL); - if (tv2.tv_sec - tv1.tv_sec > 15 || - (tv2.tv_sec - tv1.tv_sec == 15 && tv2.tv_usec >= tv1.tv_usec)) - break; + end: + kdc_log(context, config, 0, "KDC master process exiting", pid); + free(pids); + } else { + loop(context, config, d, ndescr, -1); + kdc_log(context, config, 0, "KDC exiting", pid); } - - end: - kdc_log(context, config, 0, "KDC master process exiting", pid); - free(pids); #else loop(context, config, d, ndescr, -1); kdc_log(context, config, 0, "KDC exiting", pid); #endif - free (d); + free(d); } diff --git a/kdc/kdc_locl.h b/kdc/kdc_locl.h index 10cbc1d37..adbb94765 100644 --- a/kdc/kdc_locl.h +++ b/kdc/kdc_locl.h @@ -103,6 +103,8 @@ extern int detach_from_console; extern int daemon_child; extern int do_bonjour; +extern int testing_flag; + extern const struct units _kdc_digestunits[]; #define KDC_LOG_FILE "kdc.log" -- 2.11.4.GIT