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>
34 #include <sys/fcntl.h>
39 #include <afs/com_err.h>
40 #include <afs/pterror.h>
41 #include <afs/vlserver.h>
42 #include <afs/cellconfig.h>
44 #include <afs/volser.h>
48 #include "dumpscan_errs.h"
53 extern XFILE repair_output;
54 extern afs_uint32 repair_dumphdr_cb(afs_dump_header *, XFILE *, void *);
55 extern afs_uint32 repair_volhdr_cb(afs_vol_header *, XFILE *, void *);
56 extern afs_uint32 repair_vnode_cb(afs_vnode *, XFILE *, void *);
59 static char *input_path, *gendump_path;
60 static afs_uint32 printflags, repairflags;
61 static int quiet, verbose, error_count;
63 static path_hashinfo phi;
64 static dump_parser dp;
67 /* Print a usage message and exit */
69 usage(int status, char *msg)
72 fprintf(stderr, "%s: %s\n", argv0, msg);
73 fprintf(stderr, "Usage: %s [options] [file]\n", argv0);
74 fprintf(stderr, " -Pxxx Set print options:\n");
75 fprintf(stderr, " B = Print backup system header (if any)\n");
76 fprintf(stderr, " H = Print AFS dump header\n");
77 fprintf(stderr, " V = Print AFS volume header\n");
78 fprintf(stderr, " v = List vnodes\n");
79 fprintf(stderr, " p = Include path to each vnode\n");
80 fprintf(stderr, " i = Include info for each vnode\n");
81 fprintf(stderr, " d = List directory contents\n");
82 fprintf(stderr, " a = List access control lists\n");
83 fprintf(stderr, " g = Print debugging info\n");
84 fprintf(stderr, " -Rxxx Set repair options:\n");
85 fprintf(stderr, " 0 = Skip null tags\n");
86 fprintf(stderr, " b = Seek backward to find skipped tags\n");
87 fprintf(stderr, " d = Resync after vnode data\n");
88 fprintf(stderr, " v = Resync after corrupted vnodes\n");
89 fprintf(stderr, " -h Print this help message\n");
90 fprintf(stderr, " -gxxx Generate a new dump in file xxx\n");
91 fprintf(stderr, " -q Quiet mode (don't print errors)\n");
92 fprintf(stderr, " -v Verbose mode\n");
97 /* Parse the argument given to the -P option.
98 * Returns the resulting * dumpscan print flags (DSPRINT_*).
99 * If an unrecognized flag is used, prints an error message and exits.
102 parse_printflags(char *flags)
104 afs_uint32 result = 0;
107 for (x = flags; *x; x++)
110 result |= DSPRINT_BCKHDR;
113 result |= DSPRINT_DUMPHDR;
116 result |= DSPRINT_VOLHDR;
119 result |= DSPRINT_ITEM;
122 result |= DSPRINT_PATH;
125 result |= DSPRINT_VNODE;
128 result |= DSPRINT_DIR;
131 result |= DSPRINT_ACL;
134 result |= DSPRINT_DEBUG;
137 usage(1, "Invalid print options!");
143 /* Parse the argument given to the -R option.
144 * Returns the resulting * dumpscan repair flags (DSFIX_*).
145 * If an unrecognized flag is used, prints an error message and exits.
148 parse_repairflags(char *flags)
150 afs_uint32 result = 0;
153 for (x = flags; *x; x++)
156 result |= DSFIX_SKIP;
159 result |= DSFIX_RSKIP;
162 result |= DSFIX_VDSYNC;
165 result |= DSFIX_VFSYNC;
168 usage(1, "Invalid repair options!");
174 /* Parse the command-line options */
176 parse_options(int argc, char **argv)
180 /* Set the program name */
181 if ((argv0 = strrchr(argv[0], '/')))
186 /* Initialize options */
187 input_path = gendump_path = 0;
188 printflags = repairflags = 0;
191 /* Initialize other stuff */
194 /* Parse the options */
195 while ((c = getopt(argc, argv, "P:R:g:hqv")) != EOF) {
198 printflags = parse_printflags(optarg);
201 repairflags = parse_repairflags(optarg);
204 gendump_path = optarg;
215 usage(1, "Invalid option!");
219 if (quiet && verbose)
220 usage(1, "Can't specify both -q and -v");
222 /* Parse non-option arguments */
223 if (argc - optind > 1)
224 usage(1, "Too many arguments!");
225 input_path = (argc == optind) ? "-" : argv[optind];
229 /* A callback to count and print errors */
231 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
237 va_start(alist, msg);
238 afs_com_err_va(argv0, code, msg, alist);
245 /* A callback to print the path of a vnode. */
247 print_vnode_path(afs_vnode * v, XFILE * X, void *refcon)
252 /* Do repair, but only for known vnode types */
253 if (gendump_path && (!(v->field_mask & F_VNODE_TYPE)
254 || ((v->type != vFile) && (v->type != vDirectory)
255 && (v->type != vSymlink)))) {
256 r = repair_vnode_cb(v, X, refcon);
260 r = Path_Build(X, &phi, v->vnode, &name, 0);
262 printf(" Path: %s\n", name);
269 /* Setup for generating a repaired dump */
275 r = xfopen(&repair_output, O_RDWR | O_CREAT | O_TRUNC, gendump_path);
279 dp.cb_dumphdr = repair_dumphdr_cb;
280 dp.cb_volhdr = repair_volhdr_cb;
281 dp.cb_vnode_dir = repair_vnode_cb;
282 dp.cb_vnode_file = repair_vnode_cb;
283 dp.cb_vnode_link = repair_vnode_cb;
284 dp.cb_vnode_empty = repair_vnode_cb;
288 extern afs_uint32 DumpDumpEnd(XFILE * OX);
292 main(int argc, char **argv)
297 parse_options(argc, argv);
298 initialize_acfg_error_table();
299 initialize_AVds_error_table();
300 initialize_rxk_error_table();
301 initialize_u_error_table();
302 initialize_vl_error_table();
303 initialize_vols_error_table();
304 initialize_xFil_error_table();
305 r = xfopen(&input_file, O_RDONLY, input_path);
307 afs_com_err(argv0, r, "opening %s", input_path);
311 memset(&dp, 0, sizeof(dp));
312 dp.cb_error = my_error_cb;
313 dp.repair_flags = repairflags;
314 if (input_file.is_seekable)
315 dp.flags |= DSFLAG_SEEK;
319 "Repair modes available only for seekable dumps\n");
320 if (printflags & DSPRINT_PATH)
322 "Path-printing available only for seekable dumps\n");
323 if (repairflags || (printflags & DSPRINT_PATH))
327 if (gendump_path && (r = setup_repair())) {
328 afs_com_err(argv0, r, "setting up repair output");
329 xfclose(&input_file);
333 if (printflags & DSPRINT_PATH) {
336 dp.print_flags = printflags & DSPRINT_DEBUG;
337 memset(&phi, 0, sizeof(phi));
340 if ((r = xftell(&input_file, &where))
341 || (r = Path_PreScan(&input_file, &phi, 0))
342 || (r = xfseek(&input_file, &where))) {
343 afs_com_err(argv0, r, "- path initialization failed");
344 xfclose(&input_file);
348 dp.cb_vnode_dir = print_vnode_path;
349 dp.cb_vnode_file = print_vnode_path;
350 dp.cb_vnode_link = print_vnode_path;
351 dp.cb_vnode_empty = print_vnode_path;
352 dp.cb_vnode_wierd = print_vnode_path;
355 dp.print_flags = printflags;
356 r = ParseDumpFile(&input_file, &dp);
357 xfclose(&input_file);
360 r = DumpDumpEnd(&repair_output);
362 r = xfclose(&repair_output);
364 xfclose(&repair_output);
367 if (verbose && error_count)
368 fprintf(stderr, "*** %d errors\n", error_count);
370 fprintf(stderr, "*** FAILED: %s\n", afs_error_message(r));