[Crash-utility] [PATCH v3] diskdump: Add support for reading dumpfiles compressed by Zstandard

lijiang lijiang at redhat.com
Sun Sep 26 03:20:35 UTC 2021


On Fri, Sep 24, 2021 at 10:51 AM HAGIO KAZUHITO(萩尾 一仁)
<k-hagio-ab at nec.com> wrote:
>
> Add support for reading dumpfiles compressed by Zstandard (zstd)
> using makedumpfile.
>
> To build crash with zstd support, type "make zstd".
>
> Signed-off-by: Kazuhito Hagio <k-hagio-ab at nec.com>
> ---
> v2 -> v3
> - add a 'For zstd:' section in the comment above add_extra_lib()
> - move ZSTD_createDCtx() into cache_page() and add an error when
>   it cannot create dctx
> - add a sanity check on retlen
>
>  Makefile    |  4 ++++
>  README      |  4 ++--
>  configure.c | 24 +++++++++++++++++++++---
>  defs.h      |  4 ++++
>  diskdump.c  | 38 ++++++++++++++++++++++++++++++++++++++
>  diskdump.h  |  1 +
>  help.c      |  4 ++--
>  7 files changed, 72 insertions(+), 7 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index ece13069a029..eae023c54bdd 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -333,6 +333,10 @@ snappy: make_configure
>         @./configure -x snappy ${CONF_TARGET_FLAG} -w -b
>         @make --no-print-directory gdb_merge
>
> +zstd: make_configure
> +       @./configure -x zstd ${CONF_TARGET_FLAG} -w -b
> +       @make --no-print-directory gdb_merge
> +
>  valgrind: make_configure
>         @./configure -x valgrind ${CONF_TARGET_FLAG} -w -b
>         @make --no-print-directory gdb_merge
> diff --git a/README b/README
> index 50179742e620..4962f272074b 100644
> --- a/README
> +++ b/README
> @@ -102,8 +102,8 @@
>    Traditionally when vmcores are compressed via the makedumpfile(8) facility
>    the libz compression library is used, and by default the crash utility
>    only supports libz.  Recently makedumpfile has been enhanced to optionally
> -  use either the LZO or snappy compression libraries.  To build crash with
> -  either or both of those libraries, type "make lzo" or "make snappy".
> +  use the LZO, snappy or zstd compression libraries.  To build crash with any
> +  or all of those libraries, type "make lzo", "make snappy" or "make zstd".
>
>    crash supports valgrind Memcheck tool on the crash's custom memory allocator.
>    To build crash with this feature enabled, type "make valgrind" and then run
> diff --git a/configure.c b/configure.c
> index e8f619a3c061..b691a139b960 100644
> --- a/configure.c
> +++ b/configure.c
> @@ -1738,6 +1738,10 @@ get_extra_flags(char *filename, char *initial)
>   *    - enter -DSNAPPY in the CFLAGS.extra file
>   *    - enter -lsnappy in the LDFLAGS.extra file
>   *
> + *  For zstd:
> + *    - enter -DZSTD in the CFLAGS.extra file
> + *    - enter -lzstd in the LDFLAGS.extra file
> + *
>   *  For valgrind:
>   *    - enter -DVALGRIND in the CFLAGS.extra file
>   */
> @@ -1746,6 +1750,7 @@ add_extra_lib(char *option)
>  {
>         int lzo, add_DLZO, add_llzo2;
>         int snappy, add_DSNAPPY, add_lsnappy;
> +       int zstd, add_DZSTD, add_lzstd;
>         int valgrind, add_DVALGRIND;
>         char *cflags, *ldflags;
>         FILE *fp_cflags, *fp_ldflags;
> @@ -1754,6 +1759,7 @@ add_extra_lib(char *option)
>
>         lzo = add_DLZO = add_llzo2 = 0;
>         snappy = add_DSNAPPY = add_lsnappy = 0;
> +       zstd = add_DZSTD = add_lzstd = 0;
>         valgrind = add_DVALGRIND = 0;
>
>         ldflags = get_extra_flags("LDFLAGS.extra", NULL);
> @@ -1775,13 +1781,21 @@ add_extra_lib(char *option)
>                         add_lsnappy++;
>         }
>
> +       if (strcmp(option, "zstd") == 0) {
> +               zstd++;
> +               if (!cflags || !strstr(cflags, "-DZSTD"))
> +                       add_DZSTD++;
> +               if (!ldflags || !strstr(ldflags, "-lzstd"))
> +                       add_lzstd++;
> +       }
> +
>         if (strcmp(option, "valgrind") == 0) {
>                 valgrind++;
>                 if (!cflags || !strstr(cflags, "-DVALGRIND"))
>                         add_DVALGRIND++;
>         }
>
> -       if ((lzo || snappy) &&
> +       if ((lzo || snappy || zstd) &&
>             file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) {
>                 perror("diskdump.o");
>                 return;
> @@ -1806,24 +1820,28 @@ add_extra_lib(char *option)
>                 return;
>         }
>
> -       if (add_DLZO || add_DSNAPPY || add_DVALGRIND) {
> +       if (add_DLZO || add_DSNAPPY || add_DZSTD || add_DVALGRIND) {
>                 while (fgets(inbuf, 512, fp_cflags))
>                         ;
>                 if (add_DLZO)
>                         fputs("-DLZO\n", fp_cflags);
>                 if (add_DSNAPPY)
>                         fputs("-DSNAPPY\n", fp_cflags);
> +               if (add_DZSTD)
> +                       fputs("-DZSTD\n", fp_cflags);
>                 if (add_DVALGRIND)
>                         fputs("-DVALGRIND\n", fp_cflags);
>         }
>
> -       if (add_llzo2 || add_lsnappy) {
> +       if (add_llzo2 || add_lsnappy || add_lzstd) {
>                 while (fgets(inbuf, 512, fp_ldflags))
>                         ;
>                 if (add_llzo2)
>                         fputs("-llzo2\n", fp_ldflags);
>                 if (add_lsnappy)
>                         fputs("-lsnappy\n", fp_ldflags);
> +               if (add_lzstd)
> +                       fputs("-lzstd\n", fp_ldflags);
>         }
>
>         fclose(fp_cflags);
> diff --git a/defs.h b/defs.h
> index eb1c71b5333a..b2e94722c92b 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -54,6 +54,9 @@
>  #ifdef SNAPPY
>  #include <snappy-c.h>
>  #endif
> +#ifdef ZSTD
> +#include <zstd.h>
> +#endif
>
>  #ifndef ATTRIBUTE_UNUSED
>  #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
> @@ -327,6 +330,7 @@ struct number_option {
>  #define NO_ELF_NOTES        (0x20)
>  #define LZO_SUPPORTED       (0x40)
>  #define SNAPPY_SUPPORTED    (0x80)
> +#define ZSTD_SUPPORTED      (0x100)
>  #define DISKDUMP_VALID()    (dd->flags & DISKDUMP_LOCAL)
>  #define KDUMP_CMPRS_VALID() (dd->flags & KDUMP_CMPRS_LOCAL)
>  #define KDUMP_SPLIT()       (dd->flags & DUMPFILE_SPLIT)
> diff --git a/diskdump.c b/diskdump.c
> index de3eeb2c720c..9e80cd3d6f52 100644
> --- a/diskdump.c
> +++ b/diskdump.c
> @@ -96,6 +96,10 @@ static struct diskdump_data **dd_list = NULL;
>  static int num_dd = 0;
>  static int num_dumpfiles = 0;
>
> +#ifdef ZSTD
> +static ZSTD_DCtx *dctx = NULL;
> +#endif
> +

Would it be better to move the above definition to cache_page()? Because it is
not used in other functions, and the behavior is the same.

>  int dumpfile_is_split(void)
>  {
>         return KDUMP_SPLIT();
> @@ -1001,6 +1005,9 @@ is_diskdump(char *file)
>  #ifdef SNAPPY
>         dd->flags |= SNAPPY_SUPPORTED;
>  #endif
> +#ifdef ZSTD
> +       dd->flags |= ZSTD_SUPPORTED;
> +#endif
>
>         pc->read_vmcoreinfo = vmcoreinfo_read_string;
>
> @@ -1251,6 +1258,33 @@ cache_page(physaddr_t paddr)
>                               ret);
>                         return READ_ERROR;
>                 }
> +#endif
> +       } else if (pd.flags & DUMP_DH_COMPRESSED_ZSTD) {
> +
> +               if (!(dd->flags & ZSTD_SUPPORTED)) {
> +                       error(INFO, "%s: uncompess failed: no zstd compression support\n",
> +                               DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
> +                       return READ_ERROR;
> +               }
> +#ifdef ZSTD
> +               if (!dctx)
> +                       dctx = ZSTD_createDCtx();
> +

Usually these two functions ZSTD_createDCtx()/ZSTC_free() are required
to be called in pairs, but this(static definition) seems to simplify
the code.

Thanks.
Lianbo

> +               if (!dctx) {
> +                       error(INFO, "%s: uncompess failed: cannot create ZSTD_DCtx\n",
> +                               DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
> +                       return READ_ERROR;
> +               }
> +
> +               retlen = ZSTD_decompressDCtx(dctx,
> +                               dd->page_cache_hdr[i].pg_bufptr, block_size,
> +                               dd->compressed_page, pd.size);
> +               if (ZSTD_isError(retlen) || (retlen != block_size)) {
> +                       error(INFO, "%s: uncompress failed: %d (%s)\n",
> +                               DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
> +                               retlen, ZSTD_getErrorName(retlen));
> +                       return READ_ERROR;
> +               }
>  #endif
>         } else
>                 memcpy(dd->page_cache_hdr[i].pg_bufptr,
> @@ -1806,6 +1840,8 @@ __diskdump_memory_dump(FILE *fp)
>                 fprintf(fp, "%sLZO_SUPPORTED", others++ ? "|" : "");
>         if (dd->flags & SNAPPY_SUPPORTED)
>                 fprintf(fp, "%sSNAPPY_SUPPORTED", others++ ? "|" : "");
> +       if (dd->flags & ZSTD_SUPPORTED)
> +               fprintf(fp, "%sZSTD_SUPPORTED", others++ ? "|" : "");
>          fprintf(fp, ") %s\n", FLAT_FORMAT() ? "[FLAT]" : "");
>          fprintf(fp, "               dfd: %d\n", dd->dfd);
>          fprintf(fp, "               ofp: %lx\n", (ulong)dd->ofp);
> @@ -1872,6 +1908,8 @@ __diskdump_memory_dump(FILE *fp)
>                         fprintf(fp, "DUMP_DH_COMPRESSED_LZO");
>                 if (dh->status & DUMP_DH_COMPRESSED_SNAPPY)
>                         fprintf(fp, "DUMP_DH_COMPRESSED_SNAPPY");
> +               if (dh->status & DUMP_DH_COMPRESSED_ZSTD)
> +                       fprintf(fp, "DUMP_DH_COMPRESSED_ZSTD");
>                 if (dh->status & DUMP_DH_COMPRESSED_INCOMPLETE)
>                         fprintf(fp, "DUMP_DH_COMPRESSED_INCOMPLETE");
>                 if (dh->status & DUMP_DH_EXCLUDED_VMEMMAP)
> diff --git a/diskdump.h b/diskdump.h
> index 28713407b841..c152c7b86616 100644
> --- a/diskdump.h
> +++ b/diskdump.h
> @@ -86,6 +86,7 @@ struct kdump_sub_header {
>  #define DUMP_DH_COMPRESSED_SNAPPY  0x4   /* page is compressed with snappy */
>  #define DUMP_DH_COMPRESSED_INCOMPLETE  0x8   /* dumpfile is incomplete */
>  #define DUMP_DH_EXCLUDED_VMEMMAP   0x10  /* unused vmemmap pages are excluded */
> +#define DUMP_DH_COMPRESSED_ZSTD    0x20  /* page is compressed with zstd */
>
>  /* descriptor of each page for vmcore */
>  typedef struct page_desc {
> diff --git a/help.c b/help.c
> index 6c262a3ffcbb..f34838d59908 100644
> --- a/help.c
> +++ b/help.c
> @@ -9420,8 +9420,8 @@ README_ENTER_DIRECTORY,
>  "  Traditionally when vmcores are compressed via the makedumpfile(8) facility",
>  "  the libz compression library is used, and by default the crash utility",
>  "  only supports libz.  Recently makedumpfile has been enhanced to optionally",
> -"  use either the LZO or snappy compression libraries.  To build crash with",
> -"  either or both of those libraries, type \"make lzo\" or \"make snappy\".",
> +"  use the LZO, snappy or zstd compression libraries.  To build crash with any",
> +"  or all of those libraries, type \"make lzo\", \"make snappy\" or \"make zstd\".",
>  "",
>  "  crash supports valgrind Memcheck tool on the crash's custom memory allocator.",
>  "  To build crash with this feature enabled, type \"make valgrind\" and then run",
> --
> 2.27.0
>





More information about the Crash-utility mailing list