lkml.org 
[lkml]   [2003]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    SubjectRe: /proc/net/* read drops data
    From
    Hello.

    In article <Pine.GSO.4.33.0308271935550.7750-100000@sweetums.bluetronic.net> (at Wed, 27 Aug 2003 19:58:17 -0400 (EDT)), Ricky Beam <jfbeam@bluetronic.net> says:

    > On Wed, 27 Aug 2003, Ricky Beam wrote:
    > >This smells like a simple "off by one" bug, but I've been too busy to go
    > >look at the code.
    >
    > Ah hah! it's a block size problem... netstat reads 1024 at a time.
    >
    > Using dd...
    >
    > [root:pts/5{9}]gir:~/[7:55pm]:dd if=/proc/net/udp bs=1024 | wc
    > 2+1 records in
    > 2+1 records out
    > 18 216 2304
    > [root:pts/5{9}]gir:~/[7:56pm]:dd if=/proc/net/udp bs=2048 | wc
    > 1+1 records in
    > 1+1 records out
    > 19 228 2432
    :

    Please try this patch.

    D: Fixing a bug that reading /proc/net/{udp,udp6} may drop some data

    Index: linux-2.6/net/ipv4/udp.c
    ===================================================================
    RCS file: /home/cvs/linux-2.5/net/ipv4/udp.c,v
    retrieving revision 1.38
    diff -u -r1.38 udp.c
    --- linux-2.6/net/ipv4/udp.c 14 Aug 2003 06:00:04 -0000 1.38
    +++ linux-2.6/net/ipv4/udp.c 3 Sep 2003 05:30:52 -0000
    @@ -1349,64 +1349,65 @@
    /* ------------------------------------------------------------------------ */
    #ifdef CONFIG_PROC_FS

    -static __inline__ struct sock *udp_get_bucket(struct seq_file *seq, loff_t *pos)
    +static struct sock *udp_get_first(struct seq_file *seq)
    {
    - int i;
    struct sock *sk;
    - struct hlist_node *node;
    - loff_t l = *pos;
    struct udp_iter_state *state = seq->private;

    - for (; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
    - i = 0;
    + for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
    + struct hlist_node *node;
    sk_for_each(sk, node, &udp_hash[state->bucket]) {
    - if (sk->sk_family != state->family) {
    - ++i;
    - continue;
    - }
    - if (l--) {
    - ++i;
    - continue;
    - }
    - *pos = i;
    - goto out;
    + if (sk->sk_family == state->family)
    + goto found;
    }
    }
    sk = NULL;
    -out:
    +found:
    return sk;
    }

    +static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
    +{
    + struct udp_iter_state *state = seq->private;
    +
    + do {
    + sk = sk_next(sk);
    +try_again:
    + ;
    + } while (sk && sk->sk_family != state->family);
    +
    + if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
    + sk = sk_head(&udp_hash[state->bucket]);
    + goto try_again;
    + }
    + return sk;
    +}
    +
    +static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos)
    +{
    + struct sock *sk = udp_get_first(seq);
    +
    + if (sk)
    + while(pos && (sk = udp_get_next(seq, sk)) != NULL)
    + --pos;
    + return pos ? NULL : sk;
    +}
    +
    static void *udp_seq_start(struct seq_file *seq, loff_t *pos)
    {
    read_lock(&udp_hash_lock);
    - return *pos ? udp_get_bucket(seq, pos) : (void *)1;
    + return *pos ? udp_get_idx(seq, *pos-1) : (void *)1;
    }

    static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
    {
    struct sock *sk;
    - struct hlist_node *node;
    - struct udp_iter_state *state;
    -
    - if (v == (void *)1) {
    - sk = udp_get_bucket(seq, pos);
    - goto out;
    - }

    - state = seq->private;
    + if (v == (void *)1)
    + sk = udp_get_idx(seq, 0);
    + else
    + sk = udp_get_next(seq, v);

    - sk = v;
    - sk_for_each_continue(sk, node)
    - if (sk->sk_family == state->family)
    - goto out;
    -
    - if (++state->bucket >= UDP_HTABLE_SIZE)
    - goto out;
    -
    - *pos = 0;
    - sk = udp_get_bucket(seq, pos);
    -out:
    ++*pos;
    return sk;
    }
    --
    Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
    GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:48    [W:0.028 / U:0.336 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site