3 * dumpscan - routines for scanning and manipulating AFS volume dumps
5 * Copyright (c) 1998 Carnegie Mellon University
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 * Carnegie Mellon requests users of this software to return to
20 * Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
29 /* afsdump_scan.c - General-purpose dump scanner */
31 #include <afsconfig.h>
32 #include <afs/param.h>
36 #include <afs/com_err.h>
37 #include <afs/pterror.h>
38 #include <afs/vlserver.h>
39 #include <afs/cellconfig.h>
41 #include <afs/afsint.h>
42 #include <afs/volser.h>
46 #include "dumpscan_errs.h"
51 extern XFILE repair_output
;
52 extern afs_uint32
repair_dumphdr_cb(afs_dump_header
*, XFILE
*, void *);
53 extern afs_uint32
repair_volhdr_cb(afs_vol_header
*, XFILE
*, void *);
54 extern afs_uint32
repair_vnode_cb(afs_vnode
*, XFILE
*, void *);
57 static char *input_path
, *gendump_path
;
58 static afs_uint32 printflags
, repairflags
;
59 static int quiet
, verbose
, error_count
;
61 static path_hashinfo phi
;
62 static dump_parser dp
;
65 /* Print a usage message and exit */
67 usage(int status
, char *msg
)
70 fprintf(stderr
, "%s: %s\n", argv0
, msg
);
71 fprintf(stderr
, "Usage: %s [options] [file]\n", argv0
);
72 fprintf(stderr
, " -Pxxx Set print options:\n");
73 fprintf(stderr
, " B = Print backup system header (if any)\n");
74 fprintf(stderr
, " H = Print AFS dump header\n");
75 fprintf(stderr
, " V = Print AFS volume header\n");
76 fprintf(stderr
, " v = List vnodes\n");
77 fprintf(stderr
, " p = Include path to each vnode\n");
78 fprintf(stderr
, " i = Include info for each vnode\n");
79 fprintf(stderr
, " d = List directory contents\n");
80 fprintf(stderr
, " a = List access control lists\n");
81 fprintf(stderr
, " g = Print debugging info\n");
82 fprintf(stderr
, " -Rxxx Set repair options:\n");
83 fprintf(stderr
, " 0 = Skip null tags\n");
84 fprintf(stderr
, " b = Seek backward to find skipped tags\n");
85 fprintf(stderr
, " d = Resync after vnode data\n");
86 fprintf(stderr
, " v = Resync after corrupted vnodes\n");
87 fprintf(stderr
, " -h Print this help message\n");
88 fprintf(stderr
, " -gxxx Generate a new dump in file xxx\n");
89 fprintf(stderr
, " -q Quiet mode (don't print errors)\n");
90 fprintf(stderr
, " -v Verbose mode\n");
95 /* Parse the argument given to the -P option.
96 * Returns the resulting * dumpscan print flags (DSPRINT_*).
97 * If an unrecognized flag is used, prints an error message and exits.
100 parse_printflags(char *flags
)
102 afs_uint32 result
= 0;
105 for (x
= flags
; *x
; x
++)
108 result
|= DSPRINT_BCKHDR
;
111 result
|= DSPRINT_DUMPHDR
;
114 result
|= DSPRINT_VOLHDR
;
117 result
|= DSPRINT_ITEM
;
120 result
|= DSPRINT_PATH
;
123 result
|= DSPRINT_VNODE
;
126 result
|= DSPRINT_DIR
;
129 result
|= DSPRINT_ACL
;
132 result
|= DSPRINT_DEBUG
;
135 usage(1, "Invalid print options!");
141 /* Parse the argument given to the -R option.
142 * Returns the resulting * dumpscan repair flags (DSFIX_*).
143 * If an unrecognized flag is used, prints an error message and exits.
146 parse_repairflags(char *flags
)
148 afs_uint32 result
= 0;
151 for (x
= flags
; *x
; x
++)
154 result
|= DSFIX_SKIP
;
157 result
|= DSFIX_RSKIP
;
160 result
|= DSFIX_VDSYNC
;
163 result
|= DSFIX_VFSYNC
;
166 usage(1, "Invalid repair options!");
172 /* Parse the command-line options */
174 parse_options(int argc
, char **argv
)
178 /* Set the program name */
179 if ((argv0
= strrchr(argv
[0], '/')))
184 /* Initialize options */
185 input_path
= gendump_path
= 0;
186 printflags
= repairflags
= 0;
189 /* Initialize other stuff */
192 /* Parse the options */
193 while ((c
= getopt(argc
, argv
, "P:R:g:hqv")) != EOF
) {
196 printflags
= parse_printflags(optarg
);
199 repairflags
= parse_repairflags(optarg
);
202 gendump_path
= optarg
;
213 usage(1, "Invalid option!");
217 if (quiet
&& verbose
)
218 usage(1, "Can't specify both -q and -v");
220 /* Parse non-option arguments */
221 if (argc
- optind
> 1)
222 usage(1, "Too many arguments!");
223 input_path
= (argc
== optind
) ? "-" : argv
[optind
];
227 /* A callback to count and print errors */
229 my_error_cb(afs_uint32 code
, int fatal
, void *ref
, char *msg
, ...)
235 va_start(alist
, msg
);
236 afs_com_err_va(argv0
, code
, msg
, alist
);
243 /* A callback to print the path of a vnode. */
245 print_vnode_path(afs_vnode
* v
, XFILE
* X
, void *refcon
)
250 /* Do repair, but only for known vnode types */
251 if (gendump_path
&& (!(v
->field_mask
& F_VNODE_TYPE
)
252 || ((v
->type
!= vFile
) && (v
->type
!= vDirectory
)
253 && (v
->type
!= vSymlink
)))) {
254 r
= repair_vnode_cb(v
, X
, refcon
);
258 r
= Path_Build(X
, &phi
, v
->vnode
, &name
, 0);
260 printf(" Path: %s\n", name
);
267 /* Setup for generating a repaired dump */
273 r
= xfopen(&repair_output
, O_RDWR
| O_CREAT
| O_TRUNC
, gendump_path
);
277 dp
.cb_dumphdr
= repair_dumphdr_cb
;
278 dp
.cb_volhdr
= repair_volhdr_cb
;
279 dp
.cb_vnode_dir
= repair_vnode_cb
;
280 dp
.cb_vnode_file
= repair_vnode_cb
;
281 dp
.cb_vnode_link
= repair_vnode_cb
;
282 dp
.cb_vnode_empty
= repair_vnode_cb
;
286 extern afs_uint32
DumpDumpEnd(XFILE
* OX
);
290 main(int argc
, char **argv
)
295 parse_options(argc
, argv
);
296 initialize_acfg_error_table();
297 initialize_AVds_error_table();
298 initialize_rxk_error_table();
299 initialize_u_error_table();
300 initialize_vl_error_table();
301 initialize_vols_error_table();
302 initialize_xFil_error_table();
303 r
= xfopen(&input_file
, O_RDONLY
, input_path
);
305 afs_com_err(argv0
, r
, "opening %s", input_path
);
309 memset(&dp
, 0, sizeof(dp
));
310 dp
.cb_error
= my_error_cb
;
311 dp
.repair_flags
= repairflags
;
312 if (input_file
.is_seekable
)
313 dp
.flags
|= DSFLAG_SEEK
;
317 "Repair modes available only for seekable dumps\n");
318 if (printflags
& DSPRINT_PATH
)
320 "Path-printing available only for seekable dumps\n");
321 if (repairflags
|| (printflags
& DSPRINT_PATH
))
325 if (gendump_path
&& (r
= setup_repair())) {
326 afs_com_err(argv0
, r
, "setting up repair output");
327 xfclose(&input_file
);
331 if (printflags
& DSPRINT_PATH
) {
334 dp
.print_flags
= printflags
& DSPRINT_DEBUG
;
335 memset(&phi
, 0, sizeof(phi
));
338 if ((r
= xftell(&input_file
, &where
))
339 || (r
= Path_PreScan(&input_file
, &phi
, 0))
340 || (r
= xfseek(&input_file
, &where
))) {
341 afs_com_err(argv0
, r
, "- path initialization failed");
342 xfclose(&input_file
);
346 dp
.cb_vnode_dir
= print_vnode_path
;
347 dp
.cb_vnode_file
= print_vnode_path
;
348 dp
.cb_vnode_link
= print_vnode_path
;
349 dp
.cb_vnode_empty
= print_vnode_path
;
350 dp
.cb_vnode_wierd
= print_vnode_path
;
353 dp
.print_flags
= printflags
;
354 r
= ParseDumpFile(&input_file
, &dp
);
355 xfclose(&input_file
);
358 r
= DumpDumpEnd(&repair_output
);
360 r
= xfclose(&repair_output
);
362 xfclose(&repair_output
);
365 if (verbose
&& error_count
)
366 fprintf(stderr
, "*** %d errors\n", error_count
);
368 fprintf(stderr
, "*** FAILED: %s\n", afs_error_message(r
));