diff --git a/sys/arm/arm/dump_machdep.c b/sys/arm/arm/dump_machdep.c index e8ba5768..d4d6504 100644 --- a/sys/arm/arm/dump_machdep.c +++ b/sys/arm/arm/dump_machdep.c @@ -72,11 +72,7 @@ struct md_pa { typedef int callback_t(struct md_pa *, int, void *); static struct kerneldumpheader kdh; -static off_t dumplo, fileofs; - -/* Handle buffered writes. */ -static char buffer[DEV_BSIZE]; -static size_t fragsz; +static off_t fileofs; /* XXX: I suppose 20 should be enough. */ static struct md_pa dump_map[20]; @@ -113,47 +109,6 @@ md_pa_next(struct md_pa *mdp) return (mdp); } -static int -buf_write(struct dumperinfo *di, char *ptr, size_t sz) -{ - size_t len; - int error; - - while (sz) { - len = DEV_BSIZE - fragsz; - if (len > sz) - len = sz; - bcopy(ptr, buffer + fragsz, len); - fragsz += len; - ptr += len; - sz -= len; - if (fragsz == DEV_BSIZE) { - error = dump_write(di, buffer, 0, dumplo, - DEV_BSIZE); - if (error) - return error; - dumplo += DEV_BSIZE; - fragsz = 0; - } - } - - return (0); -} - -static int -buf_flush(struct dumperinfo *di) -{ - int error; - - if (fragsz == 0) - return (0); - - error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE); - dumplo += DEV_BSIZE; - fragsz = 0; - return (error); -} - extern vm_offset_t kernel_l1kva; extern char *pouet2; @@ -198,10 +153,10 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg) wdog_kern_pat(WD_LASTVAL); #endif error = dump_write(di, - (void *)(pa - (pa & L1_ADDR_BITS)),0, dumplo, sz); + (void *)(pa - (pa & L1_ADDR_BITS)),0, di->dumplo, sz); if (error) break; - dumplo += sz; + di->dumplo += sz; pgs -= chunk; pa += sz; @@ -235,7 +190,7 @@ cb_dumphdr(struct md_pa *mdp, int seqnr, void *arg) phdr.p_memsz = size; phdr.p_align = PAGE_SIZE; - error = buf_write(di, (char*)&phdr, sizeof(phdr)); + error = dump_buf_write(di, (char*)&phdr, sizeof(phdr)); fileofs += phdr.p_filesz; return (error); } @@ -316,8 +271,8 @@ dumpsys(struct dumperinfo *di) error = ENOSPC; goto fail; } - dumplo = di->mediaoffset + di->mediasize - dumpsize; - dumplo -= sizeof(kdh) * 2; + di->dumplo = di->mediaoffset + di->mediasize - dumpsize; + di->dumplo -= sizeof(kdh) * 2; mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, dumpsize, di->blocksize); @@ -325,13 +280,13 @@ dumpsys(struct dumperinfo *di) ehdr.e_phnum); /* Dump leader */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; - dumplo += sizeof(kdh); + di->dumplo += sizeof(kdh); /* Dump ELF header */ - error = buf_write(di, (char*)&ehdr, sizeof(ehdr)); + error = dump_buf_write(di, (char*)&ehdr, sizeof(ehdr)); if (error) goto fail; @@ -339,7 +294,7 @@ dumpsys(struct dumperinfo *di) error = foreach_chunk(cb_dumphdr, di); if (error < 0) goto fail; - buf_flush(di); + dump_buf_flush(di); /* * All headers are written using blocked I/O, so we know the @@ -348,7 +303,7 @@ dumpsys(struct dumperinfo *di) * boundary. We cannot use MD_ALIGN on dumplo, because we don't * care and may very well be unaligned within the dump device. */ - dumplo += hdrgap; + di->dumplo += hdrgap; /* Dump memory chunks (updates dumplo) */ error = foreach_chunk(cb_dumpdata, di); @@ -356,7 +311,7 @@ dumpsys(struct dumperinfo *di) goto fail; /* Dump trailer */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; diff --git a/sys/ia64/ia64/dump_machdep.c b/sys/ia64/ia64/dump_machdep.c index 6fa8608..e1c0a9c 100644 --- a/sys/ia64/ia64/dump_machdep.c +++ b/sys/ia64/ia64/dump_machdep.c @@ -59,52 +59,7 @@ CTASSERT(sizeof(struct kerneldumpheader) == 512); typedef int callback_t(struct efi_md*, int, void*); static struct kerneldumpheader kdh; -static off_t dumplo, fileofs; - -/* Handle buffered writes. */ -static char buffer[DEV_BSIZE]; -static size_t fragsz; - -static int -buf_write(struct dumperinfo *di, char *ptr, size_t sz) -{ - size_t len; - int error; - - while (sz) { - len = DEV_BSIZE - fragsz; - if (len > sz) - len = sz; - bcopy(ptr, buffer + fragsz, len); - fragsz += len; - ptr += len; - sz -= len; - if (fragsz == DEV_BSIZE) { - error = dump_write(di, buffer, 0, dumplo, - DEV_BSIZE); - if (error) - return error; - dumplo += DEV_BSIZE; - fragsz = 0; - } - } - - return (0); -} - -static int -buf_flush(struct dumperinfo *di) -{ - int error; - - if (fragsz == 0) - return (0); - - error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE); - dumplo += DEV_BSIZE; - fragsz = 0; - return (error); -} +static off_t fileofs; static int cb_dumpdata(struct efi_md *mdp, int seqnr, void *arg) @@ -134,10 +89,10 @@ cb_dumpdata(struct efi_md *mdp, int seqnr, void *arg) #ifdef SW_WATCHDOG wdog_kern_pat(WD_LASTVAL); #endif - error = dump_write(di, (void*)pa, 0, dumplo, sz); + error = dump_write(di, (void*)pa, 0, di->dumplo, sz); if (error) break; - dumplo += sz; + di->dumplo += sz; pgs -= sz >> EFI_PAGE_SHIFT; pa += sz; @@ -169,7 +124,7 @@ cb_dumphdr(struct efi_md *mdp, int seqnr, void *arg) phdr.p_memsz = mdp->md_pages << EFI_PAGE_SHIFT; phdr.p_align = EFI_PAGE_SIZE; - error = buf_write(di, (char*)&phdr, sizeof(phdr)); + error = dump_buf_write(di, (char*)&phdr, sizeof(phdr)); fileofs += phdr.p_filesz; return (error); } @@ -250,8 +205,8 @@ dumpsys(struct dumperinfo *di) error = ENOSPC; goto fail; } - dumplo = di->mediaoffset + di->mediasize - dumpsize; - dumplo -= sizeof(kdh) * 2; + di->dumplo = di->mediaoffset + di->mediasize - dumpsize; + di->dumplo -= sizeof(kdh) * 2; mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_IA64_VERSION, dumpsize, di->blocksize); @@ -259,13 +214,13 @@ dumpsys(struct dumperinfo *di) ehdr.e_phnum); /* Dump leader */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; - dumplo += sizeof(kdh); + di->dumplo += sizeof(kdh); /* Dump ELF header */ - error = buf_write(di, (char*)&ehdr, sizeof(ehdr)); + error = dump_buf_write(di, (char*)&ehdr, sizeof(ehdr)); if (error) goto fail; @@ -273,7 +228,7 @@ dumpsys(struct dumperinfo *di) error = foreach_chunk(cb_dumphdr, di); if (error < 0) goto fail; - buf_flush(di); + dump_buf_flush(di); /* * All headers are written using blocked I/O, so we know the @@ -282,7 +237,7 @@ dumpsys(struct dumperinfo *di) * boundary. We cannot use MD_ALIGN on dumplo, because we don't * care and may very well be unaligned within the dump device. */ - dumplo += hdrgap; + di->dumplo += hdrgap; /* Dump memory chunks (updates dumplo) */ error = foreach_chunk(cb_dumpdata, di); @@ -290,7 +245,7 @@ dumpsys(struct dumperinfo *di) goto fail; /* Dump trailer */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index b120263..83d29cf 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -855,6 +855,48 @@ set_dumper(struct dumperinfo *di, const char *devname) return (0); } +int +dump_buf_write(struct dumperinfo *di, char *ptr, size_t sz) +{ + size_t len; + int error; + + while (sz) { + len = DEV_BSIZE - di->fragsz; + if (len > sz) + len = sz; + bcopy(ptr, di->buffer + di->fragsz, len); + di->fragsz += len; + ptr += len; + sz -= len; + if (di->fragsz == DEV_BSIZE) { + error = dump_write(di, di->buffer, 0, di->dumplo, + DEV_BSIZE); + if (error) + return (error); + di->dumplo += DEV_BSIZE; + di->fragsz = 0; + } + } + + return (0); +} + +int +dump_buf_flush(struct dumperinfo *di) +{ + int error; + + if (di->fragsz == 0) + return (0); + + error = dump_write(di, di->buffer, 0, di->dumplo, DEV_BSIZE); + di->dumplo += DEV_BSIZE; + di->fragsz = 0; + + return (error); +} + /* Call dumper with bounds checking. */ int dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, @@ -869,6 +911,8 @@ dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, (uintmax_t)length, (intmax_t)di->mediasize); return (ENOSPC); } + + return (di->dumper(di->priv, virtual, physical, offset, length)); } diff --git a/sys/mips/mips/dump_machdep.c b/sys/mips/mips/dump_machdep.c index bf8c4a3..280447d 100644 --- a/sys/mips/mips/dump_machdep.c +++ b/sys/mips/mips/dump_machdep.c @@ -72,11 +72,7 @@ struct md_pa { typedef int callback_t(struct md_pa *, int, void *); static struct kerneldumpheader kdh; -static off_t dumplo, fileofs; - -/* Handle buffered writes. */ -static char buffer[DEV_BSIZE]; -static size_t fragsz; +static off_t fileofs; /* XXX: I suppose 20 should be enough. */ static struct md_pa dump_map[20]; @@ -113,47 +109,6 @@ md_pa_next(struct md_pa *mdp) return (mdp); } -static int -buf_write(struct dumperinfo *di, char *ptr, size_t sz) -{ - size_t len; - int error; - - while (sz) { - len = DEV_BSIZE - fragsz; - if (len > sz) - len = sz; - bcopy(ptr, buffer + fragsz, len); - fragsz += len; - ptr += len; - sz -= len; - if (fragsz == DEV_BSIZE) { - error = dump_write(di, buffer, 0, dumplo, - DEV_BSIZE); - if (error) - return error; - dumplo += DEV_BSIZE; - fragsz = 0; - } - } - - return (0); -} - -static int -buf_flush(struct dumperinfo *di) -{ - int error; - - if (fragsz == 0) - return (0); - - error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE); - dumplo += DEV_BSIZE; - fragsz = 0; - return (error); -} - extern vm_offset_t kernel_l1kva; extern char *pouet2; @@ -190,10 +145,11 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg) #ifdef SW_WATCHDOG wdog_kern_pat(WD_LASTVAL); #endif - error = dump_write(di, (void *)(intptr_t)(pa),0, dumplo, sz); /* XXX fix PA */ + error = dump_write(di, (void *)(intptr_t)(pa),0, di->dumplo, + sz); /* XXX fix PA */ if (error) break; - dumplo += sz; + di->dumplo += sz; pgs -= chunk; pa += sz; @@ -227,7 +183,7 @@ cb_dumphdr(struct md_pa *mdp, int seqnr, void *arg) phdr.p_memsz = size; phdr.p_align = PAGE_SIZE; - error = buf_write(di, (char*)&phdr, sizeof(phdr)); + error = dump_buf_write(di, (char*)&phdr, sizeof(phdr)); fileofs += phdr.p_filesz; return (error); } @@ -308,8 +264,8 @@ dumpsys(struct dumperinfo *di) error = ENOSPC; goto fail; } - dumplo = di->mediaoffset + di->mediasize - dumpsize; - dumplo -= sizeof(kdh) * 2; + di->dumplo = di->mediaoffset + di->mediasize - dumpsize; + di->dumplo -= sizeof(kdh) * 2; mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_MIPS_VERSION, dumpsize, di->blocksize); @@ -317,13 +273,13 @@ dumpsys(struct dumperinfo *di) ehdr.e_phnum); /* Dump leader */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; - dumplo += sizeof(kdh); + di->dumplo += sizeof(kdh); /* Dump ELF header */ - error = buf_write(di, (char*)&ehdr, sizeof(ehdr)); + error = dump_buf_write(di, (char*)&ehdr, sizeof(ehdr)); if (error) goto fail; @@ -331,7 +287,7 @@ dumpsys(struct dumperinfo *di) error = foreach_chunk(cb_dumphdr, di); if (error < 0) goto fail; - buf_flush(di); + dump_buf_flush(di); /* * All headers are written using blocked I/O, so we know the @@ -340,7 +296,7 @@ dumpsys(struct dumperinfo *di) * boundary. We cannot use MD_ALIGN on dumplo, because we don't * care and may very well be unaligned within the dump device. */ - dumplo += hdrgap; + di->dumplo += hdrgap; /* Dump memory chunks (updates dumplo) */ error = foreach_chunk(cb_dumpdata, di); @@ -348,7 +304,7 @@ dumpsys(struct dumperinfo *di) goto fail; /* Dump trailer */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; diff --git a/sys/powerpc/powerpc/dump_machdep.c b/sys/powerpc/powerpc/dump_machdep.c index 043505f..9a91fd6 100644 --- a/sys/powerpc/powerpc/dump_machdep.c +++ b/sys/powerpc/powerpc/dump_machdep.c @@ -58,58 +58,13 @@ CTASSERT(sizeof(struct kerneldumpheader) == 512); typedef int callback_t(struct pmap_md *, int, void *); static struct kerneldumpheader kdh; -static off_t dumplo, fileofs; - -/* Handle buffered writes. */ -static char buffer[DEV_BSIZE]; -static size_t fragsz; +static off_t fileofs; int dumpsys_minidump = 1; SYSCTL_INT(_debug, OID_AUTO, minidump, CTLFLAG_RD, &dumpsys_minidump, 0, "Kernel makes compressed crash dumps"); static int -buf_write(struct dumperinfo *di, char *ptr, size_t sz) -{ - size_t len; - int error; - - while (sz) { - len = DEV_BSIZE - fragsz; - if (len > sz) - len = sz; - bcopy(ptr, buffer + fragsz, len); - fragsz += len; - ptr += len; - sz -= len; - if (fragsz == DEV_BSIZE) { - error = di->dumper(di->priv, buffer, 0, dumplo, - DEV_BSIZE); - if (error) - return error; - dumplo += DEV_BSIZE; - fragsz = 0; - } - } - - return (0); -} - -static int -buf_flush(struct dumperinfo *di) -{ - int error; - - if (fragsz == 0) - return (0); - - error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE); - dumplo += DEV_BSIZE; - fragsz = 0; - return (error); -} - -static int cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) { struct dumperinfo *di = (struct dumperinfo*)arg; @@ -137,11 +92,11 @@ cb_dumpdata(struct pmap_md *md, int seqnr, void *arg) #ifdef SW_WATCHDOG wdog_kern_pat(WD_LASTVAL); #endif - error = di->dumper(di->priv, (void*)va, 0, dumplo, sz); + error = di->dumper(di->priv, (void*)va, 0, di->dumplo, sz); pmap_dumpsys_unmap(md, ofs, va); if (error) break; - dumplo += sz; + di->dumplo += sz; resid -= sz; ofs += sz; @@ -173,7 +128,7 @@ cb_dumphdr(struct pmap_md *md, int seqnr, void *arg) phdr.p_memsz = md->md_size; phdr.p_align = PAGE_SIZE; - error = buf_write(di, (char*)&phdr, sizeof(phdr)); + error = dump_buf_write(di, (char*)&phdr, sizeof(phdr)); fileofs += phdr.p_filesz; return (error); } @@ -248,10 +203,10 @@ dumpsys(struct dumperinfo *di) error = ENOSPC; goto fail; } - dumplo = di->mediaoffset + di->mediasize - dumpsize; - dumplo -= sizeof(kdh) * 2; + di->dumplo = di->mediaoffset + di->mediasize - dumpsize; + di->dumplo -= sizeof(kdh) * 2; } else - dumplo = 0; + di->dumplo = 0; mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_POWERPC_VERSION, dumpsize, di->blocksize); @@ -260,13 +215,13 @@ dumpsys(struct dumperinfo *di) ehdr.e_phnum); /* Dump leader */ - error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh)); + error = di->dumper(di->priv, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; - dumplo += sizeof(kdh); + di->dumplo += sizeof(kdh); /* Dump ELF header */ - error = buf_write(di, (char*)&ehdr, sizeof(ehdr)); + error = dump_buf_write(di, (char*)&ehdr, sizeof(ehdr)); if (error) goto fail; @@ -274,7 +229,7 @@ dumpsys(struct dumperinfo *di) error = foreach_chunk(cb_dumphdr, di); if (error < 0) goto fail; - buf_flush(di); + dump_buf_flush(di); /* * All headers are written using blocked I/O, so we know the @@ -283,7 +238,7 @@ dumpsys(struct dumperinfo *di) * boundary. We cannot use MD_ALIGN on dumplo, because we don't * care and may very well be unaligned within the dump device. */ - dumplo += hdrgap; + di->dumplo += hdrgap; /* Dump memory chunks (updates dumplo) */ error = foreach_chunk(cb_dumpdata, di); @@ -291,7 +246,7 @@ dumpsys(struct dumperinfo *di) goto fail; /* Dump trailer */ - error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh)); + error = di->dumper(di->priv, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; diff --git a/sys/sparc64/sparc64/dump_machdep.c b/sys/sparc64/sparc64/dump_machdep.c index d5409ac..360db38 100644 --- a/sys/sparc64/sparc64/dump_machdep.c +++ b/sys/sparc64/sparc64/dump_machdep.c @@ -48,56 +48,11 @@ __FBSDID("$FreeBSD$"); CTASSERT(sizeof(struct kerneldumpheader) == DEV_BSIZE); static struct kerneldumpheader kdh; -static off_t dumplo, dumppos; - -/* Handle buffered writes. */ -static char buffer[DEV_BSIZE]; -static vm_size_t fragsz; +static off_t dumppos; #define MAXDUMPSZ (MAXDUMPPGS << PAGE_SHIFT) static int -buf_write(struct dumperinfo *di, char *ptr, size_t sz) -{ - size_t len; - int error; - - while (sz) { - len = DEV_BSIZE - fragsz; - if (len > sz) - len = sz; - bcopy(ptr, buffer + fragsz, len); - fragsz += len; - ptr += len; - sz -= len; - if (fragsz == DEV_BSIZE) { - error = dump_write(di, buffer, 0, dumplo, - DEV_BSIZE); - if (error) - return error; - dumplo += DEV_BSIZE; - fragsz = 0; - } - } - - return (0); -} - -static int -buf_flush(struct dumperinfo *di) -{ - int error; - - if (fragsz == 0) - return (0); - - error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE); - dumplo += DEV_BSIZE; - fragsz = 0; - return (error); -} - -static int reg_write(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size) { struct sparc64_dump_reg r; @@ -106,7 +61,7 @@ reg_write(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size) r.dr_size = size; r.dr_offs = dumppos; dumppos += size; - return (buf_write(di, (char *)&r, sizeof(r))); + return (dump_buf_write(di, (char *)&r, sizeof(r))); } static int @@ -126,10 +81,10 @@ blk_dump(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size) rsz = size - pos; rsz = (rsz > MAXDUMPSZ) ? MAXDUMPSZ : rsz; va = TLB_PHYS_TO_DIRECT(pa + pos); - error = dump_write(di, (void *)va, 0, dumplo, rsz); + error = dump_write(di, (void *)va, 0, di->dumplo, rsz); if (error) break; - dumplo += rsz; + di->dumplo += rsz; /* Check for user abort. */ c = cncheckc(); @@ -169,7 +124,7 @@ dumpsys(struct dumperinfo *di) } /* Determine dump offset on device. */ - dumplo = di->mediaoffset + di->mediasize - totsize; + di->dumplo = di->mediaoffset + di->mediasize - totsize; mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_SPARC64_VERSION, size, di->blocksize); @@ -177,10 +132,10 @@ dumpsys(struct dumperinfo *di) printf("Dumping %lu MB (%d chunks)\n", (u_long)(size >> 20), nreg); /* Dump leader */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; - dumplo += sizeof(kdh); + di->dumplo += sizeof(kdh); /* Dump the private header. */ hdr.dh_hdr_size = hdrsize; @@ -189,7 +144,7 @@ dumpsys(struct dumperinfo *di) hdr.dh_tsb_mask = tsb_kernel_mask; hdr.dh_nregions = nreg; - if (buf_write(di, (char *)&hdr, sizeof(hdr)) != 0) + if (dump_buf_write(di, (char *)&hdr, sizeof(hdr)) != 0) goto fail; dumppos = hdrsize; @@ -200,7 +155,7 @@ dumpsys(struct dumperinfo *di) if (error != 0) goto fail; } - buf_flush(di); + dump_buf_flush(di); /* Dump memory chunks. */ for (i = 0; i < sparc64_nmemreg; i++) { @@ -211,7 +166,7 @@ dumpsys(struct dumperinfo *di) } /* Dump trailer */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 5a579b4..f18d9d4 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -328,15 +328,20 @@ struct dumperinfo { dumper_t *dumper; /* Dumping function. */ void *priv; /* Private parts. */ u_int blocksize; /* Size of block in bytes. */ - u_int maxiosize; /* Max size allowed for an individual I/O */ + u_int maxiosize; /* Max size allowed for an individual I/O. */ off_t mediaoffset; /* Initial offset in bytes. */ off_t mediasize; /* Space available in bytes. */ + char buffer[DEV_BSIZE]; /* Space for buffered writes. */ + size_t fragsz; /* Number of buffered bytes. */ + off_t dumplo; /* Bytes written to media so far. */ }; -int set_dumper(struct dumperinfo *, const char *_devname); -int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t); -void dumpsys(struct dumperinfo *); -int doadump(boolean_t); +int set_dumper(struct dumperinfo *, const char *_devname); +int dump_buf_write(struct dumperinfo *, char *, size_t); +int dump_buf_flush(struct dumperinfo *); +int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t); +void dumpsys(struct dumperinfo *); +int doadump(boolean_t); extern int dumping; /* system is dumping */ #endif /* _KERNEL */ diff --git a/sys/x86/x86/dump_machdep.c b/sys/x86/x86/dump_machdep.c index 5c874f4..ba46399 100644 --- a/sys/x86/x86/dump_machdep.c +++ b/sys/x86/x86/dump_machdep.c @@ -74,11 +74,7 @@ struct md_pa { typedef int callback_t(struct md_pa *, int, void *); static struct kerneldumpheader kdh; -static off_t dumplo, fileofs; - -/* Handle buffered writes. */ -static char buffer[DEV_BSIZE]; -static size_t fragsz; +static off_t fileofs; /* 20 phys_avail entry pairs correspond to 10 md_pa's */ static struct md_pa dump_map[10]; @@ -115,47 +111,6 @@ md_pa_next(struct md_pa *mdp) return (mdp); } -static int -buf_write(struct dumperinfo *di, char *ptr, size_t sz) -{ - size_t len; - int error; - - while (sz) { - len = DEV_BSIZE - fragsz; - if (len > sz) - len = sz; - bcopy(ptr, buffer + fragsz, len); - fragsz += len; - ptr += len; - sz -= len; - if (fragsz == DEV_BSIZE) { - error = dump_write(di, buffer, 0, dumplo, - DEV_BSIZE); - if (error) - return error; - dumplo += DEV_BSIZE; - fragsz = 0; - } - } - - return (0); -} - -static int -buf_flush(struct dumperinfo *di) -{ - int error; - - if (fragsz == 0) - return (0); - - error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE); - dumplo += DEV_BSIZE; - fragsz = 0; - return (error); -} - #define PG2MB(pgs) ((pgs + (1 << 8) - 1) >> 8) static int @@ -199,10 +154,10 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg) wdog_kern_pat(WD_LASTVAL); - error = dump_write(di, va, 0, dumplo, sz); + error = dump_write(di, va, 0, di->dumplo, sz); if (error) break; - dumplo += sz; + di->dumplo += sz; pgs -= chunk; pa += sz; @@ -236,7 +191,7 @@ cb_dumphdr(struct md_pa *mdp, int seqnr, void *arg) phdr.p_memsz = size; phdr.p_align = PAGE_SIZE; - error = buf_write(di, (char*)&phdr, sizeof(phdr)); + error = dump_buf_write(di, (char*)&phdr, sizeof(phdr)); fileofs += phdr.p_filesz; return (error); } @@ -316,8 +271,8 @@ dumpsys(struct dumperinfo *di) error = ENOSPC; goto fail; } - dumplo = di->mediaoffset + di->mediasize - dumpsize; - dumplo -= sizeof(kdh) * 2; + di->dumplo = di->mediaoffset + di->mediasize - dumpsize; + di->dumplo -= sizeof(kdh) * 2; mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_VERSION, dumpsize, di->blocksize); @@ -326,13 +281,13 @@ dumpsys(struct dumperinfo *di) ehdr.e_phnum); /* Dump leader */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail; - dumplo += sizeof(kdh); + di->dumplo += sizeof(kdh); /* Dump ELF header */ - error = buf_write(di, (char*)&ehdr, sizeof(ehdr)); + error = dump_buf_write(di, (char*)&ehdr, sizeof(ehdr)); if (error) goto fail; @@ -340,7 +295,7 @@ dumpsys(struct dumperinfo *di) error = foreach_chunk(cb_dumphdr, di); if (error < 0) goto fail; - buf_flush(di); + dump_buf_flush(di); /* * All headers are written using blocked I/O, so we know the @@ -349,7 +304,7 @@ dumpsys(struct dumperinfo *di) * boundary. We cannot use MD_ALIGN on dumplo, because we don't * care and may very well be unaligned within the dump device. */ - dumplo += hdrgap; + di->dumplo += hdrgap; /* Dump memory chunks (updates dumplo) */ error = foreach_chunk(cb_dumpdata, di); @@ -357,7 +312,7 @@ dumpsys(struct dumperinfo *di) goto fail; /* Dump trailer */ - error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); + error = dump_write(di, &kdh, 0, di->dumplo, sizeof(kdh)); if (error) goto fail;