All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] makedumpfile: add userinfo elf section 0/4]
@ 2021-12-01 13:47 Ivan Khoronzhuk
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 1/4] makedumpfile: rename check_dump_file() on check_file_is_writable() Ivan Khoronzhuk
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Ivan Khoronzhuk @ 2021-12-01 13:47 UTC (permalink / raw)
  To: k-hagio-ab, kexec; +Cc: Ivan Khoronzhuk

These patchset suggests feature to add user specific information along
with dumpfile. One of usecases could be a platform build information
containing dubug file addresses, sources of daily build, some
platform related information and more, it's gracefully simplifies
debugging process, since an engineer doesn't need to spend time on
finding to which platform this core file is related, where to get
debugging counter part and so on. As user info can be added along with
dumpfile it frees platform from creating tar achieve spending doubled
space or using specific tools. Since this information is sorted and
selected by user it can't be standardized and should be placed in some
special generic section. This patchset roughly proposes the variant when
user information is placed/retrieved as subsection of note elf
section.

Ivan Khoronzhuk (4):
  makedumpfile: rename check_dump_file() on check_file_is_writable()
  elf: add new "userinfo" ELF section to traverse debug information
  elf_info: make int note_descsz() and offset_next_note() public
  elf: add ability to read the userinfo data from note segment

 elf_info.c     |   4 +-
 elf_info.h     |   5 +
 makedumpfile.c | 393 ++++++++++++++++++++++++++++++++++++++++++++++++-
 makedumpfile.h |  12 ++
 4 files changed, 404 insertions(+), 10 deletions(-)

-- 
2.20.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC makedumpfile: add userinfo elf section 1/4] makedumpfile: rename check_dump_file() on check_file_is_writable()
  2021-12-01 13:47 [RFC PATCH] makedumpfile: add userinfo elf section 0/4] Ivan Khoronzhuk
@ 2021-12-01 13:47 ` Ivan Khoronzhuk
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 2/4] elf: add new "userinfo" ELF section to traverse debug information Ivan Khoronzhuk
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Ivan Khoronzhuk @ 2021-12-01 13:47 UTC (permalink / raw)
  To: k-hagio-ab, kexec; +Cc: Ivan Khoronzhuk

Make function for checking the file can be written to be more flex
by renaming check_dump_file() on check_file_is_writable().

Signed-off-by: Ivan Khoronzhuk <ikhoronz@cisco.com>
---
 makedumpfile.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 3d1d412..6b62b92 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1397,7 +1397,7 @@ open_dump_file(void)
 }
 
 int
-check_dump_file(const char *path)
+check_file_is_writable(const char *path)
 {
 	char *err_str;
 
@@ -1410,7 +1410,7 @@ check_dump_file(const char *path)
 	} else {
 		err_str = strerror(EEXIST);
 	}
-	ERRMSG("Can't open the dump file (%s). %s\n", path, err_str);
+	ERRMSG("Can't open the file (%s). %s\n", path, err_str);
 	return FALSE;
 }
 
@@ -11954,7 +11954,7 @@ main(int argc, char *argv[])
 		if (info->flag_check_params)
 			goto check_ok;
 
-		if (!check_dump_file(info->name_dumpfile))
+		if (!check_file_is_writable(info->name_dumpfile))
 			goto out;
 
 		if (!open_files_for_rearranging_dumpdata())
@@ -11977,7 +11977,7 @@ main(int argc, char *argv[])
 		if (info->flag_check_params)
 			goto check_ok;
 
-		if (!check_dump_file(info->name_dumpfile))
+		if (!check_file_is_writable(info->name_dumpfile))
 			goto out;
 
 		if (!reassemble_dumpfile())
@@ -11993,7 +11993,7 @@ main(int argc, char *argv[])
 		if (info->flag_check_params)
 			goto check_ok;
 
-		if (!check_dump_file(info->name_dumpfile))
+		if (!check_file_is_writable(info->name_dumpfile))
 			goto out;
 		if (!dump_dmesg())
 			goto out;
@@ -12033,11 +12033,11 @@ main(int argc, char *argv[])
 		if (info->flag_split) {
 			for (i = 0; i < info->num_dumpfile; i++) {
 				SPLITTING_FD_BITMAP(i) = -1;
-				if (!check_dump_file(SPLITTING_DUMPFILE(i)))
+				if (!check_file_is_writable(SPLITTING_DUMPFILE(i)))
 					goto out;
 			}
 		} else {
-			if (!check_dump_file(info->name_dumpfile))
+			if (!check_file_is_writable(info->name_dumpfile))
 				goto out;
 		}
 
-- 
2.20.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC makedumpfile: add userinfo elf section 2/4] elf: add new "userinfo" ELF section to traverse debug information
  2021-12-01 13:47 [RFC PATCH] makedumpfile: add userinfo elf section 0/4] Ivan Khoronzhuk
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 1/4] makedumpfile: rename check_dump_file() on check_file_is_writable() Ivan Khoronzhuk
@ 2021-12-01 13:47 ` Ivan Khoronzhuk
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 3/4] elf_info: make int note_descsz() and offset_next_note() public Ivan Khoronzhuk
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Ivan Khoronzhuk @ 2021-12-01 13:47 UTC (permalink / raw)
  To: k-hagio-ab, kexec; +Cc: Ivan Khoronzhuk

It's only for elf dumpfile, for compressed version should be added in
separate file. It adds new note section to the NOTE segment.

Signed-off-by: Ivan Khoronzhuk <ikhoronz@cisco.com>
---
 elf_info.h     |   3 +
 makedumpfile.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++-
 makedumpfile.h |  10 ++++
 3 files changed, 167 insertions(+), 1 deletion(-)

diff --git a/elf_info.h b/elf_info.h
index d5416b3..ca96935 100644
--- a/elf_info.h
+++ b/elf_info.h
@@ -25,6 +25,9 @@
 #define ERASEINFO_NOTE_NAME		"ERASEINFO"
 #define ERASEINFO_NOTE_NAME_BYTES	(sizeof(ERASEINFO_NOTE_NAME))
 
+#define USERINFO_NOTE_NAME		"USERINFO"
+#define USERINFO_NOTE_NAME_BYTES	(sizeof(USERINFO_NOTE_NAME))
+
 #define MAX_SIZE_NHDR	MAX(sizeof(Elf64_Nhdr), sizeof(Elf32_Nhdr))
 
 int get_elf64_phdr(int fd, char *filename, int index, Elf64_Phdr *phdr);
diff --git a/makedumpfile.c b/makedumpfile.c
index 6b62b92..6b6b4d2 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1396,6 +1396,23 @@ open_dump_file(void)
 	return TRUE;
 }
 
+int
+open_userinfo_file(void)
+{
+	FILE *file_userinfo;
+
+	if (info->flag_flatten || info->flag_dry_run ||
+	    !info->flag_insert_userinfo) {
+		file_userinfo = NULL;
+	} else if ((file_userinfo = fopen(info->name_userinfo, "r")) < 0) {
+		ERRMSG("Can't open the userinfo file(%s). %s\n",
+		    info->name_userinfo, strerror(errno));
+		return FALSE;
+	}
+	info->file_userinfo = file_userinfo;
+	return TRUE;
+}
+
 int
 check_file_is_writable(const char *path)
 {
@@ -7080,12 +7097,26 @@ write_elf_phdr(struct cache_data *cd_hdr, Elf64_Phdr *load)
 	return TRUE;
 }
 
+unsigned long
+get_size_userinfo(void)
+{
+	unsigned long size_userinfo = 0;
+
+	if (info->file_userinfo) {
+		fseek(info->file_userinfo, 0, SEEK_END);
+		size_userinfo = ftell(info->file_userinfo);
+		fseek(info->file_userinfo, 0, SEEK_SET);
+	}
+
+	return size_userinfo;
+}
+
 int
 write_elf_header(struct cache_data *cd_header)
 {
 	int i, num_loads_dumpfile, phnum;
 	off_t offset_note_memory, offset_note_dumpfile;
-	size_t size_note, size_eraseinfo = 0;
+	size_t size_note, size_eraseinfo = 0, size_userinfo;
 	Elf64_Ehdr ehdr64;
 	Elf32_Ehdr ehdr32;
 	Elf64_Phdr note;
@@ -7148,6 +7179,13 @@ write_elf_header(struct cache_data *cd_header)
 	 */
 	info->size_elf_eraseinfo = size_eraseinfo;
 
+	size_userinfo = get_size_userinfo();
+	/*
+	 * Store the size_userinfo for later use in write_elf_userinfo()
+	 * function.
+	 */
+	info->size_elf_userinfo = size_userinfo;
+
 	/*
 	 * Write a PT_NOTE header.
 	 */
@@ -7224,6 +7262,19 @@ write_elf_header(struct cache_data *cd_header)
 					roundup(size_eraseinfo, 4);
 	}
 
+	/*
+	 * Modify the note size in PT_NOTE header to accomodate userinfo data.
+	 * Userinfo will be written later.
+	 */
+	if (info->size_elf_userinfo) {
+		if (is_elf64_memory())
+			note.p_filesz += sizeof(Elf64_Nhdr);
+		else
+			note.p_filesz += sizeof(Elf32_Nhdr);
+		note.p_filesz += roundup(USERINFO_NOTE_NAME_BYTES, 4) +
+					roundup(size_userinfo, 4);
+	}
+
 	if (!write_elf_phdr(cd_header, &note))
 		goto out;
 
@@ -8892,6 +8943,27 @@ out:
 	return ret;
 }
 
+/*
+ * Traverse through userinfo nodes and write it to the o/p dumpfile.
+ */
+int
+write_userinfo(struct cache_data *cd_page)
+{
+	char buf[BUFSIZE_FGETS];
+	int len;
+
+	while (fgets(buf, BUFSIZE_FGETS, info->file_userinfo)) {
+		len = strlen(buf);
+		if (!len)
+			break;
+
+		if (!write_cache(cd_page, buf, len))
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
 int
 write_elf_eraseinfo(struct cache_data *cd_header)
 {
@@ -8957,6 +9029,64 @@ write_elf_eraseinfo(struct cache_data *cd_header)
 	return TRUE;
 }
 
+static int
+write_elf_userinfo(struct cache_data *cd_header)
+{
+	char note[MAX_SIZE_NHDR];
+	char buf[USERINFO_NOTE_NAME_BYTES + 4];
+	off_t offset_userinfo;
+	unsigned long note_header_size, size_note;
+
+	DEBUG_MSG("user info size: %lu\n", info->size_elf_userinfo);
+
+	if (!info->size_elf_userinfo)
+		return TRUE;
+
+	DEBUG_MSG("Writing user info...\n");
+
+	/* calculate the userinfo ELF note offset */
+	get_pt_note(NULL, &size_note);
+	cd_header->offset = info->offset_note_dumpfile +
+				roundup(size_note, 4) +
+				roundup(info->size_elf_eraseinfo, 4);
+
+	/* Write userinfo ELF note header. */
+	memset(note, 0, sizeof(note));
+	if (is_elf64_memory()) {
+		Elf64_Nhdr *nh = (Elf64_Nhdr *)note;
+
+		note_header_size = sizeof(Elf64_Nhdr);
+		nh->n_namesz = USERINFO_NOTE_NAME_BYTES;
+		nh->n_descsz = info->size_elf_userinfo;
+		nh->n_type = 0;
+	} else {
+		Elf32_Nhdr *nh = (Elf32_Nhdr *)note;
+
+		note_header_size = sizeof(Elf32_Nhdr);
+		nh->n_namesz = USERINFO_NOTE_NAME_BYTES;
+		nh->n_descsz = info->size_elf_userinfo;
+		nh->n_type = 0;
+	}
+	if (!write_cache(cd_header, note, note_header_size))
+		return FALSE;
+
+	/* Write userinfo Note name */
+	memset(buf, 0, sizeof(buf));
+	memcpy(buf, USERINFO_NOTE_NAME, USERINFO_NOTE_NAME_BYTES);
+	if (!write_cache(cd_header, buf,
+				roundup(USERINFO_NOTE_NAME_BYTES, 4)))
+		return FALSE;
+
+	offset_userinfo = cd_header->offset;
+	if (!write_userinfo(cd_header))
+		return FALSE;
+
+	DEBUG_MSG("offset_userinfo: %llx, size_userinfo: %ld\n",
+		(unsigned long long)offset_userinfo, info->size_elf_userinfo);
+
+	return TRUE;
+}
+
 int
 write_kdump_eraseinfo(struct cache_data *cd_page)
 {
@@ -9260,6 +9390,18 @@ close_dump_file(void)
 	info->fd_dumpfile = -1;
 }
 
+void
+close_userinfo_file(void)
+{
+	if (info->flag_flatten || info->flag_dry_run)
+		return;
+
+	if (fclose(info->file_userinfo) < 0)
+		ERRMSG("Can't close the userinfo file(%s). %s\n",
+		    info->name_userinfo, strerror(errno));
+	info->file_userinfo = NULL;
+}
+
 void
 close_dump_bitmap(void)
 {
@@ -10193,6 +10335,9 @@ writeout_dumpfile(void)
 	if (!open_dump_file())
 		return FALSE;
 
+	if (!open_userinfo_file())
+		return FALSE;
+
 	if (info->flag_flatten) {
 		if (!write_start_flat_header())
 			return FALSE;
@@ -10211,6 +10356,8 @@ writeout_dumpfile(void)
 				goto write_cache_enospc;
 		if (!write_elf_eraseinfo(&cd_header))
 			goto out;
+		if (!write_elf_userinfo(&cd_header))
+			goto out;
 	} else {
 		if (!write_kdump_header())
 			goto out;
@@ -10235,6 +10382,7 @@ out:
 	free_cache_data(&cd_page);
 
 	close_dump_file();
+	close_userinfo_file();
 
 	if ((ret == FALSE) && info->flag_nospace)
 		return NOSPACE;
@@ -11693,6 +11841,7 @@ static struct option longopts[] = {
 	{"check-params", no_argument, NULL, OPT_CHECK_PARAMS},
 	{"dry-run", no_argument, NULL, OPT_DRY_RUN},
 	{"show-stats", no_argument, NULL, OPT_SHOW_STATS},
+	{"userinfo", required_argument, NULL, OPT_USERINFO},
 	{0, 0, 0, 0}
 };
 
@@ -11821,6 +11970,10 @@ main(int argc, char *argv[])
 		case OPT_COMPRESS_ZSTD:
 			info->flag_compress = DUMP_DH_COMPRESSED_ZSTD;
 			break;
+		case OPT_USERINFO:
+			info->flag_insert_userinfo = 1;
+			info->name_userinfo = optarg;
+			break;
 		case OPT_XEN_PHYS_START:
 			info->xen_phys_start = strtoul(optarg, NULL, 0);
 			break;
diff --git a/makedumpfile.h b/makedumpfile.h
index d583249..b28b0a5 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1359,6 +1359,7 @@ struct DumpInfo {
 	int		flag_elf_dumpfile;   /* flag of creating ELF dumpfile */
 	int		flag_generate_vmcoreinfo;/* flag of generating vmcoreinfo file */
 	int		flag_read_vmcoreinfo;    /* flag of reading vmcoreinfo file */
+	int		flag_insert_userinfo;    /* flag of inserting userinfo file into ELF note section */
 	int		flag_show_usage;     /* flag of showing usage */
 	int		flag_show_version;   /* flag of showing version */
 	int		flag_check_params;   /* only check parameters */
@@ -1469,6 +1470,9 @@ struct DumpInfo {
 	int			fd_xen_syms;
 	char			*name_xen_syms;
 
+	FILE			*file_userinfo;
+	char			*name_userinfo;
+
 	/*
 	 * Dump memory image info:
 	 */
@@ -1512,6 +1516,11 @@ struct DumpInfo {
 	 */
 	unsigned long           size_elf_eraseinfo;
 
+	/*
+	 * userinfo in dump memory image info:
+	 */
+	unsigned long           size_elf_userinfo;
+
 	/*
 	 * for Xen extraction
 	 */
@@ -2481,6 +2490,7 @@ struct elf_prstatus {
 #define OPT_EXCLUDE_XEN_DOM     'X'
 #define OPT_VMLINUX             'x'
 #define OPT_COMPRESS_ZSTD       'z'
+#define OPT_USERINFO            'u'
 #define OPT_START               256
 #define OPT_SPLIT               OPT_START+0
 #define OPT_REASSEMBLE          OPT_START+1
-- 
2.20.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC makedumpfile: add userinfo elf section 3/4] elf_info: make int note_descsz() and offset_next_note() public
  2021-12-01 13:47 [RFC PATCH] makedumpfile: add userinfo elf section 0/4] Ivan Khoronzhuk
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 1/4] makedumpfile: rename check_dump_file() on check_file_is_writable() Ivan Khoronzhuk
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 2/4] elf: add new "userinfo" ELF section to traverse debug information Ivan Khoronzhuk
@ 2021-12-01 13:47 ` Ivan Khoronzhuk
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 4/4] elf: add ability to read the userinfo data from note segment Ivan Khoronzhuk
  2021-12-15  0:58 ` [RFC PATCH] makedumpfile: add userinfo elf section 0/4] HAGIO KAZUHITO(萩尾 一仁)
  4 siblings, 0 replies; 6+ messages in thread
From: Ivan Khoronzhuk @ 2021-12-01 13:47 UTC (permalink / raw)
  To: k-hagio-ab, kexec; +Cc: Ivan Khoronzhuk

These usefule funcgtions are supposed to be reused in makedumfile note
travese procedures.

Signed-off-by: Ivan Khoronzhuk <ikhoronz@cisco.com>
---
 elf_info.c | 4 ++--
 elf_info.h | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/elf_info.c b/elf_info.c
index bc24083..0737b6c 100644
--- a/elf_info.c
+++ b/elf_info.c
@@ -181,7 +181,7 @@ dump_Elf_load(Elf64_Phdr *prog, int num_load)
 	return TRUE;
 }
 
-static off_t
+off_t
 offset_next_note(void *note)
 {
 	off_t offset;
@@ -240,7 +240,7 @@ note_namesz(void *note)
 	return size;
 }
 
-static int
+int
 note_descsz(void *note)
 {
 	int size;
diff --git a/elf_info.h b/elf_info.h
index ca96935..f38605d 100644
--- a/elf_info.h
+++ b/elf_info.h
@@ -74,6 +74,8 @@ int get_nr_cpus(void);
 int has_pt_note(void);
 void set_pt_note(off_t offset, unsigned long size);
 void get_pt_note(off_t *offset, unsigned long *size);
+int note_descsz(void *note);
+off_t offset_next_note(void *note);
 
 int has_vmcoreinfo(void);
 void set_vmcoreinfo(off_t offset, unsigned long size);
-- 
2.20.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC makedumpfile: add userinfo elf section 4/4] elf: add ability to read the userinfo data from note segment
  2021-12-01 13:47 [RFC PATCH] makedumpfile: add userinfo elf section 0/4] Ivan Khoronzhuk
                   ` (2 preceding siblings ...)
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 3/4] elf_info: make int note_descsz() and offset_next_note() public Ivan Khoronzhuk
@ 2021-12-01 13:47 ` Ivan Khoronzhuk
  2021-12-15  0:58 ` [RFC PATCH] makedumpfile: add userinfo elf section 0/4] HAGIO KAZUHITO(萩尾 一仁)
  4 siblings, 0 replies; 6+ messages in thread
From: Ivan Khoronzhuk @ 2021-12-01 13:47 UTC (permalink / raw)
  To: k-hagio-ab, kexec; +Cc: Ivan Khoronzhuk

Previously were added the ability to save userinfo data to separate
ELF note subsection. This patch adds read mechanism.
The command to retrieve user specific information:
makedumpfile -U userinfofile dumpfile.

Signed-off-by: Ivan Khoronzhuk <ikhoronz@cisco.com>
---
 makedumpfile.c | 224 +++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h |   2 +
 2 files changed, 226 insertions(+)

diff --git a/makedumpfile.c b/makedumpfile.c
index 6b6b4d2..0d29b87 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1519,6 +1519,60 @@ open_files_for_generating_vmcoreinfo(void)
 	return TRUE;
 }
 
+int
+open_files_for_generating_userinfo(void)
+{
+	FILE *file_userinfo;
+	int fd;
+
+	if ((file_userinfo = fopen(info->name_userinfo, "w+")) < 0) {
+		ERRMSG("Can't open the userinfo file(%s). %s\n",
+		    info->name_userinfo, strerror(errno));
+		return FALSE;
+	}
+
+	info->file_userinfo = file_userinfo;
+
+	if ((fd = open(info->name_dumpfile, O_RDONLY)) < 0) {
+		ERRMSG("Can't open the dump file(%s). %s\n",
+		    info->name_dumpfile, strerror(errno));
+		return FALSE;
+	}
+	info->fd_dumpfile = fd;
+
+	return TRUE;
+}
+
+int
+get_phdr_dumpfile(int index, Elf64_Phdr *phdr)
+{
+	Elf32_Phdr phdr32;
+
+	if (is_elf64_memory()) { /* ELF64 */
+		if (!get_elf64_phdr(info->fd_dumpfile, info->name_dumpfile,
+				    index, phdr)) {
+			ERRMSG("Can't find Phdr %d.\n", index);
+			return FALSE;
+		}
+	} else {
+		if (!get_elf32_phdr(info->fd_dumpfile, info->name_dumpfile,
+				    index, &phdr32)) {
+			ERRMSG("Can't find Phdr %d.\n", index);
+			return FALSE;
+		}
+		memset(phdr, 0, sizeof(Elf64_Phdr));
+		phdr->p_type   = phdr32.p_type;
+		phdr->p_flags  = phdr32.p_flags;
+		phdr->p_offset = phdr32.p_offset;
+		phdr->p_vaddr  = phdr32.p_vaddr;
+		phdr->p_paddr  = phdr32.p_paddr;
+		phdr->p_filesz = phdr32.p_filesz;
+		phdr->p_memsz  = phdr32.p_memsz;
+		phdr->p_align  = phdr32.p_align;
+	}
+	return TRUE;
+}
+
 /*
  * Open the following file when it rearranges the dump data.
  * - dump file
@@ -4758,6 +4812,122 @@ read_cache(struct cache_data *cd)
 	return TRUE;
 }
 
+int
+copy_userinfo(struct cache_data *cd)
+{
+	size_t buf_size, size;
+	char buf[BUFSIZE_FGETS];
+
+	cd->buf = buf;
+	buf_size = info->size_elf_userinfo;
+
+	while (buf_size > 0) {
+		size = buf_size >= BUFSIZE_FGETS ? BUFSIZE_FGETS : buf_size;
+
+		cd->cache_size = size;
+		if (!read_cache(cd))
+			return FALSE;
+
+		if (fwrite(cd->buf, size, 1, info->file_userinfo) != size)
+			return FALSE;
+
+		buf_size -= BUFSIZE_FGETS;
+	}
+
+	return TRUE;
+}
+
+int
+generate_userinfo(void)
+{
+	char buf[USERINFO_NOTE_NAME_BYTES];
+	size_t nhdr_size, size_note;
+	off_t userinfo_offset = 0;
+	Elf64_Phdr note_phdr;
+	struct cache_data ui;
+	Elf64_Ehdr ehdr64;
+	Elf32_Ehdr ehdr32;
+	int i, phnum;
+	off_t offset;
+	void *note;
+
+	if (!info->flag_elf_dumpfile)
+		return FALSE;
+
+	if (is_elf64_memory()) { /* ELF64 */
+		if (!get_elf64_ehdr(info->fd_dumpfile, info->name_dumpfile,
+				    &ehdr64)) {
+			ERRMSG("Can't get ehdr64.\n");
+			return FALSE;
+		}
+		phnum = ehdr64.e_phnum;
+
+	} else { /* ELF32 */
+		if (!get_elf32_ehdr(info->fd_dumpfile, info->name_dumpfile,
+				    &ehdr32)) {
+			ERRMSG("Can't get ehdr32.\n");
+			return FALSE;
+		}
+		phnum = ehdr32.e_phnum;
+	}
+
+	for (i = 0; i < phnum; i++) {
+		if (!get_phdr_dumpfile(i, &note_phdr))
+			return FALSE;
+
+		if (note_phdr.p_type == PT_NOTE)
+			break;
+	}
+
+	if (note_phdr.p_type != PT_NOTE) {
+		ERRMSG("Can't get a PT_NOTE header.\n");
+		return FALSE;
+	}
+
+	size_note = note_phdr.p_filesz;
+	ui.offset = note_phdr.p_offset;
+	ui.fd = info->fd_dumpfile;
+	ui.file_name = info->name_dumpfile;
+	ui.buf = buf;
+
+	nhdr_size = is_elf64_memory() ? sizeof(Elf64_Nhdr) :
+					sizeof(Elf32_Nhdr);
+
+	ui.cache_size = nhdr_size + USERINFO_NOTE_NAME_BYTES;
+
+	/* find userinfo section */
+	while (size_note > 0) {
+		if (!read_cache(&ui))
+			return FALSE;
+
+		note = ui.buf;
+		if (strcmp(note + nhdr_size, USERINFO_NOTE_NAME) == 0) {
+			userinfo_offset = ui.offset;
+			info->size_elf_userinfo = note_descsz(note);
+			break;
+		}
+
+		offset = offset_next_note(note);
+		size_note -= offset;
+
+		/* set next pnhdr */
+		ui.offset += note_descsz(note);
+	}
+
+	if (!userinfo_offset) {
+		ERRMSG("Can't get a USERINFO header.\n");
+		return FALSE;
+	}
+
+	ui.offset = userinfo_offset;
+
+	if (!copy_userinfo(&ui))
+		return FALSE;
+
+	return TRUE;
+}
+
+
 int
 is_bigendian(void)
 {
@@ -9450,6 +9620,15 @@ close_files_for_generating_vmcoreinfo(void)
 	return TRUE;
 }
 
+int
+close_files_for_generating_userinfo(void)
+{
+	close_dump_file();
+	close_userinfo_file();
+
+	return TRUE;
+}
+
 /*
  * Close the following file when it rearranges the dump data.
  * - dump file
@@ -9458,6 +9637,7 @@ int
 close_files_for_rearranging_dumpdata(void)
 {
 	close_dump_file();
+	close_userinfo_file();
 
 	return TRUE;
 }
@@ -11302,6 +11482,23 @@ check_param_for_rearranging_dumpdata(int argc, char *argv[])
 	return TRUE;
 }
 
+int
+check_param_for_creating_userinfo_file(int argc, char *argv[])
+{
+	if (argc != optind + 1)
+		return FALSE;
+
+	if (info->flag_compress        || info->dump_level
+	    || info->flag_elf_dumpfile || info->flag_read_vmcoreinfo
+	    || info->name_vmlinux      || info->name_xen_syms
+	    || info->flag_flatten      || info->flag_generate_vmcoreinfo
+	    || info->flag_exclude_xen_dom || info->flag_rearrange)
+		return FALSE;
+
+	info->name_dumpfile = argv[optind];
+	return TRUE;
+}
+
 /*
  * Parameters for reassembling multiple dumpfiles into one dumpfile.
  */
@@ -11974,6 +12171,10 @@ main(int argc, char *argv[])
 			info->flag_insert_userinfo = 1;
 			info->name_userinfo = optarg;
 			break;
+		case OPT_GENERATE_USERINFO:
+			info->flag_generate_userinfo = 1;
+			info->name_userinfo = optarg;
+			break;
 		case OPT_XEN_PHYS_START:
 			info->xen_phys_start = strtoul(optarg, NULL, 0);
 			break;
@@ -12097,6 +12298,29 @@ main(int argc, char *argv[])
 
 		MSG("\n");
 		MSG("The vmcoreinfo is saved to %s.\n", info->name_vmcoreinfo);
+	} else if (info->flag_generate_userinfo) {
+		if (!check_param_for_creating_userinfo_file(argc, argv)) {
+			MSG("Commandline parameter is invalid.\n");
+			MSG("Try `makedumpfile --help' for more information.\n");
+			goto out;
+		}
+		if (info->flag_check_params)
+			goto check_ok;
+
+		if (!check_file_is_writable(info->name_userinfo))
+			goto out;
+
+		if (!open_files_for_generating_userinfo())
+			goto out;
+
+		if (!generate_userinfo())
+			goto out;
+
+		if (!close_files_for_generating_userinfo())
+			goto out;
+
+		MSG("\n");
+		MSG("The userinfo file is saved to %s.\n", info->name_userinfo);
 
 	} else if (info->flag_rearrange) {
 		if (!check_param_for_rearranging_dumpdata(argc, argv)) {
diff --git a/makedumpfile.h b/makedumpfile.h
index b28b0a5..26f44c9 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1360,6 +1360,7 @@ struct DumpInfo {
 	int		flag_generate_vmcoreinfo;/* flag of generating vmcoreinfo file */
 	int		flag_read_vmcoreinfo;    /* flag of reading vmcoreinfo file */
 	int		flag_insert_userinfo;    /* flag of inserting userinfo file into ELF note section */
+	int		flag_generate_userinfo;    /* flag of inserting userinfo file into ELF note section */
 	int		flag_show_usage;     /* flag of showing usage */
 	int		flag_show_version;   /* flag of showing version */
 	int		flag_check_params;   /* only check parameters */
@@ -2491,6 +2492,7 @@ struct elf_prstatus {
 #define OPT_VMLINUX             'x'
 #define OPT_COMPRESS_ZSTD       'z'
 #define OPT_USERINFO            'u'
+#define OPT_GENERATE_USERINFO   'U'
 #define OPT_START               256
 #define OPT_SPLIT               OPT_START+0
 #define OPT_REASSEMBLE          OPT_START+1
-- 
2.20.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [RFC PATCH] makedumpfile: add userinfo elf section 0/4]
  2021-12-01 13:47 [RFC PATCH] makedumpfile: add userinfo elf section 0/4] Ivan Khoronzhuk
                   ` (3 preceding siblings ...)
  2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 4/4] elf: add ability to read the userinfo data from note segment Ivan Khoronzhuk
@ 2021-12-15  0:58 ` HAGIO KAZUHITO(萩尾 一仁)
  4 siblings, 0 replies; 6+ messages in thread
From: HAGIO KAZUHITO(萩尾 一仁) @ 2021-12-15  0:58 UTC (permalink / raw)
  To: Ivan Khoronzhuk, kexec; +Cc: Ivan Khoronzhuk

Hi Ivan,

sorry for the delay.

-----Original Message-----
> These patchset suggests feature to add user specific information along
> with dumpfile. One of usecases could be a platform build information
> containing dubug file addresses, sources of daily build, some
> platform related information and more, it's gracefully simplifies
> debugging process, since an engineer doesn't need to spend time on
> finding to which platform this core file is related, where to get
> debugging counter part and so on. As user info can be added along with
> dumpfile it frees platform from creating tar achieve spending doubled
> space or using specific tools.

Hmm, currently I don't think it will be worth making makedumpfile have
the memo-like feature even with accepting some code and complexity.
If makedumpfile can access that helpful data in 2nd kernel, kdump tool
will be able to place it next to the dumpfile.  There will become two
files to be handled, but I'm not sure what the problem is with it..

Thanks,
Kazu

> Since this information is sorted and
> selected by user it can't be standardized and should be placed in some
> special generic section. This patchset roughly proposes the variant when
> user information is placed/retrieved as subsection of note elf
> section.
> 
> Ivan Khoronzhuk (4):
>   makedumpfile: rename check_dump_file() on check_file_is_writable()
>   elf: add new "userinfo" ELF section to traverse debug information
>   elf_info: make int note_descsz() and offset_next_note() public
>   elf: add ability to read the userinfo data from note segment
> 
>  elf_info.c     |   4 +-
>  elf_info.h     |   5 +
>  makedumpfile.c | 393 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  makedumpfile.h |  12 ++
>  4 files changed, 404 insertions(+), 10 deletions(-)
> 
> --
> 2.20.1

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-12-15  0:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-01 13:47 [RFC PATCH] makedumpfile: add userinfo elf section 0/4] Ivan Khoronzhuk
2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 1/4] makedumpfile: rename check_dump_file() on check_file_is_writable() Ivan Khoronzhuk
2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 2/4] elf: add new "userinfo" ELF section to traverse debug information Ivan Khoronzhuk
2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 3/4] elf_info: make int note_descsz() and offset_next_note() public Ivan Khoronzhuk
2021-12-01 13:47 ` [RFC makedumpfile: add userinfo elf section 4/4] elf: add ability to read the userinfo data from note segment Ivan Khoronzhuk
2021-12-15  0:58 ` [RFC PATCH] makedumpfile: add userinfo elf section 0/4] HAGIO KAZUHITO(萩尾 一仁)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.