summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2021-11-22 13:22:05 +0100
committerSergei Golubchik <serg@mariadb.org>2021-12-15 19:13:57 +0100
commita296c52627fc46b400d4b9e79dad1e6d8690b8cc (patch)
tree862103f7ec836207358e98ed73d8bf68164e660a /sql
parenta4fc41b6b48a1e699343c20685a0e221002eba43 (diff)
downloadmariadb-git-a296c52627fc46b400d4b9e79dad1e6d8690b8cc.tar.gz
MDEV-26713 UTF8 support on Windows, mysql_upgrade_service preparation
- Tolerate situation, when datadir for service seems invalid/non-existing prior to upgrade. It could be that my.ini contains legacy ANSI characters for the data directory. Those can't be read correctly by mysql_upgrade_service, which uses a different ANSI codepage(UTF8) . - schedule upgrade_config_file at later stage, because once we convert it to UTF-8 (followup patch), this will render config file uselss with the older version of mariadbd.exe - Refactor upgrade_conf_file.cc, prepare for UTF-8 conversion.
Diffstat (limited to 'sql')
-rw-r--r--sql/mysql_upgrade_service.cc31
-rw-r--r--sql/upgrade_conf_file.cc124
-rw-r--r--sql/winservice.c25
3 files changed, 123 insertions, 57 deletions
diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc
index 19dbf93c7ce..ce16e10eeff 100644
--- a/sql/mysql_upgrade_service.cc
+++ b/sql/mysql_upgrade_service.cc
@@ -374,13 +374,17 @@ static void change_service_config()
Write datadir to my.ini, after converting backslashes to
unix style slashes.
*/
- strcpy_s(buf, MAX_PATH, service_properties.datadir);
- for(i= 0; buf[i]; i++)
+ if (service_properties.datadir[0])
{
- if (buf[i] == '\\')
- buf[i]= '/';
+ strcpy_s(buf, MAX_PATH, service_properties.datadir);
+ for (i= 0; buf[i]; i++)
+ {
+ if (buf[i] == '\\')
+ buf[i]= '/';
+ }
+ WritePrivateProfileString("mysqld", "datadir", buf,
+ service_properties.inifile);
}
- WritePrivateProfileString("mysqld", "datadir",buf, service_properties.inifile);
/*
Remove basedir from defaults file, otherwise the service wont come up in
@@ -465,13 +469,8 @@ int main(int argc, char **argv)
}
}
- old_mysqld_exe_exists = (GetFileAttributes(service_properties.mysqld_exe) != INVALID_FILE_ATTRIBUTES);
- log("Phase %d/%d: Fixing server config file%s", ++phase, max_phases, my_ini_exists ? "" : "(skipped)");
-
- snprintf(my_ini_bck, sizeof(my_ini_bck), "%s.BCK", service_properties.inifile);
- CopyFile(service_properties.inifile, my_ini_bck, FALSE);
- upgrade_config_file(service_properties.inifile);
-
+ old_mysqld_exe_exists= (GetFileAttributes(service_properties.mysqld_exe) !=
+ INVALID_FILE_ATTRIBUTES);
bool do_start_stop_server = old_mysqld_exe_exists && initial_service_state != SERVICE_RUNNING;
log("Phase %d/%d: Start and stop server in the old version, to avoid crash recovery %s", ++phase, max_phases,
@@ -526,6 +525,14 @@ int main(int argc, char **argv)
start_duration_ms += 500;
}
}
+
+ log("Phase %d/%d: Fixing server config file%s", ++phase, max_phases,
+ my_ini_exists ? "" : "(skipped)");
+ snprintf(my_ini_bck, sizeof(my_ini_bck), "%s.BCK",
+ service_properties.inifile);
+ CopyFile(service_properties.inifile, my_ini_bck, FALSE);
+ upgrade_config_file(service_properties.inifile);
+
/*
Start mysqld.exe as non-service skipping privileges (so we do not
care about the password). But disable networking and enable pipe
diff --git a/sql/upgrade_conf_file.cc b/sql/upgrade_conf_file.cc
index 543df7b9bdf..66d78595164 100644
--- a/sql/upgrade_conf_file.cc
+++ b/sql/upgrade_conf_file.cc
@@ -158,51 +158,103 @@ static int cmp_strings(const void* a, const void *b)
return strcmp((const char *)a, *(const char **)b);
}
-/**
- Convert file from a previous version, by removing
-*/
-int upgrade_config_file(const char *myini_path)
+
+#define MY_INI_SECTION_SIZE 32 * 1024 + 3
+
+
+int fix_section(const char *myini_path, const char *section_name,
+ bool is_server)
{
-#define MY_INI_SECTION_SIZE 32*1024 +3
+ if (!is_server)
+ return 0;
+
static char section_data[MY_INI_SECTION_SIZE];
- for (const char *section_name : { "mysqld","server","mariadb" })
+ DWORD size= GetPrivateProfileSection(section_name, section_data,
+ MY_INI_SECTION_SIZE, myini_path);
+ if (size == MY_INI_SECTION_SIZE - 2)
{
- DWORD size = GetPrivateProfileSection(section_name, section_data, MY_INI_SECTION_SIZE, myini_path);
- if (size == MY_INI_SECTION_SIZE - 2)
- {
- return -1;
- }
+ return -1;
+ }
- for (char *keyval = section_data; *keyval; keyval += strlen(keyval) + 1)
+ for (char *keyval= section_data; *keyval; keyval += strlen(keyval)+1)
+ {
+ char varname[256];
+ char *value;
+ char *key_end= strchr(keyval, '=');
+ if (!key_end)
+ key_end= keyval + strlen(keyval);
+
+ if (key_end - keyval > sizeof(varname))
+ continue;
+
+ value= key_end + 1;
+
+ // Check if variable should be removed from config.
+ // First, copy and normalize (convert dash to underscore) to variable
+ // names
+ for (char *p= keyval, *q= varname;; p++, q++)
{
- char varname[256];
- char *key_end = strchr(keyval, '=');
- if (!key_end)
- key_end = keyval+ strlen(keyval);
-
- if (key_end - keyval > sizeof(varname))
- continue;
- // copy and normalize (convert dash to underscore) to variable names
- for (char *p = keyval, *q = varname;; p++,q++)
+ if (p == key_end)
{
- if (p == key_end)
- {
- *q = 0;
- break;
- }
- *q = (*p == '-') ? '_' : *p;
+ *q= 0;
+ break;
}
- const char *v = (const char *)bsearch(varname, removed_variables, sizeof(removed_variables) / sizeof(removed_variables[0]),
- sizeof(char *), cmp_strings);
+ *q= (*p == '-') ? '_' : *p;
+ }
+ const char *v= (const char *) bsearch(varname, removed_variables, sizeof(removed_variables) / sizeof(removed_variables[0]),
+ sizeof(char *), cmp_strings);
- if (v)
- {
- fprintf(stdout, "Removing variable '%s' from config file\n", varname);
- // delete variable
- *key_end = 0;
- WritePrivateProfileString(section_name, keyval, 0, myini_path);
- }
+ if (v)
+ {
+ fprintf(stdout, "Removing variable '%s' from config file\n", varname);
+ // delete variable
+ *key_end= 0;
+ WritePrivateProfileString(section_name, keyval, 0, myini_path);
}
}
return 0;
}
+
+static bool is_mariadb_section(const char *name, bool *is_server)
+{
+ if (strncmp(name, "mysql", 5)
+ && strncmp(name, "mariadb", 7)
+ && strcmp(name, "client")
+ && strcmp(name, "client-server")
+ && strcmp(name, "server"))
+ {
+ return false;
+ }
+
+ for (const char *section_name : {"mysqld", "server", "mariadb"})
+ if (*is_server= !strcmp(section_name, name))
+ break;
+
+ return *is_server;
+}
+
+
+/**
+ Convert file from a previous version, by removing obsolete variables
+ Also, fix values to be UTF8, if MariaDB is running in utf8 mode
+*/
+int upgrade_config_file(const char *myini_path)
+{
+ static char all_sections[MY_INI_SECTION_SIZE];
+ int sz= GetPrivateProfileSectionNamesA(all_sections, MY_INI_SECTION_SIZE,
+ myini_path);
+ if (!sz)
+ return 0;
+ if (sz > MY_INI_SECTION_SIZE - 2)
+ {
+ fprintf(stderr, "Too many sections in config file\n");
+ return -1;
+ }
+ for (char *section= all_sections; *section; section+= strlen(section) + 1)
+ {
+ bool is_server_section;
+ if (is_mariadb_section(section, &is_server_section))
+ fix_section(myini_path, section, is_server_section);
+ }
+ return 0;
+}
diff --git a/sql/winservice.c b/sql/winservice.c
index a11087e5cd5..d4e3bb0944d 100644
--- a/sql/winservice.c
+++ b/sql/winservice.c
@@ -134,6 +134,20 @@ static void get_datadir_from_ini(const char *ini, char *service_name, char *data
}
+static int fix_and_check_datadir(mysqld_service_properties *props)
+{
+ normalize_path(props->datadir, MAX_PATH);
+ /* Check if datadir really exists */
+ if (GetFileAttributes(props->datadir) != INVALID_FILE_ATTRIBUTES)
+ return 0;
+ /*
+ It is possible, that datadir contains some unconvertable character.
+ We just pretend not to know what's the data directory
+ */
+ props->datadir[0]= 0;
+ return 0;
+}
+
/*
Retrieve some properties from windows mysqld service binary path.
We're interested in ini file location and datadir, and also in version of
@@ -284,16 +298,9 @@ int get_mysql_service_properties(const wchar_t *bin_path,
}
}
- if (props->datadir[0])
- {
- normalize_path(props->datadir, MAX_PATH);
- /* Check if datadir really exists */
- if (GetFileAttributes(props->datadir) == INVALID_FILE_ATTRIBUTES)
- goto end;
- }
- else
+ if (props->datadir[0] == 0 || fix_and_check_datadir(props))
{
- /* There is no datadir in ini file, bail out.*/
+ /* There is no datadir in ini file, or non-existing dir, bail out.*/
goto end;
}