| 278 | } |
| 279 | |
| 280 | static void update_scb(struct plugin *p, struct scb_chan **channels) |
| 281 | { |
| 282 | |
| 283 | /* If the temp file existed before, remove it */ |
| 284 | unlink_noerr("scb.tmp"); |
| 285 | |
| 286 | int fd = open("scb.tmp", O_CREAT|O_EXCL|O_WRONLY, 0400); |
| 287 | if (fd<0) |
| 288 | plugin_err(p, "Opening: %s", strerror(errno)); |
| 289 | |
| 290 | plugin_log(p, LOG_DBG, "Updating the SCB file..."); |
| 291 | |
| 292 | write_scb(p, fd, channels); |
| 293 | |
| 294 | /* fsync (mostly!) ensures that the file has reached the disk. */ |
| 295 | if (fsync(fd) != 0) { |
| 296 | unlink_noerr("scb.tmp"); |
| 297 | } |
| 298 | |
| 299 | /* This should never fail if fsync succeeded. But paranoia good, and |
| 300 | * bugs exist. */ |
| 301 | if (close(fd) != 0) { |
| 302 | unlink_noerr("scb.tmp"); |
| 303 | } |
| 304 | /* We actually need to sync the *directory itself* to make sure the |
| 305 | * file exists! You're only allowed to open directories read-only in |
| 306 | * modern Unix though. */ |
| 307 | fd = open(".", O_RDONLY); |
| 308 | if (fd < 0) { |
| 309 | plugin_log(p, LOG_DBG, "Opening: %s", strerror(errno)); |
| 310 | } |
| 311 | if (fsync(fd) != 0) { |
| 312 | unlink_noerr("scb.tmp"); |
| 313 | } |
| 314 | close(fd); |
| 315 | |
| 316 | /* This will atomically replace the main file */ |
| 317 | rename("scb.tmp", "emergency.recover"); |
| 318 | } |
| 319 | |
| 320 | static struct command_result *after_staticbackup(struct command *cmd, |
| 321 | const char *buf, |
no test coverage detected