source: lib/wandio.c @ d8e4595

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since d8e4595 was a8d184f, checked in by Shane Alcock <salcock@…>, 11 years ago
  • Disabled the directread and directwrite IO options - they're just really broken at the moment and seem more trouble than they're worth
  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
5 * New Zealand.
6 *
7 * Authors: Daniel Lawson
8 *          Perry Lorier
9 *          Shane Alcock
10 *         
11 * All rights reserved.
12 *
13 * This code has been developed by the University of Waikato WAND
14 * research group. For further information please see http://www.wand.net.nz/
15 *
16 * libtrace is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * libtrace is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with libtrace; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 *
30 * $Id$
31 *
32 */
33
34
35#include "config.h"
36#include "wandio.h"
37#include <stdlib.h>
38#include <assert.h>
39#include <errno.h>
40#include <inttypes.h>
41#include <string.h>
42
43/* This file contains the implementation of the libtrace IO API, which format
44 * modules should use to open, read from, write to, seek and close trace files.
45 */
46
47struct compression_type compression_type[]  = {
48        { "GZ",         "gz",   WANDIO_COMPRESS_ZLIB    },
49        { "BZ2",        "bz2",  WANDIO_COMPRESS_BZ2     },
50        { "LZO",        "lzo",  WANDIO_COMPRESS_LZO     },
51        { "NONE",       "",     WANDIO_COMPRESS_NONE    }
52};
53
54int keep_stats = 0;
55int force_directio_write = 0;
56int force_directio_read = 0;
57unsigned int use_threads = -1;
58
59uint64_t read_waits = 0;
60uint64_t write_waits = 0;
61
62/** Parse an option.
63 * stats -- Show summary stats
64 * directwrite -- bypass the diskcache on write
65 * directread -- bypass the diskcache on read
66 * nothreads -- Don't use threads
67 * threads=n -- Use a maximum of 'n' threads for thread farms
68 */
69static void do_option(const char *option)
70{
71        if (*option == '\0') 
72                ;
73        else if (strcmp(option,"stats") == 0)
74                keep_stats = 1;
75        /*
76        else if (strcmp(option,"directwrite") == 0)
77                force_directio_write = 1;
78        else if (strcmp(option,"directread") == 0)
79                force_directio_read  = 1;
80        */
81        else if (strcmp(option,"nothreads") == 0)
82                use_threads = 0;
83        else if (strncmp(option,"threads=",8) == 0)
84                use_threads = atoi(option+8);
85        else {
86                fprintf(stderr,"Unknown libtraceio debug option '%s'\n", option);
87        }
88}
89
90static void parse_env(void)
91{
92        const char *str = getenv("LIBTRACEIO");
93        char option[1024];
94        const char *ip;
95        char *op;
96
97        if (!str)
98                return;
99
100        for(ip=str, op=option; *ip!='\0' && op < option+sizeof(option); ++ip) {
101                if (*ip == ',') {
102                        *op='\0';
103                        do_option(option);
104                        op=option;
105                }
106                else
107                        *(op++) = *ip;
108        }
109        *op='\0';
110        do_option(option);
111}
112
113
114#define READ_TRACE 0
115#define WRITE_TRACE 0
116#define PIPELINE_TRACE 0
117
118#if PIPELINE_TRACE
119#define DEBUG_PIPELINE(x) fprintf(stderr,"PIPELINE: %s\n",x)
120#else
121#define DEBUG_PIPELINE(x)
122#endif
123
124io_t *wandio_create(const char *filename)
125{
126        parse_env();
127
128        /* Use a peeking reader to look at the start of the trace file and
129         * determine what type of compression may have been used to write
130         * the file */
131
132        DEBUG_PIPELINE("stdio");
133        DEBUG_PIPELINE("peek");
134        io_t *io = peek_open(stdio_open(filename));
135        char buffer[1024];
136        int len;
137        if (!io)
138                return NULL;
139        len = wandio_peek(io, buffer, sizeof(buffer));
140#if HAVE_LIBZ
141        /* Auto detect gzip compressed data */
142        if (len>=2 && buffer[0] == '\037' && buffer[1] == '\213') { 
143                DEBUG_PIPELINE("zlib");
144                io = zlib_open(io);
145        }
146        /* Auto detect compress(1) compressed data (gzip can read this) */
147        if (len>=2 && buffer[0] == '\037' && buffer[1] == '\235') {
148                DEBUG_PIPELINE("zlib");
149                io = zlib_open(io);
150        }
151#endif
152#if HAVE_LIBBZ2
153        /* Auto detect bzip compressed data */
154        if (len>=3 && buffer[0] == 'B' && buffer[1] == 'Z' && buffer[2] == 'h') { 
155                DEBUG_PIPELINE("bzip");
156                io = bz_open(io);
157        }
158#endif
159       
160        /* Now open a threaded, peekable reader using the appropriate module
161         * to read the data */
162
163        if (use_threads) {
164                DEBUG_PIPELINE("thread");
165                io = thread_open(io);
166        }
167       
168        DEBUG_PIPELINE("peek");
169        return peek_open(io);
170}
171
172off_t wandio_tell(io_t *io)
173{
174        if (!io->source->tell) {
175                errno = -ENOSYS;
176                return -1;
177        }
178        return io->source->tell(io);
179}
180
181off_t wandio_seek(io_t *io, off_t offset, int whence)
182{
183        if (!io->source->seek) {
184                errno = -ENOSYS;
185                return -1;
186        }
187        return io->source->seek(io,offset,whence);
188}
189
190off_t wandio_read(io_t *io, void *buffer, off_t len)
191{ 
192        off_t ret;
193        ret=io->source->read(io,buffer,len); 
194#if READ_TRACE
195        fprintf(stderr,"%p: read(%s): %d bytes = %d\n",io,io->source->name, (int)len,(int)ret);
196#endif
197        return ret;
198}
199
200off_t wandio_peek(io_t *io, void *buffer, off_t len)
201{
202        off_t ret;
203        assert(io->source->peek); /* If this fails, it means you're calling
204                                   * peek on something that doesn't support
205                                   * peeking.   Push a peek_open() on the io
206                                   * first.
207                                   */
208        ret=io->source->peek(io, buffer, len);
209#if READ_TRACE
210        fprintf(stderr,"%p: peek(%s): %d bytes = %d\n",io,io->source->name, (int)len, (int)ret);
211#endif
212        return ret;
213}
214
215void wandio_destroy(io_t *io)
216{ 
217        if (keep_stats) 
218                fprintf(stderr,"LIBTRACEIO STATS: %"PRIu64" blocks on read\n", read_waits);
219        io->source->close(io); 
220}
221
222iow_t *wandio_wcreate(const char *filename, int compress_type, int compression_level, int flags)
223{
224        iow_t *iow;
225        parse_env();
226
227        assert ( compression_level >= 0 && compression_level <= 9 );
228        assert (compress_type != WANDIO_COMPRESS_MASK);
229
230        iow=stdio_wopen(filename, flags);
231        if (!iow)
232                return NULL;
233
234        /* We prefer zlib if available, otherwise we'll use bzip. If neither
235         * are present, guess we'll just have to write uncompressed */
236#if HAVE_LIBZ
237        if (compression_level != 0 && 
238            compress_type == WANDIO_COMPRESS_ZLIB) {
239                iow = zlib_wopen(iow,compression_level);
240        }
241#endif
242#if HAVE_LIBLZO2
243        else if (compression_level != 0 && 
244            compress_type == WANDIO_COMPRESS_LZO) {
245                iow = lzo_wopen(iow,compression_level);
246        }
247#endif
248#if HAVE_LIBBZ2
249        else if (compression_level != 0 && 
250            compress_type == WANDIO_COMPRESS_BZ2) {
251                iow = bz_wopen(iow,compression_level);
252        }
253#endif
254        /* Open a threaded writer */
255        if (use_threads)
256                return thread_wopen(iow);
257        else
258                return iow;
259}
260
261off_t wandio_wwrite(iow_t *iow, const void *buffer, off_t len)
262{
263#if WRITE_TRACE
264        fprintf(stderr,"wwrite(%s): %d bytes\n",iow->source->name, (int)len);
265#endif
266        return iow->source->write(iow,buffer,len);     
267}
268
269void wandio_wdestroy(iow_t *iow)
270{
271        iow->source->close(iow);
272        if (keep_stats) 
273                fprintf(stderr,"LIBTRACEIO STATS: %"PRIu64" blocks on write\n", write_waits);
274}
275
Note: See TracBrowser for help on using the repository browser.