From: Hitoshi Mitake <[email protected]> Because we cannot utilize the journaling mechanism for config, this patch implements atomic creation and writing for it.
Signed-off-by: Hitoshi Mitake <[email protected]> --- v2: use access(2) for checking remained temporal file sheep/config.c | 30 +++++++++++++++++++++++++++--- 1 files changed, 27 insertions(+), 3 deletions(-) diff --git a/sheep/config.c b/sheep/config.c index 49916e7..5756e64 100644 --- a/sheep/config.c +++ b/sheep/config.c @@ -29,17 +29,18 @@ static struct sheepdog_config { uint64_t space; } config; -char *config_path; +char *config_path, *tmp_config_path; #define CONFIG_PATH "/config" +#define TMP_CONFIG_PATH "/config.tmp" static int write_config(void) { int fd, ret; - fd = open(config_path, O_RDWR | O_CREAT | O_DSYNC, def_fmode); + 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 +52,32 @@ 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) +{ + if (!access(tmp_config_path, F_OK)) + return; + + sd_iprintf("temporal file for config exists"); + 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) { @@ -119,6 +139,10 @@ void init_config_path(const char *base_path) config_path = xzalloc(len); snprintf(config_path, len, "%s" CONFIG_PATH, base_path); + + len = strlen(base_path) + strlen(TMP_CONFIG_PATH) + 1; + tmp_config_path = xzalloc(len); + snprintf(tmp_config_path, len, "%s" TMP_CONFIG_PATH, base_path); } int set_cluster_ctime(uint64_t ct) -- 1.7.2.5 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
