root/jlogctl.c

Revision 9b8a62c4050371b1896f1b7751c6a4f675dd4e28, 8.8 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 7 years ago)

Offer these files under a new BSD-style license. Yay

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2005-2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *    * Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *    * Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials provided
14  *      with the distribution.
15  *    * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *      of its contributors may be used to endorse or promote products
17  *      derived from this software without specific prior written
18  *      permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "jlog_config.h"
34 #include "jlog_private.h"
35 #include "getopt_long.h"
36 #include <stdio.h>
37 #if HAVE_ERRNO_H
38 #include <errno.h>
39 #endif
40 #if HAVE_DIRENT_H
41 #include <dirent.h>
42 #endif
43
44 static int verbose = 0;
45 static int show_progress = 0;
46 static int show_subscribers = 0;
47 static int show_files = 0;
48 static int show_index_info = 0;
49 static int analyze_datafiles = 0;
50 static int repair_datafiles = 0;
51 static int cleanup = 0;
52 static int quiet = 0;
53 static char *add_subscriber = NULL;
54 static char *remove_subscriber = NULL;
55
56 static void usage(const char *prog) {
57   printf("Usage:\n    %s <options> logpath1 [logpath2 [...]]\n",
58          prog);
59   printf("\t-a <sub>:\tAdd <sub> as a log subscriber\n");
60   printf("\t-e <sub>:\tErase <sub> as a log subscriber\n");
61   printf("\t-p <sub>:\tShow the perspective of the subscriber <sub>\n");
62   printf("\t      -l:\tList all log segments with sizes and readers\n");
63   printf("\t      -i:\tList index information\n");
64   printf("\t      -c:\tClean all log segments with no pending readers\n");
65   printf("\t      -s:\tShow all subscribers\n");
66   printf("\t      -d:\tAnalyze datafiles\n");
67   printf("\t      -r:\tAnalyze datafiles and repair if needed\n");
68   printf("\t      -v:\tVerbose output\n");
69   printf("\nWARNING: the -r option can't be used on jlogs that are "
70          "open by another process\n");
71 }
72 static int is_datafile(const char *f, u_int32_t *logid) {
73   int i;
74   u_int32_t l = 0;
75   for(i=0; i<8; i++) {
76     if((f[i] >= '0' && f[i] <= '9') ||
77        (f[i] >= 'a' && f[i] <= 'f')) {
78       l <<= 4;
79       l |= (f[i] < 'a') ? (f[i] - '0') : (f[i] - 'a' + 10);
80     }
81     else
82       return 0;
83   }
84   if(f[i] != '\0') return 0;
85   if(logid) *logid = l;
86   return 1;
87 }
88 static void analyze_datafile(jlog_ctx *ctx, u_int32_t logid) {
89   char idxfile[MAXPATHLEN];
90
91   if (jlog_inspect_datafile(ctx, logid) > 0) {
92     fprintf(stderr, "One or more errors were found.\n");
93     if(repair_datafiles) {
94       jlog_repair_datafile(ctx, logid);
95       fprintf(stderr,
96               "Log file reconstructed, deleting the corresponding idx file.\n");
97       STRSETDATAFILE(ctx, idxfile, logid);
98       strcat(idxfile, INDEX_EXT);
99       unlink(idxfile);
100     }
101   }
102 }
103 static void process_jlog(const char *file, const char *sub) {
104   jlog_ctx *log;
105   log = jlog_new(file);
106
107   if(add_subscriber) {
108     if(jlog_ctx_add_subscriber(log, add_subscriber, JLOG_BEGIN)) {
109       fprintf(stderr, "Could not add subscriber '%s': %s\n", add_subscriber,
110               jlog_ctx_err_string(log));
111     } else {
112       if(!quiet) printf("Added subscriber '%s'\n", add_subscriber);
113     }
114   }
115   if(remove_subscriber) {
116     if(jlog_ctx_remove_subscriber(log, remove_subscriber) <= 0) {
117       fprintf(stderr, "Could not erase subscriber '%s': %s\n",
118               remove_subscriber, jlog_ctx_err_string(log));
119     } else {
120       if(!quiet) printf("Erased subscriber '%s'\n", remove_subscriber);
121     }
122   }
123   if(!sub) {
124     if(jlog_ctx_open_writer(log)) {
125       fprintf(stderr, "error opening '%s'\n", file);
126       return;
127     }
128   } else {
129     if(jlog_ctx_open_reader(log, sub)) {
130       fprintf(stderr, "error opening '%s'\n", file);
131       return;
132     }
133   }
134   if(show_progress) {
135     jlog_id id, id2, id3;
136     char buff[20], buff2[20], buff3[20];
137     jlog_get_checkpoint(log, sub, &id);
138     if(jlog_ctx_last_log_id(log, &id3)) {
139       fprintf(stderr, "jlog_error: %s\n", jlog_ctx_err_string(log));
140       fprintf(stderr, "error callign jlog_ctx_last_log_id\n");
141     }
142     jlog_snprint_logid(buff, sizeof(buff), &id);
143     jlog_snprint_logid(buff3, sizeof(buff3), &id3);
144     if(!quiet) printf("--------------------\n");
145     if(!quiet) printf("  Perspective of the '%s' subscriber\n", sub);
146     if(!quiet) printf("    current checkpoint: %s\n", buff);
147     if(!quiet) printf("Last write: %s\n", buff3);
148     if(jlog_ctx_read_interval(log, &id, &id2) < 0) {
149       fprintf(stderr, "jlog_error: %s\n", jlog_ctx_err_string(log));
150     }
151     jlog_snprint_logid(buff, sizeof(buff), &id);
152     jlog_snprint_logid(buff2, sizeof(buff2), &id2);
153     if(!quiet) printf("\t     next interval: [%s, %s]\n", buff, buff2);
154     if(!quiet) printf("--------------------\n\n");
155   }
156   if(show_subscribers) {
157     char **list;
158     int i;
159     jlog_ctx_list_subscribers(log, &list);
160     for(i=0; list[i]; i++) {
161       jlog_id id;
162       char buff[20];
163       jlog_get_checkpoint(log, list[i], &id);
164       jlog_snprint_logid(buff, sizeof(buff), &id);
165       if(!quiet) printf("\t%32s @ %s\n", list[i], buff);
166     }
167     jlog_ctx_list_subscribers_dispose(log, list);
168   }
169   if(show_files) {
170     DIR *dir;
171     struct dirent *de;
172     dir = opendir(file);
173     if(!dir) {
174       fprintf(stderr, "error opening '%s'\n", file);
175       return;
176     }
177     while((de = readdir(dir)) != NULL) {
178       u_int32_t logid;
179       if(is_datafile(de->d_name, &logid)) {
180         char fullfile[MAXPATHLEN];
181         char fullidx[MAXPATHLEN];
182         struct stat st;
183         int readers;
184         snprintf(fullfile, sizeof(fullfile), "%s/%s", file, de->d_name);
185         snprintf(fullidx, sizeof(fullidx), "%s/%s" INDEX_EXT, file, de->d_name);
186         if(stat(fullfile, &st)) {
187           if(!quiet) printf("\t%8s [error statting file: %s\n", de->d_name, strerror(errno));
188         } else {
189           readers = __jlog_pending_readers(log, logid);
190           if(!quiet) printf("\t%8s [%9llu bytes] %d pending readers\n",
191                             de->d_name, st.st_size, readers);
192           if(show_index_info && !quiet) {
193             struct stat sb;
194             if (stat(fullidx, &sb)) {
195               printf("\t\t idx: none\n");
196             } else {
197               u_int32_t marker;
198               int closed;
199               if (jlog_idx_details(log, logid, &marker, &closed)) {
200                 printf("\t\t idx: error\n");
201               } else {
202                 printf("\t\t idx: %u messages (%08x), %s\n",
203                        marker, marker, closed?"closed":"open");
204               }
205             }
206           }
207           if (analyze_datafiles) analyze_datafile(log, logid);
208           if((readers == 0) && cleanup) {
209             unlink(fullfile);
210             unlink(fullidx);
211           }
212         }
213       }
214     }
215     closedir(dir);
216   }
217   jlog_ctx_close(log);
218 }
219 int main(int argc, char **argv) {
220   int i, c;
221   int option_index = 0;
222   char *subscriber = NULL;
223   while((c = getopt_long(argc, argv, "a:e:dsilrcp:v",
224                          NULL, &option_index)) != EOF) {
225     switch(c) {
226      case 'v':
227       verbose = 1;
228       break;
229      case 'i':
230       show_files = 1;
231       show_index_info = 1;
232       break;
233      case 'r':
234       show_files = 1;
235       analyze_datafiles = 1;
236       repair_datafiles = 1;
237       break;
238      case 'd':
239       show_files = 1;
240       analyze_datafiles = 1;
241       break;
242      case 'a':
243       add_subscriber = optarg;
244       break;
245      case 'e':
246       remove_subscriber = optarg;
247       break;
248      case 'p':
249       show_progress = 1;
250       subscriber = optarg;
251       break;
252      case 's':
253       show_subscribers = 1;
254       break;
255      case 'c':
256       show_files = 1;
257       quiet = 1;
258       cleanup = 1;
259       break;
260      case 'l':
261       show_files = 1;
262       break;
263      default:
264       usage(argv[0]);
265       exit(-1);
266     }
267   }
268   if(optind == argc) {
269     usage(argv[0]);
270     exit(-1);
271   }
272   for(i=optind; i<argc; i++) {
273     if(!quiet) printf("%s\n", argv[i]);
274     process_jlog(argv[i], subscriber);
275   }
276   return 0;
277 }
Note: See TracBrowser for help on using the browser.