static char *sccsid
= "@(#)savecore.c 4.9 (Berkeley) 82/10/24";
#define DAY (60L*60L*24L)
#define eq(a,b) (!strcmp(a,b))
#define ok(number) ((number)&0x7fffffff)
#define SHUTDOWNLOG "/usr/adm/shutdownlog"
* this magic number is found in the kernel at label "doadump"
* It is derived as follows:
* Thus, it is likely to be moderately stable, even across
* operating system releases.
#define DUMPMAG 0x8fca0101
* this magic number is found in the kernel at label "doadump"
* It is derived as follows:
* Thus, it is likely to be moderately stable, even across
* operating system releases.
#define DUMPMAG 0x8fca0101
char *dirname
; /* directory to save dumps in */
char *ddname
; /* name of dump device */
dev_t dumpdev
; /* dump device */
time_t dumptime
; /* time the dump was taken */
int dumplo
; /* where dump starts on dumpdev */
int physmem
; /* amount of memory in machine */
time_t now
; /* current date */
if (argc
!= 2 && argc
!= 3) {
fprintf(stderr
, "usage: savecore dirname [ system ]\n");
if (access(dirname
, 2) < 0) {
dumpfd
= Open(ddname
, 0);
Lseek(dumpfd
, (off_t
)(dumplo
+ ok(nl
[X_DOADUMP
].n_value
)), 0);
Read(dumpfd
, (char *)&word
, sizeof word
);
return (word
== DUMPMAG
);
dumpfd
= Open(ddname
, 1);
Lseek(dumpfd
, (off_t
)(dumplo
+ ok(nl
[X_DOADUMP
].n_value
)), 0);
Write(dumpfd
, (char *)&zero
, sizeof zero
);
strcpy(devname
, "/dev/");
if (stat(devname
, &statb
)) {
if ((statb
.st_mode
&S_IFMT
) != type
)
if (dev
== statb
.st_rdev
) {
dp
= (char *)malloc(strlen(devname
)+1);
fprintf(stderr
, "Can't find device %d,%d\n", major(dev
), minor(dev
));
if (nl
[X_DUMPDEV
].n_value
== 0) {
fprintf(stderr
, "/vmunix: dumpdev not in namelist\n");
if (nl
[X_DUMPLO
].n_value
== 0) {
fprintf(stderr
, "/vmunix: dumplo not in namelist\n");
if (nl
[X_TIME
].n_value
== 0) {
fprintf(stderr
, "/vmunix: time not in namelist\n");
if (nl
[X_PHYSMEM
].n_value
== 0) {
fprintf(stderr
, "/vmunix: physmem not in namelist\n");
if (nl
[X_VERSION
].n_value
== 0) {
fprintf(stderr
, "/vmunix: version not in namelist\n");
if (nl
[X_PANICSTR
].n_value
== 0) {
fprintf(stderr
, "/vmunix: panicstr not in namelist\n");
if (nl
[X_DOADUMP
].n_value
== 0) {
fprintf(stderr
, "/vmunix: doadump not in namelist\n");
if (nl
[X_DOADUMP
].n_value
== 0) {
fprintf(stderr
, "/vmunix: doadump not in namelist\n");
kmem
= Open("/dev/kmem", 0);
Lseek(kmem
, (long)nl
[X_DUMPDEV
].n_value
, 0);
Read(kmem
, (char *)&dumpdev
, sizeof dumpdev
);
Lseek(kmem
, (long)nl
[X_DUMPLO
].n_value
, 0);
Read(kmem
, (char *)&dumplo
, sizeof dumplo
);
Lseek(kmem
, (long)nl
[X_PHYSMEM
].n_value
, 0);
Read(kmem
, (char *)&physmem
, sizeof physmem
);
ddname
= find_dev(dumpdev
, S_IFBLK
);
if ((fp
= fdopen(kmem
, "r")) == NULL
) {
fprintf(stderr
, "Couldn't fdopen kmem\n");
fseek(fp
, (long)nl
[X_VERSION
].n_value
, 0);
fgets(vers
, sizeof vers
, fp
);
if ((fp
= fopen(ddname
, "r")) == NULL
) {
fseek(fp
, (off_t
)(dumplo
+ok(nl
[X_VERSION
].n_value
)), 0);
fgets(core_vers
, sizeof core_vers
, fp
);
if (!eq(vers
, core_vers
))
fprintf(stderr
, "Warning: vmunix version mismatch:\n\t%sand\n\t%s",
fseek(fp
, (off_t
)(dumplo
+ ok(nl
[X_PANICSTR
].n_value
)), 0);
fread((char *)&panicstr
, sizeof panicstr
, 1, fp
);
fseek(fp
, dumplo
+ ok(panicstr
), 0);
time_t clobber
= (time_t)0;
Lseek(dumpfd
, (off_t
)(dumplo
+ ok(nl
[X_TIME
].n_value
)), 0);
Read(dumpfd
, (char *)&dumptime
, sizeof dumptime
);
printf("dump time is 0\n");
printf("System went down at %s", ctime(&dumptime
));
if (dumptime
< now
- LEEWAY
|| dumptime
> now
+ LEEWAY
) {
printf("Dump time is unreasonable\n");
register char *cp
= (char *)malloc(strlen(file
) + strlen(dirname
) + 2);
(void) strcpy(cp
, dirname
);
if (stat(dirname
, &dsb
) < 0) {
ddev
= find_dev(dsb
.st_dev
, S_IFBLK
);
Lseek(dfd
, (long)(SBLOCK
* DEV_BSIZE
), 0);
Read(dfd
, (char *)&fs
, sizeof fs
);
freespace
= fs
.fs_cstotal
.cs_nbfree
* fs
.fs_bsize
/ 1024;
if (read_number("minfree") > freespace
) {
fprintf(stderr
, "Dump omitted, not enough space on device\n");
if (fs
.fs_cstotal
.cs_nbfree
* fs
.fs_frag
+ fs
.fs_cstotal
.cs_nffree
<
fs
.fs_dsize
* fs
.fs_minfree
/ 100)
"Dump performed, but free space threshold crossed\n");
if ((fp
= fopen(path(fn
), "r")) == NULL
)
if (fgets(lin
, 80, fp
) == NULL
) {
register char *cp
= buffer
;
register int ifd
, ofd
, bounds
;
bounds
= read_number("bounds");
ifd
= Open(system
?system
:"/vmunix", 0);
while((n
= Read(ifd
, cp
, BUFSIZ
)) > 0)
sprintf(cp
, "vmcore.%d", bounds
);
ofd
= Create(path(cp
), 0644);
Lseek(ifd
, (off_t
)dumplo
, 0);
printf("Saving %d bytes of image in vmcore.%d\n", NBPG
*physmem
, bounds
);
n
= Read(ifd
, cp
, (physmem
> 32 ? 32 : physmem
) * NBPG
);
fp
= fopen(path("bounds"), "w");
fprintf(fp
, "%d\n", bounds
+1);
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
struct tm
*tm
, *localtime();
fp
= fopen("/usr/adm/shutdownlog", "a");
fprintf(fp
, "%02d:%02d %s %s %2d, %4d. Reboot", tm
->tm_hour
,
tm
->tm_min
, days
[tm
->tm_wday
], months
[tm
->tm_mon
],
tm
->tm_mday
, tm
->tm_year
+ 1900);
fprintf(fp
, " after panic: %s\n", panic_mesg
);
* Versions of std routines that exit on error.
if ((fd
= open(name
, rw
)) < 0) {
if ((ret
= read(fd
, buff
, size
)) < 0) {
if ((ret
= lseek(fd
, off
, flag
)) == -1L) {
if ((fd
= creat(file
, mode
)) < 0) {
if (write(fd
, buf
, size
) < size
) {