From bbd6067d426fb2be22ff8935f415ab6d729d8f19 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 9 Jan 2025 19:54:43 +0400 Subject: [PATCH] fix: partition alignment on disks with 4k sectors Fixes #10097 See https://github.com/siderolabs/go-blockdevice/pull/121 I added an option to QEMU provisioner to create disks with custom block sizes (supported for some disk types). Unfortunately, this case can't be built as a regression as QEMU's firmware boots fine with ESP partition at 256/1024/2048 LBA. Signed-off-by: Andrey Smirnov --- cmd/talosctl/cmd/mgmt/cluster/create.go | 5 +++++ go.mod | 2 +- go.sum | 4 ++-- pkg/machinery/go.mod | 2 +- pkg/machinery/go.sum | 4 ++-- pkg/provision/providers/qemu/launch.go | 11 ++++++++--- pkg/provision/providers/qemu/node.go | 9 ++++++++- pkg/provision/request.go | 2 ++ website/content/v1.10/reference/cli.md | 1 + 9 files changed, 30 insertions(+), 10 deletions(-) diff --git a/cmd/talosctl/cmd/mgmt/cluster/create.go b/cmd/talosctl/cmd/mgmt/cluster/create.go index 8e9edcfc01..e0f67825cb 100644 --- a/cmd/talosctl/cmd/mgmt/cluster/create.go +++ b/cmd/talosctl/cmd/mgmt/cluster/create.go @@ -146,6 +146,7 @@ var ( workersMemory int clusterDiskSize int clusterDiskPreallocate bool + diskBlockSize uint clusterDisks []string extraDisks int extraDiskSize int @@ -955,6 +956,7 @@ func create(ctx context.Context) error { Size: uint64(extraDiskSize) * 1024 * 1024, SkipPreallocate: !clusterDiskPreallocate, Driver: driver, + BlockSize: diskBlockSize, }) } @@ -1181,6 +1183,7 @@ func getDisks() ([]*provision.Disk, error) { Size: uint64(clusterDiskSize) * 1024 * 1024, SkipPreallocate: !clusterDiskPreallocate, Driver: "virtio", + BlockSize: diskBlockSize, }, } @@ -1229,6 +1232,7 @@ func getDisks() ([]*provision.Disk, error) { Partitions: diskPartitions, SkipPreallocate: !clusterDiskPreallocate, Driver: "ide", + BlockSize: diskBlockSize, }) } @@ -1281,6 +1285,7 @@ func init() { createCmd.Flags().IntVar(&controlPlaneMemory, "memory", 2048, "the limit on memory usage in MB (each control plane/VM)") createCmd.Flags().IntVar(&workersMemory, "memory-workers", 2048, "the limit on memory usage in MB (each worker/VM)") createCmd.Flags().IntVar(&clusterDiskSize, clusterDiskSizeFlag, 6*1024, "default limit on disk size in MB (each VM)") + createCmd.Flags().UintVar(&diskBlockSize, "disk-block-size", 512, "disk block size (VM only)") createCmd.Flags().BoolVar(&clusterDiskPreallocate, clusterDiskPreallocateFlag, true, "whether disk space should be preallocated") createCmd.Flags().StringSliceVar(&clusterDisks, clusterDisksFlag, []string{}, "list of disks to create for each VM in format: :::") createCmd.Flags().IntVar(&extraDisks, "extra-disks", 0, "number of extra disks to create for each worker VM") diff --git a/go.mod b/go.mod index 0ef2ecfae1..641fb7bd07 100644 --- a/go.mod +++ b/go.mod @@ -142,7 +142,7 @@ require ( github.com/siderolabs/gen v0.8.0 github.com/siderolabs/go-api-signature v0.3.6 github.com/siderolabs/go-blockdevice v0.4.8 - github.com/siderolabs/go-blockdevice/v2 v2.0.9 + github.com/siderolabs/go-blockdevice/v2 v2.0.10 github.com/siderolabs/go-circular v0.2.1 github.com/siderolabs/go-cmd v0.1.3 github.com/siderolabs/go-copy v0.1.0 diff --git a/go.sum b/go.sum index ed68775997..803aec5acf 100644 --- a/go.sum +++ b/go.sum @@ -647,8 +647,8 @@ github.com/siderolabs/go-api-signature v0.3.6 h1:wDIsXbpl7Oa/FXvxB6uz4VL9INA9fmr github.com/siderolabs/go-api-signature v0.3.6/go.mod h1:hoH13AfunHflxbXfh+NoploqV13ZTDfQ1mQJWNVSW9U= github.com/siderolabs/go-blockdevice v0.4.8 h1:KfdWvIx0Jft5YVuCsFIJFwjWEF1oqtzkgX9PeU9cX4c= github.com/siderolabs/go-blockdevice v0.4.8/go.mod h1:4PeOuk71pReJj1JQEXDE7kIIQJPVe8a+HZQa+qjxSEA= -github.com/siderolabs/go-blockdevice/v2 v2.0.9 h1:OTo+ADN/3LT4XtI8p7Dz3hlh6DJABHwMAnOlK7MOtMk= -github.com/siderolabs/go-blockdevice/v2 v2.0.9/go.mod h1:74htzCV913UzaLZ4H+NBXkwWlYnBJIq5m/379ZEcu8w= +github.com/siderolabs/go-blockdevice/v2 v2.0.10 h1:hM6pUbch3GHQLeALUryNxq4vOzfOqA/RQ983ISa0BvU= +github.com/siderolabs/go-blockdevice/v2 v2.0.10/go.mod h1:74htzCV913UzaLZ4H+NBXkwWlYnBJIq5m/379ZEcu8w= github.com/siderolabs/go-circular v0.2.1 h1:a++iVCn9jyhICX3POQZZX8n72p2h5JGdGU6w1ulmpcA= github.com/siderolabs/go-circular v0.2.1/go.mod h1:ZDItzVyXK+B/XuqTBV5MtQtSv06VI+oCmWGRnNCATo8= github.com/siderolabs/go-cmd v0.1.3 h1:JrgZwqhJQeoec3QRON0LK+fv+0y7d0DyY7zsfkO6ciw= diff --git a/pkg/machinery/go.mod b/pkg/machinery/go.mod index 81331b5382..1fe70aeb01 100644 --- a/pkg/machinery/go.mod +++ b/pkg/machinery/go.mod @@ -27,7 +27,7 @@ require ( github.com/siderolabs/crypto v0.5.1 github.com/siderolabs/gen v0.8.0 github.com/siderolabs/go-api-signature v0.3.6 - github.com/siderolabs/go-blockdevice/v2 v2.0.9 + github.com/siderolabs/go-blockdevice/v2 v2.0.10 github.com/siderolabs/go-pointer v1.0.0 github.com/siderolabs/net v0.4.0 github.com/siderolabs/protoenc v0.2.1 diff --git a/pkg/machinery/go.sum b/pkg/machinery/go.sum index 8b486b0b79..fc8347a82e 100644 --- a/pkg/machinery/go.sum +++ b/pkg/machinery/go.sum @@ -114,8 +114,8 @@ github.com/siderolabs/gen v0.8.0 h1:Pj93+hexkk5hQ7izjJ6YXnEWc8vlzOmDwFz13/VzS7o= github.com/siderolabs/gen v0.8.0/go.mod h1:an3a2Y53O7kUjnnK8Bfu3gewtvnIOu5RTU6HalFtXQQ= github.com/siderolabs/go-api-signature v0.3.6 h1:wDIsXbpl7Oa/FXvxB6uz4VL9INA9fmr3EbmjEZYFJrU= github.com/siderolabs/go-api-signature v0.3.6/go.mod h1:hoH13AfunHflxbXfh+NoploqV13ZTDfQ1mQJWNVSW9U= -github.com/siderolabs/go-blockdevice/v2 v2.0.9 h1:OTo+ADN/3LT4XtI8p7Dz3hlh6DJABHwMAnOlK7MOtMk= -github.com/siderolabs/go-blockdevice/v2 v2.0.9/go.mod h1:74htzCV913UzaLZ4H+NBXkwWlYnBJIq5m/379ZEcu8w= +github.com/siderolabs/go-blockdevice/v2 v2.0.10 h1:hM6pUbch3GHQLeALUryNxq4vOzfOqA/RQ983ISa0BvU= +github.com/siderolabs/go-blockdevice/v2 v2.0.10/go.mod h1:74htzCV913UzaLZ4H+NBXkwWlYnBJIq5m/379ZEcu8w= github.com/siderolabs/go-pointer v1.0.0 h1:6TshPKep2doDQJAAtHUuHWXbca8ZfyRySjSBT/4GsMU= github.com/siderolabs/go-pointer v1.0.0/go.mod h1:HTRFUNYa3R+k0FFKNv11zgkaCLzEkWVzoYZ433P3kHc= github.com/siderolabs/go-retry v0.3.3 h1:zKV+S1vumtO72E6sYsLlmIdV/G/GcYSBLiEx/c9oCEg= diff --git a/pkg/provision/providers/qemu/launch.go b/pkg/provision/providers/qemu/launch.go index 06c8afd495..ecc9077eb7 100644 --- a/pkg/provision/providers/qemu/launch.go +++ b/pkg/provision/providers/qemu/launch.go @@ -42,6 +42,7 @@ type LaunchConfig struct { // VM options DiskPaths []string DiskDrivers []string + DiskBlockSizes []uint VCPUCount int64 MemSize int64 KernelImagePath string @@ -340,10 +341,14 @@ func launchVM(config *LaunchConfig) error { for i, disk := range config.DiskPaths { driver := config.DiskDrivers[i] + blockSize := config.DiskBlockSizes[i] switch driver { case "virtio": - args = append(args, "-drive", fmt.Sprintf("format=raw,if=virtio,file=%s,cache=none,", disk)) + args = append(args, + "-drive", fmt.Sprintf("id=virtio%d,format=raw,if=none,file=%s,cache=none", i, disk), + "-device", fmt.Sprintf("virtio-blk-pci,drive=virtio%d,logical_block_size=%d,physical_block_size=%d", i, blockSize, blockSize), + ) case "ide": args = append(args, "-drive", fmt.Sprintf("format=raw,if=ide,file=%s,cache=none,", disk)) case "ahci": @@ -366,7 +371,7 @@ func launchVM(config *LaunchConfig) error { args = append(args, "-drive", fmt.Sprintf("id=scsi%d,format=raw,if=none,file=%s,discard=unmap,aio=native,cache=none", i, disk), - "-device", fmt.Sprintf("scsi-hd,drive=scsi%d,bus=scsi0.0", i), + "-device", fmt.Sprintf("scsi-hd,drive=scsi%d,bus=scsi0.0,logical_block_size=%d,physical_block_size=%d", i, blockSize, blockSize), ) case "nvme": if !nvmeAttached { @@ -379,7 +384,7 @@ func launchVM(config *LaunchConfig) error { args = append(args, "-drive", fmt.Sprintf("id=nvme%d,format=raw,if=none,file=%s,discard=unmap,aio=native,cache=none", i, disk), - "-device", fmt.Sprintf("nvme-ns,drive=nvme%d", i), + "-device", fmt.Sprintf("nvme-ns,drive=nvme%d,logical_block_size=%d,physical_block_size=%d", i, blockSize, blockSize), ) default: return fmt.Errorf("unsupported disk driver %q", driver) diff --git a/pkg/provision/providers/qemu/node.go b/pkg/provision/providers/qemu/node.go index c9d485cad7..c4c4fe687c 100644 --- a/pkg/provision/providers/qemu/node.go +++ b/pkg/provision/providers/qemu/node.go @@ -137,8 +137,12 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe defaultBootOrder = nodeReq.DefaultBootOrder } - // backwards compatibility, set Driver if not set + // backwards compatibility, set Driver/BlockSize if not set for i := range nodeReq.Disks { + if nodeReq.Disks[i].BlockSize == 0 { + nodeReq.Disks[i].BlockSize = 512 + } + if nodeReq.Disks[i].Driver != "" { continue } @@ -156,6 +160,9 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe DiskDrivers: xslices.Map(nodeReq.Disks, func(disk *provision.Disk) string { return disk.Driver }), + DiskBlockSizes: xslices.Map(nodeReq.Disks, func(disk *provision.Disk) uint { + return disk.BlockSize + }), VCPUCount: vcpuCount, MemSize: memSize, KernelArgs: cmdline.String(), diff --git a/pkg/provision/request.go b/pkg/provision/request.go index d769347343..828debe915 100644 --- a/pkg/provision/request.go +++ b/pkg/provision/request.go @@ -165,6 +165,8 @@ type Disk struct { // // Supported types: "virtio", "ide", "ahci", "scsi", "nvme". Driver string + // Block size for the disk, defaults to 512 if not set. + BlockSize uint } // ConfigInjectionMethod describes how to inject configuration into the node. diff --git a/website/content/v1.10/reference/cli.md b/website/content/v1.10/reference/cli.md index b8d9307ffb..9126e9007c 100644 --- a/website/content/v1.10/reference/cli.md +++ b/website/content/v1.10/reference/cli.md @@ -158,6 +158,7 @@ talosctl cluster create [flags] --custom-cni-url string install custom CNI from the URL (Talos cluster) --disable-dhcp-hostname skip announcing hostname via DHCP (QEMU only) --disk int default limit on disk size in MB (each VM) (default 6144) + --disk-block-size uint disk block size (VM only) (default 512) --disk-encryption-key-types stringArray encryption key types to use for disk encryption (uuid, kms) (default [uuid]) --disk-image-path string disk image to use --disk-preallocate whether disk space should be preallocated (default true)