From: Hitoshi Mitake <mitake.hito...@gmail.com> Because we cannot utilize the journaling mechanism for config, this patch implements atomic creation and writing for it.
Signed-off-by: Hitoshi Mitake <mitake.hito...@lab.ntt.co.jp> --- v4: remove the unnecessary global variable v3: - rephrase the message of check_tmp_config() - remove a redundant constant v2: use access(2) for checking remained temporal file sheep/config.c | 30 ++++++++++++++++++++++++++++-- 1 files changed, 28 insertions(+), 2 deletions(-) diff --git a/sheep/config.c b/sheep/config.c index 49916e7..6bc092b 100644 --- a/sheep/config.c +++ b/sheep/config.c @@ -36,10 +36,13 @@ char *config_path; static int write_config(void) { int fd, ret; + char tmp_config_path[PATH_MAX]; - fd = open(config_path, O_RDWR | O_CREAT | O_DSYNC, def_fmode); + snprintf(tmp_config_path, PATH_MAX, "%s.tmp", config_path); + + fd = open(tmp_config_path, O_WRONLY | O_CREAT | O_SYNC, def_fmode); if (fd < 0) { - sd_eprintf("failed to open config file, %m"); + sd_eprintf("failed to temporal file for config, %m"); return SD_RES_EIO; } @@ -51,13 +54,36 @@ static int write_config(void) ret = SD_RES_SUCCESS; close(fd); + ret = rename(tmp_config_path, config_path); + if (ret < 0) { + sd_eprintf("failed to rename, %m"); + ret = SD_RES_EIO; + } + + unlink(tmp_config_path); + return ret; } +static void check_tmp_config(void) +{ + char tmp_config_path[PATH_MAX]; + + snprintf(tmp_config_path, PATH_MAX, "%s.tmp", config_path); + + if (!access(tmp_config_path, F_OK)) + return; + + sd_iprintf("remove temporal config file"); + unlink(tmp_config_path); +} + int init_config_file(void) { int fd, ret; + check_tmp_config(); + fd = open(config_path, O_RDONLY); if (fd < 0) { if (errno != ENOENT) { -- 1.7.2.5 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog