-
Notifications
You must be signed in to change notification settings - Fork 2
/
pv.go
87 lines (74 loc) · 2.09 KB
/
pv.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package lvm
import (
"bytes"
"fmt"
"log"
"os"
"github.com/Soulou/go-lvm/dev"
"github.com/pkg/errors"
)
type PhysicalVolume struct {
device *dev.Device
labelHeader LabelHeader
header PhysicalVolumeHeader
headerExt PhysicalVolumeHeaderExtension
metadataHeaders []MetadataHeader
}
func NewPhysicalVolume(dev *dev.Device) (*PhysicalVolume, error) {
if dev == nil {
return nil, errors.New("nil device")
}
pv := &PhysicalVolume{device: dev}
b, err := pv.ReadBlock(0)
if err != nil {
return nil, errors.Wrapf(err, "fail to read block 0")
}
reader := bytes.NewReader(b)
labelHeader, err := pv.readLabelHeader(reader)
if err != nil {
return nil, errors.Wrapf(err, "fail to read label header")
}
if crc32checksum, ok := labelHeader.CheckCRC32(b[labelHeader.Sector*SectorSize:]); !ok {
log.Printf("Fail to check label header checksum, got %v, expected: %v", crc32checksum, labelHeader.CRC)
}
pv.labelHeader = labelHeader
pvHeader, err := pv.readHeader(reader)
if err != nil {
return nil, errors.Wrapf(err, "fail to read pv header")
}
pv.header = pvHeader
pvHeaderExt, err := pv.readHeaderExt(reader)
if err != nil {
return nil, errors.Wrapf(err, "fail to reade pv header ext")
}
pv.headerExt = pvHeaderExt
metadataHeaders, err := pv.readMetadataHeaders()
if err != nil {
return nil, errors.Wrapf(err, "fail to read metadata header areas")
}
pv.metadataHeaders = metadataHeaders
fmt.Println(labelHeader)
fmt.Println(pvHeader)
fmt.Println(pvHeaderExt)
fmt.Println(metadataHeaders)
for _, h := range metadataHeaders {
m, err := pv.readMetadata(h)
if err != nil {
return nil, errors.Wrapf(err, "fail to read pv metadata")
}
fmt.Println(string(m))
}
return pv, nil
}
func (pv *PhysicalVolume) ReadBlock(offset uint64) ([]byte, error) {
block := make([]byte, pv.device.BlockSize)
_, err := pv.device.Seek(int64(offset), os.SEEK_SET)
if err != nil {
return nil, errors.Wrapf(err, "fail to seek in device")
}
_, err = pv.device.Read(block)
if err != nil {
return nil, errors.Wrapf(err, "fail to read from device")
}
return block, nil
}