Fix savecore so that it operates correctly on character devices with

sectorsizes up to 8k.

Pointed out by: sos
This commit is contained in:
Poul-Henning Kamp 1999-08-31 18:12:44 +00:00
parent ad49df8e02
commit c43f30e13a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=50711

View File

@ -123,6 +123,8 @@ void check_kmem __P((void));
int check_space __P((void)); int check_space __P((void));
void clear_dump __P((void)); void clear_dump __P((void));
int Create __P((char *, int)); int Create __P((char *, int));
void DumpRead __P((int fd, void *bp, int size, off_t off, int flag));
void DumpWrite __P((int fd, void *bp, int size, off_t off, int flag));
int dump_exists __P((void)); int dump_exists __P((void));
char *find_dev __P((dev_t, int)); char *find_dev __P((dev_t, int));
int get_crashtime __P((void)); int get_crashtime __P((void));
@ -285,31 +287,24 @@ void
check_kmem() check_kmem()
{ {
register char *cp; register char *cp;
FILE *fp; char core_vers[1024], *p;
char core_vers[1024];
fp = fdopen(dumpfd, "r"); DumpRead(dumpfd, core_vers, sizeof(core_vers),
if (fp == NULL) { (off_t)(dumplo + ok(dump_nl[X_VERSION].n_value)), L_SET);
syslog(LOG_ERR, "%s: fdopen: %m", ddname); core_vers[sizeof(core_vers) - 1] = '\0';
exit(1); p = strchr(core_vers, '\n');
} if (p)
fseek(fp, (off_t)(dumplo + ok(dump_nl[X_VERSION].n_value)), L_SET); p[1] = '\0';
fgets(core_vers, sizeof(core_vers), fp);
if (strcmp(vers, core_vers) && kernel == 0) if (strcmp(vers, core_vers) && kernel == 0)
syslog(LOG_WARNING, syslog(LOG_WARNING,
"warning: %s version mismatch:\n\t%s\nand\t%s\n", "warning: %s version mismatch:\n\t\"%s\"\nand\t\"%s\"\n",
getbootfile(), vers, core_vers); getbootfile(), vers, core_vers);
(void)fseek(fp, DumpRead(dumpfd, &panicstr, sizeof(panicstr),
(off_t)(dumplo + ok(dump_nl[X_PANICSTR].n_value)), L_SET); (off_t)(dumplo + ok(dump_nl[X_PANICSTR].n_value)), L_SET);
(void)fread(&panicstr, sizeof(panicstr), 1, fp);
if (panicstr) { if (panicstr) {
(void)fseek(fp, dumplo + ok(panicstr), L_SET); DumpRead(dumpfd, panic_mesg, sizeof(panic_mesg),
cp = panic_mesg; (off_t)(dumplo + ok(panicstr)), L_SET);
do
*cp = getc(fp);
while (*cp++ && cp < &panic_mesg[sizeof(panic_mesg)]);
} }
/* Don't fclose(fp), we use dumpfd later. */
} }
void void
@ -318,8 +313,8 @@ clear_dump()
long newdumplo; long newdumplo;
newdumplo = 0; newdumplo = 0;
Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), L_SET); DumpWrite(dumpfd, &newdumplo, sizeof(newdumplo),
Write(dumpfd, &newdumplo, sizeof(newdumplo)); (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), L_SET);
} }
int int
@ -327,8 +322,8 @@ dump_exists()
{ {
int newdumpmag; int newdumpmag;
Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), L_SET); DumpRead(dumpfd, &newdumpmag, sizeof(newdumpmag),
(void)Read(dumpfd, &newdumpmag, sizeof(newdumpmag)); (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), L_SET);
if (newdumpmag != dumpmag) { if (newdumpmag != dumpmag) {
if (verbose) if (verbose)
syslog(LOG_WARNING, "magic number mismatch (%x != %x)", syslog(LOG_WARNING, "magic number mismatch (%x != %x)",
@ -528,8 +523,8 @@ get_crashtime()
{ {
time_t dumptime; /* Time the dump was taken. */ time_t dumptime; /* Time the dump was taken. */
Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_TIME].n_value)), L_SET); DumpRead(dumpfd, &dumptime, sizeof(dumptime),
(void)Read(dumpfd, &dumptime, sizeof(dumptime)); (off_t)(dumplo + ok(dump_nl[X_TIME].n_value)), L_SET);
if (dumptime == 0) { if (dumptime == 0) {
if (verbose) if (verbose)
syslog(LOG_ERR, "dump time is zero"); syslog(LOG_ERR, "dump time is zero");
@ -548,8 +543,8 @@ void
get_dumpsize() get_dumpsize()
{ {
/* Read the dump size. */ /* Read the dump size. */
Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPSIZE].n_value)), L_SET); DumpRead(dumpfd, &dumpsize, sizeof(dumpsize),
(void)Read(dumpfd, &dumpsize, sizeof(dumpsize)); (off_t)(dumplo + ok(dump_nl[X_DUMPSIZE].n_value)), L_SET);
dumpsize *= getpagesize(); dumpsize *= getpagesize();
} }
@ -643,6 +638,74 @@ Lseek(fd, off, flag)
} }
} }
/*
* DumpWrite and DumpRead block io requests to the * dump device.
*/
#define DUMPBUFSIZE 8192
void
DumpWrite(fd, bp, size, off, flag)
int fd, size, flag;
void *bp;
off_t off;
{
unsigned char buf[DUMPBUFSIZE], *p, *q;
off_t pos;
int i, j;
if (flag != L_SET) {
syslog(LOG_ERR, "lseek: not LSET");
exit(2);
}
q = bp;
while (size) {
pos = off & ~(DUMPBUFSIZE - 1);
Lseek(fd, pos, flag);
(void)Read(fd, buf, sizeof(buf));
j = off & (DUMPBUFSIZE - 1);
p = buf + j;
i = size;
if (i > DUMPBUFSIZE - j)
i = DUMPBUFSIZE - j;
memcpy(p, q, i);
Lseek(fd, pos, flag);
(void)Write(fd, buf, sizeof(buf));
size -= i;
q += i;
off += i;
}
}
void
DumpRead(fd, bp, size, off, flag)
int fd, size, flag;
void *bp;
off_t off;
{
unsigned char buf[DUMPBUFSIZE], *p, *q;
off_t pos;
int i, j;
if (flag != L_SET) {
syslog(LOG_ERR, "lseek: not LSET");
exit(2);
}
q = bp;
while (size) {
pos = off & ~(DUMPBUFSIZE - 1);
Lseek(fd, pos, flag);
(void)Read(fd, buf, sizeof(buf));
j = off & (DUMPBUFSIZE - 1);
p = buf + j;
i = size;
if (i > DUMPBUFSIZE - j)
i = DUMPBUFSIZE - j;
memcpy(q, p, i);
size -= i;
q += i;
off += i;
}
}
int int
Create(file, mode) Create(file, mode)
char *file; char *file;