Skip to content

Commit 7ad7123

Browse files
committed
p9trace: file system trace reader
1 parent 510f6a0 commit 7ad7123

File tree

7 files changed

+585
-0
lines changed

7 files changed

+585
-0
lines changed

‎p9trace/deps.go‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This file is not ignored by 'go mod tidy',
2+
// to keep leveldb as a required module.
3+
4+
//go:build never
5+
6+
package p9trace
7+
8+
import _ "github.com/golang/leveldb/table"

‎p9trace/go.mod‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module 9fans.net/go/p9trace
2+
3+
go 1.23.0
4+
5+
require github.com/golang/leveldb v0.0.0-20170107010102-259d9253d719
6+
7+
require github.com/golang/snappy v0.0.4 // indirect

‎p9trace/go.sum‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github.com/golang/leveldb v0.0.0-20170107010102-259d9253d719 h1:yahFtfWlyALYDkXw2ETowZqG4vi8hiE0yOEBOkpaXl0=
2+
github.com/golang/leveldb v0.0.0-20170107010102-259d9253d719/go.mod h1:etEpE0xVqxA0N3WNUa5wic5HCNSsQvYm+PFNmOnx2iU=
3+
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
4+
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=

‎p9trace/reorder.go‎

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
//go:build ignore
2+
3+
// Reorder reorders the traces so that block pointers only ever point to earlier blocks
4+
// and writes the result to a single trace file.
5+
package main
6+
7+
import (
8+
"bufio"
9+
"bytes"
10+
"compress/flate"
11+
"encoding/binary"
12+
"log"
13+
"os"
14+
15+
"9fans.net/go/p9trace"
16+
)
17+
18+
var all []*p9trace.Record
19+
var remap []uint32
20+
var nbad int
21+
var nextOut uint32
22+
var bw *bufio.Writer
23+
24+
func main() {
25+
f, err := os.Create(os.Args[1])
26+
if err != nil {
27+
log.Fatal(err)
28+
}
29+
bw = bufio.NewWriterSize(f, 1<<20)
30+
31+
for r := range p9trace.FileRecords(os.Args[2:]...) {
32+
all = append(all, r)
33+
if all[r.Addr] != r {
34+
panic("mismatch")
35+
}
36+
}
37+
println("loaded", all[173927], all[173927].Addr, all[173927].Tag)
38+
39+
remap = make([]uint32, len(all))
40+
for addr, r := range all {
41+
if r.Tag == p9trace.TagSuper {
42+
writeRecord(uint32(addr))
43+
}
44+
}
45+
println(len(all), nbad, nextOut)
46+
47+
bw.Flush()
48+
if err := bw.Flush(); err != nil {
49+
log.Fatal(err)
50+
}
51+
if err := f.Close(); err != nil {
52+
log.Fatal(err)
53+
}
54+
}
55+
56+
var stack []*p9trace.Record
57+
58+
func writeRecord(addr uint32) {
59+
if remap[addr] != 0 && remap[addr] != ^uint32(0) {
60+
return
61+
}
62+
r := all[addr]
63+
if all[r.Addr] != r {
64+
println("ALL", r.Addr, all[r.Addr], r)
65+
panic("all mismatch")
66+
}
67+
68+
stack = append(stack, r)
69+
for p := range r.Pointers() {
70+
if r.Super != nil && p == &r.Super.Next {
71+
continue
72+
}
73+
if int(*p) > len(all) {
74+
println("BAD", r.Addr, *p, len(all))
75+
nbad++
76+
r.Dir = nil
77+
r.Ind = nil
78+
if r.Super != nil {
79+
*r.Super = p9trace.Super{}
80+
}
81+
break
82+
}
83+
}
84+
85+
remap[r.Addr] = ^uint32(0)
86+
if r.Super != nil {
87+
r.Super.Next = 0
88+
}
89+
for p := range r.Pointers() {
90+
if *p == 0 {
91+
continue
92+
}
93+
if remap[*p] == 0 {
94+
writeRecord(*p)
95+
}
96+
if remap[*p] == ^uint32(0) {
97+
if *p == r.Addr {
98+
*p = 0
99+
continue
100+
}
101+
println("BLOCK LOOP", r.Addr, r.Tag, *p, all[*p].Addr, all[*p].Tag)
102+
for i, r1 := range stack {
103+
println("STACK #", i, r1.Addr, r1.Tag, r1, all[r1.Addr].Addr, all[r1.Addr].Tag, all[r1.Addr])
104+
}
105+
panic("block loop")
106+
}
107+
*p = remap[*p]
108+
}
109+
remap[r.Addr] = nextOut
110+
r.Addr = nextOut
111+
nextOut++
112+
113+
if true {
114+
data, err := r.MarshalBinary()
115+
if err != nil {
116+
log.Fatal(err)
117+
}
118+
var hdr [2]byte
119+
if len(data) > p9trace.HeaderSize {
120+
var fb bytes.Buffer
121+
fw, err := flate.NewWriter(&fb, flate.BestSpeed)
122+
if err != nil {
123+
log.Fatal(err)
124+
}
125+
fw.Write(data)
126+
fw.Close()
127+
if fb.Len() < len(data) {
128+
binary.BigEndian.PutUint16(hdr[:], uint16(fb.Len())|0x8000)
129+
bw.Write(hdr[:])
130+
bw.Write(fb.Bytes())
131+
goto Done
132+
}
133+
}
134+
binary.BigEndian.PutUint16(hdr[:], uint16(len(data)))
135+
bw.Write(hdr[:])
136+
bw.Write(data)
137+
Done:
138+
}
139+
140+
stack = stack[:len(stack)-1]
141+
}

‎p9trace/super.go‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//go:build ignore
2+
3+
// Super is a port of the C "super.c" trace reading demo.
4+
// See https://github.com/9fans/p9trace/src/super.c.
5+
package main
6+
7+
import (
8+
"fmt"
9+
"log"
10+
"os"
11+
12+
"9fans.net/go/p9trace"
13+
)
14+
15+
var (
16+
offset uint32 = ^uint32(0)
17+
last uint32
18+
next uint32
19+
20+
count [p9trace.TagMax]int
21+
ndir int
22+
nind int
23+
num int
24+
)
25+
26+
func main() {
27+
28+
for b := range p9trace.FileRecords(os.Args[1:]...) {
29+
if ^offset == 0 {
30+
offset = b.Addr
31+
}
32+
if b.Addr != offset {
33+
fmt.Fprintf(os.Stderr, "bad address %v %v\n", offset, b.Addr)
34+
}
35+
offset++
36+
if b.Tag >= p9trace.TagMax {
37+
log.Fatal("bad tag")
38+
}
39+
count[b.Tag]++
40+
41+
switch b.Tag {
42+
case p9trace.TagDir:
43+
ndir += len(b.Dir)
44+
case p9trace.TagInd1, p9trace.TagInd2:
45+
nind += len(b.Ind)
46+
case p9trace.TagSuper:
47+
if next != 0 && next != b.Addr {
48+
fmt.Fprintf(os.Stderr, "missing super block %v\n", next)
49+
}
50+
if last != 0 && last != b.Super.Last {
51+
fmt.Fprintf(os.Stderr, "bad last block %v\n", b.Addr)
52+
}
53+
fmt.Printf("super %v: cwraddr %v roraddr %v last %v next %v\n",
54+
b.Addr, b.Super.CWRAddr, b.Super.RORAddr,
55+
b.Super.Last, b.Super.Next)
56+
next = b.Super.Next
57+
last = b.Addr
58+
}
59+
num++
60+
}
61+
62+
for i := range p9trace.TagMax {
63+
fmt.Fprintf(os.Stderr, "%v: %v\n", i, count[i])
64+
}
65+
fmt.Fprintf(os.Stderr, "num = %v ndir = %v nind = %v\n", num, ndir, nind)
66+
}

‎p9trace/super2.go‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build ignore
6+
7+
// Super2 is like super but reads from an SSTable instead of raw trace files.
8+
package main
9+
10+
import (
11+
"fmt"
12+
"log"
13+
"os"
14+
15+
"9fans.net/go/p9trace"
16+
"github.com/golang/leveldb/table"
17+
)
18+
19+
var (
20+
offset uint32 = ^uint32(0)
21+
last uint32
22+
next uint32
23+
24+
count [p9trace.TagMax]int
25+
ndir int
26+
nind int
27+
num int
28+
)
29+
30+
func main() {
31+
f, err := os.Open(os.Args[1])
32+
if err != nil {
33+
log.Fatal(err)
34+
}
35+
r := table.NewReader(f, nil)
36+
it := r.Find(nil, nil)
37+
for it.Next() {
38+
var b p9trace.Record
39+
if err := b.UnmarshalBinary(it.Value()); err != nil {
40+
log.Fatal(err)
41+
}
42+
43+
if ^offset == 0 {
44+
offset = b.Addr
45+
}
46+
if b.Addr != offset {
47+
fmt.Fprintf(os.Stderr, "bad address %v %v\n", offset, b.Addr)
48+
}
49+
offset++
50+
if b.Tag >= p9trace.TagMax {
51+
log.Fatal("bad tag")
52+
}
53+
count[b.Tag]++
54+
55+
switch b.Tag {
56+
case p9trace.TagDir:
57+
ndir += len(b.Dir)
58+
case p9trace.TagInd1, p9trace.TagInd2:
59+
nind += len(b.Ind)
60+
case p9trace.TagSuper:
61+
if next != 0 && next != b.Addr {
62+
fmt.Fprintf(os.Stderr, "missing super block %v\n", next)
63+
}
64+
if last != 0 && last != b.Super.Last {
65+
fmt.Fprintf(os.Stderr, "bad last block %v\n", b.Addr)
66+
}
67+
fmt.Printf("super %v: cwraddr %v roraddr %v last %v next %v\n",
68+
b.Addr, b.Super.CWRAddr, b.Super.RORAddr,
69+
b.Super.Last, b.Super.Next)
70+
next = b.Super.Next
71+
last = b.Addr
72+
}
73+
num++
74+
}
75+
if err := it.Close(); err != nil {
76+
log.Fatalf("iter: %v", err)
77+
}
78+
79+
for i := range p9trace.TagMax {
80+
fmt.Fprintf(os.Stderr, "%v: %v\n", i, count[i])
81+
}
82+
fmt.Fprintf(os.Stderr, "num = %v ndir = %v nind = %v\n", num, ndir, nind)
83+
}

0 commit comments

Comments
 (0)