Currently, kexec-tools parses legacy ifcfg-* configuration files or NetworkManager .nmconnection connection profiles to build up dracut command line parameters like ip=. Then dracut parses these parameters and runs nm-initrd-generator to generate NetworkManager connection profiles. Taking a bonding network as an example, nm-initrd-generator generates two connections as follows, $ /usr/libexec/nm-initrd-generator -s -- bootdev=mybond0 rd.neednet kdumpnic=mybond0 bond=mybond0:kdump-eth0
*** Connection 'mybond0' ***
[connection] id=mybond0 uuid=ed87d02b-dd44-4f0e-8b11-37db7e89bb48 interface-name=mybond0
[ipv4] dhcp-timeout=90 ...
*** Connection 'kdump-eth0' ***
[connection] id=kdump-eth0 uuid=ed6a7448-b5f8-4f8a-b718-3e24ea1c924b type=ethernet interface-name=kdump-eth0 master=ed87d02b-dd44-4f0e-8b11-37db7e89bb48 slave-type=bond wait-device-timeout=60000 ...
Later in kdump initrd, dracut starts NetworkManager to activate these profiles to bring up the network connections. This way of setting up kdump network is tedious, error-prone and unnecessary. A better way is to directly copy the needed connection profiles to initrd. A potential benefit of this approach for the users is they can simply edit the connection profile directly like changing ipv4.dhcp-timeout instead of being forced to use the hard-coded value enforced by nm-initrd-generator.
This patch set reuses NetworkManager connection profiles to setup kdump network. It also reduces the memory consumption of network drivers and fix other issues at the same time. A machine could have multiple network drivers and a network driver may manage multiple NICs. It's possible kdump may only need one NIC. In this case, there is no need to install unneeded network drivers or bring up unneeded NICs.
Here are the bug list that addressed by this patch set, - Bug 1962421 - [RHEL-9]"eth0: Failed to rename network interface 3 from 'eth0' to 'kdump-eth0': File exists" - Bug 2064708 - kdump: mkdumprd: failed to make kdump initrd for bridge network on z15 z/vm - bugs related to OOM caused by network driver - Bug 1950282 - shutdown those unneeded network interfaces to save memory for kdump - Bug 1958587 - the kdump initramfs includes unnecessary NIC drivers for SSH/NFS dumping target - Bug 1890021 - be2net is using too much memory during kdump - Bug 1662202 - [RHEL-8.1] aarch64: hpe-apache crashkernel OOM when dump to network targe
v1: - refactor complex kdump_copy_nmconnection_file [Philipp] - clean up temporary file in a trap [Philipp] - improve sed [Philipp] - use long name consistently [Philipp] - use nmcli -t, --terse option to suppress printing of the header [Philipp] - don't pass kdumpip to initrd [Kairui] - address the case where kdump_install_net is called multiple times like fence kdump - call kdump_install_nm_netif_allowlist after all kdump_install_net calls have been finished - ask NM to match a connection profile to a physical NIC by MAC address - stop treating vlan specially when its parent interface is a physical NIC - don't add unused NIC drivers to kdump initrd - fix the error of "/etc/NetworkManager/system-connections/*.nmconnection" not exist grep: /etc/NetworkManager/system-connections/*.nmconnection: No such file or directory - redirect the messages of nmcli to ddebug - use "grep -s" to get rid of the following warnings grep: /var/tmp/dracut.6tqUm0/initramfs//etc/NetworkManager/system-connections/*.nmconnection: No such file or directory grep: /etc/sysconfig/network-scripts/ifcfg-*: No such file or directory grep: /etc/NetworkManager/system-connections/*.nmconnection: No such file or directory
Coiby Xu (14): add function to copy NetworkManage connection profile to the initramfs clone NM connection profiles to support legacy ifcfg automatically ask NM to wait the network device to be available stop dracut 35network-manager from running nm-initrd-generator set up kdump network bridge by directly copying NM connection profile to initrd set up kdump bonding network by directly copying NM connection profile to initrd fix error for vlan over team network interface set up kdump vlan network by directly copying NM connection profile to initrd set up kdump teaming network by directly copying NM connection profile to initrd clean up unneeded code after copying .nmconnection to initrd reduce kdump memory consumption by not letting NetworkManager manage unneeded network interfaces reduce kdump memory consumption by only installing needed NIC drivers address the cases where a NIC has a different name in kdump kernel simplify setup_znet by copying connection profile to initrd
dracut-kdump.sh | 25 ++- dracut-module-setup.sh | 484 ++++++++++++++++++----------------------- kdump-lib-initramfs.sh | 12 + mkdumprd | 2 +- 4 files changed, 239 insertions(+), 284 deletions(-)
Each network interface is manged by a NM connection. Given a network interface name, this function will be used to copy a NetworkManager (NM) connection profile i.e. a .nmconnection file to the kdump initramfs.
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index c319fc2..3dc597f 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -346,6 +346,17 @@ kdump_setup_ifname() { echo "$_ifname" }
+kdump_copy_nmconnection_file() { + local _dev _nmconnection_file_path _nmconnection_name _initrd_nmconnection_file_path + + _dev=$1 + + _nmconnection_file_path=${nmconnection_map[$_dev]} + _nmconnection_name=$(basename "$_nmconnection_file_path") + _initrd_nmconnection_file_path="/etc/NetworkManager/system-connections/$_nmconnection_name" + inst "$_nmconnection_file_path" "$_initrd_nmconnection_file_path" +} + kdump_setup_bridge() { local _netdev=$1 local _brif _dev _mac _kdumpdev @@ -534,6 +545,12 @@ kdump_install_net() { local _destaddr _srcaddr _route _netdev _conpath kdumpnic local _static _proto _ip_conf _ip_opts _ifname_opts local _znet_netdev _znet_conpath + # each netowrk interface is managed by a NM connection profile + declare -A nmconnection_map + + while IFS=: read -r _ifname _nmconn; do + nmconnection_map[$_ifname]="$_nmconn" + done <<< "$(nmcli -t -f device,filename connection show --active)"
_destaddr=$(kdump_get_remote_ip "$1") _route=$(kdump_get_ip_route "$_destaddr")
NetworkManager defaults to use keyfile i.e. .nmconnnection file but still supports reading ifcfg-* file [1]. Make use of "nmcli connection clone --temporary" to automatically convert a ifcfg-* file to a .nmconnection file.
[1] https://fedoraproject.org/wiki/Changes/NetworkManager_keyfile_instead_of_ifc...
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 3dc597f..dba023d 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1,10 +1,20 @@ #!/bin/bash
+_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM" + +cleanup() { + rm -rf $_DRACUT_KDUMP_NM_TMP_DIR +} + +trap 'ret=$?; cleanup; exit $ret;' EXIT + kdump_module_init() { if ! [[ -d "${initdir}/tmp" ]]; then mkdir -p "${initdir}/tmp" fi
+ mkdir -p "$_DRACUT_KDUMP_NM_TMP_DIR" + . /lib/kdump/kdump-lib.sh }
@@ -346,6 +356,47 @@ kdump_setup_ifname() { echo "$_ifname" }
+_clone_nmconnection() { + local _clone_output _name _unique_id + + _unique_id=$1 + _name=$(nmcli --get-values connection.id connection show "$_unique_id") + if _clone_output=$(nmcli connection clone --temporary "$_unique_id" "$_name"); then + sed -E -n "s/.* (.*) cloned as.*((.*)).$/\1/p" <<< "$_clone_output" + return 0 + fi + + return 1 +} + +# Clone NM connection profiles +# +# This function makes use of "nmcli clone" to automatically convert ifcfg-* +# files to Networkmanager .nmconnection connection profiles. +clone_nmconnections() { + local _dev _cloned_nmconnection_file_path _tmp_nmconnection_file_path _old_uuid _uuid + + for _dev in "${!nmconnection_map[@]}"; do + _nmconnection_file_path=${nmconnection_map[$_dev]} + _old_uuid=$(nmcli --get-values connection.uuid connection show "$_nmconnection_file_path") + + if ! _uuid=$(_clone_nmconnection "$_old_uuid"); then + derror "Failed to clone $_old_uuid" + exit 1 + fi + + _cloned_nmconnection_file_path=$(nmcli --get-values UUID,FILENAME connection show | sed -n "s/^${_uuid}://p") + _tmp_nmconnection_file_path=$_DRACUT_KDUMP_NM_TMP_DIR/$(basename "$_nmconnection_file_path") + cp "$_cloned_nmconnection_file_path" "$_tmp_nmconnection_file_path" + # change uuid back to old value in case it's refered by other connection + # profile e.g. connection.master could be tnterface name of the master + # device or UUID of the master connection. + sed -i -E "s/(^uuid=).*$/\1${_old_uuid}/g" "$_tmp_nmconnection_file_path" + nmconnection_map[$_dev]=$_tmp_nmconnection_file_path + nmcli connection del "$_uuid" &> >(ddebug) + done +} + kdump_copy_nmconnection_file() { local _dev _nmconnection_file_path _nmconnection_name _initrd_nmconnection_file_path
@@ -551,6 +602,7 @@ kdump_install_net() { while IFS=: read -r _ifname _nmconn; do nmconnection_map[$_ifname]="$_nmconn" done <<< "$(nmcli -t -f device,filename connection show --active)" + clone_nmconnections
_destaddr=$(kdump_get_remote_ip "$1") _route=$(kdump_get_ip_route "$_destaddr") @@ -622,6 +674,7 @@ kdump_install_net() { echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf" echo "bootdev=$kdumpnic" > "${initdir}/etc/cmdline.d/70bootdev.conf" fi + }
# install etc/kdump/pre.d and /etc/kdump/post.d
Hi Coiby,
On Tue, 21 Jun 2022 14:57:16 +0800 Coiby Xu coxu@redhat.com wrote:
NetworkManager defaults to use keyfile i.e. .nmconnnection file but still supports reading ifcfg-* file [1]. Make use of "nmcli connection clone --temporary" to automatically convert a ifcfg-* file to a .nmconnection file.
[1] https://fedoraproject.org/wiki/Changes/NetworkManager_keyfile_instead_of_ifc...
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 3dc597f..dba023d 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1,10 +1,20 @@ #!/bin/bash
+_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM"
Why don't you use mktemp -d?
+cleanup() {
- rm -rf $_DRACUT_KDUMP_NM_TMP_DIR
+}
+trap 'ret=$?; cleanup; exit $ret;' EXIT
kdump_module_init() { if ! [[ -d "${initdir}/tmp" ]]; then mkdir -p "${initdir}/tmp" fi
- mkdir -p "$_DRACUT_KDUMP_NM_TMP_DIR"
- . /lib/kdump/kdump-lib.sh
}
@@ -346,6 +356,47 @@ kdump_setup_ifname() { echo "$_ifname" }
+_clone_nmconnection() {
- local _clone_output _name _unique_id
- _unique_id=$1
- _name=$(nmcli --get-values connection.id connection show "$_unique_id")
- if _clone_output=$(nmcli connection clone --temporary "$_unique_id" "$_name"); then
sed -E -n "s/.* \(.*\) cloned as.*\((.*)\)\.$/\1/p" <<< "$_clone_output"
return 0
- fi
- return 1
+}
+# Clone NM connection profiles +# +# This function makes use of "nmcli clone" to automatically convert ifcfg-* +# files to Networkmanager .nmconnection connection profiles. +clone_nmconnections() {
- local _dev _cloned_nmconnection_file_path _tmp_nmconnection_file_path _old_uuid _uuid
- for _dev in "${!nmconnection_map[@]}"; do
_nmconnection_file_path=${nmconnection_map[$_dev]}
_old_uuid=$(nmcli --get-values connection.uuid connection show "$_nmconnection_file_path")
if ! _uuid=$(_clone_nmconnection "$_old_uuid"); then
derror "Failed to clone $_old_uuid"
exit 1
fi
_cloned_nmconnection_file_path=$(nmcli --get-values UUID,FILENAME connection show | sed -n "s/^${_uuid}://p")
_tmp_nmconnection_file_path=$_DRACUT_KDUMP_NM_TMP_DIR/$(basename "$_nmconnection_file_path")
cp "$_cloned_nmconnection_file_path" "$_tmp_nmconnection_file_path"
# change uuid back to old value in case it's refered by other connection
# profile e.g. connection.master could be tnterface name of the master
s/tnterface/interface/ ?
Thanks Philipp
# device or UUID of the master connection.
sed -i -E "s/(^uuid=).*$/\1${_old_uuid}/g" "$_tmp_nmconnection_file_path"
nmconnection_map[$_dev]=$_tmp_nmconnection_file_path
nmcli connection del "$_uuid" &> >(ddebug)
- done
+}
kdump_copy_nmconnection_file() { local _dev _nmconnection_file_path _nmconnection_name _initrd_nmconnection_file_path
@@ -551,6 +602,7 @@ kdump_install_net() { while IFS=: read -r _ifname _nmconn; do nmconnection_map[$_ifname]="$_nmconn" done <<< "$(nmcli -t -f device,filename connection show --active)"
clone_nmconnections
_destaddr=$(kdump_get_remote_ip "$1") _route=$(kdump_get_ip_route "$_destaddr")
@@ -622,6 +674,7 @@ kdump_install_net() { echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf" echo "bootdev=$kdumpnic" > "${initdir}/etc/cmdline.d/70bootdev.conf" fi
}
# install etc/kdump/pre.d and /etc/kdump/post.d
Hi Philipp,
Thanks for carefully reviewing the patch!
On Mon, Aug 01, 2022 at 04:59:30PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:16 +0800 Coiby Xu coxu@redhat.com wrote:
NetworkManager defaults to use keyfile i.e. .nmconnnection file but still supports reading ifcfg-* file [1]. Make use of "nmcli connection clone --temporary" to automatically convert a ifcfg-* file to a .nmconnection file.
[1] https://fedoraproject.org/wiki/Changes/NetworkManager_keyfile_instead_of_ifc...
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 3dc597f..dba023d 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1,10 +1,20 @@ #!/bin/bash
+_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM"
Why don't you use mktemp -d?
I just tried mktemp but found two issues, - mktemp and cleanup somehow would be called 4 times (it seems dracut source dracut-module-setup.sh many times) - after running a network test, some of the temp folders are not deleted
+cleanup() {
- rm -rf $_DRACUT_KDUMP_NM_TMP_DIR
+}
+trap 'ret=$?; cleanup; exit $ret;' EXIT
kdump_module_init() { if ! [[ -d "${initdir}/tmp" ]]; then mkdir -p "${initdir}/tmp" fi
- mkdir -p "$_DRACUT_KDUMP_NM_TMP_DIR"
- . /lib/kdump/kdump-lib.sh
}
@@ -346,6 +356,47 @@ kdump_setup_ifname() { echo "$_ifname" }
+_clone_nmconnection() {
- local _clone_output _name _unique_id
- _unique_id=$1
- _name=$(nmcli --get-values connection.id connection show "$_unique_id")
- if _clone_output=$(nmcli connection clone --temporary "$_unique_id" "$_name"); then
sed -E -n "s/.* \(.*\) cloned as.*\((.*)\)\.$/\1/p" <<< "$_clone_output"
return 0
- fi
- return 1
+}
+# Clone NM connection profiles +# +# This function makes use of "nmcli clone" to automatically convert ifcfg-* +# files to Networkmanager .nmconnection connection profiles. +clone_nmconnections() {
- local _dev _cloned_nmconnection_file_path _tmp_nmconnection_file_path _old_uuid _uuid
- for _dev in "${!nmconnection_map[@]}"; do
_nmconnection_file_path=${nmconnection_map[$_dev]}
_old_uuid=$(nmcli --get-values connection.uuid connection show "$_nmconnection_file_path")
if ! _uuid=$(_clone_nmconnection "$_old_uuid"); then
derror "Failed to clone $_old_uuid"
exit 1
fi
_cloned_nmconnection_file_path=$(nmcli --get-values UUID,FILENAME connection show | sed -n "s/^${_uuid}://p")
_tmp_nmconnection_file_path=$_DRACUT_KDUMP_NM_TMP_DIR/$(basename "$_nmconnection_file_path")
cp "$_cloned_nmconnection_file_path" "$_tmp_nmconnection_file_path"
# change uuid back to old value in case it's refered by other connection
# profile e.g. connection.master could be tnterface name of the master
s/tnterface/interface/ ?
Thanks for catching this typo!
Thanks Philipp
# device or UUID of the master connection.
sed -i -E "s/(^uuid=).*$/\1${_old_uuid}/g" "$_tmp_nmconnection_file_path"
nmconnection_map[$_dev]=$_tmp_nmconnection_file_path
nmcli connection del "$_uuid" &> >(ddebug)
- done
+}
kdump_copy_nmconnection_file() { local _dev _nmconnection_file_path _nmconnection_name _initrd_nmconnection_file_path
@@ -551,6 +602,7 @@ kdump_install_net() { while IFS=: read -r _ifname _nmconn; do nmconnection_map[$_ifname]="$_nmconn" done <<< "$(nmcli -t -f device,filename connection show --active)"
clone_nmconnections
_destaddr=$(kdump_get_remote_ip "$1") _route=$(kdump_get_ip_route "$_destaddr")
@@ -622,6 +674,7 @@ kdump_install_net() { echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf" echo "bootdev=$kdumpnic" > "${initdir}/etc/cmdline.d/70bootdev.conf" fi
}
# install etc/kdump/pre.d and /etc/kdump/post.d
Hi Coiby,
finally I get some time to go through my mail backlog...
On Mon, 22 Aug 2022 20:31:32 +0800 Coiby Xu coxu@redhat.com wrote:
Hi Philipp,
Thanks for carefully reviewing the patch!
On Mon, Aug 01, 2022 at 04:59:30PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:16 +0800 Coiby Xu coxu@redhat.com wrote:
NetworkManager defaults to use keyfile i.e. .nmconnnection file but still supports reading ifcfg-* file [1]. Make use of "nmcli connection clone --temporary" to automatically convert a ifcfg-* file to a .nmconnection file.
[1] https://fedoraproject.org/wiki/Changes/NetworkManager_keyfile_instead_of_ifc...
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 3dc597f..dba023d 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1,10 +1,20 @@ #!/bin/bash
+_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM"
Why don't you use mktemp -d?
I just tried mktemp but found two issues,
- mktemp and cleanup somehow would be called 4 times (it seems dracut source dracut-module-setup.sh many times)
- after running a network test, some of the temp folders are not deleted
Alright. In that case your approach is better.
Thanks Philipp
During boot, it may take some time for a device driver to detect the its devices. By default, NetworkManager doesn't wait for the device to be available (this is not an issue for the 1st kernel because NM keeps running in the 1st kernel). So we need to set connection.wait-device-timeout=60000 [1] as the same to nm-initrd-generator to tell NM to wait for 6s. Otherwise dracut-kdump-capture.service would fail because network isn't ready. Note the user's custom value for wait-device-timeout is respected.
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index dba023d..0105048 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -406,6 +406,11 @@ kdump_copy_nmconnection_file() { _nmconnection_name=$(basename "$_nmconnection_file_path") _initrd_nmconnection_file_path="/etc/NetworkManager/system-connections/$_nmconnection_name" inst "$_nmconnection_file_path" "$_initrd_nmconnection_file_path" + + # Ask NM to wait 60s for the network device to be available + # wait-device-timeout=60000 is inserted after "[connection]" so the + # user's custom value could overwrite it + sed -i '/[connection]/a wait-device-timeout=60000' "${initdir}/$_initrd_nmconnection_file_path" }
kdump_setup_bridge() {
Hi Coiby,
On Tue, 21 Jun 2022 14:57:17 +0800 Coiby Xu coxu@redhat.com wrote:
During boot, it may take some time for a device driver to detect the its devices. By default, NetworkManager doesn't wait for the device to be available (this is not an issue for the 1st kernel because NM keeps running in the 1st kernel). So we need to set connection.wait-device-timeout=60000 [1] as the same to nm-initrd-generator
where does [1] point to?
to tell NM to wait for 6s. Otherwise dracut-kdump-capture.service would
s/6s/60s/ or fix the comment below.
Thanks Philipp
fail because network isn't ready. Note the user's custom value for wait-device-timeout is respected.
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index dba023d..0105048 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -406,6 +406,11 @@ kdump_copy_nmconnection_file() { _nmconnection_name=$(basename "$_nmconnection_file_path") _initrd_nmconnection_file_path="/etc/NetworkManager/system-connections/$_nmconnection_name" inst "$_nmconnection_file_path" "$_initrd_nmconnection_file_path"
- # Ask NM to wait 60s for the network device to be available
- # wait-device-timeout=60000 is inserted after "[connection]" so the
- # user's custom value could overwrite it
- sed -i '/[connection]/a wait-device-timeout=60000' "${initdir}/$_initrd_nmconnection_file_path"
}
kdump_setup_bridge() {
Hi Philipp,
On Mon, Aug 01, 2022 at 04:59:05PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:17 +0800 Coiby Xu coxu@redhat.com wrote:
During boot, it may take some time for a device driver to detect the its devices. By default, NetworkManager doesn't wait for the device to be available (this is not an issue for the 1st kernel because NM keeps running in the 1st kernel). So we need to set connection.wait-device-timeout=60000 [1] as the same to nm-initrd-generator
where does [1] point to?
Oh, it points to https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/803#no...
to tell NM to wait for 6s. Otherwise dracut-kdump-capture.service would
s/6s/60s/ or fix the comment below.
Thanks! They'll be fixed in v2.
Thanks Philipp
fail because network isn't ready. Note the user's custom value for wait-device-timeout is respected.
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index dba023d..0105048 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -406,6 +406,11 @@ kdump_copy_nmconnection_file() { _nmconnection_name=$(basename "$_nmconnection_file_path") _initrd_nmconnection_file_path="/etc/NetworkManager/system-connections/$_nmconnection_name" inst "$_nmconnection_file_path" "$_initrd_nmconnection_file_path"
- # Ask NM to wait 60s for the network device to be available
- # wait-device-timeout=60000 is inserted after "[connection]" so the
- # user's custom value could overwrite it
- sed -i '/[connection]/a wait-device-timeout=60000' "${initdir}/$_initrd_nmconnection_file_path"
}
kdump_setup_bridge() {
kexec-tools depends on dracut's 35network-manager module which will call nm-initrd-generator. We don't want nm-initrd-generator to generate connection profiles since we will copy them from 1st kernel to kdump kernel initramfs. NetworkManager >= 1.35.2 won't generate connection profiles if there's a connection dir with rd.neednet. For Fedora/RHEL, this connection dir is /etc/NetworkManager/system-connections. For the details, please refer to the NetworkManager commit 79885656d3 ("initrd: don't add a connection if there's a connection dir with rd.neednet") [1]. Before the release of NetworkManager >= 1.35.2, we need to mask /usr/libexec/nm-initrd-generator.
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_request...
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 0105048..6a836d5 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -667,6 +667,11 @@ kdump_install_net() { echo "rd.neednet" >> "${initdir}/etc/cmdline.d/50neednet.conf" fi
+ # Stop dracut 35network-manger to calling nm-initrd-generator. + # Note this line of code can be removed after NetworkManager >= 1.35.2 + # gets released. + echo > "${initdir}/usr/libexec/nm-initrd-generator" + # Save netdev used for kdump as cmdline # Whoever calling kdump_install_net() is setting up the default gateway, # ie. bootdev/kdumpnic. So don't override the setting if calling
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 6a836d5..1649805 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -415,30 +415,21 @@ kdump_copy_nmconnection_file() {
kdump_setup_bridge() { local _netdev=$1 - local _brif _dev _mac _kdumpdev + local _dev for _dev in "/sys/class/net/$_netdev/brif/"*; do [[ -e $_dev ]] || continue _dev=${_dev##*/} - _kdumpdev=$_dev if kdump_is_bond "$_dev"; then (kdump_setup_bond "$_dev" "$(get_nmcli_connection_apath_by_ifname "$_dev")") || exit 1 elif kdump_is_team "$_dev"; then kdump_setup_team "$_dev" elif kdump_is_vlan "$_dev"; then kdump_setup_vlan "$_dev" - else - _mac=$(kdump_get_mac_addr "$_dev") - _kdumpdev=$(kdump_setup_ifname "$_dev") - echo -n " ifname=$_kdumpdev:$_mac" >> "${initdir}/etc/cmdline.d/41bridge.conf" fi - _brif+="$_kdumpdev," + kdump_copy_nmconnection_file "$_dev" done - echo " bridge=$_netdev:${_brif%,}" >> "${initdir}/etc/cmdline.d/41bridge.conf" }
-# drauct takes bond=<bondname>[:<bondslaves>:[:<options>]] syntax to parse -# bond. For example: -# bond=bond0:eth0,eth1:mode=balance-rr kdump_setup_bond() { local _netdev="$1" local _conpath="$2" @@ -599,7 +590,7 @@ kdump_get_remote_ip() { # $1: destination host kdump_install_net() { local _destaddr _srcaddr _route _netdev _conpath kdumpnic - local _static _proto _ip_conf _ip_opts _ifname_opts + local _static _proto _ip_conf _ip_opts local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map @@ -614,7 +605,6 @@ kdump_install_net() { _srcaddr=$(kdump_get_ip_route_field "$_route" "src") _netdev=$(kdump_get_ip_route_field "$_route" "dev") _conpath=$(get_nmcli_connection_apath_by_ifname "$_netdev") - _netmac=$(kdump_get_mac_addr "$_netdev") kdumpnic=$(kdump_setup_ifname "$_netdev")
_znet_netdev=$(find_online_znet_device) @@ -655,10 +645,8 @@ kdump_install_net() { kdump_setup_team "$_netdev" elif kdump_is_vlan "$_netdev"; then kdump_setup_vlan "$_netdev" - else - _ifname_opts=" ifname=$kdumpnic:$_netmac" - echo "$_ifname_opts" >> "$_ip_conf" fi + kdump_copy_nmconnection_file "$_netdev"
kdump_setup_dns "$_netdev" "$_conpath"
Hi Coiby,
On Tue, 21 Jun 2022 14:57:19 +0800 Coiby Xu coxu@redhat.com wrote:
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 6a836d5..1649805 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -415,30 +415,21 @@ kdump_copy_nmconnection_file() {
kdump_setup_bridge() { local _netdev=$1
- local _brif _dev _mac _kdumpdev
- local _dev for _dev in "/sys/class/net/$_netdev/brif/"*; do [[ -e $_dev ]] || continue _dev=${_dev##*/}
_kdumpdev=$_dev if kdump_is_bond "$_dev"; then (kdump_setup_bond "$_dev" "$(get_nmcli_connection_apath_by_ifname "$_dev")") || exit 1 elif kdump_is_team "$_dev"; then kdump_setup_team "$_dev" elif kdump_is_vlan "$_dev"; then kdump_setup_vlan "$_dev"
else
_mac=$(kdump_get_mac_addr "$_dev")
_kdumpdev=$(kdump_setup_ifname "$_dev")
echo -n " ifname=$_kdumpdev:$_mac" >> "${initdir}/etc/cmdline.d/41bridge.conf" fi
_brif+="$_kdumpdev,"
donekdump_copy_nmconnection_file "$_dev"
- echo " bridge=$_netdev:${_brif%,}" >> "${initdir}/etc/cmdline.d/41bridge.conf"
}
up to here I'm perfectly fine. For the rest...
-# drauct takes bond=<bondname>[:<bondslaves>:[:<options>]] syntax to parse -# bond. For example: -# bond=bond0:eth0,eth1:mode=balance-rr kdump_setup_bond() { local _netdev="$1" local _conpath="$2" @@ -599,7 +590,7 @@ kdump_get_remote_ip() { # $1: destination host kdump_install_net() { local _destaddr _srcaddr _route _netdev _conpath kdumpnic
- local _static _proto _ip_conf _ip_opts _ifname_opts
- local _static _proto _ip_conf _ip_opts local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map
@@ -614,7 +605,6 @@ kdump_install_net() { _srcaddr=$(kdump_get_ip_route_field "$_route" "src") _netdev=$(kdump_get_ip_route_field "$_route" "dev") _conpath=$(get_nmcli_connection_apath_by_ifname "$_netdev")
_netmac=$(kdump_get_mac_addr "$_netdev") kdumpnic=$(kdump_setup_ifname "$_netdev")
_znet_netdev=$(find_online_znet_device)
@@ -655,10 +645,8 @@ kdump_install_net() { kdump_setup_team "$_netdev" elif kdump_is_vlan "$_netdev"; then kdump_setup_vlan "$_netdev"
- else
_ifname_opts=" ifname=$kdumpnic:$_netmac"
fiecho "$_ifname_opts" >> "$_ip_conf"
kdump_copy_nmconnection_file "$_netdev"
kdump_setup_dns "$_netdev" "$_conpath"
... I don't see how it is related to setting up a network bridge. Does that need to go into a separate commit?
Thanks Philipp
Hi Philipp,
On Mon, Aug 01, 2022 at 04:58:49PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:19 +0800 Coiby Xu coxu@redhat.com wrote:
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 6a836d5..1649805 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -415,30 +415,21 @@ kdump_copy_nmconnection_file() {
kdump_setup_bridge() { local _netdev=$1
- local _brif _dev _mac _kdumpdev
- local _dev for _dev in "/sys/class/net/$_netdev/brif/"*; do [[ -e $_dev ]] || continue _dev=${_dev##*/}
_kdumpdev=$_dev if kdump_is_bond "$_dev"; then (kdump_setup_bond "$_dev" "$(get_nmcli_connection_apath_by_ifname "$_dev")") || exit 1 elif kdump_is_team "$_dev"; then kdump_setup_team "$_dev" elif kdump_is_vlan "$_dev"; then kdump_setup_vlan "$_dev"
else
_mac=$(kdump_get_mac_addr "$_dev")
_kdumpdev=$(kdump_setup_ifname "$_dev")
echo -n " ifname=$_kdumpdev:$_mac" >> "${initdir}/etc/cmdline.d/41bridge.conf" fi
_brif+="$_kdumpdev,"
donekdump_copy_nmconnection_file "$_dev"
- echo " bridge=$_netdev:${_brif%,}" >> "${initdir}/etc/cmdline.d/41bridge.conf"
}
up to here I'm perfectly fine. For the rest...
-# drauct takes bond=<bondname>[:<bondslaves>:[:<options>]] syntax to parse -# bond. For example: -# bond=bond0:eth0,eth1:mode=balance-rr kdump_setup_bond() { local _netdev="$1" local _conpath="$2" @@ -599,7 +590,7 @@ kdump_get_remote_ip() { # $1: destination host kdump_install_net() { local _destaddr _srcaddr _route _netdev _conpath kdumpnic
- local _static _proto _ip_conf _ip_opts _ifname_opts
- local _static _proto _ip_conf _ip_opts local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map
@@ -614,7 +605,6 @@ kdump_install_net() { _srcaddr=$(kdump_get_ip_route_field "$_route" "src") _netdev=$(kdump_get_ip_route_field "$_route" "dev") _conpath=$(get_nmcli_connection_apath_by_ifname "$_netdev")
_netmac=$(kdump_get_mac_addr "$_netdev") kdumpnic=$(kdump_setup_ifname "$_netdev")
_znet_netdev=$(find_online_znet_device)
@@ -655,10 +645,8 @@ kdump_install_net() { kdump_setup_team "$_netdev" elif kdump_is_vlan "$_netdev"; then kdump_setup_vlan "$_netdev"
- else
_ifname_opts=" ifname=$kdumpnic:$_netmac"
fiecho "$_ifname_opts" >> "$_ip_conf"
kdump_copy_nmconnection_file "$_netdev"
kdump_setup_dns "$_netdev" "$_conpath"
... I don't see how it is related to setting up a network bridge. Does that need to go into a separate commit?
Sorry for the confusion. I deletd the comments about kdump_setup_bond by mistake. In v2, I switch to the new approach for different network setups all at once also to avoid causing trouble for git bisection.
Thanks Philipp
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 1649805..dc60b66 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -420,7 +420,7 @@ kdump_setup_bridge() { [[ -e $_dev ]] || continue _dev=${_dev##*/} if kdump_is_bond "$_dev"; then - (kdump_setup_bond "$_dev" "$(get_nmcli_connection_apath_by_ifname "$_dev")") || exit 1 + (kdump_setup_bond "$_dev") || exit 1 elif kdump_is_team "$_dev"; then kdump_setup_team "$_dev" elif kdump_is_vlan "$_dev"; then @@ -432,30 +432,12 @@ kdump_setup_bridge() {
kdump_setup_bond() { local _netdev="$1" - local _conpath="$2" - local _dev _mac _slaves _kdumpdev _bondoptions + local _dev + + # shellcheck disable=SC2013 # read word by word for _dev in $(cat "/sys/class/net/$_netdev/bonding/slaves"); do - _mac=$(kdump_get_perm_addr "$_dev") - _kdumpdev=$(kdump_setup_ifname "$_dev") - echo -n " ifname=$_kdumpdev:$_mac" >> "${initdir}/etc/cmdline.d/42bond.conf" - _slaves+="$_kdumpdev," + kdump_copy_nmconnection_file "$_dev" done - echo -n " bond=$_netdev:${_slaves%,}" >> "${initdir}/etc/cmdline.d/42bond.conf" - - _bondoptions=$(get_nmcli_field_by_conpath "bond.options" "$_conpath") - - if [[ -z $_bondoptions ]]; then - dwarning "Failed to get bond configuration via nmlci output. Now try sourcing ifcfg script." - source_ifcfg_file "$_netdev" - _bondoptions="$(echo "$BONDING_OPTS" | xargs echo | tr " " ",")" - fi - - if [[ -z $_bondoptions ]]; then - derror "Get empty bond options" - exit 1 - fi - - echo ":$_bondoptions" >> "${initdir}/etc/cmdline.d/42bond.conf" }
kdump_setup_team() { @@ -493,7 +475,7 @@ kdump_setup_vlan() { derror "Vlan over bridge is not supported!" exit 1 elif kdump_is_bond "$_phydev"; then - (kdump_setup_bond "$_phydev" "$(get_nmcli_connection_apath_by_ifname "$_phydev")") || exit 1 + (kdump_setup_bond "$_phydev") || exit 1 echo " vlan=$(kdump_setup_ifname "$_netdev"):$_phydev" > "${initdir}/etc/cmdline.d/43vlan.conf" else _kdumpdev="$(kdump_setup_ifname "$_phydev")" @@ -640,7 +622,7 @@ kdump_install_net() { if kdump_is_bridge "$_netdev"; then kdump_setup_bridge "$_netdev" elif kdump_is_bond "$_netdev"; then - (kdump_setup_bond "$_netdev" "$_conpath") || exit 1 + (kdump_setup_bond "$_netdev") || exit 1 elif kdump_is_team "$_netdev"; then kdump_setup_team "$_netdev" elif kdump_is_vlan "$_netdev"; then
6f9235887f7817085aabfcc67bf4a6d68e474264 ("module-setup.sh: enable vlan on team interface") skips establishing teaming network by mistake. Although it could use one of slave netifs to establish connection to transfer vmcore to remote fs, it breaks the implicit assumption of creating an identical network topology to the 1st kernel.
Fixes: 6f92358 ("module-setup.sh: enable vlan on team interface") Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index dc60b66..db1b443 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -477,6 +477,9 @@ kdump_setup_vlan() { elif kdump_is_bond "$_phydev"; then (kdump_setup_bond "$_phydev") || exit 1 echo " vlan=$(kdump_setup_ifname "$_netdev"):$_phydev" > "${initdir}/etc/cmdline.d/43vlan.conf" + elif kdump_is_team "$_phydev"; then + (kdump_setup_team "$_phydev") || exit 1 + echo " vlan=$(kdump_setup_ifname "$_netdev"):$_phydev" > "${initdir}/etc/cmdline.d/43vlan.conf" else _kdumpdev="$(kdump_setup_ifname "$_phydev")" echo " vlan=$(kdump_setup_ifname "$_netdev"):$_kdumpdev ifname=$_kdumpdev:$_netmac" > "${initdir}/etc/cmdline.d/43vlan.conf"
Also rename phydev to parent_netif to improve code readability.
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index db1b443..b2e6027 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -463,27 +463,21 @@ kdump_setup_team() {
kdump_setup_vlan() { local _netdev=$1 - local _phydev - local _netmac - local _kdumpdev + local _parent_netif
- _phydev="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")" - _netmac="$(kdump_get_mac_addr "$_phydev")" + _parent_netif="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")"
#Just support vlan over bond and team - if kdump_is_bridge "$_phydev"; then + if kdump_is_bridge "$_parent_netif"; then derror "Vlan over bridge is not supported!" exit 1 - elif kdump_is_bond "$_phydev"; then - (kdump_setup_bond "$_phydev") || exit 1 - echo " vlan=$(kdump_setup_ifname "$_netdev"):$_phydev" > "${initdir}/etc/cmdline.d/43vlan.conf" - elif kdump_is_team "$_phydev"; then - (kdump_setup_team "$_phydev") || exit 1 - echo " vlan=$(kdump_setup_ifname "$_netdev"):$_phydev" > "${initdir}/etc/cmdline.d/43vlan.conf" - else - _kdumpdev="$(kdump_setup_ifname "$_phydev")" - echo " vlan=$(kdump_setup_ifname "$_netdev"):$_kdumpdev ifname=$_kdumpdev:$_netmac" > "${initdir}/etc/cmdline.d/43vlan.conf" + elif kdump_is_bond "$_parent_netif"; then + (kdump_setup_bond "$_parent_netif") || exit 1 + elif kdump_is_team "$_parent_netif"; then + (kdump_setup_team "$_parent_netif") || exit 1 fi + + kdump_copy_nmconnection_file "$_parent_netif" }
# find online znet device
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index b2e6027..031ff87 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -442,23 +442,10 @@ kdump_setup_bond() {
kdump_setup_team() { local _netdev=$1 - local _dev _mac _slaves _kdumpdev + local _dev for _dev in $(teamnl "$_netdev" ports | awk -F':' '{print $2}'); do - _mac=$(kdump_get_perm_addr "$_dev") - _kdumpdev=$(kdump_setup_ifname "$_dev") - echo -n " ifname=$_kdumpdev:$_mac" >> "${initdir}/etc/cmdline.d/44team.conf" - _slaves+="$_kdumpdev," + kdump_copy_nmconnection_file "$_dev" done - echo " team=$_netdev:${_slaves%,}" >> "${initdir}/etc/cmdline.d/44team.conf" - #Buggy version teamdctl outputs to stderr! - #Try to use the latest version of teamd. - if ! teamdctl "$_netdev" config dump > "${initdir}/tmp/$$-$_netdev.conf"; then - derror "teamdctl failed." - exit 1 - fi - inst_dir /etc/teamd - inst_simple "${initdir}/tmp/$$-$_netdev.conf" "/etc/teamd/$_netdev.conf" - rm -f "${initdir}/tmp/$$-$_netdev.conf" }
kdump_setup_vlan() {
Clean up the related code to build up dracut cmdline parameter such rd.route, ip and etc. And there is no need to to setup dns when copying .nmconnection directly to initrd either.
Note the bootdev dracut command line parameter is only used by dracut's 35network-legacy and network-manager doesn't use it, remove related code as well.
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 148 +---------------------------------------- 1 file changed, 2 insertions(+), 146 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 031ff87..9ae3dd1 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -94,39 +94,6 @@ source_ifcfg_file() { fi }
-kdump_setup_dns() { - local _netdev="$1" - local _conpath="$2" - local _nameserver _dns _tmp array - local _dnsfile=${initdir}/etc/cmdline.d/42dns.conf - - _tmp=$(get_nmcli_field_by_conpath "IP4.DNS" "$_conpath") - # shellcheck disable=SC2206 - array=(${_tmp//|/ }) - if [[ ${array[*]} ]]; then - for _dns in "${array[@]}"; do - echo "nameserver=$_dns" >> "$_dnsfile" - done - else - dwarning "Failed to get DNS info via nmcli output. Now try sourcing ifcfg script" - source_ifcfg_file "$_netdev" - [[ -n $DNS1 ]] && echo "nameserver=$DNS1" > "$_dnsfile" - [[ -n $DNS2 ]] && echo "nameserver=$DNS2" >> "$_dnsfile" - fi - - while read -r content; do - _nameserver=$(echo "$content" | grep ^nameserver) - [[ -z $_nameserver ]] && continue - - _dns=$(echo "$_nameserver" | awk '{print $2}') - [[ -z $_dns ]] && continue - - if [[ ! -f $_dnsfile ]] || ! grep -q "$_dns" "$_dnsfile"; then - echo "nameserver=$_dns" >> "$_dnsfile" - fi - done < "/etc/resolv.conf" -} - # $1: repeat times # $2: string to be repeated # $3: separator @@ -237,89 +204,6 @@ cal_netmask_by_prefix() { fi }
-#$1: netdev name -#$2: srcaddr -#if it use static ip echo it, or echo null -kdump_static_ip() { - local _netdev="$1" _srcaddr="$2" kdumpnic="$3" _ipv6_flag - local _netmask _gateway _ipaddr _target _nexthop _prefix - - _ipaddr=$(ip addr show dev "$_netdev" permanent | awk "/ $_srcaddr/.* /{print $2}") - - if is_ipv6_address "$_srcaddr"; then - _ipv6_flag="-6" - fi - - if [[ -n $_ipaddr ]]; then - _gateway=$(ip $_ipv6_flag route list dev "$_netdev" \ - | awk '/^default /{print $3}' | head -n 1) - - if [[ "x" != "x"$_ipv6_flag ]]; then - # _ipaddr="2002::56ff:feb6:56d5/64", _netmask is the number after "/" - _netmask=${_ipaddr#*/} - _srcaddr="[$_srcaddr]" - _gateway="[$_gateway]" - else - _prefix=$(cut -d'/' -f2 <<< "$_ipaddr") - if ! _netmask=$(cal_netmask_by_prefix "$_prefix" "$_ipv6_flag"); then - derror "Failed to calculate netmask for $_ipaddr" - exit 1 - fi - fi - echo -n "${_srcaddr}::${_gateway}:${_netmask}::" - fi - - /sbin/ip $_ipv6_flag route show | grep -v default \ - | grep ".*via.* $_netdev " | grep -v "^[[:space:]]*nexthop" \ - | while read -r _route; do - _target=$(echo "$_route" | awk '{print $1}') - _nexthop=$(echo "$_route" | awk '{print $3}') - if [[ "x" != "x"$_ipv6_flag ]]; then - _target="[$_target]" - _nexthop="[$_nexthop]" - fi - echo "rd.route=$_target:$_nexthop:$kdumpnic" - done >> "${initdir}/etc/cmdline.d/45route-static.conf" - - kdump_handle_mulitpath_route "$_netdev" "$_srcaddr" "$kdumpnic" -} - -kdump_handle_mulitpath_route() { - local _netdev="$1" _srcaddr="$2" kdumpnic="$3" _ipv6_flag - local _target _nexthop _route _weight _max_weight _rule - - if is_ipv6_address "$_srcaddr"; then - _ipv6_flag="-6" - fi - - while IFS="" read -r _route; do - if [[ $_route =~ [[:space:]]+nexthop ]]; then - _route=${_route##[[:space:]]} - # Parse multipath route, using previous _target - [[ $_target == 'default' ]] && continue - [[ $_route =~ .*via.*\ $_netdev ]] || continue - - _weight=$(echo "$_route" | cut -d ' ' -f7) - if [[ $_weight -gt $_max_weight ]]; then - _nexthop=$(echo "$_route" | cut -d ' ' -f3) - _max_weight=$_weight - if [[ "x" != "x"$_ipv6_flag ]]; then - _rule="rd.route=[$_target]:[$_nexthop]:$kdumpnic" - else - _rule="rd.route=$_target:$_nexthop:$kdumpnic" - fi - fi - else - [[ -n $_rule ]] && echo "$_rule" - _target=$(echo "$_route" | cut -d ' ' -f1) - _rule="" _max_weight=0 _weight=0 - fi - done >> "${initdir}/etc/cmdline.d/45route-static.conf" \ - <<< "$(/sbin/ip $_ipv6_flag route show)" - - [[ -n $_rule ]] && echo "$_rule" >> "${initdir}/etc/cmdline.d/45route-static.conf" -} - kdump_get_mac_addr() { cat "/sys/class/net/$1/address" } @@ -555,8 +439,7 @@ kdump_get_remote_ip() { # initramfs accessing giving destination # $1: destination host kdump_install_net() { - local _destaddr _srcaddr _route _netdev _conpath kdumpnic - local _static _proto _ip_conf _ip_opts + local _destaddr _route _netdev kdumpnic local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map @@ -568,9 +451,7 @@ kdump_install_net() {
_destaddr=$(kdump_get_remote_ip "$1") _route=$(kdump_get_ip_route "$_destaddr") - _srcaddr=$(kdump_get_ip_route_field "$_route" "src") _netdev=$(kdump_get_ip_route_field "$_route" "dev") - _conpath=$(get_nmcli_connection_apath_by_ifname "$_netdev") kdumpnic=$(kdump_setup_ifname "$_netdev")
_znet_netdev=$(find_online_znet_device) @@ -582,27 +463,6 @@ kdump_install_net() { fi fi
- _static=$(kdump_static_ip "$_netdev" "$_srcaddr" "$kdumpnic") - if [[ -n $_static ]]; then - _proto=none - elif is_ipv6_address "$_srcaddr"; then - _proto=auto6 - else - _proto=dhcp - fi - - _ip_conf="${initdir}/etc/cmdline.d/40ip.conf" - _ip_opts=" ip=${_static}$kdumpnic:${_proto}" - - # dracut doesn't allow duplicated configuration for same NIC, even they're exactly the same. - # so we have to avoid adding duplicates - # We should also check /proc/cmdline for existing ip=xx arg. - # For example, iscsi boot will specify ip=xxx arg in cmdline. - if [[ ! -f $_ip_conf ]] || ! grep -q "$_ip_opts" "$_ip_conf" \ - && ! grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then - echo "$_ip_opts" >> "$_ip_conf" - fi - if kdump_is_bridge "$_netdev"; then kdump_setup_bridge "$_netdev" elif kdump_is_bond "$_netdev"; then @@ -614,8 +474,6 @@ kdump_install_net() { fi kdump_copy_nmconnection_file "$_netdev"
- kdump_setup_dns "$_netdev" "$_conpath" - if [[ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]]; then # network-manager module needs this parameter echo "rd.neednet" >> "${initdir}/etc/cmdline.d/50neednet.conf" @@ -633,10 +491,8 @@ kdump_install_net() { # the default gate way for network dump, eth1 in the fence kdump path will # call kdump_install_net again and we don't want eth1 to be the default # gateway. - if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ]] \ - && [[ ! -f ${initdir}/etc/cmdline.d/70bootdev.conf ]]; then + if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ]]; then echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf" - echo "bootdev=$kdumpnic" > "${initdir}/etc/cmdline.d/70bootdev.conf" fi
}
By default, NetworkManger will manage all the network interfaces and try to set interface IFF_UP to get carrier state. Regardless of whether the network interface is connected to a cable or not, the NIC driver will allocate memory resources for e.g. ring buffers when setting IFF_UP. This could be a waste of memory. For example it's found i40e consumes ~15GB on a power machine. On this machine, i40e manages four interfaces but only one interface is valid. This patch use "managed=false" to tell NetworkManager to not manage network interfaces that are not needed by kdump by putting /etc/NetworkManager/conf.d/10-kdump-netif.conf in the initramfs.
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 9ae3dd1..2a15e5e 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1,6 +1,7 @@ #!/bin/bash
_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM" +_TMP_KDUMP_NETIFS="$_DRACUT_KDUMP_NM_TMP_DIR/kdump_netifs"
cleanup() { rm -rf $_DRACUT_KDUMP_NM_TMP_DIR @@ -14,6 +15,7 @@ kdump_module_init() { fi
mkdir -p "$_DRACUT_KDUMP_NM_TMP_DIR" + echo -n > "$_TMP_KDUMP_NETIFS"
. /lib/kdump/kdump-lib.sh } @@ -295,6 +297,31 @@ kdump_copy_nmconnection_file() { # wait-device-timeout=60000 is inserted after "[connection]" so the # user's custom value could overwrite it sed -i '/[connection]/a wait-device-timeout=60000' "${initdir}/$_initrd_nmconnection_file_path" + + echo -n " $_dev" >> "$_TMP_KDUMP_NETIFS" +} + +kdump_install_nm_netif_allowlist() { + local _netif _except_netif _netif_allowlist _netif_allowlist_nm_conf + + for _netif in $1; do + _per_mac=$(kdump_get_perm_addr "$_netif") + if [[ "$_per_mac" != 'not set' ]]; then + _except_netif="mac:$_per_mac" + else + _except_netif="interface-name:$_netif" + fi + _netif_allowlist="${_netif_allowlist}except:${_except_netif};" + done + + _netif_allowlist_nm_conf=$_DRACUT_KDUMP_NM_TMP_DIR/netif_allowlist_nm_conf + cat <<- EOF > "$_netif_allowlist_nm_conf" + [device-others] + match-device=${_netif_allowlist} + managed=false + EOF + + inst "$_netif_allowlist_nm_conf" "/etc/NetworkManager/conf.d/10-kdump-netif.conf" }
kdump_setup_bridge() { @@ -907,7 +934,7 @@ remove_cpu_online_rule() { }
install() { - local arch + local arch _netifs
kdump_module_init kdump_install_conf @@ -966,6 +993,11 @@ install() { inst "ip" fi
+ _netifs=$(cat "$_TMP_KDUMP_NETIFS") + if [[ -n "$_netif_allowlist" ]]; then + kdump_install_nm_netif_allowlist "$_netifs" + fi + # For the lvm type target under kdump, in /etc/lvm/lvm.conf we can # safely replace "reserved_memory=XXXX"(default value is 8192) with # "reserved_memory=1024" to lower memory pressure under kdump. We do
Hi Coiby,
On Tue, 21 Jun 2022 14:57:25 +0800 Coiby Xu coxu@redhat.com wrote:
By default, NetworkManger will manage all the network interfaces and try to set interface IFF_UP to get carrier state. Regardless of whether the network interface is connected to a cable or not, the NIC driver will allocate memory resources for e.g. ring buffers when setting IFF_UP. This could be a waste of memory. For example it's found i40e consumes ~15GB on a power machine. On this machine, i40e manages four interfaces but only one interface is valid. This patch use "managed=false" to tell NetworkManager to not manage network interfaces that are not needed by kdump by putting /etc/NetworkManager/conf.d/10-kdump-netif.conf in the initramfs.
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 9ae3dd1..2a15e5e 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1,6 +1,7 @@ #!/bin/bash
_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM" +_TMP_KDUMP_NETIFS="$_DRACUT_KDUMP_NM_TMP_DIR/kdump_netifs"
Could you use a bash array instead of a file here? That would reduce the number of file operations.
Thanks Philipp
cleanup() { rm -rf $_DRACUT_KDUMP_NM_TMP_DIR @@ -14,6 +15,7 @@ kdump_module_init() { fi
mkdir -p "$_DRACUT_KDUMP_NM_TMP_DIR"
echo -n > "$_TMP_KDUMP_NETIFS"
. /lib/kdump/kdump-lib.sh
} @@ -295,6 +297,31 @@ kdump_copy_nmconnection_file() { # wait-device-timeout=60000 is inserted after "[connection]" so the # user's custom value could overwrite it sed -i '/[connection]/a wait-device-timeout=60000' "${initdir}/$_initrd_nmconnection_file_path"
- echo -n " $_dev" >> "$_TMP_KDUMP_NETIFS"
+}
+kdump_install_nm_netif_allowlist() {
- local _netif _except_netif _netif_allowlist _netif_allowlist_nm_conf
- for _netif in $1; do
_per_mac=$(kdump_get_perm_addr "$_netif")
if [[ "$_per_mac" != 'not set' ]]; then
_except_netif="mac:$_per_mac"
else
_except_netif="interface-name:$_netif"
fi
_netif_allowlist="${_netif_allowlist}except:${_except_netif};"
- done
- _netif_allowlist_nm_conf=$_DRACUT_KDUMP_NM_TMP_DIR/netif_allowlist_nm_conf
- cat <<- EOF > "$_netif_allowlist_nm_conf"
[device-others]
match-device=${_netif_allowlist}
managed=false
- EOF
- inst "$_netif_allowlist_nm_conf" "/etc/NetworkManager/conf.d/10-kdump-netif.conf"
}
kdump_setup_bridge() { @@ -907,7 +934,7 @@ remove_cpu_online_rule() { }
install() {
- local arch
local arch _netifs
kdump_module_init kdump_install_conf
@@ -966,6 +993,11 @@ install() { inst "ip" fi
- _netifs=$(cat "$_TMP_KDUMP_NETIFS")
- if [[ -n "$_netif_allowlist" ]]; then
kdump_install_nm_netif_allowlist "$_netifs"
- fi
- # For the lvm type target under kdump, in /etc/lvm/lvm.conf we can # safely replace "reserved_memory=XXXX"(default value is 8192) with # "reserved_memory=1024" to lower memory pressure under kdump. We do
Hi Philipp,
On Mon, Aug 01, 2022 at 04:58:21PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:25 +0800 Coiby Xu coxu@redhat.com wrote:
By default, NetworkManger will manage all the network interfaces and try to set interface IFF_UP to get carrier state. Regardless of whether the network interface is connected to a cable or not, the NIC driver will allocate memory resources for e.g. ring buffers when setting IFF_UP. This could be a waste of memory. For example it's found i40e consumes ~15GB on a power machine. On this machine, i40e manages four interfaces but only one interface is valid. This patch use "managed=false" to tell NetworkManager to not manage network interfaces that are not needed by kdump by putting /etc/NetworkManager/conf.d/10-kdump-netif.conf in the initramfs.
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 9ae3dd1..2a15e5e 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1,6 +1,7 @@ #!/bin/bash
_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM" +_TMP_KDUMP_NETIFS="$_DRACUT_KDUMP_NM_TMP_DIR/kdump_netifs"
Could you use a bash array instead of a file here? That would reduce the number of file operations.
I just tried using a bash array but an unexpected problem is this variable could be modified in a subshell thus the change doesn't persist. It seems I have to use a file unless we avoid calling all kdump_setup_{bond,bridge...} in a subshell.
Thanks Philipp
Hi Coiby,
On Mon, 22 Aug 2022 20:36:26 +0800 Coiby Xu coxu@redhat.com wrote:
Hi Philipp,
On Mon, Aug 01, 2022 at 04:58:21PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:25 +0800 Coiby Xu coxu@redhat.com wrote:
By default, NetworkManger will manage all the network interfaces and try to set interface IFF_UP to get carrier state. Regardless of whether the network interface is connected to a cable or not, the NIC driver will allocate memory resources for e.g. ring buffers when setting IFF_UP. This could be a waste of memory. For example it's found i40e consumes ~15GB on a power machine. On this machine, i40e manages four interfaces but only one interface is valid. This patch use "managed=false" to tell NetworkManager to not manage network interfaces that are not needed by kdump by putting /etc/NetworkManager/conf.d/10-kdump-netif.conf in the initramfs.
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 9ae3dd1..2a15e5e 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1,6 +1,7 @@ #!/bin/bash
_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM" +_TMP_KDUMP_NETIFS="$_DRACUT_KDUMP_NM_TMP_DIR/kdump_netifs"
Could you use a bash array instead of a file here? That would reduce the number of file operations.
I just tried using a bash array but an unexpected problem is this variable could be modified in a subshell thus the change doesn't persist. It seems I have to use a file unless we avoid calling all kdump_setup_{bond,bridge...} in a subshell.
true... although I must admit I don't understand why they are called in a subshell in the first place. The way I see a typical call looks like this
if kdump_is_bond "$_dev"; then (kdump_setup_bond "$_dev") || exit 1 ...
but in that case the subshell doesn't do much other than returning the exit value of the function. So it shouldn't be a problem to drop it. You'd only need to change the "exit 1" to "return 1" in the kdump_setup_* and put the error handling to the first caller.
Anyway, that's probably a clean up for itself...
Thanks for the explanation Philipp
Thanks Philipp
Even after having asked NM to stop managing a unneeded NIC, a NIC driver may still wast memory. For example, mlx5_core uses a substantial amount of memory during driver initialization,
======== Report format module_summary: ======== Module mlx5_core using 350.2MB (89650 pages), peak allocation 367.4MB (94056 pages) Module squashfs using 13.1MB (3360 pages), peak allocation 13.1MB (3360 pages) Module overlay using 2.1MB (550 pages), peak allocation 2.2MB (555 pages) Module dns_resolver using 0.9MB (219 pages), peak allocation 5.2MB (1338 pages) Module mlxfw using 0.7MB (172 pages), peak allocation 5.3MB (1349 pages) ======== Report format module_summary END ========
======== Report format module_top: ======== Top stack usage of module mlx5_core: (null) Pages: 89650 (peak: 94056) ret_from_fork (0xffffda088b4165f8) Pages: 60007 (peak: 60007) kthread (0xffffda088b4bd7e4) Pages: 60007 (peak: 60007) worker_thread (0xffffda088b4b48d0) Pages: 60007 (peak: 60007) process_one_work (0xffffda088b4b3f40) Pages: 60007 (peak: 60007) work_for_cpu_fn (0xffffda088b4aef00) Pages: 53906 (peak: 53906) local_pci_probe (0xffffda088b9e1e44) Pages: 53906 (peak: 53906) probe_one mlx5_core (0xffffda084f899cc8) Pages: 53518 (peak: 53518) mlx5_init_one mlx5_core (0xffffda084f8994ac) Pages: 49756 (peak: 49756) mlx5_function_setup.constprop.0 mlx5_core (0xffffda084f899100) Pages: 44434 (eak: 44434) mlx5_satisfy_startup_pages mlx5_core (0xffffda084f8a4f24) Pages: 44434 (peak: 44434) mlx5_function_setup.constprop.0 mlx5_core (0xffffda084f899078) Pages: 5285 (peak: 5285) mlx5_cmd_init mlx5_core (0xffffda084f89e414) Pages: 4818 (peak: 4818) mlx5_alloc_cmd_msg mlx5_core (0xffffda084f89aaa0) Pages: 4403 (peak: 4403)
This memory consumption is completely unnecessary is kdump doesn't need this NIC. Only install needed NIC drivers to prevent this kind of waste.
Note 1. this patch depends on [1] to ask dracut to not install NIC drivers. 2. "ethtool -i" somehows fails to get the vlan driver 3. team.ko doesn't depend on the team mode drivers so we need to install the team mode drivers manually.
[1] https://github.com/dracutdevs/dracut/pull/1789
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 32 +++++++++++++++++++++++++++++++- mkdumprd | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 2a15e5e..d5bec47 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -324,6 +324,35 @@ kdump_install_nm_netif_allowlist() { inst "$_netif_allowlist_nm_conf" "/etc/NetworkManager/conf.d/10-kdump-netif.conf" }
+_get_nic_driver() { + ethtool -i "$1" | sed -n -E "s/driver: (.*)/\1/p" +} + +kdump_install_nic_driver() { + local _netif _driver _drivers + + for _netif in $1; do + _driver=$(_get_nic_driver "$_netif") + if [[ -z $_driver ]]; then + derror "Failed to get the driver of $_netif" + exit 1 + fi + + if [[ $_driver == "802.1Q VLAN Support" ]]; then + # ethtool somehow doesn't return the driver name for a VLAN NIC + _driver=8021q + elif [[ $_driver == "team" ]]; then + # install the team mode drivers like team_mode_roundrobin.ko as well + _driver='=drivers/net/team' + fi + + _drivers="$_drivers $_driver" + done + + # shellcheck disable=SC2086 # split the argument to have a list of drivers + instmods $_drivers +} + kdump_setup_bridge() { local _netdev=$1 local _dev @@ -994,8 +1023,9 @@ install() { fi
_netifs=$(cat "$_TMP_KDUMP_NETIFS") - if [[ -n "$_netif_allowlist" ]]; then + if [[ -n "$_netifs" ]]; then kdump_install_nm_netif_allowlist "$_netifs" + kdump_install_nic_driver "$_netifs" fi
# For the lvm type target under kdump, in /etc/lvm/lvm.conf we can diff --git a/mkdumprd b/mkdumprd index 3e250e0..4a40f86 100644 --- a/mkdumprd +++ b/mkdumprd @@ -27,7 +27,7 @@ SAVE_PATH=$(get_save_path) OVERRIDE_RESETTABLE=0
extra_modules="" -dracut_args=(--add kdumpbase --quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict -o "plymouth resume ifcfg earlykdump") +dracut_args=(--add kdumpbase --quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict --hostonly-nics '' -o "plymouth resume ifcfg earlykdump")
MKDUMPRD_TMPDIR="$(mktemp -d -t mkdumprd.XXXXXX)" [ -d "$MKDUMPRD_TMPDIR" ] || perror_exit "dracut: mktemp -p -d -t dracut.XXXXXX failed."
Hi Coiby,
On Tue, 21 Jun 2022 14:57:26 +0800 Coiby Xu coxu@redhat.com wrote:
Even after having asked NM to stop managing a unneeded NIC, a NIC driver may still wast memory. For example, mlx5_core uses a substantial amount of memory during driver initialization,
======== Report format module_summary: ======== Module mlx5_core using 350.2MB (89650 pages), peak allocation 367.4MB (94056 pages) Module squashfs using 13.1MB (3360 pages), peak allocation 13.1MB (3360 pages) Module overlay using 2.1MB (550 pages), peak allocation 2.2MB (555 pages) Module dns_resolver using 0.9MB (219 pages), peak allocation 5.2MB (1338 pages) Module mlxfw using 0.7MB (172 pages), peak allocation 5.3MB (1349 pages) ======== Report format module_summary END ========
======== Report format module_top: ======== Top stack usage of module mlx5_core: (null) Pages: 89650 (peak: 94056) ret_from_fork (0xffffda088b4165f8) Pages: 60007 (peak: 60007) kthread (0xffffda088b4bd7e4) Pages: 60007 (peak: 60007) worker_thread (0xffffda088b4b48d0) Pages: 60007 (peak: 60007) process_one_work (0xffffda088b4b3f40) Pages: 60007 (peak: 60007) work_for_cpu_fn (0xffffda088b4aef00) Pages: 53906 (peak: 53906) local_pci_probe (0xffffda088b9e1e44) Pages: 53906 (peak: 53906) probe_one mlx5_core (0xffffda084f899cc8) Pages: 53518 (peak: 53518) mlx5_init_one mlx5_core (0xffffda084f8994ac) Pages: 49756 (peak: 49756) mlx5_function_setup.constprop.0 mlx5_core (0xffffda084f899100) Pages: 44434 (eak: 44434) mlx5_satisfy_startup_pages mlx5_core (0xffffda084f8a4f24) Pages: 44434 (peak: 44434) mlx5_function_setup.constprop.0 mlx5_core (0xffffda084f899078) Pages: 5285 (peak: 5285) mlx5_cmd_init mlx5_core (0xffffda084f89e414) Pages: 4818 (peak: 4818) mlx5_alloc_cmd_msg mlx5_core (0xffffda084f89aaa0) Pages: 4403 (peak: 4403)
This memory consumption is completely unnecessary is kdump doesn't need
s/is/if/ or maybe even better 'when'
this NIC. Only install needed NIC drivers to prevent this kind of waste.
Note
- this patch depends on [1] to ask dracut to not install NIC drivers.
- "ethtool -i" somehows fails to get the vlan driver
- team.ko doesn't depend on the team mode drivers so we need to install the team mode drivers manually.
[1] https://github.com/dracutdevs/dracut/pull/1789
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 32 +++++++++++++++++++++++++++++++- mkdumprd | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 2a15e5e..d5bec47 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -324,6 +324,35 @@ kdump_install_nm_netif_allowlist() { inst "$_netif_allowlist_nm_conf" "/etc/NetworkManager/conf.d/10-kdump-netif.conf" }
+_get_nic_driver() {
- ethtool -i "$1" | sed -n -E "s/driver: (.*)/\1/p"
+}
+kdump_install_nic_driver() {
- local _netif _driver _drivers
- for _netif in $1; do
_driver=$(_get_nic_driver "$_netif")
if [[ -z $_driver ]]; then
derror "Failed to get the driver of $_netif"
exit 1
fi
if [[ $_driver == "802.1Q VLAN Support" ]]; then
# ethtool somehow doesn't return the driver name for a VLAN NIC
_driver=8021q
elif [[ $_driver == "team" ]]; then
# install the team mode drivers like team_mode_roundrobin.ko as well
_driver='=drivers/net/team'
fi
_drivers="$_drivers $_driver"
- done
- # shellcheck disable=SC2086 # split the argument to have a list of drivers
- instmods $_drivers
Instead of disabling shellcheck here you could convert drivers into an array as it is explained in [1] under 'Exceptions'
[1] https://www.shellcheck.net/wiki/SC2086
+}
kdump_setup_bridge() { local _netdev=$1 local _dev @@ -994,8 +1023,9 @@ install() { fi
_netifs=$(cat "$_TMP_KDUMP_NETIFS")
- if [[ -n "$_netif_allowlist" ]]; then
- if [[ -n "$_netifs" ]]; then
I believe this fix should go into the previous patch.
Thanks Philipp
kdump_install_nm_netif_allowlist "$_netifs"
kdump_install_nic_driver "$_netifs"
fi
# For the lvm type target under kdump, in /etc/lvm/lvm.conf we can
diff --git a/mkdumprd b/mkdumprd index 3e250e0..4a40f86 100644 --- a/mkdumprd +++ b/mkdumprd @@ -27,7 +27,7 @@ SAVE_PATH=$(get_save_path) OVERRIDE_RESETTABLE=0
extra_modules="" -dracut_args=(--add kdumpbase --quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict -o "plymouth resume ifcfg earlykdump") +dracut_args=(--add kdumpbase --quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict --hostonly-nics '' -o "plymouth resume ifcfg earlykdump")
MKDUMPRD_TMPDIR="$(mktemp -d -t mkdumprd.XXXXXX)" [ -d "$MKDUMPRD_TMPDIR" ] || perror_exit "dracut: mktemp -p -d -t dracut.XXXXXX failed."
On Mon, Aug 01, 2022 at 04:58:01PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:26 +0800 Coiby Xu coxu@redhat.com wrote:
Even after having asked NM to stop managing a unneeded NIC, a NIC driver may still wast memory. For example, mlx5_core uses a substantial amount of memory during driver initialization,
======== Report format module_summary: ======== Module mlx5_core using 350.2MB (89650 pages), peak allocation 367.4MB (94056 pages) Module squashfs using 13.1MB (3360 pages), peak allocation 13.1MB (3360 pages) Module overlay using 2.1MB (550 pages), peak allocation 2.2MB (555 pages) Module dns_resolver using 0.9MB (219 pages), peak allocation 5.2MB (1338 pages) Module mlxfw using 0.7MB (172 pages), peak allocation 5.3MB (1349 pages) ======== Report format module_summary END ========
======== Report format module_top: ======== Top stack usage of module mlx5_core: (null) Pages: 89650 (peak: 94056) ret_from_fork (0xffffda088b4165f8) Pages: 60007 (peak: 60007) kthread (0xffffda088b4bd7e4) Pages: 60007 (peak: 60007) worker_thread (0xffffda088b4b48d0) Pages: 60007 (peak: 60007) process_one_work (0xffffda088b4b3f40) Pages: 60007 (peak: 60007) work_for_cpu_fn (0xffffda088b4aef00) Pages: 53906 (peak: 53906) local_pci_probe (0xffffda088b9e1e44) Pages: 53906 (peak: 53906) probe_one mlx5_core (0xffffda084f899cc8) Pages: 53518 (peak: 53518) mlx5_init_one mlx5_core (0xffffda084f8994ac) Pages: 49756 (peak: 49756) mlx5_function_setup.constprop.0 mlx5_core (0xffffda084f899100) Pages: 44434 (eak: 44434) mlx5_satisfy_startup_pages mlx5_core (0xffffda084f8a4f24) Pages: 44434 (peak: 44434) mlx5_function_setup.constprop.0 mlx5_core (0xffffda084f899078) Pages: 5285 (peak: 5285) mlx5_cmd_init mlx5_core (0xffffda084f89e414) Pages: 4818 (peak: 4818) mlx5_alloc_cmd_msg mlx5_core (0xffffda084f89aaa0) Pages: 4403 (peak: 4403)
This memory consumption is completely unnecessary is kdump doesn't need
s/is/if/ or maybe even better 'when'
this NIC. Only install needed NIC drivers to prevent this kind of waste.
Note
- this patch depends on [1] to ask dracut to not install NIC drivers.
- "ethtool -i" somehows fails to get the vlan driver
- team.ko doesn't depend on the team mode drivers so we need to install the team mode drivers manually.
[1] https://github.com/dracutdevs/dracut/pull/1789
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 32 +++++++++++++++++++++++++++++++- mkdumprd | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 2a15e5e..d5bec47 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -324,6 +324,35 @@ kdump_install_nm_netif_allowlist() { inst "$_netif_allowlist_nm_conf" "/etc/NetworkManager/conf.d/10-kdump-netif.conf" }
+_get_nic_driver() {
- ethtool -i "$1" | sed -n -E "s/driver: (.*)/\1/p"
+}
+kdump_install_nic_driver() {
- local _netif _driver _drivers
- for _netif in $1; do
_driver=$(_get_nic_driver "$_netif")
if [[ -z $_driver ]]; then
derror "Failed to get the driver of $_netif"
exit 1
fi
if [[ $_driver == "802.1Q VLAN Support" ]]; then
# ethtool somehow doesn't return the driver name for a VLAN NIC
_driver=8021q
elif [[ $_driver == "team" ]]; then
# install the team mode drivers like team_mode_roundrobin.ko as well
_driver='=drivers/net/team'
fi
_drivers="$_drivers $_driver"
- done
- # shellcheck disable=SC2086 # split the argument to have a list of drivers
- instmods $_drivers
Instead of disabling shellcheck here you could convert drivers into an array as it is explained in [1] under 'Exceptions'
[1] https://www.shellcheck.net/wiki/SC2086
+}
kdump_setup_bridge() { local _netdev=$1 local _dev @@ -994,8 +1023,9 @@ install() { fi
_netifs=$(cat "$_TMP_KDUMP_NETIFS")
- if [[ -n "$_netif_allowlist" ]]; then
- if [[ -n "$_netifs" ]]; then
I believe this fix should go into the previous patch.
Good catch! All the three issues have been fixed in v2. Thanks!
A NIC may get a different name in the kdump kernel from 1st kernel in cases like, - kernel assigned network interface names are not persistent e.g. [1] - there is an udev rule to rename the NIC in the 1st kernel but the kdump initrd may not have that rule e.g. [2]
If NM tries to match a NIC with a connection profile based on NIC name i.e. connection.interface-name, it will fail the above bases. A simple solution is to ask NM to match a connection profile by MAC address. Note we don't need to do this for user-created NICs like vlan, bridge and bond.
An remaining issue is passing the name of a NIC via the kdumpnic dracut command line parameter which requires passing ifname=<interface>:<MAC> to have fixed NIC name. But we can simply drop this requirement. kdumpnic is needed because kdump needs to get the IP by NIC name and use the IP to created a dumping folder named "{IP}-{DATE}". We can simply pass the IP to the kdump kernel directly via a new dracut command line parameter kdumpip instead. In addition to the benefit of simplifying the code, there are other three benefits brought by this approach, - make use of whatever network to transfer the vmcore. Because as long as we have the network to we don't care which NIC is active. - if obtained IP in the kdump kernel is different from the one in the 1st kernel. "{IP}-{DATE}" would better tell where the dumped vmcore comes from. - without passing ifname=<interface>:<MAC> to to kdump initrd, the issue of there are two interfaces with the same MAC address for Azure Hyper-V NIC SR-IOV [3] is resolved automatically.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1121778 [2] https://bugzilla.redhat.com/show_bug.cgi?id=810107 [3] https://bugzilla.redhat.com/show_bug.cgi?id=1962421
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-kdump.sh | 25 ++++++++-------- dracut-module-setup.sh | 66 +++++++++++++++++------------------------- kdump-lib-initramfs.sh | 12 ++++++++ 3 files changed, 51 insertions(+), 52 deletions(-)
diff --git a/dracut-kdump.sh b/dracut-kdump.sh index f4456a1..21622f7 100755 --- a/dracut-kdump.sh +++ b/dracut-kdump.sh @@ -479,22 +479,23 @@ save_vmcore_dmesg_ssh() get_host_ip() { if is_nfs_dump_target || is_ssh_dump_target; then - kdumpnic=$(getarg kdumpnic=) - if [ -z "$kdumpnic" ]; then - derror "failed to get kdumpnic!" - return 1 - fi - if ! kdumphost=$(ip addr show dev "$kdumpnic" | grep '[ ]*inet'); then - derror "wrong kdumpnic: $kdumpnic" + _kdump_remote_ip=$(getarg kdump_remote_ip=) + + if [ -z "$_kdump_remote_ip" ]; then + derror "failed to get remote IP address!" return 1 fi - kdumphost=$(echo "$kdumphost" | head -n 1 | awk '{print $2}') - kdumphost="${kdumphost%%/*}" - if [ -z "$kdumphost" ]; then - derror "wrong kdumpnic: $kdumpnic" + _route=$(kdump_get_ip_route "$_kdump_remote_ip") + _netdev=$(kdump_get_ip_route_field "$_route" "dev") + + if ! _kdumpip=$(ip addr show dev "$_netdev" | grep '[ ]*inet'); then + derror "Failed to get IP of $_netdev" return 1 fi - HOST_IP=$kdumphost + + _kdumpip=$(echo "$_kdumpip" | head -n 1 | awk '{print $2}') + _kdumpip="${_kdumpip%%/*}" + HOST_IP=$_kdumpip fi return 0 } diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index d5bec47..1a8f55f 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -222,26 +222,6 @@ kdump_get_perm_addr() { fi }
-# Prefix kernel assigned names with "kdump-". EX: eth0 -> kdump-eth0 -# Because kernel assigned names are not persistent between 1st and 2nd -# kernel. We could probably end up with eth0 being eth1, eth0 being -# eth1, and naming conflict happens. -kdump_setup_ifname() { - local _ifname - - # If ifname already has 'kdump-' prefix, we must be switching from - # fadump to kdump. Skip prefixing 'kdump-' in this case as adding - # another prefix may truncate the ifname. Since an ifname with - # 'kdump-' is already persistent, this should be fine. - if [[ $1 =~ eth* ]] && [[ ! $1 =~ ^kdump-* ]]; then - _ifname="kdump-$1" - else - _ifname="$1" - fi - - echo "$_ifname" -} - _clone_nmconnection() { local _clone_output _name _unique_id
@@ -255,10 +235,25 @@ _clone_nmconnection() { return 1 }
+_match_nmconnection_by_mac() { + local _unique_id _dev _mac + + _unique_id=$1 + _dev=$2 + + _mac=$(kdump_get_perm_addr "$_dev") + if [[ $_mac != 'not set' ]]; then + _mac_field=$(nmcli connection show "$_unique_id" | grep '.mac-address:' | cut -d: -f1) + nmcli connection modify --temporary "$_unique_id" "$_mac_field" "$_mac" + nmcli connection modify --temporary "$_unique_id" "connection.interface-name" "" + fi +} + # Clone NM connection profiles # # This function makes use of "nmcli clone" to automatically convert ifcfg-* -# files to Networkmanager .nmconnection connection profiles. +# files to Networkmanager .nmconnection connection profiles. It also uses +# "nmcli modify" to modify or remove properties clone_nmconnections() { local _dev _cloned_nmconnection_file_path _tmp_nmconnection_file_path _old_uuid _uuid
@@ -271,6 +266,10 @@ clone_nmconnections() { exit 1 fi
+ # For physical NIC i.e. non-user created NIC, ask NM to match a + # connection profile based on MAC address + _match_nmconnection_by_mac "$_uuid" "$_dev" + _cloned_nmconnection_file_path=$(nmcli --get-values UUID,FILENAME connection show | sed -n "s/^${_uuid}://p") _tmp_nmconnection_file_path=$_DRACUT_KDUMP_NM_TMP_DIR/$(basename "$_nmconnection_file_path") cp "$_cloned_nmconnection_file_path" "$_tmp_nmconnection_file_path" @@ -465,19 +464,6 @@ kdump_setup_znet() { echo "rd.znet=${NETTYPE},${SUBCHANNELS},${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS}" > "${initdir}/etc/cmdline.d/30znet.conf" }
-kdump_get_ip_route() { - local _route - if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then - derror "Bad kdump network destination: $1" - exit 1 - fi - echo "$_route" -} - -kdump_get_ip_route_field() { - echo "$1" | sed -n -e "s/^.*<$2>\s+(\S+).*$/\1/p" -} - kdump_get_remote_ip() { local _remote _remote_temp _remote=$(get_remote_host "$1") @@ -495,7 +481,7 @@ kdump_get_remote_ip() { # initramfs accessing giving destination # $1: destination host kdump_install_net() { - local _destaddr _route _netdev kdumpnic + local _destaddr _route _netdev local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map @@ -508,7 +494,6 @@ kdump_install_net() { _destaddr=$(kdump_get_remote_ip "$1") _route=$(kdump_get_ip_route "$_destaddr") _netdev=$(kdump_get_ip_route_field "$_route" "dev") - kdumpnic=$(kdump_setup_ifname "$_netdev")
_znet_netdev=$(find_online_znet_device) if [[ -n $_znet_netdev ]]; then @@ -528,6 +513,7 @@ kdump_install_net() { elif kdump_is_vlan "$_netdev"; then kdump_setup_vlan "$_netdev" fi + kdump_copy_nmconnection_file "$_netdev"
if [[ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]]; then @@ -547,8 +533,8 @@ kdump_install_net() { # the default gate way for network dump, eth1 in the fence kdump path will # call kdump_install_net again and we don't want eth1 to be the default # gateway. - if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ]]; then - echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf" + if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpip.conf ]]; then + echo "kdump_remote_ip=$_destaddr" > "${initdir}/etc/cmdline.d/60kdumpip.conf" fi
} @@ -1024,8 +1010,8 @@ install() {
_netifs=$(cat "$_TMP_KDUMP_NETIFS") if [[ -n "$_netifs" ]]; then - kdump_install_nm_netif_allowlist "$_netifs" - kdump_install_nic_driver "$_netifs" + kdump_install_nm_netif_allowlist "$_netifs" + kdump_install_nic_driver "$_netifs" fi
# For the lvm type target under kdump, in /etc/lvm/lvm.conf we can diff --git a/kdump-lib-initramfs.sh b/kdump-lib-initramfs.sh index 84e6bf7..c231c52 100755 --- a/kdump-lib-initramfs.sh +++ b/kdump-lib-initramfs.sh @@ -131,3 +131,15 @@ is_fs_dump_target() { [ -n "$(kdump_get_conf_val "ext[234]|xfs|btrfs|minix")" ] } + +kdump_get_ip_route() { + if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then + derror "Bad kdump network destination: $1" + exit 1 + fi + echo "$_route" +} + +kdump_get_ip_route_field() { + echo "$1" | sed -n -e "s/^.*<$2>\s+(\S+).*$/\1/p" +}
Hi Coiby,
On Tue, 21 Jun 2022 14:57:27 +0800 Coiby Xu coxu@redhat.com wrote:
A NIC may get a different name in the kdump kernel from 1st kernel in cases like,
- kernel assigned network interface names are not persistent e.g. [1]
- there is an udev rule to rename the NIC in the 1st kernel but the kdump initrd may not have that rule e.g. [2]
If NM tries to match a NIC with a connection profile based on NIC name i.e. connection.interface-name, it will fail the above bases. A simple solution is to ask NM to match a connection profile by MAC address. Note we don't need to do this for user-created NICs like vlan, bridge and bond.
An remaining issue is passing the name of a NIC via the kdumpnic dracut command line parameter which requires passing ifname=<interface>:<MAC> to have fixed NIC name. But we can simply drop this requirement. kdumpnic is needed because kdump needs to get the IP by NIC name and use the IP to created a dumping folder named "{IP}-{DATE}". We can simply pass the IP to the kdump kernel directly via a new dracut command line parameter kdumpip instead. In addition to the benefit of simplifying the code, there are other three benefits brought by this approach,
- make use of whatever network to transfer the vmcore. Because as long as we have the network to we don't care which NIC is active.
- if obtained IP in the kdump kernel is different from the one in the 1st kernel. "{IP}-{DATE}" would better tell where the dumped vmcore comes from.
- without passing ifname=<interface>:<MAC> to to kdump initrd, the
s/to to/to/
issue of there are two interfaces with the same MAC address for Azure Hyper-V NIC SR-IOV [3] is resolved automatically.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1121778 [2] https://bugzilla.redhat.com/show_bug.cgi?id=810107 [3] https://bugzilla.redhat.com/show_bug.cgi?id=1962421
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-kdump.sh | 25 ++++++++-------- dracut-module-setup.sh | 66 +++++++++++++++++------------------------- kdump-lib-initramfs.sh | 12 ++++++++ 3 files changed, 51 insertions(+), 52 deletions(-)
diff --git a/dracut-kdump.sh b/dracut-kdump.sh index f4456a1..21622f7 100755 --- a/dracut-kdump.sh +++ b/dracut-kdump.sh @@ -479,22 +479,23 @@ save_vmcore_dmesg_ssh() get_host_ip() { if is_nfs_dump_target || is_ssh_dump_target; then
kdumpnic=$(getarg kdumpnic=)
if [ -z "$kdumpnic" ]; then
derror "failed to get kdumpnic!"
return 1
fi
if ! kdumphost=$(ip addr show dev "$kdumpnic" | grep '[ ]*inet'); then
derror "wrong kdumpnic: $kdumpnic"
_kdump_remote_ip=$(getarg kdump_remote_ip=)
if [ -z "$_kdump_remote_ip" ]; then
fiderror "failed to get remote IP address!" return 1
kdumphost=$(echo "$kdumphost" | head -n 1 | awk '{print $2}')
kdumphost="${kdumphost%%/*}"
if [ -z "$kdumphost" ]; then
derror "wrong kdumpnic: $kdumpnic"
_route=$(kdump_get_ip_route "$_kdump_remote_ip")
_netdev=$(kdump_get_ip_route_field "$_route" "dev")
if ! _kdumpip=$(ip addr show dev "$_netdev" | grep '[ ]*inet'); then
fiderror "Failed to get IP of $_netdev" return 1
HOST_IP=$kdumphost
_kdumpip=$(echo "$_kdumpip" | head -n 1 | awk '{print $2}')
_kdumpip="${_kdumpip%%/*}"
fi return 0HOST_IP=$_kdumpip
}
As you are basically rewriting this function you could move everything out of the if-block and simply have an
if ! is_nfs_dump_target && ! is_ssh_dump_target; then return 0 fi
at the beginning of the function. With that you get rid of the extra indentation for all the code.
Furthermore you could declare the variables as local.
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index d5bec47..1a8f55f 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -222,26 +222,6 @@ kdump_get_perm_addr() { fi }
-# Prefix kernel assigned names with "kdump-". EX: eth0 -> kdump-eth0 -# Because kernel assigned names are not persistent between 1st and 2nd -# kernel. We could probably end up with eth0 being eth1, eth0 being -# eth1, and naming conflict happens. -kdump_setup_ifname() {
- local _ifname
- # If ifname already has 'kdump-' prefix, we must be switching from
- # fadump to kdump. Skip prefixing 'kdump-' in this case as adding
- # another prefix may truncate the ifname. Since an ifname with
- # 'kdump-' is already persistent, this should be fine.
- if [[ $1 =~ eth* ]] && [[ ! $1 =~ ^kdump-* ]]; then
_ifname="kdump-$1"
- else
_ifname="$1"
- fi
- echo "$_ifname"
-}
_clone_nmconnection() { local _clone_output _name _unique_id
@@ -255,10 +235,25 @@ _clone_nmconnection() { return 1 }
+_match_nmconnection_by_mac() {
- local _unique_id _dev _mac
- _unique_id=$1
- _dev=$2
- _mac=$(kdump_get_perm_addr "$_dev")
- if [[ $_mac != 'not set' ]]; then
_mac_field=$(nmcli connection show "$_unique_id" | grep '\.mac-address:' | cut -d: -f1)
not really sure if it's worth it but you should(tm) be able to drop the two pipes and the regex by calling nmcli twice, i.e.
_type=$(nmcli --get-values connection.type connection show "$_unique_id") _mac_field=$(nmcli --get-values ${_type}.mac_address connection show "$_unique_id")
Furthermore you should declare $_mac_field (and $_type if you use it) local.
nmcli connection modify --temporary "$_unique_id" "$_mac_field" "$_mac"
nmcli connection modify --temporary "$_unique_id" "connection.interface-name" ""
- fi
+}
# Clone NM connection profiles # # This function makes use of "nmcli clone" to automatically convert ifcfg-* -# files to Networkmanager .nmconnection connection profiles. +# files to Networkmanager .nmconnection connection profiles. It also uses +# "nmcli modify" to modify or remove properties clone_nmconnections() { local _dev _cloned_nmconnection_file_path _tmp_nmconnection_file_path _old_uuid _uuid
@@ -271,6 +266,10 @@ clone_nmconnections() { exit 1 fi
# For physical NIC i.e. non-user created NIC, ask NM to match a
# connection profile based on MAC address
_match_nmconnection_by_mac "$_uuid" "$_dev"
_cloned_nmconnection_file_path=$(nmcli --get-values UUID,FILENAME connection show | sed -n "s/^${_uuid}://p") _tmp_nmconnection_file_path=$_DRACUT_KDUMP_NM_TMP_DIR/$(basename "$_nmconnection_file_path") cp "$_cloned_nmconnection_file_path" "$_tmp_nmconnection_file_path"
@@ -465,19 +464,6 @@ kdump_setup_znet() { echo "rd.znet=${NETTYPE},${SUBCHANNELS},${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS}" > "${initdir}/etc/cmdline.d/30znet.conf" }
-kdump_get_ip_route() {
- local _route
- if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then
derror "Bad kdump network destination: $1"
exit 1
- fi
- echo "$_route"
-}
-kdump_get_ip_route_field() {
- echo "$1" | sed -n -e "s/^.*<$2>\s+(\S+).*$/\1/p"
-}
kdump_get_remote_ip() { local _remote _remote_temp _remote=$(get_remote_host "$1") @@ -495,7 +481,7 @@ kdump_get_remote_ip() { # initramfs accessing giving destination # $1: destination host kdump_install_net() {
- local _destaddr _route _netdev kdumpnic
- local _destaddr _route _netdev local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map
@@ -508,7 +494,6 @@ kdump_install_net() { _destaddr=$(kdump_get_remote_ip "$1") _route=$(kdump_get_ip_route "$_destaddr") _netdev=$(kdump_get_ip_route_field "$_route" "dev")
kdumpnic=$(kdump_setup_ifname "$_netdev")
_znet_netdev=$(find_online_znet_device) if [[ -n $_znet_netdev ]]; then
@@ -528,6 +513,7 @@ kdump_install_net() { elif kdump_is_vlan "$_netdev"; then kdump_setup_vlan "$_netdev" fi
kdump_copy_nmconnection_file "$_netdev"
if [[ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]]; then
@@ -547,8 +533,8 @@ kdump_install_net() { # the default gate way for network dump, eth1 in the fence kdump path will # call kdump_install_net again and we don't want eth1 to be the default # gateway.
- if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ]]; then
echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf"
- if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpip.conf ]]; then
fiecho "kdump_remote_ip=$_destaddr" > "${initdir}/etc/cmdline.d/60kdumpip.conf"
} @@ -1024,8 +1010,8 @@ install() {
_netifs=$(cat "$_TMP_KDUMP_NETIFS") if [[ -n "$_netifs" ]]; then
kdump_install_nm_netif_allowlist "$_netifs"
kdump_install_nic_driver "$_netifs"
kdump_install_nm_netif_allowlist "$_netifs"
kdump_install_nic_driver "$_netifs"
This should go into the two patches that introduced the two lines.
Thanks Philipp
fi # For the lvm type target under kdump, in /etc/lvm/lvm.conf we can
diff --git a/kdump-lib-initramfs.sh b/kdump-lib-initramfs.sh index 84e6bf7..c231c52 100755 --- a/kdump-lib-initramfs.sh +++ b/kdump-lib-initramfs.sh @@ -131,3 +131,15 @@ is_fs_dump_target() { [ -n "$(kdump_get_conf_val "ext[234]|xfs|btrfs|minix")" ] }
+kdump_get_ip_route() {
- if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then
derror "Bad kdump network destination: $1"
exit 1
- fi
- echo "$_route"
+}
+kdump_get_ip_route_field() {
- echo "$1" | sed -n -e "s/^.*<$2>\s+(\S+).*$/\1/p"
+}
Hi Philipp,
On Mon, Aug 01, 2022 at 04:57:22PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:27 +0800 Coiby Xu coxu@redhat.com wrote:
A NIC may get a different name in the kdump kernel from 1st kernel in cases like,
- kernel assigned network interface names are not persistent e.g. [1]
- there is an udev rule to rename the NIC in the 1st kernel but the kdump initrd may not have that rule e.g. [2]
If NM tries to match a NIC with a connection profile based on NIC name i.e. connection.interface-name, it will fail the above bases. A simple solution is to ask NM to match a connection profile by MAC address. Note we don't need to do this for user-created NICs like vlan, bridge and bond.
An remaining issue is passing the name of a NIC via the kdumpnic dracut command line parameter which requires passing ifname=<interface>:<MAC> to have fixed NIC name. But we can simply drop this requirement. kdumpnic is needed because kdump needs to get the IP by NIC name and use the IP to created a dumping folder named "{IP}-{DATE}". We can simply pass the IP to the kdump kernel directly via a new dracut command line parameter kdumpip instead. In addition to the benefit of simplifying the code, there are other three benefits brought by this approach,
- make use of whatever network to transfer the vmcore. Because as long as we have the network to we don't care which NIC is active.
- if obtained IP in the kdump kernel is different from the one in the 1st kernel. "{IP}-{DATE}" would better tell where the dumped vmcore comes from.
- without passing ifname=<interface>:<MAC> to to kdump initrd, the
s/to to/to/
Thanks for catching this typo.
issue of there are two interfaces with the same MAC address for Azure Hyper-V NIC SR-IOV [3] is resolved automatically.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1121778 [2] https://bugzilla.redhat.com/show_bug.cgi?id=810107 [3] https://bugzilla.redhat.com/show_bug.cgi?id=1962421
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-kdump.sh | 25 ++++++++-------- dracut-module-setup.sh | 66 +++++++++++++++++------------------------- kdump-lib-initramfs.sh | 12 ++++++++ 3 files changed, 51 insertions(+), 52 deletions(-)
diff --git a/dracut-kdump.sh b/dracut-kdump.sh index f4456a1..21622f7 100755 --- a/dracut-kdump.sh +++ b/dracut-kdump.sh @@ -479,22 +479,23 @@ save_vmcore_dmesg_ssh() get_host_ip() { if is_nfs_dump_target || is_ssh_dump_target; then
kdumpnic=$(getarg kdumpnic=)
if [ -z "$kdumpnic" ]; then
derror "failed to get kdumpnic!"
return 1
fi
if ! kdumphost=$(ip addr show dev "$kdumpnic" | grep '[ ]*inet'); then
derror "wrong kdumpnic: $kdumpnic"
_kdump_remote_ip=$(getarg kdump_remote_ip=)
if [ -z "$_kdump_remote_ip" ]; then
fiderror "failed to get remote IP address!" return 1
kdumphost=$(echo "$kdumphost" | head -n 1 | awk '{print $2}')
kdumphost="${kdumphost%%/*}"
if [ -z "$kdumphost" ]; then
derror "wrong kdumpnic: $kdumpnic"
_route=$(kdump_get_ip_route "$_kdump_remote_ip")
_netdev=$(kdump_get_ip_route_field "$_route" "dev")
if ! _kdumpip=$(ip addr show dev "$_netdev" | grep '[ ]*inet'); then
fiderror "Failed to get IP of $_netdev" return 1
HOST_IP=$kdumphost
_kdumpip=$(echo "$_kdumpip" | head -n 1 | awk '{print $2}')
_kdumpip="${_kdumpip%%/*}"
fi return 0HOST_IP=$_kdumpip
}
As you are basically rewriting this function you could move everything out of the if-block and simply have an
if ! is_nfs_dump_target && ! is_ssh_dump_target; then return 0 fi
at the beginning of the function. With that you get rid of the extra indentation for all the code.
Good suggestion!
Furthermore you could declare the variables as local.
dracut-kdump.sh is supposed to be POSIX-compatible so we shouldn't decare the variables as local.
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index d5bec47..1a8f55f 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -222,26 +222,6 @@ kdump_get_perm_addr() { fi }
-# Prefix kernel assigned names with "kdump-". EX: eth0 -> kdump-eth0 -# Because kernel assigned names are not persistent between 1st and 2nd -# kernel. We could probably end up with eth0 being eth1, eth0 being -# eth1, and naming conflict happens. -kdump_setup_ifname() {
- local _ifname
- # If ifname already has 'kdump-' prefix, we must be switching from
- # fadump to kdump. Skip prefixing 'kdump-' in this case as adding
- # another prefix may truncate the ifname. Since an ifname with
- # 'kdump-' is already persistent, this should be fine.
- if [[ $1 =~ eth* ]] && [[ ! $1 =~ ^kdump-* ]]; then
_ifname="kdump-$1"
- else
_ifname="$1"
- fi
- echo "$_ifname"
-}
_clone_nmconnection() { local _clone_output _name _unique_id
@@ -255,10 +235,25 @@ _clone_nmconnection() { return 1 }
+_match_nmconnection_by_mac() {
- local _unique_id _dev _mac
- _unique_id=$1
- _dev=$2
- _mac=$(kdump_get_perm_addr "$_dev")
- if [[ $_mac != 'not set' ]]; then
_mac_field=$(nmcli connection show "$_unique_id" | grep '\.mac-address:' | cut -d: -f1)
not really sure if it's worth it but you should(tm) be able to drop the two pipes and the regex by calling nmcli twice, i.e.
_type=$(nmcli --get-values connection.type connection show "$_unique_id") _mac_field=$(nmcli --get-values ${_type}.mac_address connection show "$_unique_id")
Actually I'm going to get the field name instead of value. But "nmcli --get-values" is more robust then regex, so I will use _mac_field=$(nmcli --get-values connection.type connection show "$_unique_id").mac-address
Furthermore you should declare $_mac_field (and $_type if you use it) local.
Sure, thanks for the reminder!
nmcli connection modify --temporary "$_unique_id" "$_mac_field" "$_mac"
nmcli connection modify --temporary "$_unique_id" "connection.interface-name" ""
- fi
+}
# Clone NM connection profiles # # This function makes use of "nmcli clone" to automatically convert ifcfg-* -# files to Networkmanager .nmconnection connection profiles. +# files to Networkmanager .nmconnection connection profiles. It also uses +# "nmcli modify" to modify or remove properties clone_nmconnections() { local _dev _cloned_nmconnection_file_path _tmp_nmconnection_file_path _old_uuid _uuid
@@ -271,6 +266,10 @@ clone_nmconnections() { exit 1 fi
# For physical NIC i.e. non-user created NIC, ask NM to match a
# connection profile based on MAC address
_match_nmconnection_by_mac "$_uuid" "$_dev"
_cloned_nmconnection_file_path=$(nmcli --get-values UUID,FILENAME connection show | sed -n "s/^${_uuid}://p") _tmp_nmconnection_file_path=$_DRACUT_KDUMP_NM_TMP_DIR/$(basename "$_nmconnection_file_path") cp "$_cloned_nmconnection_file_path" "$_tmp_nmconnection_file_path"
@@ -465,19 +464,6 @@ kdump_setup_znet() { echo "rd.znet=${NETTYPE},${SUBCHANNELS},${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS}" > "${initdir}/etc/cmdline.d/30znet.conf" }
-kdump_get_ip_route() {
- local _route
- if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then
derror "Bad kdump network destination: $1"
exit 1
- fi
- echo "$_route"
-}
-kdump_get_ip_route_field() {
- echo "$1" | sed -n -e "s/^.*<$2>\s+(\S+).*$/\1/p"
-}
kdump_get_remote_ip() { local _remote _remote_temp _remote=$(get_remote_host "$1") @@ -495,7 +481,7 @@ kdump_get_remote_ip() { # initramfs accessing giving destination # $1: destination host kdump_install_net() {
- local _destaddr _route _netdev kdumpnic
- local _destaddr _route _netdev local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map
@@ -508,7 +494,6 @@ kdump_install_net() { _destaddr=$(kdump_get_remote_ip "$1") _route=$(kdump_get_ip_route "$_destaddr") _netdev=$(kdump_get_ip_route_field "$_route" "dev")
kdumpnic=$(kdump_setup_ifname "$_netdev")
_znet_netdev=$(find_online_znet_device) if [[ -n $_znet_netdev ]]; then
@@ -528,6 +513,7 @@ kdump_install_net() { elif kdump_is_vlan "$_netdev"; then kdump_setup_vlan "$_netdev" fi
kdump_copy_nmconnection_file "$_netdev"
if [[ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]]; then
@@ -547,8 +533,8 @@ kdump_install_net() { # the default gate way for network dump, eth1 in the fence kdump path will # call kdump_install_net again and we don't want eth1 to be the default # gateway.
- if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ]]; then
echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf"
- if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpip.conf ]]; then
fiecho "kdump_remote_ip=$_destaddr" > "${initdir}/etc/cmdline.d/60kdumpip.conf"
} @@ -1024,8 +1010,8 @@ install() {
_netifs=$(cat "$_TMP_KDUMP_NETIFS") if [[ -n "$_netifs" ]]; then
kdump_install_nm_netif_allowlist "$_netifs"
kdump_install_nic_driver "$_netifs"
kdump_install_nm_netif_allowlist "$_netifs"
kdump_install_nic_driver "$_netifs"
This should go into the two patches that introduced the two lines.
Good catch!
Thanks Philipp
Hi Coiby,
On Tue, 23 Aug 2022 14:57:12 +0800 Coiby Xu coxu@redhat.com wrote:
[...]
Furthermore you could declare the variables as local.
dracut-kdump.sh is supposed to be POSIX-compatible so we shouldn't decare the variables as local.
Oups... missed that...
And now finally off to v2. Philipp
/usr/lib/udev/ccw_init [1] shipped by s390utils extracts the values of SUBCHANNELS, NETTYPE and LAYER2 from /etc/sysconfig/network-scripts/ifcfg-* or /etc/NetworkManager/system-connections/*.nmconnection to activate znet network device. If the connection profile is copied to initrd, there is no need to set up the "rd.znet" dracut cmdline parameter.
There are two cases addressed by this commit, 1. znet network interface is a slave of bonding/teaming/vlan/bridging network. The connection profile has been copied to initrd by kdump_copy_nmconnection_file and it contains the info needed by ccw_init. 2. znet network interface is a slave of bonding/teaming/vlan/bridging network. The corresponding ifcfg-*/*.nmconnection file may not contain info like SUBCHANNELS [2]. In this case, copy the ifcfg-*/*.nmconnection file that has this info to the kdump initrd. Also to prevent the copied connection profile from being chosen by NM, set connection.autoconnect=false for this connection profile.
Note 1. ccw_init doesn't care if SUBCHANNELS, NETTYPE and LAYER2 comes from an active NM profile or not. If an inactive NM profile contains this info, it needs to be copied to the kdump initrd as well. 2. "rd.znet_ifname=$_netdev:${SUBCHANNELS}" is no needed because now there is no renaming of s390x network interfaces when reusing NetworkManager profiles. rd.znet_ifname was introduced in commit ce0305d ("Add a new option 'rd.znet_ifname' in order to use it in udev rules") to address the special case of non-persistent MAC address by renaming a network interface by SUBCHANNELS.
[1] https://src.fedoraproject.org/rpms/s390utils/blob/rawhide/f/ccw_init [2] https://bugzilla.redhat.com/show_bug.cgi?id=2064708
Signed-off-by: Coiby Xu coxu@redhat.com --- dracut-module-setup.sh | 70 ++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 33 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 1a8f55f..12b658a 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -434,34 +434,46 @@ find_online_znet_device() { echo -n "$ifname" }
-# setup s390 znet cmdline -# $1: netdev (ifname) -# $2: nmcli connection path +_find_znet_nmconnection() { + LANG=C grep -s -E -i -l \ + "^s390-subchannels=([0-9].[0-9].[a-f0-9]+;){0,2}" \ + "$1"/*.nmconnection | LC_ALL=C sed -e "$2" +} + +# setup s390 znet +# +# Note part of code is extracted from ccw_init provided by s390utils kdump_setup_znet() { - local _netdev="$1" - local _conpath="$2" - local s390_prefix="802-3-ethernet.s390-" - local _options="" - local NETTYPE - local SUBCHANNELS - - NETTYPE=$(get_nmcli_field_by_conpath "${s390_prefix}nettype" "$_conpath") - SUBCHANNELS=$(get_nmcli_field_by_conpath "${s390_prefix}subchannels" "$_conpath") - _options=$(get_nmcli_field_by_conpath "${s390_prefix}options" "$_conpath") - - if [[ -z $NETTYPE || -z $SUBCHANNELS || -z $_options ]]; then - dwarning "Failed to get znet configuration via nmlci output. Now try sourcing ifcfg script." - source_ifcfg_file "$_netdev" - for i in $OPTIONS; do - _options=${_options},$i - done + local _config_file _uniq_name _NM_conf_dir + local __sed_discard_ignored_files='/(~|.bak|.old|.orig|.rpmnew|.rpmorig|.rpmsave)$/d' + + _NM_conf_dir="/etc/NetworkManager/system-connections" + + _config_file=$(_find_znet_nmconnection "$initdir/$_NM_conf_dir" "$__sed_discard_ignored_files") + if [[ -n "$_config_file" ]]; then + ddebug "$_config_file has already contained the znet config" + return fi
- if [[ -z $NETTYPE || -z $SUBCHANNELS || -z $_options ]]; then - exit 1 + _config_file=$(LANG=C grep -s -E -i -l \ + "^[[:space:]]*SUBCHANNELS=['"]?([0-9].[0-9].[a-f0-9]+,){0,2}" \ + /etc/sysconfig/network-scripts/ifcfg-* \ + | LC_ALL=C sed -e "$__sed_discard_ignored_files") + + if [[ -n "$_config_file" ]]; then + LANG=c grep 'SUBCHANNELS|NETTYPE|OPTIONS' "$_config_file" > "$initdir/$_config_file" + else + _config_file=$(_find_znet_nmconnection "$_NM_conf_dir" "$__sed_discard_ignored_files") + fi + + if [[ -n "$_config_file" ]]; then + _uniq_name=$(cat /proc/sys/kernel/random/uuid) + nmcli connection clone --temporary "$_config_file" "$_uniq_name" &> >(ddebug) + nmcli connection modify --temporary "$_uniq_name" connection.autoconnect false + inst "/run/NetworkManager/system-connections/${_uniq_name}.nmconnection" "${_NM_conf_dir}/${_uniq_name}.nmconnection" + nmcli connection del "$_uniq_name" &> >(ddebug) fi
- echo "rd.znet=${NETTYPE},${SUBCHANNELS},${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS}" > "${initdir}/etc/cmdline.d/30znet.conf" }
kdump_get_remote_ip() { @@ -482,7 +494,6 @@ kdump_get_remote_ip() { # $1: destination host kdump_install_net() { local _destaddr _route _netdev - local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map
@@ -495,15 +506,6 @@ kdump_install_net() { _route=$(kdump_get_ip_route "$_destaddr") _netdev=$(kdump_get_ip_route_field "$_route" "dev")
- _znet_netdev=$(find_online_znet_device) - if [[ -n $_znet_netdev ]]; then - _znet_conpath=$(get_nmcli_connection_apath_by_ifname "$_znet_netdev") - if ! (kdump_setup_znet "$_znet_netdev" "$_znet_conpath"); then - derror "Failed to set up znet" - exit 1 - fi - fi - if kdump_is_bridge "$_netdev"; then kdump_setup_bridge "$_netdev" elif kdump_is_bond "$_netdev"; then @@ -516,6 +518,8 @@ kdump_install_net() {
kdump_copy_nmconnection_file "$_netdev"
+ [[ -n "$(find_online_znet_device)" ]] && kdump_setup_znet + if [[ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]]; then # network-manager module needs this parameter echo "rd.neednet" >> "${initdir}/etc/cmdline.d/50neednet.conf"
Hi Coiby,
On Tue, 21 Jun 2022 14:57:28 +0800 Coiby Xu coxu@redhat.com wrote:
/usr/lib/udev/ccw_init [1] shipped by s390utils extracts the values of SUBCHANNELS, NETTYPE and LAYER2 from /etc/sysconfig/network-scripts/ifcfg-* or /etc/NetworkManager/system-connections/*.nmconnection to activate znet network device. If the connection profile is copied to initrd, there is no need to set up the "rd.znet" dracut cmdline parameter.
There are two cases addressed by this commit,
- znet network interface is a slave of bonding/teaming/vlan/bridging network. The connection profile has been copied to initrd by kdump_copy_nmconnection_file and it contains the info needed by ccw_init.
- znet network interface is a slave of bonding/teaming/vlan/bridging network. The corresponding ifcfg-*/*.nmconnection file may not contain info like SUBCHANNELS [2]. In this case, copy the ifcfg-*/*.nmconnection file that has this info to the kdump initrd. Also to prevent the copied connection profile from being chosen by NM, set connection.autoconnect=false for this connection profile.
Note
- ccw_init doesn't care if SUBCHANNELS, NETTYPE and LAYER2 comes from an active NM profile or not. If an inactive NM profile contains this info, it needs to be copied to the kdump initrd as well.
- "rd.znet_ifname=$_netdev:${SUBCHANNELS}" is no needed because now there is no renaming of s390x network interfaces when reusing NetworkManager profiles. rd.znet_ifname was introduced in commit ce0305d ("Add a new option 'rd.znet_ifname' in order to use it in udev rules") to address the special case of non-persistent MAC address by renaming a network interface by SUBCHANNELS.
[1] https://src.fedoraproject.org/rpms/s390utils/blob/rawhide/f/ccw_init [2] https://bugzilla.redhat.com/show_bug.cgi?id=2064708
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 70 ++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 33 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 1a8f55f..12b658a 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -434,34 +434,46 @@ find_online_znet_device() { echo -n "$ifname" }
-# setup s390 znet cmdline -# $1: netdev (ifname) -# $2: nmcli connection path +_find_znet_nmconnection() {
- LANG=C grep -s -E -i -l \
"^s390-subchannels=([0-9]\.[0-9]\.[a-f0-9]+;){0,2}" \
"$1"/*.nmconnection | LC_ALL=C sed -e "$2"
+}
+# setup s390 znet +# +# Note part of code is extracted from ccw_init provided by s390utils kdump_setup_znet() {
- local _netdev="$1"
- local _conpath="$2"
- local s390_prefix="802-3-ethernet.s390-"
- local _options=""
- local NETTYPE
- local SUBCHANNELS
- NETTYPE=$(get_nmcli_field_by_conpath "${s390_prefix}nettype" "$_conpath")
- SUBCHANNELS=$(get_nmcli_field_by_conpath "${s390_prefix}subchannels" "$_conpath")
- _options=$(get_nmcli_field_by_conpath "${s390_prefix}options" "$_conpath")
- if [[ -z $NETTYPE || -z $SUBCHANNELS || -z $_options ]]; then
dwarning "Failed to get znet configuration via nmlci output. Now try sourcing ifcfg script."
source_ifcfg_file "$_netdev"
for i in $OPTIONS; do
_options=${_options},$i
done
- local _config_file _uniq_name _NM_conf_dir
s/uniq_name/unique_name/
Thanks Philipp
- local __sed_discard_ignored_files='/(~|.bak|.old|.orig|.rpmnew|.rpmorig|.rpmsave)$/d'
- _NM_conf_dir="/etc/NetworkManager/system-connections"
- _config_file=$(_find_znet_nmconnection "$initdir/$_NM_conf_dir" "$__sed_discard_ignored_files")
- if [[ -n "$_config_file" ]]; then
ddebug "$_config_file has already contained the znet config"
fireturn
- if [[ -z $NETTYPE || -z $SUBCHANNELS || -z $_options ]]; then
exit 1
- _config_file=$(LANG=C grep -s -E -i -l \
"^[[:space:]]*SUBCHANNELS=['\"]?([0-9]\.[0-9]\.[a-f0-9]+,){0,2}" \
/etc/sysconfig/network-scripts/ifcfg-* \
| LC_ALL=C sed -e "$__sed_discard_ignored_files")
- if [[ -n "$_config_file" ]]; then
LANG=c grep 'SUBCHANNELS\|NETTYPE\|OPTIONS' "$_config_file" > "$initdir/$_config_file"
- else
_config_file=$(_find_znet_nmconnection "$_NM_conf_dir" "$__sed_discard_ignored_files")
- fi
- if [[ -n "$_config_file" ]]; then
_uniq_name=$(cat /proc/sys/kernel/random/uuid)
nmcli connection clone --temporary "$_config_file" "$_uniq_name" &> >(ddebug)
nmcli connection modify --temporary "$_uniq_name" connection.autoconnect false
inst "/run/NetworkManager/system-connections/${_uniq_name}.nmconnection" "${_NM_conf_dir}/${_uniq_name}.nmconnection"
finmcli connection del "$_uniq_name" &> >(ddebug)
- echo "rd.znet=${NETTYPE},${SUBCHANNELS},${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS}" > "${initdir}/etc/cmdline.d/30znet.conf"
}
kdump_get_remote_ip() { @@ -482,7 +494,6 @@ kdump_get_remote_ip() { # $1: destination host kdump_install_net() { local _destaddr _route _netdev
- local _znet_netdev _znet_conpath # each netowrk interface is managed by a NM connection profile declare -A nmconnection_map
@@ -495,15 +506,6 @@ kdump_install_net() { _route=$(kdump_get_ip_route "$_destaddr") _netdev=$(kdump_get_ip_route_field "$_route" "dev")
- _znet_netdev=$(find_online_znet_device)
- if [[ -n $_znet_netdev ]]; then
_znet_conpath=$(get_nmcli_connection_apath_by_ifname "$_znet_netdev")
if ! (kdump_setup_znet "$_znet_netdev" "$_znet_conpath"); then
derror "Failed to set up znet"
exit 1
fi
- fi
- if kdump_is_bridge "$_netdev"; then kdump_setup_bridge "$_netdev" elif kdump_is_bond "$_netdev"; then
@@ -516,6 +518,8 @@ kdump_install_net() {
kdump_copy_nmconnection_file "$_netdev"
- [[ -n "$(find_online_znet_device)" ]] && kdump_setup_znet
- if [[ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]]; then # network-manager module needs this parameter echo "rd.neednet" >> "${initdir}/etc/cmdline.d/50neednet.conf"
On Mon, Aug 01, 2022 at 04:56:19PM +0200, Philipp Rudo wrote:
Hi Coiby,
On Tue, 21 Jun 2022 14:57:28 +0800 Coiby Xu coxu@redhat.com wrote:
/usr/lib/udev/ccw_init [1] shipped by s390utils extracts the values of SUBCHANNELS, NETTYPE and LAYER2 from /etc/sysconfig/network-scripts/ifcfg-* or /etc/NetworkManager/system-connections/*.nmconnection to activate znet network device. If the connection profile is copied to initrd, there is no need to set up the "rd.znet" dracut cmdline parameter.
There are two cases addressed by this commit,
- znet network interface is a slave of bonding/teaming/vlan/bridging network. The connection profile has been copied to initrd by kdump_copy_nmconnection_file and it contains the info needed by ccw_init.
- znet network interface is a slave of bonding/teaming/vlan/bridging network. The corresponding ifcfg-*/*.nmconnection file may not contain info like SUBCHANNELS [2]. In this case, copy the ifcfg-*/*.nmconnection file that has this info to the kdump initrd. Also to prevent the copied connection profile from being chosen by NM, set connection.autoconnect=false for this connection profile.
Note
- ccw_init doesn't care if SUBCHANNELS, NETTYPE and LAYER2 comes from an active NM profile or not. If an inactive NM profile contains this info, it needs to be copied to the kdump initrd as well.
- "rd.znet_ifname=$_netdev:${SUBCHANNELS}" is no needed because now there is no renaming of s390x network interfaces when reusing NetworkManager profiles. rd.znet_ifname was introduced in commit ce0305d ("Add a new option 'rd.znet_ifname' in order to use it in udev rules") to address the special case of non-persistent MAC address by renaming a network interface by SUBCHANNELS.
[1] https://src.fedoraproject.org/rpms/s390utils/blob/rawhide/f/ccw_init [2] https://bugzilla.redhat.com/show_bug.cgi?id=2064708
Signed-off-by: Coiby Xu coxu@redhat.com
dracut-module-setup.sh | 70 ++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 33 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 1a8f55f..12b658a 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -434,34 +434,46 @@ find_online_znet_device() { echo -n "$ifname" }
-# setup s390 znet cmdline -# $1: netdev (ifname) -# $2: nmcli connection path +_find_znet_nmconnection() {
- LANG=C grep -s -E -i -l \
"^s390-subchannels=([0-9]\.[0-9]\.[a-f0-9]+;){0,2}" \
"$1"/*.nmconnection | LC_ALL=C sed -e "$2"
+}
+# setup s390 znet +# +# Note part of code is extracted from ccw_init provided by s390utils kdump_setup_znet() {
- local _netdev="$1"
- local _conpath="$2"
- local s390_prefix="802-3-ethernet.s390-"
- local _options=""
- local NETTYPE
- local SUBCHANNELS
- NETTYPE=$(get_nmcli_field_by_conpath "${s390_prefix}nettype" "$_conpath")
- SUBCHANNELS=$(get_nmcli_field_by_conpath "${s390_prefix}subchannels" "$_conpath")
- _options=$(get_nmcli_field_by_conpath "${s390_prefix}options" "$_conpath")
- if [[ -z $NETTYPE || -z $SUBCHANNELS || -z $_options ]]; then
dwarning "Failed to get znet configuration via nmlci output. Now try sourcing ifcfg script."
source_ifcfg_file "$_netdev"
for i in $OPTIONS; do
_options=${_options},$i
done
- local _config_file _uniq_name _NM_conf_dir
s/uniq_name/unique_name/
Fixed in v2, thanks!