Changeset 121b7e2 for lib/format_dag25.c


Ignore:
Timestamp:
03/11/08 16:19:32 (14 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
a9a91d1
Parents:
6033b99
Message:
  • Updated format_dag25 to support multiple streams - the new uri format for dag is "dag:/dev/dagX,<stream number>"
  • As each dag card can only be opened by a single process, thread-safety is now incorporated to allow separate threads to read from each dag stream
  • format_dag24 also supports the new uri format, although the stream number is ignored because old dags only have the one stream
  • Updated dagformat.h to include a whole bunch of new erf types
  • Added explicit support for the DSM Coloured Ethernet record type which will be required to deal with streamed packets
  • Fixed erf_get_padding() code that was comparing the return value of trace_get_link_type against an erf type rather than a libtrace link type
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_dag25.c

    r6033b99 r121b7e2  
    4646
    4747#include <sys/mman.h>
     48
    4849
    4950#ifdef WIN32
     
    5859#  endif
    5960#  include <sys/ioctl.h>
     61#  include <pthread.h>
    6062#endif
     63
    6164
    6265#define DATA(x) ((struct dag_format_data_t *)x->format_data)
     
    6467#define DUCK FORMAT_DATA->duck
    6568static struct libtrace_format_t dag;
     69
     70struct dag_dev_t {
     71        //pthread_mutex_t dag_mutex;
     72        char * dev_name;
     73        int fd;
     74        uint16_t ref_count;
     75        struct dag_dev_t *next;
     76};     
    6677
    6778struct dag_format_data_t {
     
    7384        } duck;
    7485
    75         int fd;
     86        struct dag_dev_t *device;
    7687        unsigned int dagstream;
    7788        int stream_attached;
     
    8293};
    8394
    84 static int dag_init_input(libtrace_t *libtrace) {
     95pthread_mutex_t open_dag_mutex;
     96struct dag_dev_t *open_dags = NULL;
     97
     98static struct dag_dev_t *dag_find_open_device(char *dev_name) {
     99        struct dag_dev_t *dag_dev;
     100       
     101        pthread_mutex_lock(&open_dag_mutex);
     102        dag_dev = open_dags;
     103
     104        /* XXX: Not exactly zippy, but how often are we going to be dealing
     105         * with multiple dag cards? */
     106        while (dag_dev != NULL) {
     107                if (strcmp(dag_dev->dev_name, dev_name) == 0) {
     108                        pthread_mutex_unlock(&open_dag_mutex);
     109                        return dag_dev;
     110                       
     111                }
     112                dag_dev = dag_dev->next;
     113        }
     114        pthread_mutex_unlock(&open_dag_mutex);
     115        return NULL;
     116               
     117       
     118}
     119
     120static void dag_close_device(struct dag_dev_t *dev) {
     121        /* Need to remove from the device list */
     122        struct dag_dev_t *prev, *d;
     123
     124        prev = NULL;
     125        pthread_mutex_lock(&open_dag_mutex);
     126
     127        d = open_dags;
     128
     129        while (d != NULL) {
     130                if (strcmp(dev->dev_name, d->dev_name) == 0) {
     131                        /* Found it! */
     132                        if (prev == NULL) {
     133                                open_dags = d->next;
     134                        } else {
     135                                prev->next = d->next;
     136                        }
     137                        assert(d->ref_count == 0);
     138                        dag_close(d->fd);
     139                        free(d->dev_name);
     140                        free(d);
     141                        return;
     142                }
     143                prev = d;
     144                d = d->next;
     145        }
     146
     147        /* Not sure what we do here - we've been asked to close a
     148         * device that isn't in our linked list - probably safest to
     149         * just return. Is there anything else we can really do? */
     150        return;
     151}
     152
     153static struct dag_dev_t *dag_open_device(libtrace_t *libtrace, char *dev_name) {
    85154        struct stat buf;
    86         libtrace->format_data = (struct dag_format_data_t *)
    87                 malloc(sizeof(struct dag_format_data_t));
    88         if (stat(libtrace->uridata, &buf) == -1) {
    89                 trace_set_err(libtrace,errno,"stat(%s)",libtrace->uridata);
    90                 return -1;
    91         }
    92 
    93         /* For now, we don't offer the ability to select the stream */
    94         FORMAT_DATA->dagstream = 0;
    95 
     155        int fd;
     156        struct dag_dev_t *new_dev;
     157       
     158        if (stat(dev_name, &buf) == -1) {
     159                trace_set_err(libtrace,errno,"stat(%s)",dev_name);
     160                return NULL;
     161        }
     162       
    96163        if (S_ISCHR(buf.st_mode)) {
    97                 if((FORMAT_DATA->fd = dag_open(libtrace->uridata)) < 0) {
     164                if((fd = dag_open(dev_name)) < 0) {
    98165                        trace_set_err(libtrace,errno,"Cannot open DAG %s",
    99                                         libtrace->uridata);
    100                         return -1;
     166                                        dev_name);
     167                        return NULL;
    101168                }
    102169        } else {
    103170                trace_set_err(libtrace,errno,"Not a valid dag device: %s",
    104                                 libtrace->uridata);
    105                 return -1;
    106         }
     171                                dev_name);
     172                return NULL;
     173        }
     174       
     175        new_dev = (struct dag_dev_t *)malloc(sizeof(struct dag_dev_t));
     176        new_dev->fd = fd;
     177        new_dev->dev_name = dev_name;
     178        new_dev->ref_count = 0;
     179       
     180        pthread_mutex_lock(&open_dag_mutex);
     181        new_dev->next = open_dags;
     182        open_dags = new_dev;
     183        pthread_mutex_unlock(&open_dag_mutex);
     184       
     185        return new_dev;
     186}
     187       
     188
     189static int dag_init_input(libtrace_t *libtrace) {
     190        char *dag_dev_name = NULL;
     191        char *scan = NULL;
     192        int stream = 0;
     193        struct dag_dev_t *dag_device = NULL;
     194       
     195        if ((scan = strchr(libtrace->uridata,',')) == NULL) {
     196                dag_dev_name = strdup(libtrace->uridata);
     197        } else {
     198                dag_dev_name = (char *)strndup(libtrace->uridata,
     199                                (size_t)(scan - libtrace->uridata));
     200                stream = atoi(++scan);
     201        }
     202       
     203       
     204        libtrace->format_data = (struct dag_format_data_t *)
     205                malloc(sizeof(struct dag_format_data_t));
     206
     207        /* For now, we don't offer the ability to select the stream */
     208        FORMAT_DATA->dagstream = stream;
     209
     210        dag_device = dag_find_open_device(dag_dev_name);
     211
     212        if (dag_device == NULL) {
     213                /* Device not yet opened - open it ourselves */
     214                dag_device = dag_open_device(libtrace, dag_dev_name);
     215        } else {
     216                free(dag_dev_name);
     217                dag_dev_name = NULL;
     218        }
     219
     220        if (dag_device == NULL) {
     221                if (dag_dev_name)
     222                        free(dag_dev_name);
     223                return -1;
     224        }
     225
     226
     227        dag_device->ref_count ++;
    107228
    108229        DUCK.last_duck = 0;
     
    110231        DUCK.last_pkt = 0;
    111232        DUCK.dummy_duck = NULL;
     233        FORMAT_DATA->device = dag_device;
    112234        FORMAT_DATA->stream_attached = 0;
    113235        FORMAT_DATA->drops = 0;
     
    125247                case TRACE_OPTION_SNAPLEN:
    126248                        snprintf(conf_str, 4096, "varlen slen=%i", *(int *)data);
    127                         if (dag_configure(FORMAT_DATA->fd, conf_str) != 0) {
     249                        if (dag_configure(FORMAT_DATA->device->fd,
     250                                                conf_str) != 0) {
    128251                                trace_set_err(libtrace, errno, "Failed to configure snaplen on DAG card: %s", libtrace->uridata);
    129252                                return -1;
     
    153276
    154277       
    155         if (dag_attach_stream(FORMAT_DATA->fd,
     278        if (dag_attach_stream(FORMAT_DATA->device->fd,
    156279                                FORMAT_DATA->dagstream, 0, 0) < 0) {
    157280                trace_set_err(libtrace, errno, "Cannot attach DAG stream");
     
    159282        }
    160283
    161         if (dag_start_stream(FORMAT_DATA->fd,
     284        if (dag_start_stream(FORMAT_DATA->device->fd,
    162285                                FORMAT_DATA->dagstream) < 0) {
    163286                trace_set_err(libtrace, errno, "Cannot start DAG stream");
     
    166289        FORMAT_DATA->stream_attached = 1;
    167290        /* We don't want the dag card to do any sleeping */
    168         dag_set_stream_poll(FORMAT_DATA->fd,
     291        dag_set_stream_poll(FORMAT_DATA->device->fd,
    169292                                FORMAT_DATA->dagstream, 0, &zero,
    170293                                &nopoll);
     
    173296       
    174297        do {
    175                 top = dag_advance_stream(FORMAT_DATA->fd,
     298                top = dag_advance_stream(FORMAT_DATA->device->fd,
    176299                                        FORMAT_DATA->dagstream,
    177300                                        &bottom);
     
    189312
    190313static int dag_pause_input(libtrace_t *libtrace) {
    191         if (dag_stop_stream(FORMAT_DATA->fd,
     314        if (dag_stop_stream(FORMAT_DATA->device->fd,
    192315                                FORMAT_DATA->dagstream) < 0) {
    193316                trace_set_err(libtrace, errno, "Could not stop DAG stream");
    194317                return -1;
    195318        }
    196         if (dag_detach_stream(FORMAT_DATA->fd,
     319        if (dag_detach_stream(FORMAT_DATA->device->fd,
    197320                                FORMAT_DATA->dagstream) < 0) {
    198321                trace_set_err(libtrace, errno, "Could not detach DAG stream");
     
    206329        if (FORMAT_DATA->stream_attached)
    207330                dag_pause_input(libtrace);
    208         dag_close(FORMAT_DATA->fd);
     331        FORMAT_DATA->device->ref_count --;
     332       
     333        if (FORMAT_DATA->device->ref_count == 0)
     334                dag_close_device(FORMAT_DATA->device);
    209335        if (DUCK.dummy_duck)
    210336                trace_destroy_dead(DUCK.dummy_duck);
     
    231357        /* No need to check if we can get DUCK or not - we're modern
    232358         * enough */
    233         if ((ioctl(FORMAT_DATA->fd, DAGIOCDUCK, (duckinf_t *)packet->payload)
    234                                 < 0)) {
     359        if ((ioctl(FORMAT_DATA->device->fd, DAGIOCDUCK,
     360                                        (duckinf_t *)packet->payload) < 0)) {
    235361                trace_set_err(libtrace, errno, "Error using DAGIOCDUCK");
    236362                return -1;
     
    251377        if (diff >= dag_record_size && FORMAT_DATA->processed < 4 * 1024 * 1024)
    252378                return diff;
    253         FORMAT_DATA->top = dag_advance_stream(FORMAT_DATA->fd,
     379        FORMAT_DATA->top = dag_advance_stream(FORMAT_DATA->device->fd,
    254380                        FORMAT_DATA->dagstream,
    255381                        &(FORMAT_DATA->bottom));
     
    332458        tv = trace_get_timeval(packet);
    333459        DUCK.last_pkt = tv.tv_sec;
    334         DATA(libtrace)->drops += ntohs(erfptr->lctr);
     460       
     461        /* No loss counter for DSM coloured records - have to use
     462         * some other API */
     463        if (erfptr->type == TYPE_DSM_COLOR_ETH) {
     464               
     465        } else {
     466                DATA(libtrace)->drops += ntohs(erfptr->lctr);
     467        }
    335468        return packet->payload ? htons(erfptr->rlen) :
    336469                                erf_get_framing_length(packet);
Note: See TracChangeset for help on using the changeset viewer.