src/tools/csqlserver.cxx

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by www.databasecache.com                           *
00003  *   Contact: praba_tuty@databasecache.com                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015   ***************************************************************************/
00016 #include<CSql.h>
00017 #include<SessionImpl.h>
00018 #include<Debug.h>
00019 #include<Process.h>
00020 #include<Database.h>
00021 #include<Transaction.h>
00022 #include<Lock.h>
00023 #include<CacheTableLoader.h>
00024 char* version = "csql-linux-i686-2.0GA";
00025 int srvStop =0;
00026 pid_t replpid=0;
00027 pid_t cachepid=0;
00028 void dumpData();
00029 static void sigTermHandler(int sig)
00030 {
00031     printf("Received signal %d\nStopping the server\n", sig);
00032     srvStop = 1;
00033 }
00034 
00035 bool checkDead(pid_t  pid)
00036 {
00037     int ret = os::kill(pid, 0);
00038     if (ret == -1) return true; else return false;
00039 }
00040 
00041 DbRetVal releaseAllResources(Database *sysdb, ThreadInfo *info )
00042 {
00043     printf("Releasing all the resources for process %d %lu\n", info->pid_, info->thrid_);
00044     //recover for all the mutexes in has_
00045     for (int i =0;  i < MAX_MUTEX_PER_THREAD; i++)
00046     {
00047         if (info->has_[i] != NULL) 
00048         {
00049             printf("Dead Procs: %d %lu holding mutex %x %s \n", info->pid_, info->thrid_, info->has_[i], info->has_[i]->name);
00050             logFine(logger, "Dead Procs: %d %lu holding mutex %x %s \n", info->pid_, info->thrid_, info->has_[i], info->has_[i]->name);
00051             //TODO::recovery of mutexes 
00052             //info->has_[i]->recoverMutex();
00053             srvStop = 1;
00054             return ErrSysFatal;
00055         }
00056     }
00057     TransactionManager *tm = new TransactionManager();
00058     LockManager *lm = new LockManager(sysdb);
00059     for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
00060     {
00061         if (info->thrTrans_[i].trans_ != NULL && info->thrTrans_[i].trans_->status_ == TransRunning)
00062         {
00063             printf("Rollback Transaction %x\n", info->thrTrans_[i].trans_);
00064             tm->rollback(lm, info->thrTrans_[i].trans_);
00065         }
00066     }
00067     info->init();
00068     delete tm;
00069     delete lm;
00070     return OK;
00071 }
00072 
00073 DbRetVal cleanupDeadProcs(Database *sysdb)
00074 {
00075     DbRetVal rv = sysdb->getProcessTableMutex(false);
00076     if (OK != rv)
00077     {
00078         printError(rv,"Unable to get process table mutex");
00079         return rv;
00080     }
00081     pid_t pid;
00082     pid = os::getpid();
00083     pthread_t thrid = os::getthrid();
00084 
00085 
00086     ThreadInfo* pInfo = sysdb->getThreadInfo(0);
00087     int i=0;
00088     ThreadInfo* freeSlot = NULL;
00089     for (; i < Conf::config.getMaxProcs(); i++)
00090     {
00091         //check whether it is alive
00092         if (pInfo->pid_ !=0 && checkDead(pInfo->pid_)) releaseAllResources(sysdb, pInfo);
00093         pInfo++;
00094     }
00095     sysdb->releaseProcessTableMutex(false);
00096     return OK;
00097 }
00098 
00099 
00100 DbRetVal logActiveProcs(Database *sysdb)
00101 {
00102     DbRetVal rv = sysdb->getProcessTableMutex(false);
00103     if (OK != rv)
00104     {
00105         printError(rv,"Unable to get process table mutex");
00106         return rv;
00107     }
00108     ThreadInfo* pInfo = sysdb->getThreadInfo(0);
00109     int i=0;
00110     ThreadInfo* freeSlot = NULL;
00111     for (; i < Conf::config.getMaxProcs(); i++)
00112     {
00113         if (pInfo->pid_ !=0 )  logFine(logger, "Registered Procs: %d %lu\n", pInfo->pid_, pInfo->thrid_);
00114         pInfo++;
00115     }
00116     sysdb->releaseProcessTableMutex(false);
00117     return OK;
00118 }
00119 void startCacheServer()
00120 {
00121      printf("Starting Cache Recv Server\n");
00122      char execName[1024];
00123      sprintf(execName, "%s/bin/csqlcacheserver", os::getenv("CSQL_INSTALL_ROOT"));
00124      printf("filename is %s\n", execName);
00125      cachepid = os::createProcess(execName, "-s");
00126      if (cachepid != -1)
00127          printf("Cache Recv Server Started pid=%d\n", cachepid);
00128      return;
00129 }
00130 
00131 void printUsage()
00132 {
00133    printf("Usage: csqlserver [-c] [-v]\n");
00134    printf("       v -> print the version.\n");
00135    printf("       c -> recover all cached tables from the target database.\n");
00136    printf("Description: Start the csql server and initialize the database.\n");
00137    return;
00138 }
00139 int main(int argc, char **argv)
00140 {
00141     int c = 0, opt = 0;
00142     while ((c = getopt(argc, argv, "cv?")) != EOF) 
00143     {
00144         switch (c)
00145         {
00146             case '?' : { opt = 10; break; } //print help 
00147             case 'c' : { opt = 1; break; } //recover all the tables from cache
00148             case 'v' : { opt = 2; break; } //print version
00149             default: opt=10; 
00150 
00151         }
00152     }//while options
00153 
00154     if (opt == 10) {
00155         printUsage();
00156         return 0;
00157     }else if (opt ==2) {
00158         printf("%s\n",version);
00159         return 0;
00160     }
00161 
00162     SessionImpl session;
00163     DbRetVal rv = session.readConfigFile();
00164     if (rv != OK)
00165     {
00166         printf("Unable to read the configuration file \n");
00167         return 1;
00168     }
00169     os::signal(SIGINT, sigTermHandler);
00170     os::signal(SIGTERM, sigTermHandler);
00171     rv = logger.startLogger(Conf::config.getLogFile(), true);
00172     if (rv != OK)
00173     {
00174         printf("Unable to start the logger\n");
00175         return 2;
00176     }
00177 
00178     logFine(logger, "Server Started");
00179     int ret  = session.initSystemDatabase();
00180     if (0  != ret)
00181     {
00182         printf(" System Database Initialization failed\n");
00183         return 3;
00184     }
00185     printf("System Database initialized\n");
00186 
00187 
00188     bool end = false;
00189 
00190     struct timeval timeout, tval;
00191     timeout.tv_sec = 5;
00192     timeout.tv_usec = 0;
00193     Database* sysdb = session.getSystemDatabase();
00194     if (FILE *file = fopen(Conf::config.getDbFile(), "r"))
00195     {
00196         fclose(file);
00197         char cmd[1024];
00198         sprintf(cmd, "csql -S -s %s",Conf::config.getDbFile()); 
00199         int ret = system(cmd);
00200         if (ret != 0) { 
00201             printf("Tables cannot be recovered. DB file corrupted\n");
00202         }
00203     }
00204     if (opt == 1) {
00205         if (Conf::config.useCache()) {
00206             printf("Database server recovering cached tables...\n");
00207             int ret = system("cachetable -U root -P manager -R");
00208             if (ret != 0) { 
00209                 printf("Cached Tables recovery failed %d\n", ret);
00210                 logger.stopLogger();
00211                 session.destroySystemDatabase();
00212                 return 2;
00213             }
00214             printf("Cached Tables recovered\n");
00215         } else {
00216             printf("Cache mode is not set in csql.conf. Cannot recover\n");
00217             logger.stopLogger();
00218             session.destroySystemDatabase();
00219             return 1;
00220         }
00221     }
00222     if (Conf::config.useReplication())
00223     {
00224         printf("Starting Replication Server\n");
00225         char execName[1024];
00226         sprintf(execName, "%s/bin/csqlreplserver", os::getenv("CSQL_INSTALL_ROOT"));
00227         printf("filename is %s\n", execName);
00228         replpid = os::createProcess(execName, "-s");
00229         if (replpid != -1) 
00230             printf("Repl Server Started pid=%d\n", replpid);
00231         
00232     }
00233     if (Conf::config.useCache() && Conf::config.useTwoWayCache()) startCacheServer();
00234 
00235     printf("Database server started\n");
00236 
00237     while(!srvStop)
00238     {
00239         tval.tv_sec = timeout.tv_sec;
00240         tval.tv_usec = timeout.tv_usec;
00241         os::select(0, 0, 0, 0, &tval);
00242         
00243         //send signal to all the registered process..check they are alive
00244         cleanupDeadProcs(sysdb);
00245 
00246         //TODO::check repl server is alive, if not restart it
00247         
00248         //TODO::if it fails to start 5 times, exit
00249         if (cachepid !=0  && checkDead(cachepid)) startCacheServer();
00250         
00251     }
00252     os::kill(cachepid, SIGTERM);
00253     dumpData();
00254     logFine(logger, "Server Exiting");
00255     logActiveProcs(sysdb);
00256     printf("Server Exiting\n");
00257     logFine(logger, "Server Ended");
00258     logger.stopLogger();
00259     session.destroySystemDatabase();
00260     return 0;
00261 }
00262 void dumpData()
00263 {
00264     char cmd[1024];
00265     sprintf(cmd, "csqldump >%s",Conf::config.getDbFile()); 
00266     int ret = system(cmd);
00267     if (ret != 0) { 
00268         printf("Table cannot be written. Recovery will fail\n");
00269     }
00270     return;
00271 }

Generated on Mon Jun 9 22:37:15 2008 for csql by  doxygen 1.4.7