Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bsc#1163149] Do not activate devices twice #81

Merged
merged 14 commits into from
Apr 2, 2020
Merged
Show file tree
Hide file tree
Changes from 8 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
7 changes: 7 additions & 0 deletions package/yast2-s390.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Tue Mar 31 13:52:28 UTC 2020 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

- Do not try to activate DASD and zFCP devices that are already
active (bsc#1163149). Related to SLE-7396.
imobachgs marked this conversation as resolved.
Show resolved Hide resolved
- 4.2.5

-------------------------------------------------------------------
Mon Mar 23 13:56:13 UTC 2020 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-s390.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


Name: yast2-s390
Version: 4.2.4
Version: 4.2.5
Release: 0
Group: System/YaST
License: GPL-2.0-only
Expand Down
172 changes: 106 additions & 66 deletions src/modules/DASDController.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def Write
channel = Ops.get_string(device, "channel", "")
format = Ops.get_boolean(device, "format", false)
do_diag = Ops.get_boolean(device, "diag", false)
act_ret = ActivateDisk(channel, do_diag)
act_ret = activate_disk_if_needed(channel, do_diag)
# FIXME: general activation error handling - also in sync with below
# for AutoInstall, format unformatted disks later at once
# even disks manually selected for formatting must be reactivated
Expand Down Expand Up @@ -381,78 +381,18 @@ def ProbeDisks
# popup label
UI.OpenDialog(Label(_("Reading Configured DASD Disks")))

disks = Convert.convert(
SCR.Read(path(".probe.disk")),
from: "any",
to: "list <map <string, any>>"
)
disks = Builtins.filter(disks) do |d|
Builtins.tolower(Ops.get_string(d, "device", "")) == "dasd"
end

disks.sort_by! { |disk| FormatChannel(disk.fetch("sysfs_bus_id", "0.0.0000")) }

disks = Builtins.maplist(disks) do |d|
channel = Ops.get_string(d, "sysfs_bus_id", "")
Ops.set(d, "channel", channel)
active = Ops.get_boolean(d, ["resource", "io", 0, "active"], false)
if active
device = Ops.get_string(d, "dev_name", "")
scr_out = Convert.to_map(
SCR.Execute(
path(".target.bash_output"),
Builtins.sformat("/sbin/dasdview --extended '%1' | grep formatted", device)
)
)
formatted = false
if Ops.get_integer(scr_out, "exit", 0) == 0
out = Ops.get_string(scr_out, "stdout", "")
formatted = !Builtins.regexpmatch(
Builtins.toupper(out),
"NOT[ \t]*FORMATTED"
)
end
Ops.set(d, "formatted", formatted)

Ops.set(d, "partition_info", GetPartitionInfo(device)) if formatted

diag_file = Builtins.sformat(
"/sys/%1/device/use_diag",
Ops.get_string(d, "sysfs_id", "")
)
if FileUtils.Exists(diag_file)
use_diag = Convert.to_string(
SCR.Read(path(".target.string"), diag_file)
)
Ops.set(d, "diag", Builtins.substring(use_diag, 0, 1) == "1")
Ops.set(@diag, channel, Builtins.substring(use_diag, 0, 1) == "1")
end
end
d = Builtins.filter(d) do |k, _v|
Builtins.contains(
[
"channel",
"diag",
"resource",
"formatted",
"partition_info",
"dev_name",
"detail",
"device_id",
"sub_device_id"
],
k
)
end
deep_copy(d)
end
disks = find_disks(true)

index = -1
@devices = Builtins.listmap(disks) do |d|
index = Ops.add(index, 1)
{ index => d }
end

disks.each do |dev|
@diag[dev["channel"]] = dev["diag"] if dev["diag"]
end

Builtins.y2milestone("probed DASD devices %1", @devices)

UI.CloseDialog
Expand Down Expand Up @@ -851,6 +791,106 @@ def report_error(headline, message, details)
Yast2::Popup.show(message, headline: headline, details: details)
end
end

# Activates a disk if its not activated
#
# When the disk is already activated, it returns '8' if the
# disk is unformatted or '0' otherwise. The idea is to mimic
# the same API that ActivateDisk.
imobachgs marked this conversation as resolved.
Show resolved Hide resolved
#
# @return [Boolean] Returns an error code (8 means 'unformatted').
imobachgs marked this conversation as resolved.
Show resolved Hide resolved
def activate_disk_if_needed(channel, diag)
disk = find_disks.find { |d| d["channel"] == channel }
if disk && active_disk?(disk)
log.info "Disk #{channel} is already active. Skipping the activation."
imobachgs marked this conversation as resolved.
Show resolved Hide resolved
return disk["formatted"] ? 0 : 8
end
ActivateDisk(channel, diag) unless disk && active_disk?(disk)
imobachgs marked this conversation as resolved.
Show resolved Hide resolved
end

# Determines whether the disk is activated or not
#
# @param disk [Hash]
# @return [Boolean]
def active_disk?(disk)
io = disk.fetch("resource", {}).fetch("io", []).first
imobachgs marked this conversation as resolved.
Show resolved Hide resolved
!!(io && io["active"])
end

# Returns the DASD disks
#
# Probes and returns the found DASD disks ordered by channel.
# It caches the found disks.
#
# @param force_probing [Boolean] Ignore the cached values and probes again.
# @return [Array<Hash>] Found DASD disks
def find_disks(force_probing = false)
imobachgs marked this conversation as resolved.
Show resolved Hide resolved
return @disks if @disks && !force_probing
disks = Convert.convert(
SCR.Read(path(".probe.disk")),
from: "any",
to: "list <map <string, any>>"
)
disks = Builtins.filter(disks) do |d|
Builtins.tolower(Ops.get_string(d, "device", "")) == "dasd"
end

disks.sort_by! { |disk| FormatChannel(disk.fetch("sysfs_bus_id", "0.0.0000")) }

@disks = Builtins.maplist(disks) do |d|
channel = Ops.get_string(d, "sysfs_bus_id", "")
Ops.set(d, "channel", channel)
active = Ops.get_boolean(d, ["resource", "io", 0, "active"], false)
if active
device = Ops.get_string(d, "dev_name", "")
scr_out = Convert.to_map(
SCR.Execute(
path(".target.bash_output"),
Builtins.sformat("/sbin/dasdview --extended '%1' | grep formatted", device)
)
)
formatted = false
if Ops.get_integer(scr_out, "exit", 0) == 0
out = Ops.get_string(scr_out, "stdout", "")
formatted = !Builtins.regexpmatch(
Builtins.toupper(out),
"NOT[ \t]*FORMATTED"
)
end
Ops.set(d, "formatted", formatted)

Ops.set(d, "partition_info", GetPartitionInfo(device)) if formatted

diag_file = Builtins.sformat(
"/sys/%1/device/use_diag",
Ops.get_string(d, "sysfs_id", "")
)
if FileUtils.Exists(diag_file)
use_diag = Convert.to_string(
SCR.Read(path(".target.string"), diag_file)
)
Ops.set(d, "diag", Builtins.substring(use_diag, 0, 1) == "1")
end
end
d = Builtins.filter(d) do |k, _v|
Builtins.contains(
[
"channel",
"diag",
"resource",
"formatted",
"partition_info",
"dev_name",
"detail",
"device_id",
"sub_device_id"
],
k
)
end
deep_copy(d)
end
end
end

DASDController = DASDControllerClass.new
Expand Down
Loading