[Midnightbsd-cvs] src [10483] trunk/sbin/savecore/savecore.c: sync
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Wed Jun 6 21:04:37 EDT 2018
Revision: 10483
http://svnweb.midnightbsd.org/src/?rev=10483
Author: laffer1
Date: 2018-06-06 21:04:36 -0400 (Wed, 06 Jun 2018)
Log Message:
-----------
sync
Modified Paths:
--------------
trunk/sbin/savecore/Makefile
trunk/sbin/savecore/savecore.8
trunk/sbin/savecore/savecore.c
Property Changed:
----------------
trunk/sbin/savecore/savecore.8
Modified: trunk/sbin/savecore/Makefile
===================================================================
--- trunk/sbin/savecore/Makefile 2018-06-07 00:37:07 UTC (rev 10482)
+++ trunk/sbin/savecore/Makefile 2018-06-07 01:04:36 UTC (rev 10483)
@@ -1,4 +1,5 @@
# $MidnightBSD$
+# $FreeBSD: stable/10/sbin/savecore/Makefile 198236 2009-10-19 16:00:24Z ru $
PROG= savecore
DPADD= ${LIBZ}
Modified: trunk/sbin/savecore/savecore.8
===================================================================
--- trunk/sbin/savecore/savecore.8 2018-06-07 00:37:07 UTC (rev 10482)
+++ trunk/sbin/savecore/savecore.8 2018-06-07 01:04:36 UTC (rev 10483)
@@ -1,3 +1,4 @@
+.\" $MidnightBSD$
.\" Copyright (c) 1980, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -26,9 +27,9 @@
.\" SUCH DAMAGE.
.\"
.\" From: @(#)savecore.8 8.1 (Berkeley) 6/5/93
-.\" $MidnightBSD$
+.\" $FreeBSD: stable/10/sbin/savecore/savecore.8 244320 2012-12-16 23:06:12Z pjd $
.\"
-.Dd December 24, 2008
+.Dd December 17, 2012
.Dt SAVECORE 8
.Os
.Sh NAME
@@ -37,12 +38,15 @@
.Sh SYNOPSIS
.Nm
.Fl c
+.Op Fl v
+.Op Ar device ...
.Nm
.Fl C
.Op Fl v
-.Op Ar directory device
+.Op Ar device ...
.Nm
.Op Fl fkvz
+.Op Fl m Ar maxdumps
.Op Ar directory Op Ar device ...
.Sh DESCRIPTION
The
@@ -57,7 +61,7 @@
the system log.
.Pp
The options are as follows:
-.Bl -tag -width indent
+.Bl -tag -width ".Fl m Ar maxdumps"
.It Fl C
Check to see if a dump exists,
and display a brief message to indicate the status.
@@ -75,6 +79,12 @@
dump header information is inconsistent.
.It Fl k
Do not clear the dump after saving it.
+.It Fl m Ar maxdumps
+Maximum number of dumps to store.
+Once the number of stored dumps is equal to
+.Ar maxdumps
+the counter will restart from
+.Dv 0 .
.It Fl v
Print out some additional debugging information.
Specify twice for more information.
Property changes on: trunk/sbin/savecore/savecore.8
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/sbin/savecore/savecore.c
===================================================================
--- trunk/sbin/savecore/savecore.c 2018-06-07 00:37:07 UTC (rev 10482)
+++ trunk/sbin/savecore/savecore.c 2018-06-07 01:04:36 UTC (rev 10483)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2002 Poul-Henning Kamp
* Copyright (c) 2002 Networks Associates Technology, Inc.
@@ -61,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/savecore/savecore.c 321212 2017-07-19 16:38:55Z ngie $");
#include <sys/param.h>
#include <sys/disk.h>
@@ -68,10 +69,12 @@
#include <sys/kerneldump.h>
#include <sys/mount.h>
#include <sys/stat.h>
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <fstab.h>
#include <paths.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -89,6 +92,7 @@
static int checkfor, compress, clear, force, keep, verbose; /* flags */
static int nfound, nsaved, nerr; /* statistics */
+static int maxdumps;
extern FILE *zopen(const char *, const char *);
@@ -149,7 +153,10 @@
}
if (fgets(buf, sizeof buf, fp) == NULL) {
- syslog(LOG_WARNING, "unable to read from bounds, using 0");
+ if (feof(fp))
+ syslog(LOG_WARNING, "bounds file is empty, using 0");
+ else
+ syslog(LOG_WARNING, "bounds file: %s", strerror(errno));
fclose(fp);
return (ret);
}
@@ -158,6 +165,7 @@
ret = (int)strtol(buf, NULL, 10);
if (ret == 0 && (errno == EINVAL || errno == ERANGE))
syslog(LOG_WARNING, "invalid value found in bounds, using 0");
+ fclose(fp);
return (ret);
}
@@ -177,42 +185,122 @@
fclose(fp);
}
+static off_t
+file_size(const char *path)
+{
+ struct stat sb;
+
+ /* Ignore all errors, those file may not exists. */
+ if (stat(path, &sb) == -1)
+ return (0);
+ return (sb.st_size);
+}
+
+static off_t
+saved_dump_size(int bounds)
+{
+ static char path[PATH_MAX];
+ off_t dumpsize;
+
+ dumpsize = 0;
+
+ (void)snprintf(path, sizeof(path), "info.%d", bounds);
+ dumpsize += file_size(path);
+ (void)snprintf(path, sizeof(path), "vmcore.%d", bounds);
+ dumpsize += file_size(path);
+ (void)snprintf(path, sizeof(path), "vmcore.%d.gz", bounds);
+ dumpsize += file_size(path);
+ (void)snprintf(path, sizeof(path), "textdump.tar.%d", bounds);
+ dumpsize += file_size(path);
+ (void)snprintf(path, sizeof(path), "textdump.tar.%d.gz", bounds);
+ dumpsize += file_size(path);
+
+ return (dumpsize);
+}
+
+static void
+saved_dump_remove(int bounds)
+{
+ static char path[PATH_MAX];
+
+ (void)snprintf(path, sizeof(path), "info.%d", bounds);
+ (void)unlink(path);
+ (void)snprintf(path, sizeof(path), "vmcore.%d", bounds);
+ (void)unlink(path);
+ (void)snprintf(path, sizeof(path), "vmcore.%d.gz", bounds);
+ (void)unlink(path);
+ (void)snprintf(path, sizeof(path), "textdump.tar.%d", bounds);
+ (void)unlink(path);
+ (void)snprintf(path, sizeof(path), "textdump.tar.%d.gz", bounds);
+ (void)unlink(path);
+}
+
+static void
+symlinks_remove(void)
+{
+
+ (void)unlink("info.last");
+ (void)unlink("vmcore.last");
+ (void)unlink("vmcore.last.gz");
+ (void)unlink("textdump.tar.last");
+ (void)unlink("textdump.tar.last.gz");
+}
+
/*
* Check that sufficient space is available on the disk that holds the
* save directory.
*/
static int
-check_space(const char *savedir, off_t dumpsize)
+check_space(const char *savedir, off_t dumpsize, int bounds)
{
FILE *fp;
- off_t minfree, spacefree, totfree, needed;
+ off_t available, minfree, spacefree, totfree, needed;
struct statfs fsbuf;
- char buf[100], path[MAXPATHLEN];
+ char buf[100];
- if (statfs(savedir, &fsbuf) < 0) {
+ if (statfs(".", &fsbuf) < 0) {
syslog(LOG_ERR, "%s: %m", savedir);
exit(1);
}
- spacefree = ((off_t) fsbuf.f_bavail * fsbuf.f_bsize) / 1024;
+ spacefree = ((off_t) fsbuf.f_bavail * fsbuf.f_bsize) / 1024;
totfree = ((off_t) fsbuf.f_bfree * fsbuf.f_bsize) / 1024;
- (void)snprintf(path, sizeof(path), "%s/minfree", savedir);
- if ((fp = fopen(path, "r")) == NULL)
+ if ((fp = fopen("minfree", "r")) == NULL)
minfree = 0;
else {
if (fgets(buf, sizeof(buf), fp) == NULL)
minfree = 0;
- else
- minfree = atoi(buf);
+ else {
+ char *endp;
+
+ errno = 0;
+ minfree = strtoll(buf, &endp, 10);
+ if (minfree == 0 && errno != 0)
+ minfree = -1;
+ else {
+ while (*endp != '\0' && isspace(*endp))
+ endp++;
+ if (*endp != '\0' || minfree < 0)
+ minfree = -1;
+ }
+ if (minfree < 0)
+ syslog(LOG_WARNING,
+ "`minfree` didn't contain a valid size "
+ "(`%s`). Defaulting to 0", buf);
+ }
(void)fclose(fp);
}
+ available = minfree > 0 ? spacefree - minfree : totfree;
needed = dumpsize / 1024 + 2; /* 2 for info file */
- if (((minfree > 0) ? spacefree : totfree) - needed < minfree) {
+ needed -= saved_dump_size(bounds);
+ if (available < needed) {
syslog(LOG_WARNING,
- "no dump, not enough free space on device (%lld available, need %lld)",
- (long long)(minfree > 0 ? spacefree : totfree),
- (long long)needed);
+ "no dump: not enough free space on device (need at least "
+ "%jdkB for dump; %jdkB available; %jdkB reserved)",
+ (intmax_t)needed,
+ (intmax_t)available + minfree,
+ (intmax_t)minfree);
return (0);
}
if (spacefree - needed < 0)
@@ -261,7 +349,7 @@
if (he >= hs + BLOCKSIZE)
break;
}
-
+
/* back down to a block boundary */
he &= BLOCKMASK;
@@ -367,7 +455,7 @@
static void
DoFile(const char *savedir, const char *device)
{
- static char filename[PATH_MAX];
+ static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX];
static char *buf = NULL;
struct kerneldumpheader kdhf, kdhl;
off_t mediasize, dumpsize, firsthd, lasthd;
@@ -382,6 +470,9 @@
mediasize = 0;
status = STATUS_UNKNOWN;
+ if (maxdumps > 0 && bounds == maxdumps)
+ bounds = 0;
+
if (buf == NULL) {
buf = malloc(BUFFERSIZE);
if (buf == NULL) {
@@ -393,7 +484,7 @@
if (verbose)
printf("checking for kernel dump on device %s\n", device);
- fd = open(device, O_RDWR);
+ fd = open(device, (checkfor || keep) ? O_RDONLY : O_RDWR);
if (fd < 0) {
syslog(LOG_ERR, "%s: %m", device);
return;
@@ -409,8 +500,8 @@
}
if (verbose) {
- printf("mediasize = %lld\n", (long long)mediasize);
- printf("sectorsize = %u\n", sectorsize);
+ printf("mediasize = %lld bytes\n", (long long)mediasize);
+ printf("sectorsize = %u bytes\n", sectorsize);
}
lasthd = mediasize - sectorsize;
@@ -432,7 +523,7 @@
syslog(LOG_ERR,
"unknown version (%d) in last dump header on %s",
dtoh32(kdhl.version), device);
-
+
status = STATUS_BAD;
if (force == 0)
goto closefd;
@@ -443,7 +534,7 @@
syslog(LOG_ERR,
"unknown version (%d) in last dump header on %s",
dtoh32(kdhl.version), device);
-
+
status = STATUS_BAD;
if (force == 0)
goto closefd;
@@ -471,7 +562,7 @@
syslog(LOG_ERR,
"unknown version (%d) in last dump header on %s",
dtoh32(kdhl.version), device);
-
+
status = STATUS_BAD;
if (force == 0)
goto closefd;
@@ -535,7 +626,8 @@
if (verbose)
printf("Checking for available free space\n");
- if (!check_space(savedir, dumpsize)) {
+
+ if (!check_space(savedir, dumpsize, bounds)) {
nerr++;
goto closefd;
}
@@ -542,29 +634,31 @@
writebounds(bounds + 1);
- sprintf(buf, "info.%d", bounds);
+ saved_dump_remove(bounds);
+ snprintf(infoname, sizeof(infoname), "info.%d", bounds);
+
/*
* Create or overwrite any existing dump header files.
*/
- fdinfo = open(buf, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ fdinfo = open(infoname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fdinfo < 0) {
- syslog(LOG_ERR, "%s: %m", buf);
+ syslog(LOG_ERR, "%s: %m", infoname);
nerr++;
goto closefd;
}
oumask = umask(S_IRWXG|S_IRWXO); /* Restrict access to the core file.*/
if (compress) {
- sprintf(filename, "%s.%d.gz", istextdump ? "textdump.tar" :
- "vmcore", bounds);
- fp = zopen(filename, "w");
+ snprintf(corename, sizeof(corename), "%s.%d.gz",
+ istextdump ? "textdump.tar" : "vmcore", bounds);
+ fp = zopen(corename, "w");
} else {
- sprintf(filename, "%s.%d", istextdump ? "textdump.tar" :
- "vmcore", bounds);
- fp = fopen(filename, "w");
+ snprintf(corename, sizeof(corename), "%s.%d",
+ istextdump ? "textdump.tar" : "vmcore", bounds);
+ fp = fopen(corename, "w");
}
if (fp == NULL) {
- syslog(LOG_ERR, "%s: %m", filename);
+ syslog(LOG_ERR, "%s: %m", corename);
close(fdinfo);
nerr++;
goto closefd;
@@ -585,15 +679,15 @@
printheader(info, &kdhl, device, bounds, status);
fclose(info);
- syslog(LOG_NOTICE, "writing %score to %s",
- compress ? "compressed " : "", filename);
+ syslog(LOG_NOTICE, "writing %score to %s/%s",
+ compress ? "compressed " : "", savedir, corename);
if (istextdump) {
if (DoTextdumpFile(fd, dumpsize, lasthd, buf, device,
- filename, fp) < 0)
+ corename, fp) < 0)
goto closeall;
} else {
- if (DoRegularFile(fd, dumpsize, buf, device, filename, fp)
+ if (DoRegularFile(fd, dumpsize, buf, device, corename, fp)
< 0)
goto closeall;
}
@@ -601,10 +695,28 @@
printf("\n");
if (fclose(fp) < 0) {
- syslog(LOG_ERR, "error on %s: %m", filename);
+ syslog(LOG_ERR, "error on %s: %m", corename);
nerr++;
- goto closeall;
+ goto closefd;
}
+
+ symlinks_remove();
+ if (symlink(infoname, "info.last") == -1) {
+ syslog(LOG_WARNING, "unable to create symlink %s/%s: %m",
+ savedir, "info.last");
+ }
+ if (compress) {
+ snprintf(linkname, sizeof(linkname), "%s.last.gz",
+ istextdump ? "textdump.tar" : "vmcore");
+ } else {
+ snprintf(linkname, sizeof(linkname), "%s.last",
+ istextdump ? "textdump.tar" : "vmcore");
+ }
+ if (symlink(corename, linkname) == -1) {
+ syslog(LOG_WARNING, "unable to create symlink %s/%s: %m",
+ savedir, linkname);
+ }
+
nsaved++;
if (verbose)
@@ -611,7 +723,7 @@
printf("dump saved\n");
nuke:
- if (clear || !keep) {
+ if (!keep) {
if (verbose)
printf("clearing dump header\n");
memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof kdhl.magic);
@@ -635,10 +747,10 @@
usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n",
- "usage: savecore -c",
- " savecore -C [-v] [directory device]",
- " savecore [-fkvz] [directory [device ...]]");
- exit (1);
+ "usage: savecore -c [-v] [device ...]",
+ " savecore -C [-v] [device ...]",
+ " savecore [-fkvz] [-m maxdumps] [directory [device ...]]");
+ exit(1);
}
int
@@ -654,7 +766,7 @@
openlog("savecore", LOG_PERROR, LOG_DAEMON);
signal(SIGINFO, infohandler);
- while ((ch = getopt(argc, argv, "Ccfkvz")) != -1)
+ while ((ch = getopt(argc, argv, "Ccfkm:vz")) != -1)
switch(ch) {
case 'C':
checkfor = 1;
@@ -662,15 +774,22 @@
case 'c':
clear = 1;
break;
+ case 'f':
+ force = 1;
+ break;
case 'k':
keep = 1;
break;
+ case 'm':
+ maxdumps = atoi(optarg);
+ if (maxdumps <= 0) {
+ syslog(LOG_ERR, "Invalid maxdump value");
+ exit(1);
+ }
+ break;
case 'v':
verbose++;
break;
- case 'f':
- force = 1;
- break;
case 'z':
compress = 1;
break;
@@ -680,9 +799,13 @@
}
if (checkfor && (clear || force || keep))
usage();
+ if (clear && (compress || keep))
+ usage();
+ if (maxdumps > 0 && (checkfor || clear))
+ usage();
argc -= optind;
argv += optind;
- if (argc >= 1) {
+ if (argc >= 1 && !checkfor && !clear) {
error = chdir(argv[0]);
if (error) {
syslog(LOG_ERR, "chdir(%s): %m", argv[0]);
More information about the Midnightbsd-cvs
mailing list