From a9dd9e21a9934bc13811bdd21813f813843dec1f Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 17 Aug 2026 23:58:03 +0300 Subject: [PATCH] MDEV-40799 Runtime plugin/UDF load errors lost under --silent-startup Regression from MDEV-32745 (7828fb475b0), which guarded the plugin-load my_error() calls with opt_silent_startup. That option is a lifetime global, set once at startup and never reset, so the guard suppressed the SQL error for the whole server lifetime, not just during startup. Runtime operations (INSTALL PLUGIN, CREATE FUNCTION ... SONAME) then skipped my_error(), never set the diagnostics area and wrongly succeeded - e.g. main.ps's "call proc_1()" no longer failed with ER_CANT_OPEN_LIBRARY. Startup callers pass MYF(ME_ERROR_LOG); runtime callers pass MYF(0). Gate the silencing on that flag via silent_plugin_startup() so it applies only to the startup error-log path, and runtime errors always reach the client. No new test case: the runtime failure path is already covered by existing tests (e.g. main.ps's ER_CANT_OPEN_LIBRARY check). The regression stayed invisible only because stock MTR does not start servers with --silent-startup. A dedicated test would have to restart the server with --silent-startup solely to assert that a startup-only option does not affect runtime, which adds little over the restored invariant. --- sql/sql_plugin.cc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index b2c921c11d846..e2aeb5a5717a5 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -525,6 +525,13 @@ static void free_plugin_mem(struct st_plugin_dl *p) } +/* Silence plugin-load errors only on the startup error-log path, never at runtime. */ +static inline bool silent_plugin_startup(myf MyFlags) +{ + return opt_silent_startup && (MyFlags & ME_ERROR_LOG); +} + + /** Reads data from mysql plugin interface @@ -545,7 +552,7 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, /* Determine interface version */ if (!sym) { - if (!opt_silent_startup) + if (!silent_plugin_startup(MyFlags)) my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, plugin_interface_version_sym, dlpath); DBUG_RETURN(TRUE); @@ -666,7 +673,7 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, Actually this branch impossible because in case of absence of maria version we try mysql version. */ - if (!opt_silent_startup) + if (!silent_plugin_startup(MyFlags)) my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, maria_plugin_interface_version_sym, dlpath); DBUG_RETURN(TRUE); @@ -782,7 +789,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, myf MyFlags) /* Open new dll handle */ if (!(plugin_dl.handle= dlopen(dlpath, RTLD_NOW))) { - if (!opt_silent_startup) + if (!silent_plugin_startup(MyFlags)) my_error(ER_CANT_OPEN_LIBRARY, MyFlags, dlpath, errno, my_dlerror(dlpath)); goto ret; @@ -827,7 +834,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, myf MyFlags) my_snprintf(buf, sizeof(buf), "service '%s' interface version mismatch", list_of_services[i].name); - if (!opt_silent_startup) + if (!silent_plugin_startup(MyFlags)) my_error(ER_CANT_OPEN_LIBRARY, MyFlags, dlpath, ENOEXEC, buf); goto ret; } @@ -1159,7 +1166,8 @@ static enum install_status plugin_add(MEM_ROOT *tmp_root, bool if_not_exists, if (!name->str && (maybe_dupe= plugin_find_internal(&tmp.name, MYSQL_ANY_PLUGIN))) { - if (plugin->name != maybe_dupe->plugin->name && !opt_silent_startup) + if (plugin->name != maybe_dupe->plugin->name && + !silent_plugin_startup(MyFlags)) { my_error(ER_UDF_EXISTS, MyFlags, plugin->name); DBUG_RETURN(INSTALL_FAIL_NOT_OK);