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