Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Mar 2005 09:16:44 -0500
From:      Matthew Hagerty <matthew@digitalstratum.com>
To:        Zera William Holladay <zholla1@uic.edu>
Cc:        FreeBSD Hackers <freebsd-hackers@freebsd.org>
Subject:   Re: Causing a process switch to test a theory.
Message-ID:  <423ED74C.1050705@digitalstratum.com>
In-Reply-To: <Pine.GSO.4.58.0503202314100.3910@icarus.cc.uic.edu>
References:  <423DE326.9000203@digitalstratum.com> <Pine.GSO.4.58.0503202314100.3910@icarus.cc.uic.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
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@freebsd.org mailing list
>http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?423ED74C.1050705>