Re: Compiling makedumpfile from source

2021-07-08 Thread manty kuma
Hi Kazuhito san,

I am looking to better understand the sections being filtering out
with each of the following options.

Zero page:
Pages that are empty. Ignoring these pages won't have any impact on analysis.

non-private cache and private cache:
What exactly are these sections of memory? Just a one-line overview
about them is sufficient.
(My understanding was that cache is not part of RAM. Is this cache
something else? Like some bookkeeping data maintained by the kernel?)


user data:
Are these sections of the memory for the user space processes/memory
sections allocated using malloc?
My understanding is that If I exclude this section, gcore would not
work. Is my understanding correct?
I expected this section to be big. But in fact excluding this did not
have much impact on the dump size.

free page:
unallocated pages. Since they are not allocated. filtering them out
won't have any impact on dump analysis.
Please correct me if I am wrong.


If there is already some place that explains what these sections
filter out, please just drop the reference to them and i will look
into it.
Thank you very much in advance!

Manty

On Thu, Jul 8, 2021 at 8:17 PM manty kuma  wrote:
>
> Sorry. I am not sure how but I completely missed this email.
> Yes, /tmp was not available in my env. I just did mkdir before
> executing `makedumpfile` and it is now working well.
> Thank you very much.
>
> On Mon, Jun 28, 2021 at 4:07 PM HAGIO KAZUHITO(萩尾 一仁)
>  wrote:
> >
> > -Original Message-
> > > Hi Kazuhito san,
> > >
> > > I am getting the following error when trying to use makedumpfile utility.
> > >
> > > > copy_vmcoreinfo: Can't open the vmcoreinfo file(/tmp/vmcoreinfoLUQc25). 
> > > > No such file or directory.
> > > > makedumpfile Failed
> > >
> > > In your setup how are you providing the vmcoreinfo file? In my case it
> > > is checking /tmp/vmcoreinfoLUQc25
> > > Who generates this file?
> >
> > Generally, vmcoreinfo is copied from vmcore's ELF note to 
> > /tmp/vmcoreinfoXX
> > by makedumpfile, please see copy_vmcoreinfo().  So no need to provide 
> > explicitly.
> >
> > Is there the /tmp directory on your environment?
> >
> > Kazu
> >
> >

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


Re: Compiling makedumpfile from source

2021-07-08 Thread manty kuma
Sorry. I am not sure how but I completely missed this email.
Yes, /tmp was not available in my env. I just did mkdir before
executing `makedumpfile` and it is now working well.
Thank you very much.

On Mon, Jun 28, 2021 at 4:07 PM HAGIO KAZUHITO(萩尾 一仁)
 wrote:
>
> -Original Message-
> > Hi Kazuhito san,
> >
> > I am getting the following error when trying to use makedumpfile utility.
> >
> > > copy_vmcoreinfo: Can't open the vmcoreinfo file(/tmp/vmcoreinfoLUQc25). 
> > > No such file or directory.
> > > makedumpfile Failed
> >
> > In your setup how are you providing the vmcoreinfo file? In my case it
> > is checking /tmp/vmcoreinfoLUQc25
> > Who generates this file?
>
> Generally, vmcoreinfo is copied from vmcore's ELF note to 
> /tmp/vmcoreinfoXX
> by makedumpfile, please see copy_vmcoreinfo().  So no need to provide 
> explicitly.
>
> Is there the /tmp directory on your environment?
>
> Kazu
>
>

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


[PATCH v2 makedumpfile 2/3] Dump dmesg using write_and_check_space()

2021-07-08 Thread Benjamin Poirier
Detect incomplete writes which may happen due to insufficient space on the
output filesystem.

Signed-off-by: Benjamin Poirier 
---
 makedumpfile.c | 36 
 makedumpfile.h |  3 ++-
 printk.c   | 24 +++-
 3 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index aa05be7..9175a6a 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -4713,7 +4713,8 @@ is_bigendian(void)
 }
 
 int
-write_and_check_space(int fd, void *buf, size_t buf_size, char *file_name)
+write_and_check_space(int fd, void *buf, size_t buf_size, const char* desc,
+ const char *file_name)
 {
int status, written_size = 0;
 
@@ -4731,8 +4732,8 @@ write_and_check_space(int fd, void *buf, size_t buf_size, 
char *file_name)
}
if (errno == ENOSPC)
info->flag_nospace = TRUE;
-   MSG("\nCan't write the dump file(%s). %s\n",
-   file_name, strerror(errno));
+   MSG("\nCan't write the %s file(%s). %s\n", desc, file_name,
+   strerror(errno));
return FALSE;
}
return TRUE;
@@ -4757,7 +4758,8 @@ write_buffer(int fd, off_t offset, void *buf, size_t 
buf_size, char *file_name)
fdh.offset   = bswap_64(offset);
fdh.buf_size = bswap_64(buf_size);
}
-   if (!write_and_check_space(fd, , sizeof(fdh), file_name))
+   if (!write_and_check_space(fd, , sizeof(fdh), "dump",
+  file_name))
return FALSE;
} else if (!info->flag_dry_run &&
lseek(fd, offset, SEEK_SET) == failed) {
@@ -4765,7 +4767,7 @@ write_buffer(int fd, off_t offset, void *buf, size_t 
buf_size, char *file_name)
return FALSE;
}
 
-   if (!write_and_check_space(fd, buf, buf_size, file_name))
+   if (!write_and_check_space(fd, buf, buf_size, "dump", file_name))
return FALSE;
 
return TRUE;
@@ -5281,7 +5283,7 @@ reset_bitmap_of_free_pages(unsigned long node_zones, 
struct cycle *cycle)
 }
 
 static int
-dump_log_entry(char *logptr, int fp)
+dump_log_entry(char *logptr, int fp, const char *file_name)
 {
char *msg, *p, *bufp;
unsigned int i, text_len, indent_len, buf_need;
@@ -5307,7 +5309,8 @@ dump_log_entry(char *logptr, int fp)
 
for (i = 0, p = msg; i < text_len; i++, p++) {
if (bufp - buf >= sizeof(buf) - buf_need) {
-   if (write(info->fd_dumpfile, buf, bufp - buf) < 0)
+   if (!write_and_check_space(fp, buf, bufp - buf, "log",
+  file_name))
return FALSE;
bufp = buf;
}
@@ -5322,10 +5325,7 @@ dump_log_entry(char *logptr, int fp)
 
*bufp++ = '\n';
 
-   if (write(info->fd_dumpfile, buf, bufp - buf) < 0)
-   return FALSE;
-   else
-   return TRUE;
+   return write_and_check_space(fp, buf, bufp - buf, "log", file_name);
 }
 
 /*
@@ -5507,7 +5507,9 @@ dump_dmesg()
ERRMSG("Can't open output file.\n");
goto out;
}
-   if (write(info->fd_dumpfile, log_buffer, length_log) < 0)
+   if (!write_and_check_space(info->fd_dumpfile, log_buffer,
+  length_log, "log",
+  info->name_dumpfile))
goto out;
 
if (!close_files_for_creating_dumpfile())
@@ -5532,7 +5534,8 @@ dump_dmesg()
idx = log_first_idx;
while (idx != log_next_idx) {
log_ptr = log_from_idx(idx, log_buffer);
-   if (!dump_log_entry(log_ptr, info->fd_dumpfile))
+   if (!dump_log_entry(log_ptr, info->fd_dumpfile,
+   info->name_dumpfile))
goto out;
idx = log_next(idx, log_buffer);
}
@@ -6947,8 +6950,9 @@ write_start_flat_header()
memset(buf, 0, sizeof(buf));
memcpy(buf, , sizeof(fh));
 
-   if (!write_and_check_space(info->fd_dumpfile, buf, MAX_SIZE_MDF_HEADER,
-   info->name_dumpfile))
+   if (!write_and_check_space(info->fd_dumpfile, buf,
+  MAX_SIZE_MDF_HEADER, "dump",
+  info->name_dumpfile))
return FALSE;
 
return TRUE;
@@ -6966,7 +6970,7 @@ write_end_flat_header(void)
fdh.buf_size = END_FLAG_FLAT_HEADER;
 
if (!write_and_check_space(info->fd_dumpfile, , sizeof(fdh),
-   info->name_dumpfile))
+  "dump", info->name_dumpfile))
  

[PATCH v2 makedumpfile 0/3] Add option to limit file size

2021-07-08 Thread Benjamin Poirier
See feature description in patch "Add -L option to limit output file
size"

v1:
http://lists.infradead.org/pipermail/kexec/2021-June/022728.html
v2:
Add patches 1, 2 to support dmesg limit with different kernel
versions.

Stricter parsing of -L option value.

Instead of using RLIMIT_FSIZE, use write_bytes or SEEK_CUR to
enforce limit. This better integrates with the -F option for
stdout output.

Benjamin Poirier (3):
  Fix off by one error when checking cache_size
  Dump dmesg using write_and_check_space()
  Add -L option to limit output file size

 makedumpfile.8 |  12 --
 makedumpfile.c | 115 +++--
 makedumpfile.h |   6 ++-
 print_info.c   |   3 ++
 printk.c   |  24 +++
 sadump_info.c  |   2 +-
 6 files changed, 116 insertions(+), 46 deletions(-)

-- 
2.32.0


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


[PATCH v2 makedumpfile 3/3] Add -L option to limit output file size

2021-07-08 Thread Benjamin Poirier
This option can be used to ensure that a certain amount of free space is
preserved. It is useful when the output of makedumpfile is on the root
filesystem and some services fail to start at boot if there is no space
left.

Note that in some cases the limit can be triggered before the output file
reaches the specified size because makedumpfile seeks and tries to write
beyond the end of the file.

Signed-off-by: Benjamin Poirier 
---
 makedumpfile.8 | 12 ++--
 makedumpfile.c | 79 --
 makedumpfile.h |  3 ++
 print_info.c   |  3 ++
 sadump_info.c  |  2 +-
 5 files changed, 79 insertions(+), 20 deletions(-)

diff --git a/makedumpfile.8 b/makedumpfile.8
index 313a41c..9a90f0e 100644
--- a/makedumpfile.8
+++ b/makedumpfile.8
@@ -157,9 +157,10 @@ will be effective if you specify domain-0's \fIvmlinux\fR 
with \-x option.
 Then the pages are excluded only from domain-0.
 .br
 If specifying multiple dump_levels with the delimiter ',', makedumpfile retries
-to create a \fIDUMPFILE\fR by other dump_level when "No space on device" error
-happens. For example, if dump_level is "11,31" and makedumpfile fails
-by dump_level 11, makedumpfile retries it by dump_level 31.
+to create \fIDUMPFILE\fR using the next dump_level when the size of a dumpfile
+exceeds the limit specified with '-L' or when when a "No space on device" error
+happens. For example, if dump_level is "11,31" and makedumpfile fails with
+dump_level 11, makedumpfile retries with dump_level 31.
 .br
 .B Example:
 .br
@@ -221,6 +222,11 @@ Here is the all combinations of the bits.
 30 |  |   X   |   X   |  X   |  X
 31 |  X   |   X   |   X   |  X   |  X
 
+.TP
+\fB\-L\fR \fISIZE\fR
+Limit the size of the output file to \fISIZE\fR bytes. An incomplete
+\fIDUMPFILE\fR or \fILOGFILE\fR is written if the size would otherwise exceed
+\fISIZE\fR.
 
 .TP
 \fB\-E\fR
diff --git a/makedumpfile.c b/makedumpfile.c
index 9175a6a..4518ef4 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -4716,27 +4716,62 @@ int
 write_and_check_space(int fd, void *buf, size_t buf_size, const char* desc,
  const char *file_name)
 {
-   int status, written_size = 0;
+   size_t limit, done = 0;
+   int retval = 0;
+   off_t pos;
 
-   write_bytes += buf_size;
+   if (fd == STDOUT_FILENO) {
+   pos = write_bytes;
+   } else {
+   pos = lseek(fd, 0, SEEK_CUR);
+   if (pos == -1) {
+   ERRMSG("Can't seek the dump file(%s). %s\n",
+  file_name, strerror(errno));
+   return FALSE;
+   }
+   }
+
+   if (info->size_limit != -1 && pos + buf_size > info->size_limit) {
+   if (pos > info->size_limit)
+   limit = 0;
+   else
+   limit = info->size_limit - pos;
+   info->flag_nospace = TRUE;
+   } else {
+   limit = buf_size;
+   }
 
if (info->flag_dry_run)
-   return TRUE;
+   done = limit;
 
-   while (written_size < buf_size) {
-   status = write(fd, buf + written_size,
-  buf_size - written_size);
-   if (0 < status) {
-   written_size += status;
-   continue;
+   while (done < limit) {
+   retval = write(fd, buf, limit - done);
+   if (retval > 0) {
+   done += retval;
+   buf += retval;
+   } else {
+   if (retval == -1) {
+   if (errno == EINTR)
+   continue;
+   if (errno == ENOSPC)
+   info->flag_nospace = TRUE;
+   else
+   info->flag_nospace = FALSE;
+   MSG("\nCan't write the %s file(%s). %s\n",
+   desc, file_name, strerror(errno));
+   }
+   break;
}
-   if (errno == ENOSPC)
-   info->flag_nospace = TRUE;
-   MSG("\nCan't write the %s file(%s). %s\n", desc, file_name,
-   strerror(errno));
-   return FALSE;
}
-   return TRUE;
+
+   write_bytes += done;
+
+   if (retval != -1 && done < buf_size) {
+   MSG("\nCan't write the %s file(%s). Size limit(%llu) 
reached.\n",
+   desc, file_name, (unsigned long long) info->size_limit);
+   }
+
+   return done == buf_size;
 }
 
 int
@@ -11589,6 +11624,7 @@ main(int argc, char *argv[])
}
info->file_vmcoreinfo = NULL;
info->fd_vmlinux = -1;
+   info->size_limit = -1;
info->fd_xen_syms = -1;
info->fd_memory = -1;

[PATCH v2 makedumpfile 1/3] Fix off by one error when checking cache_size

2021-07-08 Thread Benjamin Poirier
Given the test in write_cache():
if (cd->buf_size < cd->cache_size)
return TRUE;
a write is done if buf_size == cache_size.
The test at the beginning of write_kdump_page() intends to detect cases
when write_cache() will do a write, however it was missing this boundary
condition. This would lead write_kdump_page() to ignore errors from
write_cache().

Signed-off-by: Benjamin Poirier 
---
 makedumpfile.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index fcb571f..aa05be7 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -7993,8 +7993,8 @@ write_kdump_page(struct cache_data *cd_header, struct 
cache_data *cd_page,
 * write the buffer cd_header into dumpfile and then write the cd_page.
 * With that, when enospc occurs, we can save more useful information.
 */
-   if (cd_header->buf_size + sizeof(*pd) > cd_header->cache_size
-   || cd_page->buf_size + pd->size > cd_page->cache_size){
+   if (cd_header->buf_size + sizeof(*pd) >= cd_header->cache_size ||
+   cd_page->buf_size + pd->size >= cd_page->cache_size) {
if( !write_cd_buf(cd_header) ) {
memset(cd_header->buf, 0, cd_header->cache_size);
write_cd_buf(cd_header);
-- 
2.32.0


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