Print this page
7475 savecore should not go further if there is no dumpfile


  55 #include <sys/fm/util.h>
  56 #include <fm/libfmevent.h>
  57 #include <sys/int_fmtio.h>
  58 
  59 
  60 /* fread/fwrite buffer size */
  61 #define FBUFSIZE                (1ULL << 20)
  62 
  63 /* minimum size for output buffering */
  64 #define MINCOREBLKSIZE          (1ULL << 17)
  65 
  66 /* create this file if metrics collection is enabled in the kernel */
  67 #define METRICSFILE "METRICS.csv"
  68 
  69 static char     progname[9] = "savecore";
  70 static char     *savedir;               /* savecore directory */
  71 static char     *dumpfile;              /* source of raw crash dump */
  72 static long     bounds = -1;            /* numeric suffix */
  73 static long     pagesize;               /* dump pagesize */
  74 static int      dumpfd = -1;            /* dumpfile descriptor */

  75 static dumphdr_t corehdr, dumphdr;      /* initial and terminal dumphdrs */
  76 static boolean_t dump_incomplete;       /* dumphdr indicates incomplete */
  77 static boolean_t fm_panic;              /* dump is the result of fm_panic */
  78 static offset_t endoff;                 /* offset of end-of-dump header */
  79 static int      verbose;                /* chatty mode */
  80 static int      disregard_valid_flag;   /* disregard valid flag */
  81 static int      livedump;               /* dump the current running system */
  82 static int      interactive;            /* user invoked; no syslog */
  83 static int      csave;                  /* save dump compressed */
  84 static int      filemode;               /* processing file, not dump device */
  85 static int      percent_done;           /* progress indicator */
  86 static int      sec_done;               /* progress last report time */
  87 static hrtime_t startts;                /* timestamp at start */
  88 static volatile uint64_t saved;         /* count of pages written */
  89 static volatile uint64_t zpages;        /* count of zero pages not written */
  90 static dumpdatahdr_t datahdr;           /* compression info */
  91 static long     coreblksize;            /* preferred write size (st_blksize) */
  92 static int      cflag;                  /* run as savecore -c */
  93 static int      mflag;                  /* run as savecore -m */
  94 


 222                 code = 0;
 223                 break;
 224 
 225         case SC_EXIT_PEND:
 226                 /*
 227                  * Raise an ireport saying why we are exiting.  Do not
 228                  * raise if run as savecore -m.  If something in the
 229                  * raise_event codepath calls logprint avoid recursion.
 230                  */
 231                 if (!mflag && logprint_raised++ == 0)
 232                         raise_event(SC_EVENT_SAVECORE_FAILURE, buf);
 233                 code = 2;
 234                 break;
 235 
 236         case SC_EXIT_FM:
 237                 code = 3;
 238                 break;
 239 
 240         case SC_EXIT_ERR:
 241         default:
 242                 if (!mflag && logprint_raised++ == 0)
 243                         raise_event(SC_EVENT_SAVECORE_FAILURE, buf);
 244                 code = 1;
 245                 break;
 246         }
 247 
 248         exit(code);
 249 }
 250 
 251 /*
 252  * System call / libc wrappers that exit on error.
 253  */
 254 static int
 255 Open(const char *name, int oflags, mode_t mode)
 256 {
 257         int fd;
 258 
 259         if ((fd = open64(name, oflags, mode)) == -1)
 260                 logprint(SC_SL_ERR | SC_EXIT_ERR, "open(\"%s\"): %s",
 261                     name, strerror(errno));
 262         return (fd);


 282 Fseek(offset_t off, FILE *f)
 283 {
 284         if (fseeko64(f, off, SEEK_SET) != 0)
 285                 logprint(SC_SL_ERR | SC_EXIT_ERR, "fseeko64: %s",
 286                     strerror(errno));
 287 }
 288 
 289 typedef struct stat64 Stat_t;
 290 
 291 static void
 292 Fstat(int fd, Stat_t *sb, const char *fname)
 293 {
 294         if (fstat64(fd, sb) != 0)
 295                 logprint(SC_SL_ERR | SC_EXIT_ERR, "fstat(\"%s\"): %s", fname,
 296                     strerror(errno));
 297 }
 298 
 299 static void
 300 Stat(const char *fname, Stat_t *sb)
 301 {
 302         if (stat64(fname, sb) != 0)
 303                 logprint(SC_SL_ERR | SC_EXIT_ERR, "stat(\"%s\"): %s", fname,
 304                     strerror(errno));


 305 }
 306 
 307 static void
 308 Pread(int fd, void *buf, size_t size, offset_t off)
 309 {
 310         ssize_t sz = pread64(fd, buf, size, off);
 311 
 312         if (sz < 0)
 313                 logprint(SC_SL_ERR | SC_EXIT_ERR,
 314                     "pread: %s", strerror(errno));
 315         else if (sz != size)
 316                 logprint(SC_SL_ERR | SC_EXIT_ERR,
 317                     "pread: size %ld != %ld", sz, size);
 318 }
 319 
 320 static void
 321 Pwrite(int fd, void *buf, size_t size, off64_t off)
 322 {
 323         if (pwrite64(fd, buf, size, off) != size)
 324                 logprint(SC_SL_ERR | SC_EXIT_ERR, "pwrite: %s",


1694         /*
1695          * If doing something other than extracting an existing dump (i.e.
1696          * dumpfile has been provided as an option), the user must be root.
1697          */
1698         if (geteuid() != 0 && dumpfile == NULL) {
1699                 (void) fprintf(stderr, "%s: %s %s\n", progname,
1700                     gettext("you must be root to use"), progname);
1701                 exit(1);
1702         }
1703 
1704         interactive = isatty(STDOUT_FILENO);
1705 
1706         if (cflag && livedump)
1707                 usage();
1708 
1709         if (dumpfile == NULL || livedump)
1710                 dumpfd = Open("/dev/dump", O_RDONLY, 0444);
1711 
1712         if (dumpfile == NULL) {
1713                 dumpfile = Zalloc(MAXPATHLEN);
1714                 if (ioctl(dumpfd, DIOCGETDEV, dumpfile) == -1)

1715                         logprint(SC_SL_NONE | SC_IF_ISATTY | SC_EXIT_ERR,
1716                             "no dump device configured");

1717         }
1718 
1719         if (mflag)
1720                 return (message_save());
1721 
1722         if (optind == argc - 1)
1723                 savedir = argv[optind];
1724 
1725         if (savedir == NULL || optind < argc - 1)
1726                 usage();
1727 
1728         if (livedump && ioctl(dumpfd, DIOCDUMP, NULL) == -1)
1729                 logprint(SC_SL_NONE | SC_EXIT_ERR,
1730                     "dedicated dump device required");
1731 
1732         (void) close(dumpfd);
1733         dumpfd = -1;
1734 
1735         Stat(dumpfile, &st);
1736 




  55 #include <sys/fm/util.h>
  56 #include <fm/libfmevent.h>
  57 #include <sys/int_fmtio.h>
  58 
  59 
  60 /* fread/fwrite buffer size */
  61 #define FBUFSIZE                (1ULL << 20)
  62 
  63 /* minimum size for output buffering */
  64 #define MINCOREBLKSIZE          (1ULL << 17)
  65 
  66 /* create this file if metrics collection is enabled in the kernel */
  67 #define METRICSFILE "METRICS.csv"
  68 
  69 static char     progname[9] = "savecore";
  70 static char     *savedir;               /* savecore directory */
  71 static char     *dumpfile;              /* source of raw crash dump */
  72 static long     bounds = -1;            /* numeric suffix */
  73 static long     pagesize;               /* dump pagesize */
  74 static int      dumpfd = -1;            /* dumpfile descriptor */
  75 static boolean_t have_dumpfile = B_TRUE;        /* dumpfile existence */
  76 static dumphdr_t corehdr, dumphdr;      /* initial and terminal dumphdrs */
  77 static boolean_t dump_incomplete;       /* dumphdr indicates incomplete */
  78 static boolean_t fm_panic;              /* dump is the result of fm_panic */
  79 static offset_t endoff;                 /* offset of end-of-dump header */
  80 static int      verbose;                /* chatty mode */
  81 static int      disregard_valid_flag;   /* disregard valid flag */
  82 static int      livedump;               /* dump the current running system */
  83 static int      interactive;            /* user invoked; no syslog */
  84 static int      csave;                  /* save dump compressed */
  85 static int      filemode;               /* processing file, not dump device */
  86 static int      percent_done;           /* progress indicator */
  87 static int      sec_done;               /* progress last report time */
  88 static hrtime_t startts;                /* timestamp at start */
  89 static volatile uint64_t saved;         /* count of pages written */
  90 static volatile uint64_t zpages;        /* count of zero pages not written */
  91 static dumpdatahdr_t datahdr;           /* compression info */
  92 static long     coreblksize;            /* preferred write size (st_blksize) */
  93 static int      cflag;                  /* run as savecore -c */
  94 static int      mflag;                  /* run as savecore -m */
  95 


 223                 code = 0;
 224                 break;
 225 
 226         case SC_EXIT_PEND:
 227                 /*
 228                  * Raise an ireport saying why we are exiting.  Do not
 229                  * raise if run as savecore -m.  If something in the
 230                  * raise_event codepath calls logprint avoid recursion.
 231                  */
 232                 if (!mflag && logprint_raised++ == 0)
 233                         raise_event(SC_EVENT_SAVECORE_FAILURE, buf);
 234                 code = 2;
 235                 break;
 236 
 237         case SC_EXIT_FM:
 238                 code = 3;
 239                 break;
 240 
 241         case SC_EXIT_ERR:
 242         default:
 243                 if (!mflag && logprint_raised++ == 0 && have_dumpfile)
 244                         raise_event(SC_EVENT_SAVECORE_FAILURE, buf);
 245                 code = 1;
 246                 break;
 247         }
 248 
 249         exit(code);
 250 }
 251 
 252 /*
 253  * System call / libc wrappers that exit on error.
 254  */
 255 static int
 256 Open(const char *name, int oflags, mode_t mode)
 257 {
 258         int fd;
 259 
 260         if ((fd = open64(name, oflags, mode)) == -1)
 261                 logprint(SC_SL_ERR | SC_EXIT_ERR, "open(\"%s\"): %s",
 262                     name, strerror(errno));
 263         return (fd);


 283 Fseek(offset_t off, FILE *f)
 284 {
 285         if (fseeko64(f, off, SEEK_SET) != 0)
 286                 logprint(SC_SL_ERR | SC_EXIT_ERR, "fseeko64: %s",
 287                     strerror(errno));
 288 }
 289 
 290 typedef struct stat64 Stat_t;
 291 
 292 static void
 293 Fstat(int fd, Stat_t *sb, const char *fname)
 294 {
 295         if (fstat64(fd, sb) != 0)
 296                 logprint(SC_SL_ERR | SC_EXIT_ERR, "fstat(\"%s\"): %s", fname,
 297                     strerror(errno));
 298 }
 299 
 300 static void
 301 Stat(const char *fname, Stat_t *sb)
 302 {
 303         if (stat64(fname, sb) != 0) {
 304                 have_dumpfile = B_FALSE;
 305                 logprint(SC_SL_ERR | SC_EXIT_ERR, "failed to get status "
 306                     "of file %s", fname);
 307         }
 308 }
 309 
 310 static void
 311 Pread(int fd, void *buf, size_t size, offset_t off)
 312 {
 313         ssize_t sz = pread64(fd, buf, size, off);
 314 
 315         if (sz < 0)
 316                 logprint(SC_SL_ERR | SC_EXIT_ERR,
 317                     "pread: %s", strerror(errno));
 318         else if (sz != size)
 319                 logprint(SC_SL_ERR | SC_EXIT_ERR,
 320                     "pread: size %ld != %ld", sz, size);
 321 }
 322 
 323 static void
 324 Pwrite(int fd, void *buf, size_t size, off64_t off)
 325 {
 326         if (pwrite64(fd, buf, size, off) != size)
 327                 logprint(SC_SL_ERR | SC_EXIT_ERR, "pwrite: %s",


1697         /*
1698          * If doing something other than extracting an existing dump (i.e.
1699          * dumpfile has been provided as an option), the user must be root.
1700          */
1701         if (geteuid() != 0 && dumpfile == NULL) {
1702                 (void) fprintf(stderr, "%s: %s %s\n", progname,
1703                     gettext("you must be root to use"), progname);
1704                 exit(1);
1705         }
1706 
1707         interactive = isatty(STDOUT_FILENO);
1708 
1709         if (cflag && livedump)
1710                 usage();
1711 
1712         if (dumpfile == NULL || livedump)
1713                 dumpfd = Open("/dev/dump", O_RDONLY, 0444);
1714 
1715         if (dumpfile == NULL) {
1716                 dumpfile = Zalloc(MAXPATHLEN);
1717                 if (ioctl(dumpfd, DIOCGETDEV, dumpfile) == -1) {
1718                         have_dumpfile  = B_FALSE;
1719                         logprint(SC_SL_NONE | SC_IF_ISATTY | SC_EXIT_ERR,
1720                             "no dump device configured");
1721                 }
1722         }
1723 
1724         if (mflag)
1725                 return (message_save());
1726 
1727         if (optind == argc - 1)
1728                 savedir = argv[optind];
1729 
1730         if (savedir == NULL || optind < argc - 1)
1731                 usage();
1732 
1733         if (livedump && ioctl(dumpfd, DIOCDUMP, NULL) == -1)
1734                 logprint(SC_SL_NONE | SC_EXIT_ERR,
1735                     "dedicated dump device required");
1736 
1737         (void) close(dumpfd);
1738         dumpfd = -1;
1739 
1740         Stat(dumpfile, &st);
1741