Changeset View
Changeset View
Standalone View
Standalone View
head/sbin/savecore/savecore.c
Show First 20 Lines • Show All 485 Lines • ▼ Show 20 Lines | sparsefwrite(const char *buf, size_t nr, FILE *fp) | ||||
} | } | ||||
return (nw); | return (nw); | ||||
} | } | ||||
static char *zbuf; | static char *zbuf; | ||||
static size_t zbufsize; | static size_t zbufsize; | ||||
static size_t | static ssize_t | ||||
GunzipWrite(z_stream *z, char *in, size_t insize, FILE *fp) | GunzipWrite(z_stream *z, char *in, size_t insize, FILE *fp) | ||||
{ | { | ||||
static bool firstblock = true; /* XXX not re-entrable/usable */ | static bool firstblock = true; /* XXX not re-entrable/usable */ | ||||
const size_t hdrlen = 10; | const size_t hdrlen = 10; | ||||
size_t nw = 0; | size_t nw = 0, w; | ||||
int rv; | int rv; | ||||
z->next_in = in; | z->next_in = in; | ||||
z->avail_in = insize; | z->avail_in = insize; | ||||
/* | /* | ||||
* Since contrib/zlib for some reason is compiled | * Since contrib/zlib for some reason is compiled | ||||
* without GUNZIP define, we need to skip the gzip | * without GUNZIP define, we need to skip the gzip | ||||
* header manually. Kernel puts minimal 10 byte | * header manually. Kernel puts minimal 10 byte | ||||
* header, see sys/kern/subr_compressor.c:gz_reset(). | * header, see sys/kern/subr_compressor.c:gz_reset(). | ||||
*/ | */ | ||||
if (firstblock) { | if (firstblock) { | ||||
z->next_in += hdrlen; | z->next_in += hdrlen; | ||||
z->avail_in -= hdrlen; | z->avail_in -= hdrlen; | ||||
firstblock = false; | firstblock = false; | ||||
} | } | ||||
do { | do { | ||||
z->next_out = zbuf; | z->next_out = zbuf; | ||||
z->avail_out = zbufsize; | z->avail_out = zbufsize; | ||||
rv = inflate(z, Z_NO_FLUSH); | rv = inflate(z, Z_NO_FLUSH); | ||||
if (rv != Z_OK && rv != Z_STREAM_END) { | if (rv != Z_OK && rv != Z_STREAM_END) { | ||||
logmsg(LOG_ERR, "decompression failed: %s", z->msg); | logmsg(LOG_ERR, "decompression failed: %s", z->msg); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
nw += sparsefwrite(zbuf, zbufsize - z->avail_out, fp); | w = sparsefwrite(zbuf, zbufsize - z->avail_out, fp); | ||||
if (w < zbufsize - z->avail_out) | |||||
return (-1); | |||||
nw += w; | |||||
} while (z->avail_in > 0 && rv != Z_STREAM_END); | } while (z->avail_in > 0 && rv != Z_STREAM_END); | ||||
return (nw); | return (nw); | ||||
} | } | ||||
static size_t | static ssize_t | ||||
ZstdWrite(ZSTD_DCtx *Zctx, char *in, size_t insize, FILE *fp) | ZstdWrite(ZSTD_DCtx *Zctx, char *in, size_t insize, FILE *fp) | ||||
{ | { | ||||
ZSTD_inBuffer Zin; | ZSTD_inBuffer Zin; | ||||
ZSTD_outBuffer Zout; | ZSTD_outBuffer Zout; | ||||
size_t nw = 0; | size_t nw = 0, w; | ||||
int rv; | int rv; | ||||
Zin.src = in; | Zin.src = in; | ||||
Zin.size = insize; | Zin.size = insize; | ||||
Zin.pos = 0; | Zin.pos = 0; | ||||
do { | do { | ||||
Zout.dst = zbuf; | Zout.dst = zbuf; | ||||
Zout.size = zbufsize; | Zout.size = zbufsize; | ||||
Zout.pos = 0; | Zout.pos = 0; | ||||
rv = ZSTD_decompressStream(Zctx, &Zout, &Zin); | rv = ZSTD_decompressStream(Zctx, &Zout, &Zin); | ||||
if (ZSTD_isError(rv)) { | if (ZSTD_isError(rv)) { | ||||
logmsg(LOG_ERR, "decompression failed: %s", | logmsg(LOG_ERR, "decompression failed: %s", | ||||
ZSTD_getErrorName(rv)); | ZSTD_getErrorName(rv)); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
nw += sparsefwrite(zbuf, Zout.pos, fp); | w = sparsefwrite(zbuf, Zout.pos, fp); | ||||
if (w < Zout.pos) | |||||
return (-1); | |||||
nw += w; | |||||
} while (Zin.pos < Zin.size && rv != 0); | } while (Zin.pos < Zin.size && rv != 0); | ||||
return (nw); | return (nw); | ||||
} | } | ||||
static int | static int | ||||
DoRegularFile(int fd, off_t dumpsize, u_int sectorsize, bool sparse, | DoRegularFile(int fd, off_t dumpsize, u_int sectorsize, bool sparse, | ||||
uint8_t compression, char *buf, const char *device, | uint8_t compression, char *buf, const char *device, | ||||
const char *filename, FILE *fp) | const char *filename, FILE *fp) | ||||
{ | { | ||||
size_t nr, nw, wl; | size_t nr, wl; | ||||
ssize_t nw; | |||||
off_t dmpcnt, origsize; | off_t dmpcnt, origsize; | ||||
z_stream z; /* gzip */ | z_stream z; /* gzip */ | ||||
ZSTD_DCtx *Zctx; /* zstd */ | ZSTD_DCtx *Zctx; /* zstd */ | ||||
dmpcnt = 0; | dmpcnt = 0; | ||||
origsize = dumpsize; | origsize = dumpsize; | ||||
if (compression == KERNELDUMP_COMP_GZIP) { | if (compression == KERNELDUMP_COMP_GZIP) { | ||||
memset(&z, 0, sizeof(z)); | memset(&z, 0, sizeof(z)); | ||||
Show All 34 Lines | while (dumpsize > 0) { | ||||
if (compression == KERNELDUMP_COMP_GZIP) | if (compression == KERNELDUMP_COMP_GZIP) | ||||
nw = GunzipWrite(&z, buf, nr, fp); | nw = GunzipWrite(&z, buf, nr, fp); | ||||
else if (compression == KERNELDUMP_COMP_ZSTD) | else if (compression == KERNELDUMP_COMP_ZSTD) | ||||
nw = ZstdWrite(Zctx, buf, nr, fp); | nw = ZstdWrite(Zctx, buf, nr, fp); | ||||
else if (!sparse) | else if (!sparse) | ||||
nw = fwrite(buf, 1, wl, fp); | nw = fwrite(buf, 1, wl, fp); | ||||
else | else | ||||
nw = sparsefwrite(buf, wl, fp); | nw = sparsefwrite(buf, wl, fp); | ||||
if ((compression == KERNELDUMP_COMP_NONE && nw != wl) || | if (nw < 0 || (compression == KERNELDUMP_COMP_NONE && | ||||
(compression != KERNELDUMP_COMP_NONE && nw < 0)) { | (size_t)nw != wl)) { | ||||
logmsg(LOG_ERR, | logmsg(LOG_ERR, | ||||
"write error on %s file: %m", filename); | "write error on %s file: %m", filename); | ||||
logmsg(LOG_WARNING, | logmsg(LOG_WARNING, | ||||
"WARNING: vmcore may be incomplete"); | "WARNING: vmcore may be incomplete"); | ||||
nerr++; | nerr++; | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (verbose) { | if (verbose) { | ||||
▲ Show 20 Lines • Show All 717 Lines • Show Last 20 Lines |