int mdb_init ( size_t size ) { enum hashfunc_type hash_type = JENKINS_HASH; bool preallocate = false; bool start_lru_crawler = true; process_started = time (0); settings_init (size); init_lru_crawler (); init_lru_maintainer (); setbuf (stderr, NULL); if ( hash_init (hash_type) != 0 ) { fprintf (stderr, "Failed to initialize hash_algorithm!\n"); return - 1; } assoc_init (settings.hashpower_init); if ( enable_large_pages () == 0 ) { preallocate = true; } slabs_init (settings.maxbytes, settings.factor, preallocate); memcached_thread_init (); if ( start_assoc_maintenance_thread () == - 1 ) { return - 1; } if ( start_lru_crawler && start_lru_maintainer_thread () != 0 ) { fprintf (stderr, "Failed to enable LRU maintainer thread\n"); return - 1; } if ( settings.slab_reassign && start_slab_maintenance_thread () == - 1 ) { return - 1; } return 0; }
int main (int argc, char **argv) { int c; conn *l_conn; struct in_addr addr; int lock_memory = 0; int daemonize = 0; int maxcore = 0; char *username = 0; struct passwd *pw; struct sigaction sa; struct rlimit rlim; char *pid_file = NULL; /* init settings */ settings_init(); /* process arguments */ while ((c = getopt(argc, argv, "p:m:Mc:khirvdl:u:P:")) != -1) { switch (c) { case 'p': settings.port = atoi(optarg); break; case 'm': settings.maxbytes = atoi(optarg)*1024*1024; break; case 'M': settings.evict_to_free = 0; break; case 'c': settings.maxconns = atoi(optarg); break; case 'h': usage(); exit(0); case 'i': usage_license(); exit(0); case 'k': lock_memory = 1; break; case 'v': settings.verbose++; break; case 'l': if (!inet_aton(optarg, &addr)) { fprintf(stderr, "Illegal address: %s\n", optarg); return 1; } else { settings.interface = addr; } break; case 'd': daemonize = 1; break; case 'r': maxcore = 1; break; case 'u': username = optarg; break; case 'P': pid_file = optarg; break; default: fprintf(stderr, "Illegal argument \"%c\"\n", c); return 1; } } if (maxcore) { struct rlimit rlim_new; /* * First try raising to infinity; if that fails, try bringing * the soft limit to the hard. */ if (getrlimit(RLIMIT_CORE, &rlim)==0) { rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &rlim_new)!=0) { /* failed. try raising just to the old max */ rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_max; (void) setrlimit(RLIMIT_CORE, &rlim_new); } } /* * getrlimit again to see what we ended up with. Only fail if * the soft limit ends up 0, because then no core files will be * created at all. */ if ((getrlimit(RLIMIT_CORE, &rlim)!=0) || rlim.rlim_cur==0) { fprintf(stderr, "failed to ensure corefile creation\n"); exit(1); } } /* * If needed, increase rlimits to allow as many connections * as needed. */ if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { fprintf(stderr, "failed to getrlimit number of files\n"); exit(1); } else { int maxfiles = settings.maxconns; if (rlim.rlim_cur < maxfiles) rlim.rlim_cur = maxfiles + 3; if (rlim.rlim_max < rlim.rlim_cur) rlim.rlim_max = rlim.rlim_cur; if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { fprintf(stderr, "failed to set rlimit for open files. Try running as root or requesting smaller maxconns value.\n"); exit(1); } } /* * initialization order: first create the listening socket * (may need root on low ports), then drop root if needed, * then daemonise if needed, then init libevent (in some cases * descriptors created by libevent wouldn't survive forking). */ /* create the listening socket and bind it */ l_socket = server_socket(settings.port); if (l_socket == -1) { fprintf(stderr, "failed to listen\n"); exit(1); } /* lose root privileges if we have them */ if (getuid()== 0 || geteuid()==0) { if (username==0 || *username=='\0') { fprintf(stderr, "can't run as root without the -u switch\n"); return 1; } if ((pw = getpwnam(username)) == 0) { fprintf(stderr, "can't find the user %s to switch to\n", username); return 1; } if (setgid(pw->pw_gid)<0 || setuid(pw->pw_uid)<0) { fprintf(stderr, "failed to assume identity of user %s\n", username); return 1; } } /* daemonize if requested */ /* if we want to ensure our ability to dump core, don't chdir to / */ if (daemonize) { int res; res = daemon(maxcore, settings.verbose); if (res == -1) { fprintf(stderr, "failed to daemon() in order to daemonize\n"); return 1; } } /* initialize other stuff */ item_init(); event_init(); stats_init(); assoc_init(); conn_init(); slabs_init(settings.maxbytes); /* lock paged memory if needed */ if (lock_memory) { #ifdef HAVE_MLOCKALL mlockall(MCL_CURRENT | MCL_FUTURE); #else fprintf(stderr, "warning: mlockall() not supported on this platform. proceeding without.\n"); #endif } /* * ignore SIGPIPE signals; we can use errno==EPIPE if we * need that information */ sa.sa_handler = SIG_IGN; sa.sa_flags = 0; if (sigemptyset(&sa.sa_mask) == -1 || sigaction(SIGPIPE, &sa, 0) == -1) { perror("failed to ignore SIGPIPE; sigaction"); exit(1); } /* create the initial listening connection */ if (!(l_conn = conn_new(l_socket, conn_listening, EV_READ | EV_PERSIST))) { fprintf(stderr, "failed to create listening connection"); exit(1); } /* initialise deletion array and timer event */ deltotal = 200; delcurr = 0; todelete = malloc(sizeof(item *)*deltotal); delete_handler(0,0,0); /* sets up the event */ /* save the PID in if we're a daemon */ if (daemonize) save_pid(getpid(),pid_file); /* enter the loop */ event_loop(0); /* remove the PID file if we're a daemon */ if (daemonize) remove_pidfile(pid_file); return 0; }
int main (int argc, char **argv) { int c; int l_socket; conn *l_conn; struct in_addr addr; int lock_memory = 0; int daemonize = 0; /* initialize stuff */ event_init(); stats_init(); assoc_init(); settings_init(); conn_init(); /* process arguments */ while ((c = getopt(argc, argv, "p:s:m:c:khdl:")) != -1) { switch (c) { case 'p': settings.port = atoi(optarg); break; case 's': settings.maxitems = atoi(optarg); break; case 'm': settings.maxbytes = atoi(optarg)*1024*1024; break; case 'c': settings.maxconns = atoi(optarg); break; case 'h': usage(); exit(0); case 'k': lock_memory = 1; break; case 'l': if (!inet_aton(optarg, &addr)) { fprintf(stderr, "Illegal address: %s\n", optarg); return 1; } else { settings.interface = addr; } break; case 'd': daemonize = 1; break; default: fprintf(stderr, "Illegal argument \"%c\"\n", c); return 1; } } if (daemonize) { int child; child = fork(); if (child == -1) { fprintf(stderr, "failed to fork() in order to daemonize\n"); return 1; } if (child) { /* parent */ exit(0); } else { /* child */ setsid(); /* become a session group leader */ child = fork(); /* stop being a session group leader */ if (child) { /* parent */ exit(0); } else { int null; chdir("/"); null = open("/dev/null", O_RDWR); dup2(null, 0); dup2(null, 1); dup2(null, 2); close(null); } } } /* lock paged memory if needed */ if (lock_memory) { mlockall(MCL_CURRENT | MCL_FUTURE); } /* create the listening socket and bind it */ l_socket = server_socket(settings.port); if (l_socket == -1) { fprintf(stderr, "failed to listen\n"); exit(1); } /* create the initial listening connection */ if (!(l_conn = conn_new(l_socket, conn_listening, EV_READ | EV_PERSIST))) { fprintf(stderr, "failed to create listening connection"); exit(1); } /* initialise deletion array and timer event */ deltotal = 200; delcurr = 0; todelete = malloc(sizeof(item *)*deltotal); delete_handler(0,0,0); /* sets up the event */ /* enter the loop */ event_loop(0); return; }