[PATCH v3 1/2] Implement IP netmask calculation to replace "ipcalc -m"
by Coiby Xu
Recently, dracut-network drops depedency on dhcp-client which requires
ipcalc. Thus the dependency chain
"kexec-tools -> dracut-network -> dhcp-client -> ipcalc"
is broken. When NIC is configured to a static IP, kexec-tools depended
on "ipcalc -m" to get netmask. This commit implements the shell
equivalent of "ipcalc -m".
The following test code shows cal_netmask_by_prefix is consistent with
"ipcalc -m",
#!/bin/bash
. dracut-module-setup.sh
for i in {0..128}; do
mask_expected=$(ipcalc -m fe::/$i| cut -d"=" -f2)
mask_actual=$(cal_netmask_by_prefix $i "-6")
if [[ "$mask_expected" != "$mask_actual" ]]; then
echo "prefix="$i, "expected="$mask_expected, "acutal="$mask_actual
exit
fi
done
echo "IPv6 tests passed"
for i in {0..32}; do
mask_expected=$(ipcalc -m 8.8.8.8/$i| cut -d"=" -f2)
mask_actual=$(cal_netmask_by_prefix $i "")
if [[ "$mask_expected" != "$mask_actual" ]]; then
echo "prefix="$i, "expected="$mask_expected, "acutal="$mask_actual
exit
fi
done
echo "IPv4 tests passed"
i=-2
res=$(cal_netmask_by_prefix "$i" "")
if [[ $? -ne 1 ]]; then
echo "cal_netmask_by_prefix should exit when prefix<0"
exit
fi
res=$(cal_netmask_by_prefix "$i" "")
if [[ $? -ne 1 ]]; then
echo "cal_netmask_by_prefix should exit when prefix<0"
exit
fi
i=33
$(cal_netmask_by_prefix $i "")
if [[ $? -ne 1 ]]; then
echo "cal_netmask_by_prefix should exit when prefix>32 for IPv4"
exit
fi
i=129
$(cal_netmask_by_prefix $i "-6")
if [[ $? -ne 1 ]]; then
echo "cal_netmask_by_prefix should exit when prefix>128 for IPv4"
exit
fi
echo "Bad prefixes tests passed"
echo "All tests passed"
Reported-by: Jie Li <jieli(a)redhat.com>
Signed-off-by: Coiby Xu <coxu(a)redhat.com>
---
v3 -> v2:
1. Don't introduce "boolean" _ipv6 in kdump_static_ip and don't
use fake boolean true/false which is not reliable [Kairui]
2. use ((1)) and((0)) to tell if it's IPv6 or not instead
3. Add tests for bad prefixes
v1 -> v2:
1. Check subshell exit code when calling cal_netmask_by_prefix
2. Stop using die when bad prefix is passed to cal_netmask_by_prefix
3. Remove trailing spaces
---
dracut-module-setup.sh | 119 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 117 insertions(+), 2 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 8316589..aeb2e45 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -121,12 +121,122 @@ kdump_setup_dns() {
done < "/etc/resolv.conf"
}
+# $1: repeat times
+# $2: string to be repeated
+# $3: separator
+repeatedly_join_str() {
+ local _count="$1"
+ local _str="$2"
+ local _separator="$3"
+ local i _res
+
+ if [[ "$_count" -le 0 ]]; then
+ echo -n ""
+ return
+ fi
+
+ i=0
+ _res="$_str"
+ ((_count--))
+
+ while [[ "$i" -lt "$_count" ]]; do
+ ((i++))
+ _res="${_res}${_separator}${_str}"
+ done
+ echo -n "$_res"
+}
+
+# $1: prefix
+# $2: ipv6_flag="-6" indicates it's IPv6
+# Given a prefix, calculate the netmask (equivalent of "ipcalc -m")
+# by concatenating three parts,
+# 1) the groups with all bits set 1
+# 2) a group with partial bits set to 0
+# 3) the groups with all bits set to 0
+cal_netmask_by_prefix() {
+ local _prefix="$1"
+ local _ipv6_flag="$2" _ipv6
+ local _bits_per_octet=8
+ local _count _res _octets_per_group _octets_total _seperator _total_groups
+ local _max_group_value _max_group_value_repr _bits_per_group _tmp _zero_bits
+
+ if [[ "$_ipv6_flag" == "-6" ]]; then
+ _ipv6=1
+ else
+ _ipv6=0
+ fi
+
+ if [[ "$_prefix" -lt 0 || "$_prefix" -gt 128 ]] || \
+ (((!_ipv6)) && [[ "$_prefix" -gt 32 ]]); then
+ derror "Bad prefix:$_prefix for calculating netmask"
+ exit 1
+ fi
+
+ if ((_ipv6)); then
+ _octets_per_group=2
+ _octets_total=16
+ _seperator=":"
+ else
+ _octets_per_group=1
+ _octets_total=4
+ _seperator="."
+ fi
+
+ _total_groups=$((_octets_total/_octets_per_group))
+ _bits_per_group=$((_octets_per_group * _bits_per_octet))
+ _max_group_value=$(((1 << _bits_per_group) - 1))
+
+ if ((_ipv6)); then
+ _max_group_value_repr=$(printf "%x" $_max_group_value)
+ else
+ _max_group_value_repr="$_max_group_value"
+ fi
+
+ _count=$((_prefix/_octets_per_group/_bits_per_octet))
+ _first_part=$(repeatedly_join_str "$_count" "$_max_group_value_repr" "$_seperator")
+ _res="$_first_part"
+
+ _tmp=$((_octets_total*_bits_per_octet-_prefix))
+ _zero_bits=$(expr $_tmp % $_bits_per_group)
+ if [[ "$_zero_bits" -ne 0 ]]; then
+ _second_part=$((_max_group_value >> _zero_bits << _zero_bits))
+ if ((_ipv6)); then
+ _second_part=$(printf "%x" $_second_part)
+ fi
+ ((_count++))
+ if [[ -z "$_first_part" ]]; then
+ _res="$_second_part"
+ else
+ _res="${_first_part}${_seperator}${_second_part}"
+ fi
+ fi
+
+ _count=$((_total_groups-_count))
+ if [[ "$_count" -eq 0 ]]; then
+ echo -n "$_res"
+ return
+ fi
+
+ if ((_ipv6)) && [[ "$_count" -gt 1 ]] ; then
+ # use condensed notion for IPv6
+ _third_part=":"
+ else
+ _third_part=$(repeatedly_join_str "$_count" "0" "$_seperator")
+ fi
+
+ if [[ -z "$_res" ]] && ((!_ipv6)) ; then
+ echo -n "${_third_part}"
+ else
+ echo -n "${_res}${_seperator}${_third_part}"
+ fi
+}
+
#$1: netdev name
#$2: srcaddr
#if it use static ip echo it, or echo null
kdump_static_ip() {
local _netdev="$1" _srcaddr="$2" _ipv6_flag
- local _netmask _gateway _ipaddr _target _nexthop
+ local _netmask _gateway _ipaddr _target _nexthop _prefix
_ipaddr=$(ip addr show dev $_netdev permanent | awk "/ $_srcaddr\/.* /{print \$2}")
@@ -144,7 +254,12 @@ kdump_static_ip() {
_srcaddr="[$_srcaddr]"
_gateway="[$_gateway]"
else
- _netmask=$(ipcalc -m $_ipaddr | cut -d'=' -f2)
+ _prefix=$(cut -d'/' -f2 <<< "$_ipaddr")
+ _netmask=$(cal_netmask_by_prefix "$_prefix" "$_ipv6_flag")
+ if [[ "$?" -ne 0 ]]; then
+ derror "Failed to calculate netmask for $_ipaddr"
+ exit 1
+ fi
fi
echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
fi
--
2.31.0
3 years
[PATCH] Remove dracut-squash dependency
by Tao Liu
dracut-squash is not a must-have component for kexec, nor essential for
minimal host installations as BaseOS or CoreOS. Link [1][2] has already
changed dracut-squash dependency from "Requires" to "Recommends". As quoting
the RHEL 9 Content Structure and Guidelines: "Weak dependencies are allowed,
but discouraged." Let's drop the dependency.
[1]: https://github.com/coreos/fedora-coreos-config/pull/708
[2]: https://src.fedoraproject.org/rpms/kexec-tools/pull-request/4#
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
kexec-tools.spec | 1 -
1 file changed, 1 deletion(-)
diff --git a/kexec-tools.spec b/kexec-tools.spec
index 91bc0f3..dafb672 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -61,7 +61,6 @@ Requires(postun): systemd-units
Requires(pre): coreutils sed zlib
Requires: dracut >= 050
Requires: dracut-network >= 050
-Recommends: dracut-squash >= 050
Requires: ethtool
BuildRequires: make
BuildRequires: zlib-devel elfutils-devel glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel
--
2.29.2
3 years
[PATCH v2] Write to `/var/lib/kdump` if $KDUMP_BOOTDIR not writable
by Kelvin Fan
The /boot directory on some operating systems might be read-only.
If we cannot write to $KDUMP_BOOTDIR when generating the kdump
initrd, attempt to place the generated initrd at `/var/lib/kdump`
instead.
Signed-off by: Kelvin Fan <kfan(a)redhat.com>
---
60-kdump.install | 14 ++++++++++----
kdump-lib.sh | 24 +++++++++++++++++-------
kdumpctl | 4 ++--
kexec-tools.spec | 2 ++
4 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/60-kdump.install b/60-kdump.install
index 0a3b40e..7221e56 100755
--- a/60-kdump.install
+++ b/60-kdump.install
@@ -2,17 +2,23 @@
COMMAND="$1"
KERNEL_VERSION="$2"
-BOOT_DIR_ABS="$3"
+KDUMP_INITRD_DIR_ABS="$3"
KERNEL_IMAGE="$4"
if ! [[ ${KERNEL_INSTALL_MACHINE_ID-x} ]]; then
exit 0
fi
-if [[ -d "$BOOT_DIR_ABS" ]]; then
+if [[ -d "$KDUMP_INITRD_DIR_ABS" ]]; then
KDUMP_INITRD="initrdkdump"
else
- BOOT_DIR_ABS="/boot"
+ # If `KDUMP_BOOTDIR` is not writable, then the kdump
+ # initrd must have been placed at `/var/lib/kdump`
+ if [[ ! -w "$KDUMP_BOOTDIR" ]]; then
+ KDUMP_INITRD_DIR_ABS="/var/lib/kdump"
+ else
+ KDUMP_INITRD_DIR_ABS="/boot"
+ fi
KDUMP_INITRD="initramfs-${KERNEL_VERSION}kdump.img"
fi
@@ -23,7 +29,7 @@ case "$COMMAND" in
# and managed by kdump service
;;
remove)
- rm -f -- "$BOOT_DIR_ABS/$KDUMP_INITRD"
+ rm -f -- "$KDUMP_INITRD_DIR_ABS/$KDUMP_INITRD"
ret=$?
;;
esac
diff --git a/kdump-lib.sh b/kdump-lib.sh
index 21271cf..5f53a8a 100755
--- a/kdump-lib.sh
+++ b/kdump-lib.sh
@@ -733,20 +733,30 @@ prepare_kdump_bootinfo()
boot_initrdlist="initramfs-$KDUMP_KERNELVER.img initrd"
for initrd in $boot_initrdlist; do
if [ -f "$KDUMP_BOOTDIR/$initrd" ]; then
- DEFAULT_INITRD="$KDUMP_BOOTDIR/$initrd"
+ defaut_initrd_base="$initrd"
+ DEFAULT_INITRD="$KDUMP_BOOTDIR/$defaut_initrd_base"
break
fi
done
- # Get kdump initrd from default initrd filename
+ # Create kdump initrd basename from default initrd basename
# initramfs-5.7.9-200.fc32.x86_64.img => initramfs-5.7.9-200.fc32.x86_64kdump.img
# initrd => initrdkdump
- if [[ -z "$DEFAULT_INITRD" ]]; then
- KDUMP_INITRD=${KDUMP_BOOTDIR}/initramfs-${KDUMP_KERNELVER}kdump.img
- elif [[ $(basename $DEFAULT_INITRD) == *.* ]]; then
- KDUMP_INITRD=${DEFAULT_INITRD%.*}kdump.${DEFAULT_INITRD##*.}
+ if [[ -z "$defaut_initrd_base" ]]; then
+ kdump_initrd_base=initramfs-${KDUMP_KERNELVER}kdump.img
+ elif [[ $defaut_initrd_base == *.* ]]; then
+ kdump_initrd_base=${defaut_initrd_base%.*}kdump.${DEFAULT_INITRD##*.}
else
- KDUMP_INITRD=${DEFAULT_INITRD}kdump
+ kdump_initrd_base=${defaut_initrd_base}kdump
+ fi
+
+ # Place kdump initrd in `/var/lib/kdump` if `KDUMP_BOOTDIR` not writable
+ if [[ ! -w "$KDUMP_BOOTDIR" ]];then
+ var_target_initrd_dir="/var/lib/kdump"
+ mkdir -p "$var_target_initrd_dir"
+ KDUMP_INITRD="$var_target_initrd_dir/$kdump_initrd_base"
+ else
+ KDUMP_INITRD="$KDUMP_BOOTDIR/$kdump_initrd_base"
fi
}
diff --git a/kdumpctl b/kdumpctl
index c3311ad..b0846fa 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -151,8 +151,8 @@ rebuild_kdump_initrd()
rebuild_initrd()
{
- if [[ ! -w "$KDUMP_BOOTDIR" ]];then
- derror "$KDUMP_BOOTDIR does not have write permission. Can not rebuild $TARGET_INITRD"
+ if [[ ! -w $(dirname $TARGET_INITRD) ]];then
+ derror "$(dirname $TARGET_INITRD) does not have write permission. Cannot rebuild $TARGET_INITRD"
return 1
fi
diff --git a/kexec-tools.spec b/kexec-tools.spec
index 24c6b36..74b7877 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -170,6 +170,7 @@ mkdir -p $RPM_BUILD_ROOT%{_unitdir}
mkdir -p -m755 $RPM_BUILD_ROOT%{_bindir}
mkdir -p -m755 $RPM_BUILD_ROOT%{_libdir}
mkdir -p -m755 $RPM_BUILD_ROOT%{_prefix}/lib/kdump
+mkdir -p -m755 $RPM_BUILD_ROOT%{_sharedstatedir}/kdump
install -m 755 %{SOURCE1} $RPM_BUILD_ROOT%{_bindir}/kdumpctl
install -m 755 build/sbin/kexec $RPM_BUILD_ROOT/usr/sbin/kexec
@@ -335,6 +336,7 @@ done
%dir %{_sysconfdir}/kdump
%dir %{_sysconfdir}/kdump/pre.d
%dir %{_sysconfdir}/kdump/post.d
+%dir %{_sharedstatedir}/kdump
%{_mandir}/man8/kdumpctl.8.gz
%{_mandir}/man8/kexec.8.gz
%ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64
--
2.29.2
3 years
[PATCH 0/8] Better support for LUKS targets
by Kairui Song
This series make kdump support LUKS targets with a lower memory usage
and allow second kernel to decrypt the target automatically without
password or keyfile.
Current the problem with LUKS is master key decryption from key slot
consume massive memory and require keyfile or password prompt, make it
not very usable for kdump. This series improve it by passing master key
directly.
When there is a LUKS crypt target, and key is stored in dm-crypt,
kdump will try to retrive the key automatically. If it success, second
kernel will just work without any manual input.
Output of kdumpctl restart in such case:
# kdumpctl restart
kdump: kexec: unloaded kdump kernel
kdump: Stopping kdump: [OK]
kdump: kexec: loaded kdump kernel
kdump: Starting kdump: [OK]
<second kernel works with normal crashkernel and no password prompt>
If LUKS key is stored in kernel keyring, then kdump can't retrive
the key. kdump will still work but kdumpctl will print a warning
message, warn the user second kernel have some extra requirement:
Output of kdumpctl restart in such case:
# kdumpctl restart
kdump: kexec: unloaded kdump kernel
kdump: Stopping kdump: [OK]
kdump: Can't get key of LUKS device /dev/vda3
kdump: Can't retrive LUKS key, crashkernel value should be large enough for LUKS key decryption, and kdump kernel will prompt for password.
kdump: kexec: loaded kdump kernel
kdump: Starting kdump: [OK]
<second kernel need a large crashkernel and need password prompt>
If LUKS key is stored in kernel keyring, and a --askpass param is passed
to kdumpctl, kdumpctl will prompt for password for the LUKS device.
This way it can also get the LUKS key and pass it to second kernel,
bypass key decryption in second kernel, and avoids the extra memory
requirement and password promption.
Output of kdumpctl restart in such case:
# kdumpctl restart --askpass
kdump: kexec: unloaded kdump kernel
kdump: Stopping kdump: [OK]
Enter passphrase for /dev/vda3: <user input password here>
kdump: kexec: loaded kdump kernel
kdump: Starting kdump: [OK]
<second kernel works with normal crashkernel and no password prompt>
There is no need to rebuild initramfs for key location or LUKS config
change, just need a kdumpctl restart or reload.
And this only works for kdump, not for fadump as fadump reuse the
initramfs and we can't append the key to the default initramfs which is
too dangerous.
Useful commands for testing the patch:
To check LUKS key status:
# cryptsetup status luks-a0d62a54-6b2f-4667-ae33-65751343e212
Output of a LUKS config with key in keyring:
type: LUKS2
cipher: aes-xts-plain64
keysize: 512 bits
key location: keyring
device: /dev/vda3
sector size: 512
offset: 32768 sectors
size: 38580224 sectors
mode: read/write
flags: discards
Output of a LUKS config with key in dm-crypt:
type: LUKS1
cipher: aes-xts-plain64
keysize: 512 bits
key location: dm-crypt
device: /dev/nvme0n1p2
sector size: 512
offset: 4096 sectors
size: 1997780992 sectors
mode: read/write
flags: discards
To change the key location at runtime for LUKS2 (LUKS1 is always stored
in dm-crypt):
Change the key location to keyring:
# cryptsetup refresh luks-a0d62a54-6b2f-4667-ae33-65751343e212
Change the key location to dm-crypt:
# cryptsetup refresh luks-a0d62a54-6b2f-4667-ae33-65751343e212 --disable-keyring
Kairui Song (8):
kdump-lib: add support to get dev name from dev ID
kdump-lib: add a helper to append files into existing initramfs
kdump-lib.sh: introduce a helper to get underlying crypt device
mkdumprd: make use of the new get_luks_crypt_dev helper
Add helper to get LUKS key of a crypted target
Add master key based crypt target support
kdumpctl: accept a --askpass param for loading kdump resource
mkdumprd: remove LUKS target warning for non-fadump case
dracut-module-setup.sh | 13 +++++
kdump-lib.sh | 126 +++++++++++++++++++++++++++++++++++++++++
kdumpctl | 124 +++++++++++++++++++++++++++++++++++-----
kexec-crypt-init.sh | 18 ++++++
kexec-crypt-setup.sh | 18 ++++++
kexec-tools.spec | 4 ++
mkdumprd | 34 +++--------
7 files changed, 296 insertions(+), 41 deletions(-)
create mode 100644 kexec-crypt-init.sh
create mode 100644 kexec-crypt-setup.sh
--
2.30.2
3 years
[PATCH] Don't iterate the whole /sys/devices just to find drm device
by Kairui Song
On some large systems, /sys/devices is huge and it's not a wise idea to
iterate it. `find` may cause tremendous contention on the kernfs_mutex
when there are already stress on /sys, and it will perform very very
poorly.
Simply check if drm class presents should be good enough.
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
dracut-module-setup.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index ac0f196..ce05de7 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -58,7 +58,7 @@ depends() {
_dep="$_dep znet"
fi
- if [ -n "$( find /sys/devices -name drm )" ] || [ -d /sys/module/hyperv_fb ]; then
+ if [ -n "$( ls -A /sys/class/drm 2>/dev/null )" ] || [ -d /sys/module/hyperv_fb ]; then
add_opt_module drm
fi
--
2.29.2
3 years
[PATCH v2 0/3] Use a standalone kdump emergency shell
by Kairui Song
Currently kdump use some wrapper around dracut emergency service and
emergency shell, this have many problems:
- If dracut-initqueue failed back to emergency mode due to timeout,
and faiure action is set to dump_to_rootfs, kdump will try start
initqueue again, lead to double timeout error.
- Dracut's emergency shell have many builtin actions, like
perform dracut emergency_action, ask for root password, generate
rdsosreport etc.
This series remove the emergency wrapper, and use a standalone kdump
emergency shell. Kdump will always perform final_action after kdump
shell, so simplified version works fine.
Update from V1:
Fix initqueue status detection in patch 1/3, thanks to Coiby.
Kairui Song (3):
Don's try to restart dracut-initqueue if it's already there
Remove the kdump error handler isolation wrapper
Use a customized emergency shell
dracut-kdump-emergency.service | 25 +++++++++----------
dracut-kdump-error-handler.service | 33 ------------------------
dracut-module-setup.sh | 1 -
kdump-lib-initramfs.sh | 40 +++++++++++++++++++++++++-----
kexec-tools.spec | 2 --
5 files changed, 46 insertions(+), 55 deletions(-)
delete mode 100644 dracut-kdump-error-handler.service
--
2.30.2
3 years
[PATCH v2 1/2] Implement IP netmask calculation to replace "ipcalc -m"
by Coiby Xu
Recently, dracut-network drops depedency on dhcp-client which requires
ipcalc. Thus the dependency chain
"kexec-tools -> dracut-network -> dhcp-client -> ipcalc"
is broken. When NIC is configured to a static IP, kexec-tools depended
on "ipcalc -m" to get netmask. This commit implements the shell
equivalent of "ipcalc -m".
The following test code shows cal_netmask_by_prefix is consistent with
"ipcalc -m",
#!/bin/bash
. dracut-module-setup.sh
for i in {0..128}; do
mask_expected=$(ipcalc -m fe::/$i| cut -d"=" -f2)
mask_actual=$(cal_netmask_by_prefix $i true)
if [[ "$mask_expected" != "$mask_actual" ]]; then
echo $i, "expected=", $mask_expected, "acutal=", $mask_actual
fi
done
for i in {0..32}; do
mask_expected=$(ipcalc -m 8.8.8.8/$i| cut -d"=" -f2)
mask_actual=$(cal_netmask_by_prefix $i false)
if [[ "$mask_expected" != "$mask_actual" ]]; then
echo $i, "expected=", $mask_expected, "acutal=", $mask_actual
fi
done
Reported-by: Jie Li <jieli(a)redhat.com>
Signed-off-by: Coiby Xu <coxu(a)redhat.com>
---
v1 -> v2:
1. Check subshell exit code when calling cal_netmask_by_prefix
2. Stop using die when bad prefix is passed to cal_netmask_by_prefix
3. Remove trailing spaces
---
dracut-module-setup.sh | 115 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 113 insertions(+), 2 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 8316589..ea6f7ea 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -121,17 +121,123 @@ kdump_setup_dns() {
done < "/etc/resolv.conf"
}
+# $1: repeat times
+# $2: string to be repeated
+# $3: separator
+repeatedly_join_str() {
+ local _count="$1"
+ local _str="$2"
+ local _separator="$3"
+ local i _res
+
+ if [[ "$_count" -le 0 ]]; then
+ echo -n ""
+ return
+ fi
+
+ i=0
+ _res="$_str"
+ ((_count--))
+
+ while [[ "$i" -lt "$_count" ]]; do
+ ((i++))
+ _res="${_res}${_separator}${_str}"
+ done
+ echo -n "$_res"
+}
+
+# $1: prefix
+# $2: ipv6 or not
+# Given a prefix, calculate the netmask (equivalent of "ipcalc -m")
+# by concatenating three parts,
+# 1) the groups with all bits set 1
+# 2) a group with partial bits set to 0
+# 3) the groups with all bits set to 0
+cal_netmask_by_prefix() {
+ local _prefix="$1"
+ local _ipv6="$2"
+ local _bits_per_octet=8
+ local _count _res _octets_per_group _octets_total _seperator _total_groups
+ local _max_group_value _max_group_value_repr _bits_per_group _tmp _zero_bits
+
+ if [[ "$_prefix" -lt 0 || ("$_ipv6" && "$_prefix" -gt 128) || \
+ (!"$_ipv6" && "$_prefix" -gt 32) ]]; then
+ derror "Bad prefix:$_prefix for calculating netmask"
+ exit 1
+ fi
+
+ if "$_ipv6"; then
+ _octets_per_group=2
+ _octets_total=16
+ _seperator=":"
+ else
+ _octets_per_group=1
+ _octets_total=4
+ _seperator="."
+ fi
+
+ _total_groups=$((_octets_total/_octets_per_group))
+ _bits_per_group=$((_octets_per_group * _bits_per_octet))
+ _max_group_value=$(((1 << _bits_per_group) - 1))
+
+ if "$_ipv6"; then
+ _max_group_value_repr=$(printf "%x" $_max_group_value)
+ else
+ _max_group_value_repr="$_max_group_value"
+ fi
+
+ _count=$((_prefix/_octets_per_group/_bits_per_octet))
+ _first_part=$(repeatedly_join_str "$_count" "$_max_group_value_repr" "$_seperator")
+ _res="$_first_part"
+
+ _tmp=$((_octets_total*_bits_per_octet-_prefix))
+ _zero_bits=$(expr $_tmp % $_bits_per_group)
+ if [[ "$_zero_bits" -ne 0 ]]; then
+ _second_part=$((_max_group_value >> _zero_bits << _zero_bits))
+ if "$_ipv6"; then
+ _second_part=$(printf "%x" $_second_part)
+ fi
+ ((_count++))
+ if [[ -z "$_first_part" ]]; then
+ _res="$_second_part"
+ else
+ _res="${_first_part}${_seperator}${_second_part}"
+ fi
+ fi
+
+ _count=$((_total_groups-_count))
+ if [[ "$_count" -eq 0 ]]; then
+ echo -n "$_res"
+ return
+ fi
+
+ if "$_ipv6" && [[ "$_count" -gt 1 ]] ; then
+ # use condensed notion for IPv6
+ _third_part=":"
+ else
+ _third_part=$(repeatedly_join_str "$_count" "0" "$_seperator")
+ fi
+
+ if [[ -z "$_res" ]] && ! "$_ipv6" ; then
+ echo -n "${_third_part}"
+ else
+ echo -n "${_res}${_seperator}${_third_part}"
+ fi
+}
+
#$1: netdev name
#$2: srcaddr
#if it use static ip echo it, or echo null
kdump_static_ip() {
local _netdev="$1" _srcaddr="$2" _ipv6_flag
- local _netmask _gateway _ipaddr _target _nexthop
+ local _netmask _gateway _ipaddr _target _nexthop _prefix
+ local _ipv6=false
_ipaddr=$(ip addr show dev $_netdev permanent | awk "/ $_srcaddr\/.* /{print \$2}")
if is_ipv6_address $_srcaddr; then
_ipv6_flag="-6"
+ _ipv6=true
fi
if [ -n "$_ipaddr" ]; then
@@ -144,7 +250,12 @@ kdump_static_ip() {
_srcaddr="[$_srcaddr]"
_gateway="[$_gateway]"
else
- _netmask=$(ipcalc -m $_ipaddr | cut -d'=' -f2)
+ _prefix=$(cut -d'/' -f2 <<< "$_ipaddr")
+ _netmask=$(cal_netmask_by_prefix "$_prefix" "$_ipv6")
+ if [[ "$?" -ne 0 ]]; then
+ derror "Failed to calculate netmask for $_ipaddr"
+ exit 1
+ fi
fi
echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
fi
--
2.31.0
3 years
Re: [PATCH] kdumpctl: Write to `/var/lib/kdump` if $KDUMP_BOOTDIR not writable
by Kelvin Fan
Hi Kairui,
Thank you for the review! I have addressed all your comments and
submitted a PATCH v2.
Regarding the SELinux bit, where kexec cannot load the kdump initrd if
it's in `/var/lib/kdump`, I've removed the `chcon` line. Do you (or
your team) mind submitting a patch to the Fedora SELinux policy repo
to update the policies regarding this new directory?
This is my first time sending email patches, so I apologize in advance
if I'm not following all the proper conventions.
Thank you!
Kelvin
3 years
[PATCH] kdumpctl: Write to `/var/lib/kdump` if $KDUMP_BOOTDIR not
writable
by Kelvin Fan
The /boot directory on some operating systems might be read-only.
If we cannot write to $KDUMP_BOOTDIR when generating the kdump
initrd, attempt to place the generated initrd at `/var/lib/kdump`
instead.
Signed-off by: Kelvin Fan <kfan(a)redhat.com>
---
kdumpctl | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/kdumpctl b/kdumpctl
index 24f5cf7..2107e3e 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -152,8 +152,15 @@ rebuild_kdump_initrd()
rebuild_initrd()
{
if [[ ! -w "$KDUMP_BOOTDIR" ]];then
- derror "$KDUMP_BOOTDIR does not have write permission. Can not rebuild $TARGET_INITRD"
- return 1
+ VAR_TARGET_INITRD_DIR="/var/lib/kdump"
+ mkdir -p "$VAR_TARGET_INITRD_DIR"
+ TARGET_INITRD_BASE="$(basename $TARGET_INITRD)"
+ TARGET_INITRD="$VAR_TARGET_INITRD_DIR/$TARGET_INITRD_BASE"
+ dwarn "$KDUMP_BOOTDIR does not have write permission. Rebuilding initrd at $TARGET_INITRD"
+ if [[ ! -w "$VAR_TARGET_INITRD_DIR" ]];then
+ derror "$VAR_TARGET_INITRD_DIR does not have write permission. Cannot rebuild $TARGET_INITRD"
+ return 1
+ fi
fi
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
@@ -656,6 +663,9 @@ load_kdump()
KEXEC_ARGS="$KEXEC_ARGS -s"
fi
+ # Relabel the target initrd for SELinux.
+ chcon -t boot_t $TARGET_INITRD
+
ddebug "$KEXEC $KEXEC_ARGS $standard_kexec_args --command-line=$KDUMP_COMMANDLINE --initrd=$TARGET_INITRD $KDUMP_KERNEL"
# The '12' represents an intermediate temporary file descriptor
--
2.29.2
3 years