~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_plugin.cc

  • Committer: Brian Aker
  • Date: 2009-01-17 17:08:25 UTC
  • Revision ID: brian@gir-3.local-20090117170825-l7vo00mje6uk5cg0
Test case fixes + TABLE_CACHE to class (will rename in manner which is NOT
YELLING CASE UP).

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
#include <drizzled/server_includes.h>
17
17
#include <mysys/my_getopt.h>
 
18
#include <mysys/hash.h>
18
19
 
19
20
#include <drizzled/authentication.h>
20
21
#include <drizzled/logging.h>
24
25
#include <drizzled/parser.h>
25
26
#include <drizzled/sql_parse.h>
26
27
#include <drizzled/scheduling.h>
 
28
#include <drizzled/replicator.h>
 
29
#include <drizzled/show.h>
 
30
#include <drizzled/handler.h>
 
31
#include <drizzled/set_var.h>
 
32
#include <drizzled/session.h>
 
33
#include <drizzled/item/null.h>
27
34
 
28
35
#include <string>
 
36
#include <vector>
29
37
 
30
38
#include <drizzled/error.h>
31
39
#include <drizzled/gettext.h>
61
69
  { C_STRING_WITH_LEN("CONFIGVAR") },
62
70
  { C_STRING_WITH_LEN("QCACHE") },
63
71
  { C_STRING_WITH_LEN("PARSER") },
64
 
  { C_STRING_WITH_LEN("SCHEDULING") }
 
72
  { C_STRING_WITH_LEN("SCHEDULING") },
 
73
  { C_STRING_WITH_LEN("REPLICATOR") }
65
74
};
66
75
 
67
76
extern int initialize_schema_table(st_plugin_int *plugin);
89
98
  configvar_initializer,
90
99
  qcache_initializer,
91
100
  parser_initializer,
92
 
  scheduling_initializer
 
101
  scheduling_initializer,
 
102
  replicator_initializer
93
103
};
94
104
 
95
105
plugin_type_init plugin_type_deinitialize[DRIZZLE_MAX_PLUGIN_TYPE_NUM]=
106
116
  configvar_finalizer,
107
117
  qcache_finalizer,
108
118
  parser_finalizer,
109
 
  scheduling_finalizer
 
119
  scheduling_finalizer,
 
120
  replicator_finalizer
110
121
};
111
122
 
112
123
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
182
193
 
183
194
  static void *operator new(size_t size, MEM_ROOT *mem_root)
184
195
  { return (void*) alloc_root(mem_root, (uint) size); }
185
 
  static void operator delete(void *ptr_arg __attribute__((unused)),
186
 
                              size_t size __attribute__((unused)))
 
196
  static void operator delete(void *, size_t)
187
197
  { TRASH(ptr_arg, size); }
188
198
 
189
199
  sys_var_pluginvar(const char *name_arg,
199
209
  TYPELIB* plugin_var_typelib(void);
200
210
  unsigned char* value_ptr(Session *session, enum_var_type type, LEX_STRING *base);
201
211
  bool check(Session *session, set_var *var);
202
 
  bool check_default(enum_var_type type __attribute__((unused)))
 
212
  bool check_default(enum_var_type)
203
213
    { return is_readonly(); }
204
 
  void set_default(Session *session,
205
 
                   enum_var_type type __attribute__((unused)));
 
214
  void set_default(Session *session, enum_var_type);
206
215
  bool update(Session *session, set_var *var);
207
216
};
208
217
 
293
302
{
294
303
  uint32_t i;
295
304
  struct st_plugin_dl *tmp;
 
305
 
296
306
  for (i= 0; i < plugin_dl_array.elements; i++)
297
307
  {
298
308
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
309
319
{
310
320
  uint32_t i;
311
321
  struct st_plugin_dl *tmp;
 
322
 
312
323
  for (i= 0; i < plugin_dl_array.elements; i++)
313
324
  {
314
325
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
356
367
    if (report & REPORT_TO_USER)
357
368
      my_error(ER_UDF_NO_PATHS, MYF(0));
358
369
    if (report & REPORT_TO_LOG)
359
 
      sql_print_error("%s",ER(ER_UDF_NO_PATHS));
 
370
      errmsg_printf(ERRMSG_LVL_ERROR, "%s",ER(ER_UDF_NO_PATHS));
360
371
    return(0);
361
372
  }
362
373
  /* If this dll is already loaded just increase ref_count. */
385
396
    if (report & REPORT_TO_USER)
386
397
      my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath.c_str(), errno, errmsg);
387
398
    if (report & REPORT_TO_LOG)
388
 
      sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath.c_str(), errno, errmsg);
 
399
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_OPEN_LIBRARY), dlpath.c_str(), errno, errmsg);
389
400
    return(0);
390
401
  }
391
402
 
396
407
    if (report & REPORT_TO_USER)
397
408
      my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
398
409
    if (report & REPORT_TO_LOG)
399
 
      sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym);
 
410
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym);
400
411
    return(0);
401
412
  }
402
413
 
404
415
 
405
416
  /* Duplicate and convert dll name */
406
417
  plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1;
407
 
  if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0))))
 
418
  if (! (plugin_dl.dl.str= (char*) malloc(plugin_dl.dl.length)))
408
419
  {
409
420
    free_plugin_mem(&plugin_dl);
410
421
    if (report & REPORT_TO_USER)
411
422
      my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
412
423
    if (report & REPORT_TO_LOG)
413
 
      sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
 
424
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
414
425
    return(0);
415
426
  }
416
427
  plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length,
424
435
    if (report & REPORT_TO_USER)
425
436
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl));
426
437
    if (report & REPORT_TO_LOG)
427
 
      sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl));
 
438
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl));
428
439
    return(0);
429
440
  }
430
441
  return(tmp);
510
521
}
511
522
 
512
523
 
513
 
static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc)
 
524
static plugin_ref intern_plugin_lock(LEX *, plugin_ref rc)
514
525
{
515
526
  st_plugin_int *pi= plugin_ref_to_int(rc);
516
527
 
522
533
      memory manager and/or valgrind to track locked references and
523
534
      double unlocks to aid resolving reference counting.problems.
524
535
    */
525
 
    if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
 
536
    if (!(plugin= (plugin_ref) malloc(sizeof(pi))))
526
537
      return(NULL);
527
538
 
528
539
    *plugin= pi;
529
540
    pi->ref_count++;
530
541
 
531
 
    if (lex)
532
 
      insert_dynamic(&lex->plugins, (unsigned char*)&plugin);
533
542
    return(plugin);
534
543
  }
535
544
  return(NULL);
594
603
    if (report & REPORT_TO_USER)
595
604
      my_error(ER_UDF_EXISTS, MYF(0), name->str);
596
605
    if (report & REPORT_TO_LOG)
597
 
      sql_print_error(ER(ER_UDF_EXISTS), name->str);
 
606
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UDF_EXISTS), name->str);
598
607
    return(true);
599
608
  }
600
609
  /* Clear the whole struct to catch future extensions. */
641
650
  if (report & REPORT_TO_USER)
642
651
    my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), name->str);
643
652
  if (report & REPORT_TO_LOG)
644
 
    sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str);
 
653
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_FIND_DL_ENTRY), name->str);
645
654
err:
646
655
  plugin_dl_del(dl);
647
656
  return(true);
674
683
  {
675
684
    if ((*plugin_type_deinitialize[plugin->plugin->type])(plugin))
676
685
    {
677
 
      sql_print_error(_("Plugin '%s' of type %s failed deinitialization"),
 
686
      errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' of type %s failed deinitialization"),
678
687
                      plugin->name.str, plugin_type_names[plugin->plugin->type].str);
679
688
    }
680
689
  }
688
697
    exit until NDB is shut down.
689
698
  */
690
699
  if (ref_check && plugin->ref_count)
691
 
    sql_print_error(_("Plugin '%s' has ref_count=%d after deinitialization."),
 
700
    errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has ref_count=%d after deinitialization."),
692
701
                    plugin->name.str, plugin->ref_count);
693
702
}
694
703
 
702
711
    plugin_dl_del(&plugin->plugin_dl->dl);
703
712
  plugin->state= PLUGIN_IS_FREED;
704
713
  plugin_array_version++;
705
 
  rw_wrlock(&LOCK_system_variables_hash);
 
714
  pthread_rwlock_wrlock(&LOCK_system_variables_hash);
706
715
  mysql_del_sys_var_chain(plugin->system_vars);
707
 
  rw_unlock(&LOCK_system_variables_hash);
 
716
  pthread_rwlock_unlock(&LOCK_system_variables_hash);
708
717
  free_root(&plugin->mem_root, MYF(0));
709
718
  return;
710
719
}
711
720
 
712
721
static void reap_plugins(void)
713
722
{
714
 
  uint32_t count, idx;
715
 
  struct st_plugin_int *plugin, **reap, **list;
716
 
 
717
 
  if (!reap_needed)
718
 
    return;
 
723
  size_t count;
 
724
  uint32_t idx;
 
725
  struct st_plugin_int *plugin;
719
726
 
720
727
  reap_needed= false;
721
728
  count= plugin_array.elements;
722
 
  reap= (struct st_plugin_int **)my_alloca(sizeof(plugin)*(count+1));
723
 
  *(reap++)= NULL;
724
729
 
725
730
  for (idx= 0; idx < count; idx++)
726
731
  {
727
732
    plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
728
 
    if (plugin->state == PLUGIN_IS_DELETED && !plugin->ref_count)
729
 
    {
730
 
      /* change the status flag to prevent reaping by another thread */
731
 
      plugin->state= PLUGIN_IS_DYING;
732
 
      *(reap++)= plugin;
733
 
    }
734
 
  }
735
 
 
736
 
  list= reap;
737
 
  while ((plugin= *(--list)))
 
733
    plugin->state= PLUGIN_IS_DYING;
738
734
    plugin_deinitialize(plugin, true);
739
 
 
740
 
  while ((plugin= *(--reap)))
741
735
    plugin_del(plugin);
742
 
 
743
 
  my_afree(reap);
 
736
  }
744
737
}
745
738
 
746
 
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin)
 
739
static void intern_plugin_unlock(LEX *, plugin_ref plugin)
747
740
{
748
 
  int i;
749
741
  st_plugin_int *pi;
750
742
 
751
743
  if (!plugin)
755
747
 
756
748
  free((void *) plugin);
757
749
 
758
 
  if (lex)
759
 
  {
760
 
    /*
761
 
      Remove one instance of this plugin from the use list.
762
 
      We are searching backwards so that plugins locked last
763
 
      could be unlocked faster - optimizing for LIFO semantics.
764
 
    */
765
 
    for (i= lex->plugins.elements - 1; i >= 0; i--)
766
 
      if (plugin == *dynamic_element(&lex->plugins, i, plugin_ref*))
767
 
      {
768
 
        delete_dynamic_element(&lex->plugins, i);
769
 
        break;
770
 
      }
771
 
    assert(i >= 0);
772
 
  }
773
 
 
774
750
  assert(pi->ref_count);
775
751
  pi->ref_count--;
776
752
 
808
784
  {
809
785
    if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
810
786
    {
811
 
      sql_print_error(_("Plugin '%s' registration as a %s failed."),
 
787
      errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' registration as a %s failed."),
812
788
                      plugin->name.str, plugin_type_names[plugin->plugin->type].str);
813
789
      goto err;
814
790
    }
817
793
  {
818
794
    if (plugin->plugin->init(plugin))
819
795
    {
820
 
      sql_print_error(_("Plugin '%s' init function returned error."),
 
796
      errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' init function returned error."),
821
797
                      plugin->name.str);
822
798
      goto err;
823
799
    }
872
848
extern "C" unsigned char *get_bookmark_hash_key(const unsigned char *, size_t *, bool);
873
849
 
874
850
 
875
 
unsigned char *get_plugin_hash_key(const unsigned char *buff, size_t *length,
876
 
                           bool not_used __attribute__((unused)))
 
851
unsigned char *get_plugin_hash_key(const unsigned char *buff, size_t *length, bool)
877
852
{
878
853
  struct st_plugin_int *plugin= (st_plugin_int *)buff;
879
854
  *length= (uint)plugin->name.length;
881
856
}
882
857
 
883
858
 
884
 
unsigned char *get_bookmark_hash_key(const unsigned char *buff, size_t *length,
885
 
                             bool not_used __attribute__((unused)))
 
859
unsigned char *get_bookmark_hash_key(const unsigned char *buff, size_t *length, bool)
886
860
{
887
861
  struct st_bookmark *var= (st_bookmark *)buff;
888
862
  *length= var->name_len + 1;
899
873
*/
900
874
int plugin_init(int *argc, char **argv, int flags)
901
875
{
902
 
  uint32_t i;
 
876
  uint32_t idx;
903
877
  struct st_mysql_plugin **builtins;
904
878
  struct st_mysql_plugin *plugin;
905
 
  struct st_plugin_int tmp, *plugin_ptr, **reap;
 
879
  struct st_plugin_int tmp, *plugin_ptr;
906
880
  MEM_ROOT tmp_root;
907
881
 
908
882
  if (initialized)
922
896
                            sizeof(struct st_plugin_int *),16,16))
923
897
    goto err;
924
898
 
925
 
  for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
 
899
  for (idx= 0; idx < DRIZZLE_MAX_PLUGIN_TYPE_NUM; idx++)
926
900
  {
927
 
    if (hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0,
 
901
    if (hash_init(&plugin_hash[idx], system_charset_info, 16, 0, 0,
928
902
                  get_plugin_hash_key, NULL, HASH_UNIQUE))
929
903
      goto err;
930
904
  }
983
957
  /*
984
958
    Now we initialize all remaining plugins
985
959
  */
986
 
 
987
 
  reap= (st_plugin_int **) my_alloca((plugin_array.elements+1) * sizeof(void*));
988
 
  *(reap++)= NULL;
989
 
 
990
 
  for (i= 0; i < plugin_array.elements; i++)
 
960
  for (idx= 0; idx < plugin_array.elements; idx++)
991
961
  {
992
 
    plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
 
962
    plugin_ptr= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
993
963
    if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
994
964
    {
995
965
      if (plugin_initialize(plugin_ptr))
996
966
      {
997
967
        plugin_ptr->state= PLUGIN_IS_DYING;
998
 
        *(reap++)= plugin_ptr;
 
968
        plugin_deinitialize(plugin_ptr, true);
 
969
        plugin_del(plugin_ptr);
999
970
      }
1000
971
    }
1001
972
  }
1002
973
 
1003
 
  /*
1004
 
    Check if any plugins have to be reaped
1005
 
  */
1006
 
  while ((plugin_ptr= *(--reap)))
1007
 
  {
1008
 
    plugin_deinitialize(plugin_ptr, true);
1009
 
    plugin_del(plugin_ptr);
1010
 
  }
1011
 
 
1012
 
  my_afree(reap);
1013
974
 
1014
975
end:
1015
976
  free_root(&tmp_root, MYF(0));
1062
1023
  {
1063
1024
    if (p == buffer + sizeof(buffer) - 1)
1064
1025
    {
1065
 
      sql_print_error(_("plugin-load parameter too long"));
 
1026
      errmsg_printf(ERRMSG_LVL_ERROR, _("plugin-load parameter too long"));
1066
1027
      return(true);
1067
1028
    }
1068
1029
 
1122
1083
  }
1123
1084
  return(false);
1124
1085
error:
1125
 
  sql_print_error(_("Couldn't load plugin named '%s' with soname '%s'."),
 
1086
  errmsg_printf(ERRMSG_LVL_ERROR, _("Couldn't load plugin named '%s' with soname '%s'."),
1126
1087
                  name.str, dl.str);
1127
1088
  return(true);
1128
1089
}
1130
1091
 
1131
1092
void plugin_shutdown(void)
1132
1093
{
1133
 
  uint32_t i, count= plugin_array.elements, free_slots= 0;
1134
 
  struct st_plugin_int **plugins, *plugin;
1135
 
  struct st_plugin_dl **dl;
 
1094
  uint32_t idx, free_slots= 0;
 
1095
  size_t count= plugin_array.elements;
 
1096
  struct st_plugin_int *plugin;
 
1097
  vector<st_plugin_int *> plugins;
 
1098
  vector<st_plugin_dl *> dl;
1136
1099
 
1137
1100
  if (initialized)
1138
1101
  {
1148
1111
    while (reap_needed && (count= plugin_array.elements))
1149
1112
    {
1150
1113
      reap_plugins();
1151
 
      for (i= free_slots= 0; i < count; i++)
 
1114
      for (idx= free_slots= 0; idx < count; idx++)
1152
1115
      {
1153
 
        plugin= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
 
1116
        plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
1154
1117
        switch (plugin->state) {
1155
1118
        case PLUGIN_IS_READY:
1156
1119
          plugin->state= PLUGIN_IS_DELETED;
1173
1136
    }
1174
1137
 
1175
1138
    if (count > free_slots)
1176
 
      sql_print_warning(_("Forcing shutdown of %d plugins"),
1177
 
                        count - free_slots);
 
1139
      errmsg_printf(ERRMSG_LVL_WARN, _("Forcing shutdown of %"PRIu64" plugins"),
 
1140
                        (uint64_t)count - free_slots);
1178
1141
 
1179
 
    plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
 
1142
    plugins.reserve(count);
1180
1143
 
1181
1144
    /*
1182
1145
      If we have any plugins which did not die cleanly, we force shutdown
1183
1146
    */
1184
 
    for (i= 0; i < count; i++)
 
1147
    for (idx= 0; idx < count; idx++)
1185
1148
    {
1186
 
      plugins[i]= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
 
1149
      plugins.push_back(*dynamic_element(&plugin_array, idx,
 
1150
                                         struct st_plugin_int **));
1187
1151
      /* change the state to ensure no reaping races */
1188
 
      if (plugins[i]->state == PLUGIN_IS_DELETED)
1189
 
        plugins[i]->state= PLUGIN_IS_DYING;
 
1152
      if (plugins[idx]->state == PLUGIN_IS_DELETED)
 
1153
        plugins[idx]->state= PLUGIN_IS_DYING;
1190
1154
    }
1191
1155
 
1192
1156
    /*
1193
1157
      We loop through all plugins and call deinit() if they have one.
1194
1158
    */
1195
 
    for (i= 0; i < count; i++)
1196
 
      if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
 
1159
    for (idx= 0; idx < count; idx++)
 
1160
      if (!(plugins[idx]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
1197
1161
      {
1198
 
        sql_print_information(_("Plugin '%s' will be forced to shutdown"),
1199
 
                              plugins[i]->name.str);
 
1162
        errmsg_printf(ERRMSG_LVL_INFO, _("Plugin '%s' will be forced to shutdown"),
 
1163
                              plugins[idx]->name.str);
1200
1164
        /*
1201
1165
          We are forcing deinit on plugins so we don't want to do a ref_count
1202
1166
          check until we have processed all the plugins.
1203
1167
        */
1204
 
        plugin_deinitialize(plugins[i], false);
 
1168
        plugin_deinitialize(plugins[idx], false);
1205
1169
      }
1206
1170
 
1207
1171
    /*
1208
1172
      We defer checking ref_counts until after all plugins are deinitialized
1209
1173
      as some may have worker threads holding on to plugin references.
1210
1174
    */
1211
 
    for (i= 0; i < count; i++)
 
1175
    for (idx= 0; idx < count; idx++)
1212
1176
    {
1213
 
      if (plugins[i]->ref_count)
1214
 
        sql_print_error(_("Plugin '%s' has ref_count=%d after shutdown."),
1215
 
                        plugins[i]->name.str, plugins[i]->ref_count);
1216
 
      if (plugins[i]->state & PLUGIN_IS_UNINITIALIZED)
1217
 
        plugin_del(plugins[i]);
 
1177
      if (plugins[idx]->ref_count)
 
1178
        errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has ref_count=%d after shutdown."),
 
1179
                        plugins[idx]->name.str, plugins[idx]->ref_count);
 
1180
      if (plugins[idx]->state & PLUGIN_IS_UNINITIALIZED)
 
1181
        plugin_del(plugins[idx]);
1218
1182
    }
1219
1183
 
1220
1184
    /*
1226
1190
 
1227
1191
    initialized= 0;
1228
1192
 
1229
 
    my_afree(plugins);
1230
1193
  }
1231
1194
 
1232
1195
  /* Dispose of the memory */
1233
1196
 
1234
 
  for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
1235
 
    hash_free(&plugin_hash[i]);
 
1197
  for (idx= 0; idx < DRIZZLE_MAX_PLUGIN_TYPE_NUM; idx++)
 
1198
    hash_free(&plugin_hash[idx]);
1236
1199
  delete_dynamic(&plugin_array);
1237
1200
 
1238
1201
  count= plugin_dl_array.elements;
1239
 
  dl= (struct st_plugin_dl **)my_alloca(sizeof(void*) * count);
1240
 
  for (i= 0; i < count; i++)
1241
 
    dl[i]= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
1242
 
  for (i= 0; i < plugin_dl_array.elements; i++)
1243
 
    free_plugin_mem(dl[i]);
1244
 
  my_afree(dl);
 
1202
  dl.reserve(count);
 
1203
  for (idx= 0; idx < count; idx++)
 
1204
    dl.push_back(*dynamic_element(&plugin_dl_array, idx,
 
1205
                 struct st_plugin_dl **));
 
1206
  for (idx= 0; idx < count; idx++)
 
1207
    free_plugin_mem(dl[idx]);
1245
1208
  delete_dynamic(&plugin_dl_array);
1246
1209
 
1247
1210
  hash_free(&bookmark_hash);
1256
1219
bool plugin_foreach_with_mask(Session *session, plugin_foreach_func *func,
1257
1220
                       int type, uint32_t state_mask, void *arg)
1258
1221
{
1259
 
  uint32_t idx, total;
1260
 
  struct st_plugin_int *plugin, **plugins;
 
1222
  uint32_t idx;
 
1223
  size_t total;
 
1224
  struct st_plugin_int *plugin;
 
1225
  vector<st_plugin_int *> plugins;
1261
1226
  int version=plugin_array_version;
1262
1227
 
1263
1228
  if (!initialized)
1267
1232
 
1268
1233
  total= type == DRIZZLE_ANY_PLUGIN ? plugin_array.elements
1269
1234
                                  : plugin_hash[type].records;
1270
 
  /*
1271
 
    Do the alloca out here in case we do have a working alloca:
1272
 
        leaving the nested stack frame invalidates alloca allocation.
1273
 
  */
1274
 
  plugins=(struct st_plugin_int **)my_alloca(total*sizeof(plugin));
 
1235
  plugins.reserve(total);
 
1236
 
1275
1237
  if (type == DRIZZLE_ANY_PLUGIN)
1276
1238
  {
1277
1239
    for (idx= 0; idx < total; idx++)
1278
1240
    {
1279
1241
      plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
1280
 
      plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
 
1242
      plugins.push_back(!(plugin->state & state_mask) ? plugin : NULL);
1281
1243
    }
1282
1244
  }
1283
1245
  else
1286
1248
    for (idx= 0; idx < total; idx++)
1287
1249
    {
1288
1250
      plugin= (struct st_plugin_int *) hash_element(hash, idx);
1289
 
      plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
 
1251
      plugins.push_back(!(plugin->state & state_mask) ? plugin : NULL);
1290
1252
    }
1291
1253
  }
1292
1254
  for (idx= 0; idx < total; idx++)
1303
1265
        goto err;
1304
1266
  }
1305
1267
 
1306
 
  my_afree(plugins);
1307
 
  return(false);
 
1268
  return false;
1308
1269
err:
1309
 
  my_afree(plugins);
1310
 
  return(true);
 
1270
  return true;
1311
1271
}
1312
1272
 
1313
1273
 
1352
1312
  default variable data check and update functions
1353
1313
****************************************************************************/
1354
1314
 
1355
 
static int check_func_bool(Session *session __attribute__((unused)),
1356
 
                           struct st_mysql_sys_var *var,
 
1315
static int check_func_bool(Session *, struct st_mysql_sys_var *var,
1357
1316
                           void *save, st_mysql_value *value)
1358
1317
{
1359
1318
  char buff[STRING_BUFFER_USUAL_SIZE];
1451
1410
                              var->name, (int64_t) tmp);
1452
1411
}
1453
1412
 
1454
 
static int check_func_str(Session *session,
1455
 
                          struct st_mysql_sys_var *var __attribute__((unused)),
 
1413
static int check_func_str(Session *session, struct st_mysql_sys_var *,
1456
1414
                          void *save, st_mysql_value *value)
1457
1415
{
1458
1416
  char buff[STRING_BUFFER_USUAL_SIZE];
1467
1425
}
1468
1426
 
1469
1427
 
1470
 
static int check_func_enum(Session *session __attribute__((unused)),
1471
 
                           struct st_mysql_sys_var *var,
 
1428
static int check_func_enum(Session *, struct st_mysql_sys_var *var,
1472
1429
                           void *save, st_mysql_value *value)
1473
1430
{
1474
1431
  char buff[STRING_BUFFER_USUAL_SIZE];
1514
1471
}
1515
1472
 
1516
1473
 
1517
 
static int check_func_set(Session *session __attribute__((unused)),
1518
 
                          struct st_mysql_sys_var *var,
 
1474
static int check_func_set(Session *, struct st_mysql_sys_var *var,
1519
1475
                          void *save, st_mysql_value *value)
1520
1476
{
1521
1477
  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
1540
1496
                     &error, &error_len, &not_used);
1541
1497
    if (error_len)
1542
1498
    {
1543
 
      strmake(buff, error, cmin(sizeof(buff), (unsigned long)error_len));
 
1499
      length= cmin(sizeof(buff), (unsigned long)error_len);
 
1500
      strncpy(buff, error, length);
 
1501
      buff[length]= '\0';
1544
1502
      strvalue= buff;
1545
1503
      goto err;
1546
1504
    }
1565
1523
}
1566
1524
 
1567
1525
 
1568
 
static void update_func_bool(Session *session __attribute__((unused)),
1569
 
                             struct st_mysql_sys_var *var __attribute__((unused)),
 
1526
static void update_func_bool(Session *, struct st_mysql_sys_var *,
1570
1527
                             void *tgt, const void *save)
1571
1528
{
1572
1529
  *(bool *) tgt= *(int *) save ? 1 : 0;
1573
1530
}
1574
1531
 
1575
1532
 
1576
 
static void update_func_int(Session *session __attribute__((unused)),
1577
 
                            struct st_mysql_sys_var *var __attribute__((unused)),
 
1533
static void update_func_int(Session *, struct st_mysql_sys_var *,
1578
1534
                             void *tgt, const void *save)
1579
1535
{
1580
1536
  *(int *)tgt= *(int *) save;
1581
1537
}
1582
1538
 
1583
1539
 
1584
 
static void update_func_long(Session *session __attribute__((unused)),
1585
 
                             struct st_mysql_sys_var *var __attribute__((unused)),
 
1540
static void update_func_long(Session *, struct st_mysql_sys_var *,
1586
1541
                             void *tgt, const void *save)
1587
1542
{
1588
1543
  *(long *)tgt= *(long *) save;
1589
1544
}
1590
1545
 
1591
1546
 
1592
 
static void update_func_int64_t(Session *session __attribute__((unused)),
1593
 
                                 struct st_mysql_sys_var *var __attribute__((unused)),
 
1547
static void update_func_int64_t(Session *, struct st_mysql_sys_var *,
1594
1548
                                 void *tgt, const void *save)
1595
1549
{
1596
1550
  *(int64_t *)tgt= *(uint64_t *) save;
1597
1551
}
1598
1552
 
1599
1553
 
1600
 
static void update_func_str(Session *session __attribute__((unused)), struct st_mysql_sys_var *var,
 
1554
static void update_func_str(Session *, struct st_mysql_sys_var *var,
1601
1555
                             void *tgt, const void *save)
1602
1556
{
1603
1557
  char *old= *(char **) tgt;
1604
1558
  *(char **)tgt= *(char **) save;
1605
1559
  if (var->flags & PLUGIN_VAR_MEMALLOC)
1606
1560
  {
1607
 
    *(char **)tgt= my_strdup(*(char **) save, MYF(0));
 
1561
    *(char **)tgt= strdup(*(char **) save);
1608
1562
    free(old);
 
1563
    /*
 
1564
     * There isn't a _really_ good thing to do here until this whole set_var
 
1565
     * mess gets redesigned
 
1566
     */
 
1567
    if (tgt == NULL)
 
1568
      errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory."));
 
1569
 
1609
1570
  }
1610
1571
}
1611
1572
 
1621
1582
  sys_var_pluginvar *pi= NULL;
1622
1583
  plugin_ref plugin;
1623
1584
 
1624
 
  rw_rdlock(&LOCK_system_variables_hash);
 
1585
  pthread_rwlock_rdlock(&LOCK_system_variables_hash);
1625
1586
  if ((var= intern_find_sys_var(str, length, false)) &&
1626
1587
      (pi= var->cast_pluginvar()))
1627
1588
  {
1628
 
    rw_unlock(&LOCK_system_variables_hash);
 
1589
    pthread_rwlock_unlock(&LOCK_system_variables_hash);
1629
1590
    LEX *lex= session ? session->lex : 0;
1630
1591
    if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
1631
1592
      var= NULL; /* failed to lock it, it must be uninstalling */
1638
1599
    }
1639
1600
  }
1640
1601
  else
1641
 
    rw_unlock(&LOCK_system_variables_hash);
 
1602
    pthread_rwlock_unlock(&LOCK_system_variables_hash);
1642
1603
 
1643
1604
  /*
1644
1605
    If the variable exists but the plugin it is associated with is not ready
1668
1629
  if (plugin)
1669
1630
    pluginlen= strlen(plugin) + 1;
1670
1631
  length= namelen + pluginlen + 2;
1671
 
  varname= (char*) my_alloca(length);
 
1632
  varname= (char*) malloc(length);
1672
1633
 
1673
1634
  if (plugin)
1674
1635
  {
1675
 
    strxmov(varname + 1, plugin, "_", name, NULL);
 
1636
    sprintf(varname+1,"%s_%s",plugin,name);
1676
1637
    for (p= varname + 1; *p; p++)
1677
1638
      if (*p == '-')
1678
1639
        *p= '_';
1685
1646
  result= (st_bookmark*) hash_search(&bookmark_hash,
1686
1647
                                     (const unsigned char*) varname, length - 1);
1687
1648
 
1688
 
  my_afree(varname);
 
1649
  free(varname);
1689
1650
  return result;
1690
1651
}
1691
1652
 
1728
1689
    return NULL;
1729
1690
  };
1730
1691
 
1731
 
  varname= ((char*) my_alloca(length));
1732
 
  strxmov(varname + 1, plugin, "_", name, NULL);
 
1692
  varname= ((char*) malloc(length));
 
1693
  sprintf(varname+1, "%s_%s", plugin, name);
1733
1694
  for (p= varname + 1; *p; p++)
1734
1695
    if (*p == '-')
1735
1696
      *p= '_';
1753
1714
 
1754
1715
    if (new_size > global_variables_dynamic_size)
1755
1716
    {
1756
 
      global_system_variables.dynamic_variables_ptr= (char*)
1757
 
        my_realloc(global_system_variables.dynamic_variables_ptr, new_size,
1758
 
                   MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
1759
 
      max_system_variables.dynamic_variables_ptr= (char*)
1760
 
        my_realloc(max_system_variables.dynamic_variables_ptr, new_size,
1761
 
                   MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
 
1717
      char* tmpptr= NULL;
 
1718
      if (!(tmpptr=
 
1719
              (char *)realloc(global_system_variables.dynamic_variables_ptr,
 
1720
                              new_size)))
 
1721
        return NULL;
 
1722
      global_system_variables.dynamic_variables_ptr= tmpptr;
 
1723
      tmpptr= NULL;
 
1724
      if (!(tmpptr=
 
1725
              (char *)realloc(max_system_variables.dynamic_variables_ptr,
 
1726
                              new_size)))
 
1727
        return NULL;
 
1728
      max_system_variables.dynamic_variables_ptr= tmpptr;
 
1729
           
1762
1730
      /*
1763
1731
        Clear the new variable value space. This is required for string
1764
1732
        variables. If their value is non-NULL, it must point to a valid
1768
1736
             global_variables_dynamic_size, 0,
1769
1737
             new_size - global_variables_dynamic_size);
1770
1738
      memset(max_system_variables.dynamic_variables_ptr +
1771
 
             global_variables_dynamic_size, 0, 
 
1739
             global_variables_dynamic_size, 0,
1772
1740
             new_size - global_variables_dynamic_size);
1773
1741
      global_variables_dynamic_size= new_size;
1774
1742
    }
1789
1757
      assert(0);
1790
1758
    }
1791
1759
  }
1792
 
  my_afree(varname);
 
1760
  free(varname);
1793
1761
  return result;
1794
1762
}
1795
1763
 
1816
1784
  {
1817
1785
    uint32_t idx;
1818
1786
 
1819
 
    rw_rdlock(&LOCK_system_variables_hash);
 
1787
    pthread_rwlock_rdlock(&LOCK_system_variables_hash);
1820
1788
 
1821
 
    session->variables.dynamic_variables_ptr= (char*)
1822
 
      my_realloc(session->variables.dynamic_variables_ptr,
1823
 
                 global_variables_dynamic_size,
1824
 
                 MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
 
1789
    char *tmpptr= NULL;
 
1790
    if (!(tmpptr= (char *)realloc(session->variables.dynamic_variables_ptr,
 
1791
                                  global_variables_dynamic_size)))
 
1792
      return NULL;
 
1793
    session->variables.dynamic_variables_ptr= tmpptr;
1825
1794
 
1826
1795
    if (global_lock)
1827
1796
      pthread_mutex_lock(&LOCK_global_system_variables);
1860
1829
                             *(int*)(pi->plugin_var + 1));
1861
1830
         if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
1862
1831
                             *(int*)(pi->plugin_var + 1))))
1863
 
           *pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
 
1832
           *pp= strdup(*pp);
 
1833
         if (*pp == NULL)
 
1834
           return NULL;
1864
1835
      }
1865
1836
    }
1866
1837
 
1874
1845
    session->variables.dynamic_variables_size=
1875
1846
           global_system_variables.dynamic_variables_size;
1876
1847
 
1877
 
    rw_unlock(&LOCK_system_variables_hash);
 
1848
    pthread_rwlock_unlock(&LOCK_system_variables_hash);
1878
1849
  }
1879
1850
  return (unsigned char*)session->variables.dynamic_variables_ptr + offset;
1880
1851
}
1918
1889
void plugin_sessionvar_init(Session *session)
1919
1890
{
1920
1891
  plugin_ref old_table_plugin= session->variables.table_plugin;
1921
 
  
 
1892
 
1922
1893
  session->variables.table_plugin= NULL;
1923
1894
  cleanup_variables(session, &session->variables);
1924
 
  
 
1895
 
1925
1896
  session->variables= global_system_variables;
1926
1897
  session->variables.table_plugin= NULL;
1927
1898
 
1940
1911
/*
1941
1912
  Unlocks all system variables which hold a reference
1942
1913
*/
1943
 
static void unlock_variables(Session *session __attribute__((unused)),
1944
 
                             struct system_variables *vars)
 
1914
static void unlock_variables(Session *, struct system_variables *vars)
1945
1915
{
1946
1916
  intern_plugin_unlock(NULL, vars->table_plugin);
1947
1917
  vars->table_plugin= NULL;
1962
1932
  int flags;
1963
1933
  uint32_t idx;
1964
1934
 
1965
 
  rw_rdlock(&LOCK_system_variables_hash);
 
1935
  pthread_rwlock_rdlock(&LOCK_system_variables_hash);
1966
1936
  for (idx= 0; idx < bookmark_hash.records; idx++)
1967
1937
  {
1968
1938
    v= (st_bookmark*) hash_element(&bookmark_hash, idx);
1982
1952
      *ptr= NULL;
1983
1953
    }
1984
1954
  }
1985
 
  rw_unlock(&LOCK_system_variables_hash);
 
1955
  pthread_rwlock_unlock(&LOCK_system_variables_hash);
1986
1956
 
1987
1957
  assert(vars->table_plugin == NULL);
1988
1958
 
1995
1965
 
1996
1966
void plugin_sessionvar_cleanup(Session *session)
1997
1967
{
1998
 
  uint32_t idx;
1999
 
  plugin_ref *list;
2000
 
 
2001
1968
  unlock_variables(session, &session->variables);
2002
1969
  cleanup_variables(session, &session->variables);
2003
 
 
2004
 
  if ((idx= session->lex->plugins.elements))
2005
 
  {
2006
 
    list= ((plugin_ref*) session->lex->plugins.buffer) + idx - 1;
2007
 
    while ((unsigned char*) list >= session->lex->plugins.buffer)
2008
 
      intern_plugin_unlock(NULL, *list--);
2009
 
  }
2010
 
 
2011
 
  reset_dynamic(&session->lex->plugins);
2012
 
 
2013
 
  return;
2014
1970
}
2015
1971
 
2016
1972
 
2117
2073
}
2118
2074
 
2119
2075
 
2120
 
unsigned char* sys_var_pluginvar::value_ptr(Session *session, enum_var_type type,
2121
 
                                    LEX_STRING *base __attribute__((unused)))
 
2076
unsigned char* sys_var_pluginvar::value_ptr(Session *session, enum_var_type type, LEX_STRING *)
2122
2077
{
2123
2078
  unsigned char* result;
2124
2079
 
2373
2328
extern "C" bool get_one_plugin_option(int optid, const struct my_option *,
2374
2329
                                         char *);
2375
2330
 
2376
 
bool get_one_plugin_option(int optid __attribute__((unused)),
2377
 
                              const struct my_option *opt __attribute__((unused)),
2378
 
                              char *argument __attribute__((unused)))
 
2331
bool get_one_plugin_option(int, const struct my_option *, char *)
2379
2332
{
2380
2333
  return 0;
2381
2334
}
2396
2349
  /* support --skip-plugin-foo syntax */
2397
2350
  memcpy(name, plugin_name, namelen + 1);
2398
2351
  my_casedn_str(&my_charset_utf8_general_ci, name);
2399
 
  strxmov(name + namelen + 1, "plugin-", name, NULL);
 
2352
  sprintf(name+namelen+1, "plugin-%s", name);
2400
2353
  /* Now we have namelen + 1 + 7 + namelen + 1 == namelen * 2 + 9. */
2401
2354
 
2402
2355
  for (p= name + namelen*2 + 8; p > name; p--)
2405
2358
 
2406
2359
  if (can_disable)
2407
2360
  {
2408
 
    strxmov(name + namelen*2 + 10, "Enable ", plugin_name, " plugin. "
2409
 
            "Disable with --skip-", name," (will save memory).", NULL);
 
2361
    sprintf(name+namelen*2+10,
 
2362
            "Enable %s plugin. Disable with --skip-%s (will save memory).",
 
2363
            plugin_name, name);
2410
2364
    /*
2411
2365
      Now we have namelen * 2 + 10 (one char unused) + 7 + namelen + 9 +
2412
2366
      20 + namelen + 20 + 1 == namelen * 4 + 67.
2460
2414
      (((sessionvar_set_t *)opt)->resolve)= mysql_sys_var_ptr_set;
2461
2415
      break;
2462
2416
    default:
2463
 
      sql_print_error(_("Unknown variable type code 0x%x in plugin '%s'."),
 
2417
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
2464
2418
                      opt->flags, plugin_name);
2465
2419
      return(-1);
2466
2420
    };
2503
2457
        if ((opt->flags & (PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY)) == false)
2504
2458
        {
2505
2459
          opt->flags|= PLUGIN_VAR_READONLY;
2506
 
          sql_print_warning(_("Server variable %s of plugin %s was forced "
 
2460
          errmsg_printf(ERRMSG_LVL_WARN, _("Server variable %s of plugin %s was forced "
2507
2461
                            "to be read-only: string variable without "
2508
2462
                            "update_func and PLUGIN_VAR_MEMALLOC flag"),
2509
2463
                            opt->name, plugin_name);
2523
2477
        opt->update= update_func_int64_t;
2524
2478
      break;
2525
2479
    default:
2526
 
      sql_print_error(_("Unknown variable type code 0x%x in plugin '%s'."),
 
2480
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
2527
2481
                      opt->flags, plugin_name);
2528
2482
      return(-1);
2529
2483
    }
2534
2488
 
2535
2489
    if (!opt->name)
2536
2490
    {
2537
 
      sql_print_error(_("Missing variable name in plugin '%s'."),
 
2491
      errmsg_printf(ERRMSG_LVL_ERROR, _("Missing variable name in plugin '%s'."),
2538
2492
                      plugin_name);
2539
2493
      return(-1);
2540
2494
    }
2543
2497
    {
2544
2498
      optnamelen= strlen(opt->name);
2545
2499
      optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
2546
 
      strxmov(optname, name, "-", opt->name, NULL);
 
2500
      sprintf(optname, "%s-%s", name, opt->name);
2547
2501
      optnamelen= namelen + optnamelen + 1;
2548
2502
    }
2549
2503
    else
2551
2505
      /* this should not fail because register_var should create entry */
2552
2506
      if (!(v= find_bookmark(name, opt->name, opt->flags)))
2553
2507
      {
2554
 
        sql_print_error(_("Thread local variable '%s' not allocated "
 
2508
        errmsg_printf(ERRMSG_LVL_ERROR, _("Thread local variable '%s' not allocated "
2555
2509
                        "in plugin '%s'."), opt->name, plugin_name);
2556
2510
        return(-1);
2557
2511
      }
2561
2515
      if (opt->flags & PLUGIN_VAR_NOCMDOPT)
2562
2516
        continue;
2563
2517
 
2564
 
      optname= (char*) memdup_root(mem_root, v->key + 1, 
 
2518
      optname= (char*) memdup_root(mem_root, v->key + 1,
2565
2519
                                   (optnamelen= v->name_len) + 1);
2566
2520
    }
2567
2521
 
2586
2540
    options[1]= options[0];
2587
2541
    options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
2588
2542
    options[1].comment= 0; // hidden
2589
 
    strxmov(p, "plugin-", optname, NULL);
 
2543
    sprintf(p,"plugin-%s",optname);
2590
2544
 
2591
2545
    options+= 2;
2592
2546
  }
2670
2624
  {
2671
2625
    if (!(opts= (my_option*) alloc_root(tmp_root, sizeof(my_option) * count)))
2672
2626
    {
2673
 
      sql_print_error(_("Out of memory for plugin '%s'."), tmp->name.str);
 
2627
      errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory for plugin '%s'."), tmp->name.str);
2674
2628
      return(-1);
2675
2629
    }
2676
2630
    memset(opts, 0, sizeof(my_option) * count);
2677
2631
 
2678
2632
    if (construct_options(tmp_root, tmp, opts, can_disable))
2679
2633
    {
2680
 
      sql_print_error(_("Bad options for plugin '%s'."), tmp->name.str);
 
2634
      errmsg_printf(ERRMSG_LVL_ERROR, _("Bad options for plugin '%s'."), tmp->name.str);
2681
2635
      return(-1);
2682
2636
    }
2683
2637
 
2686
2640
 
2687
2641
    if (error)
2688
2642
    {
2689
 
       sql_print_error(_("Parsing options for plugin '%s' failed."),
 
2643
       errmsg_printf(ERRMSG_LVL_ERROR, _("Parsing options for plugin '%s' failed."),
2690
2644
                       tmp->name.str);
2691
2645
       goto err;
2692
2646
    }
2706
2660
      {
2707
2661
        len= tmp->name.length + strlen(o->name) + 2;
2708
2662
        varname= (char*) alloc_root(mem_root, len);
2709
 
        strxmov(varname, tmp->name.str, "-", o->name, NULL);
 
2663
        sprintf(varname,"%s-%s",tmp->name.str,o->name);
2710
2664
        my_casedn_str(&my_charset_utf8_general_ci, varname);
2711
2665
 
2712
2666
        for (p= varname; *p; p++)
2729
2683
      chain.last->next = NULL;
2730
2684
      if (mysql_add_sys_var_chain(chain.first, NULL))
2731
2685
      {
2732
 
        sql_print_error(_("Plugin '%s' has conflicting system variables"),
 
2686
        errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has conflicting system variables"),
2733
2687
                        tmp->name.str);
2734
2688
        goto err;
2735
2689
      }
2739
2693
  }
2740
2694
 
2741
2695
  if (enabled_saved && global_system_variables.log_warnings)
2742
 
    sql_print_information(_("Plugin '%s' disabled by command line option"),
 
2696
    errmsg_printf(ERRMSG_LVL_INFO, _("Plugin '%s' disabled by command line option"),
2743
2697
                          tmp->name.str);
2744
2698
err:
2745
2699
  if (opts)