diff --git a/SOURCES/dracut-module-setup.sh b/SOURCES/dracut-module-setup.sh index 7c28942..eeb348c 100755 --- a/SOURCES/dracut-module-setup.sh +++ b/SOURCES/dracut-module-setup.sh @@ -3,6 +3,10 @@ . $dracutfunctions . /lib/kdump/kdump-lib.sh +if ! [[ -d "${initdir}/tmp" ]]; then + mkdir -p "${initdir}/tmp" +fi + check() { [[ $debug ]] && set -x #kdumpctl sets this explicitly @@ -167,15 +171,15 @@ kdump_setup_team() { echo " team=$_netdev:$(echo $_slaves | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/44team.conf #Buggy version teamdctl outputs to stderr! #Try to use the latest version of teamd. - teamdctl "$_netdev" config dump > /tmp/$$-$_netdev.conf + teamdctl "$_netdev" config dump > ${initdir}/tmp/$$-$_netdev.conf if [ $? -ne 0 ] then derror "teamdctl failed." exit 1 fi inst_dir /etc/teamd - inst_simple /tmp/$$-$_netdev.conf "/etc/teamd/$_netdev.conf" - rm -f /tmp/$$-$_netdev.conf + inst_simple ${initdir}/tmp/$$-$_netdev.conf "/etc/teamd/$_netdev.conf" + rm -f ${initdir}/tmp/$$-$_netdev.conf } kdump_setup_vlan() { @@ -303,17 +307,29 @@ kdump_install_net() { default_dump_target_install_conf() { local _target _fstype - local _s _t - local _mntpoint - local _path _save_path + local _mntpoint _save_path is_user_configured_dump_target && return _save_path=$(get_option_value "path") [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH + # strip the duplicated "/" + _save_path=$(echo $_save_path | tr -s /) + _mntpoint=$(get_mntpoint_from_path $_save_path) _target=$(get_target_from_path $_save_path) + + if is_atomic && is_bind_mount $_mntpoint; then + _save_path=${_save_path##"$_mntpoint"} + # the real dump path in the 2nd kernel, if the mount point is bind mounted. + _save_path=$(get_bind_mount_directory $_mntpoint)/$_save_path + _mntpoint=$(get_mntpoint_from_target $_target) + + # the absolute path in the 1st kernel + _save_path=$_mntpoint/$_save_path + fi + if [ "$_mntpoint" != "/" ]; then _fstype=$(get_fs_type_from_target $_target) @@ -324,20 +340,45 @@ default_dump_target_install_conf() _target=$(kdump_to_udev_name $_target) fi - echo "$_fstype $_target" >> /tmp/$$-kdump.conf + echo "$_fstype $_target" >> ${initdir}/tmp/$$-kdump.conf + + # strip the duplicated "/" + _save_path=$(echo $_save_path | tr -s /) + _save_path=${_save_path##"$_mntpoint"} + fi + + #erase the old path line, then insert the parsed path + sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf + echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf +} + +adjust_bind_mount_path() +{ + local _target=$1 + local _save_path=$(get_option_value "path") + [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH + + # strip the duplicated "/" + _save_path=$(echo $_save_path | tr -s /) - _path=${_save_path##"$_mntpoint"} + local _absolute_save_path=$(get_mntpoint_from_target $_target)/$_save_path + _absolute_save_path=$(echo "$_absolute_save_path" | tr -s /) + local _mntpoint=$(get_mntpoint_from_path $_absolute_save_path) + + if is_bind_mount $_mntpoint; then + _save_path=${_absolute_save_path##"$_mntpoint"} + # the real dump path in the 2nd kernel, if the mount point is bind mounted. + _save_path=$(get_bind_mount_directory $_mntpoint)/$_save_path #erase the old path line, then insert the parsed path - sed -i "/^path/d" /tmp/$$-kdump.conf - echo "path $_path" >> /tmp/$$-kdump.conf + sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf + echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf fi - } #install kdump.conf and what user specifies in kdump.conf kdump_install_conf() { - sed -ne '/^#/!p' /etc/kdump.conf > /tmp/$$-kdump.conf + sed -ne '/^#/!p' /etc/kdump.conf > ${initdir}/tmp/$$-kdump.conf while read config_opt config_val; do @@ -345,7 +386,10 @@ kdump_install_conf() { config_val=$(strip_comments $config_val) case "$config_opt" in ext[234]|xfs|btrfs|minix|raw) - sed -i -e "s#^$config_opt[[:space:]]\+$config_val#$config_opt $(kdump_to_udev_name $config_val)#" /tmp/$$-kdump.conf + sed -i -e "s#^$config_opt[[:space:]]\+$config_val#$config_opt $(kdump_to_udev_name $config_val)#" ${initdir}/tmp/$$-kdump.conf + if is_atomic; then + adjust_bind_mount_path "$config_val" + fi ;; ssh|nfs) kdump_install_net "$config_val" @@ -361,9 +405,9 @@ kdump_install_conf() { default_dump_target_install_conf - kdump_configure_fence_kdump "/tmp/$$-kdump.conf" - inst "/tmp/$$-kdump.conf" "/etc/kdump.conf" - rm -f /tmp/$$-kdump.conf + kdump_configure_fence_kdump "${initdir}/tmp/$$-kdump.conf" + inst "${initdir}/tmp/$$-kdump.conf" "/etc/kdump.conf" + rm -f ${initdir}/tmp/$$-kdump.conf } # Default sysctl parameters should suffice for kdump kernel. diff --git a/SOURCES/kdump-lib.sh b/SOURCES/kdump-lib.sh index a20c6e8..ef8417a 100755 --- a/SOURCES/kdump-lib.sh +++ b/SOURCES/kdump-lib.sh @@ -86,6 +86,38 @@ get_root_fs_device() return } +# findmnt uses the option "-v, --nofsroot" to exclusive the [/dir] +# in the SOURCE column for bind-mounts, then if $_mntpoint equals to +# $_mntpoint_nofsroot, the mountpoint is not bind mounted directory. +is_bind_mount() +{ + local _mntpoint=$(findmnt $1 | tail -n 1 | awk '{print $2}') + local _mntpoint_nofsroot=$(findmnt -v $1 | tail -n 1 | awk '{print $2}') + + if [[ $_mntpoint = $_mntpoint_nofsroot ]]; then + return 1 + else + return 0 + fi +} + +# Below is just an example for mount info +# /dev/mapper/atomicos-root[/ostree/deploy/rhel-atomic-host/var], if the +# directory is bind mounted. The former part represents the device path, rest +# part is the bind mounted directory which quotes by bracket "[]". +get_bind_mount_directory() +{ + local _mntpoint=$(findmnt $1 | tail -n 1 | awk '{print $2}') + local _mntpoint_nofsroot=$(findmnt -v $1 | tail -n 1 | awk '{print $2}') + + _mntpoint=${_mntpoint#*$_mntpoint_nofsroot} + + _mntpoint=${_mntpoint#[} + _mntpoint=${_mntpoint%]} + + echo $_mntpoint +} + get_mntpoint_from_path() { echo $(df $1 | tail -1 | awk '{print $NF}') @@ -101,9 +133,33 @@ get_fs_type_from_target() echo $(findmnt -k -f -n -r -o FSTYPE $1) } +# input: device path +# output: the general mount point +# find the general mount point, not the bind mounted point in atomic +# As general system, Use the previous code +# +# ERROR and EXIT: +# the device can be umounted the general mount point, if one of the mount point is bind mounted +# For example: +# mount /dev/sda /mnt/ +# mount -o bind /mnt/var /var +# umount /mnt get_mntpoint_from_target() { - echo $(findmnt -k -f -n -r -o TARGET $1) + if is_atomic; then + for _mnt in $(findmnt -k -n -r -o TARGET $1) + do + if ! is_bind_mount $_mnt; then + echo $_mnt + return + fi + done + + echo "Mount $1 firstly, without the bind mode" >&2 + exit 1 + else + echo $(findmnt -k -f -n -r -o TARGET $1) + fi } # get_option_value @@ -126,7 +182,10 @@ make_absolute_save_path() local _mnt [ -n $_target ] && _mnt=$(get_mntpoint_from_target $1) - echo "${_mnt}/$SAVE_PATH" + _mnt="${_mnt}/$SAVE_PATH" + + # strip the duplicated "/" + echo "$_mnt" | tr -s / } check_save_path_fs() @@ -138,3 +197,7 @@ check_save_path_fs() fi } +is_atomic() +{ + grep -q "ostree" /proc/cmdline +} diff --git a/SOURCES/kdumpctl b/SOURCES/kdumpctl index b504734..f1b72da 100755 --- a/SOURCES/kdumpctl +++ b/SOURCES/kdumpctl @@ -294,14 +294,12 @@ get_pcs_cluster_modified_files() check_boot_dir() { - local _is_atomic #If user specify a boot dir for kdump kernel, let's use it. Otherwise #check whether it's a atomic host. If yes parse the subdirectory under #/boot; If not just find it under /boot. [ -n "$KDUMP_BOOTDIR" ] && return - _is_atomic=$(cat /proc/cmdline | grep "ostree") - if [ -z "$_is_atomic" ] || [ "$(uname -m)" = "s390x" ]; then + if ! is_atomic || [ "$(uname -m)" = "s390x" ]; then KDUMP_BOOTDIR="/boot" else eval $(cat /proc/cmdline| grep "BOOT_IMAGE" | cut -d' ' -f1) diff --git a/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-Support-more-than-16TB-physical-memory.patch b/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-Support-more-than-16TB-physical-memory.patch new file mode 100644 index 0000000..41b3aed --- /dev/null +++ b/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-Support-more-than-16TB-physical-memory.patch @@ -0,0 +1,127 @@ +From 37afcd52ac5dd276a51af51cbee9531b91911bfa Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Fri, 20 Feb 2015 10:18:41 +0900 +Subject: [PATCH] [PATCH] sadump: Support more than 16TB physical memory space. + +This patch makes sadump format support more than 16TB physical memory +space. + +The limitation is caused by several members of dump_header structure: +max_mapnr and the others. They have 4 byte length only. In particular, +max_mapnr member gets overflow if more than 16TB physical memory space +is given. + +To support more than 16TB physical memory space, this patch adds new 4 +64-bit length members in dump_header structure: + +- max_mapnr_64 +- total_ram_blocks_64 +- device_blocks_64 +- written_blocks_64 + +Next table shows correspondence between the 32-bit version and the +64-bit version members: + + | 32-bit version | 64-bit version | + |------------------------+---------------------------| + | max_mapnr | max_mapnr_64 | + | total_ram_blocks | total_ram_blocks_64 | + | device_blocks | device_blocks_64 | + | written_blocks | written_blocks_64 | + +In addition, header_version member of dump_header structure is +increased to 1 in this extended new format. + +Old makedumpfile can access the new sadump format under 16TB +correctly. + +Current implementation treats vmcore with kernel version 2 or later as +kernel version 1, assuming backward compatibility. + +Signed-off-by: HATAYAMA Daisuke +--- + sadump_info.c | 20 +++++++++++++++++--- + sadump_mod.h | 8 ++++++++ + 2 files changed, 25 insertions(+), 3 deletions(-) + +diff --git a/makedumpfile-1.5.7/sadump_info.c b/makedumpfile-1.5.7/sadump_info.c +index 9434ff7..e2c4f03 100644 +--- a/makedumpfile-1.5.7/sadump_info.c ++++ b/makedumpfile-1.5.7/sadump_info.c +@@ -84,6 +84,7 @@ struct sadump_info { + unsigned long backup_src_size; + unsigned long long backup_offset; + int kdump_backed_up; ++ mdf_pfn_t max_mapnr; + }; + + static char *guid_to_str(efi_guid_t *guid, char *buf, size_t buflen); +@@ -625,6 +626,19 @@ restart: + offset += sh->sub_hdr_size * block_size; + } + ++ switch (sh->header_version) { ++ case 0: ++ si->max_mapnr = (mdf_pfn_t)(uint64_t)sh->max_mapnr; ++ break; ++ default: ++ ERRMSG("sadump: unsupported header version: %u\n" ++ "sadump: assuming header version: 1\n", ++ sh->header_version); ++ case 1: ++ si->max_mapnr = (mdf_pfn_t)sh->max_mapnr_64; ++ break; ++ } ++ + if (!sh->bitmap_blocks) { + DEBUG_MSG("sadump: bitmap_blocks is zero\n"); + return FALSE; +@@ -775,7 +789,7 @@ sadump_initialize_bitmap_memory(void) + memset(bmp->buf, 0, BUFSIZE_BITMAP); + bmp->offset = dumpable_bitmap_offset; + +- max_section = divideup(sh->max_mapnr, SADUMP_PF_SECTION_NUM); ++ max_section = divideup(si->max_mapnr, SADUMP_PF_SECTION_NUM); + + block_table = calloc(sizeof(unsigned long long), max_section); + if (block_table == NULL) { +@@ -906,7 +920,7 @@ sadump_set_timestamp(struct timeval *ts) + mdf_pfn_t + sadump_get_max_mapnr(void) + { +- return si->sh_memory->max_mapnr; ++ return si->max_mapnr; + } + + #ifdef __x86_64__ +@@ -964,7 +978,7 @@ readpage_sadump(unsigned long long paddr, void *bufptr) + + pfn = paddr_to_pfn(paddr); + +- if (pfn >= si->sh_memory->max_mapnr) ++ if (pfn >= si->max_mapnr) + return FALSE; + + if (!is_dumpable(info->bitmap_memory, pfn)) { +diff --git a/makedumpfile-1.5.7/sadump_mod.h b/makedumpfile-1.5.7/sadump_mod.h +index afeead8..0dd5bb5 100644 +--- a/makedumpfile-1.5.7/sadump_mod.h ++++ b/makedumpfile-1.5.7/sadump_mod.h +@@ -106,6 +106,14 @@ struct sadump_header { + uint32_t written_blocks; /* Number of written blocks */ + uint32_t current_cpu; /* CPU# which handles dump */ + uint32_t nr_cpus; /* Number of CPUs */ ++ /* ++ * The members from below are supported in header version 1 ++ * and later. ++ */ ++ uint64_t max_mapnr_64; ++ uint64_t total_ram_blocks_64; ++ uint64_t device_blocks_64; ++ uint64_t written_blocks_64; + }; + + struct sadump_apic_state { +-- +1.8.5.3 + diff --git a/SOURCES/mkdumprd b/SOURCES/mkdumprd index 0480060..8297600 100644 --- a/SOURCES/mkdumprd +++ b/SOURCES/mkdumprd @@ -13,6 +13,9 @@ conf_file="/etc/kdump.conf" SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" SAVE_PATH=$(grep ^path $conf_file| cut -d' ' -f2) [ -z "$SAVE_PATH" ] && SAVE_PATH=$DEFAULT_PATH +# strip the duplicated "/" +SAVE_PATH=$(echo $SAVE_PATH | tr -s /) + extra_modules="" dracut_args=("--hostonly" "--hostonly-cmdline" "-o" "plymouth dash resume") OVERRIDE_RESETTABLE=0 @@ -100,7 +103,7 @@ to_mount() { local _dev=$1 _source _target _fstype _options _mntopts _pdev _source=$(findmnt -k -f -n -r -o SOURCE $_dev) - _target=$(findmnt -k -f -n -r -o TARGET $_dev) + _target=$(get_mntpoint_from_target $_dev) # mount under /sysroot if dump to root disk or mount under #/kdumproot/$_target in other cases in 2nd kernel. systemd #will be in charge to umount it. @@ -144,10 +147,6 @@ to_mount() { echo "$_pdev $_mntopts" } -to_mount_point() { - echo $(findmnt -k -f -n -r -o TARGET $1) -} - is_readonly_mount() { local _mnt _mnt=$(findmnt -k -f -n -r -o OPTIONS $1) @@ -201,7 +200,7 @@ mkdir_save_path_ssh() #Function: get_fs_size #$1=dump target get_fs_size() { - local _mnt=$(to_mount_point $1) + local _mnt=$(get_mntpoint_from_target $1) echo -n $(df -P "${_mnt}/$SAVE_PATH"|tail -1|awk '{print $4}') } @@ -363,6 +362,17 @@ handle_default_dump_target() _mntpoint=$(get_mntpoint_from_path $SAVE_PATH) _target=$(get_target_from_path $SAVE_PATH) + + if is_atomic && is_bind_mount $_mntpoint; then + SAVE_PATH=${SAVE_PATH##"$_mntpoint"} + # the real dump path in the 2nd kernel, if the mount point is bind mounted. + SAVE_PATH=$(get_bind_mount_directory $_mntpoint)/$SAVE_PATH + _mntpoint=$(get_mntpoint_from_target $_target) + + # the absolute path in the 1st kernel + SAVE_PATH=$_mntpoint/$SAVE_PATH + fi + if [ "$_mntpoint" != "/" ]; then SAVE_PATH=${SAVE_PATH##"$_mntpoint"} _fstype=$(get_fs_type_from_target $_target) @@ -534,8 +544,17 @@ do if [ "$config_opt" = "nfs" ]; then add_dracut_module "nfs" fi + + _absolute_save_path=$(make_absolute_save_path $config_val) + _mntpoint=$(get_mntpoint_from_path $_absolute_save_path) + if is_atomic && is_bind_mount $_mntpoint; then + SAVE_PATH=${_absolute_save_path##"$_mntpoint"} + # the real dump path in the 2nd kernel, if the mount point is bind mounted. + SAVE_PATH=$(get_bind_mount_directory $_mntpoint)/$SAVE_PATH + fi + add_mount "$config_val" - check_save_path_fs $(make_absolute_save_path $config_val) + check_save_path_fs $_absolute_save_path check_size fs $config_val ;; raw) diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec index da70498..16112e7 100644 --- a/SPECS/kexec-tools.spec +++ b/SPECS/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools Version: 2.0.7 -Release: 19%{?dist} +Release: 19%{?dist}.2 License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component. @@ -90,6 +90,7 @@ Patch303: kexec-tools-2.0.7-ppc64-kdump-Fix-ELF-header-endianess.patch # Patches 601 onward are generic patches # Patch601: kexec-tools-2.0.3-disable-kexec-test.patch +Patch602: kexec-tools-2.0.7-makedumpfile-sadump-Support-more-than-16TB-physical-memory.patch # # Patch 701 through 800 are meant for kdump anaconda addon @@ -130,10 +131,11 @@ tar -z -x -v -f %{SOURCE25} %patch101 -p1 -%patch601 -p1 %patch301 -p1 %patch302 -p1 %patch303 -p1 +%patch601 -p1 +%patch602 -p1 %ifarch ppc @@ -353,6 +355,18 @@ done %doc %changelog +* Tue Apr 21 2015 Baoquan He - 2.0.7-19.2 +- dracut-module-setup: Enhance kdump to support the bind mounted feature in Atomic +- Fix the warning if the target path is bind mount in Atomic +- Get the mount point correctly, if the device has several mount point +- kdump-lib: Add new function to judge the system is Atomic or not +- kdump-lib: Add the new function to enhance bind mounted judgement +- Remove duplicate slash in save path +- dracut-module-setup.sh: change the insecure use of /tmp/*$$* filenames + +* Fri Apr 10 2015 Baoquan He - 2.0.7-19.1 +- sadump: Support more than 16TB physical memory space. + * Fri Feb 6 2015 Dave Young - 2.0.7-19 - Fix to 2.0.7-18, forgot to update SOURCE25 addon tarball.