source: tools/tracemerge/tracemerge.c @ ba91618

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ba91618 was ba91618, checked in by Shane Alcock <salcock@…>, 11 years ago
  • Updated manpages for traceanon and tracemerge to reflect new -Z option.
  • Attempted to add some consistency in the naming of long options for -z and -Z across tools
  • Property mode set to 100644
File size: 6.2 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#include <string.h>
9
10static void usage(char *argv0)
11{
12        fprintf(stderr,"Usage:\n"
13        "%s flags outputuri traceuri [traceuri...]\n"
14        "-i [interfaces_per_input] --set-interface [interfaces_per_input]\n"
15        "                       Each trace is allocated an interface. Default leaves this flag as\n"
16        "                       read from the original traces, if appropriate\n"
17        "-u --unique-packets    Discard duplicate packets\n"
18        "-z level --compress-level level\n"
19        "                       Compression level\n"
20        "-Z method --compress-type method\n"
21        "                       Compression method\n"
22        "-H --libtrace-help     Print libtrace runtime documentation\n"
23        ,argv0);
24        exit(1);
25}
26
27volatile int done=0;
28
29static void cleanup_signal(int sig UNUSED)
30{
31        done=1;
32}
33
34int main(int argc, char *argv[])
35{
36       
37        struct libtrace_out_t *output;
38        struct libtrace_t **input;
39        struct libtrace_packet_t **packet;
40        bool *live;
41        int interfaces_per_input=0;
42        bool unique_packets=false;
43        int i=0;
44        uint64_t last_ts=0;
45        struct sigaction sigact;
46        int compression=-1;
47        char *compress_type_str = NULL;
48        trace_option_compresstype_t compress_type = TRACE_OPTION_COMPRESSTYPE_NONE;
49
50        while (1) {
51                int option_index;
52                struct option long_options[] = {
53                        { "set-interface",      2, 0, 'i' },
54                        { "unique-packets",     0, 0, 'u' },
55                        { "libtrace-help",      0, 0, 'H' },
56                        { "compress-level",     1, 0, 'z' },
57                        { "compress-type",      1, 0, 'Z' },
58                        { NULL,                 0, 0, 0   },
59                };
60
61                int c=getopt_long(argc, argv, "i::uHz:Z:",
62                                long_options, &option_index);
63
64                if (c==-1)
65                        break;
66
67                switch (c) {
68                        case 'i':
69                                if (optarg) 
70                                        interfaces_per_input=atoi(optarg);
71                                else
72                                        interfaces_per_input=1;
73                                break;
74                        case 'u': unique_packets=true; break;
75                        case 'H':
76                                  trace_help();
77                                  exit(1);
78                                  break;
79                        case 'z':
80                                compression = atoi(optarg);
81                                if (compression<0 || compression>9) {
82                                        fprintf(stderr,"Compression level must be between 0 and 9\n");
83                                        usage(argv[0]);
84                                }
85                                break;
86
87                        case 'Z':
88                                compress_type_str = optarg;
89                                break;
90                        default:
91                                fprintf(stderr,"unknown option: %c\n",c);
92                                usage(argv[0]);
93
94                }
95
96        }
97
98        if (optind+2>argc)
99                usage(argv[0]);
100
101        if (compress_type_str == NULL && compression >= 0) {
102                fprintf(stderr, "Compression level set, but no compression type was defined, setting to gzip\n");
103                compress_type = TRACE_OPTION_COMPRESSTYPE_ZLIB;
104        }
105
106        else if (compress_type_str == NULL) {
107                /* If a level or type is not specified, use the "none"
108                 * compression module */
109                compress_type = TRACE_OPTION_COMPRESSTYPE_NONE;
110        }
111
112        /* I decided to be fairly generous in what I accept for the
113         * compression type string */
114        else if (strncmp(compress_type_str, "gz", 2) == 0 ||
115                        strncmp(compress_type_str, "zlib", 4) == 0) {
116                compress_type = TRACE_OPTION_COMPRESSTYPE_ZLIB;
117        } else if (strncmp(compress_type_str, "bz", 2) == 0) {
118                compress_type = TRACE_OPTION_COMPRESSTYPE_BZ2;
119        } else if (strncmp(compress_type_str, "lzo", 3) == 0) {
120                compress_type = TRACE_OPTION_COMPRESSTYPE_LZO;
121        } else if (strncmp(compress_type_str, "no", 2) == 0) {
122                compress_type = TRACE_OPTION_COMPRESSTYPE_NONE;
123        } else {
124                fprintf(stderr, "Unknown compression type: %s\n",
125                        compress_type_str);
126                return 1;
127        }
128
129
130        output=trace_create_output(argv[optind++]);
131        if (trace_is_err_output(output)) {
132                trace_perror_output(output,"trace_create_output");
133                return 1;
134        }
135
136        if (compression >= 0 && 
137                        trace_config_output(output, 
138                        TRACE_OPTION_OUTPUT_COMPRESS, &compression) == -1) {
139                trace_perror_output(output,"Unable to set compression level");
140                return 1;
141        }
142
143        if (trace_config_output(output, TRACE_OPTION_OUTPUT_COMPRESSTYPE,
144                        &compress_type) == -1) {
145                trace_perror_output(output, "Unable to set compression method");
146                return 1;
147        }
148
149        if (trace_start_output(output)==-1) {
150                trace_perror_output(output,"trace_start_output");
151                return 1;
152        }
153
154        sigact.sa_handler = cleanup_signal;
155        sigemptyset(&sigact.sa_mask);
156        sigact.sa_flags = SA_RESTART;
157
158        sigaction(SIGINT,&sigact,NULL);
159        sigaction(SIGTERM,&sigact,NULL);
160
161        input=calloc((size_t)(argc-optind),sizeof(struct libtrace_t *));
162        packet=calloc((size_t)(argc-optind),sizeof(struct libtrace_packet_t *));
163        live=calloc((size_t)(argc-optind),sizeof(bool));
164        for(i=0;i<argc-optind;++i) {
165                libtrace_t *f;
166                libtrace_packet_t *p;
167                f=trace_create(argv[i+optind]);
168                if (trace_is_err(f)) {
169                        trace_perror(f,"trace_create");
170                        return 1;
171                }
172                if (trace_start(f)==-1) {
173                        trace_perror(f,"trace_start");
174                        return 1;
175                }
176                p=trace_create_packet();
177                input[i]=f;
178                packet[i]=p;
179                if (trace_read_packet(f,packet[i])>0)
180                        live[i]=true;
181        }
182
183        while(1) {
184                uint64_t oldest_ts=0;
185                int oldest=-1;
186                int curr_dir;
187                if (done)
188                        break;
189                for(i=0;i<argc-optind;++i) {
190                        if (!live[i] && input[i]) {
191                                int ret=trace_read_packet(input[i],packet[i]);
192                                if (ret<0) {
193                                        /* Error */
194                                        trace_perror(input[i], "%s", argv[i+2]);
195                                        trace_destroy(input[i]);
196                                        input[i]=NULL;
197                                }
198                                else if (ret==0) {
199                                        /* EOF */
200                                        trace_destroy(input[i]);
201                                        input[i]=NULL;
202                                }
203                                else
204                                        live[i]=true;
205                        }
206                        if (live[i] && 
207                                (oldest==-1 || 
208                                 oldest_ts>trace_get_erf_timestamp(packet[i]))) {
209                                oldest=i;
210                                oldest_ts=trace_get_erf_timestamp(packet[i]);
211                        }
212                }
213                /* We have run out of packets! */
214                if (oldest==-1) {
215                        break;
216                }
217
218                live[oldest]=false;
219
220                curr_dir = trace_get_direction(packet[oldest]);
221                if (curr_dir != -1 && interfaces_per_input) {
222                        /* If there are more interfaces than
223                         * interfaces_per_input, then clamp at the
224                         * highest input.  This means things should
225                         * end up in "OTHER" or the unused 3rd bin if
226                         * we're lucky */
227                        curr_dir = curr_dir < interfaces_per_input
228                                ? curr_dir
229                                : interfaces_per_input-1;
230
231                        trace_set_direction(packet[oldest],
232                                        oldest*interfaces_per_input
233                                        +curr_dir);
234                }
235
236                if (unique_packets && oldest_ts == last_ts)
237                        continue;
238
239                if (trace_write_packet(output,packet[oldest]) < 0) {
240                        trace_perror_output(output, "trace_write_packet");
241                        break;
242                }
243
244                last_ts=oldest_ts;
245               
246        }
247        trace_destroy_output(output);
248
249        return 0;
250}
Note: See TracBrowser for help on using the repository browser.