source: tools/tracemerge/tracemerge.c @ 341c38f

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 341c38f was 17f954f, checked in by Shane Alcock <salcock@…>, 7 years ago

Add LZMA output support to libtrace tools

Add a configuration option for LZMA output as well.

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