Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148420081
D3055.1786756695.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
D3055.1786756695.diff
View Options
Index: sys/amd64/amd64/minidump_machdep.c
===================================================================
--- sys/amd64/amd64/minidump_machdep.c
+++ sys/amd64/amd64/minidump_machdep.c
@@ -49,22 +49,10 @@
#include <machine/vmparam.h>
#include <machine/minidump.h>
-CTASSERT(sizeof(struct kerneldumpheader) == 512);
-
-/*
- * Don't touch the first SIZEOF_METADATA bytes on the dump device. This
- * is to protect us from metadata and to protect metadata from us.
- */
-#define SIZEOF_METADATA (64*1024)
-
-#define MD_ALIGN(x) (((off_t)(x) + PAGE_MASK) & ~PAGE_MASK)
-#define DEV_ALIGN(x) (((off_t)(x) + (DEV_BSIZE-1)) & ~(DEV_BSIZE-1))
-
uint64_t *vm_page_dump;
int vm_page_dump_size;
static struct kerneldumpheader kdh;
-static off_t dumplo;
/* Handle chunked writes. */
static size_t fragsz;
@@ -98,8 +86,7 @@
if (fragsz == 0)
return (0);
- error = dump_write(di, dump_va, 0, dumplo, fragsz);
- dumplo += fragsz;
+ error = dump_append(di, dump_va, 0, fragsz);
fragsz = 0;
return (error);
}
@@ -182,10 +169,9 @@
wdog_kern_pat(WD_LASTVAL);
if (ptr) {
- error = dump_write(di, ptr, 0, dumplo, len);
+ error = dump_append(di, ptr, 0, len);
if (error)
return (error);
- dumplo += len;
ptr += len;
sz -= len;
} else {
@@ -319,13 +305,6 @@
}
dumpsize += PAGE_SIZE;
- /* Determine dump offset on device. */
- if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
- error = E2BIG;
- goto fail;
- }
- dumplo = di->mediaoffset + di->mediasize - dumpsize;
- dumplo -= sizeof(kdh) * 2;
progress = dumpsize;
/* Initialize mdhdr */
@@ -344,11 +323,9 @@
printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20,
ptoa((uintmax_t)physmem) / 1048576);
- /* Dump leader */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_start(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
/* Dump my header */
bzero(&fakepd, sizeof(fakepd));
@@ -432,14 +409,10 @@
if (error)
goto fail;
- /* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ /* Signal completion, signoff and exit stage left. */
+ error = dump_finish(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
-
- /* Signal completion, signoff and exit stage left. */
- dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);
Index: sys/arm/arm/minidump_machdep.c
===================================================================
--- sys/arm/arm/minidump_machdep.c
+++ sys/arm/arm/minidump_machdep.c
@@ -50,14 +50,6 @@
#include <machine/minidump.h>
#include <machine/cpufunc.h>
-CTASSERT(sizeof(struct kerneldumpheader) == 512);
-
-/*
- * Don't touch the first SIZEOF_METADATA bytes on the dump device. This
- * is to protect us from metadata and to protect metadata from us.
- */
-#define SIZEOF_METADATA (64*1024)
-
uint32_t *vm_page_dump;
int vm_page_dump_size;
@@ -65,8 +57,6 @@
static struct kerneldumpheader kdh;
-static off_t dumplo;
-
/* Handle chunked writes. */
static size_t fragsz, offset;
static void *dump_va;
@@ -96,8 +86,7 @@
if (fragsz == 0)
return (0);
- error = dump_write(di, (char*)dump_va + offset, 0, dumplo, fragsz - offset);
- dumplo += (fragsz - offset);
+ error = dump_append(di, (char*)dump_va + offset, 0, fragsz - offset);
fragsz = 0;
offset = 0;
return (error);
@@ -149,10 +138,9 @@
wdog_kern_pat(WD_LASTVAL);
#endif
if (ptr) {
- error = dump_write(di, ptr, 0, dumplo, len);
+ error = dump_append(di, ptr, 0, len);
if (error)
return (error);
- dumplo += len;
ptr += len;
sz -= len;
} else {
@@ -294,14 +282,6 @@
dumpsize += PAGE_SIZE;
- /* Determine dump offset on device. */
- if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
- error = ENOSPC;
- goto fail;
- }
-
- dumplo = di->mediaoffset + di->mediasize - dumpsize;
- dumplo -= sizeof(kdh) * 2;
progress = dumpsize;
/* Initialize mdhdr */
@@ -319,11 +299,9 @@
printf("Physical memory: %u MB\n", ptoa((uintmax_t)physmem) / 1048576);
printf("Dumping %llu MB:", (long long)dumpsize >> 20);
- /* Dump leader */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_start(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
/* Dump my header */
bzero(&fakept, sizeof(fakept));
@@ -454,14 +432,10 @@
prev_pa = 0;
}
- /* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
- if (error)
- goto fail;
- dumplo += sizeof(kdh);
-
/* Signal completion, signoff and exit stage left. */
- dump_write(di, NULL, 0, 0, 0);
+ error = dump_finish(di, &kdh);
+ if (error != 0)
+ goto fail;
printf("\nDump complete\n");
return (0);
Index: sys/ddb/db_textdump.c
===================================================================
--- sys/ddb/db_textdump.c
+++ sys/ddb/db_textdump.c
@@ -245,7 +245,7 @@
return (EIO);
if (offset < SIZEOF_METADATA)
return (ENOSPC);
- textdump_error = dump_write(di, buffer, 0, offset + di->mediaoffset,
+ textdump_error = dump_write_raw(di, buffer, 0, offset + di->mediaoffset,
TEXTDUMP_BLOCKSIZE);
if (textdump_error)
printf("textdump_writeblock: offset %jd, error %d\n", (intmax_t)offset,
@@ -491,7 +491,7 @@
* Terminate the dump, report any errors, and clear the pending flag.
*/
if (textdump_error == 0)
- (void)dump_write(di, NULL, 0, 0, 0);
+ (void)dump_write_raw(di, NULL, 0, 0, 0);
if (textdump_error == ENOSPC)
printf("Textdump: Insufficient space on dump partition\n");
else if (textdump_error != 0)
Index: sys/geom/raid/g_raid.c
===================================================================
--- sys/geom/raid/g_raid.c
+++ sys/geom/raid/g_raid.c
@@ -1425,7 +1425,7 @@
return (ENXIO);
if (sd->sd_disk->d_kd.di.dumper == NULL)
return (EOPNOTSUPP);
- return (dump_write(&sd->sd_disk->d_kd.di,
+ return (dump_write_raw(&sd->sd_disk->d_kd.di,
virtual, physical,
sd->sd_disk->d_kd.di.mediaoffset + sd->sd_offset + offset,
length));
Index: sys/i386/i386/minidump_machdep.c
===================================================================
--- sys/i386/i386/minidump_machdep.c
+++ sys/i386/i386/minidump_machdep.c
@@ -45,17 +45,6 @@
#include <machine/vmparam.h>
#include <machine/minidump.h>
-CTASSERT(sizeof(struct kerneldumpheader) == 512);
-
-/*
- * Don't touch the first SIZEOF_METADATA bytes on the dump device. This
- * is to protect us from metadata and to protect metadata from us.
- */
-#define SIZEOF_METADATA (64*1024)
-
-#define MD_ALIGN(x) (((off_t)(x) + PAGE_MASK) & ~PAGE_MASK)
-#define DEV_ALIGN(x) (((off_t)(x) + (DEV_BSIZE-1)) & ~(DEV_BSIZE-1))
-
uint32_t *vm_page_dump;
int vm_page_dump_size;
@@ -92,8 +81,7 @@
if (fragsz == 0)
return (0);
- error = dump_write(di, dump_va, 0, dumplo, fragsz);
- dumplo += fragsz;
+ error = dump_append(di, dump_va, 0, fragsz);
fragsz = 0;
return (error);
}
@@ -141,10 +129,9 @@
wdog_kern_pat(WD_LASTVAL);
if (ptr) {
- error = dump_write(di, ptr, 0, dumplo, len);
+ error = dump_append(di, ptr, 0, len);
if (error)
return (error);
- dumplo += len;
ptr += len;
sz -= len;
} else {
@@ -244,13 +231,6 @@
}
dumpsize += PAGE_SIZE;
- /* Determine dump offset on device. */
- if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
- error = ENOSPC;
- goto fail;
- }
- dumplo = di->mediaoffset + di->mediasize - dumpsize;
- dumplo -= sizeof(kdh) * 2;
progress = dumpsize;
/* Initialize mdhdr */
@@ -271,10 +251,9 @@
printf("Dumping %llu MB:", (long long)dumpsize >> 20);
/* Dump leader */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_start(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
/* Dump my header */
bzero(&fakept, sizeof(fakept));
@@ -348,14 +327,10 @@
if (error)
goto fail;
- /* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ /* Signal completion, signoff and exit stage left. */
+ error = dump_finish(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
-
- /* Signal completion, signoff and exit stage left. */
- dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);
Index: sys/kern/kern_dump.c
===================================================================
--- sys/kern/kern_dump.c
+++ sys/kern/kern_dump.c
@@ -43,10 +43,13 @@
#ifdef SW_WATCHDOG
#include <sys/watchdog.h>
#endif
+
#include <ddb/ddb.h>
+
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
+
#include <machine/dump.h>
#include <machine/elf.h>
#include <machine/md_var.h>
@@ -64,7 +67,6 @@
#define DEV_ALIGN(x) (((off_t)(x) + (DEV_BSIZE-1)) & ~(DEV_BSIZE-1))
struct dump_pa dump_map[DUMPSYS_MD_PA_NPAIRS];
-off_t dumplo;
/* Our selected dumper. */
static struct dumperinfo dumper;
@@ -73,11 +75,12 @@
static struct pcb dumppcb; /* Registers. */
lwpid_t dumptid; /* Thread ID. */
-/* Handle buffered writes. */
+/* Dump state. */
+static off_t dumpoff;
static char buffer[DEV_BSIZE];
static size_t fragsz;
-char dumpdevname[sizeof(((struct cdev *)NULL)->si_name)];
+static char dumpdevname[sizeof(((struct cdev *)NULL)->si_name)];
SYSCTL_DECL(_kern_shutdown);
SYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD, dumpdevname, 0,
"Device for kernel dumps");
@@ -112,9 +115,71 @@
return (error);
}
+/* Perform any needed initialization in preparation for a kernel dump. */
+int
+dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh)
+{
+ uint64_t length;
+
+ length = dtoh64(kdh->dumplength);
+ if (di->mediasize < SIZEOF_METADATA + length + sizeof(*kdh) * 2)
+ return (E2BIG);
+
+ dumpoff = di->mediaoffset + di->mediasize - length - sizeof(*kdh);
+ return (0);
+}
+
+/* Complete a kernel dump. */
+int
+dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh)
+{
+ uint64_t length;
+ int error;
+
+ dumpoff = 0;
+
+ length = dtoh64(kdh->dumplength);
+
+ /* Write dump headers at the beginning and end of the dump extent. */
+ error = dump_write_raw(di, kdh, 0,
+ di->mediaoffset + di->mediasize - sizeof(*kdh), sizeof(*kdh));
+ if (error != 0)
+ return (error);
+ error = dump_write_raw(di, kdh, 0,
+ di->mediaoffset + di->mediasize - length - 2 * sizeof(*kdh),
+ sizeof(*kdh));
+ if (error != 0)
+ return (error);
+
+ /* Tell the dump media driver that we're done. */
+ return (dump_write_raw(di, NULL, 0, 0, 0));
+}
+
+/* Write starting at the current kernel dump offset. */
+int
+dump_append(struct dumperinfo *di, void *virtual, vm_offset_t physical,
+ size_t length)
+{
+ int error;
+
+ error = dump_write_raw(di, virtual, physical, dumpoff, length);
+ if (error == 0)
+ dumpoff += length;
+ return (error);
+}
+
+/* Seek forward by the specified number of bytes. */
+int
+dump_skip(struct dumperinfo *di, size_t gap)
+{
+
+ dumpoff += gap;
+ return (0);
+}
+
/* Call dumper with bounds checking. */
int
-dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
+dump_write_raw(struct dumperinfo *di, void *virtual, vm_offset_t physical,
off_t offset, size_t length)
{
@@ -238,11 +303,9 @@
ptr += len;
sz -= len;
if (fragsz == DEV_BSIZE) {
- error = dump_write(di, buffer, 0, dumplo,
- DEV_BSIZE);
+ error = dump_append(di, buffer, 0, DEV_BSIZE);
if (error)
return (error);
- dumplo += DEV_BSIZE;
fragsz = 0;
}
}
@@ -257,8 +320,7 @@
if (fragsz == 0)
return (0);
- error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
- dumplo += DEV_BSIZE;
+ error = dump_append(di, buffer, 0, DEV_BSIZE);
fragsz = 0;
return (error);
}
@@ -306,11 +368,10 @@
wdog_kern_pat(WD_LASTVAL);
#endif
- error = dump_write(di, va, 0, dumplo, sz);
+ error = dump_append(di, va, 0, sz);
dumpsys_unmap_chunk(pa, chunk, va);
if (error)
break;
- dumplo += sz;
pgs -= chunk;
pa += sz;
@@ -430,25 +491,15 @@
dumpsize += fileofs;
hdrgap = fileofs - DEV_ALIGN(hdrsz);
- /* Determine dump offset on device. */
- if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
- error = ENOSPC;
- goto fail;
- }
- dumplo = di->mediaoffset + di->mediasize - dumpsize;
- dumplo -= sizeof(kdh) * 2;
-
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARCH_VERSION, dumpsize,
di->blocksize);
printf("Dumping %ju MB (%d chunks)\n", (uintmax_t)dumpsize >> 20,
ehdr.e_phnum - DUMPSYS_NUM_AUX_HDRS);
- /* Dump leader */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_start(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
/* Dump ELF header */
error = dumpsys_buf_write(di, (char*)&ehdr, sizeof(ehdr));
@@ -468,23 +519,23 @@
* All headers are written using blocked I/O, so we know the
* current offset is (still) block aligned. Skip the alignement
* in the file to have the segment contents aligned at page
- * boundary. We cannot use MD_ALIGN on dumplo, because we don't
- * care and may very well be unaligned within the dump device.
+ * boundary. We cannot use MD_ALIGN on the current offset, because
+ * we don't care and may very well be unaligned within the dump
+ * device.
*/
- dumplo += hdrgap;
+ error = dump_skip(di, hdrgap);
+ if (error != 0)
+ goto fail;
- /* Dump memory chunks (updates dumplo) */
+ /* Dump memory chunks. */
error = dumpsys_foreach_chunk(dumpsys_cb_dumpdata, di);
if (error < 0)
goto fail;
- /* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
- if (error)
- goto fail;
-
/* Signal completion, signoff and exit stage left. */
- dump_write(di, NULL, 0, 0, 0);
+ error = dump_finish(di, &kdh);
+ if (error != 0)
+ goto fail;
printf("\nDump complete\n");
return (0);
Index: sys/mips/mips/minidump_machdep.c
===================================================================
--- sys/mips/mips/minidump_machdep.c
+++ sys/mips/mips/minidump_machdep.c
@@ -47,20 +47,10 @@
#include <machine/minidump.h>
#include <machine/cache.h>
-CTASSERT(sizeof(struct kerneldumpheader) == 512);
-
-/*
- * Don't touch the first SIZEOF_METADATA bytes on the dump device. This
- * is to protect us from metadata and to protect metadata from us.
- */
-#define SIZEOF_METADATA (64*1024)
-
uint32_t *vm_page_dump;
int vm_page_dump_size;
static struct kerneldumpheader kdh;
-static off_t dumplo;
-static off_t origdumplo;
/* Handle chunked writes. */
static uint64_t counter, progress;
@@ -132,10 +122,9 @@
}
if (ptr) {
- error = dump_write(di, ptr, 0, dumplo, len);
+ error = dump_append(di, ptr, 0, len);
if (error)
return (error);
- dumplo += len;
ptr += len;
sz -= len;
} else {
@@ -219,14 +208,6 @@
dumpsize += PAGE_SIZE;
- /* Determine dump offset on device. */
- if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
- error = ENOSPC;
- goto fail;
- }
-
- origdumplo = dumplo = di->mediaoffset + di->mediasize - dumpsize;
- dumplo -= sizeof(kdh) * 2;
progress = dumpsize;
/* Initialize mdhdr */
@@ -245,11 +226,9 @@
(uintmax_t)ptoa((uintmax_t)physmem) / 1048576);
printf("Dumping %llu MB:", (long long)dumpsize >> 20);
- /* Dump leader */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_start(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
/* Dump my header */
bzero(tmpbuffer, sizeof(tmpbuffer));
@@ -316,14 +295,10 @@
}
}
- /* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ /* Signal completion, signoff and exit stage left. */
+ error = dump_finish(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
-
- /* Signal completion, signoff and exit stage left. */
- dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);
Index: sys/sparc64/sparc64/dump_machdep.c
===================================================================
--- sys/sparc64/sparc64/dump_machdep.c
+++ sys/sparc64/sparc64/dump_machdep.c
@@ -49,7 +49,6 @@
static off_t fileofs;
-extern off_t dumplo;
extern struct dump_pa dump_map[DUMPSYS_MD_PA_NPAIRS];
int do_minidump = 0;
@@ -113,19 +112,14 @@
goto fail;
}
- /* Determine dump offset on device. */
- dumplo = di->mediaoffset + di->mediasize - totsize;
-
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_SPARC64_VERSION, size,
di->blocksize);
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_start(di, &kdh);
if (error)
goto fail;
- dumplo += sizeof(kdh);
/* Dump the private header. */
hdr.dh_hdr_size = hdrsize;
@@ -152,13 +146,10 @@
if (error < 0)
goto fail;
- /* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
- if (error)
- goto fail;
-
/* Signal completion, signoff and exit stage left. */
- dump_write(di, NULL, 0, 0, 0);
+ error = dump_finish(di, &kdh);
+ if (error != 0)
+ goto fail;
printf("\nDump complete\n");
return (0);
Index: sys/sys/kerneldump.h
===================================================================
--- sys/sys/kerneldump.h
+++ sys/sys/kerneldump.h
@@ -105,9 +105,6 @@
vm_paddr_t pa_size;
};
-void mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver,
- uint64_t dumplen, uint32_t blksz);
-
int dumpsys_generic(struct dumperinfo *);
void dumpsys_map_chunk(vm_paddr_t, size_t, void **);
@@ -123,9 +120,16 @@
void dumpsys_gen_unmap_chunk(vm_paddr_t, size_t, void *);
int dumpsys_gen_write_aux_headers(struct dumperinfo *);
-int set_dumper(struct dumperinfo *, const char *, struct thread *);
-int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t);
+int dump_start(struct dumperinfo *, struct kerneldumpheader *);
+int dump_finish(struct dumperinfo *, struct kerneldumpheader *);
+int dump_append(struct dumperinfo *, void *, vm_offset_t, size_t);
+int dump_skip(struct dumperinfo *, size_t);
+int dump_write_raw(struct dumperinfo *, void *, vm_offset_t, off_t, size_t);
+
int doadump(boolean_t);
+int set_dumper(struct dumperinfo *, const char *, struct thread *);
+void mkdumpheader(struct kerneldumpheader *, char *, uint32_t, uint64_t,
+ uint32_t);
extern int do_minidump;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 15, 1:18 AM (4 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29409050
Default Alt Text
D3055.1786756695.diff (17 KB)
Attached To
Mode
D3055: kern_dump.c: provider a higher-level API for MD dumpsys code
Attached
Detach File
Event Timeline
Log In to Comment