diff options
| author | Remi Collet <remi@remirepo.net> | 2020-11-16 11:57:40 +0100 | 
|---|---|---|
| committer | Remi Collet <remi@remirepo.net> | 2020-11-16 11:57:40 +0100 | 
| commit | 70ef0b40a559570e9588c7b22933a1f60625afe5 (patch) | |
| tree | a6760c8c1082b355be987a2ec5d866863a91d4a9 | |
| parent | 747b0eb70d4425ea5572c5e464d4c8f87fd6a634 (diff) | |
fix broken config rewrite feature using patch from
  https://github.com/redis/redis/pull/8058
| -rw-r--r-- | 0003-Fix-8051-use-old-way-as-fallback-to-save-configurati.patch | 96 | ||||
| -rw-r--r-- | redis.spec | 10 | 
2 files changed, 105 insertions, 1 deletions
| diff --git a/0003-Fix-8051-use-old-way-as-fallback-to-save-configurati.patch b/0003-Fix-8051-use-old-way-as-fallback-to-save-configurati.patch new file mode 100644 index 0000000..ddc2066 --- /dev/null +++ b/0003-Fix-8051-use-old-way-as-fallback-to-save-configurati.patch @@ -0,0 +1,96 @@ +From bd2302cb5ff137e03b056c9643991bd7ce7f0f5e Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Mon, 16 Nov 2020 11:04:10 +0100 +Subject: [PATCH] Fix #8051 use old way as fallback to save configuration file + in non writable dir + +--- + src/config.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/src/config.c b/src/config.c +index 07ed91e5f..c93407265 100644 +--- a/src/config.c ++++ b/src/config.c +@@ -1580,6 +1580,67 @@ void rewriteConfigRemoveOrphaned(struct rewriteConfigState *state) { +     dictReleaseIterator(di); + } +  ++/* This function overwrites the old configuration file with the new content. ++ * ++ * 1) The old file length is obtained. ++ * 2) If the new content is smaller, padding is added. ++ * 3) A single write(2) call is used to replace the content of the file. ++ * 4) Later the file is truncated to the length of the new content. ++ * ++ * This way we are sure the file is left in a consistent state even if the ++ * process is stopped between any of the four operations. ++ * ++ * This fallback method is called when atomic fails because of missing ++ * write permission in the configuration directory (e.g. /etc) ++ * ++ * The function returns 0 on success, otherwise -1 is returned and errno ++ * set accordingly. */ ++int rewriteConfigOverwriteFileFallback(char *configfile, sds content) { ++    int retval = 0; ++    int fd = open(configfile,O_RDWR|O_CREAT,0644); ++    int content_size = sdslen(content), padding = 0; ++    struct stat sb; ++    sds content_padded; ++ ++    /* 1) Open the old file (or create a new one if it does not ++     *    exist), get the size. */ ++    if (fd == -1) return -1; /* errno set by open(). */ ++    if (fstat(fd,&sb) == -1) { ++        close(fd); ++        return -1; /* errno set by fstat(). */ ++    } ++ ++    /* 2) Pad the content at least match the old file size. */ ++    content_padded = sdsdup(content); ++    if (content_size < sb.st_size) { ++        /* If the old file was bigger, pad the content with ++         * a newline plus as many "#" chars as required. */ ++        padding = sb.st_size - content_size; ++        content_padded = sdsgrowzero(content_padded,sb.st_size); ++        content_padded[content_size] = '\n'; ++        memset(content_padded+content_size+1,'#',padding-1); ++    } ++ ++    /* 3) Write the new content using a single write(2). */ ++    if (write(fd,content_padded,strlen(content_padded)) == -1) { ++        retval = -1; ++        goto cleanup; ++    } ++ ++    /* 4) Truncate the file to the right length if we used padding. */ ++    if (padding) { ++        if (ftruncate(fd,content_size) == -1) { ++            /* Non critical error... */ ++        } ++    } ++    serverLog(LL_DEBUG, "Rewritten config file (%s) successfully", configfile); ++ ++cleanup: ++    sdsfree(content_padded); ++    close(fd); ++    return retval; ++} ++ + /* This function replaces the old configuration file with the new content +  * in an atomic manner. +  * +@@ -1608,6 +1669,10 @@ int rewriteConfigOverwriteFile(char *configfile, sds content) { + #endif +  +     if (fd == -1) { ++        if (errno == EACCES) { ++            serverLog(LL_DEBUG, "Could not create tmp config file (%s), try fallback", strerror(errno)); ++            return rewriteConfigOverwriteFileFallback(configfile, content); ++        } +         serverLog(LL_WARNING, "Could not create tmp config file (%s)", strerror(errno)); +         return retval; +     } +--  +2.25.4 + @@ -52,7 +52,7 @@  Name:              redis  Version:           %{upstream_ver}%{?upstream_pre:~%{upstream_pre}} -Release:           1%{?dist} +Release:           2%{?dist}  Summary:           A persistent key-value database  Group:             Applications/Databases  License:           BSD @@ -83,6 +83,9 @@ Source10:          https://github.com/antirez/%{name}-doc/archive/%{doc_commit}/  Patch0001:         0001-1st-man-pageis-for-redis-cli-redis-benchmark-redis-c.patch  # https://github.com/antirez/redis/pull/3494 - symlink  Patch0002:         0002-install-redis-check-rdb-as-a-symlink-instead-of-dupl.patch +# https://github.com/antirez/redis/pull/8058 - config rewrite +Patch0003:         0003-Fix-8051-use-old-way-as-fallback-to-save-configurati.patch +  BuildRequires:     gcc  %if 0%{?rhel} == 6 @@ -207,6 +210,7 @@ and removal, status checks, resharding, rebalancing, and other operations.  mv ../%{name}-doc-%{doc_commit} doc  %patch0001 -p1  %patch0002 -p1 +%patch0003 -p1  %if %{with jemalloc}  rm -frv deps/jemalloc @@ -453,6 +457,10 @@ fi  %changelog +* Mon Nov 16 2020 Remi Collet <remi@remirepo.net> - 6.0.9-2 +- fix broken config rewrite feature using patch from +  https://github.com/redis/redis/pull/8058 +  * Tue Oct 27 2020 Remi Collet <remi@remirepo.net> - 6.0.9-1  - Redis 6.0.9 - Released Mon Oct 26 10:37:47 IST 2020  - Upgrade urgency: MODERATE. | 
