Print this page
9709 Remove support for BZIP2 from dump
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/savecore/savecore.c
          +++ new/usr/src/cmd/savecore/savecore.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1983, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright 2016 Joyent, Inc.
  24   24   */
  25   25  /*
  26      - * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
       26 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
  27   27   */
  28   28  
  29   29  #include <stdio.h>
  30   30  #include <stdlib.h>
  31   31  #include <stdarg.h>
  32   32  #include <unistd.h>
  33   33  #include <fcntl.h>
  34   34  #include <errno.h>
  35   35  #include <string.h>
  36   36  #include <deflt.h>
↓ open down ↓ 7 lines elided ↑ open up ↑
  44   44  #include <libintl.h>
  45   45  #include <sys/mem.h>
  46   46  #include <sys/statvfs.h>
  47   47  #include <sys/dumphdr.h>
  48   48  #include <sys/dumpadm.h>
  49   49  #include <sys/compress.h>
  50   50  #include <sys/panic.h>
  51   51  #include <sys/sysmacros.h>
  52   52  #include <sys/stat.h>
  53   53  #include <sys/resource.h>
  54      -#include <bzip2/bzlib.h>
  55   54  #include <sys/fm/util.h>
  56   55  #include <fm/libfmevent.h>
  57   56  #include <sys/int_fmtio.h>
  58   57  
  59   58  
  60   59  /* fread/fwrite buffer size */
  61   60  #define FBUFSIZE                (1ULL << 20)
  62   61  
  63   62  /* minimum size for output buffering */
  64   63  #define MINCOREBLKSIZE          (1ULL << 17)
↓ open down ↓ 306 lines elided ↑ open up ↑
 371  370  
 372  371          if ((dumphdr.dump_flags & DF_VALID) == 0 && !disregard_valid_flag)
 373  372                  logprint(SC_SL_NONE | SC_IF_VERBOSE | SC_EXIT_OK,
 374  373                      "dump already processed");
 375  374  
 376  375          if (dumphdr.dump_version != DUMP_VERSION)
 377  376                  logprint(SC_SL_NONE | SC_IF_VERBOSE | SC_EXIT_PEND,
 378  377                      "dump version (%d) != %s version (%d)",
 379  378                      dumphdr.dump_version, progname, DUMP_VERSION);
 380  379  
      380 +        if (datahdr.dump_clevel > DUMP_CLEVEL_LZJB)
      381 +                logprint(SC_SL_NONE | SC_EXIT_PEND,
      382 +                    "unsupported compression format (%d)", datahdr.dump_clevel);
      383 +
 381  384          if (dumphdr.dump_wordsize != DUMP_WORDSIZE)
 382  385                  logprint(SC_SL_NONE | SC_EXIT_PEND,
 383  386                      "dump is from %u-bit kernel - cannot save on %u-bit kernel",
 384  387                      dumphdr.dump_wordsize, DUMP_WORDSIZE);
 385  388  
 386  389          if (datahdr.dump_datahdr_magic == DUMP_DATAHDR_MAGIC) {
 387  390                  if (datahdr.dump_datahdr_version != DUMP_DATAHDR_VERSION)
 388  391                          logprint(SC_SL_NONE | SC_IF_VERBOSE | SC_EXIT_PEND,
 389  392                              "dump data version (%d) != %s data version (%d)",
 390  393                              datahdr.dump_datahdr_version, progname,
↓ open down ↓ 302 lines elided ↑ open up ↑
 693  696          int init;
 694  697          int tag;
 695  698          int bound;
 696  699          int nout;
 697  700          char *blkbuf;
 698  701          blockhdr_t blocks;
 699  702          pgcnt_t pagenum;
 700  703          pgcnt_t curpage;
 701  704          pgcnt_t npages;
 702  705          pgcnt_t done;
 703      -        bz_stream strm;
 704  706          dumpcsize_t sc;
 705  707          dumpstreamhdr_t sh;
 706  708  } stream_t;
 707  709  
 708  710  static stream_t *streams;
 709  711  static stream_t *endstreams;
 710  712  
 711  713  const int cs = sizeof (dumpcsize_t);
 712  714  
 713  715  typedef struct tinfo {
↓ open down ↓ 242 lines elided ↑ open up ↑
 956  958                          if (doflush) {
 957  959                                  putpage(corefd, s->blkbuf, s->curpage, s->nout);
 958  960                                  s->nout = 0;
 959  961                                  s->curpage = s->pagenum + s->done;
 960  962                          }
 961  963                          break;
 962  964                  }
 963  965          }
 964  966  }
 965  967  
 966      -/* bzlib library reports errors with this callback */
 967      -void
 968      -bz_internal_error(int errcode)
 969      -{
 970      -        logprint(SC_SL_ERR | SC_EXIT_ERR, "bz_internal_error: err %s\n",
 971      -            BZ2_bzErrorString(errcode));
 972      -}
 973      -
 974      -/*
 975      - * Return one object in the stream.
 976      - *
 977      - * An object (stream header or page) will likely span an input block
 978      - * of compression data. Return non-zero when an entire object has been
 979      - * retrieved from the stream.
 980      - */
 981      -static int
 982      -bz2decompress(stream_t *s, void *buf, size_t size)
 983      -{
 984      -        int rc;
 985      -
 986      -        if (s->strm.avail_out == 0) {
 987      -                s->strm.next_out = buf;
 988      -                s->strm.avail_out = size;
 989      -        }
 990      -        while (s->strm.avail_in > 0) {
 991      -                rc = BZ2_bzDecompress(&s->strm);
 992      -                if (rc == BZ_STREAM_END) {
 993      -                        rc = BZ2_bzDecompressReset(&s->strm);
 994      -                        if (rc != BZ_OK)
 995      -                                logprint(SC_SL_ERR | SC_EXIT_ERR,
 996      -                                    "BZ2_bzDecompressReset: %s",
 997      -                                    BZ2_bzErrorString(rc));
 998      -                        continue;
 999      -                }
1000      -
1001      -                if (s->strm.avail_out == 0)
1002      -                        break;
1003      -        }
1004      -        return (s->strm.avail_out == 0);
1005      -}
1006      -
1007      -/*
1008      - * Process one bzip2 block.
1009      - * The interface is documented here:
1010      - * http://www.bzip.org/1.0.5/bzip2-manual-1.0.5.html
1011      - */
1012      -static void
1013      -bz2block(int corefd, stream_t *s, char *block, size_t blocksz)
1014      -{
1015      -        int rc = 0;
1016      -        int doflush;
1017      -        char *out;
1018      -
1019      -        if (!s->init) {
1020      -                s->init = 1;
1021      -                rc = BZ2_bzDecompressInit(&s->strm, 0, 0);
1022      -                if (rc != BZ_OK)
1023      -                        logprint(SC_SL_ERR | SC_EXIT_ERR,
1024      -                            "BZ2_bzDecompressInit: %s", BZ2_bzErrorString(rc));
1025      -                if (s->blkbuf == NULL)
1026      -                        s->blkbuf = Zalloc(coreblksize);
1027      -                s->strm.avail_out = 0;
1028      -                s->state = STREAMSTART;
1029      -        }
1030      -        s->strm.next_in = block;
1031      -        s->strm.avail_in = blocksz;
1032      -
1033      -        while (s->strm.avail_in > 0) {
1034      -                switch (s->state) {
1035      -                case STREAMSTART:
1036      -                        if (!bz2decompress(s, &s->sh, sizeof (s->sh)))
1037      -                                return;
1038      -                        if (strcmp(DUMP_STREAM_MAGIC, s->sh.stream_magic) != 0)
1039      -                                logprint(SC_SL_ERR | SC_EXIT_ERR,
1040      -                                    "BZ2 STREAMSTART: bad stream header");
1041      -                        if (s->sh.stream_npages > datahdr.dump_maxrange)
1042      -                                logprint(SC_SL_ERR | SC_EXIT_ERR,
1043      -                                    "BZ2 STREAMSTART: bad range: %d > %d",
1044      -                                    s->sh.stream_npages, datahdr.dump_maxrange);
1045      -                        s->pagenum = s->sh.stream_pagenum;
1046      -                        s->npages = s->sh.stream_npages;
1047      -                        s->curpage = s->pagenum;
1048      -                        s->nout = 0;
1049      -                        s->done = 0;
1050      -                        s->state = STREAMPAGES;
1051      -                        break;
1052      -                case STREAMPAGES:
1053      -                        out = s->blkbuf + PTOB(s->nout);
1054      -                        if (!bz2decompress(s, out, pagesize))
1055      -                                return;
1056      -
1057      -                        atomic_inc_64(&saved);
1058      -
1059      -                        doflush = 0;
1060      -                        if (s->nout == 0 && iszpage(out)) {
1061      -                                doflush = 1;
1062      -                                atomic_inc_64(&zpages);
1063      -                        } else if (++s->nout >= BTOP(coreblksize) ||
1064      -                            isblkbnd(s->curpage + s->nout)) {
1065      -                                doflush = 1;
1066      -                        }
1067      -                        if (++s->done >= s->npages) {
1068      -                                s->state = STREAMSTART;
1069      -                                doflush = 1;
1070      -                        }
1071      -                        if (doflush) {
1072      -                                putpage(corefd, s->blkbuf, s->curpage, s->nout);
1073      -                                s->nout = 0;
1074      -                                s->curpage = s->pagenum + s->done;
1075      -                        }
1076      -                        break;
1077      -                }
1078      -        }
1079      -}
1080      -
1081  968  /* report progress */
1082  969  static void
1083  970  report_progress()
1084  971  {
1085  972          int sec, percent;
1086  973  
1087  974          if (!interactive)
1088  975                  return;
1089  976  
1090  977          percent = saved * 100LL / corehdr.dump_npages;
↓ open down ↓ 22 lines elided ↑ open up ↑
1113 1000                  for (s = streams; s != endstreams; s++) {
1114 1001                          if (s->bound || s->blocks.head == NULL)
1115 1002                                  continue;
1116 1003                          s->bound = 1;
1117 1004                          bound = 1;
1118 1005                          (void) pthread_cond_signal(&cvwork);
1119 1006                          while (s->blocks.head != NULL) {
1120 1007                                  b = deqh(&s->blocks);
1121 1008                                  (void) pthread_mutex_unlock(&lock);
1122 1009  
1123      -                                if (datahdr.dump_clevel < DUMP_CLEVEL_BZIP2)
1124      -                                        lzjbblock(t->corefd, s, b->block,
1125      -                                            b->size);
1126      -                                else
1127      -                                        bz2block(t->corefd, s, b->block,
1128      -                                            b->size);
     1010 +                                lzjbblock(t->corefd, s, b->block,
     1011 +                                    b->size);
1129 1012  
1130 1013                                  (void) pthread_mutex_lock(&lock);
1131 1014                                  enqt(&freeblocks, b);
1132 1015                                  (void) pthread_cond_signal(&cvfree);
1133 1016  
1134 1017                                  report_progress();
1135 1018                          }
1136 1019                          s->bound = 0;
1137 1020                          (void) pthread_cond_signal(&cvbarrier);
1138 1021                  }
↓ open down ↓ 18 lines elided ↑ open up ↑
1157 1040   * belonging to up to 4095 streams. In practice, the number of streams
1158 1041   * is set to one less than the number of CPUs running at crash
1159 1042   * time. One CPU processes the crash dump, the remaining CPUs
1160 1043   * separately process groups of data pages.
1161 1044   *
1162 1045   * savecore creates a thread per stream, but never more threads than
1163 1046   * the number of CPUs running savecore. This is because savecore can
1164 1047   * be processing a crash file from a remote machine, which may have
1165 1048   * more CPUs.
1166 1049   *
1167      - * When the kernel uses parallel lzjb or parallel bzip2, we expect a
1168      - * series of 128KB blocks of compression data. In this case, each
1169      - * block has a "tag", in the range 1-4095. Each block is handed off to
1170      - * to the threads running "runstreams". The dump format is either lzjb
1171      - * or bzip2, never a mixture. These threads, in turn, process the
1172      - * compression data for groups of pages. Groups of pages are delimited
1173      - * by a "stream header", which indicates a starting pfn and number of
1174      - * pages. When a stream block has been read, the condition variable
1175      - * "cvwork" is signalled, which causes one of the avaiable threads to
1176      - * wake up and process the stream.
     1050 + * When the kernel uses parallel compression we expect a series of 128KB
     1051 + * blocks of compression data. In this case, each block has a "tag" in
     1052 + * the range 1-4095. Each block is handed off to the threads running
     1053 + * "runstreams". These threads, in turn, process the compression data
     1054 + * for groups of pages. Groups of pages are delimited by a "stream header",
     1055 + * which indicates a starting pfn and number of pages. When a stream block
     1056 + * has been read, the condition variable "cvwork" is signalled, which causes
     1057 + * one of the available threads to wake up and process the stream.
1177 1058   *
1178 1059   * In the parallel case there will be streams blocks encoding all data
1179 1060   * pages. The stream of blocks is terminated by a zero size
1180 1061   * word. There can be a few lzjb pages tacked on the end, depending on
1181 1062   * the architecture. The sbarrier function ensures that all stream
1182 1063   * blocks have been processed so that the page number for the few
1183 1064   * single pages at the end can be known.
1184 1065   */
1185 1066  static void
1186 1067  decompress_pages(int corefd)
↓ open down ↓ 815 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX