source: tools/tracemerge/tracemerge.c @ 4423dc7

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 4423dc7 was 34e22d1, checked in by Perry Lorier <perry@…>, 14 years ago

Allow setting different interfaces_per_input

  • Property mode set to 100644
File size: 3.9 KB
Line 
1#include <libtrace.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <inttypes.h>
5#include <stdbool.h>
6#include <getopt.h>
7#include <signal.h>
8
9static void usage(char *argv0)
10{
11        fprintf(stderr,"Usage:\n"
12        "%s flags outputuri traceuri [traceuri...]\n"
13        "-i [interfaces_per_input] --set-interface [interfaces_per_input]\n"
14        "                       Each trace is allocated an interface. Default leaves this flag as read from the original traces, if appropriate\n"
15        "-u --unique-packets    Discard duplicate packets\n"
16        "-H --libtrace-help     Print libtrace runtime documentation\n"
17        ,argv0);
18        exit(1);
19}
20
21volatile int done=0;
22
23static void cleanup_signal(int sig)
24{
25        done=1;
26}
27
28int main(int argc, char *argv[])
29{
30       
31        struct libtrace_out_t *output;
32        struct libtrace_t **input;
33        struct libtrace_packet_t **packet;
34        bool *live;
35        int interfaces_per_input=0;
36        bool unique_packets=false;
37        int i=0;
38        uint64_t last_ts=0;
39        struct sigaction sigact;
40
41        while (1) {
42                int option_index;
43                struct option long_options[] = {
44                        { "set-interface",      2, 0, 'i' },
45                        { "unique-packets",     0, 0, 'u' },
46                        { "libtrace-help",      0, 0, 'H' },
47                        { NULL,                 0, 0, 0   },
48                };
49
50                int c=getopt_long(argc, argv, "i::uH",
51                                long_options, &option_index);
52
53                if (c==-1)
54                        break;
55
56                switch (c) {
57                        case 'i':
58                                if (optarg) 
59                                        interfaces_per_input=atoi(optarg);
60                                else
61                                        interfaces_per_input=1;
62                                break;
63                        case 'u': unique_packets=true; break;
64                        case 'H':
65                                  trace_help();
66                                  exit(1);
67                                  break;
68                        default:
69                                fprintf(stderr,"unknown option: %c\n",c);
70                                usage(argv[0]);
71
72                }
73
74        }
75
76        if (optind+2>argc)
77                usage(argv[0]);
78
79        output=trace_create_output(argv[optind++]);
80        if (trace_is_err_output(output)) {
81                trace_perror_output(output,"trace_create_output");
82                return 1;
83        }
84        if (trace_start_output(output)==-1) {
85                trace_perror_output(output,"trace_start_output");
86                return 1;
87        }
88
89        sigact.sa_handler = cleanup_signal;
90        sigemptyset(&sigact.sa_mask);
91        sigact.sa_flags = SA_RESTART;
92
93        sigaction(SIGINT,&sigact,NULL);
94        sigaction(SIGTERM,&sigact,NULL);
95
96        input=calloc((size_t)(argc-optind),sizeof(struct libtrace_t *));
97        packet=calloc((size_t)(argc-optind),sizeof(struct libtrace_packet_t *));
98        live=calloc((size_t)(argc-optind),sizeof(bool));
99        for(i=0;i<argc-optind;++i) {
100                libtrace_t *f;
101                libtrace_packet_t *p;
102                f=trace_create(argv[i+optind]);
103                if (trace_is_err(f)) {
104                        trace_perror(f,"trace_create");
105                        return 1;
106                }
107                if (trace_start(f)==-1) {
108                        trace_perror(f,"trace_start");
109                        return 1;
110                }
111                p=trace_create_packet();
112                input[i]=f;
113                packet[i]=p;
114                if (trace_read_packet(f,packet[i])>0)
115                        live[i]=true;
116        }
117
118        while(1) {
119                uint64_t oldest_ts=0;
120                int oldest=-1;
121                int curr_dir;
122                if (done)
123                        break;
124                for(i=0;i<argc-optind;++i) {
125                        if (!live[i] && input[i]) {
126                                int ret=trace_read_packet(input[i],packet[i]);
127                                if (ret<0) {
128                                        /* Error */
129                                        perror(argv[i+2]);
130                                        trace_destroy(input[i]);
131                                        input[i]=NULL;
132                                }
133                                else if (ret==0) {
134                                        /* EOF */
135                                        trace_destroy(input[i]);
136                                        input[i]=NULL;
137                                }
138                                else
139                                        live[i]=true;
140                        }
141                        if (live[i] && 
142                                (oldest==-1 || 
143                                 oldest_ts>trace_get_erf_timestamp(packet[i]))) {
144                                oldest=i;
145                                oldest_ts=trace_get_erf_timestamp(packet[i]);
146                        }
147                }
148                /* We have run out of packets! */
149                if (oldest==-1) {
150                        break;
151                }
152
153                live[oldest]=false;
154
155                curr_dir = trace_get_direction(packet[oldest]);
156                if (curr_dir != -1 && interfaces_per_input) {
157                        /* If there are more interfaces than
158                         * interfaces_per_input, then clamp at the
159                         * highest input.  This means things should
160                         * end up in "OTHER" or the unused 3rd bin if
161                         * we're lucky */
162                        curr_dir = curr_dir < interfaces_per_input
163                                ? curr_dir
164                                : interfaces_per_input-1;
165
166                        trace_set_direction(packet[oldest],
167                                        oldest*interfaces_per_input
168                                        +curr_dir);
169                }
170
171                if (unique_packets && oldest_ts == last_ts)
172                        continue;
173
174                if (trace_write_packet(output,packet[oldest]) < 0) {
175                        trace_perror_output(output, "trace_write_packet");
176                        break;
177                }
178
179                last_ts=oldest_ts;
180               
181        }
182        trace_destroy_output(output);
183
184        return 0;
185}
Note: See TracBrowser for help on using the repository browser.