Changeset f9df20e


Ignore:
Timestamp:
06/19/18 16:48:33 (2 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
cachetimestamps, develop, master, rc-4.0.4, ringdecrementfix, ringperformance
Children:
528a27c, 95ca714
Parents:
86b365b
Message:

Fix bug where two ring: trace inputs had same fanout group.

We use rand() to assign the fanout group when we create the
input, but the rand() seed state is usually equal in both threads
at the point where we call rand().

So we end up with two inputs trying to be assigned to the same
fanout group, which fails and the second input will immediately
halt.

Also added code to try incrementing the fanout group number if
we end up clashing with another existing group. This will also
resolve any issues with the RNG producing one-off clashes.

Location:
lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • lib/format_linux_common.c

    rcc9c9de rf9df20e  
    4949
    5050#include "format_linux_common.h"
     51
     52unsigned int rand_seedp = 0;
    5153
    5254#ifdef HAVE_NETPACKET_PACKET_H
     
    201203        /* Some examples use pid for the group however that would limit a single
    202204         * application to use only int/ring format, instead using rand */
    203         FORMAT_DATA->fanout_group = (uint16_t) rand();
     205        FORMAT_DATA->fanout_group = (uint16_t) (rand_r(&rand_seedp) % 65536);
    204206        return 0;
    205207}
  • lib/format_linux_common.h

    r4697684 rf9df20e  
    421421                                        struct linux_per_stream_t *stream)
    422422{
    423         int fanout_opt = ((int)FORMAT_DATA->fanout_flags << 16) |
    424                          (int)FORMAT_DATA->fanout_group;
    425         if (setsockopt(stream->fd, SOL_PACKET, PACKET_FANOUT,
    426                         &fanout_opt, sizeof(fanout_opt)) == -1) {
    427                 trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
     423        int fanout_opt;
     424        int attempts = 0;
     425        while (attempts < 5) {
     426                fanout_opt = ((int)FORMAT_DATA->fanout_flags << 16) |
     427                                 (int)FORMAT_DATA->fanout_group;
     428
     429                if (setsockopt(stream->fd, SOL_PACKET, PACKET_FANOUT,
     430                                &fanout_opt, sizeof(fanout_opt)) == -1) {
     431                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
    428432                              "Converting the fd to a socket fanout failed %s",
    429433                              libtrace->uridata);
    430                 return -1;
     434                        FORMAT_DATA->fanout_group ++;
     435                        attempts ++;
     436                        continue;
     437                }
     438                return 0;
    431439        }
    432         return 0;
     440        return -1;
    433441}
    434442#endif /* HAVE_NETPACKET_PACKET_H */
Note: See TracChangeset for help on using the changeset viewer.