root/jlogctl.c

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

no functional changes, just remove compiler warnings

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