aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2019-08-19 16:29:51 +0000
committerMark Johnston <markj@FreeBSD.org>2019-08-19 16:29:51 +0000
commitccdc986607d3a12def360e6c6d01b44f64cb0868 (patch)
tree7614631f2768dad338dc92e2a1d401347b3f7d5a
parent165b9f965d190e81a85f23dff9bd1f3977e73c01 (diff)
downloadsrc-ccdc986607d3a12def360e6c6d01b44f64cb0868.tar.gz
src-ccdc986607d3a12def360e6c6d01b44f64cb0868.zip
Fix netdump buffering after r348473.
nd_buf is used to buffer headers (for both the kernel dump itself and for EKCD) before the final call to netdump_dumper(), which flushes residual data in nd_buf. As a result, a small portion of the residual data would be corrupted. This manifests when kernel dump compression is enabled since both zstd and zlib detect the corruption during decompression. Reviewed by: cem Differential Revision: https://reviews.freebsd.org/D21294
Notes
Notes: svn path=/head/; revision=351219
-rw-r--r--sys/netinet/netdump/netdump_client.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/sys/netinet/netdump/netdump_client.c b/sys/netinet/netdump/netdump_client.c
index 262a9d9e9de1..5887a3796212 100644
--- a/sys/netinet/netdump/netdump_client.c
+++ b/sys/netinet/netdump/netdump_client.c
@@ -923,6 +923,24 @@ netdump_network_poll(void)
*/
/*
+ * Flush any buffered vmcore data.
+ */
+static int
+netdump_flush_buf(void)
+{
+ int error;
+
+ error = 0;
+ if (nd_conf.nd_buf_len != 0) {
+ error = netdump_send(NETDUMP_VMCORE, nd_conf.nd_tx_off,
+ nd_buf, nd_conf.nd_buf_len);
+ if (error == 0)
+ nd_conf.nd_buf_len = 0;
+ }
+ return (error);
+}
+
+/*
* Callback from dumpsys() to dump a chunk of memory.
* Copies it out to our static buffer then sends it across the network.
* Detects the initial KDH and makes sure it is given a special packet type.
@@ -948,13 +966,9 @@ netdump_dumper(void *priv __unused, void *virtual,
virtual, (uintmax_t)offset, length);
if (virtual == NULL) {
- if (nd_conf.nd_buf_len != 0) {
- error = netdump_send(NETDUMP_VMCORE, nd_conf.nd_tx_off, nd_buf,
- nd_conf.nd_buf_len);
- if (error != 0) {
- dump_failed = 1;
- }
- }
+ error = netdump_flush_buf();
+ if (error != 0)
+ dump_failed = 1;
if (dump_failed != 0)
printf("failed to dump the kernel core\n");
@@ -968,16 +982,14 @@ netdump_dumper(void *priv __unused, void *virtual,
if (length > sizeof(nd_buf))
return (ENOSPC);
- if (nd_conf.nd_buf_len + length > sizeof(nd_buf) ||
- (nd_conf.nd_buf_len != 0 && nd_conf.nd_tx_off +
+ if (nd_conf.nd_buf_len + length > sizeof(nd_buf) ||
+ (nd_conf.nd_buf_len != 0 && nd_conf.nd_tx_off +
nd_conf.nd_buf_len != offset)) {
- error = netdump_send(NETDUMP_VMCORE, nd_conf.nd_tx_off, nd_buf,
- nd_conf.nd_buf_len);
+ error = netdump_flush_buf();
if (error != 0) {
dump_failed = 1;
return (error);
}
- nd_conf.nd_buf_len = 0;
nd_conf.nd_tx_off = offset;
}
@@ -1078,6 +1090,9 @@ netdump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh,
{
int error;
+ error = netdump_flush_buf();
+ if (error != 0)
+ return (error);
memcpy(nd_buf, kdh, sizeof(*kdh));
error = netdump_send(NETDUMP_KDH, 0, nd_buf, sizeof(*kdh));
if (error == 0 && keysize > 0) {