forked from microsoft/azure-vhd-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vhdFile.go
93 lines (80 loc) · 2.95 KB
/
vhdFile.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
88
89
90
91
92
93
package vhdfile
import (
"fmt"
"github.com/Microsoft/azure-vhd-utils/vhdcore/bat"
"github.com/Microsoft/azure-vhd-utils/vhdcore/block"
"github.com/Microsoft/azure-vhd-utils/vhdcore/footer"
"github.com/Microsoft/azure-vhd-utils/vhdcore/header"
"github.com/Microsoft/azure-vhd-utils/vhdcore/reader"
)
// VhdFile represents a VHD.
//
type VhdFile struct {
// Footer represents the disk's footer.
Footer *footer.Footer
// Header represents the disk's header, this field is nil for fixed VHD.
// Only Dynamic and Differencing disk has header.make
Header *header.Header
// BlockAllocationTable represents the table holding absolute offset to the first sector
// of blocks in the disk. Only Dynamic and Differencing disk has BAT.
BlockAllocationTable *bat.BlockAllocationTable
// VhdReader is the reader that can be used to read the disk.
VhdReader *reader.VhdReader
// Parent represents the parent VHD of Differencing disk, this field is nil for fixed
// and dynamic disk.
Parent *VhdFile
}
// GetDiskType returns the type of the disk. Possible values are DiskTypeFixed, DiskTypeDynamic
// and DiskTypeDifferencing.
//
func (f *VhdFile) GetDiskType() footer.DiskType {
return f.Footer.DiskType
}
// GetBlockFactory returns a BlockFactory instance that can be used to create Block instances
// that represents blocks in the disk.
//
func (f *VhdFile) GetBlockFactory() (block.Factory, error) {
params := &block.FactoryParams{
VhdHeader: f.Header,
VhdFooter: f.Footer,
VhdReader: f.VhdReader,
}
switch f.GetDiskType() {
case footer.DiskTypeFixed:
return block.NewFixedDiskBlockFactoryWithDefaultBlockSize(params), nil
case footer.DiskTypeDynamic:
params.BlockAllocationTable = f.BlockAllocationTable
return block.NewDynamicDiskFactory(params), nil
case footer.DiskTypeDifferencing:
params.BlockAllocationTable = f.BlockAllocationTable
parentVhdFile := f.Parent
if parentVhdFile.GetDiskType() == footer.DiskTypeFixed {
params.ParentBlockFactory = block.NewFixedDiskBlockFactory(
&block.FactoryParams{
VhdHeader: parentVhdFile.Header,
VhdFooter: parentVhdFile.Footer,
VhdReader: parentVhdFile.VhdReader,
},
int64(f.Header.BlockSize)) // The block-size of parent FixedDisk and this DifferentialDisk will be same.
} else {
var err error
params.ParentBlockFactory, err = parentVhdFile.GetBlockFactory()
if err != nil {
return nil, err
}
}
return block.NewDifferencingDiskBlockFactory(params), nil
}
return nil, fmt.Errorf("Unsupported disk format: %d", f.GetDiskType())
}
// GetIdentityChain returns VHD identity chain, for differencing disk this will be a slice with
// unique ids of this and all it's ancestor disks. For fixed and dynamic disk, this will be a
// slice with one entry representing disk's unique id.
//
func (f *VhdFile) GetIdentityChain() []string {
ids := []string{f.Footer.UniqueID.String()}
for p := f.Parent; p != nil; p = p.Parent {
ids = append(ids, p.Footer.UniqueID.String())
}
return ids
}