summaryrefslogtreecommitdiffhomepage
path: root/src/dhcpv6-ia.c
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2020-08-08 19:08:23 -0400
committerHans Dedecker <dedeckeh@gmail.com>2020-11-15 18:33:22 +0100
commitfb55e80394c51d7502bb278f57520dec15a11355 (patch)
treed95477035551829e564a4268708de964d35a430a /src/dhcpv6-ia.c
parent735c7836bfcc08f3ecd8cdaf1368665b8a241b94 (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>
Diffstat (limited to 'src/dhcpv6-ia.c')
-rw-r--r--src/dhcpv6-ia.c12
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];