Skip to content

Commit

Permalink
Merge pull request #1104 from yast/cio_ignore_always
Browse files Browse the repository at this point in the history
Write cio_ignore kernel arguments always
  • Loading branch information
teclator committed Jan 25, 2024
2 parents 25e6ff5 + 98b1343 commit 94b7d84
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 56 deletions.
8 changes: 8 additions & 0 deletions package/yast2-installation.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
-------------------------------------------------------------------
Thu Jan 25 10:09:51 UTC 2024 - Knut Anderssen <kanderssen@suse.com>

- Keep cio_ignore kernel argument when present in the parmfile or
use the cio_ignore -k output if not and write it always even
in zVM and KVM (bsc#1210525).
- 5.0.4

-------------------------------------------------------------------
Wed Nov 29 16:27:50 UTC 2023 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

Expand Down
10 changes: 5 additions & 5 deletions package/yast2-installation.spec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#

Name: yast2-installation
Version: 5.0.3
Version: 5.0.4
Release: 0
Summary: YaST2 - Installation Parts
License: GPL-2.0-only
Expand All @@ -27,10 +27,10 @@ Source1: YaST2-Second-Stage.service
Source2: YaST2-Firstboot.service

BuildRequires: update-desktop-files
# Y2Packager::Repository.refresh
BuildRequires: yast2 >= 5.0.3
# new name for CPUMitigation widget
BuildRequires: yast2-bootloader >= 5.0.1
# Kernel: Read kernel arguments from cmdline if install.inf does not exist (bsc#1216408).
BuildRequires: yast2 >= 5.0.4
# Whitelist cio_ignore s390 parameter
BuildRequires: yast2-bootloader >= 5.0.4
# storage-ng based version
BuildRequires: yast2-country >= 3.3.1
BuildRequires: yast2-devtools >= 3.1.10
Expand Down
44 changes: 19 additions & 25 deletions src/lib/installation/cio_ignore.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ def reset

private

def kvm?
File.exist?("/proc/sysinfo") &&
File.readlines("/proc/sysinfo").grep(/Control Program: KVM\/Linux/).any?
end

def zvm?
File.exist?("/proc/sysinfo") &&
File.readlines("/proc/sysinfo").grep(/Control Program: z\/VM/).any?
end

# Get current I/O device autoconf setting (rd.zdev kernel option)
#
# @return [Boolean]
Expand All @@ -50,13 +40,7 @@ def autoconf_setting
#
# @return [Boolean]
def cio_setting
if Yast::Mode.autoinst
Yast::AutoinstConfig.cio_ignore
else
# cio_ignore does not make sense for KVM or z/VM (fate#317861)
# but for other cases return true as requested FATE#315586
!(kvm? || zvm?)
end
Yast::Mode.autoinst ? Yast::AutoinstConfig.cio_ignore : true
end
end

Expand Down Expand Up @@ -182,6 +166,7 @@ class CIOIgnoreFinish
].freeze

YAST_BASH_PATH = Yast::Path.new ".target.bash_output"
YAST_LOCAL_BASH_PATH = Yast::Path.new ".local.bash_output"

def initialize
textdomain "installation"
Expand Down Expand Up @@ -224,9 +209,9 @@ def run(*args)
def write_cio_setting
return unless CIOIgnore.instance.cio_enabled

res = Yast::SCR.Execute(YAST_BASH_PATH, "/sbin/cio_ignore --unused --purge")
res = Yast::WFM.Execute(YAST_LOCAL_BASH_PATH, "/sbin/cio_ignore --unused --purge")

log.info "result of cio_ignore call: #{res.inspect}"
log.info "result of cio_ignore --unused --purge call: #{res.inspect}"

raise "cio_ignore command failed with stderr: #{res["stderr"]}" if res["exit"] != 0

Expand Down Expand Up @@ -255,28 +240,37 @@ def write_autoconf_setting
def add_cio_boot_kernel_parameters
Yast.import "Bootloader"

param = Yast::Bootloader.kernel_param(:common, "cio_ignore")

return unless param == :missing

res = Yast::WFM.Execute(YAST_LOCAL_BASH_PATH, "/sbin/cio_ignore -k")

raise "cio_ignore -k failed with #{res["stderr"]}" if res["exit"] != 0

# boot code is already proposed and will be written in next step, so just modify
Yast::Bootloader.modify_kernel_params("cio_ignore" => "all,!ipldev,!condev")
Yast::Bootloader.modify_kernel_params("cio_ignore" => res["stdout"].lines.first.strip)
end

ACTIVE_DEVICES_FILE = "/boot/zipl/active_devices.txt".freeze
def store_active_devices
Yast.import "Installation"
res = Yast::SCR.Execute(YAST_BASH_PATH, "/sbin/cio_ignore -L")
log.info "active devices: #{res}"
res = Yast::WFM.Execute(YAST_LOCAL_BASH_PATH, "/sbin/cio_ignore -L")

raise "cio_ignore -L failed with #{res["stderr"]}" if res["exit"] != 0

# lets select only lines that looks like device. Regexp is not perfect, but good enough
devices_lines = res["stdout"].lines.grep(/^(?:\h.){0,2}\h{4}.*$/)

devices = devices_lines.map(&:chomp)
target_file = File.join(Yast::Installation.destdir, ACTIVE_DEVICES_FILE)

# make sure the file ends with a new line character
devices << "" unless devices.empty?

File.write(target_file, devices.join("\n"))
devices_txt = devices.join("\n")
log.info "active devices to be written: #{devices_txt}"

target_file = File.join(Yast::Installation.destdir, ACTIVE_DEVICES_FILE)
File.write(target_file, devices_txt)
end
end
end
86 changes: 60 additions & 26 deletions test/cio_ignore_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,28 @@
end

describe "cio_ignore enable/disable" do
it "take AutoYaST cio_ignore setting" do
allow(Yast::Mode).to receive(:autoinst).and_return(true)
allow(Yast::AutoinstConfig).to receive(:cio_ignore).and_return(false)
::Installation::CIOIgnore.instance.reset
expect(::Installation::CIOIgnore.instance.cio_enabled).to eq(false)
let(:auto) { false }

before do
allow(Yast::Mode).to receive(:autoinst).and_return(auto)
end

it "take default cio_ignore entry if it is in the normal workflow" do
allow(Yast::Mode).to receive(:autoinst).and_return(false)
expect(Yast::AutoinstConfig).not_to receive(:cio_ignore)
expect(File).to receive(:exist?).with("/proc/sysinfo").exactly(2).times.and_return(false)
::Installation::CIOIgnore.instance.reset
expect(::Installation::CIOIgnore.instance.cio_enabled).to eq(true)
context "in autoinstallation" do
let(:auto) { true }

it "takes AutoYaST cio_ignore setting" do
allow(Yast::AutoinstConfig).to receive(:cio_ignore).and_return(false)
::Installation::CIOIgnore.instance.reset
expect(::Installation::CIOIgnore.instance.cio_enabled).to eq(false)
end
end

context "in other modes" do
it "takes the default cio_ignore entry" do
expect(Yast::AutoinstConfig).not_to receive(:cio_ignore)
::Installation::CIOIgnore.instance.reset
expect(::Installation::CIOIgnore.instance.cio_enabled).to eq(true)
end
end
end
end
Expand Down Expand Up @@ -161,15 +170,19 @@
end

describe "first parameter \"Write\"" do
let(:param) { "all,!ipldev,!condev" }

before(:each) do
stub_const("Yast::Installation", double(destdir: "/mnt"))
stub_const("Yast::Bootloader", double)

allow(Yast::Bootloader).to receive(:Write) { true }
allow(Yast::Bootloader).to receive(:Read) { true }
allow(Yast::Bootloader).to receive(:modify_kernel_params) { true }
allow(Yast::Bootloader).to receive(:kernel_param)
.with(:common, "cio_ignore").and_return(param)

allow(Yast::SCR).to receive(:Execute)
allow(Yast::WFM).to receive(:Execute)
.and_return("exit" => 0, "stdout" => "", "stderr" => "")

allow(File).to receive(:write)
Expand All @@ -179,7 +192,7 @@
it "does nothing" do
::Installation::CIOIgnore.instance.cio_enabled = false

expect(Yast::SCR).to_not receive(:Execute)
expect(Yast::WFM).to_not receive(:Execute)
expect(Yast::Bootloader).to_not receive(:Read)

subject.run("Write")
Expand All @@ -190,9 +203,9 @@
it "calls `cio_ignore --unused --purge`" do
::Installation::CIOIgnore.instance.cio_enabled = true

expect(Yast::SCR).to receive(:Execute)
expect(Yast::WFM).to receive(:Execute)
.with(
::Installation::CIOIgnoreFinish::YAST_BASH_PATH,
::Installation::CIOIgnoreFinish::YAST_LOCAL_BASH_PATH,
"/sbin/cio_ignore --unused --purge"
)
.once
Expand All @@ -205,9 +218,9 @@
::Installation::CIOIgnore.instance.cio_enabled = true
stderr = "HORRIBLE ERROR!!!"

expect(Yast::SCR).to receive(:Execute)
expect(Yast::WFM).to receive(:Execute)
.with(
::Installation::CIOIgnoreFinish::YAST_BASH_PATH,
::Installation::CIOIgnoreFinish::YAST_LOCAL_BASH_PATH,
"/sbin/cio_ignore --unused --purge"
)
.once
Expand All @@ -216,12 +229,33 @@
expect { subject.run("Write") }.to raise_error(RuntimeError, /stderr/)
end

it "adds kernel parameters IPLDEV and CONDEV to the bootloader" do
expect(Yast::Bootloader).to receive(:modify_kernel_params)
.with("cio_ignore" => "all,!ipldev,!condev").once
.and_return(true)
context "when the cio_ignore kernel argument is already given" do
it "does not touch the kernel parameters" do
expect(Yast::Bootloader).to_not receive(:modify_kernel_params)
.with("cio_ignore" => anything)

subject.run("Write")
subject.run("Write")
end
end

context "when the cio_ignore kernel argument is not given" do
let(:param) { :missing }
let(:cio_k_output) { "all,!0009,!0160,!0800-0802" }

it "adds the parameter using the 'cio_ignore -k' output to the bootloader" do
expect(Yast::WFM).to receive(:Execute)
.with(
Installation::CIOIgnoreFinish::YAST_LOCAL_BASH_PATH,
"/sbin/cio_ignore -k"
)
.once
.and_return("exit" => 0, "stdout" => cio_k_output, "stderr" => "")
expect(Yast::Bootloader).to receive(:modify_kernel_params)
.with("cio_ignore" => cio_k_output).once
.and_return(true)

subject.run("Write")
end
end

it "writes list of active devices to zipl so it is not blocked" do
Expand All @@ -233,9 +267,9 @@
0.0.0700-0.0.0702
0.0.fc00
CIO_IGNORE
expect(Yast::SCR).to receive(:Execute)
expect(Yast::WFM).to receive(:Execute)
.with(
::Installation::CIOIgnoreFinish::YAST_BASH_PATH,
::Installation::CIOIgnoreFinish::YAST_LOCAL_BASH_PATH,
"/sbin/cio_ignore -L"
)
.once
Expand All @@ -251,9 +285,9 @@
end

it "raises an exception if cio_ignore -L failed" do
expect(Yast::SCR).to receive(:Execute)
expect(Yast::WFM).to receive(:Execute)
.with(
::Installation::CIOIgnoreFinish::YAST_BASH_PATH,
::Installation::CIOIgnoreFinish::YAST_LOCAL_BASH_PATH,
"/sbin/cio_ignore -L"
)
.once
Expand Down

0 comments on commit 94b7d84

Please sign in to comment.