Index: sys/netinet/netdump/netdump.h =================================================================== --- sys/netinet/netdump/netdump.h +++ sys/netinet/netdump/netdump.h @@ -78,6 +78,11 @@ #define NETDUMP_MAX_IN_FLIGHT 64 +struct nd_ctx { + off_t nd_tx_off; + size_t nd_buf_len; +}; + enum netdump_ev { NETDUMP_START, NETDUMP_END, Index: sys/netinet/netdump/netdump_client.c =================================================================== --- sys/netinet/netdump/netdump_client.c +++ sys/netinet/netdump/netdump_client.c @@ -935,7 +935,7 @@ * errno on error */ static int -netdump_dumper(void *priv __unused, void *virtual, +netdump_dumper(void *priv, void *virtual, vm_offset_t physical __unused, off_t offset, size_t length) { int error; @@ -943,7 +943,15 @@ NETDDEBUGV("netdump_dumper(NULL, %p, NULL, %ju, %zu)\n", virtual, (uintmax_t)offset, length); + struct nd_ctx *ctx = (struct nd_ctx*)priv; + if (virtual == NULL) { + if (ctx->nd_buf_len != 0) { + error = netdump_send(NETDUMP_VMCORE, ctx->nd_tx_off, nd_buf, + ctx->nd_buf_len); + if (error != 0) + dump_failed = 1; + } if (dump_failed != 0) printf("failed to dump the kernel core\n"); else if (netdump_send(NETDUMP_FINISHED, 0, NULL, 0) != 0) @@ -956,12 +964,20 @@ if (length > sizeof(nd_buf)) return (ENOSPC); - memmove(nd_buf, virtual, length); - error = netdump_send(NETDUMP_VMCORE, offset, nd_buf, length); - if (error != 0) { - dump_failed = 1; - return (error); + if (ctx->nd_buf_len + length > sizeof(nd_buf)) { + error = netdump_send(NETDUMP_VMCORE, ctx->nd_tx_off, nd_buf, + ctx->nd_buf_len); + if (error != 0) { + dump_failed = 1; + return (error); + } + ctx->nd_buf_len = 0; + ctx->nd_tx_off = offset; } + + memmove(nd_buf + ctx->nd_buf_len, virtual, length); + ctx->nd_buf_len += length; + return (0); } @@ -1232,6 +1248,7 @@ { struct diocskerneldump_arg kda_copy, *conf; struct dumperinfo dumper; + struct nd_ctx *nd_tx_state; uint8_t *encryptedkey; int error; #ifdef COMPAT_FREEBSD11 @@ -1397,11 +1414,14 @@ conf->kda_encryptedkey = encryptedkey; } + nd_tx_state = malloc(sizeof(struct nd_ctx), M_TEMP, M_WAITOK); + memset(nd_tx_state, 0, sizeof(struct nd_ctx)); + memset(&dumper, 0, sizeof(dumper)); dumper.dumper_start = netdump_start; dumper.dumper_hdr = netdump_write_headers; dumper.dumper = netdump_dumper; - dumper.priv = NULL; + dumper.priv = nd_tx_state; dumper.blocksize = NETDUMP_DATASIZE; dumper.maxiosize = MAXDUMPPGS * PAGE_SIZE; dumper.mediaoffset = 0;