~ubuntu-branches/ubuntu/vivid/cctools/vivid

« back to all changes in this revision

Viewing changes to dttools/src/debug.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2011-05-07 09:05:00 UTC
  • Revision ID: james.westby@ubuntu.com-20110507090500-lqpmdtwndor6e7os
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (C) 2003-2004 Douglas Thain and the University of Wisconsin
 
3
Copyright (C) 2005- The University of Notre Dame
 
4
This software is distributed under the GNU General Public License.
 
5
See the file COPYING for details.
 
6
*/
 
7
 
 
8
#include "debug.h"
 
9
#include "domain_name_cache.h"
 
10
#include "macros.h"
 
11
#include "stringtools.h"
 
12
#include "full_io.h"
 
13
#include "xmalloc.h"
 
14
#include "full_io.h"
 
15
 
 
16
#include <assert.h>
 
17
#include <stdlib.h>
 
18
#include <stdarg.h>
 
19
#include <stdio.h>
 
20
#include <unistd.h>
 
21
#include <string.h>
 
22
#include <signal.h>
 
23
#include <sys/time.h>
 
24
#include <sys/stat.h>
 
25
#include <fcntl.h>
 
26
#include <errno.h>
 
27
#include <time.h>
 
28
#ifdef HAS_ALLOCA_H
 
29
#include <alloca.h>
 
30
#endif
 
31
 
 
32
static int debug_fd = 2;
 
33
static char *debug_file = 0;
 
34
static int debug_file_size = 10485760;
 
35
static const char *program_name = "";
 
36
static INT64_T debug_flags = D_NOTICE;
 
37
static pid_t (*debug_getpid)() = getpid;
 
38
 
 
39
struct flag_info {
 
40
        const char *name;
 
41
        INT64_T flag;
 
42
};
 
43
 
 
44
static struct flag_info table[] = {
 
45
        { "syscall",  D_SYSCALL },
 
46
        { "notice",   D_NOTICE },
 
47
        { "channel",  D_CHANNEL },
 
48
        { "process",  D_PROCESS },
 
49
        { "resolve",  D_RESOLVE },
 
50
        { "libcall",  D_LIBCALL },
 
51
        { "tcp",      D_TCP },
 
52
        { "dns",      D_DNS },
 
53
        { "auth",     D_AUTH },
 
54
        { "local",    D_LOCAL },
 
55
        { "http",     D_HTTP },
 
56
        { "ftp",      D_FTP },
 
57
        { "nest",     D_NEST },
 
58
        { "chirp",    D_CHIRP },
 
59
        { "landlord", D_LANDLORD },
 
60
        { "multi",    D_MULTI },
 
61
        { "dcap",     D_DCAP },
 
62
        { "rfio",     D_RFIO },
 
63
        { "glite",    D_GLITE },
 
64
        { "lfc",      D_LFC },
 
65
        { "gfal",     D_GFAL },
 
66
        { "grow",     D_GROW },
 
67
        { "pstree",   D_PSTREE },
 
68
        { "alloc" ,   D_ALLOC },
 
69
        { "cache",    D_CACHE },
 
70
        { "poll",     D_POLL },
 
71
        { "hdfs",     D_HDFS },
 
72
        { "bxgrid",   D_BXGRID },
 
73
        { "debug",    D_DEBUG },
 
74
        { "login",    D_LOGIN },
 
75
        { "irods",    D_IRODS },
 
76
        { "wq",       D_WQ },
 
77
        { "user",     D_USER},
 
78
        { "xrootd",   D_XROOTD},
 
79
        { "remote",   D_REMOTE },
 
80
        { "all",      ~0 },
 
81
        { "time",     0 },      /* backwards compatibility */
 
82
        { "pid",     0 },       /* backwards compatibility */
 
83
        { 0,0 }
 
84
};
 
85
 
 
86
struct fatal_callback {
 
87
        void (*callback) ();
 
88
        struct fatal_callback *next;
 
89
};
 
90
 
 
91
struct fatal_callback * fatal_callback_list = 0;
 
92
 
 
93
 
 
94
int  debug_flags_set( const char *flagname )
 
95
{
 
96
        struct flag_info *i;
 
97
 
 
98
        for(i=table;i->name;i++) {
 
99
                if(!strcmp(flagname,i->name)) {
 
100
                        debug_flags |= i->flag;
 
101
                        return 1;
 
102
                }
 
103
        }
 
104
 
 
105
        return 0;
 
106
}
 
107
 
 
108
void debug_flags_print( FILE *stream )
 
109
{
 
110
        int i;
 
111
 
 
112
        for(i=0;table[i].name;i++) {
 
113
                fprintf(stream,"%s ",table[i].name);
 
114
        }
 
115
}
 
116
 
 
117
void debug_set_flag_name( INT64_T flag, const char *name )
 
118
{
 
119
        struct flag_info *i;
 
120
 
 
121
        for(i=table;i->name;i++) {
 
122
                if (i->flag&flag) {
 
123
                        i->name = name; 
 
124
                        break;
 
125
                }
 
126
        }
 
127
}
 
128
 
 
129
static const char * flag_to_name( INT64_T flag )
 
130
{
 
131
        struct flag_info *i;
 
132
 
 
133
        for(i=table;i->name;i++) {
 
134
                if(i->flag&flag) return i->name;
 
135
        }
 
136
 
 
137
        return "debug";
 
138
}
 
139
 
 
140
static void do_debug( int is_fatal, INT64_T flags, const char *fmt, va_list args )
 
141
{
 
142
        char newfmt[65536];
 
143
        char buffer[65536];
 
144
        int length;
 
145
 
 
146
        struct timeval tv;
 
147
        struct tm *tm;
 
148
 
 
149
        gettimeofday(&tv,0);
 
150
        tm = localtime(&tv.tv_sec);
 
151
 
 
152
        sprintf(newfmt,"%04d/%02d/%02d %02d:%02d:%02d.%02ld [%d] %s: %s: %s",
 
153
               tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,(long)tv.tv_usec/10000,(int)debug_getpid(),program_name,is_fatal ? "fatal " : flag_to_name(flags),fmt);
 
154
 
 
155
        vsprintf(buffer,newfmt,args);
 
156
        string_chomp(buffer);
 
157
        strcat(buffer,"\n");
 
158
        length = strlen(buffer);
 
159
 
 
160
        if(debug_file) {
 
161
                struct stat info;
 
162
 
 
163
                fstat(debug_fd,&info);
 
164
                if(info.st_size >= debug_file_size && debug_file_size!=0) {
 
165
                        close(debug_fd);
 
166
 
 
167
                        if(stat(debug_file,&info)==0) {
 
168
                                if(info.st_size >= debug_file_size) {
 
169
                                        char *newname = alloca(strlen(debug_file)+5);
 
170
                                        sprintf(newname,"%s.old",debug_file);
 
171
                                        rename(debug_file,newname);
 
172
                                }
 
173
                        }
 
174
 
 
175
                        debug_fd = open(debug_file,O_CREAT|O_TRUNC|O_WRONLY,0777);
 
176
                        if(debug_fd<0) fatal("couldn't open %s: %s",debug_file,strerror(errno));
 
177
                }
 
178
        }
 
179
 
 
180
        full_write(debug_fd,buffer,length);
 
181
}
 
182
 
 
183
void debug( INT64_T flags, const char *fmt, ... )
 
184
{
 
185
        va_list args;
 
186
        va_start(args,fmt);
 
187
 
 
188
        if(flags&debug_flags) {
 
189
                int save_errno = errno;
 
190
                do_debug(0,flags,fmt,args);
 
191
                errno = save_errno;
 
192
        }
 
193
 
 
194
        va_end(args);
 
195
}
 
196
 
 
197
void fatal( const char *fmt, ... ) 
 
198
{
 
199
        struct fatal_callback *f;
 
200
        va_list args;
 
201
        va_start(args,fmt);
 
202
 
 
203
        do_debug(1,0,fmt,args);
 
204
 
 
205
        for(f=fatal_callback_list;f;f=f->next) {
 
206
                f->callback();
 
207
        }
 
208
 
 
209
        while(1) {
 
210
                kill(getpid(),SIGTERM);
 
211
                kill(getpid(),SIGKILL);
 
212
        }
 
213
 
 
214
        va_end(args);
 
215
}
 
216
 
 
217
void debug_config_fatal( void (*callback) () )
 
218
{
 
219
        struct fatal_callback *f;
 
220
        f = xxmalloc(sizeof(*f));
 
221
        f->callback = callback;
 
222
        f->next = fatal_callback_list;
 
223
        fatal_callback_list = f;
 
224
}
 
225
 
 
226
void debug_config( const char *name )
 
227
{
 
228
        const char *n = strdup(name);
 
229
 
 
230
        program_name = strrchr(n,'/');
 
231
        if(program_name) {
 
232
                program_name++;
 
233
        } else {
 
234
                program_name = n;
 
235
        }
 
236
}
 
237
 
 
238
void debug_config_file( const char *f )
 
239
{
 
240
        if(debug_file) {
 
241
                free(debug_file);
 
242
                debug_file = 0;
 
243
        }
 
244
 
 
245
        if(f) {
 
246
                if (*f == '/')
 
247
                        debug_file = strdup(f);
 
248
                else {
 
249
                        char path[8192];
 
250
                        if (getcwd(path, sizeof(path)) == NULL) assert(0);
 
251
                        assert(strlen(path) + strlen(f) + 1 < 8192);
 
252
                        strcat(path, "/");
 
253
                        strcat(path, f);
 
254
                        debug_file = strdup(path);
 
255
                }
 
256
                debug_fd = open(f,O_CREAT|O_APPEND|O_WRONLY,0777);
 
257
                if(debug_fd<0) fatal("couldn't open %s: %s",f,strerror(errno));         
 
258
        } else {
 
259
                debug_fd = 2;
 
260
        }
 
261
}
 
262
 
 
263
void debug_config_file_size( int size )
 
264
{
 
265
        debug_file_size = size;
 
266
}
 
267
 
 
268
void debug_config_getpid( pid_t (*getpidfunc)() )
 
269
{
 
270
        debug_getpid = getpidfunc;
 
271
}
 
272
 
 
273
int debug_flags_clear()
 
274
{
 
275
        INT64_T result = debug_flags;
 
276
        debug_flags = 0;
 
277
        return result;  
 
278
}
 
279
 
 
280
void debug_flags_restore( INT64_T fl )
 
281
{
 
282
        debug_flags = fl;
 
283
}
 
284