~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/loader.cc

Merge Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
563
563
#define DRIZZLE_SYSVAR_NAME(name) name
564
564
#define PLUGIN_VAR_TYPEMASK 0x007f
565
565
 
566
 
#define EXTRA_OPTIONS 3 /* options for: 'foo', 'plugin-foo' and NULL */
 
566
static const uint32_t EXTRA_OPTIONS= 1; /* handle the NULL option */
567
567
 
568
568
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_bool_t, bool);
569
569
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_bool_t, bool);
790
790
  return(var);
791
791
}
792
792
 
 
793
static const string make_bookmark_name(const string &plugin, const char *name, int flags)
 
794
{
 
795
  /* Embed the flags into the first char of the string */
 
796
  string varname(1, static_cast<char>(flags & PLUGIN_VAR_TYPEMASK));
 
797
  varname.append(plugin);
 
798
  varname.push_back('_');
 
799
  varname.append(name);
 
800
 
 
801
  for (string::iterator p= varname.begin() + 1; p != varname.end(); ++p)
 
802
  {
 
803
    if (*p == '-')
 
804
    {
 
805
      *p= '_';
 
806
    }
 
807
  }
 
808
  return varname;
 
809
}
793
810
 
794
811
/*
795
812
  called by register_var, construct_options and test_plugin_options.
796
813
  Returns the 'bookmark' for the named variable.
797
814
  LOCK_system_variables_hash should be at least read locked
798
815
*/
799
 
static st_bookmark *find_bookmark(const char *plugin, const char *name, int flags)
 
816
static st_bookmark *find_bookmark(const string &plugin, const char *name, int flags)
800
817
{
801
818
  st_bookmark *result= NULL;
802
 
  uint32_t namelen, length, pluginlen= 0;
803
 
  char *varname, *p;
804
819
 
805
820
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
806
821
    return NULL;
807
822
 
808
 
  namelen= strlen(name);
809
 
  if (plugin)
810
 
    pluginlen= strlen(plugin) + 1;
811
 
  length= namelen + pluginlen + 2;
812
 
  varname= (char*) malloc(length);
813
 
 
814
 
  if (plugin)
815
 
  {
816
 
    sprintf(varname+1,"%s_%s",plugin,name);
817
 
    for (p= varname + 1; *p; p++)
818
 
      if (*p == '-')
819
 
        *p= '_';
820
 
  }
821
 
  else
822
 
    memcpy(varname + 1, name, namelen + 1);
823
 
 
824
 
  varname[0]= flags & PLUGIN_VAR_TYPEMASK;
 
823
  const string varname(make_bookmark_name(plugin, name, flags));
 
824
 
825
825
 
826
826
  result= (st_bookmark*) hash_search(&bookmark_hash,
827
 
                                     (const unsigned char*) varname, length - 1);
 
827
                                     (const unsigned char*) varname.c_str(), varname.size() - 1);
828
828
 
829
 
  free(varname);
830
829
  return result;
831
830
}
832
831
 
836
835
  returns null for non session-local variables.
837
836
  Requires that a write lock is obtained on LOCK_system_variables_hash
838
837
*/
839
 
static st_bookmark *register_var(const char *plugin, const char *name,
 
838
static st_bookmark *register_var(const string &plugin, const char *name,
840
839
                                 int flags)
841
840
{
842
 
  uint32_t length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size;
 
841
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
 
842
    return NULL;
 
843
 
 
844
  uint32_t size= 0, offset, new_size;
843
845
  st_bookmark *result;
844
 
  char *varname, *p;
845
 
 
846
 
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
847
 
    return NULL;
848
846
 
849
847
  switch (flags & PLUGIN_VAR_TYPEMASK) {
850
848
  case PLUGIN_VAR_BOOL:
867
865
    return NULL;
868
866
  };
869
867
 
870
 
  varname= ((char*) malloc(length));
871
 
  sprintf(varname+1, "%s_%s", plugin, name);
872
 
  for (p= varname + 1; *p; p++)
873
 
    if (*p == '-')
874
 
      *p= '_';
875
868
 
876
 
  if (!(result= find_bookmark(NULL, varname + 1, flags)))
 
869
  if (!(result= find_bookmark(plugin, name, flags)))
877
870
  {
878
 
    result= (st_bookmark*) alloc_root(&plugin_mem_root,
879
 
                                      sizeof(struct st_bookmark) + length-1);
880
 
    varname[0]= flags & PLUGIN_VAR_TYPEMASK;
881
 
    memcpy(result->key, varname, length);
882
 
    result->name_len= length - 2;
 
871
    const string varname(make_bookmark_name(plugin, name, flags));
 
872
 
 
873
    result= static_cast<st_bookmark*>(alloc_root(&plugin_mem_root,
 
874
                                      sizeof(struct st_bookmark) + varname.size() + 1));
 
875
    memset(result->key, 0, varname.size()+1);
 
876
    memcpy(result->key, varname.c_str(), varname.size());
 
877
    result->name_len= varname.size() - 2;
883
878
    result->offset= -1;
884
879
 
885
880
    assert(size && !(size & (size-1))); /* must be power of 2 */
935
930
      assert(0);
936
931
    }
937
932
  }
938
 
  free(varname);
939
933
  return result;
940
934
}
941
935
 
1429
1423
static int construct_options(memory::Root *mem_root, plugin::Module *tmp,
1430
1424
                             my_option *options)
1431
1425
{
1432
 
  const char *plugin_name= tmp->getManifest().name;
1433
 
  uint32_t namelen= strlen(plugin_name), optnamelen;
1434
 
  uint32_t buffer_length= namelen * 4 +  75;
1435
 
  char *name= (char*) alloc_root(mem_root, buffer_length);
1436
 
  bool *enabled_value= (bool*) alloc_root(mem_root, sizeof(bool));
 
1426
  
 
1427
  int localoptionid= 256;
 
1428
  const string plugin_name(tmp->getManifest().name);
 
1429
 
 
1430
  size_t namelen= plugin_name.size(), optnamelen;
 
1431
 
1437
1432
  char *optname, *p;
1438
1433
  int index= 0, offset= 0;
1439
1434
  drizzle_sys_var *opt, **plugin_option;
1440
1435
  st_bookmark *v;
1441
1436
 
1442
 
  /* support --skip-plugin-foo syntax */
1443
 
  memcpy(name, plugin_name, namelen + 1);
1444
 
  my_casedn_str(&my_charset_utf8_general_ci, name);
1445
 
  sprintf(name+namelen+1, "plugin-%s", name);
1446
 
  /* Now we have namelen + 1 + 7 + namelen + 1 == namelen * 2 + 9. */
1447
 
 
1448
 
  for (p= name + namelen*2 + 8; p > name; p--)
1449
 
    if (*p == '_')
1450
 
      *p= '-';
1451
 
 
1452
 
  sprintf(name+namelen*2+10,
1453
 
          "Enable %s plugin. Disable with --skip-%s (will save memory).",
1454
 
          plugin_name, name);
1455
 
  /*
1456
 
    Now we have namelen * 2 + 10 (one char unused) + 7 + namelen + 9 +
1457
 
    20 + namelen + 20 + 1 == namelen * 4 + 67.
1458
 
  */
1459
 
 
1460
 
  options[0].comment= name + namelen*2 + 10;
1461
 
 
1462
 
  /*
1463
 
    This whole code around variables and command line parameters is turd
1464
 
    soup.
1465
 
 
1466
 
    e.g. the below assignemnt of having the plugin alaways enabled is never
1467
 
    changed so that './drizzled --skip-innodb --help' shows innodb as enabled.
1468
 
 
1469
 
    But this is just as broken as it was in MySQL and properly fixing everything
1470
 
    is a decent amount of "future work"
1471
 
  */
1472
 
  *enabled_value= true; /* by default, plugin enabled */
1473
 
 
1474
 
  options[1].name= (options[0].name= name) + namelen + 1;
1475
 
  options[0].id= options[1].id= 256; /* must be >255. dup id ok */
1476
 
  options[0].var_type= options[1].var_type= GET_BOOL;
1477
 
  options[0].arg_type= options[1].arg_type= NO_ARG;
1478
 
  options[0].def_value= options[1].def_value= true;
1479
 
  options[0].value= options[0].u_max_value=
1480
 
  options[1].value= options[1].u_max_value= (char**) enabled_value;
1481
 
  options+= 2;
 
1437
  string name(plugin_name);
 
1438
  transform(name.begin(), name.end(), name.begin(), ::tolower);
 
1439
 
 
1440
  for (string::iterator iter= name.begin(); iter != name.end(); ++iter)
 
1441
  {
 
1442
    if (*iter == '_')
 
1443
      *iter= '-';
 
1444
  }
1482
1445
 
1483
1446
  /*
1484
1447
    Two passes as the 2nd pass will take pointer addresses for use
1511
1474
      break;
1512
1475
    default:
1513
1476
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1514
 
                      opt->flags, plugin_name);
 
1477
                      opt->flags, plugin_name.c_str());
1515
1478
      return(-1);
1516
1479
    };
1517
1480
  }
1556
1519
          errmsg_printf(ERRMSG_LVL_WARN, _("Server variable %s of plugin %s was forced "
1557
1520
                            "to be read-only: string variable without "
1558
1521
                            "update_func and PLUGIN_VAR_MEMALLOC flag"),
1559
 
                            opt->name, plugin_name);
 
1522
                            opt->name, plugin_name.c_str());
1560
1523
        }
1561
1524
      }
1562
1525
      break;
1563
1526
    default:
1564
1527
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1565
 
                      opt->flags, plugin_name);
 
1528
                      opt->flags, plugin_name.c_str());
1566
1529
      return(-1);
1567
1530
    }
1568
1531
 
1573
1536
    if (!opt->name)
1574
1537
    {
1575
1538
      errmsg_printf(ERRMSG_LVL_ERROR, _("Missing variable name in plugin '%s'."),
1576
 
                      plugin_name);
 
1539
                    plugin_name.c_str());
1577
1540
      return(-1);
1578
1541
    }
1579
1542
 
1581
1544
    {
1582
1545
      optnamelen= strlen(opt->name);
1583
1546
      optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
1584
 
      sprintf(optname, "%s-%s", name, opt->name);
 
1547
      sprintf(optname, "%s-%s", name.c_str(), opt->name);
1585
1548
      optnamelen= namelen + optnamelen + 1;
1586
1549
    }
1587
1550
    else
1590
1553
      if (!(v= find_bookmark(name, opt->name, opt->flags)))
1591
1554
      {
1592
1555
        errmsg_printf(ERRMSG_LVL_ERROR, _("Thread local variable '%s' not allocated "
1593
 
                        "in plugin '%s'."), opt->name, plugin_name);
 
1556
                      "in plugin '%s'."), opt->name, plugin_name.c_str());
1594
1557
        return(-1);
1595
1558
      }
1596
1559
 
1611
1574
    options->name= optname;
1612
1575
    options->comment= opt->comment;
1613
1576
    options->app_type= opt;
1614
 
    options->id= (options-1)->id + 1;
 
1577
    options->id= localoptionid++;
1615
1578
 
1616
1579
    plugin_opt_set_limits(options, opt);
1617
1580
 
1621
1584
    else
1622
1585
      options->value= options->u_max_value= *(char***) (opt + 1);
1623
1586
 
1624
 
    options[1]= options[0];
1625
 
    options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
1626
 
    options[1].comment= 0; // hidden
1627
 
    sprintf(p,"plugin-%s",optname);
1628
 
 
1629
 
    options+= 2;
 
1587
    options++;
1630
1588
  }
1631
1589
 
1632
1590
  return(0);
1639
1597
  my_option *opts;
1640
1598
  uint32_t count= EXTRA_OPTIONS;
1641
1599
 
1642
 
  for (opt= p->getManifest().system_vars; opt && *opt; opt++, count+= 2) {};
 
1600
  for (opt= p->getManifest().system_vars; opt && *opt; opt++, count++) {};
1643
1601
 
1644
1602
  opts= (my_option*)alloc_root(mem_root, (sizeof(my_option) * count));
1645
1603
  if (opts == NULL)
1694
1652
  uint32_t len, count= EXTRA_OPTIONS;
1695
1653
 
1696
1654
  for (opt= tmp->getManifest().system_vars; opt && *opt; opt++)
1697
 
    count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
 
1655
    count++;
1698
1656
 
1699
1657
 
1700
1658
  if (count > EXTRA_OPTIONS || (*argc > 1))
1732
1690
      if (((o= *opt)->flags & PLUGIN_VAR_NOSYSVAR))
1733
1691
        continue;
1734
1692
 
1735
 
      if ((var= find_bookmark(tmp->getName().c_str(), o->name, o->flags)))
 
1693
      if ((var= find_bookmark(tmp->getName(), o->name, o->flags)))
1736
1694
        v= new sys_var_pluginvar(var->key + 1, o);
1737
1695
      else
1738
1696
      {