From fb55e80394c51d7502bb278f57520dec15a11355 Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Sat, 8 Aug 2020 19:08:23 -0400 Subject: 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 Signed-off-by: Hans Dedecker --- src/dhcpv6-ia.c | 12 ++++++++++-- 1 file 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]; -- cgit v1.2.3