savecore.c revision 7950274e5799b56695a76f974ac361411ec2e515
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <deflt.h>
#include <time.h>
#include <syslog.h>
#include <stropts.h>
#include <sys/compress.h>
#include <sys/sysmacros.h>
static char *savedir; /* savecore directory */
static char *dumpfile; /* source of raw crash dump */
static long pagesize; /* dump pagesize */
static int verbose; /* chatty mode */
static int disregard_valid_flag; /* disregard valid flag */
static int livedump; /* dump the current running system */
static void
usage(void)
{
"usage: %s [-Lvd] [-f dumpfile] [dirname]\n", progname);
exit(1);
}
static void
{
char buf[1024];
if (showmsg) {
if (logpri >= 0)
}
if (exitcode >= 0)
}
/*
* System call / libc wrappers that exit on error.
*/
static int
{
int fd;
return (fd);
}
static void
{
}
static void
{
}
static void *
{
void *buf;
return (buf);
}
static long
{
long file_value = -1;
}
}
static void
read_dumphdr(void)
{
"dump version (%d) != %s version (%d)",
"dump is from %u-bit kernel - cannot save on %u-bit kernel",
/*
* Read the initial header, clear the valid bits, and compare headers.
* The main header may have been overwritten by swapping if we're
* using a swap partition as the dump device, in which case we bail.
*/
/*
* Clear valid bit so we don't complain on every invocation.
*/
}
}
static void
check_space(void)
{
"not enough space in %s (%lld MB avail, %lld MB needed)",
}
static void
{
long i;
static long misses = 0;
for (i = 0; i < corehdr.dump_nvtop; i++) {
long first = 0;
long middle;
uintptr_t h;
break;
else
}
if (++misses <= 10)
"pfn %ld not found for as=%p, va=%p\n",
continue;
}
}
}
static void
{
int percent_done = 0;
/*
* Read in the compressed symbol table, copy it to corefile,
* decompress it, and write the result to namelist.
*/
ksyms_size)) != ksyms_size)
/*
* Read in and write out the pfn table.
*/
/*
* Convert the raw translation data into a hashed dump map.
*/
/*
* Decompress and save the pages.
*/
break;
break;
}
}
/*
* Write out the modified dump headers.
*/
}
/*
* When the system panics, the kernel saves all undelivered messages (messages
* that never made it out to syslogd(1M)) in the dump. At a mimimum, the
* panic message itself will always fall into this category. Upon reboot,
* the syslog startup script runs savecore -m to recover these messages.
*
* To do this, we read the unsent messages from the dump and send them to
* to any already-accumulated messages in the console backlog, thus preserving
* temporal ordering across the reboot.
*
* Note: since savecore -m is used *only* for this purpose, it does *not*
* attempt to save the crash dump. The dump will be saved later, after
* syslogd(1M) starts, by the savecore startup script.
*/
static int
message_save(void)
{
int logfd;
for (;;) {
dumpoff += sizeof (log_dump_t);
break;
}
return (0);
}
int
{
int c, bfd;
int mflag = 0;
long bounds;
(void) defopen("/etc/dumpadm.conf");
switch (c) {
case 'L':
livedump++;
break;
case 'v':
verbose++;
break;
case 'd':
break;
case 'm':
mflag++;
break;
case 'f':
break;
case '?':
usage();
}
}
/*
* If this isn't an interactive session, we are running
* as part of the boot process. If this is the case,
* don't complain about the lack of dump device.
*/
if (isatty(STDOUT_FILENO))
"no dump device configured");
else
return (1);
}
}
if (mflag)
return (message_save());
usage();
read_dumphdr();
/*
* We want this message to go to the log file, but not the console.
* There's no good way to do that with the existing syslog facility.
* We could extend it to handle this, but there doesn't seem to be
* a general need for it, so we isolate the complexity here instead.
*/
char fmt[] = "reboot after panic: %s";
}
check_space();
return (0);
}