From 727e82b0bb9b229d8d27411db827f947ad2ecd23 Mon Sep 17 00:00:00 2001 From: Adarsh Kumar Yadav Date: Thu, 23 Apr 2026 11:17:18 +0530 Subject: [PATCH] libvirt: omit PAE/ACPI/APIC features for s390x domains newDomainDef() always set x86-oriented features. On s390x, RHEL 9 + QEMU 9 with machine types like s390-ccw-virtio-rhel9.6.0 reject with virError 67 (machine type does not support ACPI), blocking worker Machine creation. Clear the features block for s390 after resolving host arch and machine type in newDomainDefForConnection. Add unit tests (ClearX86Only). --- pkg/cloud/libvirt/client/domain.go | 17 +++++++++++++++++ pkg/cloud/libvirt/client/domain_test.go | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/pkg/cloud/libvirt/client/domain.go b/pkg/cloud/libvirt/client/domain.go index 168d8f593..36bff7168 100644 --- a/pkg/cloud/libvirt/client/domain.go +++ b/pkg/cloud/libvirt/client/domain.go @@ -68,6 +68,20 @@ func newDomainDef() libvirtxml.Domain { return domainDef } +// clearX86OnlyDomainFeaturesForArch removes PAE/ACPI/APIC features for +// architectures where libvirt does not support them. newDomainDef() always +// sets x86-style features; s390x guests use virtio-ccw / SCLP, and machine +// types such as s390-ccw-virtio-rhel9.6.0 on RHEL 9 + QEMU 9 reject +// with virError 67 (does not support ACPI). +func clearX86OnlyDomainFeaturesForArch(d *libvirtxml.Domain) { + if d == nil || d.OS == nil || d.OS.Type == nil { + return + } + if strings.HasPrefix(d.OS.Type.Arch, "s390") { + d.Features = nil + } +} + func newDevicesDef() *libvirtxml.DomainDeviceList { domainList := libvirtxml.DomainDeviceList{ Channels: []libvirtxml.DomainChannel{ @@ -201,6 +215,9 @@ func newDomainDefForConnection(virConn *libvirt.Connect) (libvirtxml.Domain, err return d, err } d.OS.Type.Machine = canonicalmachine + + clearX86OnlyDomainFeaturesForArch(&d) + return d, nil } diff --git a/pkg/cloud/libvirt/client/domain_test.go b/pkg/cloud/libvirt/client/domain_test.go index ba0320407..7916ce2f7 100644 --- a/pkg/cloud/libvirt/client/domain_test.go +++ b/pkg/cloud/libvirt/client/domain_test.go @@ -7,6 +7,28 @@ import ( libvirtxml "github.com/libvirt/libvirt-go-xml" ) +func TestClearX86OnlyDomainFeaturesForArchS390x(t *testing.T) { + d := newDomainDef() + if d.Features == nil || d.Features.ACPI == nil { + t.Fatal("newDomainDef should set x86-style features including ACPI") + } + d.OS.Type.Arch = "s390x" + clearX86OnlyDomainFeaturesForArch(&d) + if d.Features != nil { + t.Fatalf("s390x: expected Features=nil, got %#v", d.Features) + } +} + +func TestClearX86OnlyDomainFeaturesForArchAmd64(t *testing.T) { + d := newDomainDef() + orig := d.Features + d.OS.Type.Arch = "x86_64" + clearX86OnlyDomainFeaturesForArch(&d) + if d.Features != orig { + t.Fatal("x86_64: Features should be unchanged") + } +} + func TestSetCoreOSIgnition(t *testing.T) { testCases := []struct { ignKey string