Previously, we assumed the ifcfg of a network "interface" is "/etc/sysconfig/network-scripts/ifcfg-<interface>", but actually it is not the case.
For example, for network interface "enp0s25", we are able to generate like "/etc/sysconfig/network-scripts/ifcfg-enp0s25-test" for it via network-manger.
The "suffix" in "ifcfg-<suffix>" is actually a "configuration" name not a "interface" name, though normally we use "interface" name as its "configuration" name. You can refer to "man ifup" for the detail.
So, this patch adds some assistant functions to acquire the right ifcfg file for an interface. Get some help from the following script: "/etc/sysconfig/network-scripts/network-functions"
Signed-off-by: Xunlei Pang xlpang@redhat.com --- kdump-lib.sh | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+)
diff --git a/kdump-lib.sh b/kdump-lib.sh index 4d34206..5277966 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -230,3 +230,96 @@ is_hostname() fi echo $1 | grep -q "[a-zA-Z]" } + +get_hwaddr() +{ + if [ -f /sys/class/net/${1}/address ]; then + awk '{ print toupper($0) }' < /sys/class/net/${1}/address + elif [ -d "/sys/class/net/${1}" ]; then + ip -o link show ${1} 2>/dev/null | \ + awk '{ print toupper(gensub(/.*link/[^ ]* ([[:alnum:]:]*).*/, + "\1", 1)); }' + fi +} + +get_config_by_device() +{ + grep -E -i -l "^[[:space:]]*DEVICE=${1}" \ + /etc/sysconfig/network-scripts/ifcfg-* | head -1 +} + +get_config_by_hwaddr() +{ + grep -E -i -l "^[[:space:]]*HWADDR=${1}" \ + /etc/sysconfig/network-scripts/ifcfg-* | head -1 +} + +get_config_by_name() +{ + grep -E -i -l "^[[:space:]]*NAME=${1}" \ + /etc/sysconfig/network-scripts/ifcfg-* | head -1 +} + +is_nm_running () +{ + [ "$(LANG=C nmcli -t --fields running general status 2>/dev/null)" = "running" ] +} + +# $1: netdev name +get_ifcfg_nmcli() +{ + local nm_name + local ifcfg_file + + # Get the active nmcli config name of $1 + if [[ -x /usr/bin/nmcli && is_nm_running ]]; then + # The configuration name generated by nm is wrote to the ifcfg file + # as "NAME=<nm_name>", if <nm_name> contains whitespaces, a pair of + # quote will also be added(i.e. NAME="My Test"). + nm_name=$(nmcli d show $1 2>/dev/null |grep GENERAL.CONNECTION \ + |sed -e 's/GENERAL.CONNECTION: *//') + if [[ ${nm_name} && ${nm_name} != "--" ]]; then + # Add quota for nm name that contains any whitespace + $(echo $"${nm_name}" | grep -q " ") && nm_name=""${nm_name}"" + ifcfg_file=$(get_config_by_name ${nm_name}) + fi + fi + + echo -n ${ifcfg_file} +} + +# $1: netdev name +get_ifcfg_legacy() +{ + local ifcfg_file + + ifcfg_file="/etc/sysconfig/network-scripts/ifcfg-${1}" + [ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return + + ifcfg_file=$(get_config_by_name "${1}") + [ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return + + local hwaddr=$(get_hwaddr ${1}) + if [ -n "$hwaddr" ]; then + ifcfg_file=$(get_config_by_hwaddr ${hwaddr}) + [ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return + fi + + ifcfg_file=$(get_config_by_device ${1}) + + echo -n "${ifcfg_file}" +} + +# $1: netdev name +# Return the ifcfg file whole name(including the path) of $1 if any. +get_ifcfg_filename() { + local ifcfg_file + + ifcfg_file=$(get_ifcfg_nmcli $1) + if [ -z ${ifcfg_file} ]; then + ifcfg_file=$(get_ifcfg_legacy $1) + fi + + echo -n "${ifcfg_file}" +} +
Currently kdump uses dracut's "nameserver=" command to hande DNS, it is acquired both from ifcfg files and "/etc/resolv.conf".
This is improper for dhcp cases, as "/etc/resolv.conf" is generated by dhcp, the proper logic should be: 1) For static cases, DNS can be acquired from the ifcfg file. 2) For dhcp cases, DNS is normally generated by dhcp, but extra DNS can still be specified in the ifcfg files mannually. 3) For special user-assigned DNS not specified in any ifcfg file, we can pass it to dracut via "nameserver=".
This patch improves the logic using the following "ip=" command format provided by dracut: ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>: <interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<dns1>][:<dns2>]]
Signed-off-by: Xunlei Pang xlpang@redhat.com --- dracut-module-setup.sh | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 4cd7107..c784f93 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -63,26 +63,23 @@ kdump_is_vlan() { }
# $1: netdev name -kdump_setup_dns() { - local _nameserver _dns - local _dnsfile=${initdir}/etc/cmdline.d/42dns.conf - . /etc/sysconfig/network-scripts/ifcfg-$1 +# return pattern ":<dns1>[<:dns2>]" if not "" +kdump_get_dns_from_ifcfg() { + local ifcfg_file + local _dns
- [ -n "$DNS1" ] && echo "nameserver=$DNS1" > "$_dnsfile" - [ -n "$DNS2" ] && echo "nameserver=$DNS2" >> "$_dnsfile" + ifcfg_file=$(get_ifcfg_filename $1)
- while read content; - do - _nameserver=$(echo $content | grep ^nameserver) - [ -z "$_nameserver" ] && continue + unset DNS1 DNS2 + if [ -f ${ifcfg_file} ]; then + . ${ifcfg_file} + fi
- _dns=$(echo $_nameserver | cut -d' ' -f2) - [ -z "$_dns" ] && continue + # Maximum two dns we need + [ -n "$DNS1" ] && _dns=${_dns}:$(echo $DNS1) + [ -n "$DNS2" ] && _dns=${_dns}:$(echo $DNS2)
- if [ ! -f $_dnsfile ] || [ ! $(cat $_dnsfile | grep -q $_dns) ]; then - echo "nameserver=$_dns" >> "$_dnsfile" - fi - done < "/etc/resolv.conf" + echo -n "${_dns}" | cut -d':' -f1,2,3 }
#$1: netdev name @@ -254,22 +251,27 @@ kdump_setup_znet() { # Setup dracut to bringup a given network interface kdump_setup_netdev() { local _netdev=$1 _srcaddr=$2 - local _static _proto _ip_conf _ip_opts _ifname_opts + local _static _proto _ip_conf _ip_opts _ifname_opts _ifcfg_dns + local _global_dnsfile=${initdir}/etc/cmdline.d/42dns.conf
if [ "$(uname -m)" = "s390x" ]; then kdump_setup_znet $_netdev fi
- _netmac=$(kdump_get_mac_addr $_netdev) + # Using below "ip=" command format provided by dracut: + # ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>: + # <interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<dns1>][:<dns2>]] _static=$(kdump_static_ip $_netdev $_srcaddr) if [ -n "$_static" ]; then _proto=none else _proto=dhcp + _static=":::::" fi
+ _ifcfg_dns=$(kdump_get_dns_from_ifcfg $_netdev) _ip_conf="${initdir}/etc/cmdline.d/40ip.conf" - _ip_opts=" ip=${_static}$(kdump_setup_ifname $_netdev):${_proto}" + _ip_opts=" ip=${_static}$(kdump_setup_ifname $_netdev):${_proto}${_ifcfg_dns}"
# dracut doesn't allow duplicated configuration for same NIC, even they're exactly the same. # so we have to avoid adding duplicates @@ -278,6 +280,14 @@ kdump_setup_netdev() { if [ ! -f $_ip_conf ] || ! grep -q $_ip_opts $_ip_conf &&\ ! grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then echo "$_ip_opts" >> $_ip_conf + elif grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then + # In case of no DNS specified by iscsi. + if [ -n "${_ifcfg_dns}" ]; then + _ifcfg_dns=${_ifcfg_dns##:} + echo "nameserver=${_ifcfg_dns%%:*}" >> ${_global_dnsfile} + [ "${_ifcfg_dns}" = "${_ifcfg_dns%%:*}" ] || \ + echo "nameserver=${_ifcfg_dns##*:}" >> ${_global_dnsfile} + fi fi
if kdump_is_bridge "$_netdev"; then @@ -292,8 +302,6 @@ kdump_setup_netdev() { _ifname_opts=" ifname=$(kdump_setup_ifname $_netdev):$(kdump_get_mac_addr $_netdev)" echo "$_ifname_opts" >> $_ip_conf fi - - kdump_setup_dns "$_netdev" }
get_ip_route_field()
On 2016/04/08 at 14:57, Xunlei Pang wrote:
Currently kdump uses dracut's "nameserver=" command to hande DNS, it is acquired both from ifcfg files and "/etc/resolv.conf".
This is improper for dhcp cases, as "/etc/resolv.conf" is generated by dhcp, the proper logic should be:
- For static cases, DNS can be acquired from the ifcfg file.
- For dhcp cases, DNS is normally generated by dhcp, but extra DNS can still be specified in the ifcfg files mannually.
- For special user-assigned DNS not specified in any ifcfg file, we can pass it to dracut via "nameserver=".
This patch improves the logic using the following "ip=" command format provided by dracut: ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>: <interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<dns1>][:<dns2>]]
Signed-off-by: Xunlei Pang xlpang@redhat.com
dracut-module-setup.sh | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 4cd7107..c784f93 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -63,26 +63,23 @@ kdump_is_vlan() { }
# $1: netdev name -kdump_setup_dns() {
- local _nameserver _dns
- local _dnsfile=${initdir}/etc/cmdline.d/42dns.conf
- . /etc/sysconfig/network-scripts/ifcfg-$1
+# return pattern ":<dns1>[<:dns2>]" if not "" +kdump_get_dns_from_ifcfg() {
- local ifcfg_file
- local _dns
- [ -n "$DNS1" ] && echo "nameserver=$DNS1" > "$_dnsfile"
- [ -n "$DNS2" ] && echo "nameserver=$DNS2" >> "$_dnsfile"
- ifcfg_file=$(get_ifcfg_filename $1)
- while read content;
- do
_nameserver=$(echo $content | grep ^nameserver)
[ -z "$_nameserver" ] && continue
- unset DNS1 DNS2
- if [ -f ${ifcfg_file} ]; then
. ${ifcfg_file}
- fi
_dns=$(echo $_nameserver | cut -d' ' -f2)
[ -z "$_dns" ] && continue
- # Maximum two dns we need
- [ -n "$DNS1" ] && _dns=${_dns}:$(echo $DNS1)
- [ -n "$DNS2" ] && _dns=${_dns}:$(echo $DNS2)
if [ ! -f $_dnsfile ] || [ ! $(cat $_dnsfile | grep -q $_dns) ]; then
echo "nameserver=$_dns" >> "$_dnsfile"
fi
- done < "/etc/resolv.conf"
- echo -n "${_dns}" | cut -d':' -f1,2,3
}
#$1: netdev name @@ -254,22 +251,27 @@ kdump_setup_znet() { # Setup dracut to bringup a given network interface kdump_setup_netdev() { local _netdev=$1 _srcaddr=$2
- local _static _proto _ip_conf _ip_opts _ifname_opts
local _static _proto _ip_conf _ip_opts _ifname_opts _ifcfg_dns
local _global_dnsfile=${initdir}/etc/cmdline.d/42dns.conf
if [ "$(uname -m)" = "s390x" ]; then kdump_setup_znet $_netdev fi
- _netmac=$(kdump_get_mac_addr $_netdev)
# Using below "ip=" command format provided by dracut:
# ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:
# <interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<dns1>][:<dns2>]] _static=$(kdump_static_ip $_netdev $_srcaddr) if [ -n "$_static" ]; then _proto=none else _proto=dhcp
_static=":::::"
fi
_ifcfg_dns=$(kdump_get_dns_from_ifcfg $_netdev) _ip_conf="${initdir}/etc/cmdline.d/40ip.conf"
- _ip_opts=" ip=${_static}$(kdump_setup_ifname $_netdev):${_proto}"
_ip_opts=" ip=${_static}$(kdump_setup_ifname $_netdev):${_proto}${_ifcfg_dns}"
# dracut doesn't allow duplicated configuration for same NIC, even they're exactly the same. # so we have to avoid adding duplicates
@@ -278,6 +280,14 @@ kdump_setup_netdev() { if [ ! -f $_ip_conf ] || ! grep -q $_ip_opts $_ip_conf &&\ ! grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then echo "$_ip_opts" >> $_ip_conf
- elif grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then
# In case of no DNS specified by iscsi.
if [ -n "${_ifcfg_dns}" ]; then
_ifcfg_dns=${_ifcfg_dns##:}
echo "nameserver=${_ifcfg_dns%%:*}" >> ${_global_dnsfile}
[ "${_ifcfg_dns}" = "${_ifcfg_dns%%:*}" ] || \
echo "nameserver=${_ifcfg_dns##*:}" >> ${_global_dnsfile}
fifi
Thinking more, this patch is problematic, I should consider more about bridge/bond/team/vlan cases(getting its memember's DNS).
Regards, Xunlei
if kdump_is_bridge "$_netdev"; then
@@ -292,8 +302,6 @@ kdump_setup_netdev() { _ifname_opts=" ifname=$(kdump_setup_ifname $_netdev):$(kdump_get_mac_addr $_netdev)" echo "$_ifname_opts" >> $_ip_conf fi
- kdump_setup_dns "$_netdev"
}
get_ip_route_field()