convert to 4.1c directory layout
[unix-history] / usr / src / sbin / savecore / savecore.c
index a67d283..81871b3 100644 (file)
@@ -1,4 +1,4 @@
-static char *sccsid = "@(#)savecore.c  4.6 (Berkeley) 81/05/20";
+static char *sccsid = "@(#)savecore.c  4.9 (Berkeley) 82/10/24";
 /*
  * savecore
  */
 /*
  * savecore
  */
@@ -8,7 +8,6 @@ static  char *sccsid = "@(#)savecore.c  4.6 (Berkeley) 81/05/20";
 #include <sys/param.h>
 #include <sys/dir.h>
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <sys/dir.h>
 #include <sys/stat.h>
-#include <sys/filsys.h>
 #include <time.h>
 
 #define        DAY     (60L*60L*24L)
 #include <time.h>
 
 #define        DAY     (60L*60L*24L)
@@ -32,9 +31,44 @@ struct nlist nl[] = {
        { "_version" },
 #define X_PANICSTR     5
        { "_panicstr" },
        { "_version" },
 #define X_PANICSTR     5
        { "_panicstr" },
+#define X_DOADUMP      6
+       { "_doadump" },
+#define X_DOADUMP      6
+       { "_doadump" },
        { 0 },
 };
 
        { 0 },
 };
 
+/*
+ *     this magic number is found in the kernel at label "doadump"
+ *
+ *     It is derived as follows:
+ *
+ *             doadump:        nop                     01
+ *                             nop                     01
+ *                             bicl2 $...              ca
+ *                                                     8f
+ *
+ *     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:
+ *
+ *             doadump:        nop                     01
+ *                             nop                     01
+ *                             bicl2 $...              ca
+ *                                                     8f
+ *
+ *     Thus, it is likely to be moderately stable, even across
+ *     operating system releases.
+ */
+#define DUMPMAG 0x8fca0101
+
+char   *system;
 char   *dirname;                       /* directory to save dumps in */
 char   *ddname;                        /* name of dump device */
 char   *find_dev();
 char   *dirname;                       /* directory to save dumps in */
 char   *ddname;                        /* name of dump device */
 char   *find_dev();
@@ -58,22 +92,42 @@ main(argc, argv)
        int argc;
 {
 
        int argc;
 {
 
-       if (argc != 2) {
-               fprintf(stderr, "usage: savecore dirname\n");
+       if (argc != 2 && argc != 3) {
+               fprintf(stderr, "usage: savecore dirname [ system ]\n");
                exit(1);
        }
        dirname = argv[1];
                exit(1);
        }
        dirname = argv[1];
+       if (argc == 3)
+               system = argv[2];
        if (access(dirname, 2) < 0) {
                perror(dirname);
                exit(1);
        }
        if (access(dirname, 2) < 0) {
                perror(dirname);
                exit(1);
        }
-       (void) time(&now);
        read_kmem();
        read_kmem();
-       log_entry();
-       if (get_crashtime() && check_space())
-               save_core();
-       else
-               exit(1);
+}
+
+int
+dump_exists()
+{
+       register int dumpfd;
+       int word;
+
+       dumpfd = Open(ddname, 0);
+       Lseek(dumpfd, (off_t)(dumplo + ok(nl[X_DOADUMP].n_value)), 0);
+       Read(dumpfd, (char *)&word, sizeof word);
+       close(dumpfd);
+       return (word == DUMPMAG);
+}
+
+clear_dump()
+{
+       register int dumpfd;
+       int zero = 0;
+
+       dumpfd = Open(ddname, 1);
+       Lseek(dumpfd, (off_t)(dumplo + ok(nl[X_DOADUMP].n_value)), 0);
+       Write(dumpfd, (char *)&zero, sizeof zero);
+       close(dumpfd);
 }
 
 char *
 }
 
 char *
@@ -81,18 +135,10 @@ find_dev(dev, type)
        register dev_t dev;
        register int type;
 {
        register dev_t dev;
        register int type;
 {
-       register int dfd = Open("/dev", 0);
-       struct direct dir;
        struct stat statb;
        struct stat statb;
-       static char devname[DIRSIZ + 1];
        char *dp;
 
        strcpy(devname, "/dev/");
        char *dp;
 
        strcpy(devname, "/dev/");
-       while(Read(dfd, (char *)&dir, sizeof dir) > 0) {
-               if (dir.d_ino == 0)
-                       continue;
-               strncpy(devname + 5, dir.d_name, DIRSIZ);
-               devname[DIRSIZ] = '\0';
                if (stat(devname, &statb)) {
                        perror(devname);
                        continue;
                if (stat(devname, &statb)) {
                        perror(devname);
                        continue;
@@ -100,13 +146,11 @@ find_dev(dev, type)
                if ((statb.st_mode&S_IFMT) != type)
                        continue;
                if (dev == statb.st_rdev) {
                if ((statb.st_mode&S_IFMT) != type)
                        continue;
                if (dev == statb.st_rdev) {
-                       close(dfd);
                        dp = (char *)malloc(strlen(devname)+1);
                        strcpy(dp, devname);
                        return dp;
                }
        }
                        dp = (char *)malloc(strlen(devname)+1);
                        strcpy(dp, devname);
                        return dp;
                }
        }
-       close(dfd);
        fprintf(stderr, "Can't find device %d,%d\n", major(dev), minor(dev));
        exit(1);
        /*NOTREACHED*/
        fprintf(stderr, "Can't find device %d,%d\n", major(dev), minor(dev));
        exit(1);
        /*NOTREACHED*/
@@ -143,6 +187,14 @@ read_kmem()
                fprintf(stderr, "/vmunix: panicstr not in namelist\n");
                exit(1);
        }
                fprintf(stderr, "/vmunix: panicstr not in namelist\n");
                exit(1);
        }
+       if (nl[X_DOADUMP].n_value == 0) {
+               fprintf(stderr, "/vmunix: doadump not in namelist\n");
+               exit(1);
+       }
+       if (nl[X_DOADUMP].n_value == 0) {
+               fprintf(stderr, "/vmunix: doadump not in namelist\n");
+               exit(1);
+       }
        kmem = Open("/dev/kmem", 0);
        Lseek(kmem, (long)nl[X_DUMPDEV].n_value, 0);
        Read(kmem, (char *)&dumpdev, sizeof dumpdev);
        kmem = Open("/dev/kmem", 0);
        Lseek(kmem, (long)nl[X_DUMPDEV].n_value, 0);
        Read(kmem, (char *)&dumpdev, sizeof dumpdev);
@@ -156,9 +208,17 @@ read_kmem()
                fprintf(stderr, "Couldn't fdopen kmem\n");
                exit(1);
        }
                fprintf(stderr, "Couldn't fdopen kmem\n");
                exit(1);
        }
+       if (system)
+               return;
        fseek(fp, (long)nl[X_VERSION].n_value, 0);
        fgets(vers, sizeof vers, fp);
        fclose(fp);
        fseek(fp, (long)nl[X_VERSION].n_value, 0);
        fgets(vers, sizeof vers, fp);
        fclose(fp);
+}
+
+check_kmem() {
+       FILE *fp;
+       register char *cp;
+
        if ((fp = fopen(ddname, "r")) == NULL) {
                perror(ddname);
                exit(1);
        if ((fp = fopen(ddname, "r")) == NULL) {
                perror(ddname);
                exit(1);
@@ -180,18 +240,17 @@ read_kmem()
                while (*cp++);
        }
        fclose(fp);
                while (*cp++);
        }
        fclose(fp);
-}      
+}
 
 get_crashtime()
 {
        int dumpfd;
        time_t clobber = (time_t)0;
 
 
 get_crashtime()
 {
        int dumpfd;
        time_t clobber = (time_t)0;
 
-       dumpfd = Open(ddname, 2);
+       if (system)
+               return (1);
        Lseek(dumpfd, (off_t)(dumplo + ok(nl[X_TIME].n_value)), 0);
        Read(dumpfd, (char *)&dumptime, sizeof dumptime);
        Lseek(dumpfd, (off_t)(dumplo + ok(nl[X_TIME].n_value)), 0);
        Read(dumpfd, (char *)&dumptime, sizeof dumptime);
-       Lseek(dumpfd, (off_t)(dumplo + ok(nl[X_TIME].n_value)), 0);
-       Write(dumpfd, (char *)&clobber, sizeof clobber);
        close(dumpfd);
        if (dumptime == 0) {
 #ifdef DEBUG
        close(dumpfd);
        if (dumptime == 0) {
 #ifdef DEBUG
@@ -223,8 +282,8 @@ check_space()
 {
        struct stat dsb;
        register char *ddev;
 {
        struct stat dsb;
        register char *ddev;
-       register int dfd;
-       struct filsys sblk;
+       int dfd, freespace;
+       struct fs fs;
 
        if (stat(dirname, &dsb) < 0) {
                perror(dirname);
 
        if (stat(dirname, &dsb) < 0) {
                perror(dirname);
@@ -232,13 +291,18 @@ check_space()
        }
        ddev = find_dev(dsb.st_dev, S_IFBLK);
        dfd = Open(ddev, 0);
        }
        ddev = find_dev(dsb.st_dev, S_IFBLK);
        dfd = Open(ddev, 0);
-       Lseek(dfd, 1L<<BSHIFT, 0);
-       Read(dfd, (char *)&sblk, sizeof sblk);
+       Lseek(dfd, (long)(SBLOCK * DEV_BSIZE), 0);
+       Read(dfd, (char *)&fs, sizeof fs);
        close(dfd);
        close(dfd);
-       if (read_number("minfree") > sblk.s_tfree) {
+       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");
                return (0);
        }
                fprintf(stderr, "Dump omitted, not enough space on device\n");
                return (0);
        }
+       if (fs.fs_cstotal.cs_nbfree * fs.fs_frag + fs.fs_cstotal.cs_nffree <
+           fs.fs_dsize * fs.fs_minfree / 100)
+               fprintf(stderr,
+                       "Dump performed, but free space threshold crossed\n");
        return (1);
 }
 
        return (1);
 }
 
@@ -267,14 +331,14 @@ save_core()
        register FILE *fp;
 
        bounds = read_number("bounds");
        register FILE *fp;
 
        bounds = read_number("bounds");
-       ifd = Open("/vmunix", 0);
-       ofd = Create(path(sprintf(cp, "vmunix.%d", bounds)), 0666);
+       ifd = Open(system?system:"/vmunix", 0);
        while((n = Read(ifd, cp, BUFSIZ)) > 0)
                Write(ofd, cp, n);
        close(ifd);
        close(ofd);
        ifd = Open(ddname, 0);
        while((n = Read(ifd, cp, BUFSIZ)) > 0)
                Write(ofd, cp, n);
        close(ifd);
        close(ofd);
        ifd = Open(ddname, 0);
-       ofd = Create(path(sprintf(cp, "vmcore.%d", bounds)), 0666);
+       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);
        while(physmem > 0) {
        Lseek(ifd, (off_t)dumplo, 0);
        printf("Saving %d bytes of image in vmcore.%d\n", NBPG*physmem, bounds);
        while(physmem > 0) {
@@ -386,3 +450,7 @@ Write(fd, buf, size)
                exit(1);
        }
 }
                exit(1);
        }
 }
+
+
+
+