Changeset View
Changeset View
Standalone View
Standalone View
sbin/savecore/savecore.c
Show First 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | writebounds(int bounds) { | ||||
if (verbose) | if (verbose) | ||||
printf("bounds number: %d\n", bounds); | printf("bounds number: %d\n", bounds); | ||||
fprintf(fp, "%d\n", bounds); | fprintf(fp, "%d\n", bounds); | ||||
fclose(fp); | 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 | static void | ||||
saved_dump_remove(int bounds) | saved_dump_remove(int bounds) | ||||
{ | { | ||||
static char path[PATH_MAX]; | static char path[PATH_MAX]; | ||||
(void)snprintf(path, sizeof(path), "info.%d", bounds); | (void)snprintf(path, sizeof(path), "info.%d", bounds); | ||||
(void)unlink(path); | (void)unlink(path); | ||||
(void)snprintf(path, sizeof(path), "vmcore.%d", bounds); | (void)snprintf(path, sizeof(path), "vmcore.%d", bounds); | ||||
Show All 12 Lines | symlinks_remove(void) | ||||
(void)unlink("info.last"); | (void)unlink("info.last"); | ||||
(void)unlink("vmcore.last"); | (void)unlink("vmcore.last"); | ||||
(void)unlink("vmcore.last.gz"); | (void)unlink("vmcore.last.gz"); | ||||
(void)unlink("textdump.tar.last"); | (void)unlink("textdump.tar.last"); | ||||
(void)unlink("textdump.tar.last.gz"); | (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, int bounds) | |||||
{ | |||||
FILE *fp; | |||||
off_t minfree, spacefree, totfree, needed; | |||||
struct statfs fsbuf; | |||||
char buf[100]; | |||||
if (statfs(".", &fsbuf) < 0) { | |||||
syslog(LOG_ERR, "%s: %m", savedir); | |||||
exit(1); | |||||
} | |||||
spacefree = ((off_t) fsbuf.f_bavail * fsbuf.f_bsize) / 1024; | |||||
totfree = ((off_t) fsbuf.f_bfree * fsbuf.f_bsize) / 1024; | |||||
if ((fp = fopen("minfree", "r")) == NULL) | |||||
minfree = 0; | |||||
else { | |||||
if (fgets(buf, sizeof(buf), fp) == NULL) | |||||
minfree = 0; | |||||
else | |||||
minfree = atoi(buf); | |||||
(void)fclose(fp); | |||||
} | |||||
needed = dumpsize / 1024 + 2; /* 2 for info file */ | |||||
needed -= saved_dump_size(bounds); | |||||
if ((minfree > 0 ? spacefree : totfree) - needed < minfree) { | |||||
syslog(LOG_WARNING, | |||||
"no dump, not enough free space on device (%lld available, need %lld)", | |||||
(long long)(minfree > 0 ? spacefree : totfree), | |||||
(long long)needed); | |||||
return (0); | |||||
} | |||||
if (spacefree - needed < 0) | |||||
syslog(LOG_WARNING, | |||||
"dump performed, but free space threshold crossed"); | |||||
return (1); | |||||
} | |||||
def: This empty line should be removed. | |||||
#define BLOCKSIZE (1<<12) | #define BLOCKSIZE (1<<12) | ||||
#define BLOCKMASK (~(BLOCKSIZE-1)) | #define BLOCKMASK (~(BLOCKSIZE-1)) | ||||
static int | static int | ||||
DoRegularFile(int fd, off_t dumpsize, char *buf, const char *device, | DoRegularFile(int fd, off_t dumpsize, char *buf, const char *device, | ||||
const char *filename, FILE *fp) | const char *filename, FILE *fp) | ||||
{ | { | ||||
int he, hs, nr, nw, wl; | int he, hs, nr, nw, wl; | ||||
▲ Show 20 Lines • Show All 306 Lines • ▼ Show 20 Lines | if (checkfor) { | ||||
exit(0); | exit(0); | ||||
} | } | ||||
if (kdhl.panicstring[0]) | if (kdhl.panicstring[0]) | ||||
syslog(LOG_ALERT, "reboot after panic: %s", kdhl.panicstring); | syslog(LOG_ALERT, "reboot after panic: %s", kdhl.panicstring); | ||||
else | else | ||||
syslog(LOG_ALERT, "reboot"); | syslog(LOG_ALERT, "reboot"); | ||||
if (verbose) | if (verbose) | ||||
printf("Checking for available free space\n"); | printf("Checking for available free space\n"); | ||||
defUnsubmitted Not Done Inline ActionsIf we don't check free space then we shouldn't write this message. def: If we don't check free space then we shouldn't write this message. | |||||
if (!check_space(savedir, dumpsize, bounds)) { | |||||
nerr++; | |||||
goto closefd; | |||||
} | |||||
writebounds(bounds + 1); | writebounds(bounds + 1); | ||||
defUnsubmitted Not Done Inline Actionssavecore can fail during saving a core dump. writebounds should be called after the core was successfully written. Otherwise a user can delete old core dumps (because of low maxdumps value) when it repeatedly tries to save the new core dump without enough space. Also it would be better to overwrite a partial core dump with a full core dump once a user has more free space. def: savecore can fail during saving a core dump. writebounds should be called after the core was… | |||||
saved_dump_remove(bounds); | saved_dump_remove(bounds); | ||||
snprintf(infoname, sizeof(infoname), "info.%d", bounds); | snprintf(infoname, sizeof(infoname), "info.%d", bounds); | ||||
/* | /* | ||||
* Create or overwrite any existing dump header files. | * Create or overwrite any existing dump header files. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 231 Lines • Show Last 20 Lines |
This empty line should be removed.