00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
00052
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
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; }
00147 case 'c' : { opt = 1; break; }
00148 case 'v' : { opt = 2; break; }
00149 default: opt=10;
00150
00151 }
00152 }
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
00244 cleanupDeadProcs(sysdb);
00245
00246
00247
00248
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 }