Page MenuHomeFreeBSD

D5848.diff
No OneTemporary

D5848.diff

Index: head/sbin/savecore/savecore.c
===================================================================
--- head/sbin/savecore/savecore.c
+++ head/sbin/savecore/savecore.c
@@ -436,7 +436,7 @@
{
xo_handle_t *xostdout, *xoinfo;
static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX];
- static char *buf = NULL;
+ static char *buf = NULL, *temp = NULL;
struct kerneldumpheader kdhf, kdhl;
off_t mediasize, dumpsize, firsthd, lasthd;
FILE *info, *fp;
@@ -490,14 +490,29 @@
printf("sectorsize = %u\n", sectorsize);
}
+ if (sectorsize < sizeof(kdhl)) {
+ syslog(LOG_ERR,
+ "Sector size is less the kernel dump header %zu",
+ sizeof(kdhl));
+ goto closefd;
+ }
+
lasthd = mediasize - sectorsize;
+ if (temp == NULL) {
+ temp = malloc(sectorsize);
+ if (temp == NULL) {
+ syslog(LOG_ERR, "%m");
+ return;
+ }
+ }
if (lseek(fd, lasthd, SEEK_SET) != lasthd ||
- read(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl)) {
+ read(fd, temp, sectorsize) != sectorsize) {
syslog(LOG_ERR,
"error reading last dump header at offset %lld in %s: %m",
(long long)lasthd, device);
goto closefd;
}
+ memcpy(&kdhl, temp, sizeof(kdhl));
istextdump = 0;
if (strncmp(kdhl.magic, TEXTDUMPMAGIC, sizeof kdhl) == 0) {
if (verbose)
@@ -567,15 +582,16 @@
goto closefd;
}
dumpsize = dtoh64(kdhl.dumplength);
- firsthd = lasthd - dumpsize - sizeof kdhf;
+ firsthd = lasthd - dumpsize - sectorsize;
if (lseek(fd, firsthd, SEEK_SET) != firsthd ||
- read(fd, &kdhf, sizeof(kdhf)) != sizeof(kdhf)) {
+ read(fd, temp, sectorsize) != sectorsize) {
syslog(LOG_ERR,
"error reading first dump header at offset %lld in %s: %m",
(long long)firsthd, device);
nerr++;
goto closefd;
}
+ memcpy(&kdhf, temp, sizeof(kdhf));
if (verbose >= 2) {
printf("First dump headers:\n");
@@ -586,7 +602,7 @@
printf("\n");
}
- if (memcmp(&kdhl, &kdhf, sizeof kdhl)) {
+ if (memcmp(&kdhl, &kdhf, sizeof(kdhl))) {
syslog(LOG_ERR,
"first and last dump headers disagree on %s", device);
nerr++;
@@ -603,7 +619,7 @@
exit(0);
}
- if (kdhl.panicstring[0])
+ if (kdhl.panicstring[0] != '\0')
syslog(LOG_ALERT, "reboot after panic: %*s",
(int)sizeof(kdhl.panicstring), kdhl.panicstring);
else
@@ -724,9 +740,10 @@
if (!keep) {
if (verbose)
printf("clearing dump header\n");
- memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof kdhl.magic);
+ memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof(kdhl.magic));
+ memcpy(temp, &kdhl, sizeof(kdhl));
if (lseek(fd, lasthd, SEEK_SET) != lasthd ||
- write(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl))
+ write(fd, temp, sectorsize) != sectorsize)
syslog(LOG_ERR,
"error while clearing the dump header: %m");
}
Index: head/sys/amd64/amd64/minidump_machdep.c
===================================================================
--- head/sys/amd64/amd64/minidump_machdep.c
+++ head/sys/amd64/amd64/minidump_machdep.c
@@ -56,9 +56,6 @@
*/
#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;
@@ -222,6 +219,7 @@
int error;
uint64_t bits;
uint64_t *pml4, *pdp, *pd, *pt, pa;
+ size_t size;
int i, ii, j, k, n, bit;
int retry_count;
struct minidumphdr mdhdr;
@@ -319,12 +317,12 @@
dumpsize += PAGE_SIZE;
/* Determine dump offset on device. */
- if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
+ if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2) {
error = E2BIG;
goto fail;
}
dumplo = di->mediaoffset + di->mediasize - dumpsize;
- dumplo -= sizeof(kdh) * 2;
+ dumplo -= di->blocksize * 2;
progress = dumpsize;
/* Initialize mdhdr */
@@ -344,10 +342,10 @@
ptoa((uintmax_t)physmem) / 1048576);
/* Dump leader */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_write_pad(di, &kdh, 0, dumplo, sizeof(kdh), &size);
if (error)
goto fail;
- dumplo += sizeof(kdh);
+ dumplo += size;
/* Dump my header */
bzero(&fakepd, sizeof(fakepd));
@@ -432,10 +430,10 @@
goto fail;
/* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_write_pad(di, &kdh, 0, dumplo, sizeof(kdh), &size);
if (error)
goto fail;
- dumplo += sizeof(kdh);
+ dumplo += size;
/* Signal completion, signoff and exit stage left. */
dump_write(di, NULL, 0, 0, 0);
Index: head/sys/kern/kern_dump.c
===================================================================
--- head/sys/kern/kern_dump.c
+++ head/sys/kern/kern_dump.c
@@ -55,13 +55,11 @@
*/
#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))
+#define MD_ALIGN(x) roundup2((off_t)(x), PAGE_SIZE)
off_t dumplo;
/* Handle buffered writes. */
-static char buffer[DEV_BSIZE];
static size_t fragsz;
struct dump_pa dump_map[DUMPSYS_MD_PA_NPAIRS];
@@ -125,19 +123,19 @@
int error;
while (sz) {
- len = DEV_BSIZE - fragsz;
+ len = di->blocksize - fragsz;
if (len > sz)
len = sz;
- bcopy(ptr, buffer + fragsz, len);
+ memcpy((char *)di->blockbuf + fragsz, ptr, len);
fragsz += len;
ptr += len;
sz -= len;
- if (fragsz == DEV_BSIZE) {
- error = dump_write(di, buffer, 0, dumplo,
- DEV_BSIZE);
+ if (fragsz == di->blocksize) {
+ error = dump_write(di, di->blockbuf, 0, dumplo,
+ di->blocksize);
if (error)
return (error);
- dumplo += DEV_BSIZE;
+ dumplo += di->blocksize;
fragsz = 0;
}
}
@@ -152,8 +150,8 @@
if (fragsz == 0)
return (0);
- error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
- dumplo += DEV_BSIZE;
+ error = dump_write(di, di->blockbuf, 0, dumplo, di->blocksize);
+ dumplo += di->blocksize;
fragsz = 0;
return (error);
}
@@ -286,7 +284,7 @@
Elf_Ehdr ehdr;
uint64_t dumpsize;
off_t hdrgap;
- size_t hdrsz;
+ size_t hdrsz, size;
int error;
#ifndef __powerpc__
@@ -324,15 +322,15 @@
hdrsz = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
fileofs = MD_ALIGN(hdrsz);
dumpsize += fileofs;
- hdrgap = fileofs - DEV_ALIGN(hdrsz);
+ hdrgap = fileofs - roundup2((off_t)hdrsz, di->blocksize);
/* Determine dump offset on device. */
- if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
+ if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2) {
error = ENOSPC;
goto fail;
}
dumplo = di->mediaoffset + di->mediasize - dumpsize;
- dumplo -= sizeof(kdh) * 2;
+ dumplo -= di->blocksize * 2;
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARCH_VERSION, dumpsize,
di->blocksize);
@@ -341,10 +339,10 @@
ehdr.e_phnum - DUMPSYS_NUM_AUX_HDRS);
/* Dump leader */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_write_pad(di, &kdh, 0, dumplo, sizeof(kdh), &size);
if (error)
goto fail;
- dumplo += sizeof(kdh);
+ dumplo += size;
/* Dump ELF header */
error = dumpsys_buf_write(di, (char*)&ehdr, sizeof(ehdr));
@@ -375,7 +373,7 @@
goto fail;
/* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+ error = dump_write_pad(di, &kdh, 0, dumplo, sizeof(kdh), &size);
if (error)
goto fail;
Index: head/sys/kern/kern_shutdown.c
===================================================================
--- head/sys/kern/kern_shutdown.c
+++ head/sys/kern/kern_shutdown.c
@@ -88,6 +88,8 @@
#include <sys/signalvar.h>
+static MALLOC_DEFINE(M_DUMPER, "dumper", "dumper block buffer");
+
#ifndef PANIC_REBOOT_WAIT_TIME
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
#endif
@@ -848,7 +850,9 @@
return (error);
if (di == NULL) {
- bzero(&dumper, sizeof dumper);
+ if (dumper.blockbuf != NULL)
+ free(dumper.blockbuf, M_DUMPER);
+ bzero(&dumper, sizeof(dumper));
dumpdevname[0] = '\0';
return (0);
}
@@ -860,6 +864,7 @@
printf("set_dumper: device name truncated from '%s' -> '%s'\n",
devname, dumpdevname);
}
+ dumper.blockbuf = malloc(di->blocksize, M_DUMPER, M_WAITOK | M_ZERO);
return (0);
}
@@ -880,6 +885,31 @@
return (di->dumper(di->priv, virtual, physical, offset, length));
}
+/* Call dumper with bounds checking. */
+int
+dump_write_pad(struct dumperinfo *di, void *virtual, vm_offset_t physical,
+ off_t offset, size_t length, size_t *size)
+{
+ char *temp;
+ int ret;
+
+ if (length > di->blocksize)
+ return (ENOMEM);
+
+ *size = di->blocksize;
+ if (length == di->blocksize)
+ temp = virtual;
+ else {
+ temp = di->blockbuf;
+ memset(temp + length, 0, di->blocksize - length);
+ memcpy(temp, virtual, length);
+ }
+ ret = dump_write(di, temp, physical, offset, *size);
+
+ return (ret);
+}
+
+
void
mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver,
uint64_t dumplen, uint32_t blksz)
Index: head/sys/sys/conf.h
===================================================================
--- head/sys/sys/conf.h
+++ head/sys/sys/conf.h
@@ -328,15 +328,18 @@
struct dumperinfo {
dumper_t *dumper; /* Dumping function. */
- void *priv; /* Private parts. */
- u_int blocksize; /* Size of block in bytes. */
+ void *priv; /* Private parts. */
+ u_int blocksize; /* Size of block in bytes. */
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. */
+ off_t mediaoffset; /* Initial offset in bytes. */
+ off_t mediasize; /* Space available in bytes. */
+ void *blockbuf; /* Buffer for padding shorter dump blocks */
};
int set_dumper(struct dumperinfo *, const char *_devname, struct thread *td);
int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t);
+int dump_write_pad(struct dumperinfo *, void *, vm_offset_t, off_t, size_t,
+ size_t *);
int doadump(boolean_t);
extern int dumping; /* system is dumping */

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 4, 8:28 AM (6 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
9066732
Default Alt Text
D5848.diff (9 KB)

Event Timeline