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.
This commit is contained in:
@@ -52,6 +52,7 @@ static char *max_request_str; /* `max_request' as a string */
|
|||||||
static int disable_des = -1;
|
static int disable_des = -1;
|
||||||
|
|
||||||
static int builtin_hdb_flag;
|
static int builtin_hdb_flag;
|
||||||
|
int testing_flag;
|
||||||
static int help_flag;
|
static int help_flag;
|
||||||
static int version_flag;
|
static int version_flag;
|
||||||
|
|
||||||
@@ -120,6 +121,7 @@ static struct getargs args[] = {
|
|||||||
{ "chroot", 0, arg_string, &chroot_string,
|
{ "chroot", 0, arg_string, &chroot_string,
|
||||||
"chroot directory to run in", NULL
|
"chroot directory to run in", NULL
|
||||||
},
|
},
|
||||||
|
{ "testing", 0, arg_flag, &testing_flag, NULL, NULL },
|
||||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
||||||
{ "version", 'v', arg_flag, &version_flag, NULL, NULL }
|
{ "version", 'v', arg_flag, &version_flag, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
186
kdc/connect.c
186
kdc/connect.c
@@ -1153,109 +1153,115 @@ start_kdc(krb5_context context,
|
|||||||
tv1.tv_usec = 0;
|
tv1.tv_usec = 0;
|
||||||
|
|
||||||
#ifdef HAVE_FORK
|
#ifdef HAVE_FORK
|
||||||
/* Note that we might never execute the body of this loop */
|
if (!testing_flag) {
|
||||||
while (exit_flag == 0) {
|
/* 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);
|
gettimeofday(&tv2, NULL);
|
||||||
if (tv1.tv_sec == tv2.tv_sec && tv2.tv_usec - tv1.tv_usec < 25000) {
|
if (tv1.tv_sec == tv2.tv_sec && tv2.tv_usec - tv1.tv_usec < 25000) {
|
||||||
#if 0 /* XXXrcd: should print a message... */
|
#if 0 /* XXXrcd: should print a message... */
|
||||||
kdc_log(context, config, 0, "Spawning KDCs too quickly, "
|
kdc_log(context, config, 0, "Spawning KDCs too quickly, "
|
||||||
"pausing for 50ms");
|
"pausing for 50ms");
|
||||||
#endif
|
#endif
|
||||||
select_sleep(12500);
|
select_sleep(12500);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_kdcs >= max_kdcs) {
|
if (num_kdcs >= max_kdcs) {
|
||||||
num_kdcs -= reap_kid(context, config, pids, max_kdcs, 0);
|
num_kdcs -= reap_kid(context, config, pids, max_kdcs, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_kdcs > 0)
|
if (num_kdcs > 0)
|
||||||
num_kdcs -= reap_kids(context, config, pids, max_kdcs);
|
num_kdcs -= reap_kids(context, config, pids, max_kdcs);
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
switch (pid) {
|
switch (pid) {
|
||||||
case 0:
|
case 0:
|
||||||
close(islive[0]);
|
close(islive[0]);
|
||||||
loop(context, config, d, ndescr, islive[1]);
|
loop(context, config, d, ndescr, islive[1]);
|
||||||
exit(0);
|
exit(0);
|
||||||
case -1:
|
case -1:
|
||||||
/* XXXrcd: hmmm, do something useful?? */
|
/* XXXrcd: hmmm, do something useful?? */
|
||||||
kdc_log(context, config, 0,
|
kdc_log(context, config, 0,
|
||||||
"KDC master process could not fork worker process");
|
"KDC master process could not fork worker process");
|
||||||
sleep(10);
|
sleep(10);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (i=0; i < max_kdcs; i++) {
|
for (i=0; i < max_kdcs; i++) {
|
||||||
if (pids[i] == 0) {
|
if (pids[i] == 0) {
|
||||||
pids[i] = pid;
|
pids[i] = pid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kdc_log(context, config, 0, "KDC worker process started: %d", pid);
|
kdc_log(context, config, 0, "KDC worker process started: %d",
|
||||||
num_kdcs++;
|
pid);
|
||||||
gettimeofday(&tv1, NULL);
|
num_kdcs++;
|
||||||
break;
|
gettimeofday(&tv1, NULL);
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Closing these sockets should cause the kids to die... */
|
|
||||||
|
|
||||||
close(islive[0]);
|
|
||||||
close(islive[1]);
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Kill stragglers and reap every 200ms, give up after 15s */
|
/* Closing these sockets should cause the kids to die... */
|
||||||
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:
|
close(islive[0]);
|
||||||
kdc_log(context, config, 0, "KDC master process exiting", pid);
|
close(islive[1]);
|
||||||
free(pids);
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
loop(context, config, d, ndescr, -1);
|
loop(context, config, d, ndescr, -1);
|
||||||
kdc_log(context, config, 0, "KDC exiting", pid);
|
kdc_log(context, config, 0, "KDC exiting", pid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free (d);
|
free(d);
|
||||||
}
|
}
|
||||||
|
@@ -103,6 +103,8 @@ extern int detach_from_console;
|
|||||||
extern int daemon_child;
|
extern int daemon_child;
|
||||||
extern int do_bonjour;
|
extern int do_bonjour;
|
||||||
|
|
||||||
|
extern int testing_flag;
|
||||||
|
|
||||||
extern const struct units _kdc_digestunits[];
|
extern const struct units _kdc_digestunits[];
|
||||||
|
|
||||||
#define KDC_LOG_FILE "kdc.log"
|
#define KDC_LOG_FILE "kdc.log"
|
||||||
|
Reference in New Issue
Block a user