Blame SOURCES/kexec-tools-2.0.8-makedumpfile-Make-the-incomplete-dumpfile-generated-.patch

a6d77e
Return-Path: yishimat@redhat.com
a6d77e
Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO
a6d77e
 zmta03.collab.prod.int.phx2.redhat.com) (10.5.81.10) by
a6d77e
 zmail24.collab.prod.int.phx2.redhat.com with LMTP; Thu, 2 Jul 2015 01:14:45
a6d77e
 -0400 (EDT)
a6d77e
Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23])
a6d77e
	by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 4A6B242574;
a6d77e
	Thu,  2 Jul 2015 01:14:45 -0400 (EDT)
a6d77e
Received: from [10.3.112.13] ([10.3.112.13])
a6d77e
	by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t625EgU7006706;
a6d77e
	Thu, 2 Jul 2015 01:14:43 -0400
a6d77e
Subject: [RHEL7.2 PATCH resend v3 2/4] Make the incomplete dumpfile generated
a6d77e
 by ENOSPC error analyzable.
a6d77e
To: kexec-kdump-list@redhat.com
a6d77e
References: <55929BD5.7050709@redhat.com> <5594C856.6050503@redhat.com>
a6d77e
Cc: Minfei Huang <mhuang@redhat.com>, bhe@redhat.com, yishimat@redhat.com
a6d77e
From: Yasuaki Ishimatsu <yishimat@redhat.com>
a6d77e
Message-ID: <5594C8C2.8080603@redhat.com>
a6d77e
Date: Thu, 2 Jul 2015 01:14:42 -0400
a6d77e
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101
a6d77e
 Thunderbird/38.0.1
a6d77e
MIME-Version: 1.0
a6d77e
In-Reply-To: <5594C856.6050503@redhat.com>
a6d77e
Content-Type: text/plain; charset=utf-8
a6d77e
Content-Transfer-Encoding: 7bit
a6d77e
X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23
a6d77e
Content-Length: 5485
a6d77e
a6d77e
https://bugzilla.redhat.com/show_bug.cgi?id=1182377
a6d77e
a6d77e
The patch is back ported directory from the following upstream commit:
a6d77e
a6d77e
commit e39216fce9f73759509ec158e39c289e6c211125
a6d77e
Author: Wang Xiao <wangx.fnst@cn.fujitsu.com>
a6d77e
Date:   Mon Oct 20 13:39:03 2014 +0900
a6d77e
a6d77e
    [PATCH v4 2/4] Make the incomplete dumpfile generated by ENOSPC error analyzable.
a6d77e
a6d77e
    Since the incomplete dumpfile generated by ENOSPC error can't be anylyzed
a6d77e
    by crash utility, but sometimes this file may contain important information
a6d77e
    and the panic problem won't be reproduced, then we came up with an idea to
a6d77e
    modify the exist data of the incomplete dumpfile to make it analyzable by
a6d77e
    crash utility. And each of those dumpfiles has a flag to indicate that it
a6d77e
    has been modified. As there are two formats of these dumpfiles, different
a6d77e
    methods and flags are needed to deal with each of them,
a6d77e
a6d77e
    elf:
a6d77e
    This format use the "e_flags" of "elf header" to indicate that it has been
a6d77e
    modified.
a6d77e
a6d77e
    The method of dealing with "kdump-compressed" format dumpfiles is
a6d77e
    implemented
a6d77e
    in the next patch.
a6d77e
a6d77e
    Signed-of-by: Wang Xiao <wangx.fnst@cn.fujitsu.com>
a6d77e
a6d77e
Resolves: rhbz#1182377
a6d77e
Signed-off-by: Yasuaki Ishimatsu <yishimat@redhat.com>
a6d77e
Acked-by: Minfei Huang <mhuang@redhat.com>
a6d77e
a6d77e
---
a6d77e
 makedumpfile-1.5.7/makedumpfile.c |  115 +++++++++++++++++++++++++++++++++++-
a6d77e
 1 files changed, 111 insertions(+), 4 deletions(-)
a6d77e
a6d77e
diff --git a/makedumpfile-1.5.7/makedumpfile.c b/makedumpfile-1.5.7/makedumpfile.c
a6d77e
index b4d43d8..141d290 100644
a6d77e
--- a/makedumpfile-1.5.7/makedumpfile.c
a6d77e
+++ b/makedumpfile-1.5.7/makedumpfile.c
a6d77e
@@ -24,6 +24,7 @@
a6d77e
 #include <ctype.h>
a6d77e
 #include <sys/time.h>
a6d77e
 #include <limits.h>
a6d77e
+#include <assert.h>
a6d77e
a6d77e
 struct symbol_table	symbol_table;
a6d77e
 struct size_table	size_table;
a6d77e
@@ -3768,6 +3769,93 @@ read_flat_data_header(struct makedumpfile_data_header *fdh)
a6d77e
 }
a6d77e
a6d77e
 int
a6d77e
+reserve_diskspace(int fd, off_t start_offset, off_t end_offset, char *file_name)
a6d77e
+{
a6d77e
+	size_t buf_size;
a6d77e
+	char *buf = NULL;
a6d77e
+
a6d77e
+	int ret = FALSE;
a6d77e
+
a6d77e
+	assert(start_offset < end_offset);
a6d77e
+	buf_size = end_offset - start_offset;
a6d77e
+
a6d77e
+	if ((buf = malloc(buf_size)) == NULL) {
a6d77e
+		ERRMSG("Can't allocate memory for the size of reserved diskspace. %s\n",
a6d77e
+		       strerror(errno));
a6d77e
+		return FALSE;
a6d77e
+	}
a6d77e
+
a6d77e
+	memset(buf, 0, buf_size);
a6d77e
+	if (!write_buffer(fd, start_offset, buf, buf_size, file_name))
a6d77e
+		goto out;
a6d77e
+
a6d77e
+	ret = TRUE;
a6d77e
+out:
a6d77e
+	if (buf != NULL) {
a6d77e
+		free(buf);
a6d77e
+	}
a6d77e
+
a6d77e
+	return ret;
a6d77e
+}
a6d77e
+
a6d77e
+#define DUMP_ELF_INCOMPLETE 0x1
a6d77e
+int
a6d77e
+check_and_modify_elf_headers(char *filename)
a6d77e
+{
a6d77e
+	int fd, ret = FALSE;
a6d77e
+	Elf64_Ehdr ehdr64;
a6d77e
+	Elf32_Ehdr ehdr32;
a6d77e
+
a6d77e
+	if ((fd = open(filename, O_RDWR)) < 0) {
a6d77e
+		ERRMSG("Can't open the dump file(%s). %s\n",
a6d77e
+		       filename, strerror(errno));
a6d77e
+		return FALSE;
a6d77e
+	}
a6d77e
+
a6d77e
+	/*
a6d77e
+	 * the is_elf64_memory() function still can be used.
a6d77e
+	 */
a6d77e
+	/*
a6d77e
+	 * Set the incomplete flag to the e_flags of elf header.
a6d77e
+	 */
a6d77e
+	if (is_elf64_memory()) { /* ELF64 */
a6d77e
+		if (!get_elf64_ehdr(fd, filename, &ehdr64)) {
a6d77e
+			ERRMSG("Can't get ehdr64.\n");
a6d77e
+			goto out_close_file;
a6d77e
+		}
a6d77e
+		ehdr64.e_flags |= DUMP_ELF_INCOMPLETE;
a6d77e
+		if (!write_buffer(fd, 0, &ehdr64, sizeof(Elf64_Ehdr), filename))
a6d77e
+			goto out_close_file;
a6d77e
+
a6d77e
+	} else { /* ELF32 */
a6d77e
+		if (!get_elf32_ehdr(fd, filename, &ehdr32)) {
a6d77e
+			ERRMSG("Can't get ehdr32.\n");
a6d77e
+			goto out_close_file;
a6d77e
+		}
a6d77e
+		ehdr32.e_flags |= DUMP_ELF_INCOMPLETE;
a6d77e
+		if (!write_buffer(fd, 0, &ehdr32, sizeof(Elf32_Ehdr), filename))
a6d77e
+			goto out_close_file;
a6d77e
+
a6d77e
+	}
a6d77e
+	ret = TRUE;
a6d77e
+out_close_file:
a6d77e
+	if (close(fd) < 0) {
a6d77e
+		ERRMSG("Can't close the dump file(%s). %s\n",
a6d77e
+		       filename, strerror(errno));
a6d77e
+	}
a6d77e
+	return ret;
a6d77e
+}
a6d77e
+
a6d77e
+int
a6d77e
+check_and_modify_headers()
a6d77e
+{
a6d77e
+	if (info->flag_elf_dumpfile)
a6d77e
+		return check_and_modify_elf_headers(info->name_dumpfile);
a6d77e
+	return FALSE;
a6d77e
+}
a6d77e
+
a6d77e
+
a6d77e
+int
a6d77e
 rearrange_dumpdata(void)
a6d77e
 {
a6d77e
 	int read_size, tmp_read_size;
a6d77e
@@ -5498,6 +5586,13 @@ write_elf_header(struct cache_data *cd_header)
a6d77e
 	size_note          = note.p_filesz;
a6d77e
a6d77e
 	/*
a6d77e
+	 * Reserve a space to store the whole program headers.
a6d77e
+	 */
a6d77e
+	if (!reserve_diskspace(cd_header->fd, cd_header->offset,
a6d77e
+				offset_note_dumpfile, cd_header->file_name))
a6d77e
+		goto out;
a6d77e
+
a6d77e
+	/*
a6d77e
 	 * Modify the note size in PT_NOTE header to accomodate eraseinfo data.
a6d77e
 	 * Eraseinfo will be written later.
a6d77e
 	 */
a6d77e
@@ -8015,10 +8110,10 @@ writeout_dumpfile(void)
a6d77e
 			goto out;
a6d77e
 		if (info->flag_cyclic) {
a6d77e
 			if (!write_elf_pages_cyclic(&cd_header, &cd_page))
a6d77e
-				goto out;
a6d77e
+				goto write_cache_enospc;
a6d77e
 		} else {
a6d77e
 			if (!write_elf_pages(&cd_header, &cd_page))
a6d77e
-				goto out;
a6d77e
+				goto write_cache_enospc;
a6d77e
 		}
a6d77e
 		if (!write_elf_eraseinfo(&cd_header))
a6d77e
 			goto out;
a6d77e
@@ -8045,6 +8140,11 @@ writeout_dumpfile(void)
a6d77e
 	}
a6d77e
a6d77e
 	ret = TRUE;
a6d77e
+write_cache_enospc:
a6d77e
+	if ((ret == FALSE) && info->flag_nospace && !info->flag_flatten) {
a6d77e
+		if (!write_cache_bufsz(&cd_header))
a6d77e
+			ERRMSG("This dumpfile may lost some important data.\n");
a6d77e
+	}
a6d77e
 out:
a6d77e
 	free_cache_data(&cd_header);
a6d77e
 	free_cache_data(&cd_page);
a6d77e
@@ -8237,8 +8337,15 @@ retry:
a6d77e
 		 * to create a dumpfile with it again.
a6d77e
 		 */
a6d77e
 		num_retry++;
a6d77e
-		if ((info->dump_level = get_next_dump_level(num_retry)) < 0)
a6d77e
- 			return FALSE;
a6d77e
+		if ((info->dump_level = get_next_dump_level(num_retry)) < 0) {
a6d77e
+			if (!info->flag_flatten) {
a6d77e
+				if (check_and_modify_headers())
a6d77e
+					MSG("This is an incomplete dumpfile,"
a6d77e
+						" but might analyzable.\n");
a6d77e
+			}
a6d77e
+
a6d77e
+			return FALSE;
a6d77e
+		}
a6d77e
 		MSG("Retry to create a dumpfile by dump_level(%d).\n",
a6d77e
 		    info->dump_level);
a6d77e
 		if (!delete_dumpfile())
a6d77e
-- 
a6d77e
1.7.1
a6d77e