1 Star 0 Fork 1

mysnapcore/mysnapd

forked from tupelo-shen/mysnapd 
Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
文件
Clone or Download
gpt.go 3.98 KB
Copy Edit Raw Blame History
tupelo-shen authored 2022-11-07 00:20 +08:00 . fix: osutil 2 commit
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2022 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package disks
import (
"bytes"
"encoding/binary"
"fmt"
"hash/crc32"
"os"
)
type GPTLBA uint64
type GPTGUID [16]byte
// https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_table_header_(LBA_1)
type GPTHeader struct {
Signature [8]byte
Revision uint32
HeaderSize uint32
HeaderCRC uint32
Reserved uint32
CurrentLBA GPTLBA
AlternateLBA GPTLBA
FirstUsableLBA GPTLBA
LastUsableLBA GPTLBA
DiskGUID [16]byte
EntriesLBA GPTLBA
NEntries uint32
EntrySize uint32
EntriesCRC uint32
}
func verifyHeader(rawHeader []byte, header GPTHeader) error {
if !bytes.Equal(header.Signature[:], []byte("EFI PART")) {
return fmt.Errorf("GPT Header does not start with the magic string")
}
if header.Revision != 1<<16 {
return fmt.Errorf("GPT header revision is not 1.0")
}
if int(header.HeaderSize) < binary.Size(header) {
return fmt.Errorf("GPT header size is smaller than the minimum valid size")
}
if int(header.HeaderSize) > len(rawHeader) {
return fmt.Errorf("GPT header size is larger than the maximum supported size")
}
// To calculate the proper CRC, we need to reset the value
// of the CRC in the header to 0.
for i := 0; i < 4; i++ {
rawHeader[8+4+4+i] = 0
}
crc := crc32.ChecksumIEEE(rawHeader[:header.HeaderSize])
if crc != header.HeaderCRC {
return fmt.Errorf("GPT header CRC32 checksum failed: %v != %v", crc, header.HeaderCRC)
}
return nil
}
func LoadGPTHeader(devfd *os.File, sectorSize uint64) (GPTHeader, error) {
var header GPTHeader
rawHeader := make([]byte, sectorSize)
read, err := devfd.Read(rawHeader)
if err != nil {
return GPTHeader{}, err
}
if read < binary.Size(header) {
return GPTHeader{}, fmt.Errorf("Not enough data was read")
}
buf := bytes.NewReader(rawHeader[:read])
binary.Read(buf, binary.LittleEndian, &header)
if err := verifyHeader(rawHeader[:read], header); err != nil {
return GPTHeader{}, err
}
return header, nil
}
func ReadGPTHeader(device string, sectorSize uint64) (GPTHeader, error) {
devfd, err := os.Open(device)
if err != nil {
return GPTHeader{}, err
}
defer devfd.Close()
if _, err := devfd.Seek(int64(sectorSize), os.SEEK_SET); err != nil {
return GPTHeader{}, err
}
header, main_err := LoadGPTHeader(devfd, sectorSize)
if main_err != nil {
// Read the backup header
_, err := devfd.Seek(-int64(sectorSize), os.SEEK_END)
if err != nil {
return GPTHeader{}, main_err
}
header, err = LoadGPTHeader(devfd, sectorSize)
if err != nil {
return GPTHeader{}, main_err
}
}
return header, nil
}
func CalculateLastUsableLBA(device string, diskSize uint64, sectorSize uint64) (uint64, error) {
header, err := ReadGPTHeader(device, sectorSize)
if err != nil {
return 0, err
}
sectors := diskSize / sectorSize
tableSize := uint64(header.NEntries) * uint64(header.EntrySize)
if tableSize < 16*1024 {
tableSize = 16 * 1024
}
// Rounded up division for number of sectors
tableSizeInSectors := (tableSize + sectorSize - 1) / sectorSize
// | |
// | Last Usable LBA | sectors - tableSizeInSectors - 2
// +-----------------+
// | Backup Table | sectors - 1 - tableSizeInSectors
// | |
// +-----------------+
// | Backup Header | sectors - 1
// +-----------------+
// End of disk sectors
return sectors - tableSizeInSectors - 2, nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/mysnapcore/mysnapd.git
git@gitee.com:mysnapcore/mysnapd.git
mysnapcore
mysnapd
mysnapd
v0.1.0

Search