Skip to content

Commit

Permalink
write objects.precache in tmp file first, then move it
Browse files Browse the repository at this point in the history
It's a good standard to do so and in fact, we do this already in several
places, ex. the status.dat. This ensures the file is ready and completly
written before it will be used.

The issue here is, that naemon starts without any issues if the precached file
is empty for any reason. Except it has zero hosts/services then and removes all
existing states/downtime/comments.

Signed-off-by: Sven Nierlein <[email protected]>
  • Loading branch information
sni committed Oct 12, 2023
1 parent ffeecc1 commit e75cc3d
Showing 1 changed file with 54 additions and 5 deletions.
59 changes: 54 additions & 5 deletions src/naemon/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "logging.h"
#include "globals.h"
#include "nm_alloc.h"
#include "utils.h"

int __nagios_object_structure_version = CURRENT_OBJECT_STRUCTURE_VERSION;

Expand All @@ -20,17 +21,32 @@ int fcache_objects(char *cache_file)
FILE *fp = NULL;
time_t current_time = 0L;
unsigned int i;
char *tmp_file = NULL;
int fd = 0;
int result = OK;

/* some people won't want to cache their objects */
if (!cache_file || !strcmp(cache_file, "/dev/null"))
return OK;

time(&current_time);

nm_asprintf(&tmp_file, "%sXXXXXX", cache_file);
if (tmp_file == NULL)
return ERROR;

if ((fd = mkstemp(tmp_file)) == -1) {
nm_log(NSLOG_RUNTIME_ERROR, "Error: Unable to create temp file '%s' for writing object cache data: %s\n", tmp_file, strerror(errno));
nm_free(tmp_file);
return ERROR;
}

/* open the cache file for writing */
fp = fopen(cache_file, "w");
fp = (FILE *)fopen(tmp_file, "w");
if (fp == NULL) {
nm_log(NSLOG_CONFIG_WARNING, "Warning: Could not open object cache file '%s' for writing!\n", cache_file);
unlink(tmp_file);
nm_log(NSLOG_CONFIG_WARNING, "Warning: Could not open object cache data file '%s' for writing!\n", tmp_file);
nm_free(tmp_file);
return ERROR;
}

Expand All @@ -44,7 +60,6 @@ int fcache_objects(char *cache_file)
fprintf(fp, "# Created: %s", ctime(&current_time));
fprintf(fp, "########################################\n\n");


/* cache timeperiods */
for (i = 0; i < num_objects.timeperiods; i++)
fcache_timeperiod(fp, timeperiod_ary[i]);
Expand Down Expand Up @@ -109,7 +124,41 @@ int fcache_objects(char *cache_file)
fcache_hostescalation(fp, esclist->object_ptr);
}

fclose(fp);
/* reset file permissions */
fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);

/* flush the file to disk */
fflush(fp);

/* fsync the file so that it is completely written out before moving it */
fsync(fd);

/* close the temp file */
result = ferror(fp) | fclose(fp);

/* save/close was successful */
if (result == 0) {

result = OK;

/* move the temp file to the status log (overwrite the old status log) */
if (my_rename(tmp_file, cache_file)) {
unlink(tmp_file);
nm_log(NSLOG_RUNTIME_ERROR, "Error: Unable to update cache data file '%s': %s", cache_file, strerror(errno));
result = ERROR;
}
}

/* a problem occurred saving the file */
else {
result = ERROR;

/* remove temp file and log an error */
unlink(tmp_file);
nm_log(NSLOG_RUNTIME_ERROR, "Error: Unable to save cache data file: %s", strerror(errno));
}

nm_free(tmp_file);

return OK;
return result;
}

0 comments on commit e75cc3d

Please sign in to comment.