Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F81916699
D5848.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D5848.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D5848: Add support of 4Kn kernel dumps.
Attached
Detach File
Event Timeline
Log In to Comment