Whamcloud - gitweb
Fix compiler warnings.
[fs/lustre-release.git] / lustre / utils / lr_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  *   Author: Nathan Rutman <nathan@clusterfs.com>
6  *
7  *   This file is part of Lustre, http://www.lustre.org.
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  */
23  /* Safely read the last_rcvd file from a device */
24
25 #ifndef _GNU_SOURCE
26 #define _GNU_SOURCE
27 #endif
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <stdarg.h>
33 #include <mntent.h>
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <sys/mount.h>
38
39 #include <string.h>
40 #include <getopt.h>
41
42 #include <lustre_disk.h>
43 #include <lustre_ver.h>
44
45 int run_command(char *cmd)
46 {
47         char log[] = "/tmp/mkfs_logXXXXXX";
48         int fd, rc;
49         
50         
51         if ((fd = mkstemp(log)) >= 0) {
52                 close(fd);
53                 strcat(cmd, " >");
54                 strcat(cmd, log);
55         }
56         strcat(cmd, " 2>&1");
57
58         /* Can't use popen because we need the rv of the command */
59         rc = system(cmd);
60         if (rc && fd >= 0) {
61                 char buf[128];
62                 FILE *fp;
63                 fp = fopen(log, "r");
64                 if (fp) {
65                         while (fgets(buf, sizeof(buf), fp) != NULL) {
66                                 if (rc) 
67                                         printf("   %s", buf);
68                         }
69                         fclose(fp);
70                 }
71         }
72         if (fd >= 0) 
73                 remove(log);
74         return rc;
75 }                                                       
76
77
78
79 int main(int argc, char *const argv[])
80 {
81         char tmpdir[] = "/tmp/dirXXXXXX";
82         char cmd[128];
83         char filepnm[128];
84         char *progname, *dev;
85         struct lr_server_data lsd;
86         FILE *filep;
87         int ret;
88
89         if ((argc < 2) || (argv[argc - 1][0] == '-')) {
90                 printf("Usage: %s devicename\n", argv[0]);
91                 printf("Read and print the last_rcvd file from a device\n");
92                 printf("(safe for mounted devices)\n");
93                 return EINVAL;
94         }
95
96         progname = argv[0];
97         dev = argv[argc - 1];
98
99         /* Make a temporary directory to hold Lustre data files. */
100         if (!mkdtemp(tmpdir)) {
101                 fprintf(stderr, "%s: Can't create temporary directory %s: %s\n",
102                         progname, tmpdir, strerror(errno));
103                 return errno;
104         }
105
106         memset(cmd, 0, sizeof(cmd));
107         sprintf(cmd,
108                 "debugfs -c -R 'dump /%s %s/%s' %s",
109                 LAST_RCVD, tmpdir, LAST_RCVD, dev);
110
111         ret = run_command(cmd);
112         if (ret) {
113                 fprintf(stderr, "%s: Unable to dump %s file\n",
114                         progname, LAST_RCVD);
115                 goto out_rmdir;
116         }
117
118         sprintf(filepnm, "%s/%s", tmpdir, LAST_RCVD);
119         filep = fopen(filepnm, "r");
120         if (!filep) {
121                 fprintf(stderr, "%s: Unable to read old data\n",
122                         progname);
123                 ret = -errno;
124                 goto out_rmdir;
125         }
126
127         printf("Reading %s\n", LAST_RCVD);
128         ret = fread(&lsd, 1, sizeof(lsd), filep);
129         if (ret < sizeof(lsd)) {
130                 fprintf(stderr, "%s: Short read (%d of %d)\n",
131                         progname, ret, (int)sizeof(lsd));
132                 ret = -ferror(filep);
133                 if (ret) 
134                         goto out_close;
135         }
136
137         #if 0
138         __u8  lsd_uuid[40];        /* server UUID */
139         __u64 lsd_last_transno;    /* last completed transaction ID */
140         __u64 lsd_compat14;        /* reserved - compat with old last_rcvd */
141         __u64 lsd_mount_count;     /* incarnation number */
142         __u32 lsd_feature_compat;  /* compatible feature flags */
143         __u32 lsd_feature_rocompat;/* read-only compatible feature flags */
144         __u32 lsd_feature_incompat;/* incompatible feature flags */
145         __u32 lsd_server_size;     /* size of server data area */
146         __u32 lsd_client_start;    /* start of per-client data area */
147         __u16 lsd_client_size;     /* size of per-client data area */
148         __u16 lsd_subdir_count;    /* number of subdirectories for objects */
149         __u64 lsd_catalog_oid;     /* recovery catalog object id */
150         __u32 lsd_catalog_ogen;    /* recovery catalog inode generation */
151         __u8  lsd_peeruuid[40];    /* UUID of MDS associated with this OST */
152         __u32 lsd_ost_index;       /* index number of OST in LOV */
153         __u32 lsd_mdt_index;       /* index number of MDT in LMV */
154         __u8  lsd_padding[LR_SERVER_SIZE - 148];
155         #endif
156
157         printf("UUID %s\n", lsd.lsd_uuid);
158         printf("Feature compat=%#x\n", lsd.lsd_feature_compat);
159         printf("Feature incompat=%#x\n", lsd.lsd_feature_incompat);
160         printf("Feature rocompat=%#x\n", lsd.lsd_feature_rocompat);
161         printf("Last transaction %llu\n", (long long)lsd.lsd_last_transno);
162         printf("ost index %u\n", lsd.lsd_ost_index);
163         printf("mdt index %u\n", lsd.lsd_mdt_index);
164
165         if ((lsd.lsd_feature_compat & OBD_COMPAT_OST) ||
166             (lsd.lsd_feature_incompat & OBD_INCOMPAT_OST)) {
167                 printf("OST, index %d\n", lsd.lsd_ost_index);
168         } else if ((lsd.lsd_feature_compat & OBD_COMPAT_MDT) ||
169                    (lsd.lsd_feature_incompat & OBD_INCOMPAT_MDT)) {
170                 /* We must co-locate so mgs can see old logs.
171                    If user doesn't want this, they can copy the old
172                    logs manually and re-tunefs. */
173                 printf("MDS, index %d\n", lsd.lsd_mdt_index);
174         } else  {
175                 /* If neither is set, we're pre-1.4.6, make a guess. */
176                 /* Construct debugfs command line. */
177                 memset(cmd, 0, sizeof(cmd));
178                 sprintf(cmd,
179                         "debugfs -c -R 'rdump /%s %s' %s",
180                         MDT_LOGS_DIR, tmpdir, dev);
181
182                 run_command(cmd);
183
184                 sprintf(filepnm, "%s/%s", tmpdir, MDT_LOGS_DIR);
185                 if (lsd.lsd_ost_index > 0) {
186                         printf("non-flagged OST, index %d\n", 
187                                lsd.lsd_ost_index);
188                 } else {
189                         /* If there's a LOGS dir, it's an MDT */
190                         if ((ret = access(filepnm, F_OK)) == 0) {
191                                 /* Old MDT's are always index 0 
192                                    (pre CMD) */
193                                 printf("non-flagged MDS, index 0\n");
194                         } else {
195                                 printf("non-flagged OST, index unknown\n");
196                         }
197                 }
198         }
199         
200 out_close:        
201         fclose(filep);
202
203 out_rmdir:
204         memset(cmd, 0, sizeof(cmd));
205         sprintf(cmd, "rm -rf %s", tmpdir);
206         run_command(cmd);
207         return ret;
208 }
209
210
211