]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame_incremental - logprint/logprint.c
xfs: don't treat unknown di_flags2 as corruption in scrub
[thirdparty/xfsprogs-dev.git] / logprint / logprint.c
... / ...
CommitLineData
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2000-2004 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6#include <sys/types.h>
7#include <sys/stat.h>
8
9#include "libxfs.h"
10#include "libxlog.h"
11
12#include "logprint.h"
13
14#define OP_PRINT 0
15#define OP_PRINT_TRANS 1
16#define OP_DUMP 2
17#define OP_COPY 3
18
19int print_data;
20int print_only_data;
21int print_inode;
22int print_quota;
23int print_buffer;
24int print_overwrite;
25int print_no_data;
26int print_no_print;
27int print_exit = 1; /* -e is now default. specify -c to override */
28int print_operation = OP_PRINT;
29
30void
31usage(void)
32{
33 fprintf(stderr, _("Usage: %s [options...] <device>\n\n\
34Options:\n\
35 -c try to continue if error found in log\n\
36 -C <filename> copy the log from the filesystem to filename\n\
37 -d dump the log in log-record format\n\
38 -e exit when an error is found in the log\n\
39 -f specified device is actually a file\n\
40 -l <device> filename of external log\n\
41 -n don't try and interpret log data\n\
42 -o print buffer data in hex\n\
43 -s <start blk> block # to start printing\n\
44 -v print \"overwrite\" data\n\
45 -t print out transactional view\n\
46 -b in transactional view, extract buffer info\n\
47 -i in transactional view, extract inode info\n\
48 -q in transactional view, extract quota info\n\
49 -D print only data; no decoding\n\
50 -V print version information\n"),
51 progname);
52 exit(1);
53}
54
55int
56logstat(xfs_mount_t *mp)
57{
58 int fd;
59 char buf[BBSIZE];
60 xfs_sb_t *sb;
61
62 /* On Linux we always read the superblock of the
63 * filesystem. We need this to get the length of the
64 * log. Otherwise we end up seeking forever. -- mkp
65 */
66 if ((fd = open(x.dname, O_RDONLY)) == -1) {
67 fprintf(stderr, _(" Can't open device %s: %s\n"),
68 x.dname, strerror(errno));
69 exit(1);
70 }
71 lseek(fd, 0, SEEK_SET);
72 if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
73 fprintf(stderr, _(" read of XFS superblock failed\n"));
74 exit(1);
75 }
76 close (fd);
77
78 if (!x.disfile) {
79 /*
80 * Conjure up a mount structure
81 */
82 sb = &mp->m_sb;
83 libxfs_sb_from_disk(sb, (xfs_dsb_t *)buf);
84 mp->m_blkbb_log = sb->sb_blocklog - BBSHIFT;
85
86 x.logBBsize = XFS_FSB_TO_BB(mp, sb->sb_logblocks);
87 x.logBBstart = XFS_FSB_TO_DADDR(mp, sb->sb_logstart);
88 x.lbsize = BBSIZE;
89 if (xfs_sb_version_hassector(sb))
90 x.lbsize <<= (sb->sb_logsectlog - BBSHIFT);
91
92 if (!x.logname && sb->sb_logstart == 0) {
93 fprintf(stderr, _(" external log device not specified\n\n"));
94 usage();
95 /*NOTREACHED*/
96 }
97 } else {
98 struct stat s;
99
100 stat(x.dname, &s);
101 x.logBBsize = s.st_size >> 9;
102 x.logBBstart = 0;
103 x.lbsize = BBSIZE;
104 }
105
106
107 if (x.logname && *x.logname) { /* External log */
108 if ((fd = open(x.logname, O_RDONLY)) == -1) {
109 fprintf(stderr, _("Can't open file %s: %s\n"),
110 x.logname, strerror(errno));
111 exit(1);
112 }
113 close(fd);
114 } else { /* Internal log */
115 x.logdev = x.ddev;
116 }
117
118 return 0;
119}
120
121int
122main(int argc, char **argv)
123{
124 int print_start = -1;
125 int c;
126 int logfd;
127 char *copy_file = NULL;
128 struct xlog log = {0};
129 xfs_mount_t mount;
130
131 setlocale(LC_ALL, "");
132 bindtextdomain(PACKAGE, LOCALEDIR);
133 textdomain(PACKAGE);
134 memset(&mount, 0, sizeof(mount));
135
136 progname = basename(argv[0]);
137 while ((c = getopt(argc, argv, "bC:cdefl:iqnors:tDVv")) != EOF) {
138 switch (c) {
139 case 'D':
140 print_only_data++;
141 print_data++;
142 break;
143 case 'b':
144 print_buffer++;
145 break;
146 case 'c':
147 /* default is to stop on error.
148 * -c turns this off.
149 */
150 print_exit = 0;
151 break;
152 case 'e':
153 /* -e is now default
154 */
155 print_exit++;
156 break;
157 case 'C':
158 print_operation = OP_COPY;
159 copy_file = optarg;
160 break;
161 case 'd':
162 print_operation = OP_DUMP;
163 break;
164 case 'f':
165 print_skip_uuid++;
166 x.disfile = 1;
167 break;
168 case 'l':
169 x.logname = optarg;
170 x.lisfile = 1;
171 break;
172 case 'i':
173 print_inode++;
174 break;
175 case 'q':
176 print_quota++;
177 break;
178 case 'n':
179 print_no_data++;
180 break;
181 case 'o':
182 print_data++;
183 break;
184 case 's':
185 print_start = atoi(optarg);
186 break;
187 case 't':
188 print_operation = OP_PRINT_TRANS;
189 break;
190 case 'v':
191 print_overwrite++;
192 break;
193 case 'V':
194 printf(_("%s version %s\n"), progname, VERSION);
195 exit(0);
196 case '?':
197 usage();
198 }
199 }
200
201 if (argc - optind != 1)
202 usage();
203
204 x.dname = argv[optind];
205
206 if (x.dname == NULL)
207 usage();
208
209 x.isreadonly = LIBXFS_ISINACTIVE;
210 printf(_("xfs_logprint:\n"));
211 if (!libxfs_init(&x))
212 exit(1);
213
214 logstat(&mount);
215 libxfs_buftarg_init(&mount, x.ddev, x.logdev, x.rtdev);
216
217 logfd = (x.logfd < 0) ? x.dfd : x.logfd;
218
219 printf(_(" data device: 0x%llx\n"), (unsigned long long)x.ddev);
220
221 if (x.logname) {
222 printf(_(" log file: \"%s\" "), x.logname);
223 } else {
224 printf(_(" log device: 0x%llx "), (unsigned long long)x.logdev);
225 }
226
227 printf(_("daddr: %lld length: %lld\n\n"),
228 (long long)x.logBBstart, (long long)x.logBBsize);
229
230 ASSERT(x.logBBsize <= INT_MAX);
231
232 log.l_dev = mount.m_logdev_targp;
233 log.l_logBBstart = x.logBBstart;
234 log.l_logBBsize = x.logBBsize;
235 log.l_sectBBsize = BTOBB(x.lbsize);
236 log.l_mp = &mount;
237
238 switch (print_operation) {
239 case OP_PRINT:
240 xfs_log_print(&log, logfd, print_start);
241 break;
242 case OP_PRINT_TRANS:
243 xfs_log_print_trans(&log, print_start);
244 break;
245 case OP_DUMP:
246 xfs_log_dump(&log, logfd, print_start);
247 break;
248 case OP_COPY:
249 xfs_log_copy(&log, logfd, copy_file);
250 break;
251 }
252 exit(0);
253}