diff options
author | Hans Dedecker <dedeckeh@gmail.com> | 2020-08-08 19:08:23 -0400 |
---|---|---|
committer | Hans Dedecker <dedeckeh@gmail.com> | 2020-11-15 18:33:22 +0100 |
commit | fb55e80394c51d7502bb278f57520dec15a11355 (patch) | |
tree | d95477035551829e564a4268708de964d35a430a | |
parent | 735c7836bfcc08f3ecd8cdaf1368665b8a241b94 (diff) |
dhcpv6-ia : write statefile atomically
Applications (e.g. unbound) need a consistent view of the statefile;
therefore write all the lease info to a temporary file which is later
renamed to the configured statefile name
Suggested-by : John Fremlin <john@fremlin.org>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
-rw-r--r-- | src/dhcpv6-ia.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index 38a901b..7ca8e4f 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -306,18 +306,24 @@ void dhcpv6_ia_write_statefile(void) md5_begin(&ctxt.md5); if (config.dhcp_statefile) { + unsigned tmp_statefile_strlen = strlen(config.dhcp_statefile) + strlen(".tmp") + 1; + char *tmp_statefile = alloca(tmp_statefile_strlen); time_t now = odhcpd_time(), wall_time = time(NULL); - int fd = open(config.dhcp_statefile, O_CREAT | O_WRONLY | O_CLOEXEC, 0644); + int fd, ret; char leasebuf[512]; + snprintf(tmp_statefile, tmp_statefile_strlen, "%s.tmp", config.dhcp_statefile); + + fd = open(tmp_statefile, O_CREAT | O_WRONLY | O_CLOEXEC, 0644); if (fd < 0) return; - int ret; + ret = lockf(fd, F_LOCK, 0); if (ret < 0) { close(fd); return; } + if (ftruncate(fd, 0) < 0) {} ctxt.fp = fdopen(fd, "w"); @@ -410,6 +416,8 @@ void dhcpv6_ia_write_statefile(void) } fclose(ctxt.fp); + + rename(tmp_statefile, config.dhcp_statefile); } uint8_t newmd5[16]; |