source: tools/tracemerge/tracemerge.c @ a8f2692

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

Tidy up a bazillion tiny warnings

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