Move config unixsocketperm to generic configs (#9607)

Since the size of mode_t is platform dependant we handle the
`unixsocketperm` configuration as a generic int type.
mode_t is either an unsigned int or unsigned short (macOS) and
the range-limits allows for a simple cast to a mode_t.
This commit is contained in:
Bjorn Svensson 2021-10-19 08:58:52 +02:00 committed by GitHub
parent 1c2b5f5318
commit c9fabc2ef0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 24 deletions

View File

@ -201,6 +201,7 @@ typedef enum numericType {
#define INTEGER_CONFIG 0 /* No flags means a simple integer configuration */
#define MEMORY_CONFIG (1<<0) /* Indicates if this value can be loaded as a memory value */
#define PERCENT_CONFIG (1<<1) /* Indicates if this value can be loaded as a percent (and stored as a negative int) */
#define OCTAL_CONFIG (1<<2) /* This value uses octal representation */
typedef struct numericConfigData {
union {
@ -525,12 +526,6 @@ void loadServerConfigFromString(char *config) {
for (j = 0; j < addresses; j++)
server.bindaddr[j] = zstrdup(argv[j+1]);
server.bindaddr_count = addresses;
} else if (!strcasecmp(argv[0],"unixsocketperm") && argc == 2) {
errno = 0;
server.unixsocketperm = (mode_t)strtol(argv[1], NULL, 8);
if (errno || server.unixsocketperm > 0777) {
err = "Invalid socket file permissions"; goto loaderr;
}
} else if (!strcasecmp(argv[0],"save")) {
/* We don't reset save params before loading, because if they're not part
* of the file the defaults should be used.
@ -1034,13 +1029,6 @@ void configGetCommand(client *c) {
sdsfree(buf);
matches++;
}
if (stringmatch(pattern,"unixsocketperm",1)) {
char buf[32];
snprintf(buf,sizeof(buf),"%lo",(unsigned long) server.unixsocketperm);
addReplyBulkCString(c,"unixsocketperm");
addReplyBulkCString(c,buf);
matches++;
}
for (int i = 0; i < 2; i++) {
char *optname = i == 0 ? "replicaof" : "slaveof";
if (!stringmatch(pattern, optname, 1)) continue;
@ -1412,9 +1400,9 @@ void rewriteConfigNumericalOption(struct rewriteConfigState *state, const char *
}
/* Rewrite an octal option. */
void rewriteConfigOctalOption(struct rewriteConfigState *state, char *option, int value, int defvalue) {
void rewriteConfigOctalOption(struct rewriteConfigState *state, const char *option, long long value, long long defvalue) {
int force = value != defvalue;
sds line = sdscatprintf(sdsempty(),"%s %o",option,value);
sds line = sdscatprintf(sdsempty(),"%s %llo",option,value);
rewriteConfigRewriteLine(state,option,line,force);
}
@ -1799,7 +1787,6 @@ int rewriteConfig(char *path, int force_write) {
}
rewriteConfigBindOption(state);
rewriteConfigOctalOption(state,"unixsocketperm",server.unixsocketperm,CONFIG_DEFAULT_UNIX_SOCKET_PERM);
rewriteConfigSaveOption(state);
rewriteConfigUserOption(state);
rewriteConfigDirOption(state);
@ -2104,10 +2091,17 @@ static int numericBoundaryCheck(typeData data, long long ll, const char **err) {
unsigned long long upper_bound = data.numeric.upper_bound;
unsigned long long lower_bound = data.numeric.lower_bound;
if (ull > upper_bound || ull < lower_bound) {
snprintf(loadbuf, LOADBUF_SIZE,
"argument must be between %llu and %llu inclusive",
lower_bound,
upper_bound);
if (data.numeric.flags & OCTAL_CONFIG) {
snprintf(loadbuf, LOADBUF_SIZE,
"argument must be between %llo and %llo inclusive",
lower_bound,
upper_bound);
} else {
snprintf(loadbuf, LOADBUF_SIZE,
"argument must be between %llu and %llu inclusive",
lower_bound,
upper_bound);
}
*err = loadbuf;
return 0;
}
@ -2154,6 +2148,15 @@ static int numericParseString(typeData data, sds value, const char **err, long l
return 1;
}
/* Attempt to parse as an octal number */
if (data.numeric.flags & OCTAL_CONFIG) {
char *endptr;
errno = 0;
*res = strtoll(value, &endptr, 8);
if (errno == 0 && *endptr == '\0')
return 1; /* No overflow or invalid characters */
}
/* Attempt a simple number (no special flags set) */
if (!data.numeric.flags && string2ll(value, sdslen(value), res))
return 1;
@ -2164,6 +2167,8 @@ static int numericParseString(typeData data, sds value, const char **err, long l
*err = "argument must be a memory or percent value" ;
else if (data.numeric.flags & MEMORY_CONFIG)
*err = "argument must be a memory value";
else if (data.numeric.flags & OCTAL_CONFIG)
*err = "argument couldn't be parsed as an octal number";
else
*err = "argument couldn't be parsed into an integer";
return 0;
@ -2204,6 +2209,8 @@ static void numericConfigGet(client *c, typeData data) {
}
else if (data.numeric.flags & MEMORY_CONFIG) {
ull2string(buf, sizeof(buf), value);
} else if (data.numeric.flags & OCTAL_CONFIG) {
snprintf(buf, sizeof(buf), "%llo", value);
} else {
ll2string(buf, sizeof(buf), value);
}
@ -2219,6 +2226,8 @@ static void numericConfigRewrite(typeData data, const char *name, struct rewrite
rewriteConfigPercentOption(state, name, -value, data.numeric.default_value);
} else if (data.numeric.flags & MEMORY_CONFIG) {
rewriteConfigBytesOption(state, name, value, data.numeric.default_value);
} else if (data.numeric.flags & OCTAL_CONFIG) {
rewriteConfigOctalOption(state, name, value, data.numeric.default_value);
} else {
rewriteConfigNumericalOption(state, name, value, data.numeric.default_value);
}
@ -2661,6 +2670,7 @@ standardConfig configs[] = {
/* Unsigned int configs */
createUIntConfig("maxclients", NULL, MODIFIABLE_CONFIG, 1, UINT_MAX, server.maxclients, 10000, INTEGER_CONFIG, NULL, updateMaxclients),
createUIntConfig("unixsocketperm", NULL, IMMUTABLE_CONFIG, 0, 0777, server.unixsocketperm, 0, OCTAL_CONFIG, NULL, NULL),
/* Unsigned Long configs */
createULongConfig("active-defrag-max-scan-fields", NULL, MODIFIABLE_CONFIG, 1, LONG_MAX, server.active_defrag_max_scan_fields, 1000, INTEGER_CONFIG, NULL, NULL), /* Default: keys with more than 1000 fields will be processed separately */

View File

@ -3167,7 +3167,6 @@ void initServerConfig(void) {
server.bindaddr_count = CONFIG_DEFAULT_BINDADDR_COUNT;
for (j = 0; j < CONFIG_DEFAULT_BINDADDR_COUNT; j++)
server.bindaddr[j] = zstrdup(default_bindaddr[j]);
server.unixsocketperm = CONFIG_DEFAULT_UNIX_SOCKET_PERM;
server.ipfd.count = 0;
server.tlsfd.count = 0;
server.sofd = -1;
@ -3720,7 +3719,7 @@ void initServer(void) {
if (server.unixsocket != NULL) {
unlink(server.unixsocket); /* don't care if this fails */
server.sofd = anetUnixServer(server.neterr,server.unixsocket,
server.unixsocketperm, server.tcp_backlog);
(mode_t)server.unixsocketperm, server.tcp_backlog);
if (server.sofd == ANET_ERR) {
serverLog(LL_WARNING, "Opening Unix socket: %s", server.neterr);
exit(1);

View File

@ -112,7 +112,6 @@ typedef long long ustime_t; /* microsecond time type. */
#define CONFIG_REPL_BACKLOG_MIN_SIZE (1024*16) /* 16k */
#define CONFIG_BGSAVE_RETRY_DELAY 5 /* Wait a few secs before trying again. */
#define CONFIG_DEFAULT_PID_FILE "/var/run/redis.pid"
#define CONFIG_DEFAULT_UNIX_SOCKET_PERM 0
#define CONFIG_DEFAULT_BINDADDR_COUNT 2
#define CONFIG_DEFAULT_BINDADDR { "*", "-::*" }
#define NET_HOST_STR_LEN 256 /* Longest valid hostname */
@ -1295,7 +1294,7 @@ struct redisServer {
int bindaddr_count; /* Number of addresses in server.bindaddr[] */
char *bind_source_addr; /* Source address to bind on for outgoing connections */
char *unixsocket; /* UNIX socket path */
mode_t unixsocketperm; /* UNIX socket permission */
unsigned int unixsocketperm; /* UNIX socket permission (see mode_t) */
socketFds ipfd; /* TCP socket file descriptors */
socketFds tlsfd; /* TLS socket file descriptors */
int sofd; /* Unix socket file descriptor */