Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion service/lib/agama/dbus/storage/dasd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def configure(serialized_config)

private

# @return [Agama::Storage::ISCSI::Manager]
# @return [Agama::Storage::DASD::Manager]
attr_reader :manager

# Performs the configuration process in a separate thread.
Expand Down
46 changes: 1 addition & 45 deletions service/lib/agama/storage/dasd/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ def initialize(logger: nil)
# Keeps whether a configuration was already applied. In some cases it is necessary to
# consider that the config has not being applied yet, see {#probe}.
@configured = false
# Keeps the list of locked devices. A device is considered as locked if it is active at
# the time of probing. Those devices should not be deactivated when applying a config that
# does not include such devices.
@locked_devices = []
# Keeps the list of formatted devices. A device is added to the list when it was formatted
# as effect of applying a config. Those devices should not be formatted anymore when
# applying a new config.
Expand All @@ -88,7 +84,6 @@ def probe
@devices = reader.list(force_probing: true)
# Initialize the attribute just in case the reader doesn't do it (see bsc#1209162)
@devices.each { |d| d.diag_wanted = d.use_diag }
assign_locked_devices(@devices)
end

# Applies the given DASD config.
Expand All @@ -106,7 +101,6 @@ def configure(config_json)
format_devices(config)
enable_diag(config)
disable_diag(config)
remove_locked_devices(config)
end

# Whether the system is already configured for the given config.
Expand Down Expand Up @@ -169,20 +163,10 @@ def activate_devices(config)
# @param config [Config]
# @return [Array<Y2S390::Dasd>] Deactivated devices.
def deactivate_devices(config)
# Explictly deactivated devices.
deactivated_devices = config.devices
devices = config.devices
.reject(&:active?)
.map { |d| find_device(d.channel) }
.compact

# Devices that are not included in the config and are not locked.
missing_devices = devices
.reject { |d| device_locked?(d) }
.reject { |d| config.include_device?(d.id) }

devices = deactivated_devices
.concat(missing_devices)
.uniq
.select(&:active?)

return [] if devices.empty?
Expand Down Expand Up @@ -267,34 +251,6 @@ def refresh_devices(devices)
devices.each { |d| reader.update_info(d, extended: true) }
end

# Sets the list of locked devices.
#
# A device is considered as locked if it is active and not configured yet.
#
# @param devices [Array<Y2S390::Dasd>]
def assign_locked_devices(devices)
config = ConfigImporter.new(config_json || {}).import
@locked_devices = devices
.reject(&:offline?)
.reject { |d| config.include_device?(d.id) }
.map(&:id)
end

# Removes the given devices from the list of locked devices.
#
# @param config [Config]
def remove_locked_devices(config)
config.devices.each { |d| @locked_devices.delete(d.channel) }
end

# Whether the given device is locked.
#
# @param device [Y2S390::Dasd]
# @return [Boolean]
def device_locked?(device)
@locked_devices.include?(device.id)
end

# Whether the given device was formatted.
#
# @param device [Y2S390::Dasd]
Expand Down
6 changes: 6 additions & 0 deletions service/package/rubygem-agama-yast.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Mon Feb 16 16:31:50 UTC 2026 - José Iván López González <jlopez@suse.com>

- Avoid automatic deactivation of unlisted DASD devices
(gh#agama-project/agama#3181).

-------------------------------------------------------------------
Fri Feb 13 09:22:48 UTC 2026 - José Iván López González <jlopez@suse.com>

Expand Down
85 changes: 2 additions & 83 deletions service/test/agama/storage/dasd/manager_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,33 +101,6 @@ def all
expect(dasd2).to receive(:diag_wanted=).with(false)
subject.probe
end

it "locks devices that are not offline" do
subject.probe
expect(subject.send(:device_locked?, dasd1)).to be(true)
expect(subject.send(:device_locked?, dasd2)).to be(false)
end

context "when a configuration is already present" do
let(:config_json) { { devices: [{ channel: "0.0.0100" }] } }

before do
allow(subject).to receive(:config_json).and_return(config_json)
end

context "if a device is part of the configuration" do
before do
allow(dasd1).to receive(:offline?).and_return(false)
allow(dasd2).to receive(:offline?).and_return(false)
end

it "does not lock active devices that are part of the configuration" do
subject.probe
expect(subject.send(:device_locked?, dasd1)).to be(false)
expect(subject.send(:device_locked?, dasd2)).to be(true)
end
end
end
end

describe "#configured?" do
Expand Down Expand Up @@ -207,7 +180,6 @@ def all
before do
devices.each { |d| allow(d).to receive(:diag_wanted=) }
allow(reader).to receive(:update_info)
allow(subject).to receive(:device_locked?).and_return(false)

# Mock all operations
allow(Agama::Storage::DASD::EnableOperation).to receive(:new).and_return(enable_operation)
Expand Down Expand Up @@ -338,27 +310,10 @@ def all
allow(dasd4).to receive(:active?).and_return(false)
end

it "deactivates the unlisted device if active" do
expect(Agama::Storage::DASD::DisableOperation).to receive(:new) do |devices, _|
expect(devices).to contain_exactly(dasd1, dasd3)
disable_operation
end
it "does not deactivate the unlisted devices" do
expect(Agama::Storage::DASD::DisableOperation).to_not receive(:new)
subject.configure(config_json)
end

context "and some unlisted device is locked" do
before do
allow(subject).to receive(:device_locked?).with(dasd1).and_return(true)
end

it "does not deactivate the locked devices" do
expect(Agama::Storage::DASD::DisableOperation).to receive(:new) do |devices, _|
expect(devices).to contain_exactly(dasd3)
disable_operation
end
subject.configure(config_json)
end
end
end

context "if the config formats a device" do
Expand Down Expand Up @@ -590,42 +545,6 @@ def all
subject.configure(config_json)
end
end

context "if a device is configured" do
let(:config_json) do
{
devices: [
{
channel: "0.0.0002",
state: "active",
format: false
},
{
channel: "0.0.0003",
state: "active",
format: false
}
]
}
end

before do
allow(dasd1).to receive(:offline?).and_return(true)
allow(dasd2).to receive(:offline?).and_return(false)
allow(dasd2).to receive(:active?).and_return(true)
allow(dasd3).to receive(:offline?).and_return(false)
allow(dasd4).to receive(:offline?).and_return(false)
allow(subject).to receive(:device_locked?).and_call_original
end

it "removes configured devices from locked devices" do
subject.configure(config_json)
expect(subject.send(:device_locked?, dasd1)).to eq(false)
expect(subject.send(:device_locked?, dasd2)).to eq(false)
expect(subject.send(:device_locked?, dasd3)).to eq(false)
expect(subject.send(:device_locked?, dasd4)).to eq(true)
end
end
end

describe "#device_type" do
Expand Down