Allow paths to be created if they don't exist

A module can now declare a path parameter for a directory that does not
yet exist. If the directory does not exist, MaxScale will create the
directory with the requested permissions.
This commit is contained in:
Markus Mäkelä
2017-04-20 12:53:17 +03:00
parent e4941044aa
commit 5704ae5ffd
4 changed files with 43 additions and 7 deletions

View File

@ -102,7 +102,8 @@ enum mxs_module_param_options
MXS_MODULE_OPT_PATH_R_OK = (1 << 2), /**< PATH: Read permission to path required */ MXS_MODULE_OPT_PATH_R_OK = (1 << 2), /**< PATH: Read permission to path required */
MXS_MODULE_OPT_PATH_W_OK = (1 << 3), /**< PATH: Write permission to path required */ MXS_MODULE_OPT_PATH_W_OK = (1 << 3), /**< PATH: Write permission to path required */
MXS_MODULE_OPT_PATH_F_OK = (1 << 4), /**< PATH: Path must exist */ MXS_MODULE_OPT_PATH_F_OK = (1 << 4), /**< PATH: Path must exist */
MXS_MODULE_OPT_ENUM_UNIQUE = (1 << 5) /**< ENUM: Only one value can be defined */ MXS_MODULE_OPT_PATH_CREAT = (1 << 5), /**< PATH: Create path if it doesn't exist */
MXS_MODULE_OPT_ENUM_UNIQUE = (1 << 6) /**< ENUM: Only one value can be defined */
}; };
/** String to enum value mappings */ /** String to enum value mappings */

View File

@ -3276,18 +3276,21 @@ static bool check_path_parameter(const MXS_MODULE_PARAM *params, const char *val
} }
int mode = F_OK; int mode = F_OK;
int mask = X_OK;
if (params->options & MXS_MODULE_OPT_PATH_W_OK) if (params->options & MXS_MODULE_OPT_PATH_W_OK)
{ {
mask |= S_IWUSR;
mode |= W_OK; mode |= W_OK;
} }
if (params->options & MXS_MODULE_OPT_PATH_R_OK) if (params->options & MXS_MODULE_OPT_PATH_R_OK)
{ {
mask |= S_IRUSR;
mode |= R_OK; mode |= R_OK;
} }
if (params->options & MXS_MODULE_OPT_PATH_X_OK) if (params->options & MXS_MODULE_OPT_PATH_X_OK)
{ {
mode |= X_OK; mask |= S_IXUSR;
} }
if (access(buf, mode) == 0) if (access(buf, mode) == 0)
@ -3296,8 +3299,30 @@ static bool check_path_parameter(const MXS_MODULE_PARAM *params, const char *val
} }
else else
{ {
MXS_ERROR("Bad path parameter '%s' (absolute path '%s'): %d, %s", value, /** Save errno as we do a second call to `accept` */
buf, errno, mxs_strerror(errno)); int er = errno;
if (access(buf, F_OK) == 0 || (params->options & MXS_MODULE_OPT_PATH_CREAT) == 0)
{
/**
* Path already exists and it doesn't have the requested access
* right or the module doesn't want the directory to be created
* if it doesn't exist.
*/
MXS_ERROR("Bad path parameter '%s' (absolute path '%s'): %d, %s",
value, buf, er, mxs_strerror(er));
}
else if (mxs_mkdir_all(buf, mask))
{
/** Successfully created path */
valid = true;
}
else
{
/** Failed to create the directory, errno is set in `mxs_mkdir_all` */
MXS_ERROR("Can't create path '%s' (absolute path '%s'): %d, %s",
value, buf, errno, mxs_strerror(errno));
}
} }
} }
else else

View File

@ -181,13 +181,16 @@ MXS_MODULE* MXS_CREATE_MODULE()
"binlogdir", "binlogdir",
MXS_MODULE_PARAM_PATH, MXS_MODULE_PARAM_PATH,
NULL, NULL,
MXS_MODULE_OPT_PATH_R_OK MXS_MODULE_OPT_PATH_R_OK |
MXS_MODULE_OPT_PATH_CREAT
}, },
{ {
"avrodir", "avrodir",
MXS_MODULE_PARAM_PATH, MXS_MODULE_PARAM_PATH,
MXS_DEFAULT_DATADIR, MXS_DEFAULT_DATADIR,
MXS_MODULE_OPT_PATH_W_OK MXS_MODULE_OPT_PATH_R_OK |
MXS_MODULE_OPT_PATH_W_OK |
MXS_MODULE_OPT_PATH_CREAT
}, },
{"source", MXS_MODULE_PARAM_SERVICE}, {"source", MXS_MODULE_PARAM_SERVICE},
{"filestem", MXS_MODULE_PARAM_STRING, BINLOG_NAME_ROOT}, {"filestem", MXS_MODULE_PARAM_STRING, BINLOG_NAME_ROOT},

View File

@ -201,7 +201,14 @@ MXS_MODULE* MXS_CREATE_MODULE()
{"burstsize", MXS_MODULE_PARAM_SIZE, DEF_BURST_SIZE}, {"burstsize", MXS_MODULE_PARAM_SIZE, DEF_BURST_SIZE},
{"heartbeat", MXS_MODULE_PARAM_COUNT, BLR_HEARTBEAT_DEFAULT_INTERVAL}, {"heartbeat", MXS_MODULE_PARAM_COUNT, BLR_HEARTBEAT_DEFAULT_INTERVAL},
{"send_slave_heartbeat", MXS_MODULE_PARAM_BOOL, "false"}, {"send_slave_heartbeat", MXS_MODULE_PARAM_BOOL, "false"},
{"binlogdir", MXS_MODULE_PARAM_PATH, NULL, MXS_MODULE_OPT_PATH_W_OK}, {
"binlogdir",
MXS_MODULE_PARAM_PATH,
NULL,
MXS_MODULE_OPT_PATH_R_OK |
MXS_MODULE_OPT_PATH_W_OK |
MXS_MODULE_OPT_PATH_CREAT
},
{"ssl_cert_verification_depth", MXS_MODULE_PARAM_COUNT, "9"}, {"ssl_cert_verification_depth", MXS_MODULE_PARAM_COUNT, "9"},
{MXS_END_MODULE_PARAMS} {MXS_END_MODULE_PARAMS}
} }