~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Brian Aker
  • Date: 2010-04-17 19:30:18 UTC
  • mfrom: (1471.3.5 drizzled-as-lib)
  • Revision ID: brian@gaz-20100417193018-knv47o35k146bnow
Merge Monty

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>
54
53
#include "drizzled/session_list.h"
55
54
#include "drizzled/charset.h"
56
55
#include "plugin/myisam/myisam.h"
 
56
#include "drizzled/drizzled.h"
57
57
 
58
58
#include <google/protobuf/stubs/common.h>
59
59
 
73
73
#endif
74
74
#include <sys/socket.h>
75
75
 
76
 
#include <locale.h>
77
 
 
78
76
 
79
77
#include <errno.h>
80
78
#include <sys/stat.h>
85
83
#include <pwd.h>                                // For getpwent
86
84
#include <grp.h>
87
85
 
88
 
#include <sys/resource.h>
89
 
 
90
86
#ifdef HAVE_SELECT_H
91
87
#  include <select.h>
92
88
#endif
191
187
/*
192
188
  Used with --help for detailed option
193
189
*/
194
 
static bool opt_help= false;
195
 
static bool opt_help_extended= false;
 
190
bool opt_help= false;
 
191
bool opt_help_extended= false;
196
192
 
197
193
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
198
194
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
203
199
 
204
200
/* static variables */
205
201
 
206
 
static bool volatile select_thread_in_use;
207
 
static bool volatile ready_to_exit;
208
202
static bool opt_debugging= 0;
209
203
static uint32_t wake_thread;
210
 
static uint32_t killed_threads;
211
 
static char *drizzled_user, *drizzled_chroot;
 
204
static char *drizzled_chroot;
212
205
static char *language_ptr;
213
206
static const char *default_character_set_name;
214
207
static const char *character_set_filesystem_name;
219
212
 
220
213
/* Global variables */
221
214
 
 
215
bool volatile ready_to_exit;
 
216
char *drizzled_user;
 
217
bool volatile select_thread_in_use;
222
218
bool volatile abort_loop;
223
219
bool volatile shutdown_in_progress;
224
220
uint32_t max_used_connections;
235
231
 
236
232
char* opt_secure_file_priv= 0;
237
233
 
238
 
static bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
 
234
bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
239
235
 
240
236
uint32_t drizzled_bind_timeout;
241
237
std::bitset<12> test_flags;
294
290
char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
295
291
char *default_tz_name;
296
292
char glob_hostname[FN_REFLEN];
297
 
char drizzle_real_data_home[FN_REFLEN],
 
293
char data_home_real[FN_REFLEN],
298
294
     language[FN_REFLEN], 
299
295
     *opt_tc_log_file;
300
 
char drizzle_unpacked_real_data_home[FN_REFLEN];
 
296
char data_home_real_unpacked[FN_REFLEN];
301
297
const key_map key_map_empty(0);
302
298
key_map key_map_full(0);                        // Will be initialized later
303
299
 
304
 
uint32_t drizzle_data_home_len;
305
 
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;
306
302
char *drizzle_tmpdir= NULL;
307
303
char *opt_drizzle_tmpdir= NULL;
308
304
 
347
343
 
348
344
/* Static variables */
349
345
 
350
 
static bool segfaulted;
351
346
int cleanup_done;
352
347
static char *drizzle_home_ptr, *pidfile_name_ptr;
353
348
static int defaults_argc;
354
349
static char **defaults_argv;
355
350
 
356
 
struct passwd *user_info;
357
 
static pthread_t select_thread;
358
 
static uint32_t thr_kill_signal;
 
351
passwd *user_info;
359
352
 
360
353
/**
361
354
  Number of currently active user connections. The variable is protected by
379
372
static const char *get_relative_path(const char *path);
380
373
static void fix_paths(string &progname);
381
374
extern "C" pthread_handler_t handle_slave(void *arg);
382
 
static void clean_up(bool print_message);
383
375
 
384
376
static void usage(void);
385
 
static void clean_up_mutexes(void);
386
377
void close_connections(void);
387
378
 
388
379
/****************************************************************************
467
458
  }
468
459
}
469
460
 
470
 
extern "C" void print_signal_warning(int sig);
471
 
 
472
 
extern "C" void print_signal_warning(int sig)
473
 
{
474
 
  if (global_system_variables.log_warnings)
475
 
    errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu64),
476
 
                  sig, global_thread_id);
477
 
#ifndef HAVE_BSD_SIGNALS
478
 
  my_sigset(sig,print_signal_warning);          /* int. thread system calls */
479
 
#endif
480
 
  if (sig == SIGALRM)
481
 
    alarm(2);                                   /* reschedule alarm */
482
 
}
483
 
 
484
461
/**
485
462
  cleanup all memory and end program nicely.
486
463
 
517
494
}
518
495
 
519
496
 
520
 
static void clean_up(bool print_message)
 
497
void clean_up(bool print_message)
521
498
{
522
499
  if (cleanup_done++)
523
500
    return;
559
536
} /* clean_up */
560
537
 
561
538
 
562
 
static void clean_up_mutexes()
 
539
void clean_up_mutexes()
563
540
{
564
541
  (void) pthread_mutex_destroy(&LOCK_create_db);
565
542
  (void) pthread_mutex_destroy(&LOCK_open);
577
554
 
578
555
/* Change to run as another user if started with --user */
579
556
 
580
 
static struct passwd *check_user(const char *user)
 
557
passwd *check_user(const char *user)
581
558
{
582
 
  struct passwd *tmp_user_info;
 
559
  passwd *tmp_user_info;
583
560
  uid_t user_id= geteuid();
584
561
 
585
562
  // Don't bother if we aren't superuser
637
614
 
638
615
}
639
616
 
640
 
static void set_user(const char *user, struct passwd *user_info_arg)
 
617
void set_user(const char *user, passwd *user_info_arg)
641
618
{
642
619
  assert(user_info_arg != 0);
643
620
  /*
662
639
}
663
640
 
664
641
 
 
642
 
665
643
/** Change root user if started with @c --chroot . */
666
644
static void set_root(const char *path)
667
645
{
672
650
  }
673
651
}
674
652
 
675
 
extern "C" void end_thread_signal(int );
676
 
 
677
 
/** Called when a thread is aborted. */
678
 
extern "C" void end_thread_signal(int )
679
 
{
680
 
  Session *session=current_session;
681
 
  if (session)
682
 
  {
683
 
    statistic_increment(killed_threads, &LOCK_status);
684
 
    session->scheduler->killSessionNow(session);
685
 
    DRIZZLE_CONNECTION_DONE(session->thread_id);
686
 
  }
687
 
  return;
688
 
}
689
 
 
690
653
 
691
654
/*
692
655
  Unlink session from global list of available connections and free session
734
697
}
735
698
#endif
736
699
 
737
 
#if defined(BACKTRACE_DEMANGLE)
738
 
#include <cxxabi.h>
739
 
extern "C" char *my_demangle(const char *mangled_name, int *status)
740
 
{
741
 
  return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
742
 
}
743
 
#endif
744
 
 
745
 
extern "C" void handle_segfault(int sig);
746
 
 
747
 
extern "C" void handle_segfault(int sig)
748
 
{
749
 
  time_t curr_time;
750
 
  struct tm tm;
751
 
 
752
 
  /*
753
 
    Strictly speaking, one needs a mutex here
754
 
    but since we have got SIGSEGV already, things are a mess
755
 
    so not having the mutex is not as bad as possibly using a buggy
756
 
    mutex - so we keep things simple
757
 
  */
758
 
  if (segfaulted)
759
 
  {
760
 
    fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
761
 
    exit(1);
762
 
  }
763
 
 
764
 
  segfaulted = 1;
765
 
 
766
 
  curr_time= time(NULL);
767
 
  if(curr_time == (time_t)-1)
768
 
  {
769
 
    fprintf(stderr, "Fetal: time() call failed\n");
770
 
    exit(1);
771
 
  }
772
 
 
773
 
  localtime_r(&curr_time, &tm);
774
 
  
775
 
  fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
776
 
          "This could be because you hit a bug. It is also possible that "
777
 
          "this binary\n or one of the libraries it was linked against is "
778
 
          "corrupt, improperly built,\n or misconfigured. This error can "
779
 
          "also be caused by malfunctioning hardware.\n",
780
 
          tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
781
 
          tm.tm_hour, tm.tm_min, tm.tm_sec,
782
 
          sig);
783
 
  fprintf(stderr, _("We will try our best to scrape up some info that "
784
 
                    "will hopefully help diagnose\n"
785
 
                    "the problem, but since we have already crashed, "
786
 
                    "something is definitely wrong\nand this may fail.\n\n"));
787
 
  fprintf(stderr, "key_buffer_size=%u\n",
788
 
          (uint32_t) dflt_key_cache->key_cache_mem_size);
789
 
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
790
 
  fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
791
 
  fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
792
 
  fprintf(stderr, _("It is possible that drizzled could use up to \n"
793
 
                    "key_buffer_size + (read_buffer_size + "
794
 
                    "sort_buffer_size)*thread_count\n"
795
 
                    "bytes of memory\n"
796
 
                    "Hope that's ok; if not, decrease some variables in the "
797
 
                    "equation.\n\n"));
798
 
 
799
 
#ifdef HAVE_STACKTRACE
800
 
  Session *session= current_session;
801
 
 
802
 
  if (! (test_flags.test(TEST_NO_STACKTRACE)))
803
 
  {
804
 
    fprintf(stderr,"session: 0x%lx\n",(long) session);
805
 
    fprintf(stderr,_("Attempting backtrace. You can use the following "
806
 
                     "information to find out\n"
807
 
                     "where drizzled died. If you see no messages after this, "
808
 
                     "something went\n"
809
 
                     "terribly wrong...\n"));
810
 
    print_stacktrace(session ? (unsigned char*) session->thread_stack : (unsigned char*) 0,
811
 
                     my_thread_stack_size);
812
 
  }
813
 
  if (session)
814
 
  {
815
 
    const char *kreason= "UNKNOWN";
816
 
    switch (session->killed) {
817
 
    case Session::NOT_KILLED:
818
 
      kreason= "NOT_KILLED";
819
 
      break;
820
 
    case Session::KILL_BAD_DATA:
821
 
      kreason= "KILL_BAD_DATA";
822
 
      break;
823
 
    case Session::KILL_CONNECTION:
824
 
      kreason= "KILL_CONNECTION";
825
 
      break;
826
 
    case Session::KILL_QUERY:
827
 
      kreason= "KILL_QUERY";
828
 
      break;
829
 
    case Session::KILLED_NO_VALUE:
830
 
      kreason= "KILLED_NO_VALUE";
831
 
      break;
832
 
    }
833
 
    fprintf(stderr, _("Trying to get some variables.\n"
834
 
                      "Some pointers may be invalid and cause the "
835
 
                      "dump to abort...\n"));
836
 
    safe_print_str("session->query", session->query.c_str(), 1024);
837
 
    fprintf(stderr, "session->thread_id=%"PRIu32"\n", (uint32_t) session->thread_id);
838
 
    fprintf(stderr, "session->killed=%s\n", kreason);
839
 
  }
840
 
  fflush(stderr);
841
 
#endif /* HAVE_STACKTRACE */
842
 
 
843
 
  if (calling_initgroups)
844
 
    fprintf(stderr, _("\nThis crash occurred while the server was calling "
845
 
                      "initgroups(). This is\n"
846
 
                      "often due to the use of a drizzled that is statically "
847
 
                      "linked against glibc\n"
848
 
                      "and configured to use LDAP in /etc/nsswitch.conf. "
849
 
                      "You will need to either\n"
850
 
                      "upgrade to a version of glibc that does not have this "
851
 
                      "problem (2.3.4 or\n"
852
 
                      "later when used with nscd), disable LDAP in your "
853
 
                      "nsswitch.conf, or use a\n"
854
 
                      "drizzled that is not statically linked.\n"));
855
 
 
856
 
  if (internal::thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
857
 
    fprintf(stderr,
858
 
            _("\nYou are running a statically-linked LinuxThreads binary "
859
 
              "on an NPTL system.\n"
860
 
              "This can result in crashes on some distributions due "
861
 
              "to LT/NPTL conflicts.\n"
862
 
              "You should either build a dynamically-linked binary, or force "
863
 
              "LinuxThreads\n"
864
 
              "to be used with the LD_ASSUME_KERNEL environment variable. "
865
 
              "Please consult\n"
866
 
              "the documentation for your distribution on how to do that.\n"));
867
 
 
868
 
#ifdef HAVE_WRITE_CORE
869
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
870
 
  {
871
 
    fprintf(stderr, _("Writing a core file\n"));
872
 
    fflush(stderr);
873
 
    write_core(sig);
874
 
  }
875
 
#endif
876
 
 
877
 
  exit(1);
878
 
}
879
700
 
880
701
#ifndef SA_RESETHAND
881
702
#define SA_RESETHAND 0
885
706
#endif
886
707
 
887
708
 
888
 
/**
889
 
  All global error messages are sent here where the first one is stored
890
 
  for the client.
891
 
*/
892
 
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
 
709
 
 
710
 
 
711
const char *load_default_groups[]= 
893
712
{
894
 
  Session *session;
895
 
  /*
896
 
    Put here following assertion when situation with EE_* error codes
897
 
    will be fixed
898
 
  */
899
 
  if ((session= current_session))
900
 
  {
901
 
    if (MyFlags & ME_FATALERROR)
902
 
      session->is_fatal_error= 1;
903
 
 
904
 
    /*
905
 
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
906
 
      this could be improved by having a common stack of handlers.
907
 
    */
908
 
    if (session->handle_error(error, str,
909
 
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
910
 
      return;;
911
 
 
912
 
    /*
913
 
      session->lex->current_select == 0 if lex structure is not inited
914
 
      (not query command (COM_QUERY))
915
 
    */
916
 
    if (! (session->lex->current_select &&
917
 
        session->lex->current_select->no_error && !session->is_fatal_error))
918
 
    {
919
 
      if (! session->main_da.is_error())            // Return only first message
920
 
      {
921
 
        if (error == 0)
922
 
          error= ER_UNKNOWN_ERROR;
923
 
        if (str == NULL)
924
 
          str= ER(error);
925
 
        session->main_da.set_error_status(error, str);
926
 
      }
927
 
    }
928
 
 
929
 
    if (!session->no_warnings_for_error && !session->is_fatal_error)
930
 
    {
931
 
      /*
932
 
        Suppress infinite recursion if there a memory allocation error
933
 
        inside push_warning.
934
 
      */
935
 
      session->no_warnings_for_error= true;
936
 
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
937
 
      session->no_warnings_for_error= false;
938
 
    }
939
 
  }
940
 
  if (!session || MyFlags & ME_NOREFRESH)
941
 
    errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
942
 
}
943
 
 
944
 
 
945
 
static const char *load_default_groups[]= {
946
 
DRIZZLE_CONFIG_NAME, "server", 0, 0};
 
713
  DRIZZLE_CONFIG_NAME, "server", 0, 0
 
714
};
947
715
 
948
716
static int show_starttime(drizzle_show_var *var, char *buff)
949
717
{
1061
829
  {NULL, NULL, SHOW_LONGLONG}
1062
830
};
1063
831
 
1064
 
static int init_common_variables(const char *conf_file_name, int argc,
1065
 
                                 char **argv, const char **groups)
 
832
int init_common_variables(const char *conf_file_name, int argc,
 
833
                          char **argv, const char **groups)
1066
834
{
1067
835
  time_t curr_time;
1068
836
  umask(((~internal::my_umask) & 0666));
1211
979
}
1212
980
 
1213
981
 
1214
 
static int init_server_components(plugin::Registry &plugins)
 
982
int init_server_components(plugin::Registry &plugins)
1215
983
{
1216
984
  /*
1217
985
    We need to call each of these following functions to ensure that
1446
1214
   NO_ARG, 0, 0, 0, 0, 0, 0},
1447
1215
  {"datadir", 'h',
1448
1216
   N_("Path to the database root."),
1449
 
   (char**) &drizzle_data_home,
1450
 
   (char**) &drizzle_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1217
   (char**) &data_home,
 
1218
   (char**) &data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1451
1219
  {"default-storage-engine", OPT_STORAGE_ENGINE,
1452
1220
   N_("Set the default storage engine (table type) for tables."),
1453
1221
   (char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
1793
1561
  drizzle_home[0]= pidfile_name[0]= 0;
1794
1562
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
1795
1563
  opt_secure_file_priv= 0;
1796
 
  segfaulted= 0;
1797
1564
  cleanup_done= 0;
1798
1565
  defaults_argc= 0;
1799
1566
  defaults_argv= 0;
1818
1585
  drizzle_home_ptr= drizzle_home;
1819
1586
  pidfile_name_ptr= pidfile_name;
1820
1587
  language_ptr= language;
1821
 
  drizzle_data_home= drizzle_real_data_home;
 
1588
  data_home= data_home_real;
1822
1589
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
1823
1590
  refresh_version= 1L;  /* Increments on each reload */
1824
1591
  global_thread_id= 1UL;
1826
1593
 
1827
1594
  /* Set directory paths */
1828
1595
  strncpy(language, LANGUAGE, sizeof(language)-1);
1829
 
  strncpy(drizzle_real_data_home, get_relative_path(LOCALSTATEDIR),
1830
 
          sizeof(drizzle_real_data_home)-1);
1831
 
  drizzle_data_home_buff[0]=FN_CURLIB;  // all paths are relative from here
1832
 
  drizzle_data_home_buff[1]=0;
1833
 
  drizzle_data_home_len= 2;
 
1596
  strncpy(data_home_real, get_relative_path(LOCALSTATEDIR),
 
1597
          sizeof(data_home_real)-1);
 
1598
  data_home_buff[0]=FN_CURLIB;  // all paths are relative from here
 
1599
  data_home_buff[1]=0;
 
1600
  data_home_len= 2;
1834
1601
 
1835
1602
  /* Variables in libraries */
1836
1603
  default_character_set_name= "utf8";
1877
1644
      default_collation_name= 0;
1878
1645
    break;
1879
1646
  case 'h':
1880
 
    strncpy(drizzle_real_data_home,argument, sizeof(drizzle_real_data_home)-1);
 
1647
    strncpy(data_home_real,argument, sizeof(data_home_real)-1);
1881
1648
    /* Correct pointer set by my_getopt (for embedded library) */
1882
 
    drizzle_data_home= drizzle_real_data_home;
1883
 
    drizzle_data_home_len= strlen(drizzle_data_home);
 
1649
    data_home= data_home_real;
 
1650
    data_home_len= strlen(data_home);
1884
1651
    break;
1885
1652
  case 'u':
1886
1653
    if (!drizzled_user || !strcmp(drizzled_user, argument))
2065
1832
    pos[0]= FN_LIBCHAR;
2066
1833
    pos[1]= 0;
2067
1834
  }
2068
 
  internal::convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
2069
 
  (void) internal::fn_format(buff, drizzle_real_data_home, "", "",
 
1835
  internal::convert_dirname(data_home_real,data_home_real,NULL);
 
1836
  (void) internal::fn_format(buff, data_home_real, "", "",
2070
1837
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
2071
 
  (void) internal::unpack_dirname(drizzle_unpacked_real_data_home, buff);
 
1838
  (void) internal::unpack_dirname(data_home_real_unpacked, buff);
2072
1839
  internal::convert_dirname(language,language,NULL);
2073
1840
  (void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
2074
 
  (void) internal::my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
2075
 
  (void) internal::my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
 
1841
  (void) internal::my_load_path(data_home_real, data_home_real,drizzle_home);
 
1842
  (void) internal::my_load_path(pidfile_name, pidfile_name,data_home_real);
2076
1843
 
2077
1844
  if (opt_plugin_dir_ptr == NULL)
2078
1845
  {
2100
1867
      progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
2101
1868
    }
2102
1869
    string testfile(progdir);
2103
 
    testfile.append("drizzled.o");
 
1870
    testfile.append("drizzled.lo");
2104
1871
    struct stat testfile_stat;
2105
1872
    if (stat(testfile.c_str(), &testfile_stat))
2106
1873
    {
2107
 
      /* drizzled.o doesn't exist - we are not in a source dir.
 
1874
      /* drizzled.lo doesn't exist - we are not in a source dir.
2108
1875
       * Go on as usual
2109
1876
       */
2110
1877
      (void) internal::my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
2173
1940
 
2174
1941
} /* namespace drizzled */
2175
1942
 
2176
 
using namespace drizzled;
2177
 
 
2178
 
 
2179
 
static void init_signals(void)
2180
 
{
2181
 
  sigset_t set;
2182
 
  struct sigaction sa;
2183
 
 
2184
 
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
2185
 
        test_flags.test(TEST_CORE_ON_SIGNAL)))
2186
 
  {
2187
 
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
2188
 
    sigemptyset(&sa.sa_mask);
2189
 
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
2190
 
 
2191
 
    init_stacktrace();
2192
 
    sa.sa_handler=handle_segfault;
2193
 
    sigaction(SIGSEGV, &sa, NULL);
2194
 
    sigaction(SIGABRT, &sa, NULL);
2195
 
#ifdef SIGBUS
2196
 
    sigaction(SIGBUS, &sa, NULL);
2197
 
#endif
2198
 
    sigaction(SIGILL, &sa, NULL);
2199
 
    sigaction(SIGFPE, &sa, NULL);
2200
 
  }
2201
 
 
2202
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
2203
 
  {
2204
 
    /* Change limits so that we will get a core file */
2205
 
    struct rlimit rl;
2206
 
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
2207
 
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
2208
 
        errmsg_printf(ERRMSG_LVL_WARN,
2209
 
                      _("setrlimit could not change the size of core files "
2210
 
                        "to 'infinity';  We may not be able to generate a "
2211
 
                        "core file on signals"));
2212
 
  }
2213
 
  (void) sigemptyset(&set);
2214
 
  my_sigset(SIGPIPE,SIG_IGN);
2215
 
  sigaddset(&set,SIGPIPE);
2216
 
#ifndef IGNORE_SIGHUP_SIGQUIT
2217
 
  sigaddset(&set,SIGQUIT);
2218
 
  sigaddset(&set,SIGHUP);
2219
 
#endif
2220
 
  sigaddset(&set,SIGTERM);
2221
 
 
2222
 
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
2223
 
  sigemptyset(&sa.sa_mask);
2224
 
  sa.sa_flags = 0;
2225
 
  sa.sa_handler = print_signal_warning;
2226
 
  sigaction(SIGTERM, &sa, (struct sigaction*) 0);
2227
 
  sa.sa_flags = 0;
2228
 
  sa.sa_handler = print_signal_warning;
2229
 
  sigaction(SIGHUP, &sa, (struct sigaction*) 0);
2230
 
#ifdef SIGTSTP
2231
 
  sigaddset(&set,SIGTSTP);
2232
 
#endif
2233
 
  if (test_flags.test(TEST_SIGINT))
2234
 
  {
2235
 
    my_sigset(thr_kill_signal, end_thread_signal);
2236
 
    // May be SIGINT
2237
 
    sigdelset(&set, thr_kill_signal);
2238
 
  }
2239
 
  else
2240
 
    sigaddset(&set,SIGINT);
2241
 
  sigprocmask(SIG_SETMASK,&set,NULL);
2242
 
  pthread_sigmask(SIG_SETMASK,&set,NULL);
2243
 
  return;;
2244
 
}
2245
 
 
2246
 
int main(int argc, char **argv)
2247
 
{
2248
 
#if defined(ENABLE_NLS)
2249
 
# if defined(HAVE_LOCALE_H)
2250
 
  setlocale(LC_ALL, "");
2251
 
# endif
2252
 
  bindtextdomain("drizzle", LOCALEDIR);
2253
 
  textdomain("drizzle");
2254
 
#endif
2255
 
 
2256
 
  plugin::Registry &plugins= plugin::Registry::singleton();
2257
 
  plugin::Client *client;
2258
 
  Session *session;
2259
 
 
2260
 
  MY_INIT(argv[0]);             // init my_sys library & pthreads
2261
 
  /* nothing should come before this line ^^^ */
2262
 
 
2263
 
  /* Set signal used to kill Drizzle */
2264
 
#if defined(SIGUSR2)
2265
 
  thr_kill_signal= internal::thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
2266
 
#else
2267
 
  thr_kill_signal= SIGINT;
2268
 
#endif
2269
 
 
2270
 
  if (init_common_variables(DRIZZLE_CONFIG_NAME,
2271
 
                            argc, argv, load_default_groups))
2272
 
    unireg_abort(1);                            // Will do exit
2273
 
 
2274
 
  init_signals();
2275
 
 
2276
 
 
2277
 
  select_thread=pthread_self();
2278
 
  select_thread_in_use=1;
2279
 
 
2280
 
  if (chdir(drizzle_real_data_home) && !opt_help)
2281
 
  {
2282
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), drizzle_real_data_home);
2283
 
    unireg_abort(1);
2284
 
  }
2285
 
  drizzle_data_home= drizzle_data_home_buff;
2286
 
  drizzle_data_home[0]=FN_CURLIB;               // all paths are relative from here
2287
 
  drizzle_data_home[1]=0;
2288
 
  drizzle_data_home_len= 2;
2289
 
 
2290
 
  if ((user_info= check_user(drizzled_user)))
2291
 
  {
2292
 
    set_user(drizzled_user, user_info);
2293
 
  }
2294
 
 
2295
 
  if (server_id == 0)
2296
 
  {
2297
 
    server_id= 1;
2298
 
  }
2299
 
 
2300
 
  if (init_server_components(plugins))
2301
 
    unireg_abort(1);
2302
 
 
2303
 
  /**
2304
 
   * This check must be done after init_server_components for now
2305
 
   * because we don't yet have plugin dependency tracking...
2306
 
   *
2307
 
   * ReplicationServices::evaluateRegisteredPlugins() will print error messages to stderr
2308
 
   * via errmsg_printf().
2309
 
   *
2310
 
   * @todo
2311
 
   *
2312
 
   * not checking return since unireg_abort() hangs
2313
 
   */
2314
 
  ReplicationServices &replication_services= ReplicationServices::singleton();
2315
 
  (void) replication_services.evaluateRegisteredPlugins();
2316
 
 
2317
 
  if (plugin::Listen::setup())
2318
 
    unireg_abort(1);
2319
 
 
2320
 
  /*
2321
 
    init signals & alarm
2322
 
    After this we can't quit by a simple unireg_abort
2323
 
  */
2324
 
  error_handler_hook= my_message_sql;
2325
 
 
2326
 
  assert(plugin::num_trx_monitored_objects > 0);
2327
 
  if (drizzle_rm_tmp_tables() ||
2328
 
      my_tz_init((Session *)0, default_tz_name))
2329
 
  {
2330
 
    abort_loop= true;
2331
 
    select_thread_in_use=0;
2332
 
    (void) pthread_kill(signal_thread, SIGTERM);
2333
 
 
2334
 
    (void) unlink(pidfile_name);        // Not needed anymore
2335
 
 
2336
 
    exit(1);
2337
 
  }
2338
 
 
2339
 
  init_status_vars();
2340
 
 
2341
 
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
2342
 
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
2343
 
 
2344
 
 
2345
 
  /* Listen for new connections and start new session for each connection
2346
 
     accepted. The listen.getClient() method will return NULL when the server
2347
 
     should be shutdown. */
2348
 
  while ((client= plugin::Listen::getClient()) != NULL)
2349
 
  {
2350
 
    if (!(session= new Session(client)))
2351
 
    {
2352
 
      delete client;
2353
 
      continue;
2354
 
    }
2355
 
 
2356
 
    /* If we error on creation we drop the connection and delete the session. */
2357
 
    if (session->schedule())
2358
 
      Session::unlink(session);
2359
 
  }
2360
 
 
2361
 
  /* (void) pthread_attr_destroy(&connection_attrib); */
2362
 
 
2363
 
 
2364
 
  (void) pthread_mutex_lock(&LOCK_thread_count);
2365
 
  select_thread_in_use=0;                       // For close_connections
2366
 
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2367
 
  (void) pthread_cond_broadcast(&COND_thread_count);
2368
 
 
2369
 
  /* Wait until cleanup is done */
2370
 
  (void) pthread_mutex_lock(&LOCK_thread_count);
2371
 
  while (!ready_to_exit)
2372
 
    pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
2373
 
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2374
 
 
2375
 
  clean_up(1);
2376
 
  plugin::Registry::shutdown();
2377
 
  clean_up_mutexes();
2378
 
  internal::my_end();
2379
 
  return 0;
2380
 
}
2381