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