[OpenAFS] Re: help, salvaged volume won't come back online, is it corrupt?
[trimmed log]
Adam Megacz
megacz@cs.berkeley.edu
Wed, 13 Sep 2006 20:39:03 -0700
John Koyle <jkoyle@koyle.org> writes:
> ./afsdump_extract volume_name dest/ -v -i <- dump the
> data to dest/
> ./afsdump_scan -Pd -v volume > FileList.txt <- Create a
> flat file with vnode/filename mappings for finding things from the
> above dump.
I ultimately patched together a solution using this and the code below
(which I'm attaching mainly for posterity via the mailing list
archives). Apparently if you lose the root vnode, attach-orphans
won't give you anything back.
- a
Grok.java:
______________________________________________________________________________
// It is my deep and sincere hope that nobody will ever
// need to use this program.
//
// Adam Megacz / public domain
//
// to use:
// $ javac Grok.java
// $ mkdir in
// $ afsdump_extract dumpfile -v -i in
// $ afsdump_scan -Pdvi | java -cp . Grok
//
// if you're lucky, stuff winds up in ./out/
//
// the top two levels of the directory hierarchy are the
// vnode number of the "missing" parent of each orphan
// and the vnode number of the orphan itself. This way
// orphaned siblings wind up together.
//
// the code below is not pretty at all.
import java.util.*;
import java.io.*;
public class Grok {
public static void main(String[] ss) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
while(true) {
if (s==null) break;
if (!s.startsWith("* VNODE ")) throw new Error("expected *: " + s);
s = s.substring(9);
int a = Integer.parseInt(s.substring(0, s.indexOf('/')));
int b = Integer.parseInt(s.substring(s.indexOf('/')+1, s.indexOf(' ')));
VNode v = new VNode(a);
while (s != null &&
!s.startsWith(" Parent:"))
s = br.readLine();
if (s!=null && s.startsWith(" Parent:"))
v.setParent(Integer.parseInt(s.substring(8).trim()));
while (s != null &&
!s.startsWith(" ========== ========== =============================="))
s = br.readLine();
if (s==null) break;
s = br.readLine();
System.out.println("directory " + a+":"+b);
while (s != null && !s.startsWith("*")) {
int x = Integer.parseInt(s.substring(0, 12).trim());
int y = Integer.parseInt(s.substring(12, 12+11).trim());
String z = s.substring(25).trim();
v.add(x,z);
System.out.println(" "+x+":"+y+" = " + z);
s = br.readLine();
}
}
System.out.println("..........................................................");
files = new File("out").list();
for(VNode v : vnodes.values()) {
if (!(v.parent == -1 || vnodes.get(v.parent)==null)) continue;
System.out.println(v);
new File("out/"+v.parent).mkdirs();
v.creat("out/"+v.parent+"/"+v.a);
}
}
public static HashMap<Integer,VNode> vnodes = new HashMap<Integer,VNode>();
public static String[] files;
public static class VNode {
public int a;
public int parent = -1;
public HashMap<String,Integer> children = new HashMap<String,Integer>();
public void creat(String path) throws IOException {
new File(path).mkdirs();
for(String c : children.keySet()) {
VNode v = vnodes.get(children.get(c));
if (v!=null) v.creat(path+"/"+c);
else {
boolean good = false;
for(String s : files) {
if (s.indexOf(':')!=-1 &&
Integer.parseInt(s.substring(0,s.indexOf(':')))==children.get(c)) {
new File("in/"+s).renameTo(new File(path+"/"+c));
good = true;
break;
}
}
if (!good)
System.out.println("bad: " + children.get(c));
}
}
}
public void setParent(int a) {
if (parent != -1 && parent != a)
throw new Error("overwrite " + parent + " => " + a);
parent = a;
}
public VNode(int a) {
this.a = a;
if (vnodes.get(a)!=null) throw new Error("dupe " + a);
vnodes.put(a, this);
}
public void add(int a, String z) {
if (z.equals(".")) return;
if (z.equals("..")) {
if (parent != -1 && parent != a)
throw new Error("overwrite " + parent + " => " + a);
parent = a;
} else
children.put(z, a);
}
public String toString() {
StringBuffer ret = new StringBuffer();
ret.append("VNode " + a+" [parent="+parent+"]\n");
for(String s: children.keySet())
ret.append(" " + s+"\n");
return ret.toString();
}
}
}