]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/init.c
xfs_db: don't crash in ablock if there's no inode
[thirdparty/xfsprogs-dev.git] / db / init.c
CommitLineData
2bd0ea18 1/*
da23017d
NS
2 * Copyright (c) 2000-2002,2005 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
6b803e5a 19#include "libxfs.h"
7f725646 20#include "libxlog.h"
2bd0ea18
NS
21#include <signal.h>
22#include "command.h"
2bd0ea18
NS
23#include "init.h"
24#include "input.h"
25#include "io.h"
4ca431fc 26#include "init.h"
2bd0ea18
NS
27#include "sig.h"
28#include "output.h"
c6b24b3b 29#include "malloc.h"
c2907bd7 30#include "type.h"
2bd0ea18 31
7f725646
BF
32static char **cmdline;
33static int ncmdline;
34char *fsdevice;
35int blkbb;
36int exitcode;
37int expert_mode;
38int force;
39struct xfs_mount xmount;
40struct xfs_mount *mp;
41struct xlog xlog;
42libxfs_init_t x;
43xfs_agnumber_t cur_agno = NULLAGNUMBER;
2bd0ea18
NS
44
45static void
46usage(void)
47{
4ca431fc 48 fprintf(stderr, _(
30626ef6 49 "Usage: %s [-ifFrxV] [-p prog] [-l logdev] [-c cmd]... device\n"
7f98455a 50 ), progname);
2bd0ea18
NS
51 exit(1);
52}
53
54void
55init(
4ca431fc
NS
56 int argc,
57 char **argv)
2bd0ea18 58{
72298d16
DC
59 struct xfs_sb *sbp;
60 struct xfs_buf *bp;
a547152d 61 unsigned int agcount;
4ca431fc 62 int c;
2bd0ea18 63
9ee7055c
AM
64 setlocale(LC_ALL, "");
65 bindtextdomain(PACKAGE, LOCALEDIR);
66 textdomain(PACKAGE);
67
2bd0ea18 68 progname = basename(argv[0]);
7f98455a 69 while ((c = getopt(argc, argv, "c:fFip:rxVl:")) != EOF) {
2bd0ea18
NS
70 switch (c) {
71 case 'c':
c6b24b3b
NS
72 cmdline = xrealloc(cmdline, (ncmdline+1)*sizeof(char*));
73 cmdline[ncmdline++] = optarg;
2bd0ea18
NS
74 break;
75 case 'f':
4ca431fc 76 x.disfile = 1;
2bd0ea18 77 break;
7f98455a
CH
78 case 'F':
79 force = 1;
80 break;
2bd0ea18 81 case 'i':
4ca431fc 82 x.isreadonly = (LIBXFS_ISREADONLY|LIBXFS_ISINACTIVE);
2bd0ea18
NS
83 break;
84 case 'p':
85 progname = optarg;
86 break;
87 case 'r':
4ca431fc 88 x.isreadonly = LIBXFS_ISREADONLY;
2bd0ea18
NS
89 break;
90 case 'l':
4ca431fc 91 x.logname = optarg;
2bd0ea18
NS
92 break;
93 case 'x':
4ca431fc 94 expert_mode = 1;
2bd0ea18
NS
95 break;
96 case 'V':
9ee7055c 97 printf(_("%s version %s\n"), progname, VERSION);
3d98fe63 98 exit(0);
2bd0ea18
NS
99 case '?':
100 usage();
101 /*NOTREACHED*/
102 }
103 }
104 if (optind + 1 != argc) {
105 usage();
106 /*NOTREACHED*/
107 }
4ca431fc 108
2bd0ea18 109 fsdevice = argv[optind];
4ca431fc
NS
110 if (!x.disfile)
111 x.volname = fsdevice;
2bd0ea18 112 else
4ca431fc 113 x.dname = fsdevice;
4ca431fc 114
ba9ecd40 115 x.bcache_flags = CACHE_MISCOMPARE_PURGE;
4ca431fc
NS
116 if (!libxfs_init(&x)) {
117 fputs(_("\nfatal error -- couldn't initialize XFS library\n"),
2bd0ea18
NS
118 stderr);
119 exit(1);
120 }
4ca431fc 121
72298d16
DC
122 /*
123 * Read the superblock, but don't validate it - we are a diagnostic
124 * tool and so need to be able to mount busted filesystems.
125 */
126 memset(&xmount, 0, sizeof(struct xfs_mount));
127 libxfs_buftarg_init(&xmount, x.ddev, x.logdev, x.rtdev);
128 bp = libxfs_readbuf(xmount.m_ddev_targp, XFS_SB_DADDR,
129 1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0, NULL);
130
131 if (!bp || bp->b_error) {
61983f67
BN
132 fprintf(stderr, _("%s: %s is invalid (cannot read first 512 "
133 "bytes)\n"), progname, fsdevice);
2bd0ea18 134 exit(1);
2bd0ea18 135 }
4ca431fc
NS
136
137 /* copy SB from buffer to in-core, converting architecture as we go */
72298d16
DC
138 libxfs_sb_from_disk(&xmount.m_sb, XFS_BUF_TO_SBP(bp));
139 libxfs_putbuf(bp);
140 libxfs_purgebuf(bp);
4ca431fc
NS
141
142 sbp = &xmount.m_sb;
143 if (sbp->sb_magicnum != XFS_SB_MAGIC) {
7f98455a
CH
144 fprintf(stderr, _("%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n"),
145 progname, fsdevice, sbp->sb_magicnum);
4e83ac7b
ES
146 if (!force) {
147 fprintf(stderr, _("Use -F to force a read attempt.\n"));
7f98455a 148 exit(EXIT_FAILURE);
4e83ac7b 149 }
4ca431fc
NS
150 }
151
a547152d 152 agcount = sbp->sb_agcount;
4ca431fc 153 mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev,
9aa57116 154 LIBXFS_MOUNT_DEBUGGER);
d1ee9d75 155 if (!mp) {
9aa57116
DC
156 fprintf(stderr,
157 _("%s: device %s unusable (not an XFS filesystem?)\n"),
158 progname, fsdevice);
159 exit(1);
d1ee9d75 160 }
7f725646 161 mp->m_log = &xlog;
2bd0ea18 162 blkbb = 1 << mp->m_blkbb_log;
4ca431fc 163
a547152d
ES
164 /* Did we limit a broken agcount in libxfs_mount? */
165 if (sbp->sb_agcount != agcount)
166 exitcode = 1;
167
9aa57116
DC
168 /*
169 * xfs_check needs corrected incore superblock values
170 */
171 if (sbp->sb_rootino != NULLFSINO &&
172 xfs_sb_version_haslazysbcount(&mp->m_sb)) {
e2f60652 173 int error = -libxfs_initialize_perag_data(mp, sbp->sb_agcount);
9aa57116
DC
174 if (error) {
175 fprintf(stderr,
176 _("%s: cannot init perag data (%d). Continuing anyway.\n"),
177 progname, error);
178 }
179 }
180
061e316e
BF
181 if (xfs_sb_version_hassparseinodes(&mp->m_sb))
182 type_set_tab_spcrc();
183 else if (xfs_sb_version_hascrc(&mp->m_sb))
c2907bd7
DC
184 type_set_tab_crc();
185
2bd0ea18
NS
186 push_cur();
187 init_commands();
188 init_sig();
2bd0ea18 189}
4ca431fc
NS
190
191int
192main(
193 int argc,
194 char **argv)
195{
196 int c, i, done = 0;
197 char *input;
198 char **v;
72298d16 199 int start_iocur_sp;
4ca431fc 200
4ca431fc 201 init(argc, argv);
72298d16 202 start_iocur_sp = iocur_sp;
4ca431fc
NS
203
204 for (i = 0; !done && i < ncmdline; i++) {
205 v = breakline(cmdline[i], &c);
206 if (c)
207 done = command(c, v);
208 xfree(v);
209 }
210 if (cmdline) {
211 xfree(cmdline);
1adfff6f 212 goto close_devices;
4ca431fc
NS
213 }
214
c8dc4235 215 pushfile(stdin);
4ca431fc
NS
216 while (!done) {
217 if ((input = fetchline()) == NULL)
218 break;
219 v = breakline(input, &c);
220 if (c)
221 done = command(c, v);
222 doneline(input, v);
223 }
1adfff6f
DC
224
225close_devices:
72298d16
DC
226 /*
227 * Make sure that we pop the all the buffer contexts we hold so that
228 * they are released before we purge the caches during unmount.
229 */
230 while (iocur_sp > start_iocur_sp)
231 pop_cur();
232 libxfs_umount(mp);
1adfff6f
DC
233 if (x.ddev)
234 libxfs_device_close(x.ddev);
235 if (x.logdev && x.logdev != x.ddev)
236 libxfs_device_close(x.logdev);
237 if (x.rtdev)
238 libxfs_device_close(x.rtdev);
2ce8bff5
ES
239 libxfs_destroy();
240
4ca431fc
NS
241 return exitcode;
242}