OpenSolaris

Printable Version Enter a New Search
Bug ID 6580293
Synopsis syslogd should use private pool of door server threads
State 10-Fix Delivered (Fix available in build)
Category:Subcategory utility:logger
Keywords rtiq_internal
Responsible Engineer Nobutomo Nakano
Reported Against
Duplicate Of
Introduced In solaris_2.6
Commit to Fix snv_88
Fixed In snv_88
Release Fixed solaris_nevada(snv_88) , solaris_10u6(s10u6_03) (Bug ID:2163405)
Related Bugs 4015825 , 6635129
Submit Date 13-July-2007
Last Update Date 23-April-2008
Description
Customer had an issue where syslogd would die every few weeks.
The customer had a cron job which sigHUP to syslogd every hour.
Extensive investigation showed that syslogd died because it ran out of
virtual address space due to door service threads allocation 1Mb stacks.

The particular customer system heavily used syslogd with many concurrent door_calls.

Further investigation showed that the issue is that active door_calls within the server thread will cause new door service threads to be created if active during a fork1()

The issue appears to be due to the lwp_suspend()/lwp_resume() of the threads in door_return()

The following testcase reproduces the issue on 

SunOS t2000-c 5.10 Generic_125100-07 sun4v sparc SUNW,Sun-Fire-T200

server.c                  [gcc -o server server.c -ldoor]

#include <sys/types.h>
#include <unistd.h>
#include <door.h>

char *DoorFileName = "testdoor";

extern int __nthreads();

static void
server(void *cookie, char *argp, size_t arg_size,
     door_desc_t *dp, uint_t n)
{
    (void) door_return(NULL, 0, NULL, 0);
}

main(int argc, char argv[]) {
    int DoorFd;

    if ((DoorFd = door_create(server, 0, DOOR_REFUSE_DESC)) < 0) {
        perror("door create failed");
        exit(1);
    }
    if (fattach(DoorFd, DoorFileName) < 0) {
        perror("door attach failed");
        exit(1);
    }
    while (1) {
        sleep(2);
        if ((argc > 1) && fork1() == 0) {
            sleep(1);
            exit(0);
        }
        printf("current threads = %d\n", __nthreads());
    }
}

knockdoor.c            [gcc -o knockdoor knockdoor.c -ldoor]

#include <fcntl.h>
#include <thread.h>
#include <sys/types.h>
#include <unistd.h>
#include <door.h>

char *DoorFileName = "testdoor";

void *knockdoor(void * a) {
    int d;
    int s;
    door_arg_t darg;
    door_info_t info;

    while (1) {
    if ((d = open(DoorFileName, O_RDONLY)) < 0)
            return (0);
    darg.data_ptr = NULL;
    darg.data_size = 0;
    darg.desc_ptr = NULL;
    darg.desc_num = 0;
    darg.rbuf = NULL;
    darg.rsize = 0;
    s = __door_call(d, &darg);
    close(d);
    }
}

main(int argc, char argv[]) {

    int i;

    for (i = 0; i < 100; i++) {
        int tid;

        thr_create(NULL, 0, knockdoor, NULL, THR_DETACHED, &tid);
    }
    while (1) sleep(1);
}

------------------------------------------
rm testdoor; touch testdoor
./server fork &
./knockdoor &

server will run serviceing door_calls and fork1() every couple of seconds;
knockdoor will create 100 threads/lwps which loop doing door_calls.

we see the number of threads within server steady if we dont do fork1()
but increasing everytime we do fork1().
Work Around
N/A
Comments
N/A