Causing a process switch to test a theory.

Matthew Hagerty matthew at digitalstratum.com
Mon Mar 21 06:16:54 PST 2005


Zera William Holladay wrote:

>If you post the section(s) of code in question, then you'll probably
>elicit some responses.  PIPE_BUF is a POSIX defined minimum, so you might
>grep for sections of code that contain fpathconf(*, _PC_PIPE_BUF) to
>determine if the programmers took this into consideration.  At least
>you'll be able to follow the logical flow of the program from fpathconf()
>forward.
>
>Further, if you do some fancy programming (like preempting a process
>unnaturally) to determine if there is an error in this particular aspect
>of Apache, then you'll also have to show that you have not inflicted the
>error too, which will probably be harder than what you set out to solve or
>figure out.
>
>Good luck, Zera Holladay
>_______________________________________________
>freebsd-hackers at freebsd.org mailing list
>http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
>  
>

I was not wanting to preempt any of the processes unnaturally, I was 
looking more for suggestions as to how I can reliably cause preemption 
for testing.  Without knowing the details of how FreeBSD's scheduler 
works, I could only assume that making a heavy load might cause such 
preemption to happen, but that is just an under educated guess.

I'm not familiar with fpathconf(), I'll go look that up for sure and 
check Apache's code for it's use.  Thanks!

As for code, below is the portion that does to actual writing to the log 
file, opened as either a normal file or a pipe depending on the config 
file.  Also note that BUFFERED_LOGS is not normally defined (must be 
passed to make at compile time), and even then it only makes sure there 
is *at least* LOG_BUFSIZE bytes to write before writing.  It does not 
prevent longer than LOG_BUFSIZE bytes from being written.

Matthew

---

#ifdef PIPE_BUF
#define LOG_BUFSIZE     PIPE_BUF
#else
#define LOG_BUFSIZE     (512)
#endif

<snip>

static int config_log_transaction(request_rec *r, config_log_state *cls,
                                  array_header *default_format)

    <snip>
    code that checks if any conditional envariable-controlled logging 
decisions prevent logging.
    </snip>

    format = cls->format ? cls->format : default_format;

    strs = ap_palloc(r->pool, sizeof(char *) * (format->nelts));
    strl = ap_palloc(r->pool, sizeof(int) * (format->nelts));
    items = (log_format_item *) format->elts;

    orig = r;
    while (orig->prev) {
        orig = orig->prev;
    }
    while (r->next) {
        r = r->next;
    }

    for (i = 0; i < format->nelts; ++i) {
        strs[i] = process_item(r, orig, &items[i]);
    }

    for (i = 0; i < format->nelts; ++i) {
        len += strl[i] = strlen(strs[i]);
    }

#ifdef BUFFERED_LOGS
    if (len + cls->outcnt > LOG_BUFSIZE) {
        flush_log(cls);
    }
    if (len >= LOG_BUFSIZE) {
        str = ap_palloc(r->pool, len + 1);
        for (i = 0, s = str; i < format->nelts; ++i) {
            memcpy(s, strs[i], strl[i]);
            s += strl[i];
        }
        write(cls->log_fd, str, len);
    }
    else {
        for (i = 0, s = &cls->outbuf[cls->outcnt]; i < format->nelts; ++i) {
            memcpy(s, strs[i], strl[i]);
            s += strl[i];
        }
        cls->outcnt += len;
    }
#else
    str = ap_palloc(r->pool, len + 1);

    for (i = 0, s = str; i < format->nelts; ++i) {
        memcpy(s, strs[i], strl[i]);
        s += strl[i];
    }

    write(cls->log_fd, str, len);
#endif

    return OK;
}


#ifdef BUFFERED_LOGS
static void flush_log(config_log_state *cls)
{
    if (cls->outcnt && cls->log_fd != -1) {
        write(cls->log_fd, cls->outbuf, cls->outcnt);
        cls->outcnt = 0;
    }
}
#endif



More information about the freebsd-hackers mailing list