MXS-589: Separated persistent and temporary data directories
Both the passwords and temporary files of the embedded library were stored in the same directory. Now the directories are separated and the embedded library uses the temporary directory. The datadir cleanup also now only cleans up the temporary data directory.
This commit is contained in:
@ -1812,33 +1812,6 @@ char datadir_arg[OPTIONS_DATADIR_SIZE];
|
|||||||
char language_arg[OPTIONS_LANGUAGE_SIZE];
|
char language_arg[OPTIONS_LANGUAGE_SIZE];
|
||||||
|
|
||||||
|
|
||||||
bool create_datadir(const char* base, char* datadir)
|
|
||||||
{
|
|
||||||
bool created = false;
|
|
||||||
|
|
||||||
if (snprintf(datadir, PATH_MAX, "%s/data%d", base, getpid()) < PATH_MAX)
|
|
||||||
{
|
|
||||||
int rc = mkdir(datadir, 0777);
|
|
||||||
|
|
||||||
if ((rc == 0) || (errno == EEXIST))
|
|
||||||
{
|
|
||||||
created = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char errbuf[STRERROR_BUFLEN];
|
|
||||||
fprintf(stderr, "MaxScale: error: Cannot create data directory '%s': %d %s\n",
|
|
||||||
datadir, errno, strerror_r(errno, errbuf, sizeof(errbuf)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "MaxScale: error: Too long data directory: %s/data%d.", base, getpid());
|
|
||||||
}
|
|
||||||
|
|
||||||
return created;
|
|
||||||
}
|
|
||||||
|
|
||||||
void configure_options(const char* datadir, const char* langdir)
|
void configure_options(const char* datadir, const char* langdir)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
@ -1861,7 +1834,6 @@ void configure_options(const char* datadir, const char* langdir)
|
|||||||
bool qc_init(void)
|
bool qc_init(void)
|
||||||
{
|
{
|
||||||
bool inited = false;
|
bool inited = false;
|
||||||
char datadir[PATH_MAX];
|
|
||||||
|
|
||||||
if (strlen(get_langdir()) >= PATH_MAX)
|
if (strlen(get_langdir()) >= PATH_MAX)
|
||||||
{
|
{
|
||||||
@ -1869,25 +1841,22 @@ bool qc_init(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (create_datadir(get_datadir(), datadir))
|
configure_options(get_process_datadir(), get_langdir());
|
||||||
|
|
||||||
|
int argc = N_OPTIONS;
|
||||||
|
char** argv = const_cast<char**>(server_options);
|
||||||
|
char** groups = const_cast<char**>(server_groups);
|
||||||
|
|
||||||
|
int rc = mysql_library_init(argc, argv, groups);
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
{
|
{
|
||||||
configure_options(datadir, get_langdir());
|
MXS_ERROR("mysql_library_init() failed. Error code: %d", rc);
|
||||||
|
}
|
||||||
int argc = N_OPTIONS;
|
else
|
||||||
char** argv = const_cast<char**>(server_options);
|
{
|
||||||
char** groups = const_cast<char**>(server_groups);
|
MXS_NOTICE("Query classifier initialized.");
|
||||||
|
inited = true;
|
||||||
int rc = mysql_library_init(argc, argv, groups);
|
|
||||||
|
|
||||||
if (rc != 0)
|
|
||||||
{
|
|
||||||
MXS_ERROR("mysql_library_init() failed. Error code: %d", rc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MXS_NOTICE("Query classifier initialized.");
|
|
||||||
inited = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +439,54 @@ static int signal_set(int sig, void (*handler)(int))
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create the data directory for this process
|
||||||
|
*
|
||||||
|
* This will prevent conflicts when multiple MaxScale instances are run on the
|
||||||
|
* same machine.
|
||||||
|
* @param base Base datadir path
|
||||||
|
* @param datadir The result where the process specific datadir is stored
|
||||||
|
* @return True if creation was successful and false on error
|
||||||
|
*/
|
||||||
|
static bool create_datadir(const char* base, char* datadir)
|
||||||
|
{
|
||||||
|
bool created = false;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if ((len = snprintf(datadir, PATH_MAX, "%s", base)) < PATH_MAX &&
|
||||||
|
(mkdir(datadir, 0777) == 0 || errno == EEXIST))
|
||||||
|
{
|
||||||
|
if ((len = snprintf(datadir, PATH_MAX, "%s/data%d", base, getpid())) < PATH_MAX)
|
||||||
|
{
|
||||||
|
if ((mkdir(datadir, 0777) == 0) || (errno == EEXIST))
|
||||||
|
{
|
||||||
|
created = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char errbuf[STRERROR_BUFLEN];
|
||||||
|
MXS_ERROR("Cannot create data directory '%s': %d %s\n",
|
||||||
|
datadir, errno, strerror_r(errno, errbuf, sizeof(errbuf)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (len < PATH_MAX)
|
||||||
|
{
|
||||||
|
char errbuf[STRERROR_BUFLEN];
|
||||||
|
fprintf(stderr, "Error: Cannot create data directory '%s': %d %s\n",
|
||||||
|
datadir, errno, strerror_r(errno, errbuf, sizeof(errbuf)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MXS_ERROR("Data directory pathname exceeds the maximum allowed pathname "
|
||||||
|
"length: %s/data%d.", base, getpid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleanup the temporary data directory we created for the gateway
|
* Cleanup the temporary data directory we created for the gateway
|
||||||
@ -456,23 +503,28 @@ int ntfw_cb(const char* filename,
|
|||||||
int eno = errno;
|
int eno = errno;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
char errbuf[STRERROR_BUFLEN];
|
char errbuf[STRERROR_BUFLEN];
|
||||||
MXS_ERROR("Failed to remove the data directory %s of "
|
MXS_ERROR("Failed to remove the data directory %s of MaxScale due to %d, %s.",
|
||||||
"MaxScale due to %d, %s.",
|
datadir, eno, strerror_r(eno, errbuf, sizeof(errbuf)));
|
||||||
datadir,
|
|
||||||
eno,
|
|
||||||
strerror_r(eno, errbuf, sizeof(errbuf)));
|
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void datadir_cleanup()
|
/**
|
||||||
|
* @brief Clean up the data directory
|
||||||
|
*
|
||||||
|
* This removes the process specific datadir which is currently only used by
|
||||||
|
* the embedded library. In the future this directory could contain other
|
||||||
|
* temporary files and relocating this to to, for example, /tmp/ could make sense.
|
||||||
|
*/
|
||||||
|
void cleanup_process_datadir()
|
||||||
{
|
{
|
||||||
int depth = 1;
|
int depth = 1;
|
||||||
int flags = FTW_CHDIR|FTW_DEPTH|FTW_MOUNT;
|
int flags = FTW_CHDIR|FTW_DEPTH|FTW_MOUNT;
|
||||||
|
const char *proc_datadir = get_process_datadir();
|
||||||
|
|
||||||
if (datadir[0] != 0 && access(datadir, F_OK) == 0)
|
if (strcmp(proc_datadir, get_datadir()) != 0 && access(proc_datadir, F_OK) == 0)
|
||||||
{
|
{
|
||||||
nftw(datadir, ntfw_cb, depth, flags);
|
nftw(proc_datadir, ntfw_cb, depth, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1235,7 +1287,7 @@ int main(int argc, char **argv)
|
|||||||
ssize_t log_flush_timeout_ms = 0;
|
ssize_t log_flush_timeout_ms = 0;
|
||||||
sigset_t sigpipe_mask;
|
sigset_t sigpipe_mask;
|
||||||
sigset_t saved_mask;
|
sigset_t saved_mask;
|
||||||
void (*exitfunp[4])(void) = { mxs_log_finish, datadir_cleanup, write_footer, NULL };
|
void (*exitfunp[4])(void) = { mxs_log_finish, cleanup_process_datadir, write_footer, NULL };
|
||||||
|
|
||||||
*syslog_enabled = 1;
|
*syslog_enabled = 1;
|
||||||
*maxlog_enabled = 1;
|
*maxlog_enabled = 1;
|
||||||
@ -1718,23 +1770,20 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set a data directory for the mysqld library, we use
|
* Set the data directory for the mysqld library. We use
|
||||||
* a unique directory name to avoid clauses if multiple
|
* a unique directory name to avoid conflicts if multiple
|
||||||
* instances of the gateway are being run on the same
|
* instances of MaxScale are being run on the same machine.
|
||||||
* machine.
|
|
||||||
*/
|
*/
|
||||||
|
if (create_datadir(get_datadir(), datadir))
|
||||||
snprintf(datadir, PATH_MAX, "%s", get_datadir());
|
{
|
||||||
datadir[PATH_MAX] = '\0';
|
set_process_datadir(datadir);
|
||||||
if (mkdir(datadir, 0777) != 0){
|
}
|
||||||
|
else
|
||||||
if (errno != EEXIST){
|
{
|
||||||
char errbuf[STRERROR_BUFLEN];
|
char errbuf[STRERROR_BUFLEN];
|
||||||
fprintf(stderr,
|
MXS_ERROR("Cannot create data directory '%s': %d %s\n",
|
||||||
"Error: Cannot create data directory '%s': %d %s\n",
|
datadir, errno, strerror_r(errno, errbuf, sizeof(errbuf)));
|
||||||
datadir, errno, strerror_r(errno, errbuf, sizeof(errbuf)));
|
goto return_main;
|
||||||
goto return_main;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!daemon_mode)
|
if (!daemon_mode)
|
||||||
@ -1946,7 +1995,7 @@ int main(int argc, char **argv)
|
|||||||
qc_end();
|
qc_end();
|
||||||
|
|
||||||
utils_end();
|
utils_end();
|
||||||
datadir_cleanup();
|
cleanup_process_datadir();
|
||||||
MXS_NOTICE("MaxScale shutdown completed.");
|
MXS_NOTICE("MaxScale shutdown completed.");
|
||||||
|
|
||||||
unload_all_modules();
|
unload_all_modules();
|
||||||
|
@ -85,6 +85,17 @@ void set_datadir(char* param)
|
|||||||
maxscaledatadir = param;
|
maxscaledatadir = param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data directory
|
||||||
|
* @param str Path to directory
|
||||||
|
*/
|
||||||
|
void set_process_datadir(char* param)
|
||||||
|
{
|
||||||
|
free(processdatadir);
|
||||||
|
clean_up_pathname(param);
|
||||||
|
processdatadir = param;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the library directory. Modules will be loaded from here.
|
* Set the library directory. Modules will be loaded from here.
|
||||||
* @param str Path to directory
|
* @param str Path to directory
|
||||||
@ -127,14 +138,23 @@ char* get_cachedir()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the service cache directory
|
* Get the MaxScale data directory
|
||||||
* @return The path to the cache directory
|
* @return The path to the data directory
|
||||||
*/
|
*/
|
||||||
char* get_datadir()
|
char* get_datadir()
|
||||||
{
|
{
|
||||||
return maxscaledatadir ? maxscaledatadir : (char*) default_datadir;
|
return maxscaledatadir ? maxscaledatadir : (char*) default_datadir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the process specific data directory
|
||||||
|
* @return The path to the process specific directory
|
||||||
|
*/
|
||||||
|
char* get_process_datadir()
|
||||||
|
{
|
||||||
|
return processdatadir ? processdatadir : (char*) default_datadir;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the configuration file directory
|
* Get the configuration file directory
|
||||||
* @return The path to the configuration file directory
|
* @return The path to the configuration file directory
|
||||||
|
@ -35,7 +35,7 @@ static const char* default_configdir = "/etc";
|
|||||||
* uses /run for PID files.*/
|
* uses /run for PID files.*/
|
||||||
static const char* default_piddir = "@MAXSCALE_VARDIR@/run/maxscale";
|
static const char* default_piddir = "@MAXSCALE_VARDIR@/run/maxscale";
|
||||||
static const char* default_logdir = "@MAXSCALE_VARDIR@/log/maxscale";
|
static const char* default_logdir = "@MAXSCALE_VARDIR@/log/maxscale";
|
||||||
static const char* default_datadir = "@MAXSCALE_VARDIR@/lib/maxscale/data";
|
static const char* default_datadir = "@MAXSCALE_VARDIR@/lib/maxscale";
|
||||||
static const char* default_libdir = "@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@";
|
static const char* default_libdir = "@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@";
|
||||||
static const char* default_cachedir = "@MAXSCALE_VARDIR@/cache/maxscale";
|
static const char* default_cachedir = "@MAXSCALE_VARDIR@/cache/maxscale";
|
||||||
static const char* default_langdir = "@MAXSCALE_VARDIR@/lib/maxscale";
|
static const char* default_langdir = "@MAXSCALE_VARDIR@/lib/maxscale";
|
||||||
@ -45,13 +45,15 @@ static char* configdir = NULL;
|
|||||||
static char* logdir = NULL;
|
static char* logdir = NULL;
|
||||||
static char* libdir = NULL;
|
static char* libdir = NULL;
|
||||||
static char* cachedir = NULL;
|
static char* cachedir = NULL;
|
||||||
static char* maxscaledatadir = NULL;
|
static char* maxscaledatadir = NULL; /*< The data directory */
|
||||||
|
static char* processdatadir = NULL; /*< Process specific data directory */
|
||||||
static char* langdir = NULL;
|
static char* langdir = NULL;
|
||||||
static char* piddir = NULL;
|
static char* piddir = NULL;
|
||||||
static char* execdir = NULL;
|
static char* execdir = NULL;
|
||||||
|
|
||||||
void set_libdir(char* param);
|
void set_libdir(char* param);
|
||||||
void set_datadir(char* param);
|
void set_datadir(char* param);
|
||||||
|
void set_process_datadir(char* param);
|
||||||
void set_cachedir(char* param);
|
void set_cachedir(char* param);
|
||||||
void set_configdir(char* param);
|
void set_configdir(char* param);
|
||||||
void set_logdir(char* param);
|
void set_logdir(char* param);
|
||||||
@ -60,6 +62,7 @@ void set_piddir(char* param);
|
|||||||
void set_execdir(char* param);
|
void set_execdir(char* param);
|
||||||
char* get_libdir();
|
char* get_libdir();
|
||||||
char* get_datadir();
|
char* get_datadir();
|
||||||
|
char* get_process_datadir();
|
||||||
char* get_cachedir();
|
char* get_cachedir();
|
||||||
char* get_configdir();
|
char* get_configdir();
|
||||||
char* get_piddir();
|
char* get_piddir();
|
||||||
|
Reference in New Issue
Block a user