root/jlogctl.c

Revision 81ac86a15e3940ff0b787698853fb6a6157f800b, 7.5 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 7 years ago)

initial import with Ecelerity bits removed and some autoconf glue added in. Could certainly use some work on the build/install. Needs shared lib support for multiple platforms

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2001-2006 OmniTI, Inc. All rights reserved
3  *
4  * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF OMNITI
5  * The copyright notice above does not evidence any
6  * actual or intended publication of such source code.
7  *
8  * Redistribution of this material is strictly prohibited.
9  *
10  */
11
12 #include "jlog_config.h"
13 #include "jlog_private.h"
14 #include "getopt_long.h"
15 #include <stdio.h>
16 #if HAVE_ERRNO_H
17 #include <errno.h>
18 #endif
19 #if HAVE_DIRENT_H
20 #include <dirent.h>
21 #endif
22
23 static int verbose = 0;
24 static int show_progress = 0;
25 static int show_subscribers = 0;
26 static int show_files = 0;
27 static int show_index_info = 0;
28 static int analyze_datafiles = 0;
29 static int repair_datafiles = 0;
30 static int cleanup = 0;
31 static int quiet = 0;
32 static char *add_subscriber = NULL;
33 static char *remove_subscriber = NULL;
34
35 static void usage(const char *prog) {
36   printf("Usage:\n    %s <options> logpath1 [logpath2 [...]]\n",
37          prog);
38   printf("\t-a <sub>:\tAdd <sub> as a log subscriber\n");
39   printf("\t-e <sub>:\tErase <sub> as a log subscriber\n");
40   printf("\t-p <sub>:\tShow the perspective of the subscriber <sub>\n");
41   printf("\t      -l:\tList all log segments with sizes and readers\n");
42   printf("\t      -i:\tList index information\n");
43   printf("\t      -c:\tClean all log segments with no pending readers\n");
44   printf("\t      -s:\tShow all subscribers\n");
45   printf("\t      -d:\tAnalyze datafiles\n");
46   printf("\t      -r:\tAnalyze datafiles and repair if needed\n");
47   printf("\t      -v:\tVerbose output\n");
48   printf("\nWARNING: the -r option can't be used on jlogs that are "
49          "open by another process\n");
50 }
51 static int is_datafile(const char *f, u_int32_t *logid) {
52   int i;
53   u_int32_t l = 0;
54   for(i=0; i<8; i++) {
55     if((f[i] >= '0' && f[i] <= '9') ||
56        (f[i] >= 'a' && f[i] <= 'f')) {
57       l <<= 4;
58       l |= (f[i] < 'a') ? (f[i] - '0') : (f[i] - 'a' + 10);
59     }
60     else
61       return 0;
62   }
63   if(f[i] != '\0') return 0;
64   if(logid) *logid = l;
65   return 1;
66 }
67 static void analyze_datafile(jlog_ctx *ctx, u_int32_t logid) {
68   char idxfile[MAXPATHLEN];
69
70   if (jlog_inspect_datafile(ctx, logid) > 0) {
71     fprintf(stderr, "One or more errors were found.\n");
72     if(repair_datafiles) {
73       jlog_repair_datafile(ctx, logid);
74       fprintf(stderr,
75               "Log file reconstructed, deleting the corresponding idx file.\n");
76       STRSETDATAFILE(ctx, idxfile, logid);
77       strcat(idxfile, INDEX_EXT);
78       unlink(idxfile);
79     }
80   }
81 }
82 static void process_jlog(const char *file, const char *sub) {
83   jlog_ctx *log;
84   log = jlog_new(file);
85
86   if(add_subscriber) {
87     if(jlog_ctx_add_subscriber(log, add_subscriber, JLOG_BEGIN)) {
88       fprintf(stderr, "Could not add subscriber '%s': %s\n", add_subscriber,
89               jlog_ctx_err_string(log));
90     } else {
91       if(!quiet) printf("Added subscriber '%s'\n", add_subscriber);
92     }
93   }
94   if(remove_subscriber) {
95     if(jlog_ctx_remove_subscriber(log, remove_subscriber) <= 0) {
96       fprintf(stderr, "Could not erase subscriber '%s': %s\n",
97               remove_subscriber, jlog_ctx_err_string(log));
98     } else {
99       if(!quiet) printf("Erased subscriber '%s'\n", remove_subscriber);
100     }
101   }
102   if(!sub) {
103     if(jlog_ctx_open_writer(log)) {
104       fprintf(stderr, "error opening '%s'\n", file);
105       return;
106     }
107   } else {
108     if(jlog_ctx_open_reader(log, sub)) {
109       fprintf(stderr, "error opening '%s'\n", file);
110       return;
111     }
112   }
113   if(show_progress) {
114     jlog_id id, id2, id3;
115     char buff[20], buff2[20], buff3[20];
116     jlog_get_checkpoint(log, sub, &id);
117     if(jlog_ctx_last_log_id(log, &id3)) {
118       fprintf(stderr, "jlog_error: %s\n", jlog_ctx_err_string(log));
119       fprintf(stderr, "error callign jlog_ctx_last_log_id\n");
120     }
121     jlog_snprint_logid(buff, sizeof(buff), &id);
122     jlog_snprint_logid(buff3, sizeof(buff3), &id3);
123     if(!quiet) printf("--------------------\n");
124     if(!quiet) printf("  Perspective of the '%s' subscriber\n", sub);
125     if(!quiet) printf("    current checkpoint: %s\n", buff);
126     if(!quiet) printf("Last write: %s\n", buff3);
127     if(jlog_ctx_read_interval(log, &id, &id2) < 0) {
128       fprintf(stderr, "jlog_error: %s\n", jlog_ctx_err_string(log));
129     }
130     jlog_snprint_logid(buff, sizeof(buff), &id);
131     jlog_snprint_logid(buff2, sizeof(buff2), &id2);
132     if(!quiet) printf("\t     next interval: [%s, %s]\n", buff, buff2);
133     if(!quiet) printf("--------------------\n\n");
134   }
135   if(show_subscribers) {
136     char **list;
137     int i;
138     jlog_ctx_list_subscribers(log, &list);
139     for(i=0; list[i]; i++) {
140       jlog_id id;
141       char buff[20];
142       jlog_get_checkpoint(log, list[i], &id);
143       jlog_snprint_logid(buff, sizeof(buff), &id);
144       if(!quiet) printf("\t%32s @ %s\n", list[i], buff);
145     }
146     jlog_ctx_list_subscribers_dispose(log, list);
147   }
148   if(show_files) {
149     DIR *dir;
150     struct dirent *de;
151     dir = opendir(file);
152     if(!dir) {
153       fprintf(stderr, "error opening '%s'\n", file);
154       return;
155     }
156     while((de = readdir(dir)) != NULL) {
157       u_int32_t logid;
158       if(is_datafile(de->d_name, &logid)) {
159         char fullfile[MAXPATHLEN];
160         char fullidx[MAXPATHLEN];
161         struct stat st;
162         int readers;
163         snprintf(fullfile, sizeof(fullfile), "%s/%s", file, de->d_name);
164         snprintf(fullidx, sizeof(fullidx), "%s/%s" INDEX_EXT, file, de->d_name);
165         if(stat(fullfile, &st)) {
166           if(!quiet) printf("\t%8s [error statting file: %s\n", de->d_name, strerror(errno));
167         } else {
168           readers = __jlog_pending_readers(log, logid);
169           if(!quiet) printf("\t%8s [%9llu bytes] %d pending readers\n",
170                             de->d_name, st.st_size, readers);
171           if(show_index_info && !quiet) {
172             struct stat sb;
173             if (stat(fullidx, &sb)) {
174               printf("\t\t idx: none\n");
175             } else {
176               u_int32_t marker;
177               int closed;
178               if (jlog_idx_details(log, logid, &marker, &closed)) {
179                 printf("\t\t idx: error\n");
180               } else {
181                 printf("\t\t idx: %u messages (%08x), %s\n",
182                        marker, marker, closed?"closed":"open");
183               }
184             }
185           }
186           if (analyze_datafiles) analyze_datafile(log, logid);
187           if((readers == 0) && cleanup) {
188             unlink(fullfile);
189             unlink(fullidx);
190           }
191         }
192       }
193     }
194     closedir(dir);
195   }
196   jlog_ctx_close(log);
197 }
198 int main(int argc, char **argv) {
199   int i, c;
200   int option_index = 0;
201   char *subscriber = NULL;
202   while((c = getopt_long(argc, argv, "a:e:dsilrcp:v",
203                          NULL, &option_index)) != EOF) {
204     switch(c) {
205      case 'v':
206       verbose = 1;
207       break;
208      case 'i':
209       show_files = 1;
210       show_index_info = 1;
211       break;
212      case 'r':
213       show_files = 1;
214       analyze_datafiles = 1;
215       repair_datafiles = 1;
216       break;
217      case 'd':
218       show_files = 1;
219       analyze_datafiles = 1;
220       break;
221      case 'a':
222       add_subscriber = optarg;
223       break;
224      case 'e':
225       remove_subscriber = optarg;
226       break;
227      case 'p':
228       show_progress = 1;
229       subscriber = optarg;
230       break;
231      case 's':
232       show_subscribers = 1;
233       break;
234      case 'c':
235       show_files = 1;
236       quiet = 1;
237       cleanup = 1;
238       break;
239      case 'l':
240       show_files = 1;
241       break;
242      default:
243       usage(argv[0]);
244       exit(-1);
245     }
246   }
247   if(optind == argc) {
248     usage(argv[0]);
249     exit(-1);
250   }
251   for(i=optind; i<argc; i++) {
252     if(!quiet) printf("%s\n", argv[i]);
253     process_jlog(argv[i], subscriber);
254   }
255   return 0;
256 }
Note: See TracBrowser for help on using the browser.