Re: [PATCH 5/5] [RFC] Replace lseek/read into pread for kcore and vmcore reading

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2023/04/12 18:04, lijiang wrote:
>>>> On 2023/03/25 13:12, Tao Liu wrote:
>>>>> Previously crash use lseek/read for kcore and vmcore reading, this
>> involves 2
>>>>> syscalls. And we can replace them with pread, only 1 syscall is needed
>> for
>>>>> kcore/vmcore reading, and we can have a better performance. Please
>> note there
>>>>> are plenty of places in crash using lseek/read, this patch doesn't
>> modify all
>>>>> of them, just the most commonly used kcore and diskdump vmcore reading.
>>>>
>>>> This is nice as an optimization, but can we distinguish a seek error and
>>>> read error with errno as currently we can do?
>>>>
>>>
>>> Sorry I didn't understand your question...
>>>
>>> The functions which I modified in this patch didn't use a global errno
>>> to distinguish error types, they used a returned value instead.
>>> Currently if read error, READ_ERROR will be returned, same as seek
>>> error returns SEEK_ERROR. Do you want to distinguish pread error by
>>> introducing a new error number as PREAD_ERROR?
>>
>> No, I would like to know which causes an error in pread(), seek or read.
>> In other words, is there any way to know which is wrong, the specified
>> offset or file/media?
>>
>>
> Good questions.
> 
> In fact, the SEEK_ERROR is simply returned to the top-level call, but it
> seems that there is no corresponding processing for the type of errors at
> the top-level code. Only saw two cases(please correct me if I missed
> anything):
> [1] readmem()
> ...
>                  case SEEK_ERROR:
>                          if (PRINT_ERROR_MESSAGE)
>                                  error(INFO, SEEK_ERRMSG,
> memtype_string(memtype, 0), addr, type);
>                          goto readmem_error;
> 
>                  case READ_ERROR:
>                          if (PRINT_ERROR_MESSAGE)
>                                  error(INFO, READ_ERRMSG,
> memtype_string(memtype, 0), addr, type);
>                          if ((pc->flags & DEVMEM) && (kt->flags &
> PRE_KERNEL_INIT) &&
>                              !(error_handle & NO_DEVMEM_SWITCH) &&
> devmem_is_restricted() &&
>                              switch_to_proc_kcore()) {
>                                  error_handle &= ~QUIET;
>                                  return(readmem(addr, memtype, bufptr, size,
>                                          type, error_handle));
>                          }
>                          goto readmem_error;..
> 
> [2] read_diskdump()
> ...
> 
>                  if ((ret = cache_page(curpaddr)) < 0) {
>                          if (CRASHDEBUG(8))
>                                  fprintf(fp, "read_diskdump: "
>                                      "%s: cannot cache page: %llx\n",
>                                          ret == SEEK_ERROR ?
>                                          "SEEK_ERROR" : "READ_ERROR",
>                                          (ulonglong)curpaddr);
>                          return ret;
>                  }
> ...
> 
> Given that, only recognizing the type of errors, it can not do anything.
> Would it really make sense to distinguish the type of errors(seek/read
> errors)?

I can see some seek errors on GitHub issues [1] and I don't think that 
it's useless at all for the first step of debugging.

[1] https://github.com/crash-utility/crash/issues?q=is%3Aissue+seek+error

But according to the man page and some experiments, lseek() allows an 
offset beyond the end of the file for normal dumpfiles (a vmcore, 
/proc/kcore and etc.) and just does not allow a negative offset.

So, my concern will be mostly solved by adding a negative offset check, 
for example,

   if (offset < 0) {
      if (CRASHDEBUG(8))
          fprintf(fp, " ... offset: %llx\n", offset);
      return SEEK_ERROR;
   }

How about adding something like this, instead of just removing lseek?

> 
> BTW: Could it be helpful to print an actual error when the pread() fails?
> For example:
> 
> +       ssize_t prdcnt = pread(fd, bufptr, readcnt, offset);
> +       if (prdcnt != readcnt) {
> +               if (prdcnt == -1)
> +                       error(WARNING, "/proc/kcore: %s\n",
> strerror(errno));
>                  return READ_ERROR;
> +       }

Yes, it's also sounds good to print errno for better debugging.
I would prefer it with CRASHDEBUG(8) same as the other error messages.

Thanks,
Kazu
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux