Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / utils / llog_reader.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2006 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22  /* Interpret configuration llogs */
23
24
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29
30 #include <time.h>
31 #include <liblustre.h>
32 #include <lustre/lustre_idl.h>
33
34 int llog_pack_buffer(int fd, struct llog_log_hdr **llog_buf,
35                      struct llog_rec_hdr ***recs, int *recs_number);
36
37 void print_llog_header(struct llog_log_hdr *llog_buf);
38 void print_records(struct llog_rec_hdr **recs_buf,int rec_number);
39 void llog_unpack_buffer(int fd, struct llog_log_hdr *llog_buf,
40                         struct llog_rec_hdr **recs_buf);
41
42 #define CANCELLED 0x678
43
44 #define PTL_CMD_BASE 100
45 char* portals_command[17]=
46 {
47         "REGISTER_PEER_FD",
48         "CLOSE_CONNECTION",
49         "REGISTER_MYNID",
50         "PUSH_CONNECTION",
51         "GET_CONN",
52         "DEL_PEER",
53         "ADD_PEER",
54         "GET_PEER",
55         "GET_TXDESC",
56         "ADD_ROUTE",
57         "DEL_ROUTE",
58         "GET_ROUTE",
59         "NOTIFY_ROUTER",
60         "ADD_INTERFACE",
61         "DEL_INTERFACE",
62         "GET_INTERFACE",
63         ""
64 };
65
66 int main(int argc, char **argv)
67 {
68         int rc = 0;
69         int fd, rec_number;
70         struct llog_log_hdr *llog_buf = NULL;
71         struct llog_rec_hdr **recs_buf = NULL;
72
73         setlinebuf(stdout);
74
75         if(argc != 2 ){
76                 printf("Usage: llog_reader filename\n");
77                 return -1;
78         }
79
80         fd = open(argv[1],O_RDONLY);
81         if (fd < 0){
82                 printf("Could not open the file %s\n", argv[1]);
83                 goto out;
84         }
85         rc = llog_pack_buffer(fd, &llog_buf, &recs_buf, &rec_number);
86         if (rc < 0) {
87                 printf("Could not pack buffer; rc=%d\n", rc);
88                 goto out_fd;
89         }
90
91         print_llog_header(llog_buf);
92         print_records(recs_buf,rec_number);
93         llog_unpack_buffer(fd,llog_buf,recs_buf);
94 out_fd:
95         close(fd);
96 out:
97         return rc;
98 }
99
100
101
102 int llog_pack_buffer(int fd, struct llog_log_hdr **llog,
103                      struct llog_rec_hdr ***recs,
104                      int *recs_number)
105 {
106         int rc = 0, recs_num,rd;
107         off_t file_size;
108         struct stat st;
109         char *file_buf=NULL, *recs_buf=NULL;
110         struct llog_rec_hdr **recs_pr=NULL;
111         char *ptr=NULL;
112         int i;
113
114         rc = fstat(fd,&st);
115         if (rc < 0){
116                 printf("Get file stat error.\n");
117                 goto out;
118         }
119         file_size = st.st_size;
120
121         file_buf = malloc(file_size);
122         if (file_buf == NULL){
123                 printf("Memory Alloc for file_buf error.\n");
124                 rc = -ENOMEM;
125                 goto out;
126         }
127         *llog = (struct llog_log_hdr*)file_buf;
128
129         rd = read(fd,file_buf,file_size);
130         if (rd < file_size){
131                 printf("Read file error.\n");
132                 rc = -EIO; /*FIXME*/
133                 goto clear_file_buf;
134         }
135
136         /* the llog header not countable here.*/
137         recs_num = le32_to_cpu((*llog)->llh_count)-1;
138
139         recs_buf = malloc(recs_num * sizeof(struct llog_rec_hdr *));
140         if (recs_buf == NULL){
141                 printf("Memory Alloc for recs_buf error.\n");
142                 rc = -ENOMEM;
143                 goto clear_file_buf;
144         }
145         recs_pr = (struct llog_rec_hdr **)recs_buf;
146
147         ptr = file_buf + le32_to_cpu((*llog)->llh_hdr.lrh_len);
148         i = 0;
149
150         while (i < recs_num){
151                 struct llog_rec_hdr *cur_rec = (struct llog_rec_hdr*)ptr;
152                 int idx = le32_to_cpu(cur_rec->lrh_index);
153                 recs_pr[i] = cur_rec;
154
155                 if (ext2_test_bit(idx, (*llog)->llh_bitmap)) {
156                         if (le32_to_cpu(cur_rec->lrh_type) != OBD_CFG_REC) 
157                                 printf("rec #%d type=%x len=%u\n", idx,
158                                        cur_rec->lrh_type, cur_rec->lrh_len);
159                 } else {
160                         printf("Bit %d of %d not set\n", idx, recs_num);
161                         cur_rec->padding = CANCELLED;
162                         /* The header counts only set records */
163                         i--;
164                 }
165                 
166                 ptr += le32_to_cpu(cur_rec->lrh_len);
167                 if ((ptr - file_buf) > file_size) {
168                         printf("The log is corrupt (too big at %d)\n", i);
169                         rc = -EINVAL;
170                         goto clear_recs_buf;
171                 }
172                 i++;
173         }
174
175         *recs = recs_pr;
176         *recs_number = recs_num;
177
178 out:
179         return rc;
180
181 clear_recs_buf:
182         free(recs_buf);
183
184 clear_file_buf:
185         free(file_buf);
186
187         *llog=NULL;
188         goto out;
189 }
190
191 void llog_unpack_buffer(int fd, struct llog_log_hdr *llog_buf,
192                         struct llog_rec_hdr **recs_buf)
193 {
194         free(llog_buf);
195         free(recs_buf);
196         return;
197 }
198
199 void print_llog_header(struct llog_log_hdr *llog_buf)
200 {
201         time_t t;
202
203         printf("Header size : %u\n",
204                le32_to_cpu(llog_buf->llh_hdr.lrh_len));
205
206         t = le64_to_cpu(llog_buf->llh_timestamp);
207         printf("Time : %s", ctime(&t));
208
209         printf("Number of records: %u\n",
210                le32_to_cpu(llog_buf->llh_count)-1);
211
212         printf("Target uuid : %s \n",
213                (char *)(&llog_buf->llh_tgtuuid));
214
215         /* Add the other info you want to view here */
216
217         printf("-----------------------\n");
218         return;
219 }
220
221 static void print_1_cfg(struct lustre_cfg *lcfg)
222 {
223         int i;
224
225         if (lcfg->lcfg_nid)
226                 printf("nid=%s("LPX64")  ", libcfs_nid2str(lcfg->lcfg_nid),
227                        lcfg->lcfg_nid);
228         if (lcfg->lcfg_nal)
229                 printf("nal=%d ", lcfg->lcfg_nal);
230         for (i = 0; i <  lcfg->lcfg_bufcount; i++)
231                 printf("%d:%.*s  ", i, lcfg->lcfg_buflens[i],
232                        (char*)lustre_cfg_buf(lcfg, i));
233         return;
234 }
235
236
237 static void print_setup_cfg(struct lustre_cfg *lcfg)
238 {
239         struct lov_desc *desc;
240
241         if ((lcfg->lcfg_bufcount == 2) &&
242             (lcfg->lcfg_buflens[1] == sizeof(*desc))) {
243                 printf("lov_setup ");
244                 printf("0:%s  ", lustre_cfg_string(lcfg, 0));
245                 printf("1:(struct lov_desc)\n");
246                 desc = (struct lov_desc*)(lustre_cfg_string(lcfg, 1));
247                 printf("\t\tuuid=%s  ", (char*)desc->ld_uuid.uuid);
248                 printf("stripe:cnt=%u ", desc->ld_default_stripe_count);
249                 printf("size="LPU64" ", desc->ld_default_stripe_size);
250                 printf("offset="LPU64" ", desc->ld_default_stripe_offset);
251                 printf("pattern=%#x", desc->ld_pattern);
252         } else {
253                 printf("setup     ");
254                 print_1_cfg(lcfg);
255         }
256         
257         return;
258 }
259
260 void print_lustre_cfg(struct lustre_cfg *lcfg, int *skip)
261 {
262         enum lcfg_command_type cmd = le32_to_cpu(lcfg->lcfg_command);
263
264         if (*skip > 0)
265                 printf("SKIP ");
266
267         switch(cmd){
268         case(LCFG_ATTACH):{
269                 printf("attach    ");
270                 print_1_cfg(lcfg);
271                 break;
272         }
273         case(LCFG_SETUP):{
274                 print_setup_cfg(lcfg);
275                 break;
276         }
277         case(LCFG_DETACH):{
278                 printf("detach    ");
279                 print_1_cfg(lcfg);
280                 break;
281         }
282         case(LCFG_CLEANUP):{
283                 printf("cleanup   ");
284                 print_1_cfg(lcfg);
285                 break;
286         }
287         case(LCFG_ADD_UUID):{
288                 printf("add_uuid  ");
289                 print_1_cfg(lcfg);
290                 break;
291         }
292         case(LCFG_DEL_UUID):{
293                 printf("del_uuid  ");
294                 print_1_cfg(lcfg);
295                 break;
296         }
297         case(LCFG_ADD_CONN):{
298                 printf("add_conn  ");
299                 print_1_cfg(lcfg);
300                 break;
301         }
302         case(LCFG_DEL_CONN):{
303                 printf("del_conn  ");
304                 print_1_cfg(lcfg);
305                 break;
306         }
307         case(LCFG_LOV_ADD_OBD):{
308                 printf("lov_modify_tgts add ");
309                 print_1_cfg(lcfg);
310                 break;
311         }
312         case(LCFG_LOV_DEL_OBD):{
313                 printf("lov_modify_tgts del ");
314                 print_1_cfg(lcfg);
315                 break;
316         }
317         case(LCFG_ADD_MDC):{
318                 printf("modify_mdc_tgts add ");
319                 print_1_cfg(lcfg);
320                 break;
321         }
322         case(LCFG_DEL_MDC):{
323                 printf("modify_mdc_tgts del ");
324                 print_1_cfg(lcfg);
325                 break;
326         }
327         case(LCFG_MOUNTOPT):{
328                 printf("mount_option ");
329                 print_1_cfg(lcfg);
330                 break;
331         }
332         case(LCFG_DEL_MOUNTOPT):{
333                 printf("del_mount_option ");
334                 print_1_cfg(lcfg);
335                 break;
336         }
337         case(LCFG_SET_TIMEOUT):{
338                 printf("set_timeout=%d ", lcfg->lcfg_num);
339                 print_1_cfg(lcfg);
340                 break;
341         }
342         case(LCFG_SET_UPCALL):{
343                 printf("set_lustre_upcall ");
344                 print_1_cfg(lcfg);
345                 break;
346         }
347         case(LCFG_PARAM):{
348                 printf("param ");
349                 print_1_cfg(lcfg);
350                 break;
351         }
352         case(LCFG_MARKER):{
353                 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
354                 char createtime[26], canceltime[26] = "";
355
356                 if (marker->cm_flags & CM_SKIP) {
357                         if (marker->cm_flags & CM_START) {
358                                 printf("SKIP START ");
359                                 (*skip)++;
360                         } else {
361                                 printf(     "END   ");
362                                 *skip = 0;
363                         }
364                 }
365                 if (marker->cm_flags & CM_EXCLUDE) {
366                         if (marker->cm_flags & CM_START) 
367                                 printf("EXCLUDE START ");
368                         else
369                                 printf("EXCLUDE END   ");
370                 }
371                 ctime_r(&marker->cm_createtime, createtime);
372                 createtime[strlen(createtime) - 1] = 0;
373                 if (marker->cm_canceltime) {
374                         ctime_r(&marker->cm_canceltime, canceltime);
375                         canceltime[strlen(canceltime) - 1] = 0;
376                 }
377                 printf("marker %3d (flags=%#04x, v%d.%d.%d.%d) %-15s '%s' %s-%s",
378                        marker->cm_step, marker->cm_flags,
379                        OBD_OCD_VERSION_MAJOR(marker->cm_vers),
380                        OBD_OCD_VERSION_MINOR(marker->cm_vers),
381                        OBD_OCD_VERSION_PATCH(marker->cm_vers),
382                        OBD_OCD_VERSION_FIX(marker->cm_vers),
383                        marker->cm_tgtname, marker->cm_comment,
384                        createtime, canceltime);
385                 break;
386         }
387         default:
388                 printf("unsupported cmd_code = %x\n",cmd);
389         }
390         printf("\n");
391         return;
392 }
393
394 void print_records(struct llog_rec_hdr **recs, int rec_number)
395 {
396         __u32 lopt;
397         int i, skip = 0;
398         
399         for(i = 0; i < rec_number; i++) {
400                 printf("#%.2d (%.3d)", le32_to_cpu(recs[i]->lrh_index),
401                        le32_to_cpu(recs[i]->lrh_len));
402
403                 lopt = le32_to_cpu(recs[i]->lrh_type);
404
405                 if (recs[i]->padding == CANCELLED) 
406                         printf("NOT SET ");
407             
408                 if (lopt == OBD_CFG_REC) {
409                         struct lustre_cfg *lcfg;
410                         lcfg = (struct lustre_cfg *)((char*)(recs[i]) +
411                                                      sizeof(struct llog_rec_hdr));
412                         print_lustre_cfg(lcfg, &skip);
413                 } else if (lopt == LLOG_PAD_MAGIC) {
414                         printf("padding\n");
415                 } else
416                         printf("unknown type %x\n", lopt);
417         }
418 }