Open Itxaka opened 2 months ago
Hi @Itxaka
No, don't apologize for the wall of text. This is helpful, and much better than "I tried it, it didn't work." 😃
I'll try to dig in over the coming days.
Modified it slightly to enable passing parameters and creating a disk image if it does not exist:
package main
import (
"os"
"github.com/diskfs/go-diskfs"
"github.com/diskfs/go-diskfs/disk"
"github.com/diskfs/go-diskfs/filesystem"
"github.com/diskfs/go-diskfs/partition/gpt"
)
func main() {
filePath := os.Args[1]
var fileSize int64 = 200*1024*1024
if err := createFileIfNotExists(filePath, fileSize); err != nil {
panic(err)
}
d, err := diskfs.Open(filePath, diskfs.WithSectorSize(512))
if err != nil {
panic(err)
}
sizeFirst := uint64(10 * 1024 * 1024)
startFirst := 1024 * 1024 / uint64(diskfs.SectorSize512)
endFirst := sizeFirst/uint64(diskfs.SectorSize512) + startFirst - 1
sizeSecond := uint64(20 * 1024 * 1024)
startSecond := endFirst + 1
endSecond := sizeSecond/uint64(diskfs.SectorSize512) + startSecond - 1
table := &gpt.Table{
LogicalSectorSize: int(diskfs.SectorSize512),
PhysicalSectorSize: int(diskfs.SectorSize512),
ProtectiveMBR: true,
Partitions: []*gpt.Partition{
{
Start: startFirst,
End: endFirst,
Size: sizeFirst,
Type: gpt.EFISystemPartition,
Name: "part1",
},
{
Start: startSecond,
End: endSecond,
Size: sizeSecond,
Type: gpt.LinuxFilesystem,
Name: "part2",
},
},
}
err = d.Partition(table)
if err != nil {
panic(err)
}
_, err = d.CreateFilesystem(disk.FilesystemSpec{
Partition: 0,
FSType: filesystem.TypeFat32,
VolumeLabel: "part1",
})
if err != nil {
panic(err)
}
_, err = d.CreateFilesystem(disk.FilesystemSpec{
Partition: 1,
FSType: filesystem.TypeExt4,
VolumeLabel: "part1",
})
if err != nil {
panic(err)
}
}
func createFileIfNotExists(filePath string, fileSize int64) error {
// Check if the file exists
_, err := os.Stat(filePath)
if err == nil {
// File exists, do nothing
return nil
}
if !os.IsNotExist(err) {
// If the error is not "file does not exist", return the error
return err
}
// File does not exist, create it
file, err := os.Create(filePath)
if err != nil {
return err
}
defer file.Close()
// Set the file size
err = file.Truncate(fileSize)
if err != nil {
return err
}
return nil
}
The whole Create()
part is fairly new, just enabled a few weeks ago. I already am seeing some missing pieces. The maxfilesystem parts had some errors, those will be fixed shortly. It still is missing the gdt creation here. It just creates blank ones. Happy to take help on it.
Hey there!
as part of our hackweek, we are trying to move the Kairos installer (https://github.com/kairos-io/kairos-agent) to use pure go instead of shelling out and having to depend on external binaries.
Diskfs works wonderfully, it was so easy to create and partition a disk! great work there.
My main issue came when trying to create a partition in ext4 format. It looks like some of the blockgroups calculation is wrong as you get an error dividing by zero.
Minimum reproducible case:
This is a very simple reproducible case, you open
/dev/vda
, create a table with 2 partitions, and then create the filesystem. Disk and partition creation goes correctly with zero issues and fat32 filesystem creation as well, but ext4 creation fails.Looks like because the
disk.CreateFilesystem
method calls theext4.Create
with noParams
, the check on https://github.com/diskfs/go-diskfs/blob/master/filesystem/ext4/ext4.go#L158 will always fail, because the Params.SectorsPerBlock is gonna be always zeroOkay, no problem thats fixable, we can manually call the ext4.Create ourselves with proper params :)
so we substitute in our example this
for this
But that results in a panic as well:
This seems to point to https://github.com/diskfs/go-diskfs/blob/master/filesystem/ext4/ext4.go#L226 being the issue. I added some logging around and it kind of makes sense as at that point the values are:
Which points to https://github.com/diskfs/go-diskfs/blob/master/filesystem/ext4/ext4.go#L194 in which the values are:
Which points to
blocksPerGroup
being too big to dividenumblocks
onto it. Again this comes from theParams
having an empty value forBlocksPerGroup
and it defaulting toblocksize * 8
at https://github.com/diskfs/go-diskfs/blob/master/filesystem/ext4/ext4.go#L184so lets add those to params
Which causes another panic :D
This time its the https://github.com/diskfs/go-diskfs/blob/master/filesystem/ext4/ext4.go#L398 check as
maxBlockGroups
is 0. This is due tomaxFilesystemSize64Bit
resolving to 62 so the operation ends up being zeroNow here I have no idea how to continue troubleshooting this as I dont know what
maxFilesystemSize64Bit
refers to. Is this the maximum size of a filesystem in ext4 in bytes? is that missing a transformation to bytes or something? https://github.com/diskfs/go-diskfs/blob/master/filesystem/ext4/ext4.go#L59Sorry about the big wall of text. I know enough to troubleshoot but not enough about ext4 to tackle this, otherwise I would have send a PR to try to fix it, but that
maxFilesystemSize64Bit
got me stumped :DRunning version v1.4.1