From 26a7a543427eac59ed39728466f3d95d320f735a Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2018 05:00:46 +0000 Subject: import kexec-tools-2.0.15-21.el7 --- diff --git a/.gitignore b/.gitignore index a6ef97a..980a7f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ SOURCES/eppic_050615.tar.gz -SOURCES/kdump-anaconda-addon-003-23-g80e78fb.tar.gz +SOURCES/kdump-anaconda-addon-003-29-g4c517c5.tar.gz SOURCES/kexec-tools-2.0.15.tar.xz SOURCES/makedumpfile-1.6.2.tar.gz diff --git a/.kexec-tools.metadata b/.kexec-tools.metadata index cae8820..091e2e7 100644 --- a/.kexec-tools.metadata +++ b/.kexec-tools.metadata @@ -1,4 +1,4 @@ a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz -dfa17c4a04bc3775ede56c1fd3a8904e938f0fe1 SOURCES/kdump-anaconda-addon-003-23-g80e78fb.tar.gz +8d688495efaf6d17e58a6e597934023040eabbf1 SOURCES/kdump-anaconda-addon-003-29-g4c517c5.tar.gz e723b075f2183066e8ee174edf9d85dff4f863e4 SOURCES/kexec-tools-2.0.15.tar.xz 3f1b8092a71cf174c4685634982f1d5abc30d3e6 SOURCES/makedumpfile-1.6.2.tar.gz diff --git a/SOURCES/dracut-module-setup.sh b/SOURCES/dracut-module-setup.sh index bed9fde..c833bfe 100755 --- a/SOURCES/dracut-module-setup.sh +++ b/SOURCES/dracut-module-setup.sh @@ -7,13 +7,6 @@ if ! [[ -d "${initdir}/tmp" ]]; then mkdir -p "${initdir}/tmp" fi -is_mpath() { - local _dev=$1 - [ -e /sys/dev/block/$_dev/dm/uuid ] || return 1 - [[ $(cat /sys/dev/block/$_dev/dm/uuid) =~ mpath- ]] && return 0 - return 1 -} - check() { [[ $debug ]] && set -x #kdumpctl sets this explicitly @@ -27,7 +20,7 @@ check() { depends() { local _dep="base shutdown" - if [ -d /sys/module/drm/drivers ]; then + if [ -n "$( find /sys/devices -name drm )" ] || [ -d /sys/module/hyperv_fb ]; then _dep="$_dep drm" fi @@ -35,7 +28,6 @@ depends() { _dep="$_dep network" fi - for_each_host_dev_and_slaves is_mpath && _dep="$_dep multipath-hostonly" echo $_dep return 0 } @@ -293,6 +285,8 @@ kdump_setup_netdev() { _static=$(kdump_static_ip $_netdev $_srcaddr) if [ -n "$_static" ]; then _proto=none + elif is_ipv6_address $_srcaddr; then + _proto=either6 else _proto=dhcp fi @@ -693,6 +687,8 @@ kdump_configure_fence_kdump () { kdump_install_net $node done + dracut_install /etc/hosts + dracut_install /etc/nsswitch.conf dracut_install $FENCE_KDUMP_SEND } diff --git a/SOURCES/kdump-lib.sh b/SOURCES/kdump-lib.sh index c40b0d6..043800a 100755 --- a/SOURCES/kdump-lib.sh +++ b/SOURCES/kdump-lib.sh @@ -103,7 +103,7 @@ kdump_get_persistent_dev() { } if [[ $2 = "raw" ]];then - _lookup_dirs="/dev/mapper/* /dev/disk/by-id/*" + _lookup_dirs="/dev/mapper/* /dev/disk/by-id/* /dev/disk/by-path/*" else _lookup_dirs="/dev/mapper/* /dev/disk/by-uuid/* /dev/disk/by-id/*" fi @@ -507,3 +507,14 @@ get_dracut_args_target() { echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f1 } + +# Get currently loaded modules +# sorted, and delimited by newline +get_loaded_kernel_modules() +{ + local modules=( ) + while read _module _size _used _used_by; do + modules+=( "$_module" ) + done <<< "$(lsmod | sed -n '1!p')" + printf '%s\n' "${modules[@]}" | sort +} diff --git a/SOURCES/kdump.sysconfig.x86_64 b/SOURCES/kdump.sysconfig.x86_64 index 9093209..9595271 100644 --- a/SOURCES/kdump.sysconfig.x86_64 +++ b/SOURCES/kdump.sysconfig.x86_64 @@ -17,7 +17,7 @@ KDUMP_COMMANDLINE="" # This variable lets us remove arguments from the current kdump commandline # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline # NOTE: some arguments such as crashkernel will always be removed -KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug notsc kaslr" +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug kaslr" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE diff --git a/SOURCES/kdumpctl b/SOURCES/kdumpctl index 3e273b1..0a65d10 100755 --- a/SOURCES/kdumpctl +++ b/SOURCES/kdumpctl @@ -134,6 +134,9 @@ prepare_cmdline() # KDUMP_COMMANDLINE_APPEND. cmdline=$(remove_cmdline_param "$cmdline" root) + # With the help of "--hostonly-cmdline", we can avoid some interitage. + cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe) + # Remove netroot, rd.iscsi.initiator and iscsi_initiator since # we get duplicate entries for the same in case iscsi code adds # it as well. @@ -401,10 +404,12 @@ check_files_modified() EXTRA_BINS=`grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2` CHECK_FILES=`grep ^kdump_pre $KDUMP_CONFIG_FILE | cut -d\ -f2` + CORE_COLLECTOR=`grep ^core_collector $KDUMP_CONFIG_FILE | cut -d\ -f2` + CORE_COLLECTOR=`type -P $CORE_COLLECTOR` EXTRA_BINS="$EXTRA_BINS $CHECK_FILES" CHECK_FILES=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-` EXTRA_BINS="$EXTRA_BINS $CHECK_FILES" - files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS" + files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS $CORE_COLLECTOR" [[ -e /etc/fstab ]] && files="$files /etc/fstab" check_exist "$files" && check_executable "$EXTRA_BINS" @@ -555,6 +560,31 @@ check_wdt_modified() return 1 } +check_kmodules_modified() +{ + # always sort again to avoid LANG/LC inconsistent problem + local _old_modules="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | sort)" + local _new_modules="$(get_loaded_kernel_modules | sort)" + + [[ -z $_old_modules ]] && echo "Warning: Previous loaded kernel module list is absent or empty" + + local _added_modules=$(comm -13 <(echo "$_old_modules") <(echo "$_new_modules")) + local _dropped_modules=$(comm -23 <(echo "$_old_modules") <(echo "$_new_modules")) + + if [ "$_old_modules" != "$_new_modules" ]; then + echo "Detected change(s) of loaded kernel modules list:" + [[ -n $_added_modules ]] && for _module in $_added_modules; do + echo " +$_module" + done + [[ -n $_dropped_modules ]] && for _module in $_dropped_modules; do + echo " -$_module" + done + return 1 + fi + + return 0 +} + # returns 0 if system is not modified # returns 1 if system is modified # returns 2 if system modification is invalid @@ -582,6 +612,11 @@ check_system_modified() return 1 fi + check_kmodules_modified + if [ $? -ne 0 ]; then + return 1 + fi + return 0 } diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-Add-a-new-helper-file-tools.c-that-provides-some-use.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-Add-a-new-helper-file-tools.c-that-provides-some-use.patch new file mode 100644 index 0000000..f4687c9 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-Add-a-new-helper-file-tools.c-that-provides-some-use.patch @@ -0,0 +1,875 @@ +From 4d86cc76f09f7632bb60833832406d7f294baf25 Mon Sep 17 00:00:00 2001 +From: Bhupesh Sharma +Date: Tue, 6 Mar 2018 02:13:00 +0900 +Subject: [PATCH 1/3] Add a new helper file 'tools.c' that provides some useful + APIs + +This patch borrows the 'tools.c' helper file from the crash utility +project and adds it to the makedumpfile source code, to allow +some basic useful APIs to be present which can be invoked from +other source code files. + +'tools.c' provides some useful APIs like 'htol' (convert +a string to a hexadecimal long value), etc. which can be +invoked by other functions (a functionality that is exposed +by follow-up patches). + +Signed-off-by: Bhupesh Sharma +--- + Makefile | 2 +- + common.h | 8 + + makedumpfile.h | 14 ++ + tools.c | 766 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 789 insertions(+), 1 deletion(-) + create mode 100644 tools.c + +diff --git a/makedumpfile-1.6.2/Makefile b/makedumpfile-1.6.2/Makefile +index f4b7c56b6f3d..e870b1362c95 100644 +--- a/makedumpfile-1.6.2/Makefile ++++ b/makedumpfile-1.6.2/Makefile +@@ -46,7 +46,7 @@ CFLAGS_ARCH += -m32 + endif + + SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h +-SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c ++SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c + OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART)) + SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c + OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) +diff --git a/makedumpfile-1.6.2/common.h b/makedumpfile-1.6.2/common.h +index 6ad3ca7b952c..6e2f657a79c7 100644 +--- a/makedumpfile-1.6.2/common.h ++++ b/makedumpfile-1.6.2/common.h +@@ -19,6 +19,8 @@ + #define TRUE (1) + #define FALSE (0) + #define ERROR (-1) ++#define UNUSED (-1) ++#define RETURN_ON_ERROR (0x2) + + #ifndef LONG_MAX + #define LONG_MAX ((long)(~0UL>>1)) +@@ -35,12 +37,18 @@ + #define round(x, y) (((x) / (y)) * (y)) + #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) + ++#define NUM_HEX (0x1) ++#define NUM_DEC (0x2) ++#define NUM_EXPR (0x4) ++#define NUM_ANY (NUM_HEX|NUM_DEC|NUM_EXPR) ++ + /* + * Incorrect address + */ + #define NOT_MEMMAP_ADDR (0x0) + #define NOT_KV_ADDR (0x0) + #define NOT_PADDR (ULONGLONG_MAX) ++#define BADADDR ((ulong)(-1)) + + #endif /* COMMON_H */ + +diff --git a/makedumpfile-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h +index c2143a8d794b..733ac4ef40d1 100644 +--- a/makedumpfile-1.6.2/makedumpfile.h ++++ b/makedumpfile-1.6.2/makedumpfile.h +@@ -244,6 +244,9 @@ isAnon(unsigned long mapping) + #define MIN_ELF_HEADER_SIZE \ + MAX(MIN_ELF32_HEADER_SIZE, MIN_ELF64_HEADER_SIZE) + static inline int string_exists(char *s) { return (s ? TRUE : FALSE); } ++#define STREQ(A, B) (string_exists((char *)A) && \ ++ string_exists((char *)B) && \ ++ (strcmp((char *)(A), (char *)(B)) == 0)) + #define STRNEQ(A, B)(string_exists((char *)(A)) && \ + string_exists((char *)(B)) && \ + (strncmp((char *)(A), (char *)(B), strlen((char *)(B))) == 0)) +@@ -2328,4 +2331,15 @@ int prepare_splitblock_table(void); + int initialize_zlib(z_stream *stream, int level); + int finalize_zlib(z_stream *stream); + ++int parse_line(char *str, char *argv[]); ++char *shift_string_left(char *s, int cnt); ++char *clean_line(char *line); ++char *strip_linefeeds(char *line); ++char *strip_beginning_whitespace(char *line); ++char *strip_ending_whitespace(char *line); ++ulong htol(char *s, int flags); ++int hexadecimal(char *s, int count); ++int decimal(char *s, int count); ++int file_exists(char *file); ++ + #endif /* MAKEDUMPFILE_H */ +diff --git a/makedumpfile-1.6.2/tools.c b/makedumpfile-1.6.2/tools.c +new file mode 100644 +index 000000000000..5814a775d42d +--- /dev/null ++++ b/makedumpfile-1.6.2/tools.c +@@ -0,0 +1,766 @@ ++/* tools.c - Borrowed from crash utility code ++ * (https://github.com/crash-utility/crash) ++ * ++ * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. ++ * Copyright (C) 2002-2017 David Anderson ++ * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include "common.h" ++#include "makedumpfile.h" ++#include ++ ++#define FAULT_ON_ERROR (0x1) ++#define RETURN_ON_ERROR (0x2) ++#define QUIET (0x4) ++#define HEX_BIAS (0x8) ++#define LONG_LONG (0x10) ++#define RETURN_PARTIAL (0x20) ++#define NO_DEVMEM_SWITCH (0x40) ++ ++#define MAX_HEXADDR_STRLEN (16) ++ ++#define FIRSTCHAR(s) (s[0]) ++ ++/* ++ * Determine whether a file exists, using the caller's stat structure if ++ * one was passed in. ++ */ ++int ++file_exists(char *file) ++{ ++ struct stat sbuf; ++ ++ if (stat(file, &sbuf) == 0) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++/* ++ * Parse a line into tokens, populate the passed-in argv[] array, and ++ * return the count of arguments found. This function modifies the ++ * passed-string by inserting a NULL character at the end of each token. ++ * Expressions encompassed by parentheses, and strings encompassed by ++ * apostrophes, are collected into single tokens. ++ */ ++int ++parse_line(char *str, char *argv[]) ++{ ++ int i, j, k; ++ int string; ++ int expression; ++ ++ for (i = 0; i < MAXARGS; i++) ++ argv[i] = NULL; ++ ++ clean_line(str); ++ ++ if (str == NULL || strlen(str) == 0) ++ return(0); ++ ++ i = j = k = 0; ++ string = expression = FALSE; ++ ++ /* ++ * Special handling for when the first character is a '"'. ++ */ ++ if (str[0] == '"') { ++next: ++ do { ++ i++; ++ } while ((str[i] != NULLCHAR) && (str[i] != '"')); ++ ++ switch (str[i]) ++ { ++ case NULLCHAR: ++ argv[j] = &str[k]; ++ return j+1; ++ case '"': ++ argv[j++] = &str[k+1]; ++ str[i++] = NULLCHAR; ++ if (str[i] == '"') { ++ k = i; ++ goto next; ++ } ++ break; ++ } ++ } else ++ argv[j++] = str; ++ ++ while (TRUE) { ++ if (j == MAXARGS) ++ ERRMSG("too many arguments in string!\n"); ++ ++ while (str[i] != ' ' && str[i] != '\t' && str[i] != NULLCHAR) { ++ i++; ++ } ++ ++ switch (str[i]) ++ { ++ case ' ': ++ case '\t': ++ str[i++] = NULLCHAR; ++ ++ while (str[i] == ' ' || str[i] == '\t') { ++ i++; ++ } ++ ++ if (str[i] == '"') { ++ str[i] = ' '; ++ string = TRUE; ++ i++; ++ } ++ ++ if (!string && str[i] == '(') { ++ expression = TRUE; ++ } ++ ++ if (str[i] != NULLCHAR && str[i] != '\n') { ++ argv[j++] = &str[i]; ++ if (string) { ++ string = FALSE; ++ while (str[i] != '"' && str[i] != NULLCHAR) ++ i++; ++ if (str[i] == '"') ++ str[i] = ' '; ++ } ++ if (expression) { ++ expression = FALSE; ++ while (str[i] != ')' && str[i] != NULLCHAR) ++ i++; ++ } ++ break; ++ } ++ /* else fall through */ ++ case '\n': ++ str[i] = NULLCHAR; ++ /* keep falling... */ ++ case NULLCHAR: ++ argv[j] = NULLCHAR; ++ return(j); ++ } ++ } ++} ++ ++/* ++ * Defuse controversy re: extensions to ctype.h ++ */ ++int ++whitespace(int c) ++{ ++ return ((c == ' ') ||(c == '\t')); ++} ++ ++int ++ascii(int c) ++{ ++ return ((c >= 0) && (c <= 0x7f)); ++} ++ ++/* ++ * Strip line-ending whitespace and linefeeds. ++ */ ++char * ++strip_line_end(char *line) ++{ ++ strip_linefeeds(line); ++ strip_ending_whitespace(line); ++ return(line); ++} ++ ++/* ++ * Strip line-beginning and line-ending whitespace and linefeeds. ++ */ ++char * ++clean_line(char *line) ++{ ++ strip_beginning_whitespace(line); ++ strip_linefeeds(line); ++ strip_ending_whitespace(line); ++ return(line); ++} ++ ++/* ++ * Strip line-ending linefeeds in a string. ++ */ ++char * ++strip_linefeeds(char *line) ++{ ++ char *p; ++ ++ if (line == NULL || strlen(line) == 0) ++ return(line); ++ ++ p = &LASTCHAR(line); ++ ++ while (*p == '\n') { ++ *p = NULLCHAR; ++ if (--p < line) ++ break; ++ } ++ ++ return(line); ++} ++ ++/* ++ * Strip a specified line-ending character in a string. ++ */ ++char * ++strip_ending_char(char *line, char c) ++{ ++ char *p; ++ ++ if (line == NULL || strlen(line) == 0) ++ return(line); ++ ++ p = &LASTCHAR(line); ++ ++ if (*p == c) ++ *p = NULLCHAR; ++ ++ return(line); ++} ++ ++/* ++ * Strip a specified line-beginning character in a string. ++ */ ++char * ++strip_beginning_char(char *line, char c) ++{ ++ if (line == NULL || strlen(line) == 0) ++ return(line); ++ ++ if (FIRSTCHAR(line) == c) ++ shift_string_left(line, 1); ++ ++ return(line); ++} ++ ++/* ++ * Strip line-ending whitespace. ++ */ ++char * ++strip_ending_whitespace(char *line) ++{ ++ char *p; ++ ++ if (line == NULL || strlen(line) == 0) ++ return(line); ++ ++ p = &LASTCHAR(line); ++ ++ while (*p == ' ' || *p == '\t') { ++ *p = NULLCHAR; ++ if (p == line) ++ break; ++ p--; ++ } ++ ++ return(line); ++} ++ ++/* ++ * Strip line-beginning whitespace. ++ */ ++char * ++strip_beginning_whitespace(char *line) ++{ ++ char buf[BUFSIZE]; ++ char *p; ++ ++ if (line == NULL || strlen(line) == 0) ++ return(line); ++ ++ strcpy(buf, line); ++ p = &buf[0]; ++ while (*p == ' ' || *p == '\t') ++ p++; ++ strcpy(line, p); ++ ++ return(line); ++} ++ ++/* ++ * End line at first comma found. ++ */ ++char * ++strip_comma(char *line) ++{ ++ char *p; ++ ++ if ((p = strstr(line, ","))) ++ *p = NULLCHAR; ++ ++ return(line); ++} ++ ++/* ++ * Strip the 0x from the beginning of a hexadecimal value string. ++ */ ++char * ++strip_hex(char *line) ++{ ++ if (STRNEQ(line, "0x")) ++ shift_string_left(line, 2); ++ ++ return(line); ++} ++ ++/* ++ * Turn a string into upper-case. ++ */ ++char * ++upper_case(const char *s, char *buf) ++{ ++ const char *p1; ++ char *p2; ++ ++ p1 = s; ++ p2 = buf; ++ ++ while (*p1) { ++ *p2 = toupper(*p1); ++ p1++, p2++; ++ } ++ ++ *p2 = NULLCHAR; ++ ++ return(buf); ++} ++ ++/* ++ * Return pointer to first non-space/tab in a string. ++ */ ++char * ++first_nonspace(char *s) ++{ ++ return(s + strspn(s, " \t")); ++} ++ ++/* ++ * Return pointer to first space/tab in a string. If none are found, ++ * return a pointer to the string terminating NULL. ++ */ ++char * ++first_space(char *s) ++{ ++ return(s + strcspn(s, " \t")); ++} ++ ++/* ++ * Replace the first space/tab found in a string with a NULL character. ++ */ ++char * ++null_first_space(char *s) ++{ ++ char *p1; ++ ++ p1 = first_space(s); ++ if (*p1) ++ *p1 = NULLCHAR; ++ ++ return s; ++} ++ ++/* ++ * Replace any instances of the characters in string c that are found in ++ * string s with the character passed in r. ++ */ ++char * ++replace_string(char *s, char *c, char r) ++{ ++ int i, j; ++ ++ for (i = 0; s[i]; i++) { ++ for (j = 0; c[j]; j++) { ++ if (s[i] == c[j]) ++ s[i] = r; ++ } ++ } ++ ++ return s; ++} ++ ++/* ++ * Find the rightmost instance of a substring in a string. ++ */ ++char * ++strstr_rightmost(char *s, char *lookfor) ++{ ++ char *next, *last, *p; ++ ++ for (p = s, last = NULL; *p; p++) { ++ if (!(next = strstr(p, lookfor))) ++ break; ++ last = p = next; ++ } ++ ++ return last; ++} ++ ++/* ++ * Shifts the contents of a string to the left by cnt characters, ++ * disposing the leftmost characters. ++ */ ++char * ++shift_string_left(char *s, int cnt) ++{ ++ int origlen; ++ ++ if (!cnt) ++ return(s); ++ ++ origlen = strlen(s); ++ memmove(s, s+cnt, (origlen-cnt)); ++ *(s+(origlen-cnt)) = NULLCHAR; ++ return(s); ++} ++ ++/* ++ * Prints a string verbatim, allowing strings with % signs to be displayed ++ * without printf conversions. ++ */ ++void ++print_verbatim(FILE *filep, char *line) ++{ ++ int i; ++ ++ for (i = 0; i < strlen(line); i++) { ++ fputc(line[i], filep); ++ fflush(filep); ++ } ++} ++ ++char * ++fixup_percent(char *s) ++{ ++ char *p1; ++ ++ if ((p1 = strstr(s, "%")) == NULL) ++ return s; ++ ++ s[strlen(s)+1] = NULLCHAR; ++ memmove(p1+1, p1, strlen(p1)); ++ *p1 = '%'; ++ ++ return s; ++} ++ ++/* ++ * Append a two-character string to a number to make 1, 2, 3 and 4 into ++ * 1st, 2nd, 3rd, 4th, and so on... ++ */ ++char * ++ordinal(ulong val, char *buf) ++{ ++ char *p1; ++ ++ sprintf(buf, "%ld", val); ++ p1 = &buf[strlen(buf)-1]; ++ ++ switch (*p1) ++ { ++ case '1': ++ strcat(buf, "st"); ++ break; ++ case '2': ++ strcat(buf, "nd"); ++ break; ++ case '3': ++ strcat(buf, "rd"); ++ break; ++ default: ++ strcat(buf, "th"); ++ break; ++ } ++ ++ return buf; ++} ++ ++/* ++ * Determine whether a string contains only decimal characters. ++ * If count is non-zero, limit the search to count characters. ++ */ ++int ++decimal(char *s, int count) ++{ ++ char *p; ++ int cnt, digits; ++ ++ if (!count) { ++ strip_line_end(s); ++ cnt = 0; ++ } else ++ cnt = count; ++ ++ for (p = &s[0], digits = 0; *p; p++) { ++ switch(*p) ++ { ++ case '0': ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ case '8': ++ case '9': ++ digits++; ++ case ' ': ++ break; ++ default: ++ return FALSE; ++ } ++ ++ if (count && (--cnt == 0)) ++ break; ++ } ++ ++ return (digits ? TRUE : FALSE); ++} ++ ++/* ++ * Determine whether a string contains only ASCII characters. ++ */ ++int ++ascii_string(char *s) ++{ ++ char *p; ++ ++ for (p = &s[0]; *p; p++) { ++ if (!ascii(*p)) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* ++ * Check whether a string contains only printable ASCII characters. ++ */ ++int ++printable_string(char *s) ++{ ++ char *p; ++ ++ for (p = &s[0]; *p; p++) { ++ if (!isprint(*p)) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* ++ * Convert a string to a hexadecimal long value. ++ */ ++ulong ++htol(char *s, int flags) ++{ ++ ulong i, j; ++ ulong n; ++ ++ if (s == NULL) { ++ if (!(flags & QUIET)) ++ ERRMSG("received NULL string\n"); ++ goto htol_error; ++ } ++ ++ if (STRNEQ(s, "0x") || STRNEQ(s, "0X")) ++ s += 2; ++ ++ if (strlen(s) > MAX_HEXADDR_STRLEN) { ++ if (!(flags & QUIET)) ++ ERRMSG("input string too large: \"%s\" (%d vs %d)\n", ++ s, (int)strlen(s), (int)MAX_HEXADDR_STRLEN); ++ goto htol_error; ++ } ++ ++ for (n = i = 0; s[i] != 0; i++) { ++ switch (s[i]) ++ { ++ case 'a': ++ case 'b': ++ case 'c': ++ case 'd': ++ case 'e': ++ case 'f': ++ j = (s[i] - 'a') + 10; ++ break; ++ case 'A': ++ case 'B': ++ case 'C': ++ case 'D': ++ case 'E': ++ case 'F': ++ j = (s[i] - 'A') + 10; ++ break; ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ case '8': ++ case '9': ++ case '0': ++ j = s[i] - '0'; ++ break; ++ case 'x': ++ case 'X': ++ case 'h': ++ continue; ++ default: ++ if (!(flags & QUIET)) ++ ERRMSG("invalid input: \"%s\"\n", s); ++ goto htol_error; ++ } ++ n = (16 * n) + j; ++ } ++ ++ return(n); ++ ++htol_error: ++ return BADADDR; ++} ++ ++/* ++ * Determine whether a string contains only hexadecimal characters. ++ * If count is non-zero, limit the search to count characters. ++ */ ++int ++hexadecimal(char *s, int count) ++{ ++ char *p; ++ int cnt, digits; ++ ++ if (!count) { ++ strip_line_end(s); ++ cnt = 0; ++ } else ++ cnt = count; ++ ++ for (p = &s[0], digits = 0; *p; p++) { ++ switch(*p) ++ { ++ case 'a': ++ case 'b': ++ case 'c': ++ case 'd': ++ case 'e': ++ case 'f': ++ case 'A': ++ case 'B': ++ case 'C': ++ case 'D': ++ case 'E': ++ case 'F': ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ case '8': ++ case '9': ++ case '0': ++ digits++; ++ case 'x': ++ case 'X': ++ break; ++ ++ case ' ': ++ if (*(p+1) == NULLCHAR) ++ break; ++ else ++ return FALSE; ++ default: ++ return FALSE; ++ } ++ ++ if (count && (--cnt == 0)) ++ break; ++ } ++ ++ return (digits ? TRUE : FALSE); ++} ++ ++/* ++ * Determine whether a string contains only hexadecimal characters. ++ * and cannot be construed as a decimal number. ++ * If count is non-zero, limit the search to count characters. ++ */ ++int ++hexadecimal_only(char *s, int count) ++{ ++ char *p; ++ int cnt, only; ++ ++ if (!count) { ++ strip_line_end(s); ++ cnt = 0; ++ } else ++ cnt = count; ++ ++ only = 0; ++ ++ for (p = &s[0]; *p; p++) { ++ switch(*p) ++ { ++ case 'a': ++ case 'b': ++ case 'c': ++ case 'd': ++ case 'e': ++ case 'f': ++ case 'A': ++ case 'B': ++ case 'C': ++ case 'D': ++ case 'E': ++ case 'F': ++ case 'x': ++ case 'X': ++ only++; ++ break; ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ case '8': ++ case '9': ++ case '0': ++ break; ++ ++ case ' ': ++ if (*(p+1) == NULLCHAR) ++ break; ++ else ++ return FALSE; ++ default: ++ return FALSE; ++ } ++ ++ if (count && (--cnt == 0)) ++ break; ++ } ++ ++ return only; ++} +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-Check-if-clock_gettime-requires-lrt.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-Check-if-clock_gettime-requires-lrt.patch new file mode 100644 index 0000000..56f10c2 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-Check-if-clock_gettime-requires-lrt.patch @@ -0,0 +1,39 @@ +From aec51ef7aee483cc5bf16844bdbacb1c70619f15 Mon Sep 17 00:00:00 2001 +From: Petr Tesarik +Date: Wed, 20 Jun 2018 11:50:19 +0200 +Subject: [PATCH 2/2] [PATCH 2/2] Check if clock_gettime() requires -lrt + +For glibc versions before 2.17, clock_gettime() was contained in a +separate library and required linking with -lrt. + +Signed-off-by: Petr Tesarik +--- + Makefile | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/makedumpfile-1.6.2/Makefile b/makedumpfile-1.6.2/Makefile +index 612b9d0..142a387 100644 +--- a/makedumpfile-1.6.2/Makefile ++++ b/makedumpfile-1.6.2/Makefile +@@ -68,6 +68,18 @@ endif + + LIBS := -lpthread $(LIBS) + ++try-run = $(shell set -e; \ ++ TMP=".$$$$.tmp"; \ ++ if ($(1)) >/dev/null 2>&1; \ ++ then echo "$(2)"; \ ++ else echo "$(3)"; \ ++ fi; \ ++ rm -f "$$TMP") ++ ++LINK_TEST_PROG="int clock_gettime(); int main(){ return clock_gettime(); }" ++LIBS := $(LIBS) $(call try-run,\ ++ echo $(LINK_TEST_PROG) | $(CC) $(CFLAGS) -o "$$TMP" -x c -,,-lrt) ++ + all: makedumpfile + + $(OBJ_PART): $(SRC_PART) +-- +2.9.5 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-Documentation-Update-documentation-regarding-mem-usa.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-Documentation-Update-documentation-regarding-mem-usa.patch new file mode 100644 index 0000000..e62286d --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-Documentation-Update-documentation-regarding-mem-usa.patch @@ -0,0 +1,36 @@ +From 8449bda73ab14516d4bf81d29503c1ea203bb865 Mon Sep 17 00:00:00 2001 +From: Bhupesh Sharma +Date: Tue, 6 Mar 2018 02:13:00 +0900 +Subject: [PATCH 3/3] Documentation: Update documentation regarding + --mem-usage' option + +Earlier patch in this patchset, enables the '--mem-usage' makedumpfile +option on arm64 platforms. + +In addition, I have validated the '--mem-usage' makedumpfile option +on several ppc64/ppc64le and s390x machines, so update the +'makedumpfile.8' documentation to indicate that '--mem-usage' option is +supported not only on x86_64, but also on ppc64, s390x and arm64 +platforms. + +Signed-off-by: Bhupesh Sharma +--- + makedumpfile.8 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/makedumpfile-1.6.2/makedumpfile.8 b/makedumpfile-1.6.2/makedumpfile.8 +index 15db7947d62f..3ccfc65798be 100644 +--- a/makedumpfile-1.6.2/makedumpfile.8 ++++ b/makedumpfile-1.6.2/makedumpfile.8 +@@ -593,7 +593,7 @@ last cleared on the crashed kernel, through "dmesg --clear" for example. + + .TP + \fB\-\-mem-usage\fR +-This option is only for x86_64. ++This option is currently supported on x86_64, arm64, ppc64 and s390x. + This option is used to show the page numbers of current system in different + use. It should be executed in 1st kernel. By the help of this, user can know + how many pages is dumpable when different dump_level is specified. It analyzes +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-Fix-array-index-out-of-bound-exception.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-Fix-array-index-out-of-bound-exception.patch new file mode 100644 index 0000000..bb35f7a --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-Fix-array-index-out-of-bound-exception.patch @@ -0,0 +1,79 @@ +From e5f96e79d69a1d295f19130da00ec6514d28a8ae Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Tue, 6 Mar 2018 19:07:00 +0900 +Subject: [PATCH] Fix array index out of bound exception + +A data overflow may lead to a reversal, which may turn a positive +number into a large negative number, in this case, the string's +length will exceed the array size(for example, eta: -2147483648s), +here the array size is defined 16 characters. So, it is nessasary +to consider some exceptions. + +Signed-off-by: Lianbo Jiang +--- + print_info.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/makedumpfile-1.6.2/print_info.c b/makedumpfile-1.6.2/print_info.c +index e0e6a27..09e215a 100644 +--- a/makedumpfile-1.6.2/print_info.c ++++ b/makedumpfile-1.6.2/print_info.c +@@ -16,6 +16,8 @@ + #include "print_info.h" + #include + #include ++#include ++#include + + #define PROGRESS_MAXLEN "50" + +@@ -352,18 +354,21 @@ static void calc_delta(struct timeval *tv_start, struct timeval *delta) + } + + /* produce less than 12 bytes on msg */ +-static int eta_to_human_short (int secs, char* msg) ++static int eta_to_human_short (int64_t secs, char* msg, int maxsize) + { + strcpy(msg, "eta: "); + msg += strlen("eta: "); + if (secs < 100) +- sprintf(msg, "%ds", secs); ++ snprintf(msg, maxsize, "%"PRId64"s", secs); + else if (secs < 100 * 60) +- sprintf(msg, "%dm%ds", secs / 60, secs % 60); ++ snprintf(msg, maxsize, "%"PRId64"m""%"PRId64"s", ++ secs / 60, secs % 60); + else if (secs < 48 * 3600) +- sprintf(msg, "%dh%dm", secs / 3600, (secs / 60) % 60); ++ snprintf(msg, maxsize, "%"PRId64"h""%"PRId64"m", ++ secs / 3600, (secs / 60) % 60); + else if (secs < 100 * 86400) +- sprintf(msg, "%dd%dh", secs / 86400, (secs / 3600) % 24); ++ snprintf(msg, maxsize, "%"PRId64"d""%"PRId64"h", ++ secs / 86400, (secs / 3600) % 24); + else + sprintf(msg, ">2day"); + return 0; +@@ -379,8 +384,8 @@ print_progress(const char *msg, unsigned long current, unsigned long end, struct + static unsigned int lapse = 0; + static const char *spinner = "/|\\-"; + struct timeval delta; +- double eta; +- char eta_msg[16] = " "; ++ int64_t eta; ++ char eta_msg[32] = " "; + + if (current < end) { + tm = time(NULL); +@@ -395,7 +400,7 @@ print_progress(const char *msg, unsigned long current, unsigned long end, struct + calc_delta(start, &delta); + eta = delta.tv_sec + delta.tv_usec / 1e6; + eta = (100 - progress) * eta / progress; +- eta_to_human_short(eta, eta_msg); ++ eta_to_human_short(eta, eta_msg, sizeof(eta_msg)); + } + if (flag_ignore_r_char) { + PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c %16s\n", +-- +2.9.5 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-Use-integer-arithmetics-for-th.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-Use-integer-arithmetics-for-th.patch new file mode 100644 index 0000000..339bc5d --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-Use-integer-arithmetics-for-th.patch @@ -0,0 +1,139 @@ +From c6b79cbc990b3b4933730205f58812fb44b6fcd5 Mon Sep 17 00:00:00 2001 +From: Petr Tesarik +Date: Tue, 10 Apr 2018 20:39:00 +0900 +Subject: [PATCH] [PATCH v2] makedumpfile: Use integer arithmetics for the + progress bar + +Essentially, the estimated remaining time is calculated as: + + elapsed * (100 - progress) / progress + +Since the calculation is done with floating point numbers, it had +masked a division by zero (if progress is 0), producing a NaN or +infinity. The following conversion to int produces INT_MIN with GCC +on major platforms, which originally overflowed the eta buffer. This +bug was fixed by commit e5f96e79d69a1d295f19130da00ec6514d28a8ae, +but conversion of NaN and infinity is undefined behaviour in ISO C, +plus the corresponding output is still wrong, e.g.: + +Copying data : [ 0.0 %] / eta: +-9223372036854775808s + +Most importantly, using the FPU for a progress bar is overkill. +Since the progress percentage is reported with one decimal digit +following the decimal point, it can be stored as an integer tenths +of a percent. + +Second, the estimated time can be calculated in milliseconds. Up to +49 days can be represented this way even on 32-bit platforms. Note +that delta.tv_usec can be ignored in the subtraction, because the +resulting eta is printed as seconds, so elapsed microseconds are +irrelevant. + +Last but not least, the original buffer overflow was probably caused +by the wrong assumption that integers < 100 can be interpreted with +less than 3 ASCII characters, but that's not true for signed +integers. To make eta_to_human_short() a bit safer, use an unsigned +integer type. + +Signed-off-by: Petr Tesarik +--- + print_info.c | 43 ++++++++++++++++++++----------------------- + 1 file changed, 20 insertions(+), 23 deletions(-) + +diff --git a/makedumpfile-1.6.2/print_info.c b/makedumpfile-1.6.2/print_info.c +index 09e215a..6bfcd11 100644 +--- a/makedumpfile-1.6.2/print_info.c ++++ b/makedumpfile-1.6.2/print_info.c +@@ -16,8 +16,6 @@ + #include "print_info.h" + #include + #include +-#include +-#include + + #define PROGRESS_MAXLEN "50" + +@@ -354,21 +352,18 @@ static void calc_delta(struct timeval *tv_start, struct timeval *delta) + } + + /* produce less than 12 bytes on msg */ +-static int eta_to_human_short (int64_t secs, char* msg, int maxsize) ++static int eta_to_human_short (unsigned long secs, char* msg) + { + strcpy(msg, "eta: "); + msg += strlen("eta: "); + if (secs < 100) +- snprintf(msg, maxsize, "%"PRId64"s", secs); ++ sprintf(msg, "%lus", secs); + else if (secs < 100 * 60) +- snprintf(msg, maxsize, "%"PRId64"m""%"PRId64"s", +- secs / 60, secs % 60); ++ sprintf(msg, "%lum%lus", secs / 60, secs % 60); + else if (secs < 48 * 3600) +- snprintf(msg, maxsize, "%"PRId64"h""%"PRId64"m", +- secs / 3600, (secs / 60) % 60); ++ sprintf(msg, "%luh%lum", secs / 3600, (secs / 60) % 60); + else if (secs < 100 * 86400) +- snprintf(msg, maxsize, "%"PRId64"d""%"PRId64"h", +- secs / 86400, (secs / 3600) % 24); ++ sprintf(msg, "%lud%luh", secs / 86400, (secs / 3600) % 24); + else + sprintf(msg, ">2day"); + return 0; +@@ -378,37 +373,39 @@ static int eta_to_human_short (int64_t secs, char* msg, int maxsize) + void + print_progress(const char *msg, unsigned long current, unsigned long end, struct timeval *start) + { +- float progress; ++ unsigned progress; /* in promilles (tenths of a percent) */ + time_t tm; + static time_t last_time = 0; + static unsigned int lapse = 0; + static const char *spinner = "/|\\-"; + struct timeval delta; +- int64_t eta; +- char eta_msg[32] = " "; ++ unsigned long eta; ++ char eta_msg[16] = " "; + + if (current < end) { + tm = time(NULL); + if (tm - last_time < 1) + return; + last_time = tm; +- progress = (float)current * 100 / end; ++ progress = current * 1000 / end; + } else +- progress = 100; ++ progress = 1000; + +- if (start != NULL) { ++ if (start != NULL && progress != 0) { + calc_delta(start, &delta); +- eta = delta.tv_sec + delta.tv_usec / 1e6; +- eta = (100 - progress) * eta / progress; +- eta_to_human_short(eta, eta_msg, sizeof(eta_msg)); ++ eta = 1000 * delta.tv_sec + delta.tv_usec / 1000; ++ eta = eta / progress - delta.tv_sec; ++ eta_to_human_short(eta, eta_msg); + } + if (flag_ignore_r_char) { +- PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c %16s\n", +- msg, progress, spinner[lapse % 4], eta_msg); ++ PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%3u.%u %%] %c %16s\n", ++ msg, progress / 10, progress % 10, ++ spinner[lapse % 4], eta_msg); + } else { + PROGRESS_MSG("\r"); +- PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c %16s", +- msg, progress, spinner[lapse % 4], eta_msg); ++ PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%3u.%u %%] %c %16s", ++ msg, progress / 10, progress % 10, ++ spinner[lapse % 4], eta_msg); + } + lapse++; + } +-- +2.9.5 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-Use-monotonic-clock-to-calculate-ETA-and-s.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-Use-monotonic-clock-to-calculate-ETA-and-s.patch new file mode 100644 index 0000000..cc7be1c --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-Use-monotonic-clock-to-calculate-ETA-and-s.patch @@ -0,0 +1,456 @@ +From 0f4e25c5d7c031201fa7ad384cd9562b9c9c6004 Mon Sep 17 00:00:00 2001 +From: Petr Tesarik +Date: Wed, 20 Jun 2018 11:50:18 +0200 +Subject: [PATCH 1/2] [PATCH 1/2] Use monotonic clock to calculate ETA and + stats + +Execution time should be always measured by a monotonic clock, +because the system clock may be affected by discontinuous jumps, +e.g. when time is set manually by an admin. + +Signed-off-by: Petr Tesarik +--- + makedumpfile.c | 84 +++++++++++++++++++++++++++++----------------------------- + print_info.c | 30 +++++++++++---------- + print_info.h | 6 ++--- + 3 files changed, 61 insertions(+), 59 deletions(-) + +diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c +index 1ed3d61..abe7a2b 100644 +--- a/makedumpfile-1.6.2/makedumpfile.c ++++ b/makedumpfile-1.6.2/makedumpfile.c +@@ -5364,7 +5364,7 @@ _exclude_free_page(struct cycle *cycle) + { + int i, nr_zones, num_nodes, node; + unsigned long node_zones, zone, spanned_pages, pgdat; +- struct timeval tv_start; ++ struct timespec ts_start; + + if ((node = next_online_node(0)) < 0) { + ERRMSG("Can't get next online node.\n"); +@@ -5374,7 +5374,7 @@ _exclude_free_page(struct cycle *cycle) + ERRMSG("Can't get pgdat list.\n"); + return FALSE; + } +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + + for (num_nodes = 1; num_nodes <= vt.numnodes; num_nodes++) { + +@@ -5420,7 +5420,7 @@ _exclude_free_page(struct cycle *cycle) + * print [100 %] + */ + print_progress(PROGRESS_FREE_PAGES, vt.numnodes, vt.numnodes, NULL); +- print_execution_time(PROGRESS_FREE_PAGES, &tv_start); ++ print_execution_time(PROGRESS_FREE_PAGES, &ts_start); + + return TRUE; + } +@@ -5567,7 +5567,7 @@ create_1st_bitmap_file(void) + char buf[info->page_size]; + mdf_pfn_t pfn, pfn_start, pfn_end, pfn_bitmap1; + unsigned long long phys_start, phys_end; +- struct timeval tv_start; ++ struct timespec ts_start; + off_t offset_page; + + if (info->flag_refiltering) +@@ -5597,7 +5597,7 @@ create_1st_bitmap_file(void) + offset_page += info->page_size; + } + +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + + /* + * If page is on memory hole, set bit on the 1st-bitmap. +@@ -5629,7 +5629,7 @@ create_1st_bitmap_file(void) + */ + if (!info->flag_mem_usage) { + print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr, NULL); +- print_execution_time(PROGRESS_HOLES, &tv_start); ++ print_execution_time(PROGRESS_HOLES, &ts_start); + } + + if (!sync_1st_bitmap()) +@@ -5731,7 +5731,7 @@ create_bitmap_from_memhole(struct cycle *cycle, struct dump_bitmap *bitmap, int + mdf_pfn_t pfn_start_roundup, pfn_end_round; + unsigned long pfn_start_byte, pfn_end_byte; + unsigned int num_pt_loads = get_num_pt_loads(); +- struct timeval tv_start; ++ struct timespec ts_start; + + /* + * At first, clear all the bits on the bitmap. +@@ -5741,7 +5741,7 @@ create_bitmap_from_memhole(struct cycle *cycle, struct dump_bitmap *bitmap, int + /* + * If page is on memory hole, set bit on the bitmap. + */ +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + for (i = 0; get_pt_load(i, &phys_start, &phys_end, NULL, NULL); i++) { + pfn_start = MAX(paddr_to_pfn(phys_start), cycle->start_pfn); + pfn_end = MIN(paddr_to_pfn(phys_end), cycle->end_pfn); +@@ -5786,7 +5786,7 @@ create_bitmap_from_memhole(struct cycle *cycle, struct dump_bitmap *bitmap, int + * print 100 % + */ + print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr, NULL); +- print_execution_time(PROGRESS_HOLES, &tv_start); ++ print_execution_time(PROGRESS_HOLES, &ts_start); + + return TRUE; + } +@@ -6045,14 +6045,14 @@ exclude_unnecessary_pages(struct cycle *cycle) + { + unsigned int mm; + struct mem_map_data *mmd; +- struct timeval tv_start; ++ struct timespec ts_start; + + if (is_xen_memory() && !info->dom0_mapnr) { + ERRMSG("Can't get max domain-0 PFN for excluding pages.\n"); + return FALSE; + } + +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + + for (mm = 0; mm < info->num_mem_map; mm++) { + +@@ -6076,7 +6076,7 @@ exclude_unnecessary_pages(struct cycle *cycle) + */ + if (!info->flag_mem_usage) { + print_progress(PROGRESS_UNN_PAGES, info->num_mem_map, info->num_mem_map, NULL); +- print_execution_time(PROGRESS_UNN_PAGES, &tv_start); ++ print_execution_time(PROGRESS_UNN_PAGES, &ts_start); + } + + return TRUE; +@@ -7474,7 +7474,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) + unsigned long frac_head, frac_tail; + off_t off_seg_load, off_memory; + Elf64_Phdr load; +- struct timeval tv_start; ++ struct timespec ts_start; + struct cycle cycle = {0}; + + if (!info->flag_elf_dumpfile) +@@ -7499,7 +7499,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) + if (!(phnum = get_phnum_memory())) + return FALSE; + +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + + for (i = 0; i < phnum; i++) { + if (!get_phdr_memory(i, &load)) +@@ -7547,7 +7547,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) + } + + if ((num_dumped % per) == 0) +- print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &ts_start); + + num_dumped++; + +@@ -7666,8 +7666,8 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) + /* + * print [100 %] + */ +- print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &tv_start); +- print_execution_time(PROGRESS_COPY, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &ts_start); ++ print_execution_time(PROGRESS_COPY, &ts_start); + PROGRESS_MSG("\n"); + + return TRUE; +@@ -8008,8 +8008,8 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header, + mdf_pfn_t per; + mdf_pfn_t start_pfn, end_pfn; + struct page_desc pd; +- struct timeval tv_start; +- struct timeval last, new; ++ struct timespec ts_start; ++ struct timespec last, new; + pthread_t **threads = NULL; + struct thread_args *kdump_thread_args = NULL; + void *thread_result; +@@ -8047,7 +8047,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header, + per = info->num_dumpable / 10000; + per = per ? per : 1; + +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + + start_pfn = cycle->start_pfn; + end_pfn = cycle->end_pfn; +@@ -8095,7 +8095,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header, + * The next pfn is smallest pfn in all page_flag_buf. + */ + sem_wait(&info->page_flag_buf_sem); +- gettimeofday(&last, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &last); + while (1) { + current_pfn = end_pfn; + +@@ -8138,7 +8138,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header, + * So we should recheck. + */ + if (info->page_flag_buf[consuming]->ready != FLAG_READY) { +- gettimeofday(&new, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &new); + if (new.tv_sec - last.tv_sec > WAIT_TIME) { + ERRMSG("Can't get data of pfn.\n"); + goto out; +@@ -8151,7 +8151,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header, + } + + if ((num_dumped % per) == 0) +- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start); + + num_dumped++; + +@@ -8187,8 +8187,8 @@ finish: + /* + * print [100 %] + */ +- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start); +- print_execution_time(PROGRESS_COPY, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start); ++ print_execution_time(PROGRESS_COPY, &ts_start); + PROGRESS_MSG("\n"); + + out: +@@ -8238,7 +8238,7 @@ write_kdump_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_pag + struct page_desc pd; + unsigned char buf[info->page_size], *buf_out = NULL; + unsigned long len_buf_out; +- struct timeval tv_start; ++ struct timespec ts_start; + const off_t failed = (off_t)-1; + unsigned long len_buf_out_zlib, len_buf_out_lzo, len_buf_out_snappy; + +@@ -8299,12 +8299,12 @@ write_kdump_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_pag + end_pfn = info->split_end_pfn; + } + +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + + for (pfn = start_pfn; pfn < end_pfn; pfn++) { + + if ((num_dumped % per) == 0) +- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start); + + /* + * Check the excluded page. +@@ -8384,8 +8384,8 @@ out: + free(wrkmem); + #endif + +- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start); +- print_execution_time(PROGRESS_COPY, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start); ++ print_execution_time(PROGRESS_COPY, &ts_start); + + return ret; + } +@@ -8747,7 +8747,7 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d + off_t offset_data=0; + struct disk_dump_header *dh = info->dump_header; + unsigned char buf[info->page_size]; +- struct timeval tv_start; ++ struct timespec ts_start; + + cd_header->offset + = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks) +@@ -8829,7 +8829,7 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d + } + free_bitmap2_buffer(); + +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + + /* + * Write the remainder. +@@ -8842,8 +8842,8 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d + /* + * print [100 %] + */ +- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start); +- print_execution_time(PROGRESS_COPY, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start); ++ print_execution_time(PROGRESS_COPY, &ts_start); + PROGRESS_MSG("\n"); + + return TRUE; +@@ -9563,10 +9563,10 @@ exclude_xen4_user_domain(void) + int + exclude_xen_user_domain(void) + { +- struct timeval tv_start; ++ struct timespec ts_start; + int ret; + +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + + if (info->xen_crash_info.com && + info->xen_crash_info.com->xen_major_version >= 4) +@@ -9578,7 +9578,7 @@ exclude_xen_user_domain(void) + * print [100 %] + */ + print_progress(PROGRESS_XEN_DOMAIN, 1, 1, NULL); +- print_execution_time(PROGRESS_XEN_DOMAIN, &tv_start); ++ print_execution_time(PROGRESS_XEN_DOMAIN, &ts_start); + + return ret; + } +@@ -10502,7 +10502,7 @@ reassemble_kdump_pages(void) + struct disk_dump_header dh; + struct page_desc pd, pd_zero; + struct cache_data cd_pd, cd_data; +- struct timeval tv_start; ++ struct timespec ts_start; + char *data = NULL; + unsigned long data_buf_size = info->page_size; + +@@ -10538,7 +10538,7 @@ reassemble_kdump_pages(void) + /* + * Write page header of zero-filled page. + */ +- gettimeofday(&tv_start, NULL); ++ clock_gettime(CLOCK_MONOTONIC, &ts_start); + if (info->dump_level & DL_EXCLUDE_ZERO) { + /* + * makedumpfile outputs the data of zero-filled page at first +@@ -10573,7 +10573,7 @@ reassemble_kdump_pages(void) + + num_dumped++; + +- print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &ts_start); + + if (lseek(fd, offset_ph_org, SEEK_SET) < 0) { + ERRMSG("Can't seek a file(%s). %s\n", +@@ -10670,8 +10670,8 @@ reassemble_kdump_pages(void) + size_eraseinfo)) + goto out; + } +- print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &tv_start); +- print_execution_time(PROGRESS_COPY, &tv_start); ++ print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &ts_start); ++ print_execution_time(PROGRESS_COPY, &ts_start); + + ret = TRUE; + out: +diff --git a/makedumpfile-1.6.2/print_info.c b/makedumpfile-1.6.2/print_info.c +index 6bfcd11..732d5b8 100644 +--- a/makedumpfile-1.6.2/print_info.c ++++ b/makedumpfile-1.6.2/print_info.c +@@ -19,6 +19,8 @@ + + #define PROGRESS_MAXLEN "50" + ++#define NSEC_PER_SEC 1000000000L ++ + int message_level; + int flag_strerr_message; + int flag_ignore_r_char; /* 0: '\r' is effective. 1: not effective. */ +@@ -338,16 +340,16 @@ print_usage(void) + MSG("\n"); + } + +-static void calc_delta(struct timeval *tv_start, struct timeval *delta) ++static void calc_delta(struct timespec *ts_start, struct timespec *delta) + { +- struct timeval tv_end; ++ struct timespec ts_end; + +- gettimeofday(&tv_end, NULL); +- delta->tv_sec = tv_end.tv_sec - tv_start->tv_sec; +- delta->tv_usec = tv_end.tv_usec - tv_start->tv_usec; +- if (delta->tv_usec < 0) { ++ clock_gettime(CLOCK_MONOTONIC, &ts_end); ++ delta->tv_sec = ts_end.tv_sec - ts_start->tv_sec; ++ delta->tv_nsec = ts_end.tv_nsec - ts_start->tv_nsec; ++ if (delta->tv_nsec < 0) { + delta->tv_sec--; +- delta->tv_usec += 1000000; ++ delta->tv_nsec += NSEC_PER_SEC; + } + } + +@@ -371,14 +373,14 @@ static int eta_to_human_short (unsigned long secs, char* msg) + + + void +-print_progress(const char *msg, unsigned long current, unsigned long end, struct timeval *start) ++print_progress(const char *msg, unsigned long current, unsigned long end, struct timespec *start) + { + unsigned progress; /* in promilles (tenths of a percent) */ + time_t tm; + static time_t last_time = 0; + static unsigned int lapse = 0; + static const char *spinner = "/|\\-"; +- struct timeval delta; ++ struct timespec delta; + unsigned long eta; + char eta_msg[16] = " "; + +@@ -393,7 +395,7 @@ print_progress(const char *msg, unsigned long current, unsigned long end, struct + + if (start != NULL && progress != 0) { + calc_delta(start, &delta); +- eta = 1000 * delta.tv_sec + delta.tv_usec / 1000; ++ eta = 1000 * delta.tv_sec + delta.tv_nsec / (NSEC_PER_SEC / 1000); + eta = eta / progress - delta.tv_sec; + eta_to_human_short(eta, eta_msg); + } +@@ -411,12 +413,12 @@ print_progress(const char *msg, unsigned long current, unsigned long end, struct + } + + void +-print_execution_time(char *step_name, struct timeval *tv_start) ++print_execution_time(char *step_name, struct timespec *ts_start) + { +- struct timeval delta; ++ struct timespec delta; + +- calc_delta(tv_start, &delta); ++ calc_delta(ts_start, &delta); + REPORT_MSG("STEP [%s] : %ld.%06ld seconds\n", +- step_name, delta.tv_sec, delta.tv_usec); ++ step_name, delta.tv_sec, delta.tv_nsec / 1000); + } + +diff --git a/makedumpfile-1.6.2/print_info.h b/makedumpfile-1.6.2/print_info.h +index 1ce3593..49b70f4 100644 +--- a/makedumpfile-1.6.2/print_info.h ++++ b/makedumpfile-1.6.2/print_info.h +@@ -17,7 +17,7 @@ + #define _PRINT_INFO_H + + #include +-#include ++#include + + extern int message_level; + extern int flag_strerr_message; +@@ -25,9 +25,9 @@ extern int flag_ignore_r_char; + + void show_version(void); + void print_usage(void); +-void print_progress(const char *msg, unsigned long current, unsigned long end, struct timeval *start); ++void print_progress(const char *msg, unsigned long current, unsigned long end, struct timespec *start); + +-void print_execution_time(char *step_name, struct timeval *tv_start); ++void print_execution_time(char *step_name, struct timespec *ts_start); + + /* + * Message texts +-- +2.9.5 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-Add-support-to-read-symbols-like-_stext-from-p.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-Add-support-to-read-symbols-like-_stext-from-p.patch new file mode 100644 index 0000000..e48b21e --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-Add-support-to-read-symbols-like-_stext-from-p.patch @@ -0,0 +1,152 @@ +From d1e780507b6ed4b67e5e0e4e4b7c9796dc537210 Mon Sep 17 00:00:00 2001 +From: Bhupesh Sharma +Date: Tue, 6 Mar 2018 02:13:00 +0900 +Subject: [PATCH 2/3] arm64: Add support to read symbols like _stext from + '/proc/kallsyms' + +On ARM64 platforms the VA_BITS supported by a linux kernel being run +can be selected by setting 'ARM64_VA_BITS_*' (see 'arch/arm64/Kconfig' +for details). + +Now, to determine the 'info->page_offset' in arm64 makedumpfile +context ('arch/arm64.c') we need to determine the VA_BITS which was +selected by the underlying linux kernel. + +There can be several ways to determine the VA_BITS, out of which +reading the '_stext' symbol and calculating the 'va_bits' using the +same is the simplest yet portable method. + +For reading the kernel symbols like '_stext', we can read the +'/proc/kallsyms' file which contains these symbols and +works even in case of KASLR enabled arm64 kernels, as in those cases, +the '_stext' symbol will end up being randomized and hence +cannot be correctly read from the 'vmlinux' file. + +Signed-off-by: Bhupesh Sharma +--- + arch/arm64.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 73 insertions(+), 4 deletions(-) + +diff --git a/makedumpfile-1.6.2/arch/arm64.c b/makedumpfile-1.6.2/arch/arm64.c +index 25d7a1f4db98..c9dab677f2c9 100644 +--- a/makedumpfile-1.6.2/arch/arm64.c ++++ b/makedumpfile-1.6.2/arch/arm64.c +@@ -48,6 +48,12 @@ static unsigned long kimage_voffset; + #define SZ_64K (64 * 1024) + #define SZ_128M (128 * 1024 * 1024) + ++#define PAGE_OFFSET_36 ((0xffffffffffffffffUL) << 36) ++#define PAGE_OFFSET_39 ((0xffffffffffffffffUL) << 39) ++#define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) ++#define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) ++#define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) ++ + #define pgd_val(x) ((x).pgd) + #define pud_val(x) (pgd_val((x).pgd)) + #define pmd_val(x) (pud_val((x).pud)) +@@ -140,8 +146,6 @@ pud_offset(pgd_t *pgda, pgd_t *pgdv, unsigned long vaddr) + + static int calculate_plat_config(void) + { +- va_bits = NUMBER(VA_BITS); +- + /* derive pgtable_level as per arch/arm64/Kconfig */ + if ((PAGESIZE() == SZ_16K && va_bits == 36) || + (PAGESIZE() == SZ_64K && va_bits == 42)) { +@@ -177,6 +181,44 @@ get_phys_base_arm64(void) + return TRUE; + } + ++ulong ++get_stext_symbol(void) ++{ ++ int found; ++ FILE *fp; ++ char buf[BUFSIZE]; ++ char *kallsyms[MAXARGS]; ++ ulong kallsym; ++ ++ if (!file_exists("/proc/kallsyms")) { ++ ERRMSG("(%s) does not exist, will not be able to read symbols. %s\n", ++ "/proc/kallsyms", strerror(errno)); ++ return FALSE; ++ } ++ ++ if ((fp = fopen("/proc/kallsyms", "r")) == NULL) { ++ ERRMSG("Cannot open (%s) to read symbols. %s\n", ++ "/proc/kallsyms", strerror(errno)); ++ return FALSE; ++ } ++ ++ found = FALSE; ++ kallsym = 0; ++ ++ while (!found && fgets(buf, BUFSIZE, fp) && ++ (parse_line(buf, kallsyms) == 3)) { ++ if (hexadecimal(kallsyms[0], 0) && ++ STREQ(kallsyms[2], "_stext")) { ++ kallsym = htol(kallsyms[0], 0); ++ found = TRUE; ++ break; ++ } ++ } ++ fclose(fp); ++ ++ return(found ? kallsym : FALSE); ++} ++ + int + get_machdep_info_arm64(void) + { +@@ -188,12 +230,10 @@ get_machdep_info_arm64(void) + kimage_voffset = NUMBER(kimage_voffset); + info->max_physmem_bits = PHYS_MASK_SHIFT; + info->section_size_bits = SECTIONS_SIZE_BITS; +- info->page_offset = 0xffffffffffffffffUL << (va_bits - 1); + + DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); + DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits); + DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits); +- DEBUG_MSG("page_offset : %lx\n", info->page_offset); + + return TRUE; + } +@@ -219,6 +259,35 @@ get_xen_info_arm64(void) + int + get_versiondep_info_arm64(void) + { ++ ulong _stext; ++ ++ _stext = get_stext_symbol(); ++ if (!_stext) { ++ ERRMSG("Can't get the symbol of _stext.\n"); ++ return FALSE; ++ } ++ ++ /* Derive va_bits as per arch/arm64/Kconfig */ ++ if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { ++ va_bits = 36; ++ } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { ++ va_bits = 39; ++ } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { ++ va_bits = 42; ++ } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { ++ va_bits = 47; ++ } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { ++ va_bits = 48; ++ } else { ++ ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); ++ return FALSE; ++ } ++ ++ info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); ++ ++ DEBUG_MSG("page_offset=%lx, va_bits=%d\n", info->page_offset, ++ va_bits); ++ + return TRUE; + } + +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-Fix-calculation-of-page_offset-in-case-we-are-.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-Fix-calculation-of-page_offset-in-case-we-are-.patch new file mode 100644 index 0000000..7e140ad --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-Fix-calculation-of-page_offset-in-case-we-are-.patch @@ -0,0 +1,41 @@ +From 441b3fd88149c03c0eb4ba373f3c6633df2f3196 Mon Sep 17 00:00:00 2001 +From: Bhupesh Sharma +Date: Fri, 29 Jun 2018 16:14:48 +0530 +Subject: [PATCH] arm64: Fix calculation of page_offset in case we are running + cases other than mem-usage + +Patch f49ca13e5eed5bbdc69e0fd5ef099cb46050cb3d added '--mem-usage' +support for arm64 architecture. + +However, we also need to make sure that the calculation of +'page_offset' is valid in case we are running cases other than +'--mem-usage'. + +This patch does the same. I tested this patch on my qualcomm and apm +mustang arm64 boards. + +Signed-off-by: Bhupesh Sharma +--- + arch/arm64.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/makedumpfile-1.6.2/arch/arm64.c b/makedumpfile-1.6.2/arch/arm64.c +index c9dab677f2c9..2fd3e1874376 100644 +--- a/makedumpfile-1.6.2/arch/arm64.c ++++ b/makedumpfile-1.6.2/arch/arm64.c +@@ -222,6 +222,12 @@ get_stext_symbol(void) + int + get_machdep_info_arm64(void) + { ++ /* Check if va_bits is still not initialized. If still 0, call ++ * get_versiondep_info() to initialize the same. ++ */ ++ if (!va_bits) ++ get_versiondep_info_arm64(); ++ + if (!calculate_plat_config()) { + ERRMSG("Can't determine platform config values\n"); + return FALSE; +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-when-refiltering-initialize-refiltered-bitm.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-when-refiltering-initialize-refiltered-bitm.patch new file mode 100644 index 0000000..7d6332c --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-when-refiltering-initialize-refiltered-bitm.patch @@ -0,0 +1,106 @@ +From 3adf612137e8e488fe721ba154c089efbfead30a Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +Date: Wed, 8 Aug 2018 13:21:44 +0800 +Subject: [PATCH] [PATCH v3] when refiltering, initialize refiltered bitmap2 + from the kdump file's bitmap2 + +When refiltering on kdump format file, there is no info about pt_load[] for +exclude_nodata_pages(), and also we can not expect more data than the kdump +file can provide, hence this patch suggests to initialize the refiltered +bitmap2 from the kdump file's bitmap2. As for the statistic of pfn_memhole, +it should be calculated and discount the bits in kdump file's bitmap1. + +Note about the bug reported by the following ops: + makedumpfile -l --message-level 1 -d 31 /proc/vmcore /path/to/vmcore + makedumpfile --split -d 31 ./vmcore dumpfile_{1,2,3} 2>&1 +And get the following error: + Excluding unnecessary pages : [100.0 %] \ + readpage_kdump_compressed: pfn(9b) is excluded from /var/crash/127.0.0.1-2018-07-02-22:10:38/vmcore. + readmem: type_addr: 1, addr:9b000, size:4096 + read_pfn: Can't get the page data. + writeout_multiple_dumpfiles: Child process(2277) finished incompletely.(256) + Copying data : [ 24.6 %] - eta: 2s + makedumpfile Failed. + +Cc: Kazuhito Hagio +Signed-off-by: Pingfan Liu +--- + makedumpfile.c | 40 +++++++++++++++++++++++++++++++++++----- + 1 file changed, 35 insertions(+), 5 deletions(-) + +diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c +index 915cbf4..3ccdaae 100644 +--- a/makedumpfile-1.6.2/makedumpfile.c ++++ b/makedumpfile-1.6.2/makedumpfile.c +@@ -5516,6 +5516,27 @@ out: + "follow free lists instead of mem_map array.\n"); + } + ++static mdf_pfn_t count_bits(char *buf, int sz) ++{ ++ char *p = buf; ++ int i, j; ++ mdf_pfn_t cnt = 0; ++ ++ for (i = 0; i < sz; i++, p++) { ++ if (*p == 0) ++ continue; ++ else if (*p == 0xff) { ++ cnt += 8; ++ continue; ++ } ++ for (j = 0; j < 8; j++) { ++ if (*p & (1<name_memory, strerror(errno)); + return FALSE; + } ++ pfn_memhole -= count_bits(buf, sizeof(buf)); + if (write(info->bitmap1->fd, buf, sizeof(buf)) != sizeof(buf)) { + ERRMSG("Can't write the bitmap(%s). %s\n", + info->bitmap1->file_name, strerror(errno)); +@@ -6093,19 +6115,27 @@ copy_bitmap_buffer(void) + int + copy_bitmap_file(void) + { +- off_t offset; ++ off_t base, offset = 0; + unsigned char buf[info->page_size]; + const off_t failed = (off_t)-1; ++ int fd; ++ struct disk_dump_header *dh = info->dh_memory; + +- offset = 0; ++ if (info->flag_refiltering) { ++ fd = info->fd_memory; ++ base = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size) * dh->block_size; ++ base += info->len_bitmap / 2; ++ } else { ++ fd = info->bitmap1->fd; ++ base = info->bitmap1->offset; ++ } + while (offset < (info->len_bitmap / 2)) { +- if (lseek(info->bitmap1->fd, info->bitmap1->offset + offset, +- SEEK_SET) == failed) { ++ if (lseek(fd, base + offset, SEEK_SET) == failed) { + ERRMSG("Can't seek the bitmap(%s). %s\n", + info->name_bitmap, strerror(errno)); + return FALSE; + } +- if (read(info->bitmap1->fd, buf, sizeof(buf)) != sizeof(buf)) { ++ if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { + ERRMSG("Can't read the dump memory(%s). %s\n", + info->name_memory, strerror(errno)); + return FALSE; +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.3-disable-kexec-test.patch b/SOURCES/kexec-tools-2.0.3-disable-kexec-test.patch deleted file mode 100644 index 6fc73f2..0000000 --- a/SOURCES/kexec-tools-2.0.3-disable-kexec-test.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git kexec-tools-2.0.3/kexec_test/Makefile kexec-tools-2.0.3/kexec_test/Makefile -index fec6210..2ed4d51 100644 ---- kexec-tools-2.0.3/kexec_test/Makefile -+++ kexec-tools-2.0.3/kexec_test/Makefile -@@ -8,12 +8,6 @@ dist += kexec_test/Makefile $(KEXEC_TEST_SRCS) \ - kexec_test/x86-setup-legacy-pic.S - - BUILD_KEXEC_TEST = no --ifeq ($(ARCH),i386) --BUILD_KEXEC_TEST = yes --endif --ifeq ($(ARCH),x86_64) --BUILD_KEXEC_TEST = yes --endif - - ifeq ($(BUILD_KEXEC_TEST),yes) - diff --git a/SOURCES/mkdumprd b/SOURCES/mkdumprd index 719633d..ee0ea6b 100644 --- a/SOURCES/mkdumprd +++ b/SOURCES/mkdumprd @@ -35,7 +35,7 @@ is_wdt_addition_needed [[ $? -eq 0 ]] && WDTCFG="-a watchdog" extra_modules="" -dracut_args=("--hostonly" "--hostonly-cmdline" "--hostonly-i18n" "-o" "plymouth dash resume ifcfg" $WDTCFG) +dracut_args=("--hostonly" "--hostonly-cmdline" "--hostonly-i18n" "--hostonly-mode" "strict" "-o" "plymouth dash resume ifcfg" $WDTCFG) OVERRIDE_RESETTABLE=0 add_dracut_arg() { diff --git a/SOURCES/supported-kdump-targets.txt b/SOURCES/supported-kdump-targets.txt index b5fd08c..c761489 100644 --- a/SOURCES/supported-kdump-targets.txt +++ b/SOURCES/supported-kdump-targets.txt @@ -42,6 +42,9 @@ storage: hardware RAID (cciss, hpsa, megaraid_sas, mpt2sas, aacraid) SCSI/SATA disks iSCSI HBA (all offload) + hardware FCoE (qla2xxx, lpfc, bfa) + software FCoE (bnx2fc, fcoe/ixgbe) (Extra configuration required, + please read "Note on FCoE" section below) network: Hardware using kernel modules: (tg3, igb, ixgbe, sfc, e1000e, bna, @@ -61,7 +64,6 @@ hypervisor: filesystem: ext[234] - btrfs xfs nfs @@ -92,6 +94,9 @@ network: Infiniband (IB) vlan over bridge/team +filesystem: + btrfs + Unknown/tech-preview -------------------- storage: @@ -102,6 +107,21 @@ hypervisor: Hyper-V 2012 +Note on FCoE +===================== +If you are trying to dump to a software FCoE target, you may encounter OOM +issue, because some software FCoE requires more memory to work. In such case, +you may need to increase the kdump reserved memory size in "crashkernel=" +kernel parameter. + +By default, RHEL systems have "crashkernel=auto" in kernel boot arguments. +The auto reserved memory size is designed to balance the coverage of use cases +and an acceptable memory overhead, so not every use case could fit in, software +FCoE is one of the case. + +For hardware FCoE, kdump should work naturally as firmware will do the +initialization job. The capture kernel and kdump tools will run just fine. + Useful Links ============ [1] RHEL6: Enabling kdump for full-virt (HVM) Xen DomU diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec index 260d4d3..64b0d35 100644 --- a/SPECS/kexec-tools.spec +++ b/SPECS/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools Version: 2.0.15 -Release: 13%{?dist}.2 +Release: 21%{?dist} License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component. @@ -25,7 +25,7 @@ Source21: kdump-in-cluster-environment.txt Source22: supported-kdump-targets.txt Source23: kdump-dep-generator.sh Source24: kdump-lib-initramfs.sh -Source25: kdump-anaconda-addon-003-23-g80e78fb.tar.gz +Source25: kdump-anaconda-addon-003-29-g4c517c5.tar.gz Source26: kdump.sysconfig.ppc64le Source27: kdump.sysconfig.aarch64 Source28: kdumpctl.8 @@ -47,8 +47,8 @@ Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units Requires(pre): coreutils sed zlib -Requires: dracut >= 033-522 -Requires: dracut-network >= 033-522 +Requires: dracut >= 033-552 +Requires: dracut-network >= 033-552 Requires: ethtool BuildRequires: zlib-devel zlib zlib-static elfutils-devel-static glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel BuildRequires: pkgconfig intltool gettext @@ -81,6 +81,7 @@ Patch304: kexec-tools-2.0.15-ppc64-fix-leak-while-checking-for-cohere.patch Patch305: kexec-tools-2.0.15-makedumpfile-ppc64-get-the-info-of-mem-reserved-for-.patch Patch306: kexec-tools-2.0.15-makedumpfile-ppc64-set-page_offset-in-get_versiondep.patch + # # Patches 401 through 500 are meant for s390 kexec-tools enablement # @@ -94,7 +95,6 @@ Patch306: kexec-tools-2.0.15-makedumpfile-ppc64-set-page_offset-in-get_versionde # # Patches 701 onward are generic patches # -Patch701: kexec-tools-2.0.3-disable-kexec-test.patch Patch702: kexec-tools-2.0.15-makedumpfile-Fix-SECTION_MAP_MASK-for-kernel-v.13.patch Patch703: kexec-tools-2.0.15-makedumpfile-Support-symbol-__cpu_online_mask.patch Patch704: kexec-tools-2.0.15-makedumpfile-Introduce-vtop4_x86_64_pagetable.patch @@ -107,6 +107,15 @@ Patch710: kexec-tools-2.0.15-makedumpfile-Fix-physical-to-virtual-conversion-in- Patch711: kexec-tools-2.0.15-makedumpfile-sadump-Fix-a-problem-of-PTI-enabled-kernel.patch Patch712: kexec-tools-2.0.15-makedumpfile-PATCH-Support-newer-kernels.patch Patch713: kexec-tools-2.0.15-makedumpfile-fix-for-hugepages-filtering.patch +Patch714: kexec-tools-2.0.15-makedumpfile-Add-a-new-helper-file-tools.c-that-provides-some-use.patch +Patch715: kexec-tools-2.0.15-makedumpfile-arm64-Add-support-to-read-symbols-like-_stext-from-p.patch +Patch716: kexec-tools-2.0.15-makedumpfile-Documentation-Update-documentation-regarding-mem-usa.patch +Patch717: kexec-tools-2.0.15-makedumpfile-arm64-Fix-calculation-of-page_offset-in-case-we-are-.patch +Patch718: kexec-tools-2.0.15-makedumpfile-Fix-array-index-out-of-bound-exception.patch +Patch719: kexec-tools-2.0.15-makedumpfile-Use-integer-arithmetics-for-th.patch +Patch720: kexec-tools-2.0.15-makedumpfile-Use-monotonic-clock-to-calculate-ETA-and-s.patch +Patch721: kexec-tools-2.0.15-makedumpfile-Check-if-clock_gettime-requires-lrt.patch +Patch722: kexec-tools-2.0.15-makedumpfile-when-refiltering-initialize-refiltered-bitm.patch # @@ -154,7 +163,6 @@ tar -z -x -v -f %{SOURCE25} %patch304 -p1 %patch305 -p1 %patch306 -p1 -%patch701 -p1 %patch702 -p1 %patch703 -p1 %patch704 -p1 @@ -167,6 +175,15 @@ tar -z -x -v -f %{SOURCE25} %patch711 -p1 %patch712 -p1 %patch713 -p1 +%patch714 -p1 +%patch715 -p1 +%patch716 -p1 +%patch717 -p1 +%patch718 -p1 +%patch719 -p1 +%patch720 -p1 +%patch721 -p1 +%patch722 -p1 %ifarch ppc @@ -210,7 +227,7 @@ make -C makedumpfile-1.6.2 LDFLAGS="-I../eppic/libeppic -L../eppic/libeppic" epp make -C kdump-anaconda-addon/po %install -make install DESTDIR=$RPM_BUILD_ROOT +mkdir -p -m755 $RPM_BUILD_ROOT/sbin mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig mkdir -p -m755 $RPM_BUILD_ROOT%{_localstatedir}/crash mkdir -p -m755 $RPM_BUILD_ROOT%{_mandir}/man8/ @@ -224,6 +241,11 @@ mkdir -p -m755 $RPM_BUILD_ROOT%{_libdir} mkdir -p -m755 $RPM_BUILD_ROOT%{_prefix}/lib/kdump install -m 755 %{SOURCE1} $RPM_BUILD_ROOT%{_bindir}/kdumpctl +install -m 755 build/sbin/kexec $RPM_BUILD_ROOT/sbin/kexec +install -m 755 build/sbin/vmcore-dmesg $RPM_BUILD_ROOT/sbin/vmcore-dmesg +install -m 644 build/man/man8/kexec.8 $RPM_BUILD_ROOT%{_mandir}/man8/ +install -m 644 build/man/man8/vmcore-dmesg.8 $RPM_BUILD_ROOT%{_mandir}/man8/ + SYSCONFIG=$RPM_SOURCE_DIR/kdump.sysconfig.%{_target_cpu} [ -f $SYSCONFIG ] || SYSCONFIG=$RPM_SOURCE_DIR/kdump.sysconfig.%{_arch} [ -f $SYSCONFIG ] || SYSCONFIG=$RPM_SOURCE_DIR/kdump.sysconfig @@ -354,7 +376,12 @@ do done %files -/sbin/* +/sbin/kexec +/sbin/vmcore-dmesg +%ifarch %{ix86} x86_64 ia64 ppc64 s390x ppc64le aarch64 +/sbin/makedumpfile +%endif +/sbin/mkdumprd %{_bindir}/* %{_datadir}/kdump %{_prefix}/lib/kdump @@ -368,7 +395,13 @@ done %endif %{dracutlibdir}/modules.d/* %dir %{_localstatedir}/crash -%{_mandir}/man8/* +%{_mandir}/man8/kdumpctl.8.gz +%{_mandir}/man8/kexec.8.gz +%ifarch %{ix86} x86_64 ia64 ppc64 s390x ppc64le aarch64 +%{_mandir}/man8/makedumpfile.8.gz +%endif +%{_mandir}/man8/mkdumprd.8.gz +%{_mandir}/man8/vmcore-dmesg.8.gz %{_mandir}/man5/* %{_unitdir}/kdump.service %{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh @@ -392,10 +425,49 @@ done %doc %changelog -* Thu Aug 16 2018 Pingfan Liu 2.0.15-13.2 +* Thu Aug 30 2018 Pingfan Liu 2.0.15-21 +- kexec/ppc64: add support to parse ibm, dynamic-memory-v2 + +* Wed Aug 15 2018 Pingfan Liu 2.0.15-20 +- makedumpfile: when refiltering, initialize refiltered bitmap2 from the kdump file's bitmap2 +- dracut-module-setup: Fix DRM module inclusion test for hyper-v +- kdumpctl: remove some cmdline inheritage from 1st kernel +- kdump-lib.sh:get_loaded_kernel_modules() Fix missing newline +- kdumpctl: Rebuild initramfs if loaded kernel modules changed (V2) +- Revert "kdumpctl: Rebuild initramfs if loaded kernel modules changed" +- dracut-module-setup: Fix test for inclusion of DRM modules + +* Wed Aug 01 2018 Pingfan Liu 2.0.15-19 +kexec-tools.spec: Drop kexec-tools-2.0.3-disable-kexec-test.patch +Remove obsolete kdump tool + +* Tue Jul 31 2018 Pingfan Liu 2.0.15-18 +kdumpctl: Rebuild initramfs if loaded kernel modules changed +dracut-module-setup.sh: don't include multipath-hostonly +Add document to declare FCoE support (V2) +Revert "Add document to declare FCoE support" +Add document to declare FCoE support +makedumpfile: fix makedumpfile Not tainted in 2nd kernel + +* Tue Jul 10 2018 Pingfan Liu 2.0.15-17 +- arm64: Fix calculation of page_offset in case we are running cases other than mem-usage + +* Fri Jun 22 2018 Pingfan Liu 2.0.15-16 +- kexec/ppc64: add support to parse ibm, dynamic-memory-v2 + +* Thu Jun 21 2018 Pingfan Liu 2.0.15-15 +- dracut-module-setup.sh: pass ip=either6 param for ipv6 +- dracut-module-setup.sh: install /etc/hosts when using fence_kdump +- update kdump-anaconda-addon-003-29-g4c517c5.tar.gz + +* Tue Jun 19 2018 Pingfan Liu 2.0.15-14 - kdumpctl: Remove 'netroot' and 'iscsi initiator' entries from kdump cmdline - -* Tue Jun 26 2018 Pingfan Liu 2.0.15-13.1 +- doc: remove btrfs from supported filesystems list +- Update kdump anaconda addon +- makedumpfile/arm64: Add '--mem-usage' support +- Fix warning about persistent device name not found. +- kdumpctl: Check the modification time of core_collector +- kdump.sysconfig.x86_64: Remove 'notsc' from KDUMP_COMMANDLINE_REMOVE - makedumpfile: fix for hugepages filtering * Thu Feb 8 2018 Pingfan Liu 2.0.15-13