Skip to content

Commit

Permalink
Merge pull request #5250 from steffen-maier/zdev
Browse files Browse the repository at this point in the history
consolidated s390 device configuration
  • Loading branch information
rvykydal authored Oct 11, 2024
2 parents 48d5f97 + 9e3cb46 commit 7c96bd8
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 110 deletions.
5 changes: 4 additions & 1 deletion anaconda.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Source0: https://github.com/rhinstaller/%{name}/releases/download/%{name}-%{vers
%define dasbusver 1.3
%define dbusver 1.2.3
%define dnfver 3.6.0
%define dracutver 034-7
%define dracutver 102-3
%define fcoeutilsver 1.0.12-3.20100323git
%define gettextver 0.19.8
%define gtk3ver 3.22.17
Expand All @@ -46,6 +46,7 @@ Source0: https://github.com/rhinstaller/%{name}/releases/download/%{name}-%{vers
%define subscriptionmanagerver 1.26
%define utillinuxver 2.15.1
%define rpmostreever 2023.2
%define s390utilscorever 2.31.0

BuildRequires: libtool
BuildRequires: gettext-devel >= %{gettextver}
Expand Down Expand Up @@ -125,6 +126,8 @@ Requires: NetworkManager-team
%endif
%ifarch s390 s390x
Requires: openssh
Requires: s390utils-core >= %{s390utilscorever}
Requires: dracut-network >= %{dracutver}
%endif
Requires: NetworkManager >= %{nmver}
Requires: NetworkManager-libnm >= %{nmver}
Expand Down
1 change: 1 addition & 0 deletions data/systemd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dist_systemd_DATA = anaconda.service \
anaconda-nm-config.service \
anaconda-nm-disable-autocons.service \
anaconda-pre.service \
anaconda-s390-device-config-import.service \
anaconda-fips.service

dist_generator_SCRIPTS = anaconda-generator
Expand Down
21 changes: 21 additions & 0 deletions data/systemd/anaconda-s390-device-config-import.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[Unit]
# This service is to be run before anaconda starts and log data before anaconda changes them
# Import persistent config of any s390 devices (dasd, zfcp, znet) from
# initrd to retain user choices made with rd.dasd, rd.zfcp, rd.znet.
Description=pre-anaconda s390 device persistent config import
ConditionArchitecture=s390x
Requires=basic.target
After=basic.target
Before=anaconda.target
Wants=rsyslog.service
Wants=systemd-udev-settle.service
Wants=plymouth-quit.service plymouth-quit-wait.service
Wants=systemd-logind.service

[Service]
Type=oneshot
ExecStart=-/sbin/chzdev --import /run/zdev.initrd.config --persistent --yes --no-root-update --force --verbose
StandardInput=tty
StandardOutput=journal+console
StandardError=journal+console
TimeoutSec=0
1 change: 1 addition & 0 deletions data/systemd/anaconda.target
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Wants=anaconda-direct.service anaconda.service
Wants=anaconda-sshd.service
Wants=anaconda-pre.service
Wants=anaconda-fips.service
Wants=anaconda-s390-device-config-import.service
Wants=systemd-logind.service
Wants=brltty.service
Wants=rhsm.service
Expand Down
1 change: 0 additions & 1 deletion dracut/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ dist_dracut_SCRIPTS = module-setup.sh \
anaconda-copy-cmdline.sh \
anaconda-copy-dhclient.sh \
anaconda-copy-prefixdevname.sh \
anaconda-copy-s390ccwconf.sh \
anaconda-ifcfg.sh \
anaconda-set-kernel-hung-timeout.sh \
anaconda-error-reporting.sh \
Expand Down
3 changes: 0 additions & 3 deletions dracut/anaconda-copy-s390ccwconf.sh

This file was deleted.

1 change: 0 additions & 1 deletion dracut/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ install() {
inst "$moddir/anaconda-diskroot" "/sbin/anaconda-diskroot"
inst_hook pre-pivot 50 "$moddir/anaconda-copy-ks.sh"
inst_hook pre-pivot 50 "$moddir/anaconda-copy-cmdline.sh"
inst_hook pre-pivot 50 "$moddir/anaconda-copy-s390ccwconf.sh"
inst_hook pre-pivot 90 "$moddir/anaconda-copy-dhclient.sh"
inst_hook pre-pivot 91 "$moddir/anaconda-copy-prefixdevname.sh"
inst_hook pre-pivot 95 "$moddir/anaconda-set-kernel-hung-timeout.sh"
Expand Down
20 changes: 5 additions & 15 deletions pyanaconda/modules/network/nm_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from pyanaconda.modules.network.utils import get_s390_settings, netmask2prefix, prefix2netmask
from pyanaconda.modules.network.config_file import is_config_file_for_system
from pyanaconda.core.dbus import SystemBus
from pyanaconda.core import util

from pyanaconda.anaconda_loggers import get_module_logger
log = get_module_logger(__name__)
Expand Down Expand Up @@ -437,12 +438,6 @@ def _update_wired_connection_with_s390_settings(connection, s390cfg):
if s390cfg['SUBCHANNELS']:
subchannels = s390cfg['SUBCHANNELS'].split(",")
s_wired.props.s390_subchannels = subchannels
if s390cfg['NETTYPE']:
s_wired.props.s390_nettype = s390cfg['NETTYPE']
if s390cfg['OPTIONS']:
opts = s390cfg['OPTIONS'].split(" ")
opts_dict = {k: v for k, v in (o.split("=") for o in opts)}
s_wired.props.s390_options = opts_dict


def _create_new_connection(network_data, device_name):
Expand Down Expand Up @@ -1379,15 +1374,10 @@ def _get_dracut_znet_argument_from_connection(connection):
argument = ""
wired_setting = connection.get_setting_wired()
if wired_setting and is_s390():
nettype = wired_setting.get_s390_nettype()
# get_s390_subchannels() returns a list of subchannels
subchannels = wired_setting.get_s390_subchannels()
if nettype and subchannels:
argument = "rd.znet={},{}".format(nettype, ",".join(subchannels))
options = wired_setting.get_property(NM.SETTING_WIRED_S390_OPTIONS)
if options:
options_string = ','.join("{}={}".format(key, val) for key, val in options.items())
argument += ",{}".format(options_string)
devspec = util.execWithCapture("/lib/s390-tools/zdev-to-rd.znet",
["persistent",
connection.get_interface_name()]).strip()
argument = "rd.znet={}".format(devspec)
return argument


Expand Down
19 changes: 0 additions & 19 deletions pyanaconda/modules/network/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
def get_s390_settings(devname):
cfg = {
'SUBCHANNELS': '',
'NETTYPE': '',
'OPTIONS': ''
}

subchannels = []
Expand All @@ -46,23 +44,6 @@ def get_s390_settings(devname):
return cfg
cfg['SUBCHANNELS'] = ','.join(subchannels)

# Example of the ccw.conf file content:
# qeth,0.0.0900,0.0.0901,0.0.0902,layer2=0,portname=FOOBAR,portno=0
#
# SUBCHANNELS="0.0.0900,0.0.0901,0.0.0902"
# NETTYPE="qeth"
# OPTIONS="layer2=1 portname=FOOBAR portno=0"
if not os.path.exists('/run/install/ccw.conf'):
return cfg
with open('/run/install/ccw.conf') as f:
# pylint: disable=redefined-outer-name
for line in f:
if cfg['SUBCHANNELS'] in line:
items = line.strip().split(',')
cfg['NETTYPE'] = items[0]
cfg['OPTIONS'] = " ".join(i for i in items[1:] if '=' in i)
break

return cfg


Expand Down
11 changes: 9 additions & 2 deletions pyanaconda/modules/storage/dasd/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from pyanaconda.core.regexes import DASD_DEVICE_NUMBER
from pyanaconda.modules.common.task import Task
from pyanaconda.modules.common.errors.configuration import StorageDiscoveryError
from pyanaconda.core.util import execWithRedirect


class DASDDiscoverTask(Task):
Expand Down Expand Up @@ -58,6 +59,12 @@ def _discover_device(self):
"""Discover the device."""
# pylint: disable=try-except-raise
try:
blockdev.s390.dasd_online(self._device_number)
except blockdev.S390Error as e:
rc = execWithRedirect("chzdev",
["--enable", "dasd", self._device_number,
"--active", "--persistent",
"--yes", "--no-root-update", "--force"])
except RuntimeError as e:
raise StorageDiscoveryError(str(e)) from e
if rc != 0:
raise StorageDiscoveryError(
"Could not set the device online. It might not exist.")
62 changes: 17 additions & 45 deletions pyanaconda/modules/storage/installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@

from pyanaconda.anaconda_loggers import get_module_logger
from pyanaconda.core.i18n import _
from pyanaconda.core.util import join_paths
from pyanaconda.core.util import join_paths, execWithRedirect
from pyanaconda.core.path import make_directories
from pyanaconda.core.configuration.anaconda import conf
from pyanaconda.modules.common.constants.objects import ISCSI, FCOE, ZFCP, NVME
from pyanaconda.modules.common.constants.objects import ISCSI, FCOE, NVME
from pyanaconda.modules.common.constants.services import STORAGE
from pyanaconda.modules.common.errors.installation import StorageInstallationError
from pyanaconda.modules.common.task import Task
Expand Down Expand Up @@ -290,13 +290,10 @@ def _write_storage_configuration(self, storage, sysroot=None):
fcoe_proxy = STORAGE.get_proxy(FCOE)
fcoe_proxy.WriteConfiguration()

zfcp_proxy = STORAGE.get_proxy(ZFCP)
zfcp_proxy.WriteConfiguration()

nvme_proxy = STORAGE.get_proxy(NVME)
nvme_proxy.WriteConfiguration()

self._write_dasd_conf(storage, sysroot)
self._write_s390_device_config(sysroot)

def _write_escrow_packets(self, storage, sysroot):
"""Write the escrow packets.
Expand Down Expand Up @@ -361,46 +358,21 @@ def _write_lvm_devices_file(storage, sysroot):
make_directories(os.path.dirname(out_filename))
shutil.copyfile(in_filename, out_filename)

def _write_dasd_conf(self, storage, sysroot):
"""Write DASD configuration to sysroot.
def _write_s390_device_config(self, sysroot):
"""Copy entire persistent config of any s390 devices to sysroot.
Write /etc/dasd.conf to target system for all DASD devices
configured during installation.
This includes config imported from initrd as well as anything the user
configured via the installer user interface.
:param storage: the storage object
:param sysroot: a path to the target OS installation
"""
dasds = [d for d in storage.devices if d.type == "dasd"]
dasds.sort(key=lambda d: d.name)
if not (arch.is_s390() and dasds):
return

with open(os.path.realpath(sysroot + "/etc/dasd.conf"), "w") as f:
for dasd in dasds:
fields = [dasd.busid] + dasd.get_opts()
f.write("%s\n" % " ".join(fields),)

# check for hyper PAV aliases; they need to get added to dasd.conf as well
sysfs = "/sys/bus/ccw/drivers/dasd-eckd"

# in the case that someone is installing with *only* FBA DASDs,the above
# sysfs path will not exist; so check for it and just bail out of here if
# that's the case
if not os.path.exists(sysfs):
return

# this does catch every DASD, even non-aliases, but we're only going to be
# checking for a very specific flag, so there won't be any duplicate entries
# in dasd.conf
devs = [d for d in os.listdir(sysfs) if d.startswith("0.0")]
with open(os.path.realpath(sysroot + "/etc/dasd.conf"), "a") as f:
for d in devs:
aliasfile = "%s/%s/alias" % (sysfs, d)
with open(aliasfile, "r") as falias:
alias = falias.read().strip()

# if alias == 1, then the device is an alias; otherwise it is a
# normal dasd (alias == 0) and we can skip it, since it will have
# been added to dasd.conf in the above block of code
if alias == "1":
f.write("%s\n" % d)
if arch.is_s390():
execWithRedirect("chzdev",
["--export", "/tmp/zdev.config",
"--all", "--type", "--persistent",
"--verbose"])
execWithRedirect("chzdev",
["--import", "/tmp/zdev.config",
"--persistent",
"--yes", "--no-root-update", "--force", "--verbose",
"--base", "/etc=%s/etc" % sysroot])
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,20 @@ def test_get_ports_from_connections(self, get_iface_from_connection):
assert get_ports_from_connections(nm_client, "team", [TEAM1_UUID]) == \
set([("ens11", "ens11", ENS11_UUID)])

@patch("pyanaconda.modules.network.nm_client._get_dracut_znet_argument_from_connection")
@patch("pyanaconda.modules.network.nm_client.get_connections_available_for_iface")
@patch("pyanaconda.modules.network.nm_client.get_ports_from_connections")
@patch("pyanaconda.modules.network.nm_client.is_s390")
def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_connections_mock,
get_connections_available_for_iface):
get_connections_available_for_iface,
_get_dracut_znet_argument_from_connection):
nm_client = Mock()

CON_UUID = "44755f4c-ee12-45b4-ba5e-e10f83de51af"

# IPv4 config auto, IPv6 config auto, mac address specified
is_s390.return_value = False
_get_dracut_znet_argument_from_connection.return_value = ""
ip4_config_attrs = {
"get_method.return_value": NM.SETTING_IP4_CONFIG_METHOD_AUTO,
}
Expand Down Expand Up @@ -162,6 +165,8 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn

# IPv4 config static, mac address not specified, s390
is_s390.return_value = True
_get_dracut_znet_argument_from_connection.return_value = \
"rd.znet=qeth,0.0.0900,0.0.0901,0.0.0902,layer2=1,portname=FOOBAR,portno=0"
address_attrs = {
"get_address.return_value": "10.34.39.44",
"get_prefix.return_value": 24,
Expand All @@ -176,11 +181,6 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn
ip4_config = self._get_mock_objects_from_attrs([ip4_config_attrs])[0]
wired_setting_attrs = {
"get_mac_address.return_value": None,
"get_s390_nettype.return_value": "qeth",
"get_s390_subchannels.return_value": ["0.0.0900", "0.0.0901", "0.0.0902"],
"get_property.return_value": {"layer2": "1",
"portname": "FOOBAR",
"portno": "0"},
}
wired_setting = self._get_mock_objects_from_attrs([wired_setting_attrs])[0]
cons_attrs = [
Expand All @@ -199,6 +199,7 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn

# IPv6 config dhcp
is_s390.return_value = False
_get_dracut_znet_argument_from_connection.return_value = ""
ip6_config_attrs = {
"get_method.return_value": NM.SETTING_IP6_CONFIG_METHOD_DHCP,
}
Expand All @@ -222,6 +223,7 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn

# IPv6 config manual
is_s390.return_value = False
_get_dracut_znet_argument_from_connection.return_value = ""
address_attrs = {
"get_address.return_value": "2001::5",
"get_prefix.return_value": 64,
Expand Down Expand Up @@ -253,6 +255,7 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn

# IPv4 config auto, team
is_s390.return_value = False
_get_dracut_znet_argument_from_connection.return_value = ""
ip4_config_attrs = {
"get_method.return_value": NM.SETTING_IP4_CONFIG_METHOD_AUTO,
}
Expand All @@ -279,6 +282,8 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn

# IPv4 config auto, vlan, s390, parent specified by interface name
is_s390.return_value = True
_get_dracut_znet_argument_from_connection.return_value = \
"rd.znet=qeth,0.0.0900,0.0.0901,0.0.0902,layer2=1,portname=FOOBAR,portno=0"
ip4_config_attrs = {
"get_method.return_value": NM.SETTING_IP4_CONFIG_METHOD_AUTO,
}
Expand All @@ -300,11 +305,6 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn
# Mock parent connection
wired_setting_attrs = {
"get_mac_address.return_value": None,
"get_s390_nettype.return_value": "qeth",
"get_s390_subchannels.return_value": ["0.0.0900", "0.0.0901", "0.0.0902"],
"get_property.return_value": {"layer2": "1",
"portname": "FOOBAR",
"portno": "0"},
}
wired_setting = self._get_mock_objects_from_attrs([wired_setting_attrs])[0]
parent_cons_attrs = [
Expand All @@ -326,6 +326,7 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn
# IPv4 config auto, vlan, parent specified by connection uuid
VLAN_PARENT_UUID = "5e6ead30-d133-4c8c-ba59-818c5ced6a7c"
is_s390.return_value = False
_get_dracut_znet_argument_from_connection.return_value = ""
ip4_config_attrs = {
"get_method.return_value": NM.SETTING_IP4_CONFIG_METHOD_AUTO,
}
Expand Down Expand Up @@ -361,6 +362,8 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn
# IPv4 config auto, vlan, parent specified by connection uuid, s390 (we
# need the parent connection in s390 case, not only parent iface)
is_s390.return_value = True
_get_dracut_znet_argument_from_connection.return_value = \
"rd.znet=qeth,0.0.0900,0.0.0901,0.0.0902,layer2=1,portname=FOOBAR,portno=0"
ip4_config_attrs = {
"get_method.return_value": NM.SETTING_IP4_CONFIG_METHOD_AUTO,
}
Expand All @@ -382,11 +385,6 @@ def test_get_dracut_arguments_from_connection(self, is_s390, get_ports_from_conn
# Mock parent connection
wired_setting_attrs = {
"get_mac_address.return_value": None,
"get_s390_nettype.return_value": "qeth",
"get_s390_subchannels.return_value": ["0.0.0900", "0.0.0901", "0.0.0902"],
"get_property.return_value": {"layer2": "1",
"portname": "FOOBAR",
"portno": "0"},
}
wired_setting = self._get_mock_objects_from_attrs([wired_setting_attrs])[0]
parent_cons_attrs = [
Expand Down
Loading

0 comments on commit 7c96bd8

Please sign in to comment.