Page MenuHomeFreeBSD

D3055.1786756695.diff
No OneTemporary

Size
17 KB
Referenced Files
None
Subscribers
None

D3055.1786756695.diff

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

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)

Event Timeline