~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Brian Aker
  • Date: 2010-05-15 01:19:45 UTC
  • Revision ID: brian@gaz-20100515011945-uxhf94vi0tzm0vq6
Rename of KEY to KeyInfo

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include "drizzled/internal/my_sys.h"
32
32
#include "drizzled/internal/my_bit.h"
33
33
#include <drizzled/my_hash.h>
34
 
#include <drizzled/stacktrace.h>
35
34
#include <drizzled/error.h>
36
35
#include <drizzled/errmsg_print.h>
37
36
#include <drizzled/tztime.h>
49
48
#include "drizzled/plugin/scheduler.h"
50
49
#include "drizzled/plugin/xa_resource_manager.h"
51
50
#include "drizzled/plugin/monitored_in_transaction.h"
 
51
#include "drizzled/replication_services.h" /* For ReplicationServices::evaluateRegisteredPlugins() */
52
52
#include "drizzled/probes.h"
53
53
#include "drizzled/session_list.h"
54
54
#include "drizzled/charset.h"
55
55
#include "plugin/myisam/myisam.h"
 
56
#include "drizzled/drizzled.h"
56
57
 
57
58
#include <google/protobuf/stubs/common.h>
58
59
 
72
73
#endif
73
74
#include <sys/socket.h>
74
75
 
75
 
#include <locale.h>
76
 
 
77
76
 
78
77
#include <errno.h>
79
78
#include <sys/stat.h>
84
83
#include <pwd.h>                                // For getpwent
85
84
#include <grp.h>
86
85
 
87
 
#include <sys/resource.h>
88
 
 
89
86
#ifdef HAVE_SELECT_H
90
87
#  include <select.h>
91
88
#endif
190
187
/*
191
188
  Used with --help for detailed option
192
189
*/
193
 
static bool opt_help= false;
194
 
static bool opt_help_extended= false;
 
190
bool opt_help= false;
 
191
bool opt_help_extended= false;
195
192
 
196
193
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
197
194
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
202
199
 
203
200
/* static variables */
204
201
 
205
 
static bool volatile select_thread_in_use;
206
 
static bool volatile ready_to_exit;
207
202
static bool opt_debugging= 0;
208
203
static uint32_t wake_thread;
209
 
static uint32_t killed_threads;
210
 
static char *drizzled_user, *drizzled_chroot;
 
204
static char *drizzled_chroot;
211
205
static char *language_ptr;
212
206
static const char *default_character_set_name;
213
207
static const char *character_set_filesystem_name;
218
212
 
219
213
/* Global variables */
220
214
 
 
215
bool volatile ready_to_exit;
 
216
char *drizzled_user;
 
217
bool volatile select_thread_in_use;
221
218
bool volatile abort_loop;
222
219
bool volatile shutdown_in_progress;
223
220
uint32_t max_used_connections;
234
231
 
235
232
char* opt_secure_file_priv= 0;
236
233
 
237
 
static bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
 
234
bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
238
235
 
239
236
uint32_t drizzled_bind_timeout;
240
237
std::bitset<12> test_flags;
293
290
char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
294
291
char *default_tz_name;
295
292
char glob_hostname[FN_REFLEN];
296
 
char drizzle_real_data_home[FN_REFLEN],
 
293
char data_home_real[FN_REFLEN],
297
294
     language[FN_REFLEN], 
298
295
     *opt_tc_log_file;
299
 
char drizzle_unpacked_real_data_home[FN_REFLEN];
 
296
char data_home_real_unpacked[FN_REFLEN];
300
297
const key_map key_map_empty(0);
301
298
key_map key_map_full(0);                        // Will be initialized later
302
299
 
303
 
uint32_t drizzle_data_home_len;
304
 
char drizzle_data_home_buff[2], *drizzle_data_home=drizzle_real_data_home;
 
300
uint32_t data_home_len;
 
301
char data_home_buff[2], *data_home=data_home_real;
305
302
char *drizzle_tmpdir= NULL;
306
303
char *opt_drizzle_tmpdir= NULL;
307
304
 
346
343
 
347
344
/* Static variables */
348
345
 
349
 
static bool segfaulted;
350
346
int cleanup_done;
351
347
static char *drizzle_home_ptr, *pidfile_name_ptr;
352
348
static int defaults_argc;
353
349
static char **defaults_argv;
354
350
 
355
 
struct passwd *user_info;
356
 
static pthread_t select_thread;
357
 
static uint32_t thr_kill_signal;
 
351
passwd *user_info;
358
352
 
359
353
/**
360
354
  Number of currently active user connections. The variable is protected by
370
364
/* Function declarations */
371
365
bool drizzle_rm_tmp_tables();
372
366
 
373
 
extern "C" pthread_handler_t signal_hand(void *arg);
374
367
static void drizzle_init_variables(void);
375
368
static void get_options(int *argc,char **argv);
376
369
int drizzled_get_one_option(int, const struct option *, char *);
377
370
static int init_thread_environment();
378
371
static const char *get_relative_path(const char *path);
379
372
static void fix_paths(string &progname);
380
 
extern "C" pthread_handler_t handle_slave(void *arg);
381
 
static void clean_up(bool print_message);
382
373
 
383
374
static void usage(void);
384
 
static void clean_up_mutexes(void);
385
375
void close_connections(void);
386
376
 
387
377
/****************************************************************************
466
456
  }
467
457
}
468
458
 
469
 
extern "C" void print_signal_warning(int sig);
470
 
 
471
 
extern "C" void print_signal_warning(int sig)
472
 
{
473
 
  if (global_system_variables.log_warnings)
474
 
    errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu64),
475
 
                  sig, global_thread_id);
476
 
#ifndef HAVE_BSD_SIGNALS
477
 
  my_sigset(sig,print_signal_warning);          /* int. thread system calls */
478
 
#endif
479
 
  if (sig == SIGALRM)
480
 
    alarm(2);                                   /* reschedule alarm */
481
 
}
482
 
 
483
459
/**
484
460
  cleanup all memory and end program nicely.
485
461
 
516
492
}
517
493
 
518
494
 
519
 
static void clean_up(bool print_message)
 
495
void clean_up(bool print_message)
520
496
{
521
497
  if (cleanup_done++)
522
498
    return;
558
534
} /* clean_up */
559
535
 
560
536
 
561
 
static void clean_up_mutexes()
 
537
void clean_up_mutexes()
562
538
{
563
539
  (void) pthread_mutex_destroy(&LOCK_create_db);
564
540
  (void) pthread_mutex_destroy(&LOCK_open);
576
552
 
577
553
/* Change to run as another user if started with --user */
578
554
 
579
 
static struct passwd *check_user(const char *user)
 
555
passwd *check_user(const char *user)
580
556
{
581
 
  struct passwd *tmp_user_info;
 
557
  passwd *tmp_user_info;
582
558
  uid_t user_id= geteuid();
583
559
 
584
560
  // Don't bother if we aren't superuser
636
612
 
637
613
}
638
614
 
639
 
static void set_user(const char *user, struct passwd *user_info_arg)
 
615
void set_user(const char *user, passwd *user_info_arg)
640
616
{
641
617
  assert(user_info_arg != 0);
642
618
  /*
661
637
}
662
638
 
663
639
 
 
640
 
664
641
/** Change root user if started with @c --chroot . */
665
642
static void set_root(const char *path)
666
643
{
671
648
  }
672
649
}
673
650
 
674
 
extern "C" void end_thread_signal(int );
675
 
 
676
 
/** Called when a thread is aborted. */
677
 
extern "C" void end_thread_signal(int )
678
 
{
679
 
  Session *session=current_session;
680
 
  if (session)
681
 
  {
682
 
    statistic_increment(killed_threads, &LOCK_status);
683
 
    session->scheduler->killSessionNow(session);
684
 
    DRIZZLE_CONNECTION_DONE(session->thread_id);
685
 
  }
686
 
  return;
687
 
}
688
 
 
689
651
 
690
652
/*
691
653
  Unlink session from global list of available connections and free session
733
695
}
734
696
#endif
735
697
 
736
 
#if defined(BACKTRACE_DEMANGLE)
737
 
#include <cxxabi.h>
738
 
extern "C" char *my_demangle(const char *mangled_name, int *status)
739
 
{
740
 
  return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
741
 
}
742
 
#endif
743
 
 
744
 
extern "C" void handle_segfault(int sig);
745
 
 
746
 
extern "C" void handle_segfault(int sig)
747
 
{
748
 
  time_t curr_time;
749
 
  struct tm tm;
750
 
 
751
 
  /*
752
 
    Strictly speaking, one needs a mutex here
753
 
    but since we have got SIGSEGV already, things are a mess
754
 
    so not having the mutex is not as bad as possibly using a buggy
755
 
    mutex - so we keep things simple
756
 
  */
757
 
  if (segfaulted)
758
 
  {
759
 
    fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
760
 
    exit(1);
761
 
  }
762
 
 
763
 
  segfaulted = 1;
764
 
 
765
 
  curr_time= time(NULL);
766
 
  if(curr_time == (time_t)-1)
767
 
  {
768
 
    fprintf(stderr, "Fetal: time() call failed\n");
769
 
    exit(1);
770
 
  }
771
 
 
772
 
  localtime_r(&curr_time, &tm);
773
 
  
774
 
  fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
775
 
          "This could be because you hit a bug. It is also possible that "
776
 
          "this binary\n or one of the libraries it was linked against is "
777
 
          "corrupt, improperly built,\n or misconfigured. This error can "
778
 
          "also be caused by malfunctioning hardware.\n",
779
 
          tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
780
 
          tm.tm_hour, tm.tm_min, tm.tm_sec,
781
 
          sig);
782
 
  fprintf(stderr, _("We will try our best to scrape up some info that "
783
 
                    "will hopefully help diagnose\n"
784
 
                    "the problem, but since we have already crashed, "
785
 
                    "something is definitely wrong\nand this may fail.\n\n"));
786
 
  fprintf(stderr, "key_buffer_size=%u\n",
787
 
          (uint32_t) dflt_key_cache->key_cache_mem_size);
788
 
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
789
 
  fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
790
 
  fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
791
 
  fprintf(stderr, _("It is possible that drizzled could use up to \n"
792
 
                    "key_buffer_size + (read_buffer_size + "
793
 
                    "sort_buffer_size)*thread_count\n"
794
 
                    "bytes of memory\n"
795
 
                    "Hope that's ok; if not, decrease some variables in the "
796
 
                    "equation.\n\n"));
797
 
 
798
 
#ifdef HAVE_STACKTRACE
799
 
  Session *session= current_session;
800
 
 
801
 
  if (! (test_flags.test(TEST_NO_STACKTRACE)))
802
 
  {
803
 
    fprintf(stderr,"session: 0x%lx\n",(long) session);
804
 
    fprintf(stderr,_("Attempting backtrace. You can use the following "
805
 
                     "information to find out\n"
806
 
                     "where drizzled died. If you see no messages after this, "
807
 
                     "something went\n"
808
 
                     "terribly wrong...\n"));
809
 
    print_stacktrace(session ? (unsigned char*) session->thread_stack : (unsigned char*) 0,
810
 
                     my_thread_stack_size);
811
 
  }
812
 
  if (session)
813
 
  {
814
 
    const char *kreason= "UNKNOWN";
815
 
    switch (session->killed) {
816
 
    case Session::NOT_KILLED:
817
 
      kreason= "NOT_KILLED";
818
 
      break;
819
 
    case Session::KILL_BAD_DATA:
820
 
      kreason= "KILL_BAD_DATA";
821
 
      break;
822
 
    case Session::KILL_CONNECTION:
823
 
      kreason= "KILL_CONNECTION";
824
 
      break;
825
 
    case Session::KILL_QUERY:
826
 
      kreason= "KILL_QUERY";
827
 
      break;
828
 
    case Session::KILLED_NO_VALUE:
829
 
      kreason= "KILLED_NO_VALUE";
830
 
      break;
831
 
    }
832
 
    fprintf(stderr, _("Trying to get some variables.\n"
833
 
                      "Some pointers may be invalid and cause the "
834
 
                      "dump to abort...\n"));
835
 
    safe_print_str("session->query", session->query.c_str(), 1024);
836
 
    fprintf(stderr, "session->thread_id=%"PRIu32"\n", (uint32_t) session->thread_id);
837
 
    fprintf(stderr, "session->killed=%s\n", kreason);
838
 
  }
839
 
  fflush(stderr);
840
 
#endif /* HAVE_STACKTRACE */
841
 
 
842
 
  if (calling_initgroups)
843
 
    fprintf(stderr, _("\nThis crash occurred while the server was calling "
844
 
                      "initgroups(). This is\n"
845
 
                      "often due to the use of a drizzled that is statically "
846
 
                      "linked against glibc\n"
847
 
                      "and configured to use LDAP in /etc/nsswitch.conf. "
848
 
                      "You will need to either\n"
849
 
                      "upgrade to a version of glibc that does not have this "
850
 
                      "problem (2.3.4 or\n"
851
 
                      "later when used with nscd), disable LDAP in your "
852
 
                      "nsswitch.conf, or use a\n"
853
 
                      "drizzled that is not statically linked.\n"));
854
 
 
855
 
  if (internal::thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
856
 
    fprintf(stderr,
857
 
            _("\nYou are running a statically-linked LinuxThreads binary "
858
 
              "on an NPTL system.\n"
859
 
              "This can result in crashes on some distributions due "
860
 
              "to LT/NPTL conflicts.\n"
861
 
              "You should either build a dynamically-linked binary, or force "
862
 
              "LinuxThreads\n"
863
 
              "to be used with the LD_ASSUME_KERNEL environment variable. "
864
 
              "Please consult\n"
865
 
              "the documentation for your distribution on how to do that.\n"));
866
 
 
867
 
#ifdef HAVE_WRITE_CORE
868
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
869
 
  {
870
 
    fprintf(stderr, _("Writing a core file\n"));
871
 
    fflush(stderr);
872
 
    write_core(sig);
873
 
  }
874
 
#endif
875
 
 
876
 
  exit(1);
877
 
}
878
698
 
879
699
#ifndef SA_RESETHAND
880
700
#define SA_RESETHAND 0
884
704
#endif
885
705
 
886
706
 
887
 
/**
888
 
  All global error messages are sent here where the first one is stored
889
 
  for the client.
890
 
*/
891
 
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
 
707
 
 
708
 
 
709
const char *load_default_groups[]= 
892
710
{
893
 
  Session *session;
894
 
  /*
895
 
    Put here following assertion when situation with EE_* error codes
896
 
    will be fixed
897
 
  */
898
 
  if ((session= current_session))
899
 
  {
900
 
    if (MyFlags & ME_FATALERROR)
901
 
      session->is_fatal_error= 1;
902
 
 
903
 
    /*
904
 
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
905
 
      this could be improved by having a common stack of handlers.
906
 
    */
907
 
    if (session->handle_error(error, str,
908
 
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
909
 
      return;;
910
 
 
911
 
    /*
912
 
      session->lex->current_select == 0 if lex structure is not inited
913
 
      (not query command (COM_QUERY))
914
 
    */
915
 
    if (! (session->lex->current_select &&
916
 
        session->lex->current_select->no_error && !session->is_fatal_error))
917
 
    {
918
 
      if (! session->main_da.is_error())            // Return only first message
919
 
      {
920
 
        if (error == 0)
921
 
          error= ER_UNKNOWN_ERROR;
922
 
        if (str == NULL)
923
 
          str= ER(error);
924
 
        session->main_da.set_error_status(error, str);
925
 
      }
926
 
    }
927
 
 
928
 
    if (!session->no_warnings_for_error && !session->is_fatal_error)
929
 
    {
930
 
      /*
931
 
        Suppress infinite recursion if there a memory allocation error
932
 
        inside push_warning.
933
 
      */
934
 
      session->no_warnings_for_error= true;
935
 
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
936
 
      session->no_warnings_for_error= false;
937
 
    }
938
 
  }
939
 
  if (!session || MyFlags & ME_NOREFRESH)
940
 
    errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
941
 
}
942
 
 
943
 
 
944
 
static const char *load_default_groups[]= {
945
 
DRIZZLE_CONFIG_NAME, "server", 0, 0};
 
711
  DRIZZLE_CONFIG_NAME, "server", 0, 0
 
712
};
946
713
 
947
714
static int show_starttime(drizzle_show_var *var, char *buff)
948
715
{
964
731
 
965
732
static st_show_var_func_container show_flushstatustime_cont= { &show_flushstatustime };
966
733
 
967
 
/*
968
 
  Variables shown by SHOW STATUS in alphabetical order
969
 
*/
970
 
static drizzle_show_var com_status_vars[]= {
971
 
  {"admin_commands",       (char*) offsetof(system_status_var, com_other), SHOW_LONG_STATUS},
972
 
  {"alter_db",             (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
973
 
  {"alter_table",          (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
974
 
  {"analyze",              (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
975
 
  {"begin",                (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
976
 
  {"change_db",            (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
977
 
  {"check",                (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHECK]), SHOW_LONG_STATUS},
978
 
  {"checksum",             (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
979
 
  {"commit",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
980
 
  {"create_db",            (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
981
 
  {"create_index",         (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
982
 
  {"create_table",         (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
983
 
  {"delete",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DELETE]), SHOW_LONG_STATUS},
984
 
  {"drop_db",              (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
985
 
  {"drop_index",           (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
986
 
  {"drop_table",           (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
987
 
  {"empty_query",          (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
988
 
  {"flush",                (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
989
 
  {"insert",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_INSERT]), SHOW_LONG_STATUS},
990
 
  {"insert_select",        (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
991
 
  {"kill",                 (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_KILL]), SHOW_LONG_STATUS},
992
 
  {"load",                 (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_LOAD]), SHOW_LONG_STATUS},
993
 
  {"release_savepoint",    (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
994
 
  {"rename_table",         (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
995
 
  {"replace",              (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
996
 
  {"replace_select",       (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
997
 
  {"rollback",             (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
998
 
  {"rollback_to_savepoint",(char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
999
 
  {"savepoint",            (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
1000
 
  {"select",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SELECT]), SHOW_LONG_STATUS},
1001
 
  {"set_option",           (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
1002
 
  {"show_create_db",       (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
1003
 
  {"show_create_table",    (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
1004
 
  {"show_errors",          (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
1005
 
  {"show_warnings",        (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
1006
 
  {"truncate",             (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
1007
 
  {"unlock_tables",        (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
1008
 
  {"update",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
1009
 
  {NULL, NULL, SHOW_LONGLONG}
1010
 
};
1011
 
 
1012
734
static drizzle_show_var status_vars[]= {
1013
735
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONGLONG},
1014
736
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONGLONG},
1060
782
  {NULL, NULL, SHOW_LONGLONG}
1061
783
};
1062
784
 
1063
 
static int init_common_variables(const char *conf_file_name, int argc,
1064
 
                                 char **argv, const char **groups)
 
785
int init_common_variables(const char *conf_file_name, int argc,
 
786
                          char **argv, const char **groups)
1065
787
{
1066
788
  time_t curr_time;
1067
789
  umask(((~internal::my_umask) & 0666));
1105
827
    strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
1106
828
  strcpy(internal::fn_ext(pidfile_name),".pid");                // Add proper extension
1107
829
 
1108
 
  /*
1109
 
    Add server status variables to the dynamic list of
1110
 
    status variables that is shown by SHOW STATUS.
1111
 
    Later, in plugin_init, new entries could be added to that list.
1112
 
  */
1113
 
  if (add_com_status_vars(com_status_vars))
1114
 
    return 1; // an error was already reported
1115
 
 
1116
830
  if (add_status_vars(status_vars))
1117
831
    return 1; // an error was already reported
1118
832
 
1210
924
}
1211
925
 
1212
926
 
1213
 
static int init_server_components(plugin::Registry &plugins)
 
927
int init_server_components(plugin::Registry &plugins)
1214
928
{
1215
929
  /*
1216
930
    We need to call each of these following functions to ensure that
1445
1159
   NO_ARG, 0, 0, 0, 0, 0, 0},
1446
1160
  {"datadir", 'h',
1447
1161
   N_("Path to the database root."),
1448
 
   (char**) &drizzle_data_home,
1449
 
   (char**) &drizzle_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1162
   (char**) &data_home,
 
1163
   (char**) &data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1450
1164
  {"default-storage-engine", OPT_STORAGE_ENGINE,
1451
1165
   N_("Set the default storage engine (table type) for tables."),
1452
1166
   (char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
1792
1506
  drizzle_home[0]= pidfile_name[0]= 0;
1793
1507
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
1794
1508
  opt_secure_file_priv= 0;
1795
 
  segfaulted= 0;
1796
1509
  cleanup_done= 0;
1797
1510
  defaults_argc= 0;
1798
1511
  defaults_argv= 0;
1817
1530
  drizzle_home_ptr= drizzle_home;
1818
1531
  pidfile_name_ptr= pidfile_name;
1819
1532
  language_ptr= language;
1820
 
  drizzle_data_home= drizzle_real_data_home;
 
1533
  data_home= data_home_real;
1821
1534
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
1822
1535
  refresh_version= 1L;  /* Increments on each reload */
1823
1536
  global_thread_id= 1UL;
1825
1538
 
1826
1539
  /* Set directory paths */
1827
1540
  strncpy(language, LANGUAGE, sizeof(language)-1);
1828
 
  strncpy(drizzle_real_data_home, get_relative_path(LOCALSTATEDIR),
1829
 
          sizeof(drizzle_real_data_home)-1);
1830
 
  drizzle_data_home_buff[0]=FN_CURLIB;  // all paths are relative from here
1831
 
  drizzle_data_home_buff[1]=0;
1832
 
  drizzle_data_home_len= 2;
 
1541
  strncpy(data_home_real, get_relative_path(LOCALSTATEDIR),
 
1542
          sizeof(data_home_real)-1);
 
1543
  data_home_buff[0]=FN_CURLIB;  // all paths are relative from here
 
1544
  data_home_buff[1]=0;
 
1545
  data_home_len= 2;
1833
1546
 
1834
1547
  /* Variables in libraries */
1835
1548
  default_character_set_name= "utf8";
1876
1589
      default_collation_name= 0;
1877
1590
    break;
1878
1591
  case 'h':
1879
 
    strncpy(drizzle_real_data_home,argument, sizeof(drizzle_real_data_home)-1);
 
1592
    strncpy(data_home_real,argument, sizeof(data_home_real)-1);
1880
1593
    /* Correct pointer set by my_getopt (for embedded library) */
1881
 
    drizzle_data_home= drizzle_real_data_home;
1882
 
    drizzle_data_home_len= strlen(drizzle_data_home);
 
1594
    data_home= data_home_real;
 
1595
    data_home_len= strlen(data_home);
1883
1596
    break;
1884
1597
  case 'u':
1885
1598
    if (!drizzled_user || !strcmp(drizzled_user, argument))
2064
1777
    pos[0]= FN_LIBCHAR;
2065
1778
    pos[1]= 0;
2066
1779
  }
2067
 
  internal::convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
2068
 
  (void) internal::fn_format(buff, drizzle_real_data_home, "", "",
 
1780
  internal::convert_dirname(data_home_real,data_home_real,NULL);
 
1781
  (void) internal::fn_format(buff, data_home_real, "", "",
2069
1782
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
2070
 
  (void) internal::unpack_dirname(drizzle_unpacked_real_data_home, buff);
 
1783
  (void) internal::unpack_dirname(data_home_real_unpacked, buff);
2071
1784
  internal::convert_dirname(language,language,NULL);
2072
1785
  (void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
2073
 
  (void) internal::my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
2074
 
  (void) internal::my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
 
1786
  (void) internal::my_load_path(data_home_real, data_home_real,drizzle_home);
 
1787
  (void) internal::my_load_path(pidfile_name, pidfile_name,data_home_real);
2075
1788
 
2076
1789
  if (opt_plugin_dir_ptr == NULL)
2077
1790
  {
2098
1811
    {
2099
1812
      progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
2100
1813
    }
2101
 
    string testfile(progdir);
2102
 
    testfile.append("drizzled.o");
 
1814
    string testlofile(progdir);
 
1815
    testlofile.append("drizzled.lo");
 
1816
    string testofile(progdir);
 
1817
    testofile.append("drizzled.o");
2103
1818
    struct stat testfile_stat;
2104
 
    if (stat(testfile.c_str(), &testfile_stat))
 
1819
    if (stat(testlofile.c_str(), &testfile_stat) && stat(testofile.c_str(), &testfile_stat))
2105
1820
    {
2106
 
      /* drizzled.o doesn't exist - we are not in a source dir.
 
1821
      /* neither drizzled.lo or drizzled.o exist - we are not in a source dir.
2107
1822
       * Go on as usual
2108
1823
       */
2109
1824
      (void) internal::my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
2172
1887
 
2173
1888
} /* namespace drizzled */
2174
1889
 
2175
 
using namespace drizzled;
2176
 
 
2177
 
 
2178
 
static void init_signals(void)
2179
 
{
2180
 
  sigset_t set;
2181
 
  struct sigaction sa;
2182
 
 
2183
 
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
2184
 
        test_flags.test(TEST_CORE_ON_SIGNAL)))
2185
 
  {
2186
 
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
2187
 
    sigemptyset(&sa.sa_mask);
2188
 
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
2189
 
 
2190
 
    init_stacktrace();
2191
 
    sa.sa_handler=handle_segfault;
2192
 
    sigaction(SIGSEGV, &sa, NULL);
2193
 
    sigaction(SIGABRT, &sa, NULL);
2194
 
#ifdef SIGBUS
2195
 
    sigaction(SIGBUS, &sa, NULL);
2196
 
#endif
2197
 
    sigaction(SIGILL, &sa, NULL);
2198
 
    sigaction(SIGFPE, &sa, NULL);
2199
 
  }
2200
 
 
2201
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
2202
 
  {
2203
 
    /* Change limits so that we will get a core file */
2204
 
    struct rlimit rl;
2205
 
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
2206
 
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
2207
 
        errmsg_printf(ERRMSG_LVL_WARN,
2208
 
                      _("setrlimit could not change the size of core files "
2209
 
                        "to 'infinity';  We may not be able to generate a "
2210
 
                        "core file on signals"));
2211
 
  }
2212
 
  (void) sigemptyset(&set);
2213
 
  my_sigset(SIGPIPE,SIG_IGN);
2214
 
  sigaddset(&set,SIGPIPE);
2215
 
#ifndef IGNORE_SIGHUP_SIGQUIT
2216
 
  sigaddset(&set,SIGQUIT);
2217
 
  sigaddset(&set,SIGHUP);
2218
 
#endif
2219
 
  sigaddset(&set,SIGTERM);
2220
 
 
2221
 
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
2222
 
  sigemptyset(&sa.sa_mask);
2223
 
  sa.sa_flags = 0;
2224
 
  sa.sa_handler = print_signal_warning;
2225
 
  sigaction(SIGTERM, &sa, (struct sigaction*) 0);
2226
 
  sa.sa_flags = 0;
2227
 
  sa.sa_handler = print_signal_warning;
2228
 
  sigaction(SIGHUP, &sa, (struct sigaction*) 0);
2229
 
#ifdef SIGTSTP
2230
 
  sigaddset(&set,SIGTSTP);
2231
 
#endif
2232
 
  if (test_flags.test(TEST_SIGINT))
2233
 
  {
2234
 
    my_sigset(thr_kill_signal, end_thread_signal);
2235
 
    // May be SIGINT
2236
 
    sigdelset(&set, thr_kill_signal);
2237
 
  }
2238
 
  else
2239
 
    sigaddset(&set,SIGINT);
2240
 
  sigprocmask(SIG_SETMASK,&set,NULL);
2241
 
  pthread_sigmask(SIG_SETMASK,&set,NULL);
2242
 
  return;;
2243
 
}
2244
 
 
2245
 
int main(int argc, char **argv)
2246
 
{
2247
 
#if defined(ENABLE_NLS)
2248
 
# if defined(HAVE_LOCALE_H)
2249
 
  setlocale(LC_ALL, "");
2250
 
# endif
2251
 
  bindtextdomain("drizzle", LOCALEDIR);
2252
 
  textdomain("drizzle");
2253
 
#endif
2254
 
 
2255
 
  plugin::Registry &plugins= plugin::Registry::singleton();
2256
 
  plugin::Client *client;
2257
 
  Session *session;
2258
 
 
2259
 
  MY_INIT(argv[0]);             // init my_sys library & pthreads
2260
 
  /* nothing should come before this line ^^^ */
2261
 
 
2262
 
  /* Set signal used to kill Drizzle */
2263
 
#if defined(SIGUSR2)
2264
 
  thr_kill_signal= internal::thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
2265
 
#else
2266
 
  thr_kill_signal= SIGINT;
2267
 
#endif
2268
 
 
2269
 
  if (init_common_variables(DRIZZLE_CONFIG_NAME,
2270
 
                            argc, argv, load_default_groups))
2271
 
    unireg_abort(1);                            // Will do exit
2272
 
 
2273
 
  init_signals();
2274
 
 
2275
 
 
2276
 
  select_thread=pthread_self();
2277
 
  select_thread_in_use=1;
2278
 
 
2279
 
  if (chdir(drizzle_real_data_home) && !opt_help)
2280
 
  {
2281
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), drizzle_real_data_home);
2282
 
    unireg_abort(1);
2283
 
  }
2284
 
  drizzle_data_home= drizzle_data_home_buff;
2285
 
  drizzle_data_home[0]=FN_CURLIB;               // all paths are relative from here
2286
 
  drizzle_data_home[1]=0;
2287
 
  drizzle_data_home_len= 2;
2288
 
 
2289
 
  if ((user_info= check_user(drizzled_user)))
2290
 
  {
2291
 
    set_user(drizzled_user, user_info);
2292
 
  }
2293
 
 
2294
 
  if (server_id == 0)
2295
 
  {
2296
 
    server_id= 1;
2297
 
  }
2298
 
 
2299
 
  if (init_server_components(plugins))
2300
 
    unireg_abort(1);
2301
 
 
2302
 
  if (plugin::Listen::setup())
2303
 
    unireg_abort(1);
2304
 
 
2305
 
  /*
2306
 
    init signals & alarm
2307
 
    After this we can't quit by a simple unireg_abort
2308
 
  */
2309
 
  error_handler_hook= my_message_sql;
2310
 
 
2311
 
  assert(plugin::num_trx_monitored_objects > 0);
2312
 
  if (drizzle_rm_tmp_tables() ||
2313
 
      my_tz_init((Session *)0, default_tz_name))
2314
 
  {
2315
 
    abort_loop= true;
2316
 
    select_thread_in_use=0;
2317
 
    (void) pthread_kill(signal_thread, SIGTERM);
2318
 
 
2319
 
    (void) unlink(pidfile_name);        // Not needed anymore
2320
 
 
2321
 
    exit(1);
2322
 
  }
2323
 
 
2324
 
  init_status_vars();
2325
 
 
2326
 
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
2327
 
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
2328
 
 
2329
 
 
2330
 
  /* Listen for new connections and start new session for each connection
2331
 
     accepted. The listen.getClient() method will return NULL when the server
2332
 
     should be shutdown. */
2333
 
  while ((client= plugin::Listen::getClient()) != NULL)
2334
 
  {
2335
 
    if (!(session= new Session(client)))
2336
 
    {
2337
 
      delete client;
2338
 
      continue;
2339
 
    }
2340
 
 
2341
 
    /* If we error on creation we drop the connection and delete the session. */
2342
 
    if (session->schedule())
2343
 
      Session::unlink(session);
2344
 
  }
2345
 
 
2346
 
  /* (void) pthread_attr_destroy(&connection_attrib); */
2347
 
 
2348
 
 
2349
 
  (void) pthread_mutex_lock(&LOCK_thread_count);
2350
 
  select_thread_in_use=0;                       // For close_connections
2351
 
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2352
 
  (void) pthread_cond_broadcast(&COND_thread_count);
2353
 
 
2354
 
  /* Wait until cleanup is done */
2355
 
  (void) pthread_mutex_lock(&LOCK_thread_count);
2356
 
  while (!ready_to_exit)
2357
 
    pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
2358
 
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2359
 
 
2360
 
  clean_up(1);
2361
 
  plugin::Registry::shutdown();
2362
 
  clean_up_mutexes();
2363
 
  internal::my_end();
2364
 
  return 0;
2365
 
}
2366