From 11cc3a2fa9b4a2ccf233b0ac1616a14b1d39186d Mon Sep 17 00:00:00 2001 From: Maksim An Date: Thu, 11 Mar 2021 21:10:00 -0800 Subject: [PATCH] add utility method to read ext4 superblock from a VHD The change enables getting accurate information about ext4 fs on a given VHD, rather than doing os.Stat or temp mounting the VHD. Signed-off-by: Maksim An --- ext4/tar2ext4/tar2ext4.go | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/ext4/tar2ext4/tar2ext4.go b/ext4/tar2ext4/tar2ext4.go index ad09210469..874855bca8 100644 --- a/ext4/tar2ext4/tar2ext4.go +++ b/ext4/tar2ext4/tar2ext4.go @@ -5,10 +5,12 @@ import ( "bufio" "encoding/binary" "io" + "os" "path" "strings" "github.com/Microsoft/hcsshim/ext4/internal/compactext4" + "github.com/Microsoft/hcsshim/ext4/internal/format" ) type params struct { @@ -172,3 +174,36 @@ func Convert(r io.Reader, w io.ReadWriteSeeker, options ...Option) error { } return nil } + +// ReadExt4SuperBlock reads and returns ext4 super block from VHD +// +// The layout on disk is as follows: +// | Group 0 padding | - 1024 bytes +// | ext4 SuperBlock | - 1 block +// | Group Descriptors | - many blocks +// | Reserved GDT Blocks | - many blocks +// | Data Block Bitmap | - 1 block +// | inode Bitmap | - 1 block +// | inode Table | - many blocks +// | Data Blocks | - many blocks +// +// More details can be found here https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout +// +// Our goal is to skip the Group 0 padding, read and return the ext4 SuperBlock +func ReadExt4SuperBlock(vhdPath string) (*format.SuperBlock, error) { + vhd, err := os.OpenFile(vhdPath, os.O_RDONLY, 0) + if err != nil { + return nil, err + } + defer vhd.Close() + + // Skip padding at the start + if _, err := vhd.Seek(1024, io.SeekStart); err != nil { + return nil, err + } + var sb format.SuperBlock + if err := binary.Read(vhd, binary.LittleEndian, &sb); err != nil { + return nil, err + } + return &sb, nil +}