1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2006 Cluster File Systems, Inc.
5 * Author: Nathan Rutman <nathan@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org.
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.
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.
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.
23 /* Safely read the last_rcvd file from a device */
35 #include <sys/types.h>
37 #include <sys/mount.h>
42 #include <lustre_disk.h>
43 #include <lustre_ver.h>
45 int run_command(char *cmd)
47 char log[] = "/tmp/mkfs_logXXXXXX";
51 if ((fd = mkstemp(log)) >= 0) {
58 /* Can't use popen because we need the rv of the command */
65 while (fgets(buf, sizeof(buf), fp) != NULL) {
79 int main(int argc, char *const argv[])
81 char tmpdir[] = "/tmp/dirXXXXXX";
85 struct lr_server_data lsd;
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");
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));
106 memset(cmd, 0, sizeof(cmd));
108 "debugfs -c -R 'dump /%s %s/%s' %s",
109 LAST_RCVD, tmpdir, LAST_RCVD, dev);
111 ret = run_command(cmd);
113 fprintf(stderr, "%s: Unable to dump %s file\n",
114 progname, LAST_RCVD);
118 sprintf(filepnm, "%s/%s", tmpdir, LAST_RCVD);
119 filep = fopen(filepnm, "r");
121 fprintf(stderr, "%s: Unable to read old data\n",
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);
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];
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);
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);
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));
179 "debugfs -c -R 'rdump /%s %s' %s",
180 MDT_LOGS_DIR, tmpdir, dev);
184 sprintf(filepnm, "%s/%s", tmpdir, MDT_LOGS_DIR);
185 if (lsd.lsd_ost_index > 0) {
186 printf("non-flagged OST, index %d\n",
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
193 printf("non-flagged MDS, index 0\n");
195 printf("non-flagged OST, index unknown\n");
204 memset(cmd, 0, sizeof(cmd));
205 sprintf(cmd, "rm -rf %s", tmpdir);