[Pkg-mysql-commits] [mariadb-5.5] 01/03: Imported Upstream version 5.5.53

Otto Kekäläinen otto at moszumanska.debian.org
Mon Oct 31 21:58:06 UTC 2016


This is an automated email from the git hooks/post-receive script.

otto pushed a commit to branch ubuntu-14.04
in repository mariadb-5.5.

commit ad9e6670cea444f217a67fd8b294d76d8adec2da
Author: Otto Kekäläinen <otto at seravo.fi>
Date:   Mon Oct 31 23:46:29 2016 +0200

    Imported Upstream version 5.5.53
---
 Docs/INFO_SRC                                      |  10 +-
 VERSION                                            |   2 +-
 client/mysql.cc                                    |  56 +++----
 client/mysqldump.c                                 |  60 +++++--
 client/mysqltest.cc                                |   4 -
 extra/yassl/README                                 |  18 +++
 extra/yassl/certs/dsa-cert.pem                     |  38 ++---
 extra/yassl/include/openssl/ssl.h                  |   2 +-
 extra/yassl/src/ssl.cpp                            |  60 +++++--
 extra/yassl/taocrypt/include/aes.hpp               |  58 +++++++
 extra/yassl/taocrypt/include/integer.hpp           |   3 +
 extra/yassl/taocrypt/src/aes.cpp                   | 172 +++++++++++++--------
 extra/yassl/taocrypt/src/asn.cpp                   |  24 +--
 extra/yassl/taocrypt/src/dsa.cpp                   |  16 +-
 extra/yassl/taocrypt/test/test.cpp                 |   3 +
 extra/yassl/testsuite/test.hpp                     |   2 +-
 include/my_global.h                                |   3 +-
 mysql-test/lib/My/CoreDump.pm                      |   6 +-
 mysql-test/lib/My/Platform.pm                      |  49 +++++-
 mysql-test/lib/mtr_io.pl                           |   9 +-
 mysql-test/r/mysql.result                          |   8 +
 mysql-test/r/mysql_not_windows.result              |   6 +
 mysql-test/r/mysqldump-nl.result                   | 126 +++++++++++++++
 mysql-test/r/mysqltest.result                      |   6 -
 mysql-test/suite/plugins/r/server_audit.result     |   3 -
 .../plugins/r/thread_pool_server_audit.result      |   3 -
 mysql-test/t/mysql.test                            |   8 +
 mysql-test/t/mysql_not_windows.test                |   9 ++
 mysql-test/t/mysqldump-nl.test                     |  38 +++++
 mysql-test/t/mysqltest.test                        |   9 --
 mysys/my_fopen.c                                   |   6 +-
 plugin/feedback/utils.cc                           |  13 +-
 plugin/server_audit/server_audit.c                 |   5 +-
 scripts/mysqld_safe.sh                             |   6 +-
 sql/log.cc                                         |   2 +-
 sql/parse_file.h                                   |   6 +-
 sql/sql_plugin.cc                                  | 151 ++++++++----------
 storage/xtradb/btr/btr0btr.c                       |   4 +-
 storage/xtradb/handler/ha_innodb.cc                | 107 +++++++++++--
 storage/xtradb/include/buf0buf.h                   |  14 +-
 storage/xtradb/include/buf0buf.ic                  |  14 ++
 storage/xtradb/include/srv0srv.h                   |   8 +
 storage/xtradb/include/univ.i                      |   4 +-
 storage/xtradb/log/log0log.c                       |   9 +-
 storage/xtradb/log/log0online.c                    |  12 +-
 storage/xtradb/log/log0recv.c                      |   2 +-
 storage/xtradb/mach/mach0data.c                    |  13 +-
 storage/xtradb/srv/srv0srv.c                       |  42 +++--
 support-files/mysql.server.sh                      |   2 +-
 tests/async_queries.c                              |   2 +-
 50 files changed, 876 insertions(+), 357 deletions(-)

diff --git a/Docs/INFO_SRC b/Docs/INFO_SRC
index f2751c3..8730503 100644
--- a/Docs/INFO_SRC
+++ b/Docs/INFO_SRC
@@ -1,8 +1,8 @@
-commit: 0da39caceea7733a94d898427d63ba2670160af4
-date: 2016-09-12 16:42:05 +0200
-build-date: 2016-09-12 16:54:58 +0200 
-short: 0da39ca
+commit: eac8d95ffcdea7cd31d60d273e30cb3dfec66add
+date: 2016-10-14 12:51:53 +0200
+build-date: 2016-10-14 12:55:57 +0200 
+short: eac8d95
 branch: HEAD
 
 
-MySQL source 5.5.52
+MySQL source 5.5.53
diff --git a/VERSION b/VERSION
index acabf9b..d44c8b2 100644
--- a/VERSION
+++ b/VERSION
@@ -1,4 +1,4 @@
 MYSQL_VERSION_MAJOR=5
 MYSQL_VERSION_MINOR=5
-MYSQL_VERSION_PATCH=52
+MYSQL_VERSION_PATCH=53
 MYSQL_VERSION_EXTRA=
diff --git a/client/mysql.cc b/client/mysql.cc
index 9d255b5..9b1999f 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -245,7 +245,8 @@ static void end_pager();
 static void init_tee(const char *);
 static void end_tee();
 static const char* construct_prompt();
-static char *get_arg(char *line, my_bool get_next_arg);
+enum get_arg_mode { CHECK, GET, GET_NEXT};
+static char *get_arg(char *line, get_arg_mode mode);
 static void init_username();
 static void add_int_to_prompt(int toadd);
 static int get_result_width(MYSQL_RES *res);
@@ -2223,7 +2224,7 @@ static COMMANDS *find_command(char *name)
       if (!my_strnncoll(&my_charset_latin1, (uchar*) name, len,
                         (uchar*) commands[i].name, len) &&
           (commands[i].name[len] == '\0') &&
-          (!end || commands[i].takes_params))
+          (!end || (commands[i].takes_params && get_arg(name, CHECK))))
       {
         index= i;
         break;
@@ -3143,7 +3144,7 @@ com_charset(String *buffer __attribute__((unused)), char *line)
   char buff[256], *param;
   CHARSET_INFO * new_cs;
   strmake_buf(buff, line);
-  param= get_arg(buff, 0);
+  param= get_arg(buff, GET);
   if (!param || !*param)
   {
     return put_info("Usage: \\C charset_name | charset charset_name", 
@@ -4228,12 +4229,12 @@ com_connect(String *buffer, char *line)
 #ifdef EXTRA_DEBUG
     tmp[1]= 0;
 #endif
-    tmp= get_arg(buff, 0);
+    tmp= get_arg(buff, GET);
     if (tmp && *tmp)
     {
       my_free(current_db);
       current_db= my_strdup(tmp, MYF(MY_WME));
-      tmp= get_arg(buff, 1);
+      tmp= get_arg(buff, GET_NEXT);
       if (tmp)
       {
 	my_free(current_host);
@@ -4336,7 +4337,7 @@ com_delimiter(String *buffer __attribute__((unused)), char *line)
   char buff[256], *tmp;
 
   strmake_buf(buff, line);
-  tmp= get_arg(buff, 0);
+  tmp= get_arg(buff, GET);
 
   if (!tmp || !*tmp)
   {
@@ -4367,7 +4368,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
 
   bzero(buff, sizeof(buff));
   strmake_buf(buff, line);
-  tmp= get_arg(buff, 0);
+  tmp= get_arg(buff, GET);
   if (!tmp || !*tmp)
   {
     put_info("USE must be followed by a database name", INFO_ERROR);
@@ -4452,23 +4453,22 @@ com_nowarnings(String *buffer __attribute__((unused)),
 }
 
 /*
-  Gets argument from a command on the command line. If get_next_arg is
-  not defined, skips the command and returns the first argument. The
-  line is modified by adding zero to the end of the argument. If
-  get_next_arg is defined, then the function searches for end of string
-  first, after found, returns the next argument and adds zero to the
-  end. If you ever wish to use this feature, remember to initialize all
-  items in the array to zero first.
+  Gets argument from a command on the command line. If mode is not GET_NEXT,
+  skips the command and returns the first argument. The line is modified by
+  adding zero to the end of the argument. If mode is GET_NEXT, then the
+  function searches for end of string first, after found, returns the next
+  argument and adds zero to the end. If you ever wish to use this feature,
+  remember to initialize all items in the array to zero first.
 */
 
-char *get_arg(char *line, my_bool get_next_arg)
+static char *get_arg(char *line, get_arg_mode mode)
 {
   char *ptr, *start;
-  my_bool quoted= 0, valid_arg= 0;
+  bool short_cmd= false;
   char qtype= 0;
 
   ptr= line;
-  if (get_next_arg)
+  if (mode == GET_NEXT)
   {
     for (; *ptr; ptr++) ;
     if (*(ptr + 1))
@@ -4479,7 +4479,7 @@ char *get_arg(char *line, my_bool get_next_arg)
     /* skip leading white spaces */
     while (my_isspace(charset_info, *ptr))
       ptr++;
-    if (*ptr == '\\') // short command was used
+    if ((short_cmd= *ptr == '\\')) // short command was used
       ptr+= 2;
     else
       while (*ptr &&!my_isspace(charset_info, *ptr)) // skip command
@@ -4492,24 +4492,28 @@ char *get_arg(char *line, my_bool get_next_arg)
   if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
   {
     qtype= *ptr;
-    quoted= 1;
     ptr++;
   }
   for (start=ptr ; *ptr; ptr++)
   {
-    if (*ptr == '\\' && ptr[1]) // escaped character
+    if ((*ptr == '\\' && ptr[1]) ||  // escaped character
+        (!short_cmd && qtype && *ptr == qtype && ptr[1] == qtype)) // quote
     {
-      // Remove the backslash
-      strmov_overlapp(ptr, ptr+1);
+      // Remove (or skip) the backslash (or a second quote)
+      if (mode != CHECK)
+        strmov_overlapp(ptr, ptr+1);
+      else
+        ptr++;
     }
-    else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
+    else if (*ptr == (qtype ? qtype : ' '))
     {
-      *ptr= 0;
+      qtype= 0;
+      if (mode != CHECK)
+        *ptr= 0;
       break;
     }
   }
-  valid_arg= ptr != start;
-  return valid_arg ? start : NullS;
+  return ptr != start && !qtype ? start : NullS;
 }
 
 
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 16b39b7..32c350d 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -547,9 +547,7 @@ static int dump_all_tablespaces();
 static int dump_tablespaces_for_tables(char *db, char **table_names, int tables);
 static int dump_tablespaces_for_databases(char** databases);
 static int dump_tablespaces(char* ts_where);
-static void print_comment(FILE *sql_file, my_bool is_error, const char *format,
-                          ...);
-
+static void print_comment(FILE *, my_bool, const char *, ...);
 
 /*
   Print the supplied message if in verbose mode
@@ -627,6 +625,30 @@ static void short_usage(FILE *f)
 }
 
 
+/** returns a string fixed to be safely printed inside a -- comment
+
+  that is, any new line in it gets prefixed with --
+*/
+static const char *fix_for_comment(const char *ident)
+{
+  static char buf[1024];
+  char c, *s= buf;
+
+  while ((c= *s++= *ident++))
+  {
+    if (s >= buf + sizeof(buf) - 10)
+    {
+      strmov(s, "...");
+      break;
+    }
+    if (c == '\n')
+      s= strmov(s, "-- ");
+  }
+
+  return buf;
+}
+
+
 static void write_header(FILE *sql_file, char *db_name)
 {
   if (opt_xml)
@@ -649,8 +671,8 @@ static void write_header(FILE *sql_file, char *db_name)
                   DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE,
                   MACHINE_TYPE);
     print_comment(sql_file, 0, "-- Host: %s    Database: %s\n",
-                  current_host ? current_host : "localhost",
-                  db_name ? db_name : "");
+                  fix_for_comment(current_host ? current_host : "localhost"),
+                  fix_for_comment(db_name ? db_name : ""));
     print_comment(sql_file, 0,
                   "-- ------------------------------------------------------\n"
                  );
@@ -2094,7 +2116,8 @@ static uint dump_events_for_db(char *db)
 
   /* nice comments */
   print_comment(sql_file, 0,
-                "\n--\n-- Dumping events for database '%s'\n--\n", db);
+                "\n--\n-- Dumping events for database '%s'\n--\n",
+                fix_for_comment(db));
 
   /*
     not using "mysql_query_with_error_report" because we may have not
@@ -2307,7 +2330,8 @@ static uint dump_routines_for_db(char *db)
 
   /* nice comments */
   print_comment(sql_file, 0,
-                "\n--\n-- Dumping routines for database '%s'\n--\n", db);
+                "\n--\n-- Dumping routines for database '%s'\n--\n",
+                fix_for_comment(db));
 
   /*
     not using "mysql_query_with_error_report" because we may have not
@@ -2580,11 +2604,11 @@ static uint get_table_structure(char *table, char *db, char *table_type,
       if (strcmp (table_type, "VIEW") == 0)         /* view */
         print_comment(sql_file, 0,
                       "\n--\n-- Temporary table structure for view %s\n--\n\n",
-                      result_table);
+                      fix_for_comment(result_table));
       else
         print_comment(sql_file, 0,
                       "\n--\n-- Table structure for table %s\n--\n\n",
-                      result_table);
+                      fix_for_comment(result_table));
 
       if (opt_drop)
       {
@@ -2826,7 +2850,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
 
       print_comment(sql_file, 0,
                     "\n--\n-- Table structure for table %s\n--\n\n",
-                    result_table);
+                    fix_for_comment(result_table));
       if (opt_drop)
         fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
       if (!opt_xml)
@@ -3530,21 +3554,21 @@ static void dump_table(char *table, char *db)
   {
     print_comment(md_result_file, 0,
                   "\n--\n-- Dumping data for table %s\n--\n",
-                  result_table);
+                  fix_for_comment(result_table));
     
     dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
     dynstr_append_checked(&query_string, result_table);
 
     if (where)
     {
-      print_comment(md_result_file, 0, "-- WHERE:  %s\n", where);
+      print_comment(md_result_file, 0, "-- WHERE:  %s\n", fix_for_comment(where));
 
       dynstr_append_checked(&query_string, " WHERE ");
       dynstr_append_checked(&query_string, where);
     }
     if (order_by)
     {
-      print_comment(md_result_file, 0, "-- ORDER BY:  %s\n", order_by);
+      print_comment(md_result_file, 0, "-- ORDER BY:  %s\n", fix_for_comment(order_by));
 
       dynstr_append_checked(&query_string, " ORDER BY ");
       dynstr_append_checked(&query_string, order_by);
@@ -4053,7 +4077,7 @@ static int dump_tablespaces(char* ts_where)
     if (first)
     {
       print_comment(md_result_file, 0, "\n--\n-- Logfile group: %s\n--\n",
-                    row[0]);
+                    fix_for_comment(row[0]));
 
       fprintf(md_result_file, "\nCREATE");
     }
@@ -4122,7 +4146,8 @@ static int dump_tablespaces(char* ts_where)
       first= 1;
     if (first)
     {
-      print_comment(md_result_file, 0, "\n--\n-- Tablespace: %s\n--\n", row[0]);
+      print_comment(md_result_file, 0, "\n--\n-- Tablespace: %s\n--\n",
+                    fix_for_comment(row[0]));
       fprintf(md_result_file, "\nCREATE");
     }
     else
@@ -4326,7 +4351,8 @@ static int init_dumping(char *database, int init_func(char*))
       char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
 
       print_comment(md_result_file, 0,
-                    "\n--\n-- Current Database: %s\n--\n", qdatabase);
+                    "\n--\n-- Current Database: %s\n--\n",
+                    fix_for_comment(qdatabase));
 
       /* Call the view or table specific function */
       init_func(qdatabase);
@@ -5356,7 +5382,7 @@ static my_bool get_view_structure(char *table, char* db)
 
   print_comment(sql_file, 0,
                 "\n--\n-- Final view structure for view %s\n--\n\n",
-                result_table);
+                fix_for_comment(result_table));
 
   /* Table might not exist if this view was dumped with --tab. */
   fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table);
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 3652d1a..acb9e8b 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -3349,10 +3349,6 @@ void do_exec(struct st_command *command)
 #endif
 #endif
 
-  /* exec command is interpreted externally and will not take newlines */
-  while(replace(&ds_cmd, "\n", 1, " ", 1) == 0)
-    ;
-  
   DBUG_PRINT("info", ("Executing '%s' as '%s'",
                       command->first_argument, ds_cmd.str));
 
diff --git a/extra/yassl/README b/extra/yassl/README
index b5eb888..a3d4f60 100644
--- a/extra/yassl/README
+++ b/extra/yassl/README
@@ -12,6 +12,24 @@ before calling SSL_new();
 
 *** end Note ***
 
+yaSSL Release notes, version 2.4.2 (9/22/2016)
+    This release of yaSSL fixes a medium security vulnerability. A fix for
+    potential AES side channel leaks is included that a local user monitoring
+    the same CPU core cache could exploit.  VM users, hyper-threading users,
+    and users where potential attackers have access to the CPU cache will need
+    to update if they utilize AES.
+
+    DSA padding fixes for unusual sizes is included as well.  Users with DSA
+    certficiates should update.
+
+yaSSL Release notes, version 2.4.0 (5/20/2016)
+    This release of yaSSL fixes the OpenSSL compatibility function
+    SSL_CTX_load_verify_locations() when using the path directory to allow
+    unlimited path sizes.  Minor Windows build fixes are included.
+    No high level security fixes in this version but we always recommend
+    updating.
+
+
 yaSSL Release notes, version 2.3.9b (2/03/2016)
     This release of yaSSL fixes the OpenSSL compatibility function
     X509_NAME_get_index_by_NID() to use the actual index of the common name
diff --git a/extra/yassl/certs/dsa-cert.pem b/extra/yassl/certs/dsa-cert.pem
index 10d533e..10794cb 100644
--- a/extra/yassl/certs/dsa-cert.pem
+++ b/extra/yassl/certs/dsa-cert.pem
@@ -1,22 +1,22 @@
 -----BEGIN CERTIFICATE-----
-MIIDqzCCA2ugAwIBAgIJAMGqrgDU6DyhMAkGByqGSM44BAMwgY4xCzAJBgNVBAYT
+MIIDrzCCA2+gAwIBAgIJAK1zRM7YFcNjMAkGByqGSM44BAMwgZAxCzAJBgNVBAYT
 AlVTMQ8wDQYDVQQIDAZPcmVnb24xETAPBgNVBAcMCFBvcnRsYW5kMRAwDgYDVQQK
-DAd3b2xmU1NMMRAwDgYDVQQLDAd0ZXN0aW5nMRYwFAYDVQQDDA13d3cueWFzc2wu
-Y29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMB4XDTEzMDQyMjIw
-MDk0NFoXDTE2MDExNzIwMDk0NFowgY4xCzAJBgNVBAYTAlVTMQ8wDQYDVQQIDAZP
-cmVnb24xETAPBgNVBAcMCFBvcnRsYW5kMRAwDgYDVQQKDAd3b2xmU1NMMRAwDgYD
-VQQLDAd0ZXN0aW5nMRYwFAYDVQQDDA13d3cueWFzc2wuY29tMR8wHQYJKoZIhvcN
-AQkBFhBpbmZvQHdvbGZzc2wuY29tMIIBuDCCASwGByqGSM44BAEwggEfAoGBAL1R
-7koy4IrH6sbh6nDEUUPPKgfhxxLCWCVexF2+qzANEr+hC9M002haJXFOfeS9DyoO
-WFbL0qMZOuqv+22CaHnoUWl7q3PjJOAI3JH0P54ZyUPuU1909RzgTdIDp5+ikbr7
-KYjnltL73FQVMbjTZQKthIpPn3MjYcF+4jp2W2zFAhUAkcntYND6MGf+eYzIJDN2
-L7SonHUCgYEAklpxErfqznIZjVvqqHFaq+mgAL5J8QrKVmdhYZh/Y8z4jCjoCA8o
-TDoFKxf7s2ZzgaPKvglaEKiYqLqic9qY78DYJswzQMLFvjsF4sFZ+pYCBdWPQI4N
-PgxCiznK6Ce+JH9ikSBvMvG+tevjr2UpawDIHX3+AWYaZBZwKADAaboDgYUAAoGB
-AJ3LY89yHyvQ/TsQ6zlYbovjbk/ogndsMqPdNUvL4RuPTgJP/caaDDa0XJ7ak6A7
-TJ+QheLNwOXoZPYJC4EGFSDAXpYniGhbWIrVTCGe6lmZDfnx40WXS0kk3m/DHaC0
-3ElLAiybxVGxyqoUfbT3Zv1JwftWMuiqHH5uADhdXuXVo1AwTjAdBgNVHQ4EFgQU
-IJjk416o4v8qpH9LBtXlR9v8gccwHwYDVR0jBBgwFoAUIJjk416o4v8qpH9LBtXl
-R9v8gccwDAYDVR0TBAUwAwEB/zAJBgcqhkjOOAQDAy8AMCwCFCjGKIdOSV12LcTu
-k08owGM6YkO1AhQe+K173VuaO/OsDNsxZlKpyH8+1g==
+DAd3b2xmU1NMMRAwDgYDVQQLDAd0ZXN0aW5nMRgwFgYDVQQDDA93d3cud29sZnNz
+bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMTYwOTIy
+MjEyMzA0WhcNMjIwMzE1MjEyMzA0WjCBkDELMAkGA1UEBhMCVVMxDzANBgNVBAgM
+Bk9yZWdvbjERMA8GA1UEBwwIUG9ydGxhbmQxEDAOBgNVBAoMB3dvbGZTU0wxEDAO
+BgNVBAsMB3Rlc3RpbmcxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG
+SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCAbgwggEsBgcqhkjOOAQBMIIBHwKB
+gQC9Ue5KMuCKx+rG4epwxFFDzyoH4ccSwlglXsRdvqswDRK/oQvTNNNoWiVxTn3k
+vQ8qDlhWy9KjGTrqr/ttgmh56FFpe6tz4yTgCNyR9D+eGclD7lNfdPUc4E3SA6ef
+opG6+ymI55bS+9xUFTG402UCrYSKT59zI2HBfuI6dltsxQIVAJHJ7WDQ+jBn/nmM
+yCQzdi+0qJx1AoGBAJJacRK36s5yGY1b6qhxWqvpoAC+SfEKylZnYWGYf2PM+Iwo
+6AgPKEw6BSsX+7Nmc4Gjyr4JWhComKi6onPamO/A2CbMM0DCxb47BeLBWfqWAgXV
+j0CODT4MQos5yugnviR/YpEgbzLxvrXr469lKWsAyB19/gFmGmQWcCgAwGm6A4GF
+AAKBgQCdy2PPch8r0P07EOs5WG6L425P6IJ3bDKj3TVLy+Ebj04CT/3Gmgw2tFye
+2pOgO0yfkIXizcDl6GT2CQuBBhUgwF6WJ4hoW1iK1UwhnupZmQ358eNFl0tJJN5v
+wx2gtNxJSwIsm8VRscqqFH2092b9ScH7VjLoqhx+bgA4XV7l1aNQME4wHQYDVR0O
+BBYEFCCY5ONeqOL/KqR/SwbV5Ufb/IHHMB8GA1UdIwQYMBaAFCCY5ONeqOL/KqR/
+SwbV5Ufb/IHHMAwGA1UdEwQFMAMBAf8wCQYHKoZIzjgEAwMvADAsAhQRYSCVN/Ge
+agV3mffU3qNZ92fI0QIUPH7Jp+iASI7U1ocaYDc10qXGaGY=
 -----END CERTIFICATE-----
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index 83daf3c..0609dfc 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -35,7 +35,7 @@
 #include "rsa.h"
 
 
-#define YASSL_VERSION "2.3.9b"
+#define YASSL_VERSION "2.4.2"
 
 
 #if defined(__cplusplus)
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index 778c6a8..1deb827 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -161,7 +161,7 @@ int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
             TaoCrypt::DSA_PrivateKey dsaKey;
             dsaKey.Initialize(dsaSource);
 
-            if (rsaSource.GetError().What()) {
+            if (dsaSource.GetError().What()) {
                 // neither worked
                 ret = SSL_FAILURE;
             }
@@ -784,40 +784,67 @@ int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
         WIN32_FIND_DATA FindFileData;
         HANDLE hFind;
 
-        char name[MAX_PATH + 1];  // directory specification
-        strncpy(name, path, MAX_PATH - 3);
-        strncat(name, "\\*", 3);
+        const int DELIMITER_SZ      = 2;
+        const int DELIMITER_STAR_SZ = 3;
+        int pathSz = (int)strlen(path);
+        int nameSz = pathSz + DELIMITER_STAR_SZ + 1; // plus 1 for terminator
+        char* name = NEW_YS char[nameSz];  // directory specification
+        memset(name, 0, nameSz);
+        strncpy(name, path, nameSz - DELIMITER_STAR_SZ - 1);
+        strncat(name, "\\*", DELIMITER_STAR_SZ);
 
         hFind = FindFirstFile(name, &FindFileData);
-        if (hFind == INVALID_HANDLE_VALUE) return SSL_BAD_PATH;
+        if (hFind == INVALID_HANDLE_VALUE) {
+            ysArrayDelete(name);
+            return SSL_BAD_PATH;
+        }
 
         do {
-            if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
-                strncpy(name, path, MAX_PATH - 2 - HALF_PATH);
-                strncat(name, "\\", 2);
-                strncat(name, FindFileData.cFileName, HALF_PATH);
+            if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+                int curSz = (int)strlen(FindFileData.cFileName);
+                if (pathSz + curSz + DELIMITER_SZ + 1 > nameSz) {
+                    ysArrayDelete(name);
+                    // plus 1 for terminator
+                    nameSz = pathSz + curSz + DELIMITER_SZ + 1;
+                    name = NEW_YS char[nameSz];
+                }
+                memset(name, 0, nameSz);
+                strncpy(name, path, nameSz - curSz - DELIMITER_SZ - 1);
+                strncat(name, "\\", DELIMITER_SZ);
+                strncat(name, FindFileData.cFileName,
+                                            nameSz - pathSz - DELIMITER_SZ - 1);
                 ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
             }
         } while (ret == SSL_SUCCESS && FindNextFile(hFind, &FindFileData));
 
+        ysArrayDelete(name);
         FindClose(hFind);
 
 #else   // _WIN32
-
-        const int MAX_PATH = 260;
-
         DIR* dir = opendir(path);
         if (!dir) return SSL_BAD_PATH;
 
         struct dirent* entry;
         struct stat    buf;
-        char           name[MAX_PATH + 1];
+        const int DELIMITER_SZ = 1;
+        int pathSz = (int)strlen(path);
+        int nameSz = pathSz + DELIMITER_SZ + 1; //plus 1 for null terminator
+        char* name = NEW_YS char[nameSz];  // directory specification
 
         while (ret == SSL_SUCCESS && (entry = readdir(dir))) {
-            strncpy(name, path, MAX_PATH - 1 - HALF_PATH);
-            strncat(name, "/", 1);
-            strncat(name, entry->d_name, HALF_PATH);
+            int curSz = (int)strlen(entry->d_name);
+            if (pathSz + curSz + DELIMITER_SZ + 1 > nameSz) {
+                ysArrayDelete(name);
+                nameSz = pathSz + DELIMITER_SZ + curSz + 1;
+                name = NEW_YS char[nameSz];
+            }
+            memset(name, 0, nameSz);
+            strncpy(name, path, nameSz - curSz - 1);
+            strncat(name, "/",  DELIMITER_SZ);
+            strncat(name, entry->d_name, nameSz - pathSz - DELIMITER_SZ - 1);
+
             if (stat(name, &buf) < 0) {
+                ysArrayDelete(name);
                 closedir(dir);
                 return SSL_BAD_STAT;
             }
@@ -826,6 +853,7 @@ int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
                 ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
         }
 
+        ysArrayDelete(name);
         closedir(dir);
 
 #endif
diff --git a/extra/yassl/taocrypt/include/aes.hpp b/extra/yassl/taocrypt/include/aes.hpp
index 0176303..bccf6e7 100644
--- a/extra/yassl/taocrypt/include/aes.hpp
+++ b/extra/yassl/taocrypt/include/aes.hpp
@@ -60,6 +60,7 @@ private:
 
     static const word32 Te[5][256];
     static const word32 Td[5][256];
+    static const byte   CTd4[256];
 
     static const word32* Te0;
     static const word32* Te1;
@@ -80,11 +81,68 @@ private:
 
     void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
 
+    word32 PreFetchTe() const;
+    word32 PreFetchTd() const;
+    word32 PreFetchCTd4() const;
+
     AES(const AES&);            // hide copy
     AES& operator=(const AES&); // and assign
 };
 
 
+#if defined(__x86_64__) || defined(_M_X64) || \
+           (defined(__ILP32__) && (__ILP32__ >= 1))
+    #define TC_CACHE_LINE_SZ 64
+#else
+    /* default cache line size */
+    #define TC_CACHE_LINE_SZ 32
+#endif
+
+inline word32 AES::PreFetchTe() const
+{
+    word32 x = 0;
+
+    /* 4 tables of 256 entries */
+    for (int i = 0; i < 4; i++) {
+        /* each entry is 4 bytes */
+        for (int j = 0; j < 256; j += TC_CACHE_LINE_SZ/4) {
+            x &= Te[i][j];
+        }
+    }
+
+    return x;
+}
+
+
+inline word32 AES::PreFetchTd() const
+{
+    word32 x = 0;
+
+    /* 4 tables of 256 entries */
+    for (int i = 0; i < 4; i++) {
+        /* each entry is 4 bytes */
+        for (int j = 0; j < 256; j += TC_CACHE_LINE_SZ/4) {
+            x &= Td[i][j];
+        }
+    }
+
+    return x;
+}
+
+
+inline word32 AES::PreFetchCTd4() const
+{
+    word32 x = 0;
+    int i;
+
+    for (i = 0; i < 256; i += TC_CACHE_LINE_SZ) {
+        x &= CTd4[i];
+    }
+
+    return x;
+}
+
+
 typedef BlockCipher<ENCRYPTION, AES, ECB> AES_ECB_Encryption;
 typedef BlockCipher<DECRYPTION, AES, ECB> AES_ECB_Decryption;
 
diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp
index 75a3ee3..05fe189 100644
--- a/extra/yassl/taocrypt/include/integer.hpp
+++ b/extra/yassl/taocrypt/include/integer.hpp
@@ -119,6 +119,9 @@ namespace TaoCrypt {
 
 
 
+#ifdef _WIN32
+    #undef max // avoid name clash
+#endif
 // general MAX
 template<typename T> inline
 const T& max(const T& a, const T& b)
diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp
index e47765b..2321c72 100644
--- a/extra/yassl/taocrypt/src/aes.cpp
+++ b/extra/yassl/taocrypt/src/aes.cpp
@@ -109,10 +109,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
         {
             temp  = rk[3];
             rk[4] = rk[0] ^
-                (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
+                (Te2[GETBYTE(temp, 2)] & 0xff000000) ^
+                (Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
+                (Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
+                (Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
                 rcon_[i];
             rk[5] = rk[1] ^ rk[4];
             rk[6] = rk[2] ^ rk[5];
@@ -128,10 +128,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
         {
             temp = rk[ 5];
             rk[ 6] = rk[ 0] ^
-                (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
+                (Te2[GETBYTE(temp, 2)] & 0xff000000) ^
+                (Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
+                (Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
+                (Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
                 rcon_[i];
             rk[ 7] = rk[ 1] ^ rk[ 6];
             rk[ 8] = rk[ 2] ^ rk[ 7];
@@ -149,10 +149,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
         {
             temp = rk[ 7];
             rk[ 8] = rk[ 0] ^
-                (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
+                (Te2[GETBYTE(temp, 2)] & 0xff000000) ^
+                (Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
+                (Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
+                (Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
                 rcon_[i];
             rk[ 9] = rk[ 1] ^ rk[ 8];
             rk[10] = rk[ 2] ^ rk[ 9];
@@ -161,10 +161,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
                 break;
             temp = rk[11];
             rk[12] = rk[ 4] ^
-                (Te4[GETBYTE(temp, 3)] & 0xff000000) ^
-                (Te4[GETBYTE(temp, 2)] & 0x00ff0000) ^
-                (Te4[GETBYTE(temp, 1)] & 0x0000ff00) ^
-                (Te4[GETBYTE(temp, 0)] & 0x000000ff);
+                (Te2[GETBYTE(temp, 3)] & 0xff000000) ^
+                (Te3[GETBYTE(temp, 2)] & 0x00ff0000) ^
+                (Te0[GETBYTE(temp, 1)] & 0x0000ff00) ^
+                (Te1[GETBYTE(temp, 0)] & 0x000000ff);
             rk[13] = rk[ 5] ^ rk[12];
             rk[14] = rk[ 6] ^ rk[13];
             rk[15] = rk[ 7] ^ rk[14];
@@ -191,25 +191,25 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
         for (i = 1; i < rounds_; i++) {
             rk += 4;
             rk[0] =
-                Td0[Te4[GETBYTE(rk[0], 3)] & 0xff] ^
-                Td1[Te4[GETBYTE(rk[0], 2)] & 0xff] ^
-                Td2[Te4[GETBYTE(rk[0], 1)] & 0xff] ^
-                Td3[Te4[GETBYTE(rk[0], 0)] & 0xff];
+                Td0[Te1[GETBYTE(rk[0], 3)] & 0xff] ^
+                Td1[Te1[GETBYTE(rk[0], 2)] & 0xff] ^
+                Td2[Te1[GETBYTE(rk[0], 1)] & 0xff] ^
+                Td3[Te1[GETBYTE(rk[0], 0)] & 0xff];
             rk[1] =
-                Td0[Te4[GETBYTE(rk[1], 3)] & 0xff] ^
-                Td1[Te4[GETBYTE(rk[1], 2)] & 0xff] ^
-                Td2[Te4[GETBYTE(rk[1], 1)] & 0xff] ^
-                Td3[Te4[GETBYTE(rk[1], 0)] & 0xff];
+                Td0[Te1[GETBYTE(rk[1], 3)] & 0xff] ^
+                Td1[Te1[GETBYTE(rk[1], 2)] & 0xff] ^
+                Td2[Te1[GETBYTE(rk[1], 1)] & 0xff] ^
+                Td3[Te1[GETBYTE(rk[1], 0)] & 0xff];
             rk[2] =
-                Td0[Te4[GETBYTE(rk[2], 3)] & 0xff] ^
-                Td1[Te4[GETBYTE(rk[2], 2)] & 0xff] ^
-                Td2[Te4[GETBYTE(rk[2], 1)] & 0xff] ^
-                Td3[Te4[GETBYTE(rk[2], 0)] & 0xff];
+                Td0[Te1[GETBYTE(rk[2], 3)] & 0xff] ^
+                Td1[Te1[GETBYTE(rk[2], 2)] & 0xff] ^
+                Td2[Te1[GETBYTE(rk[2], 1)] & 0xff] ^
+                Td3[Te1[GETBYTE(rk[2], 0)] & 0xff];
             rk[3] =
-                Td0[Te4[GETBYTE(rk[3], 3)] & 0xff] ^
-                Td1[Te4[GETBYTE(rk[3], 2)] & 0xff] ^
-                Td2[Te4[GETBYTE(rk[3], 1)] & 0xff] ^
-                Td3[Te4[GETBYTE(rk[3], 0)] & 0xff];
+                Td0[Te1[GETBYTE(rk[3], 3)] & 0xff] ^
+                Td1[Te1[GETBYTE(rk[3], 2)] & 0xff] ^
+                Td2[Te1[GETBYTE(rk[3], 1)] & 0xff] ^
+                Td3[Te1[GETBYTE(rk[3], 0)] & 0xff];
         }
     }
 }
@@ -244,6 +244,7 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
     s2 ^= rk[2];
     s3 ^= rk[3];
    
+    s0 |= PreFetchTe();
     /*
      * Nr - 1 full rounds:
      */
@@ -312,28 +313,28 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
      */
 
     s0 =
-        (Te4[GETBYTE(t0, 3)] & 0xff000000) ^
-        (Te4[GETBYTE(t1, 2)] & 0x00ff0000) ^
-        (Te4[GETBYTE(t2, 1)] & 0x0000ff00) ^
-        (Te4[GETBYTE(t3, 0)] & 0x000000ff) ^
+        (Te2[GETBYTE(t0, 3)] & 0xff000000) ^
+        (Te3[GETBYTE(t1, 2)] & 0x00ff0000) ^
+        (Te0[GETBYTE(t2, 1)] & 0x0000ff00) ^
+        (Te1[GETBYTE(t3, 0)] & 0x000000ff) ^
         rk[0];
     s1 =
-        (Te4[GETBYTE(t1, 3)] & 0xff000000) ^
-        (Te4[GETBYTE(t2, 2)] & 0x00ff0000) ^
-        (Te4[GETBYTE(t3, 1)] & 0x0000ff00) ^
-        (Te4[GETBYTE(t0, 0)] & 0x000000ff) ^
+        (Te2[GETBYTE(t1, 3)] & 0xff000000) ^
+        (Te3[GETBYTE(t2, 2)] & 0x00ff0000) ^
+        (Te0[GETBYTE(t3, 1)] & 0x0000ff00) ^
+        (Te1[GETBYTE(t0, 0)] & 0x000000ff) ^
         rk[1];
     s2 =
-        (Te4[GETBYTE(t2, 3)] & 0xff000000) ^
-        (Te4[GETBYTE(t3, 2)] & 0x00ff0000) ^
-        (Te4[GETBYTE(t0, 1)] & 0x0000ff00) ^
-        (Te4[GETBYTE(t1, 0)] & 0x000000ff) ^
+        (Te2[GETBYTE(t2, 3)] & 0xff000000) ^
+        (Te3[GETBYTE(t3, 2)] & 0x00ff0000) ^
+        (Te0[GETBYTE(t0, 1)] & 0x0000ff00) ^
+        (Te1[GETBYTE(t1, 0)] & 0x000000ff) ^
         rk[2];
     s3 =
-        (Te4[GETBYTE(t3, 3)] & 0xff000000) ^
-        (Te4[GETBYTE(t0, 2)] & 0x00ff0000) ^
-        (Te4[GETBYTE(t1, 1)] & 0x0000ff00) ^
-        (Te4[GETBYTE(t2, 0)] & 0x000000ff) ^
+        (Te2[GETBYTE(t3, 3)] & 0xff000000) ^
+        (Te3[GETBYTE(t0, 2)] & 0x00ff0000) ^
+        (Te0[GETBYTE(t1, 1)] & 0x0000ff00) ^
+        (Te1[GETBYTE(t2, 0)] & 0x000000ff) ^
         rk[3];
 
 
@@ -358,6 +359,8 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
     s2 ^= rk[2];
     s3 ^= rk[3];
 
+    s0 |= PreFetchTd();
+
     /*
      * Nr - 1 full rounds:
      */
@@ -423,29 +426,32 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
      * apply last round and
      * map cipher state to byte array block:
      */
+
+    t0 |= PreFetchCTd4();
+
     s0 =
-        (Td4[GETBYTE(t0, 3)] & 0xff000000) ^
-        (Td4[GETBYTE(t3, 2)] & 0x00ff0000) ^
-        (Td4[GETBYTE(t2, 1)] & 0x0000ff00) ^
-        (Td4[GETBYTE(t1, 0)] & 0x000000ff) ^
+        ((word32)CTd4[GETBYTE(t0, 3)] << 24) ^
+        ((word32)CTd4[GETBYTE(t3, 2)] << 16) ^
+        ((word32)CTd4[GETBYTE(t2, 1)] <<  8) ^
+        ((word32)CTd4[GETBYTE(t1, 0)]) ^
         rk[0];
     s1 =
-        (Td4[GETBYTE(t1, 3)] & 0xff000000) ^
-        (Td4[GETBYTE(t0, 2)] & 0x00ff0000) ^
-        (Td4[GETBYTE(t3, 1)] & 0x0000ff00) ^
-        (Td4[GETBYTE(t2, 0)] & 0x000000ff) ^
+        ((word32)CTd4[GETBYTE(t1, 3)]  << 24) ^
+        ((word32)CTd4[GETBYTE(t0, 2)]  << 16) ^
+        ((word32)CTd4[GETBYTE(t3, 1)]  <<  8) ^
+        ((word32)CTd4[GETBYTE(t2, 0)]) ^
         rk[1];
     s2 =
-        (Td4[GETBYTE(t2, 3)] & 0xff000000) ^
-        (Td4[GETBYTE(t1, 2)] & 0x00ff0000) ^
-        (Td4[GETBYTE(t0, 1)] & 0x0000ff00) ^
-        (Td4[GETBYTE(t3, 0)] & 0x000000ff) ^
+        ((word32)CTd4[GETBYTE(t2, 3)] << 24  ) ^
+        ((word32)CTd4[GETBYTE(t1, 2)] << 16 ) ^
+        ((word32)CTd4[GETBYTE(t0, 1)] <<  8 ) ^
+        ((word32)CTd4[GETBYTE(t3, 0)]) ^
         rk[2];
     s3 =
-        (Td4[GETBYTE(t3, 3)] & 0xff000000) ^
-        (Td4[GETBYTE(t2, 2)] & 0x00ff0000) ^
-        (Td4[GETBYTE(t1, 1)] & 0x0000ff00) ^
-        (Td4[GETBYTE(t0, 0)] & 0x000000ff) ^
+        ((word32)CTd4[GETBYTE(t3, 3)] << 24) ^
+        ((word32)CTd4[GETBYTE(t2, 2)] << 16) ^
+        ((word32)CTd4[GETBYTE(t1, 1)] <<  8) ^
+        ((word32)CTd4[GETBYTE(t0, 0)]) ^
         rk[3];
 
     gpBlock::Put(xorBlock, outBlock)(s0)(s1)(s2)(s3);
@@ -1826,18 +1832,52 @@ const word32 AES::Td[5][256] = {
 }
 };
 
+const byte AES::CTd4[256] =
+{
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+
 
 const word32* AES::Te0 = AES::Te[0];
 const word32* AES::Te1 = AES::Te[1];
 const word32* AES::Te2 = AES::Te[2];
 const word32* AES::Te3 = AES::Te[3];
-const word32* AES::Te4 = AES::Te[4];
 
 const word32* AES::Td0 = AES::Td[0];
 const word32* AES::Td1 = AES::Td[1];
 const word32* AES::Td2 = AES::Td[2];
 const word32* AES::Td3 = AES::Td[3];
-const word32* AES::Td4 = AES::Td[4];
 
 
 
diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp
index a210d80..7ff3c71 100644
--- a/extra/yassl/taocrypt/src/asn.cpp
+++ b/extra/yassl/taocrypt/src/asn.cpp
@@ -1209,17 +1209,17 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
     }
     word32 rLen = GetLength(source);
     if (rLen != 20) {
-        if (rLen == 21) {       // zero at front, eat
+        while (rLen > 20 && source.remaining() > 0) {  // zero's at front, eat
             source.next();
             --rLen;
         }
-        else if (rLen == 19) {  // add zero to front so 20 bytes
+        if (rLen < 20) { // add zero's to front so 20 bytes
+            word32 tmpLen = rLen;
+            while (tmpLen < 20) {
             decoded[0] = 0;
             decoded++;
+                tmpLen++;
         }
-        else {
-            source.SetError(DSA_SZ_E);
-            return 0;
         }
     }
     memcpy(decoded, source.get_buffer() + source.get_index(), rLen);
@@ -1232,17 +1232,17 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
     }
     word32 sLen = GetLength(source);
     if (sLen != 20) {
-        if (sLen == 21) {
-            source.next();          // zero at front, eat
+        while (sLen > 20 && source.remaining() > 0) {
+            source.next();          // zero's at front, eat
             --sLen;
         }
-        else if (sLen == 19) {
-            decoded[rLen] = 0;      // add zero to front so 20 bytes
+        if (sLen < 20) { // add zero's to front so 20 bytes
+            word32 tmpLen = sLen;
+            while (tmpLen < 20) {
+                decoded[rLen] = 0;
             decoded++;
+                tmpLen++;
         }
-        else {
-            source.SetError(DSA_SZ_E);
-            return 0;
         }
     }
     memcpy(decoded + rLen, source.get_buffer() + source.get_index(), sLen);
diff --git a/extra/yassl/taocrypt/src/dsa.cpp b/extra/yassl/taocrypt/src/dsa.cpp
index 7222144..fda0188 100644
--- a/extra/yassl/taocrypt/src/dsa.cpp
+++ b/extra/yassl/taocrypt/src/dsa.cpp
@@ -172,6 +172,7 @@ word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
     const Integer& q = key_.GetSubGroupOrder();
     const Integer& g = key_.GetSubGroupGenerator();
     const Integer& x = key_.GetPrivatePart();
+    byte* tmpPtr = sig;  // initial signature output
 
     Integer k(rng, 1, q - 1);
 
@@ -187,22 +188,23 @@ word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
       return (word32) -1;
 
     int rSz = r_.ByteCount();
+    int tmpSz = rSz;
 
-    if (rSz == 19) {
-        sig[0] = 0;
-        sig++;
+    while (tmpSz++ < SHA::DIGEST_SIZE) {
+        *sig++ = 0;
     }
     
     r_.Encode(sig,  rSz);
 
+    sig = tmpPtr + SHA::DIGEST_SIZE;  // advance sig output to s
     int sSz = s_.ByteCount();
+    tmpSz = sSz;
 
-    if (sSz == 19) {
-        sig[rSz] = 0;
-        sig++;
+    while (tmpSz++ < SHA::DIGEST_SIZE) {
+        *sig++ = 0;
     }
 
-    s_.Encode(sig + rSz, sSz);
+    s_.Encode(sig, sSz);
 
     return 40;
 }
diff --git a/extra/yassl/taocrypt/test/test.cpp b/extra/yassl/taocrypt/test/test.cpp
index c23d981..b07a9eb 100644
--- a/extra/yassl/taocrypt/test/test.cpp
+++ b/extra/yassl/taocrypt/test/test.cpp
@@ -1281,6 +1281,9 @@ int dsa_test()
     if (!verifier.Verify(digest, decoded))
         return -90;
 
+    if (!verifier.Verify(digest, signature))
+        return -91;
+
     return 0;
 }
 
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index 5374edd..a65a212 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -22,7 +22,6 @@
 #define yaSSL_TEST_HPP
 
 #include "runtime.hpp"
-#include "openssl/ssl.h"   /* openssl compatibility test */
 #include "error.hpp"
 #include <stdio.h>
 #include <stdlib.h>
@@ -56,6 +55,7 @@
 #endif
     #define SOCKET_T int
 #endif /* _WIN32 */
+#include "openssl/ssl.h"   /* openssl compatibility test */
 
 
 #ifdef _MSC_VER
diff --git a/include/my_global.h b/include/my_global.h
index dce38a1..0c15478 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -857,8 +857,7 @@ typedef long long	my_ptrdiff_t;
   and related routines are refactored.
 */
 
-#define my_offsetof(TYPE, MEMBER) \
-        ((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
+#define my_offsetof(TYPE, MEMBER) PTR_BYTE_DIFF(&((TYPE *)0x10)->MEMBER, 0x10)
 
 #define NullS		(char *) 0
 
diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm
index 0e90967..f9f7b3d 100644
--- a/mysql-test/lib/My/CoreDump.pm
+++ b/mysql-test/lib/My/CoreDump.pm
@@ -261,11 +261,7 @@ sub show {
   # On Windows, rely on cdb to be there...
   if (IS_WINDOWS)
   {
-    # Starting cdb is unsafe when used with --parallel > 1 option 
-    if ( $parallel < 2 )
-    {
-      _cdb($core_name);
-    }
+    _cdb($core_name);
     return;
   }
   
diff --git a/mysql-test/lib/My/Platform.pm b/mysql-test/lib/My/Platform.pm
index 1776f10..110cf8a 100644
--- a/mysql-test/lib/My/Platform.pm
+++ b/mysql-test/lib/My/Platform.pm
@@ -24,7 +24,7 @@ use File::Path;
 use base qw(Exporter);
 our @EXPORT= qw(IS_CYGWIN IS_WINDOWS IS_WIN32PERL
 		native_path posix_path mixed_path
-                check_socket_path_length process_alive);
+                check_socket_path_length process_alive open_for_append);
 
 BEGIN {
   if ($^O eq "cygwin") {
@@ -161,4 +161,51 @@ sub process_alive {
 }
 
 
+
+use Symbol qw( gensym );
+
+use if $^O eq 'MSWin32', 'Win32API::File', qw( CloseHandle CreateFile GetOsFHandle OsFHandleOpen  OPEN_ALWAYS FILE_APPEND_DATA 
+  FILE_SHARE_READ FILE_SHARE_WRITE FILE_SHARE_DELETE );
+use if $^O eq 'MSWin32', 'Win32::API';
+
+use constant WIN32API_FILE_NULL => [];
+
+# Open a file for append
+# On Windows we use CreateFile with FILE_APPEND_DATA
+# to insure that writes are atomic, not interleaved
+# with writes by another processes. 
+sub open_for_append
+{
+  my ($file) = @_;
+  my $fh = gensym();
+
+  if (IS_WIN32PERL)
+  {
+    my $handle;
+    if (!($handle = CreateFile(
+        $file,
+        FILE_APPEND_DATA(),
+        FILE_SHARE_READ()|FILE_SHARE_WRITE()|FILE_SHARE_DELETE(),
+        WIN32API_FILE_NULL,
+        OPEN_ALWAYS(),# Create if doesn't exist.
+        0,
+        WIN32API_FILE_NULL,
+      )))
+    {
+      return undef;
+    }
+
+    if (!OsFHandleOpen($fh, $handle, 'wat'))
+    {
+      CloseHandle($handle);
+      return undef;
+    }
+    return $fh;
+  }
+  
+  open($fh,">>",$file) or return undef;
+  return $fh;
+}
+
+
 1;
diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl
index 8c2803f..0de4d96 100644
--- a/mysql-test/lib/mtr_io.pl
+++ b/mysql-test/lib/mtr_io.pl
@@ -21,6 +21,7 @@
 
 use strict;
 use Carp;
+use My::Platform;
 
 sub mtr_fromfile ($);
 sub mtr_tofile ($@);
@@ -45,10 +46,10 @@ sub mtr_fromfile ($) {
 
 sub mtr_tofile ($@) {
   my $file=  shift;
-
-  open(FILE,">>",$file) or mtr_error("can't open file \"$file\": $!");
-  print FILE join("", @_);
-  close FILE;
+  my $fh= open_for_append $file;
+  mtr_error("can't open file \"$file\": $!") unless defined($fh);
+  print $fh join("", @_);
+  close $fh;
 }
 
 
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index cb705d2..dd0129d 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -512,6 +512,14 @@ DROP DATABASE connected_db;
 create database `aa``bb````cc`;
 DATABASE()
 aa`bb``cc
+DATABASE()
+test
+DATABASE()
+aa`bb``cc
+DATABASE()
+test
+DATABASE()
+aa`bb``cc
 drop database `aa``bb````cc`;
 a
 >>\ndelimiter\n<<
diff --git a/mysql-test/r/mysql_not_windows.result b/mysql-test/r/mysql_not_windows.result
index d5670a1..1df62d9 100644
--- a/mysql-test/r/mysql_not_windows.result
+++ b/mysql-test/r/mysql_not_windows.result
@@ -3,3 +3,9 @@ a
 1
 
 End of tests
+1
+1
+2
+2
+X
+3
diff --git a/mysql-test/r/mysqldump-nl.result b/mysql-test/r/mysqldump-nl.result
new file mode 100644
index 0000000..6de439b
--- /dev/null
+++ b/mysql-test/r/mysqldump-nl.result
@@ -0,0 +1,126 @@
+create database `mysqltest1
+1tsetlqsym`;
+use `mysqltest1
+1tsetlqsym`;
+create table `t1
+1t` (`foobar
+raboof` int);
+create view `v1
+1v` as select * from `t1
+1t`;
+create procedure sp() select * from `v1
+1v`;
+flush tables;
+use test;
+
+--
+-- Current Database: `mysqltest1
+-- 1tsetlqsym`
+--
+
+/*!40000 DROP DATABASE IF EXISTS `mysqltest1
+1tsetlqsym`*/;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1
+1tsetlqsym` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `mysqltest1
+1tsetlqsym`;
+
+--
+-- Table structure for table `t1
+-- 1t`
+--
+
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1
+1t` (
+  `foobar
+raboof` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t1
+-- 1t`
+--
+
+--
+-- Temporary table structure for view `v1
+-- 1v`
+--
+
+SET @saved_cs_client     = @@character_set_client;
+SET character_set_client = utf8;
+/*!50001 CREATE TABLE `v1
+1v` (
+  `foobar
+raboof` tinyint NOT NULL
+) ENGINE=MyISAM */;
+SET character_set_client = @saved_cs_client;
+
+--
+-- Dumping routines for database 'mysqltest1
+-- 1tsetlqsym'
+--
+/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
+/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
+/*!50003 SET @saved_col_connection = @@collation_connection */ ;
+/*!50003 SET character_set_client  = latin1 */ ;
+/*!50003 SET character_set_results = latin1 */ ;
+/*!50003 SET collation_connection  = latin1_swedish_ci */ ;
+/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
+/*!50003 SET sql_mode              = '' */ ;
+DELIMITER ;;
+CREATE DEFINER=`root`@`localhost` PROCEDURE `sp`()
+select * from `v1
+1v` ;;
+DELIMITER ;
+/*!50003 SET sql_mode              = @saved_sql_mode */ ;
+/*!50003 SET character_set_client  = @saved_cs_client */ ;
+/*!50003 SET character_set_results = @saved_cs_results */ ;
+/*!50003 SET collation_connection  = @saved_col_connection */ ;
+
+--
+-- Current Database: `mysqltest1
+-- 1tsetlqsym`
+--
+
+USE `mysqltest1
+1tsetlqsym`;
+
+--
+-- Final view structure for view `v1
+-- 1v`
+--
+
+/*!50001 DROP TABLE IF EXISTS `v1
+1v`*/;
+/*!50001 SET @saved_cs_client          = @@character_set_client */;
+/*!50001 SET @saved_cs_results         = @@character_set_results */;
+/*!50001 SET @saved_col_connection     = @@collation_connection */;
+/*!50001 SET character_set_client      = latin1 */;
+/*!50001 SET character_set_results     = latin1 */;
+/*!50001 SET collation_connection      = latin1_swedish_ci */;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
+/*!50001 VIEW `v1
+1v` AS select `t1
+1t`.`foobar
+raboof` AS `foobar
+raboof` from `t1
+1t` */;
+/*!50001 SET character_set_client      = @saved_cs_client */;
+/*!50001 SET character_set_results     = @saved_cs_results */;
+/*!50001 SET collation_connection      = @saved_col_connection */;
+show tables from `mysqltest1
+1tsetlqsym`;
+Tables_in_mysqltest1
+1tsetlqsym
+t1
+1t
+v1
+1v
+drop database `mysqltest1
+1tsetlqsym`;
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 865c8d7..0ebef58 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -269,12 +269,6 @@ source database
 echo message echo message
 
 mysqltest: At line 1: Missing argument in exec
-1
-1
-2
-2
-X
-3
 MySQL
 "MySQL"
 MySQL: The
diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result
index 2dcfa10..c807107 100644
--- a/mysql-test/suite/plugins/r/server_audit.result
+++ b/mysql-test/suite/plugins/r/server_audit.result
@@ -8,7 +8,6 @@ server_audit_file_rotate_now	OFF
 server_audit_file_rotate_size	1000000
 server_audit_file_rotations	9
 server_audit_incl_users	
-server_audit_loc_info	
 server_audit_logging	OFF
 server_audit_mode	0
 server_audit_output_type	file
@@ -72,7 +71,6 @@ server_audit_file_rotate_now	OFF
 server_audit_file_rotate_size	1000000
 server_audit_file_rotations	9
 server_audit_incl_users	odin, root, dva, tri
-server_audit_loc_info	
 server_audit_logging	ON
 server_audit_mode	0
 server_audit_output_type	file
@@ -218,7 +216,6 @@ server_audit_file_rotate_now	OFF
 server_audit_file_rotate_size	1000000
 server_audit_file_rotations	9
 server_audit_incl_users	odin, root, dva, tri
-server_audit_loc_info	
 server_audit_logging	ON
 server_audit_mode	1
 server_audit_output_type	file
diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result
index 2dcfa10..c807107 100644
--- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result
+++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result
@@ -8,7 +8,6 @@ server_audit_file_rotate_now	OFF
 server_audit_file_rotate_size	1000000
 server_audit_file_rotations	9
 server_audit_incl_users	
-server_audit_loc_info	
 server_audit_logging	OFF
 server_audit_mode	0
 server_audit_output_type	file
@@ -72,7 +71,6 @@ server_audit_file_rotate_now	OFF
 server_audit_file_rotate_size	1000000
 server_audit_file_rotations	9
 server_audit_incl_users	odin, root, dva, tri
-server_audit_loc_info	
 server_audit_logging	ON
 server_audit_mode	0
 server_audit_output_type	file
@@ -218,7 +216,6 @@ server_audit_file_rotate_now	OFF
 server_audit_file_rotate_size	1000000
 server_audit_file_rotations	9
 server_audit_incl_users	odin, root, dva, tri
-server_audit_loc_info	
 server_audit_logging	ON
 server_audit_mode	1
 server_audit_output_type	file
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 6281bb5..d59083d 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -586,8 +586,16 @@ DROP DATABASE connected_db;
 # USE and names with backticks
 #
 --write_file $MYSQLTEST_VARDIR/tmp/backticks.sql
+\u aa`bb``cc
+SELECT DATABASE();
+USE test
+SELECT DATABASE();
 USE aa`bb``cc
 SELECT DATABASE();
+USE test
+SELECT DATABASE();
+USE `aa``bb````cc`
+SELECT DATABASE();
 EOF
 create database `aa``bb````cc`;
 --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/backticks.sql
diff --git a/mysql-test/t/mysql_not_windows.test b/mysql-test/t/mysql_not_windows.test
index 6685367..591de74 100644
--- a/mysql-test/t/mysql_not_windows.test
+++ b/mysql-test/t/mysql_not_windows.test
@@ -13,3 +13,12 @@
 
 --echo
 --echo End of tests
+
+# Multi-line exec
+exec $MYSQL \
+    test -e "select 1";
+exec $MYSQL test -e "select
+    2";
+let $query = select 3
+    as X;
+exec $MYSQL test -e "$query";
diff --git a/mysql-test/t/mysqldump-nl.test b/mysql-test/t/mysqldump-nl.test
new file mode 100644
index 0000000..311996e
--- /dev/null
+++ b/mysql-test/t/mysqldump-nl.test
@@ -0,0 +1,38 @@
+#
+# New lines in identifiers
+#
+
+# embedded server doesn't support external clients
+--source include/not_embedded.inc
+# cmd.exe doesn't like new lines on the command line
+--source include/not_windows.inc
+
+create database `mysqltest1
+1tsetlqsym`;
+use `mysqltest1
+1tsetlqsym`;
+
+create table `t1
+1t` (`foobar
+raboof` int);
+create view `v1
+1v` as select * from `t1
+1t`;
+
+create procedure sp() select * from `v1
+1v`;
+
+flush tables;
+use test;
+
+exec $MYSQL_DUMP --compact --comment --routines --add-drop-database --databases 'mysqltest1
+1tsetlqsym';
+
+exec $MYSQL_DUMP --compact --comment --routines --add-drop-database --databases 'mysqltest1
+1tsetlqsym' | $MYSQL;
+
+show tables from `mysqltest1
+1tsetlqsym`;
+
+drop database `mysqltest1
+1tsetlqsym`;
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index ffbec36..6470ede 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -741,15 +741,6 @@ echo ;
 --error 1
 --exec echo "--exec " | $MYSQL_TEST 2>&1
 
-# Multi-line exec
-exec $MYSQL
-    test -e "select 1";
-exec $MYSQL test -e "select
-    2";
-let $query = select 3
-    as X;
-exec $MYSQL test -e "$query";
-
 # ----------------------------------------------------------------------------
 # Test let command
 # ----------------------------------------------------------------------------
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index 52f6164..cc10193 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -102,6 +102,7 @@ static FILE *my_win_freopen(const char *path, const char *mode, FILE *stream)
   HANDLE osfh;
 
   DBUG_ASSERT(path && stream);
+  DBUG_ASSERT(strchr(mode, 'a')); /* We use FILE_APPEND_DATA below */
 
   /* Services don't have stdout/stderr on Windows, so _fileno returns -1. */
   if (fd < 0)
@@ -112,15 +113,14 @@ static FILE *my_win_freopen(const char *path, const char *mode, FILE *stream)
     fd= _fileno(stream);
   }
 
-  if ((osfh= CreateFile(path, GENERIC_READ | GENERIC_WRITE,
+  if ((osfh= CreateFile(path, GENERIC_READ | FILE_APPEND_DATA,
                         FILE_SHARE_READ | FILE_SHARE_WRITE |
                         FILE_SHARE_DELETE, NULL,
                         OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
                         NULL)) == INVALID_HANDLE_VALUE)
     return NULL;
 
-  if ((handle_fd= _open_osfhandle((intptr_t)osfh,
-                                  _O_APPEND | _O_TEXT)) == -1)
+  if ((handle_fd= _open_osfhandle((intptr_t)osfh, _O_TEXT)) == -1)
   {
     CloseHandle(osfh);
     return NULL;
diff --git a/plugin/feedback/utils.cc b/plugin/feedback/utils.cc
index f6fcb3d..cff19c9 100644
--- a/plugin/feedback/utils.cc
+++ b/plugin/feedback/utils.cc
@@ -43,7 +43,11 @@ static const char *get_os_version_name(OSVERSIONINFOEX *ver)
 {
   DWORD major = ver->dwMajorVersion;
   DWORD minor = ver->dwMinorVersion;
-
+  if (major == 10 && minor == 0)
+  {
+    return (ver->wProductType == VER_NT_WORKSTATION) ?
+      "Windows 10" : "Windows Server 2016";
+  }
   if (major == 6 && minor == 3)
   {
     return (ver->wProductType == VER_NT_WORKSTATION)?
@@ -102,7 +106,12 @@ static int uname(struct utsname *buf)
   if(version_str && version_str[0])
     sprintf(buf->version, "%s %s",version_str, ver.szCSDVersion);
   else
-    sprintf(buf->version, "%s", ver.szCSDVersion);
+  {
+    /* Fallback for unknown versions, e.g "Windows <major_ver>.<minor_ver>" */
+    sprintf(buf->version, "Windows %d.%d%s",
+      ver.dwMajorVersion, ver.dwMinorVersion,
+      (ver.wProductType == VER_NT_WORKSTATION ? "" : " Server"));
+  }
 
 #ifdef _WIN64
   strcpy(buf->machine, "x64");
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index 30b7cdb..95150c8 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -429,9 +429,8 @@ static MYSQL_SYSVAR_UINT(query_log_limit, query_log_limit,
 char locinfo_ini_value[sizeof(struct connection_info)+4];
 
 static MYSQL_THDVAR_STR(loc_info,
-                        PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC,
-                        "Auxiliary info.", NULL, NULL,
-                        locinfo_ini_value);
+                        PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_MEMALLOC,
+                        "Internal info", NULL, NULL, locinfo_ini_value);
 
 static const char *syslog_facility_names[]=
 {
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 7f18abb..7cadce7 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -620,6 +620,10 @@ else
   logging=syslog
 fi
 
+# close stdout and stderr, everything goes to $logging now
+exec 1>&-
+exec 2>&-
+
 USER_OPTION=""
 if test -w / -o "$USER" = "root"
 then
@@ -650,7 +654,7 @@ if [ ! -d $mysql_unix_port_dir ]
 then
   if ! `mkdir -p $mysql_unix_port_dir`
   then
-    echo "Fatal error Can't create database directory '$mysql_unix_port'"
+    log_error "Fatal error Can't create database directory '$mysql_unix_port'"
     exit 1
   fi
   chown $user $mysql_unix_port_dir
diff --git a/sql/log.cc b/sql/log.cc
index da45a84..bb8f06c 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2863,7 +2863,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
       if (! write_error)
       {
         write_error= 1;
-        sql_print_error(ER(ER_ERROR_ON_WRITE), name, error);
+        sql_print_error(ER(ER_ERROR_ON_WRITE), name, tmp_errno);
       }
     }
   }
diff --git a/sql/parse_file.h b/sql/parse_file.h
index 2a0266e..83a8eab 100644
--- a/sql/parse_file.h
+++ b/sql/parse_file.h
@@ -42,9 +42,9 @@ enum file_opt_type {
 
 struct File_option
 {
-  LEX_STRING name;		/**< Name of the option */
-  int offset;			/**< offset to base address of value */
-  file_opt_type type;		/**< Option type */
+  LEX_STRING name;              /**< Name of the option */
+  my_ptrdiff_t offset;          /**< offset to base address of value */
+  file_opt_type type;           /**< Option type */
 };
 
 
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index c8c8c8b..2ec67a8 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -2756,6 +2756,22 @@ static st_bookmark *find_bookmark(const char *plugin, const char *name,
 }
 
 
+static size_t var_storage_size(int flags)
+{
+  switch (flags & PLUGIN_VAR_TYPEMASK) {
+  case PLUGIN_VAR_BOOL:         return sizeof(my_bool);
+  case PLUGIN_VAR_INT:          return sizeof(int);
+  case PLUGIN_VAR_LONG:         return sizeof(long);
+  case PLUGIN_VAR_ENUM:         return sizeof(long);
+  case PLUGIN_VAR_LONGLONG:     return sizeof(ulonglong);
+  case PLUGIN_VAR_SET:          return sizeof(ulonglong);
+  case PLUGIN_VAR_STR:          return sizeof(char*);
+  case PLUGIN_VAR_DOUBLE:       return sizeof(double);
+  default: DBUG_ASSERT(0);      return 0;
+  }
+}
+
+
 /*
   returns a bookmark for thd-local variables, creating if neccessary.
   returns null for non thd-local variables.
@@ -2764,39 +2780,13 @@ static st_bookmark *find_bookmark(const char *plugin, const char *name,
 static st_bookmark *register_var(const char *plugin, const char *name,
                                  int flags)
 {
-  uint length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size;
+  uint length= strlen(plugin) + strlen(name) + 3, size, offset, new_size;
   st_bookmark *result;
   char *varname, *p;
 
-  if (!(flags & PLUGIN_VAR_THDLOCAL))
-    return NULL;
-
-  switch (flags & PLUGIN_VAR_TYPEMASK) {
-  case PLUGIN_VAR_BOOL:
-    size= sizeof(my_bool);
-    break;
-  case PLUGIN_VAR_INT:
-    size= sizeof(int);
-    break;
-  case PLUGIN_VAR_LONG:
-  case PLUGIN_VAR_ENUM:
-    size= sizeof(long);
-    break;
-  case PLUGIN_VAR_LONGLONG:
-  case PLUGIN_VAR_SET:
-    size= sizeof(ulonglong);
-    break;
-  case PLUGIN_VAR_STR:
-    size= sizeof(char*);
-    break;
-  case PLUGIN_VAR_DOUBLE:
-    size= sizeof(double);
-    break;
-  default:
-    DBUG_ASSERT(0);
-    return NULL;
-  };
+  DBUG_ASSERT(flags & PLUGIN_VAR_THDLOCAL);
 
+  size= var_storage_size(flags);
   varname= ((char*) my_alloca(length));
   strxmov(varname + 1, plugin, "_", name, NullS);
   for (p= varname + 1; *p; p++)
@@ -3005,25 +2995,17 @@ void sync_dynamic_session_variables(THD* thd, bool global_lock)
   */
   for (idx= 0; idx < bookmark_hash.records; idx++)
   {
-    sys_var_pluginvar *pi;
-    sys_var *var;
     st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx);
 
     if (v->version <= thd->variables.dynamic_variables_version)
       continue; /* already in thd->variables */
 
-    if (!(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
-        !(pi= var->cast_pluginvar()) ||
-        v->key[0] != plugin_var_bookmark_key(pi->plugin_var->flags))
-      continue;
-
     /* Here we do anything special that may be required of the data types */
 
-    if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
-        pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
+    if ((v->key[0] & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
+         v->key[0] & BOOKMARK_MEMALLOC)
     {
-      int offset= ((thdvar_str_t *)(pi->plugin_var))->offset;
-      char **pp= (char**) (thd->variables.dynamic_variables_ptr + offset);
+      char **pp= (char**) (thd->variables.dynamic_variables_ptr + v->offset);
       if (*pp)
         *pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
     }
@@ -3284,69 +3266,58 @@ bool sys_var_pluginvar::session_update(THD *thd, set_var *var)
   return false;
 }
 
-bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
+static const void *var_def_ptr(st_mysql_sys_var *pv)
 {
-  DBUG_ASSERT(!is_readonly());
-  mysql_mutex_assert_owner(&LOCK_global_system_variables);
-
-  void *tgt= real_value_ptr(thd, var->type);
-  const void *src= &var->save_result;
-
-  if (!var->value)
-  {
-    switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) {
+    switch (pv->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) {
     case PLUGIN_VAR_INT:
-      src= &((sysvar_uint_t*) plugin_var)->def_val;
-      break;
+      return &((sysvar_uint_t*) pv)->def_val;
     case PLUGIN_VAR_LONG:
-      src= &((sysvar_ulong_t*) plugin_var)->def_val;
-      break;
+      return &((sysvar_ulong_t*) pv)->def_val;
     case PLUGIN_VAR_LONGLONG:
-      src= &((sysvar_ulonglong_t*) plugin_var)->def_val;
-      break;
+      return &((sysvar_ulonglong_t*) pv)->def_val;
     case PLUGIN_VAR_ENUM:
-      src= &((sysvar_enum_t*) plugin_var)->def_val;
-      break;
+      return &((sysvar_enum_t*) pv)->def_val;
     case PLUGIN_VAR_SET:
-      src= &((sysvar_set_t*) plugin_var)->def_val;
-      break;
+      return &((sysvar_set_t*) pv)->def_val;
     case PLUGIN_VAR_BOOL:
-      src= &((sysvar_bool_t*) plugin_var)->def_val;
-      break;
+      return &((sysvar_bool_t*) pv)->def_val;
     case PLUGIN_VAR_STR:
-      src= &((sysvar_str_t*) plugin_var)->def_val;
-      break;
+      return &((sysvar_str_t*) pv)->def_val;
     case PLUGIN_VAR_DOUBLE:
-      src= &((sysvar_double_t*) plugin_var)->def_val;
-      break;
+      return &((sysvar_double_t*) pv)->def_val;
     case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
-      src= &((thdvar_uint_t*) plugin_var)->def_val;
-      break;
+      return &((thdvar_uint_t*) pv)->def_val;
     case PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL:
-      src= &((thdvar_ulong_t*) plugin_var)->def_val;
-      break;
+      return &((thdvar_ulong_t*) pv)->def_val;
     case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL:
-      src= &((thdvar_ulonglong_t*) plugin_var)->def_val;
-      break;
+      return &((thdvar_ulonglong_t*) pv)->def_val;
     case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
-      src= &((thdvar_enum_t*) plugin_var)->def_val;
-      break;
+      return &((thdvar_enum_t*) pv)->def_val;
     case PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL:
-      src= &((thdvar_set_t*) plugin_var)->def_val;
-      break;
+      return &((thdvar_set_t*) pv)->def_val;
     case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
-      src= &((thdvar_bool_t*) plugin_var)->def_val;
-      break;
+      return &((thdvar_bool_t*) pv)->def_val;
     case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
-      src= &((thdvar_str_t*) plugin_var)->def_val;
-      break;
+      return &((thdvar_str_t*) pv)->def_val;
     case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL:
-      src= &((thdvar_double_t*) plugin_var)->def_val;
-      break;
+      return &((thdvar_double_t*) pv)->def_val;
     default:
       DBUG_ASSERT(0);
+      return NULL;
     }
-  }
+}
+
+
+bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
+{
+  DBUG_ASSERT(!is_readonly());
+  mysql_mutex_assert_owner(&LOCK_global_system_variables);
+
+  void *tgt= real_value_ptr(thd, var->type);
+  const void *src= &var->save_result;
+
+  if (!var->value)
+    src= var_def_ptr(plugin_var);
 
   plugin_var->update(thd, plugin_var, tgt, src);
   return false;
@@ -3713,7 +3684,18 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
       *(int*)(opt + 1)= offset= v->offset;
 
       if (opt->flags & PLUGIN_VAR_NOCMDOPT)
+      {
+        char *val= global_system_variables.dynamic_variables_ptr + offset;
+        if (((opt->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) &&
+             (opt->flags & PLUGIN_VAR_MEMALLOC))
+        {
+          char *def_val= *(char**)var_def_ptr(opt);
+          *(char**)val= def_val ? my_strdup(def_val, MYF(0)) : NULL;
+        }
+        else
+          memcpy(val, var_def_ptr(opt), var_storage_size(opt->flags));
         continue;
+      }
 
       optname= (char*) memdup_root(mem_root, v->key + 1, 
                                    (optnamelen= v->name_len) + 1);
@@ -3912,9 +3894,10 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
         *str->value= strdup_root(mem_root, *str->value);
     }
 
+    var= find_bookmark(plugin_name.str, o->name, o->flags);
     if (o->flags & PLUGIN_VAR_NOSYSVAR)
       continue;
-    if ((var= find_bookmark(plugin_name.str, o->name, o->flags)))
+    if (var)
       v= new (mem_root) sys_var_pluginvar(&chain, var->key + 1, o, tmp);
     else
     {
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index a9e3bfe..0c42936 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -76,7 +76,7 @@ btr_corruption_report(
 			       buf_block_get_zip_size(block),
 			       BUF_PAGE_PRINT_NO_CRASH);
 	}
-	buf_page_print(buf_block_get_frame_fast(block), 0, 0);
+	buf_page_print(buf_nonnull_block_get_frame(block), 0, 0);
 }
 
 #ifndef UNIV_HOTBACKUP
@@ -1077,7 +1077,7 @@ btr_get_size(
 	SRV_CORRUPT_TABLE_CHECK(root,
 	{
 		mtr_commit(mtr);
-		return(0);
+		return(ULINT_UNDEFINED);
 	});
 
 	if (flag == BTR_N_LEAF_PAGES) {
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index d5da382..66fcc27 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -469,6 +469,19 @@ innobase_is_fake_change(
 	THD*		thd) __attribute__((unused));	/*!< in: MySQL thread handle of the user for
 				  whom the transaction is being committed */
 
+/** Get the list of foreign keys referencing a specified table
+table.
+ at param thd		The thread handle
+ at param path		Path to the table
+ at param f_key_list[out]	The list of foreign keys
+
+ at return error code or zero for success */
+static
+int
+innobase_get_parent_fk_list(
+	THD*			thd,
+	const char*		path,
+	List<FOREIGN_KEY_INFO>*	f_key_list) __attribute__((unused));
 
 /******************************************************************//**
 Maps a MySQL trx isolation level code to the InnoDB isolation level code
@@ -10008,7 +10021,14 @@ ha_innobase::check(
 
 		prebuilt->select_lock_type = LOCK_NONE;
 
-		if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) {
+		bool check_result
+			= row_check_index_for_mysql(prebuilt, index, &n_rows);
+		DBUG_EXECUTE_IF(
+			"dict_set_index_corrupted",
+			if (!(index->type & DICT_CLUSTERED)) {
+				check_result = false;
+			});
+		if (!check_result) {
 			innobase_format_name(
 				index_name, sizeof index_name,
 				index->name, TRUE);
@@ -10344,6 +10364,73 @@ get_foreign_key_info(
 	return(pf_key_info);
 }
 
+/** Get the list of foreign keys referencing a specified table
+table.
+ at param thd		The thread handle
+ at param path		Path to the table
+ at param f_key_list[out]	The list of foreign keys */
+static
+void
+fill_foreign_key_list(THD* thd,
+		      const dict_table_t* table,
+		      List<FOREIGN_KEY_INFO>* f_key_list)
+{
+	ut_ad(mutex_own(&dict_sys->mutex));
+
+	for (dict_foreign_t* foreign
+		     = UT_LIST_GET_FIRST(table->referenced_list);
+	     foreign != NULL;
+	     foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
+
+		FOREIGN_KEY_INFO* pf_key_info
+			= get_foreign_key_info(thd, foreign);
+		if (pf_key_info) {
+			f_key_list->push_back(pf_key_info);
+		}
+	}
+}
+
+/** Get the list of foreign keys referencing a specified table
+table.
+ at param thd		The thread handle
+ at param path		Path to the table
+ at param f_key_list[out]	The list of foreign keys
+
+ at return error code or zero for success */
+static
+int
+innobase_get_parent_fk_list(
+	THD*			thd,
+	const char*		path,
+	List<FOREIGN_KEY_INFO>*	f_key_list)
+{
+	ut_a(strlen(path) <= FN_REFLEN);
+	char	norm_name[FN_REFLEN + 1];
+	normalize_table_name(norm_name, path);
+
+	trx_t*	parent_trx = check_trx_exists(thd);
+	parent_trx->op_info = "getting list of referencing foreign keys";
+	trx_search_latch_release_if_reserved(parent_trx);
+
+	mutex_enter(&dict_sys->mutex);
+
+	dict_table_t*	table
+		= dict_table_get_low(norm_name,
+				     static_cast<dict_err_ignore_t>(
+					     DICT_ERR_IGNORE_INDEX_ROOT
+					     | DICT_ERR_IGNORE_CORRUPT));
+	if (!table) {
+		mutex_exit(&dict_sys->mutex);
+		return(HA_ERR_NO_SUCH_TABLE);
+	}
+
+	fill_foreign_key_list(thd, table, f_key_list);
+
+	mutex_exit(&dict_sys->mutex);
+	parent_trx->op_info = "";
+	return(0);
+}
+
 /*******************************************************************//**
 Gets the list of foreign keys in this table.
 @return always 0, that is, always succeeds */
@@ -10392,9 +10479,6 @@ ha_innobase::get_parent_foreign_key_list(
 	THD*			thd,		/*!< in: user thread handle */
 	List<FOREIGN_KEY_INFO>*	f_key_list)	/*!< out: foreign key list */
 {
-	FOREIGN_KEY_INFO*	pf_key_info;
-	dict_foreign_t*		foreign;
-
 	ut_a(prebuilt != NULL);
 	update_thd(ha_thd());
 
@@ -10403,16 +10487,7 @@ ha_innobase::get_parent_foreign_key_list(
 	trx_search_latch_release_if_reserved(prebuilt->trx);
 
 	mutex_enter(&(dict_sys->mutex));
-
-	for (foreign = UT_LIST_GET_FIRST(prebuilt->table->referenced_list);
-	     foreign != NULL;
-	     foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
-		pf_key_info = get_foreign_key_info(thd, foreign);
-		if (pf_key_info) {
-			f_key_list->push_back(pf_key_info);
-		}
-	}
-
+	fill_foreign_key_list(thd, prebuilt->table, f_key_list);
 	mutex_exit(&(dict_sys->mutex));
 
 	prebuilt->trx->op_info = "";
@@ -12817,7 +12892,6 @@ innodb_track_changed_pages_validate(
 						for update function */
 	struct st_mysql_value*		value)	/*!< in: incoming bool */
 {
-	static bool     enabled_on_startup = false;
 	long long	intbuf = 0;
 
 	if (value->val_int(value, &intbuf)) {
@@ -12825,8 +12899,7 @@ innodb_track_changed_pages_validate(
 		return 1;
 	}
 
-	if (srv_track_changed_pages || enabled_on_startup) {
-		enabled_on_startup = true;
+	if (srv_redo_log_thread_started) {
 		*reinterpret_cast<ulong*>(save)
 			= static_cast<ulong>(intbuf);
 		return 0;
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index 701e820..23692c9 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -1110,10 +1110,20 @@ buf_block_get_frame(
 /*================*/
 	const buf_block_t*	block)	/*!< in: pointer to the control block */
 	__attribute__((pure));
-# define buf_block_get_frame_fast(block) buf_block_get_frame(block)
+
+/*********************************************************************//**
+Gets a pointer to the memory frame of a block, where block is known not to be
+NULL.
+ at return	pointer to the frame */
+UNIV_INLINE
+buf_frame_t*
+buf_nonnull_block_get_frame(
+	const buf_block_t*	block)	/*!< in: pointer to the control block */
+	__attribute__((pure));
+
 #else /* UNIV_DEBUG */
 # define buf_block_get_frame(block) (block ? (block)->frame : 0)
-# define buf_block_get_frame_fast(block) (block)->frame
+# define buf_nonnull_block_get_frame(block) ((block)->frame)
 #endif /* UNIV_DEBUG */
 /*********************************************************************//**
 Gets the space id of a block.
diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic
index 1d79248..f62964d 100644
--- a/storage/xtradb/include/buf0buf.ic
+++ b/storage/xtradb/include/buf0buf.ic
@@ -718,6 +718,19 @@ buf_block_get_frame(
 {
 	SRV_CORRUPT_TABLE_CHECK(block, return(0););
 
+	return(buf_nonnull_block_get_frame(block));
+}
+
+/*********************************************************************//**
+Gets a pointer to the memory frame of a block, where block is known not to be
+NULL.
+ at return	pointer to the frame */
+UNIV_INLINE
+buf_frame_t*
+buf_nonnull_block_get_frame(
+/*========================*/
+	const buf_block_t*	block)	/*!< in: pointer to the control block */
+{
 	switch (buf_block_get_state(block)) {
 	case BUF_BLOCK_ZIP_FREE:
 	case BUF_BLOCK_ZIP_PAGE:
@@ -739,6 +752,7 @@ buf_block_get_frame(
 ok:
 	return((buf_frame_t*) block->frame);
 }
+
 #endif /* UNIV_DEBUG */
 
 /*********************************************************************//**
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 3b94247..6eee44c 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -78,6 +78,11 @@ extern os_event_t	srv_checkpoint_completed_event;
 that the (slow) shutdown may proceed */
 extern os_event_t	srv_redo_log_thread_finished_event;
 
+/** Whether the redo log tracker thread has been started. Does not take into
+account whether the tracking is currently enabled (see srv_track_changed_pages
+for that) */
+extern my_bool		srv_redo_log_thread_started;
+
 /* If the last data file is auto-extended, we add this many pages to it
 at a time */
 #define SRV_AUTO_EXTEND_INCREMENT	\
@@ -145,6 +150,9 @@ extern char*	srv_doublewrite_file;
 
 extern ibool	srv_recovery_stats;
 
+/** Whether the redo log tracking is currently enabled. Note that it is
+possible for the log tracker thread to be running and the tracking to be
+disabled */
 extern my_bool		srv_track_changed_pages;
 extern ib_uint64_t	srv_max_bitmap_file_size;
 
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 9d4b3e5..7c5fdff 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -64,10 +64,10 @@ component, i.e. we show M.N.P as M.N */
 	(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
 
 #ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 38.0
+#define PERCONA_INNODB_VERSION 38.3
 #endif
 
-#define INNODB_VERSION_STR	"5.5.49-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION)
+#define INNODB_VERSION_STR	"5.5.52-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION)
 
 #define REFMAN "http://dev.mysql.com/doc/refman/"	\
 	IB_TO_STR(MYSQL_MAJOR_VERSION) "."		\
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c
index bc208f4..e5063e9 100644
--- a/storage/xtradb/log/log0log.c
+++ b/storage/xtradb/log/log0log.c
@@ -3420,7 +3420,8 @@ logs_empty_and_mark_files_at_shutdown(void)
 	algorithm only works if the server is idle at shutdown */
 
 	srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
-	os_event_set(srv_shutdown_event);
+
+	srv_wake_purge_thread();
 loop:
 	os_thread_sleep(100000);
 
@@ -3594,7 +3595,7 @@ loop:
 		srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
 		/* Wake the log tracking thread which will then immediatelly
 		quit because of srv_shutdown_state value */
-		if (srv_track_changed_pages) {
+		if (srv_redo_log_thread_started) {
 			os_event_set(srv_checkpoint_completed_event);
 			os_event_wait(srv_redo_log_thread_finished_event);
 		}
@@ -3671,7 +3672,7 @@ loop:
 	srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
 
 	/* Signal the log following thread to quit */
-	if (srv_track_changed_pages) {
+	if (srv_redo_log_thread_started) {
 		os_event_set(srv_checkpoint_completed_event);
 	}
 
@@ -3695,7 +3696,7 @@ loop:
 
 	fil_flush_file_spaces(FIL_TABLESPACE);
 
-	if (srv_track_changed_pages) {
+	if (srv_redo_log_thread_started) {
 		os_event_wait(srv_redo_log_thread_finished_event);
 	}
 
diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c
index d012748..fa2c8b8 100644
--- a/storage/xtradb/log/log0online.c
+++ b/storage/xtradb/log/log0online.c
@@ -1813,7 +1813,7 @@ log_online_purge_changed_page_bitmaps(
 		lsn = IB_ULONGLONG_MAX;
 	}
 
-	if (srv_track_changed_pages) {
+	if (srv_redo_log_thread_started) {
 		/* User requests might happen with both enabled and disabled
 		tracking */
 		mutex_enter(&log_bmp_sys->mutex);
@@ -1821,13 +1821,13 @@ log_online_purge_changed_page_bitmaps(
 
 	if (!log_online_setup_bitmap_file_range(&bitmap_files, 0,
 						IB_ULONGLONG_MAX)) {
-		if (srv_track_changed_pages) {
+		if (srv_redo_log_thread_started) {
 			mutex_exit(&log_bmp_sys->mutex);
 		}
 		return TRUE;
 	}
 
-	if (srv_track_changed_pages && lsn > log_bmp_sys->end_lsn) {
+	if (srv_redo_log_thread_started && lsn > log_bmp_sys->end_lsn) {
 		/* If we have to delete the current output file, close it
 		first. */
 		os_file_close(log_bmp_sys->out.file);
@@ -1858,7 +1858,7 @@ log_online_purge_changed_page_bitmaps(
 		}
 	}
 
-	if (srv_track_changed_pages) {
+	if (srv_redo_log_thread_started) {
 		if (lsn > log_bmp_sys->end_lsn) {
 			ib_uint64_t	new_file_lsn;
 			if (lsn == IB_ULONGLONG_MAX) {
@@ -1869,9 +1869,7 @@ log_online_purge_changed_page_bitmaps(
 				new_file_lsn = log_bmp_sys->end_lsn;
 			}
 			if (!log_online_rotate_bitmap_file(new_file_lsn)) {
-				/* If file create failed, signal the log
-				tracking thread to quit next time it wakes
-				up.  */
+				/* If file create failed, stop log tracking */
 				srv_track_changed_pages = FALSE;
 			}
 		}
diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c
index 1e670d5..aea83c9 100644
--- a/storage/xtradb/log/log0recv.c
+++ b/storage/xtradb/log/log0recv.c
@@ -3022,7 +3022,7 @@ recv_recovery_from_checkpoint_start_func(
 	ib_uint64_t	checkpoint_lsn;
 	ib_uint64_t	checkpoint_no;
 	ib_uint64_t	old_scanned_lsn;
-	ib_uint64_t	group_scanned_lsn= 0;
+	ib_uint64_t	group_scanned_lsn = 0;
 	ib_uint64_t	contiguous_lsn;
 #ifdef UNIV_LOG_ARCHIVE
 	ib_uint64_t	archived_lsn;
diff --git a/storage/xtradb/mach/mach0data.c b/storage/xtradb/mach/mach0data.c
index 95b135b..00378f0 100644
--- a/storage/xtradb/mach/mach0data.c
+++ b/storage/xtradb/mach/mach0data.c
@@ -56,7 +56,18 @@ mach_parse_compressed(
 		*val = flag;
 		return(ptr + 1);
 
-	} else if (flag < 0xC0UL) {
+	}
+
+	/* Workaround GCC bug
+	https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673:
+	the compiler moves mach_read_from_4 right to the beginning of the
+	function, causing and out-of-bounds read if we are reading a short
+	integer close to the end of buffer. */
+#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__)
+	asm volatile("": : :"memory");
+#endif
+
+	if (flag < 0xC0UL) {
 		if (end_ptr < ptr + 2) {
 			return(NULL);
 		}
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index 90a1291..31a8b30 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -180,6 +180,9 @@ UNIV_INTERN char*	srv_doublewrite_file = NULL;
 
 UNIV_INTERN ibool	srv_recovery_stats = FALSE;
 
+/** Whether the redo log tracking is currently enabled. Note that it is
+possible for the log tracker thread to be running and the tracking to be
+disabled */
 UNIV_INTERN my_bool	srv_track_changed_pages = FALSE;
 
 UNIV_INTERN ib_uint64_t	srv_max_bitmap_file_size = 100 * 1024 * 1024;
@@ -830,6 +833,11 @@ UNIV_INTERN os_event_t	srv_checkpoint_completed_event;
 
 UNIV_INTERN os_event_t	srv_redo_log_thread_finished_event;
 
+/** Whether the redo log tracker thread has been started. Does not take into
+account whether the tracking is currently enabled (see srv_track_changed_pages
+for that) */
+UNIV_INTERN my_bool	srv_redo_log_thread_started = FALSE;
+
 UNIV_INTERN srv_sys_t*	srv_sys	= NULL;
 
 /* padding to prevent other memory update hotspots from residing on
@@ -3201,18 +3209,15 @@ srv_redo_log_follow_thread(
 #endif
 
 	my_thread_init();
+	srv_redo_log_thread_started = TRUE;
 
 	do {
 		os_event_wait(srv_checkpoint_completed_event);
 		os_event_reset(srv_checkpoint_completed_event);
 
-#ifdef UNIV_DEBUG
-		if (!srv_track_changed_pages) {
-			continue;
-		}
-#endif
+		if (srv_track_changed_pages
+		    && srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) {
 
-		if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) {
 			if (!log_online_follow_redo_log()) {
 				/* TODO: sync with I_S log tracking status? */
 				fprintf(stderr,
@@ -3228,6 +3233,7 @@ srv_redo_log_follow_thread(
 	srv_track_changed_pages = FALSE;
 	log_online_read_shutdown();
 	os_event_set(srv_redo_log_thread_finished_event);
+	srv_redo_log_thread_started = FALSE; /* Defensive, not required */
 
 	my_thread_end();
 	os_thread_exit(NULL);
@@ -3349,7 +3355,7 @@ srv_master_do_purge(void)
 
 	ut_ad(!mutex_own(&kernel_mutex));
 
-	ut_a(srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0));
+	ut_a(srv_n_purge_threads == 0);
 
 	do {
 		/* Check for shutdown and change in purge config. */
@@ -3875,7 +3881,7 @@ retry_flush_batch:
 	/* Flush logs if needed */
 	srv_sync_log_buffer_in_background();
 
-	if (srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0)) {
+	if (srv_n_purge_threads == 0) {
 		srv_main_thread_op_info = "master purging";
 
 		srv_master_do_purge();
@@ -3953,7 +3959,7 @@ background_loop:
 		}
 	}
 
-	if (srv_n_purge_threads == 0 || (srv_shutdown_state > 0 && srv_n_threads_active[SRV_WORKER] == 0)) {
+	if (srv_n_purge_threads == 0) {
 		srv_main_thread_op_info = "master purging";
 
 		srv_master_do_purge();
@@ -4170,9 +4176,10 @@ srv_purge_thread(
 	        We peek at the history len without holding any mutex
 		because in the worst case we will end up waiting for
 		the next purge event. */
-		if (trx_sys->rseg_history_len < srv_purge_batch_size
-		    || (n_total_purged == 0
-			&& retries >= TRX_SYS_N_RSEGS)) {
+		if (srv_shutdown_state == SRV_SHUTDOWN_NONE
+		    && (trx_sys->rseg_history_len < srv_purge_batch_size
+			|| (n_total_purged == 0
+			    && retries >= TRX_SYS_N_RSEGS))) {
 
 			mutex_enter(&kernel_mutex);
 
@@ -4187,8 +4194,12 @@ srv_purge_thread(
 
 		/* Check for shutdown and whether we should do purge at all. */
 		if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
-		    || srv_shutdown_state != 0
-		    || srv_fast_shutdown) {
+		    || (srv_shutdown_state != SRV_SHUTDOWN_NONE
+			&& srv_fast_shutdown)
+		    || (srv_shutdown_state != SRV_SHUTDOWN_NONE
+			&& srv_fast_shutdown == 0
+			&& n_total_purged == 0
+			&& retries >= TRX_SYS_N_RSEGS)) {
 
 			break;
 		}
@@ -4211,6 +4222,9 @@ srv_purge_thread(
 
 		srv_sync_log_buffer_in_background();
 
+		if (srv_shutdown_state != SRV_SHUTDOWN_NONE)
+			continue;
+
 		cur_time = ut_time_ms();
 		sig_count = os_event_reset(srv_shutdown_event);
 		if (next_itr_time > cur_time) {
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
index e5c8814..d4fff33 100644
--- a/support-files/mysql.server.sh
+++ b/support-files/mysql.server.sh
@@ -308,7 +308,7 @@ case "$mode" in
     then
       # Give extra arguments to mysqld with the my.cnf file. This script
       # may be overwritten at next upgrade.
-      $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &
+      $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args &
       wait_for_ready; return_value=$?
 
       # Make lock for RedHat / SuSE
diff --git a/tests/async_queries.c b/tests/async_queries.c
index 75229ee..c91edf5 100644
--- a/tests/async_queries.c
+++ b/tests/async_queries.c
@@ -425,7 +425,7 @@ main(int argc, char *argv[])
 
   event_dispatch();
 
-  free(sds);
+  my_free(sds);
 
   mysql_library_end();
 

-- 
Alioth's hooks/post-receive on /srv/git.debian.org/git/pkg-mysql/mariadb-5.5.git



More information about the Pkg-mysql-commits mailing list