diff options
author | zhaozhao.zz <276441700@qq.com> | 2022-03-22 16:34:01 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-22 16:34:01 +0800 |
commit | 79db037a4f7bf18962f4255de84d1767d63da1f5 (patch) | |
tree | 882832e0f1b673485dda627596646fcadcf38262 /src/config.c | |
parent | 93dda65354e502e8b8db07f85b668710dd0aac68 (diff) | |
download | redis-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.c | 36 |
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; } |