1 package MogileFS
::Server
;
9 MogileFS::Server - MogileFS (distributed filesystem) server
13 $s = MogileFS::Server->server;
18 # based on where we found this file (a pure-perl module),
19 # add the mogdeps/ subdirectory of that base to our @INC search
20 # path, where all the misc Mogile dependencies are installed.
23 if (! $ENV{MOGILE_NO_BUILTIN_DEPS} &&
24 ($libpath = $INC{"MogileFS/Server.pm"}) &&
25 $libpath =~ s!MogileFS/Server.pm$!!)
27 my $dep_dir = "${libpath}mogdeps";
29 unless (($ENV{PERL5LIB} || "") =~ /$dep_dir/) {
30 $ENV{PERL5LIB} = join(":",
31 split(/:/, $ENV{PERL5LIB} || ""),
42 use File::Basename ();
51 use MogileFS::Util qw(daemonize);
55 use MogileFS
::ProcManager
;
56 use MogileFS
::Connection
::Client
;
57 use MogileFS
::Connection
::Worker
;
59 use MogileFS
::Worker
::Query
;
60 use MogileFS
::Worker
::Delete
;
61 use MogileFS
::Worker
::Replicate
;
62 use MogileFS
::Worker
::Reaper
;
63 use MogileFS
::Worker
::Monitor
;
64 use MogileFS
::Worker
::Fsck
;
65 use MogileFS
::Worker
::JobMaster
;
67 use MogileFS
::HTTPFile
;
76 use MogileFS
::Store
::MySQL
; # FIXME: don't load this until after reading their config, but before fork.
78 use MogileFS
::ReplicationPolicy
::MultipleHosts
;
80 my $server; # server singleton
83 return $server ||= bless {}, $pkg;
86 # --------------------------------------------------------------------------
88 # --------------------------------------------------------------------------
93 MogileFS
::Config
->load_config;
96 die "mogilefsd cannot be run as root\n"
97 if $< == 0 && MogileFS
->config('user') ne "root";
99 MogileFS
::Config
->check_database;
100 daemonize
() if MogileFS
->config("daemonize");
102 MogileFS
::ProcManager
->set_min_workers('queryworker' => MogileFS
->config('query_jobs'));
103 MogileFS
::ProcManager
->set_min_workers('delete' => MogileFS
->config('delete_jobs'));
104 MogileFS
::ProcManager
->set_min_workers('replicate' => MogileFS
->config('replicate_jobs'));
105 MogileFS
::ProcManager
->set_min_workers('reaper' => MogileFS
->config('reaper_jobs'));
106 MogileFS
::ProcManager
->set_min_workers('monitor' => MogileFS
->config('monitor_jobs'));
107 MogileFS
::ProcManager
->set_min_workers('fsck' => MogileFS
->config('fsck_jobs'));
108 MogileFS
::ProcManager
->set_min_workers('job_master' => 1);
111 Sys
::Syslog
::openlog
('mogilefsd', 'pid', 'daemon');
112 Mgd
::log('info', 'beginning run');
114 unless (MogileFS
::ProcManager
->write_pidfile) {
115 Mgd
::log('info', "Couldn't write pidfile, ending run");
116 Sys
::Syslog
::closelog
();
120 # Install signal handlers.
122 my @children = MogileFS
::ProcManager
->child_pids;
123 print STDERR
scalar @children, " children to kill.\n" if $DEBUG;
124 my $count = kill( 'TERM' => @children );
125 print STDERR
"Sent SIGTERM to $count children.\n" if $DEBUG;
126 MogileFS
::ProcManager
->remove_pidfile;
127 Mgd
::log('info', 'ending run due to SIGTERM');
128 Sys
::Syslog
::closelog
();
134 my @children = MogileFS
::ProcManager
->child_pids;
135 print STDERR
scalar @children, " children to kill.\n" if $DEBUG;
136 my $count = kill( 'INT' => @children );
137 print STDERR
"Sent SIGINT to $count children.\n" if $DEBUG;
138 MogileFS
::ProcManager
->remove_pidfile;
139 Mgd
::log('info', 'ending run due to SIGINT');
142 $SIG{PIPE
} = 'IGNORE'; # catch them by hand
144 # setup server sockets to listen for client connections
146 foreach my $listen (@
{ MogileFS
->config('listen') }) {
147 my $server = IO
::Socket
::INET
->new(LocalAddr
=> $listen,
153 or die "Error creating socket: $@\n";
155 # save sub to accept a client
156 push @servers, $server;
157 Danga
::Socket
->AddOtherFds( fileno($server) => sub {
158 my $csock = $server->accept
160 MogileFS
::Connection
::Client
->new($csock);
164 MogileFS
::ProcManager
->push_pre_fork_cleanup(sub {
165 # so children don't hold server connection open
166 close($_) foreach @servers;
169 # setup the post event loop callback to spawn jobs, and the timeout
170 Danga
::Socket
->DebugLevel(3);
171 Danga
::Socket
->SetLoopTimeout( 250 ); # 250 milliseconds
172 Danga
::Socket
->SetPostLoopCallback(MogileFS
::ProcManager
->PostEventLoopChecker);
174 # and now, actually start listening for events
176 print( "Starting event loop for frontend job on pid $$.\n" ) if $DEBUG;
177 Danga
::Socket
->EventLoop();
181 Mgd
::log('err', "crash log: $@");
184 Mgd
::log('info', 'ending run');
185 Sys
::Syslog
::closelog
();
189 # --------------------------------------------------------------------------
192 # just so MogileFS->config($key) will work:
193 use MogileFS
::Config
qw(config);
197 sub register_worker_command
{
198 # just pass this through to the Worker class
199 return MogileFS
::Worker
::Query
::register_command
(@_);
202 sub register_global_hook
{
203 $hooks{$_[0]} = $_[1];
207 sub unregister_global_hook
{
208 delete $hooks{$_[0]};
212 sub run_global_hook
{
213 my $hookname = shift;
214 my $ref = $hooks{$hookname};
215 return $ref->(@_) if defined $ref;
219 # --------------------------------------------------------------------------
221 package Mgd
; # conveniently short name
224 use MogileFS
::Config
;
225 use MogileFS
::Util
qw(error fatal debug); # for others calling Mgd::foo()
228 return MogileFS
::Server
->server;
231 # database checking/connecting
232 sub validate_dbh
{ Mgd
::get_store
()->recheck_dbh }
233 sub get_dbh
{ return Mgd
::get_store
()->dbh }
235 # the eventual replacement for callers asking for a dbh directly:
236 # they'll ask for the current store, which is a database abstraction
238 my ($store, $store_pid);
240 return $store if $store && $store_pid == $$;
242 return $store = MogileFS
::Store
->new;
245 # only for t/ scripts to explicitly set a store, without loading in a config
252 # log stuff to syslog or the screen
254 # simple logging functionality
255 if (! $MogileFS::Config
::daemonize
) {
256 # syslog acts like printf so we have to use printf and append a \n
257 shift; # ignore the first parameter (info, warn, critical, etc)
258 my $mask = shift; # format string
259 $mask .= "\n" unless $mask =~ /\n$/;
260 my $message = @_ ?
sprintf($mask, @_) : $mask;
263 # just pass the parameters to syslog
264 Sys
::Syslog
::syslog
(@_);
270 #Just for MakeMaker's kinda lame regexp for ABSTRACT_FROM
272 mogilefs
::server
- MogileFS
(distributed filesystem
) server
.