From: Date: February 10 2009 9:37am Subject: bzr commit into mysql-5.1-bugteam branch (ramil:2796) Bug#40757 List-Archive: http://lists.mysql.com/commits/65700 X-Bug: 40757 Message-Id: <0KEU0020WDATRI20@fe-emea-10.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7BIT #At file:///home/ram/mysql/b40757-5.1-bugteam/ based on revid:davi.arnaut@stripped 2796 Ramil Kalimullin 2009-02-10 Fix for bug #40757: Starting server on Windows with innodb_flush_method=wrong_value causes crash Problem: after a failed plugin initialization, incompletely initialized data remained in the plugin and handlerton data structures. These were used later and caused the crash. Fix: clean-up plugin related data if initialization failed. Note: no test case added, hand tested. modified: sql/handler.cc per-file messages: sql/handler.cc Fix for bug #40757: Starting server on Windows with innodb_flush_method=wrong_value causes crash - free allocated hton and set plugin->data (pointing to handlerton) to NULL if plugin->init() fails, as we use it as a sign that ha_initialize_handlerton() is failed, which is used in ha_finalize_handlerton(). - do the same if there's no free slot for a plugin in the hton2plugin[] array or there are too many storage engines. - call plugin->deinit() in such cases as we successfully called plugin->init() before. === modified file 'sql/handler.cc' --- a/sql/handler.cc 2009-01-30 13:44:49 +0000 +++ b/sql/handler.cc 2009-02-10 08:37:27 +0000 @@ -429,14 +429,11 @@ int ha_initialize_handlerton(st_plugin_i MYF(MY_WME | MY_ZEROFILL)); /* Historical Requirement */ plugin->data= hton; // shortcut for the future - if (plugin->plugin->init) + if (plugin->plugin->init && plugin->plugin->init(hton)) { - if (plugin->plugin->init(hton)) - { - sql_print_error("Plugin '%s' init function returned error.", - plugin->name.str); - goto err; - } + sql_print_error("Plugin '%s' init function returned error.", + plugin->name.str); + goto err; } /* @@ -463,17 +460,13 @@ int ha_initialize_handlerton(st_plugin_i if (idx == (int) DB_TYPE_DEFAULT) { sql_print_warning("Too many storage engines!"); - DBUG_RETURN(1); + goto err_deinit; } if (hton->db_type != DB_TYPE_UNKNOWN) sql_print_warning("Storage engine '%s' has conflicting typecode. " "Assigning value %d.", plugin->plugin->name, idx); hton->db_type= (enum legacy_db_type) idx; } - installed_htons[hton->db_type]= hton; - tmp= hton->savepoint_offset; - hton->savepoint_offset= savepoint_alloc_size; - savepoint_alloc_size+= tmp; /* In case a plugin is uninstalled and re-installed later, it should @@ -494,11 +487,14 @@ int ha_initialize_handlerton(st_plugin_i { sql_print_error("Too many plugins loaded. Limit is %lu. " "Failed on '%s'", (ulong) MAX_HA, plugin->name.str); - goto err; + goto err_deinit; } hton->slot= total_ha++; } - + installed_htons[hton->db_type]= hton; + tmp= hton->savepoint_offset; + hton->savepoint_offset= savepoint_alloc_size; + savepoint_alloc_size+= tmp; hton2plugin[hton->slot]=plugin; if (hton->prepare) total_ha_2pc++; @@ -530,7 +526,18 @@ int ha_initialize_handlerton(st_plugin_i }; DBUG_RETURN(0); + +err_deinit: + /* + Let plugin do its inner deinitialization as plugin->init() + was successfully called before. + */ + if (plugin->plugin->deinit) + (void) plugin->plugin->deinit(NULL); + err: + my_free((uchar*) hton, MYF(0)); + plugin->data= NULL; DBUG_RETURN(1); }