summaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
authorzhaozhao.zz <276441700@qq.com>2022-03-22 16:34:01 +0800
committerGitHub <noreply@github.com>2022-03-22 16:34:01 +0800
commit79db037a4f7bf18962f4255de84d1767d63da1f5 (patch)
tree882832e0f1b673485dda627596646fcadcf38262 /src/config.c
parent93dda65354e502e8b8db07f85b668710dd0aac68 (diff)
downloadredis-79db037a4f7bf18962f4255de84d1767d63da1f5.tar.gz
config rewrite enhancement, in case of line longer than 1024 (#8009)
When rewrite the config file, we need read the old config file first, but the CONFIG_MAX_LEN is 1024, so if some lines are longer than it, it will generate a wrong config file, and redis cannot reboot from the new config file. Rename CONFIG_MAX_LINE to CONFIG_READ_LEN
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/config.c b/src/config.c
index c45cf3ff0..e36315743 100644
--- a/src/config.c
+++ b/src/config.c
@@ -592,9 +592,10 @@ loaderr:
* Both filename and options can be NULL, in such a case are considered
* empty. This way loadServerConfig can be used to just load a file or
* just load a string. */
+#define CONFIG_READ_LEN 1024
void loadServerConfig(char *filename, char config_from_stdin, char *options) {
sds config = sdsempty();
- char buf[CONFIG_MAX_LINE+1];
+ char buf[CONFIG_READ_LEN+1];
FILE *fp;
glob_t globbuf;
@@ -626,7 +627,7 @@ void loadServerConfig(char *filename, char config_from_stdin, char *options) {
globbuf.gl_pathv[i], strerror(errno));
exit(1);
}
- while(fgets(buf,CONFIG_MAX_LINE+1,fp) != NULL)
+ while(fgets(buf,CONFIG_READ_LEN+1,fp) != NULL)
config = sdscat(config,buf);
fclose(fp);
}
@@ -642,7 +643,7 @@ void loadServerConfig(char *filename, char config_from_stdin, char *options) {
filename, strerror(errno));
exit(1);
}
- while(fgets(buf,CONFIG_MAX_LINE+1,fp) != NULL)
+ while(fgets(buf,CONFIG_READ_LEN+1,fp) != NULL)
config = sdscat(config,buf);
fclose(fp);
}
@@ -652,7 +653,7 @@ void loadServerConfig(char *filename, char config_from_stdin, char *options) {
if (config_from_stdin) {
serverLog(LL_WARNING,"Reading config from stdin");
fp = stdin;
- while(fgets(buf,CONFIG_MAX_LINE+1,fp) != NULL)
+ while(fgets(buf,CONFIG_READ_LEN+1,fp) != NULL)
config = sdscat(config,buf);
}
@@ -1010,17 +1011,32 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
FILE *fp = fopen(path,"r");
if (fp == NULL && errno != ENOENT) return NULL;
- char buf[CONFIG_MAX_LINE+1];
+ struct redis_stat sb;
+ if (fp && redis_fstat(fileno(fp),&sb) == -1) return NULL;
+
int linenum = -1;
struct rewriteConfigState *state = rewriteConfigCreateState();
- if (fp == NULL) return state;
+ if (fp == NULL || sb.st_size == 0) return state;
+
+ /* Load the file content */
+ sds config = sdsnewlen(SDS_NOINIT,sb.st_size);
+ if (fread(config,1,sb.st_size,fp) == 0) {
+ sdsfree(config);
+ rewriteConfigReleaseState(state);
+ fclose(fp);
+ return NULL;
+ }
+
+ int i, totlines;
+ sds *lines = sdssplitlen(config,sdslen(config),"\n",1,&totlines);
- /* Read the old file line by line, populate the state. */
- while(fgets(buf,CONFIG_MAX_LINE+1,fp) != NULL) {
+ /* Read the old content line by line, populate the state. */
+ for (i = 0; i < totlines; i++) {
int argc;
sds *argv;
- sds line = sdstrim(sdsnew(buf),"\r\n\t ");
+ sds line = sdstrim(lines[i],"\r\n\t ");
+ lines[i] = NULL;
linenum++; /* Zero based, so we init at -1 */
@@ -1076,6 +1092,8 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
sdsfreesplitres(argv,argc);
}
fclose(fp);
+ sdsfreesplitres(lines,totlines);
+ sdsfree(config);
return state;
}