00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "VestaLog.H"
00026 #include "Recovery.H"
00027 #include "VestaSource.H"
00028 #include "ShortIdImpl.H"
00029 #include "ReadersWritersLock.H"
00030 #include "VRConcurrency.H"
00031 #include "VestaConfig.H"
00032 #include "VestaSourceServer.H"
00033 #include "VMemPool.H"
00034 #include "VRWeed.H"
00035 #include "DirShortId.H"
00036 #include "FPShortId.H"
00037 #include "Mastership.H"
00038 #include "Replication.H"
00039 #include "nfsd.H"
00040 #include "logging.H"
00041 #include "getopt.h"
00042 #include <stdlib.h>
00043 #include <pthread.h>
00044 #include <errno.h>
00045 #include <iomanip>
00046 #include <stdio.h>
00047 #include <signal.h>
00048 #include <sys/resource.h>
00049 #ifdef __osf__
00050 #include <sys/sysinfo.h>
00051 #include <machine/hal_sysinfo.h>
00052 #endif
00053
00054 #include "MutableSidref.H"
00055
00056 #include "timing.H"
00057 #include "lock_timing.H"
00058
00059 using std::fstream;
00060 using std::endl;
00061 using std::cerr;
00062 using std::cout;
00063
00064 #define progress(letter)
00065
00066
00067
00068 char *program_name;
00069 int nfs_bufreqs;
00070 int nfs_threads;
00071
00072
00073 extern int nfs_port;
00074 extern void GlueInit();
00075
00076 #define DEFAULT_UMASK 022
00077
00078 static void usage(FILE *fp, int n)
00079 {
00080 cerr << "Usage: " << program_name
00081 << " [-h] [-d level] [-f first-ckp]" << endl;
00082 exit(n);
00083 }
00084
00085
00086
00087
00088 void
00089 Recover(Text log_dir, int first, Text log_dir2, bool bakckp)
00090 {
00091 VRLog.open(log_dir.chars(), first, false, true,
00092 log_dir2.Empty() ? NULL : log_dir2.chars(), bakckp);
00093
00094 fstream* ckpt = VRLog.openCheckpoint();
00095 if (ckpt != NULL) {
00096 VMemPool::readCheckpoint(*ckpt, false);
00097 RecoveryReader crr(ckpt);
00098 RecoverFrom(&crr);
00099 ckpt->close();
00100 delete ckpt;
00101 }
00102 if(MutableSidrefRecoveryCheck())
00103 {
00104 MutableSidrefInit();
00105 }
00106
00107 do {
00108 RecoveryReader lrr(&VRLog);
00109 RecoverFrom(&lrr);
00110 if(MutableSidrefRecoveryCheck())
00111 {
00112 MutableSidrefCheck(0, LongId::noLock);
00113 }
00114 } while (VRLog.nextLog());
00115 }
00116
00117
00118 #if defined(__linux__)
00119
00120 static pthread_t g_main_thread = pthread_self();
00121 #endif
00122 extern "C" void
00123 SigHandler(int sig)
00124 {
00125 #if defined(__linux__)
00126
00127
00128
00129
00130
00131
00132
00133 if(pthread_self() != g_main_thread)
00134 {
00135 return;
00136 }
00137 #endif
00138 char* msg;
00139 if (sig == SIGINT) {
00140 msg = "repository: Got SIGINT (^C interrupt signal); exiting.\n";
00141 } else if (sig == SIGTERM) {
00142 msg = "repository: Got SIGTERM (kill signal); exiting.\n";
00143 } else {
00144 assert(false);
00145 }
00146 write(2, msg, strlen(msg));
00147 exit(3);
00148 }
00149
00150
00151 void
00152 Siguser1Inner(int sig)
00153 {
00154 return;
00155 }
00156
00157 extern "C" void
00158 Sigusr1Handler(int sig)
00159 {
00160 Siguser1Inner(sig);
00161 }
00162
00163 void
00164 Siguser2Inner(int sig)
00165 {
00166 return;
00167 }
00168
00169 extern "C" void
00170 Sigusr2Handler(int sig)
00171 {
00172 Siguser2Inner(sig);
00173 }
00174
00175 #ifdef __osf__
00176 extern int __first_fit;
00177 #endif
00178
00179
00180 extern const char *Version;
00181
00182
00183 time_t serverStartTime;
00184
00185 int
00186 main(int argc, char *argv[])
00187 {
00188 int c;
00189 sigset_t set;
00190
00191 signal(SIGINT, SigHandler);
00192 signal(SIGTERM, SigHandler);
00193 signal(SIGPIPE, SIG_IGN);
00194 signal(SIGQUIT, SIG_DFL);
00195 signal(SIGSEGV, SIG_DFL);
00196 signal(SIGABRT, SIG_DFL);
00197 signal(SIGILL, SIG_DFL);
00198 signal(SIGBUS, SIG_DFL);
00199 signal(SIGUSR1, Sigusr1Handler);
00200 signal(SIGUSR2, Sigusr2Handler);
00201
00202
00203 sigemptyset(&set);
00204 sigaddset(&set, SIGUSR1);
00205 sigaddset(&set, SIGUSR2);
00206 sigprocmask(SIG_BLOCK, &set, NULL);
00207
00208 #ifdef __osf__
00209
00210 __first_fit = 2;
00211 #endif
00212
00213
00214 bool ok, bakckp = 0;
00215 Text metadata_root, log_dir, log_dir2, scratch;
00216 try {
00217 Text t;
00218 metadata_root = VestaConfig::get_Text("Repository", "metadata_root");
00219 chdir(metadata_root.cchars());
00220 SourceOrDerived::setMetadataRootLocalName("");
00221 nfs_port = VestaConfig::get_int("Repository", "NFS_port");
00222 log_dir = VestaConfig::get_Text("Repository", "log_dir");
00223 if (!VestaConfig::get("Repository", "log_dir2", log_dir2)) {
00224 log_dir2 = "";
00225 }
00226 if (VestaConfig::get("Repository", "backup_ckp", t)) {
00227 bakckp = strtol(t.cchars(), NULL, 0) != 0;
00228 }
00229 nfs_bufreqs = VestaConfig::get_int("Repository", "bufreqs");
00230 nfs_threads = VestaConfig::get_int("Repository", "threads");
00231 if (VestaConfig::get("Repository", "debug_level", t)) {
00232 Repos::setDebugLevel(strtol(t.cchars(), NULL, 0));
00233 }
00234 if (VestaConfig::get("Repository", "umask", t)) {
00235 umask(strtol(t.cchars(), NULL, 0));
00236 } else {
00237 umask(DEFAULT_UMASK);
00238 }
00239
00240 if(VestaConfig::get("Repository", "descriptor_limit", t))
00241 {
00242 int new_limit = strtol(t.cchars(), NULL, 0);
00243 if(errno == ERANGE)
00244 {
00245 cerr << "[Repository]descriptor_limit: " << strerror(ERANGE)
00246 << endl;
00247 exit(2);
00248 }
00249
00250 #ifdef __osf__
00251
00252
00253 if(new_limit > 4096)
00254 {
00255 int err = setsysinfo(SSI_FD_NEWMAX, NULL, 0, NULL, 1);
00256 if(err != 0)
00257 {
00258 int l_errno = errno;
00259 cerr << "Enabling more than 4096 descriptors: "
00260 << strerror(l_errno) << endl;
00261 }
00262 }
00263 #endif
00264
00265
00266 struct rlimit new_rlimit;
00267 new_rlimit.rlim_cur = new_limit;
00268 new_rlimit.rlim_max = new_limit;
00269 int err = setrlimit(RLIMIT_NOFILE, &new_rlimit);
00270 if(err != 0)
00271 {
00272 int l_errno = errno;
00273 cerr << "setrlimit(RLIMIT_NOFILE, {"
00274 << new_limit << ", " << new_limit << "}): "
00275 << strerror(l_errno) << endl;
00276 }
00277 }
00278 } catch (VestaConfig::failure f) {
00279 cerr << f.msg << endl;
00280 exit(2);
00281 }
00282
00283
00284 program_name = argv[0];
00285 int first = -1;
00286 opterr = 0;
00287 while ((c = getopt(argc, argv, "hd:f:")) != EOF)
00288 switch (c) {
00289 case 'h':
00290 usage(stdout, 0);
00291 break;
00292 case 'd':
00293 Repos::setDebugLevel(strtol(optarg, NULL, 0));
00294 break;
00295 case 'f':
00296 first = strtol(optarg, NULL, 0);
00297 break;
00298 case 0:
00299 break;
00300 case '?':
00301 default:
00302 usage(stderr, 1);
00303 }
00304
00305
00306 if (optind != argc)
00307 usage(stderr, 1);
00308
00309
00310 if (Repos::isDebugLevel(DBG_SAVECORE)) {
00311 system("if [ -e core ] ; then mv core core.`date +%m-%d-%y.%T` ; fi");
00312 }
00313
00314 #ifdef __osf__
00315
00316
00317 Basics::thread::self().set_sched_param(SCHED_RR,
00318 sched_get_priority_min(SCHED_RR));
00319 #endif
00320
00321
00322 try {
00323 progress('a');
00324 ShortIdServerInit();
00325 progress('b');
00326 AccessControl::serverInit();
00327 progress('c');
00328 VestaSource::init();
00329 progress('d');
00330 InitDirShortId();
00331 progress('e');
00332 InitFPShortId();
00333 progress('f');
00334 MastershipInit1();
00335 progress('g');
00336 Recover(log_dir, first, log_dir2, bakckp);
00337 progress('h');
00338 VRLog.loggingBegin();
00339 progress('i');
00340 if (!Repos::isDebugLevel(DBG_NOWEEDREC)) {
00341 int err = SourceWeed();
00342 if (err) {
00343 Repos::dprintf(DBG_ALWAYS,
00344 "source weed failed during recovery, errno = %d\n", err);
00345 abort();
00346 }
00347 err = DoDeletions();
00348 if (err) {
00349 Repos::dprintf(DBG_ALWAYS,
00350 "deletions failed during recovery, errno = %d\n", err);
00351 abort();
00352 }
00353 }
00354 progress('j');
00355 ShortIdServerInit2();
00356 progress('k');
00357 ShortIdServerExport(NULL);
00358 progress('l');
00359 VestaSource::recoveryDone();
00360 progress('m');
00361 MastershipInit2();
00362 progress('n');
00363 ReplicationCleanup();
00364 progress('o');
00365
00366 serverStartTime = time((time_t *) 0);
00367 VestaSourceServerExport();
00368 progress('p');
00369 GlueInit();
00370 progress('q');
00371 nfsd_init(nfs_threads);
00372 progress('r');
00373 Repos::dprintf(DBG_ALWAYS, "Repository server started. Version %s\n",
00374 Version);
00375
00376
00377
00378
00379 sigemptyset(&set);
00380 sigaddset(&set, SIGUSR1);
00381 sigaddset(&set, SIGUSR2);
00382 sigprocmask(SIG_UNBLOCK, &set, NULL);
00383 progress('s');
00384 CheckpointServer();
00385
00386 } catch (SRPC::failure f) {
00387 cerr << program_name << ": SRPC::failure in initialization: "
00388 << f.msg << " (" << f.r << ")" << endl;
00389 abort();
00390 } catch (VestaLog::Error e) {
00391 cerr << program_name << ": VestaLog::Error in initialization: "
00392 << e.msg << " (" << e.r << ")" << endl;
00393 if (e.msg == "VestaLog::open got \"Permission denied\" locking lock") {
00394 cerr << "Check if there is already a repository running."<< endl;
00395 exit(1);
00396 } else if (e.msg ==
00397 "VestaLog::open got \"Permission denied\" opening lock") {
00398 cerr << "Check that you have the right user id." << endl;
00399 exit(1);
00400 }
00401 abort();
00402 } catch (VestaConfig::failure f) {
00403 cerr << f.msg << endl;
00404 exit(2);
00405 }
00406
00407
00408 assert(false);
00409 return 0;
00410 }
00411